summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c')
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c60
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 {