Merge tag 'boards-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[pandora-kernel.git] / drivers / gpio / gpio-pxa.c
index 2d3af98..d7a5c9d 100644 (file)
@@ -85,20 +85,61 @@ struct pxa_gpio_chip {
 #endif
 };
 
-enum {
+enum pxa_gpio_type {
        PXA25X_GPIO = 0,
        PXA26X_GPIO,
        PXA27X_GPIO,
        PXA3XX_GPIO,
        PXA93X_GPIO,
        MMP_GPIO = 0x10,
+       MMP2_GPIO,
+};
+
+struct pxa_gpio_id {
+       enum pxa_gpio_type      type;
+       int                     gpio_nums;
 };
 
 static DEFINE_SPINLOCK(gpio_lock);
 static struct pxa_gpio_chip *pxa_gpio_chips;
-static int gpio_type;
+static enum pxa_gpio_type gpio_type;
 static void __iomem *gpio_reg_base;
 
+static struct pxa_gpio_id pxa25x_id = {
+       .type           = PXA25X_GPIO,
+       .gpio_nums      = 85,
+};
+
+static struct pxa_gpio_id pxa26x_id = {
+       .type           = PXA26X_GPIO,
+       .gpio_nums      = 90,
+};
+
+static struct pxa_gpio_id pxa27x_id = {
+       .type           = PXA27X_GPIO,
+       .gpio_nums      = 121,
+};
+
+static struct pxa_gpio_id pxa3xx_id = {
+       .type           = PXA3XX_GPIO,
+       .gpio_nums      = 128,
+};
+
+static struct pxa_gpio_id pxa93x_id = {
+       .type           = PXA93X_GPIO,
+       .gpio_nums      = 192,
+};
+
+static struct pxa_gpio_id mmp_id = {
+       .type           = MMP_GPIO,
+       .gpio_nums      = 128,
+};
+
+static struct pxa_gpio_id mmp2_id = {
+       .type           = MMP2_GPIO,
+       .gpio_nums      = 192,
+};
+
 #define for_each_gpio_chip(i, c)                       \
        for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
 
@@ -431,47 +472,39 @@ static struct irq_chip pxa_muxed_gpio_chip = {
        .irq_set_wake   = pxa_gpio_set_wake,
 };
 
-static int pxa_gpio_nums(void)
+static int pxa_gpio_nums(struct platform_device *pdev)
 {
+       const struct platform_device_id *id = platform_get_device_id(pdev);
+       struct pxa_gpio_id *pxa_id = (struct pxa_gpio_id *)id->driver_data;
        int count = 0;
 
-#ifdef CONFIG_ARCH_PXA
-       if (cpu_is_pxa25x()) {
-#ifdef CONFIG_CPU_PXA26x
-               count = 89;
-               gpio_type = PXA26X_GPIO;
-#elif defined(CONFIG_PXA25x)
-               count = 84;
-               gpio_type = PXA26X_GPIO;
-#endif /* CONFIG_CPU_PXA26x */
-       } else if (cpu_is_pxa27x()) {
-               count = 120;
-               gpio_type = PXA27X_GPIO;
-       } else if (cpu_is_pxa93x()) {
-               count = 191;
-               gpio_type = PXA93X_GPIO;
-       } else if (cpu_is_pxa3xx()) {
-               count = 127;
-               gpio_type = PXA3XX_GPIO;
-       }
-#endif /* CONFIG_ARCH_PXA */
-
-#ifdef CONFIG_ARCH_MMP
-       if (cpu_is_pxa168() || cpu_is_pxa910()) {
-               count = 127;
-               gpio_type = MMP_GPIO;
-       } else if (cpu_is_mmp2()) {
-               count = 191;
-               gpio_type = MMP_GPIO;
+       switch (pxa_id->type) {
+       case PXA25X_GPIO:
+       case PXA26X_GPIO:
+       case PXA27X_GPIO:
+       case PXA3XX_GPIO:
+       case PXA93X_GPIO:
+       case MMP_GPIO:
+       case MMP2_GPIO:
+               gpio_type = pxa_id->type;
+               count = pxa_id->gpio_nums - 1;
+               break;
+       default:
+               count = -EINVAL;
+               break;
        }
-#endif /* CONFIG_ARCH_MMP */
        return count;
 }
 
 #ifdef CONFIG_OF
 static struct of_device_id pxa_gpio_dt_ids[] = {
-       { .compatible = "mrvl,pxa-gpio" },
-       { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
+       { .compatible = "intel,pxa25x-gpio",    .data = &pxa25x_id, },
+       { .compatible = "intel,pxa26x-gpio",    .data = &pxa26x_id, },
+       { .compatible = "intel,pxa27x-gpio",    .data = &pxa27x_id, },
+       { .compatible = "intel,pxa3xx-gpio",    .data = &pxa3xx_id, },
+       { .compatible = "marvell,pxa93x-gpio",  .data = &pxa93x_id, },
+       { .compatible = "marvell,mmp-gpio",     .data = &mmp_id, },
+       { .compatible = "marvell,mmp2-gpio",    .data = &mmp2_id, },
        {}
 };
 
@@ -491,16 +524,18 @@ const struct irq_domain_ops pxa_irq_domain_ops = {
 
 static int pxa_gpio_probe_dt(struct platform_device *pdev)
 {
-       int ret, nr_banks, nr_gpios;
+       int ret, nr_gpios;
        struct device_node *prev, *next, *np = pdev->dev.of_node;
        const struct of_device_id *of_id =
                                of_match_device(pxa_gpio_dt_ids, &pdev->dev);
+       const struct pxa_gpio_id *gpio_id;
 
-       if (!of_id) {
+       if (!of_id || !of_id->data) {
                dev_err(&pdev->dev, "Failed to find gpio controller\n");
                return -EFAULT;
        }
-       gpio_type = (int)of_id->data;
+       gpio_id = of_id->data;
+       gpio_type = gpio_id->type;
 
        next = of_get_next_child(np, NULL);
        prev = next;
@@ -509,14 +544,8 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
                ret = -EINVAL;
                goto err;
        }
-       for (nr_banks = 1; ; nr_banks++) {
-               next = of_get_next_child(np, prev);
-               if (!next)
-                       break;
-               prev = next;
-       }
        of_node_put(prev);
-       nr_gpios = nr_banks << 5;
+       nr_gpios = gpio_id->gpio_nums;
        pxa_last_gpio = nr_gpios - 1;
 
        irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
@@ -545,19 +574,18 @@ static int pxa_gpio_probe(struct platform_device *pdev)
        int gpio, irq, ret, use_of = 0;
        int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
 
-       ret = pxa_gpio_probe_dt(pdev);
-       if (ret < 0) {
-               pxa_last_gpio = pxa_gpio_nums();
-#ifdef CONFIG_ARCH_PXA
-               if (gpio_is_pxa_type(gpio_type))
-                       irq_base = PXA_GPIO_TO_IRQ(0);
-#endif
-#ifdef CONFIG_ARCH_MMP
-               if (gpio_is_mmp_type(gpio_type))
-                       irq_base = MMP_GPIO_TO_IRQ(0);
-#endif
+       info = dev_get_platdata(&pdev->dev);
+       if (info) {
+               irq_base = info->irq_base;
+               if (irq_base <= 0)
+                       return -EINVAL;
+               pxa_last_gpio = pxa_gpio_nums(pdev);
        } else {
+               irq_base = 0;
                use_of = 1;
+               ret = pxa_gpio_probe_dt(pdev);
+               if (ret < 0)
+                       return -EINVAL;
        }
 
        if (!pxa_last_gpio)
@@ -594,7 +622,6 @@ static int pxa_gpio_probe(struct platform_device *pdev)
        }
 
        /* Initialize GPIO chips */
-       info = dev_get_platdata(&pdev->dev);
        pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);
 
        /* clear all GPIO edge detects */
@@ -634,12 +661,24 @@ static int pxa_gpio_probe(struct platform_device *pdev)
        return 0;
 }
 
+static const struct platform_device_id gpio_id_table[] = {
+       { "pxa25x-gpio",        (unsigned long)&pxa25x_id },
+       { "pxa26x-gpio",        (unsigned long)&pxa26x_id },
+       { "pxa27x-gpio",        (unsigned long)&pxa27x_id },
+       { "pxa3xx-gpio",        (unsigned long)&pxa3xx_id },
+       { "pxa93x-gpio",        (unsigned long)&pxa93x_id },
+       { "mmp-gpio",           (unsigned long)&mmp_id },
+       { "mmp2-gpio",          (unsigned long)&mmp2_id },
+       { },
+};
+
 static struct platform_driver pxa_gpio_driver = {
        .probe          = pxa_gpio_probe,
        .driver         = {
                .name   = "pxa-gpio",
                .of_match_table = of_match_ptr(pxa_gpio_dt_ids),
        },
+       .id_table       = gpio_id_table,
 };
 
 static int __init pxa_gpio_init(void)