[PATCH] pcmcia: default suspend and resume handling

In all but one case, the suspend and resume functions of PCMCIA drivers
contain mostly of calls to pcmcia_release_configuration() and
pcmcia_request_configuration(). Therefore, move this code out of the
drivers and into the core.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>

diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 16159e9..ec2d416 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -10,7 +10,7 @@
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * (C) 1999		David A. Hinds
- * (C) 2003 - 2005	Dominik Brodowski
+ * (C) 2003 - 2006	Dominik Brodowski
  */
 
 #include <linux/kernel.h>
@@ -1030,12 +1030,22 @@
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
 	struct pcmcia_driver *p_drv = NULL;
+	int ret;
 
 	if (dev->driver)
 		p_drv = to_pcmcia_drv(dev->driver);
 
-	if (p_drv && p_drv->suspend)
-		return p_drv->suspend(p_dev);
+	if (p_drv && p_drv->suspend) {
+		ret = p_drv->suspend(p_dev);
+		if (ret)
+			return ret;
+		if (p_dev->instance) {
+			p_dev->instance->state |= DEV_SUSPEND;
+			if ((p_dev->instance->state & DEV_CONFIG) &&
+			    !(p_dev->instance->state & DEV_SUSPEND_NORELEASE))
+				pcmcia_release_configuration(p_dev);
+		}
+	}
 
 	return 0;
 }
@@ -1045,12 +1055,24 @@
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
         struct pcmcia_driver *p_drv = NULL;
+	int ret;
 
 	if (dev->driver)
 		p_drv = to_pcmcia_drv(dev->driver);
 
-	if (p_drv && p_drv->resume)
+	if (p_drv && p_drv->resume) {
+		if (p_dev->instance) {
+			p_dev->instance->state &= ~DEV_SUSPEND;
+			if ((p_dev->instance->state & DEV_CONFIG) &&
+			    !(p_dev->instance->state & DEV_SUSPEND_NORELEASE)){
+				ret = pcmcia_request_configuration(p_dev,
+						 &p_dev->instance->conf);
+				if (ret)
+					return ret;
+			}
+		}
 		return p_drv->resume(p_dev);
+	}
 
 	return 0;
 }