* [RFC 00/10] irqchip: meson: add support for the gpio interrupt controller @ 2016-10-04 15:08 Jerome Brunet 2016-10-04 15:08 ` [RFC 06/10] ARM64: meson: enable MESON_IRQ_GPIO in Kconfig Jerome Brunet ` (3 more replies) 0 siblings, 4 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic, linux-arm-kernel, devicetree, linux-gpio This patch series adds support for the GPIO interrupt controller found on Amlogic's meson SoC families. Unlike what the name suggests, this controller is not part of the SoC GPIO subsystem. It's an indepedent controller which can watch almost all pad of the SoC and generate and interrupt from it. Some pins, which are not part of the public datasheet, don't seem to have this capability though. Hardware wise, the controller is a 256 to 8 multiplexer. It can take up to 256 input pads and route them to any of 8 GIC's interrupts. There is also a filter block in the middle to select the appropriate edge or level. The number of interrupt declared by the irqchip is lowered from 256 to the actual number of signal routed to the controller on each SoC family. As we have access to only 8 GIC’s interrupts, these are allocated when an interrupt is requested from the controller, on a first come, first served basis. This series has been tested on Amlogic S905-P200 board with the front panel power button. Directly passing an IRQ or using gpio_to_irq both work with this driver. This work is derived from the previous work of Carlo Caione [1]. http://lkml.kernel.org/r/1448987062-31225-1-git-send-email-carlo@caione.org Note: As the comment will explain, patch 10 is not strictly required but would be an appreciated bonus. Jerome Brunet (10): irqchip: meson: add support for gpio interrupt controller dt-bindings: interrupt-controller: add DT binding for meson GPIO interrupt controller pinctrl: meson: update pinctrl data with gpio irq base number pinctrl: meson: allow gpio to request irq dt-bindings: pinctrl: meson: update gpio dt-bindings ARM64: meson: enable MESON_IRQ_GPIO in Kconfig ARM: meson: enable MESON_IRQ_GPIO in Kconfig for meson8 ARM64: dts: amlogic: enable gpio interrupt controller on gxbb ARM: dts: amlogic: enable gpio interrupt controller on meson8 irqchip: meson: Add support for IRQ_TYPE_EDGE_BOTH .../amlogic,meson-gpio-intc.txt | 39 ++ .../devicetree/bindings/pinctrl/meson,pinctrl.txt | 4 + arch/arm/boot/dts/meson8.dtsi | 19 + arch/arm/boot/dts/meson8b.dtsi | 19 + arch/arm/mach-meson/Kconfig | 2 + arch/arm64/Kconfig.platforms | 1 + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 17 + drivers/irqchip/Kconfig | 9 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-meson-gpio.c | 437 +++++++++++++++++++++ drivers/pinctrl/Kconfig | 2 + drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 22 +- drivers/pinctrl/meson/pinctrl-meson.c | 83 +++- drivers/pinctrl/meson/pinctrl-meson.h | 16 +- drivers/pinctrl/meson/pinctrl-meson8.c | 20 +- drivers/pinctrl/meson/pinctrl-meson8b.c | 32 +- 16 files changed, 686 insertions(+), 37 deletions(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt create mode 100644 drivers/irqchip/irq-meson-gpio.c -- 2.7.4 ^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC 06/10] ARM64: meson: enable MESON_IRQ_GPIO in Kconfig 2016-10-04 15:08 [RFC 00/10] irqchip: meson: add support for the gpio interrupt controller Jerome Brunet @ 2016-10-04 15:08 ` Jerome Brunet 2016-10-04 15:08 ` [RFC 08/10] ARM64: dts: amlogic: enable gpio interrupt controller on gxbb Jerome Brunet ` (2 subsequent siblings) 3 siblings, 0 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic, linux-arm-kernel, devicetree, linux-gpio Add select MESON_IRQ_GPIO in Kconfig for Amlogic's meson SoC family Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> --- arch/arm64/Kconfig.platforms | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index cfbdf02ef566..846479d4492d 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -95,6 +95,7 @@ config ARCH_MESON select PINCTRL_MESON select COMMON_CLK_AMLOGIC select COMMON_CLK_GXBB + select MESON_GPIO_IRQ help This enables support for the Amlogic S905 SoCs. -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC 08/10] ARM64: dts: amlogic: enable gpio interrupt controller on gxbb 2016-10-04 15:08 [RFC 00/10] irqchip: meson: add support for the gpio interrupt controller Jerome Brunet 2016-10-04 15:08 ` [RFC 06/10] ARM64: meson: enable MESON_IRQ_GPIO in Kconfig Jerome Brunet @ 2016-10-04 15:08 ` Jerome Brunet [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> 2016-10-04 15:08 ` [RFC 10/10] irqchip: meson: Add support for IRQ_TYPE_EDGE_BOTH Jerome Brunet 3 siblings, 0 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic, linux-arm-kernel, devicetree, linux-gpio Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> --- arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index 610e0e1c3cee..e5c6372dbe1c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -183,6 +183,21 @@ #reset-cells = <1>; }; + gpio_interrupt: interrupt-controller@9880 { + compatible = "amlogic,gxbb-gpio-intc"; + reg = <0x0 0x9880 0x0 0x10>; + interrupts = <GIC_SPI 64 IRQ_TYPE_NONE>, + <GIC_SPI 65 IRQ_TYPE_NONE>, + <GIC_SPI 66 IRQ_TYPE_NONE>, + <GIC_SPI 67 IRQ_TYPE_NONE>, + <GIC_SPI 68 IRQ_TYPE_NONE>, + <GIC_SPI 69 IRQ_TYPE_NONE>, + <GIC_SPI 70 IRQ_TYPE_NONE>, + <GIC_SPI 71 IRQ_TYPE_NONE>; + interrupt-controller; + #interrupt-cells = <2>; + }; + uart_A: serial@84c0 { compatible = "amlogic,meson-uart"; reg = <0x0 0x84c0 0x0 0x14>; @@ -307,6 +322,7 @@ reg-names = "mux", "pull", "gpio"; gpio-controller; #gpio-cells = <2>; + interrupt-parent = <&gpio_interrupt>; }; uart_ao_a_pins: uart_ao_a { @@ -426,6 +442,7 @@ reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; + interrupt-parent = <&gpio_interrupt>; }; emmc_pins: emmc { -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
[parent not found: <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>]
* [RFC 01/10] irqchip: meson: add support for gpio interrupt controller [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> @ 2016-10-04 15:08 ` Jerome Brunet 2016-10-04 15:08 ` [RFC 02/10] dt-bindings: interrupt-controller: add DT binding for meson GPIO " Jerome Brunet ` (5 subsequent siblings) 6 siblings, 0 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-gpio-u79uwXL29TY76Z2rM5mHXA Add support for the intterrupt gpio controller found on Amlogic's meson SoC family. Unlike what the IP name suggest, it is not directly linked to the gpio subsystem. It is actually an indepedent IP that is able to spy on the SoC pad. For that purpose, it can mux and filter (edge or level and polarity) any single SoC pad to one of the 8 GIC's interrupts it owns. Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> --- drivers/irqchip/Kconfig | 9 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-meson-gpio.c | 398 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 408 insertions(+) create mode 100644 drivers/irqchip/irq-meson-gpio.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 82b0b5daf3f5..168837263e80 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -279,3 +279,12 @@ config EZNPS_GIC config STM32_EXTI bool select IRQ_DOMAIN + +config MESON_GPIO_IRQ + bool "Meson GPIO Interrupt Multiplexer" + depends on ARCH_MESON || COMPILE_TEST + select IRQ_DOMAIN + select IRQ_DOMAIN_HIERARCHY + help + Support Meson SoC Family GPIO Interrupt Multiplexer + diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index e4dbfc85abdb..33f913d037d0 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -74,3 +74,4 @@ obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o +obj-$(CONFIG_MESON_GPIO_IRQ) += irq-meson-gpio.o diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c new file mode 100644 index 000000000000..184025a9cdaf --- /dev/null +++ b/drivers/irqchip/irq-meson-gpio.c @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2015 Endless Mobile, Inc. + * Author: Carlo Caione <carlo-6IF/jdPJHihWk0Htik3J/w@public.gmane.org> + * Copyright (c) 2016 BayLibre, SAS. + * Author: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/irqchip.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> + +#define IRQ_FREE (-1) + +#define REG_EDGE_POL 0x00 +#define REG_PIN_03_SEL 0x04 +#define REG_PIN_47_SEL 0x08 +#define REG_FILTER_SEL 0x0c + +#define REG_EDGE_POL_MASK(x) (BIT(x) | BIT(16 + (x))) +#define REG_EDGE_POL_EDGE(x) BIT(x) +#define REG_EDGE_POL_LOW(x) BIT(16 + (x)) +#define REG_PIN_SEL_SHIFT(x) (((x) % 4) * 8) +#define REG_FILTER_SEL_SHIFT(x) ((x) * 4) + +struct meson_gpio_irq_params { + unsigned int nr_hwirqs; +}; + +struct meson_gpio_irq_domain { + struct irq_fwspec *parent_irqs; + void __iomem *base; + int nr_parent_irqs; + int *irq_map; +}; + +struct meson_gpio_irq_chip { + void __iomem *base; + int index; +}; + +static const struct meson_gpio_irq_params meson8_params = { + .nr_hwirqs = 134, +}; + +static const struct meson_gpio_irq_params meson8b_params = { + .nr_hwirqs = 119, +}; + +static const struct meson_gpio_irq_params gxbb_params = { + .nr_hwirqs = 133, +}; + +static const struct of_device_id meson_irq_gpio_matches[] = { + { .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params }, + { .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params }, + { .compatible = "amlogic,gxbb-gpio-intc", .data = &gxbb_params }, + { } +}; + +static void meson_gpio_irq_update_bits(void __iomem *base, unsigned int reg, + u32 mask, u32 val) +{ + u32 tmp; + + tmp = readl(base + reg); + tmp &= ~mask; + tmp |= val; + + writel(tmp, base + reg); +} + +static int meson_gpio_irq_get_index(struct meson_gpio_irq_domain *domain_data, + int hwirq) +{ + int i; + + for (i = 0; i < domain_data->nr_parent_irqs; i++) { + if (domain_data->irq_map[i] == hwirq) + return i; + } + + return -1; +} + +static int meson_gpio_irq_map_pirq(struct meson_gpio_irq_domain *domain_data, + irq_hw_number_t hwirq) +{ + int index; + unsigned int reg; + + index = meson_gpio_irq_get_index(domain_data, IRQ_FREE); + if (index < 0) { + pr_err("No irq available\n"); + return -ENOSPC; + } + + domain_data->irq_map[index] = hwirq; + + reg = (index < 4) ? REG_PIN_03_SEL : REG_PIN_47_SEL; + meson_gpio_irq_update_bits(domain_data->base, reg, + 0xff << REG_PIN_SEL_SHIFT(index), + hwirq << REG_PIN_SEL_SHIFT(index)); + + pr_debug("hwirq %d assigned to channel %d\n", (int)hwirq, index); + + return index; +} + +static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type) +{ + struct meson_gpio_irq_chip *cd = irq_data_get_irq_chip_data(data); + u32 val = 0; + + pr_debug("set type of hwirq %lu to %u\n", data->hwirq, type); + + if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) + return -EINVAL; + + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) + val |= REG_EDGE_POL_EDGE(cd->index); + + if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) { + val |= REG_EDGE_POL_LOW(cd->index); + + /* + * According to the datasheet, the polarity block invert the + * signal on the path to parent interrupt + */ + if (type & IRQ_TYPE_LEVEL_LOW) + type = (type & ~IRQ_TYPE_LEVEL_LOW) + | IRQ_TYPE_LEVEL_HIGH; + else + type = (type & ~IRQ_TYPE_EDGE_FALLING) + | IRQ_TYPE_EDGE_RISING; + } + + meson_gpio_irq_update_bits(cd->base, REG_EDGE_POL, + REG_EDGE_POL_MASK(cd->index), val); + + return irq_chip_set_type_parent(data, type); +} + +static struct irq_chip meson_gpio_irq_chip = { + .name = "meson-gpio-irqchip", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_type = meson_gpio_irq_set_type, + .irq_retrigger = irq_chip_retrigger_hierarchy, +#ifdef CONFIG_SMP + .irq_set_affinity = irq_chip_set_affinity_parent, +#endif +}; + +static int meson_gpio_irq_domain_translate(struct irq_domain *domain, + struct irq_fwspec *fwspec, + unsigned long *hwirq, + unsigned int *type) +{ + if (is_of_node(fwspec->fwnode)) { + if (fwspec->param_count != 2) + return -EINVAL; + + *hwirq = fwspec->param[0]; + *type = fwspec->param[1]; + + return 0; + } + + return -EINVAL; +} + +static int meson_gpio_irq_domain_alloc(struct irq_domain *domain, + unsigned int virq, + unsigned int nr_irqs, + void *data) +{ + struct irq_fwspec *fwspec_parent, *fwspec = data; + struct meson_gpio_irq_domain *domain_data = domain->host_data; + struct meson_gpio_irq_chip *cd; + unsigned long hwirq; + unsigned int type; + int i, index, ret; + + ret = meson_gpio_irq_domain_translate(domain, fwspec, &hwirq, &type); + if (ret) + return ret; + + pr_debug("irq %d, nr_irqs %d, hwirqs %lu\n", virq, nr_irqs, hwirq); + + for (i = 0; i < nr_irqs; i++) { + index = meson_gpio_irq_map_pirq(domain_data, hwirq + i); + if (index < 0) + return index; + + cd = kzalloc(sizeof(*cd), GFP_KERNEL); + if (!cd) + return -ENOMEM; + + cd->base = domain_data->base; + cd->index = index; + fwspec_parent = &domain_data->parent_irqs[index]; + + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &meson_gpio_irq_chip, + cd); + + ret = irq_domain_alloc_irqs_parent(domain, virq + i, 1, + fwspec_parent); + if (ret < 0) + return ret; + } + + return 0; +} + +static void meson_gpio_irq_domain_free(struct irq_domain *domain, + unsigned int virq, + unsigned int nr_irqs) +{ + struct meson_gpio_irq_domain *domain_data = domain->host_data; + struct meson_gpio_irq_chip *cd; + struct irq_data *irq_data; + int i; + + for (i = 0; i < nr_irqs; i++) { + irq_data = irq_domain_get_irq_data(domain, virq + i); + cd = irq_data_get_irq_chip_data(irq_data); + + domain_data->irq_map[cd->index] = IRQ_FREE; + kfree(cd); + } + + irq_domain_free_irqs_parent(domain, virq, nr_irqs); +} + + +static const struct irq_domain_ops meson_gpio_irq_domain_ops = { + .alloc = meson_gpio_irq_domain_alloc, + .free = meson_gpio_irq_domain_free, + .translate = meson_gpio_irq_domain_translate, +}; + + +static int __init meson_gpio_irq_get_one_pirq(struct device_node *node, + int index, + struct irq_fwspec *pirq) +{ + int ret, i; + struct of_phandle_args oirq; + + ret = of_irq_parse_one(node, index, &oirq); + if (ret < 0) + return ret; + + pirq->fwnode = of_node_to_fwnode(oirq.np); + + if (!pirq->fwnode) { + pr_err("can't get interrupt fwnode\n"); + return -ENODEV; + } + + pirq->param_count = oirq.args_count; + for (i = 0; i < oirq.args_count; i++) + pirq->param[i] = oirq.args[i]; + + return 0; +} + + +static int __init +meson_gpio_irq_init_domain(struct device_node *node, + struct meson_gpio_irq_domain *domain_data) +{ + int ret, i, n_pirqs; + int *map; + struct irq_fwspec *pirqs; + + n_pirqs = of_irq_count(node); + if (n_pirqs == 0) { + pr_err("missing parent interrupts\n"); + return -ENODEV; + } + + pirqs = kcalloc(n_pirqs, sizeof(*pirqs), GFP_KERNEL); + if (!pirqs) + return -ENOMEM; + + map = kcalloc(n_pirqs, sizeof(*map), GFP_KERNEL); + if (!map) + return -ENOMEM; + + for (i = 0; i < n_pirqs; i++) { + map[i] = IRQ_FREE; + ret = meson_gpio_irq_get_one_pirq(node, i, &pirqs[i]); + if (ret < 0) + return ret; + } + + domain_data->nr_parent_irqs = n_pirqs; + domain_data->parent_irqs = pirqs; + domain_data->irq_map = map; + + return 0; +} + +static int __init meson_gpio_irq_of_init(struct device_node *node, + struct device_node *parent) +{ + struct irq_domain *domain, *parent_domain; + const struct of_device_id *match; + const struct meson_gpio_irq_params *params; + struct meson_gpio_irq_domain *domain_data; + int ret; + + match = of_match_node(meson_irq_gpio_matches, node); + if (!match) + return -ENODEV; + params = match->data; + + if (!parent) { + pr_err("missing parent interrupt node\n"); + return -ENODEV; + } + + parent_domain = irq_find_host(parent); + if (!parent_domain) { + pr_err("unable to obtain parent domain\n"); + return -ENXIO; + } + + domain_data = kzalloc(sizeof(*domain_data), GFP_KERNEL); + if (!domain_data) + return -ENOMEM; + + domain_data->base = of_iomap(node, 0); + if (!domain_data->base) { + ret = -ENOMEM; + goto out_free_dev; + } + + ret = meson_gpio_irq_init_domain(node, domain_data); + if (ret < 0) + goto out_free_dev_content; + + domain = irq_domain_add_hierarchy(parent_domain, 0, params->nr_hwirqs, + node, &meson_gpio_irq_domain_ops, + domain_data); + + if (!domain) { + pr_err("failed to allocated domain\n"); + ret = -ENOMEM; + goto out_free_dev_content; + } + + pr_info("%d to %d gpio interrupt mux initialized\n", + params->nr_hwirqs, domain_data->nr_parent_irqs); + + return 0; + +out_free_dev_content: + kfree(domain_data->parent_irqs); + kfree(domain_data->irq_map); + iounmap(domain_data->base); + +out_free_dev: + kfree(domain_data); + + return ret; +} +IRQCHIP_DECLARE(meson8_gpio_intc, "amlogic,meson8-gpio-intc", + meson_gpio_irq_of_init); +IRQCHIP_DECLARE(meson8b_gpio_intc, "amlogic,meson8b-gpio-intc", + meson_gpio_irq_of_init); +IRQCHIP_DECLARE(gxbb_gpio_intc, "amlogic,gxbb-gpio-intc", + meson_gpio_irq_of_init); -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC 02/10] dt-bindings: interrupt-controller: add DT binding for meson GPIO interrupt controller [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> 2016-10-04 15:08 ` [RFC 01/10] irqchip: meson: add support for gpio interrupt controller Jerome Brunet @ 2016-10-04 15:08 ` Jerome Brunet 2016-10-09 1:29 ` Rob Herring 2016-10-04 15:08 ` [RFC 03/10] pinctrl: meson: update pinctrl data with gpio irq base number Jerome Brunet ` (4 subsequent siblings) 6 siblings, 1 reply; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-gpio-u79uwXL29TY76Z2rM5mHXA This commit adds the device tree bindings description for Amlogic's GPIO interrupt controller available on the meson8, meson8b and gxbb SoC families Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> --- .../amlogic,meson-gpio-intc.txt | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt new file mode 100644 index 000000000000..bd4cceefcda1 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt @@ -0,0 +1,39 @@ +Amlogic meson GPIO interrupt controller + +Meson SoCs contains an interrupt controller which is able watch the SoC pads +and generate an interrupt on edges or level. The controller is essentially a +256 pads to 8 GIC interrupt multiplexer, with a filter block to select edge +or level and polarity. We don’t expose all 256 mux inputs because the +documentation shows that upper part is not mapped to any pad. The actual number +of interrupt exposed depends on the SoC. + +Required properties: + +- compatible : should be: "amlogic,meson8-gpio-intc” or + “amlogic,meson8b-gpio-intc” or “amlogic,gxbb-gpio-intc” +- interrupts : List of the GIC’s interrupts used as parent interrupts. + There should 8 of these interrupts. +- interrupt-parent : a phandle to the GIC the interrupts are routed to. + Usually this is provided at the root level of the device tree as it is + common to most of the SoC +- reg : Specifies base physical address and size of the registers. +- interrupt-controller : Identifies the node as an interrupt controller. +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value must be 2. + +Exemple: + +gpio_interrupt: interrupt-controller@9880 { + compatible = "amlogic,gxbb-gpio-intc"; + reg = <0x0 0x9880 0x0 0x10>; + interrupts = <GIC_SPI 64 IRQ_TYPE_NONE>, + <GIC_SPI 65 IRQ_TYPE_NONE>, + <GIC_SPI 66 IRQ_TYPE_NONE>, + <GIC_SPI 67 IRQ_TYPE_NONE>, + <GIC_SPI 68 IRQ_TYPE_NONE>, + <GIC_SPI 69 IRQ_TYPE_NONE>, + <GIC_SPI 70 IRQ_TYPE_NONE>, + <GIC_SPI 71 IRQ_TYPE_NONE>; + interrupt-controller; + #interrupt-cells = <2>; +}; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC 02/10] dt-bindings: interrupt-controller: add DT binding for meson GPIO interrupt controller 2016-10-04 15:08 ` [RFC 02/10] dt-bindings: interrupt-controller: add DT binding for meson GPIO " Jerome Brunet @ 2016-10-09 1:29 ` Rob Herring 2016-10-10 8:11 ` Jerome Brunet 0 siblings, 1 reply; 14+ messages in thread From: Rob Herring @ 2016-10-09 1:29 UTC (permalink / raw) To: Jerome Brunet Cc: devicetree, Jason Cooper, Marc Zyngier, Kevin Hilman, linux-gpio, Carlo Caione, linux-amlogic, Thomas Gleixner, linux-arm-kernel On Tue, Oct 04, 2016 at 05:08:20PM +0200, Jerome Brunet wrote: > This commit adds the device tree bindings description for Amlogic's GPIO > interrupt controller available on the meson8, meson8b and gxbb SoC families > > Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> > --- > .../amlogic,meson-gpio-intc.txt | 39 ++++++++++++++++++++++ > 1 file changed, 39 insertions(+) > create mode 100644 Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt > > diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt > new file mode 100644 > index 000000000000..bd4cceefcda1 > --- /dev/null > +++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt > @@ -0,0 +1,39 @@ > +Amlogic meson GPIO interrupt controller > + > +Meson SoCs contains an interrupt controller which is able watch the SoC pads > +and generate an interrupt on edges or level. The controller is essentially a > +256 pads to 8 GIC interrupt multiplexer, with a filter block to select edge > +or level and polarity. We don’t expose all 256 mux inputs because the > +documentation shows that upper part is not mapped to any pad. The actual number > +of interrupt exposed depends on the SoC. > + > +Required properties: > + > +- compatible : should be: "amlogic,meson8-gpio-intc” or > + “amlogic,meson8b-gpio-intc” or “amlogic,gxbb-gpio-intc” One per line please if you respin the series. Acked-by: Rob Herring <robh@kernel.org> _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC 02/10] dt-bindings: interrupt-controller: add DT binding for meson GPIO interrupt controller 2016-10-09 1:29 ` Rob Herring @ 2016-10-10 8:11 ` Jerome Brunet 0 siblings, 0 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-10 8:11 UTC (permalink / raw) To: Rob Herring Cc: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-gpio-u79uwXL29TY76Z2rM5mHXA On Sat, 2016-10-08 at 20:29 -0500, Rob Herring wrote: > On Tue, Oct 04, 2016 at 05:08:20PM +0200, Jerome Brunet wrote: > > > > This commit adds the device tree bindings description for Amlogic's > > GPIO > > interrupt controller available on the meson8, meson8b and gxbb SoC > > families > > > > Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> > > --- > > .../amlogic,meson-gpio-intc.txt | 39 > > ++++++++++++++++++++++ > > 1 file changed, 39 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/interrupt- > > controller/amlogic,meson-gpio-intc.txt > > > > diff --git a/Documentation/devicetree/bindings/interrupt- > > controller/amlogic,meson-gpio-intc.txt > > b/Documentation/devicetree/bindings/interrupt- > > controller/amlogic,meson-gpio-intc.txt > > new file mode 100644 > > index 000000000000..bd4cceefcda1 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/interrupt- > > controller/amlogic,meson-gpio-intc.txt > > @@ -0,0 +1,39 @@ > > +Amlogic meson GPIO interrupt controller > > + > > +Meson SoCs contains an interrupt controller which is able watch > > the SoC pads > > +and generate an interrupt on edges or level. The controller is > > essentially a > > +256 pads to 8 GIC interrupt multiplexer, with a filter block to > > select edge > > +or level and polarity. We don’t expose all 256 mux inputs because > > the > > +documentation shows that upper part is not mapped to any pad. The > > actual number > > +of interrupt exposed depends on the SoC. > > + > > +Required properties: > > + > > +- compatible : should be: "amlogic,meson8-gpio-intc” or > > + “amlogic,meson8b-gpio-intc” or “amlogic,gxbb-gpio-intc” > > One per line please if you respin the series. Got it. There will be a respin for sure. Thx Rob > > Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC 03/10] pinctrl: meson: update pinctrl data with gpio irq base number [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> 2016-10-04 15:08 ` [RFC 01/10] irqchip: meson: add support for gpio interrupt controller Jerome Brunet 2016-10-04 15:08 ` [RFC 02/10] dt-bindings: interrupt-controller: add DT binding for meson GPIO " Jerome Brunet @ 2016-10-04 15:08 ` Jerome Brunet 2016-10-04 15:08 ` [RFC 04/10] pinctrl: meson: allow gpio to request irq Jerome Brunet ` (3 subsequent siblings) 6 siblings, 0 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-gpio-u79uwXL29TY76Z2rM5mHXA This patch extends meson's pinctrl SoC specific data by adding the gpio irq base number. This will allow gpios to request an interrupt on the gpio interrupt controller using this base irq number the pin offset in bank Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> --- drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 22 ++++++++++---------- drivers/pinctrl/meson/pinctrl-meson.h | 15 +++++++++----- drivers/pinctrl/meson/pinctrl-meson8.c | 20 +++++++++---------- drivers/pinctrl/meson/pinctrl-meson8b.c | 32 ++++++++++++++++++++---------- 4 files changed, 53 insertions(+), 36 deletions(-) diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c index c3928aa3fefa..29b66684b287 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c @@ -715,20 +715,20 @@ static struct meson_pmx_func meson_gxbb_aobus_functions[] = { }; static struct meson_bank meson_gxbb_periphs_banks[] = { - /* name first last pullen pull dir out in */ - BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_22, EE_OFF), 4, 0, 4, 0, 12, 0, 13, 0, 14, 0), - BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_16, EE_OFF), 1, 0, 1, 0, 3, 0, 4, 0, 5, 0), - BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 0, 0, 0, 0, 0, 0, 1, 0, 2, 0), - BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_3, EE_OFF), 1, 20, 1, 20, 3, 20, 4, 20, 5, 20), - BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 3, 0, 3, 0, 9, 0, 10, 0, 11, 0), - BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 2, 20, 2, 20, 6, 20, 7, 20, 8, 20), - BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_17, EE_OFF), 2, 0, 2, 0, 6, 0, 7, 0, 8, 0), - BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_3, EE_OFF), 3, 28, 3, 28, 9, 28, 10, 28, 11, 28), + /* name first last irq pullen pull dir out in */ + BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_22, EE_OFF), 106, 128, 4, 0, 4, 0, 12, 0, 13, 0, 14, 0), + BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_16, EE_OFF), 89, 105, 1, 0, 1, 0, 3, 0, 4, 0, 5, 0), + BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 59, 88, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0), + BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_3, EE_OFF), 30, 33, 1, 20, 1, 20, 3, 20, 4, 20, 5, 20), + BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 14, 29, 3, 0, 3, 0, 9, 0, 10, 0, 11, 0), + BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 52, 58, 2, 20, 2, 20, 6, 20, 7, 20, 8, 20), + BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_17, EE_OFF), 34, 51, 2, 0, 2, 0, 6, 0, 7, 0, 8, 0), + BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_3, EE_OFF), 129, 132, 3, 28, 3, 28, 9, 28, 10, 28, 11, 28), }; static struct meson_bank meson_gxbb_aobus_banks[] = { - /* name first last pullen pull dir out in */ - BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0), + /* name first last irq pullen pull dir out in */ + BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0), 0, 13, 0, 0, 0, 16, 0, 0, 0, 16, 1, 0), }; struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = { diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index 98b5080650c1..785705996e60 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -81,6 +81,7 @@ enum meson_reg_type { * @name: bank name * @first: first pin of the bank * @last: last pin of the bank + * @irq: hwirq base number of the bank * @regs: array of register descriptors * * A bank represents a set of pins controlled by a contiguous set of @@ -92,6 +93,8 @@ struct meson_bank { const char *name; unsigned int first; unsigned int last; + int irq_first; + int irq_last; struct meson_reg_desc regs[NUM_REG]; }; @@ -147,12 +150,14 @@ struct meson_pinctrl { .num_groups = ARRAY_SIZE(fn ## _groups), \ } -#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \ +#define BANK(n, f, l, fi, li, per, peb, pr, pb, dr, db, or, ob, ir, ib) \ { \ - .name = n, \ - .first = f, \ - .last = l, \ - .regs = { \ + .name = n, \ + .first = f, \ + .last = l, \ + .irq_first = fi, \ + .irq_last = li, \ + .regs = { \ [REG_PULLEN] = { per, peb }, \ [REG_PULL] = { pr, pb }, \ [REG_DIR] = { dr, db }, \ diff --git a/drivers/pinctrl/meson/pinctrl-meson8.c b/drivers/pinctrl/meson/pinctrl-meson8.c index 07f1cb21c1b8..32449820f455 100644 --- a/drivers/pinctrl/meson/pinctrl-meson8.c +++ b/drivers/pinctrl/meson/pinctrl-meson8.c @@ -916,19 +916,19 @@ static struct meson_pmx_func meson8_aobus_functions[] = { }; static struct meson_bank meson8_cbus_banks[] = { - /* name first last pullen pull dir out in */ - BANK("X", PIN(GPIOX_0, 0), PIN(GPIOX_21, 0), 4, 0, 4, 0, 0, 0, 1, 0, 2, 0), - BANK("Y", PIN(GPIOY_0, 0), PIN(GPIOY_16, 0), 3, 0, 3, 0, 3, 0, 4, 0, 5, 0), - BANK("DV", PIN(GPIODV_0, 0), PIN(GPIODV_29, 0), 0, 0, 0, 0, 7, 0, 8, 0, 9, 0), - BANK("H", PIN(GPIOH_0, 0), PIN(GPIOH_9, 0), 1, 16, 1, 16, 9, 19, 10, 19, 11, 19), - BANK("Z", PIN(GPIOZ_0, 0), PIN(GPIOZ_14, 0), 1, 0, 1, 0, 3, 17, 4, 17, 5, 17), - BANK("CARD", PIN(CARD_0, 0), PIN(CARD_6, 0), 2, 20, 2, 20, 0, 22, 1, 22, 2, 22), - BANK("BOOT", PIN(BOOT_0, 0), PIN(BOOT_18, 0), 2, 0, 2, 0, 9, 0, 10, 0, 11, 0), + /* name first last irq pullen pull dir out in */ + BANK("X", PIN(GPIOX_0, 0), PIN(GPIOX_21, 0), 112, 133, 4, 0, 4, 0, 0, 0, 1, 0, 2, 0), + BANK("Y", PIN(GPIOY_0, 0), PIN(GPIOY_16, 0), 95, 111, 3, 0, 3, 0, 3, 0, 4, 0, 5, 0), + BANK("DV", PIN(GPIODV_0, 0), PIN(GPIODV_29, 0), 65, 94, 0, 0, 0, 0, 7, 0, 8, 0, 9, 0), + BANK("H", PIN(GPIOH_0, 0), PIN(GPIOH_9, 0), 29, 38, 1, 16, 1, 16, 9, 19, 10, 19, 11, 19), + BANK("Z", PIN(GPIOZ_0, 0), PIN(GPIOZ_14, 0), 14, 28, 1, 0, 1, 0, 3, 17, 4, 17, 5, 17), + BANK("CARD", PIN(CARD_0, 0), PIN(CARD_6, 0), 58, 64, 2, 20, 2, 20, 0, 22, 1, 22, 2, 22), + BANK("BOOT", PIN(BOOT_0, 0), PIN(BOOT_18, 0), 39, 57, 2, 0, 2, 0, 9, 0, 10, 0, 11, 0), }; static struct meson_bank meson8_aobus_banks[] = { - /* name first last pullen pull dir out in */ - BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0), + /* name first last irq pullen pull dir out in */ + BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 13, 0, 0, 0, 16, 0, 0, 0, 16, 1, 0), }; struct meson_pinctrl_data meson8_cbus_pinctrl_data = { diff --git a/drivers/pinctrl/meson/pinctrl-meson8b.c b/drivers/pinctrl/meson/pinctrl-meson8b.c index 76f077f18193..9242888fea5f 100644 --- a/drivers/pinctrl/meson/pinctrl-meson8b.c +++ b/drivers/pinctrl/meson/pinctrl-meson8b.c @@ -124,6 +124,12 @@ static const struct pinctrl_pin_desc meson8b_aobus_pins[] = { MESON_PIN(GPIOAO_11, AO_OFF), MESON_PIN(GPIOAO_12, AO_OFF), MESON_PIN(GPIOAO_13, AO_OFF), + + /* + * The following 2 pins are not mentionned in the public datasheet + * According to this datasheet, they can't be used with the gpio + * interrupt controller + */ MESON_PIN(GPIO_BSD_EN, AO_OFF), MESON_PIN(GPIO_TEST_N, AO_OFF), }; @@ -881,19 +887,25 @@ static struct meson_pmx_func meson8b_aobus_functions[] = { }; static struct meson_bank meson8b_cbus_banks[] = { - /* name first last pullen pull dir out in */ - BANK("X", PIN(GPIOX_0, 0), PIN(GPIOX_21, 0), 4, 0, 4, 0, 0, 0, 1, 0, 2, 0), - BANK("Y", PIN(GPIOY_0, 0), PIN(GPIOY_14, 0), 3, 0, 3, 0, 3, 0, 4, 0, 5, 0), - BANK("DV", PIN(GPIODV_9, 0), PIN(GPIODV_29, 0), 0, 0, 0, 0, 7, 0, 8, 0, 9, 0), - BANK("H", PIN(GPIOH_0, 0), PIN(GPIOH_9, 0), 1, 16, 1, 16, 9, 19, 10, 19, 11, 19), - BANK("CARD", PIN(CARD_0, 0), PIN(CARD_6, 0), 2, 20, 2, 20, 0, 22, 1, 22, 2, 22), - BANK("BOOT", PIN(BOOT_0, 0), PIN(BOOT_18, 0), 2, 0, 2, 0, 9, 0, 10, 0, 11, 0), - BANK("DIF", PIN(DIF_0_P, 0), PIN(DIF_4_N, 0), 5, 8, 5, 8, 12, 12, 13, 12, 14, 12), + /* name first last irq pullen pull dir out in */ + BANK("X", PIN(GPIOX_0, 0), PIN(GPIOX_21, 0), 97, 118, 4, 0, 4, 0, 0, 0, 1, 0, 2, 0), + BANK("Y", PIN(GPIOY_0, 0), PIN(GPIOY_14, 0), 80, 96, 3, 0, 3, 0, 3, 0, 4, 0, 5, 0), + BANK("DV", PIN(GPIODV_9, 0), PIN(GPIODV_29, 0), 59, 79, 0, 0, 0, 0, 7, 0, 8, 0, 9, 0), + BANK("H", PIN(GPIOH_0, 0), PIN(GPIOH_9, 0), 14, 23, 1, 16, 1, 16, 9, 19, 10, 19, 11, 19), + BANK("CARD", PIN(CARD_0, 0), PIN(CARD_6, 0), 43, 49, 2, 20, 2, 20, 0, 22, 1, 22, 2, 22), + BANK("BOOT", PIN(BOOT_0, 0), PIN(BOOT_18, 0), 24, 42, 2, 0, 2, 0, 9, 0, 10, 0, 11, 0), + + /* + * The following bank is not mentionned in the public datasheet + * There is no information whether it can be used with the gpio + * interrupt controller + */ + BANK("DIF", PIN(DIF_0_P, 0), PIN(DIF_4_N, 0), -1, -1, 5, 8, 5, 8, 12, 12, 13, 12, 14, 12), }; static struct meson_bank meson8b_aobus_banks[] = { - /* name first last pullen pull dir out in */ - BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0), + /* name first last irq pullen pull dir out in */ + BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 13, 0, 0, 0, 16, 0, 0, 0, 16, 1, 0), }; struct meson_pinctrl_data meson8b_cbus_pinctrl_data = { -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC 04/10] pinctrl: meson: allow gpio to request irq [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> ` (2 preceding siblings ...) 2016-10-04 15:08 ` [RFC 03/10] pinctrl: meson: update pinctrl data with gpio irq base number Jerome Brunet @ 2016-10-04 15:08 ` Jerome Brunet 2016-10-04 15:08 ` [RFC 05/10] dt-bindings: pinctrl: meson: update gpio dt-bindings Jerome Brunet ` (2 subsequent siblings) 6 siblings, 0 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-gpio-u79uwXL29TY76Z2rM5mHXA Add the ability for gpio to request irq from the gpio interrupt controller if present. We have to specificaly that the parent interrupt controller is the gpio interrupt controller because gpio on meson SoCs can't generate interrupt directly on the GIC. Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> --- drivers/pinctrl/Kconfig | 2 + drivers/pinctrl/meson/pinctrl-meson.c | 83 ++++++++++++++++++++++++++++++++++- drivers/pinctrl/meson/pinctrl-meson.h | 1 + 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 0e75d94972ba..d5bfbfcddab0 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -126,7 +126,9 @@ config PINCTRL_MESON select PINCONF select GENERIC_PINCONF select GPIOLIB + select IRQ_DOMAIN select OF_GPIO + select OF_IRQ select REGMAP_MMIO config PINCTRL_OXNAS diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 57122eda155a..f9be3ff5e11d 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -50,6 +50,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/pinctrl/pinconf-generic.h> #include <linux/pinctrl/pinconf.h> #include <linux/pinctrl/pinctrl.h> @@ -481,6 +482,58 @@ static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value) value ? BIT(bit) : 0); } +static int meson_gpio_to_hwirq(struct meson_bank *bank, unsigned int offset) +{ + unsigned int hwirq; + + if (bank->irq_first < 0) + /* this bank cannot generate irqs */ + return -1; + + hwirq = offset - bank->first + bank->irq_first; + + if (hwirq > bank->irq_last) + /* this pin cannot generate irqs */ + return -1; + + return hwirq; +} + +static int meson_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) +{ + struct meson_pinctrl *pc = gpiochip_get_data(chip); + struct meson_bank *bank; + struct irq_fwspec fwspec; + unsigned int hwirq; + int ret; + + ret = meson_get_bank(pc, offset, &bank); + if (ret) + return ret; + + /* + * The interrupt controller might be missing, in such case we can't + * provide an interrupt for a pin + */ + if (is_fwnode_irqchip(pc->fwnode)) { + dev_info(pc->dev, "interrupt controller not found\n"); + return 0; + } + + hwirq = meson_gpio_to_hwirq(bank, offset); + if (hwirq < 0) { + dev_dbg(pc->dev, "no interrupt for pin %u\n", offset); + return 0; + } + + fwspec.fwnode = pc->fwnode; + fwspec.param_count = 2; + fwspec.param[0] = hwirq; + fwspec.param[1] = IRQ_TYPE_NONE; + + return irq_create_fwspec_mapping(&fwspec); +} + static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio) { struct meson_pinctrl *pc = gpiochip_get_data(chip); @@ -539,6 +592,7 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc) pc->chip.direction_output = meson_gpio_direction_output; pc->chip.get = meson_gpio_get; pc->chip.set = meson_gpio_set; + pc->chip.to_irq = meson_gpio_to_irq; pc->chip.base = pc->data->pin_base; pc->chip.ngpio = pc->data->num_pins; pc->chip.can_sleep = false; @@ -598,6 +652,33 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc, return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config); } +static int meson_pinctrl_get_irq_gpio_intc(struct meson_pinctrl *pc, + struct device_node *node) +{ + struct device_node *np; + + /* + * Make sure gpio don't request IRQ directly to the GIC + * TODO: Find a better way to make sure we have a compatible + * Interrupt controller here + */ + if (!of_get_property(node, "interrupt-parent", NULL)) { + dev_dbg(pc->dev, "interrupt controller not found\n"); + pc->fwnode = NULL; + return 0; + } + + np = of_irq_find_parent(node); + if (!np) { + dev_err(pc->dev, "irq parent not found\n"); + return -EINVAL; + } + + pc->fwnode = of_node_to_fwnode(np); + + return 0; +} + static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc, struct device_node *node) { @@ -643,7 +724,7 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc, return PTR_ERR(pc->reg_gpio); } - return 0; + return meson_pinctrl_get_irq_gpio_intc(pc, gpio_np); } static int meson_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index 785705996e60..4bcc4900b3eb 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -122,6 +122,7 @@ struct meson_pinctrl { struct regmap *reg_gpio; struct gpio_chip chip; struct device_node *of_node; + struct fwnode_handle *fwnode; }; #define PIN(x, b) (b + x) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC 05/10] dt-bindings: pinctrl: meson: update gpio dt-bindings [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> ` (3 preceding siblings ...) 2016-10-04 15:08 ` [RFC 04/10] pinctrl: meson: allow gpio to request irq Jerome Brunet @ 2016-10-04 15:08 ` Jerome Brunet [not found] ` <1475593708-10526-6-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> 2016-10-04 15:08 ` [RFC 07/10] ARM: meson: enable MESON_IRQ_GPIO in Kconfig for meson8 Jerome Brunet 2016-10-04 15:08 ` [RFC 09/10] ARM: dts: amlogic: enable gpio interrupt controller on meson8 Jerome Brunet 6 siblings, 1 reply; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-gpio-u79uwXL29TY76Z2rM5mHXA Add description for the interrupt-parent property of the gpio sub-node If provided here, this property must be a phandle to an interrupt controller suitable for meson pinctrl, like the meson gpio interrupt controller. Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> --- Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt index fe7fe0b03cfb..39932c4dfb32 100644 --- a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt @@ -23,6 +23,10 @@ Required properties for sub-nodes are: - gpio-controller: identifies the node as a gpio controller - #gpio-cells: must be 2 +Optional property for sub-nodes is: + - interrupt-parent: must be a phandle to the meson gpio interrupt controller. + if this property is provided, enables gpio ability to generate interrupts + === Other sub-nodes === Child nodes without the "gpio-controller" represent some desired -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 14+ messages in thread
[parent not found: <1475593708-10526-6-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>]
* Re: [RFC 05/10] dt-bindings: pinctrl: meson: update gpio dt-bindings [not found] ` <1475593708-10526-6-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> @ 2016-10-09 1:29 ` Rob Herring 0 siblings, 0 replies; 14+ messages in thread From: Rob Herring @ 2016-10-09 1:29 UTC (permalink / raw) To: Jerome Brunet Cc: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-gpio-u79uwXL29TY76Z2rM5mHXA On Tue, Oct 04, 2016 at 05:08:23PM +0200, Jerome Brunet wrote: > Add description for the interrupt-parent property of the gpio sub-node > If provided here, this property must be a phandle to an interrupt > controller suitable for meson pinctrl, like the meson gpio interrupt > controller. > > Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> > --- > Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt | 4 ++++ > 1 file changed, 4 insertions(+) Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC 07/10] ARM: meson: enable MESON_IRQ_GPIO in Kconfig for meson8 [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> ` (4 preceding siblings ...) 2016-10-04 15:08 ` [RFC 05/10] dt-bindings: pinctrl: meson: update gpio dt-bindings Jerome Brunet @ 2016-10-04 15:08 ` Jerome Brunet 2016-10-04 15:08 ` [RFC 09/10] ARM: dts: amlogic: enable gpio interrupt controller on meson8 Jerome Brunet 6 siblings, 0 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-gpio-u79uwXL29TY76Z2rM5mHXA Add select MESON_IRQ_GPIO in Kconfig for Amlogic's meson8 and meson8b SoC Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> --- arch/arm/mach-meson/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig index b6e3acc63e14..63157295cd9d 100644 --- a/arch/arm/mach-meson/Kconfig +++ b/arch/arm/mach-meson/Kconfig @@ -21,11 +21,13 @@ config MACH_MESON8 bool "Amlogic Meson8 SoCs support" default ARCH_MESON select MESON6_TIMER + select MESON_IRQ_GPIO config MACH_MESON8B bool "Amlogic Meson8b SoCs support" default ARCH_MESON select MESON6_TIMER select COMMON_CLK_MESON8B + select MESON_IRQ_GPIO endif -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC 09/10] ARM: dts: amlogic: enable gpio interrupt controller on meson8 [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> ` (5 preceding siblings ...) 2016-10-04 15:08 ` [RFC 07/10] ARM: meson: enable MESON_IRQ_GPIO in Kconfig for meson8 Jerome Brunet @ 2016-10-04 15:08 ` Jerome Brunet 6 siblings, 0 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-gpio-u79uwXL29TY76Z2rM5mHXA Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> --- arch/arm/boot/dts/meson8.dtsi | 19 +++++++++++++++++++ arch/arm/boot/dts/meson8b.dtsi | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi index 45619f6162c5..82690e0352c9 100644 --- a/arch/arm/boot/dts/meson8.dtsi +++ b/arch/arm/boot/dts/meson8.dtsi @@ -43,6 +43,8 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/gpio/meson8-gpio.h> /include/ "meson.dtsi" @@ -91,6 +93,21 @@ clock-frequency = <141666666>; }; + gpio_interrupt: interrupt-controller@c1109880 { + compatible = "amlogic,meson8-gpio-intc"; + reg = <0xc1109880 0x10>; + interrupts = <GIC_SPI 64 IRQ_TYPE_NONE>, + <GIC_SPI 65 IRQ_TYPE_NONE>, + <GIC_SPI 66 IRQ_TYPE_NONE>, + <GIC_SPI 67 IRQ_TYPE_NONE>, + <GIC_SPI 68 IRQ_TYPE_NONE>, + <GIC_SPI 69 IRQ_TYPE_NONE>, + <GIC_SPI 70 IRQ_TYPE_NONE>, + <GIC_SPI 71 IRQ_TYPE_NONE>; + interrupt-controller; + #interrupt-cells = <2>; + }; + pinctrl_cbus: pinctrl@c1109880 { compatible = "amlogic,meson8-cbus-pinctrl"; reg = <0xc1109880 0x10>; @@ -106,6 +123,7 @@ reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; + interrupt-parent = <&gpio_interrupt>; }; spi_nor_pins: nor { @@ -148,6 +166,7 @@ reg-names = "mux", "pull", "gpio"; gpio-controller; #gpio-cells = <2>; + interrupt-parent = <&gpio_interrupt>; }; uart_ao_a_pins: uart_ao_a { diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi index 41fd53671859..d76e7cb4d3dc 100644 --- a/arch/arm/boot/dts/meson8b.dtsi +++ b/arch/arm/boot/dts/meson8b.dtsi @@ -44,6 +44,8 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/clock/meson8b-clkc.h> #include <dt-bindings/gpio/meson8b-gpio.h> #include <dt-bindings/reset/amlogic,meson8b-reset.h> @@ -183,6 +185,21 @@ status = "disabled"; }; + gpio_interrupt: interrupt-controller@c1109880 { + compatible = "amlogic,meson8b-gpio-intc"; + reg = <0xc1109880 0x10>; + interrupts = <GIC_SPI 64 IRQ_TYPE_NONE>, + <GIC_SPI 65 IRQ_TYPE_NONE>, + <GIC_SPI 66 IRQ_TYPE_NONE>, + <GIC_SPI 67 IRQ_TYPE_NONE>, + <GIC_SPI 68 IRQ_TYPE_NONE>, + <GIC_SPI 69 IRQ_TYPE_NONE>, + <GIC_SPI 70 IRQ_TYPE_NONE>, + <GIC_SPI 71 IRQ_TYPE_NONE>; + interrupt-controller; + #interrupt-cells = <2>; + }; + pinctrl_cbus: pinctrl@c1109880 { compatible = "amlogic,meson8b-cbus-pinctrl"; reg = <0xc1109880 0x10>; @@ -198,6 +215,7 @@ reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; + interrupt-parent = <&gpio_interrupt>; }; }; @@ -215,6 +233,7 @@ reg-names = "mux", "pull", "gpio"; gpio-controller; #gpio-cells = <2>; + interrupt-parent = <&gpio_interrupt>; }; uart_ao_a_pins: uart_ao_a { -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC 10/10] irqchip: meson: Add support for IRQ_TYPE_EDGE_BOTH 2016-10-04 15:08 [RFC 00/10] irqchip: meson: add support for the gpio interrupt controller Jerome Brunet ` (2 preceding siblings ...) [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> @ 2016-10-04 15:08 ` Jerome Brunet 3 siblings, 0 replies; 14+ messages in thread From: Jerome Brunet @ 2016-10-04 15:08 UTC (permalink / raw) To: Kevin Hilman, Carlo Caione, Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Jerome Brunet, linux-amlogic, linux-arm-kernel, devicetree, linux-gpio The IP cannot take IRQ_EDGE_BOTH because the polarity in the filtering block is just one bit. It can trigger on either edge, but not both with the same configuration. This prevents meson based SoC to use some simple generic driver, like gpio-keys. The proposition is to change edge polarity in the end of interrupt callback (just toggling the polarity register of the IP). This works nicely but has 2 limitations: 1) If the signal is initially high, the first falling edge will not be detected, because the chip is initially configured for a rising edge. 2) If the signal changes too quickly for all edges to be properly handled, an additional edge might get lost, for the same reason as point 1. There is no drawback for introducing this work around so, knowing the limitation, it would be nice to have it Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> --- drivers/irqchip/irq-meson-gpio.c | 45 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c index 184025a9cdaf..5bcbefef3e94 100644 --- a/drivers/irqchip/irq-meson-gpio.c +++ b/drivers/irqchip/irq-meson-gpio.c @@ -58,6 +58,7 @@ struct meson_gpio_irq_domain { struct meson_gpio_irq_chip { void __iomem *base; int index; + unsigned int flow_type; }; static const struct meson_gpio_irq_params meson8_params = { @@ -91,6 +92,19 @@ static void meson_gpio_irq_update_bits(void __iomem *base, unsigned int reg, writel(tmp, base + reg); } +static void meson_gpio_irq_flip_bits(void __iomem *base, unsigned int reg, + u32 mask) +{ + u32 tmp, val; + + tmp = readl(base + reg); + val = tmp ^ mask; + tmp = (tmp & val) | val; + + writel(tmp, base + reg); +} + + static int meson_gpio_irq_get_index(struct meson_gpio_irq_domain *domain_data, int hwirq) { @@ -135,11 +149,15 @@ static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type) pr_debug("set type of hwirq %lu to %u\n", data->hwirq, type); - if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) - return -EINVAL; + cd->flow_type = type; if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) val |= REG_EDGE_POL_EDGE(cd->index); + /* + * Take care of the dual polarity issue here, starting positive + */ + if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) + type &= ~IRQ_TYPE_EDGE_FALLING; if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) { val |= REG_EDGE_POL_LOW(cd->index); @@ -162,11 +180,31 @@ static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type) return irq_chip_set_type_parent(data, type); } +static void meson_gpio_irq_eoi(struct irq_data *data) +{ + struct meson_gpio_irq_chip *cd = irq_data_get_irq_chip_data(data); + + /* + * To simulate IRQ_TYPE_EDGE_BOTH, change the polarity of the edge + * after each interrupt. + * Limitation: + * 1) If the signal is initially high, the first falling edge will not + * be detected + * 2) If the signal changes too quickly to detect all the edges, an + * additional edge might get lost. + */ + if ((cd->flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) + meson_gpio_irq_flip_bits(cd->base, REG_EDGE_POL, + REG_EDGE_POL_LOW(cd->index)); + + irq_chip_eoi_parent(data); +} + static struct irq_chip meson_gpio_irq_chip = { .name = "meson-gpio-irqchip", .irq_mask = irq_chip_mask_parent, .irq_unmask = irq_chip_unmask_parent, - .irq_eoi = irq_chip_eoi_parent, + .irq_eoi = meson_gpio_irq_eoi, .irq_set_type = meson_gpio_irq_set_type, .irq_retrigger = irq_chip_retrigger_hierarchy, #ifdef CONFIG_SMP @@ -221,6 +259,7 @@ static int meson_gpio_irq_domain_alloc(struct irq_domain *domain, cd->base = domain_data->base; cd->index = index; + cd->flow_type = type; fwspec_parent = &domain_data->parent_irqs[index]; irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2016-10-10 8:11 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-10-04 15:08 [RFC 00/10] irqchip: meson: add support for the gpio interrupt controller Jerome Brunet 2016-10-04 15:08 ` [RFC 06/10] ARM64: meson: enable MESON_IRQ_GPIO in Kconfig Jerome Brunet 2016-10-04 15:08 ` [RFC 08/10] ARM64: dts: amlogic: enable gpio interrupt controller on gxbb Jerome Brunet [not found] ` <1475593708-10526-1-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> 2016-10-04 15:08 ` [RFC 01/10] irqchip: meson: add support for gpio interrupt controller Jerome Brunet 2016-10-04 15:08 ` [RFC 02/10] dt-bindings: interrupt-controller: add DT binding for meson GPIO " Jerome Brunet 2016-10-09 1:29 ` Rob Herring 2016-10-10 8:11 ` Jerome Brunet 2016-10-04 15:08 ` [RFC 03/10] pinctrl: meson: update pinctrl data with gpio irq base number Jerome Brunet 2016-10-04 15:08 ` [RFC 04/10] pinctrl: meson: allow gpio to request irq Jerome Brunet 2016-10-04 15:08 ` [RFC 05/10] dt-bindings: pinctrl: meson: update gpio dt-bindings Jerome Brunet [not found] ` <1475593708-10526-6-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> 2016-10-09 1:29 ` Rob Herring 2016-10-04 15:08 ` [RFC 07/10] ARM: meson: enable MESON_IRQ_GPIO in Kconfig for meson8 Jerome Brunet 2016-10-04 15:08 ` [RFC 09/10] ARM: dts: amlogic: enable gpio interrupt controller on meson8 Jerome Brunet 2016-10-04 15:08 ` [RFC 10/10] irqchip: meson: Add support for IRQ_TYPE_EDGE_BOTH Jerome Brunet
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).