if_spi: howto implement suspend/resume?

Dan Williams dcbw at redhat.com
Fri Apr 17 17:52:30 EDT 2009


On Fri, 2009-04-17 at 18:24 +0200, Uli Luckas wrote:
> 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?

Does SPI suspend cut power to the libertas chip?  Does it do
bus-specific low-power stuff?  The current suspend code assumes that the
libertas chip does not require complete reinitialization (ie, new
firmware load, etc), which of course implies that the libertas chip is
still powered across suspend so that when the host wakes up, a command
can simply be sent to the card that will wake it up.

That is an artifact of the OLPC use-case, which isn't necessarily
applicable elsewhere.

Dan

> 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
> 
> 
> _______________________________________________
> libertas-dev mailing list
> libertas-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libertas-dev




More information about the libertas-dev mailing list