* [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity
@ 2014-11-13 15:37 Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 1/6] irqdomain: Use consistent prototype for irq_domain_free_irqs_* Yingjoe Chen
` (6 more replies)
0 siblings, 7 replies; 10+ messages in thread
From: Yingjoe Chen @ 2014-11-13 15:37 UTC (permalink / raw)
To: Thomas Gleixner, Jiang Liu, Marc Zyngier
Cc: Rob Herring, Pawel Moll, Mark Rutland, Matthias Brugger,
Russell King, Jason Cooper, Yingjoe Chen, Grant Likely,
Boris BREZILLON, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Bjorn Helgaas,
Yijing Wang, 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
This series is 6th version of interrupt polarity support for MediaTek SoCs.
This is based on tip/irq/irqdomain[1] and my mediatek SoC basic support[2].
In this version, I added a minor fix to irqdomain as first patch. Patch 3,
4 are changed to use newly added helper functions. The other patches are
unchanged.
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 v6:
- Rebased to tip/irq/irqdomain [1]
Changes in v5:
- Discussed in [3]
- 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 [4]
- Remove arm,hierarchy-irq-domain. When GIC is probed by DT, it will
support hierarchy irqdomain.
Changes in v3:
- Discussed in [5]
- 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/298161.html
[4] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/296911.html
[5] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/293766.html
Yingjoe Chen (6):
irqdomain: Use consistent prototype for irq_domain_free_irqs_*
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 | 80 +++++++----
drivers/irqchip/irq-mtk-sysirq.c | 156 +++++++++++++++++++++
include/linux/irq.h | 6 +
include/linux/irqdomain.h | 8 +-
kernel/irq/chip.c | 28 ++++
kernel/irq/irqdomain.c | 8 +-
12 files changed, 317 insertions(+), 39 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt
create mode 100644 drivers/irqchip/irq-mtk-sysirq.c
--
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 [flat|nested] 10+ messages in thread
* [PATCH v6 1/6] irqdomain: Use consistent prototype for irq_domain_free_irqs_*
2014-11-13 15:37 [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
@ 2014-11-13 15:37 ` Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 2/6] genirq: Add more helper functions to support stacked irq_chip Yingjoe Chen
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Yingjoe Chen @ 2014-11-13 15:37 UTC (permalink / raw)
To: Thomas Gleixner, Jiang Liu, Marc Zyngier
Cc: Rob Herring, Pawel Moll, Mark Rutland, Matthias Brugger,
Russell King, Jason Cooper, Yingjoe Chen, Grant Likely,
Boris BREZILLON, devicetree, linux-kernel, linux-arm-kernel,
Bjorn Helgaas, Yijing Wang, srv_heupstream, yingjoe.chen, hc.yen,
eddie.huang, nathan.chung, yh.chen, Sascha Hauer
When using irq_domain_free_irqs_top() directly in irq_domain_ops, gcc
generate the following warnings:
../drivers/irqchip/irq-gic.c:879:2: warning: initialization from incompatible pointer type [enabled by default]
../drivers/irqchip/irq-gic.c:879:2: warning: (near initialization for 'gic_irq_domain_hierarchy_ops.free') [enabled by default]
Change to use consistent prototype for all irq_domain_free_irqs*
Better to fold this into "irqdomain: Introduce new interfaces to
support hierarchy irqdomains"
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
---
include/linux/irqdomain.h | 8 +++++---
kernel/irq/irqdomain.c | 8 ++++----
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 640a1ec..534dd72 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -270,9 +270,10 @@ extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
void *handler_data, const char *handler_name);
extern void irq_domain_reset_irq_data(struct irq_data *irq_data);
extern void irq_domain_free_irqs_common(struct irq_domain *domain,
- int virq, int nr_irqs);
+ unsigned int virq,
+ unsigned int nr_irqs);
extern void irq_domain_free_irqs_top(struct irq_domain *domain,
- int virq, int nr_irqs);
+ unsigned int virq, unsigned int nr_irqs);
static inline int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
int irq_base, unsigned int nr_irqs, void *arg)
@@ -284,7 +285,8 @@ static inline int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
}
static inline void irq_domain_free_irqs_parent(struct irq_domain *domain,
- int irq_base, unsigned int nr_irqs)
+ unsigned int irq_base,
+ unsigned int nr_irqs)
{
if (domain->parent && domain->parent->ops->free)
domain->parent->ops->free(domain->parent, irq_base, nr_irqs);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 8b0edde..705fb57 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -899,8 +899,8 @@ void irq_domain_reset_irq_data(struct irq_data *irq_data)
irq_data->chip_data = NULL;
}
-void irq_domain_free_irqs_common(struct irq_domain *domain, int virq,
- int nr_irqs)
+void irq_domain_free_irqs_common(struct irq_domain *domain, unsigned int virq,
+ unsigned int nr_irqs)
{
int i;
struct irq_data *irq_data;
@@ -913,8 +913,8 @@ void irq_domain_free_irqs_common(struct irq_domain *domain, int virq,
irq_domain_free_irqs_parent(domain, virq, nr_irqs);
}
-void irq_domain_free_irqs_top(struct irq_domain *domain, int virq,
- int nr_irqs)
+void irq_domain_free_irqs_top(struct irq_domain *domain, unsigned int virq,
+ unsigned int nr_irqs)
{
int i;
--
1.8.1.1.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v6 2/6] genirq: Add more helper functions to support stacked irq_chip
2014-11-13 15:37 [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 1/6] irqdomain: Use consistent prototype for irq_domain_free_irqs_* Yingjoe Chen
@ 2014-11-13 15:37 ` Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 3/6] irqchip: gic: Support hierarchy irq domain Yingjoe Chen
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Yingjoe Chen @ 2014-11-13 15:37 UTC (permalink / raw)
To: Thomas Gleixner, Jiang Liu, Marc Zyngier
Cc: Rob Herring, Pawel Moll, Mark Rutland, Matthias Brugger,
Russell King, Jason Cooper, Yingjoe Chen, Grant Likely,
Boris BREZILLON, devicetree, linux-kernel, linux-arm-kernel,
Bjorn Helgaas, Yijing Wang, srv_heupstream, yingjoe.chen, hc.yen,
eddie.huang, nathan.chung, yh.chen, Sascha Hauer
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 d88a28a..aa0703b 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -452,6 +452,12 @@ extern void handle_nested_irq(unsigned int irq);
extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg);
#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 8f362db..7abdef5 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] 10+ messages in thread
* [PATCH v6 3/6] irqchip: gic: Support hierarchy irq domain.
2014-11-13 15:37 [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 1/6] irqdomain: Use consistent prototype for irq_domain_free_irqs_* Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 2/6] genirq: Add more helper functions to support stacked irq_chip Yingjoe Chen
@ 2014-11-13 15:37 ` Yingjoe Chen
[not found] ` <1415893029-2971-4-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
2014-11-13 15:37 ` [PATCH v6 4/6] ARM: mediatek: Add sysirq interrupt polarity support Yingjoe Chen
` (3 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Yingjoe Chen @ 2014-11-13 15:37 UTC (permalink / raw)
To: Thomas Gleixner, Jiang Liu, Marc Zyngier
Cc: Rob Herring, Pawel Moll, Mark Rutland, Matthias Brugger,
Russell King, Jason Cooper, Yingjoe Chen, Grant Likely,
Boris BREZILLON, devicetree, linux-kernel, linux-arm-kernel,
Bjorn Helgaas, Yijing Wang, srv_heupstream, yingjoe.chen, hc.yen,
eddie.huang, nathan.chung, yh.chen, Sascha Hauer
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 | 80 ++++++++++++++++++++++++++++++++---------------
2 files changed, 55 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..fe9ab93 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -788,17 +788,16 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
{
if (hw < 32) {
irq_set_percpu_devid(irq);
- irq_set_chip_and_handler(irq, &gic_chip,
- handle_percpu_devid_irq);
+ irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
+ handle_percpu_devid_irq, NULL, NULL);
set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
} else {
- irq_set_chip_and_handler(irq, &gic_chip,
- handle_fasteoi_irq);
+ irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
+ handle_fasteoi_irq, NULL, NULL);
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 +813,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 +855,31 @@ 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 const struct irq_domain_ops gic_irq_domain_hierarchy_ops = {
+ .xlate = gic_irq_domain_xlate,
+ .alloc = gic_irq_domain_alloc,
+ .free = irq_domain_free_irqs_top,
+};
+
static const struct irq_domain_ops gic_irq_domain_ops = {
.map = gic_irq_domain_map,
.unmap = gic_irq_domain_unmap,
@@ -948,18 +970,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 +979,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 +1015,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] 10+ messages in thread
* [PATCH v6 4/6] ARM: mediatek: Add sysirq interrupt polarity support
2014-11-13 15:37 [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
` (2 preceding siblings ...)
2014-11-13 15:37 ` [PATCH v6 3/6] irqchip: gic: Support hierarchy irq domain Yingjoe Chen
@ 2014-11-13 15:37 ` Yingjoe Chen
[not found] ` <1415893029-2971-5-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
2014-11-13 15:37 ` [PATCH v6 5/6] ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi Yingjoe Chen
` (2 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Yingjoe Chen @ 2014-11-13 15:37 UTC (permalink / raw)
To: Thomas Gleixner, Jiang Liu, Marc Zyngier
Cc: Rob Herring, Pawel Moll, Mark Rutland, Matthias Brugger,
Russell King, Jason Cooper, Yingjoe Chen, Grant Likely,
Boris BREZILLON, devicetree, linux-kernel, linux-arm-kernel,
Bjorn Helgaas, Yijing Wang, srv_heupstream, yingjoe.chen, hc.yen,
eddie.huang, nathan.chung, yh.chen, Sascha Hauer
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 | 156 +++++++++++++++++++++++++++++++++++++++
2 files changed, 157 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..976b7eb
--- /dev/null
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -0,0 +1,156 @@
+/*
+ * 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;
+ 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 struct irq_domain_ops sysirq_domain_ops = {
+ .xlate = mtk_sysirq_domain_xlate,
+ .alloc = mtk_sysirq_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+};
+
+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] 10+ messages in thread
* [PATCH v6 5/6] ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi
2014-11-13 15:37 [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
` (3 preceding siblings ...)
2014-11-13 15:37 ` [PATCH v6 4/6] ARM: mediatek: Add sysirq interrupt polarity support Yingjoe Chen
@ 2014-11-13 15:37 ` Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 6/6] dt-bindings: add bindings for mediatek sysirq Yingjoe Chen
2014-11-14 11:13 ` [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Matthias Brugger
6 siblings, 0 replies; 10+ messages in thread
From: Yingjoe Chen @ 2014-11-13 15:37 UTC (permalink / raw)
To: Thomas Gleixner, Jiang Liu, Marc Zyngier
Cc: Rob Herring, Pawel Moll, Mark Rutland, Matthias Brugger,
Russell King, Jason Cooper, Yingjoe Chen, Grant Likely,
Boris BREZILLON, devicetree, linux-kernel, linux-arm-kernel,
Bjorn Helgaas, Yijing Wang, srv_heupstream, yingjoe.chen, hc.yen,
eddie.huang, nathan.chung, yh.chen, Sascha Hauer
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 c3ee060..49f5976 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>;
@@ -82,15 +82,25 @@
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 5faae6e..60338d9 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 {
@@ -105,15 +105,25 @@
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] 10+ messages in thread
* [PATCH v6 6/6] dt-bindings: add bindings for mediatek sysirq
2014-11-13 15:37 [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
` (4 preceding siblings ...)
2014-11-13 15:37 ` [PATCH v6 5/6] ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi Yingjoe Chen
@ 2014-11-13 15:37 ` Yingjoe Chen
2014-11-14 11:13 ` [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Matthias Brugger
6 siblings, 0 replies; 10+ messages in thread
From: Yingjoe Chen @ 2014-11-13 15:37 UTC (permalink / raw)
To: Thomas Gleixner, Jiang Liu, Marc Zyngier
Cc: Rob Herring, Pawel Moll, Mark Rutland, Matthias Brugger,
Russell King, Jason Cooper, Yingjoe Chen, Grant Likely,
Boris BREZILLON, devicetree, linux-kernel, linux-arm-kernel,
Bjorn Helgaas, Yijing Wang, srv_heupstream, yingjoe.chen, hc.yen,
eddie.huang, nathan.chung, yh.chen, Sascha Hauer
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] 10+ messages in thread
* Re: [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity
2014-11-13 15:37 [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
` (5 preceding siblings ...)
2014-11-13 15:37 ` [PATCH v6 6/6] dt-bindings: add bindings for mediatek sysirq Yingjoe Chen
@ 2014-11-14 11:13 ` Matthias Brugger
6 siblings, 0 replies; 10+ messages in thread
From: Matthias Brugger @ 2014-11-14 11:13 UTC (permalink / raw)
To: Yingjoe Chen
Cc: Thomas Gleixner, Jiang Liu, Marc Zyngier, Rob Herring, Pawel Moll,
Mark Rutland, Russell King, Jason Cooper, Grant Likely,
Boris BREZILLON, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Bjorn Helgaas, Yijing Wang,
srv_heupstream, Yingjoe Chen, HC Yen, huang eddie, Nathan Chung,
Yuhau Chen <yh>
2014-11-13 16:37 GMT+01:00 Yingjoe Chen <yingjoe.chen@mediatek.com>:
>
> This series is 6th version of interrupt polarity support for MediaTek SoCs.
> This is based on tip/irq/irqdomain[1] and my mediatek SoC basic support[2].
>
> In this version, I added a minor fix to irqdomain as first patch. Patch 3,
> 4 are changed to use newly added helper functions. The other patches are
> unchanged.
>
>
> 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
It works for me on mt6589.
Tested-by: Matthias Brugger <matthias.bgg@gmail.com>
>
> Changes in v6:
> - Rebased to tip/irq/irqdomain [1]
>
> Changes in v5:
> - Discussed in [3]
> - 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 [4]
> - Remove arm,hierarchy-irq-domain. When GIC is probed by DT, it will
> support hierarchy irqdomain.
>
> Changes in v3:
> - Discussed in [5]
> - 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/298161.html
> [4] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/296911.html
> [5] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/293766.html
>
>
> Yingjoe Chen (6):
> irqdomain: Use consistent prototype for irq_domain_free_irqs_*
> 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 | 80 +++++++----
> drivers/irqchip/irq-mtk-sysirq.c | 156 +++++++++++++++++++++
> include/linux/irq.h | 6 +
> include/linux/irqdomain.h | 8 +-
> kernel/irq/chip.c | 28 ++++
> kernel/irq/irqdomain.c | 8 +-
> 12 files changed, 317 insertions(+), 39 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt
> create mode 100644 drivers/irqchip/irq-mtk-sysirq.c
>
> --
> 1.8.1.1.dirty
>
--
motzblog.wordpress.com
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v6 3/6] irqchip: gic: Support hierarchy irq domain.
[not found] ` <1415893029-2971-4-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
@ 2014-11-14 18:30 ` Marc Zyngier
0 siblings, 0 replies; 10+ messages in thread
From: Marc Zyngier @ 2014-11-14 18:30 UTC (permalink / raw)
To: Yingjoe Chen
Cc: Thomas Gleixner, Jiang Liu, Rob Herring, Pawel Moll, Mark Rutland,
Matthias Brugger, Russell King, Jason Cooper,
grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
Boris BREZILLON,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Bjorn Helgaas, Yijing Wang,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org,
yingjoe.chen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
hc.yen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org,
"eddie.huang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org" <eddie.hua>
On 13/11/14 15:37, Yingjoe Chen wrote:
> Add support to use gic as a parent for stacked irq domain.
>
> Signed-off-by: Yingjoe Chen <yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
> drivers/irqchip/Kconfig | 1 +
> drivers/irqchip/irq-gic.c | 80 ++++++++++++++++++++++++++++++++---------------
> 2 files changed, 55 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..fe9ab93 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -788,17 +788,16 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
> {
> if (hw < 32) {
> irq_set_percpu_devid(irq);
> - irq_set_chip_and_handler(irq, &gic_chip,
> - handle_percpu_devid_irq);
> + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
> + handle_percpu_devid_irq, NULL, NULL);
> set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
> } else {
> - irq_set_chip_and_handler(irq, &gic_chip,
> - handle_fasteoi_irq);
> + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
> + handle_fasteoi_irq, NULL, NULL);
> 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 +813,6 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
> {
> unsigned long ret = 0;
>
> - if (d->of_node != controller)
> - return -EINVAL;
I'm not sure if removing that check is the right thing to do. You had to
remove it because your sysirq driver passes its own of_phandle_args
directly to the GIC code. I think that's a bad idea, and you should fix
the sysirq layer instead.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
--
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] 10+ messages in thread
* Re: [PATCH v6 4/6] ARM: mediatek: Add sysirq interrupt polarity support
[not found] ` <1415893029-2971-5-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
@ 2014-11-14 18:35 ` Marc Zyngier
0 siblings, 0 replies; 10+ messages in thread
From: Marc Zyngier @ 2014-11-14 18:35 UTC (permalink / raw)
To: Yingjoe Chen
Cc: Thomas Gleixner, Jiang Liu, Rob Herring, Pawel Moll, Mark Rutland,
Matthias Brugger, Russell King, Jason Cooper,
grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
Boris BREZILLON,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Bjorn Helgaas, Yijing Wang,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org,
yingjoe.chen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
hc.yen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org,
"eddie.huang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org" <eddie.hua>
On 13/11/14 15:37, Yingjoe Chen wrote:
> 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-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-mtk-sysirq.c | 156 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 157 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..976b7eb
> --- /dev/null
> +++ b/drivers/irqchip/irq-mtk-sysirq.c
> @@ -0,0 +1,156 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: Joe.C <yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> + *
> + * 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;
> + 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);
This is exactly why you have this hack in the GIC driver. I'd suggest
the following instead:
{
[...]
struct of_phandle_args *irq_data = arg;
struct of_phandle_args gic_data = *irq_data;
[...]
gic_data.np = domain->parent->of_node;
return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
&gic_data);
}
Thanks,
M.
--
Jazz is not dead. It just smells funny...
--
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] 10+ messages in thread
end of thread, other threads:[~2014-11-14 18:35 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-13 15:37 [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 1/6] irqdomain: Use consistent prototype for irq_domain_free_irqs_* Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 2/6] genirq: Add more helper functions to support stacked irq_chip Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 3/6] irqchip: gic: Support hierarchy irq domain Yingjoe Chen
[not found] ` <1415893029-2971-4-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
2014-11-14 18:30 ` Marc Zyngier
2014-11-13 15:37 ` [PATCH v6 4/6] ARM: mediatek: Add sysirq interrupt polarity support Yingjoe Chen
[not found] ` <1415893029-2971-5-git-send-email-yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
2014-11-14 18:35 ` Marc Zyngier
2014-11-13 15:37 ` [PATCH v6 5/6] ARM: mediatek: Add sysirq in mt6589/mt8135/mt8127 dtsi Yingjoe Chen
2014-11-13 15:37 ` [PATCH v6 6/6] dt-bindings: add bindings for mediatek sysirq Yingjoe Chen
2014-11-14 11:13 ` [PATCH v6 0/6] ARM: mediatek: Add support for interrupt polarity Matthias Brugger
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).