Merge branches 'regmap-core', 'regmap-mmio' and 'regmap-naming' into regmap-stride
[deliverable/linux.git] / drivers / gpio / gpio-omap.c
index f49bd6f47a504b0ec732173e202f6f3dca716afd..1adc2ec1e3835ae98e230b160b63264eb0afb3bc 100644 (file)
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/slab.h>
+#include <linux/device.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/irqdomain.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -50,10 +53,10 @@ struct gpio_regs {
 
 struct gpio_bank {
        struct list_head node;
-       unsigned long pbase;
        void __iomem *base;
        u16 irq;
-       u16 virtual_irq_start;
+       int irq_base;
+       struct irq_domain *domain;
        u32 suspend_wakeup;
        u32 saved_wakeup;
        u32 non_wakeup_gpios;
@@ -77,7 +80,6 @@ struct gpio_bank {
        int stride;
        u32 width;
        int context_loss_count;
-       u16 id;
        int power_mode;
        bool workaround_enabled;
 
@@ -91,6 +93,11 @@ struct gpio_bank {
 #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
 #define GPIO_MOD_CTRL_BIT      BIT(0)
 
+static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq)
+{
+       return gpio_irq - bank->irq_base + bank->chip.base;
+}
+
 static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 {
        void __iomem *reg = bank->base;
@@ -113,10 +120,13 @@ static void _set_gpio_dataout_reg(struct gpio_bank *bank, int gpio, int enable)
        void __iomem *reg = bank->base;
        u32 l = GPIO_BIT(bank, gpio);
 
-       if (enable)
+       if (enable) {
                reg += bank->regs->set_dataout;
-       else
+               bank->context.dataout |= l;
+       } else {
                reg += bank->regs->clr_dataout;
+               bank->context.dataout &= ~l;
+       }
 
        __raw_writel(l, reg);
 }
@@ -137,25 +147,25 @@ static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable)
        bank->context.dataout = l;
 }
 
-static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
+static int _get_gpio_datain(struct gpio_bank *bank, int offset)
 {
        void __iomem *reg = bank->base + bank->regs->datain;
 
-       return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
+       return (__raw_readl(reg) & (1 << offset)) != 0;
 }
 
-static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
+static int _get_gpio_dataout(struct gpio_bank *bank, int offset)
 {
        void __iomem *reg = bank->base + bank->regs->dataout;
 
-       return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
+       return (__raw_readl(reg) & (1 << offset)) != 0;
 }
 
 static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
 {
        int l = __raw_readl(base + reg);
 
-       if (set) 
+       if (set)
                l |= mask;
        else
                l &= ~mask;
@@ -238,7 +248,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 }
 
 static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
-                                               int trigger)
+                                               unsigned trigger)
 {
        void __iomem *base = bank->base;
        u32 gpio_bit = 1 << gpio;
@@ -320,7 +330,8 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) {}
 #endif
 
-static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
+static int _set_gpio_triggering(struct gpio_bank *bank, int gpio,
+                                                       unsigned trigger)
 {
        void __iomem *reg = bank->base;
        void __iomem *base = bank->base;
@@ -367,7 +378,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 
 static int gpio_irq_type(struct irq_data *d, unsigned type)
 {
-       struct gpio_bank *bank;
+       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
        unsigned gpio;
        int retval;
        unsigned long flags;
@@ -375,13 +386,11 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
        if (!cpu_class_is_omap2() && d->irq > IH_MPUIO_BASE)
                gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
        else
-               gpio = d->irq - IH_GPIO_BASE;
+               gpio = irq_to_gpio(bank, d->irq);
 
        if (type & ~IRQ_TYPE_SENSE_MASK)
                return -EINVAL;
 
-       bank = irq_data_get_irq_chip_data(d);
-
        if (!bank->regs->leveldetect0 &&
                (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
                return -EINVAL;
@@ -442,6 +451,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
        if (bank->regs->set_irqenable) {
                reg += bank->regs->set_irqenable;
                l = gpio_mask;
+               bank->context.irqenable1 |= gpio_mask;
        } else {
                reg += bank->regs->irqenable;
                l = __raw_readl(reg);
@@ -449,10 +459,10 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
                        l &= ~gpio_mask;
                else
                        l |= gpio_mask;
+               bank->context.irqenable1 = l;
        }
 
        __raw_writel(l, reg);
-       bank->context.irqenable1 = l;
 }
 
 static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
@@ -463,6 +473,7 @@ static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
        if (bank->regs->clr_irqenable) {
                reg += bank->regs->clr_irqenable;
                l = gpio_mask;
+               bank->context.irqenable1 &= ~gpio_mask;
        } else {
                reg += bank->regs->irqenable;
                l = __raw_readl(reg);
@@ -470,15 +481,18 @@ static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
                        l |= gpio_mask;
                else
                        l &= ~gpio_mask;
+               bank->context.irqenable1 = l;
        }
 
        __raw_writel(l, reg);
-       bank->context.irqenable1 = l;
 }
 
 static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
 {
-       _enable_gpio_irqbank(bank, GPIO_BIT(bank, gpio));
+       if (enable)
+               _enable_gpio_irqbank(bank, GPIO_BIT(bank, gpio));
+       else
+               _disable_gpio_irqbank(bank, GPIO_BIT(bank, gpio));
 }
 
 /*
@@ -495,7 +509,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
        unsigned long flags;
 
        if (bank->non_wakeup_gpios & gpio_bit) {
-               dev_err(bank->dev, 
+               dev_err(bank->dev,
                        "Unable to modify wakeup on non-wakeup GPIO%d\n", gpio);
                return -EINVAL;
        }
@@ -506,6 +520,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
        else
                bank->suspend_wakeup &= ~gpio_bit;
 
+       __raw_writel(bank->suspend_wakeup, bank->base + bank->regs->wkup_en);
        spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
@@ -522,14 +537,10 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio)
 /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
 static int gpio_wake_enable(struct irq_data *d, unsigned int enable)
 {
-       unsigned int gpio = d->irq - IH_GPIO_BASE;
-       struct gpio_bank *bank;
-       int retval;
-
-       bank = irq_data_get_irq_chip_data(d);
-       retval = _set_gpio_wakeup(bank, gpio, enable);
+       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irq_to_gpio(bank, d->irq);
 
-       return retval;
+       return _set_gpio_wakeup(bank, gpio, enable);
 }
 
 static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
@@ -671,13 +682,15 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                if (!isr)
                        break;
 
-               gpio_irq = bank->virtual_irq_start;
+               gpio_irq = bank->irq_base;
                for (; isr != 0; isr >>= 1, gpio_irq++) {
-                       gpio_index = GPIO_INDEX(bank, irq_to_gpio(gpio_irq));
+                       int gpio = irq_to_gpio(bank, gpio_irq);
 
                        if (!(isr & 1))
                                continue;
 
+                       gpio_index = GPIO_INDEX(bank, gpio);
+
                        /*
                         * Some chips can't respond to both rising and falling
                         * at the same time.  If this irq was requested with
@@ -703,8 +716,8 @@ exit:
 
 static void gpio_irq_shutdown(struct irq_data *d)
 {
-       unsigned int gpio = d->irq - IH_GPIO_BASE;
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irq_to_gpio(bank, d->irq);
        unsigned long flags;
 
        spin_lock_irqsave(&bank->lock, flags);
@@ -714,16 +727,16 @@ static void gpio_irq_shutdown(struct irq_data *d)
 
 static void gpio_ack_irq(struct irq_data *d)
 {
-       unsigned int gpio = d->irq - IH_GPIO_BASE;
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irq_to_gpio(bank, d->irq);
 
        _clear_gpio_irqstatus(bank, gpio);
 }
 
 static void gpio_mask_irq(struct irq_data *d)
 {
-       unsigned int gpio = d->irq - IH_GPIO_BASE;
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irq_to_gpio(bank, d->irq);
        unsigned long flags;
 
        spin_lock_irqsave(&bank->lock, flags);
@@ -734,8 +747,8 @@ static void gpio_mask_irq(struct irq_data *d)
 
 static void gpio_unmask_irq(struct irq_data *d)
 {
-       unsigned int gpio = d->irq - IH_GPIO_BASE;
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = irq_to_gpio(bank, d->irq);
        unsigned int irq_mask = GPIO_BIT(bank, gpio);
        u32 trigger = irqd_get_trigger_type(d);
        unsigned long flags;
@@ -852,19 +865,15 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
 static int gpio_get(struct gpio_chip *chip, unsigned offset)
 {
        struct gpio_bank *bank;
-       void __iomem *reg;
-       int gpio;
        u32 mask;
 
-       gpio = chip->base + offset;
        bank = container_of(chip, struct gpio_bank, chip);
-       reg = bank->base;
-       mask = GPIO_BIT(bank, gpio);
+       mask = (1 << offset);
 
        if (gpio_is_input(bank, mask))
-               return _get_gpio_datain(bank, gpio);
+               return _get_gpio_datain(bank, offset);
        else
-               return _get_gpio_dataout(bank, gpio);
+               return _get_gpio_dataout(bank, offset);
 }
 
 static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
@@ -917,7 +926,7 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
        struct gpio_bank *bank;
 
        bank = container_of(chip, struct gpio_bank, chip);
-       return bank->virtual_irq_start + offset;
+       return bank->irq_base + offset;
 }
 
 /*---------------------------------------------------------------------*/
@@ -970,7 +979,7 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
                _gpio_rmw(base, bank->regs->ctrl, 0, 1);
 }
 
-static __init void
+static __devinit void
 omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
                    unsigned int num)
 {
@@ -1030,8 +1039,7 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
 
        gpiochip_add(&bank->chip);
 
-       for (j = bank->virtual_irq_start;
-                    j < bank->virtual_irq_start + bank->width; j++) {
+       for (j = bank->irq_base; j < bank->irq_base + bank->width; j++) {
                irq_set_lockdep_class(j, &gpio_lock_class);
                irq_set_chip_data(j, bank);
                if (bank->is_mpuio) {
@@ -1046,39 +1054,38 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
        irq_set_handler_data(bank->irq, bank);
 }
 
+static const struct of_device_id omap_gpio_match[];
+
 static int __devinit omap_gpio_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->of_node;
+       const struct of_device_id *match;
        struct omap_gpio_platform_data *pdata;
        struct resource *res;
        struct gpio_bank *bank;
        int ret = 0;
 
-       if (!pdev->dev.platform_data) {
-               ret = -EINVAL;
-               goto err_exit;
-       }
+       match = of_match_device(of_match_ptr(omap_gpio_match), dev);
+
+       pdata = match ? match->data : dev->platform_data;
+       if (!pdata)
+               return -EINVAL;
 
-       bank = kzalloc(sizeof(struct gpio_bank), GFP_KERNEL);
+       bank = devm_kzalloc(&pdev->dev, sizeof(struct gpio_bank), GFP_KERNEL);
        if (!bank) {
-               dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
-               ret = -ENOMEM;
-               goto err_exit;
+               dev_err(dev, "Memory alloc failed\n");
+               return -ENOMEM;
        }
 
        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (unlikely(!res)) {
-               dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n",
-                               pdev->id);
-               ret = -ENODEV;
-               goto err_free;
+               dev_err(dev, "Invalid IRQ resource\n");
+               return -ENODEV;
        }
 
        bank->irq = res->start;
-       bank->id = pdev->id;
-
-       pdata = pdev->dev.platform_data;
-       bank->virtual_irq_start = pdata->virtual_irq_start;
-       bank->dev = &pdev->dev;
+       bank->dev = dev;
        bank->dbck_flag = pdata->dbck_flag;
        bank->stride = pdata->bank_stride;
        bank->width = pdata->bank_width;
@@ -1087,6 +1094,18 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
        bank->loses_context = pdata->loses_context;
        bank->get_context_loss_count = pdata->get_context_loss_count;
        bank->regs = pdata->regs;
+#ifdef CONFIG_OF_GPIO
+       bank->chip.of_node = of_node_get(node);
+#endif
+
+       bank->irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
+       if (bank->irq_base < 0) {
+               dev_err(dev, "Couldn't allocate IRQ numbers\n");
+               return -ENODEV;
+       }
+
+       bank->domain = irq_domain_add_legacy(node, bank->width, bank->irq_base,
+                                            0, &irq_domain_simple_ops, NULL);
 
        if (bank->regs->set_dataout && bank->regs->clr_dataout)
                bank->set_dataout = _set_gpio_dataout_reg;
@@ -1098,18 +1117,20 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
        /* Static mapping, never released */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (unlikely(!res)) {
-               dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n",
-                               pdev->id);
-               ret = -ENODEV;
-               goto err_free;
+               dev_err(dev, "Invalid mem resource\n");
+               return -ENODEV;
        }
 
-       bank->base = ioremap(res->start, resource_size(res));
+       if (!devm_request_mem_region(dev, res->start, resource_size(res),
+                                    pdev->name)) {
+               dev_err(dev, "Region already claimed\n");
+               return -EBUSY;
+       }
+
+       bank->base = devm_ioremap(dev, res->start, resource_size(res));
        if (!bank->base) {
-               dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n",
-                               pdev->id);
-               ret = -ENOMEM;
-               goto err_free;
+               dev_err(dev, "Could not ioremap\n");
+               return -ENOMEM;
        }
 
        platform_set_drvdata(pdev, bank);
@@ -1130,11 +1151,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
        list_add_tail(&bank->node, &omap_gpio_list);
 
        return ret;
-
-err_free:
-       kfree(bank);
-err_exit:
-       return ret;
 }
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
@@ -1196,8 +1212,30 @@ static int omap_gpio_runtime_suspend(struct device *dev)
        struct gpio_bank *bank = platform_get_drvdata(pdev);
        u32 l1 = 0, l2 = 0;
        unsigned long flags;
+       u32 wake_low, wake_hi;
 
        spin_lock_irqsave(&bank->lock, flags);
+
+       /*
+        * Only edges can generate a wakeup event to the PRCM.
+        *
+        * Therefore, ensure any wake-up capable GPIOs have
+        * edge-detection enabled before going idle to ensure a wakeup
+        * to the PRCM is generated on a GPIO transition. (c.f. 34xx
+        * NDA TRM 25.5.3.1)
+        *
+        * The normal values will be restored upon ->runtime_resume()
+        * by writing back the values saved in bank->context.
+        */
+       wake_low = bank->context.leveldetect0 & bank->context.wake_en;
+       if (wake_low)
+               __raw_writel(wake_low | bank->context.fallingdetect,
+                            bank->base + bank->regs->fallingdetect);
+       wake_hi = bank->context.leveldetect1 & bank->context.wake_en;
+       if (wake_hi)
+               __raw_writel(wake_hi | bank->context.risingdetect,
+                            bank->base + bank->regs->risingdetect);
+
        if (bank->power_mode != OFF_MODE) {
                bank->power_mode = 0;
                goto update_gpio_context_count;
@@ -1207,9 +1245,6 @@ static int omap_gpio_runtime_suspend(struct device *dev)
         * non-wakeup GPIOs.  Otherwise spurious IRQs will be
         * generated.  See OMAP2420 Errata item 1.101.
         */
-       if (!(bank->enabled_non_wakeup_gpios))
-               goto update_gpio_context_count;
-
        bank->saved_datain = __raw_readl(bank->base +
                                                bank->regs->datain);
        l1 = __raw_readl(bank->base + bank->regs->fallingdetect);
@@ -1246,7 +1281,19 @@ static int omap_gpio_runtime_resume(struct device *dev)
 
        spin_lock_irqsave(&bank->lock, flags);
        _gpio_dbck_enable(bank);
-       if (!bank->enabled_non_wakeup_gpios || !bank->workaround_enabled) {
+
+       /*
+        * In ->runtime_suspend(), level-triggered, wakeup-enabled
+        * GPIOs were set to edge trigger also in order to be able to
+        * generate a PRCM wakeup.  Here we restore the
+        * pre-runtime_suspend() values for edge triggering.
+        */
+       __raw_writel(bank->context.fallingdetect,
+                    bank->base + bank->regs->fallingdetect);
+       __raw_writel(bank->context.risingdetect,
+                    bank->base + bank->regs->risingdetect);
+
+       if (!bank->workaround_enabled) {
                spin_unlock_irqrestore(&bank->lock, flags);
                return 0;
        }
@@ -1397,11 +1444,95 @@ static const struct dev_pm_ops gpio_pm_ops = {
                                                                        NULL)
 };
 
+#if defined(CONFIG_OF)
+static struct omap_gpio_reg_offs omap2_gpio_regs = {
+       .revision =             OMAP24XX_GPIO_REVISION,
+       .direction =            OMAP24XX_GPIO_OE,
+       .datain =               OMAP24XX_GPIO_DATAIN,
+       .dataout =              OMAP24XX_GPIO_DATAOUT,
+       .set_dataout =          OMAP24XX_GPIO_SETDATAOUT,
+       .clr_dataout =          OMAP24XX_GPIO_CLEARDATAOUT,
+       .irqstatus =            OMAP24XX_GPIO_IRQSTATUS1,
+       .irqstatus2 =           OMAP24XX_GPIO_IRQSTATUS2,
+       .irqenable =            OMAP24XX_GPIO_IRQENABLE1,
+       .irqenable2 =           OMAP24XX_GPIO_IRQENABLE2,
+       .set_irqenable =        OMAP24XX_GPIO_SETIRQENABLE1,
+       .clr_irqenable =        OMAP24XX_GPIO_CLEARIRQENABLE1,
+       .debounce =             OMAP24XX_GPIO_DEBOUNCE_VAL,
+       .debounce_en =          OMAP24XX_GPIO_DEBOUNCE_EN,
+       .ctrl =                 OMAP24XX_GPIO_CTRL,
+       .wkup_en =              OMAP24XX_GPIO_WAKE_EN,
+       .leveldetect0 =         OMAP24XX_GPIO_LEVELDETECT0,
+       .leveldetect1 =         OMAP24XX_GPIO_LEVELDETECT1,
+       .risingdetect =         OMAP24XX_GPIO_RISINGDETECT,
+       .fallingdetect =        OMAP24XX_GPIO_FALLINGDETECT,
+};
+
+static struct omap_gpio_reg_offs omap4_gpio_regs = {
+       .revision =             OMAP4_GPIO_REVISION,
+       .direction =            OMAP4_GPIO_OE,
+       .datain =               OMAP4_GPIO_DATAIN,
+       .dataout =              OMAP4_GPIO_DATAOUT,
+       .set_dataout =          OMAP4_GPIO_SETDATAOUT,
+       .clr_dataout =          OMAP4_GPIO_CLEARDATAOUT,
+       .irqstatus =            OMAP4_GPIO_IRQSTATUS0,
+       .irqstatus2 =           OMAP4_GPIO_IRQSTATUS1,
+       .irqenable =            OMAP4_GPIO_IRQSTATUSSET0,
+       .irqenable2 =           OMAP4_GPIO_IRQSTATUSSET1,
+       .set_irqenable =        OMAP4_GPIO_IRQSTATUSSET0,
+       .clr_irqenable =        OMAP4_GPIO_IRQSTATUSCLR0,
+       .debounce =             OMAP4_GPIO_DEBOUNCINGTIME,
+       .debounce_en =          OMAP4_GPIO_DEBOUNCENABLE,
+       .ctrl =                 OMAP4_GPIO_CTRL,
+       .wkup_en =              OMAP4_GPIO_IRQWAKEN0,
+       .leveldetect0 =         OMAP4_GPIO_LEVELDETECT0,
+       .leveldetect1 =         OMAP4_GPIO_LEVELDETECT1,
+       .risingdetect =         OMAP4_GPIO_RISINGDETECT,
+       .fallingdetect =        OMAP4_GPIO_FALLINGDETECT,
+};
+
+static struct omap_gpio_platform_data omap2_pdata = {
+       .regs = &omap2_gpio_regs,
+       .bank_width = 32,
+       .dbck_flag = false,
+};
+
+static struct omap_gpio_platform_data omap3_pdata = {
+       .regs = &omap2_gpio_regs,
+       .bank_width = 32,
+       .dbck_flag = true,
+};
+
+static struct omap_gpio_platform_data omap4_pdata = {
+       .regs = &omap4_gpio_regs,
+       .bank_width = 32,
+       .dbck_flag = true,
+};
+
+static const struct of_device_id omap_gpio_match[] = {
+       {
+               .compatible = "ti,omap4-gpio",
+               .data = &omap4_pdata,
+       },
+       {
+               .compatible = "ti,omap3-gpio",
+               .data = &omap3_pdata,
+       },
+       {
+               .compatible = "ti,omap2-gpio",
+               .data = &omap2_pdata,
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, omap_gpio_match);
+#endif
+
 static struct platform_driver omap_gpio_driver = {
        .probe          = omap_gpio_probe,
        .driver         = {
                .name   = "omap_gpio",
                .pm     = &gpio_pm_ops,
+               .of_match_table = of_match_ptr(omap_gpio_match),
        },
 };
 
This page took 0.035474 seconds and 5 git commands to generate.