[ARM] 3283/1: S3C2400 - defines the number of serial ports
[pandora-kernel.git] / drivers / pcmcia / cs.c
index a30aa74..613f2f1 100644 (file)
@@ -309,41 +309,6 @@ struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)
 }
 EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
 
-
-/**
- * socket_setup() and shutdown_socket() are called by the main event
- * handler when card insertion and removal events are received.
- * socket_setup() turns on socket power and resets the socket, in two stages.
- * shutdown_socket() unconfigures a socket and turns off socket power.
- */
-static void shutdown_socket(struct pcmcia_socket *s)
-{
-       cs_dbg(s, 1, "shutdown_socket\n");
-
-       /* Blank out the socket state */
-       s->socket = dead_socket;
-       s->ops->init(s);
-       s->ops->set_socket(s, &s->socket);
-       s->irq.AssignedIRQ = s->irq.Config = 0;
-       s->lock_count = 0;
-       destroy_cis_cache(s);
-#ifdef CONFIG_CARDBUS
-       cb_free(s);
-#endif
-       s->functions = 0;
-       kfree(s->config);
-       s->config = NULL;
-
-       {
-               int status;
-               s->ops->get_status(s, &status);
-               if (status & SS_POWERON) {
-                       printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
-               }
-       }
-} /* shutdown_socket */
-
-
 /**
  * The central event handler.  Send_event() sends an event to the
  * 16-bit subsystem, which then calls the relevant device drivers.
@@ -383,17 +348,6 @@ static void socket_remove_drivers(struct pcmcia_socket *skt)
        send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
 }
 
-static void socket_shutdown(struct pcmcia_socket *skt)
-{
-       cs_dbg(skt, 4, "shutdown\n");
-
-       socket_remove_drivers(skt);
-       skt->state &= SOCKET_INUSE|SOCKET_PRESENT;
-       msleep(shutdown_delay * 10);
-       skt->state &= SOCKET_INUSE;
-       shutdown_socket(skt);
-}
-
 static int socket_reset(struct pcmcia_socket *skt)
 {
        int status, i;
@@ -424,6 +378,45 @@ static int socket_reset(struct pcmcia_socket *skt)
        return CS_GENERAL_FAILURE;
 }
 
+/**
+ * socket_setup() and socket_shutdown() are called by the main event handler
+ * when card insertion and removal events are received.
+ * socket_setup() turns on socket power and resets the socket, in two stages.
+ * socket_shutdown() unconfigures a socket and turns off socket power.
+ */
+static void socket_shutdown(struct pcmcia_socket *s)
+{
+       int status;
+
+       cs_dbg(s, 4, "shutdown\n");
+
+       socket_remove_drivers(s);
+       s->state &= SOCKET_INUSE | SOCKET_PRESENT;
+       msleep(shutdown_delay * 10);
+       s->state &= SOCKET_INUSE;
+
+       /* Blank out the socket state */
+       s->socket = dead_socket;
+       s->ops->init(s);
+       s->ops->set_socket(s, &s->socket);
+       s->irq.AssignedIRQ = s->irq.Config = 0;
+       s->lock_count = 0;
+       destroy_cis_cache(s);
+#ifdef CONFIG_CARDBUS
+       cb_free(s);
+#endif
+       s->functions = 0;
+       kfree(s->config);
+       s->config = NULL;
+
+       s->ops->get_status(s, &status);
+       if (status & SS_POWERON) {
+               printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
+       }
+
+       cs_socket_put(s);
+}
+
 static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
 {
        int status, i;
@@ -529,7 +522,6 @@ static int socket_insert(struct pcmcia_socket *skt)
                send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
        } else {
                socket_shutdown(skt);
-               cs_socket_put(skt);
        }
 
        return ret;
@@ -593,7 +585,6 @@ static int socket_resume(struct pcmcia_socket *skt)
                }
        } else {
                socket_shutdown(skt);
-               cs_socket_put(skt);
        }
 
        skt->state &= ~SOCKET_SUSPEND;
@@ -605,7 +596,6 @@ static void socket_remove(struct pcmcia_socket *skt)
 {
        printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
        socket_shutdown(skt);
-       cs_socket_put(skt);
 }
 
 /*
@@ -780,8 +770,13 @@ int pccard_reset_card(struct pcmcia_socket *skt)
                ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
                if (ret == 0) {
                        send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
-                       if (socket_reset(skt) == CS_SUCCESS)
+                       if (skt->callback)
+                               skt->callback->suspend(skt);
+                       if (socket_reset(skt) == CS_SUCCESS) {
                                send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
+                               if (skt->callback)
+                                       skt->callback->resume(skt);
+                       }
                }
 
                ret = CS_SUCCESS;
@@ -812,6 +807,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
                        ret = CS_UNSUPPORTED_FUNCTION;
                        break;
                }
+               if (skt->callback) {
+                       ret = skt->callback->suspend(skt);
+                       if (ret)
+                               break;
+               }
                ret = socket_suspend(skt);
        } while (0);
        up(&skt->skt_sem);
@@ -838,6 +838,8 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
                        break;
                }
                ret = socket_resume(skt);
+               if (!ret && skt->callback)
+                       skt->callback->resume(skt);
        } while (0);
        up(&skt->skt_sem);
 
@@ -901,14 +903,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
 EXPORT_SYMBOL(pcmcia_insert_card);
 
 
-static int pcmcia_socket_hotplug(struct class_device *dev, char **envp,
-                               int num_envp, char *buffer, int buffer_size)
+static int pcmcia_socket_uevent(struct class_device *dev, char **envp,
+                               int num_envp, char *buffer, int buffer_size)
 {
        struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
        int i = 0, length = 0;
 
-       if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
-                               &length, "SOCKET_NO=%u", s->sock))
+       if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+                          &length, "SOCKET_NO=%u", s->sock))
                return -ENOMEM;
 
        envp[i] = NULL;
@@ -927,7 +929,7 @@ static void pcmcia_release_socket_class(struct class *data)
 
 struct class pcmcia_socket_class = {
        .name = "pcmcia_socket",
-        .hotplug = pcmcia_socket_hotplug,
+       .uevent = pcmcia_socket_uevent,
        .release = pcmcia_release_socket,
        .class_release = pcmcia_release_socket_class,
 };