]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpio/gpio-omap.c
Merge tag 'devicetree-for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / drivers / gpio / gpio-omap.c
index 19b886c21b1dbe357a806100fc44cf4f480620d2..00f29aa1fb9dda1a981b3d8245af3b1b9f1232e2 100644 (file)
@@ -24,9 +24,9 @@
 #include <linux/pm.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/irqdomain.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/gpio.h>
+#include <linux/bitops.h>
 #include <linux/platform_data/gpio-omap.h>
 
 #define OFF_MODE       1
@@ -52,7 +52,6 @@ struct gpio_bank {
        struct list_head node;
        void __iomem *base;
        u16 irq;
-       struct irq_domain *domain;
        u32 non_wakeup_gpios;
        u32 enabled_non_wakeup_gpios;
        struct gpio_regs context;
@@ -84,22 +83,21 @@ struct gpio_bank {
 };
 
 #define GPIO_INDEX(bank, gpio) (gpio % bank->width)
-#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
+#define GPIO_BIT(bank, gpio) (BIT(GPIO_INDEX(bank, gpio)))
 #define GPIO_MOD_CTRL_BIT      BIT(0)
 
 #define BANK_USED(bank) (bank->mod_usage || bank->irq_usage)
-#define LINE_USED(line, offset) (line & (1 << offset))
+#define LINE_USED(line, offset) (line & (BIT(offset)))
 
 static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq)
 {
        return bank->chip.base + gpio_irq;
 }
 
-static int omap_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+static inline struct gpio_bank *_irq_data_get_bank(struct irq_data *d)
 {
-       struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
-
-       return irq_find_mapping(bank->domain, offset);
+       struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+       return container_of(chip, struct gpio_bank, chip);
 }
 
 static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
@@ -110,9 +108,9 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
        reg += bank->regs->direction;
        l = readl_relaxed(reg);
        if (is_input)
-               l |= 1 << gpio;
+               l |= BIT(gpio);
        else
-               l &= ~(1 << gpio);
+               l &= ~(BIT(gpio));
        writel_relaxed(l, reg);
        bank->context.oe = l;
 }
@@ -155,14 +153,14 @@ static int _get_gpio_datain(struct gpio_bank *bank, int offset)
 {
        void __iomem *reg = bank->base + bank->regs->datain;
 
-       return (readl_relaxed(reg) & (1 << offset)) != 0;
+       return (readl_relaxed(reg) & (BIT(offset))) != 0;
 }
 
 static int _get_gpio_dataout(struct gpio_bank *bank, int offset)
 {
        void __iomem *reg = bank->base + bank->regs->dataout;
 
-       return (readl_relaxed(reg) & (1 << offset)) != 0;
+       return (readl_relaxed(reg) & (BIT(offset))) != 0;
 }
 
 static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
@@ -180,7 +178,7 @@ static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
 static inline void _gpio_dbck_enable(struct gpio_bank *bank)
 {
        if (bank->dbck_enable_mask && !bank->dbck_enabled) {
-               clk_enable(bank->dbck);
+               clk_prepare_enable(bank->dbck);
                bank->dbck_enabled = true;
 
                writel_relaxed(bank->dbck_enable_mask,
@@ -198,7 +196,7 @@ static inline void _gpio_dbck_disable(struct gpio_bank *bank)
                 */
                writel_relaxed(0, bank->base + bank->regs->debounce_en);
 
-               clk_disable(bank->dbck);
+               clk_disable_unprepare(bank->dbck);
                bank->dbck_enabled = false;
        }
 }
@@ -231,7 +229,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 
        l = GPIO_BIT(bank, gpio);
 
-       clk_enable(bank->dbck);
+       clk_prepare_enable(bank->dbck);
        reg = bank->base + bank->regs->debounce;
        writel_relaxed(debounce, reg);
 
@@ -245,7 +243,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
        bank->dbck_enable_mask = val;
 
        writel_relaxed(val, reg);
-       clk_disable(bank->dbck);
+       clk_disable_unprepare(bank->dbck);
        /*
         * Enable debounce clock per module.
         * This call is mandatory because in omap_gpio_request() when
@@ -290,7 +288,7 @@ static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio)
                bank->context.debounce = 0;
                writel_relaxed(bank->context.debounce, bank->base +
                             bank->regs->debounce);
-               clk_disable(bank->dbck);
+               clk_disable_unprepare(bank->dbck);
                bank->dbck_enabled = false;
        }
 }
@@ -299,7 +297,7 @@ static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
                                                unsigned trigger)
 {
        void __iomem *base = bank->base;
-       u32 gpio_bit = 1 << gpio;
+       u32 gpio_bit = BIT(gpio);
 
        _gpio_rmw(base, bank->regs->leveldetect0, gpio_bit,
                  trigger & IRQ_TYPE_LEVEL_LOW);
@@ -368,9 +366,9 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 
        l = readl_relaxed(reg);
        if ((l >> gpio) & 1)
-               l &= ~(1 << gpio);
+               l &= ~(BIT(gpio));
        else
-               l |= 1 << gpio;
+               l |= BIT(gpio);
 
        writel_relaxed(l, reg);
 }
@@ -392,11 +390,11 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio,
 
                l = readl_relaxed(reg);
                if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-                       bank->toggle_mask |= 1 << gpio;
+                       bank->toggle_mask |= BIT(gpio);
                if (trigger & IRQ_TYPE_EDGE_RISING)
-                       l |= 1 << gpio;
+                       l |= BIT(gpio);
                else if (trigger & IRQ_TYPE_EDGE_FALLING)
-                       l &= ~(1 << gpio);
+                       l &= ~(BIT(gpio));
                else
                        return -EINVAL;
 
@@ -413,10 +411,10 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio,
                if (trigger & IRQ_TYPE_EDGE_RISING)
                        l |= 2 << (gpio << 1);
                if (trigger & IRQ_TYPE_EDGE_FALLING)
-                       l |= 1 << (gpio << 1);
+                       l |= BIT(gpio << 1);
 
                /* Enable wake-up during idle for dynamic tick */
-               _gpio_rmw(base, bank->regs->wkup_en, 1 << gpio, trigger);
+               _gpio_rmw(base, bank->regs->wkup_en, BIT(gpio), trigger);
                bank->context.wake_en =
                        readl_relaxed(bank->base + bank->regs->wkup_en);
                writel_relaxed(l, reg);
@@ -430,7 +428,7 @@ static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset)
                void __iomem *reg = bank->base + bank->regs->pinctrl;
 
                /* Claim the pin for MPU */
-               writel_relaxed(readl_relaxed(reg) | (1 << offset), reg);
+               writel_relaxed(readl_relaxed(reg) | (BIT(offset)), reg);
        }
 
        if (bank->regs->ctrl && !BANK_USED(bank)) {
@@ -453,7 +451,7 @@ static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset)
            !LINE_USED(bank->mod_usage, offset) &&
            !LINE_USED(bank->irq_usage, offset)) {
                /* Disable wake-up during idle for dynamic tick */
-               _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0);
+               _gpio_rmw(base, bank->regs->wkup_en, BIT(offset), 0);
                bank->context.wake_en =
                        readl_relaxed(bank->base + bank->regs->wkup_en);
        }
@@ -479,7 +477,7 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
 
 static int gpio_irq_type(struct irq_data *d, unsigned type)
 {
-       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       struct gpio_bank *bank = _irq_data_get_bank(d);
        unsigned gpio = 0;
        int retval;
        unsigned long flags;
@@ -509,20 +507,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
        if (!LINE_USED(bank->mod_usage, offset)) {
                _enable_gpio_module(bank, offset);
                _set_gpio_direction(bank, offset, 1);
-       } else if (!gpio_is_input(bank, 1 << offset)) {
+       } else if (!gpio_is_input(bank, BIT(offset))) {
                spin_unlock_irqrestore(&bank->lock, flags);
                return -EINVAL;
        }
 
-       retval = gpio_lock_as_irq(&bank->chip, offset);
-       if (retval) {
-               dev_err(bank->dev, "unable to lock offset %d for IRQ\n",
-                       offset);
-               spin_unlock_irqrestore(&bank->lock, flags);
-               return retval;
-       }
-
-       bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio);
+       bank->irq_usage |= BIT(GPIO_INDEX(bank, gpio));
        spin_unlock_irqrestore(&bank->lock, flags);
 
        if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@@ -559,7 +549,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
 {
        void __iomem *reg = bank->base;
        u32 l;
-       u32 mask = (1 << bank->width) - 1;
+       u32 mask = (BIT(bank->width)) - 1;
 
        reg += bank->regs->irqenable;
        l = readl_relaxed(reg);
@@ -664,7 +654,7 @@ 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)
 {
-       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       struct gpio_bank *bank = _irq_data_get_bank(d);
        unsigned int gpio = irq_to_gpio(bank, d->hwirq);
 
        return _set_gpio_wakeup(bank, gpio, enable);
@@ -691,7 +681,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
                _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
                _enable_gpio_module(bank, offset);
        }
-       bank->mod_usage |= 1 << offset;
+       bank->mod_usage |= BIT(offset);
        spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
@@ -703,7 +693,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
        unsigned long flags;
 
        spin_lock_irqsave(&bank->lock, flags);
-       bank->mod_usage &= ~(1 << offset);
+       bank->mod_usage &= ~(BIT(offset));
        _disable_gpio_module(bank, offset);
        _reset_gpio(bank, bank->chip.base + offset);
        spin_unlock_irqrestore(&bank->lock, flags);
@@ -732,11 +722,12 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
        unsigned int bit;
        struct gpio_bank *bank;
        int unmasked = 0;
-       struct irq_chip *chip = irq_desc_get_chip(desc);
+       struct irq_chip *irqchip = irq_desc_get_chip(desc);
+       struct gpio_chip *chip = irq_get_handler_data(irq);
 
-       chained_irq_enter(chip, desc);
+       chained_irq_enter(irqchip, desc);
 
-       bank = irq_get_handler_data(irq);
+       bank = container_of(chip, struct gpio_bank, chip);
        isr_reg = bank->base + bank->regs->irqstatus;
        pm_runtime_get_sync(bank->dev);
 
@@ -764,7 +755,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                configured, we could unmask GPIO bank interrupt immediately */
                if (!level_mask && !unmasked) {
                        unmasked = 1;
-                       chained_irq_exit(chip, desc);
+                       chained_irq_exit(irqchip, desc);
                }
 
                if (!isr)
@@ -772,7 +763,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 
                while (isr) {
                        bit = __ffs(isr);
-                       isr &= ~(1 << bit);
+                       isr &= ~(BIT(bit));
 
                        /*
                         * Some chips can't respond to both rising and falling
@@ -781,10 +772,11 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                         * to respond to the IRQ for the opposite direction.
                         * This will be indicated in the bank toggle_mask.
                         */
-                       if (bank->toggle_mask & (1 << bit))
+                       if (bank->toggle_mask & (BIT(bit)))
                                _toggle_gpio_edge_triggering(bank, bit);
 
-                       generic_handle_irq(irq_find_mapping(bank->domain, bit));
+                       generic_handle_irq(irq_find_mapping(bank->chip.irqdomain,
+                                                           bit));
                }
        }
        /* if bank has any level sensitive GPIO pin interrupt
@@ -793,20 +785,20 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
        interrupt */
 exit:
        if (!unmasked)
-               chained_irq_exit(chip, desc);
+               chained_irq_exit(irqchip, desc);
        pm_runtime_put(bank->dev);
 }
 
 static void gpio_irq_shutdown(struct irq_data *d)
 {
-       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       struct gpio_bank *bank = _irq_data_get_bank(d);
        unsigned int gpio = irq_to_gpio(bank, d->hwirq);
        unsigned long flags;
        unsigned offset = GPIO_INDEX(bank, gpio);
 
        spin_lock_irqsave(&bank->lock, flags);
        gpio_unlock_as_irq(&bank->chip, offset);
-       bank->irq_usage &= ~(1 << offset);
+       bank->irq_usage &= ~(BIT(offset));
        _disable_gpio_module(bank, offset);
        _reset_gpio(bank, gpio);
        spin_unlock_irqrestore(&bank->lock, flags);
@@ -821,7 +813,7 @@ static void gpio_irq_shutdown(struct irq_data *d)
 
 static void gpio_ack_irq(struct irq_data *d)
 {
-       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       struct gpio_bank *bank = _irq_data_get_bank(d);
        unsigned int gpio = irq_to_gpio(bank, d->hwirq);
 
        _clear_gpio_irqstatus(bank, gpio);
@@ -829,7 +821,7 @@ static void gpio_ack_irq(struct irq_data *d)
 
 static void gpio_mask_irq(struct irq_data *d)
 {
-       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       struct gpio_bank *bank = _irq_data_get_bank(d);
        unsigned int gpio = irq_to_gpio(bank, d->hwirq);
        unsigned long flags;
 
@@ -841,7 +833,7 @@ static void gpio_mask_irq(struct irq_data *d)
 
 static void gpio_unmask_irq(struct irq_data *d)
 {
-       struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       struct gpio_bank *bank = _irq_data_get_bank(d);
        unsigned int gpio = irq_to_gpio(bank, d->hwirq);
        unsigned int irq_mask = GPIO_BIT(bank, gpio);
        u32 trigger = irqd_get_trigger_type(d);
@@ -936,6 +928,21 @@ static inline void mpuio_init(struct gpio_bank *bank)
 
 /*---------------------------------------------------------------------*/
 
+static int gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+       struct gpio_bank *bank;
+       unsigned long flags;
+       void __iomem *reg;
+       int dir;
+
+       bank = container_of(chip, struct gpio_bank, chip);
+       reg = bank->base + bank->regs->direction;
+       spin_lock_irqsave(&bank->lock, flags);
+       dir = !!(readl_relaxed(reg) & BIT(offset));
+       spin_unlock_irqrestore(&bank->lock, flags);
+       return dir;
+}
+
 static int gpio_input(struct gpio_chip *chip, unsigned offset)
 {
        struct gpio_bank *bank;
@@ -954,7 +961,7 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)
        u32 mask;
 
        bank = container_of(chip, struct gpio_bank, chip);
-       mask = (1 << offset);
+       mask = (BIT(offset));
 
        if (gpio_is_input(bank, mask))
                return _get_gpio_datain(bank, offset);
@@ -1081,10 +1088,12 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
                               IRQ_NOREQUEST | IRQ_NOPROBE, 0);
 }
 
-static void omap_gpio_chip_init(struct gpio_bank *bank)
+static int omap_gpio_chip_init(struct gpio_bank *bank)
 {
        int j;
        static int gpio;
+       int irq_base = 0;
+       int ret;
 
        /*
         * REVISIT eventually switch from OMAP-specific gpio structs
@@ -1092,12 +1101,12 @@ static void omap_gpio_chip_init(struct gpio_bank *bank)
         */
        bank->chip.request = omap_gpio_request;
        bank->chip.free = omap_gpio_free;
+       bank->chip.get_direction = gpio_get_direction;
        bank->chip.direction_input = gpio_input;
        bank->chip.get = gpio_get;
        bank->chip.direction_output = gpio_output;
        bank->chip.set_debounce = gpio_debounce;
        bank->chip.set = gpio_set;
-       bank->chip.to_irq = omap_gpio_to_irq;
        if (bank->is_mpuio) {
                bank->chip.label = "mpuio";
                if (bank->regs->wkup_en)
@@ -1110,22 +1119,48 @@ static void omap_gpio_chip_init(struct gpio_bank *bank)
        }
        bank->chip.ngpio = bank->width;
 
-       gpiochip_add(&bank->chip);
+       ret = gpiochip_add(&bank->chip);
+       if (ret) {
+               dev_err(bank->dev, "Could not register gpio chip %d\n", ret);
+               return ret;
+       }
+
+#ifdef CONFIG_ARCH_OMAP1
+       /*
+        * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
+        * irq_alloc_descs() since a base IRQ offset will no longer be needed.
+        */
+       irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
+       if (irq_base < 0) {
+               dev_err(bank->dev, "Couldn't allocate IRQ numbers\n");
+               return -ENODEV;
+       }
+#endif
+
+       ret = gpiochip_irqchip_add(&bank->chip, &gpio_irq_chip,
+                                  irq_base, gpio_irq_handler,
+                                  IRQ_TYPE_NONE);
+
+       if (ret) {
+               dev_err(bank->dev, "Couldn't add irqchip to gpiochip %d\n", ret);
+               ret = gpiochip_remove(&bank->chip);
+               return -ENODEV;
+       }
+
+       gpiochip_set_chained_irqchip(&bank->chip, &gpio_irq_chip,
+                                    bank->irq, gpio_irq_handler);
 
        for (j = 0; j < bank->width; j++) {
-               int irq = irq_create_mapping(bank->domain, j);
+               int irq = irq_find_mapping(bank->chip.irqdomain, j);
                irq_set_lockdep_class(irq, &gpio_lock_class);
-               irq_set_chip_data(irq, bank);
                if (bank->is_mpuio) {
                        omap_mpuio_alloc_gc(bank, irq, bank->width);
-               } else {
-                       irq_set_chip_and_handler(irq, &gpio_irq_chip,
-                                                handle_simple_irq);
-                       set_irq_flags(irq, IRQF_VALID);
+                       irq_set_chip_and_handler(irq, NULL, NULL);
+                       set_irq_flags(irq, 0);
                }
        }
-       irq_set_chained_handler(bank->irq, gpio_irq_handler);
-       irq_set_handler_data(bank->irq, bank);
+
+       return 0;
 }
 
 static const struct of_device_id omap_gpio_match[];
@@ -1138,9 +1173,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
        const struct omap_gpio_platform_data *pdata;
        struct resource *res;
        struct gpio_bank *bank;
-#ifdef CONFIG_ARCH_OMAP1
-       int irq_base;
-#endif
+       int ret;
 
        match = of_match_device(of_match_ptr(omap_gpio_match), dev);
 
@@ -1162,6 +1195,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
 
        bank->irq = res->start;
        bank->dev = dev;
+       bank->chip.dev = dev;
        bank->dbck_flag = pdata->dbck_flag;
        bank->stride = pdata->bank_stride;
        bank->width = pdata->bank_width;
@@ -1182,29 +1216,6 @@ static int omap_gpio_probe(struct platform_device *pdev)
                                pdata->get_context_loss_count;
        }
 
-#ifdef CONFIG_ARCH_OMAP1
-       /*
-        * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
-        * irq_alloc_descs() and irq_domain_add_legacy() and just use a
-        * linear IRQ domain mapping for all OMAP platforms.
-        */
-       irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
-       if (irq_base < 0) {
-               dev_err(dev, "Couldn't allocate IRQ numbers\n");
-               return -ENODEV;
-       }
-
-       bank->domain = irq_domain_add_legacy(node, bank->width, irq_base,
-                                            0, &irq_domain_simple_ops, NULL);
-#else
-       bank->domain = irq_domain_add_linear(node, bank->width,
-                                            &irq_domain_simple_ops, NULL);
-#endif
-       if (!bank->domain) {
-               dev_err(dev, "Couldn't register an IRQ domain\n");
-               return -ENODEV;
-       }
-
        if (bank->regs->set_dataout && bank->regs->clr_dataout)
                bank->set_dataout = _set_gpio_dataout_reg;
        else
@@ -1216,7 +1227,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        bank->base = devm_ioremap_resource(dev, res);
        if (IS_ERR(bank->base)) {
-               irq_domain_remove(bank->domain);
+               irq_domain_remove(bank->chip.irqdomain);
                return PTR_ERR(bank->base);
        }
 
@@ -1230,7 +1241,11 @@ static int omap_gpio_probe(struct platform_device *pdev)
                mpuio_init(bank);
 
        omap_gpio_mod_init(bank);
-       omap_gpio_chip_init(bank);
+
+       ret = omap_gpio_chip_init(bank);
+       if (ret)
+               return ret;
+
        omap_gpio_show_rev(bank);
 
        pm_runtime_put(bank->dev);