 drivers/pcmcia/i82092.c       |   22 -----------------
 drivers/pcmcia/i82365.c       |   53 +++---------------------------------------
 drivers/pcmcia/sa11xx_core.c  |   26 +++++++-------------
 drivers/pcmcia/sa11xx_core.h  |    1 
 drivers/pcmcia/tcic.c         |   25 -------------------
 drivers/pcmcia/yenta_socket.c |   22 -----------------
 drivers/pcmcia/yenta_socket.h |    3 --
 7 files changed, 17 insertions(+), 135 deletions(-)

diff -puN drivers/pcmcia/i82092.c~pcmcia-event-20030623-6 drivers/pcmcia/i82092.c
--- 25/drivers/pcmcia/i82092.c~pcmcia-event-20030623-6	2003-06-26 18:39:54.000000000 -0700
+++ 25-akpm/drivers/pcmcia/i82092.c	2003-06-26 18:39:54.000000000 -0700
@@ -83,8 +83,6 @@ struct socket_info {
 				    3 = operational card */
 	int 	io_base; 	/* base io address of the socket */
 	
-	unsigned int pending_events; /* Pending events on this interface */
-	
 	struct pcmcia_socket socket;
 	struct pci_dev *dev;	/* The PCI device for the socket */
 };
@@ -319,23 +317,6 @@ static int to_cycles(int ns)
 
 /* Interrupt handler functionality */
 
-static void i82092aa_bh(void *dummy)
-{
-        unsigned int events;
-	int i;
-                
-        for (i=0; i < socket_count; i++) {
-        	events = xchg(&(sockets[i].pending_events),0);
-        	printk("events = %x \n",events);
-        	if (events)
-			pcmcia_parse_events(&sockets[i].socket, events);
-	}
-}
-                                                                                                                                        
-
-static DECLARE_WORK(i82092aa_task, i82092aa_bh, NULL);
-        
-
 static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs)
 {
 	int i;
@@ -383,8 +364,7 @@ static irqreturn_t i82092aa_interrupt(in
 			}
 			
 			if (events) {
-				sockets[i].pending_events |= events;
-				schedule_work(&i82092aa_task);
+				pcmcia_parse_events(&sockets[i].socket, events);
 			}
 			active |= events;
 		}
diff -puN drivers/pcmcia/i82365.c~pcmcia-event-20030623-6 drivers/pcmcia/i82365.c
--- 25/drivers/pcmcia/i82365.c~pcmcia-event-20030623-6	2003-06-26 18:39:54.000000000 -0700
+++ 25-akpm/drivers/pcmcia/i82365.c	2003-06-26 18:39:54.000000000 -0700
@@ -861,35 +861,6 @@ static void __init isa_probe(void)
 
 /*====================================================================*/
 
-static u_int pending_events[8];
-static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
-
-static void pcic_bh(void *dummy)
-{
-	u_int events;
-	int i;
-
-	for (i=0; i < sockets; i++) {
-		spin_lock_irq(&pending_event_lock);
-		events = pending_events[i];
-		pending_events[i] = 0;
-		spin_unlock_irq(&pending_event_lock);
-		/* 
-		SS_DETECT events need a small delay here. The reason for this is that 
-		the "is there a card" electronics need time to see the card after the
-		"we have a card coming in" electronics have seen it. 
-		*/
-		if (events & SS_DETECT) 
-			mdelay(4);
-		if (events)
-			pcmcia_parse_events(&socket[i].socket, events);
-	}
-}
-
-static DECLARE_WORK(pcic_task, pcic_bh, NULL);
-
-static unsigned long last_detect_jiffies;
-
 static irqreturn_t pcic_interrupt(int irq, void *dev,
 				    struct pt_regs *regs)
 {
@@ -914,20 +885,7 @@ static irqreturn_t pcic_interrupt(int ir
 		continue;
 	    }
 	    events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
-	    
-	    
-	    /* Several sockets will send multiple "new card detected"
-	       events in rapid succession. However, the rest of the pcmcia expects 
-	       only one such event. We just ignore these events by having a
-               timeout */
-
-	    if (events) {
-	    	if ((jiffies - last_detect_jiffies)<(HZ/20)) 
-	    		events = 0;
-	    	last_detect_jiffies = jiffies;
-	    	
-	    }
-	
+
 	    if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
 		events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
 	    else {
@@ -938,12 +896,9 @@ static irqreturn_t pcic_interrupt(int ir
 	    ISA_UNLOCK(i, flags);
 	    DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events);
 
-	    if (events) {
-		    spin_lock(&pending_event_lock);
-		    pending_events[i] |= events;
-		    spin_unlock(&pending_event_lock);
-		    schedule_work(&pcic_task);
-	    }
+	    if (events)
+		pcmcia_parse_events(&socket[i].socket, events);
+
 	    active |= events;
 	}
 	if (!active) break;
diff -puN drivers/pcmcia/sa11xx_core.c~pcmcia-event-20030623-6 drivers/pcmcia/sa11xx_core.c
--- 25/drivers/pcmcia/sa11xx_core.c~pcmcia-event-20030623-6	2003-06-26 18:39:54.000000000 -0700
+++ 25-akpm/drivers/pcmcia/sa11xx_core.c	2003-06-26 18:39:54.000000000 -0700
@@ -38,15 +38,13 @@
 #include <linux/init.h>
 #include <linux/config.h>
 #include <linux/cpufreq.h>
-#include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
-#include <linux/workqueue.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/notifier.h>
-#include <linux/version.h>
 #include <linux/interrupt.h>
+#include <linux/spinlock.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -263,29 +261,27 @@ static int sa1100_pcmcia_suspend(struct 
 	return ret;
 }
 
+static spinlock_t status_lock = SPIN_LOCK_UNLOCKED;
 
-/* sa1100_pcmcia_task_handler()
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * Processes serviceable socket events using the "eventd" thread context.
- *
- * Event processing (specifically, the invocation of the Card Services event
- * callback) occurs in this thread rather than in the actual interrupt
- * handler due to the use of scheduling operations in the PCMCIA core.
+/* sa1100_check_status()
+ * ^^^^^^^^^^^^^^^^^^^^^
  */
-static void sa1100_pcmcia_task_handler(void *data)
+static void sa1100_check_status(struct sa1100_pcmcia_socket *skt)
 {
-	struct sa1100_pcmcia_socket *skt = data;
 	unsigned int events;
 
 	DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
 
 	do {
 		unsigned int status;
+		unsigned long flags;
 
 		status = sa1100_pcmcia_skt_state(skt);
 
+		spin_lock_irqsave(&status_lock, flags);
 		events = (status ^ skt->status) & skt->cs_state.csc_mask;
 		skt->status = status;
+		spin_unlock_irqrestore(&status_lock, flags);
 
 		DEBUG(2, "events: %s%s%s%s%s%s\n",
 			events == 0         ? "<NONE>"   : "",
@@ -311,7 +307,7 @@ static void sa1100_pcmcia_poll_event(uns
 
 	mod_timer(&skt->poll_timer, jiffies + SA1100_PCMCIA_POLL_PERIOD);
 
-	schedule_work(&skt->work);
+	sa1100_check_status(skt);
 }
 
 
@@ -330,7 +326,7 @@ static irqreturn_t sa1100_pcmcia_interru
 
 	DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
 
-	schedule_work(&skt->work);
+	sa1100_check_status(skt);
 
 	return IRQ_HANDLED;
 }
@@ -733,8 +729,6 @@ int sa11xx_drv_pcmcia_probe(struct devic
 		skt->socket.owner = ops->owner;
 		skt->socket.dev.dev = dev;
 
-		INIT_WORK(&skt->work, sa1100_pcmcia_task_handler, skt);
-
 		init_timer(&skt->poll_timer);
 		skt->poll_timer.function = sa1100_pcmcia_poll_event;
 		skt->poll_timer.data = (unsigned long)skt;
diff -puN drivers/pcmcia/sa11xx_core.h~pcmcia-event-20030623-6 drivers/pcmcia/sa11xx_core.h
--- 25/drivers/pcmcia/sa11xx_core.h~pcmcia-event-20030623-6	2003-06-26 18:39:54.000000000 -0700
+++ 25-akpm/drivers/pcmcia/sa11xx_core.h	2003-06-26 18:39:54.000000000 -0700
@@ -73,7 +73,6 @@ struct sa1100_pcmcia_socket {
 	unsigned int		irq_state;
 
 	struct timer_list	poll_timer;
-	struct work_struct	work;
 };
 
 struct pcmcia_low_level {
diff -puN drivers/pcmcia/tcic.c~pcmcia-event-20030623-6 drivers/pcmcia/tcic.c
--- 25/drivers/pcmcia/tcic.c~pcmcia-event-20030623-6	2003-06-26 18:39:54.000000000 -0700
+++ 25-akpm/drivers/pcmcia/tcic.c	2003-06-26 18:39:54.000000000 -0700
@@ -555,26 +555,6 @@ static void __exit exit_tcic(void)
 
 /*====================================================================*/
 
-static u_int pending_events[2];
-static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
-
-static void tcic_bh(void *dummy)
-{
-	u_int events;
-	int i;
-
-	for (i=0; i < sockets; i++) {
-		spin_lock_irq(&pending_event_lock);
-		events = pending_events[i];
-		pending_events[i] = 0;
-		spin_unlock_irq(&pending_event_lock);
-		if (events)
-			pcmcia_parse_events(&socket_table[i].socket, events);
-	}
-}
-
-static DECLARE_WORK(tcic_task, tcic_bh, NULL);
-
 static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
 {
     int i, quick = 0;
@@ -614,10 +594,7 @@ static irqreturn_t tcic_interrupt(int ir
 	    events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
 	}
 	if (events) {
-		spin_lock(&pending_event_lock);
-		pending_events[i] |= events;
-		spin_unlock(&pending_event_lock);
-		schedule_work(&tcic_task);
+		pcmcia_parse_events(&socket_table[i].socket, events);
 	}
     }
 
diff -puN drivers/pcmcia/yenta_socket.c~pcmcia-event-20030623-6 drivers/pcmcia/yenta_socket.c
--- 25/drivers/pcmcia/yenta_socket.c~pcmcia-event-20030623-6	2003-06-26 18:39:54.000000000 -0700
+++ 25-akpm/drivers/pcmcia/yenta_socket.c	2003-06-26 18:39:54.000000000 -0700
@@ -250,7 +250,6 @@ static int yenta_set_socket(struct pcmci
 
 	if (state->flags & SS_DEBOUNCED) {
 		/* The insertion debounce period has ended.  Clear any pending insertion events */
-		socket->events &= ~SS_DETECT;
 		state->flags &= ~SS_DEBOUNCED;		/* SS_DEBOUNCED is oneshot */
 	}
 	yenta_set_power(socket, state);
@@ -420,19 +419,6 @@ static unsigned int yenta_events(struct 
 }
 
 
-static void yenta_bh(void *data)
-{
-	struct yenta_socket *socket = data;
-	unsigned int events;
-
-	spin_lock_irq(&socket->event_lock);
-	events = socket->events;
-	socket->events = 0;
-	spin_unlock_irq(&socket->event_lock);
-	if (events)
-		pcmcia_parse_events(&socket->socket, events);
-}
-
 static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned int events;
@@ -440,10 +426,7 @@ static irqreturn_t yenta_interrupt(int i
 
 	events = yenta_events(socket);
 	if (events) {
-		spin_lock(&socket->event_lock);
-		socket->events |= events;
-		spin_unlock(&socket->event_lock);
-		schedule_work(&socket->tq_task);
+		pcmcia_parse_events(&socket->socket, events);
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
@@ -853,7 +836,6 @@ static int __devinit yenta_probe (struct
 	/* prepare struct yenta_socket */
 	socket->dev = dev;
 	pci_set_drvdata(dev, socket);
-	spin_lock_init(&socket->event_lock);
 
 	/*
 	 * Do some basic sanity checking..
@@ -896,8 +878,6 @@ static int __devinit yenta_probe (struct
 
 	/* We must finish initialization here */
 
-	INIT_WORK(&socket->tq_task, yenta_bh, socket);
-
 	if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, SA_SHIRQ, socket->dev->dev.name, socket)) {
 		/* No IRQ or request_irq failed. Poll */
 		socket->cb_irq = 0; /* But zero is a valid IRQ number. */
diff -puN drivers/pcmcia/yenta_socket.h~pcmcia-event-20030623-6 drivers/pcmcia/yenta_socket.h
--- 25/drivers/pcmcia/yenta_socket.h~pcmcia-event-20030623-6	2003-06-26 18:39:54.000000000 -0700
+++ 25-akpm/drivers/pcmcia/yenta_socket.h	2003-06-26 18:39:54.000000000 -0700
@@ -99,9 +99,6 @@ struct yenta_socket {
 	struct pci_dev *dev;
 	int cb_irq, io_irq;
 	void *base;
-	spinlock_t event_lock;
-	unsigned int events;
-	struct work_struct tq_task;
 	struct timer_list poll_timer;
 
 	struct pcmcia_socket socket;

_
