if_spi: howto implement suspend/resume?

Uli Luckas u.luckas at road.de
Fri Apr 17 12:24:45 EDT 2009


Hi all,
I am trying to implement suspend/resume support for libertas_spi as suspending 
a device with the libertas_spi driver loaded now crashes the kernel.
As I have no firmware documentation, I naively followed the if_usb driver.
As expected this did not work. With the patch below the kernel does not crash 
any more but the libertas chip is non-functional after resume:
Apr 17 18:14:51 [kernel] [    0.000931] libertas: I/O error
Apr 17 18:14:51 [kernel] [    0.000963] libertas: lbs_spi_thread: got error 
-108
Apr 17 18:14:51 [kernel] [    0.104789] pxa27x-udc pxa27x-udc: UDC connecting
Apr 17 18:14:51 [kernel] [    0.104789] pxa27x-udc pxa27x-udc: UDC connecting
Apr 17 18:14:51 [kernel] [    0.104818] UDC connect command, vbus=0 
UP2OCR=0x20010 UDCCR=0x1
Apr 17 18:14:51 [kernel] [    0.104908] set_ctrlr_state: driver not active
Apr 17 18:14:51 [kernel] [    0.137551] sa1100-rtc sa1100-rtc: Current time:     
17.03.0109 18:14.51
Apr 17 18:14:51 [kernel] [    0.137839] soc-audio soc-audio: scheduling resume 
work
Apr 17 18:14:51 [kernel] [    0.201723] soc-audio soc-audio: starting resume 
work
Apr 17 18:14:51 [kernel] [    0.237665] soc-audio soc-audio: resume work 
completed
Apr 17 18:14:51 [kernel] [    0.243683]  XXXXX irq_worker() ... hs: 0
Apr 17 18:14:51 [kernel] [    0.244840] libertas: command 0x0000 timed out
Apr 17 18:14:51 [kernel] [    0.244931] libertas: requeueing command 0x0000 
due to timeout (#1)
Apr 17 18:14:51 [kernel] [    0.244967] libertas: if_spi_host_to_card: invalid 
size requested: 0
Apr 17 18:14:51 [kernel] [    0.244989] libertas: DNLD_CMD: hw_host_to_card 
failed: -22
Apr 17 18:14:51 [kernel] [    0.325061] pxa27x-udc pxa27x-udc: USB reset
Apr 17 18:14:51 [kernel] [    0.409421] sa1100-rtc sa1100-rtc: Current time:     
17.03.0109 18:14.51
Apr 17 18:14:51 [kernel] [    0.429994] pxa27x-udc pxa27x-udc: USB reset
Apr 17 18:14:51 [kernel] [    0.494870] libertas: command 0x0000 timed out
Apr 17 18:14:51 [kernel] [    0.494974] libertas: requeueing command 0x0000 
due to timeout (#2)
Apr 17 18:14:51 [kernel] [    0.495010] libertas: if_spi_host_to_card: invalid 
size requested: 0
Apr 17 18:14:51 [kernel] [    0.495033] libertas: DNLD_CMD: hw_host_to_card 
failed: -22

Can anybody sched some ligt on how to approach suspend functionality in 
if_spi?

Thanks
Uli


Index: drivers/net/wireless/libertas/if_spi.c
===================================================================
--- drivers/net/wireless/libertas/if_spi.c	(revision 11391)
+++ drivers/net/wireless/libertas/if_spi.c	(working copy)
@@ -31,6 +31,7 @@
 #include "decl.h"
 #include "defs.h"
 #include "dev.h"
+#include "cmd.h"
 #include "if_spi.h"
 
 struct if_spi_packet {
@@ -1139,6 +1140,10 @@
 	if (err)
 		goto release_irq;
 
+	priv->wol_gpio = 2; /* Wake via GPIO2... */
+	priv->wol_gap = 20; /* ... after 20ms    */
+	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
+
 	lbs_deb_spi("Finished initializing WLAN module.\n");
 
 	/* successful exit */
@@ -1183,9 +1188,49 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int if_spi_suspend(struct spi_device *spi, pm_message_t mesg)
+{
+	struct if_spi_card *card = spi_get_drvdata(spi);
+	struct lbs_private *priv = card->priv;
+	int ret;
+
+	lbs_deb_enter(LBS_DEB_USB);
+
+	ret = lbs_suspend(priv);
+	if (ret)
+		goto out;
+
+ out:
+	lbs_deb_leave(LBS_DEB_USB);
+	return ret;
+}
+
+static int if_spi_resume(struct spi_device *spi)
+{
+	struct if_spi_card *card = spi_get_drvdata(spi);
+	struct lbs_private *priv = card->priv;
+
+	lbs_deb_enter(LBS_DEB_USB);
+
+	up(&card->spi_ready);
+
+	lbs_resume(priv);
+
+	lbs_deb_leave(LBS_DEB_USB);
+	return 0;
+}
+#else
+#define if_spi_suspend NULL
+#define if_spi_resume NULL
+#endif
+
+
 static struct spi_driver libertas_spi_driver = {
 	.probe	= if_spi_probe,
 	.remove = __devexit_p(libertas_spi_remove),
+	.suspend = if_spi_suspend,
+	.resume = if_spi_resume,
 	.driver = {
 		.name	= "libertas_spi",
 		.bus	= &spi_bus_type,

-- 

------- ROAD ...the handyPC Company - - -  ) ) )

Uli Luckas
Head of Software Development

ROAD GmbH
Bennigsenstr. 14 | 12159 Berlin | Germany
fon: +49 (30) 230069 - 62 | fax: +49 (30) 230069 - 69
url: www.road.de

Amtsgericht Charlottenburg: HRB 96688 B
Managing director: Hans-Peter Constien




More information about the libertas-dev mailing list