From 7c946b7a905921590630e3a7710ca5d16ea765ef Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 13 Nov 2008 16:41:07 -0800 Subject: [PATCH] Revert "twl4030-core simplification" This reverts commit 041d1e14acc3dbee1755667ab12cca41ed584d13. Use the updated version instead as pointed out by Dave. Signed-off-by: Tony Lindgren --- drivers/mfd/twl4030-core.c | 299 +++++++++++++++++++++++++++---------- 1 file changed, 216 insertions(+), 83 deletions(-) diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c index 18028706476..cf687fb9648 100644 --- a/drivers/mfd/twl4030-core.c +++ b/drivers/mfd/twl4030-core.c @@ -360,128 +360,261 @@ EXPORT_SYMBOL(twl4030_i2c_read_u8); /*----------------------------------------------------------------------*/ -static int add_child(unsigned chip, const char *name, - void *pdata, unsigned pdata_len, - bool can_wakeup, int irq0, int irq1) +/* + * NOTE: We know the first 8 IRQs after pdata->base_irq are + * for the PIH, and the next are for the PWR_INT SIH, since + * that's how twl_init_irq() sets things up. + */ + +static int add_children(struct twl4030_platform_data *pdata) { - struct platform_device *pdev; - struct twl4030_client *twl = &twl4030_modules[chip]; - int status; - - pdev = platform_device_alloc(name, -1); - if (!pdev) { - dev_dbg(&twl->client->dev, "can't alloc dev\n"); - status = -ENOMEM; - goto err; - } + struct platform_device *pdev = NULL; + struct twl4030_client *twl = NULL; + int status = 0; - device_init_wakeup(&pdev->dev, can_wakeup); - pdev->dev.parent = &twl->client->dev; + if (twl_has_bci() && pdata->bci) { + twl = &twl4030_modules[3]; - if (pdata) { - status = platform_device_add_data(pdev, pdata, pdata_len); - if (status < 0) { - dev_dbg(&pdev->dev, "can't add platform_data\n"); + pdev = platform_device_alloc("twl4030_bci", -1); + if (!pdev) { + pr_debug("%s: can't alloc bci dev\n", DRIVER_NAME); + status = -ENOMEM; goto err; } - } - if (irq0) { - struct resource r[2] = { - { .start = irq0, .flags = IORESOURCE_IRQ, }, - { .start = irq1, .flags = IORESOURCE_IRQ, }, - }; + if (status == 0) { + pdev->dev.parent = &twl->client->dev; + status = platform_device_add_data(pdev, pdata->bci, + sizeof(*pdata->bci)); + if (status < 0) { + dev_dbg(&twl->client->dev, + "can't add bci data, %d\n", + status); + goto err; + } + } + + if (status == 0) { + struct resource r = { + .start = pdata->irq_base + 8 + 1, + .flags = IORESOURCE_IRQ, + }; + + status = platform_device_add_resources(pdev, &r, 1); + } + + if (status == 0) + status = platform_device_add(pdev); - status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1); if (status < 0) { - dev_dbg(&pdev->dev, "can't add irqs\n"); + platform_device_put(pdev); + dev_dbg(&twl->client->dev, + "can't create bci dev, %d\n", + status); goto err; } } - status = platform_device_add(pdev); + if (twl_has_gpio() && pdata->gpio) { + twl = &twl4030_modules[1]; -err: - if (status < 0) { - platform_device_put(pdev); - dev_err(&twl->client->dev, "can't add %s dev\n", name); - } - return status; -} + pdev = platform_device_alloc("twl4030_gpio", -1); + if (!pdev) { + pr_debug("%s: can't alloc gpio dev\n", DRIVER_NAME); + status = -ENOMEM; + goto err; + } -/* - * NOTE: We know the first 8 IRQs after pdata->base_irq are - * for the PIH, and the next are for the PWR_INT SIH, since - * that's how twl_init_irq() sets things up. - */ + /* more driver model init */ + if (status == 0) { + pdev->dev.parent = &twl->client->dev; + /* device_init_wakeup(&pdev->dev, 1); */ + + status = platform_device_add_data(pdev, pdata->gpio, + sizeof(*pdata->gpio)); + if (status < 0) { + dev_dbg(&twl->client->dev, + "can't add gpio data, %d\n", + status); + goto err; + } + } -static int add_children(struct twl4030_platform_data *pdata) -{ - int status; + /* GPIO module IRQ */ + if (status == 0) { + struct resource r = { + .start = pdata->irq_base + 0, + .flags = IORESOURCE_IRQ, + }; - if (twl_has_bci() && pdata->bci) { - status = add_child(3, "twl4030_bci", - pdata->bci, sizeof(*pdata->bci), - false, - /* irq0 = CHG_PRES, irq1 = BCI */ - pdata->irq_base + 8 + 1, pdata->irq_base + 2); - if (status < 0) - return status; - } + status = platform_device_add_resources(pdev, &r, 1); + } - if (twl_has_gpio() && pdata->gpio) { - status = add_child(1, "twl4030_gpio", - pdata->gpio, sizeof(*pdata->gpio), - false, pdata->irq_base + 0, 0); - if (status < 0) - return status; + if (status == 0) + status = platform_device_add(pdev); + + if (status < 0) { + platform_device_put(pdev); + dev_dbg(&twl->client->dev, + "can't create gpio dev, %d\n", + status); + goto err; + } } if (twl_has_keypad() && pdata->keypad) { - status = add_child(2, "twl4030_keypad", - pdata->keypad, sizeof(*pdata->keypad), - true, pdata->irq_base + 1, 0); - if (status < 0) - return status; + pdev = platform_device_alloc("twl4030_keypad", -1); + if (pdev) { + twl = &twl4030_modules[2]; + pdev->dev.parent = &twl->client->dev; + device_init_wakeup(&pdev->dev, 1); + status = platform_device_add_data(pdev, pdata->keypad, + sizeof(*pdata->keypad)); + if (status < 0) { + dev_dbg(&twl->client->dev, + "can't add keypad data, %d\n", + status); + platform_device_put(pdev); + goto err; + } + status = platform_device_add(pdev); + if (status < 0) { + platform_device_put(pdev); + dev_dbg(&twl->client->dev, + "can't create keypad dev, %d\n", + status); + goto err; + } + } else { + pr_debug("%s: can't alloc keypad dev\n", DRIVER_NAME); + status = -ENOMEM; + goto err; + } } if (twl_has_madc() && pdata->madc) { - status = add_child(2, "twl4030_madc", - pdata->madc, sizeof(*pdata->madc), - true, pdata->irq_base + 3, 0); - if (status < 0) - return status; + pdev = platform_device_alloc("twl4030_madc", -1); + if (pdev) { + twl = &twl4030_modules[2]; + pdev->dev.parent = &twl->client->dev; + device_init_wakeup(&pdev->dev, 1); + status = platform_device_add_data(pdev, pdata->madc, + sizeof(*pdata->madc)); + if (status < 0) { + platform_device_put(pdev); + dev_dbg(&twl->client->dev, + "can't add madc data, %d\n", + status); + goto err; + } + status = platform_device_add(pdev); + if (status < 0) { + platform_device_put(pdev); + dev_dbg(&twl->client->dev, + "can't create madc dev, %d\n", + status); + goto err; + } + } else { + pr_debug("%s: can't alloc madc dev\n", DRIVER_NAME); + status = -ENOMEM; + goto err; + } } if (twl_has_power() && pdata->power) twl4030_power_init(pdata->power); if (twl_has_rtc()) { + twl = &twl4030_modules[3]; + + pdev = platform_device_alloc("twl4030_rtc", -1); + if (!pdev) { + pr_debug("%s: can't alloc rtc dev\n", DRIVER_NAME); + status = -ENOMEM; + } else { + pdev->dev.parent = &twl->client->dev; + device_init_wakeup(&pdev->dev, 1); + } + /* - * REVISIT platform_data here currently might expose the + * REVISIT platform_data here currently might use of * "msecure" line ... but for now we just expect board - * setup to tell the chip "it's always ok to SET_TIME". + * setup to tell the chip "we are secure" at all times. * Eventually, Linux might become more aware of such * HW security concerns, and "least privilege". */ - status = add_child(3, "twl4030_rtc", - NULL, 0, - true, pdata->irq_base + 8 + 3, 0); - if (status < 0) - return status; + + /* RTC module IRQ */ + if (status == 0) { + struct resource r = { + .start = pdata->irq_base + 8 + 3, + .flags = IORESOURCE_IRQ, + }; + + status = platform_device_add_resources(pdev, &r, 1); + } + + if (status == 0) + status = platform_device_add(pdev); + + if (status < 0) { + platform_device_put(pdev); + dev_dbg(&twl->client->dev, + "can't create rtc dev, %d\n", + status); + goto err; + } } if (twl_has_usb() && pdata->usb) { - status = 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 (status < 0) - return status; + twl = &twl4030_modules[0]; + + pdev = platform_device_alloc("twl4030_usb", -1); + if (!pdev) { + pr_debug("%s: can't alloc usb dev\n", DRIVER_NAME); + status = -ENOMEM; + goto err; + } + + if (status == 0) { + pdev->dev.parent = &twl->client->dev; + device_init_wakeup(&pdev->dev, 1); + status = platform_device_add_data(pdev, pdata->usb, + sizeof(*pdata->usb)); + if (status < 0) { + platform_device_put(pdev); + dev_dbg(&twl->client->dev, + "can't add usb data, %d\n", + status); + goto err; + } + } + + if (status == 0) { + struct resource r = { + .start = pdata->irq_base + 8 + 2, + .flags = IORESOURCE_IRQ, + }; + + status = platform_device_add_resources(pdev, &r, 1); + } + + if (status == 0) + status = platform_device_add(pdev); + + if (status < 0) { + platform_device_put(pdev); + dev_dbg(&twl->client->dev, + "can't create usb dev, %d\n", + status); + } } - return 0; +err: + if (status) + pr_err("failed to add twl4030's children (status %d)\n", status); + return status; } /*----------------------------------------------------------------------*/ -- 2.41.0