aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/cs.c')
-rw-r--r--drivers/pcmcia/cs.c79
1 files changed, 16 insertions, 63 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 976d80706eae..2ec8ac97445c 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -32,7 +32,6 @@
32#include <asm/system.h> 32#include <asm/system.h>
33#include <asm/irq.h> 33#include <asm/irq.h>
34 34
35#include <pcmcia/cs_types.h>
36#include <pcmcia/ss.h> 35#include <pcmcia/ss.h>
37#include <pcmcia/cs.h> 36#include <pcmcia/cs.h>
38#include <pcmcia/cistpl.h> 37#include <pcmcia/cistpl.h>
@@ -252,38 +251,6 @@ struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr)
252} 251}
253EXPORT_SYMBOL(pcmcia_get_socket_by_nr); 252EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
254 253
255/*
256 * The central event handler. Send_event() sends an event to the
257 * 16-bit subsystem, which then calls the relevant device drivers.
258 * Parse_events() interprets the event bits from
259 * a card status change report. Do_shutdown() handles the high
260 * priority stuff associated with a card removal.
261 */
262
263/* NOTE: send_event needs to be called with skt->sem held. */
264
265static int send_event(struct pcmcia_socket *s, event_t event, int priority)
266{
267 int ret;
268
269 if ((s->state & SOCKET_CARDBUS) && (event != CS_EVENT_CARD_REMOVAL))
270 return 0;
271
272 dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n",
273 event, priority, s->callback);
274
275 if (!s->callback)
276 return 0;
277 if (!try_module_get(s->callback->owner))
278 return 0;
279
280 ret = s->callback->event(s, event, priority);
281
282 module_put(s->callback->owner);
283
284 return ret;
285}
286
287static int socket_reset(struct pcmcia_socket *skt) 254static int socket_reset(struct pcmcia_socket *skt)
288{ 255{
289 int status, i; 256 int status, i;
@@ -326,7 +293,8 @@ static void socket_shutdown(struct pcmcia_socket *s)
326 293
327 dev_dbg(&s->dev, "shutdown\n"); 294 dev_dbg(&s->dev, "shutdown\n");
328 295
329 send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); 296 if (s->callback)
297 s->callback->remove(s);
330 298
331 mutex_lock(&s->ops_mutex); 299 mutex_lock(&s->ops_mutex);
332 s->state &= SOCKET_INUSE | SOCKET_PRESENT; 300 s->state &= SOCKET_INUSE | SOCKET_PRESENT;
@@ -477,7 +445,8 @@ static int socket_insert(struct pcmcia_socket *skt)
477 dev_dbg(&skt->dev, "insert done\n"); 445 dev_dbg(&skt->dev, "insert done\n");
478 mutex_unlock(&skt->ops_mutex); 446 mutex_unlock(&skt->ops_mutex);
479 447
480 send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); 448 if (!(skt->state & SOCKET_CARDBUS) && (skt->callback))
449 skt->callback->add(skt);
481 } else { 450 } else {
482 mutex_unlock(&skt->ops_mutex); 451 mutex_unlock(&skt->ops_mutex);
483 socket_shutdown(skt); 452 socket_shutdown(skt);
@@ -494,7 +463,6 @@ static int socket_suspend(struct pcmcia_socket *skt)
494 mutex_lock(&skt->ops_mutex); 463 mutex_lock(&skt->ops_mutex);
495 skt->suspended_state = skt->state; 464 skt->suspended_state = skt->state;
496 465
497 send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
498 skt->socket = dead_socket; 466 skt->socket = dead_socket;
499 skt->ops->set_socket(skt, &skt->socket); 467 skt->ops->set_socket(skt, &skt->socket);
500 if (skt->ops->suspend) 468 if (skt->ops->suspend)
@@ -555,8 +523,8 @@ static int socket_late_resume(struct pcmcia_socket *skt)
555 return 0; 523 return 0;
556 } 524 }
557#endif 525#endif
558 526 if (!(skt->state & SOCKET_CARDBUS) && (skt->callback))
559 send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW); 527 skt->callback->early_resume(skt);
560 return 0; 528 return 0;
561} 529}
562 530
@@ -654,16 +622,8 @@ static int pccardd(void *__skt)
654 spin_unlock_irqrestore(&skt->thread_lock, flags); 622 spin_unlock_irqrestore(&skt->thread_lock, flags);
655 623
656 mutex_lock(&skt->skt_mutex); 624 mutex_lock(&skt->skt_mutex);
657 if (events) { 625 if (events & SS_DETECT)
658 if (events & SS_DETECT) 626 socket_detect_change(skt);
659 socket_detect_change(skt);
660 if (events & SS_BATDEAD)
661 send_event(skt, CS_EVENT_BATTERY_DEAD, CS_EVENT_PRI_LOW);
662 if (events & SS_BATWARN)
663 send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
664 if (events & SS_READY)
665 send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
666 }
667 627
668 if (sysfs_events) { 628 if (sysfs_events) {
669 if (sysfs_events & PCMCIA_UEVENT_EJECT) 629 if (sysfs_events & PCMCIA_UEVENT_EJECT)
@@ -783,7 +743,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
783 s->callback = c; 743 s->callback = c;
784 744
785 if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) 745 if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT)
786 send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); 746 s->callback->add(s);
787 } else 747 } else
788 s->callback = NULL; 748 s->callback = NULL;
789 err: 749 err:
@@ -823,20 +783,13 @@ int pcmcia_reset_card(struct pcmcia_socket *skt)
823 break; 783 break;
824 } 784 }
825 785
826 ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW); 786 if (skt->callback)
827 if (ret == 0) { 787 skt->callback->suspend(skt);
828 send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); 788 mutex_lock(&skt->ops_mutex);
829 if (skt->callback) 789 ret = socket_reset(skt);
830 skt->callback->suspend(skt); 790 mutex_unlock(&skt->ops_mutex);
831 mutex_lock(&skt->ops_mutex); 791 if ((ret == 0) && (skt->callback))
832 ret = socket_reset(skt); 792 skt->callback->resume(skt);
833 mutex_unlock(&skt->ops_mutex);
834 if (ret == 0) {
835 send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
836 if (skt->callback)
837 skt->callback->resume(skt);
838 }
839 }
840 793
841 ret = 0; 794 ret = 0;
842 } while (0); 795 } while (0);