diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-06-24 21:25:51 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-06-24 21:25:51 +0200 |
commit | 36099365c7cc64e5184b66b6eb094950a13f540c (patch) | |
tree | c91b9f3719f94864a62f2d15a71aaecd54c56711 /drivers/net/wireless/libertas | |
parent | qlcnic: multi protocol internal loopback support added. (diff) | |
parent | Bluetooth: include scatterlist.h where needed (diff) | |
download | linux-36099365c7cc64e5184b66b6eb094950a13f540c.tar.xz linux-36099365c7cc64e5184b66b6eb094950a13f540c.zip |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
drivers/net/wireless/rtlwifi/pci.c
include/linux/netlink.h
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r-- | drivers/net/wireless/libertas/if_sdio.c | 34 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/if_spi.c | 6 |
2 files changed, 37 insertions, 3 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 224e9853c480..387786e1b394 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -892,6 +892,37 @@ static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv) } +static struct mmc_host *reset_host; + +static void if_sdio_reset_card_worker(struct work_struct *work) +{ + /* + * The actual reset operation must be run outside of lbs_thread. This + * is because mmc_remove_host() will cause the device to be instantly + * destroyed, and the libertas driver then needs to end lbs_thread, + * leading to a deadlock. + * + * We run it in a workqueue totally independent from the if_sdio_card + * instance for that reason. + */ + + pr_info("Resetting card..."); + mmc_remove_host(reset_host); + mmc_add_host(reset_host); +} +static DECLARE_WORK(card_reset_work, if_sdio_reset_card_worker); + +static void if_sdio_reset_card(struct lbs_private *priv) +{ + struct if_sdio_card *card = priv->card; + + if (work_pending(&card_reset_work)) + return; + + reset_host = card->func->card->host; + schedule_work(&card_reset_work); +} + /*******************************************************************/ /* SDIO callbacks */ /*******************************************************************/ @@ -1065,6 +1096,7 @@ static int if_sdio_probe(struct sdio_func *func, priv->enter_deep_sleep = if_sdio_enter_deep_sleep; priv->exit_deep_sleep = if_sdio_exit_deep_sleep; priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; + priv->reset_card = if_sdio_reset_card; sdio_claim_host(func); @@ -1301,6 +1333,8 @@ static void __exit if_sdio_exit_module(void) /* Set the flag as user is removing this module. */ user_rmmod = 1; + cancel_work_sync(&card_reset_work); + sdio_unregister_driver(&if_sdio_driver); lbs_deb_leave(LBS_DEB_SDIO); diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 4fa0be9943f9..e0286cfbc91d 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -1034,7 +1034,6 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) static int if_spi_init_card(struct if_spi_card *card) { struct lbs_private *priv = card->priv; - struct spi_device *spi = card->spi; int err, i; u32 scratch; const struct firmware *helper = NULL; @@ -1082,8 +1081,9 @@ static int if_spi_init_card(struct if_spi_card *card) "attached to SPI bus_num %d, chip_select %d. " "spi->max_speed_hz=%d\n", card->card_id, card->card_rev, - spi->master->bus_num, spi->chip_select, - spi->max_speed_hz); + card->spi->master->bus_num, + card->spi->chip_select, + card->spi->max_speed_hz); err = if_spi_prog_helper_firmware(card, helper); if (err) goto out; |