genirq: Remove irq argument from irq flow handlers
[linux-drm-fsl-dcu.git] / drivers / gpio / gpio-mpc8xxx.c
index 20aa66f34f6e04b26c26b02346ff6b5d040d155c..48ef368347ab2cd63cdb1d4f922572c608af9e89 100644 (file)
@@ -32,7 +32,7 @@
 
 struct mpc8xxx_gpio_chip {
        struct of_mm_gpio_chip mm_gc;
-       spinlock_t lock;
+       raw_spinlock_t lock;
 
        /*
         * shadowed data register to be able to clear/set output pins in
@@ -95,7 +95,7 @@ static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
        struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
        unsigned long flags;
 
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+       raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
        if (val)
                mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio);
@@ -104,7 +104,7 @@ static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 
        out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
 
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+       raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
 
 static void mpc8xxx_gpio_set_multiple(struct gpio_chip *gc,
@@ -115,7 +115,7 @@ static void mpc8xxx_gpio_set_multiple(struct gpio_chip *gc,
        unsigned long flags;
        int i;
 
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+       raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
        for (i = 0; i < gc->ngpio; i++) {
                if (*mask == 0)
@@ -130,7 +130,7 @@ static void mpc8xxx_gpio_set_multiple(struct gpio_chip *gc,
 
        out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
 
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+       raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
 
 static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
@@ -139,11 +139,11 @@ static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
        struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
        unsigned long flags;
 
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+       raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
        clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
 
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+       raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 
        return 0;
 }
@@ -156,11 +156,11 @@ static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val
 
        mpc8xxx_gpio_set(gc, gpio, val);
 
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+       raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
        setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
 
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+       raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 
        return 0;
 }
@@ -174,6 +174,15 @@ static int mpc5121_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val
        return mpc8xxx_gpio_dir_out(gc, gpio, val);
 }
 
+static int mpc5125_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       /* GPIO 0..3 are input only on MPC5125 */
+       if (gpio <= 3)
+               return -EINVAL;
+
+       return mpc8xxx_gpio_dir_out(gc, gpio, val);
+}
+
 static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
 {
        struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
@@ -185,7 +194,7 @@ static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
                return -ENXIO;
 }
 
-static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
+static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc)
 {
        struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
        struct irq_chip *chip = irq_desc_get_chip(desc);
@@ -206,11 +215,11 @@ static void mpc8xxx_irq_unmask(struct irq_data *d)
        struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
        unsigned long flags;
 
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+       raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
        setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+       raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
 
 static void mpc8xxx_irq_mask(struct irq_data *d)
@@ -219,11 +228,11 @@ static void mpc8xxx_irq_mask(struct irq_data *d)
        struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
        unsigned long flags;
 
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+       raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
        clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+       raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
 
 static void mpc8xxx_irq_ack(struct irq_data *d)
@@ -242,17 +251,17 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
 
        switch (flow_type) {
        case IRQ_TYPE_EDGE_FALLING:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
                setbits32(mm->regs + GPIO_ICR,
                          mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
                break;
 
        case IRQ_TYPE_EDGE_BOTH:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
                clrbits32(mm->regs + GPIO_ICR,
                          mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
                break;
 
        default:
@@ -282,22 +291,22 @@ static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
        switch (flow_type) {
        case IRQ_TYPE_EDGE_FALLING:
        case IRQ_TYPE_LEVEL_LOW:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
                clrsetbits_be32(reg, 3 << shift, 2 << shift);
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
                break;
 
        case IRQ_TYPE_EDGE_RISING:
        case IRQ_TYPE_LEVEL_HIGH:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
                clrsetbits_be32(reg, 3 << shift, 1 << shift);
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
                break;
 
        case IRQ_TYPE_EDGE_BOTH:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
                clrbits32(reg, 3 << shift);
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
                break;
 
        default:
@@ -312,17 +321,13 @@ static struct irq_chip mpc8xxx_irq_chip = {
        .irq_unmask     = mpc8xxx_irq_unmask,
        .irq_mask       = mpc8xxx_irq_mask,
        .irq_ack        = mpc8xxx_irq_ack,
+       /* this might get overwritten in mpc8xxx_probe() */
        .irq_set_type   = mpc8xxx_irq_set_type,
 };
 
 static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int irq,
                                irq_hw_number_t hwirq)
 {
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
-
-       if (mpc8xxx_gc->of_dev_id_data)
-               mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
-
        irq_set_chip_data(irq, h->host_data);
        irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_level_irq);
 
@@ -334,11 +339,38 @@ static const struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
        .xlate  = irq_domain_xlate_twocell,
 };
 
-static struct of_device_id mpc8xxx_gpio_ids[] = {
+struct mpc8xxx_gpio_devtype {
+       int (*gpio_dir_out)(struct gpio_chip *, unsigned int, int);
+       int (*gpio_get)(struct gpio_chip *, unsigned int);
+       int (*irq_set_type)(struct irq_data *, unsigned int);
+};
+
+static const struct mpc8xxx_gpio_devtype mpc512x_gpio_devtype = {
+       .gpio_dir_out = mpc5121_gpio_dir_out,
+       .irq_set_type = mpc512x_irq_set_type,
+};
+
+static const struct mpc8xxx_gpio_devtype mpc5125_gpio_devtype = {
+       .gpio_dir_out = mpc5125_gpio_dir_out,
+       .irq_set_type = mpc512x_irq_set_type,
+};
+
+static const struct mpc8xxx_gpio_devtype mpc8572_gpio_devtype = {
+       .gpio_get = mpc8572_gpio_get,
+};
+
+static const struct mpc8xxx_gpio_devtype mpc8xxx_gpio_devtype_default = {
+       .gpio_dir_out = mpc8xxx_gpio_dir_out,
+       .gpio_get = mpc8xxx_gpio_get,
+       .irq_set_type = mpc8xxx_irq_set_type,
+};
+
+static const struct of_device_id mpc8xxx_gpio_ids[] = {
        { .compatible = "fsl,mpc8349-gpio", },
-       { .compatible = "fsl,mpc8572-gpio", },
+       { .compatible = "fsl,mpc8572-gpio", .data = &mpc8572_gpio_devtype, },
        { .compatible = "fsl,mpc8610-gpio", },
-       { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
+       { .compatible = "fsl,mpc5121-gpio", .data = &mpc512x_gpio_devtype, },
+       { .compatible = "fsl,mpc5125-gpio", .data = &mpc5125_gpio_devtype, },
        { .compatible = "fsl,pq3-gpio",     },
        { .compatible = "fsl,qoriq-gpio",   },
        {}
@@ -351,6 +383,8 @@ static int mpc8xxx_probe(struct platform_device *pdev)
        struct of_mm_gpio_chip *mm_gc;
        struct gpio_chip *gc;
        const struct of_device_id *id;
+       const struct mpc8xxx_gpio_devtype *devtype =
+               of_device_get_match_data(&pdev->dev);
        int ret;
 
        mpc8xxx_gc = devm_kzalloc(&pdev->dev, sizeof(*mpc8xxx_gc), GFP_KERNEL);
@@ -359,7 +393,7 @@ static int mpc8xxx_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, mpc8xxx_gc);
 
-       spin_lock_init(&mpc8xxx_gc->lock);
+       raw_spin_lock_init(&mpc8xxx_gc->lock);
 
        mm_gc = &mpc8xxx_gc->mm_gc;
        gc = &mm_gc->gc;
@@ -367,10 +401,18 @@ static int mpc8xxx_probe(struct platform_device *pdev)
        mm_gc->save_regs = mpc8xxx_gpio_save_regs;
        gc->ngpio = MPC8XXX_GPIO_PINS;
        gc->direction_input = mpc8xxx_gpio_dir_in;
-       gc->direction_output = of_device_is_compatible(np, "fsl,mpc5121-gpio") ?
-               mpc5121_gpio_dir_out : mpc8xxx_gpio_dir_out;
-       gc->get = of_device_is_compatible(np, "fsl,mpc8572-gpio") ?
-               mpc8572_gpio_get : mpc8xxx_gpio_get;
+
+       if (!devtype)
+               devtype = &mpc8xxx_gpio_devtype_default;
+
+       /*
+        * It's assumed that only a single type of gpio controller is available
+        * on the current machine, so overwriting global data is fine.
+        */
+       mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type;
+
+       gc->direction_output = devtype->gpio_dir_out ?: mpc8xxx_gpio_dir_out;
+       gc->get = devtype->gpio_get ?: mpc8xxx_gpio_get;
        gc->set = mpc8xxx_gpio_set;
        gc->set_multiple = mpc8xxx_gpio_set_multiple;
        gc->to_irq = mpc8xxx_gpio_to_irq;
@@ -396,8 +438,8 @@ static int mpc8xxx_probe(struct platform_device *pdev)
        out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
        out_be32(mm_gc->regs + GPIO_IMR, 0);
 
-       irq_set_handler_data(mpc8xxx_gc->irqn, mpc8xxx_gc);
-       irq_set_chained_handler(mpc8xxx_gc->irqn, mpc8xxx_gpio_irq_cascade);
+       irq_set_chained_handler_and_data(mpc8xxx_gc->irqn,
+                                        mpc8xxx_gpio_irq_cascade, mpc8xxx_gc);
 
        return 0;
 }
@@ -407,8 +449,7 @@ static int mpc8xxx_remove(struct platform_device *pdev)
        struct mpc8xxx_gpio_chip *mpc8xxx_gc = platform_get_drvdata(pdev);
 
        if (mpc8xxx_gc->irq) {
-               irq_set_handler_data(mpc8xxx_gc->irqn, NULL);
-               irq_set_chained_handler(mpc8xxx_gc->irqn, NULL);
+               irq_set_chained_handler_and_data(mpc8xxx_gc->irqn, NULL, NULL);
                irq_domain_remove(mpc8xxx_gc->irq);
        }