Loading arch/mips/sgi-ip22/ip22-eisa.c +67 −81 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/mipsregs.h> #include <asm/addrspace.h> Loading @@ -37,42 +38,29 @@ #include <asm/sgi/mc.h> #include <asm/sgi/ip22.h> #define EISA_MAX_SLOTS 4 /* I2 has four EISA slots. */ #define IP22_EISA_MAX_SLOTS 4 #define EISA_MAX_IRQ 16 #define EISA_TO_PHYS(x) (0x00080000 | (x)) #define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x)))) #define EIU_MODE_REG 0x0009ffc0 #define EIU_STAT_REG 0x0009ffc4 #define EIU_PREMPT_REG 0x0009ffc8 #define EIU_QUIET_REG 0x0009ffcc #define EIU_INTRPT_ACK 0x00090004 #define EISA_DMA1_STATUS 8 #define EISA_INT1_CTRL 0x20 #define EISA_INT1_MASK 0x21 #define EISA_INT2_CTRL 0xA0 #define EISA_INT2_MASK 0xA1 #define EISA_DMA2_STATUS 0xD0 #define EISA_DMA2_WRITE_SINGLE 0xD4 #define EISA_EXT_NMI_RESET_CTRL 0x461 #define EISA_INT1_EDGE_LEVEL 0x4D0 #define EISA_INT2_EDGE_LEVEL 0x4D1 #define EISA_VENDOR_ID_OFFSET 0xC80 #define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); } #define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x)) #define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); } #define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x)) static char *decode_eisa_sig(u8 * sig) #define EIU_MODE_REG 0x0001ffc0 #define EIU_STAT_REG 0x0001ffc4 #define EIU_PREMPT_REG 0x0001ffc8 #define EIU_QUIET_REG 0x0001ffcc #define EIU_INTRPT_ACK 0x00010004 static char __init *decode_eisa_sig(unsigned long addr) { static char sig_str[8]; static char sig_str[EISA_SIG_LEN]; u8 sig[4]; u16 rev; int i; for (i = 0; i < 4; i++) { sig[i] = inb (addr + i); if (sig[0] & 0x80) if (!i && (sig[0] & 0x80)) return NULL; } sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1); sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1); Loading @@ -83,23 +71,26 @@ static char *decode_eisa_sig(u8 * sig) return sig_str; } static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs) { u8 eisa_irq; u8 dma1, dma2; eisa_irq = EIU_READ_8(EIU_INTRPT_ACK); dma1 = EISA_READ_8(EISA_DMA1_STATUS); dma2 = EISA_READ_8(EISA_DMA2_STATUS); eisa_irq = inb(EIU_INTRPT_ACK); dma1 = inb(EISA_DMA1_STATUS); dma2 = inb(EISA_DMA2_STATUS); if (eisa_irq < EISA_MAX_IRQ) { do_IRQ(eisa_irq, regs); return IRQ_HANDLED; } if (eisa_irq >= EISA_MAX_IRQ) { /* Oops, Bad Stuff Happened... */ printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq); EISA_WRITE_8(EISA_INT2_CTRL, 0x20); EISA_WRITE_8(EISA_INT1_CTRL, 0x20); } else do_IRQ(eisa_irq, regs); outb(0x20, EISA_INT2_CTRL); outb(0x20, EISA_INT1_CTRL); return IRQ_NONE; } static void enable_eisa1_irq(unsigned int irq) Loading @@ -109,9 +100,9 @@ static void enable_eisa1_irq(unsigned int irq) local_irq_save(flags); mask = EISA_READ_8(EISA_INT1_MASK); mask = inb(EISA_INT1_MASK); mask &= ~((u8) (1 << irq)); EISA_WRITE_8(EISA_INT1_MASK, mask); outb(mask, EISA_INT1_MASK); local_irq_restore(flags); } Loading @@ -122,9 +113,9 @@ static unsigned int startup_eisa1_irq(unsigned int irq) /* Only use edge interrupts for EISA */ edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL); edge = inb(EISA_INT1_EDGE_LEVEL); edge &= ~((u8) (1 << irq)); EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge); outb(edge, EISA_INT1_EDGE_LEVEL); enable_eisa1_irq(irq); return 0; Loading @@ -134,9 +125,9 @@ static void disable_eisa1_irq(unsigned int irq) { u8 mask; mask = EISA_READ_8(EISA_INT1_MASK); mask = inb(EISA_INT1_MASK); mask |= ((u8) (1 << irq)); EISA_WRITE_8(EISA_INT1_MASK, mask); outb(mask, EISA_INT1_MASK); } #define shutdown_eisa1_irq disable_eisa1_irq Loading @@ -145,7 +136,7 @@ static void mask_and_ack_eisa1_irq(unsigned int irq) { disable_eisa1_irq(irq); EISA_WRITE_8(EISA_INT1_CTRL, 0x20); outb(0x20, EISA_INT1_CTRL); } static void end_eisa1_irq(unsigned int irq) Loading @@ -171,9 +162,9 @@ static void enable_eisa2_irq(unsigned int irq) local_irq_save(flags); mask = EISA_READ_8(EISA_INT2_MASK); mask = inb(EISA_INT2_MASK); mask &= ~((u8) (1 << (irq - 8))); EISA_WRITE_8(EISA_INT2_MASK, mask); outb(mask, EISA_INT2_MASK); local_irq_restore(flags); } Loading @@ -184,9 +175,9 @@ static unsigned int startup_eisa2_irq(unsigned int irq) /* Only use edge interrupts for EISA */ edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL); edge = inb(EISA_INT2_EDGE_LEVEL); edge &= ~((u8) (1 << (irq - 8))); EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge); outb(edge, EISA_INT2_EDGE_LEVEL); enable_eisa2_irq(irq); return 0; Loading @@ -196,9 +187,9 @@ static void disable_eisa2_irq(unsigned int irq) { u8 mask; mask = EISA_READ_8(EISA_INT2_MASK); mask = inb(EISA_INT2_MASK); mask |= ((u8) (1 << (irq - 8))); EISA_WRITE_8(EISA_INT2_MASK, mask); outb(mask, EISA_INT2_MASK); } #define shutdown_eisa2_irq disable_eisa2_irq Loading @@ -207,8 +198,7 @@ static void mask_and_ack_eisa2_irq(unsigned int irq) { disable_eisa2_irq(irq); EISA_WRITE_8(EISA_INT2_CTRL, 0x20); EISA_WRITE_8(EISA_INT1_CTRL, 0x20); outb(0x20, EISA_INT2_CTRL); } static void end_eisa2_irq(unsigned int irq) Loading Loading @@ -241,7 +231,6 @@ int __init ip22_eisa_init(void) { int i, c; char *str; u8 *slot_addr; if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { printk(KERN_INFO "EISA: bus not present.\n"); Loading @@ -249,11 +238,8 @@ int __init ip22_eisa_init(void) } printk(KERN_INFO "EISA: Probing bus...\n"); for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) { slot_addr = (u8 *) EISA_TO_KSEG1((0x1000 * i) + EISA_VENDOR_ID_OFFSET); if ((str = decode_eisa_sig(slot_addr))) { for (c = 0, i = 1; i <= IP22_EISA_MAX_SLOTS; i++) { if ((str = decode_eisa_sig(0x1000 * i + EISA_VENDOR_ID_OFFSET))) { printk(KERN_INFO "EISA: slot %d : %s detected.\n", i, str); c++; Loading @@ -268,25 +254,25 @@ int __init ip22_eisa_init(void) Please wave your favorite dead chicken over the busses */ /* First say hello to the EIU */ EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF); EIU_WRITE_32(EIU_QUIET_REG, 1); EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F); outl(0x0000FFFF, EIU_PREMPT_REG); outl(1, EIU_QUIET_REG); outl(0x40f3c07F, EIU_MODE_REG); /* Now be nice to the EISA chipset */ EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1); for (i = 0; i < 10000; i++); /* Wait long enough for the dust to settle */ EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0); EISA_WRITE_8(EISA_INT1_CTRL, 0x11); EISA_WRITE_8(EISA_INT2_CTRL, 0x11); EISA_WRITE_8(EISA_INT1_MASK, 0); EISA_WRITE_8(EISA_INT2_MASK, 8); EISA_WRITE_8(EISA_INT1_MASK, 4); EISA_WRITE_8(EISA_INT2_MASK, 2); EISA_WRITE_8(EISA_INT1_MASK, 1); EISA_WRITE_8(EISA_INT2_MASK, 1); EISA_WRITE_8(EISA_INT1_MASK, 0xfb); EISA_WRITE_8(EISA_INT2_MASK, 0xff); EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0); outb(1, EISA_EXT_NMI_RESET_CTRL); udelay(50); /* Wait long enough for the dust to settle */ outb(0, EISA_EXT_NMI_RESET_CTRL); outb(0x11, EISA_INT1_CTRL); outb(0x11, EISA_INT2_CTRL); outb(0, EISA_INT1_MASK); outb(8, EISA_INT2_MASK); outb(4, EISA_INT1_MASK); outb(2, EISA_INT2_MASK); outb(1, EISA_INT1_MASK); outb(1, EISA_INT2_MASK); outb(0xfb, EISA_INT1_MASK); outb(0xff, EISA_INT2_MASK); outb(0, EISA_DMA2_WRITE_SINGLE); for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) { irq_desc[i].status = IRQ_DISABLED; Loading Loading
arch/mips/sgi-ip22/ip22-eisa.c +67 −81 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/mipsregs.h> #include <asm/addrspace.h> Loading @@ -37,42 +38,29 @@ #include <asm/sgi/mc.h> #include <asm/sgi/ip22.h> #define EISA_MAX_SLOTS 4 /* I2 has four EISA slots. */ #define IP22_EISA_MAX_SLOTS 4 #define EISA_MAX_IRQ 16 #define EISA_TO_PHYS(x) (0x00080000 | (x)) #define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x)))) #define EIU_MODE_REG 0x0009ffc0 #define EIU_STAT_REG 0x0009ffc4 #define EIU_PREMPT_REG 0x0009ffc8 #define EIU_QUIET_REG 0x0009ffcc #define EIU_INTRPT_ACK 0x00090004 #define EISA_DMA1_STATUS 8 #define EISA_INT1_CTRL 0x20 #define EISA_INT1_MASK 0x21 #define EISA_INT2_CTRL 0xA0 #define EISA_INT2_MASK 0xA1 #define EISA_DMA2_STATUS 0xD0 #define EISA_DMA2_WRITE_SINGLE 0xD4 #define EISA_EXT_NMI_RESET_CTRL 0x461 #define EISA_INT1_EDGE_LEVEL 0x4D0 #define EISA_INT2_EDGE_LEVEL 0x4D1 #define EISA_VENDOR_ID_OFFSET 0xC80 #define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); } #define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x)) #define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); } #define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x)) static char *decode_eisa_sig(u8 * sig) #define EIU_MODE_REG 0x0001ffc0 #define EIU_STAT_REG 0x0001ffc4 #define EIU_PREMPT_REG 0x0001ffc8 #define EIU_QUIET_REG 0x0001ffcc #define EIU_INTRPT_ACK 0x00010004 static char __init *decode_eisa_sig(unsigned long addr) { static char sig_str[8]; static char sig_str[EISA_SIG_LEN]; u8 sig[4]; u16 rev; int i; for (i = 0; i < 4; i++) { sig[i] = inb (addr + i); if (sig[0] & 0x80) if (!i && (sig[0] & 0x80)) return NULL; } sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1); sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1); Loading @@ -83,23 +71,26 @@ static char *decode_eisa_sig(u8 * sig) return sig_str; } static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs) { u8 eisa_irq; u8 dma1, dma2; eisa_irq = EIU_READ_8(EIU_INTRPT_ACK); dma1 = EISA_READ_8(EISA_DMA1_STATUS); dma2 = EISA_READ_8(EISA_DMA2_STATUS); eisa_irq = inb(EIU_INTRPT_ACK); dma1 = inb(EISA_DMA1_STATUS); dma2 = inb(EISA_DMA2_STATUS); if (eisa_irq < EISA_MAX_IRQ) { do_IRQ(eisa_irq, regs); return IRQ_HANDLED; } if (eisa_irq >= EISA_MAX_IRQ) { /* Oops, Bad Stuff Happened... */ printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq); EISA_WRITE_8(EISA_INT2_CTRL, 0x20); EISA_WRITE_8(EISA_INT1_CTRL, 0x20); } else do_IRQ(eisa_irq, regs); outb(0x20, EISA_INT2_CTRL); outb(0x20, EISA_INT1_CTRL); return IRQ_NONE; } static void enable_eisa1_irq(unsigned int irq) Loading @@ -109,9 +100,9 @@ static void enable_eisa1_irq(unsigned int irq) local_irq_save(flags); mask = EISA_READ_8(EISA_INT1_MASK); mask = inb(EISA_INT1_MASK); mask &= ~((u8) (1 << irq)); EISA_WRITE_8(EISA_INT1_MASK, mask); outb(mask, EISA_INT1_MASK); local_irq_restore(flags); } Loading @@ -122,9 +113,9 @@ static unsigned int startup_eisa1_irq(unsigned int irq) /* Only use edge interrupts for EISA */ edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL); edge = inb(EISA_INT1_EDGE_LEVEL); edge &= ~((u8) (1 << irq)); EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge); outb(edge, EISA_INT1_EDGE_LEVEL); enable_eisa1_irq(irq); return 0; Loading @@ -134,9 +125,9 @@ static void disable_eisa1_irq(unsigned int irq) { u8 mask; mask = EISA_READ_8(EISA_INT1_MASK); mask = inb(EISA_INT1_MASK); mask |= ((u8) (1 << irq)); EISA_WRITE_8(EISA_INT1_MASK, mask); outb(mask, EISA_INT1_MASK); } #define shutdown_eisa1_irq disable_eisa1_irq Loading @@ -145,7 +136,7 @@ static void mask_and_ack_eisa1_irq(unsigned int irq) { disable_eisa1_irq(irq); EISA_WRITE_8(EISA_INT1_CTRL, 0x20); outb(0x20, EISA_INT1_CTRL); } static void end_eisa1_irq(unsigned int irq) Loading @@ -171,9 +162,9 @@ static void enable_eisa2_irq(unsigned int irq) local_irq_save(flags); mask = EISA_READ_8(EISA_INT2_MASK); mask = inb(EISA_INT2_MASK); mask &= ~((u8) (1 << (irq - 8))); EISA_WRITE_8(EISA_INT2_MASK, mask); outb(mask, EISA_INT2_MASK); local_irq_restore(flags); } Loading @@ -184,9 +175,9 @@ static unsigned int startup_eisa2_irq(unsigned int irq) /* Only use edge interrupts for EISA */ edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL); edge = inb(EISA_INT2_EDGE_LEVEL); edge &= ~((u8) (1 << (irq - 8))); EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge); outb(edge, EISA_INT2_EDGE_LEVEL); enable_eisa2_irq(irq); return 0; Loading @@ -196,9 +187,9 @@ static void disable_eisa2_irq(unsigned int irq) { u8 mask; mask = EISA_READ_8(EISA_INT2_MASK); mask = inb(EISA_INT2_MASK); mask |= ((u8) (1 << (irq - 8))); EISA_WRITE_8(EISA_INT2_MASK, mask); outb(mask, EISA_INT2_MASK); } #define shutdown_eisa2_irq disable_eisa2_irq Loading @@ -207,8 +198,7 @@ static void mask_and_ack_eisa2_irq(unsigned int irq) { disable_eisa2_irq(irq); EISA_WRITE_8(EISA_INT2_CTRL, 0x20); EISA_WRITE_8(EISA_INT1_CTRL, 0x20); outb(0x20, EISA_INT2_CTRL); } static void end_eisa2_irq(unsigned int irq) Loading Loading @@ -241,7 +231,6 @@ int __init ip22_eisa_init(void) { int i, c; char *str; u8 *slot_addr; if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { printk(KERN_INFO "EISA: bus not present.\n"); Loading @@ -249,11 +238,8 @@ int __init ip22_eisa_init(void) } printk(KERN_INFO "EISA: Probing bus...\n"); for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) { slot_addr = (u8 *) EISA_TO_KSEG1((0x1000 * i) + EISA_VENDOR_ID_OFFSET); if ((str = decode_eisa_sig(slot_addr))) { for (c = 0, i = 1; i <= IP22_EISA_MAX_SLOTS; i++) { if ((str = decode_eisa_sig(0x1000 * i + EISA_VENDOR_ID_OFFSET))) { printk(KERN_INFO "EISA: slot %d : %s detected.\n", i, str); c++; Loading @@ -268,25 +254,25 @@ int __init ip22_eisa_init(void) Please wave your favorite dead chicken over the busses */ /* First say hello to the EIU */ EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF); EIU_WRITE_32(EIU_QUIET_REG, 1); EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F); outl(0x0000FFFF, EIU_PREMPT_REG); outl(1, EIU_QUIET_REG); outl(0x40f3c07F, EIU_MODE_REG); /* Now be nice to the EISA chipset */ EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1); for (i = 0; i < 10000; i++); /* Wait long enough for the dust to settle */ EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0); EISA_WRITE_8(EISA_INT1_CTRL, 0x11); EISA_WRITE_8(EISA_INT2_CTRL, 0x11); EISA_WRITE_8(EISA_INT1_MASK, 0); EISA_WRITE_8(EISA_INT2_MASK, 8); EISA_WRITE_8(EISA_INT1_MASK, 4); EISA_WRITE_8(EISA_INT2_MASK, 2); EISA_WRITE_8(EISA_INT1_MASK, 1); EISA_WRITE_8(EISA_INT2_MASK, 1); EISA_WRITE_8(EISA_INT1_MASK, 0xfb); EISA_WRITE_8(EISA_INT2_MASK, 0xff); EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0); outb(1, EISA_EXT_NMI_RESET_CTRL); udelay(50); /* Wait long enough for the dust to settle */ outb(0, EISA_EXT_NMI_RESET_CTRL); outb(0x11, EISA_INT1_CTRL); outb(0x11, EISA_INT2_CTRL); outb(0, EISA_INT1_MASK); outb(8, EISA_INT2_MASK); outb(4, EISA_INT1_MASK); outb(2, EISA_INT2_MASK); outb(1, EISA_INT1_MASK); outb(1, EISA_INT2_MASK); outb(0xfb, EISA_INT1_MASK); outb(0xff, EISA_INT2_MASK); outb(0, EISA_DMA2_WRITE_SINGLE); for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) { irq_desc[i].status = IRQ_DISABLED; Loading