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

werner at docs.openmoko.org werner at docs.openmoko.org
Sun Nov 2 10:43:39 CET 2008


Author: werner
Date: 2008-11-02 10:43:38 +0100 (Sun, 02 Nov 2008)
New Revision: 4738

Modified:
   developers/werner/wlan-spi/patches-tracking/gta02-mmc-mci.patch
   developers/werner/wlan-spi/patches-tracking/hif-linux-sdio.patch
Log:
Cleanup.

drivers/ar6000/hif/hif2.c:
- MODULE_LICENSE is GPLv2, not just GPL
- added cleanup after initialization errors
- added partial cleanup on removal
- removed solved/obsolete problems from list of known bugs
- added description of differences to Atheros's HIFs
- removed initialization thread, since it doesn't seem to be needed
- removed out-of-band interrupt code
- removed setting of SDIO_POWER_EMPC in SDIO_CCCR_POWER (still needs checking
  with Atheros, though)
- added sections and moved HIFInit to a more logical place



Modified: developers/werner/wlan-spi/patches-tracking/gta02-mmc-mci.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/gta02-mmc-mci.patch	2008-11-02 06:41:14 UTC (rev 4737)
+++ developers/werner/wlan-spi/patches-tracking/gta02-mmc-mci.patch	2008-11-02 09:43:38 UTC (rev 4738)
@@ -2,8 +2,8 @@
 
 Index: ktrack/arch/arm/mach-s3c2440/Kconfig
 ===================================================================
---- ktrack.orig/arch/arm/mach-s3c2440/Kconfig	2008-11-02 04:29:34.000000000 -0200
-+++ ktrack/arch/arm/mach-s3c2440/Kconfig	2008-11-02 04:32:14.000000000 -0200
+--- ktrack.orig/arch/arm/mach-s3c2440/Kconfig	2008-11-02 07:32:56.000000000 -0200
++++ ktrack/arch/arm/mach-s3c2440/Kconfig	2008-11-02 07:32:56.000000000 -0200
 @@ -113,6 +113,11 @@
                  bool "GPIO bit-banging SPI"
                  select MMC_SPI
@@ -18,8 +18,8 @@
  endmenu
 Index: ktrack/arch/arm/mach-s3c2440/mach-gta02.c
 ===================================================================
---- ktrack.orig/arch/arm/mach-s3c2440/mach-gta02.c	2008-11-02 04:29:34.000000000 -0200
-+++ ktrack/arch/arm/mach-s3c2440/mach-gta02.c	2008-11-02 04:33:05.000000000 -0200
+--- ktrack.orig/arch/arm/mach-s3c2440/mach-gta02.c	2008-11-02 07:32:56.000000000 -0200
++++ ktrack/arch/arm/mach-s3c2440/mach-gta02.c	2008-11-02 07:32:56.000000000 -0200
 @@ -1720,6 +1720,11 @@
  	platform_device_register(&gta02_spi_wlan);
  #endif /* CONFIG_AR6K_SPI_S3C24XX_GPIO */

Modified: developers/werner/wlan-spi/patches-tracking/hif-linux-sdio.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/hif-linux-sdio.patch	2008-11-02 06:41:14 UTC (rev 4737)
+++ developers/werner/wlan-spi/patches-tracking/hif-linux-sdio.patch	2008-11-02 09:43:38 UTC (rev 4738)
@@ -11,8 +11,8 @@
 
 Index: ktrack/drivers/ar6000/Makefile
 ===================================================================
---- ktrack.orig/drivers/ar6000/Makefile	2008-10-15 22:04:35.000000000 -0200
-+++ ktrack/drivers/ar6000/Makefile	2008-10-15 22:04:35.000000000 -0200
+--- ktrack.orig/drivers/ar6000/Makefile	2008-11-02 05:48:42.000000000 -0200
++++ ktrack/drivers/ar6000/Makefile	2008-11-02 05:48:44.000000000 -0200
 @@ -21,7 +21,7 @@
                 htc/htc_recv.o       	   \
                 htc/htc_services.o          \
@@ -25,8 +25,8 @@
 Index: ktrack/drivers/ar6000/hif/hif2.c
 ===================================================================
 --- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ ktrack/drivers/ar6000/hif/hif2.c	2008-10-17 04:26:14.000000000 -0200
-@@ -0,0 +1,625 @@
++++ ktrack/drivers/ar6000/hif/hif2.c	2008-11-02 07:39:48.000000000 -0200
+@@ -0,0 +1,569 @@
 +/*
 + * hif2.c - HIF layer re-implementation for the Linux SDIO stack
 + *
@@ -63,15 +63,41 @@
 + * KNOWN BUGS:
 + *
 + * - HIF_DEVICE_IRQ_ASYNC_SYNC doesn't work yet (gets MMC errors)
-+ * - does not work with S3C SDI (probably due to bugs in the latter)
-+ * - not ready for S3C SPI yet
-+ * - no cleanup on setup errors yet
 + * - 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
 + */
 +
++/*
++ * Differences from Atheros' HIFs:
++ *
++ * - synchronous and asynchronous requests may get reordered with respect to
++ *   each other, e.g., if HIFReadWrite returns for an asynchronous request and
++ *   then HIFReadWrite is called for a synchronous request, the synchronous
++ *   request may be executed before the asynchronous request.
++ *
++ * - request queue locking seems unnecessarily complex in the Atheros HIFs.
++ *
++ * - Atheros mask interrupts by calling sdio_claim_irq/sdio_release_irq, which
++ *   can cause quite a bit of overhead. This HIF has its own light-weight
++ *   interrupt masking.
++ *
++ * - Atheros call deviceInsertedHandler from a thread spawned off the probe or
++ *   device insertion function. The original explanation for the Atheros SDIO
++ *   stack said that this is done because a delay is needed to let the chip
++ *   complete initialization. There is indeed a one second delay in the thread.
++ *
++ *   The Atheros Linux SDIO HIF removes the delay and only retains the thread.
++ *   Experimentally removing the thread didn't show any conflicts, so let's get
++ *   rid of it for good.
++ *
++ * - The Atheros SDIO stack with Samuel's driver sets SDIO_CCCR_POWER in
++ *   SDIO_POWER_EMPC. Atheros' Linux SDIO code apparently doesn't. We don't
++ *   either, and this seems to work fine.
++ *   @@@ Need to check this with Atheros.
++ */
 +
++
 +//#define dev_dbg dev_info
 +#define dev_dbg(dev, ...) ((void) dev)
 +
@@ -117,17 +143,9 @@
 +static HTC_CALLBACKS htcCallbacks;
 +
 +
-+int HIFInit(HTC_CALLBACKS *callbacks)
-+{
-+	BUG_ON(!callbacks);
++/* ----- Request processing ------------------------------------------------ */
 +
-+	printk(KERN_INFO "HIFInit\n");
-+	htcCallbacks = *callbacks;
 +
-+	return 0;
-+}
-+
-+
 +static A_STATUS process_request(struct hif_request *req)
 +{
 +	int ret;
@@ -181,28 +199,23 @@
 +static int io(void *data)
 +{
 +	struct hif_device *hif = data;
-+	DECLARE_WAITQUEUE(wait, current);
++	DEFINE_WAIT(wait);
 +	struct hif_request *req;
 +
 +	while (1) {
-+		add_wait_queue(&hif->wait, &wait);
 +		while (1) {
-+			set_current_state(TASK_INTERRUPTIBLE);
-+			if (signal_pending(current)) {
-+				req = NULL;
-+				break;
++			prepare_to_wait(&hif->wait, &wait, TASK_INTERRUPTIBLE);
++			if (kthread_should_stop()) {
++				finish_wait(&hif->wait, &wait);
++				return 0;
 +			}
 +			req = dequeue_request(hif);
 +			if (req)
 +				break;
 +			schedule();
 +		}
-+		set_current_state(TASK_RUNNING);
-+		remove_wait_queue(&hif->wait, &wait);
++		finish_wait(&hif->wait, &wait);
 +
-+		if (!req)
-+			break;
-+
 +		(void) process_request(req);
 +	}
 +	return 0;
@@ -267,6 +280,20 @@
 +}
 +
 +
++/* ----- Device initialization and shutdown (HIF side) --------------------- */
++
++
++int HIFInit(HTC_CALLBACKS *callbacks)
++{
++	BUG_ON(!callbacks);
++
++	printk(KERN_INFO "HIFInit\n");
++	htcCallbacks = *callbacks;
++
++	return 0;
++}
++
++
 +A_STATUS HIFConfigureDevice(HIF_DEVICE *hif,
 +    HIF_DEVICE_CONFIG_OPCODE opcode, void *config, A_UINT32 configLen)
 +{
@@ -305,10 +332,8 @@
 +}
 +
 +
-+/* ========================================================================= */
++/* ----- Interrupt handling ------------------------------------------------ */
 +
-+#if 1
-+
 +/*
 + * Volatile ought to be good enough to make gcc do the right thing on S3C24xx.
 + * No need to use atomic or put barriers, keeping the code more readable.
@@ -415,84 +440,10 @@
 +		yield();
 +}
 +
-+#endif
 +
-+/* ========================================================================= */
++/* ----- HIF API glue functions -------------------------------------------- */
 +
-+/*
-+ * The code below is for handling interrupts signalled out-of-band.
-+ */
-+#if 0
-+#define IRQ_GPIO S3C2410_GPE8 /* SDDAT1 */
 +
-+
-+static atomic_t mask = ATOMIC_INIT(1);
-+
-+
-+static void sdio_ar6000_irq(struct sdio_func *func)
-+{
-+	HIF_DEVICE *hif = sdio_get_drvdata(func);
-+
-+	printk(KERN_DEBUG "sdio_ar6000_irq -> %p\n", htcCallbacks.dsrHandler);
-+	BUG();
-+}
-+
-+
-+static void sdio_ar6000_poll(void *context)
-+{
-+	HIF_DEVICE *hif = context;
-+	A_STATUS status;
-+
-+	while (1) {
-+		yield();
-+		if (!gpio_get_value(IRQ_GPIO))
-+			continue;
-+		if (!atomic_add_unless(&mask, 1, 1))
-+			continue;
-+		status = htcCallbacks.dsrHandler(hif->htc_handle);
-+		BUG_ON(status != A_OK);
-+	}
-+}
-+
-+
-+void HIFAckInterrupt(HIF_DEVICE *hif)
-+{
-+	struct device *dev = HIFGetOSDevice(hif);
-+	int ret;
-+
-+	ret = atomic_dec_return(&mask);
-+	BUG_ON(ret < 0);
-+	dev_dbg(dev, "HIFAckInterrupt (%d)\n", ret);
-+}
-+
-+
-+void HIFUnMaskInterrupt(HIF_DEVICE *hif)
-+{
-+	struct device *dev = HIFGetOSDevice(hif);
-+	int ret;
-+
-+	ret = atomic_dec_return(&mask);
-+	BUG_ON(ret < 0);
-+	dev_dbg(dev, "HIFUnMaskInterrupt (%d)\n", ret);
-+}
-+
-+
-+void HIFMaskInterrupt(HIF_DEVICE *hif)
-+{
-+	struct device *dev = HIFGetOSDevice(hif);
-+	int ret;
-+
-+	ret = atomic_inc_return(&mask);
-+	BUG_ON(ret > 1);
-+	dev_dbg(dev, "HIFMaskInterrupt (%d)\n", ret);
-+}
-+#endif
-+
-+/* ========================================================================= */
-+
-+
-+/* ----- Some stuff needed for Atheros' API -------------------------------- */
-+
 +struct device *HIFGetOSDevice(HIF_DEVICE *hif)
 +{
 +	return &hif->func->dev;
@@ -507,31 +458,14 @@
 +}
 +
 +
-+/* -----  */
++/* ----- Device setup and removal (Linux side) ----------------------------- */
 +
 +
-+
-+/*
-+ * @@@ Atheros' HIF says this hack is necessary. Check this.
-+ */
-+
-+static int inserter(void *data)
-+{
-+	int ret;
-+
-+	msleep(1000);
-+	ret = htcCallbacks.deviceInsertedHandler(&hif_device);
-+	printk(KERN_ERR "got %d\n", ret);
-+	return 0;
-+}
-+
-+
 +static int sdio_ar6000_probe(struct sdio_func *func,
 +    const struct sdio_device_id *id)
 +{
 +	struct device *dev = &func->dev;
 +	int ret;
-+	struct task_struct *task;
 +
 +	dev_dbg(dev, "sdio_ar6000_probe\n");
 +	BUG_ON(!htcCallbacks.deviceInsertedHandler);
@@ -548,12 +482,12 @@
 +	ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
 +	if (ret < 0) {
 +		dev_err(dev, "sdio_set_block_size returns %d\n", ret);
-+		/* @@@ cleanup */
++		goto out_enabled;
 +	}
 +	ret = sdio_claim_irq(func, sdio_ar6000_irq);
 +	if (ret) {
 +		dev_err(dev, "sdio_claim_irq returns %d\n", ret);
-+		/* @@@ cleanup */
++		goto out_enabled;
 +	}
 +	/* Set SDIO_BUS_CD_DISABLE in SDIO_CCCR_IF ? */
 +#if 0
@@ -561,47 +495,57 @@
 +	if (ret) {
 +		dev_err(dev, "sdio_f0_writeb(SDIO_CCCR_CAPS) returns %d\n",
 +		    ret);
-+		/* @@@ cleanup */
++		goto out_got_irq;
 +	}
 +#endif
-+#if 0
-+	/*
-+	 * @@@ Samuel's driver sets this, Atheros' Linux SDIO HIF apparently
-+	 * doesn't, and things seem to work okay without it here as well.
-+	 * Check with Atheros.
-+	 */
-+	sdio_f0_writeb(func, SDIO_POWER_EMPC, SDIO_CCCR_POWER, &ret);
-+	if (ret) {
-+		dev_err(dev, "sdio_f0_writeb(SDIO_CCCR_POWER) returns %d\n",
-+		    ret);
-+		/* @@@ cleanup */
-+	}
-+#endif
++
 +	sdio_release_host(func);
 +
 +	hif_device.io_task = kthread_run(io, &hif_device, "ar6000_io");
 +	if (IS_ERR(hif_device.io_task)) {
 +		dev_err(dev, "kthread_run(ar6000_io): %d\n", ret);
-+		/* @@@ cleanup */
++		goto out_func_ready;
 +	}
-+	task = kthread_run(inserter, NULL, "ar6000_inserter");
-+	if (IS_ERR(task)) {
-+		dev_err(dev, "kthread_run (ar6000_inserter): %d\n", ret);
-+		/* @@@ cleanup */
-+	}
 +
-+	return 0;
++	ret = htcCallbacks.deviceInsertedHandler(&hif_device);
++	if (ret == A_OK)
++		return 0;
++
++	dev_err(dev, "deviceInsertedHandler: %d\n", ret);
++
++	ret = kthread_stop(hif_device.io_task);
++	if (ret)
++		dev_err(dev, "kthread_stop (ar6000_io): %d\n", ret);
++
++out_func_ready:
++	sdio_claim_host(func);
++
++/* generates a warning */
++out_got_irq:
++	sdio_release_irq(func);
++
++out_enabled:
++	sdio_set_drvdata(func, NULL);
++	sdio_disable_func(func);
++	sdio_release_host(func);
++
++	return ret;
 +}
 +
 +
 +static void sdio_ar6000_remove(struct sdio_func *func)
 +{
++	struct device *dev = &func->dev;
++	int ret;
++
++	ret = kthread_stop(hif_device.io_task);
++	if (ret)
++		dev_err(dev, "kthread_stop (ar6000_io): %d\n", ret);
 +	sdio_claim_host(func);
 +	sdio_release_irq(func);
 +	sdio_disable_func(func);
 +	sdio_release_host(func);
 +	/* @@@ remove */
-+	/* @@@ kill _tasks */
 +}
 +
 +
@@ -651,4 +595,4 @@
 +module_exit(sdio_ar6000_exit);
 +
 +MODULE_AUTHOR("Werner Almesberger");
-+MODULE_LICENSE("GPL");
++MODULE_LICENSE("GPL v2");




More information about the commitlog mailing list