lantiq: add v3.10 patches
[openwrt.git] / target / linux / lantiq / patches-3.8 / 0019-MIPS-lantiq-rework-external-irq-code.patch
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 (file)
index c78d738..0000000
+++ /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 = &ltq_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");