diff options
Diffstat (limited to 'target/linux/lantiq/patches-3.8/0019-MIPS-lantiq-rework-external-irq-code.patch')
-rw-r--r-- | target/linux/lantiq/patches-3.8/0019-MIPS-lantiq-rework-external-irq-code.patch | 209 |
1 files changed, 0 insertions, 209 deletions
diff --git a/target/linux/lantiq/patches-3.8/0019-MIPS-lantiq-rework-external-irq-code.patch b/target/linux/lantiq/patches-3.8/0019-MIPS-lantiq-rework-external-irq-code.patch deleted file mode 100644 index c78d738..0000000 --- a/target/linux/lantiq/patches-3.8/0019-MIPS-lantiq-rework-external-irq-code.patch +++ /dev/null @@ -1,209 +0,0 @@ -From d8f6bf3fb606ee8fdd5b7aff4aedb54e30792b84 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Sat, 19 Jan 2013 08:54:27 +0000 -Subject: [PATCH 19/40] MIPS: lantiq: rework external irq code - -This code makes the irqs used by the EIU loadable from the DT. Additionally we -add a helper that allows the pinctrl layer to map external irqs to real irq -numbers. - -Signed-off-by: John Crispin <blogic@openwrt.org> -Patchwork: http://patchwork.linux-mips.org/patch/4818/ ---- - arch/mips/include/asm/mach-lantiq/lantiq.h | 1 + - arch/mips/lantiq/irq.c | 105 +++++++++++++++++++--------- - 2 files changed, 74 insertions(+), 32 deletions(-) - ---- a/arch/mips/include/asm/mach-lantiq/lantiq.h -+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h -@@ -34,6 +34,7 @@ extern spinlock_t ebu_lock; - extern void ltq_disable_irq(struct irq_data *data); - extern void ltq_mask_and_ack_irq(struct irq_data *data); - extern void ltq_enable_irq(struct irq_data *data); -+extern int ltq_eiu_get_irq(int exin); - - /* clock handling */ - extern int clk_activate(struct clk *clk); ---- a/arch/mips/lantiq/irq.c -+++ b/arch/mips/lantiq/irq.c -@@ -33,17 +33,10 @@ - /* register definitions - external irqs */ - #define LTQ_EIU_EXIN_C 0x0000 - #define LTQ_EIU_EXIN_INIC 0x0004 -+#define LTQ_EIU_EXIN_INC 0x0008 - #define LTQ_EIU_EXIN_INEN 0x000C - --/* irq numbers used by the external interrupt unit (EIU) */ --#define LTQ_EIU_IR0 (INT_NUM_IM4_IRL0 + 30) --#define LTQ_EIU_IR1 (INT_NUM_IM3_IRL0 + 31) --#define LTQ_EIU_IR2 (INT_NUM_IM1_IRL0 + 26) --#define LTQ_EIU_IR3 INT_NUM_IM1_IRL0 --#define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1) --#define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2) --#define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30) --#define XWAY_EXIN_COUNT 3 -+/* number of external interrupts */ - #define MAX_EIU 6 - - /* the performance counter */ -@@ -72,20 +65,19 @@ - int gic_present; - #endif - --static unsigned short ltq_eiu_irq[MAX_EIU] = { -- LTQ_EIU_IR0, -- LTQ_EIU_IR1, -- LTQ_EIU_IR2, -- LTQ_EIU_IR3, -- LTQ_EIU_IR4, -- LTQ_EIU_IR5, --}; -- - static int exin_avail; -+static struct resource ltq_eiu_irq[MAX_EIU]; - static void __iomem *ltq_icu_membase[MAX_IM]; - static void __iomem *ltq_eiu_membase; - static struct irq_domain *ltq_domain; - -+int ltq_eiu_get_irq(int exin) -+{ -+ if (exin < exin_avail) -+ return ltq_eiu_irq[exin].start; -+ return -1; -+} -+ - void ltq_disable_irq(struct irq_data *d) - { - u32 ier = LTQ_ICU_IM0_IER; -@@ -128,19 +120,65 @@ void ltq_enable_irq(struct irq_data *d) - ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier); - } - -+static int ltq_eiu_settype(struct irq_data *d, unsigned int type) -+{ -+ int i; -+ -+ for (i = 0; i < MAX_EIU; i++) { -+ if (d->hwirq == ltq_eiu_irq[i].start) { -+ int val = 0; -+ int edge = 0; -+ -+ switch (type) { -+ case IRQF_TRIGGER_NONE: -+ break; -+ case IRQF_TRIGGER_RISING: -+ val = 1; -+ edge = 1; -+ break; -+ case IRQF_TRIGGER_FALLING: -+ val = 2; -+ edge = 1; -+ break; -+ case IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING: -+ val = 3; -+ edge = 1; -+ break; -+ case IRQF_TRIGGER_HIGH: -+ val = 5; -+ break; -+ case IRQF_TRIGGER_LOW: -+ val = 6; -+ break; -+ default: -+ pr_err("invalid type %d for irq %ld\n", -+ type, d->hwirq); -+ return -EINVAL; -+ } -+ -+ if (edge) -+ irq_set_handler(d->hwirq, handle_edge_irq); -+ -+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | -+ (val << (i * 4)), LTQ_EIU_EXIN_C); -+ } -+ } -+ -+ return 0; -+} -+ - static unsigned int ltq_startup_eiu_irq(struct irq_data *d) - { - int i; - - ltq_enable_irq(d); - for (i = 0; i < MAX_EIU; i++) { -- if (d->hwirq == ltq_eiu_irq[i]) { -- /* low level - we should really handle set_type */ -- ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | -- (0x6 << (i * 4)), LTQ_EIU_EXIN_C); -+ if (d->hwirq == ltq_eiu_irq[i].start) { -+ /* by default we are low level triggered */ -+ ltq_eiu_settype(d, IRQF_TRIGGER_LOW); - /* clear all pending */ -- ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~BIT(i), -- LTQ_EIU_EXIN_INIC); -+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INC) & ~BIT(i), -+ LTQ_EIU_EXIN_INC); - /* enable */ - ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i), - LTQ_EIU_EXIN_INEN); -@@ -157,7 +195,7 @@ static void ltq_shutdown_eiu_irq(struct - - ltq_disable_irq(d); - for (i = 0; i < MAX_EIU; i++) { -- if (d->hwirq == ltq_eiu_irq[i]) { -+ if (d->hwirq == ltq_eiu_irq[i].start) { - /* disable */ - ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i), - LTQ_EIU_EXIN_INEN); -@@ -186,6 +224,7 @@ static struct irq_chip ltq_eiu_type = { - .irq_ack = ltq_ack_irq, - .irq_mask = ltq_disable_irq, - .irq_mask_ack = ltq_mask_and_ack_irq, -+ .irq_set_type = ltq_eiu_settype, - }; - - static void ltq_hw_irqdispatch(int module) -@@ -301,7 +340,7 @@ static int icu_map(struct irq_domain *d, - return 0; - - for (i = 0; i < exin_avail; i++) -- if (hw == ltq_eiu_irq[i]) -+ if (hw == ltq_eiu_irq[i].start) - chip = <q_eiu_type; - - irq_set_chip_and_handler(hw, chip, handle_level_irq); -@@ -323,7 +362,7 @@ int __init icu_of_init(struct device_nod - { - struct device_node *eiu_node; - struct resource res; -- int i; -+ int i, ret; - - for (i = 0; i < MAX_IM; i++) { - if (of_address_to_resource(node, i, &res)) -@@ -340,17 +379,19 @@ int __init icu_of_init(struct device_nod - } - - /* the external interrupts are optional and xway only */ -- eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu"); -+ eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway"); - if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { - /* find out how many external irq sources we have */ -- const __be32 *count = of_get_property(node, -- "lantiq,count", NULL); -+ exin_avail = of_irq_count(eiu_node); - -- if (count) -- exin_avail = *count; - if (exin_avail > MAX_EIU) - exin_avail = MAX_EIU; - -+ ret = of_irq_to_resource_table(eiu_node, -+ ltq_eiu_irq, exin_avail); -+ if (ret != exin_avail) -+ panic("failed to load external irq resources\n"); -+ - if (request_mem_region(res.start, resource_size(&res), - res.name) < 0) - pr_err("Failed to request eiu memory"); |