aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-01-02 17:19:45 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2010-01-24 13:57:47 -0500
commit3970dd8c5169505f0cc5e4c3e2fde7bdd9bbad3e (patch)
tree86113b333d7de9d5e6f65b2dc077e44c6656c90b
parent593f010bc0d8f7fde2ce948cac3f77f6a3d9db2b (diff)
pcmcia: do not lock socket driver module on card insert
Do not lock the socket driver module on card insert, as the PCMCIA core can handle a socket module removal, at least if we add a call to socket_remove() on pccardd()'s shutdown. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--drivers/pcmcia/cs.c13
-rw-r--r--drivers/pcmcia/cs_internal.h20
2 files changed, 10 insertions, 23 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index f0630a61da90..137a5db2eca2 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -407,7 +407,7 @@ static void socket_shutdown(struct pcmcia_socket *s)
407 "*** DANGER *** unable to remove socket power\n"); 407 "*** DANGER *** unable to remove socket power\n");
408 } 408 }
409 409
410 cs_socket_put(s); 410 s->state &= ~SOCKET_INUSE;
411} 411}
412 412
413static int socket_setup(struct pcmcia_socket *skt, int initial_delay) 413static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
@@ -496,8 +496,8 @@ static int socket_insert(struct pcmcia_socket *skt)
496 496
497 dev_dbg(&skt->dev, "insert\n"); 497 dev_dbg(&skt->dev, "insert\n");
498 498
499 if (!cs_socket_get(skt)) 499 WARN_ON(skt->state & SOCKET_INUSE);
500 return -ENODEV; 500 skt->state |= SOCKET_INUSE;
501 501
502 ret = socket_setup(skt, setup_delay); 502 ret = socket_setup(skt, setup_delay);
503 if (ret == 0) { 503 if (ret == 0) {
@@ -697,6 +697,13 @@ static int pccardd(void *__skt)
697 /* make sure we are running before we exit */ 697 /* make sure we are running before we exit */
698 set_current_state(TASK_RUNNING); 698 set_current_state(TASK_RUNNING);
699 699
700 /* shut down socket, if a device is still present */
701 if (skt->state & SOCKET_PRESENT) {
702 mutex_lock(&skt->skt_mutex);
703 socket_remove(skt);
704 mutex_unlock(&skt->skt_mutex);
705 }
706
700 /* remove from the device core */ 707 /* remove from the device core */
701 pccard_sysfs_remove_socket(&skt->dev); 708 pccard_sysfs_remove_socket(&skt->dev);
702 device_unregister(&skt->dev); 709 device_unregister(&skt->dev);
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 3bc02d53a3a3..9a3bbad7761b 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -87,26 +87,6 @@ struct pccard_resource_ops {
87#define SOCKET_CARDBUS 0x8000 87#define SOCKET_CARDBUS 0x8000
88#define SOCKET_CARDBUS_CONFIG 0x10000 88#define SOCKET_CARDBUS_CONFIG 0x10000
89 89
90static inline int cs_socket_get(struct pcmcia_socket *skt)
91{
92 int ret;
93
94 WARN_ON(skt->state & SOCKET_INUSE);
95
96 ret = try_module_get(skt->owner);
97 if (ret)
98 skt->state |= SOCKET_INUSE;
99 return ret;
100}
101
102static inline void cs_socket_put(struct pcmcia_socket *skt)
103{
104 if (skt->state & SOCKET_INUSE) {
105 skt->state &= ~SOCKET_INUSE;
106 module_put(skt->owner);
107 }
108}
109
110 90
111/* 91/*
112 * Stuff internal to module "pcmcia_core": 92 * Stuff internal to module "pcmcia_core":