UPSTREAM: PM / devfreq: rk3399_dmc: Remove explictly regulator_put call in .remove
[firefly-linux-kernel-4.4.55.git] / drivers / gpio / gpio-mpc8xxx.c
index a0b33a216d4a788f4983b71d700350b3fff76d51..9e02cb6afb0bb15872581684d0c806dff4596c51 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
 #include <linux/irq.h>
@@ -30,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
@@ -38,6 +40,7 @@ struct mpc8xxx_gpio_chip {
         */
        u32 data;
        struct irq_domain *irq;
+       unsigned int irqn;
        const void *of_dev_id_data;
 };
 
@@ -69,10 +72,14 @@ static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
        u32 val;
        struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
        struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+       u32 out_mask, out_shadow;
 
-       val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
+       out_mask = in_be32(mm->regs + GPIO_DIR);
 
-       return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
+       val = in_be32(mm->regs + GPIO_DAT) & ~out_mask;
+       out_shadow = mpc8xxx_gc->data & out_mask;
+
+       return (val | out_shadow) & mpc8xxx_gpio2mask(gpio);
 }
 
 static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
@@ -88,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);
@@ -97,7 +104,33 @@ 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,
+                                     unsigned long *mask, unsigned long *bits)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+       unsigned long flags;
+       int i;
+
+       raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       for (i = 0; i < gc->ngpio; i++) {
+               if (*mask == 0)
+                       break;
+               if (__test_and_clear_bit(i, mask)) {
+                       if (test_bit(i, bits))
+                               mpc8xxx_gc->data |= mpc8xxx_gpio2mask(i);
+                       else
+                               mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(i);
+               }
+       }
+
+       out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
+
+       raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
 
 static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
@@ -106,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;
 }
@@ -123,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;
 }
@@ -141,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);
@@ -152,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);
@@ -173,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)
@@ -186,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)
@@ -209,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:
@@ -249,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:
@@ -279,54 +321,79 @@ 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 virq,
-                               irq_hw_number_t hw)
+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(virq, h->host_data);
-       irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
+       irq_set_chip_data(irq, h->host_data);
+       irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_edge_irq);
 
        return 0;
 }
 
-static struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
+static const struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
        .map    = mpc8xxx_gpio_irq_map,
        .xlate  = irq_domain_xlate_twocell,
 };
 
-static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
+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",   },
        {}
 };
 
-static void __init mpc8xxx_add_controller(struct device_node *np)
+static int mpc8xxx_probe(struct platform_device *pdev)
 {
+       struct device_node *np = pdev->dev.of_node;
        struct mpc8xxx_gpio_chip *mpc8xxx_gc;
        struct of_mm_gpio_chip *mm_gc;
        struct gpio_chip *gc;
        const struct of_device_id *id;
-       unsigned hwirq;
+       const struct mpc8xxx_gpio_devtype *devtype =
+               of_device_get_match_data(&pdev->dev);
        int ret;
 
-       mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL);
-       if (!mpc8xxx_gc) {
-               ret = -ENOMEM;
-               goto err;
-       }
+       mpc8xxx_gc = devm_kzalloc(&pdev->dev, sizeof(*mpc8xxx_gc), GFP_KERNEL);
+       if (!mpc8xxx_gc)
+               return -ENOMEM;
 
-       spin_lock_init(&mpc8xxx_gc->lock);
+       platform_set_drvdata(pdev, mpc8xxx_gc);
+
+       raw_spin_lock_init(&mpc8xxx_gc->lock);
 
        mm_gc = &mpc8xxx_gc->mm_gc;
        gc = &mm_gc->gc;
@@ -334,25 +401,34 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
        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;
 
        ret = of_mm_gpiochip_add(np, mm_gc);
        if (ret)
-               goto err;
+               return ret;
 
-       hwirq = irq_of_parse_and_map(np, 0);
-       if (hwirq == NO_IRQ)
-               goto skip_irq;
+       mpc8xxx_gc->irqn = irq_of_parse_and_map(np, 0);
+       if (mpc8xxx_gc->irqn == NO_IRQ)
+               return 0;
 
        mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS,
                                        &mpc8xxx_gpio_irq_ops, mpc8xxx_gc);
        if (!mpc8xxx_gc->irq)
-               goto skip_irq;
+               return 0;
 
        id = of_match_node(mpc8xxx_gpio_ids, np);
        if (id)
@@ -362,27 +438,38 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
        out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
        out_be32(mm_gc->regs + GPIO_IMR, 0);
 
-       irq_set_handler_data(hwirq, mpc8xxx_gc);
-       irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
+       irq_set_chained_handler_and_data(mpc8xxx_gc->irqn,
+                                        mpc8xxx_gpio_irq_cascade, mpc8xxx_gc);
 
-skip_irq:
-       return;
-
-err:
-       pr_err("%s: registration failed with status %d\n",
-              np->full_name, ret);
-       kfree(mpc8xxx_gc);
-
-       return;
+       return 0;
 }
 
-static int __init mpc8xxx_add_gpiochips(void)
+static int mpc8xxx_remove(struct platform_device *pdev)
 {
-       struct device_node *np;
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = platform_get_drvdata(pdev);
 
-       for_each_matching_node(np, mpc8xxx_gpio_ids)
-               mpc8xxx_add_controller(np);
+       if (mpc8xxx_gc->irq) {
+               irq_set_chained_handler_and_data(mpc8xxx_gc->irqn, NULL, NULL);
+               irq_domain_remove(mpc8xxx_gc->irq);
+       }
+
+       of_mm_gpiochip_remove(&mpc8xxx_gc->mm_gc);
 
        return 0;
 }
-arch_initcall(mpc8xxx_add_gpiochips);
+
+static struct platform_driver mpc8xxx_plat_driver = {
+       .probe          = mpc8xxx_probe,
+       .remove         = mpc8xxx_remove,
+       .driver         = {
+               .name = "gpio-mpc8xxx",
+               .of_match_table = mpc8xxx_gpio_ids,
+       },
+};
+
+static int __init mpc8xxx_init(void)
+{
+       return platform_driver_register(&mpc8xxx_plat_driver);
+}
+
+arch_initcall(mpc8xxx_init);