diff options
-rw-r--r-- | drivers/mfd/twl-core.c | 61 |
1 files changed, 27 insertions, 34 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index c1e4f1a277e..a0297f7ac49 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, | |||
652 | */ | 652 | */ |
653 | 653 | ||
654 | static int | 654 | static int |
655 | add_children(struct twl4030_platform_data *pdata, unsigned long features) | 655 | add_children(struct twl4030_platform_data *pdata, unsigned irq_base, |
656 | unsigned long features) | ||
656 | { | 657 | { |
657 | struct device *child; | 658 | struct device *child; |
658 | unsigned sub_chip_id; | 659 | unsigned sub_chip_id; |
@@ -660,7 +661,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
660 | if (twl_has_gpio() && pdata->gpio) { | 661 | if (twl_has_gpio() && pdata->gpio) { |
661 | child = add_child(SUB_CHIP_ID1, "twl4030_gpio", | 662 | child = add_child(SUB_CHIP_ID1, "twl4030_gpio", |
662 | pdata->gpio, sizeof(*pdata->gpio), | 663 | pdata->gpio, sizeof(*pdata->gpio), |
663 | false, pdata->irq_base + GPIO_INTR_OFFSET, 0); | 664 | false, irq_base + GPIO_INTR_OFFSET, 0); |
664 | if (IS_ERR(child)) | 665 | if (IS_ERR(child)) |
665 | return PTR_ERR(child); | 666 | return PTR_ERR(child); |
666 | } | 667 | } |
@@ -668,7 +669,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
668 | if (twl_has_keypad() && pdata->keypad) { | 669 | if (twl_has_keypad() && pdata->keypad) { |
669 | child = add_child(SUB_CHIP_ID2, "twl4030_keypad", | 670 | child = add_child(SUB_CHIP_ID2, "twl4030_keypad", |
670 | pdata->keypad, sizeof(*pdata->keypad), | 671 | pdata->keypad, sizeof(*pdata->keypad), |
671 | true, pdata->irq_base + KEYPAD_INTR_OFFSET, 0); | 672 | true, irq_base + KEYPAD_INTR_OFFSET, 0); |
672 | if (IS_ERR(child)) | 673 | if (IS_ERR(child)) |
673 | return PTR_ERR(child); | 674 | return PTR_ERR(child); |
674 | } | 675 | } |
@@ -676,7 +677,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
676 | if (twl_has_madc() && pdata->madc) { | 677 | if (twl_has_madc() && pdata->madc) { |
677 | child = add_child(2, "twl4030_madc", | 678 | child = add_child(2, "twl4030_madc", |
678 | pdata->madc, sizeof(*pdata->madc), | 679 | pdata->madc, sizeof(*pdata->madc), |
679 | true, pdata->irq_base + MADC_INTR_OFFSET, 0); | 680 | true, irq_base + MADC_INTR_OFFSET, 0); |
680 | if (IS_ERR(child)) | 681 | if (IS_ERR(child)) |
681 | return PTR_ERR(child); | 682 | return PTR_ERR(child); |
682 | } | 683 | } |
@@ -692,7 +693,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
692 | sub_chip_id = twl_map[TWL_MODULE_RTC].sid; | 693 | sub_chip_id = twl_map[TWL_MODULE_RTC].sid; |
693 | child = add_child(sub_chip_id, "twl_rtc", | 694 | child = add_child(sub_chip_id, "twl_rtc", |
694 | NULL, 0, | 695 | NULL, 0, |
695 | true, pdata->irq_base + RTC_INTR_OFFSET, 0); | 696 | true, irq_base + RTC_INTR_OFFSET, 0); |
696 | if (IS_ERR(child)) | 697 | if (IS_ERR(child)) |
697 | return PTR_ERR(child); | 698 | return PTR_ERR(child); |
698 | } | 699 | } |
@@ -745,8 +746,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
745 | pdata->usb, sizeof(*pdata->usb), | 746 | pdata->usb, sizeof(*pdata->usb), |
746 | true, | 747 | true, |
747 | /* irq0 = USB_PRES, irq1 = USB */ | 748 | /* irq0 = USB_PRES, irq1 = USB */ |
748 | pdata->irq_base + USB_PRES_INTR_OFFSET, | 749 | irq_base + USB_PRES_INTR_OFFSET, |
749 | pdata->irq_base + USB_INTR_OFFSET); | 750 | irq_base + USB_INTR_OFFSET); |
750 | 751 | ||
751 | if (IS_ERR(child)) | 752 | if (IS_ERR(child)) |
752 | return PTR_ERR(child); | 753 | return PTR_ERR(child); |
@@ -794,8 +795,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
794 | pdata->usb, sizeof(*pdata->usb), | 795 | pdata->usb, sizeof(*pdata->usb), |
795 | true, | 796 | true, |
796 | /* irq1 = VBUS_PRES, irq0 = USB ID */ | 797 | /* irq1 = VBUS_PRES, irq0 = USB ID */ |
797 | pdata->irq_base + USBOTG_INTR_OFFSET, | 798 | irq_base + USBOTG_INTR_OFFSET, |
798 | pdata->irq_base + USB_PRES_INTR_OFFSET); | 799 | irq_base + USB_PRES_INTR_OFFSET); |
799 | 800 | ||
800 | if (IS_ERR(child)) | 801 | if (IS_ERR(child)) |
801 | return PTR_ERR(child); | 802 | return PTR_ERR(child); |
@@ -822,7 +823,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
822 | 823 | ||
823 | if (twl_has_pwrbutton() && twl_class_is_4030()) { | 824 | if (twl_has_pwrbutton() && twl_class_is_4030()) { |
824 | child = add_child(1, "twl4030_pwrbutton", | 825 | child = add_child(1, "twl4030_pwrbutton", |
825 | NULL, 0, true, pdata->irq_base + 8 + 0, 0); | 826 | NULL, 0, true, irq_base + 8 + 0, 0); |
826 | if (IS_ERR(child)) | 827 | if (IS_ERR(child)) |
827 | return PTR_ERR(child); | 828 | return PTR_ERR(child); |
828 | } | 829 | } |
@@ -1056,8 +1057,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
1056 | child = add_child(3, "twl4030_bci", | 1057 | child = add_child(3, "twl4030_bci", |
1057 | pdata->bci, sizeof(*pdata->bci), false, | 1058 | pdata->bci, sizeof(*pdata->bci), false, |
1058 | /* irq0 = CHG_PRES, irq1 = BCI */ | 1059 | /* irq0 = CHG_PRES, irq1 = BCI */ |
1059 | pdata->irq_base + BCI_PRES_INTR_OFFSET, | 1060 | irq_base + BCI_PRES_INTR_OFFSET, |
1060 | pdata->irq_base + BCI_INTR_OFFSET); | 1061 | irq_base + BCI_INTR_OFFSET); |
1061 | if (IS_ERR(child)) | 1062 | if (IS_ERR(child)) |
1062 | return PTR_ERR(child); | 1063 | return PTR_ERR(child); |
1063 | } | 1064 | } |
@@ -1191,6 +1192,8 @@ static int twl_remove(struct i2c_client *client) | |||
1191 | static int __devinit | 1192 | static int __devinit |
1192 | twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | 1193 | twl_probe(struct i2c_client *client, const struct i2c_device_id *id) |
1193 | { | 1194 | { |
1195 | int irq_base; | ||
1196 | int irq_end; | ||
1194 | int status; | 1197 | int status; |
1195 | unsigned i; | 1198 | unsigned i; |
1196 | struct twl4030_platform_data *pdata = client->dev.platform_data; | 1199 | 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) | |||
1219 | return -EINVAL; | 1222 | return -EINVAL; |
1220 | } | 1223 | } |
1221 | 1224 | ||
1222 | status = irq_alloc_descs(-1, pdata->irq_base, nr_irqs, 0); | 1225 | status = irq_alloc_descs(-1, 0, nr_irqs, 0); |
1223 | if (IS_ERR_VALUE(status)) { | 1226 | if (IS_ERR_VALUE(status)) { |
1224 | dev_err(&client->dev, "Fail to allocate IRQ descs\n"); | 1227 | dev_err(&client->dev, "Fail to allocate IRQ descs\n"); |
1225 | return status; | 1228 | return status; |
1226 | } | 1229 | } |
1227 | 1230 | ||
1228 | pdata->irq_base = status; | 1231 | irq_base = status; |
1229 | pdata->irq_end = pdata->irq_base + nr_irqs; | 1232 | irq_end = irq_base + nr_irqs; |
1230 | 1233 | irq_domain_add_legacy(node, nr_irqs, irq_base, 0, | |
1231 | #ifdef CONFIG_IRQ_DOMAIN | 1234 | &irq_domain_simple_ops, NULL); |
1232 | domain.irq_base = pdata->irq_base; | ||
1233 | domain.nr_irq = nr_irqs; | ||
1234 | domain.of_node = of_node_get(node); | ||
1235 | domain.ops = &irq_domain_simple_ops; | ||
1236 | irq_domain_add(&domain); | ||
1237 | #endif | ||
1238 | 1235 | ||
1239 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { | 1236 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { |
1240 | dev_dbg(&client->dev, "can't talk I2C?\n"); | 1237 | 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) | |||
1287 | twl4030_power_init(pdata->power); | 1284 | twl4030_power_init(pdata->power); |
1288 | 1285 | ||
1289 | /* Maybe init the T2 Interrupt subsystem */ | 1286 | /* Maybe init the T2 Interrupt subsystem */ |
1290 | if (client->irq | 1287 | if (client->irq) { |
1291 | && pdata->irq_base | ||
1292 | && pdata->irq_end > pdata->irq_base) { | ||
1293 | if (twl_class_is_4030()) { | 1288 | if (twl_class_is_4030()) { |
1294 | twl4030_init_chip_irq(id->name); | 1289 | twl4030_init_chip_irq(id->name); |
1295 | status = twl4030_init_irq(client->irq, pdata->irq_base, | 1290 | status = twl4030_init_irq(client->irq, irq_base, |
1296 | pdata->irq_end); | 1291 | irq_end); |
1297 | } else { | 1292 | } else { |
1298 | status = twl6030_init_irq(client->irq, pdata->irq_base, | 1293 | status = twl6030_init_irq(client->irq, irq_base, |
1299 | pdata->irq_end); | 1294 | irq_end); |
1300 | } | 1295 | } |
1301 | 1296 | ||
1302 | if (status < 0) | 1297 | if (status < 0) |
@@ -1315,12 +1310,10 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1315 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); | 1310 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); |
1316 | } | 1311 | } |
1317 | 1312 | ||
1318 | #ifdef CONFIG_OF_DEVICE | ||
1319 | if (node) | 1313 | if (node) |
1320 | status = of_platform_populate(node, NULL, NULL, &client->dev); | 1314 | status = of_platform_populate(node, NULL, NULL, &client->dev); |
1321 | else | 1315 | if (status) |
1322 | #endif | 1316 | status = add_children(pdata, irq_base, id->driver_data); |
1323 | status = add_children(pdata, id->driver_data); | ||
1324 | 1317 | ||
1325 | fail: | 1318 | fail: |
1326 | if (status < 0) | 1319 | if (status < 0) |