Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1487469 > unrolled thread
| Started by | Alexandre TORGUE <alexandre.torgue@st.com> |
|---|---|
| First post | 2016-09-20 18:10 +0200 |
| Last post | 2016-09-21 14:30 +0200 |
| Articles | 13 — 5 participants |
Back to article view | Back to linux.kernel
[PATCH v6 0/4] Add STM32 EXTI interrupt controller support Alexandre TORGUE <alexandre.torgue@st.com> - 2016-09-20 18:10 +0200
[PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support Alexandre TORGUE <alexandre.torgue@st.com> - 2016-09-20 18:10 +0200
Re: [PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support Thomas Gleixner <tglx@linutronix.de> - 2016-09-20 22:20 +0200
Re: [PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support Alexandre Torgue <alexandre.torgue@st.com> - 2016-09-21 09:50 +0200
Re: [PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support Thomas Gleixner <tglx@linutronix.de> - 2016-09-21 10:00 +0200
Re: [PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support Maxime Coquelin <mcoquelin.stm32@gmail.com> - 2016-09-21 10:00 +0200
[tip:irq/core] drivers/irqchip: Add STM32 external interrupts support tip-bot for Alexandre TORGUE <tipbot@zytor.com> - 2016-09-21 14:20 +0200
[PATCH v6 3/4] ARM: STM32: Select external interrupts controller Alexandre TORGUE <alexandre.torgue@st.com> - 2016-09-20 18:10 +0200
[tip:irq/core] ARM/STM32: Select external interrupts controller tip-bot for Alexandre TORGUE <tipbot@zytor.com> - 2016-09-21 14:30 +0200
[PATCH v6 1/4] Documentation: dt-bindings: Document STM32 EXTI controller bindings Alexandre TORGUE <alexandre.torgue@st.com> - 2016-09-20 18:10 +0200
[tip:irq/core] Documentation/dt-bindings: Document STM32 EXTI controller bindings tip-bot for Alexandre TORGUE <tipbot@zytor.com> - 2016-09-21 14:20 +0200
[PATCH v6 4/4] ARM: dts: Add EXTI controller node to stm32f429 Alexandre TORGUE <alexandre.torgue@st.com> - 2016-09-20 18:10 +0200
[tip:irq/core] ARM/dts: Add EXTI controller node to stm32f429 tip-bot for Alexandre TORGUE <tipbot@zytor.com> - 2016-09-21 14:30 +0200
| From | Alexandre TORGUE <alexandre.torgue@st.com> |
|---|---|
| Date | 2016-09-20 18:10 +0200 |
| Subject | [PATCH v6 0/4] Add STM32 EXTI interrupt controller support |
| Message-ID | <sjvMl-5fH-1@gated-at.bofh.it> |
Hi, This v6 fix useless mask in .free callback of stm32 exti driver (thanks Thomas). I resend only patches concerning STM32 EXTI driver (as pinctrl part has already been applied by Linus W.) The series adds support to EXTI interrupt controller and GPIO IRQ support in STM32 pinctrl driver. The STM32 external interrupt controller consists of edge detectors that generate interrupts requests or wake-up events. Each line can be independently configured as interrupt or wake-up source, and triggers either on rising, fallin or both edges. Each line can also be masked independently. Regards Alex Changes since v5: ----------------- - Fix .free callback according to Thomas Changes since v4: ----------------- - Fix bad copy/paste in stm32 exti driver - Remove GPIOLIB_IRQCHIP config in stm32 pinctrl driver Changes since v3: ----------------- - Review domain dealloc/free irq in stm32 pinctrl driver - Review domain dealloc/free irq in stm32 exti driver - Fix remarks on coding style Changes since v2: ----------------- - Define irq_chip for GPIO banks - Use hierarchical domain for GPIO banks - Improve search loop inside stm32_exti handler - Rebased on top of v4.8-rc1 Changes since v1: ----------------- - Rebased on top of v4.6-rc1 - Change variable name from virq to irq (Linus W.) Alexandre TORGUE (4): Documentation: dt-bindings: Document STM32 EXTI controller bindings drivers: irqchip: Add STM32 external interrupts support ARM: STM32: Select external interrupts controller ARM: dts: Add EXTI controller node to stm32f429 .../interrupt-controller/st,stm32-exti.txt | 20 ++ arch/arm/Kconfig | 1 + arch/arm/boot/dts/stm32f429.dtsi | 8 + drivers/irqchip/Kconfig | 4 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-stm32-exti.c | 201 +++++++++++++++++++++ 6 files changed, 235 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt create mode 100644 drivers/irqchip/irq-stm32-exti.c -- 1.9.1
[toc] | [next] | [standalone]
| From | Alexandre TORGUE <alexandre.torgue@st.com> |
|---|---|
| Date | 2016-09-20 18:10 +0200 |
| Subject | [PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support |
| Message-ID | <sjvMl-5fH-9@gated-at.bofh.it> |
| In reply to | #1487469 |
The STM32 external interrupt controller consists of edge detectors that
generate interrupts requests or wake-up events.
Each line can be independently configured as interrupt or wake-up source,
and triggers either on rising, falling or both edges. Each line can also
be masked independently.
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 7f87289..bc62d1f 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -264,3 +264,7 @@ config EZNPS_GIC
select IRQ_DOMAIN
help
Support the EZchip NPS400 global interrupt controller
+
+config STM32_EXTI
+ bool
+ select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 4c203b6..96383b2 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -71,3 +71,4 @@ obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o
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
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
new file mode 100644
index 0000000..491568c
--- /dev/null
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define EXTI_IMR 0x0
+#define EXTI_EMR 0x4
+#define EXTI_RTSR 0x8
+#define EXTI_FTSR 0xc
+#define EXTI_SWIER 0x10
+#define EXTI_PR 0x14
+
+static void stm32_irq_handler(struct irq_desc *desc)
+{
+ struct irq_domain *domain = irq_desc_get_handler_data(desc);
+ struct irq_chip_generic *gc = domain->gc->gc[0];
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ unsigned long pending;
+ int n;
+
+ chained_irq_enter(chip, desc);
+
+ while ((pending = irq_reg_readl(gc, EXTI_PR))) {
+ for_each_set_bit(n, &pending, BITS_PER_LONG) {
+ generic_handle_irq(irq_find_mapping(domain, n));
+ irq_reg_writel(gc, BIT(n), EXTI_PR);
+ }
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static int stm32_irq_set_type(struct irq_data *data, unsigned int type)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+ int pin = data->hwirq;
+ u32 rtsr, ftsr;
+
+ irq_gc_lock(gc);
+
+ rtsr = irq_reg_readl(gc, EXTI_RTSR);
+ ftsr = irq_reg_readl(gc, EXTI_FTSR);
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ rtsr |= BIT(pin);
+ ftsr &= ~BIT(pin);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ rtsr &= ~BIT(pin);
+ ftsr |= BIT(pin);
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ rtsr |= BIT(pin);
+ ftsr |= BIT(pin);
+ break;
+ default:
+ irq_gc_unlock(gc);
+ return -EINVAL;
+ }
+
+ irq_reg_writel(gc, rtsr, EXTI_RTSR);
+ irq_reg_writel(gc, ftsr, EXTI_FTSR);
+
+ irq_gc_unlock(gc);
+
+ return 0;
+}
+
+static int stm32_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+ int pin = data->hwirq;
+ u32 emr;
+
+ irq_gc_lock(gc);
+
+ emr = irq_reg_readl(gc, EXTI_EMR);
+ if (on)
+ emr |= BIT(pin);
+ else
+ emr &= ~BIT(pin);
+ irq_reg_writel(gc, emr, EXTI_EMR);
+
+ irq_gc_unlock(gc);
+
+ return 0;
+}
+
+static int stm32_exti_alloc(struct irq_domain *d, unsigned int virq,
+ unsigned int nr_irqs, void *data)
+{
+ struct irq_chip_generic *gc = d->gc->gc[0];
+ struct irq_fwspec *fwspec = data;
+ irq_hw_number_t hwirq;
+
+ hwirq = fwspec->param[0];
+
+ irq_map_generic_chip(d, virq, hwirq);
+ irq_domain_set_info(d, virq, hwirq, &gc->chip_types->chip, gc,
+ handle_simple_irq, NULL, NULL);
+
+ return 0;
+}
+
+static void stm32_exti_free(struct irq_domain *d, unsigned int virq,
+ unsigned int nr_irqs)
+{
+ struct irq_data *data = irq_domain_get_irq_data(d, virq);
+
+ irq_domain_reset_irq_data(data);
+}
+
+struct irq_domain_ops irq_exti_domain_ops = {
+ .map = irq_map_generic_chip,
+ .xlate = irq_domain_xlate_onetwocell,
+ .alloc = stm32_exti_alloc,
+ .free = stm32_exti_free,
+};
+
+static int __init stm32_exti_init(struct device_node *node,
+ struct device_node *parent)
+{
+ unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+ int nr_irqs, nr_exti, ret, i;
+ struct irq_chip_generic *gc;
+ struct irq_domain *domain;
+ void *base;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s: Unable to map registers\n", node->full_name);
+ return -ENOMEM;
+ }
+
+ /* Determine number of irqs supported */
+ writel_relaxed(~0UL, base + EXTI_RTSR);
+ nr_exti = fls(readl_relaxed(base + EXTI_RTSR));
+ writel_relaxed(0, base + EXTI_RTSR);
+
+ pr_info("%s: %d External IRQs detected\n", node->full_name, nr_exti);
+
+ domain = irq_domain_add_linear(node, nr_exti,
+ &irq_exti_domain_ops, NULL);
+ if (!domain) {
+ pr_err("%s: Could not register interrupt domain.\n",
+ node->name);
+ ret = -ENOMEM;
+ goto out_unmap;
+ }
+
+ ret = irq_alloc_domain_generic_chips(domain, nr_exti, 1, "exti",
+ handle_edge_irq, clr, 0, 0);
+ if (ret) {
+ pr_err("%s: Could not allocate generic interrupt chip.\n",
+ node->full_name);
+ goto out_free_domain;
+ }
+
+ gc = domain->gc->gc[0];
+ gc->reg_base = base;
+ gc->chip_types->type = IRQ_TYPE_EDGE_BOTH;
+ gc->chip_types->chip.name = gc->chip_types[0].chip.name;
+ gc->chip_types->chip.irq_ack = irq_gc_ack_set_bit;
+ gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit;
+ gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit;
+ gc->chip_types->chip.irq_set_type = stm32_irq_set_type;
+ gc->chip_types->chip.irq_set_wake = stm32_irq_set_wake;
+ gc->chip_types->regs.ack = EXTI_PR;
+ gc->chip_types->regs.mask = EXTI_IMR;
+ gc->chip_types->handler = handle_edge_irq;
+
+ nr_irqs = of_irq_count(node);
+ for (i = 0; i < nr_irqs; i++) {
+ unsigned int irq = irq_of_parse_and_map(node, i);
+
+ irq_set_handler_data(irq, domain);
+ irq_set_chained_handler(irq, stm32_irq_handler);
+ }
+
+ return 0;
+
+out_free_domain:
+ irq_domain_remove(domain);
+out_unmap:
+ iounmap(base);
+ return ret;
+}
+
+IRQCHIP_DECLARE(stm32_exti, "st,stm32-exti", stm32_exti_init);
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2016-09-20 22:20 +0200 |
| Subject | Re: [PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support |
| Message-ID | <sjzGh-7MY-13@gated-at.bofh.it> |
| In reply to | #1487472 |
Alexandre, On Tue, 20 Sep 2016, Alexandre TORGUE wrote: > The STM32 external interrupt controller consists of edge detectors that > generate interrupts requests or wake-up events. > > Each line can be independently configured as interrupt or wake-up source, > and triggers either on rising, falling or both edges. Each line can also > be masked independently. > > Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com> > Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com> That all looks very reasonable now. The only remaining question is your SOB chain. Who is the author of these patches? You or Maxime? If it's Maxime, then the changelog misses a From: tag. If it's you then Maximes SOB is bogus. Thanks, tglx
[toc] | [prev] | [next] | [standalone]
| From | Alexandre Torgue <alexandre.torgue@st.com> |
|---|---|
| Date | 2016-09-21 09:50 +0200 |
| Subject | Re: [PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support |
| Message-ID | <sjKs2-68g-21@gated-at.bofh.it> |
| In reply to | #1487614 |
Hi Thomas, On 09/20/2016 10:16 PM, Thomas Gleixner wrote: > Alexandre, > > On Tue, 20 Sep 2016, Alexandre TORGUE wrote: > >> The STM32 external interrupt controller consists of edge detectors that >> generate interrupts requests or wake-up events. >> >> Each line can be independently configured as interrupt or wake-up source, >> and triggers either on rising, falling or both edges. Each line can also >> be masked independently. >> >> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com> >> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com> > > That all looks very reasonable now. The only remaining question is your SOB > chain. Who is the author of these patches? You or Maxime? If it's Maxime, > then the changelog misses a From: tag. If it's you then Maximes SOB is > bogus. Actually Maxime wrote the main part of this driver and sent version 1 and 2 of the series. After Linus W. reviews, rework was required to use hierarchical domain. According to Maxime, I coded the rework (adaptation to hierarchical domain) and sent other version of the series. Regards Alex > > Thanks, > > tglx > >
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2016-09-21 10:00 +0200 |
| Subject | Re: [PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support |
| Message-ID | <sjKBH-6bG-3@gated-at.bofh.it> |
| In reply to | #1487877 |
On Wed, 21 Sep 2016, Alexandre Torgue wrote: > Hi Thomas, > > On 09/20/2016 10:16 PM, Thomas Gleixner wrote: > > Alexandre, > > > > On Tue, 20 Sep 2016, Alexandre TORGUE wrote: > > > > > The STM32 external interrupt controller consists of edge detectors that > > > generate interrupts requests or wake-up events. > > > > > > Each line can be independently configured as interrupt or wake-up source, > > > and triggers either on rising, falling or both edges. Each line can also > > > be masked independently. > > > > > > Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com> > > > Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com> > > > > That all looks very reasonable now. The only remaining question is your SOB > > chain. Who is the author of these patches? You or Maxime? If it's Maxime, > > then the changelog misses a From: tag. If it's you then Maximes SOB is > > bogus. > > Actually Maxime wrote the main part of this driver and sent version 1 and 2 of > the series. After Linus W. reviews, rework was required to use hierarchical > domain. According to Maxime, I coded the rework (adaptation to hierarchical > domain) and sent other version of the series. So I replace Maximes SOB with Originally-by: Does that apply to all four patches? Thanks, tglx
[toc] | [prev] | [next] | [standalone]
| From | Maxime Coquelin <mcoquelin.stm32@gmail.com> |
|---|---|
| Date | 2016-09-21 10:00 +0200 |
| Subject | Re: [PATCH v6 2/4] drivers: irqchip: Add STM32 external interrupts support |
| Message-ID | <sjKBI-6bG-37@gated-at.bofh.it> |
| In reply to | #1487878 |
2016-09-21 9:50 GMT+02:00 Thomas Gleixner <tglx@linutronix.de>: > On Wed, 21 Sep 2016, Alexandre Torgue wrote: > >> Hi Thomas, >> >> On 09/20/2016 10:16 PM, Thomas Gleixner wrote: >> > Alexandre, >> > >> > On Tue, 20 Sep 2016, Alexandre TORGUE wrote: >> > >> > > The STM32 external interrupt controller consists of edge detectors that >> > > generate interrupts requests or wake-up events. >> > > >> > > Each line can be independently configured as interrupt or wake-up source, >> > > and triggers either on rising, falling or both edges. Each line can also >> > > be masked independently. >> > > >> > > Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com> >> > > Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com> >> > >> > That all looks very reasonable now. The only remaining question is your SOB >> > chain. Who is the author of these patches? You or Maxime? If it's Maxime, >> > then the changelog misses a From: tag. If it's you then Maximes SOB is >> > bogus. >> >> Actually Maxime wrote the main part of this driver and sent version 1 and 2 of >> the series. After Linus W. reviews, rework was required to use hierarchical >> domain. According to Maxime, I coded the rework (adaptation to hierarchical >> domain) and sent other version of the series. > > So I replace Maximes SOB with Originally-by: Does that apply to all four > patches? Yes, that's fine. Alex did a lot of rework on this series, he deserves the SoB. Thanks, Maxime
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Alexandre TORGUE <tipbot@zytor.com> |
|---|---|
| Date | 2016-09-21 14:20 +0200 |
| Subject | [tip:irq/core] drivers/irqchip: Add STM32 external interrupts support |
| Message-ID | <sjOFk-sk-15@gated-at.bofh.it> |
| In reply to | #1487472 |
Commit-ID: e072041688ca73f125719815fa4b0fd23a45152c
Gitweb: http://git.kernel.org/tip/e072041688ca73f125719815fa4b0fd23a45152c
Author: Alexandre TORGUE <alexandre.torgue@st.com>
AuthorDate: Tue, 20 Sep 2016 18:00:57 +0200
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 21 Sep 2016 14:13:21 +0200
drivers/irqchip: Add STM32 external interrupts support
The STM32 external interrupt controller consists of edge detectors that
generate interrupts requests or wake-up events.
Each line can be independently configured as interrupt or wake-up source,
and triggers either on rising, falling or both edges. Each line can also
be masked independently.
Originally-from: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Cc: Daniel Thompson <daniel.thompson@linaro.org>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: arnd@arndb.de
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: bruherrera@gmail.com
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-gpio@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: lee.jones@linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/1474387259-18926-3-git-send-email-alexandre.torgue@st.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/Kconfig | 4 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-stm32-exti.c | 201 +++++++++++++++++++++++++++++++++++++++
3 files changed, 206 insertions(+)
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 9aeea1d..329c941 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -265,3 +265,7 @@ config EZNPS_GIC
select IRQ_DOMAIN
help
Support the EZchip NPS400 global interrupt controller
+
+config STM32_EXTI
+ bool
+ select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 4c203b6..96383b2 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -71,3 +71,4 @@ obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o
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
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
new file mode 100644
index 0000000..491568c
--- /dev/null
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define EXTI_IMR 0x0
+#define EXTI_EMR 0x4
+#define EXTI_RTSR 0x8
+#define EXTI_FTSR 0xc
+#define EXTI_SWIER 0x10
+#define EXTI_PR 0x14
+
+static void stm32_irq_handler(struct irq_desc *desc)
+{
+ struct irq_domain *domain = irq_desc_get_handler_data(desc);
+ struct irq_chip_generic *gc = domain->gc->gc[0];
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ unsigned long pending;
+ int n;
+
+ chained_irq_enter(chip, desc);
+
+ while ((pending = irq_reg_readl(gc, EXTI_PR))) {
+ for_each_set_bit(n, &pending, BITS_PER_LONG) {
+ generic_handle_irq(irq_find_mapping(domain, n));
+ irq_reg_writel(gc, BIT(n), EXTI_PR);
+ }
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static int stm32_irq_set_type(struct irq_data *data, unsigned int type)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+ int pin = data->hwirq;
+ u32 rtsr, ftsr;
+
+ irq_gc_lock(gc);
+
+ rtsr = irq_reg_readl(gc, EXTI_RTSR);
+ ftsr = irq_reg_readl(gc, EXTI_FTSR);
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ rtsr |= BIT(pin);
+ ftsr &= ~BIT(pin);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ rtsr &= ~BIT(pin);
+ ftsr |= BIT(pin);
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ rtsr |= BIT(pin);
+ ftsr |= BIT(pin);
+ break;
+ default:
+ irq_gc_unlock(gc);
+ return -EINVAL;
+ }
+
+ irq_reg_writel(gc, rtsr, EXTI_RTSR);
+ irq_reg_writel(gc, ftsr, EXTI_FTSR);
+
+ irq_gc_unlock(gc);
+
+ return 0;
+}
+
+static int stm32_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+ int pin = data->hwirq;
+ u32 emr;
+
+ irq_gc_lock(gc);
+
+ emr = irq_reg_readl(gc, EXTI_EMR);
+ if (on)
+ emr |= BIT(pin);
+ else
+ emr &= ~BIT(pin);
+ irq_reg_writel(gc, emr, EXTI_EMR);
+
+ irq_gc_unlock(gc);
+
+ return 0;
+}
+
+static int stm32_exti_alloc(struct irq_domain *d, unsigned int virq,
+ unsigned int nr_irqs, void *data)
+{
+ struct irq_chip_generic *gc = d->gc->gc[0];
+ struct irq_fwspec *fwspec = data;
+ irq_hw_number_t hwirq;
+
+ hwirq = fwspec->param[0];
+
+ irq_map_generic_chip(d, virq, hwirq);
+ irq_domain_set_info(d, virq, hwirq, &gc->chip_types->chip, gc,
+ handle_simple_irq, NULL, NULL);
+
+ return 0;
+}
+
+static void stm32_exti_free(struct irq_domain *d, unsigned int virq,
+ unsigned int nr_irqs)
+{
+ struct irq_data *data = irq_domain_get_irq_data(d, virq);
+
+ irq_domain_reset_irq_data(data);
+}
+
+struct irq_domain_ops irq_exti_domain_ops = {
+ .map = irq_map_generic_chip,
+ .xlate = irq_domain_xlate_onetwocell,
+ .alloc = stm32_exti_alloc,
+ .free = stm32_exti_free,
+};
+
+static int __init stm32_exti_init(struct device_node *node,
+ struct device_node *parent)
+{
+ unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+ int nr_irqs, nr_exti, ret, i;
+ struct irq_chip_generic *gc;
+ struct irq_domain *domain;
+ void *base;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s: Unable to map registers\n", node->full_name);
+ return -ENOMEM;
+ }
+
+ /* Determine number of irqs supported */
+ writel_relaxed(~0UL, base + EXTI_RTSR);
+ nr_exti = fls(readl_relaxed(base + EXTI_RTSR));
+ writel_relaxed(0, base + EXTI_RTSR);
+
+ pr_info("%s: %d External IRQs detected\n", node->full_name, nr_exti);
+
+ domain = irq_domain_add_linear(node, nr_exti,
+ &irq_exti_domain_ops, NULL);
+ if (!domain) {
+ pr_err("%s: Could not register interrupt domain.\n",
+ node->name);
+ ret = -ENOMEM;
+ goto out_unmap;
+ }
+
+ ret = irq_alloc_domain_generic_chips(domain, nr_exti, 1, "exti",
+ handle_edge_irq, clr, 0, 0);
+ if (ret) {
+ pr_err("%s: Could not allocate generic interrupt chip.\n",
+ node->full_name);
+ goto out_free_domain;
+ }
+
+ gc = domain->gc->gc[0];
+ gc->reg_base = base;
+ gc->chip_types->type = IRQ_TYPE_EDGE_BOTH;
+ gc->chip_types->chip.name = gc->chip_types[0].chip.name;
+ gc->chip_types->chip.irq_ack = irq_gc_ack_set_bit;
+ gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit;
+ gc->chip_types->chip.irq_unmask = irq_gc_mask_set_bit;
+ gc->chip_types->chip.irq_set_type = stm32_irq_set_type;
+ gc->chip_types->chip.irq_set_wake = stm32_irq_set_wake;
+ gc->chip_types->regs.ack = EXTI_PR;
+ gc->chip_types->regs.mask = EXTI_IMR;
+ gc->chip_types->handler = handle_edge_irq;
+
+ nr_irqs = of_irq_count(node);
+ for (i = 0; i < nr_irqs; i++) {
+ unsigned int irq = irq_of_parse_and_map(node, i);
+
+ irq_set_handler_data(irq, domain);
+ irq_set_chained_handler(irq, stm32_irq_handler);
+ }
+
+ return 0;
+
+out_free_domain:
+ irq_domain_remove(domain);
+out_unmap:
+ iounmap(base);
+ return ret;
+}
+
+IRQCHIP_DECLARE(stm32_exti, "st,stm32-exti", stm32_exti_init);
[toc] | [prev] | [next] | [standalone]
| From | Alexandre TORGUE <alexandre.torgue@st.com> |
|---|---|
| Date | 2016-09-20 18:10 +0200 |
| Subject | [PATCH v6 3/4] ARM: STM32: Select external interrupts controller |
| Message-ID | <sjvMm-5fH-19@gated-at.bofh.it> |
| In reply to | #1487469 |
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2d601d7..157cea9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -877,6 +877,7 @@ config ARCH_STM32 select CLKSRC_STM32 select PINCTRL select RESET_CONTROLLER + select STM32_EXTI help Support for STMicroelectronics STM32 processors. -- 1.9.1
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Alexandre TORGUE <tipbot@zytor.com> |
|---|---|
| Date | 2016-09-21 14:30 +0200 |
| Subject | [tip:irq/core] ARM/STM32: Select external interrupts controller |
| Message-ID | <sjOP0-vu-23@gated-at.bofh.it> |
| In reply to | #1487474 |
Commit-ID: 47f91519546ce39cceee2c51b0f5045eadc688a9 Gitweb: http://git.kernel.org/tip/47f91519546ce39cceee2c51b0f5045eadc688a9 Author: Alexandre TORGUE <alexandre.torgue@st.com> AuthorDate: Tue, 20 Sep 2016 18:00:58 +0200 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Wed, 21 Sep 2016 14:13:21 +0200 ARM/STM32: Select external interrupts controller Originally-from: Maxime Coquelin <mcoquelin.stm32@gmail.com> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: devicetree@vger.kernel.org Cc: Daniel Thompson <daniel.thompson@linaro.org> Cc: Jason Cooper <jason@lakedaemon.net> Cc: arnd@arndb.de Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: bruherrera@gmail.com Cc: Linus Walleij <linus.walleij@linaro.org> Cc: linux-gpio@vger.kernel.org Cc: Rob Herring <robh+dt@kernel.org> Cc: lee.jones@linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1474387259-18926-4-git-send-email-alexandre.torgue@st.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a9c4e48..bc9d6df 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -878,6 +878,7 @@ config ARCH_STM32 select CLKSRC_STM32 select PINCTRL select RESET_CONTROLLER + select STM32_EXTI help Support for STMicroelectronics STM32 processors.
[toc] | [prev] | [next] | [standalone]
| From | Alexandre TORGUE <alexandre.torgue@st.com> |
|---|---|
| Date | 2016-09-20 18:10 +0200 |
| Subject | [PATCH v6 1/4] Documentation: dt-bindings: Document STM32 EXTI controller bindings |
| Message-ID | <sjvMm-5fH-39@gated-at.bofh.it> |
| In reply to | #1487469 |
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
new file mode 100644
index 0000000..6e7703d
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
@@ -0,0 +1,20 @@
+STM32 External Interrupt Controller
+
+Required properties:
+
+- compatible: Should be "st,stm32-exti"
+- reg: Specifies base physical address and size of the registers
+- interrupt-controller: Indentifies the node as an interrupt controller
+- #interrupt-cells: Specifies the number of cells to encode an interrupt
+ specifier, shall be 2
+- interrupts: interrupts references to primary interrupt controller
+
+Example:
+
+exti: interrupt-controller@40013c00 {
+ compatible = "st,stm32-exti";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x40013C00 0x400>;
+ interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
+};
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Alexandre TORGUE <tipbot@zytor.com> |
|---|---|
| Date | 2016-09-21 14:20 +0200 |
| Subject | [tip:irq/core] Documentation/dt-bindings: Document STM32 EXTI controller bindings |
| Message-ID | <sjOFk-sk-13@gated-at.bofh.it> |
| In reply to | #1487478 |
Commit-ID: 3027f78bb7243bef28c103507fc857e1471d769d
Gitweb: http://git.kernel.org/tip/3027f78bb7243bef28c103507fc857e1471d769d
Author: Alexandre TORGUE <alexandre.torgue@st.com>
AuthorDate: Tue, 20 Sep 2016 18:00:56 +0200
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 21 Sep 2016 14:13:21 +0200
Documentation/dt-bindings: Document STM32 EXTI controller bindings
Originally-from: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Cc: Daniel Thompson <daniel.thompson@linaro.org>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: arnd@arndb.de
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: bruherrera@gmail.com
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-gpio@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: lee.jones@linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/1474387259-18926-2-git-send-email-alexandre.torgue@st.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
.../bindings/interrupt-controller/st,stm32-exti.txt | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
new file mode 100644
index 0000000..6e7703d
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt
@@ -0,0 +1,20 @@
+STM32 External Interrupt Controller
+
+Required properties:
+
+- compatible: Should be "st,stm32-exti"
+- reg: Specifies base physical address and size of the registers
+- interrupt-controller: Indentifies the node as an interrupt controller
+- #interrupt-cells: Specifies the number of cells to encode an interrupt
+ specifier, shall be 2
+- interrupts: interrupts references to primary interrupt controller
+
+Example:
+
+exti: interrupt-controller@40013c00 {
+ compatible = "st,stm32-exti";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x40013C00 0x400>;
+ interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
+};
[toc] | [prev] | [next] | [standalone]
| From | Alexandre TORGUE <alexandre.torgue@st.com> |
|---|---|
| Date | 2016-09-20 18:10 +0200 |
| Subject | [PATCH v6 4/4] ARM: dts: Add EXTI controller node to stm32f429 |
| Message-ID | <sjvMn-5fH-49@gated-at.bofh.it> |
| In reply to | #1487469 |
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 35df462..1a189d4 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -176,6 +176,14 @@
reg = <0x40013800 0x400>;
};
+ exti: interrupt-controller@40013c00 {
+ compatible = "st,stm32-exti";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x40013C00 0x400>;
+ interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
+ };
+
pin-controller {
#address-cells = <1>;
#size-cells = <1>;
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Alexandre TORGUE <tipbot@zytor.com> |
|---|---|
| Date | 2016-09-21 14:30 +0200 |
| Subject | [tip:irq/core] ARM/dts: Add EXTI controller node to stm32f429 |
| Message-ID | <sjOP0-vu-27@gated-at.bofh.it> |
| In reply to | #1487483 |
Commit-ID: 5a79d596378b65e773d93d00edcb57a33f87ea94
Gitweb: http://git.kernel.org/tip/5a79d596378b65e773d93d00edcb57a33f87ea94
Author: Alexandre TORGUE <alexandre.torgue@st.com>
AuthorDate: Tue, 20 Sep 2016 18:00:59 +0200
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 21 Sep 2016 14:13:21 +0200
ARM/dts: Add EXTI controller node to stm32f429
Originally-from: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Cc: Daniel Thompson <daniel.thompson@linaro.org>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: arnd@arndb.de
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: bruherrera@gmail.com
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-gpio@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: lee.jones@linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/1474387259-18926-5-git-send-email-alexandre.torgue@st.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/arm/boot/dts/stm32f429.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 35df462..1a189d4 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -176,6 +176,14 @@
reg = <0x40013800 0x400>;
};
+ exti: interrupt-controller@40013c00 {
+ compatible = "st,stm32-exti";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x40013C00 0x400>;
+ interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
+ };
+
pin-controller {
#address-cells = <1>;
#size-cells = <1>;
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web