diff options
author | Andrey Konovalov <andrey.konovalov@linaro.org> | 2012-05-22 20:39:11 +0400 |
---|---|---|
committer | Andrey Konovalov <andrey.konovalov@linaro.org> | 2012-05-22 20:39:11 +0400 |
commit | 0801288cee8791cf441e9a3ce8e93937960f5a6e (patch) | |
tree | 854cbec5a3025096c28d17b389a420c8739346de | |
parent | 28489b18693b5b551c61d1aa84f6c8713b2ad869 (diff) | |
parent | 06115973bcc339b55bc156c97a8bb7b6918afb68 (diff) | |
download | linux-topics-0801288cee8791cf441e9a3ce8e93937960f5a6e.tar.gz |
Automatically merging rebase-samslt-wlan into merge-linux-linaro
Conflicting files:
-rw-r--r-- | arch/arm/configs/exynos4_defconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-exynos/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mach-origen.c | 100 | ||||
-rw-r--r-- | configs/origen.conf | 2 | ||||
-rw-r--r-- | drivers/Makefile | 2 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_irq.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_ops.c | 40 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_ops.h | 1 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/Kconfig | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/Makefile | 26 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/sdio.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath/platform_data.c | 26 | ||||
-rw-r--r-- | include/linux/ath6kl.h | 38 |
15 files changed, 256 insertions, 16 deletions
diff --git a/arch/arm/configs/exynos4_defconfig b/arch/arm/configs/exynos4_defconfig index 6a19e5b567b..5ccb3561338 100644 --- a/arch/arm/configs/exynos4_defconfig +++ b/arch/arm/configs/exynos4_defconfig @@ -53,6 +53,11 @@ CONFIG_USB_PEGASUS=y CONFIG_USB_USBNET=y CONFIG_USB_NET_DM9601=y CONFIG_USB_NET_MCS7830=y +CONFIG_ATH_COMMON=y +CONFIG_ATH_DEBUG=y +CONFIG_ATH6KL=m +CONFIG_ATH6KL_PLATFORM_DATA=y +CONFIG_ATH6KL_POLL=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index b07c346f3c5..ee0b6c3caa1 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -326,6 +326,7 @@ config MACH_ORIGEN select S3C_DEV_WDT select S3C_DEV_HSMMC select S3C_DEV_HSMMC2 + select S3C_DEV_HSMMC3 select S3C_DEV_USB_HSOTG select S5P_DEV_FIMC0 select S5P_DEV_FIMC1 diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index 70ddf1087a7..7e473e0017e 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -22,6 +22,8 @@ #include <linux/mfd/max8997.h> #include <linux/lcd.h> #include <linux/rfkill-gpio.h> +#include <linux/ath6kl.h> +#include <linux/delay.h> #include <asm/mach/arch.h> #include <asm/hardware/gic.h> @@ -485,6 +487,100 @@ static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = { .cd_type = S3C_SDHCI_CD_INTERNAL, }; + +/* + * WLAN: SDIO Host will call this func at booting time + */ +static int origen_wifi_status_register(void (*notify_func) + (struct platform_device *, int state)); + +/* WLAN: MMC3-SDIO */ +static struct s3c_sdhci_platdata origen_hsmmc3_pdata __initdata = { + .max_width = 4, + .host_caps = MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .pm_caps = MMC_PM_KEEP_POWER, + .cd_type = S3C_SDHCI_CD_EXTERNAL, + .ext_cd_init = origen_wifi_status_register, +}; + +/* + * WLAN: Save SDIO Card detect func into this pointer + */ +static void (*wifi_status_cb)(struct platform_device *, int state); + +static int origen_wifi_status_register(void (*notify_func) + (struct platform_device *, int state)) +{ + /* Assign sdhci_s3c_notify_change to wifi_status_cb */ + if (!notify_func) + return -EAGAIN; + else + wifi_status_cb = notify_func; + + return 0; +} + +#define ORIGEN_WLAN_WOW EXYNOS4_GPX2(3) +#define ORIGEN_WLAN_RESET EXYNOS4_GPX2(4) + + +static void origen_wlan_setup_power(bool val) +{ + int err; + + if (val) { + err = gpio_request_one(ORIGEN_WLAN_RESET, + GPIOF_OUT_INIT_LOW, "GPX2_4"); + if (err) { + pr_warning("ORIGEN: Not obtain WIFI gpios\n"); + return; + } + s3c_gpio_cfgpin(ORIGEN_WLAN_RESET, S3C_GPIO_OUTPUT); + s3c_gpio_setpull(ORIGEN_WLAN_RESET, + S3C_GPIO_PULL_NONE); + /* VDD33,I/O Supply must be done */ + gpio_set_value(ORIGEN_WLAN_RESET, 0); + udelay(30); /*Tb */ + gpio_direction_output(ORIGEN_WLAN_RESET, 1); + } else { + gpio_direction_output(ORIGEN_WLAN_RESET, 0); + gpio_free(ORIGEN_WLAN_RESET); + } + + mdelay(100); + + return; +} + +/* + * This will be called at init time of WLAN driver + */ +static int origen_wifi_set_detect(bool val) +{ + + if (!wifi_status_cb) { + pr_warning("ORIGEN: WLAN: No callback \n" + "ORIGEN: WLAN: MMC should boot earlier than net \n"); + + return -EAGAIN; + } + if (true == val) { + origen_wlan_setup_power(true); + wifi_status_cb(&s3c_device_hsmmc3, 1); + } else { + origen_wlan_setup_power(false); + wifi_status_cb(&s3c_device_hsmmc3, 0); + } + + return 0; +} + +struct ath6kl_platform_data origen_wlan_data __initdata = { + .setup_power = origen_wifi_set_detect, +}; + + /* USB EHCI */ static struct s5p_ehci_platdata origen_ehci_pdata; @@ -671,6 +767,7 @@ static struct platform_device origen_device_bluetooth = { static struct platform_device *origen_devices[] __initdata = { &s3c_device_hsmmc2, &s3c_device_hsmmc0, + &s3c_device_hsmmc3, &s3c_device_i2c0, &s3c_device_rtc, &s3c_device_wdt, @@ -759,6 +856,7 @@ static void __init origen_machine_init(void) */ s3c_sdhci2_set_platdata(&origen_hsmmc2_pdata); s3c_sdhci0_set_platdata(&origen_hsmmc0_pdata); + s3c_sdhci3_set_platdata(&origen_hsmmc3_pdata); origen_ehci_init(); origen_ohci_init(); @@ -775,6 +873,8 @@ static void __init origen_machine_init(void) samsung_bl_set(&origen_bl_gpio_info, &origen_bl_data); origen_bt_setup(); + + ath6kl_set_platform_data(&origen_wlan_data); } MACHINE_START(ORIGEN, "ORIGEN") diff --git a/configs/origen.conf b/configs/origen.conf index 1b2fdb2e62c..374884cf4c2 100644 --- a/configs/origen.conf +++ b/configs/origen.conf @@ -33,6 +33,8 @@ CONFIG_USB_NET_MCS7830=y CONFIG_ATH_COMMON=y CONFIG_ATH_DEBUG=y CONFIG_ATH6KL=y +CONFIG_ATH6KL_PLATFORM_DATA=y +CONFIG_ATH6KL_POLL=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y CONFIG_INPUT_TOUCHSCREEN=y diff --git a/drivers/Makefile b/drivers/Makefile index 4f7acbf9c2b..b3347860c6f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_TARGET_CORE) += target/ obj-$(CONFIG_MTD) += mtd/ obj-$(CONFIG_SPI) += spi/ obj-y += hsi/ +obj-y += mmc/ obj-y += net/ obj-$(CONFIG_ATM) += atm/ obj-$(CONFIG_FUSION) += message/ @@ -97,7 +98,6 @@ obj-$(CONFIG_EISA) += eisa/ obj-y += lguest/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_CPU_IDLE) += cpuidle/ -obj-y += mmc/ obj-$(CONFIG_MEMSTICK) += memstick/ obj-y += leds/ obj-$(CONFIG_SWITCH) += switch/ diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index f573e7f9f74..2a07aed6e59 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -44,7 +44,7 @@ static int process_sdio_pending_irqs(struct mmc_card *card) return 1; } - ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending); + ret = mmc_io_rw_direct_irq(card, &pending); if (ret) { pr_debug("%s: error %d reading SDIO_CCCR_INTx\n", mmc_card_id(card), ret); diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index d29e20630ee..2fcb53e678c 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c @@ -111,6 +111,46 @@ static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn, return 0; } +static struct mmc_command sdio_intx_cmd = { + .opcode = SD_IO_RW_DIRECT, + .arg = SDIO_CCCR_INTx << 9, + .flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC, +}; + +int mmc_io_rw_direct_irq(struct mmc_card *card, u8 *out) +{ + int err; + struct mmc_host *host ; + + BUG_ON(!card); + host = card->host; + BUG_ON(!host); + + err = mmc_wait_for_cmd(host, &sdio_intx_cmd, 0); + if (err) + return err; + + if (mmc_host_is_spi(host)) { + /* host driver already reported errors */ + } else { + if (sdio_intx_cmd.resp[0] & R5_ERROR) + return -EIO; + if (sdio_intx_cmd.resp[0] & R5_FUNCTION_NUMBER) + return -EINVAL; + if (sdio_intx_cmd.resp[0] & R5_OUT_OF_RANGE) + return -ERANGE; + } + + if (out) { + if (mmc_host_is_spi(host)) + *out = (sdio_intx_cmd.resp[0] >> 8) & 0xFF; + else + *out = sdio_intx_cmd.resp[0] & 0xFF; + } + + return 0; +} + int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, unsigned addr, u8 in, u8 *out) { diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h index 12a4d3ab174..5fe8ad66745 100644 --- a/drivers/mmc/core/sdio_ops.h +++ b/drivers/mmc/core/sdio_ops.h @@ -15,6 +15,7 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, unsigned addr, u8 in, u8* out); +int mmc_io_rw_direct_irq(struct mmc_card *card, u8 *out); int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); int sdio_reset(struct mmc_host *host); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 37601ec6a95..2ebe589a616 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2747,7 +2747,11 @@ int sdhci_add_host(struct sdhci_host *host) mmc->max_discard_to = (1 << 27) / host->timeout_clk; +#if defined(CONFIG_MACH_ORIGEN) && defined(CONFIG_ATH6KL_POLL) + mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; +#else mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; +#endif if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) host->flags |= SDHCI_AUTO_CMD12; diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index d716b748e57..fc2851e2b7c 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_ATH5K) += ath5k/ obj-$(CONFIG_ATH9K_HW) += ath9k/ obj-$(CONFIG_CARL9170) += carl9170/ obj-$(CONFIG_ATH6KL) += ath6kl/ - +obj-$(CONFIG_ATH6KL_PLATFORM_DATA) += platform_data.o obj-$(CONFIG_ATH_COMMON) += ath.o ath-objs := main.o \ diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index d755a5e7ed2..734a6ef3d08 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig @@ -30,3 +30,15 @@ config ATH6KL_DEBUG depends on ATH6KL ---help--- Enables debug support + +config ATH6KL_PLATFORM_DATA + bool "Atheros ath6kl Platform data support" + depends on ATH6KL + ---help--- + Enables ath6kl platform data + +config ATH6KL_POLL + bool "Atheros ath6kl Polling support" + depends on ATH6KL + ---help--- + Enables workaround for ar6003 hw2.0 diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 85746c3eb02..9e8f15b7de6 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -22,21 +22,21 @@ # Author(s): ="Atheros" #------------------------------------------------------------------------------ -obj-$(CONFIG_ATH6KL) += ath6kl_core.o -ath6kl_core-y += debug.o -ath6kl_core-y += hif.o -ath6kl_core-y += htc.o -ath6kl_core-y += bmi.o -ath6kl_core-y += cfg80211.o -ath6kl_core-y += init.o -ath6kl_core-y += main.o -ath6kl_core-y += txrx.o -ath6kl_core-y += wmi.o -ath6kl_core-y += core.o -ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o +obj-$(CONFIG_ATH6KL) += ath6kl.o +ath6kl-y += debug.o +ath6kl-y += hif.o +ath6kl-y += htc.o +ath6kl-y += bmi.o +ath6kl-y += cfg80211.o +ath6kl-y += init.o +ath6kl-y += main.o +ath6kl-y += txrx.o +ath6kl-y += wmi.o +ath6kl-y += core.o +ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o -ath6kl_sdio-y += sdio.o +ath6kl-y += sdio.o obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o ath6kl_usb-y += usb.o diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 53528648b42..7c7e12fe58f 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -23,6 +23,7 @@ #include <linux/mmc/sdio_ids.h> #include <linux/mmc/sdio.h> #include <linux/mmc/sd.h> +#include <linux/ath6kl.h> #include "hif.h" #include "hif-ops.h" #include "target.h" @@ -1421,7 +1422,11 @@ static struct sdio_driver ath6kl_sdio_driver = { static int __init ath6kl_sdio_init(void) { int ret; + const struct ath6kl_platform_data *wlan_data; + wlan_data = ath6kl_get_platform_data(); + if (!IS_ERR(wlan_data)) + wlan_data->setup_power(true); ret = sdio_register_driver(&ath6kl_sdio_driver); if (ret) ath6kl_err("sdio driver registration failed: %d\n", ret); @@ -1431,7 +1436,13 @@ static int __init ath6kl_sdio_init(void) static void __exit ath6kl_sdio_exit(void) { + const struct ath6kl_platform_data *wlan_data; + sdio_unregister_driver(&ath6kl_sdio_driver); + + wlan_data = ath6kl_get_platform_data(); + if (!IS_ERR(wlan_data)) + wlan_data->setup_power(false); } module_init(ath6kl_sdio_init); diff --git a/drivers/net/wireless/ath/platform_data.c b/drivers/net/wireless/ath/platform_data.c new file mode 100644 index 00000000000..dddffe409b0 --- /dev/null +++ b/drivers/net/wireless/ath/platform_data.c @@ -0,0 +1,26 @@ +#include <linux/module.h> +#include <linux/err.h> +#include <linux/ath6kl.h> + +static const struct ath6kl_platform_data *platform_data; + +int __init ath6kl_set_platform_data(const struct ath6kl_platform_data *data) +{ + if (platform_data) + return -EBUSY; + if (!data) + return -EINVAL; + + platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); + if (!platform_data) + return -ENOMEM; + return 0; +} + +const struct ath6kl_platform_data *ath6kl_get_platform_data(void) +{ + if (!platform_data) + return ERR_PTR(-ENODEV); + return platform_data; +} +EXPORT_SYMBOL(ath6kl_get_platform_data); diff --git a/include/linux/ath6kl.h b/include/linux/ath6kl.h new file mode 100644 index 00000000000..0e0ff495481 --- /dev/null +++ b/include/linux/ath6kl.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008 Atheros Communications Inc. + * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> + * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LINUX_ATH6KL_PLATFORM_H +#define _LINUX_ATH6KL_PLATFORM_H + +struct ath6kl_platform_data { + int (*setup_power)(bool); +}; + +#ifdef CONFIG_ATH6KL_PLATFORM_DATA +int ath6kl_set_platform_data(const struct ath6kl_platform_data *data); +#else +static inline +int ath6kl_set_platform_data(const struct ath6kl_platform_data *data) +{ + return -ENOSYS; +} +#endif + +const struct ath6kl_platform_data *ath6kl_get_platform_data(void); + +#endif /* _LINUX_ATH6KL_PLATFORM_H */ |