Merge tag 'mmc-updates-for-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / gpio / gpio-davinci.c
index 84be701..7629b4f 100644 (file)
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/gpio-davinci.h>
+#include <linux/irqchip/chained_irq.h>
 
 struct davinci_gpio_regs {
        u32     dir;
@@ -82,14 +87,14 @@ static inline int __davinci_direction(struct gpio_chip *chip,
        u32 mask = 1 << offset;
 
        spin_lock_irqsave(&d->lock, flags);
-       temp = __raw_readl(&g->dir);
+       temp = readl_relaxed(&g->dir);
        if (out) {
                temp &= ~mask;
-               __raw_writel(mask, value ? &g->set_data : &g->clr_data);
+               writel_relaxed(mask, value ? &g->set_data : &g->clr_data);
        } else {
                temp |= mask;
        }
-       __raw_writel(temp, &g->dir);
+       writel_relaxed(temp, &g->dir);
        spin_unlock_irqrestore(&d->lock, flags);
 
        return 0;
@@ -118,7 +123,7 @@ static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
        struct davinci_gpio_controller *d = chip2controller(chip);
        struct davinci_gpio_regs __iomem *g = d->regs;
 
-       return (1 << offset) & __raw_readl(&g->in_data);
+       return (1 << offset) & readl_relaxed(&g->in_data);
 }
 
 /*
@@ -130,7 +135,41 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
        struct davinci_gpio_controller *d = chip2controller(chip);
        struct davinci_gpio_regs __iomem *g = d->regs;
 
-       __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
+       writel_relaxed((1 << offset), value ? &g->set_data : &g->clr_data);
+}
+
+static struct davinci_gpio_platform_data *
+davinci_gpio_get_pdata(struct platform_device *pdev)
+{
+       struct device_node *dn = pdev->dev.of_node;
+       struct davinci_gpio_platform_data *pdata;
+       int ret;
+       u32 val;
+
+       if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
+               return pdev->dev.platform_data;
+
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return NULL;
+
+       ret = of_property_read_u32(dn, "ti,ngpio", &val);
+       if (ret)
+               goto of_err;
+
+       pdata->ngpio = val;
+
+       ret = of_property_read_u32(dn, "ti,davinci-gpio-unbanked", &val);
+       if (ret)
+               goto of_err;
+
+       pdata->gpio_unbanked = val;
+
+       return pdata;
+
+of_err:
+       dev_err(&pdev->dev, "Populating pdata from DT failed: err %d\n", ret);
+       return NULL;
 }
 
 static int davinci_gpio_probe(struct platform_device *pdev)
@@ -143,12 +182,14 @@ static int davinci_gpio_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct resource *res;
 
-       pdata = dev->platform_data;
+       pdata = davinci_gpio_get_pdata(pdev);
        if (!pdata) {
                dev_err(dev, "No platform data found\n");
                return -EINVAL;
        }
 
+       dev->platform_data = pdata;
+
        /*
         * The gpio banks conceptually expose a segmented bitmap,
         * and "ngpio" is one more than the largest zero-based
@@ -160,8 +201,8 @@ static int davinci_gpio_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       if (WARN_ON(DAVINCI_N_GPIO < ngpio))
-               ngpio = DAVINCI_N_GPIO;
+       if (WARN_ON(ARCH_NR_GPIOS < ngpio))
+               ngpio = ARCH_NR_GPIOS;
 
        chips = devm_kzalloc(dev,
                             ngpio * sizeof(struct davinci_gpio_controller),
@@ -194,6 +235,9 @@ static int davinci_gpio_probe(struct platform_device *pdev)
                if (chips[i].chip.ngpio > 32)
                        chips[i].chip.ngpio = 32;
 
+#ifdef CONFIG_OF_GPIO
+               chips[i].chip.of_node = dev->of_node;
+#endif
                spin_lock_init(&chips[i].lock);
 
                regs = gpio2regs(base);
@@ -227,8 +271,8 @@ static void gpio_irq_disable(struct irq_data *d)
        struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
        u32 mask = (u32) irq_data_get_irq_handler_data(d);
 
-       __raw_writel(mask, &g->clr_falling);
-       __raw_writel(mask, &g->clr_rising);
+       writel_relaxed(mask, &g->clr_falling);
+       writel_relaxed(mask, &g->clr_rising);
 }
 
 static void gpio_irq_enable(struct irq_data *d)
@@ -242,9 +286,9 @@ static void gpio_irq_enable(struct irq_data *d)
                status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
 
        if (status & IRQ_TYPE_EDGE_FALLING)
-               __raw_writel(mask, &g->set_falling);
+               writel_relaxed(mask, &g->set_falling);
        if (status & IRQ_TYPE_EDGE_RISING)
-               __raw_writel(mask, &g->set_rising);
+               writel_relaxed(mask, &g->set_rising);
 }
 
 static int gpio_irq_type(struct irq_data *d, unsigned trigger)
@@ -278,34 +322,28 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
                mask <<= 16;
 
        /* temporarily mask (level sensitive) parent IRQ */
-       desc->irq_data.chip->irq_mask(&desc->irq_data);
-       desc->irq_data.chip->irq_ack(&desc->irq_data);
+       chained_irq_enter(irq_desc_get_chip(desc), desc);
        while (1) {
                u32             status;
-               int             n;
-               int             res;
+               int             bit;
 
                /* ack any irqs */
-               status = __raw_readl(&g->intstat) & mask;
+               status = readl_relaxed(&g->intstat) & mask;
                if (!status)
                        break;
-               __raw_writel(status, &g->intstat);
+               writel_relaxed(status, &g->intstat);
 
                /* now demux them to the right lowlevel handler */
-               n = d->irq_base;
-               if (irq & 1) {
-                       n += 16;
-                       status >>= 16;
-               }
 
                while (status) {
-                       res = ffs(status);
-                       n += res;
-                       generic_handle_irq(n - 1);
-                       status >>= res;
+                       bit = __ffs(status);
+                       status &= ~BIT(bit);
+                       generic_handle_irq(
+                               irq_find_mapping(d->irq_domain,
+                                                d->chip.base + bit));
                }
        }
-       desc->irq_data.chip->irq_unmask(&desc->irq_data);
+       chained_irq_exit(irq_desc_get_chip(desc), desc);
        /* now it may re-trigger */
 }
 
@@ -313,10 +351,10 @@ static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
 {
        struct davinci_gpio_controller *d = chip2controller(chip);
 
-       if (d->irq_base >= 0)
-               return d->irq_base + offset;
+       if (d->irq_domain)
+               return irq_create_mapping(d->irq_domain, d->chip.base + offset);
        else
-               return -ENODEV;
+               return -ENXIO;
 }
 
 static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
@@ -346,14 +384,35 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger)
        if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
                return -EINVAL;
 
-       __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
+       writel_relaxed(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
                     ? &g->set_falling : &g->clr_falling);
-       __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
+       writel_relaxed(mask, (trigger & IRQ_TYPE_EDGE_RISING)
                     ? &g->set_rising : &g->clr_rising);
 
        return 0;
 }
 
+static int
+davinci_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+                    irq_hw_number_t hw)
+{
+       struct davinci_gpio_regs __iomem *g = gpio2regs(hw);
+
+       irq_set_chip_and_handler_name(irq, &gpio_irqchip, handle_simple_irq,
+                               "davinci_gpio");
+       irq_set_irq_type(irq, IRQ_TYPE_NONE);
+       irq_set_chip_data(irq, (__force void *)g);
+       irq_set_handler_data(irq, (void *)__gpio_mask(hw));
+       set_irq_flags(irq, IRQF_VALID);
+
+       return 0;
+}
+
+static const struct irq_domain_ops davinci_gpio_irq_ops = {
+       .map = davinci_gpio_irq_map,
+       .xlate = irq_domain_xlate_onetwocell,
+};
+
 /*
  * NOTE:  for suspend/resume, probably best to make a platform_device with
  * suspend_late/resume_resume calls hooking into results of the set_wake()
@@ -373,6 +432,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
        struct davinci_gpio_controller *chips = platform_get_drvdata(pdev);
        struct davinci_gpio_platform_data *pdata = dev->platform_data;
        struct davinci_gpio_regs __iomem *g;
+       struct irq_domain       *irq_domain = NULL;
 
        ngpio = pdata->ngpio;
        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -396,6 +456,22 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
        }
        clk_prepare_enable(clk);
 
+       if (!pdata->gpio_unbanked) {
+               irq = irq_alloc_descs(-1, 0, ngpio, 0);
+               if (irq < 0) {
+                       dev_err(dev, "Couldn't allocate IRQ numbers\n");
+                       return irq;
+               }
+
+               irq_domain = irq_domain_add_legacy(NULL, ngpio, irq, 0,
+                                                       &davinci_gpio_irq_ops,
+                                                       chips);
+               if (!irq_domain) {
+                       dev_err(dev, "Couldn't register an IRQ domain\n");
+                       return -ENODEV;
+               }
+       }
+
        /*
         * Arrange gpio_to_irq() support, handling either direct IRQs or
         * banked IRQs.  Having GPIOs in the first GPIO bank use direct
@@ -404,9 +480,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
         */
        for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
                chips[bank].chip.to_irq = gpio_to_irq_banked;
-               chips[bank].irq_base = pdata->gpio_unbanked
-                       ? -EINVAL
-                       : (pdata->intc_irq_num + gpio);
+               chips[bank].irq_domain = irq_domain;
        }
 
        /*
@@ -432,8 +506,8 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
 
                /* default trigger: both edges */
                g = gpio2regs(0);
-               __raw_writel(~0, &g->set_falling);
-               __raw_writel(~0, &g->set_rising);
+               writel_relaxed(~0, &g->set_falling);
+               writel_relaxed(~0, &g->set_rising);
 
                /* set the direct IRQs up to use that irqchip */
                for (gpio = 0; gpio < pdata->gpio_unbanked; gpio++, irq++) {
@@ -449,15 +523,11 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
         * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we
         * then chain through our own handler.
         */
-       for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
-                       gpio < ngpio;
-                       bank++, bank_irq++) {
-               unsigned                i;
-
+       for (gpio = 0, bank = 0; gpio < ngpio; bank++, bank_irq++, gpio += 16) {
                /* disabled by default, enabled only as needed */
                g = gpio2regs(gpio);
-               __raw_writel(~0, &g->clr_falling);
-               __raw_writel(~0, &g->clr_rising);
+               writel_relaxed(~0, &g->clr_falling);
+               writel_relaxed(~0, &g->clr_rising);
 
                /* set up all irqs in this bank */
                irq_set_chained_handler(bank_irq, gpio_irq_handler);
@@ -469,14 +539,6 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
                 */
                irq_set_handler_data(bank_irq, &chips[gpio / 32]);
 
-               for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
-                       irq_set_chip(irq, &gpio_irqchip);
-                       irq_set_chip_data(irq, (__force void *)g);
-                       irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
-                       irq_set_handler(irq, handle_simple_irq);
-                       set_irq_flags(irq, IRQF_VALID);
-               }
-
                binten |= BIT(bank);
        }
 
@@ -485,18 +547,25 @@ done:
         * BINTEN -- per-bank interrupt enable. genirq would also let these
         * bits be set/cleared dynamically.
         */
-       __raw_writel(binten, gpio_base + BINTEN);
-
-       printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
+       writel_relaxed(binten, gpio_base + BINTEN);
 
        return 0;
 }
 
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id davinci_gpio_ids[] = {
+       { .compatible = "ti,dm6441-gpio", },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, davinci_gpio_ids);
+#endif
+
 static struct platform_driver davinci_gpio_driver = {
        .probe          = davinci_gpio_probe,
        .driver         = {
-               .name   = "davinci_gpio",
-               .owner  = THIS_MODULE,
+               .name           = "davinci_gpio",
+               .owner          = THIS_MODULE,
+               .of_match_table = of_match_ptr(davinci_gpio_ids),
        },
 };