r4795 - in developers/werner/wlan-spi/patches-tracking: . attic2 nand

werner at docs.openmoko.org werner at docs.openmoko.org
Mon Nov 17 09:46:25 CET 2008


Author: werner
Date: 2008-11-17 09:46:24 +0100 (Mon, 17 Nov 2008)
New Revision: 4795

Added:
   developers/werner/wlan-spi/patches-tracking/attic2/
   developers/werner/wlan-spi/patches-tracking/attic2/ar6k-without-sdio.patch
   developers/werner/wlan-spi/patches-tracking/attic2/gta02-remove-sdio.patch
   developers/werner/wlan-spi/patches-tracking/attic2/hif-linux-sdio.patch
   developers/werner/wlan-spi/patches-tracking/attic2/sdio-add-atheros-ar6k.patch
   developers/werner/wlan-spi/patches-tracking/attic2/series
   developers/werner/wlan-spi/patches-tracking/nand/
   developers/werner/wlan-spi/patches-tracking/nand/hack-disable-ecc.patch
   developers/werner/wlan-spi/patches-tracking/nand/reverse-ecc-fix.patch
   developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-handle-bytes.patch
   developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-shift-not-div.patch
   developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-use-iomem.patch
Removed:
   developers/werner/wlan-spi/patches-tracking/ar6k-without-sdio.patch
   developers/werner/wlan-spi/patches-tracking/gta02-remove-sdio.patch
   developers/werner/wlan-spi/patches-tracking/hif-linux-sdio.patch
   developers/werner/wlan-spi/patches-tracking/sdio-add-atheros-ar6k.patch
   developers/werner/wlan-spi/patches-tracking/series
Log:
- move patches now in stable-tracking over to attic2/
- keep NAND patches for posteriority (note: they're on a parallel track via
  Ben's tree - this is merely a backup)



Deleted: developers/werner/wlan-spi/patches-tracking/ar6k-without-sdio.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/ar6k-without-sdio.patch	2008-11-16 07:57:38 UTC (rev 4794)
+++ developers/werner/wlan-spi/patches-tracking/ar6k-without-sdio.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -1,63 +0,0 @@
-ar6k-without-sdio.patch
-
-Make the AR6000 WLAN driver compile after moving it outside the
-Atheros SDIO stack. Note that the config option's name changes
-as well.
-
-The choice of a non-standard location (drivers/ar6000/) is
-intentional. The driver is still very far from being in shape for
-mainline inclusion, and the odd location should serve as an
-immediate warning.
-
-Not-Yet-Signed-off-by: Werner Almesberger <werner at openmoko.org>
-
-Index: ktrack/arch/arm/Kconfig
-===================================================================
---- ktrack.orig/arch/arm/Kconfig	2008-11-02 02:50:01.000000000 -0200
-+++ ktrack/arch/arm/Kconfig	2008-11-02 04:29:20.000000000 -0200
-@@ -1269,7 +1269,7 @@
- 
- source "drivers/uwb/Kconfig"
- 
--source "drivers/sdio/Kconfig"
-+source "drivers/ar6000/Kconfig"
- 
- source "drivers/mmc/Kconfig"
- 
-Index: ktrack/drivers/Makefile
-===================================================================
---- ktrack.orig/drivers/Makefile	2008-11-02 02:50:02.000000000 -0200
-+++ ktrack/drivers/Makefile	2008-11-02 04:29:20.000000000 -0200
-@@ -87,6 +87,7 @@
- obj-$(CONFIG_MMC)		+= mmc/
- obj-$(CONFIG_MEMSTICK)		+= memstick/
- obj-$(CONFIG_SDIO)              += sdio/
-+obj-$(CONFIG_AR6000_WLAN)	+= ar6000/
- obj-$(CONFIG_NEW_LEDS)		+= leds/
- obj-$(CONFIG_INFINIBAND)	+= infiniband/
- obj-$(CONFIG_SGI_SN)		+= sn/
-Index: ktrack/drivers/ar6000/Kconfig
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ ktrack/drivers/ar6000/Kconfig	2008-11-02 04:29:20.000000000 -0200
-@@ -0,0 +1,7 @@
-+config AR6000_WLAN
-+        tristate "AR6000 wireless networking over SDIO"
-+	depends on MMC
-+        select WIRELESS_EXT
-+        default m
-+        help
-+          good luck.
-Index: ktrack/drivers/ar6000/Makefile
-===================================================================
---- ktrack.orig/drivers/ar6000/Makefile	2008-11-02 02:50:02.000000000 -0200
-+++ ktrack/drivers/ar6000/Makefile	2008-11-02 04:29:20.000000000 -0200
-@@ -13,7 +13,7 @@
- 
- EXTRA_CFLAGS += -DKERNEL_2_6
- 
--obj-$(CONFIG_SDIO_AR6000_WLAN) += ar6000.o
-+obj-$(CONFIG_AR6000_WLAN) += ar6000.o
- 
- ar6000-objs += htc/ar6k.o      		   \
- 	       htc/ar6k_events.o 	   \

Copied: developers/werner/wlan-spi/patches-tracking/attic2/ar6k-without-sdio.patch (from rev 4746, developers/werner/wlan-spi/patches-tracking/ar6k-without-sdio.patch)
===================================================================
--- developers/werner/wlan-spi/patches-tracking/attic2/ar6k-without-sdio.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/attic2/ar6k-without-sdio.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,63 @@
+ar6k-without-sdio.patch
+
+Make the AR6000 WLAN driver compile after moving it outside the
+Atheros SDIO stack. Note that the config option's name changes
+as well.
+
+The choice of a non-standard location (drivers/ar6000/) is
+intentional. The driver is still very far from being in shape for
+mainline inclusion, and the odd location should serve as an
+immediate warning.
+
+Not-Yet-Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+Index: ktrack/arch/arm/Kconfig
+===================================================================
+--- ktrack.orig/arch/arm/Kconfig	2008-11-02 02:50:01.000000000 -0200
++++ ktrack/arch/arm/Kconfig	2008-11-02 04:29:20.000000000 -0200
+@@ -1269,7 +1269,7 @@
+ 
+ source "drivers/uwb/Kconfig"
+ 
+-source "drivers/sdio/Kconfig"
++source "drivers/ar6000/Kconfig"
+ 
+ source "drivers/mmc/Kconfig"
+ 
+Index: ktrack/drivers/Makefile
+===================================================================
+--- ktrack.orig/drivers/Makefile	2008-11-02 02:50:02.000000000 -0200
++++ ktrack/drivers/Makefile	2008-11-02 04:29:20.000000000 -0200
+@@ -87,6 +87,7 @@
+ obj-$(CONFIG_MMC)		+= mmc/
+ obj-$(CONFIG_MEMSTICK)		+= memstick/
+ obj-$(CONFIG_SDIO)              += sdio/
++obj-$(CONFIG_AR6000_WLAN)	+= ar6000/
+ obj-$(CONFIG_NEW_LEDS)		+= leds/
+ obj-$(CONFIG_INFINIBAND)	+= infiniband/
+ obj-$(CONFIG_SGI_SN)		+= sn/
+Index: ktrack/drivers/ar6000/Kconfig
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ ktrack/drivers/ar6000/Kconfig	2008-11-02 04:29:20.000000000 -0200
+@@ -0,0 +1,7 @@
++config AR6000_WLAN
++        tristate "AR6000 wireless networking over SDIO"
++	depends on MMC
++        select WIRELESS_EXT
++        default m
++        help
++          good luck.
+Index: ktrack/drivers/ar6000/Makefile
+===================================================================
+--- ktrack.orig/drivers/ar6000/Makefile	2008-11-02 02:50:02.000000000 -0200
++++ ktrack/drivers/ar6000/Makefile	2008-11-02 04:29:20.000000000 -0200
+@@ -13,7 +13,7 @@
+ 
+ EXTRA_CFLAGS += -DKERNEL_2_6
+ 
+-obj-$(CONFIG_SDIO_AR6000_WLAN) += ar6000.o
++obj-$(CONFIG_AR6000_WLAN) += ar6000.o
+ 
+ ar6000-objs += htc/ar6k.o      		   \
+ 	       htc/ar6k_events.o 	   \

Copied: developers/werner/wlan-spi/patches-tracking/attic2/gta02-remove-sdio.patch (from rev 4733, developers/werner/wlan-spi/patches-tracking/gta02-remove-sdio.patch)
===================================================================
--- developers/werner/wlan-spi/patches-tracking/attic2/gta02-remove-sdio.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/attic2/gta02-remove-sdio.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,57 @@
+gta02-remove-sdio.patch
+
+After killing the Atheros SDIO stack, we shall no longer deny ourselves
+the pleasure of also getting rid of the glue that keeps it on the
+platform.
+
+Not-Yet-Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+Index: ktrack/arch/arm/mach-s3c2440/mach-gta02.c
+===================================================================
+--- ktrack.orig/arch/arm/mach-s3c2440/mach-gta02.c	2008-10-29 03:31:14.000000000 -0200
++++ ktrack/arch/arm/mach-s3c2440/mach-gta02.c	2008-10-29 03:33:37.000000000 -0200
+@@ -876,36 +876,6 @@
+ };
+ 
+ 
+-
+-static struct resource gta02_sdio_resources[] = {
+-	[0] = {
+-		.flags	= IORESOURCE_IRQ,
+-		.start	= IRQ_SDI,
+-		.end	= IRQ_SDI,
+-	},
+-	[1] = {
+-		.flags = IORESOURCE_MEM,
+-		.start = S3C2410_PA_SDI,
+-		.end   = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1,
+-	},
+-	[2] = {
+-		.flags = IORESOURCE_DMA,
+-		.start = 0, /* Channel 0 for SDI */
+-		.end = 0,
+-	},
+-};
+-
+-
+-static struct platform_device gta02_sdio_dev = {
+-        .name           = "s3c24xx-sdio",
+-        .id             = -1,
+-        .dev            = {
+-                                .coherent_dma_mask      = 0xffffffff,
+-        },
+-        .resource       = gta02_sdio_resources,
+-        .num_resources  = ARRAY_SIZE(gta02_sdio_resources),
+-};
+-
+ struct platform_device s3c24xx_pwm_device = {
+ 	.name 		= "s3c24xx_pwm",
+ 	.num_resources	= 0,
+@@ -1582,7 +1552,6 @@
+ 	&gta01_pm_gps_dev,
+ 	&gta01_pm_bt_dev,
+ 	&gta02_pm_gsm_dev,
+-	&gta02_sdio_dev,
+ 	&gta02_pm_usbhost_dev,
+ 	&s3c_device_spi_acc1, /* input 2 */
+ 	&s3c_device_spi_acc2, /* input 3 */

Copied: developers/werner/wlan-spi/patches-tracking/attic2/hif-linux-sdio.patch (from rev 4744, developers/werner/wlan-spi/patches-tracking/hif-linux-sdio.patch)
===================================================================
--- developers/werner/wlan-spi/patches-tracking/attic2/hif-linux-sdio.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/attic2/hif-linux-sdio.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,627 @@
+hif-linux-sdio.patch
+
+This is a replacement for Atheros' HIF layer that uses the Linux SDIO
+stack.
+
+Using GPLv2, like Atheros' code this is based on.
+
+Work in progress.
+
+Not-Yet-Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+Index: ktrack/drivers/ar6000/Makefile
+===================================================================
+--- ktrack.orig/drivers/ar6000/Makefile	2008-11-02 23:09:13.000000000 -0200
++++ ktrack/drivers/ar6000/Makefile	2008-11-02 23:09:15.000000000 -0200
+@@ -21,7 +21,7 @@
+                htc/htc_recv.o       	   \
+                htc/htc_services.o          \
+                htc/htc.o     		   \
+-               hif/hif.o     		   \
++               hif/hif2.o     		   \
+                bmi/bmi.o                   \
+                ar6000/ar6000_drv.o         \
+                ar6000/ar6000_raw_if.o	   \
+Index: ktrack/drivers/ar6000/hif/hif2.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ ktrack/drivers/ar6000/hif/hif2.c	2008-11-02 23:46:53.000000000 -0200
+@@ -0,0 +1,598 @@
++/*
++ * hif2.c - HIF layer re-implementation for the Linux SDIO stack
++ *
++ * Copyright (C) 2008 by OpenMoko, Inc.
++ * Written by Werner Almesberger <werner at openmoko.org>
++ * All Rights Reserved
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation;
++ *
++ * Based on:
++ *
++ * @abstract: HIF layer reference implementation for Atheros SDIO stack
++ * @notice: Copyright (c) 2004-2006 Atheros Communications Inc.
++ */
++
++
++#include <linux/kernel.h>
++#include <linux/kthread.h>
++#include <linux/list.h>
++#include <linux/wait.h>
++#include <linux/spinlock.h>
++#include <linux/sched.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/sdio_ids.h>
++#include <asm/gpio.h>
++
++#include "athdefs.h"
++#include "a_types.h"
++#include "hif.h"
++
++
++/*
++ * 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
++ */
++
++/*
++ * 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 MBOXES			4
++
++#define HIF_MBOX_BLOCK_SIZE	128
++#define	HIF_MBOX_BASE_ADDR	0x800
++#define	HIF_MBOX_WIDTH		0x800
++#define	HIF_MBOX_START_ADDR(mbox) \
++    (HIF_MBOX_BASE_ADDR+(mbox)*HIF_MBOX_WIDTH)
++
++
++struct hif_device {
++	void *htc_handle;
++	struct sdio_func *func;
++
++	/*
++	 * @@@ our sweet little bit of bogosity - the mechanism that lets us
++	 * use the SDIO stack from softirqs. This really wants to use skbs.
++	 */
++	struct list_head queue;
++	spinlock_t queue_lock;
++	struct task_struct *io_task;
++	wait_queue_head_t wait;
++};
++
++struct hif_request {
++	struct list_head list;
++	struct sdio_func *func;
++	int (*read)(struct sdio_func *func,
++	    void *dst, unsigned int addr, int count);
++	int (*write)(struct sdio_func *func,
++	    unsigned int addr, void *src, int count);
++	void *buf;
++	unsigned long addr;
++	int len;
++	A_STATUS (*completion)(void *context, A_STATUS status);
++	void *context;
++};
++
++
++static HTC_CALLBACKS htcCallbacks;
++
++
++/* ----- Request processing ------------------------------------------------ */
++
++
++static A_STATUS process_request(struct hif_request *req)
++{
++	int ret;
++	A_STATUS status;
++
++	dev_dbg(&req->func->dev, "process_request(req %p)\n", req);
++	sdio_claim_host(req->func);
++	if (req->read)
++		ret = req->read(req->func, req->buf, req->addr, req->len);
++	else
++		ret = req->write(req->func, req->addr, req->buf, req->len);
++	sdio_release_host(req->func);
++	status = ret ? A_ERROR : A_OK;
++	if (req->completion)
++		req->completion(req->context, status);
++	kfree(req);
++	return status;
++}
++
++
++static void enqueue_request(struct hif_device *hif, struct hif_request *req)
++{
++	unsigned long flags;
++
++	dev_dbg(&req->func->dev, "enqueue_request(req %p)\n", req);
++	spin_lock_irqsave(&hif->queue_lock, flags);
++	list_add_tail(&req->list, &hif->queue);
++	spin_unlock_irqrestore(&hif->queue_lock, flags);
++	wake_up(&hif->wait);
++}
++
++
++static struct hif_request *dequeue_request(struct hif_device *hif)
++{
++	struct hif_request *req;
++	unsigned long flags;
++
++	spin_lock_irqsave(&hif->queue_lock, flags);
++	if (list_empty(&hif->queue))
++		req = NULL;
++	else {
++		req = list_first_entry(&hif->queue,
++		    struct hif_request, list);
++		list_del(&req->list);
++	}
++	spin_unlock_irqrestore(&hif->queue_lock, flags);
++	return req;
++}
++
++
++static void wait_queue_empty(struct hif_device *hif)
++{
++	unsigned long flags;
++	int empty;
++
++	while (1) {
++		spin_lock_irqsave(&hif->queue_lock, flags);
++		empty = list_empty(&hif->queue);
++		spin_unlock_irqrestore(&hif->queue_lock, flags);
++		if (empty)
++			break;
++		else
++			yield();
++	}
++}
++
++
++static int io(void *data)
++{
++	struct hif_device *hif = data;
++	struct sched_param param = { .sched_priority = 2 };
++		/* one priority level slower than ksdioirqd (which is at 1) */
++	DEFINE_WAIT(wait);
++	struct hif_request *req;
++
++	sched_setscheduler(current, SCHED_FIFO, &param);
++
++	while (1) {
++		while (1) {
++			/*
++			 * Since we never use signals here, one might think
++			 * that this ought to be TASK_UNINTERRUPTIBLE. However,
++			 * such a task would increase the load average and,
++			 * worse, it would trigger the softlockup check.
++			 */
++			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();
++		}
++		finish_wait(&hif->wait, &wait);
++
++		(void) process_request(req);
++	}
++	return 0;
++}
++
++
++A_STATUS HIFReadWrite(HIF_DEVICE *hif, A_UINT32 address, A_UCHAR *buffer,
++    A_UINT32 length, A_UINT32 request, void *context)
++{
++	struct device *dev = HIFGetOSDevice(hif);
++	struct hif_request *req;
++
++	dev_dbg(dev, "HIFReadWrite(device %p, address 0x%x, buffer %p, "
++	    "length %d, request 0x%x, context %p)\n",
++	    hif, address, buffer, length, request, context);
++
++	BUG_ON(!(request & (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)));
++	BUG_ON(!(request & (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)));
++	BUG_ON(!(request & (HIF_READ | HIF_WRITE)));
++	BUG_ON(!(request & HIF_EXTENDED_IO));
++
++	if (address >= HIF_MBOX_START_ADDR(0) &&
++	    address < HIF_MBOX_START_ADDR(MBOXES+1)) {
++		BUG_ON(length > HIF_MBOX_WIDTH);
++		/* Adjust the address so that the last byte falls on the EOM
++		   address. */
++		address += HIF_MBOX_WIDTH-length;
++	}
++
++	req = kzalloc(sizeof(*req), GFP_ATOMIC);
++	if (!req) {
++		if (request & HIF_ASYNCHRONOUS)
++			htcCallbacks.rwCompletionHandler(context, A_ERROR);
++		return A_ERROR;
++	}
++
++	req->func = hif->func;
++	req->addr = address;
++	req->buf = buffer;
++	req->len = length;
++
++	if (request & HIF_READ) {
++		if (request & HIF_FIXED_ADDRESS)
++			req->read = sdio_readsb;
++		else
++			req->read = sdio_memcpy_fromio;
++	} else {
++		if (request & HIF_FIXED_ADDRESS)
++			req->write = sdio_writesb;
++		else
++			req->write = sdio_memcpy_toio;
++	}
++
++	if (!(request & HIF_ASYNCHRONOUS))
++		return process_request(req);
++
++	req->completion = htcCallbacks.rwCompletionHandler;
++	req->context = context;
++	enqueue_request(hif, req);
++
++	return A_OK;
++}
++
++
++/* ----- Interrupt handling ------------------------------------------------ */
++
++/*
++ * 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.
++ *
++ * Warning: this story changes if going SMP/SMT.
++ */
++
++static volatile int masked = 1;
++static volatile int pending;
++static volatile int in_interrupt;
++
++
++static void ar6000_do_irq(struct sdio_func *func)
++{
++	HIF_DEVICE *hif = sdio_get_drvdata(func);
++	struct device *dev = HIFGetOSDevice(hif);
++	A_STATUS status;
++
++	dev_dbg(dev, "ar6000_do_irq -> %p\n", htcCallbacks.dsrHandler);
++
++	status = htcCallbacks.dsrHandler(hif->htc_handle);
++	BUG_ON(status != A_OK);
++}
++
++
++static void sdio_ar6000_irq(struct sdio_func *func)
++{
++	HIF_DEVICE *hif = sdio_get_drvdata(func);
++	struct device *dev = HIFGetOSDevice(hif);
++
++	dev_dbg(dev, "sdio_ar6000_irq\n");
++
++	in_interrupt = 1;
++	if (masked) {
++		in_interrupt = 0;
++		pending++;
++		return;
++	}
++	/*
++	 * @@@ This is ugly. If we don't drop the lock, we'll deadlock when
++	 * the handler tries to do SDIO. So there are four choices:
++	 *
++	 * 1) Break the call chain by calling the callback from a workqueue.
++	 *    Ugh.
++	 * 2) Make process_request aware that we already have the lock.
++	 * 3) Drop the lock. Which is ugly but should be safe as long as we're
++	 *    making sure the device doesn't go away.
++	 * 4) Change the AR6k driver such that it only issues asynchronous
++	 *    quests when called from an interrupt.
++	 *
++	 * Solution 2) is probably the best for now. Will try it later.
++	 */
++	sdio_release_host(func);
++	ar6000_do_irq(func);
++	sdio_claim_host(func);
++	in_interrupt = 0;
++}
++
++
++void HIFAckInterrupt(HIF_DEVICE *hif)
++{
++	struct device *dev = HIFGetOSDevice(hif);
++
++	dev_dbg(dev, "HIFAckInterrupt\n");
++	/* do nothing */
++}
++
++
++void HIFUnMaskInterrupt(HIF_DEVICE *hif)
++{
++	struct device *dev = HIFGetOSDevice(hif);
++
++	dev_dbg(dev, "HIFUnMaskInterrupt\n");
++	do {
++		masked = 1;
++		if (pending) {
++			pending = 0;
++			ar6000_do_irq(hif->func);
++			/* We may take an interrupt before unmasking and thus
++			   get it pending. In this case, we just loop back. */
++		}
++		masked = 0;
++	}
++	while (pending);
++}
++
++
++void HIFMaskInterrupt(HIF_DEVICE *hif)
++{
++	struct device *dev = HIFGetOSDevice(hif);
++
++	dev_dbg(dev, "HIFMaskInterrupt\n");
++	/*
++	 * Since sdio_ar6000_irq can also be called from a process context, we
++	 * may conceivably end up racing with it. Thus, we need to wait until
++	 * we can be sure that no concurrent interrupt processing is going on
++	 * before we return.
++	 *
++	 * Note: this may be a bit on the paranoid side - the callers may
++	 * actually be nice enough to disable scheduling. Check later.
++	 */
++	masked = 1;
++	while (in_interrupt)
++		yield();
++}
++
++
++/* ----- HIF API glue functions -------------------------------------------- */
++
++
++struct device *HIFGetOSDevice(HIF_DEVICE *hif)
++{
++	return &hif->func->dev;
++}
++
++
++void HIFSetHandle(void *hif_handle, void *handle)
++{
++	HIF_DEVICE *hif = (HIF_DEVICE *) hif_handle;
++
++	hif->htc_handle = handle;
++}
++
++
++/* ----- Device configuration (HIF side) ----------------------------------- */
++
++
++A_STATUS HIFConfigureDevice(HIF_DEVICE *hif,
++    HIF_DEVICE_CONFIG_OPCODE opcode, void *config, A_UINT32 configLen)
++{
++	struct device *dev = HIFGetOSDevice(hif);
++	HIF_DEVICE_IRQ_PROCESSING_MODE *ipm_cfg = config;
++	A_UINT32 *mbs_cfg = config;
++	int i;
++
++	dev_dbg(dev, "HIFConfigureDevice\n");
++
++	switch (opcode) {
++	case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
++		for (i = 0; i != MBOXES; i++)
++			mbs_cfg[i] = HIF_MBOX_BLOCK_SIZE;
++		break;
++	case HIF_DEVICE_GET_MBOX_ADDR:
++		for (i = 0; i != MBOXES; i++)
++			mbs_cfg[i] = HIF_MBOX_START_ADDR(i);
++		break;
++	case HIF_DEVICE_GET_IRQ_PROC_MODE:
++		*ipm_cfg = HIF_DEVICE_IRQ_SYNC_ONLY;
++//		*ipm_cfg = HIF_DEVICE_IRQ_ASYNC_SYNC;
++		break;
++	default:
++		return A_ERROR;
++	}
++	return A_OK;
++}
++
++
++/* ----- Device probe and removal (Linux side) ----------------------------- */
++
++
++static int sdio_ar6000_probe(struct sdio_func *func,
++    const struct sdio_device_id *id)
++{
++	struct device *dev = &func->dev;
++	struct hif_device *hif;
++	int ret;
++
++	dev_dbg(dev, "sdio_ar6000_probe\n");
++	BUG_ON(!htcCallbacks.deviceInsertedHandler);
++
++	hif = kzalloc(sizeof(*hif), GFP_KERNEL);
++	if (!hif)
++		return -ENOMEM;
++
++	sdio_set_drvdata(func, hif);
++	sdio_claim_host(func);
++	sdio_enable_func(func);
++
++	hif->func = func;
++	INIT_LIST_HEAD(&hif->queue);
++	init_waitqueue_head(&hif->wait);
++	spin_lock_init(&hif->queue_lock);
++
++	ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
++	if (ret < 0) {
++		dev_err(dev, "sdio_set_block_size returns %d\n", ret);
++		goto out_enabled;
++	}
++	ret = sdio_claim_irq(func, sdio_ar6000_irq);
++	if (ret) {
++		dev_err(dev, "sdio_claim_irq returns %d\n", ret);
++		goto out_enabled;
++	}
++	/* Set SDIO_BUS_CD_DISABLE in SDIO_CCCR_IF ? */
++#if 0
++	sdio_f0_writeb(func, SDIO_CCCR_CAP_E4MI, SDIO_CCCR_CAPS, &ret);
++	if (ret) {
++		dev_err(dev, "sdio_f0_writeb(SDIO_CCCR_CAPS) returns %d\n",
++		    ret);
++		goto out_got_irq;
++	}
++#endif
++
++	sdio_release_host(func);
++
++	hif->io_task = kthread_run(io, hif, "ar6000_io");
++	if (IS_ERR(hif->io_task)) {
++		dev_err(dev, "kthread_run(ar6000_io): %d\n", ret);
++		goto out_func_ready;
++	}
++
++	ret = htcCallbacks.deviceInsertedHandler(hif);
++	if (ret == A_OK)
++		return 0;
++
++	dev_err(dev, "deviceInsertedHandler: %d\n", ret);
++
++	ret = kthread_stop(hif->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;
++	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
++	wait_queue_empty(hif);
++	ret = kthread_stop(hif->io_task);
++	if (ret)
++		dev_err(dev, "kthread_stop (ar6000_io): %d\n", ret);
++	sdio_claim_host(func);
++	sdio_release_irq(func);
++	sdio_set_drvdata(func, NULL);
++	sdio_disable_func(func);
++	sdio_release_host(func);
++	kfree(hif);
++}
++
++
++/* ----- Device registration/unregistration (called by HIF) ---------------- */
++
++
++#define ATHEROS_SDIO_DEVICE(id, offset) \
++    SDIO_DEVICE(SDIO_VENDOR_ID_ATHEROS, SDIO_DEVICE_ID_ATHEROS_##id | (offset))
++
++static const struct sdio_device_id sdio_ar6000_ids[] = {
++	{ ATHEROS_SDIO_DEVICE(AR6000, 0)	},
++	{ ATHEROS_SDIO_DEVICE(AR6000, 0x1)	},
++	{ ATHEROS_SDIO_DEVICE(AR6000, 0x8)	},
++	{ ATHEROS_SDIO_DEVICE(AR6000, 0x9)	},
++	{ ATHEROS_SDIO_DEVICE(AR6000, 0xa)	},
++	{ ATHEROS_SDIO_DEVICE(AR6000, 0xb)	},
++	{ /* end: all zeroes */			},
++};
++
++MODULE_DEVICE_TABLE(sdio, sdio_ar6000_ids);
++
++
++static struct sdio_driver sdio_ar6000_driver = {
++	.probe		= sdio_ar6000_probe,
++	.remove		= sdio_ar6000_remove,
++	.name		= "sdio_ar6000",
++	.id_table	= sdio_ar6000_ids,
++};
++
++
++int HIFInit(HTC_CALLBACKS *callbacks)
++{
++	int ret;
++
++	BUG_ON(!callbacks);
++
++	printk(KERN_DEBUG "HIFInit\n");
++	htcCallbacks = *callbacks;
++
++	ret = sdio_register_driver(&sdio_ar6000_driver);
++	if (ret) {
++		printk(KERN_ERR
++		    "sdio_register_driver(sdio_ar6000_driver): %d\n", ret);
++		return A_ERROR;
++	}
++
++	return 0;
++}
++
++
++void HIFShutDownDevice(HIF_DEVICE *hif)
++{
++	/* Beware, HTCShutDown calls us with hif == NULL ! */
++	sdio_unregister_driver(&sdio_ar6000_driver);
++}

Copied: developers/werner/wlan-spi/patches-tracking/attic2/sdio-add-atheros-ar6k.patch (from rev 4740, developers/werner/wlan-spi/patches-tracking/sdio-add-atheros-ar6k.patch)
===================================================================
--- developers/werner/wlan-spi/patches-tracking/attic2/sdio-add-atheros-ar6k.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/attic2/sdio-add-atheros-ar6k.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,12 @@
+Index: ktrack/include/linux/mmc/sdio_ids.h
+===================================================================
+--- ktrack.orig/include/linux/mmc/sdio_ids.h	2008-11-02 08:02:38.000000000 -0200
++++ ktrack/include/linux/mmc/sdio_ids.h	2008-11-02 08:02:55.000000000 -0200
+@@ -25,5 +25,7 @@
+ 
+ #define SDIO_VENDOR_ID_MARVELL			0x02df
+ #define SDIO_DEVICE_ID_MARVELL_LIBERTAS		0x9103
++#define SDIO_VENDOR_ID_ATHEROS			0x0271
++#define SDIO_DEVICE_ID_ATHEROS_AR6000		0x0100
+ 
+ #endif

Copied: developers/werner/wlan-spi/patches-tracking/attic2/series (from rev 4794, developers/werner/wlan-spi/patches-tracking/series)
===================================================================
--- developers/werner/wlan-spi/patches-tracking/attic2/series	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/attic2/series	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,31 @@
+#
+# This patch stack is for the Openmoko stable-tracking branch. Before applying
+# the patches, you need to remove the Atheros SDIO stack as follows:
+#
+# cd drivers
+# rm -rf ar6000
+# mv sdio/function/wlan/ar6000 .
+# rm -rf sdio ../include/linux/sdio
+#
+# Alternative procedure:
+#
+# rm -rf drivers/ar6000		# in case this operation is repeated
+# git mv drivers/sdio/function/wlan/ar6000 drivers/ar6000
+# git rm -r drivers/sdio include/linux/sdio
+# git commit -m "Remove Atheros SDIO stack."
+# rm -rf drivers/sdio
+#
+
+ar6k-without-sdio.patch
+gta02-remove-sdio.patch
+sdio-add-atheros-ar6k.patch
+hif-linux-sdio.patch
+
+gta02-mmc-mci.patch
+
+# dirty experimental stuff follows
+
+#hif-can-do-async.patch
+
+# still needs a bit more love ...
+#s3c-mmc-sdio-int.patch

Deleted: developers/werner/wlan-spi/patches-tracking/gta02-remove-sdio.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/gta02-remove-sdio.patch	2008-11-16 07:57:38 UTC (rev 4794)
+++ developers/werner/wlan-spi/patches-tracking/gta02-remove-sdio.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -1,57 +0,0 @@
-gta02-remove-sdio.patch
-
-After killing the Atheros SDIO stack, we shall no longer deny ourselves
-the pleasure of also getting rid of the glue that keeps it on the
-platform.
-
-Not-Yet-Signed-off-by: Werner Almesberger <werner at openmoko.org>
-
-Index: ktrack/arch/arm/mach-s3c2440/mach-gta02.c
-===================================================================
---- ktrack.orig/arch/arm/mach-s3c2440/mach-gta02.c	2008-10-29 03:31:14.000000000 -0200
-+++ ktrack/arch/arm/mach-s3c2440/mach-gta02.c	2008-10-29 03:33:37.000000000 -0200
-@@ -876,36 +876,6 @@
- };
- 
- 
--
--static struct resource gta02_sdio_resources[] = {
--	[0] = {
--		.flags	= IORESOURCE_IRQ,
--		.start	= IRQ_SDI,
--		.end	= IRQ_SDI,
--	},
--	[1] = {
--		.flags = IORESOURCE_MEM,
--		.start = S3C2410_PA_SDI,
--		.end   = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1,
--	},
--	[2] = {
--		.flags = IORESOURCE_DMA,
--		.start = 0, /* Channel 0 for SDI */
--		.end = 0,
--	},
--};
--
--
--static struct platform_device gta02_sdio_dev = {
--        .name           = "s3c24xx-sdio",
--        .id             = -1,
--        .dev            = {
--                                .coherent_dma_mask      = 0xffffffff,
--        },
--        .resource       = gta02_sdio_resources,
--        .num_resources  = ARRAY_SIZE(gta02_sdio_resources),
--};
--
- struct platform_device s3c24xx_pwm_device = {
- 	.name 		= "s3c24xx_pwm",
- 	.num_resources	= 0,
-@@ -1582,7 +1552,6 @@
- 	&gta01_pm_gps_dev,
- 	&gta01_pm_bt_dev,
- 	&gta02_pm_gsm_dev,
--	&gta02_sdio_dev,
- 	&gta02_pm_usbhost_dev,
- 	&s3c_device_spi_acc1, /* input 2 */
- 	&s3c_device_spi_acc2, /* input 3 */

Deleted: developers/werner/wlan-spi/patches-tracking/hif-linux-sdio.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/hif-linux-sdio.patch	2008-11-16 07:57:38 UTC (rev 4794)
+++ developers/werner/wlan-spi/patches-tracking/hif-linux-sdio.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -1,627 +0,0 @@
-hif-linux-sdio.patch
-
-This is a replacement for Atheros' HIF layer that uses the Linux SDIO
-stack.
-
-Using GPLv2, like Atheros' code this is based on.
-
-Work in progress.
-
-Not-Yet-Signed-off-by: Werner Almesberger <werner at openmoko.org>
-
-Index: ktrack/drivers/ar6000/Makefile
-===================================================================
---- ktrack.orig/drivers/ar6000/Makefile	2008-11-02 23:09:13.000000000 -0200
-+++ ktrack/drivers/ar6000/Makefile	2008-11-02 23:09:15.000000000 -0200
-@@ -21,7 +21,7 @@
-                htc/htc_recv.o       	   \
-                htc/htc_services.o          \
-                htc/htc.o     		   \
--               hif/hif.o     		   \
-+               hif/hif2.o     		   \
-                bmi/bmi.o                   \
-                ar6000/ar6000_drv.o         \
-                ar6000/ar6000_raw_if.o	   \
-Index: ktrack/drivers/ar6000/hif/hif2.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ ktrack/drivers/ar6000/hif/hif2.c	2008-11-02 23:46:53.000000000 -0200
-@@ -0,0 +1,598 @@
-+/*
-+ * hif2.c - HIF layer re-implementation for the Linux SDIO stack
-+ *
-+ * Copyright (C) 2008 by OpenMoko, Inc.
-+ * Written by Werner Almesberger <werner at openmoko.org>
-+ * All Rights Reserved
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Based on:
-+ *
-+ * @abstract: HIF layer reference implementation for Atheros SDIO stack
-+ * @notice: Copyright (c) 2004-2006 Atheros Communications Inc.
-+ */
-+
-+
-+#include <linux/kernel.h>
-+#include <linux/kthread.h>
-+#include <linux/list.h>
-+#include <linux/wait.h>
-+#include <linux/spinlock.h>
-+#include <linux/sched.h>
-+#include <linux/mmc/sdio_func.h>
-+#include <linux/mmc/sdio.h>
-+#include <linux/mmc/sdio_ids.h>
-+#include <asm/gpio.h>
-+
-+#include "athdefs.h"
-+#include "a_types.h"
-+#include "hif.h"
-+
-+
-+/*
-+ * 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
-+ */
-+
-+/*
-+ * 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 MBOXES			4
-+
-+#define HIF_MBOX_BLOCK_SIZE	128
-+#define	HIF_MBOX_BASE_ADDR	0x800
-+#define	HIF_MBOX_WIDTH		0x800
-+#define	HIF_MBOX_START_ADDR(mbox) \
-+    (HIF_MBOX_BASE_ADDR+(mbox)*HIF_MBOX_WIDTH)
-+
-+
-+struct hif_device {
-+	void *htc_handle;
-+	struct sdio_func *func;
-+
-+	/*
-+	 * @@@ our sweet little bit of bogosity - the mechanism that lets us
-+	 * use the SDIO stack from softirqs. This really wants to use skbs.
-+	 */
-+	struct list_head queue;
-+	spinlock_t queue_lock;
-+	struct task_struct *io_task;
-+	wait_queue_head_t wait;
-+};
-+
-+struct hif_request {
-+	struct list_head list;
-+	struct sdio_func *func;
-+	int (*read)(struct sdio_func *func,
-+	    void *dst, unsigned int addr, int count);
-+	int (*write)(struct sdio_func *func,
-+	    unsigned int addr, void *src, int count);
-+	void *buf;
-+	unsigned long addr;
-+	int len;
-+	A_STATUS (*completion)(void *context, A_STATUS status);
-+	void *context;
-+};
-+
-+
-+static HTC_CALLBACKS htcCallbacks;
-+
-+
-+/* ----- Request processing ------------------------------------------------ */
-+
-+
-+static A_STATUS process_request(struct hif_request *req)
-+{
-+	int ret;
-+	A_STATUS status;
-+
-+	dev_dbg(&req->func->dev, "process_request(req %p)\n", req);
-+	sdio_claim_host(req->func);
-+	if (req->read)
-+		ret = req->read(req->func, req->buf, req->addr, req->len);
-+	else
-+		ret = req->write(req->func, req->addr, req->buf, req->len);
-+	sdio_release_host(req->func);
-+	status = ret ? A_ERROR : A_OK;
-+	if (req->completion)
-+		req->completion(req->context, status);
-+	kfree(req);
-+	return status;
-+}
-+
-+
-+static void enqueue_request(struct hif_device *hif, struct hif_request *req)
-+{
-+	unsigned long flags;
-+
-+	dev_dbg(&req->func->dev, "enqueue_request(req %p)\n", req);
-+	spin_lock_irqsave(&hif->queue_lock, flags);
-+	list_add_tail(&req->list, &hif->queue);
-+	spin_unlock_irqrestore(&hif->queue_lock, flags);
-+	wake_up(&hif->wait);
-+}
-+
-+
-+static struct hif_request *dequeue_request(struct hif_device *hif)
-+{
-+	struct hif_request *req;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&hif->queue_lock, flags);
-+	if (list_empty(&hif->queue))
-+		req = NULL;
-+	else {
-+		req = list_first_entry(&hif->queue,
-+		    struct hif_request, list);
-+		list_del(&req->list);
-+	}
-+	spin_unlock_irqrestore(&hif->queue_lock, flags);
-+	return req;
-+}
-+
-+
-+static void wait_queue_empty(struct hif_device *hif)
-+{
-+	unsigned long flags;
-+	int empty;
-+
-+	while (1) {
-+		spin_lock_irqsave(&hif->queue_lock, flags);
-+		empty = list_empty(&hif->queue);
-+		spin_unlock_irqrestore(&hif->queue_lock, flags);
-+		if (empty)
-+			break;
-+		else
-+			yield();
-+	}
-+}
-+
-+
-+static int io(void *data)
-+{
-+	struct hif_device *hif = data;
-+	struct sched_param param = { .sched_priority = 2 };
-+		/* one priority level slower than ksdioirqd (which is at 1) */
-+	DEFINE_WAIT(wait);
-+	struct hif_request *req;
-+
-+	sched_setscheduler(current, SCHED_FIFO, &param);
-+
-+	while (1) {
-+		while (1) {
-+			/*
-+			 * Since we never use signals here, one might think
-+			 * that this ought to be TASK_UNINTERRUPTIBLE. However,
-+			 * such a task would increase the load average and,
-+			 * worse, it would trigger the softlockup check.
-+			 */
-+			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();
-+		}
-+		finish_wait(&hif->wait, &wait);
-+
-+		(void) process_request(req);
-+	}
-+	return 0;
-+}
-+
-+
-+A_STATUS HIFReadWrite(HIF_DEVICE *hif, A_UINT32 address, A_UCHAR *buffer,
-+    A_UINT32 length, A_UINT32 request, void *context)
-+{
-+	struct device *dev = HIFGetOSDevice(hif);
-+	struct hif_request *req;
-+
-+	dev_dbg(dev, "HIFReadWrite(device %p, address 0x%x, buffer %p, "
-+	    "length %d, request 0x%x, context %p)\n",
-+	    hif, address, buffer, length, request, context);
-+
-+	BUG_ON(!(request & (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)));
-+	BUG_ON(!(request & (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)));
-+	BUG_ON(!(request & (HIF_READ | HIF_WRITE)));
-+	BUG_ON(!(request & HIF_EXTENDED_IO));
-+
-+	if (address >= HIF_MBOX_START_ADDR(0) &&
-+	    address < HIF_MBOX_START_ADDR(MBOXES+1)) {
-+		BUG_ON(length > HIF_MBOX_WIDTH);
-+		/* Adjust the address so that the last byte falls on the EOM
-+		   address. */
-+		address += HIF_MBOX_WIDTH-length;
-+	}
-+
-+	req = kzalloc(sizeof(*req), GFP_ATOMIC);
-+	if (!req) {
-+		if (request & HIF_ASYNCHRONOUS)
-+			htcCallbacks.rwCompletionHandler(context, A_ERROR);
-+		return A_ERROR;
-+	}
-+
-+	req->func = hif->func;
-+	req->addr = address;
-+	req->buf = buffer;
-+	req->len = length;
-+
-+	if (request & HIF_READ) {
-+		if (request & HIF_FIXED_ADDRESS)
-+			req->read = sdio_readsb;
-+		else
-+			req->read = sdio_memcpy_fromio;
-+	} else {
-+		if (request & HIF_FIXED_ADDRESS)
-+			req->write = sdio_writesb;
-+		else
-+			req->write = sdio_memcpy_toio;
-+	}
-+
-+	if (!(request & HIF_ASYNCHRONOUS))
-+		return process_request(req);
-+
-+	req->completion = htcCallbacks.rwCompletionHandler;
-+	req->context = context;
-+	enqueue_request(hif, req);
-+
-+	return A_OK;
-+}
-+
-+
-+/* ----- Interrupt handling ------------------------------------------------ */
-+
-+/*
-+ * 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.
-+ *
-+ * Warning: this story changes if going SMP/SMT.
-+ */
-+
-+static volatile int masked = 1;
-+static volatile int pending;
-+static volatile int in_interrupt;
-+
-+
-+static void ar6000_do_irq(struct sdio_func *func)
-+{
-+	HIF_DEVICE *hif = sdio_get_drvdata(func);
-+	struct device *dev = HIFGetOSDevice(hif);
-+	A_STATUS status;
-+
-+	dev_dbg(dev, "ar6000_do_irq -> %p\n", htcCallbacks.dsrHandler);
-+
-+	status = htcCallbacks.dsrHandler(hif->htc_handle);
-+	BUG_ON(status != A_OK);
-+}
-+
-+
-+static void sdio_ar6000_irq(struct sdio_func *func)
-+{
-+	HIF_DEVICE *hif = sdio_get_drvdata(func);
-+	struct device *dev = HIFGetOSDevice(hif);
-+
-+	dev_dbg(dev, "sdio_ar6000_irq\n");
-+
-+	in_interrupt = 1;
-+	if (masked) {
-+		in_interrupt = 0;
-+		pending++;
-+		return;
-+	}
-+	/*
-+	 * @@@ This is ugly. If we don't drop the lock, we'll deadlock when
-+	 * the handler tries to do SDIO. So there are four choices:
-+	 *
-+	 * 1) Break the call chain by calling the callback from a workqueue.
-+	 *    Ugh.
-+	 * 2) Make process_request aware that we already have the lock.
-+	 * 3) Drop the lock. Which is ugly but should be safe as long as we're
-+	 *    making sure the device doesn't go away.
-+	 * 4) Change the AR6k driver such that it only issues asynchronous
-+	 *    quests when called from an interrupt.
-+	 *
-+	 * Solution 2) is probably the best for now. Will try it later.
-+	 */
-+	sdio_release_host(func);
-+	ar6000_do_irq(func);
-+	sdio_claim_host(func);
-+	in_interrupt = 0;
-+}
-+
-+
-+void HIFAckInterrupt(HIF_DEVICE *hif)
-+{
-+	struct device *dev = HIFGetOSDevice(hif);
-+
-+	dev_dbg(dev, "HIFAckInterrupt\n");
-+	/* do nothing */
-+}
-+
-+
-+void HIFUnMaskInterrupt(HIF_DEVICE *hif)
-+{
-+	struct device *dev = HIFGetOSDevice(hif);
-+
-+	dev_dbg(dev, "HIFUnMaskInterrupt\n");
-+	do {
-+		masked = 1;
-+		if (pending) {
-+			pending = 0;
-+			ar6000_do_irq(hif->func);
-+			/* We may take an interrupt before unmasking and thus
-+			   get it pending. In this case, we just loop back. */
-+		}
-+		masked = 0;
-+	}
-+	while (pending);
-+}
-+
-+
-+void HIFMaskInterrupt(HIF_DEVICE *hif)
-+{
-+	struct device *dev = HIFGetOSDevice(hif);
-+
-+	dev_dbg(dev, "HIFMaskInterrupt\n");
-+	/*
-+	 * Since sdio_ar6000_irq can also be called from a process context, we
-+	 * may conceivably end up racing with it. Thus, we need to wait until
-+	 * we can be sure that no concurrent interrupt processing is going on
-+	 * before we return.
-+	 *
-+	 * Note: this may be a bit on the paranoid side - the callers may
-+	 * actually be nice enough to disable scheduling. Check later.
-+	 */
-+	masked = 1;
-+	while (in_interrupt)
-+		yield();
-+}
-+
-+
-+/* ----- HIF API glue functions -------------------------------------------- */
-+
-+
-+struct device *HIFGetOSDevice(HIF_DEVICE *hif)
-+{
-+	return &hif->func->dev;
-+}
-+
-+
-+void HIFSetHandle(void *hif_handle, void *handle)
-+{
-+	HIF_DEVICE *hif = (HIF_DEVICE *) hif_handle;
-+
-+	hif->htc_handle = handle;
-+}
-+
-+
-+/* ----- Device configuration (HIF side) ----------------------------------- */
-+
-+
-+A_STATUS HIFConfigureDevice(HIF_DEVICE *hif,
-+    HIF_DEVICE_CONFIG_OPCODE opcode, void *config, A_UINT32 configLen)
-+{
-+	struct device *dev = HIFGetOSDevice(hif);
-+	HIF_DEVICE_IRQ_PROCESSING_MODE *ipm_cfg = config;
-+	A_UINT32 *mbs_cfg = config;
-+	int i;
-+
-+	dev_dbg(dev, "HIFConfigureDevice\n");
-+
-+	switch (opcode) {
-+	case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
-+		for (i = 0; i != MBOXES; i++)
-+			mbs_cfg[i] = HIF_MBOX_BLOCK_SIZE;
-+		break;
-+	case HIF_DEVICE_GET_MBOX_ADDR:
-+		for (i = 0; i != MBOXES; i++)
-+			mbs_cfg[i] = HIF_MBOX_START_ADDR(i);
-+		break;
-+	case HIF_DEVICE_GET_IRQ_PROC_MODE:
-+		*ipm_cfg = HIF_DEVICE_IRQ_SYNC_ONLY;
-+//		*ipm_cfg = HIF_DEVICE_IRQ_ASYNC_SYNC;
-+		break;
-+	default:
-+		return A_ERROR;
-+	}
-+	return A_OK;
-+}
-+
-+
-+/* ----- Device probe and removal (Linux side) ----------------------------- */
-+
-+
-+static int sdio_ar6000_probe(struct sdio_func *func,
-+    const struct sdio_device_id *id)
-+{
-+	struct device *dev = &func->dev;
-+	struct hif_device *hif;
-+	int ret;
-+
-+	dev_dbg(dev, "sdio_ar6000_probe\n");
-+	BUG_ON(!htcCallbacks.deviceInsertedHandler);
-+
-+	hif = kzalloc(sizeof(*hif), GFP_KERNEL);
-+	if (!hif)
-+		return -ENOMEM;
-+
-+	sdio_set_drvdata(func, hif);
-+	sdio_claim_host(func);
-+	sdio_enable_func(func);
-+
-+	hif->func = func;
-+	INIT_LIST_HEAD(&hif->queue);
-+	init_waitqueue_head(&hif->wait);
-+	spin_lock_init(&hif->queue_lock);
-+
-+	ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
-+	if (ret < 0) {
-+		dev_err(dev, "sdio_set_block_size returns %d\n", ret);
-+		goto out_enabled;
-+	}
-+	ret = sdio_claim_irq(func, sdio_ar6000_irq);
-+	if (ret) {
-+		dev_err(dev, "sdio_claim_irq returns %d\n", ret);
-+		goto out_enabled;
-+	}
-+	/* Set SDIO_BUS_CD_DISABLE in SDIO_CCCR_IF ? */
-+#if 0
-+	sdio_f0_writeb(func, SDIO_CCCR_CAP_E4MI, SDIO_CCCR_CAPS, &ret);
-+	if (ret) {
-+		dev_err(dev, "sdio_f0_writeb(SDIO_CCCR_CAPS) returns %d\n",
-+		    ret);
-+		goto out_got_irq;
-+	}
-+#endif
-+
-+	sdio_release_host(func);
-+
-+	hif->io_task = kthread_run(io, hif, "ar6000_io");
-+	if (IS_ERR(hif->io_task)) {
-+		dev_err(dev, "kthread_run(ar6000_io): %d\n", ret);
-+		goto out_func_ready;
-+	}
-+
-+	ret = htcCallbacks.deviceInsertedHandler(hif);
-+	if (ret == A_OK)
-+		return 0;
-+
-+	dev_err(dev, "deviceInsertedHandler: %d\n", ret);
-+
-+	ret = kthread_stop(hif->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;
-+	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
-+	wait_queue_empty(hif);
-+	ret = kthread_stop(hif->io_task);
-+	if (ret)
-+		dev_err(dev, "kthread_stop (ar6000_io): %d\n", ret);
-+	sdio_claim_host(func);
-+	sdio_release_irq(func);
-+	sdio_set_drvdata(func, NULL);
-+	sdio_disable_func(func);
-+	sdio_release_host(func);
-+	kfree(hif);
-+}
-+
-+
-+/* ----- Device registration/unregistration (called by HIF) ---------------- */
-+
-+
-+#define ATHEROS_SDIO_DEVICE(id, offset) \
-+    SDIO_DEVICE(SDIO_VENDOR_ID_ATHEROS, SDIO_DEVICE_ID_ATHEROS_##id | (offset))
-+
-+static const struct sdio_device_id sdio_ar6000_ids[] = {
-+	{ ATHEROS_SDIO_DEVICE(AR6000, 0)	},
-+	{ ATHEROS_SDIO_DEVICE(AR6000, 0x1)	},
-+	{ ATHEROS_SDIO_DEVICE(AR6000, 0x8)	},
-+	{ ATHEROS_SDIO_DEVICE(AR6000, 0x9)	},
-+	{ ATHEROS_SDIO_DEVICE(AR6000, 0xa)	},
-+	{ ATHEROS_SDIO_DEVICE(AR6000, 0xb)	},
-+	{ /* end: all zeroes */			},
-+};
-+
-+MODULE_DEVICE_TABLE(sdio, sdio_ar6000_ids);
-+
-+
-+static struct sdio_driver sdio_ar6000_driver = {
-+	.probe		= sdio_ar6000_probe,
-+	.remove		= sdio_ar6000_remove,
-+	.name		= "sdio_ar6000",
-+	.id_table	= sdio_ar6000_ids,
-+};
-+
-+
-+int HIFInit(HTC_CALLBACKS *callbacks)
-+{
-+	int ret;
-+
-+	BUG_ON(!callbacks);
-+
-+	printk(KERN_DEBUG "HIFInit\n");
-+	htcCallbacks = *callbacks;
-+
-+	ret = sdio_register_driver(&sdio_ar6000_driver);
-+	if (ret) {
-+		printk(KERN_ERR
-+		    "sdio_register_driver(sdio_ar6000_driver): %d\n", ret);
-+		return A_ERROR;
-+	}
-+
-+	return 0;
-+}
-+
-+
-+void HIFShutDownDevice(HIF_DEVICE *hif)
-+{
-+	/* Beware, HTCShutDown calls us with hif == NULL ! */
-+	sdio_unregister_driver(&sdio_ar6000_driver);
-+}

Added: developers/werner/wlan-spi/patches-tracking/nand/hack-disable-ecc.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/nand/hack-disable-ecc.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/nand/hack-disable-ecc.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,32 @@
+Index: ktrack/drivers/mtd/nand/nand_base.c
+===================================================================
+--- ktrack.orig/drivers/mtd/nand/nand_base.c	2008-10-29 00:57:08.000000000 -0200
++++ ktrack/drivers/mtd/nand/nand_base.c	2008-10-29 03:17:39.000000000 -0200
+@@ -775,6 +775,7 @@
+ 	uint32_t *eccpos = chip->ecc.layout->eccpos;
+ 
+ 	chip->ecc.read_page_raw(mtd, chip, buf);
++	return 0;
+ 
+ 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+ 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+@@ -830,6 +831,7 @@
+ 
+ 	p = bufpoi + data_col_addr;
+ 	chip->read_buf(mtd, p, datafrag_len);
++	return 0;
+ 
+ 	/* Calculate  ECC */
+ 	for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
+Index: ktrack/drivers/mtd/nand/nand_ecc.c
+===================================================================
+--- ktrack.orig/drivers/mtd/nand/nand_ecc.c	2008-10-29 00:57:08.000000000 -0200
++++ ktrack/drivers/mtd/nand/nand_ecc.c	2008-10-29 03:17:56.000000000 -0200
+@@ -434,6 +434,7 @@
+ 	const uint32_t eccsize_mult =
+ 			(((struct nand_chip *)mtd->priv)->ecc.size) >> 8;
+ 
++	return 0;
+ 	/*
+ 	 * b0 to b2 indicate which bit is faulty (if any)
+ 	 * we might need the xor result  more than once,

Added: developers/werner/wlan-spi/patches-tracking/nand/reverse-ecc-fix.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/nand/reverse-ecc-fix.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/nand/reverse-ecc-fix.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,17 @@
+Index: ktrack/drivers/mtd/nand/s3c2410.c
+===================================================================
+--- ktrack.orig/drivers/mtd/nand/s3c2410.c	2008-11-03 12:55:06.000000000 -0200
++++ ktrack/drivers/mtd/nand/s3c2410.c	2008-11-03 12:55:11.000000000 -0200
+@@ -530,12 +530,7 @@
+ static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+ {
+ 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+-	u8 *ptr = buf + (len & ~3);
+-	int i;
+-
+ 	readsl(info->regs + S3C2440_NFDATA, buf, len / 4);
+-	for (i = 0; i != (len & 3); i++)
+-		ptr[i] = readb(info->regs + S3C2440_NFDATA);
+ }
+ 
+ static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)

Added: developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-handle-bytes.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-handle-bytes.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-handle-bytes.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,43 @@
+s3c2440-nand-handle-bytes.patch
+
+With the introduction of optimized OOB reads in nand_read_subpage,
+the length of the data requested may not be a multiple of four bytes.
+
+This caused a partial read on the 2440, leading to false ECC errors
+and, worse, attempts to "correct" them.
+
+This patch adds reading/writing of trailing bytes to
+s3c2440_nand_read_buf and (untested) s3c2410_nand_write_buf.
+
+Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+---
+
+Index: ktrack/drivers/mtd/nand/s3c2410.c
+===================================================================
+--- ktrack.orig/drivers/mtd/nand/s3c2410.c	2008-11-03 14:06:00.000000000 -0200
++++ ktrack/drivers/mtd/nand/s3c2410.c	2008-11-03 14:06:20.000000000 -0200
+@@ -530,7 +530,11 @@
+ static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+ {
+ 	struct nand_chip *chip = mtd->priv;
++	int i;
++
+ 	readsl(chip->IO_ADDR_R, buf, len >> 2);
++	for (i = len & ~3; unlikely(i != len); i++)
++		buf[i] = readb(chip->IO_ADDR_R);
+ }
+ 
+ static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+@@ -542,7 +546,11 @@
+ static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+ {
+ 	struct nand_chip *chip = mtd->priv;
++	int i;
++
+ 	writesl(chip->IO_ADDR_W, buf, len >> 2);
++	for (i = len & ~3; unlikely(i != len); i++)
++		writeb(buf[i], chip->IO_ADDR_W);
+ }
+ 
+ /* cpufreq driver support */

Added: developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-shift-not-div.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-shift-not-div.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-shift-not-div.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,33 @@
+s3c2440-nand-shift-not-div.patch
+
+The divisions of the signed access lengths caused GCC to emit
+unnecessary code for handling negative values.
+
+Changing them to shifts saves 24 bytes.
+
+Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+---
+
+Index: ktrack/drivers/mtd/nand/s3c2410.c
+===================================================================
+--- ktrack.orig/drivers/mtd/nand/s3c2410.c	2008-11-03 12:55:53.000000000 -0200
++++ ktrack/drivers/mtd/nand/s3c2410.c	2008-11-03 12:58:18.000000000 -0200
+@@ -530,7 +530,7 @@
+ static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+ {
+ 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+-	readsl(info->regs + S3C2440_NFDATA, buf, len / 4);
++	readsl(info->regs + S3C2440_NFDATA, buf, len >> 2);
+ }
+ 
+ static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+@@ -542,7 +542,7 @@
+ static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+ {
+ 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+-	writesl(info->regs + S3C2440_NFDATA, buf, len / 4);
++	writesl(info->regs + S3C2440_NFDATA, buf, len >> 2);
+ }
+ 
+ /* cpufreq driver support */

Added: developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-use-iomem.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-use-iomem.patch	                        (rev 0)
+++ developers/werner/wlan-spi/patches-tracking/nand/s3c2440-nand-use-iomem.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -0,0 +1,35 @@
+s3c2440-nand-use-iomem.patch
+
+Using chip->IO_ADDR_R/IO_ADDR_W, which is __iomem, prevents the
+compiler from needlessly reloading constant data.
+
+Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+---
+
+Index: ktrack/drivers/mtd/nand/s3c2410.c
+===================================================================
+--- ktrack.orig/drivers/mtd/nand/s3c2410.c	2008-11-03 14:05:19.000000000 -0200
++++ ktrack/drivers/mtd/nand/s3c2410.c	2008-11-03 14:06:00.000000000 -0200
+@@ -529,8 +529,8 @@
+ 
+ static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+ {
+-	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+-	readsl(info->regs + S3C2440_NFDATA, buf, len >> 2);
++	struct nand_chip *chip = mtd->priv;
++	readsl(chip->IO_ADDR_R, buf, len >> 2);
+ }
+ 
+ static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+@@ -541,8 +541,8 @@
+ 
+ static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+ {
+-	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+-	writesl(info->regs + S3C2440_NFDATA, buf, len >> 2);
++	struct nand_chip *chip = mtd->priv;
++	writesl(chip->IO_ADDR_W, buf, len >> 2);
+ }
+ 
+ /* cpufreq driver support */

Deleted: developers/werner/wlan-spi/patches-tracking/sdio-add-atheros-ar6k.patch
===================================================================
--- developers/werner/wlan-spi/patches-tracking/sdio-add-atheros-ar6k.patch	2008-11-16 07:57:38 UTC (rev 4794)
+++ developers/werner/wlan-spi/patches-tracking/sdio-add-atheros-ar6k.patch	2008-11-17 08:46:24 UTC (rev 4795)
@@ -1,12 +0,0 @@
-Index: ktrack/include/linux/mmc/sdio_ids.h
-===================================================================
---- ktrack.orig/include/linux/mmc/sdio_ids.h	2008-11-02 08:02:38.000000000 -0200
-+++ ktrack/include/linux/mmc/sdio_ids.h	2008-11-02 08:02:55.000000000 -0200
-@@ -25,5 +25,7 @@
- 
- #define SDIO_VENDOR_ID_MARVELL			0x02df
- #define SDIO_DEVICE_ID_MARVELL_LIBERTAS		0x9103
-+#define SDIO_VENDOR_ID_ATHEROS			0x0271
-+#define SDIO_DEVICE_ID_ATHEROS_AR6000		0x0100
- 
- #endif

Deleted: developers/werner/wlan-spi/patches-tracking/series
===================================================================
--- developers/werner/wlan-spi/patches-tracking/series	2008-11-16 07:57:38 UTC (rev 4794)
+++ developers/werner/wlan-spi/patches-tracking/series	2008-11-17 08:46:24 UTC (rev 4795)
@@ -1,31 +0,0 @@
-#
-# This patch stack is for the Openmoko stable-tracking branch. Before applying
-# the patches, you need to remove the Atheros SDIO stack as follows:
-#
-# cd drivers
-# rm -rf ar6000
-# mv sdio/function/wlan/ar6000 .
-# rm -rf sdio ../include/linux/sdio
-#
-# Alternative procedure:
-#
-# rm -rf drivers/ar6000		# in case this operation is repeated
-# git mv drivers/sdio/function/wlan/ar6000 drivers/ar6000
-# git rm -r drivers/sdio include/linux/sdio
-# git commit -m "Remove Atheros SDIO stack."
-# rm -rf drivers/sdio
-#
-
-ar6k-without-sdio.patch
-gta02-remove-sdio.patch
-sdio-add-atheros-ar6k.patch
-hif-linux-sdio.patch
-
-gta02-mmc-mci.patch
-
-# dirty experimental stuff follows
-
-#hif-can-do-async.patch
-
-# still needs a bit more love ...
-#s3c-mmc-sdio-int.patch




More information about the commitlog mailing list