r4626 - in developers/werner/wlan-spi: . patches
werner at docs.openmoko.org
werner at docs.openmoko.org
Thu Sep 4 08:56:09 CEST 2008
Author: werner
Date: 2008-09-04 08:56:08 +0200 (Thu, 04 Sep 2008)
New Revision: 4626
Added:
developers/werner/wlan-spi/patches/
developers/werner/wlan-spi/patches/ar6k-without-sdio.patch
developers/werner/wlan-spi/patches/config-ar6k-mmc-spi-bitbang.patch
developers/werner/wlan-spi/patches/gta02-mmc-spi-bitbang.patch
developers/werner/wlan-spi/patches/gta02-remove-sdio.patch
developers/werner/wlan-spi/patches/sdio-f0-unrestrict.patch
developers/werner/wlan-spi/patches/series
developers/werner/wlan-spi/patches/wlan-spi-hif.patch
Log:
WLAN-SPI driver sneak preview. There are still several dirty spots and
it only works with:
WLAN -> SDIO -> MMC-SPI -> S3C SPI-GPIO (bitbang)
Future options include:
WLAN -> SDIO -> S3C SDI
WLAN -> SDIO -> MMC-SPI -> S3C SPI (hardware-accelerated)
WLAN -> SPI -> S3C SPI
Added: developers/werner/wlan-spi/patches/ar6k-without-sdio.patch
===================================================================
--- developers/werner/wlan-spi/patches/ar6k-without-sdio.patch (rev 0)
+++ developers/werner/wlan-spi/patches/ar6k-without-sdio.patch 2008-09-04 06:56:08 UTC (rev 4626)
@@ -0,0 +1,64 @@
+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: korig/arch/arm/Kconfig
+===================================================================
+--- korig.orig/arch/arm/Kconfig 2008-09-04 02:18:24.000000000 -0300
++++ korig/arch/arm/Kconfig 2008-09-04 02:18:43.000000000 -0300
+@@ -1071,7 +1071,7 @@
+
+ source "drivers/usb/Kconfig"
+
+-source "drivers/sdio/Kconfig"
++source "drivers/ar6000/Kconfig"
+
+ source "drivers/mmc/Kconfig"
+
+Index: korig/drivers/Makefile
+===================================================================
+--- korig.orig/drivers/Makefile 2008-09-04 02:19:01.000000000 -0300
++++ korig/drivers/Makefile 2008-09-04 02:19:22.000000000 -0300
+@@ -77,7 +77,7 @@
+ obj-$(CONFIG_CPU_FREQ) += cpufreq/
+ obj-$(CONFIG_CPU_IDLE) += cpuidle/
+ obj-$(CONFIG_MMC) += mmc/
+-obj-$(CONFIG_SDIO) += sdio/
++obj-$(CONFIG_AR6000_WLAN) += ar6000/
+ obj-$(CONFIG_NEW_LEDS) += leds/
+ obj-$(CONFIG_INFINIBAND) += infiniband/
+ obj-$(CONFIG_SGI_SN) += sn/
+Index: korig/drivers/ar6000/Kconfig
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ korig/drivers/ar6000/Kconfig 2008-09-04 02:17:43.000000000 -0300
+@@ -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: korig/drivers/ar6000/Makefile
+===================================================================
+--- korig.orig/drivers/ar6000/Makefile 2008-09-04 02:15:43.000000000 -0300
++++ korig/drivers/ar6000/Makefile 2008-09-04 02:15:49.000000000 -0300
+@@ -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 \
Added: developers/werner/wlan-spi/patches/config-ar6k-mmc-spi-bitbang.patch
===================================================================
--- developers/werner/wlan-spi/patches/config-ar6k-mmc-spi-bitbang.patch (rev 0)
+++ developers/werner/wlan-spi/patches/config-ar6k-mmc-spi-bitbang.patch 2008-09-04 06:56:08 UTC (rev 4626)
@@ -0,0 +1,133 @@
+config-ar6k-mmc-spi-bitbang.patch
+
+Convenience patch to switch the GTA02 defconfig to use MMC-SPI for
+the AR6000 driver.
+
+Index: korig/defconfig-gta02
+===================================================================
+--- korig.orig/defconfig-gta02 2008-09-04 03:35:43.000000000 -0300
++++ korig/defconfig-gta02 2008-09-04 03:35:50.000000000 -0300
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+ # Linux kernel version: 2.6.24
+-# Mon Feb 25 07:03:56 2008
++# Thu Sep 4 03:29:51 2008
+ #
+ CONFIG_ARM=y
+ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+@@ -207,6 +207,7 @@
+ CONFIG_MACH_HXD8=y
+ CONFIG_MACH_NEO1973_GTA02=y
+ # CONFIG_NEO1973_GTA02_2440 is not set
++CONFIG_AR6K_SPI_S3C24XX_GPIO=y
+ CONFIG_CPU_S3C2442=y
+
+ #
+@@ -710,13 +711,6 @@
+ #
+ # CONFIG_MTD_UBI is not set
+ # CONFIG_PARPORT is not set
+-CONFIG_PNP=y
+-CONFIG_PNP_DEBUG=y
+-
+-#
+-# Protocols
+-#
+-# CONFIG_PNPACPI is not set
+ CONFIG_BLK_DEV=y
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+ CONFIG_BLK_DEV_LOOP=m
+@@ -784,7 +778,6 @@
+ # CONFIG_EQUALIZER is not set
+ CONFIG_TUN=m
+ # CONFIG_VETH is not set
+-# CONFIG_NET_SB1000 is not set
+ # CONFIG_PHYLIB is not set
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=y
+@@ -1136,6 +1129,7 @@
+ CONFIG_SND=m
+ CONFIG_SND_TIMER=m
+ CONFIG_SND_PCM=m
++CONFIG_SND_RAWMIDI=m
+ # CONFIG_SND_SEQUENCER is not set
+ CONFIG_SND_OSSEMUL=y
+ CONFIG_SND_MIXER_OSS=m
+@@ -1176,6 +1170,7 @@
+ CONFIG_SND_S3C24XX_SOC=m
+ CONFIG_SND_S3C24XX_SOC_I2S=m
+ CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753=m
++# CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753_DEBUG is not set
+ CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753=m
+
+ #
+@@ -1380,19 +1375,13 @@
+ # CONFIG_USB_GADGET_DUALSPEED is not set
+ # CONFIG_USB_ZERO is not set
+ CONFIG_USB_ETH=m
+-CONFIG_USB_ETH_RNDIS=m
++CONFIG_USB_ETH_RNDIS=y
+ CONFIG_USB_GADGETFS=m
+ CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
+ CONFIG_USB_G_SERIAL=m
+ CONFIG_USB_MIDI_GADGET=m
+-
+-#
+-# SDIO support
+-#
+-CONFIG_SDIO=y
+-CONFIG_SDIO_S3C24XX=y
+-CONFIG_SDIO_S3C24XX_DMA=y
+-CONFIG_SDIO_AR6000_WLAN=y
++CONFIG_AR6000_WLAN=y
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+ CONFIG_MMC_UNSAFE_RESUME=y
+@@ -1407,7 +1396,7 @@
+ #
+ # MMC/SD Host Controller Drivers
+ #
+-# CONFIG_MMC_SPI is not set
++CONFIG_MMC_SPI=y
+ CONFIG_MMC_S3C=y
+ CONFIG_NEW_LEDS=y
+ CONFIG_LEDS_CLASS=y
+@@ -1510,6 +1499,7 @@
+ CONFIG_JOLIET=y
+ # CONFIG_ZISOFS is not set
+ CONFIG_UDF_FS=m
++CONFIG_UDF_NLS=y
+
+ #
+ # DOS/FAT/NT Filesystems
+@@ -1542,16 +1532,6 @@
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
+-CONFIG_YAFFS_FS=y
+-CONFIG_YAFFS_YAFFS1=y
+-CONFIG_YAFFS_9BYTE_TAGS=y
+-CONFIG_YAFFS_YAFFS2=y
+-CONFIG_YAFFS_AUTO_YAFFS2=y
+-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+-CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+ CONFIG_JFFS2_FS=y
+ CONFIG_JFFS2_FS_DEBUG=0
+ CONFIG_JFFS2_FS_WRITEBUFFER=y
+@@ -1751,9 +1731,9 @@
+ CONFIG_BITREVERSE=y
+ CONFIG_CRC_CCITT=m
+ CONFIG_CRC16=m
+-# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC_ITU_T=y
+ CONFIG_CRC32=y
+-# CONFIG_CRC7 is not set
++CONFIG_CRC7=y
+ CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=y
+ CONFIG_ZLIB_DEFLATE=y
Added: developers/werner/wlan-spi/patches/gta02-mmc-spi-bitbang.patch
===================================================================
--- developers/werner/wlan-spi/patches/gta02-mmc-spi-bitbang.patch (rev 0)
+++ developers/werner/wlan-spi/patches/gta02-mmc-spi-bitbang.patch 2008-09-04 06:56:08 UTC (rev 4626)
@@ -0,0 +1,274 @@
+gta02-mmc-spio-bitbang.patch
+
+This patch adds the platform definitions for using the AR6000 driver
+with MMC-SPI and the S3C SPI GPIO (bit-banging) driver.
+
+This configuration should work with all GTA02 models. No rework
+required.
+
+Not-Yet-Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+Index: korig/arch/arm/mach-s3c2440/Kconfig
+===================================================================
+--- korig.orig/arch/arm/mach-s3c2440/Kconfig 2008-09-04 03:30:55.000000000 -0300
++++ korig/arch/arm/mach-s3c2440/Kconfig 2008-09-04 03:32:29.000000000 -0300
+@@ -98,6 +98,20 @@
+ Say Y here if you are using an early hardware revision
+ of the FIC/Openmoko Neo1973 GTA02 GSM Phone.
+
++# @@@ Not a great place for this, but still better than dragging platform
++# details into driver land.
++
++choice
++ prompt "AR6K interface"
++ default AR6K_SPI_S3C24XX_GPIO
++ depends on MACH_NEO1973_GTA02 && AR6000_WLAN
++
++ config AR6K_SPI_S3C24XX_GPIO
++ bool "GPIO bit-banging SPI"
++ select MMC_SPI
++ select SPI_S3C24XX_GPIO
++endchoice
++
+ endmenu
+
+ #source "arch/arm/mach-s3c2440/camera/Kconfig"
+Index: korig/arch/arm/mach-s3c2440/mach-gta02.c
+===================================================================
+--- korig.orig/arch/arm/mach-s3c2440/mach-gta02.c 2008-09-04 03:30:55.000000000 -0300
++++ korig/arch/arm/mach-s3c2440/mach-gta02.c 2008-09-04 03:31:20.000000000 -0300
+@@ -37,6 +37,7 @@
+ #include <linux/spi/spi.h>
+ #include <linux/spi/glamo.h>
+ #include <linux/spi/spi_bitbang.h>
++#include <linux/spi/mmc_spi.h>
+ #include <linux/mmc/host.h>
+
+ #include <linux/mtd/mtd.h>
+@@ -1229,6 +1230,85 @@
+ },
+ };
+
++
++/* ----- AR6000 WLAN interface --------------------------------------------- */
++
++
++/* shared by all SPI drivers */
++
++#if defined(CONFIG_AR6K_SPI_S3C24XX_GPIO)
++
++static struct spi_board_info gta02_spi_mmc_bdinfo = {
++ .modalias = "mmc_spi",
++ .irq = IRQ_EINT3, /* unused ? */
++ .max_speed_hz = 1 * 1000 * 1000,
++ .bus_num = 0,
++ .chip_select = 0,
++ .mode = SPI_MODE_0,
++};
++
++#endif /* CONFIG_AR6K_SPI_S3C24XX_GPIO */
++
++
++#ifdef CONFIG_AR6K_SPI_S3C24XX_GPIO
++
++static void spi_wlan_cs(struct s3c2410_spigpio_info *spigpio_info,
++ int csid, int cs)
++{
++ switch (cs) {
++ case BITBANG_CS_ACTIVE:
++ s3c2410_gpio_setpin(S3C2410_GPE10, 0);
++ break;
++ case BITBANG_CS_INACTIVE:
++ s3c2410_gpio_setpin(S3C2410_GPE10, 1);
++ break;
++ }
++}
++
++static struct s3c2410_spigpio_info spi_gpio_wlan_cfg = {
++ .pin_clk = S3C2410_GPE5,
++ .pin_mosi = S3C2410_GPE6,
++ .pin_miso = S3C2410_GPE7,
++ .board_size = 1,
++ .board_info = >a02_spi_mmc_bdinfo,
++ .chip_select = &spi_wlan_cs,
++ .num_chipselect = 1,
++};
++
++static struct resource gta02_spi_wlan_resource[] = {
++ [0] = {
++ .start = S3C2410_GPE5,
++ .end = S3C2410_GPE5,
++ },
++ [1] = {
++ .start = S3C2410_GPE6,
++ .end = S3C2410_GPE6,
++ },
++ [2] = {
++ .start = S3C2410_GPE7,
++ .end = S3C2410_GPE7,
++ },
++ [3] = {
++ .start = S3C2410_GPE10,
++ .end = S3C2410_GPE10,
++ },
++};
++
++static struct platform_device gta02_spi_wlan = {
++ .name = "spi_s3c24xx_gpio",
++ .id = 1,
++ .num_resources = ARRAY_SIZE(gta02_spi_wlan_resource),
++ .resource = gta02_spi_wlan_resource,
++ .dev = {
++ .platform_data = &spi_gpio_wlan_cfg,
++ },
++};
++
++#endif /* CONFIG_AR6K_SPI_S3C2410_GPIO */
++
++
++/* ------------------------------------------------------------------------- */
++
+ static struct resource gta02_led_resources[] = {
+ {
+ .name = "gta02-power:orange",
+@@ -1603,6 +1683,12 @@
+ mangle_glamo_res_by_system_rev();
+ platform_device_register(>a02_glamo_dev);
+
++#ifdef CONFIG_AR6K_SPI_S3C24XX_GPIO
++ s3c2410_gpio_setpin(S3C2410_GPE10, 1);
++ s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPIO_OUTPUT);
++ platform_device_register(>a02_spi_wlan);
++#endif /* CONFIG_AR6K_SPI_S3C24XX_GPIO */
++
+ platform_device_register(&s3c_device_spi_acc);
+ platform_device_register(>a02_button_dev);
+ platform_device_register(>a02_pm_gsm_dev);
+Index: korig/defconfig-gta02
+===================================================================
+--- korig.orig/defconfig-gta02 2008-09-04 03:30:55.000000000 -0300
++++ korig/defconfig-gta02 2008-09-04 03:31:20.000000000 -0300
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+ # Linux kernel version: 2.6.24
+-# Mon Feb 25 07:03:56 2008
++# Thu Sep 4 03:29:51 2008
+ #
+ CONFIG_ARM=y
+ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+@@ -207,6 +207,7 @@
+ CONFIG_MACH_HXD8=y
+ CONFIG_MACH_NEO1973_GTA02=y
+ # CONFIG_NEO1973_GTA02_2440 is not set
++CONFIG_AR6K_SPI_S3C24XX_GPIO=y
+ CONFIG_CPU_S3C2442=y
+
+ #
+@@ -710,13 +711,6 @@
+ #
+ # CONFIG_MTD_UBI is not set
+ # CONFIG_PARPORT is not set
+-CONFIG_PNP=y
+-CONFIG_PNP_DEBUG=y
+-
+-#
+-# Protocols
+-#
+-# CONFIG_PNPACPI is not set
+ CONFIG_BLK_DEV=y
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+ CONFIG_BLK_DEV_LOOP=m
+@@ -784,7 +778,6 @@
+ # CONFIG_EQUALIZER is not set
+ CONFIG_TUN=m
+ # CONFIG_VETH is not set
+-# CONFIG_NET_SB1000 is not set
+ # CONFIG_PHYLIB is not set
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=y
+@@ -1136,6 +1129,7 @@
+ CONFIG_SND=m
+ CONFIG_SND_TIMER=m
+ CONFIG_SND_PCM=m
++CONFIG_SND_RAWMIDI=m
+ # CONFIG_SND_SEQUENCER is not set
+ CONFIG_SND_OSSEMUL=y
+ CONFIG_SND_MIXER_OSS=m
+@@ -1176,6 +1170,7 @@
+ CONFIG_SND_S3C24XX_SOC=m
+ CONFIG_SND_S3C24XX_SOC_I2S=m
+ CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753=m
++# CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753_DEBUG is not set
+ CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753=m
+
+ #
+@@ -1380,19 +1375,13 @@
+ # CONFIG_USB_GADGET_DUALSPEED is not set
+ # CONFIG_USB_ZERO is not set
+ CONFIG_USB_ETH=m
+-CONFIG_USB_ETH_RNDIS=m
++CONFIG_USB_ETH_RNDIS=y
+ CONFIG_USB_GADGETFS=m
+ CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
+ CONFIG_USB_G_SERIAL=m
+ CONFIG_USB_MIDI_GADGET=m
+-
+-#
+-# SDIO support
+-#
+-CONFIG_SDIO=y
+-CONFIG_SDIO_S3C24XX=y
+-CONFIG_SDIO_S3C24XX_DMA=y
+-CONFIG_SDIO_AR6000_WLAN=y
++CONFIG_AR6000_WLAN=y
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+ CONFIG_MMC_UNSAFE_RESUME=y
+@@ -1407,7 +1396,7 @@
+ #
+ # MMC/SD Host Controller Drivers
+ #
+-# CONFIG_MMC_SPI is not set
++CONFIG_MMC_SPI=y
+ CONFIG_MMC_S3C=y
+ CONFIG_NEW_LEDS=y
+ CONFIG_LEDS_CLASS=y
+@@ -1510,6 +1499,7 @@
+ CONFIG_JOLIET=y
+ # CONFIG_ZISOFS is not set
+ CONFIG_UDF_FS=m
++CONFIG_UDF_NLS=y
+
+ #
+ # DOS/FAT/NT Filesystems
+@@ -1542,16 +1532,6 @@
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
+-CONFIG_YAFFS_FS=y
+-CONFIG_YAFFS_YAFFS1=y
+-CONFIG_YAFFS_9BYTE_TAGS=y
+-CONFIG_YAFFS_YAFFS2=y
+-CONFIG_YAFFS_AUTO_YAFFS2=y
+-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+-CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+ CONFIG_JFFS2_FS=y
+ CONFIG_JFFS2_FS_DEBUG=0
+ CONFIG_JFFS2_FS_WRITEBUFFER=y
+@@ -1751,9 +1731,9 @@
+ CONFIG_BITREVERSE=y
+ CONFIG_CRC_CCITT=m
+ CONFIG_CRC16=m
+-# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC_ITU_T=y
+ CONFIG_CRC32=y
+-# CONFIG_CRC7 is not set
++CONFIG_CRC7=y
+ CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=y
+ CONFIG_ZLIB_DEFLATE=y
Added: developers/werner/wlan-spi/patches/gta02-remove-sdio.patch
===================================================================
--- developers/werner/wlan-spi/patches/gta02-remove-sdio.patch (rev 0)
+++ developers/werner/wlan-spi/patches/gta02-remove-sdio.patch 2008-09-04 06:56:08 UTC (rev 4626)
@@ -0,0 +1,59 @@
+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: korig/arch/arm/mach-s3c2440/mach-gta02.c
+===================================================================
+--- korig.orig/arch/arm/mach-s3c2440/mach-gta02.c 2008-09-04 03:06:16.000000000 -0300
++++ korig/arch/arm/mach-s3c2440/mach-gta02.c 2008-09-04 03:06:39.000000000 -0300
+@@ -810,36 +810,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,
+@@ -1643,9 +1613,6 @@
+ platform_device_register(>a02_vibrator_dev);
+ platform_device_register(>a02_led_dev);
+
+-
+- platform_device_register(>a02_sdio_dev);
+-
+ platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
+
+ #ifdef CONFIG_GTA02_HDQ
Added: developers/werner/wlan-spi/patches/sdio-f0-unrestrict.patch
===================================================================
--- developers/werner/wlan-spi/patches/sdio-f0-unrestrict.patch (rev 0)
+++ developers/werner/wlan-spi/patches/sdio-f0-unrestrict.patch 2008-09-04 06:56:08 UTC (rev 4626)
@@ -0,0 +1,28 @@
+sdio-f0-unrestrict.patch
+
+In order to set the EMPC bit in the CCCR, we must be allowed to write
+to more than just the vendor registers of function 0.
+
+This is just a local work-around. Need to check how upstream thinks
+this should be done.
+
+Not-Yet-Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+Index: korig/drivers/mmc/core/sdio_io.c
+===================================================================
+--- korig.orig/drivers/mmc/core/sdio_io.c 2008-09-04 02:32:42.000000000 -0300
++++ korig/drivers/mmc/core/sdio_io.c 2008-09-04 02:32:55.000000000 -0300
+@@ -535,11 +535,13 @@
+
+ BUG_ON(!func);
+
++#if 0
+ if (addr < 0xF0 || addr > 0xFF) {
+ if (err_ret)
+ *err_ret = -EINVAL;
+ return;
+ }
++#endif
+
+ ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL);
+ if (err_ret)
Added: developers/werner/wlan-spi/patches/series
===================================================================
--- developers/werner/wlan-spi/patches/series (rev 0)
+++ developers/werner/wlan-spi/patches/series 2008-09-04 06:56:08 UTC (rev 4626)
@@ -0,0 +1,20 @@
+#
+# This series of patches gets rid of the Atheros SDIO stack and makes the
+# AR6000 driver work directly with the Linux SDIO stack.
+#
+# Before applying these patches, do this:
+#
+# cd drivers
+# mv sdio/function/wlan/ar6000 .
+#
+# If you wish, you can now
+#
+# rm -rf sdio ../include/linux/sdio
+#
+
+wlan-spi-hif.patch
+ar6k-without-sdio.patch
+sdio-f0-unrestrict.patch
+gta02-remove-sdio.patch
+gta02-mmc-spi-bitbang.patch
+config-ar6k-mmc-spi-bitbang.patch
Added: developers/werner/wlan-spi/patches/wlan-spi-hif.patch
===================================================================
--- developers/werner/wlan-spi/patches/wlan-spi-hif.patch (rev 0)
+++ developers/werner/wlan-spi/patches/wlan-spi-hif.patch 2008-09-04 06:56:08 UTC (rev 4626)
@@ -0,0 +1,660 @@
+wlan-spi-hif.patch
+
+This is a replacement for Atheros' HIF layer. We use the Linux SDIO
+stack.
+
+Using Atheros' GPLv2 clause for now. Since there's only very little of
+the original code left, we should perhaps switch to GPL>=v2, which is
+preferred by Openmoko.
+
+Work in progress.
+
+Not-Yet-Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+Index: korig/drivers/ar6000/Makefile
+===================================================================
+--- korig.orig/drivers/ar6000/Makefile 2008-09-04 02:02:08.000000000 -0300
++++ korig/drivers/ar6000/Makefile 2008-09-04 02:44:29.000000000 -0300
+@@ -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: korig/drivers/ar6000/hif/hif2.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ korig/drivers/ar6000/hif/hif2.c 2008-09-04 02:52:58.000000000 -0300
+@@ -0,0 +1,629 @@
++/*
++ * 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/mmc/sdio_func.h>
++#include <linux/mmc/sdio.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)
++ * - 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
++ */
++
++
++//#define dev_dbg dev_info
++#define dev_dbg(dev, ...) ((void) dev)
++
++#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 HIF_DEVICE hif_device;
++static HTC_CALLBACKS htcCallbacks;
++
++
++int HIFInit(HTC_CALLBACKS *callbacks)
++{
++ BUG_ON(!callbacks);
++
++ printk(KERN_INFO "HIFInit\n");
++ htcCallbacks = *callbacks;
++
++ return 0;
++}
++
++
++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);
++ return status;
++}
++
++
++static void enqueue_request(struct hif_device *device, struct hif_request *req)
++{
++ unsigned long flags;
++
++ dev_dbg(&req->func->dev, "enqueue_request(req %p)\n", req);
++ spin_lock_irqsave(&device->queue_lock, flags);
++ list_add_tail(&req->list, &device->queue);
++ spin_unlock_irqrestore(&device->queue_lock, flags);
++ wake_up(&device->wait);
++}
++
++
++static struct hif_request *dequeue_request(struct hif_device *device)
++{
++ struct hif_request *req;
++ unsigned long flags;
++
++ spin_lock_irqsave(&device->queue_lock, flags);
++ if (list_empty(&device->queue))
++ req = NULL;
++ else {
++ req = list_first_entry(&device->queue,
++ struct hif_request, list);
++ list_del(&req->list);
++ }
++ spin_unlock_irqrestore(&device->queue_lock, flags);
++ return req;
++}
++
++
++static int io(void *data)
++{
++ struct hif_device *device = data;
++ DECLARE_WAITQUEUE(wait, current);
++ struct hif_request *req;
++
++ while (1) {
++ add_wait_queue(&device->wait, &wait);
++ while (1) {
++ set_current_state(TASK_INTERRUPTIBLE);
++ if (signal_pending(current)) {
++ req = NULL;
++ break;
++ }
++ req = dequeue_request(device);
++ if (req)
++ break;
++ schedule();
++ }
++ set_current_state(TASK_RUNNING);
++ remove_wait_queue(&device->wait, &wait);
++
++ if (!req)
++ break;
++
++ (void) process_request(req);
++ }
++ return 0;
++}
++
++
++A_STATUS HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer,
++ A_UINT32 length, A_UINT32 request, void *context)
++{
++ struct device *dev = HIFGetOSDevice(device);
++ struct hif_request *req;
++ A_STATUS status;
++
++ dev_dbg(dev, "HIFReadWrite(device %p, address 0x%x, buffer %p, "
++ "length %d, request 0x%x, context %p)\n",
++ device, 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 = device->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)) {
++ status = process_request(req);
++ kfree(req);
++ return status;
++ }
++
++ req->completion = htcCallbacks.rwCompletionHandler;
++ req->context = context;
++ enqueue_request(device, req);
++
++ return A_OK;
++}
++
++
++A_STATUS HIFConfigureDevice(HIF_DEVICE *device,
++ HIF_DEVICE_CONFIG_OPCODE opcode, void *config, A_UINT32 configLen)
++{
++ struct device *dev = HIFGetOSDevice(device);
++ 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;
++}
++
++
++void HIFShutDownDevice(HIF_DEVICE *device)
++{
++ struct device *dev = HIFGetOSDevice(device);
++
++ dev_dbg(dev, "HIFShutDownDevice\n");
++}
++
++
++/* ========================================================================= */
++
++#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.
++ *
++ * 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 *device = sdio_get_drvdata(func);
++ struct device *dev = HIFGetOSDevice(device);
++ A_STATUS status;
++
++ dev_dbg(dev, "ar6000_do_irq -> %p\n", htcCallbacks.dsrHandler);
++
++ status = htcCallbacks.dsrHandler(device->htc_handle);
++ BUG_ON(status != A_OK);
++}
++
++
++static void sdio_ar6000_irq(struct sdio_func *func)
++{
++ HIF_DEVICE *device = sdio_get_drvdata(func);
++ struct device *dev = HIFGetOSDevice(device);
++
++ 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 *device)
++{
++ struct device *dev = HIFGetOSDevice(device);
++
++ dev_dbg(dev, "HIFAckInterrupt\n");
++ /* do nothing */
++}
++
++
++void HIFUnMaskInterrupt(HIF_DEVICE *device)
++{
++ struct device *dev = HIFGetOSDevice(device);
++
++ dev_dbg(dev, "HIFUnMaskInterrupt\n");
++ do {
++ masked = 1;
++ if (pending) {
++ pending = 0;
++ ar6000_do_irq(device->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 *device)
++{
++ struct device *dev = HIFGetOSDevice(device);
++
++ 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();
++}
++
++#endif
++
++/* ========================================================================= */
++
++/*
++ * 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 *device = sdio_get_drvdata(func);
++
++ printk(KERN_DEBUG "sdio_ar6000_irq -> %p\n", htcCallbacks.dsrHandler);
++ BUG();
++}
++
++
++static void sdio_ar6000_poll(void *context)
++{
++ HIF_DEVICE *device = 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(device->htc_handle);
++ BUG_ON(status != A_OK);
++ }
++}
++
++
++void HIFAckInterrupt(HIF_DEVICE *device)
++{
++ struct device *dev = HIFGetOSDevice(device);
++ int ret;
++
++ ret = atomic_dec_return(&mask);
++ BUG_ON(ret < 0);
++ dev_dbg(dev, "HIFAckInterrupt (%d)\n", ret);
++}
++
++
++void HIFUnMaskInterrupt(HIF_DEVICE *device)
++{
++ struct device *dev = HIFGetOSDevice(device);
++ int ret;
++
++ ret = atomic_dec_return(&mask);
++ BUG_ON(ret < 0);
++ dev_dbg(dev, "HIFUnMaskInterrupt (%d)\n", ret);
++}
++
++
++void HIFMaskInterrupt(HIF_DEVICE *device)
++{
++ struct device *dev = HIFGetOSDevice(device);
++ 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 *device)
++{
++ return &device->func->dev;
++}
++
++
++void HIFSetHandle(void *hif_handle, void *handle)
++{
++ HIF_DEVICE *device = (HIF_DEVICE *) hif_handle;
++
++ device->htc_handle = handle;
++}
++
++
++/* ----- */
++
++
++
++/*
++ * @@@ 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);
++
++ sdio_set_drvdata(func, &hif_device);
++ sdio_claim_host(func);
++ sdio_enable_func(func);
++
++ hif_device.func = func;
++ INIT_LIST_HEAD(&hif_device.queue);
++ init_waitqueue_head(&hif_device.wait);
++
++ 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 */
++ }
++ ret = sdio_claim_irq(func, sdio_ar6000_irq);
++ if (ret) {
++ dev_err(dev, "sdio_claim_irq returns %d\n", ret);
++ /* @@@ cleanup */
++ }
++#if 0 /* only for hw SDIO */
++ sdio_f0_writeb(func, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT,
++ SDIO_CCCR_IF, &ret);
++ if (ret) {
++ dev_err(dev, "sdio_f0_writeb(SDIO_CCCR_IF) returns %d\n",
++ ret);
++ /* @@@ cleanup */
++ }
++#endif
++#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);
++ /* @@@ cleanup */
++ }
++#endif
++ 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 */
++ }
++ 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 */
++ }
++ task = kthread_run(inserter, NULL, "ar6000_inserter");
++ if (IS_ERR(task)) {
++ dev_err(dev, "kthread_run (ar6000_inserter): %d\n", ret);
++ /* @@@ cleanup */
++ }
++
++ return 0;
++}
++
++
++static void sdio_ar6000_remove(struct sdio_func *func)
++{
++ sdio_claim_host(func);
++ sdio_release_irq(func);
++ sdio_disable_func(func);
++ sdio_release_host(func);
++ /* @@@ remove */
++ /* @@@ kill _tasks */
++}
++
++
++/* @@@ move these definitions to linux/mmc/sdio_ids.h */
++#define SDIO_VENDOR_ID_ATHEROS 0x271
++#define SDIO_DEVICE_ID_ATHEROS_AR6000 0x100
++
++#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_uart_ids);
++
++
++static struct sdio_driver sdio_ar6000_driver = {
++ .probe = sdio_ar6000_probe,
++ .remove = sdio_ar6000_remove,
++ .name = "sdio_ar6000",
++ .id_table = sdio_ar6000_ids,
++};
++
++
++static int __devinit sdio_ar6000_init(void)
++{
++ printk(KERN_INFO "sdio_ar6000_init\n");
++ return sdio_register_driver(&sdio_ar6000_driver);
++}
++
++
++static void __exit sdio_ar6000_exit(void)
++{
++ printk(KERN_INFO "sdio_ar6000_exit\n");
++ sdio_unregister_driver(&sdio_ar6000_driver);
++}
++
++
++module_init(sdio_ar6000_init);
++module_exit(sdio_ar6000_exit);
++
++MODULE_AUTHOR("Werner Almesberger");
++MODULE_LICENSE("GPL");
More information about the commitlog
mailing list