diff options
Diffstat (limited to 'drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c')
-rw-r--r-- | drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c index 1a370862b334..656953939b71 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdh_sdmmc_linux.c,v 1.8.6.2 2011-02-01 18:38:36 Exp $ + * $Id: bcmsdh_sdmmc_linux.c 312783 2012-02-03 22:53:56Z $ */ #include <typedefs.h> @@ -55,13 +55,22 @@ #if !defined(SDIO_DEVICE_ID_BROADCOM_4330) #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 #endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4330) */ +#if !defined(SDIO_DEVICE_ID_BROADCOM_4334) +#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 +#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4334) */ +#if !defined(SDIO_DEVICE_ID_BROADCOM_4324) +#define SDIO_DEVICE_ID_BROADCOM_4324 0x4324 +#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4324) */ +#if !defined(SDIO_DEVICE_ID_BROADCOM_43239) +#define SDIO_DEVICE_ID_BROADCOM_43239 43239 +#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_43239) */ #include <bcmsdh_sdmmc.h> #include <dhd_dbg.h> #ifdef WL_CFG80211 -extern void wl_cfg80211_set_sdio_func(void *func); +extern void wl_cfg80211_set_parent_dev(void *dev); #endif extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); @@ -118,7 +127,7 @@ static int bcmsdh_sdmmc_probe(struct sdio_func *func, if (func->num == 2) { #ifdef WL_CFG80211 - wl_cfg80211_set_sdio_func(func); + wl_cfg80211_set_parent_dev(&func->dev); #endif sd_trace(("F2 found, calling bcmsdh_probe_bcmdhd...\n")); ret = bcmsdh_probe_bcmdhd(&func->dev); @@ -153,12 +162,15 @@ static const struct sdio_device_id bcmsdh_sdmmc_ids[] = { { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) }, { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) }, { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330) }, + { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334) }, + { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4324) }, + { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43239) }, { /* end: all zeroes */ }, }; MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) static int bcmsdh_sdmmc_suspend(struct device *pdev) { struct sdio_func *func = dev_to_sdio_func(pdev); @@ -167,12 +179,30 @@ static int bcmsdh_sdmmc_suspend(struct device *pdev) if (func->num != 2) return 0; + + sd_trace(("%s Enter\n", __FUNCTION__)); + if (dhd_os_check_wakelock(bcmsdh_get_drvdata())) return -EBUSY; + + + sdio_flags = sdio_get_host_pm_caps(func); + + if (!(sdio_flags & MMC_PM_KEEP_POWER)) { + sd_err(("%s: can't keep power while host is suspended\n", __FUNCTION__)); + return -EINVAL; + } + + /* keep power while host suspended */ + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + if (ret) { + sd_err(("%s: error while trying to keep power\n", __FUNCTION__)); + return ret; + } + #if defined(OOB_INTR_ONLY) bcmsdh_oob_intr_set(0); -#endif - smp_mb(); +#endif /* defined(OOB_INTR_ONLY) */ sdio_flags = sdio_get_host_pm_caps(func); @@ -191,6 +221,7 @@ static int bcmsdh_sdmmc_suspend(struct device *pdev) } dhd_mmc_suspend = TRUE; + smp_mb(); out: return ret; @@ -198,15 +229,16 @@ out: static int bcmsdh_sdmmc_resume(struct device *pdev) { +#if defined(OOB_INTR_ONLY) struct sdio_func *func = dev_to_sdio_func(pdev); - - if (func->num != 2) - return 0; +#endif + sd_trace(("%s Enter\n", __FUNCTION__)); dhd_mmc_suspend = FALSE; #if defined(OOB_INTR_ONLY) - if (dhd_os_check_if_up(bcmsdh_get_drvdata())) + if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata())) bcmsdh_oob_intr_set(1); -#endif +#endif /* (OOB_INTR_ONLY) */ + smp_mb(); return 0; } @@ -215,18 +247,18 @@ static const struct dev_pm_ops bcmsdh_sdmmc_pm_ops = { .suspend = bcmsdh_sdmmc_suspend, .resume = bcmsdh_sdmmc_resume, }; -#endif +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */ static struct sdio_driver bcmsdh_sdmmc_driver = { .probe = bcmsdh_sdmmc_probe, .remove = bcmsdh_sdmmc_remove, .name = "bcmsdh_sdmmc", .id_table = bcmsdh_sdmmc_ids, -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) .drv = { .pm = &bcmsdh_sdmmc_pm_ops, }, -#endif +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */ }; struct sdos_info { |