[PATCH] suspend/resume vs eject/insert

Rodolfo Giometti giometti at linux.it
Mon Aug 7 08:19:43 EDT 2006


Hello,

I'm working on a MIPS machine which has an on board WiFi module
connected by the PCMCIA interface to the main CPU.

My WiFi is capable to freeze and unfreeze its internal status but I
cannot remove the power supply nor move the reset line!

Using the pccardctl suspend/resume and eject/suspend I get the
following sequences into my low level driver:

   hostname:~# pccardctl suspend
   WWPC-PCMCIA: : config_skt 0 Vcc 0V Vpp 0V, flags 0 (reset 0)
   WWPC-PCMCIA: : suspend_skt 0

   hostname:~# pccardctl resume
   WWPC-PCMCIA: : init_skt 0
   WWPC-PCMCIA: : config_skt 0 Vcc 0V Vpp 0V, flags 0 (reset 0)
   WWPC-PCMCIA: : config_skt 0 Vcc 33V Vpp 33V, flags 0 (reset 0)
   WWPC-PCMCIA: : config_skt 0 Vcc 33V Vpp 0V, flags 240 (reset 1)
   WWPC-PCMCIA: : config_skt 0 Vcc 33V Vpp 0V, flags 200 (reset 0)

   hostname:~# pccardctl eject 
   pccard: card ejected from slot 0
   WWPC-PCMCIA: init_skt 0
   WWPC-PCMCIA: config_skt 0 Vcc 0V Vpp 0V, flags 0 (reset 0)

   hostname:~# pccardctl insert
   WWPC-PCMCIA: config_skt 0 Vcc 33V Vpp 33V, flags 0 (reset 0)
   WWPC-PCMCIA: config_skt 0 Vcc 33V Vpp 0V, flags 240 (reset 1)
   WWPC-PCMCIA: config_skt 0 Vcc 33V Vpp 0V, flags 200 (reset 0)
   pccard: PCMCIA card inserted into slot 0
   pcmcia: registering new device pcmcia0.0

In this situation I cannot distinguish whether functions config_skt()
and init_skt() are called during a suspend/resume or eject/suspend
cycle!  Expecially for function config_skt() which is the one that
should move power and reset signals.

So I propose this little patch that adds a new flag "SS_COMA" which
can be used to identify suspend/resume cycle from eject/suspend. The
patch also should not modify old behaviour.

   hostname:~# pccardctl suspend
   WWPC-PCMCIA: config_skt 0 Vcc 0V Vpp 0V, flags 400 (reset 0)
   WWPC-PCMCIA: suspend_skt 0

   hostname:~# pccardctl resume
   WWPC-PCMCIA: init_skt 0
   WWPC-PCMCIA: config_skt 0 Vcc 0V Vpp 0V, flags 400 (reset 0)
   WWPC-PCMCIA: config_skt 0 Vcc 33V Vpp 33V, flags 400 (reset 0)
   WWPC-PCMCIA: config_skt 0 Vcc 33V Vpp 0V, flags 640 (reset 1)
   WWPC-PCMCIA: config_skt 0 Vcc 33V Vpp 0V, flags 600 (reset 0)

Ciao,

Rodolfo


Signed-off-by: Rodolfo Giometti <giometti at linux.it>

-- 

GNU/Linux Solutions                  e-mail:    giometti at enneenne.com
Linux Device Driver                             giometti at gnudd.com
Embedded Systems                     		giometti at linux.it
UNIX programming                     phone:     +39 349 2432127
-------------- next part --------------
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index f9cd831..985877c 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -79,6 +79,10 @@ socket_state_t dead_socket = {
 	.csc_mask	= SS_DETECT,
 };
 EXPORT_SYMBOL(dead_socket);
+socket_state_t coma_socket = {
+	.flags		= SS_COMA,
+	.csc_mask	= SS_DETECT,
+};
 
 
 /* List of all sockets, protected by a rwsem */
@@ -417,7 +421,7 @@ #endif
 	cs_socket_put(s);
 }
 
-static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
+static int socket_setup(struct pcmcia_socket *skt, int flags, int initial_delay)
 {
 	int status, i;
 
@@ -468,7 +472,7 @@ static int socket_setup(struct pcmcia_so
 	if (skt->power_hook)
 		skt->power_hook(skt, HOOK_POWER_PRE);
 
-	skt->socket.flags = 0;
+	skt->socket.flags = flags;
 	skt->ops->set_socket(skt, &skt->socket);
 
 	/*
@@ -503,7 +507,7 @@ static int socket_insert(struct pcmcia_s
 	if (!cs_socket_get(skt))
 		return CS_NO_CARD;
 
-	ret = socket_setup(skt, setup_delay);
+	ret = socket_setup(skt, 0, setup_delay);
 	if (ret == CS_SUCCESS) {
 		skt->state |= SOCKET_PRESENT;
 
@@ -533,7 +537,7 @@ static int socket_suspend(struct pcmcia_
 		return CS_IN_USE;
 
 	send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
-	skt->socket = dead_socket;
+	skt->socket = coma_socket;
 	skt->ops->set_socket(skt, &skt->socket);
 	if (skt->ops->suspend)
 		skt->ops->suspend(skt);
@@ -554,7 +558,7 @@ static int socket_resume(struct pcmcia_s
 	if (!(skt->state & SOCKET_SUSPEND))
 		return CS_IN_USE;
 
-	skt->socket = dead_socket;
+	skt->socket = coma_socket;
 	skt->ops->init(skt);
 	skt->ops->set_socket(skt, &skt->socket);
 
@@ -563,7 +567,7 @@ static int socket_resume(struct pcmcia_s
 		return socket_insert(skt);
 	}
 
-	ret = socket_setup(skt, resume_delay);
+	ret = socket_setup(skt, SS_COMA, resume_delay);
 	if (ret == CS_SUCCESS) {
 		/*
 		 * FIXME: need a better check here for cardbus cards.
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index ede6398..c8136e6 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -69,6 +69,7 @@ #define SS_RESET	0x0040
 #define SS_DMA_MODE	0x0080
 #define SS_SPKR_ENA	0x0100
 #define SS_OUTPUT_ENA	0x0200
+#define SS_COMA		0x0400
 
 /* Flags for I/O port and memory windows */
 #define MAP_ACTIVE	0x01
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.infradead.org/pipermail/linux-pcmcia/attachments/20060807/407e0e81/attachment.bin 


More information about the linux-pcmcia mailing list