From: Jim P. <jim...@us...> - 2001-11-26 20:19:56
|
Update of /cvsroot/linux-mips/linux/drivers/pcmcia In directory usw-pr-cvs1:/tmp/cvs-serv11286 Modified Files: Config.in cs.c i82365.c Log Message: Add support for ISA IRQ remapping Index: Config.in =================================================================== RCS file: /cvsroot/linux-mips/linux/drivers/pcmcia/Config.in,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- Config.in 2001/11/06 09:10:22 1.2 +++ Config.in 2001/11/26 20:19:53 1.3 @@ -19,6 +19,7 @@ fi bool ' i82092 compatible bridge support' CONFIG_I82092 bool ' i82365 compatible bridge support' CONFIG_I82365 + dep_bool ' Support ISA IRQ remapping' CONFIG_PCMCIA_IRQ_REMAP $CONFIG_I82365 bool ' Databook TCIC host bridge support' CONFIG_TCIC if [ "$CONFIG_HD64465" = "y" ]; then dep_tristate ' HD64465 host bridge support' CONFIG_HD64465_PCMCIA $CONFIG_PCMCIA Index: cs.c =================================================================== RCS file: /cvsroot/linux-mips/linux/drivers/pcmcia/cs.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- cs.c 2001/11/26 20:17:35 1.4 +++ cs.c 2001/11/26 20:19:53 1.5 @@ -268,6 +268,18 @@ return s->ss_entry->set_mem_map(s->sock, mem); } +#ifdef CONFIG_PCMCIA_IRQ_REMAP +static int get_io_irq(socket_info_t *s, int *irq) +{ + return s->ss_entry->get_io_irq(s->sock, irq); +} + +static int get_bus_irq(socket_info_t *s, int *irq) +{ + return s->ss_entry->get_bus_irq(s->sock, irq); +} +#endif + static int suspend_socket(socket_info_t *s) { s->socket = dead_socket; @@ -1348,6 +1360,16 @@ if (mod->Attributes & CONF_ENABLE_IRQ) { c->Attributes |= CONF_ENABLE_IRQ; s->socket.io_irq = s->irq.AssignedIRQ; +#ifdef CONFIG_PCMCIA_IRQ_REMAP + int irq; + c->Attributes |= CONF_ENABLE_IRQ; + irq = s->irq.AssignedIRQ; + get_io_irq(s, &irq); + s->socket.io_irq = irq; +#else + c->Attributes |= CONF_ENABLE_IRQ; + s->socket.io_irq = s->irq.AssignedIRQ; +#endif } else { c->Attributes &= ~CONF_ENABLE_IRQ; s->socket.io_irq = 0; @@ -1694,7 +1716,16 @@ if (req->Attributes & CONF_ENABLE_SPKR) s->socket.flags |= SS_SPKR_ENA; if (req->Attributes & CONF_ENABLE_IRQ) +#ifdef CONFIG_PCMCIA_IRQ_REMAP + { + int irq; + irq = s->irq.AssignedIRQ; + get_io_irq(s, &irq); + s->socket.io_irq = irq; + } +#else s->socket.io_irq = s->irq.AssignedIRQ; +#endif else s->socket.io_irq = 0; set_socket(s, &s->socket); @@ -1882,6 +1913,15 @@ for (try = 0; try < 2; try++) { for (irq = 0; irq < 32; irq++) if ((mask >> irq) & 1) { +#ifdef CONFIG_PCMCIA_IRQ_REMAP + get_bus_irq(s, &irq); + if ((req->Attributes & IRQ_TYPE) == IRQ_TYPE_DYNAMIC_SHARING) { + if (try == 0) + req->Attributes |= IRQ_FIRST_SHARED; + else + req->Attributes &= ~IRQ_FIRST_SHARED; + } +#endif ret = try_irq(req->Attributes, irq, try); if (ret == 0) break; } Index: i82365.c =================================================================== RCS file: /cvsroot/linux-mips/linux/drivers/pcmcia/i82365.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- i82365.c 2001/11/26 20:17:35 1.1 +++ i82365.c 2001/11/26 20:19:53 1.2 @@ -46,6 +46,9 @@ #include <linux/ioport.h> #include <linux/delay.h> #include <linux/proc_fs.h> +#ifdef CONFIG_PCMCIA_IRQ_REMAP +#include <linux/interrupt.h> +#endif #include <asm/irq.h> #include <asm/io.h> #include <asm/bitops.h> @@ -106,6 +109,10 @@ static int irq_list[16] = { -1 }; /* The card status change interrupt -- 0 means autoselect */ static int cs_irq = 0; +#ifdef CONFIG_PCMCIA_IRQ_REMAP +/* IRQ map for IO IRQ convert to ISA IRQ */ +static int irq_map[16] = { [0 ... 15] = 0 }; +#endif #endif /* Probe for safe interrupts? */ @@ -139,6 +146,9 @@ MODULE_PARM(irq_mask, "i"); MODULE_PARM(irq_list, "1-16i"); MODULE_PARM(cs_irq, "i"); +#ifdef CONFIG_PCMCIA_IRQ_REMAP +MODULE_PARM(irq_map, "1-16i"); +#endif MODULE_PARM(async_clock, "i"); MODULE_PARM(cable_mode, "i"); MODULE_PARM(wakeup, "i"); @@ -548,6 +558,15 @@ static u_int __init test_irq(u_short sock, int irq) { DEBUG(2, " testing ISA irq %d\n", irq); +#ifdef CONFIG_PCMCIA_IRQ_REMAP +{ + unsigned long irqs; + int probe_irq, i; + udelay(1000); + probe_irq_off(probe_irq_on()); + irq_hits = 0; + irqs = probe_irq_on(); +#else if (request_irq(irq, irq_count, 0, "scan", irq_count) != 0) return 1; irq_hits = 0; irq_sock = sock; @@ -558,13 +577,26 @@ DEBUG(2, " spurious hit!\n"); return 1; } - +#endif /* Generate one interrupt */ i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4)); i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ); udelay(1000); +#ifdef CONFIG_PCMCIA_IRQ_REMAP + probe_irq = probe_irq_off(irqs); + if (probe_irq) { + for (i = 0; i < 16; i++) + if (irq_map[i] == probe_irq) break; + if (i >= 16 || i == irq) { + irq_map[irq] = probe_irq; + irq_hits = 1; + } + } +} +#else free_irq(irq, irq_count); +#endif /* mask all interrupts */ i365_set(sock, I365_CSCINT, 0); @@ -585,7 +617,6 @@ /* Don't probe level-triggered interrupts -- reserved for PCI */ mask0 &= ~(inb(PIC) | (inb(PIC+1) << 8)); #endif - if (do_scan) { set_bridge_state(sock); i365_set(sock, I365_CSCINT, 0); @@ -601,10 +632,12 @@ if (mask1) { printk("scanned"); } else { +#ifndef CONFIG_PCMCIA_IRQ_REMAP /* Fallback: just find interrupts that aren't in use */ for (i = 0; i < 16; i++) if ((mask0 & (1 << i)) && (_check_irq(i, 0) == 0)) mask1 |= (1 << i); +#endif printk("default"); /* If scan failed, default to polled status */ if (!cs_irq && (poll_interval == 0)) poll_interval = HZ; @@ -613,7 +646,11 @@ for (i = 0; i < 16; i++) if (mask1 & (1<<i)) +#ifdef CONFIG_PCMCIA_IRQ_REMAP + printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), irq_map[i]); +#else printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i); +#endif if (mask1 == 0) printk("none!"); return mask1; @@ -1549,6 +1586,33 @@ LOCKED(i365_set_mem_map(sock, mem)); } +#ifdef CONFIG_PCMCIA_IRQ_REMAP +static int pcic_get_io_irq(unsigned int sock, int *irq) +{ + int i; + + for (i = 0; i < 16; i++) + if (irq_map[i] == *irq) break; + + if (i < 16) + *irq = i; + else + *irq = 0; + + return 0; +} + +static int pcic_get_bus_irq(unsigned int sock, int *irq) +{ + if (*irq < 0 || *irq >= 16) + return -EINVAL; + + *irq = irq_map[*irq]; + + return 0; +} +#endif + static int pcic_init(unsigned int s) { int i; @@ -1585,6 +1649,10 @@ pcic_set_io_map, pcic_get_mem_map, pcic_set_mem_map, +#ifdef CONFIG_PCMCIA_IRQ_REMAP + pcic_get_io_irq, + pcic_get_bus_irq, +#endif pcic_proc_setup }; |