summaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/ab5500-core.c1
-rw-r--r--drivers/mfd/ab8500-core.c5
-rw-r--r--drivers/mfd/mfd-core.c2
-rw-r--r--drivers/mfd/s5m-core.c2
-rw-r--r--drivers/mfd/tps65910.c2
-rw-r--r--drivers/mfd/tps65912-core.c2
-rw-r--r--drivers/mfd/twl-core.c71
-rw-r--r--drivers/mfd/wm8350-irq.c1
-rw-r--r--drivers/mfd/wm8994-core.c14
-rw-r--r--drivers/mfd/wm8994-regmap.c1
11 files changed, 73 insertions, 29 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f147395bac9..1489c3540f9 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -201,6 +201,7 @@ config MENELAUS
config TWL4030_CORE
bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
depends on I2C=y && GENERIC_HARDIRQS
+ select IRQ_DOMAIN
help
Say yes here if you have TWL4030 / TWL6030 family chip on your board.
This core driver provides register access and IRQ handling
diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c
index bd56a764dea..54d0fe40845 100644
--- a/drivers/mfd/ab5500-core.c
+++ b/drivers/mfd/ab5500-core.c
@@ -28,7 +28,6 @@
#include <linux/bitops.h>
#include <linux/spinlock.h>
#include <linux/mfd/core.h>
-#include <linux/version.h>
#include <linux/mfd/db5500-prcmu.h>
#include "ab5500-core.h"
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 53e2a80f42f..d295941c9a3 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -956,11 +956,12 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
return ret;
out_freeirq:
- if (ab8500->irq_base) {
+ if (ab8500->irq_base)
free_irq(ab8500->irq, ab8500);
out_removeirq:
+ if (ab8500->irq_base)
ab8500_irq_remove(ab8500);
- }
+
return ret;
}
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 0f5922812bf..411f523d487 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -123,7 +123,7 @@ static int mfd_add_device(struct device *parent, int id,
}
if (!cell->ignore_resource_conflicts) {
- ret = acpi_check_resource_conflict(res);
+ ret = acpi_check_resource_conflict(&res[r]);
if (ret)
goto fail_res;
}
diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c
index e075c113eec..caadabeed8e 100644
--- a/drivers/mfd/s5m-core.c
+++ b/drivers/mfd/s5m-core.c
@@ -105,7 +105,7 @@ static int s5m87xx_i2c_probe(struct i2c_client *i2c,
s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
i2c_set_clientdata(s5m87xx->rtc, s5m87xx);
- if (pdata->cfg_pmic_irq)
+ if (pdata && pdata->cfg_pmic_irq)
pdata->cfg_pmic_irq();
s5m_irq_init(s5m87xx);
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index 01cf5012a08..4392f6bca15 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -168,7 +168,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
goto err;
init_data->irq = pmic_plat_data->irq;
- init_data->irq_base = pmic_plat_data->irq;
+ init_data->irq_base = pmic_plat_data->irq_base;
tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base);
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c
index 5fec23a9ac0..74fd8cb5f37 100644
--- a/drivers/mfd/tps65912-core.c
+++ b/drivers/mfd/tps65912-core.c
@@ -151,7 +151,7 @@ int tps65912_device_init(struct tps65912 *tps65912)
goto err;
init_data->irq = pmic_plat_data->irq;
- init_data->irq_base = pmic_plat_data->irq;
+ init_data->irq_base = pmic_plat_data->irq_base;
ret = tps65912_irq_init(tps65912, init_data->irq, init_data);
if (ret < 0)
goto err;
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 8ce3959c691..806680d1bbb 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -38,6 +38,7 @@
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
+#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/regulator/machine.h>
@@ -149,7 +150,7 @@
#define TWL_MODULE_LAST TWL4030_MODULE_LAST
-#define TWL4030_NR_IRQS 8
+#define TWL4030_NR_IRQS 34 /* core:8, power:8, gpio: 18 */
#define TWL6030_NR_IRQS 20
/* Base Address defns for twl4030_map[] */
@@ -263,10 +264,6 @@ struct twl_client {
static struct twl_client twl_modules[TWL_NUM_SLAVES];
-#ifdef CONFIG_IRQ_DOMAIN
-static struct irq_domain domain;
-#endif
-
/* mapping the module id to slave id and base address */
struct twl_mapping {
unsigned char sid; /* Slave ID */
@@ -621,6 +618,8 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
unsigned num_consumers, unsigned long features)
{
unsigned sub_chip_id;
+ struct twl_regulator_driver_data drv_data;
+
/* regulator framework demands init_data ... */
if (!pdata)
return NULL;
@@ -630,7 +629,19 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
pdata->num_consumer_supplies = num_consumers;
}
- pdata->driver_data = (void *)features;
+ if (pdata->driver_data) {
+ /* If we have existing drv_data, just add the flags */
+ struct twl_regulator_driver_data *tmp;
+ tmp = pdata->driver_data;
+ tmp->features |= features;
+ } else {
+ /* add new driver data struct, used only during init */
+ drv_data.features = features;
+ drv_data.set_voltage = NULL;
+ drv_data.get_voltage = NULL;
+ drv_data.data = NULL;
+ pdata->driver_data = &drv_data;
+ }
/* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */
sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
@@ -753,9 +764,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
/* we need to connect regulators to this transceiver */
if (twl_has_regulator() && child) {
- usb1v5.dev = child;
- usb1v8.dev = child;
- usb3v1.dev = child;
+ usb1v5.dev_name = dev_name(child);
+ usb1v8.dev_name = dev_name(child);
+ usb3v1.dev_name = dev_name(child);
}
}
if (twl_has_usb() && pdata->usb && twl_class_is_6030()) {
@@ -801,7 +812,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
return PTR_ERR(child);
/* we need to connect regulators to this transceiver */
if (twl_has_regulator() && child)
- usb3v3.dev = child;
+ usb3v3.dev_name = dev_name(child);
} else if (twl_has_regulator() && twl_class_is_6030()) {
if (features & TWL6025_SUBCLASS)
child = add_regulator(TWL6025_REG_LDOUSB,
@@ -937,6 +948,31 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
/* twl6030 regulators */
if (twl_has_regulator() && twl_class_is_6030() &&
!(features & TWL6025_SUBCLASS)) {
+ child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1,
+ features);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+
+ child = add_regulator(TWL6030_REG_VDD2, pdata->vdd2,
+ features);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+
+ child = add_regulator(TWL6030_REG_VDD3, pdata->vdd3,
+ features);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+
+ child = add_regulator(TWL6030_REG_V1V8, pdata->v1v8,
+ features);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+
+ child = add_regulator(TWL6030_REG_V2V1, pdata->v2v1,
+ features);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+
child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc,
features);
if (IS_ERR(child))
@@ -1227,14 +1263,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
pdata->irq_base = status;
pdata->irq_end = pdata->irq_base + nr_irqs;
-
-#ifdef CONFIG_IRQ_DOMAIN
- domain.irq_base = pdata->irq_base;
- domain.nr_irq = nr_irqs;
- domain.of_node = of_node_get(node);
- domain.ops = &irq_domain_simple_ops;
- irq_domain_add(&domain);
-#endif
+ irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
+ &irq_domain_simple_ops, NULL);
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
dev_dbg(&client->dev, "can't talk I2C?\n");
@@ -1315,11 +1345,10 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
}
-#ifdef CONFIG_OF_DEVICE
+ status = -ENODEV;
if (node)
status = of_platform_populate(node, NULL, NULL, &client->dev);
- else
-#endif
+ if (status)
status = add_children(pdata, id->driver_data);
fail:
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
index 8a1fafd0bf7..9fd01bf63c5 100644
--- a/drivers/mfd/wm8350-irq.c
+++ b/drivers/mfd/wm8350-irq.c
@@ -496,7 +496,6 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
mutex_init(&wm8350->irq_lock);
wm8350->chip_irq = irq;
- wm8350->irq_base = pdata->irq_base;
if (pdata && pdata->irq_base > 0)
irq_base = pdata->irq_base;
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index f117e7fb932..a04b3c108c8 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -256,6 +256,20 @@ static int wm8994_suspend(struct device *dev)
break;
}
+ switch (wm8994->type) {
+ case WM1811:
+ ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
+ if (ret < 0) {
+ dev_err(dev, "Failed to read jackdet: %d\n", ret);
+ } else if (ret & WM1811_JACKDET_MODE_MASK) {
+ dev_dbg(dev, "CODEC still active, ignoring suspend\n");
+ return 0;
+ }
+ break;
+ default:
+ break;
+ }
+
/* Disable LDO pulldowns while the device is suspended if we
* don't know that something will be driving them. */
if (!wm8994->ldo_ena_always_driven)
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c
index c598ae69b8f..bc0c5096539 100644
--- a/drivers/mfd/wm8994-regmap.c
+++ b/drivers/mfd/wm8994-regmap.c
@@ -806,6 +806,7 @@ static bool wm1811_readable_register(struct device *dev, unsigned int reg)
case WM8994_DC_SERVO_2:
case WM8994_DC_SERVO_READBACK:
case WM8994_DC_SERVO_4:
+ case WM8994_DC_SERVO_4E:
case WM8994_ANALOGUE_HP_1:
case WM8958_MIC_DETECT_1:
case WM8958_MIC_DETECT_2: