Loading drivers/gpio/gpio-pxa.c +98 −18 Original line number Diff line number Diff line Loading @@ -11,13 +11,17 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/module.h> #include <linux/clk.h> #include <linux/err.h> #include <linux/gpio.h> #include <linux/gpio-pxa.h> #include <linux/init.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/io.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/syscore_ops.h> #include <linux/slab.h> Loading Loading @@ -56,6 +60,10 @@ int pxa_last_gpio; #ifdef CONFIG_OF static struct irq_domain *domain; #endif struct pxa_gpio_chip { struct gpio_chip chip; void __iomem *regbase; Loading @@ -81,7 +89,6 @@ enum { PXA3XX_GPIO, PXA93X_GPIO, MMP_GPIO = 0x10, MMP2_GPIO, }; static DEFINE_SPINLOCK(gpio_lock); Loading Loading @@ -475,22 +482,92 @@ static int pxa_gpio_nums(void) gpio_type = MMP_GPIO; } else if (cpu_is_mmp2()) { count = 191; gpio_type = MMP2_GPIO; gpio_type = MMP_GPIO; } #endif /* CONFIG_ARCH_MMP */ return count; } static struct of_device_id pxa_gpio_dt_ids[] = { { .compatible = "mrvl,pxa-gpio" }, { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, {} }; static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); return 0; } const struct irq_domain_ops pxa_irq_domain_ops = { .map = pxa_irq_domain_map, }; #ifdef CONFIG_OF static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) { int ret, nr_banks, nr_gpios, irq_base; struct device_node *prev, *next, *np = pdev->dev.of_node; const struct of_device_id *of_id = of_match_device(pxa_gpio_dt_ids, &pdev->dev); if (!of_id) { dev_err(&pdev->dev, "Failed to find gpio controller\n"); return -EFAULT; } gpio_type = (int)of_id->data; next = of_get_next_child(np, NULL); prev = next; if (!next) { dev_err(&pdev->dev, "Failed to find child gpio node\n"); ret = -EINVAL; goto err; } for (nr_banks = 1; ; nr_banks++) { next = of_get_next_child(np, prev); if (!next) break; prev = next; } of_node_put(prev); nr_gpios = nr_banks << 5; pxa_last_gpio = nr_gpios - 1; irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); if (irq_base < 0) { dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); goto err; } domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, &pxa_irq_domain_ops, NULL); return 0; err: iounmap(gpio_reg_base); return ret; } #else #define pxa_gpio_probe_dt(pdev) (-1) #endif static int __devinit pxa_gpio_probe(struct platform_device *pdev) { struct pxa_gpio_chip *c; struct resource *res; struct clk *clk; struct pxa_gpio_platform_data *info; int gpio, irq, ret; int gpio, irq, ret, use_of = 0; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; ret = pxa_gpio_probe_dt(pdev); if (ret < 0) pxa_last_gpio = pxa_gpio_nums(); else use_of = 1; if (!pxa_last_gpio) return -EINVAL; Loading Loading @@ -545,6 +622,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); } if (!use_of) { #ifdef CONFIG_ARCH_PXA irq = gpio_to_irq(0); irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, Loading @@ -565,6 +643,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); return 0; Loading @@ -574,6 +653,7 @@ static struct platform_driver pxa_gpio_driver = { .probe = pxa_gpio_probe, .driver = { .name = "pxa-gpio", .of_match_table = pxa_gpio_dt_ids, }, }; Loading Loading
drivers/gpio/gpio-pxa.c +98 −18 Original line number Diff line number Diff line Loading @@ -11,13 +11,17 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/module.h> #include <linux/clk.h> #include <linux/err.h> #include <linux/gpio.h> #include <linux/gpio-pxa.h> #include <linux/init.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/io.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/syscore_ops.h> #include <linux/slab.h> Loading Loading @@ -56,6 +60,10 @@ int pxa_last_gpio; #ifdef CONFIG_OF static struct irq_domain *domain; #endif struct pxa_gpio_chip { struct gpio_chip chip; void __iomem *regbase; Loading @@ -81,7 +89,6 @@ enum { PXA3XX_GPIO, PXA93X_GPIO, MMP_GPIO = 0x10, MMP2_GPIO, }; static DEFINE_SPINLOCK(gpio_lock); Loading Loading @@ -475,22 +482,92 @@ static int pxa_gpio_nums(void) gpio_type = MMP_GPIO; } else if (cpu_is_mmp2()) { count = 191; gpio_type = MMP2_GPIO; gpio_type = MMP_GPIO; } #endif /* CONFIG_ARCH_MMP */ return count; } static struct of_device_id pxa_gpio_dt_ids[] = { { .compatible = "mrvl,pxa-gpio" }, { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, {} }; static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); return 0; } const struct irq_domain_ops pxa_irq_domain_ops = { .map = pxa_irq_domain_map, }; #ifdef CONFIG_OF static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) { int ret, nr_banks, nr_gpios, irq_base; struct device_node *prev, *next, *np = pdev->dev.of_node; const struct of_device_id *of_id = of_match_device(pxa_gpio_dt_ids, &pdev->dev); if (!of_id) { dev_err(&pdev->dev, "Failed to find gpio controller\n"); return -EFAULT; } gpio_type = (int)of_id->data; next = of_get_next_child(np, NULL); prev = next; if (!next) { dev_err(&pdev->dev, "Failed to find child gpio node\n"); ret = -EINVAL; goto err; } for (nr_banks = 1; ; nr_banks++) { next = of_get_next_child(np, prev); if (!next) break; prev = next; } of_node_put(prev); nr_gpios = nr_banks << 5; pxa_last_gpio = nr_gpios - 1; irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); if (irq_base < 0) { dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); goto err; } domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, &pxa_irq_domain_ops, NULL); return 0; err: iounmap(gpio_reg_base); return ret; } #else #define pxa_gpio_probe_dt(pdev) (-1) #endif static int __devinit pxa_gpio_probe(struct platform_device *pdev) { struct pxa_gpio_chip *c; struct resource *res; struct clk *clk; struct pxa_gpio_platform_data *info; int gpio, irq, ret; int gpio, irq, ret, use_of = 0; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; ret = pxa_gpio_probe_dt(pdev); if (ret < 0) pxa_last_gpio = pxa_gpio_nums(); else use_of = 1; if (!pxa_last_gpio) return -EINVAL; Loading Loading @@ -545,6 +622,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); } if (!use_of) { #ifdef CONFIG_ARCH_PXA irq = gpio_to_irq(0); irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, Loading @@ -565,6 +643,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); return 0; Loading @@ -574,6 +653,7 @@ static struct platform_driver pxa_gpio_driver = { .probe = pxa_gpio_probe, .driver = { .name = "pxa-gpio", .of_match_table = pxa_gpio_dt_ids, }, }; Loading