pcmcia: do not lock socket driver module on card insert
Dominik Brodowski [Sat, 2 Jan 2010 22:19:45 +0000 (23:19 +0100)]
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>

drivers/pcmcia/cs.c
drivers/pcmcia/cs_internal.h

index f0630a6..137a5db 100644 (file)
@@ -407,7 +407,7 @@ static void socket_shutdown(struct pcmcia_socket *s)
                           "*** DANGER *** unable to remove socket power\n");
        }
 
-       cs_socket_put(s);
+       s->state &= ~SOCKET_INUSE;
 }
 
 static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
@@ -496,8 +496,8 @@ static int socket_insert(struct pcmcia_socket *skt)
 
        dev_dbg(&skt->dev, "insert\n");
 
-       if (!cs_socket_get(skt))
-               return -ENODEV;
+       WARN_ON(skt->state & SOCKET_INUSE);
+       skt->state |= SOCKET_INUSE;
 
        ret = socket_setup(skt, setup_delay);
        if (ret == 0) {
@@ -697,6 +697,13 @@ static int pccardd(void *__skt)
        /* make sure we are running before we exit */
        set_current_state(TASK_RUNNING);
 
+       /* shut down socket, if a device is still present */
+       if (skt->state & SOCKET_PRESENT) {
+               mutex_lock(&skt->skt_mutex);
+               socket_remove(skt);
+               mutex_unlock(&skt->skt_mutex);
+       }
+
        /* remove from the device core */
        pccard_sysfs_remove_socket(&skt->dev);
        device_unregister(&skt->dev);
index 3bc02d5..9a3bbad 100644 (file)
@@ -87,26 +87,6 @@ struct pccard_resource_ops {
 #define SOCKET_CARDBUS         0x8000
 #define SOCKET_CARDBUS_CONFIG  0x10000
 
-static inline int cs_socket_get(struct pcmcia_socket *skt)
-{
-       int ret;
-
-       WARN_ON(skt->state & SOCKET_INUSE);
-
-       ret = try_module_get(skt->owner);
-       if (ret)
-               skt->state |= SOCKET_INUSE;
-       return ret;
-}
-
-static inline void cs_socket_put(struct pcmcia_socket *skt)
-{
-       if (skt->state & SOCKET_INUSE) {
-               skt->state &= ~SOCKET_INUSE;
-               module_put(skt->owner);
-       }
-}
-
 
 /*
  * Stuff internal to module "pcmcia_core":