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();