diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-01-02 17:19:45 -0500 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-01-24 13:57:47 -0500 |
commit | 3970dd8c5169505f0cc5e4c3e2fde7bdd9bbad3e (patch) | |
tree | 86113b333d7de9d5e6f65b2dc077e44c6656c90b | |
parent | 593f010bc0d8f7fde2ce948cac3f77f6a3d9db2b (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.c | 13 | ||||
-rw-r--r-- | drivers/pcmcia/cs_internal.h | 20 |
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 | ||
413 | static int socket_setup(struct pcmcia_socket *skt, int initial_delay) | 413 | static 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 | ||
90 | static 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 | |||
102 | static 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": |