From: Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> To: arnd-r2nGTMty4D4@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org, linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org, eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org Subject: [PATCH 5/9] gpio: pxa: parse gpio from DTS file Date: Fri, 27 Apr 2012 16:39:13 +0800 [thread overview] Message-ID: <1335515957-1798-6-git-send-email-haojian.zhuang@gmail.com> (raw) In-Reply-To: <1335515957-1798-1-git-send-email-haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> Parse GPIO numbers from DTS file. Allocate interrupt according to GPIO numbers. Signed-off-by: Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> --- drivers/gpio/gpio-pxa.c | 116 +++++++++++++++++++++++++++++++++++++++------- 1 files changed, 98 insertions(+), 18 deletions(-) diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 5689ce6..1f5f1ac 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -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> @@ -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; @@ -80,7 +88,6 @@ enum { PXA3XX_GPIO, PXA93X_GPIO, MMP_GPIO = 0x10, - MMP2_GPIO, }; static DEFINE_SPINLOCK(gpio_lock); @@ -460,21 +467,91 @@ 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; - int gpio, irq, ret; + int gpio, irq, ret, use_of = 0; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; - pxa_last_gpio = pxa_gpio_nums(); + 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; @@ -528,25 +605,27 @@ 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, - handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); - - irq = gpio_to_irq(1); - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, - handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); -#endif + irq = gpio_to_irq(0); + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, + handle_edge_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); - for (irq = gpio_to_irq(gpio_offset); - irq <= gpio_to_irq(pxa_last_gpio); irq++) { + irq = gpio_to_irq(1); irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); +#endif + + for (irq = gpio_to_irq(gpio_offset); + irq <= gpio_to_irq(pxa_last_gpio); irq++) { + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, + handle_edge_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } } irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); @@ -557,6 +636,7 @@ static struct platform_driver pxa_gpio_driver = { .probe = pxa_gpio_probe, .driver = { .name = "pxa-gpio", + .of_match_table = pxa_gpio_dt_ids, }, }; -- 1.7.5.4
WARNING: multiple messages have this Message-ID (diff)
From: haojian.zhuang@gmail.com (Haojian Zhuang) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 5/9] gpio: pxa: parse gpio from DTS file Date: Fri, 27 Apr 2012 16:39:13 +0800 [thread overview] Message-ID: <1335515957-1798-6-git-send-email-haojian.zhuang@gmail.com> (raw) In-Reply-To: <1335515957-1798-1-git-send-email-haojian.zhuang@gmail.com> Parse GPIO numbers from DTS file. Allocate interrupt according to GPIO numbers. Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com> --- drivers/gpio/gpio-pxa.c | 116 +++++++++++++++++++++++++++++++++++++++------- 1 files changed, 98 insertions(+), 18 deletions(-) diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 5689ce6..1f5f1ac 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -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> @@ -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; @@ -80,7 +88,6 @@ enum { PXA3XX_GPIO, PXA93X_GPIO, MMP_GPIO = 0x10, - MMP2_GPIO, }; static DEFINE_SPINLOCK(gpio_lock); @@ -460,21 +467,91 @@ 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; - int gpio, irq, ret; + int gpio, irq, ret, use_of = 0; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; - pxa_last_gpio = pxa_gpio_nums(); + 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; @@ -528,25 +605,27 @@ 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, - handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); - - irq = gpio_to_irq(1); - irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, - handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); -#endif + irq = gpio_to_irq(0); + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, + handle_edge_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); - for (irq = gpio_to_irq(gpio_offset); - irq <= gpio_to_irq(pxa_last_gpio); irq++) { + irq = gpio_to_irq(1); irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); +#endif + + for (irq = gpio_to_irq(gpio_offset); + irq <= gpio_to_irq(pxa_last_gpio); irq++) { + irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, + handle_edge_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } } irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); @@ -557,6 +636,7 @@ static struct platform_driver pxa_gpio_driver = { .probe = pxa_gpio_probe, .driver = { .name = "pxa-gpio", + .of_match_table = pxa_gpio_dt_ids, }, }; -- 1.7.5.4
next prev parent reply other threads:[~2012-04-27 8:39 UTC|newest] Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top 2012-04-27 8:39 [PATCH 0/9] add more devicetree support in arch-mmp Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang [not found] ` <1335515957-1798-1-git-send-email-haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2012-04-27 8:39 ` [PATCH 1/9] ARM: mmp: fix build issue on mmp with device tree Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang [not found] ` <1335515957-1798-2-git-send-email-haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2012-04-27 20:15 ` Arnd Bergmann 2012-04-27 20:15 ` Arnd Bergmann [not found] ` <201204272015.49611.arnd-r2nGTMty4D4@public.gmane.org> 2012-04-28 3:11 ` Haojian Zhuang 2012-04-28 3:11 ` Haojian Zhuang 2012-04-27 8:39 ` [PATCH 2/9] ARM: mmp: distinguish mmp and mmp2 in Kconfig Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang [not found] ` <1335515957-1798-3-git-send-email-haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2012-04-27 20:14 ` Arnd Bergmann 2012-04-27 20:14 ` Arnd Bergmann [not found] ` <201204272014.49443.arnd-r2nGTMty4D4@public.gmane.org> 2012-05-02 5:53 ` Haojian Zhuang 2012-05-02 5:53 ` Haojian Zhuang [not found] ` <CAN1soZy=OdS=GUc93mgJ0bXTLJSX3+=WuWT=0yLDxkgjjG=wgQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2012-05-02 12:58 ` Arnd Bergmann 2012-05-02 12:58 ` Arnd Bergmann 2012-04-27 8:39 ` [PATCH 3/9] ARM: mmp: support DT in irq Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang [not found] ` <1335515957-1798-4-git-send-email-haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2012-04-27 19:06 ` Grant Likely 2012-04-27 19:06 ` Grant Likely 2012-05-02 5:40 ` Haojian Zhuang 2012-05-02 5:40 ` Haojian Zhuang [not found] ` <CAN1soZz5b0bc10isc6syxM7WzKfvVqc-HzotW6Auqv1A1mnC9A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2012-05-02 12:51 ` Arnd Bergmann 2012-05-02 12:51 ` Arnd Bergmann [not found] ` <201205021251.16967.arnd-r2nGTMty4D4@public.gmane.org> 2012-05-04 3:41 ` Haojian Zhuang 2012-05-04 3:41 ` Haojian Zhuang [not found] ` <CAN1soZwE7MoifmxtPS8f_x6CrK-dF97=vPMTMStg=VW1wsoLrA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2012-05-04 12:56 ` Arnd Bergmann 2012-05-04 12:56 ` Arnd Bergmann 2012-05-30 19:38 ` Chris Ball 2012-05-30 19:38 ` Chris Ball 2012-05-31 3:07 ` Haojian Zhuang 2012-05-31 3:07 ` Haojian Zhuang [not found] ` <CAN1soZz2=NcadK1kD6d9t92G6Xdfn=TPGP5_ngwX_fGj+QhOVA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2012-05-31 3:23 ` Chris Ball 2012-05-31 3:23 ` Chris Ball 2012-05-31 21:11 ` Chris Ball 2012-05-31 21:11 ` Chris Ball 2012-04-27 8:39 ` [PATCH 4/9] ARM: mmp: support DT in timer Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang [this message] 2012-04-27 8:39 ` [PATCH 5/9] gpio: pxa: parse gpio from DTS file Haojian Zhuang 2012-04-27 8:39 ` [PATCH 6/9] ARM: mmp: support mmp2 with device tree Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang 2012-04-27 8:39 ` [PATCH 7/9] ARM: mmp: support pxa910 " Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang 2012-04-27 8:39 ` [PATCH 8/9] ARM: dts: refresh dts file for arch mmp Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang 2012-04-27 8:39 ` [PATCH 9/9] Documentation: update docs for mmp dt Haojian Zhuang 2012-04-27 8:39 ` Haojian Zhuang
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1335515957-1798-6-git-send-email-haojian.zhuang@gmail.com \ --to=haojian.zhuang-re5jqeeqqe8avxtiumwx3w@public.gmane.org \ --cc=arnd-r2nGTMty4D4@public.gmane.org \ --cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \ --cc=eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \ --cc=grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org \ --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \ --cc=linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.