summaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-12-01 15:16:22 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2009-12-01 15:16:22 +0800
commit838632438145ac6863377eb12d8b8eef9c55d288 (patch)
treefbb0757df837f3c75a99c518a3596c38daef162d /drivers/mfd
parent9996508b3353063f2d6c48c1a28a84543d72d70b (diff)
parent29e553631b2a0d4eebd23db630572e1027a9967a (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/ab3100-core.c6
-rw-r--r--drivers/mfd/ezx-pcap.c1
-rw-r--r--drivers/mfd/twl4030-core.c91
-rw-r--r--drivers/mfd/ucb1400_core.c32
-rw-r--r--drivers/mfd/ucb1x00-core.c1
-rw-r--r--drivers/mfd/wm831x-irq.c3
6 files changed, 81 insertions, 53 deletions
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index c533f86ff5e..61348102827 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -57,8 +57,6 @@
* The AB3100 is usually assigned address 0x48 (7-bit)
* The chip is defined in the platform i2c_board_data section.
*/
-static unsigned short normal_i2c[] = { 0x48, I2C_CLIENT_END };
-I2C_CLIENT_INSMOD_1(ab3100);
u8 ab3100_get_chip_type(struct ab3100 *ab3100)
{
@@ -647,7 +645,7 @@ struct ab3100_init_setting {
u8 setting;
};
-static const struct ab3100_init_setting __initdata
+static const struct ab3100_init_setting __initconst
ab3100_init_settings[] = {
{
.abreg = AB3100_MCA,
@@ -966,7 +964,7 @@ static int __exit ab3100_remove(struct i2c_client *client)
}
static const struct i2c_device_id ab3100_id[] = {
- { "ab3100", ab3100 },
+ { "ab3100", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ab3100_id);
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index 016be4938e4..87628891797 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -548,3 +548,4 @@ module_exit(ezx_pcap_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Daniel Ribeiro / Harald Welte");
MODULE_DESCRIPTION("Motorola PCAP2 ASIC Driver");
+MODULE_ALIAS("spi:ezx-pcap");
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index e424cf6d8e9..a1c47ee95c0 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -480,7 +480,6 @@ static int
add_children(struct twl4030_platform_data *pdata, unsigned long features)
{
struct device *child;
- struct device *usb_transceiver = NULL;
if (twl_has_bci() && pdata->bci && !(features & TPS_SUBSET)) {
child = add_child(3, "twl4030_bci",
@@ -532,16 +531,61 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
}
if (twl_has_usb() && pdata->usb) {
+
+ static struct regulator_consumer_supply usb1v5 = {
+ .supply = "usb1v5",
+ };
+ static struct regulator_consumer_supply usb1v8 = {
+ .supply = "usb1v8",
+ };
+ static struct regulator_consumer_supply usb3v1 = {
+ .supply = "usb3v1",
+ };
+
+ /* First add the regulators so that they can be used by transceiver */
+ if (twl_has_regulator()) {
+ /* this is a template that gets copied */
+ struct regulator_init_data usb_fixed = {
+ .constraints.valid_modes_mask =
+ REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .constraints.valid_ops_mask =
+ REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ };
+
+ child = add_regulator_linked(TWL4030_REG_VUSB1V5,
+ &usb_fixed, &usb1v5, 1);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+
+ child = add_regulator_linked(TWL4030_REG_VUSB1V8,
+ &usb_fixed, &usb1v8, 1);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+
+ child = add_regulator_linked(TWL4030_REG_VUSB3V1,
+ &usb_fixed, &usb3v1, 1);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+
+ }
+
child = add_child(0, "twl4030_usb",
pdata->usb, sizeof(*pdata->usb),
true,
/* irq0 = USB_PRES, irq1 = USB */
pdata->irq_base + 8 + 2, pdata->irq_base + 4);
+
if (IS_ERR(child))
return PTR_ERR(child);
/* we need to connect regulators to this transceiver */
- usb_transceiver = child;
+ if (twl_has_regulator() && child) {
+ usb1v5.dev = child;
+ usb1v8.dev = child;
+ usb3v1.dev = child;
+ }
}
if (twl_has_watchdog()) {
@@ -580,47 +624,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
return PTR_ERR(child);
}
- if (twl_has_regulator() && usb_transceiver) {
- static struct regulator_consumer_supply usb1v5 = {
- .supply = "usb1v5",
- };
- static struct regulator_consumer_supply usb1v8 = {
- .supply = "usb1v8",
- };
- static struct regulator_consumer_supply usb3v1 = {
- .supply = "usb3v1",
- };
-
- /* this is a template that gets copied */
- struct regulator_init_data usb_fixed = {
- .constraints.valid_modes_mask =
- REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .constraints.valid_ops_mask =
- REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- };
-
- usb1v5.dev = usb_transceiver;
- usb1v8.dev = usb_transceiver;
- usb3v1.dev = usb_transceiver;
-
- child = add_regulator_linked(TWL4030_REG_VUSB1V5, &usb_fixed,
- &usb1v5, 1);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator_linked(TWL4030_REG_VUSB1V8, &usb_fixed,
- &usb1v8, 1);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator_linked(TWL4030_REG_VUSB3V1, &usb_fixed,
- &usb3v1, 1);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
/* maybe add LDOs that are omitted on cost-reduced parts */
if (twl_has_regulator() && !(features & TPS_SUBSET)) {
child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
@@ -792,7 +795,7 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
twl->client = i2c_new_dummy(client->adapter,
twl->address);
if (!twl->client) {
- dev_err(&twl->client->dev,
+ dev_err(&client->dev,
"can't attach client %d\n", i);
status = -ENOMEM;
goto fail;
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c
index 78c2135c5de..fa294b6d600 100644
--- a/drivers/mfd/ucb1400_core.c
+++ b/drivers/mfd/ucb1400_core.c
@@ -21,6 +21,7 @@
*/
#include <linux/module.h>
+#include <linux/sched.h>
#include <linux/ucb1400.h>
unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
@@ -48,9 +49,11 @@ static int ucb1400_core_probe(struct device *dev)
int err;
struct ucb1400 *ucb;
struct ucb1400_ts ucb_ts;
+ struct ucb1400_gpio ucb_gpio;
struct snd_ac97 *ac97;
memset(&ucb_ts, 0, sizeof(ucb_ts));
+ memset(&ucb_gpio, 0, sizeof(ucb_gpio));
ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL);
if (!ucb) {
@@ -68,25 +71,44 @@ static int ucb1400_core_probe(struct device *dev)
goto err0;
}
+ /* GPIO */
+ ucb_gpio.ac97 = ac97;
+ ucb->ucb1400_gpio = platform_device_alloc("ucb1400_gpio", -1);
+ if (!ucb->ucb1400_gpio) {
+ err = -ENOMEM;
+ goto err0;
+ }
+ err = platform_device_add_data(ucb->ucb1400_gpio, &ucb_gpio,
+ sizeof(ucb_gpio));
+ if (err)
+ goto err1;
+ err = platform_device_add(ucb->ucb1400_gpio);
+ if (err)
+ goto err1;
+
/* TOUCHSCREEN */
ucb_ts.ac97 = ac97;
ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1);
if (!ucb->ucb1400_ts) {
err = -ENOMEM;
- goto err0;
+ goto err2;
}
err = platform_device_add_data(ucb->ucb1400_ts, &ucb_ts,
sizeof(ucb_ts));
if (err)
- goto err1;
+ goto err3;
err = platform_device_add(ucb->ucb1400_ts);
if (err)
- goto err1;
+ goto err3;
return 0;
-err1:
+err3:
platform_device_put(ucb->ucb1400_ts);
+err2:
+ platform_device_unregister(ucb->ucb1400_gpio);
+err1:
+ platform_device_put(ucb->ucb1400_gpio);
err0:
kfree(ucb);
err:
@@ -98,6 +120,8 @@ static int ucb1400_core_remove(struct device *dev)
struct ucb1400 *ucb = dev_get_drvdata(dev);
platform_device_unregister(ucb->ucb1400_ts);
+ platform_device_unregister(ucb->ucb1400_gpio);
+
kfree(ucb);
return 0;
}
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index fea9085fe52..60c3988f3cf 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -18,6 +18,7 @@
*/
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/errno.h>
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index d3015dfb913..ac056ea6b66 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -507,6 +507,8 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
{
int i, ret;
+ mutex_init(&wm831x->irq_lock);
+
if (!irq) {
dev_warn(wm831x->dev,
"No interrupt specified - functionality limited\n");
@@ -521,7 +523,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
}
wm831x->irq = irq;
- mutex_init(&wm831x->irq_lock);
INIT_WORK(&wm831x->irq_work, wm831x_irq_worker);
/* Mask the individual interrupt sources */