patch-2.3.39 linux/drivers/pcmcia/yenta.c
Next file: linux/drivers/pnp/Makefile
Previous file: linux/drivers/pcmcia/pci_socket.h
Back to the patch index
Back to the overall index
- Lines: 96
- Date:
Mon Jan 10 16:42:56 2000
- Orig file:
v2.3.38/linux/drivers/pcmcia/yenta.c
- Orig date:
Fri Jan 7 19:13:22 2000
diff -u --recursive --new-file v2.3.38/linux/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
@@ -385,13 +385,12 @@
/* Not done yet */
}
-static void yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static unsigned int yenta_events(pci_socket_t *socket)
{
u8 csc;
u32 cb_event;
unsigned int events;
- pci_socket_t *socket = (pci_socket_t *) dev_id;
-
+
/* Clear interrupt status for the event */
cb_event = cb_readl(socket, CB_SOCKET_EVENT);
cb_writel(socket, CB_SOCKET_EVENT, cb_event);
@@ -407,16 +406,50 @@
events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
events |= (csc & I365_CSC_READY) ? SS_READY : 0;
}
+ return events;
+}
- if (events && socket->handler)
- socket->handler(socket->info, events);
+static void yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned int events;
+ pci_socket_t *socket = (pci_socket_t *) dev_id;
- mod_timer(&socket->timer, jiffies + HZ);
+ events = yenta_events(socket);
+ if (events) {
+ socket->events |= events;
+ wake_up_interruptible(&socket->wait);
+ }
}
-static void yenta_timer(unsigned long data)
+/*
+ * Watch a socket every second (and possibly in a
+ * more timely manner if the state change interrupt
+ * works..)
+ */
+static int socket_thread(void * data)
{
- yenta_interrupt(0, (pci_socket_t *) data, NULL);
+ 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 unsigned int yenta_probe_irq(pci_socket_t *socket)
@@ -645,22 +678,13 @@
/* Set up the bridge regions.. */
yenta_allocate_resources(socket);
- /*
- * Always poll the socket too, just in case the cardbus interrupt
- * doesn't exist (it happens), or we just lose an interrupt..
- */
- init_timer(&socket->timer);
- socket->timer.expires = jiffies + HZ;
- socket->timer.data = (unsigned long)socket;
- socket->timer.function = yenta_timer;
- add_timer(&socket->timer);
-
if (dev->irq && !request_irq(dev->irq, yenta_interrupt, SA_SHIRQ, dev->name, socket))
socket->cb_irq = dev->irq;
/* And figure out what the dang thing can do for the PCMCIA layer... */
yenta_get_socket_capabilities(socket);
+ kernel_thread(socket_thread, socket, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)