]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
twl4030: simplified child creation code
authorDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 12 Nov 2008 01:57:10 +0000 (17:57 -0800)
committerTony Lindgren <tony@atomide.com>
Fri, 14 Nov 2008 00:42:55 +0000 (16:42 -0800)
Minor cleanup to twl4030-core: define a helper function to populate
a single child node, and use it to replace six inconsistent versions
of the same logic.  Both object and source code shrink.

As part of this, some devices now have more IRQ resources:  battery
charger, keypad, ADC, and USB transceiver.  That will help to remove
some irq #defines that prevent this code from compiling on non-OMAP
platforms.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Tony Lindgren <tony@atomide.com>
drivers/mfd/twl4030-core.c

index cf687fb9648f96e30cfc35aad9fd9b9fa5df7620..61cdd75ede345e4a7d990223bbc9b7dc16fd6b69 100644 (file)
@@ -360,261 +360,129 @@ EXPORT_SYMBOL(twl4030_i2c_read_u8);
 
 /*----------------------------------------------------------------------*/
 
-/*
- * 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)
+static struct device *add_child(unsigned chip, const char *name,
+               void *pdata, unsigned pdata_len,
+               bool can_wakeup, int irq0, int irq1)
 {
-       struct platform_device  *pdev = NULL;
-       struct twl4030_client   *twl = NULL;
-       int                     status = 0;
+       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;
+       }
 
-       if (twl_has_bci() && pdata->bci) {
-               twl = &twl4030_modules[3];
+       device_init_wakeup(&pdev->dev, can_wakeup);
+       pdev->dev.parent = &twl->client->dev;
 
-               pdev = platform_device_alloc("twl4030_bci", -1);
-               if (!pdev) {
-                       pr_debug("%s: can't alloc bci dev\n", DRIVER_NAME);
-                       status = -ENOMEM;
+       if (pdata) {
+               status = platform_device_add_data(pdev, pdata, pdata_len);
+               if (status < 0) {
+                       dev_dbg(&pdev->dev, "can't add platform_data\n");
                        goto err;
                }
+       }
 
-               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);
+       if (irq0) {
+               struct resource r[2] = {
+                       { .start = irq0, .flags = IORESOURCE_IRQ, },
+                       { .start = irq1, .flags = IORESOURCE_IRQ, },
+               };
 
+               status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1);
                if (status < 0) {
-                       platform_device_put(pdev);
-                       dev_dbg(&twl->client->dev,
-                                       "can't create bci dev, %d\n",
-                                       status);
+                       dev_dbg(&pdev->dev, "can't add irqs\n");
                        goto err;
                }
        }
 
-       if (twl_has_gpio() && pdata->gpio) {
-               twl = &twl4030_modules[1];
+       status = platform_device_add(pdev);
 
-               pdev = platform_device_alloc("twl4030_gpio", -1);
-               if (!pdev) {
-                       pr_debug("%s: can't alloc gpio dev\n", DRIVER_NAME);
-                       status = -ENOMEM;
-                       goto err;
-               }
-
-               /* 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;
-                       }
-               }
+err:
+       if (status < 0) {
+               platform_device_put(pdev);
+               dev_err(&twl->client->dev, "can't add %s dev\n", name);
+               return ERR_PTR(status);
+       }
+       return &pdev->dev;
+}
 
-               /* GPIO module IRQ */
-               if (status == 0) {
-                       struct resource r = {
-                               .start = pdata->irq_base + 0,
-                               .flags = IORESOURCE_IRQ,
-                       };
+/*
+ * 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.
+ */
 
-                       status = platform_device_add_resources(pdev, &r, 1);
-               }
+static int add_children(struct twl4030_platform_data *pdata)
+{
+       struct device   *child;
 
-               if (status == 0)
-                       status = platform_device_add(pdev);
+       if (twl_has_bci() && pdata->bci) {
+               child = 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 (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
 
-               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_gpio() && pdata->gpio) {
+               child = add_child(1, "twl4030_gpio",
+                               pdata->gpio, sizeof(*pdata->gpio),
+                               false, pdata->irq_base + 0, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
        }
 
        if (twl_has_keypad() && pdata->keypad) {
-               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;
-               }
+               child = add_child(2, "twl4030_keypad",
+                               pdata->keypad, sizeof(*pdata->keypad),
+                               true, pdata->irq_base + 1, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
        }
 
        if (twl_has_madc() && pdata->madc) {
-               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;
-               }
+               child = add_child(2, "twl4030_madc",
+                               pdata->madc, sizeof(*pdata->madc),
+                               true, pdata->irq_base + 3, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
        }
 
        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 use of
+                * REVISIT platform_data here currently might expose the
                 * "msecure" line ... but for now we just expect board
-                * setup to tell the chip "we are secure" at all times.
+                * setup to tell the chip "it's always ok to SET_TIME".
                 * Eventually, Linux might become more aware of such
                 * HW security concerns, and "least privilege".
                 */
-
-               /* 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;
-               }
+               child = add_child(3, "twl4030_rtc",
+                               NULL, 0,
+                               true, pdata->irq_base + 8 + 3, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
        }
 
        if (twl_has_usb() && pdata->usb) {
-               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);
-               }
+               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);
        }
 
-err:
-       if (status)
-               pr_err("failed to add twl4030's children (status %d)\n", status);
-       return status;
+       return 0;
 }
 
 /*----------------------------------------------------------------------*/