summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
commit546db14ee74118296f425f3b91634fb767d67290 (patch)
tree22b613a3da8d4bf663eec5e155af01b87fdf9094 /drivers/pcmcia
parent1e25e41c4f5474e14452094492dbc169b800e4c8 (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.in6
-rw-r--r--drivers/pcmcia/Makefile18
-rw-r--r--drivers/pcmcia/cardbus.c13
-rw-r--r--drivers/pcmcia/cb_enabler.c7
-rw-r--r--drivers/pcmcia/cs.c66
-rw-r--r--drivers/pcmcia/i82365.c367
-rw-r--r--drivers/pcmcia/o2micro.h35
-rw-r--r--drivers/pcmcia/rsrc_mgr.c120
-rw-r--r--drivers/pcmcia/rsrc_mgr.h6
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 */