[ARM] 3283/1: S3C2400 - defines the number of serial ports
[pandora-kernel.git] / drivers / pcmcia / cs.c
index d5e7642..613f2f1 100644 (file)
@@ -309,43 +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;
-       if (s->config) {
-               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.
@@ -385,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;
@@ -426,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;
@@ -515,6 +506,11 @@ static int socket_insert(struct pcmcia_socket *skt)
        ret = socket_setup(skt, setup_delay);
        if (ret == CS_SUCCESS) {
                skt->state |= SOCKET_PRESENT;
+
+               printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n",
+                      (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
+                      skt->sock);
+
 #ifdef CONFIG_CARDBUS
                if (skt->state & SOCKET_CARDBUS) {
                        cb_alloc(skt);
@@ -526,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;
@@ -590,7 +585,6 @@ static int socket_resume(struct pcmcia_socket *skt)
                }
        } else {
                socket_shutdown(skt);
-               cs_socket_put(skt);
        }
 
        skt->state &= ~SOCKET_SUSPEND;
@@ -600,8 +594,8 @@ static int socket_resume(struct pcmcia_socket *skt)
 
 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);
 }
 
 /*
@@ -776,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;
@@ -808,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);
@@ -834,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);
 
@@ -897,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;
@@ -923,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,
 };