234 lines
6.6 KiB
Diff
234 lines
6.6 KiB
Diff
|
Index: linux-3.3.8/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||
|
===================================================================
|
||
|
--- linux-3.3.8.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2012-07-31 08:34:35.000000000 +0200
|
||
|
+++ linux-3.3.8/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2012-07-31 08:34:46.063369976 +0200
|
||
|
@@ -9,6 +9,8 @@
|
||
|
#ifndef _LANTIQ_XWAY_IRQ_H__
|
||
|
#define _LANTIQ_XWAY_IRQ_H__
|
||
|
|
||
|
+#define IM_NUM 5
|
||
|
+
|
||
|
#define INT_NUM_IRQ0 8
|
||
|
#define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0)
|
||
|
#define INT_NUM_IM1_IRL0 (INT_NUM_IRQ0 + 32)
|
||
|
Index: linux-3.3.8/arch/mips/lantiq/irq.c
|
||
|
===================================================================
|
||
|
--- linux-3.3.8.orig/arch/mips/lantiq/irq.c 2012-07-31 08:34:35.000000000 +0200
|
||
|
+++ linux-3.3.8/arch/mips/lantiq/irq.c 2012-07-31 08:51:40.203413329 +0200
|
||
|
@@ -48,8 +48,8 @@
|
||
|
*/
|
||
|
#define LTQ_ICU_EBU_IRQ 22
|
||
|
|
||
|
-#define ltq_icu_w32(x, y) ltq_w32((x), ltq_icu_membase + (y))
|
||
|
-#define ltq_icu_r32(x) ltq_r32(ltq_icu_membase + (x))
|
||
|
+#define ltq_icu_w32(x, y, m) ltq_w32((x), ltq_icu_membase[m] + (y))
|
||
|
+#define ltq_icu_r32(x, m) ltq_r32(ltq_icu_membase[m] + (x))
|
||
|
|
||
|
#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
|
||
|
#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
|
||
|
@@ -63,11 +63,78 @@
|
||
|
LTQ_EIU_IR5,
|
||
|
};
|
||
|
|
||
|
-static struct resource ltq_icu_resource = {
|
||
|
- .name = "icu",
|
||
|
- .start = LTQ_ICU_BASE_ADDR,
|
||
|
- .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1,
|
||
|
- .flags = IORESOURCE_MEM,
|
||
|
+static struct resource ltq_icu_resource[IM_NUM] = {
|
||
|
+{
|
||
|
+ .name = "icu_im0",
|
||
|
+ .start = LTQ_ICU_BASE_ADDR,
|
||
|
+ .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_OFFSET - 1,
|
||
|
+ .flags = IORESOURCE_MEM,
|
||
|
+},
|
||
|
+#if IM_NUM >= 2
|
||
|
+{
|
||
|
+ .name = "icu_im1",
|
||
|
+#ifdef LTQ_ICU_BASE_ADDR1
|
||
|
+ .start = LTQ_ICU_BASE_ADDR1,
|
||
|
+ .end = LTQ_ICU_BASE_ADDR1 + LTQ_ICU_OFFSET - 1,
|
||
|
+#else
|
||
|
+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 1),
|
||
|
+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 2) - 1,
|
||
|
+#endif
|
||
|
+ .flags = IORESOURCE_MEM,
|
||
|
+},
|
||
|
+#endif
|
||
|
+#if IM_NUM >= 3
|
||
|
+{
|
||
|
+ .name = "icu_im2",
|
||
|
+#ifdef LTQ_ICU_BASE_ADDR2
|
||
|
+ .start = LTQ_ICU_BASE_ADDR2,
|
||
|
+ .end = LTQ_ICU_BASE_ADDR2 + LTQ_ICU_OFFSET - 1,
|
||
|
+#else
|
||
|
+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 2),
|
||
|
+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 3) - 1,
|
||
|
+#endif
|
||
|
+ .flags = IORESOURCE_MEM,
|
||
|
+},
|
||
|
+#endif
|
||
|
+#if IM_NUM >= 4
|
||
|
+{
|
||
|
+ .name = "icu_im3",
|
||
|
+#ifdef LTQ_ICU_BASE_ADDR3
|
||
|
+ .start = LTQ_ICU_BASE_ADDR3,
|
||
|
+ .end = LTQ_ICU_BASE_ADDR3 + LTQ_ICU_OFFSET - 1,
|
||
|
+#else
|
||
|
+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 3),
|
||
|
+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 4) - 1,
|
||
|
+#endif
|
||
|
+ .flags = IORESOURCE_MEM,
|
||
|
+},
|
||
|
+#endif
|
||
|
+#if IM_NUM >= 5
|
||
|
+{
|
||
|
+ .name = "icu_im4",
|
||
|
+#ifdef LTQ_ICU_BASE_ADDR4
|
||
|
+ .start = LTQ_ICU_BASE_ADDR4,
|
||
|
+ .end = LTQ_ICU_BASE_ADDR4 + LTQ_ICU_OFFSET - 1,
|
||
|
+#else
|
||
|
+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 4),
|
||
|
+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 5) - 1,
|
||
|
+#endif
|
||
|
+ .flags = IORESOURCE_MEM,
|
||
|
+},
|
||
|
+#endif
|
||
|
+#if IM_NUM >= 6
|
||
|
+{
|
||
|
+ .name = "icu_im5",
|
||
|
+#ifdef LTQ_ICU_BASE_ADDR5
|
||
|
+ .start = LTQ_ICU_BASE_ADDR5,
|
||
|
+ .end = LTQ_ICU_BASE_ADDR5 + LTQ_ICU_OFFSET - 1,
|
||
|
+#else
|
||
|
+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 5),
|
||
|
+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 6) - 1,
|
||
|
+#endif
|
||
|
+ .flags = IORESOURCE_MEM,
|
||
|
+},
|
||
|
+#endif
|
||
|
};
|
||
|
|
||
|
static struct resource ltq_eiu_resource = {
|
||
|
@@ -77,50 +144,56 @@
|
||
|
.flags = IORESOURCE_MEM,
|
||
|
};
|
||
|
|
||
|
-static void __iomem *ltq_icu_membase;
|
||
|
+static void __iomem *ltq_icu_membase[IM_NUM];
|
||
|
static void __iomem *ltq_eiu_membase;
|
||
|
|
||
|
void ltq_disable_irq(struct irq_data *d)
|
||
|
{
|
||
|
- u32 ier = LTQ_ICU_IM0_IER;
|
||
|
int irq_nr = d->irq - INT_NUM_IRQ0;
|
||
|
+ unsigned int im_nr;
|
||
|
|
||
|
- ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||
|
+ im_nr = (irq_nr / INT_NUM_IM_OFFSET);
|
||
|
irq_nr %= INT_NUM_IM_OFFSET;
|
||
|
- ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
|
||
|
+
|
||
|
+ ltq_icu_w32(ltq_icu_r32(LTQ_ICU_IM0_IER, im_nr) & ~(1 << irq_nr),
|
||
|
+ LTQ_ICU_IM0_IER, im_nr);
|
||
|
}
|
||
|
|
||
|
void ltq_mask_and_ack_irq(struct irq_data *d)
|
||
|
{
|
||
|
- u32 ier = LTQ_ICU_IM0_IER;
|
||
|
- u32 isr = LTQ_ICU_IM0_ISR;
|
||
|
int irq_nr = d->irq - INT_NUM_IRQ0;
|
||
|
+ unsigned int im_nr;
|
||
|
|
||
|
- ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||
|
- isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||
|
+ irq_nr -= INT_NUM_IRQ0;
|
||
|
+ im_nr = (irq_nr / INT_NUM_IM_OFFSET);
|
||
|
irq_nr %= INT_NUM_IM_OFFSET;
|
||
|
- ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
|
||
|
- ltq_icu_w32((1 << irq_nr), isr);
|
||
|
+
|
||
|
+ ltq_icu_w32(ltq_icu_r32(LTQ_ICU_IM0_IER, im_nr) & ~(1 << irq_nr), LTQ_ICU_IM0_IER, im_nr);
|
||
|
+ ltq_icu_w32((1 << irq_nr), LTQ_ICU_IM0_ISR, im_nr);
|
||
|
}
|
||
|
|
||
|
static void ltq_ack_irq(struct irq_data *d)
|
||
|
{
|
||
|
- u32 isr = LTQ_ICU_IM0_ISR;
|
||
|
int irq_nr = d->irq - INT_NUM_IRQ0;
|
||
|
+ unsigned int im_nr;
|
||
|
|
||
|
- isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||
|
+ irq_nr -= INT_NUM_IRQ0;
|
||
|
+ im_nr = (irq_nr / INT_NUM_IM_OFFSET);
|
||
|
irq_nr %= INT_NUM_IM_OFFSET;
|
||
|
- ltq_icu_w32((1 << irq_nr), isr);
|
||
|
+
|
||
|
+ ltq_icu_w32((1 << irq_nr), LTQ_ICU_IM0_ISR, im_nr);
|
||
|
}
|
||
|
|
||
|
void ltq_enable_irq(struct irq_data *d)
|
||
|
{
|
||
|
- u32 ier = LTQ_ICU_IM0_IER;
|
||
|
int irq_nr = d->irq - INT_NUM_IRQ0;
|
||
|
+ unsigned int im_nr;
|
||
|
|
||
|
- ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||
|
+ irq_nr -= INT_NUM_IRQ0;
|
||
|
+ im_nr = (irq_nr / INT_NUM_IM_OFFSET);
|
||
|
irq_nr %= INT_NUM_IM_OFFSET;
|
||
|
- ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier);
|
||
|
+
|
||
|
+ ltq_icu_w32(ltq_icu_r32(LTQ_ICU_IM0_IER, im_nr) | (1 << irq_nr), LTQ_ICU_IM0_IER, im_nr);
|
||
|
}
|
||
|
|
||
|
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
|
||
|
@@ -187,7 +260,7 @@
|
||
|
{
|
||
|
u32 irq;
|
||
|
|
||
|
- irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
|
||
|
+ irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR, module);
|
||
|
if (irq == 0)
|
||
|
return;
|
||
|
|
||
|
@@ -250,8 +323,19 @@
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
- if (insert_resource(&iomem_resource, <q_icu_resource) < 0)
|
||
|
- panic("Failed to insert icu memory");
|
||
|
+ for (i=0; i < IM_NUM; i++) {
|
||
|
+ if (insert_resource(&iomem_resource, <q_icu_resource[i]) < 0)
|
||
|
+ panic("Failed to insert icu memory\n");
|
||
|
+
|
||
|
+ if (request_mem_region(ltq_icu_resource[i].start,
|
||
|
+ resource_size(<q_icu_resource[i]), "icu") < 0)
|
||
|
+ panic("Failed to request icu memory\n");
|
||
|
+
|
||
|
+ ltq_icu_membase[i] = ioremap_nocache(ltq_icu_resource[i].start,
|
||
|
+ resource_size(<q_icu_resource[i]));
|
||
|
+ if (!ltq_icu_membase[i])
|
||
|
+ panic("Failed to remap icu memory\n");
|
||
|
+ }
|
||
|
|
||
|
if (request_mem_region(ltq_icu_resource.start,
|
||
|
resource_size(<q_icu_resource), "icu") < 0)
|
||
|
@@ -277,11 +361,11 @@
|
||
|
}
|
||
|
|
||
|
/* make sure all irqs are turned off by default */
|
||
|
- for (i = 0; i < 5; i++)
|
||
|
- ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
|
||
|
-
|
||
|
- /* clear all possibly pending interrupts */
|
||
|
- ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
|
||
|
+ for (i = 0; i < IM_NUM; i++)
|
||
|
+ ltq_icu_w32(0, LTQ_ICU_IM0_IER, i);
|
||
|
+ /* clear all possibly pending interrupts */
|
||
|
+ ltq_icu_w32(~0, LTQ_ICU_IM0_ISR, i);
|
||
|
+ }
|
||
|
|
||
|
mips_cpu_irq_init();
|
||
|
|