/* Helper function */
void *brcmf_sdcard_get_sdioh(struct brcmf_sdio *sdh);
+/* Watchdog timer interface for pm ops */
+extern void brcmf_sdio_wdtmr_enable(bool enable);
+
#endif /* _sdio_api_h_ */
extern uint sd_f2_blocksize;
module_param(sd_f2_blocksize, int, 0);
+
+void brcmf_sdio_wdtmr_enable(bool enable)
+{
+ if (enable)
+ brcmf_os_wd_timer(sdhcinfo->ch, brcmf_watchdog_ms);
+ else
+ brcmf_os_wd_timer(sdhcinfo->ch, 0);
+}
int brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr,
int regsize, u32 *data);
-void brcmf_sdioh_set_host_pm_flags(int flag)
-{
- if (sdio_set_host_pm_flags(gInstance->func[1], flag))
- printk(KERN_ERR "%s: Failed to set pm_flags 0x%08x\n",\
- __func__, (unsigned int)flag);
-}
-
static int brcmf_sdioh_enablefuncs(struct sdioh_info *sd)
{
int err_ret;
MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
+#ifdef CONFIG_PM
+static int brcmf_sdio_suspend(struct device *dev)
+{
+ mmc_pm_flag_t sdio_flags;
+ int ret = 0;
+
+ sd_trace(("%s\n", __func__));
+
+ sdio_flags = sdio_get_host_pm_caps(gInstance->func[1]);
+ if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
+ sd_err(("Host can't keep power while suspended\n"));
+ return -EINVAL;
+ }
+
+ ret = sdio_set_host_pm_flags(gInstance->func[1], MMC_PM_KEEP_POWER);
+ if (ret) {
+ sd_err(("Failed to set pm_flags\n"));
+ return ret;
+ }
+
+ brcmf_sdio_wdtmr_enable(false);
+
+ return ret;
+}
+
+static int brcmf_sdio_resume(struct device *dev)
+{
+ brcmf_sdio_wdtmr_enable(true);
+ return 0;
+}
+
+static const struct dev_pm_ops brcmf_sdio_pm_ops = {
+ .suspend = brcmf_sdio_suspend,
+ .resume = brcmf_sdio_resume,
+};
+#endif /* CONFIG_PM */
+
static struct sdio_driver bcmsdh_sdmmc_driver = {
.probe = brcmf_ops_sdio_probe,
.remove = brcmf_ops_sdio_remove,
.name = "brcmfmac",
.id_table = bcmsdh_sdmmc_ids,
+#ifdef CONFIG_PM
+ .drv = {
+ .pm = &brcmf_sdio_pm_ops,
+ },
+#endif /* CONFIG_PM */
};
struct sdos_info {
return pend;
}
-void brcmf_netdev_os_wd_timer(struct net_device *ndev, uint wdtick)
-{
- dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(ndev);
-
- brcmf_os_wd_timer(&dhd->pub, wdtick);
-}
-
#ifdef BCMDBG
int brcmf_write_to_file(dhd_pub_t *dhd, u8 *buf, int size)
{
#include "dhd.h"
#include "wl_cfg80211.h"
-void brcmf_sdioh_set_host_pm_flags(int flag);
-
static struct sdio_func *cfg80211_sdio_func;
static struct wl_dev *wl_cfg80211_dev;
static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
static s32 wl_cfg80211_resume(struct wiphy *wiphy)
{
struct wl_priv *wl = wiphy_to_wl(wiphy);
- struct net_device *ndev = wl_to_ndev(wl);
/*
* Check for WL_STATUS_READY before any function call which
atomic_set(&brcmf_mmc_suspend, false);
#endif /* defined(CONFIG_PM_SLEEP) */
- if (test_bit(WL_STATUS_READY, &wl->status)) {
- /* Turn on Watchdog timer */
- brcmf_netdev_os_wd_timer(ndev, brcmf_watchdog_ms);
+ if (test_bit(WL_STATUS_READY, &wl->status))
wl_invoke_iscan(wiphy_to_wl(wiphy));
- }
WL_TRACE("Exit\n");
return 0;
clear_bit(WL_STATUS_SCANNING, &wl->status);
clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
- /* Inform SDIO stack not to switch off power to the chip */
- brcmf_sdioh_set_host_pm_flags(MMC_PM_KEEP_POWER);
-
/* Turn off watchdog timer */
if (test_bit(WL_STATUS_READY, &wl->status)) {
- WL_INFO("Terminate watchdog timer and enable MPC\n");
+ WL_INFO("Enable MPC\n");
wl_set_mpc(ndev, 1);
- brcmf_netdev_os_wd_timer(ndev, 0);
}
#if defined(CONFIG_PM_SLEEP)
the dongle */
extern s8 *wl_cfg80211_get_nvramname(void); /* get nvram name for
the dongle */
-extern void brcmf_netdev_os_wd_timer(struct net_device *ndev, uint wdtick);
-
#endif /* _wl_cfg80211_h_ */