mfd: provide and use setup hook for tc6393xb
Dmitry Baryshkov [Wed, 24 Sep 2008 21:36:23 +0000 (23:36 +0200)]
Instead of using bitfields for initial gpio setup,
provide generic setup/teardown hooks that can be used
to set the gpio states, register child devices, etc.

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@openedhand.com>

arch/arm/mach-pxa/include/mach/tosa.h
arch/arm/mach-pxa/tosa.c
drivers/mfd/tc6393xb.c
include/linux/mfd/tc6393xb.h

index a72803f..8bce6d8 100644 (file)
@@ -59,8 +59,6 @@
  * TC6393XB GPIOs
  */
 #define TOSA_TC6393XB_GPIO_BASE                (NR_BUILTIN_GPIO + 2 * 12)
-#define TOSA_TC6393XB_GPIO(i)          (TOSA_TC6393XB_GPIO_BASE + (i))
-#define TOSA_TC6393XB_GPIO_BIT(gpio)   (1 << (gpio - TOSA_TC6393XB_GPIO_BASE))
 
 #define TOSA_GPIO_TG_ON                        (TOSA_TC6393XB_GPIO_BASE + 0)
 #define TOSA_GPIO_L_MUTE               (TOSA_TC6393XB_GPIO_BASE + 1)
index 130e37e..fac846b 100644 (file)
@@ -706,16 +706,39 @@ static struct tmio_nand_data tosa_tc6393xb_nand_config = {
        .badblock_pattern = &tosa_tc6393xb_nand_bbt,
 };
 
-static struct tc6393xb_platform_data tosa_tc6393xb_setup = {
+static int tosa_tc6393xb_setup(struct platform_device *dev)
+{
+       int rc;
+
+       rc = gpio_request(TOSA_GPIO_CARD_VCC_ON, "CARD_VCC_ON");
+       if (rc)
+               goto err_req;
+
+       rc = gpio_direction_output(TOSA_GPIO_CARD_VCC_ON, 1);
+       if (rc)
+               goto err_dir;
+
+       return rc;
+
+err_dir:
+       gpio_free(TOSA_GPIO_CARD_VCC_ON);
+err_req:
+       return rc;
+}
+
+static void tosa_tc6393xb_teardown(struct platform_device *dev)
+{
+       gpio_free(TOSA_GPIO_CARD_VCC_ON);
+}
+
+static struct tc6393xb_platform_data tosa_tc6393xb_data = {
        .scr_pll2cr     = 0x0cc1,
        .scr_gper       = 0x3300,
-       .scr_gpo_dsr    =
-               TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
-       .scr_gpo_doecr  =
-               TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
 
        .irq_base       = IRQ_BOARD_START,
        .gpio_base      = TOSA_TC6393XB_GPIO_BASE,
+       .setup          = tosa_tc6393xb_setup,
+       .teardown       = tosa_tc6393xb_teardown,
 
        .enable         = tosa_tc6393xb_enable,
        .disable        = tosa_tc6393xb_disable,
@@ -730,7 +753,7 @@ static struct platform_device tc6393xb_device = {
        .name   = "tc6393xb",
        .id     = -1,
        .dev    = {
-               .platform_data  = &tosa_tc6393xb_setup,
+               .platform_data  = &tosa_tc6393xb_data,
        },
        .num_resources  = ARRAY_SIZE(tc6393xb_resources),
        .resource       = tc6393xb_resources,
index e4c1c78..83dc703 100644 (file)
@@ -460,13 +460,6 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
 
        tc6393xb->suspend_state.fer = 0;
 
-       for (i = 0; i < 3; i++) {
-               tc6393xb->suspend_state.gpo_dsr[i] =
-                       (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff;
-               tc6393xb->suspend_state.gpo_doecr[i] =
-                       (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff;
-       }
-
        tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 |
                                        SCR_CCR_HCLK_48;
 
@@ -488,6 +481,12 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
 
        tc6393xb_attach_irq(dev);
 
+       if (tcpd->setup) {
+               ret = tcpd->setup(dev);
+               if (ret)
+                       goto err_setup;
+       }
+
        tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data;
        tc6393xb_cells[TC6393XB_CELL_NAND].platform_data =
                &tc6393xb_cells[TC6393XB_CELL_NAND];
@@ -506,6 +505,10 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
        if (!ret)
                return 0;
 
+       if (tcpd->teardown)
+               tcpd->teardown(dev);
+
+err_setup:
        tc6393xb_detach_irq(dev);
 
 err_gpio_add:
@@ -535,6 +538,10 @@ static int __devexit tc6393xb_remove(struct platform_device *dev)
        int ret;
 
        mfd_remove_devices(&dev->dev);
+
+       if (tcpd->teardown)
+               tcpd->teardown(dev);
+
        tc6393xb_detach_irq(dev);
 
        if (tc6393xb->gpio.base != -1) {
index fec7b3f..1fa8206 100644 (file)
@@ -21,8 +21,6 @@
 struct tc6393xb_platform_data {
        u16     scr_pll2cr;     /* PLL2 Control */
        u16     scr_gper;       /* GP Enable */
-       u32     scr_gpo_doecr;  /* GPO Data OE Control */
-       u32     scr_gpo_dsr;    /* GPO Data Set */
 
        int     (*enable)(struct platform_device *dev);
        int     (*disable)(struct platform_device *dev);
@@ -31,6 +29,8 @@ struct tc6393xb_platform_data {
 
        int     irq_base;       /* base for subdevice irqs */
        int     gpio_base;
+       int     (*setup)(struct platform_device *dev);
+       void    (*teardown)(struct platform_device *dev);
 
        struct tmio_nand_data   *nand_data;
 };