From 0dcc9a9d83dde6e34429b1914c9ac10aa447c7cb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Feb 2012 11:05:37 +0000 Subject: mfd: twl-core: Don't specify regulator consumers by struct device This has been deprecated for considerable time now and support has been removed from the regulator API. dev_name should be used instead. Reported-by: Stephen Rothwell Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mfd/twl-core.c') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 8ce3959c6919..c1e4f1a277e9 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -753,9 +753,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 +801,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, -- cgit v1.2.3 From 9e1786202704f199941f7c2f5c9fe12879de7917 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 22 Feb 2012 14:32:16 +0200 Subject: mfd: Make twl-core not depend on pdata->irq_base/end With sparse IRQs the driver shouldn't depend at all on any IRQ values coming from board-file. Remove every occurences of pdata->irq_base/end. Signed-off-by: Felipe Balbi Signed-off-by: Benoit Cousson Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 61 ++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'drivers/mfd/twl-core.c') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index c1e4f1a277e9..a0297f7ac496 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -652,7 +652,8 @@ add_regulator(int num, struct regulator_init_data *pdata, */ static int -add_children(struct twl4030_platform_data *pdata, unsigned long features) +add_children(struct twl4030_platform_data *pdata, unsigned irq_base, + unsigned long features) { struct device *child; unsigned sub_chip_id; @@ -660,7 +661,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) if (twl_has_gpio() && pdata->gpio) { child = add_child(SUB_CHIP_ID1, "twl4030_gpio", pdata->gpio, sizeof(*pdata->gpio), - false, pdata->irq_base + GPIO_INTR_OFFSET, 0); + false, irq_base + GPIO_INTR_OFFSET, 0); if (IS_ERR(child)) return PTR_ERR(child); } @@ -668,7 +669,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) if (twl_has_keypad() && pdata->keypad) { child = add_child(SUB_CHIP_ID2, "twl4030_keypad", pdata->keypad, sizeof(*pdata->keypad), - true, pdata->irq_base + KEYPAD_INTR_OFFSET, 0); + true, irq_base + KEYPAD_INTR_OFFSET, 0); if (IS_ERR(child)) return PTR_ERR(child); } @@ -676,7 +677,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) if (twl_has_madc() && pdata->madc) { child = add_child(2, "twl4030_madc", pdata->madc, sizeof(*pdata->madc), - true, pdata->irq_base + MADC_INTR_OFFSET, 0); + true, irq_base + MADC_INTR_OFFSET, 0); if (IS_ERR(child)) return PTR_ERR(child); } @@ -692,7 +693,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) sub_chip_id = twl_map[TWL_MODULE_RTC].sid; child = add_child(sub_chip_id, "twl_rtc", NULL, 0, - true, pdata->irq_base + RTC_INTR_OFFSET, 0); + true, irq_base + RTC_INTR_OFFSET, 0); if (IS_ERR(child)) return PTR_ERR(child); } @@ -745,8 +746,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) pdata->usb, sizeof(*pdata->usb), true, /* irq0 = USB_PRES, irq1 = USB */ - pdata->irq_base + USB_PRES_INTR_OFFSET, - pdata->irq_base + USB_INTR_OFFSET); + irq_base + USB_PRES_INTR_OFFSET, + irq_base + USB_INTR_OFFSET); if (IS_ERR(child)) return PTR_ERR(child); @@ -794,8 +795,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) pdata->usb, sizeof(*pdata->usb), true, /* irq1 = VBUS_PRES, irq0 = USB ID */ - pdata->irq_base + USBOTG_INTR_OFFSET, - pdata->irq_base + USB_PRES_INTR_OFFSET); + irq_base + USBOTG_INTR_OFFSET, + irq_base + USB_PRES_INTR_OFFSET); if (IS_ERR(child)) return PTR_ERR(child); @@ -822,7 +823,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) if (twl_has_pwrbutton() && twl_class_is_4030()) { child = add_child(1, "twl4030_pwrbutton", - NULL, 0, true, pdata->irq_base + 8 + 0, 0); + NULL, 0, true, irq_base + 8 + 0, 0); if (IS_ERR(child)) return PTR_ERR(child); } @@ -1056,8 +1057,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) child = add_child(3, "twl4030_bci", pdata->bci, sizeof(*pdata->bci), false, /* irq0 = CHG_PRES, irq1 = BCI */ - pdata->irq_base + BCI_PRES_INTR_OFFSET, - pdata->irq_base + BCI_INTR_OFFSET); + irq_base + BCI_PRES_INTR_OFFSET, + irq_base + BCI_INTR_OFFSET); if (IS_ERR(child)) return PTR_ERR(child); } @@ -1191,6 +1192,8 @@ static int twl_remove(struct i2c_client *client) static int __devinit twl_probe(struct i2c_client *client, const struct i2c_device_id *id) { + int irq_base; + int irq_end; int status; unsigned i; struct twl4030_platform_data *pdata = client->dev.platform_data; @@ -1219,22 +1222,16 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) return -EINVAL; } - status = irq_alloc_descs(-1, pdata->irq_base, nr_irqs, 0); + status = irq_alloc_descs(-1, 0, nr_irqs, 0); if (IS_ERR_VALUE(status)) { dev_err(&client->dev, "Fail to allocate IRQ descs\n"); return status; } - 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_base = status; + irq_end = irq_base + nr_irqs; + irq_domain_add_legacy(node, nr_irqs, 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"); @@ -1287,16 +1284,14 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) twl4030_power_init(pdata->power); /* Maybe init the T2 Interrupt subsystem */ - if (client->irq - && pdata->irq_base - && pdata->irq_end > pdata->irq_base) { + if (client->irq) { if (twl_class_is_4030()) { twl4030_init_chip_irq(id->name); - status = twl4030_init_irq(client->irq, pdata->irq_base, - pdata->irq_end); + status = twl4030_init_irq(client->irq, irq_base, + irq_end); } else { - status = twl6030_init_irq(client->irq, pdata->irq_base, - pdata->irq_end); + status = twl6030_init_irq(client->irq, irq_base, + irq_end); } if (status < 0) @@ -1315,12 +1310,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 if (node) status = of_platform_populate(node, NULL, NULL, &client->dev); - else -#endif - status = add_children(pdata, id->driver_data); + if (status) + status = add_children(pdata, irq_base, id->driver_data); fail: if (status < 0) -- cgit v1.2.3 From 5fd32d6a3a0812ef730b7b83031fc00fa4c4075f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 22 Feb 2012 14:39:09 +0200 Subject: mfd: Remove unneeded header from twl-core This driver doesn't really need , so remove it. Signed-off-by: Felipe Balbi Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/mfd/twl-core.c') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index a0297f7ac496..140340f9559b 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -45,10 +45,6 @@ #include #include -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) -#include -#endif - /* * The TWL4030 "Triton 2" is one of a family of a multi-function "Power * Management and System Companion Device" chips originally designed for -- cgit v1.2.3 From 1b8f333ff49f778a1215f65754c31c02408d1d08 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Wed, 29 Feb 2012 19:28:14 +0100 Subject: mfd: Remove references already defineid in header file from twl-core The twl-core exported functions are already declared in twl-core.h Include the header file instead or re-declaring the functions. Signed-off-by: Benoit Cousson Acked-by: Felipe Balbi Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/mfd/twl-core.c') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 140340f9559b..712e262ba99c 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -45,6 +45,8 @@ #include #include +#include "twl-core.h" + /* * The TWL4030 "Triton 2" is one of a family of a multi-function "Power * Management and System Companion Device" chips originally designed for @@ -1154,11 +1156,6 @@ static void clocks_init(struct device *dev, /*----------------------------------------------------------------------*/ -int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end); -int twl4030_exit_irq(void); -int twl4030_init_chip_irq(const char *chip); -int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end); -int twl6030_exit_irq(void); static int twl_remove(struct i2c_client *client) { -- cgit v1.2.3 From 78518ffa08fceee42d61359303c58bdd0a82033f Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Wed, 29 Feb 2012 19:40:31 +0100 Subject: mfd: Move twl-core IRQ allocation into twl[4030|6030]-irq files During DT adaptation, the irq_alloc_desc was added into twl-core, but due to the rather different and weird IRQ management required by the twl4030, it is much better to have a different approach for it. The issue is that twl4030 uses a two level IRQ mechanism but handles all the PWR interrupts as part of the twl-core interrupt range. It ends up with a range of 16 interrupts total for CORE and PWR. The other twl4030 functionalities already have a dedicated driver and thus their IRQs and irqdomain can and should be defined localy. twl6030 is using a single level IRQ controller and thus does not require any trick. Move the irq_alloc_desc and irq_domain_add_legacy in twl4030-irq and twl6030-irq. Allocate together CORE and PWR IRQs for twl4030-irq. Conflicts: drivers/mfd/twl-core.c Signed-off-by: Benoit Cousson Acked-by: Felipe Balbi Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 29 +++++------------------------ drivers/mfd/twl-core.h | 4 ++-- drivers/mfd/twl4030-irq.c | 29 +++++++++++++++++++++++++++-- drivers/mfd/twl6030-irq.c | 31 ++++++++++++++++++++++--------- 4 files changed, 56 insertions(+), 37 deletions(-) (limited to 'drivers/mfd/twl-core.c') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 712e262ba99c..764c5b5d914e 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -147,9 +147,6 @@ #define TWL_MODULE_LAST TWL4030_MODULE_LAST -#define TWL4030_NR_IRQS 8 -#define TWL6030_NR_IRQS 20 - /* Base Address defns for twl4030_map[] */ /* subchip/slave 0 - USB ID */ @@ -1186,17 +1183,12 @@ static int __devinit twl_probe(struct i2c_client *client, const struct i2c_device_id *id) { int irq_base; - int irq_end; int status; unsigned i; struct twl4030_platform_data *pdata = client->dev.platform_data; struct device_node *node = client->dev.of_node; u8 temp; int ret = 0; - int nr_irqs = TWL4030_NR_IRQS; - - if ((id->driver_data) & TWL6030_CLASS) - nr_irqs = TWL6030_NR_IRQS; if (node && !pdata) { /* @@ -1215,17 +1207,6 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) return -EINVAL; } - status = irq_alloc_descs(-1, 0, nr_irqs, 0); - if (IS_ERR_VALUE(status)) { - dev_err(&client->dev, "Fail to allocate IRQ descs\n"); - return status; - } - - irq_base = status; - irq_end = irq_base + nr_irqs; - irq_domain_add_legacy(node, nr_irqs, 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"); return -EIO; @@ -1280,15 +1261,15 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) if (client->irq) { if (twl_class_is_4030()) { twl4030_init_chip_irq(id->name); - status = twl4030_init_irq(client->irq, irq_base, - irq_end); + irq_base = twl4030_init_irq(&client->dev, client->irq); } else { - status = twl6030_init_irq(client->irq, irq_base, - irq_end); + irq_base = twl6030_init_irq(&client->dev, client->irq); } - if (status < 0) + if (irq_base < 0) { + status = irq_base; goto fail; + } } /* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. diff --git a/drivers/mfd/twl-core.h b/drivers/mfd/twl-core.h index 8c50a556e986..6ff99dce714f 100644 --- a/drivers/mfd/twl-core.h +++ b/drivers/mfd/twl-core.h @@ -1,9 +1,9 @@ #ifndef __TWL_CORE_H__ #define __TWL_CORE_H__ -extern int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end); +extern int twl6030_init_irq(struct device *dev, int irq_num); extern int twl6030_exit_irq(void); -extern int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end); +extern int twl4030_init_irq(struct device *dev, int irq_num); extern int twl4030_exit_irq(void); extern int twl4030_init_chip_irq(const char *chip); diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index b31f920feb51..a3dc1d929070 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -28,10 +28,13 @@ */ #include +#include #include #include #include +#include +#include #include #include "twl-core.h" @@ -53,6 +56,8 @@ * base + 8 .. base + 15 SIH for PWR_INT * base + 16 .. base + 33 SIH for GPIO */ +#define TWL4030_CORE_NR_IRQS 8 +#define TWL4030_PWR_NR_IRQS 8 /* PIH register offsets */ #define REG_PIH_ISR_P1 0x01 @@ -695,13 +700,33 @@ int twl4030_sih_setup(int module) /* FIXME pass in which interrupt line we'll use ... */ #define twl_irq_line 0 -int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) +int twl4030_init_irq(struct device *dev, int irq_num) { static struct irq_chip twl4030_irq_chip; + int irq_base, irq_end, nr_irqs; + struct device_node *node = dev->of_node; int status; int i; + /* + * TWL core and pwr interrupts must be contiguous because + * the hwirqs numbers are defined contiguously from 1 to 15. + * Create only one domain for both. + */ + nr_irqs = TWL4030_PWR_NR_IRQS + TWL4030_CORE_NR_IRQS; + + irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); + if (IS_ERR_VALUE(irq_base)) { + dev_err(dev, "Fail to allocate IRQ descs\n"); + return irq_base; + } + + irq_domain_add_legacy(node, nr_irqs, irq_base, 0, + &irq_domain_simple_ops, NULL); + + irq_end = irq_base + TWL4030_CORE_NR_IRQS; + /* * Mask and clear all TWL4030 interrupts since initially we do * not have any TWL4030 module interrupt handlers present @@ -747,7 +772,7 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) goto fail_rqirq; } - return status; + return irq_base; fail_rqirq: /* clean up twl4030_sih_setup */ fail: diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index bb3d762280f9..86c4082fa411 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include "twl-core.h" @@ -53,6 +55,7 @@ * specifies mapping between interrupt number and the associated module. * */ +#define TWL6030_NR_IRQS 20 static int twl6030_interrupt_mapping[24] = { PWR_INTR_OFFSET, /* Bit 0 PWRON */ @@ -246,11 +249,6 @@ static int twl6030_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } -/*----------------------------------------------------------------------*/ - -static unsigned twl6030_irq_next; - -/*----------------------------------------------------------------------*/ int twl6030_interrupt_unmask(u8 bit_mask, u8 offset) { int ret; @@ -350,8 +348,10 @@ int twl6030_mmc_card_detect(struct device *dev, int slot) } EXPORT_SYMBOL(twl6030_mmc_card_detect); -int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) +int twl6030_init_irq(struct device *dev, int irq_num) { + struct device_node *node = dev->of_node; + int nr_irqs, irq_base, irq_end; int status = 0; int i; @@ -360,6 +360,20 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) u8 mask[4]; static struct irq_chip twl6030_irq_chip; + + nr_irqs = TWL6030_NR_IRQS; + + irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); + if (IS_ERR_VALUE(irq_base)) { + dev_err(dev, "Fail to allocate IRQ descs\n"); + return irq_base; + } + + irq_domain_add_legacy(node, nr_irqs, irq_base, 0, + &irq_domain_simple_ops, NULL); + + irq_end = irq_base + nr_irqs; + mask[1] = 0xFF; mask[2] = 0xFF; mask[3] = 0xFF; @@ -387,9 +401,8 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) activate_irq(i); } - twl6030_irq_next = i; pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH", - irq_num, irq_base, twl6030_irq_next - 1); + irq_num, irq_base, irq_end); /* install an irq handler to demultiplex the TWL6030 interrupt */ init_completion(&irq_event); @@ -410,7 +423,7 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) twl_irq = irq_num; register_pm_notifier(&twl6030_irq_pm_notifier_block); - return status; + return irq_base; fail_kthread: free_irq(irq_num, &irq_event); -- cgit v1.2.3 From ec1a07b3440cc28946a77a974c21570bbef6ffa1 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Fri, 2 Mar 2012 11:11:26 +0100 Subject: mfd: Replace twl-* pr_ macros by the dev_ equivalent and do various cleanups Since a structure device is available now, use the dev_ macros instead of the pr_ ones. Clean some badly formatted comments. Remove some unused variables. Move some variable to the place they belong. Clean some badly wrapped lines. Align variable definition Add missing braces in if-then-else block. Add blank line for better readability. Move stuff here and there... Conflicts: drivers/mfd/twl-core.c Signed-off-by: Benoit Cousson Cc: Felipe Balbi Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 33 +++++++++++++++++++-------------- drivers/mfd/twl4030-irq.c | 19 ++++++++----------- drivers/mfd/twl6030-irq.c | 39 +++++++++++++++++++-------------------- 3 files changed, 46 insertions(+), 45 deletions(-) (limited to 'drivers/mfd/twl-core.c') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 764c5b5d914e..eb9bd203e497 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -1178,17 +1178,15 @@ static int twl_remove(struct i2c_client *client) return 0; } -/* NOTE: this driver only handles a single twl4030/tps659x0 chip */ +/* NOTE: This driver only handles a single twl4030/tps659x0 chip */ static int __devinit twl_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int irq_base; - int status; - unsigned i; struct twl4030_platform_data *pdata = client->dev.platform_data; struct device_node *node = client->dev.of_node; - u8 temp; - int ret = 0; + int irq_base = 0; + int status; + unsigned i; if (node && !pdata) { /* @@ -1218,12 +1216,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) } for (i = 0; i < TWL_NUM_SLAVES; i++) { - struct twl_client *twl = &twl_modules[i]; + struct twl_client *twl = &twl_modules[i]; twl->address = client->addr + i; - if (i == 0) + if (i == 0) { twl->client = client; - else { + } else { twl->client = i2c_new_dummy(client->adapter, twl->address); if (!twl->client) { @@ -1235,7 +1233,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) } mutex_init(&twl->xfer_lock); } + inuse = true; + if ((id->driver_data) & TWL6030_CLASS) { twl_id = TWL6030_CLASS_ID; twl_map = &twl6030_map[0]; @@ -1249,8 +1249,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) /* read TWL IDCODE Register */ if (twl_id == TWL4030_CLASS_ID) { - ret = twl_read_idcode_register(); - WARN(ret < 0, "Error: reading twl_idcode register value\n"); + status = twl_read_idcode_register(); + WARN(status < 0, "Error: reading twl_idcode register value\n"); } /* load power event scripts */ @@ -1272,18 +1272,22 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) } } - /* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. + /* + * Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0, * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0. */ - if (twl_class_is_4030()) { + u8 temp; + twl_i2c_read_u8(TWL4030_MODULE_INTBR, &temp, REG_GPPUPDCTR1); temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \ - I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU); + I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU); twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); } + status = -ENODEV; + if (node) status = of_platform_populate(node, NULL, NULL, &client->dev); if (status) @@ -1292,6 +1296,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) fail: if (status < 0) twl_remove(client); + return status; } diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 3b748b71c0f3..5d656e814358 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -32,7 +32,6 @@ #include #include #include - #include #include #include @@ -639,14 +638,14 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) int status = -EINVAL; /* only support modules with standard clear-on-read for now */ - for (sih_mod = 0, sih = sih_modules; - sih_mod < nr_sih_modules; + for (sih_mod = 0, sih = sih_modules; sih_mod < nr_sih_modules; sih_mod++, sih++) { if (sih->module == module && sih->set_cor) { status = 0; break; } } + if (status < 0) return status; @@ -676,7 +675,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) 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, + dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, irq, irq_base, irq_base + i - 1); return status < 0 ? status : irq_base; @@ -692,12 +691,10 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) int twl4030_init_irq(struct device *dev, int irq_num) { static struct irq_chip twl4030_irq_chip; + int status, i; int irq_base, irq_end, nr_irqs; struct device_node *node = dev->of_node; - int status; - int i; - /* * TWL core and pwr interrupts must be contiguous because * the hwirqs numbers are defined contiguously from 1 to 15. @@ -727,7 +724,7 @@ int twl4030_init_irq(struct device *dev, int irq_num) twl4030_irq_base = irq_base; /* - * install an irq handler for each of the SIH modules; + * Install an irq handler for each of the SIH modules; * clone dummy irq_chip since PIH can't *do* anything */ twl4030_irq_chip = dummy_irq_chip; @@ -742,13 +739,13 @@ int twl4030_init_irq(struct device *dev, int irq_num) activate_irq(i); } - pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", "PIH", + dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", "PIH", irq_num, irq_base, irq_end); /* ... and the PWR_INT module ... */ status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end); if (status < 0) { - pr_err("twl4030: sih_setup PWR INT --> %d\n", status); + dev_err(dev, "sih_setup PWR INT --> %d\n", status); goto fail; } @@ -757,7 +754,7 @@ int twl4030_init_irq(struct device *dev, int irq_num) IRQF_ONESHOT, "TWL4030-PIH", NULL); if (status < 0) { - pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status); + dev_err(dev, "could not claim irq%d: %d\n", irq_num, status); goto fail_rqirq; } diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index 86c4082fa411..b76902f1e44a 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c @@ -53,7 +53,6 @@ * * We set up IRQs starting at a platform-specified base. An interrupt map table, * specifies mapping between interrupt number and the associated module. - * */ #define TWL6030_NR_IRQS 20 @@ -352,14 +351,11 @@ int twl6030_init_irq(struct device *dev, int irq_num) { struct device_node *node = dev->of_node; int nr_irqs, irq_base, irq_end; - - int status = 0; - int i; struct task_struct *task; - int ret; - u8 mask[4]; - - static struct irq_chip twl6030_irq_chip; + static struct irq_chip twl6030_irq_chip; + int status = 0; + int i; + u8 mask[4]; nr_irqs = TWL6030_NR_IRQS; @@ -377,16 +373,18 @@ int twl6030_init_irq(struct device *dev, int irq_num) mask[1] = 0xFF; mask[2] = 0xFF; mask[3] = 0xFF; - ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0], - REG_INT_MSK_LINE_A, 3); /* MASK ALL INT LINES */ - ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0], - REG_INT_MSK_STS_A, 3); /* MASK ALL INT STS */ - ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0], - REG_INT_STS_A, 3); /* clear INT_STS_A,B,C */ + + /* mask all int lines */ + twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3); + /* mask all int sts */ + twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3); + /* clear INT_STS_A,B,C */ + twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3); twl6030_irq_base = irq_base; - /* install an irq handler for each of the modules; + /* + * install an irq handler for each of the modules; * clone dummy irq_chip since PIH can't *do* anything */ twl6030_irq_chip = dummy_irq_chip; @@ -401,22 +399,22 @@ int twl6030_init_irq(struct device *dev, int irq_num) activate_irq(i); } - pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH", + dev_info(dev, "PIH (irq %d) chaining IRQs %d..%d\n", irq_num, irq_base, irq_end); /* install an irq handler to demultiplex the TWL6030 interrupt */ init_completion(&irq_event); - status = request_irq(irq_num, handle_twl6030_pih, 0, - "TWL6030-PIH", &irq_event); + status = request_irq(irq_num, handle_twl6030_pih, 0, "TWL6030-PIH", + &irq_event); if (status < 0) { - pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status); + dev_err(dev, "could not claim irq %d: %d\n", irq_num, status); goto fail_irq; } task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq"); if (IS_ERR(task)) { - pr_err("twl6030: could not create irq %d thread!\n", irq_num); + dev_err(dev, "could not create irq %d thread!\n", irq_num); status = PTR_ERR(task); goto fail_kthread; } @@ -431,6 +429,7 @@ fail_kthread: fail_irq: for (i = irq_base; i < irq_end; i++) irq_set_chip_and_handler(i, NULL, NULL); + return status; } -- cgit v1.2.3 From 364cedb2f97063d649b2950c099883b89b60c000 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 4 Jan 2012 14:58:33 +0200 Subject: mfd: Detach twl6040 from the pmic mfd driver On OMAP4 platform audio has separate IC, it is no longer part of the pmic chip. Prevent twl-core to claim the 0x4b address, which belongs to the twl6040 audio IC. Signed-off-by: Peter Ujfalusi Acked-by: Samuel Ortiz Signed-off-by: Benoit Cousson Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 59 ++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 26 deletions(-) (limited to 'drivers/mfd/twl-core.c') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index eb9bd203e497..8bff96848102 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -113,8 +113,8 @@ #define twl_has_watchdog() false #endif -#if defined(CONFIG_MFD_TWL4030_AUDIO) || defined(CONFIG_MFD_TWL4030_AUDIO_MODULE) ||\ - defined(CONFIG_TWL6040_CORE) || defined(CONFIG_TWL6040_CORE_MODULE) +#if defined(CONFIG_MFD_TWL4030_AUDIO) || \ + defined(CONFIG_MFD_TWL4030_AUDIO_MODULE) #define twl_has_codec() true #else #define twl_has_codec() false @@ -144,6 +144,7 @@ #define SUB_CHIP_ID1 1 #define SUB_CHIP_ID2 2 #define SUB_CHIP_ID3 3 +#define SUB_CHIP_ID_INVAL 0xff #define TWL_MODULE_LAST TWL4030_MODULE_LAST @@ -312,7 +313,7 @@ static struct twl_mapping twl6030_map[] = { * so they continue to match the order in this table. */ { SUB_CHIP_ID1, TWL6030_BASEADD_USB }, - { SUB_CHIP_ID3, TWL6030_BASEADD_AUDIO }, + { SUB_CHIP_ID_INVAL, TWL6030_BASEADD_AUDIO }, { SUB_CHIP_ID2, TWL6030_BASEADD_DIEID }, { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, { SUB_CHIP_ID1, TWL6030_BASEADD_PIH }, @@ -374,6 +375,11 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) return -EPERM; } sid = twl_map[mod_no].sid; + if (unlikely(sid == SUB_CHIP_ID_INVAL)) { + pr_err("%s: module %d is not part of the pmic\n", + DRIVER_NAME, mod_no); + return -EINVAL; + } twl = &twl_modules[sid]; mutex_lock(&twl->xfer_lock); @@ -431,6 +437,11 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) return -EPERM; } sid = twl_map[mod_no].sid; + if (unlikely(sid == SUB_CHIP_ID_INVAL)) { + pr_err("%s: module %d is not part of the pmic\n", + DRIVER_NAME, mod_no); + return -EINVAL; + } twl = &twl_modules[sid]; mutex_lock(&twl->xfer_lock); @@ -832,15 +843,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, return PTR_ERR(child); } - if (twl_has_codec() && pdata->audio && twl_class_is_6030()) { - sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; - child = add_child(sub_chip_id, "twl6040", - pdata->audio, sizeof(*pdata->audio), - false, 0, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - /* twl4030 regulators */ if (twl_has_regulator() && twl_class_is_4030()) { child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1, @@ -1156,18 +1158,21 @@ static void clocks_init(struct device *dev, static int twl_remove(struct i2c_client *client) { - unsigned i; + unsigned i, num_slaves; int status; - if (twl_class_is_4030()) + if (twl_class_is_4030()) { status = twl4030_exit_irq(); - else + num_slaves = TWL_NUM_SLAVES; + } else { status = twl6030_exit_irq(); + num_slaves = TWL_NUM_SLAVES - 1; + } if (status < 0) return status; - for (i = 0; i < TWL_NUM_SLAVES; i++) { + for (i = 0; i < num_slaves; i++) { struct twl_client *twl = &twl_modules[i]; if (twl->client && twl->client != client) @@ -1186,7 +1191,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) struct device_node *node = client->dev.of_node; int irq_base = 0; int status; - unsigned i; + unsigned i, num_slaves; if (node && !pdata) { /* @@ -1215,7 +1220,17 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) return -EBUSY; } - for (i = 0; i < TWL_NUM_SLAVES; i++) { + if ((id->driver_data) & TWL6030_CLASS) { + twl_id = TWL6030_CLASS_ID; + twl_map = &twl6030_map[0]; + num_slaves = TWL_NUM_SLAVES - 1; + } else { + twl_id = TWL4030_CLASS_ID; + twl_map = &twl4030_map[0]; + num_slaves = TWL_NUM_SLAVES; + } + + for (i = 0; i < num_slaves; i++) { struct twl_client *twl = &twl_modules[i]; twl->address = client->addr + i; @@ -1236,14 +1251,6 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) inuse = true; - if ((id->driver_data) & TWL6030_CLASS) { - twl_id = TWL6030_CLASS_ID; - twl_map = &twl6030_map[0]; - } else { - twl_id = TWL4030_CLASS_ID; - twl_map = &twl4030_map[0]; - } - /* setup clock framework */ clocks_init(&client->dev, pdata->clock); -- cgit v1.2.3