diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
commit | 546db14ee74118296f425f3b91634fb767d67290 (patch) | |
tree | 22b613a3da8d4bf663eec5e155af01b87fdf9094 /drivers/pcmcia | |
parent | 1e25e41c4f5474e14452094492dbc169b800e4c8 (diff) |
Merge with Linux 2.3.23. The new bootmem stuff has broken various
platforms. At this time I've only verified that IP22 support compiles
and IP27 actually works.
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/Config.in | 6 | ||||
-rw-r--r-- | drivers/pcmcia/Makefile | 18 | ||||
-rw-r--r-- | drivers/pcmcia/cardbus.c | 13 | ||||
-rw-r--r-- | drivers/pcmcia/cb_enabler.c | 7 | ||||
-rw-r--r-- | drivers/pcmcia/cs.c | 66 | ||||
-rw-r--r-- | drivers/pcmcia/i82365.c | 367 | ||||
-rw-r--r-- | drivers/pcmcia/o2micro.h | 35 | ||||
-rw-r--r-- | drivers/pcmcia/rsrc_mgr.c | 120 | ||||
-rw-r--r-- | drivers/pcmcia/rsrc_mgr.h | 6 |
9 files changed, 282 insertions, 356 deletions
diff --git a/drivers/pcmcia/Config.in b/drivers/pcmcia/Config.in index 2883046c1..aaedbf74a 100644 --- a/drivers/pcmcia/Config.in +++ b/drivers/pcmcia/Config.in @@ -2,13 +2,15 @@ # PCMCIA bus subsystem configuration # mainmenu_option next_comment -comment 'PCMCIA/Cardbus support' +comment 'PCMCIA/CardBus support' -tristate 'PCMCIA/Cardbus support' CONFIG_PCMCIA +tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA if [ "$CONFIG_PCMCIA" != "n" ]; then if [ "$CONFIG_PCI" != "n" ]; then bool ' CardBus support' CONFIG_CARDBUS fi + bool ' i82365/Yenta compatible bridge support' CONFIG_I82365 + bool ' Databook TCIC host bridge support' CONFIG_TCIC fi endmenu diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 71750544d..703a7c6c8 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -15,20 +15,34 @@ ALL_SUB_DIRS := $(SUB_DIRS) MOD_LIST_NAME := PCMCIA_MODULES ifeq ($(CONFIG_PCMCIA),y) - O_OBJS := i82365.o tcic.o cistpl.o rsrc_mgr.o bulkmem.o + O_OBJS := cistpl.o rsrc_mgr.o bulkmem.o OX_OBJS := ds.o cs.o O_TARGET := pcmcia.o + ifeq ($(CONFIG_I82365),y) + O_OBJS += i82365.o + endif + ifeq ($(CONFIG_TCIC),y) + O_OBJS += tcic.o + endif ifeq ($(CONFIG_CARDBUS),y) O_OBJS += cardbus.o + OX_OBJS += cb_enabler.o endif else ifeq ($(CONFIG_PCMCIA),m) - M_OBJS := i82365.o tcic.o pcmcia_core.o + M_OBJS := pcmcia_core.o MX_OBJS := ds.o MIX_OBJS := cs.o CORE_OBJS := cistpl.o rsrc_mgr.o bulkmem.o cs.o + ifeq ($(CONFIG_I82365),y) + M_OBJS += i82365.o + endif + ifeq ($(CONFIG_TCIC),y) + M_OBJS += tcic.o + endif ifeq ($(CONFIG_CARDBUS),y) CORE_OBJS += cardbus.o + MX_OBJS += cb_enabler.o endif endif endif diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index de8b76da3..490182e00 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -2,7 +2,7 @@ Cardbus device configuration - cardbus.c 1.59 1999/09/15 15:32:19 + cardbus.c 1.61 1999/10/20 22:36:57 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -325,9 +325,9 @@ int cb_alloc(socket_info_t *s) pci_readl(bus, i, PCI_CLASS_REVISION, &c[i].dev.class); c[i].dev.class >>= 8; c[i].dev.hdr_type = hdr; -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS pci_proc_attach_device(&c[i].dev); -#endif +#endif } return CS_SUCCESS; @@ -344,9 +344,9 @@ void cb_free(socket_info_t *s) if (*p == &c[0].dev) break; for (q = *p; q; q = q->next) { if (q->bus != (*p)->bus) break; -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS pci_proc_detach_device(q); -#endif +#endif } if (*p) *p = q; s->cap.cb_bus->devices = NULL; @@ -496,7 +496,8 @@ int cb_config(socket_info_t *s) s->irq.AssignedIRQ = irq; } } - c[0].dev.irq = irq; + for (i = 0; i < fn; i++) + c[i].dev.irq = irq; return CS_SUCCESS; diff --git a/drivers/pcmcia/cb_enabler.c b/drivers/pcmcia/cb_enabler.c index b0e75ceec..00cf824b3 100644 --- a/drivers/pcmcia/cb_enabler.c +++ b/drivers/pcmcia/cb_enabler.c @@ -2,7 +2,7 @@ Cardbus device enabler - cb_enabler.c 1.23 1999/09/15 15:32:19 + cb_enabler.c 1.24 1999/10/20 00:19:09 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -58,7 +58,7 @@ static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"cb_enabler.c 1.23 1999/09/15 15:32:19 (David Hinds)"; +"cb_enabler.c 1.24 1999/10/20 00:19:09 (David Hinds)"; #else #define DEBUG(n, args...) do { } while (0) #endif @@ -372,6 +372,9 @@ void unregister_driver(struct driver_operations *ops) /*====================================================================*/ +EXPORT_SYMBOL(register_driver); +EXPORT_SYMBOL(unregister_driver); + static int __init init_cb_enabler(void) { servinfo_t serv; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 470514c55..f7fda7d8d 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -2,7 +2,7 @@ PCMCIA Card Services -- core services - cs.c 1.228 1999/09/15 15:32:19 + cs.c 1.232 1999/10/20 22:17:24 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -70,7 +70,7 @@ static int handle_apm_event(apm_event_t event); int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); static const char *version = -"cs.c 1.228 1999/09/15 15:32:19 (David Hinds)"; +"cs.c 1.232 1999/10/20 22:17:24 (David Hinds)"; #endif static const char *release = "Linux PCMCIA Card Services " CS_RELEASE; @@ -353,41 +353,40 @@ void unregister_ss_entry(ss_entry_t ss_entry) socket_info_t *s = NULL; client_t *client; +#ifdef CONFIG_PROC_FS + for (i = 0; i < sockets; i++) { + s = socket_table[i]; + if (s->ss_entry != ss_entry) continue; + if (proc_pccard) { + char name[3]; + sprintf(name, "%02d", i); +#ifdef PCMCIA_DEBUG + remove_proc_entry("clients", s->proc); +#endif + } + } +#endif + for (;;) { for (i = 0; i < sockets; i++) { s = socket_table[i]; if (s->ss_entry == ss_entry) break; } - if (i == sockets) { + if (i == sockets) break; - } else { -#ifdef CONFIG_PROC_FS - if (proc_pccard) { - char name[3]; - sprintf(name, "%02d", i); -#ifdef PCMCIA_DEBUG - remove_proc_entry("clients", s->proc); -#endif - remove_proc_entry(name, proc_pccard); - } -#endif - while (s->clients) { - client = s->clients; - s->clients = s->clients->next; - kfree(client); - } - init_socket(s); - release_cis_mem(s); -#ifdef CONFIG_CARDBUS - cb_release_cis_mem(s); -#endif - s->ss_entry = NULL; - kfree(s); - socket_table[i] = NULL; - for (j = i; j < sockets-1; j++) - socket_table[j] = socket_table[j+1]; - sockets--; + shutdown_socket(i); + release_cis_mem(s); + while (s->clients) { + client = s->clients; + s->clients = s->clients->next; + kfree(client); } + s->ss_entry = NULL; + kfree(s); + socket_table[i] = NULL; + for (j = i; j < sockets-1; j++) + socket_table[j] = socket_table[j+1]; + sockets--; } } /* unregister_ss_entry */ @@ -1808,7 +1807,7 @@ static int request_window(client_handle_t *handle, win_req_t *req) { socket_info_t *s; window_t *win; - int w; + int w, align; if (CHECK_HANDLE(*handle)) return CS_BAD_HANDLE; @@ -1835,9 +1834,10 @@ static int request_window(client_handle_t *handle, win_req_t *req) win->sock = s; win->base = req->Base; win->size = req->Size; + align = ((s->cap.features & SS_CAP_MEM_ALIGN) || + (req->Attributes & WIN_STRICT_ALIGN)); if (find_mem_region(&win->base, win->size, (*handle)->dev_info, - ((s->cap.features & SS_CAP_MEM_ALIGN) ? - req->Size : s->cap.map_size), + (align ? req->Size : s->cap.map_size), (req->Attributes & WIN_MAP_BELOW_1MB) || !(s->cap.features & SS_CAP_PAGE_REGS))) return CS_IN_USE; diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 9e80943e4..ed7bd3c30 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -3,7 +3,7 @@ Device driver for Intel 82365 and compatible PC Card controllers, and Yenta-compatible PCI-to-CardBus controllers. - i82365.c 1.254 1999/09/15 15:32:19 + i82365.c 1.260 1999/10/21 00:56:07 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -76,7 +76,7 @@ static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static const char *version = -"i82365.c 1.254 1999/09/15 15:32:19 (David Hinds)"; +"i82365.c 1.260 1999/10/21 00:56:07 (David Hinds)"; #else #define DEBUG(n, args...) do { } while (0) #endif @@ -189,7 +189,7 @@ MODULE_PARM(cb_write_post, "i"); #ifdef CONFIG_ISA #ifdef CONFIG_PCI /* PCI card status change interrupts? */ -static int pci_csc = 0; +static int pci_csc = 1; /* PCI IO card functional interrupts? */ static int pci_int = 0; MODULE_PARM(pci_csc, "i"); @@ -240,7 +240,7 @@ typedef struct topic_state_t { typedef struct socket_info_t { u_short type, flags; socket_cap_t cap; - u_short ioaddr; + ioaddr_t ioaddr; u_short psock; u_char cs_irq, intr; void (*handler)(void *info, u_int events); @@ -278,18 +278,18 @@ static socket_info_t socket[8] = { /* Default ISA interrupt mask */ #define I365_MASK 0xdeb8 /* irq 15,14,12,11,10,9,7,5,4,3 */ -static void pcic_interrupt_wrapper(u_long); -static void pcic_interrupt(int irq, void *dev, - struct pt_regs *regs); -static int pcic_service(u_int sock, u_int cmd, void *arg); -#ifdef CONFIG_PROC_FS -static void pcic_proc_remove(u_short sock); -#endif - #ifdef CONFIG_ISA static int grab_irq; static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED; +#define ISA_LOCK(n, f) \ + if (!(socket[n].flags & IS_CARDBUS)) spin_lock_irqsave(&isa_lock, f) +#define ISA_UNLOCK(n, f) \ + if (!(socket[n].flags & IS_CARDBUS)) spin_unlock_irqrestore(&isa_lock, f) +#else +#define ISA_LOCK(n, f) do { } while (0) +#define ISA_UNLOCK(n, f) do { } while (0) #endif + static struct timer_list poll_timer; /*====================================================================*/ @@ -322,7 +322,7 @@ typedef enum pcic_id { #ifdef CONFIG_PCI IS_PD6729, IS_PD6730, IS_OZ6729, IS_OZ6730, IS_I82092AA, IS_OM82C092G, - IS_PD6832, IS_OZ6832, IS_OZ6836, + IS_PD6832, IS_OZ6832, IS_OZ6836, IS_OZ6812, IS_RL5C465, IS_RL5C466, IS_RL5C475, IS_RL5C476, IS_RL5C478, IS_SMC34C90, IS_TI1130, IS_TI1131, IS_TI1250A, IS_TI1220, IS_TI1221, IS_TI1210, @@ -388,6 +388,8 @@ static pcic_t pcic[] = { PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6832 }, { "O2Micro OZ6836/OZ6860", IS_O2MICRO|IS_CARDBUS|IS_VG_PWR, PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6836 }, + { "O2Micro OZ6812", IS_O2MICRO|IS_CARDBUS|IS_VG_PWR, + PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6812 }, { "Ricoh RL5C465", IS_RICOH|IS_CARDBUS|IS_DF_PWR, PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465 }, { "Ricoh RL5C466", IS_RICOH|IS_CARDBUS|IS_DF_PWR, @@ -441,8 +443,6 @@ static pcic_t pcic[] = { /* Some PCI shortcuts */ -#ifdef CONFIG_PCI - #define pci_readb pcibios_read_config_byte #define pci_writeb pcibios_write_config_byte #define pci_readw pcibios_read_config_word @@ -457,7 +457,6 @@ static pcic_t pcic[] = { static void cb_get_power(u_short sock, socket_state_t *state); static void cb_set_power(u_short sock, socket_state_t *state); -#endif /*====================================================================*/ @@ -469,7 +468,7 @@ static u_char i365_get(u_short sock, u_short reg) else #endif { - u_short port = socket[sock].ioaddr; + ioaddr_t port = socket[sock].ioaddr; u_char val; reg = I365_REG(socket[sock].psock, reg); outb(reg, port); val = inb(port+1); @@ -485,7 +484,7 @@ static void i365_set(u_short sock, u_short reg, u_char data) else #endif { - u_short port = socket[sock].ioaddr; + ioaddr_t port = socket[sock].ioaddr; u_char val = I365_REG(socket[sock].psock, reg); outb(val, port); outb(data, port+1); } @@ -954,6 +953,8 @@ static u_int __init o2micro_set_opts(u_short s, char *buf) p->mode_e &= ~O2_MODE_E_MHPG_DMA; p->mhpg |= O2_MHPG_CINT_ENA | O2_MHPG_CSC_ENA; p->mhpg &= ~O2_MHPG_CHANNEL; + if (t->revision == 0x34) + p->mode_c = 0x20; } else { if (p->mode_b & O2_MODE_B_IRQ15_RI) mask &= ~0x8000; } @@ -1125,7 +1126,7 @@ static void __init cb_set_opts(u_short s, char *buf) ======================================================================*/ -static void get_host_state(u_short s) +static void get_bridge_state(u_short s) { socket_info_t *t = &socket[s]; if (t->flags & IS_CIRRUS) @@ -1148,7 +1149,7 @@ static void get_host_state(u_short s) #endif } -static void set_host_state(u_short s) +static void set_bridge_state(u_short s) { socket_info_t *t = &socket[s]; #ifdef CONFIG_PCI @@ -1178,7 +1179,7 @@ static void set_host_state(u_short s) #endif } -static u_int __init set_host_opts(u_short s, u_short ns) +static u_int __init set_bridge_opts(u_short s, u_short ns) { u_short i; u_int m = 0xffff; @@ -1190,7 +1191,7 @@ static u_int __init set_host_opts(u_short s, u_short ns) continue; } buf[0] = '\0'; - get_host_state(i); + get_bridge_state(i); if (socket[i].flags & IS_CIRRUS) m = cirrus_set_opts(i, buf); #ifdef CONFIG_ISA @@ -1209,7 +1210,7 @@ static u_int __init set_host_opts(u_short s, u_short ns) if (socket[i].flags & IS_CARDBUS) cb_set_opts(i, buf+strlen(buf)); #endif - set_host_state(i); + set_bridge_state(i); printk(KERN_INFO " host opts [%d]:%s\n", i, (*buf) ? buf : " none"); } @@ -1255,7 +1256,7 @@ static u_int __init test_irq(u_short sock, int irq, int pci) if (request_irq(irq, irq_count, (pci?SA_SHIRQ:0), "scan", NULL) != 0) return 1; irq_hits = 0; irq_sock = sock; - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/100); if (irq_hits) { free_irq(irq, NULL); @@ -1310,7 +1311,7 @@ static u_int __init isa_scan(u_short sock, u_int mask0) (cb_set_irq_mode(sock, 0, 0) == 0)) #endif if (do_scan) { - set_host_state(sock); + set_bridge_state(sock); i365_set(sock, I365_CSCINT, 0); for (i = 0; i < 16; i++) if ((mask0 & (1 << i)) && (test_irq(sock, i, 0) == 0)) @@ -1351,7 +1352,7 @@ static void __init pci_scan(u_short sock) u_int i; cb_set_irq_mode(sock, 1, 0); - set_host_state(sock); + set_bridge_state(sock); i365_set(sock, I365_CSCINT, 0); /* Only probe irq's 9..11, to be conservative */ for (i = 9; i < 12; i++) { @@ -1371,7 +1372,7 @@ static void __init pci_scan(u_short sock) static int to_cycles(int ns) { return ns/cycle_time; -} /* speed_convert */ +} static int to_ns(int cycles) { @@ -1517,7 +1518,7 @@ static void __init add_pcic(int ns, int type) for (i = mask = 0; i < 16; i++) mask |= (1<<irq_list[i]); #endif - mask &= I365_MASK & set_host_opts(base, ns); + mask &= I365_MASK & set_bridge_opts(base, ns); #ifdef CONFIG_ISA /* Scan for ISA interrupts */ mask = isa_scan(base, mask); @@ -1672,8 +1673,7 @@ static void __init add_cb_bridge(int type, u_char bus, u_char devfn, s->cb_virt = ioremap(s->cb_phys, 0x1000); pci_writel(bus, devfn, PCI_BASE_ADDRESS_0, s->cb_phys); /* Simple sanity checks */ - if (((readb(s->cb_virt+0x800+I365_IDENT) & 0xf0) - == 0x80) && + if (!(readb(s->cb_virt+0x800+I365_IDENT) & 0x70) && !(readb(s->cb_virt+0x800+I365_CSC) && readb(s->cb_virt+0x800+I365_CSC) && readb(s->cb_virt+0x800+I365_CSC))) @@ -1712,7 +1712,7 @@ static void __init add_cb_bridge(int type, u_char bus, u_char devfn, /* Re-do card type & voltage detection */ cb_writel(sockets-ns, CB_SOCKET_FORCE, CB_SF_CVSTEST); - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/5); /* Set up PCI bus bridge structures if needed */ @@ -1762,9 +1762,8 @@ static void __init pci_probe(u_int class, void (add_fn) static void __init isa_probe(void) { - int i, j, sock, k; - int ns, id; - u_short port; + int i, j, sock, k, ns, id; + ioaddr_t port; if (check_region(i365_base, 2) != 0) { if (sockets == 0) @@ -1812,115 +1811,6 @@ static void __init isa_probe(void) /*====================================================================*/ -static int __init init_i82365(void) -{ - servinfo_t serv; - CardServices(GetCardServicesInfo, &serv); - if (serv.Revision != CS_RELEASE_CODE) { - printk(KERN_NOTICE "i82365: Card Services release " - "does not match!\n"); - return -1; - } - DEBUG(0, "%s\n", version); - printk(KERN_INFO "Intel PCIC probe: "); - sockets = 0; - -#ifdef CONFIG_PCI - if (do_pci_probe && pcibios_present()) { - pci_probe(PCI_CLASS_BRIDGE_CARDBUS, add_cb_bridge); - pci_probe(PCI_CLASS_BRIDGE_PCMCIA, add_pci_bridge); - } -#endif - -#ifdef CONFIG_ISA - isa_probe(); -#endif - - if (sockets == 0) { - printk("not found.\n"); - return -ENODEV; - } - - /* Set up interrupt handler(s) */ -#ifdef CONFIG_ISA - if (grab_irq != 0) - request_irq(cs_irq, pcic_interrupt, 0, "i82365", NULL); -#endif -#ifdef CONFIG_PCI - if (pci_csc) { - u_int i, irq, mask = 0; - for (i = 0; i < sockets; i++) { - irq = socket[i].cap.pci_irq; - if (irq && !(mask & (1<<irq))) - request_irq(irq, pcic_interrupt, SA_SHIRQ, "i82365", NULL); - mask |= (1<<irq); - } - } -#endif - - if (register_ss_entry(sockets, &pcic_service) != 0) - printk(KERN_NOTICE "i82365: register_ss_entry() failed\n"); - - /* Finally, schedule a polling interrupt */ - if (poll_interval != 0) { - poll_timer.function = pcic_interrupt_wrapper; - poll_timer.data = 0; - poll_timer.prev = poll_timer.next = NULL; - poll_timer.expires = jiffies + poll_interval; - add_timer(&poll_timer); - } - - return 0; - -} /* init_i82365 */ - -/*====================================================================*/ - -static void __exit exit_i82365(void) -{ - int i; -#ifdef CONFIG_PROC_FS - for (i = 0; i < sockets; i++) pcic_proc_remove(i); -#endif - unregister_ss_entry(&pcic_service); - if (poll_interval != 0) - del_timer(&poll_timer); -#ifdef CONFIG_ISA - if (grab_irq != 0) - free_irq(cs_irq, NULL); -#endif -#ifdef CONFIG_PCI - if (pci_csc) { - u_int irq, mask = 0; - for (i = 0; i < sockets; i++) { - irq = socket[i].cap.pci_irq; - if (irq && !(mask & (1<<irq))) - free_irq(irq, NULL); - mask |= (1<<irq); - } - } -#endif - for (i = 0; i < sockets; i++) { - i365_set(i, I365_CSCINT, 0); -#ifdef CONFIG_PCI - if (socket[i].cb_virt) { - iounmap(socket[i].cb_virt); - release_mem_region(socket[i].cb_phys, 0x1000); - } else -#endif - release_region(socket[i].ioaddr, 2); - } -} /* exit_i82365 */ - -/*====================================================================*/ - -static void pcic_interrupt_wrapper(u_long data) -{ - pcic_interrupt(0, NULL, NULL); - poll_timer.expires = jiffies + poll_interval; - add_timer(&poll_timer); -} - static void pcic_interrupt(int irq, void *dev, struct pt_regs *regs) { @@ -1938,17 +1828,18 @@ static void pcic_interrupt(int irq, void *dev, if ((socket[i].cs_irq != irq) && (socket[i].cap.pci_irq != irq)) continue; -#ifdef CONFIG_ISA - if (!(socket[i].flags & IS_CARDBUS)) - spin_lock_irqsave(&isa_lock, flags); -#endif + ISA_LOCK(i, flags); csc = i365_get(i, I365_CSC); +#ifdef CONFIG_PCI + if ((socket[i].flags & IS_CARDBUS) && + (cb_readl(i,CB_SOCKET_EVENT) & (CB_SE_CCD1|CB_SE_CCD2))) { + cb_writel(i, CB_SOCKET_EVENT, CB_SE_CCD1|CB_SE_CCD2); + csc |= I365_CSC_DETECT; + } +#endif if ((csc == 0) || (!socket[i].handler) || (i365_get(i, I365_IDENT) & 0x70)) { -#ifdef CONFIG_ISA - if (!(socket[i].flags & IS_CARDBUS)) - spin_unlock_irqrestore(&isa_lock, flags); -#endif + ISA_UNLOCK(i, flags); continue; } events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0; @@ -1959,10 +1850,7 @@ static void pcic_interrupt(int irq, void *dev, events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0; events |= (csc & I365_CSC_READY) ? SS_READY : 0; } -#ifdef CONFIG_ISA - if (!(socket[i].flags & IS_CARDBUS)) - spin_unlock_irqrestore(&isa_lock, flags); -#endif + ISA_UNLOCK(i, flags); DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events); if (events) socket[i].handler(socket[i].info, events); @@ -1976,6 +1864,13 @@ static void pcic_interrupt(int irq, void *dev, DEBUG(4, "i82365: interrupt done\n"); } /* pcic_interrupt */ +static void pcic_interrupt_wrapper(u_long data) +{ + pcic_interrupt(0, NULL, NULL); + poll_timer.expires = jiffies + poll_interval; + add_timer(&poll_timer); +} + /*====================================================================*/ static int pcic_register_callback(u_short sock, ss_callback_t *call) @@ -2149,7 +2044,7 @@ static int i365_set_socket(u_short sock, socket_state_t *state) (t->cap.pci_irq == state->io_irq)); t->bcr &= ~CB_BCR_CB_RESET; #endif - set_host_state(sock); + set_bridge_state(sock); /* IO card, RESET flag, IO interrupt */ reg = t->intr; @@ -2250,6 +2145,13 @@ static int i365_set_socket(u_short sock, socket_state_t *state) } i365_set(sock, I365_CSCINT, reg); i365_get(sock, I365_CSC); +#ifdef CONFIG_PCI + if (t->flags & IS_CARDBUS) { + if (t->cs_irq || (pci_csc && t->cap.pci_irq)) + cb_writel(sock, CB_SOCKET_MASK, CB_SM_CCD); + cb_writel(sock, CB_SOCKET_EVENT, -1); + } +#endif return 0; } /* i365_set_socket */ @@ -2428,7 +2330,7 @@ static void cb_get_power(u_short sock, socket_state_t *state) case CB_SC_VCC_3V: state->Vcc = 33; break; case CB_SC_VCC_5V: state->Vcc = 50; break; } - switch (reg & CB_SC_VCC_MASK) { + switch (reg & CB_SC_VPP_MASK) { case CB_SC_VPP_3V: state->Vpp = 33; break; case CB_SC_VPP_5V: state->Vpp = 50; break; case CB_SC_VPP_12V: state->Vpp = 120; break; @@ -2509,12 +2411,12 @@ static int cb_set_socket(u_short sock, socket_state_t *state) (s->cap.pci_irq == state->io_irq)); s->bcr &= ~CB_BCR_CB_RESET; s->bcr |= (state->flags & SS_RESET) ? CB_BCR_CB_RESET : 0; - set_host_state(sock); + set_bridge_state(sock); cb_set_power(sock, state); /* Handle IO interrupt using ISA routing */ - reg = i365_get(sock, I365_INTCTL) & ~I365_IRQ_MASK; + reg = s->intr; if (state->io_irq != s->cap.pci_irq) reg |= state->io_irq; i365_set(sock, I365_INTCTL, reg); @@ -2523,6 +2425,9 @@ static int cb_set_socket(u_short sock, socket_state_t *state) if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT; i365_set(sock, I365_CSCINT, reg); i365_get(sock, I365_CSC); + if (s->cs_irq || (pci_csc && s->cap.pci_irq)) + cb_writel(sock, CB_SOCKET_MASK, CB_SM_CCD); + cb_writel(sock, CB_SOCKET_EVENT, -1); return 0; } /* cb_set_socket */ @@ -2623,9 +2528,8 @@ static int proc_read_exca(char *buf, char **start, off_t pos, #ifdef CONFIG_ISA u_long flags = 0; - if (!(socket[sock].flags & IS_CARDBUS)) - spin_lock_irqsave(&isa_lock, flags); #endif + ISA_LOCK(sock, flags); top = 0x40; if (socket[sock].flags & IS_CARDBUS) top = (socket[sock].flags & IS_CIRRUS) ? 0x140 : 0x50; @@ -2639,10 +2543,7 @@ static int proc_read_exca(char *buf, char **start, off_t pos, i365_get(sock,i+2), i365_get(sock,i+3), ((i % 16) == 12) ? "\n" : " "); } -#ifdef CONFIG_ISA - if (!(socket[sock].flags & IS_CARDBUS)) - spin_unlock_irqrestore(&isa_lock, flags); -#endif + ISA_UNLOCK(sock, flags); return (p - buf); } @@ -2672,13 +2573,15 @@ static int proc_read_cardbus(char *buf, char **start, off_t pos, int count, int *eof, void *data) { u_short sock = (socket_info_t *)data - socket; - int len; - - len = sprintf(buf, "%08x %08x %08x %08x %08x %08x\n", - cb_readl(sock,0), cb_readl(sock,4), - cb_readl(sock,8), cb_readl(sock,12), - cb_readl(sock,16), cb_readl(sock,32)); - return len; + char *p = buf; + int i, top; + + top = (socket[sock].flags & IS_O2MICRO) ? 0x30 : 0x20; + for (i = 0; i < top; i += 0x10) + p += sprintf(p, "%08x %08x %08x %08x\n", + cb_readl(sock,i+0x00), cb_readl(sock,i+0x04), + cb_readl(sock,i+0x08), cb_readl(sock,i+0x0c)); + return (p - buf); } #endif @@ -2757,7 +2660,11 @@ static subfn_t pcic_service_table[] = { static int pcic_service(u_int sock, u_int cmd, void *arg) { subfn_t fn; - + int ret; +#ifdef CONFIG_ISA + u_long flags = 0; +#endif + DEBUG(2, "pcic_ioctl(%d, %d, 0x%p)\n", sock, cmd, arg); if (cmd >= NFUNC) @@ -2782,20 +2689,114 @@ static int pcic_service(u_int sock, u_int cmd, void *arg) } #endif + ISA_LOCK(sock, flags); + ret = (fn == NULL) ? -EINVAL : fn(sock, arg); + ISA_UNLOCK(sock, flags); + return ret; +} /* pcic_service */ + +/*====================================================================*/ + +static int __init init_i82365(void) +{ + servinfo_t serv; + CardServices(GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk(KERN_NOTICE "i82365: Card Services release " + "does not match!\n"); + return -1; + } + DEBUG(0, "%s\n", version); + printk(KERN_INFO "Intel PCIC probe: "); + sockets = 0; + +#ifdef CONFIG_PCI + if (do_pci_probe && pcibios_present()) { + pci_probe(PCI_CLASS_BRIDGE_CARDBUS, add_cb_bridge); + pci_probe(PCI_CLASS_BRIDGE_PCMCIA, add_pci_bridge); + } +#endif + #ifdef CONFIG_ISA - if (!(socket[sock].flags & IS_CARDBUS)) { - int ret; - u_long flags; - spin_lock_irqsave(&isa_lock, flags); - ret = (fn == NULL) ? -EINVAL : fn(sock, arg); - spin_unlock_irqrestore(&isa_lock, flags); - return ret; + isa_probe(); +#endif + + if (sockets == 0) { + printk("not found.\n"); + return -ENODEV; } + + /* Set up interrupt handler(s) */ +#ifdef CONFIG_ISA + if (grab_irq != 0) + request_irq(cs_irq, pcic_interrupt, 0, "i82365", NULL); #endif - return (fn == NULL) ? -EINVAL : fn(sock, arg); -} /* pcic_service */ +#ifdef CONFIG_PCI + if (pci_csc) { + u_int i, irq, mask = 0; + for (i = 0; i < sockets; i++) { + irq = socket[i].cap.pci_irq; + if (irq && !(mask & (1<<irq))) + request_irq(irq, pcic_interrupt, SA_SHIRQ, "i82365", NULL); + mask |= (1<<irq); + } + } +#endif + + if (register_ss_entry(sockets, &pcic_service) != 0) + printk(KERN_NOTICE "i82365: register_ss_entry() failed\n"); -/*====================================================================*/ + /* Finally, schedule a polling interrupt */ + if (poll_interval != 0) { + poll_timer.function = pcic_interrupt_wrapper; + poll_timer.data = 0; + poll_timer.prev = poll_timer.next = NULL; + poll_timer.expires = jiffies + poll_interval; + add_timer(&poll_timer); + } + + return 0; + +} /* init_i82365 */ + +static void __exit exit_i82365(void) +{ + int i; +#ifdef CONFIG_PROC_FS + for (i = 0; i < sockets; i++) pcic_proc_remove(i); +#endif + unregister_ss_entry(&pcic_service); + if (poll_interval != 0) + del_timer(&poll_timer); +#ifdef CONFIG_ISA + if (grab_irq != 0) + free_irq(cs_irq, NULL); +#endif +#ifdef CONFIG_PCI + if (pci_csc) { + u_int irq, mask = 0; + for (i = 0; i < sockets; i++) { + irq = socket[i].cap.pci_irq; + if (irq && !(mask & (1<<irq))) + free_irq(irq, NULL); + mask |= (1<<irq); + } + } +#endif + for (i = 0; i < sockets; i++) { + /* Turn off all interrupt sources! */ + i365_set(i, I365_CSCINT, 0); +#ifdef CONFIG_PCI + if (socket[i].flags & IS_CARDBUS) + cb_writel(i, CB_SOCKET_MASK, 0); + if (socket[i].cb_virt) { + iounmap(socket[i].cb_virt); + release_mem_region(socket[i].cb_phys, 0x1000); + } else +#endif + release_region(socket[i].ioaddr, 2); + } +} /* exit_i82365 */ module_init(init_i82365); module_exit(exit_i82365); diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h index 89cb6cf01..a3f922239 100644 --- a/drivers/pcmcia/o2micro.h +++ b/drivers/pcmcia/o2micro.h @@ -1,5 +1,5 @@ /* - * o2micro.h 1.10 1999/09/03 16:43:35 + * o2micro.h 1.12 1999/10/16 01:43:24 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -45,17 +45,38 @@ #ifndef PCI_DEVICE_ID_O2_6836 #define PCI_DEVICE_ID_O2_6836 0x6836 #endif +#ifndef PCI_DEVICE_ID_O2_6812 +#define PCI_DEVICE_ID_O2_6812 0x6872 +#endif + +/* Additional PCI configuration registers */ + +#define O2_MUX_CONTROL 0x90 /* 32 bit */ +#define O2_MUX_RING_OUT 0x0000000f +#define O2_MUX_SKTB_ACTV 0x000000f0 +#define O2_MUX_SCTA_ACTV_ENA 0x00000100 +#define O2_MUX_SCTB_ACTV_ENA 0x00000200 +#define O2_MUX_SER_IRQ_ROUTE 0x0000e000 +#define O2_MUX_SER_PCI 0x00010000 + +#define O2_MUX_SKTA_TURBO 0x000c0000 /* for 6833, 6860 */ +#define O2_MUX_SKTB_TURBO 0x00300000 +#define O2_MUX_AUX_VCC_3V 0x00400000 +#define O2_MUX_PCI_VCC_5V 0x00800000 +#define O2_MUX_PME_MUX 0x0f000000 + +/* Additional ExCA registers */ #define O2_MODE_A 0x38 -#define O2_MODE_A_2 0x26 /* For 6833B, 6860C */ +#define O2_MODE_A_2 0x26 /* for 6833B, 6860C */ #define O2_MODE_A_CD_PULSE 0x04 #define O2_MODE_A_SUSP_EDGE 0x08 #define O2_MODE_A_HOST_SUSP 0x10 -#define O2_MODE_A_PWRCHIP 0x60 +#define O2_MODE_A_PWR_MASK 0x60 #define O2_MODE_A_QUIET 0x80 #define O2_MODE_B 0x39 -#define O2_MODE_B_2 0x2e /* For 6833B, 6860C */ +#define O2_MODE_B_2 0x2e /* for 6833B, 6860C */ #define O2_MODE_B_IDENT 0x03 #define O2_MODE_B_ID_BSTEP 0x00 #define O2_MODE_B_ID_CSTEP 0x01 @@ -70,12 +91,16 @@ #define O2_MODE_C_DREQ_WP 0x02 #define O2_MODE_C_DREQ_BVD2 0x03 #define O2_MODE_C_ZVIDEO 0x08 +#define O2_MODE_C_IREQ_SEL 0x30 +#define O2_MODE_C_MGMT_SEL 0xc0 #define O2_MODE_D 0x3b #define O2_MODE_D_IRQ_MODE 0x03 +#define O2_MODE_D_PCI_CLKRUN 0x04 +#define O2_MODE_D_CB_CLKRUN 0x08 #define O2_MODE_D_SKT_ACTV 0x20 #define O2_MODE_D_PCI_FIFO 0x40 /* for OZ6729, OZ6730 */ -#define O2_MODE_D_W97_IRQ 0x40 /* for OZ6832 */ +#define O2_MODE_D_W97_IRQ 0x40 #define O2_MODE_D_ISA_IRQ 0x80 #define O2_MHPG_DMA 0x3c diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 52813cb5a..fa6eba768 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -2,7 +2,7 @@ Resource management routines - rsrc_mgr.c 1.71 1999/09/15 15:32:19 + rsrc_mgr.c 1.73 1999/10/19 00:54:04 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -98,124 +98,15 @@ static irq_info_t irq_table[NR_IRQS] = { { 0, 0, 0 }, /* etc */ }; #endif -static spinlock_t rsrc_lock = SPIN_LOCK_UNLOCKED; - /*====================================================================== Linux resource management extensions ======================================================================*/ -typedef struct resource_entry_t { - u_long base, num; - char *name; - struct resource_entry_t *next; -} resource_entry_t; - -/* Ordered linked lists of allocated IO and memory blocks */ -static resource_entry_t io_list = { 0, 0, NULL, NULL }; - -static resource_entry_t *find_gap(resource_entry_t *root, - resource_entry_t *entry) -{ - resource_entry_t *p; - - if (entry->base > entry->base+entry->num-1) - return NULL; - for (p = root; ; p = p->next) { - if ((p != root) && (p->base+p->num-1 >= entry->base)) { - p = NULL; - break; - } - if ((p->next == NULL) || - (p->next->base > entry->base+entry->num-1)) - break; - } - return p; -} - -static int register_my_resource(resource_entry_t *list, - u_long base, u_long num, char *name) -{ - u_long flags; - resource_entry_t *p, *entry; - - entry = kmalloc(sizeof(resource_entry_t), GFP_ATOMIC); - entry->base = base; - entry->num = num; - entry->name = name; - - spin_lock_irqsave(&rsrc_lock, flags); - p = find_gap(list, entry); - if (p == NULL) { - spin_unlock_irqrestore(&rsrc_lock, flags); - kfree(entry); - return -EBUSY; - } - entry->next = p->next; - p->next = entry; - spin_unlock_irqrestore(&rsrc_lock, flags); - return 0; -} - -static void release_my_resource(resource_entry_t *list, - u_long base, u_long num) -{ - u_long flags; - resource_entry_t *p, *q; - - spin_lock_irqsave(&rsrc_lock, flags); - for (p = list; ; p = q) { - q = p->next; - if (q == NULL) break; - if ((q->base == base) && (q->num == num)) { - p->next = q->next; - kfree(q); - spin_unlock_irqrestore(&rsrc_lock, flags); - return; - } - } - spin_unlock_irqrestore(&rsrc_lock, flags); - return; -} - -static int check_my_resource(resource_entry_t *list, - u_long base, u_long num) -{ - if (register_my_resource(list, base, num, NULL) != 0) - return -EBUSY; - release_my_resource(list, base, num); - return 0; -} +static spinlock_t rsrc_lock = SPIN_LOCK_UNLOCKED; -int check_io_region(u_long base, u_long num) -{ - return check_my_resource(&io_list, base, num); -} -void request_io_region(u_long base, u_long num, char *name) -{ - register_my_resource(&io_list, base, num, name); -} -void release_io_region(u_long base, u_long num) -{ - release_my_resource(&io_list, base, num); -} -#ifdef CONFIG_PROC_FS -int proc_read_io(char *buf, char **start, off_t pos, - int count, int *eof, void *data) -{ - resource_entry_t *r; - u_long flags; - char *p = buf; - - spin_lock_irqsave(&rsrc_lock, flags); - for (r = io_list.next; r; r = r->next) - p += sprintf(p, "%04lx-%04lx : %s\n", r->base, - r->base+r->num-1, r->name); - spin_unlock_irqrestore(&rsrc_lock, flags); - return (p - buf); -} -#endif +#define check_io_region(b,n) (0) /*====================================================================== @@ -773,7 +664,6 @@ int adjust_resource_info(client_handle_t handle, adjust_t *adj) void release_resource_db(void) { resource_map_t *p, *q; - resource_entry_t *u, *v; for (p = mem_db.next; p != &mem_db; p = q) { q = p->next; @@ -783,8 +673,4 @@ void release_resource_db(void) q = p->next; kfree(p); } - for (u = io_list.next; u; u = v) { - v = u->next; - kfree(u); - } } diff --git a/drivers/pcmcia/rsrc_mgr.h b/drivers/pcmcia/rsrc_mgr.h index 3b7f12e09..37faa3b26 100644 --- a/drivers/pcmcia/rsrc_mgr.h +++ b/drivers/pcmcia/rsrc_mgr.h @@ -30,10 +30,4 @@ #ifndef _RSRC_MGR_H #define _RSRC_MGR_H -#ifdef __BEOS__ -int check_resource(int type, u_long base, u_long num); -int register_resource(int type, u_long base, u_long num); -int release_resource(int type, u_long base, u_long num); -#endif - #endif /* _RSRC_MGR_H */ |