devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity
@ 2014-10-29 10:00 Yingjoe Chen
       [not found] ` <1414576824-16143-1-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Yingjoe Chen @ 2014-10-29 10:00 UTC (permalink / raw)
  To: Matthias Brugger, Thomas Gleixner, Jiang Liu, Marc Zyngier,
	arm-DgEjT+Ai2ygdnm+yROfE0A
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Jason Cooper, Benjamin Herrenschmidt, Yingjoe Chen,
	Grant Likely, Boris BREZILLON, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
	yingjoe.chen-Re5JQEeQqe8AvxtiuMwx3w,
	hc.yen-NuS5LvNUpcJWk0Htik3J/w, eddie.huang-NuS5LvNUpcJWk0Htik3J/w,
	nathan.chung-NuS5LvNUpcJWk0Htik3J/w,
	yh.chen-NuS5LvNUpcJWk0Htik3J/w, Sascha Hauer, Olof Johansson,
	Arnd Bergmann

This series is 5th version of interrupt polarity support for MediaTek SoCs.
This is based on Jiang's hierarchy irqdomain p2v3 [1], which is based on 
v3.18-rc2, and my mediatek SoC basic support [2].

Besides changing base, this version addressed comments from Thomas and Marc
and also fix a bug on mt6589 reported by Matthias.

In Jiang's version of irq_create_of_mapping, if irqdomain is hierarchy, it
will not perform irq_find_mapping check and set_type. The outermost
irqdomain need to take care of that. Because we will have several different
outermost irqdomain in different ARM SoCs, this cause code duplication. I
moved them back to irq_create_of_mapping.

Simplified block diagram for interrupt on my system:

    +-------+      +-------+
 ---| SYSIRQ|------|ARM GIC|
 ---|       |------|       |
 ---|       |------|       |
 ---|       |------|       |
 ---|       |------|       |
    +-------+      +-------+

In device tree, interrupt-parent for other devices is sysirq, child of gic.
This describe HW better and allow device to specify polarity as it is sent
by the device.

When using hierarchy irq domain, gic will use irq_domain_add_linear to
create irqdomain and all interrupt numbers must come from device tree. My
/proc/interrupts looks like this now:

# cat /proc/interrupts
           CPU0
 16:     149578  MT_SYSIRQ 113  mtk_timer
 20:       1082  MT_SYSIRQ  54  serial

Changes in v5:
 - Fix bug on mt6589 reported by Matthias
 - Fix bug for irq_find_mapping in irq_create_of_mapping
 - Merge Marc's change to proper handle non-DT case in gic_init_bases

Changes in v4:
 - Discussed in [3]
 - Remove arm,hierarchy-irq-domain. When GIC is probed by DT, it will
support hierarchy irqdomain.

Changes in v3:
 - Discussed in [4]
 - First implementation using hierarchy irqdomain

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/297624.html
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/296093.html
[3] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/296911.html
[4] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/293766.html


Yingjoe Chen (6):
  irqdomain: do irq_find_mapping and set_type for hierarchy irqdomain
  genirq: Add more helper functions to support stacked irq_chip
  irqchip: gic: Support hierarchy irq domain.
  ARM: mediatek: Add sysirq interrupt polarity support
  ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi
  dt-bindings: add bindings for mediatek sysirq

 .../bindings/arm/mediatek/mediatek,sysirq.txt      |  26 ++++
 arch/arm/boot/dts/mt6589.dtsi                      |  14 +-
 arch/arm/boot/dts/mt8127.dtsi                      |  14 +-
 arch/arm/boot/dts/mt8135.dtsi                      |  14 +-
 drivers/irqchip/Kconfig                            |   1 +
 drivers/irqchip/Makefile                           |   1 +
 drivers/irqchip/irq-gic.c                          |  90 +++++++----
 drivers/irqchip/irq-mtk-sysirq.c                   | 168 +++++++++++++++++++++
 include/linux/irq.h                                |   6 +
 kernel/irq/chip.c                                  |  28 ++++
 kernel/irq/irqdomain.c                             |  27 ++--
 11 files changed, 348 insertions(+), 41 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt
 create mode 100644 drivers/irqchip/irq-mtk-sysirq.c

--
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] 12+ messages in thread

* [PATCH v5 1/6] irqdomain: do irq_find_mapping and set_type for hierarchy irqdomain
       [not found] ` <1414576824-16143-1-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
@ 2014-10-29 10:00   ` Yingjoe Chen
  0 siblings, 0 replies; 12+ messages in thread
From: Yingjoe Chen @ 2014-10-29 10:00 UTC (permalink / raw)
  To: Matthias Brugger, Thomas Gleixner, Jiang Liu, Marc Zyngier,
	arm-DgEjT+Ai2ygdnm+yROfE0A
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Jason Cooper, Benjamin Herrenschmidt, Yingjoe Chen,
	Grant Likely, Boris BREZILLON, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
	yingjoe.chen-Re5JQEeQqe8AvxtiuMwx3w,
	hc.yen-NuS5LvNUpcJWk0Htik3J/w, eddie.huang-NuS5LvNUpcJWk0Htik3J/w,
	nathan.chung-NuS5LvNUpcJWk0Htik3J/w,
	yh.chen-NuS5LvNUpcJWk0Htik3J/w, Sascha Hauer, Olof Johansson,
	Arnd Bergmann

It is possible to call irq_create_of_mapping to create/translate the
same IRQ from DT for multiple times. Perform irq_find_mapping check
and set_type for hierarchy irqdomain in irq_create_of_mapping() to
avoid duplicate these functionality in all outer most irqdomain.

Signed-off-by: Yingjoe Chen <yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 kernel/irq/irqdomain.c | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 7cc9cbb..c292603 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -478,11 +478,6 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
 		return 0;
 	}
 
-	if (irq_domain_is_hierarchy(domain)) {
-		virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, irq_data);
-		return virq <= 0 ? 0 : virq;
-	}
-
 	/* If domain has no translation, then we assume interrupt line */
 	if (domain->ops->xlate == NULL)
 		hwirq = irq_data->args[0];
@@ -492,10 +487,24 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
 			return 0;
 	}
 
-	/* Create mapping */
-	virq = irq_create_mapping(domain, hwirq);
-	if (!virq)
-		return virq;
+	if (irq_domain_is_hierarchy(domain)) {
+		/*
+		 * If we've already configured this interrupt,
+		 * don't do it again, or hell will break loose.
+		 */
+		virq = irq_find_mapping(domain, hwirq);
+		if (virq)
+			return virq;
+
+		virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, irq_data);
+		if (virq <= 0)
+			return 0;
+	} else {
+		/* Create mapping */
+		virq = irq_create_mapping(domain, hwirq);
+		if (!virq)
+			return virq;
+	}
 
 	/* Set type if specified and different than the current one */
 	if (type != IRQ_TYPE_NONE &&
-- 
1.8.1.1.dirty

--
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] 12+ messages in thread

* [PATCH v5 2/6] genirq: Add more helper functions to support stacked irq_chip
  2014-10-29 10:00 [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
       [not found] ` <1414576824-16143-1-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
@ 2014-10-29 10:00 ` Yingjoe Chen
  2014-10-29 10:00 ` [PATCH v5 3/6] irqchip: gic: Support hierarchy irq domain Yingjoe Chen
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Yingjoe Chen @ 2014-10-29 10:00 UTC (permalink / raw)
  To: Matthias Brugger, Thomas Gleixner, Jiang Liu, Marc Zyngier, arm
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Jason Cooper, Benjamin Herrenschmidt, Yingjoe Chen,
	Grant Likely, Boris BREZILLON, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, yingjoe.chen, hc.yen,
	eddie.huang, nathan.chung, yh.chen, Sascha Hauer, Olof Johansson,
	Arnd Bergmann

Add more helper function for stacked irq_chip to just call parent's
function.

Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
---
 include/linux/irq.h |  6 ++++++
 kernel/irq/chip.c   | 28 ++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 0adcbbb..ff0a89c 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -445,6 +445,12 @@ extern void handle_nested_irq(unsigned int irq);
 
 #ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
 extern void irq_chip_ack_parent(struct irq_data *data);
+extern void irq_chip_mask_parent(struct irq_data *data);
+extern void irq_chip_unmask_parent(struct irq_data *data);
+extern void irq_chip_eoi_parent(struct irq_data *data);
+extern int irq_chip_set_affinity_parent(struct irq_data *data,
+					const struct cpumask *dest,
+					bool force);
 extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
 #endif
 
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 12f3e72..fe53575 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -858,6 +858,34 @@ void irq_chip_ack_parent(struct irq_data *data)
 	data->chip->irq_ack(data);
 }
 
+void irq_chip_mask_parent(struct irq_data *data)
+{
+	data = data->parent_data;
+	data->chip->irq_mask(data);
+}
+
+void irq_chip_unmask_parent(struct irq_data *data)
+{
+	data = data->parent_data;
+	data->chip->irq_unmask(data);
+}
+
+void irq_chip_eoi_parent(struct irq_data *data)
+{
+	data = data->parent_data;
+	data->chip->irq_eoi(data);
+}
+
+int irq_chip_set_affinity_parent(struct irq_data *data,
+				 const struct cpumask *dest, bool force)
+{
+	data = data->parent_data;
+	if (data->chip->irq_set_affinity)
+		return data->chip->irq_set_affinity(data, dest, force);
+
+	return -ENOSYS;
+}
+
 int irq_chip_retrigger_hierarchy(struct irq_data *data)
 {
 	for (data = data->parent_data; data; data = data->parent_data)
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 3/6] irqchip: gic: Support hierarchy irq domain.
  2014-10-29 10:00 [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
       [not found] ` <1414576824-16143-1-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
  2014-10-29 10:00 ` [PATCH v5 2/6] genirq: Add more helper functions to support stacked irq_chip Yingjoe Chen
@ 2014-10-29 10:00 ` Yingjoe Chen
  2014-11-09  7:04   ` Jiang Liu
  2014-10-29 10:00 ` [PATCH v5 4/6] ARM: mediatek: Add sysirq interrupt polarity support Yingjoe Chen
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Yingjoe Chen @ 2014-10-29 10:00 UTC (permalink / raw)
  To: Matthias Brugger, Thomas Gleixner, Jiang Liu, Marc Zyngier, arm
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Jason Cooper, Benjamin Herrenschmidt, Yingjoe Chen,
	Grant Likely, Boris BREZILLON, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, yingjoe.chen, hc.yen,
	eddie.huang, nathan.chung, yh.chen, Sascha Hauer, Olof Johansson,
	Arnd Bergmann

Add support to use gic as a parent for stacked irq domain.

Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
---
 drivers/irqchip/Kconfig   |  1 +
 drivers/irqchip/irq-gic.c | 90 +++++++++++++++++++++++++++++++++--------------
 2 files changed, 65 insertions(+), 26 deletions(-)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index b21f12f..7f34138 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -5,6 +5,7 @@ config IRQCHIP
 config ARM_GIC
 	bool
 	select IRQ_DOMAIN
+	select IRQ_DOMAIN_HIERARCHY
 	select MULTI_IRQ_HANDLER
 
 config GIC_NON_BANKED
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 38493ff..6f39bef 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -786,19 +786,17 @@ void __init gic_init_physaddr(struct device_node *node)
 static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 				irq_hw_number_t hw)
 {
+	irq_domain_set_hwirq_and_chip(d, irq, hw, &gic_chip, d->host_data);
 	if (hw < 32) {
 		irq_set_percpu_devid(irq);
-		irq_set_chip_and_handler(irq, &gic_chip,
-					 handle_percpu_devid_irq);
+		irq_set_handler(irq, handle_percpu_devid_irq);
 		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
 	} else {
-		irq_set_chip_and_handler(irq, &gic_chip,
-					 handle_fasteoi_irq);
+		irq_set_handler(irq, handle_fasteoi_irq);
 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 
 		gic_routable_irq_domain_ops->map(d, irq, hw);
 	}
-	irq_set_chip_data(irq, d->host_data);
 	return 0;
 }
 
@@ -814,8 +812,6 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
 {
 	unsigned long ret = 0;
 
-	if (d->of_node != controller)
-		return -EINVAL;
 	if (intsize < 3)
 		return -EINVAL;
 
@@ -858,6 +854,42 @@ static struct notifier_block gic_cpu_notifier = {
 };
 #endif
 
+static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				unsigned int nr_irqs, void *arg)
+{
+	int i, ret;
+	irq_hw_number_t hwirq;
+	unsigned int type = IRQ_TYPE_NONE;
+	struct of_phandle_args *irq_data = arg;
+
+	ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
+				   irq_data->args_count, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nr_irqs; i++)
+		gic_irq_domain_map(domain, virq+i, hwirq+i);
+
+	return 0;
+}
+
+static void gic_irq_domain_free(struct irq_domain *domain, unsigned int virq,
+				unsigned int nr_irqs)
+{
+	int i;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_set_handler(virq + i, NULL);
+		irq_domain_set_hwirq_and_chip(domain, virq + i, 0, NULL, NULL);
+	}
+}
+
+static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = {
+	.xlate = gic_irq_domain_xlate,
+	.alloc = gic_irq_domain_alloc,
+	.free = gic_irq_domain_free,
+};
+
 static const struct irq_domain_ops gic_irq_domain_ops = {
 	.map = gic_irq_domain_map,
 	.unmap = gic_irq_domain_unmap,
@@ -948,18 +980,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		gic_cpu_map[i] = 0xff;
 
 	/*
-	 * For primary GICs, skip over SGIs.
-	 * For secondary GICs, skip over PPIs, too.
-	 */
-	if (gic_nr == 0 && (irq_start & 31) > 0) {
-		hwirq_base = 16;
-		if (irq_start != -1)
-			irq_start = (irq_start & ~31) + 16;
-	} else {
-		hwirq_base = 32;
-	}
-
-	/*
 	 * Find out how many interrupts are supported.
 	 * The GIC only supports up to 1020 interrupt sources.
 	 */
@@ -969,10 +989,32 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		gic_irqs = 1020;
 	gic->gic_irqs = gic_irqs;
 
-	gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
+	if (node) {		/* DT case */
+		const struct irq_domain_ops *ops =
+					&gic_irq_domain_hierarchy_ops;
+
+		if (!of_property_read_u32(node, "arm,routable-irqs",
+					  &nr_routable_irqs)) {
+			ops = &gic_irq_domain_ops;
+			gic_irqs = nr_routable_irqs;
+		}
+
+		gic->domain = irq_domain_add_linear(node, gic_irqs, ops, gic);
+	} else {		/* Non-DT case */
+		/*
+		 * For primary GICs, skip over SGIs.
+		 * For secondary GICs, skip over PPIs, too.
+		 */
+		if (gic_nr == 0 && (irq_start & 31) > 0) {
+			hwirq_base = 16;
+			if (irq_start != -1)
+				irq_start = (irq_start & ~31) + 16;
+		} else {
+			hwirq_base = 32;
+		}
+
+		gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
 
-	if (of_property_read_u32(node, "arm,routable-irqs",
-				 &nr_routable_irqs)) {
 		irq_base = irq_alloc_descs(irq_start, 16, gic_irqs,
 					   numa_node_id());
 		if (IS_ERR_VALUE(irq_base)) {
@@ -983,10 +1025,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 
 		gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
 					hwirq_base, &gic_irq_domain_ops, gic);
-	} else {
-		gic->domain = irq_domain_add_linear(node, nr_routable_irqs,
-						    &gic_irq_domain_ops,
-						    gic);
 	}
 
 	if (WARN_ON(!gic->domain))
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 4/6] ARM: mediatek: Add sysirq interrupt polarity support
  2014-10-29 10:00 [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
                   ` (2 preceding siblings ...)
  2014-10-29 10:00 ` [PATCH v5 3/6] irqchip: gic: Support hierarchy irq domain Yingjoe Chen
@ 2014-10-29 10:00 ` Yingjoe Chen
       [not found]   ` <1414576824-16143-5-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
  2014-10-29 10:00 ` [PATCH v5 5/6] ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi Yingjoe Chen
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Yingjoe Chen @ 2014-10-29 10:00 UTC (permalink / raw)
  To: Matthias Brugger, Thomas Gleixner, Jiang Liu, Marc Zyngier, arm
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Jason Cooper, Benjamin Herrenschmidt, Yingjoe Chen,
	Grant Likely, Boris BREZILLON, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, yingjoe.chen, hc.yen,
	eddie.huang, nathan.chung, yh.chen, Sascha Hauer, Olof Johansson,
	Arnd Bergmann

Mediatek SoCs have interrupt polarity support in sysirq which
allows to invert polarity for given interrupt. Add this support
using hierarchy irq domain.

Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
---
 drivers/irqchip/Makefile         |   1 +
 drivers/irqchip/irq-mtk-sysirq.c | 168 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+)
 create mode 100644 drivers/irqchip/irq-mtk-sysirq.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 173bb5f..4e0f254 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -38,3 +38,4 @@ obj-$(CONFIG_IRQ_CROSSBAR)		+= irq-crossbar.o
 obj-$(CONFIG_BRCMSTB_L2_IRQ)		+= irq-brcmstb-l2.o \
 					   irq-bcm7120-l2.o
 obj-$(CONFIG_KEYSTONE_IRQ)		+= irq-keystone.o
+obj-$(CONFIG_ARCH_MEDIATEK)		+= irq-mtk-sysirq.o
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
new file mode 100644
index 0000000..4403bcf
--- /dev/null
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Joe.C <yingjoe.chen@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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.
+ */
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "irqchip.h"
+
+#define MT6577_SYS_INTPOL_NUM	(224)
+
+struct mtk_sysirq_chip_data {
+	spinlock_t lock;
+	void __iomem *intpol_base;
+};
+
+static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
+{
+	irq_hw_number_t hwirq = data->hwirq;
+	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
+	u32 offset, reg_index, value;
+	unsigned long flags;
+	int ret;
+
+	offset = hwirq & 0x1f;
+	reg_index = hwirq >> 5;
+
+	spin_lock_irqsave(&chip_data->lock, flags);
+	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
+	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
+		if (type == IRQ_TYPE_LEVEL_LOW)
+			type = IRQ_TYPE_LEVEL_HIGH;
+		else
+			type = IRQ_TYPE_EDGE_RISING;
+		value |= (1 << offset);
+	} else
+		value &= ~(1 << offset);
+	writel(value, chip_data->intpol_base + reg_index * 4);
+
+	data = data->parent_data;
+	ret = data->chip->irq_set_type(data, type);
+	spin_unlock_irqrestore(&chip_data->lock, flags);
+	return ret;
+}
+
+static struct irq_chip mtk_sysirq_chip = {
+	.name			= "MT_SYSIRQ",
+	.irq_mask		= irq_chip_mask_parent,
+	.irq_unmask		= irq_chip_unmask_parent,
+	.irq_eoi		= irq_chip_eoi_parent,
+	.irq_set_type		= mtk_sysirq_set_type,
+	.irq_retrigger		= irq_chip_retrigger_hierarchy,
+	.irq_set_affinity	= irq_chip_set_affinity_parent,
+};
+
+static int mtk_sysirq_domain_xlate(struct irq_domain *d,
+				   struct device_node *controller,
+				   const u32 *intspec, unsigned int intsize,
+				   unsigned long *out_hwirq,
+				   unsigned int *out_type)
+{
+	if (intsize < 3)
+		return -EINVAL;
+
+	/* sysirq doesn't support PPI */
+	if (intspec[0])
+		return -EINVAL;
+
+	*out_hwirq = intspec[1];
+	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
+	return 0;
+}
+
+static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				   unsigned int nr_irqs, void *arg)
+{
+	int i, ret;
+	irq_hw_number_t hwirq;
+	struct of_phandle_args *irq_data = arg;
+
+	if (irq_data->args_count < 3)
+		return -EINVAL;
+
+	hwirq = irq_data->args[1];
+	for (i = 0; i < nr_irqs; i++)
+		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
+					      &mtk_sysirq_chip,
+					      domain->host_data);
+
+	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
+}
+
+static void mtk_sysirq_domain_free(struct irq_domain *domain, unsigned int virq,
+				   unsigned int nr_irqs)
+{
+	int i;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_set_handler(virq + i, NULL);
+		irq_domain_set_hwirq_and_chip(domain, virq + i, 0, NULL, NULL);
+	}
+	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+}
+
+static struct irq_domain_ops sysirq_domain_ops = {
+	.xlate = mtk_sysirq_domain_xlate,
+	.alloc = mtk_sysirq_domain_alloc,
+	.free = mtk_sysirq_domain_free,
+};
+
+static int __init mtk_sysirq_of_init(struct device_node *node,
+				     struct device_node *parent)
+{
+	struct irq_domain *domain, *domain_parent;
+	struct mtk_sysirq_chip_data *chip_data;
+	int ret = 0;
+
+	domain_parent = irq_find_host(parent);
+	if (!domain_parent) {
+		pr_err("mtk_sysirq: interrupt-parent not found\n");
+		return -EINVAL;
+	}
+
+	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
+	if (!chip_data)
+		return -ENOMEM;
+
+	chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol");
+	if (!chip_data->intpol_base) {
+		pr_err("mtk_sysirq: unable to map sysirq register\n");
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	domain = irq_domain_add_linear(node, MT6577_SYS_INTPOL_NUM,
+				       &sysirq_domain_ops, chip_data);
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out_unmap;
+	}
+	domain->parent = domain_parent;
+	spin_lock_init(&chip_data->lock);
+
+	return 0;
+
+out_unmap:
+	iounmap(chip_data->intpol_base);
+out_free:
+	kfree(chip_data);
+	return ret;
+}
+IRQCHIP_DECLARE(mtk_sysirq, "mediatek,mt6577-sysirq", mtk_sysirq_of_init);
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 5/6] ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi
  2014-10-29 10:00 [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
                   ` (3 preceding siblings ...)
  2014-10-29 10:00 ` [PATCH v5 4/6] ARM: mediatek: Add sysirq interrupt polarity support Yingjoe Chen
@ 2014-10-29 10:00 ` Yingjoe Chen
  2014-10-29 10:00 ` [PATCH v5 6/6] dt-bindings: add bindings for mediatek sysirq Yingjoe Chen
  2014-11-09  5:38 ` [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Jason Cooper
  6 siblings, 0 replies; 12+ messages in thread
From: Yingjoe Chen @ 2014-10-29 10:00 UTC (permalink / raw)
  To: Matthias Brugger, Thomas Gleixner, Jiang Liu, Marc Zyngier, arm
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Jason Cooper, Benjamin Herrenschmidt, Yingjoe Chen,
	Grant Likely, Boris BREZILLON, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, yingjoe.chen, hc.yen,
	eddie.huang, nathan.chung, yh.chen, Sascha Hauer, Olof Johansson,
	Arnd Bergmann

Add sysirq settings for mt6589/mt8135/mt8127
This also correct timer interrupt flag. The old setting works
because boot loader already set polarity for timer interrupt.
Without intpol support, the setting was not changed so gic
can get the irq correctly.

Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
---
 arch/arm/boot/dts/mt6589.dtsi | 14 ++++++++++++--
 arch/arm/boot/dts/mt8127.dtsi | 14 ++++++++++++--
 arch/arm/boot/dts/mt8135.dtsi | 14 ++++++++++++--
 3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/mt6589.dtsi b/arch/arm/boot/dts/mt6589.dtsi
index e3c7600..c91b2a9 100644
--- a/arch/arm/boot/dts/mt6589.dtsi
+++ b/arch/arm/boot/dts/mt6589.dtsi
@@ -19,7 +19,7 @@
 
 / {
 	compatible = "mediatek,mt6589";
-	interrupt-parent = <&gic>;
+	interrupt-parent = <&sysirq>;
 
 	cpus {
 		#address-cells = <1>;
@@ -76,15 +76,25 @@
 		timer: timer@10008000 {
 			compatible = "mediatek,mt6577-timer";
 			reg = <0x10008000 0x80>;
-			interrupts = <GIC_SPI 113 IRQ_TYPE_EDGE_RISING>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>;
 			clocks = <&system_clk>, <&rtc_clk>;
 			clock-names = "system-clk", "rtc-clk";
 		};
 
+		sysirq: interrupt-controller@10200100 {
+			compatible = "mediatek,mt6589-sysirq",
+				     "mediatek,mt6577-sysirq";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
+			reg = <0x10200100 0x1c>;
+		};
+
 		gic: interrupt-controller@10211000 {
 			compatible = "arm,cortex-a7-gic";
 			interrupt-controller;
 			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
 			reg = <0x10211000 0x1000>,
 			      <0x10212000 0x1000>,
 			      <0x10214000 0x2000>,
diff --git a/arch/arm/boot/dts/mt8127.dtsi b/arch/arm/boot/dts/mt8127.dtsi
index 249c218..59efb07 100644
--- a/arch/arm/boot/dts/mt8127.dtsi
+++ b/arch/arm/boot/dts/mt8127.dtsi
@@ -18,7 +18,7 @@
 
 / {
 	compatible = "mediatek,mt8127";
-	interrupt-parent = <&gic>;
+	interrupt-parent = <&sysirq>;
 
 	cpus {
 		#address-cells = <1>;
@@ -81,15 +81,25 @@
 		timer: timer@10008000 {
 			compatible = "mediatek,mt8127-timer", "mediatek,mt6577-timer";
 			reg = <0 0x10008000 0 0x80>;
-			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
 			clocks = <&system_clk>, <&rtc_clk>;
 			clock-names = "system-clk", "rtc-clk";
 		};
 
+		sysirq: interrupt-controller@10200100 {
+			compatible = "mediatek,mt8127-sysirq",
+				     "mediatek,mt6577-sysirq";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
+			reg = <0 0x10200100 0 0x1c>;
+		};
+
 		gic: interrupt-controller@10211000 {
 			compatible = "arm,cortex-a7-gic";
 			interrupt-controller;
 			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
 			reg = <0 0x10211000 0 0x1000>,
 			      <0 0x10212000 0 0x1000>,
 			      <0 0x10214000 0 0x2000>,
diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi
index 683b761..2b6d5c8 100644
--- a/arch/arm/boot/dts/mt8135.dtsi
+++ b/arch/arm/boot/dts/mt8135.dtsi
@@ -18,7 +18,7 @@
 
 / {
 	compatible = "mediatek,mt8135";
-	interrupt-parent = <&gic>;
+	interrupt-parent = <&sysirq>;
 
 	cpu-map {
 		cluster0 {
@@ -104,15 +104,25 @@
 		timer: timer@10008000 {
 			compatible = "mediatek,mt8135-timer", "mediatek,mt6577-timer";
 			reg = <0 0x10008000 0 0x80>;
-			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>;
 			clocks = <&system_clk>, <&rtc_clk>;
 			clock-names = "system-clk", "rtc-clk";
 		};
 
+		sysirq: interrupt-controller@10200030 {
+			compatible = "mediatek,mt8135-sysirq",
+				     "mediatek,mt6577-sysirq";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
+			reg = <0 0x10200030 0 0x1c>;
+		};
+
 		gic: interrupt-controller@10211000 {
 			compatible = "arm,cortex-a15-gic";
 			interrupt-controller;
 			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
 			reg = <0 0x10211000 0 0x1000>,
 			      <0 0x10212000 0 0x1000>,
 			      <0 0x10214000 0 0x2000>,
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 6/6] dt-bindings: add bindings for mediatek sysirq
  2014-10-29 10:00 [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
                   ` (4 preceding siblings ...)
  2014-10-29 10:00 ` [PATCH v5 5/6] ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi Yingjoe Chen
@ 2014-10-29 10:00 ` Yingjoe Chen
  2014-11-09  5:38 ` [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Jason Cooper
  6 siblings, 0 replies; 12+ messages in thread
From: Yingjoe Chen @ 2014-10-29 10:00 UTC (permalink / raw)
  To: Matthias Brugger, Thomas Gleixner, Jiang Liu, Marc Zyngier, arm
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Jason Cooper, Benjamin Herrenschmidt, Yingjoe Chen,
	Grant Likely, Boris BREZILLON, devicetree, linux-kernel,
	linux-arm-kernel, srv_heupstream, yingjoe.chen, hc.yen,
	eddie.huang, nathan.chung, yh.chen, Sascha Hauer, Olof Johansson,
	Arnd Bergmann

Add binding documentation for Mediatek SoC SYSIRQ.

Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
---
 .../bindings/arm/mediatek/mediatek,sysirq.txt      | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt
new file mode 100644
index 0000000..8669536
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt
@@ -0,0 +1,26 @@
+Mediatek 65xx/81xx sysirq
+
+Mediatek SOCs sysirq support controllable irq inverter for each GIC SPI
+interrupt.
+
+Required properties:
+- compatible: should be one of:
+	"mediatek,mt8135-sysirq"
+	"mediatek,mt8127-sysirq"
+	"mediatek,mt6589-sysirq"
+	"mediatek,mt6582-sysirq"
+	"mediatek,mt6577-sysirq"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Must use the same cells/format as parent controller.
+- interrupt-parent: phandle of irq domain parent for sysirq.
+- reg: Physical base address of the intpol registers and length of memory
+  mapped region.
+
+Example:
+	sysirq: interrupt-controller@10200100 {
+		compatible = "mediatek,mt6589-sysirq", "mediatek,mt6577-sysirq";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		interrupt-parent = <&gic>;
+		reg = <0 0x10200100 0 0x1c>;
+	};
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 4/6] ARM: mediatek: Add sysirq interrupt polarity support
       [not found]   ` <1414576824-16143-5-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
@ 2014-11-04  7:04     ` Yingjoe Chen
  0 siblings, 0 replies; 12+ messages in thread
From: Yingjoe Chen @ 2014-11-04  7:04 UTC (permalink / raw)
  To: Matthias Brugger, Thomas Gleixner, Marc Zyngier,
	arm-DgEjT+Ai2ygdnm+yROfE0A
  Cc: Jiang Liu, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King, Jason Cooper, Benjamin Herrenschmidt,
	Grant Likely, Boris BREZILLON, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
	yingjoe.chen-Re5JQEeQqe8AvxtiuMwx3w,
	hc.yen-NuS5LvNUpcJWk0Htik3J/w, eddie.huang-NuS5LvNUpcJWk0Htik3J/w,
	nathan.chung-NuS5LvNUpcJWk0Htik3J/w,
	yh.chen-NuS5LvNUpcJWk0Htik3J/w, Sascha Hauer, Olof Johansson,
	Arnd Bergmann

On Wed, 2014-10-29 at 18:00 +0800, Yingjoe Chen wrote:
> diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
> new file mode 100644
> index 0000000..4403bcf
> --- /dev/null
> +++ b/drivers/irqchip/irq-mtk-sysirq.c
> +static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> +				   unsigned int nr_irqs, void *arg)
> +{
> +	int i, ret;
> +	irq_hw_number_t hwirq;
> +	struct of_phandle_args *irq_data = arg;
> +
> +	if (irq_data->args_count < 3)
> +		return -EINVAL;
> +
> +	hwirq = irq_data->args[1];
> +	for (i = 0; i < nr_irqs; i++)
> +		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
> +					      &mtk_sysirq_chip,
> +					      domain->host_data);
> +
> +	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
> +}

(answering my own patch)
The ret is not used in this function. I'll remove it in next version.

Besides this, is there anything that should be changed in this series?

Joe.C


--
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] 12+ messages in thread

* Re: [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity
  2014-10-29 10:00 [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
                   ` (5 preceding siblings ...)
  2014-10-29 10:00 ` [PATCH v5 6/6] dt-bindings: add bindings for mediatek sysirq Yingjoe Chen
@ 2014-11-09  5:38 ` Jason Cooper
  2014-11-11 11:35   ` Thomas Gleixner
  6 siblings, 1 reply; 12+ messages in thread
From: Jason Cooper @ 2014-11-09  5:38 UTC (permalink / raw)
  To: Yingjoe Chen, Thomas Gleixner, Marc Zyngier
  Cc: Matthias Brugger, Jiang Liu, arm, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
	Benjamin Herrenschmidt, Grant Likely, Boris BREZILLON, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, yingjoe.chen,
	hc.yen, eddie.huang, nathan.chung, yh.chen, Sascha Hauer,
	Olof Johansson, Arnd Bergmann

Thomas, Marc,

Could I get Acks for the core changes and gic changes when you have
a moment?

thx,

Jason.

On Wed, Oct 29, 2014 at 06:00:18PM +0800, Yingjoe Chen wrote:
> This series is 5th version of interrupt polarity support for MediaTek SoCs.
> This is based on Jiang's hierarchy irqdomain p2v3 [1], which is based on 
> v3.18-rc2, and my mediatek SoC basic support [2].
> 
> Besides changing base, this version addressed comments from Thomas and Marc
> and also fix a bug on mt6589 reported by Matthias.
> 
> In Jiang's version of irq_create_of_mapping, if irqdomain is hierarchy, it
> will not perform irq_find_mapping check and set_type. The outermost
> irqdomain need to take care of that. Because we will have several different
> outermost irqdomain in different ARM SoCs, this cause code duplication. I
> moved them back to irq_create_of_mapping.
> 
> Simplified block diagram for interrupt on my system:
> 
>     +-------+      +-------+
>  ---| SYSIRQ|------|ARM GIC|
>  ---|       |------|       |
>  ---|       |------|       |
>  ---|       |------|       |
>  ---|       |------|       |
>     +-------+      +-------+
> 
> In device tree, interrupt-parent for other devices is sysirq, child of gic.
> This describe HW better and allow device to specify polarity as it is sent
> by the device.
> 
> When using hierarchy irq domain, gic will use irq_domain_add_linear to
> create irqdomain and all interrupt numbers must come from device tree. My
> /proc/interrupts looks like this now:
> 
> # cat /proc/interrupts
>            CPU0
>  16:     149578  MT_SYSIRQ 113  mtk_timer
>  20:       1082  MT_SYSIRQ  54  serial
> 
> Changes in v5:
>  - Fix bug on mt6589 reported by Matthias
>  - Fix bug for irq_find_mapping in irq_create_of_mapping
>  - Merge Marc's change to proper handle non-DT case in gic_init_bases
> 
> Changes in v4:
>  - Discussed in [3]
>  - Remove arm,hierarchy-irq-domain. When GIC is probed by DT, it will
> support hierarchy irqdomain.
> 
> Changes in v3:
>  - Discussed in [4]
>  - First implementation using hierarchy irqdomain
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/297624.html
> [2] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/296093.html
> [3] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/296911.html
> [4] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/293766.html
> 
> 
> Yingjoe Chen (6):
>   irqdomain: do irq_find_mapping and set_type for hierarchy irqdomain
>   genirq: Add more helper functions to support stacked irq_chip
>   irqchip: gic: Support hierarchy irq domain.
>   ARM: mediatek: Add sysirq interrupt polarity support
>   ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi
>   dt-bindings: add bindings for mediatek sysirq
> 
>  .../bindings/arm/mediatek/mediatek,sysirq.txt      |  26 ++++
>  arch/arm/boot/dts/mt6589.dtsi                      |  14 +-
>  arch/arm/boot/dts/mt8127.dtsi                      |  14 +-
>  arch/arm/boot/dts/mt8135.dtsi                      |  14 +-
>  drivers/irqchip/Kconfig                            |   1 +
>  drivers/irqchip/Makefile                           |   1 +
>  drivers/irqchip/irq-gic.c                          |  90 +++++++----
>  drivers/irqchip/irq-mtk-sysirq.c                   | 168 +++++++++++++++++++++
>  include/linux/irq.h                                |   6 +
>  kernel/irq/chip.c                                  |  28 ++++
>  kernel/irq/irqdomain.c                             |  27 ++--
>  11 files changed, 348 insertions(+), 41 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt
>  create mode 100644 drivers/irqchip/irq-mtk-sysirq.c
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 3/6] irqchip: gic: Support hierarchy irq domain.
  2014-10-29 10:00 ` [PATCH v5 3/6] irqchip: gic: Support hierarchy irq domain Yingjoe Chen
@ 2014-11-09  7:04   ` Jiang Liu
  0 siblings, 0 replies; 12+ messages in thread
From: Jiang Liu @ 2014-11-09  7:04 UTC (permalink / raw)
  To: Yingjoe Chen, Matthias Brugger, Thomas Gleixner, Marc Zyngier,
	arm
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Jason Cooper, Benjamin Herrenschmidt, Grant Likely,
	Boris BREZILLON, devicetree, linux-kernel, linux-arm-kernel,
	srv_heupstream, yingjoe.chen, hc.yen, eddie.huang, nathan.chung,
	yh.chen, Sascha Hauer, Olof Johansson, Arnd Bergmann



On 2014/10/29 18:00, Yingjoe Chen wrote:
> Add support to use gic as a parent for stacked irq domain.
> 
> Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
> ---
>  drivers/irqchip/Kconfig   |  1 +
>  drivers/irqchip/irq-gic.c | 90 +++++++++++++++++++++++++++++++++--------------
>  2 files changed, 65 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index b21f12f..7f34138 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -5,6 +5,7 @@ config IRQCHIP
>  config ARM_GIC
>  	bool
>  	select IRQ_DOMAIN
> +	select IRQ_DOMAIN_HIERARCHY
>  	select MULTI_IRQ_HANDLER
>  
>  config GIC_NON_BANKED
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 38493ff..6f39bef 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -786,19 +786,17 @@ void __init gic_init_physaddr(struct device_node *node)
>  static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
>  				irq_hw_number_t hw)
>  {
> +	irq_domain_set_hwirq_and_chip(d, irq, hw, &gic_chip, d->host_data);
>  	if (hw < 32) {
>  		irq_set_percpu_devid(irq);
> -		irq_set_chip_and_handler(irq, &gic_chip,
> -					 handle_percpu_devid_irq);
> +		irq_set_handler(irq, handle_percpu_devid_irq);
Hi Joe,
	This may trigger a warning when dealing with hierarchy
irqdomain as below. It's because the child domain hasn't set
irq_data->chip yet when parent domain's gic_irq_domain_map() gets
called. We may need to relax the WARNING_ON() in  __irq_set_handler().
    WARN_ON(desc->irq_data.chip == &no_irq_chip)

------------[ cut here ]------------
WARNING: CPU: 2 PID: 912 at kernel/irq/chip.c:734
__irq_set_handler+0x138/0x13c()
Modules linked in: mlx4_core(+) rtc_efi efivarfs
CPU: 2 PID: 912 Comm: modprobe Not tainted 3.18.0-rc3-p2v5+ #53
Call trace:
[<fffffe00000963d4>] dump_backtrace+0x0/0x16c
[<fffffe0000096550>] show_stack+0x10/0x1c
[<fffffe000067545c>] dump_stack+0x74/0x98
[<fffffe00000b205c>] warn_slowpath_common+0x84/0xac
[<fffffe00000b2148>] warn_slowpath_null+0x14/0x20
[<fffffe00000ed968>] __irq_set_handler+0x134/0x13c
[<fffffe000042af14>] gic_irq_domain_map+0x4c/0xac
[<fffffe000042afd4>] gic_irq_domain_alloc+0x60/0x88
[<fffffe000042b374>] gicv2m_domain_alloc+0x30/0xa8
[<fffffe00000efc1c>] __irq_domain_alloc_irqs+0x144/0x30c
[<fffffe000042b58c>] gicv2m_setup_msi_irq+0xc0/0x118
[<fffffe000044548c>] arch_setup_msi_irq+0x34/0x60
[<fffffe0000445544>] arch_setup_msi_irqs+0x50/0xb0
[<fffffe0000445e3c>] pci_enable_msix+0x310/0x39c
[<fffffe0000445efc>] pci_enable_msix_range+0x34/0x9c
>  		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
>  	} else {
> -		irq_set_chip_and_handler(irq, &gic_chip,
> -					 handle_fasteoi_irq);
> +		irq_set_handler(irq, handle_fasteoi_irq);
>  		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
>  
>  		gic_routable_irq_domain_ops->map(d, irq, hw);
>  	}
> -	irq_set_chip_data(irq, d->host_data);
>  	return 0;
>  }
>  
> @@ -814,8 +812,6 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
>  {
>  	unsigned long ret = 0;
>  
> -	if (d->of_node != controller)
> -		return -EINVAL;
>  	if (intsize < 3)
>  		return -EINVAL;
>  
> @@ -858,6 +854,42 @@ static struct notifier_block gic_cpu_notifier = {
>  };
>  #endif
>  
> +static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> +				unsigned int nr_irqs, void *arg)
> +{
> +	int i, ret;
> +	irq_hw_number_t hwirq;
> +	unsigned int type = IRQ_TYPE_NONE;
> +	struct of_phandle_args *irq_data = arg;
> +
> +	ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
> +				   irq_data->args_count, &hwirq, &type);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; i < nr_irqs; i++)
> +		gic_irq_domain_map(domain, virq+i, hwirq+i);
> +
> +	return 0;
> +}
> +
> +static void gic_irq_domain_free(struct irq_domain *domain, unsigned int virq,
> +				unsigned int nr_irqs)
> +{
> +	int i;
> +
> +	for (i = 0; i < nr_irqs; i++) {
> +		irq_set_handler(virq + i, NULL);
> +		irq_domain_set_hwirq_and_chip(domain, virq + i, 0, NULL, NULL);
> +	}
> +}
> +
> +static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = {
> +	.xlate = gic_irq_domain_xlate,
> +	.alloc = gic_irq_domain_alloc,
> +	.free = gic_irq_domain_free,
> +};
> +
>  static const struct irq_domain_ops gic_irq_domain_ops = {
>  	.map = gic_irq_domain_map,
>  	.unmap = gic_irq_domain_unmap,
> @@ -948,18 +980,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  		gic_cpu_map[i] = 0xff;
>  
>  	/*
> -	 * For primary GICs, skip over SGIs.
> -	 * For secondary GICs, skip over PPIs, too.
> -	 */
> -	if (gic_nr == 0 && (irq_start & 31) > 0) {
> -		hwirq_base = 16;
> -		if (irq_start != -1)
> -			irq_start = (irq_start & ~31) + 16;
> -	} else {
> -		hwirq_base = 32;
> -	}
> -
> -	/*
>  	 * Find out how many interrupts are supported.
>  	 * The GIC only supports up to 1020 interrupt sources.
>  	 */
> @@ -969,10 +989,32 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  		gic_irqs = 1020;
>  	gic->gic_irqs = gic_irqs;
>  
> -	gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
> +	if (node) {		/* DT case */
> +		const struct irq_domain_ops *ops =
> +					&gic_irq_domain_hierarchy_ops;
> +
> +		if (!of_property_read_u32(node, "arm,routable-irqs",
> +					  &nr_routable_irqs)) {
> +			ops = &gic_irq_domain_ops;
> +			gic_irqs = nr_routable_irqs;
> +		}
> +
> +		gic->domain = irq_domain_add_linear(node, gic_irqs, ops, gic);
> +	} else {		/* Non-DT case */
> +		/*
> +		 * For primary GICs, skip over SGIs.
> +		 * For secondary GICs, skip over PPIs, too.
> +		 */
> +		if (gic_nr == 0 && (irq_start & 31) > 0) {
> +			hwirq_base = 16;
> +			if (irq_start != -1)
> +				irq_start = (irq_start & ~31) + 16;
> +		} else {
> +			hwirq_base = 32;
> +		}
> +
> +		gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
>  
> -	if (of_property_read_u32(node, "arm,routable-irqs",
> -				 &nr_routable_irqs)) {
>  		irq_base = irq_alloc_descs(irq_start, 16, gic_irqs,
>  					   numa_node_id());
>  		if (IS_ERR_VALUE(irq_base)) {
> @@ -983,10 +1025,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  
>  		gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
>  					hwirq_base, &gic_irq_domain_ops, gic);
> -	} else {
> -		gic->domain = irq_domain_add_linear(node, nr_routable_irqs,
> -						    &gic_irq_domain_ops,
> -						    gic);
>  	}
>  
>  	if (WARN_ON(!gic->domain))
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity
  2014-11-09  5:38 ` [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Jason Cooper
@ 2014-11-11 11:35   ` Thomas Gleixner
  2014-11-11 11:41     ` Jiang Liu
  0 siblings, 1 reply; 12+ messages in thread
From: Thomas Gleixner @ 2014-11-11 11:35 UTC (permalink / raw)
  To: Jason Cooper
  Cc: Yingjoe Chen, Marc Zyngier, Matthias Brugger, Jiang Liu, arm,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, Benjamin Herrenschmidt, Grant Likely,
	Boris BREZILLON, devicetree, linux-kernel, linux-arm-kernel,
	srv_heupstream, yingjoe.chen, hc.yen, eddie.huang, nathan.chung,
	yh.chen, Sascha Hauer, Olof Johansson

On Sun, 9 Nov 2014, Jason Cooper wrote:

> Thomas, Marc,
> 
> Could I get Acks for the core changes and gic changes when you have
> a moment?

this depends on the core irqdomain changes which are not yet in
tip. I'm waiting for Jiangs latest iteration and Marcs feedback on
those.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity
  2014-11-11 11:35   ` Thomas Gleixner
@ 2014-11-11 11:41     ` Jiang Liu
  0 siblings, 0 replies; 12+ messages in thread
From: Jiang Liu @ 2014-11-11 11:41 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper
  Cc: Yingjoe Chen, Marc Zyngier, Matthias Brugger, arm, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
	Benjamin Herrenschmidt, Grant Likely, Boris BREZILLON, devicetree,
	linux-kernel, linux-arm-kernel, srv_heupstream, yingjoe.chen,
	hc.yen, eddie.huang, nathan.chung, yh.chen, Sascha Hauer,
	Olof Johansson, Arnd Bergmann



On 2014/11/11 19:35, Thomas Gleixner wrote:
> On Sun, 9 Nov 2014, Jason Cooper wrote:
> 
>> Thomas, Marc,
>>
>> Could I get Acks for the core changes and gic changes when you have
>> a moment?
> 
> this depends on the core irqdomain changes which are not yet in
> tip. I'm waiting for Jiangs latest iteration and Marcs feedback on
> those.
Hi Thomas,
	Sorry for dealy:)
	I think my previous version is good for merging. I only need to
update one patch to address a possible conflict on other architectures.
I'm testing the patch and should send it out soon.
Regards!
Gerry

> 
> Thanks,
> 
> 	tglx
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-11-11 11:41 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-29 10:00 [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
     [not found] ` <1414576824-16143-1-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
2014-10-29 10:00   ` [PATCH v5 1/6] irqdomain: do irq_find_mapping and set_type for hierarchy irqdomain Yingjoe Chen
2014-10-29 10:00 ` [PATCH v5 2/6] genirq: Add more helper functions to support stacked irq_chip Yingjoe Chen
2014-10-29 10:00 ` [PATCH v5 3/6] irqchip: gic: Support hierarchy irq domain Yingjoe Chen
2014-11-09  7:04   ` Jiang Liu
2014-10-29 10:00 ` [PATCH v5 4/6] ARM: mediatek: Add sysirq interrupt polarity support Yingjoe Chen
     [not found]   ` <1414576824-16143-5-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
2014-11-04  7:04     ` Yingjoe Chen
2014-10-29 10:00 ` [PATCH v5 5/6] ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi Yingjoe Chen
2014-10-29 10:00 ` [PATCH v5 6/6] dt-bindings: add bindings for mediatek sysirq Yingjoe Chen
2014-11-09  5:38 ` [PATCH v5 0/6] ARM: mediatek: Add support for interrupt polarity Jason Cooper
2014-11-11 11:35   ` Thomas Gleixner
2014-11-11 11:41     ` Jiang Liu

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).