r4811 - developers/werner/wlan-spi/patches-tracking

werner at docs.openmoko.org werner at docs.openmoko.org
Sat Nov 22 02:04:08 CET 2008


Author: werner
Date: 2008-11-22 02:04:08 +0100 (Sat, 22 Nov 2008)
New Revision: 4811

Added:
   developers/werner/wlan-spi/patches-tracking/hif-fix-suspend.patch
Log:
Backup, before changing in_suspend to a mutex.



Added: developers/werner/wlan-spi/patches-tracking/hif-fix-suspend.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/hif-fix-suspend.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/hif-fix-suspend.patch	2008-11-22 01:04:08 UTC (rev 4811)
@@ -0,0 +1,99 @@
+Index: ktrack/drivers/ar6000/hif/hif2.c
+===================================================================
+--- ktrack.orig/drivers/ar6000/hif/hif2.c	2008-11-21 22:48:42.000000000 -0200
++++ ktrack/drivers/ar6000/hif/hif2.c	2008-11-21 22:58:33.000000000 -0200
+@@ -36,7 +36,6 @@
+  * KNOWN BUGS:
+  *
+  * - HIF_DEVICE_IRQ_ASYNC_SYNC doesn't work yet (gets MMC errors)
+- * - driver doesn't remove cleanly yet
+  * - latency can reach hundreds of ms, probably because of scheduling delays
+  * - packets go through about three queues before finally hitting the network
+  */
+@@ -110,6 +109,7 @@
+ 
+ 
+ static HTC_CALLBACKS htcCallbacks;
++static int in_shutdown; /* prevent recursion through HIFShutDownDevice */
+ 
+ 
+ /* ----- Request processing ------------------------------------------------ */
+@@ -521,16 +521,22 @@
+ 	HIF_DEVICE *hif = sdio_get_drvdata(func);
+ 	int ret;
+ 
+-#if 0
+-	/*
+-	 * Funny, Atheros' HIF does this call, but this just puts us in a
+-	 * recursion through HTCShutDown/HIFShutDown if unloading the
+-	 * module.
+-	 */
+-	ret = htcCallbacks.deviceRemovedHandler(hif->htc_handle, A_OK);
+-	if (ret != A_OK)
+-		dev_err(dev, "deviceRemovedHandler: %d\n", ret);
+-#endif
++	dev_dbg(dev, "sdio_ar6000_remove\n");
++	if (!in_shutdown) {
++		/*
++		 * Funny, Atheros' HIF does this call, but this just puts us in
++		 * a recursion through HTCShutDown/HIFShutDown if unloading the
++		 * module.
++		 *
++		 * However, we need it for suspend/resume. See the comment at
++		 * HIFShutDown, below.
++		 */
++		in_shutdown++;
++		ret = htcCallbacks.deviceRemovedHandler(hif->htc_handle, A_OK);
++		in_shutdown--;
++		if (ret != A_OK)
++			dev_err(dev, "deviceRemovedHandler: %d\n", ret);
++	}
+ 	wait_queue_empty(hif);
+ 	ret = kthread_stop(hif->io_task);
+ 	if (ret)
+@@ -591,8 +597,44 @@
+ }
+ 
+ 
++/*
++ * We have three possible call chains here:
++ *
++ * System shutdown/reboot:
++ *
++ *   kernel_restart_prepare ...> device_shutdown ... > s3cmci_shutdown ->
++ *     mmc_remove_host ..> sdio_bus_remove -> sdio_ar6000_remove ->
++ *     deviceRemovedHandler (HTCTargetRemovedHandler) -> HIFShutDownDevice
++ *
++ *   This is roughly the same sequence as suspend, described below.
++ *
++ * Module removal:
++ *
++ *   sys_delete_module -> ar6000_cleanup_module -> HTCShutDown ->
++ *     HIFShutDownDevice -> sdio_unregister_driver ...> sdio_bus_remove ->
++ *     sdio_ar6000_remove
++ *
++ *   In this case, HIFShutDownDevice must call sdio_unregister_driver to
++ *   notify the driver about its removal. sdio_ar6000_remove must not call
++ *   deviceRemovedHandler, because that would loop back into HIFShutDownDevice.
++ *
++ * Suspend:
++ *
++ *   device_suspend ...> s3cmci_suspend ...> sdio_bus_remove ->
++ *     sdio_ar6000_remove -> deviceRemovedHandler (HTCTargetRemovedHandler) ->
++ *     HIFShutDownDevice
++ *
++ *   We must call deviceRemovedHandler to inform the ar6k stack that the device
++ *   has been removed. Since HTCTargetRemovedHandler calls back into
++ *   HIFShutDownDevice, we must also prevent the call to
++ *   sdio_unregister_driver, or we'd end up recursing into the SDIO stack,
++ *   eventually deadlocking somewhere.
++ */
++
+ void HIFShutDownDevice(HIF_DEVICE *hif)
+ {
+ 	/* Beware, HTCShutDown calls us with hif == NULL ! */
+-	sdio_unregister_driver(&sdio_ar6000_driver);
++	if (!in_shutdown++)
++		sdio_unregister_driver(&sdio_ar6000_driver);
++	in_shutdown--;
+ }




More information about the commitlog mailing list