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 #include #include -#include #include #include -#include #include #include #include -#include #include +#include #include #include @@ -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 ? "" : "", @@ -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; _