Loading arch/mips/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ config MIPS_COBALT select HW_HAS_PCI select I8259 select IRQ_CPU select IRQ_GT641XX select PCI_GT64XXX_PCI0 select SYS_HAS_CPU_NEVADA select SYS_HAS_EARLY_PRINTK Loading Loading @@ -806,6 +807,9 @@ config IRQ_MSP_CIC config IRQ_TXX9 bool config IRQ_GT641XX bool config MIPS_BOARDS_GEN bool Loading arch/mips/cobalt/irq.c +31 −87 Original line number Diff line number Diff line Loading @@ -15,104 +15,48 @@ #include <asm/i8259.h> #include <asm/irq_cpu.h> #include <asm/irq_gt641xx.h> #include <asm/gt64120.h> #include <cobalt.h> #include <irq.h> /* * We have two types of interrupts that we handle, ones that come in through * the CPU interrupt lines, and ones that come in on the via chip. The CPU * mappings are: * * 16 - Software interrupt 0 (unused) IE_SW0 * 17 - Software interrupt 1 (unused) IE_SW1 * 18 - Galileo chip (timer) IE_IRQ0 * 19 - Tulip 0 + NCR SCSI IE_IRQ1 * 20 - Tulip 1 IE_IRQ2 * 21 - 16550 UART IE_IRQ3 * 22 - VIA southbridge PIC IE_IRQ4 * 23 - unused IE_IRQ5 * * The VIA chip is a master/slave 8259 setup and has the following interrupts: * * 8 - RTC * 9 - PCI * 14 - IDE0 * 15 - IDE1 */ static inline void galileo_irq(void) { unsigned int mask, pending, devfn; mask = GT_READ(GT_INTRMASK_OFS); pending = GT_READ(GT_INTRCAUSE_OFS) & mask; if (pending & GT_INTR_T0EXP_MSK) { GT_WRITE(GT_INTRCAUSE_OFS, ~GT_INTR_T0EXP_MSK); do_IRQ(COBALT_GALILEO_IRQ); } else if (pending & GT_INTR_RETRYCTR0_MSK) { devfn = GT_READ(GT_PCI0_CFGADDR_OFS) >> 8; GT_WRITE(GT_INTRCAUSE_OFS, ~GT_INTR_RETRYCTR0_MSK); printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n", PCI_SLOT(devfn), PCI_FUNC(devfn)); } else { GT_WRITE(GT_INTRMASK_OFS, mask & ~pending); printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending); } } static inline void via_pic_irq(void) asmlinkage void plat_irq_dispatch(void) { unsigned pending = read_c0_status() & read_c0_cause() & ST0_IM; int irq; if (pending & CAUSEF_IP2) gt641xx_irq_dispatch(); else if (pending & CAUSEF_IP6) { irq = i8259_irq(); if (irq >= 0) if (irq < 0) spurious_interrupt(); else do_IRQ(irq); } else if (pending & CAUSEF_IP3) do_IRQ(MIPS_CPU_IRQ_BASE + 3); else if (pending & CAUSEF_IP4) do_IRQ(MIPS_CPU_IRQ_BASE + 4); else if (pending & CAUSEF_IP5) do_IRQ(MIPS_CPU_IRQ_BASE + 5); else if (pending & CAUSEF_IP7) do_IRQ(MIPS_CPU_IRQ_BASE + 7); else spurious_interrupt(); } asmlinkage void plat_irq_dispatch(void) { unsigned pending = read_c0_status() & read_c0_cause(); if (pending & CAUSEF_IP2) /* COBALT_GALILEO_IRQ (18) */ galileo_irq(); else if (pending & CAUSEF_IP6) /* COBALT_VIA_IRQ (22) */ via_pic_irq(); else if (pending & CAUSEF_IP3) /* COBALT_ETH0_IRQ (19) */ do_IRQ(COBALT_CPU_IRQ + 3); else if (pending & CAUSEF_IP4) /* COBALT_ETH1_IRQ (20) */ do_IRQ(COBALT_CPU_IRQ + 4); else if (pending & CAUSEF_IP5) /* COBALT_SERIAL_IRQ (21) */ do_IRQ(COBALT_CPU_IRQ + 5); else if (pending & CAUSEF_IP7) /* IRQ 23 */ do_IRQ(COBALT_CPU_IRQ + 7); } static struct irqaction irq_via = { static struct irqaction cascade = { .handler = no_action, .mask = CPU_MASK_NONE, .name = "cascade" .name = "cascade", }; void __init arch_init_irq(void) { /* * Mask all Galileo interrupts. The Galileo * handler is set in cobalt_timer_setup() */ GT_WRITE(GT_INTRMASK_OFS, 0); init_i8259_irqs(); /* 0 ... 15 */ mips_cpu_irq_init(); /* 16 ... 23 */ /* * Mask all cpu interrupts * (except IE4, we already masked those at VIA level) */ change_c0_status(ST0_IM, IE_IRQ4); mips_cpu_irq_init(); gt641xx_irq_init(); init_i8259_irqs(); setup_irq(COBALT_VIA_IRQ, &irq_via); setup_irq(GT641XX_CASCADE_IRQ, &cascade); setup_irq(I8259_CASCADE_IRQ, &cascade); } arch/mips/cobalt/rtc.c +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/errno.h> #include <linux/init.h> #include <linux/ioport.h> #include <linux/mc146818rtc.h> #include <linux/platform_device.h> static struct resource cobalt_rtc_resource[] __initdata = { Loading @@ -29,8 +30,8 @@ static struct resource cobalt_rtc_resource[] __initdata = { .flags = IORESOURCE_IO, }, { .start = 8, .end = 8, .start = RTC_IRQ, .end = RTC_IRQ, .flags = IORESOURCE_IRQ, }, }; Loading arch/mips/cobalt/serial.c +4 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/serial_8250.h> #include <cobalt.h> #include <irq.h> static struct resource cobalt_uart_resource[] __initdata = { { Loading @@ -32,15 +33,15 @@ static struct resource cobalt_uart_resource[] __initdata = { .flags = IORESOURCE_MEM, }, { .start = COBALT_SERIAL_IRQ, .end = COBALT_SERIAL_IRQ, .start = SERIAL_IRQ, .end = SERIAL_IRQ, .flags = IORESOURCE_IRQ, }, }; static struct plat_serial8250_port cobalt_serial8250_port[] = { { .irq = COBALT_SERIAL_IRQ, .irq = SERIAL_IRQ, .uartclk = 18432000, .iotype = UPIO_MEM, .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, Loading arch/mips/cobalt/setup.c +3 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <asm/gt64120.h> #include <cobalt.h> #include <irq.h> extern void cobalt_machine_restart(char *command); extern void cobalt_machine_halt(void); Loading @@ -45,14 +46,10 @@ void __init plat_timer_setup(struct irqaction *irq) /* Load timer value for HZ (TCLK is 50MHz) */ GT_WRITE(GT_TC0_OFS, 50*1000*1000 / HZ); /* Enable timer */ /* Enable timer0 */ GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); /* Register interrupt */ setup_irq(COBALT_GALILEO_IRQ, irq); /* Enable interrupt */ GT_WRITE(GT_INTRMASK_OFS, GT_INTR_T0EXP_MSK | GT_READ(GT_INTRMASK_OFS)); setup_irq(GT641XX_TIMER0_IRQ, irq); } /* Loading Loading
arch/mips/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ config MIPS_COBALT select HW_HAS_PCI select I8259 select IRQ_CPU select IRQ_GT641XX select PCI_GT64XXX_PCI0 select SYS_HAS_CPU_NEVADA select SYS_HAS_EARLY_PRINTK Loading Loading @@ -806,6 +807,9 @@ config IRQ_MSP_CIC config IRQ_TXX9 bool config IRQ_GT641XX bool config MIPS_BOARDS_GEN bool Loading
arch/mips/cobalt/irq.c +31 −87 Original line number Diff line number Diff line Loading @@ -15,104 +15,48 @@ #include <asm/i8259.h> #include <asm/irq_cpu.h> #include <asm/irq_gt641xx.h> #include <asm/gt64120.h> #include <cobalt.h> #include <irq.h> /* * We have two types of interrupts that we handle, ones that come in through * the CPU interrupt lines, and ones that come in on the via chip. The CPU * mappings are: * * 16 - Software interrupt 0 (unused) IE_SW0 * 17 - Software interrupt 1 (unused) IE_SW1 * 18 - Galileo chip (timer) IE_IRQ0 * 19 - Tulip 0 + NCR SCSI IE_IRQ1 * 20 - Tulip 1 IE_IRQ2 * 21 - 16550 UART IE_IRQ3 * 22 - VIA southbridge PIC IE_IRQ4 * 23 - unused IE_IRQ5 * * The VIA chip is a master/slave 8259 setup and has the following interrupts: * * 8 - RTC * 9 - PCI * 14 - IDE0 * 15 - IDE1 */ static inline void galileo_irq(void) { unsigned int mask, pending, devfn; mask = GT_READ(GT_INTRMASK_OFS); pending = GT_READ(GT_INTRCAUSE_OFS) & mask; if (pending & GT_INTR_T0EXP_MSK) { GT_WRITE(GT_INTRCAUSE_OFS, ~GT_INTR_T0EXP_MSK); do_IRQ(COBALT_GALILEO_IRQ); } else if (pending & GT_INTR_RETRYCTR0_MSK) { devfn = GT_READ(GT_PCI0_CFGADDR_OFS) >> 8; GT_WRITE(GT_INTRCAUSE_OFS, ~GT_INTR_RETRYCTR0_MSK); printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n", PCI_SLOT(devfn), PCI_FUNC(devfn)); } else { GT_WRITE(GT_INTRMASK_OFS, mask & ~pending); printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending); } } static inline void via_pic_irq(void) asmlinkage void plat_irq_dispatch(void) { unsigned pending = read_c0_status() & read_c0_cause() & ST0_IM; int irq; if (pending & CAUSEF_IP2) gt641xx_irq_dispatch(); else if (pending & CAUSEF_IP6) { irq = i8259_irq(); if (irq >= 0) if (irq < 0) spurious_interrupt(); else do_IRQ(irq); } else if (pending & CAUSEF_IP3) do_IRQ(MIPS_CPU_IRQ_BASE + 3); else if (pending & CAUSEF_IP4) do_IRQ(MIPS_CPU_IRQ_BASE + 4); else if (pending & CAUSEF_IP5) do_IRQ(MIPS_CPU_IRQ_BASE + 5); else if (pending & CAUSEF_IP7) do_IRQ(MIPS_CPU_IRQ_BASE + 7); else spurious_interrupt(); } asmlinkage void plat_irq_dispatch(void) { unsigned pending = read_c0_status() & read_c0_cause(); if (pending & CAUSEF_IP2) /* COBALT_GALILEO_IRQ (18) */ galileo_irq(); else if (pending & CAUSEF_IP6) /* COBALT_VIA_IRQ (22) */ via_pic_irq(); else if (pending & CAUSEF_IP3) /* COBALT_ETH0_IRQ (19) */ do_IRQ(COBALT_CPU_IRQ + 3); else if (pending & CAUSEF_IP4) /* COBALT_ETH1_IRQ (20) */ do_IRQ(COBALT_CPU_IRQ + 4); else if (pending & CAUSEF_IP5) /* COBALT_SERIAL_IRQ (21) */ do_IRQ(COBALT_CPU_IRQ + 5); else if (pending & CAUSEF_IP7) /* IRQ 23 */ do_IRQ(COBALT_CPU_IRQ + 7); } static struct irqaction irq_via = { static struct irqaction cascade = { .handler = no_action, .mask = CPU_MASK_NONE, .name = "cascade" .name = "cascade", }; void __init arch_init_irq(void) { /* * Mask all Galileo interrupts. The Galileo * handler is set in cobalt_timer_setup() */ GT_WRITE(GT_INTRMASK_OFS, 0); init_i8259_irqs(); /* 0 ... 15 */ mips_cpu_irq_init(); /* 16 ... 23 */ /* * Mask all cpu interrupts * (except IE4, we already masked those at VIA level) */ change_c0_status(ST0_IM, IE_IRQ4); mips_cpu_irq_init(); gt641xx_irq_init(); init_i8259_irqs(); setup_irq(COBALT_VIA_IRQ, &irq_via); setup_irq(GT641XX_CASCADE_IRQ, &cascade); setup_irq(I8259_CASCADE_IRQ, &cascade); }
arch/mips/cobalt/rtc.c +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/errno.h> #include <linux/init.h> #include <linux/ioport.h> #include <linux/mc146818rtc.h> #include <linux/platform_device.h> static struct resource cobalt_rtc_resource[] __initdata = { Loading @@ -29,8 +30,8 @@ static struct resource cobalt_rtc_resource[] __initdata = { .flags = IORESOURCE_IO, }, { .start = 8, .end = 8, .start = RTC_IRQ, .end = RTC_IRQ, .flags = IORESOURCE_IRQ, }, }; Loading
arch/mips/cobalt/serial.c +4 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/serial_8250.h> #include <cobalt.h> #include <irq.h> static struct resource cobalt_uart_resource[] __initdata = { { Loading @@ -32,15 +33,15 @@ static struct resource cobalt_uart_resource[] __initdata = { .flags = IORESOURCE_MEM, }, { .start = COBALT_SERIAL_IRQ, .end = COBALT_SERIAL_IRQ, .start = SERIAL_IRQ, .end = SERIAL_IRQ, .flags = IORESOURCE_IRQ, }, }; static struct plat_serial8250_port cobalt_serial8250_port[] = { { .irq = COBALT_SERIAL_IRQ, .irq = SERIAL_IRQ, .uartclk = 18432000, .iotype = UPIO_MEM, .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, Loading
arch/mips/cobalt/setup.c +3 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <asm/gt64120.h> #include <cobalt.h> #include <irq.h> extern void cobalt_machine_restart(char *command); extern void cobalt_machine_halt(void); Loading @@ -45,14 +46,10 @@ void __init plat_timer_setup(struct irqaction *irq) /* Load timer value for HZ (TCLK is 50MHz) */ GT_WRITE(GT_TC0_OFS, 50*1000*1000 / HZ); /* Enable timer */ /* Enable timer0 */ GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); /* Register interrupt */ setup_irq(COBALT_GALILEO_IRQ, irq); /* Enable interrupt */ GT_WRITE(GT_INTRMASK_OFS, GT_INTR_T0EXP_MSK | GT_READ(GT_INTRMASK_OFS)); setup_irq(GT641XX_TIMER0_IRQ, irq); } /* Loading