genirq: Remove irq argument from irq flow handlers
[cascardo/linux.git] / drivers / gpio / gpio-omap.c
index 61a731f..9df014c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/platform_data/gpio-omap.h>
 
 #define OFF_MODE       1
+#define OMAP4_GPIO_DEBOUNCINGTIME_MASK 0xFF
 
 static LIST_HEAD(omap_gpio_list);
 
@@ -57,7 +58,7 @@ struct gpio_bank {
        u32 saved_datain;
        u32 level_mask;
        u32 toggle_mask;
-       spinlock_t lock;
+       raw_spinlock_t lock;
        struct gpio_chip chip;
        struct clk *dbck;
        u32 mod_usage;
@@ -175,7 +176,7 @@ static inline void omap_gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set
 static inline void omap_gpio_dbck_enable(struct gpio_bank *bank)
 {
        if (bank->dbck_enable_mask && !bank->dbck_enabled) {
-               clk_prepare_enable(bank->dbck);
+               clk_enable(bank->dbck);
                bank->dbck_enabled = true;
 
                writel_relaxed(bank->dbck_enable_mask,
@@ -193,7 +194,7 @@ static inline void omap_gpio_dbck_disable(struct gpio_bank *bank)
                 */
                writel_relaxed(0, bank->base + bank->regs->debounce_en);
 
-               clk_disable_unprepare(bank->dbck);
+               clk_disable(bank->dbck);
                bank->dbck_enabled = false;
        }
 }
@@ -204,8 +205,9 @@ static inline void omap_gpio_dbck_disable(struct gpio_bank *bank)
  * @offset: the gpio number on this @bank
  * @debounce: debounce time to use
  *
- * OMAP's debounce time is in 31us steps so we need
- * to convert and round up to the closest unit.
+ * OMAP's debounce time is in 31us steps
+ *   <debounce time> = (GPIO_DEBOUNCINGTIME[7:0].DEBOUNCETIME + 1) x 31
+ * so we need to convert and round up to the closest unit.
  */
 static void omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
                                    unsigned debounce)
@@ -213,34 +215,33 @@ static void omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
        void __iomem            *reg;
        u32                     val;
        u32                     l;
+       bool                    enable = !!debounce;
 
        if (!bank->dbck_flag)
                return;
 
-       if (debounce < 32)
-               debounce = 0x01;
-       else if (debounce > 7936)
-               debounce = 0xff;
-       else
-               debounce = (debounce / 0x1f) - 1;
+       if (enable) {
+               debounce = DIV_ROUND_UP(debounce, 31) - 1;
+               debounce &= OMAP4_GPIO_DEBOUNCINGTIME_MASK;
+       }
 
        l = BIT(offset);
 
-       clk_prepare_enable(bank->dbck);
+       clk_enable(bank->dbck);
        reg = bank->base + bank->regs->debounce;
        writel_relaxed(debounce, reg);
 
        reg = bank->base + bank->regs->debounce_en;
        val = readl_relaxed(reg);
 
-       if (debounce)
+       if (enable)
                val |= l;
        else
                val &= ~l;
        bank->dbck_enable_mask = val;
 
        writel_relaxed(val, reg);
-       clk_disable_unprepare(bank->dbck);
+       clk_disable(bank->dbck);
        /*
         * Enable debounce clock per module.
         * This call is mandatory because in omap_gpio_request() when
@@ -285,7 +286,7 @@ static void omap_clear_gpio_debounce(struct gpio_bank *bank, unsigned offset)
                bank->context.debounce = 0;
                writel_relaxed(bank->context.debounce, bank->base +
                             bank->regs->debounce);
-               clk_disable_unprepare(bank->dbck);
+               clk_disable(bank->dbck);
                bank->dbck_enabled = false;
        }
 }
@@ -498,24 +499,24 @@ static int omap_gpio_irq_type(struct irq_data *d, unsigned type)
        if (!BANK_USED(bank))
                pm_runtime_get_sync(bank->dev);
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        retval = omap_set_gpio_triggering(bank, offset, type);
        if (retval) {
-               spin_unlock_irqrestore(&bank->lock, flags);
+               raw_spin_unlock_irqrestore(&bank->lock, flags);
                goto error;
        }
        omap_gpio_init_irq(bank, offset);
        if (!omap_gpio_is_input(bank, offset)) {
-               spin_unlock_irqrestore(&bank->lock, flags);
+               raw_spin_unlock_irqrestore(&bank->lock, flags);
                retval = -EINVAL;
                goto error;
        }
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
-               __irq_set_handler_locked(d->irq, handle_level_irq);
+               irq_set_handler_locked(d, handle_level_irq);
        else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
-               __irq_set_handler_locked(d->irq, handle_edge_irq);
+               irq_set_handler_locked(d, handle_edge_irq);
 
        return 0;
 
@@ -636,14 +637,14 @@ static int omap_set_gpio_wakeup(struct gpio_bank *bank, unsigned offset,
                return -EINVAL;
        }
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        if (enable)
                bank->context.wake_en |= gpio_bit;
        else
                bank->context.wake_en &= ~gpio_bit;
 
        writel_relaxed(bank->context.wake_en, bank->base + bank->regs->wkup_en);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
 }
@@ -669,10 +670,10 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
        if (!BANK_USED(bank))
                pm_runtime_get_sync(bank->dev);
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        omap_enable_gpio_module(bank, offset);
        bank->mod_usage |= BIT(offset);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
 }
@@ -682,14 +683,14 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
        struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
        unsigned long flags;
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        bank->mod_usage &= ~(BIT(offset));
        if (!LINE_USED(bank->irq_usage, offset)) {
                omap_set_gpio_direction(bank, offset, 1);
                omap_clear_gpio_debounce(bank, offset);
        }
        omap_disable_gpio_module(bank, offset);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        /*
         * If this is the last gpio to be freed in the bank,
@@ -708,7 +709,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
  * line's interrupt handler has been run, we may miss some nested
  * interrupts.
  */
-static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+static void omap_gpio_irq_handler(struct irq_desc *desc)
 {
        void __iomem *isr_reg = NULL;
        u32 isr;
@@ -716,7 +717,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
        struct gpio_bank *bank;
        int unmasked = 0;
        struct irq_chip *irqchip = irq_desc_get_chip(desc);
-       struct gpio_chip *chip = irq_get_handler_data(irq);
+       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+       unsigned long lock_flags;
 
        chained_irq_enter(irqchip, desc);
 
@@ -731,6 +733,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                u32 isr_saved, level_mask = 0;
                u32 enabled;
 
+               raw_spin_lock_irqsave(&bank->lock, lock_flags);
+
                enabled = omap_get_gpio_irqbank_mask(bank);
                isr_saved = isr = readl_relaxed(isr_reg) & enabled;
 
@@ -744,6 +748,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
                omap_enable_gpio_irqbank(bank, isr_saved & ~level_mask);
 
+               raw_spin_unlock_irqrestore(&bank->lock, lock_flags);
+
                /* if there is only edge sensitive GPIO pin interrupts
                configured, we could unmask GPIO bank interrupt immediately */
                if (!level_mask && !unmasked) {
@@ -758,6 +764,7 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                        bit = __ffs(isr);
                        isr &= ~(BIT(bit));
 
+                       raw_spin_lock_irqsave(&bank->lock, lock_flags);
                        /*
                         * Some chips can't respond to both rising and falling
                         * at the same time.  If this irq was requested with
@@ -768,6 +775,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                        if (bank->toggle_mask & (BIT(bit)))
                                omap_toggle_gpio_edge_triggering(bank, bit);
 
+                       raw_spin_unlock_irqrestore(&bank->lock, lock_flags);
+
                        generic_handle_irq(irq_find_mapping(bank->chip.irqdomain,
                                                            bit));
                }
@@ -791,7 +800,7 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d)
        if (!BANK_USED(bank))
                pm_runtime_get_sync(bank->dev);
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
 
        if (!LINE_USED(bank->mod_usage, offset))
                omap_set_gpio_direction(bank, offset, 1);
@@ -800,12 +809,12 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d)
        omap_enable_gpio_module(bank, offset);
        bank->irq_usage |= BIT(offset);
 
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
        omap_gpio_unmask_irq(d);
 
        return 0;
 err:
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
        if (!BANK_USED(bank))
                pm_runtime_put(bank->dev);
        return -EINVAL;
@@ -817,7 +826,7 @@ static void omap_gpio_irq_shutdown(struct irq_data *d)
        unsigned long flags;
        unsigned offset = d->hwirq;
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        bank->irq_usage &= ~(BIT(offset));
        omap_set_gpio_irqenable(bank, offset, 0);
        omap_clear_gpio_irqstatus(bank, offset);
@@ -825,7 +834,7 @@ static void omap_gpio_irq_shutdown(struct irq_data *d)
        if (!LINE_USED(bank->mod_usage, offset))
                omap_clear_gpio_debounce(bank, offset);
        omap_disable_gpio_module(bank, offset);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        /*
         * If this is the last IRQ to be freed in the bank,
@@ -849,10 +858,10 @@ static void omap_gpio_mask_irq(struct irq_data *d)
        unsigned offset = d->hwirq;
        unsigned long flags;
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        omap_set_gpio_irqenable(bank, offset, 0);
        omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 }
 
 static void omap_gpio_unmask_irq(struct irq_data *d)
@@ -862,7 +871,7 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
        u32 trigger = irqd_get_trigger_type(d);
        unsigned long flags;
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        if (trigger)
                omap_set_gpio_triggering(bank, offset, trigger);
 
@@ -874,7 +883,7 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
        }
 
        omap_set_gpio_irqenable(bank, offset, 1);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 }
 
 /*---------------------------------------------------------------------*/
@@ -887,9 +896,9 @@ static int omap_mpuio_suspend_noirq(struct device *dev)
                                        OMAP_MPUIO_GPIO_MASKIT / bank->stride;
        unsigned long           flags;
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        writel_relaxed(0xffff & ~bank->context.wake_en, mask_reg);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
 }
@@ -902,9 +911,9 @@ static int omap_mpuio_resume_noirq(struct device *dev)
                                        OMAP_MPUIO_GPIO_MASKIT / bank->stride;
        unsigned long           flags;
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        writel_relaxed(bank->context.wake_en, mask_reg);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
 }
@@ -950,9 +959,9 @@ static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
 
        bank = container_of(chip, struct gpio_bank, chip);
        reg = bank->base + bank->regs->direction;
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        dir = !!(readl_relaxed(reg) & BIT(offset));
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
        return dir;
 }
 
@@ -962,9 +971,9 @@ static int omap_gpio_input(struct gpio_chip *chip, unsigned offset)
        unsigned long flags;
 
        bank = container_of(chip, struct gpio_bank, chip);
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        omap_set_gpio_direction(bank, offset, 1);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
        return 0;
 }
 
@@ -986,10 +995,10 @@ static int omap_gpio_output(struct gpio_chip *chip, unsigned offset, int value)
        unsigned long flags;
 
        bank = container_of(chip, struct gpio_bank, chip);
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        bank->set_dataout(bank, offset, value);
        omap_set_gpio_direction(bank, offset, 0);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
        return 0;
 }
 
@@ -1001,9 +1010,9 @@ static int omap_gpio_debounce(struct gpio_chip *chip, unsigned offset,
 
        bank = container_of(chip, struct gpio_bank, chip);
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        omap2_set_gpio_debounce(bank, offset, debounce);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
 }
@@ -1014,9 +1023,9 @@ static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
        unsigned long flags;
 
        bank = container_of(chip, struct gpio_bank, chip);
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
        bank->set_dataout(bank, offset, value);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 }
 
 /*---------------------------------------------------------------------*/
@@ -1061,10 +1070,6 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
         /* Initialize interface clk ungated, module enabled */
        if (bank->regs->ctrl)
                writel_relaxed(0, base + bank->regs->ctrl);
-
-       bank->dbck = clk_get(bank->dev, "dbclk");
-       if (IS_ERR(bank->dbck))
-               dev_err(bank->dev, "Could not get gpio dbck\n");
 }
 
 static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
@@ -1178,13 +1183,16 @@ static int omap_gpio_probe(struct platform_device *pdev)
        irqc->irq_set_wake = omap_gpio_wake_enable,
        irqc->name = dev_name(&pdev->dev);
 
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (unlikely(!res)) {
-               dev_err(dev, "Invalid IRQ resource\n");
-               return -ENODEV;
+       bank->irq = platform_get_irq(pdev, 0);
+       if (bank->irq <= 0) {
+               if (!bank->irq)
+                       bank->irq = -ENXIO;
+               if (bank->irq != -EPROBE_DEFER)
+                       dev_err(dev,
+                               "can't get irq resource ret=%d\n", bank->irq);
+               return bank->irq;
        }
 
-       bank->irq = res->start;
        bank->dev = dev;
        bank->chip.dev = dev;
        bank->chip.owner = THIS_MODULE;
@@ -1213,16 +1221,26 @@ static int omap_gpio_probe(struct platform_device *pdev)
        else
                bank->set_dataout = omap_set_gpio_dataout_mask;
 
-       spin_lock_init(&bank->lock);
+       raw_spin_lock_init(&bank->lock);
 
        /* Static mapping, never released */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        bank->base = devm_ioremap_resource(dev, res);
        if (IS_ERR(bank->base)) {
-               irq_domain_remove(bank->chip.irqdomain);
                return PTR_ERR(bank->base);
        }
 
+       if (bank->dbck_flag) {
+               bank->dbck = devm_clk_get(bank->dev, "dbclk");
+               if (IS_ERR(bank->dbck)) {
+                       dev_err(bank->dev,
+                               "Could not get gpio dbck. Disable debounce\n");
+                       bank->dbck_flag = false;
+               } else {
+                       clk_prepare(bank->dbck);
+               }
+       }
+
        platform_set_drvdata(pdev, bank);
 
        pm_runtime_enable(bank->dev);
@@ -1254,6 +1272,8 @@ static int omap_gpio_remove(struct platform_device *pdev)
        list_del(&bank->node);
        gpiochip_remove(&bank->chip);
        pm_runtime_disable(bank->dev);
+       if (bank->dbck_flag)
+               clk_unprepare(bank->dbck);
 
        return 0;
 }
@@ -1271,7 +1291,7 @@ static int omap_gpio_runtime_suspend(struct device *dev)
        unsigned long flags;
        u32 wake_low, wake_hi;
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
 
        /*
         * Only edges can generate a wakeup event to the PRCM.
@@ -1324,7 +1344,7 @@ update_gpio_context_count:
                                bank->get_context_loss_count(bank->dev);
 
        omap_gpio_dbck_disable(bank);
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
 }
@@ -1339,7 +1359,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
        unsigned long flags;
        int c;
 
-       spin_lock_irqsave(&bank->lock, flags);
+       raw_spin_lock_irqsave(&bank->lock, flags);
 
        /*
         * On the first resume during the probe, the context has not
@@ -1375,14 +1395,14 @@ static int omap_gpio_runtime_resume(struct device *dev)
                        if (c != bank->context_loss_count) {
                                omap_gpio_restore_context(bank);
                        } else {
-                               spin_unlock_irqrestore(&bank->lock, flags);
+                               raw_spin_unlock_irqrestore(&bank->lock, flags);
                                return 0;
                        }
                }
        }
 
        if (!bank->workaround_enabled) {
-               spin_unlock_irqrestore(&bank->lock, flags);
+               raw_spin_unlock_irqrestore(&bank->lock, flags);
                return 0;
        }
 
@@ -1437,7 +1457,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
        }
 
        bank->workaround_enabled = false;
-       spin_unlock_irqrestore(&bank->lock, flags);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
 }