summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-28 22:58:42 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-28 22:58:42 +0000
commiteed6b7c84cc33f229f6fecd884d9a22af5bec514 (patch)
tree422a7a49328c59053f4fb11805adb753523c2f2c /drivers/pcmcia
parenta3b90e3c6976551acbac09f5aacd736a1658aaa8 (diff)
Merge with Linux 2.4.0-test5-pre6.
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/ds.c9
-rw-r--r--drivers/pcmcia/pci_socket.c11
-rw-r--r--drivers/pcmcia/yenta.c134
3 files changed, 89 insertions, 65 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index f536e42cb..a2a963215 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -878,7 +878,14 @@ int __init init_pcmcia_ds(void)
int i, ret;
DEBUG(0, "%s\n", version);
-
+
+ /*
+ * Ugly. But we want to wait for the socket threads to have started up.
+ * We really should let the drivers themselves drive some of this..
+ */
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ/10);
+
pcmcia_get_card_services_info(&serv);
if (serv.Revision != CS_RELEASE_CODE) {
printk(KERN_NOTICE "ds: Card Services release does not match!\n");
diff --git a/drivers/pcmcia/pci_socket.c b/drivers/pcmcia/pci_socket.c
index ce2fd652b..7f21f827e 100644
--- a/drivers/pcmcia/pci_socket.c
+++ b/drivers/pcmcia/pci_socket.c
@@ -181,6 +181,13 @@ static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_sock
return socket->op->open(socket);
}
+void cardbus_register(pci_socket_t *socket)
+{
+ int nr = socket - pci_socket_array;
+
+ socket->pcmcia_socket = pcmcia_register_socket(nr, &pci_socket_operations, 1);
+}
+
static int __devinit
cardbus_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
@@ -189,10 +196,6 @@ cardbus_probe (struct pci_dev *dev, const struct pci_device_id *id)
for (s = 0; s < MAX_SOCKETS; s++) {
if (pci_socket_array [s].dev == 0) {
add_pci_socket (s, dev, &yenta_operations);
- pci_socket_array [s].pcmcia_socket =
- pcmcia_register_socket (s,
- &pci_socket_operations,
- 1);
return 0;
}
}
diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c
index 25d3ed11f..0556c7906 100644
--- a/drivers/pcmcia/yenta.c
+++ b/drivers/pcmcia/yenta.c
@@ -470,35 +470,15 @@ static void yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
/*
- * Watch a socket every second (and possibly in a
- * more timely manner if the state change interrupt
- * works..)
+ * Only probe "regular" interrupts, don't
+ * touch dangerous spots like the mouse irq,
+ * because there are mice that apparently
+ * get really confused if they get fondled
+ * too intimately.
+ *
+ * Default to 11, 10, 9, 7, 6, 5, 4, 3.
*/
-static int yenta_socket_thread(void * data)
-{
- pci_socket_t * socket = (pci_socket_t *) data;
- DECLARE_WAITQUEUE(wait, current);
-
- daemonize();
- strcpy(current->comm, "CardBus Watcher");
-
- do {
- unsigned int events = socket->events | yenta_events(socket);
-
- if (events) {
- socket->events = 0;
- if (socket->handler)
- socket->handler(socket->info, events);
- }
-
- current->state = TASK_INTERRUPTIBLE;
- add_wait_queue(&socket->wait, &wait);
- if (!socket->events)
- schedule_timeout(HZ);
- remove_wait_queue(&socket->wait, &wait);
- } while (!signal_pending(current));
- return 0;
-}
+static u32 isa_interrupts = 0x0ef8;
static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask)
{
@@ -540,6 +520,61 @@ static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask)
return mask;
}
+/*
+ * Set static data that doesn't need re-initializing..
+ */
+static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask)
+{
+ socket->cap.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
+ socket->cap.map_size = 0x1000;
+ socket->cap.pci_irq = socket->cb_irq;
+ socket->cap.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
+ socket->cap.cb_dev = socket->dev;
+ socket->cap.bus = NULL;
+
+ printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq);
+}
+
+extern void cardbus_register(pci_socket_t *socket);
+
+/*
+ * Watch a socket every second (and possibly in a
+ * more timely manner if the state change interrupt
+ * works..)
+ */
+static int yenta_socket_thread(void * data)
+{
+ pci_socket_t * socket = (pci_socket_t *) data;
+ DECLARE_WAITQUEUE(wait, current);
+
+ daemonize();
+ strcpy(current->comm, "CardBus Watcher");
+
+ /* Figure out what the dang thing can do for the PCMCIA layer... */
+ yenta_get_socket_capabilities(socket, isa_interrupts);
+ printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
+
+ /* Register it with the pcmcia layer.. */
+ cardbus_register(socket);
+
+ do {
+ unsigned int events = socket->events | yenta_events(socket);
+
+ if (events) {
+ socket->events = 0;
+ if (socket->handler)
+ socket->handler(socket->info, events);
+ }
+
+ current->state = TASK_INTERRUPTIBLE;
+ add_wait_queue(&socket->wait, &wait);
+ if (!socket->events)
+ schedule_timeout(HZ);
+ remove_wait_queue(&socket->wait, &wait);
+ } while (!signal_pending(current));
+ return 0;
+}
+
static void yenta_clear_maps(pci_socket_t *socket)
{
int i;
@@ -558,8 +593,10 @@ static void yenta_clear_maps(pci_socket_t *socket)
}
}
-/* Called at resume and initialization events */
-static int yenta_init(pci_socket_t *socket)
+/*
+ * Initialize the standard cardbus registers
+ */
+static int yenta_config_init(pci_socket_t *socket)
{
u16 bridge;
struct pci_dev *dev = socket->dev;
@@ -600,7 +637,12 @@ static int yenta_init(pci_socket_t *socket)
/* Redo card voltage interrogation */
cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
+}
+/* Called at resume and initialization events */
+static int yenta_init(pci_socket_t *socket)
+{
+ yenta_config_init(socket);
yenta_clear_maps(socket);
return 0;
}
@@ -624,21 +666,6 @@ static int yenta_suspend(pci_socket_t *socket)
return 0;
}
-/*
- * Set static data that doesn't need re-initializing..
- */
-static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask)
-{
- socket->cap.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
- socket->cap.map_size = 0x1000;
- socket->cap.pci_irq = socket->cb_irq;
- socket->cap.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
- socket->cap.cb_dev = socket->dev;
- socket->cap.bus = NULL;
-
- printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq);
-}
-
static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type)
{
struct pci_bus *bus;
@@ -742,17 +769,6 @@ static struct cardbus_override_struct {
#define NR_OVERRIDES (sizeof(cardbus_override)/sizeof(struct cardbus_override_struct))
/*
- * Only probe "regular" interrupts, don't
- * touch dangerous spots like the mouse irq,
- * because there are mice that apparently
- * get really confused if they get fondled
- * too intimately.
- *
- * Default to 11, 10, 9, 7, 6, 5, 4, 3.
- */
-static u32 isa_interrupts = 0x0ef8;
-
-/*
* Initialize a cardbus controller. Make sure we have a usable
* interrupt, and that we can map the cardbus area. Fill in the
* socket information structure..
@@ -780,6 +796,8 @@ static int yenta_open(pci_socket_t *socket)
if (!socket->base)
return -1;
+ yenta_config_init(socket);
+
/* Disable all events */
cb_writel(socket, CB_SOCKET_MASK, 0x0);
@@ -802,11 +820,7 @@ static int yenta_open(pci_socket_t *socket)
}
}
- /* Figure out what the dang thing can do for the PCMCIA layer... */
- yenta_get_socket_capabilities(socket, isa_interrupts);
-
kernel_thread(yenta_socket_thread, socket, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
- printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
return 0;
}