[PATCH 44/133] [Jaunty SRU] ARM.imx51 Freescale:ENGR00110257 unifi_fs: re-initialize chip every time insert module
Brad Figg
brad.figg at canonical.com
Thu Jul 9 16:48:34 UTC 2009
When rmmod, driver will try to poweroff wifi chip, so it may be in a wrong
state when insmod it again.
When insert unifi_sdio module, it will first pull down reset pin to remove
sdio device if it exists and add sdio device, init it again.
Signed-off-by: Richard Zhao <b20223 at freescale.com>
Signed-off-by: Brad Figg <brad.figg at canonical.com>
---
arch/arm/mach-mx51/mx51_3stack.c | 13 +-----
arch/arm/plat-mxc/include/mach/mxc.h | 2 +-
drivers/mmc/card/unifi_fs/fs_lx.c | 69 ++++++++++++++-------------------
drivers/mmc/host/mx_sdhci.c | 2 -
4 files changed, 32 insertions(+), 54 deletions(-)
diff --git a/arch/arm/mach-mx51/mx51_3stack.c b/arch/arm/mach-mx51/mx51_3stack.c
index 452b6f9..7e4d887 100644
--- a/arch/arm/mach-mx51/mx51_3stack.c
+++ b/arch/arm/mach-mx51/mx51_3stack.c
@@ -952,12 +952,9 @@ static void mxc_init_bluetooth(void)
(void)platform_device_register(&mxc_bt_device);
}
-#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
-static void mxc_unifi_hardreset(void)
+static void mxc_unifi_hardreset(int pin_level)
{
- mxc_set_gpio_dataout(MX51_PIN_EIM_D19, 0);
- msleep(100);
- mxc_set_gpio_dataout(MX51_PIN_EIM_D19, 1);
+ mxc_set_gpio_dataout(MX51_PIN_EIM_D19, pin_level & 0x01);
}
static struct mxc_unifi_platform_data unifi_data = {
@@ -971,12 +968,6 @@ struct mxc_unifi_platform_data *get_unifi_plat_data(void)
{
return &unifi_data;
}
-#else
-struct mxc_unifi_platform_data *get_unifi_plat_data(void)
-{
- return NULL;
-}
-#endif
EXPORT_SYMBOL(get_unifi_plat_data);
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 1b1ce12..b8d738e 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -293,7 +293,7 @@ struct mxc_keyp_platform_data {
};
struct mxc_unifi_platform_data {
- void (*hardreset) (void);
+ void (*hardreset) (int pin_level);
void (*enable) (int en);
/* power parameters */
char *reg_gpo1;
diff --git a/drivers/mmc/card/unifi_fs/fs_lx.c b/drivers/mmc/card/unifi_fs/fs_lx.c
index 37b7bba..a33b6ce 100644
--- a/drivers/mmc/card/unifi_fs/fs_lx.c
+++ b/drivers/mmc/card/unifi_fs/fs_lx.c
@@ -245,7 +245,7 @@ EXPORT_SYMBOL(fs_sdio_set_block_size);
*
* ---------------------------------------------------------------------------
*/
-static void fs_unifi_power_on(int check_card)
+static void fs_unifi_power_on(void)
{
struct regulator_unifi *reg_unifi;
unsigned int tmp;
@@ -284,11 +284,6 @@ static void fs_unifi_power_on(int check_card)
regulator_enable(reg_unifi->reg_1v5_dd);
}
msleep(10);
- if (check_card) {
- do_sdio_hard_reset(NULL);
- msleep(500);
- mxc_mmc_force_detect(plat_data->host_id);
- }
}
/*
@@ -298,7 +293,7 @@ static void fs_unifi_power_on(int check_card)
*
* ---------------------------------------------------------------------------
*/
-static void fs_unifi_power_off(int check_card)
+static void fs_unifi_power_off(void)
{
struct regulator_unifi *reg_unifi;
@@ -319,10 +314,6 @@ static void fs_unifi_power_off(int check_card)
if (reg_unifi->reg_gpo1)
regulator_disable(reg_unifi->reg_gpo1);
-
- if (check_card)
- mxc_mmc_force_detect(plat_data->host_id);
-
}
/* This should be made conditional on being slot 2 too - so we can
@@ -334,12 +325,6 @@ int fs_sdio_hard_reset(struct sdio_dev *fdev)
}
EXPORT_SYMBOL(fs_sdio_hard_reset);
-static int do_sdio_hard_reset(struct sdio_dev *fdev)
-{
- plat_data->hardreset();
- return 0;
-}
-
static const struct sdio_device_id fs_sdio_ids[] = {
{SDIO_DEVICE(0x032a, 0x0001)},
{ /* end: all zeroes */ },
@@ -358,11 +343,32 @@ static struct sdio_driver sdio_unifi_driver = {
int fs_sdio_register_driver(struct fs_driver *driver)
{
- int ret;
+ int ret, retry;
/* Switch us on, sdio device may exist if power is on by default. */
- fs_unifi_power_on(available_sdio_dev ? 0 : 1);
-
+ plat_data->hardreset(0);
+ mxc_mmc_force_detect(plat_data->host_id);
+ /* Wait for card removed */
+ for (retry = 0; retry < 100; retry++) {
+ if (!available_sdio_dev)
+ break;
+ msleep(100);
+ }
+ if (retry == 100)
+ printk(KERN_ERR "fs_sdio_register_driver: sdio device exists, "
+ "timeout for card removed");
+ fs_unifi_power_on();
+ plat_data->hardreset(1);
+ msleep(500);
+ mxc_mmc_force_detect(plat_data->host_id);
+ for (retry = 0; retry < 100; retry++) {
+ if (available_sdio_dev)
+ break;
+ msleep(50);
+ }
+ if (retry == 1000)
+ printk(KERN_ERR "fs_sdio_register_driver: Timeout waiting"
+ " for card added\n");
/* Store the context to the device driver to the global */
available_driver = driver;
@@ -392,6 +398,7 @@ EXPORT_SYMBOL(fs_sdio_register_driver);
void fs_sdio_unregister_driver(struct fs_driver *driver)
{
+ int retry;
/*
* If available_sdio_dev is not NULL, probe has been called,
* so pass the remove to the registered driver to clean up.
@@ -421,9 +428,8 @@ void fs_sdio_unregister_driver(struct fs_driver *driver)
/* invalidate the context to the device driver to the global */
available_driver = NULL;
/* Power down the UniFi */
- fs_unifi_power_off(-1);
- /* Wait for card removed */
- msleep(100);
+ fs_unifi_power_off();
+
}
EXPORT_SYMBOL(fs_sdio_unregister_driver);
@@ -488,23 +494,6 @@ static int fs_sdio_probe(struct sdio_func *func,
printk(KERN_INFO "fs_sdio_probe: Add glue driver\n");
sdio_set_drvdata(func, fdev);
- /* TODO: If a device driver is registered, call it's probe here */
- if (available_driver) {
- /* Store the context to the device driver */
- fdev->driver = available_driver;
-
- printk(KERN_INFO "fs_sdio_probe: Add device driver and "
- "register IRQ\n");
- available_driver->probe(fdev);
-
- /* Register the IRQ handler to the SDIO IRQ. */
- sdio_claim_host(fdev->func);
- ret = sdio_claim_irq(func, fs_sdio_irq);
- sdio_release_host(fdev->func);
- if (ret)
- return ret;
- }
-
return 0;
}
diff --git a/drivers/mmc/host/mx_sdhci.c b/drivers/mmc/host/mx_sdhci.c
index f4c51b5..986338f 100644
--- a/drivers/mmc/host/mx_sdhci.c
+++ b/drivers/mmc/host/mx_sdhci.c
@@ -129,8 +129,6 @@ void mxc_mmc_force_detect(int id)
if (!mxc_fix_chips[id])
return;
host = mxc_fix_chips[id]->hosts[0];
- if (host->flags & SDHCI_CD_PRESENT)
- return;
if (host->detect_irq)
return;
--
1.6.0.4
More information about the kernel-team
mailing list