Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: mfd: Include linux/io.h to jz4740-adc mfd: Use request_threaded_irq for twl4030-irq instead of irq_set_chained_handler mfd: Base interrupt for twl4030-irq must be one-shot mfd: Handle tps65910 clear-mask correctly mfd: add #ifdef CONFIG_DEBUG_FS guard for ab8500_debug_resources mfd: Fix twl-core oops while calling twl_i2c_* for unbound driver mfd: include linux/module.h for ab5500-debugfs mfd: Update wm8994 active device checks for WM1811 mfd: Set tps6586x bits if new value is different from the old one mfd: Set da903x bits if new value is different from the old one mfd: Set adp5520 bits if new value is different from the old one mfd: Add missed free_irq in da903x_remove
This commit is contained in:
commit
0703c680f6
@ -4,7 +4,7 @@
|
|||||||
* Debugfs support for the AB5500 MFD driver
|
* Debugfs support for the AB5500 MFD driver
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/export.h>
|
#include <linux/module.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/mfd/ab5500/ab5500.h>
|
#include <linux/mfd/ab5500/ab5500.h>
|
||||||
|
@ -620,6 +620,7 @@ static struct resource __devinitdata ab8500_fg_resources[] = {
|
|||||||
|
|
||||||
static struct resource __devinitdata ab8500_chargalg_resources[] = {};
|
static struct resource __devinitdata ab8500_chargalg_resources[] = {};
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
static struct resource __devinitdata ab8500_debug_resources[] = {
|
static struct resource __devinitdata ab8500_debug_resources[] = {
|
||||||
{
|
{
|
||||||
.name = "IRQ_FIRST",
|
.name = "IRQ_FIRST",
|
||||||
@ -634,6 +635,7 @@ static struct resource __devinitdata ab8500_debug_resources[] = {
|
|||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct resource __devinitdata ab8500_usb_resources[] = {
|
static struct resource __devinitdata ab8500_usb_resources[] = {
|
||||||
{
|
{
|
||||||
|
@ -109,7 +109,7 @@ int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask)
|
|||||||
|
|
||||||
ret = __adp5520_read(chip->client, reg, ®_val);
|
ret = __adp5520_read(chip->client, reg, ®_val);
|
||||||
|
|
||||||
if (!ret && ((reg_val & bit_mask) == 0)) {
|
if (!ret && ((reg_val & bit_mask) != bit_mask)) {
|
||||||
reg_val |= bit_mask;
|
reg_val |= bit_mask;
|
||||||
ret = __adp5520_write(chip->client, reg, reg_val);
|
ret = __adp5520_write(chip->client, reg, reg_val);
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if ((reg_val & bit_mask) == 0) {
|
if ((reg_val & bit_mask) != bit_mask) {
|
||||||
reg_val |= bit_mask;
|
reg_val |= bit_mask;
|
||||||
ret = __da903x_write(chip->client, reg, reg_val);
|
ret = __da903x_write(chip->client, reg, reg_val);
|
||||||
}
|
}
|
||||||
@ -549,6 +549,7 @@ static int __devexit da903x_remove(struct i2c_client *client)
|
|||||||
struct da903x_chip *chip = i2c_get_clientdata(client);
|
struct da903x_chip *chip = i2c_get_clientdata(client);
|
||||||
|
|
||||||
da903x_remove_subdevs(chip);
|
da903x_remove_subdevs(chip);
|
||||||
|
free_irq(client->irq, chip);
|
||||||
kfree(chip);
|
kfree(chip);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/io.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -197,7 +197,7 @@ int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if ((reg_val & bit_mask) == 0) {
|
if ((reg_val & bit_mask) != bit_mask) {
|
||||||
reg_val |= bit_mask;
|
reg_val |= bit_mask;
|
||||||
ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val);
|
ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val);
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
data &= mask;
|
data &= ~mask;
|
||||||
err = tps65910_i2c_write(tps65910, reg, 1, &data);
|
err = tps65910_i2c_write(tps65910, reg, 1, &data);
|
||||||
if (err)
|
if (err)
|
||||||
dev_err(tps65910->dev, "write to reg %x failed\n", reg);
|
dev_err(tps65910->dev, "write to reg %x failed\n", reg);
|
||||||
|
@ -363,13 +363,13 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
|
|||||||
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
|
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
if (unlikely(!inuse)) {
|
||||||
|
pr_err("%s: not initialized\n", DRIVER_NAME);
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
sid = twl_map[mod_no].sid;
|
sid = twl_map[mod_no].sid;
|
||||||
twl = &twl_modules[sid];
|
twl = &twl_modules[sid];
|
||||||
|
|
||||||
if (unlikely(!inuse)) {
|
|
||||||
pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
mutex_lock(&twl->xfer_lock);
|
mutex_lock(&twl->xfer_lock);
|
||||||
/*
|
/*
|
||||||
* [MSG1]: fill the register address data
|
* [MSG1]: fill the register address data
|
||||||
@ -420,13 +420,13 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
|
|||||||
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
|
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
if (unlikely(!inuse)) {
|
||||||
|
pr_err("%s: not initialized\n", DRIVER_NAME);
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
sid = twl_map[mod_no].sid;
|
sid = twl_map[mod_no].sid;
|
||||||
twl = &twl_modules[sid];
|
twl = &twl_modules[sid];
|
||||||
|
|
||||||
if (unlikely(!inuse)) {
|
|
||||||
pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
mutex_lock(&twl->xfer_lock);
|
mutex_lock(&twl->xfer_lock);
|
||||||
/* [MSG1] fill the register address data */
|
/* [MSG1] fill the register address data */
|
||||||
msg = &twl->xfer_msg[0];
|
msg = &twl->xfer_msg[0];
|
||||||
|
@ -432,6 +432,7 @@ struct sih_agent {
|
|||||||
u32 edge_change;
|
u32 edge_change;
|
||||||
|
|
||||||
struct mutex irq_lock;
|
struct mutex irq_lock;
|
||||||
|
char *irq_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
@ -589,7 +590,7 @@ static inline int sih_read_isr(const struct sih *sih)
|
|||||||
* Generic handler for SIH interrupts ... we "know" this is called
|
* Generic handler for SIH interrupts ... we "know" this is called
|
||||||
* in task context, with IRQs enabled.
|
* in task context, with IRQs enabled.
|
||||||
*/
|
*/
|
||||||
static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
|
static irqreturn_t handle_twl4030_sih(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct sih_agent *agent = irq_get_handler_data(irq);
|
struct sih_agent *agent = irq_get_handler_data(irq);
|
||||||
const struct sih *sih = agent->sih;
|
const struct sih *sih = agent->sih;
|
||||||
@ -602,7 +603,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
|
|||||||
pr_err("twl4030: %s SIH, read ISR error %d\n",
|
pr_err("twl4030: %s SIH, read ISR error %d\n",
|
||||||
sih->name, isr);
|
sih->name, isr);
|
||||||
/* REVISIT: recover; eventually mask it all, etc */
|
/* REVISIT: recover; eventually mask it all, etc */
|
||||||
return;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (isr) {
|
while (isr) {
|
||||||
@ -616,6 +617,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
|
|||||||
pr_err("twl4030: %s SIH, invalid ISR bit %d\n",
|
pr_err("twl4030: %s SIH, invalid ISR bit %d\n",
|
||||||
sih->name, irq);
|
sih->name, irq);
|
||||||
}
|
}
|
||||||
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned twl4030_irq_next;
|
static unsigned twl4030_irq_next;
|
||||||
@ -668,18 +670,19 @@ int twl4030_sih_setup(int module)
|
|||||||
activate_irq(irq);
|
activate_irq(irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = irq_base;
|
|
||||||
twl4030_irq_next += i;
|
twl4030_irq_next += i;
|
||||||
|
|
||||||
/* replace generic PIH handler (handle_simple_irq) */
|
/* replace generic PIH handler (handle_simple_irq) */
|
||||||
irq = sih_mod + twl4030_irq_base;
|
irq = sih_mod + twl4030_irq_base;
|
||||||
irq_set_handler_data(irq, agent);
|
irq_set_handler_data(irq, agent);
|
||||||
irq_set_chained_handler(irq, handle_twl4030_sih);
|
agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name);
|
||||||
|
status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0,
|
||||||
|
agent->irq_name ?: sih->name, NULL);
|
||||||
|
|
||||||
pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name,
|
pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name,
|
||||||
irq, irq_base, twl4030_irq_next - 1);
|
irq, irq_base, twl4030_irq_next - 1);
|
||||||
|
|
||||||
return status;
|
return status < 0 ? status : irq_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME need a call to reverse twl4030_sih_setup() ... */
|
/* FIXME need a call to reverse twl4030_sih_setup() ... */
|
||||||
@ -733,8 +736,9 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* install an irq handler to demultiplex the TWL4030 interrupt */
|
/* install an irq handler to demultiplex the TWL4030 interrupt */
|
||||||
status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, 0,
|
status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih,
|
||||||
"TWL4030-PIH", NULL);
|
IRQF_ONESHOT,
|
||||||
|
"TWL4030-PIH", NULL);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status);
|
pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status);
|
||||||
goto fail_rqirq;
|
goto fail_rqirq;
|
||||||
|
@ -239,6 +239,7 @@ static int wm8994_suspend(struct device *dev)
|
|||||||
|
|
||||||
switch (wm8994->type) {
|
switch (wm8994->type) {
|
||||||
case WM8958:
|
case WM8958:
|
||||||
|
case WM1811:
|
||||||
ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1);
|
ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "Failed to read power status: %d\n", ret);
|
dev_err(dev, "Failed to read power status: %d\n", ret);
|
||||||
|
Loading…
Reference in New Issue
Block a user