[PATCH 4/13] pcmcia: new suspend core

Dominik Brodowski linux at dominikbrodowski.net
Wed Sep 7 17:36:56 EDT 2005


Add support to the PCMCIA core to move the supend and resume methods out
of the event handler. Also use these functions for pre- and post-reset,
as almost all drivers do it this way anyway. Convert pcnet_cs as an
example.

Signed-off-by: Dominik Brodowski <linux at dominikbrodoswki.net>
---
 Documentation/pcmcia/driver-changes.txt |    6 +++
 drivers/net/pcmcia/pcnet_cs.c           |   58 +++++++++++++++++++-------------
 drivers/pcmcia/ds.c                     |   10 +++++
 include/pcmcia/ds.h                     |    6 +++
 4 files changed, 57 insertions(+), 23 deletions(-)

Index: 2.6.13-rc4-git1/drivers/net/pcmcia/pcnet_cs.c
===================================================================
--- 2.6.13-rc4-git1.orig/drivers/net/pcmcia/pcnet_cs.c
+++ 2.6.13-rc4-git1/drivers/net/pcmcia/pcnet_cs.c
@@ -780,6 +780,39 @@ static void pcnet_release(dev_link_t *li
 
 ======================================================================*/
 
+static int pcnet_suspend(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
+	}
+
+	return 0;
+}
+
+static int pcnet_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			pcnet_reset_8390(dev);
+			NS8390_init(dev, 1);
+			netif_device_attach(dev);
+		}
+	}
+
+	return 0;
+}
+
 static int pcnet_event(event_t event, int priority,
 		       event_callback_args_t *args)
 {
@@ -798,29 +831,6 @@ static int pcnet_event(event_t event, in
 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 	pcnet_config(link);
 	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
-	}
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		pcnet_reset_8390(dev);
-		NS8390_init(dev, 1);
-		netif_device_attach(dev);
-	    }
-	}
-	break;
     }
     return 0;
 } /* pcnet_event */
@@ -1843,6 +1853,8 @@ static struct pcmcia_driver pcnet_driver
 	.detach		= pcnet_detach,
 	.owner		= THIS_MODULE,
 	.id_table	= pcnet_ids,
+	.suspend	= pcnet_suspend,
+	.resume		= pcnet_resume,
 };
 
 static int __init init_pcnet_cs(void)
Index: 2.6.13-rc4-git1/include/pcmcia/ds.h
===================================================================
--- 2.6.13-rc4-git1.orig/include/pcmcia/ds.h
+++ 2.6.13-rc4-git1/include/pcmcia/ds.h
@@ -137,6 +137,10 @@ struct pcmcia_driver {
 	int (*event)		(event_t event, int priority,
 				 event_callback_args_t *);
 	void			(*detach)(dev_link_t *);
+
+	int (*suspend)		(struct pcmcia_device *dev);
+	int (*resume)		(struct pcmcia_device *dev);
+
 	struct module		*owner;
 	struct pcmcia_device_id	*id_table;
 	struct device_driver	drv;
@@ -193,6 +197,8 @@ struct pcmcia_device {
 #define handle_to_pdev(handle) (handle)
 #define handle_to_dev(handle) (handle->dev)
 
+#define dev_to_instance(dev) (dev->instance);
+
 /* error reporting */
 void cs_error(client_handle_t handle, int func, int ret);
 
Index: 2.6.13-rc4-git1/drivers/pcmcia/ds.c
===================================================================
--- 2.6.13-rc4-git1.orig/drivers/pcmcia/ds.c
+++ 2.6.13-rc4-git1/drivers/pcmcia/ds.c
@@ -946,6 +946,16 @@ static int send_event_callback(struct de
 	if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
 		return 0;
 
+	if ((data->event == CS_EVENT_PM_SUSPEND) ||
+	    (data->event == CS_EVENT_RESET_PHYSICAL)) {
+		if (p_drv->suspend)
+			return p_drv->suspend(p_dev);
+	} else if ((data->event == CS_EVENT_PM_RESUME) ||
+		   (data->event == CS_EVENT_CARD_RESET)) {
+		if (p_drv->resume)
+			return p_drv->resume(p_dev);
+	}
+
 	if (p_drv->event)
 		return p_drv->event(data->event, data->priority,
 				    &p_dev->event_callback_args);
Index: 2.6.13-rc4-git1/Documentation/pcmcia/driver-changes.txt
===================================================================
--- 2.6.13-rc4-git1.orig/Documentation/pcmcia/driver-changes.txt
+++ 2.6.13-rc4-git1/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,11 @@
 This file details changes in 2.6 which affect PCMCIA card driver authors:
 
+* Move suspend, resume and reset out of event handler (as of 2.6.14)
+       int (*suspend)          (struct pcmcia_device *dev);
+       int (*resume)           (struct pcmcia_device *dev);
+  should be initialized in struct pcmcia_driver, and handle
+  (SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
+
 * event handler initialization in struct pcmcia_driver (as of 2.6.13)
    The event handler is notified of all events, and must be initialized
    as the event() callback in the driver's struct pcmcia_driver.



More information about the linux-pcmcia mailing list