static int bcmsdh_sdmmc_resume(struct device *pdev) { #ifdef CONFIG_MACH_NOTLE struct sdio_func *func = dev_to_sdio_func(pdev); dev_err(pdev,"%s(%d) [%08x]\n",__func__, __LINE__,(unsigned int*) pdev); sd_err(("%s Enter\n", __FUNCTION__)); if (func->num != 2) return 0; bcmshd_resume_work_sdio_func = dev_to_sdio_func(pdev); queue_delayed_work(sdmmc_pm_workqueue, &bcmshd_resume_work, msecs_to_jiffies(0)); #else sdioh_info_t *sdioh; struct sdio_func *func = dev_to_sdio_func(pdev); sd_err(("%s Enter\n", __FUNCTION__)); if (func->num != 2) return 0; sdioh = sdio_get_drvdata(func); dhd_mmc_suspend = FALSE; #if defined(OOB_INTR_ONLY) bcmsdh_resume(sdioh->bcmsdh); #endif smp_mb(); #endif return 0; }
static int ath6kl_hifdev_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); int status = 0; struct hif_device *device; device = ath6kl_get_hifdev(func); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { /* set true first for PowerStateChangeNotify(..) */ device->is_suspend = true; status = osdrvCallbacks. deviceSuspendHandler(device->claimedContext); if (status) device->is_suspend = false; } CleanupHIFScatterResources(device); switch (status) { case 0: return 0; case A_EBUSY: /* Hack for kernel in order to support deep sleep and wow */ return -EBUSY; default: return -1; } }
static int wl1271_suspend(struct device *dev) { /* Tell MMC/SDIO core it's OK to power down the card * (if it isn't already), but not to remove it completely */ struct sdio_func *func = dev_to_sdio_func(dev); struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); struct wl1271 *wl = platform_get_drvdata(glue->core); mmc_pm_flag_t sdio_flags; int ret = 0; dev_dbg(dev, "wl1271 suspend. wow_enabled: %d\n", wl->wow_enabled); /* check whether sdio should keep power */ if (wl->wow_enabled) { sdio_flags = sdio_get_host_pm_caps(func); if (!(sdio_flags & MMC_PM_KEEP_POWER)) { dev_err(dev, "can't keep power while host " "is suspended\n"); ret = -EINVAL; goto out; } /* keep power while host suspended */ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) { dev_err(dev, "error while trying to keep power\n"); goto out; } } out: return ret; }
static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) { int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); struct mmc_card *card = func->card; ret = pm_runtime_get_sync(&card->dev); if (ret < 0) { pm_runtime_put_noidle(&card->dev); dev_err(glue->dev, "%s: failed to get_sync(%d)\n", __func__, ret); return ret; } sdio_claim_host(func); /* * To guarantee that the SDIO card is power cycled, as required to make * the FW programming to succeed, let's do a brute force HW reset. */ mmc_hw_reset(card->host); sdio_enable_func(func); sdio_release_host(func); return 0; }
static int bcmsdio_sdio_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); int ret = 0; printk(KERN_ERR "%s: FUNC Start\n" , __func__); ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) { printk(KERN_ERR "%s: Error Host doesn't support the keep power capability\n" , __func__); return ret; } if (bcmsdio_suspend_hldr) { printk(KERN_ERR "%s: Disable SDIO IRQ when driver is being suspended\n" , __func__); /* Disable SDIO IRQ when driver is being suspended */ bcmsdio_enable_sdio_irq(func, 0); ret = bcmsdio_suspend_hldr(func); if (ret) { printk(KERN_ERR "%s: BCM driver is not able to suspend\n" , __func__); /* Error - Restore SDIO IRQ */ bcmsdio_enable_sdio_irq(func, 1); return ret; } } printk(KERN_ERR "%s: FUNC End\n" , __func__); return sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); }
static int brcmf_sdio_suspend(struct device *dev) { mmc_pm_flag_t sdio_flags; struct brcmf_sdio_dev *sdiodev; struct sdio_func *func = dev_to_sdio_func(dev); int ret = 0; brcmf_dbg(TRACE, "\n"); sdiodev = dev_get_drvdata(&func->card->dev); atomic_set(&sdiodev->suspend, true); sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]); if (!(sdio_flags & MMC_PM_KEEP_POWER)) { brcmf_dbg(ERROR, "Host can't keep power while suspended\n"); return -EINVAL; } ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER); if (ret) { brcmf_dbg(ERROR, "Failed to set pm_flags\n"); return ret; } brcmf_sdio_wdtmr_enable(sdiodev, false); return ret; }
/** @brief This function handles client driver resume * * @param dev A pointer to device structure * @return BT_STATUS_SUCCESS */ int bt_sdio_resume(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); mmc_pm_flag_t pm_flags = 0; bt_private *priv = NULL; struct sdio_mmc_card *cardp; struct m_dev *m_dev = NULL; ENTER(); pm_flags = sdio_get_host_pm_caps(func); PRINTM(CMD, "BT: %s: resume: PM flags = 0x%x\n", sdio_func_id(func), pm_flags); cardp = sdio_get_drvdata(func); if (!cardp || !cardp->priv) { PRINTM(ERROR, "BT: Card or priv structure is not valid\n"); LEAVE(); return BT_STATUS_SUCCESS; } priv = cardp->priv; priv->adapter->is_suspended = FALSE; m_dev = &(priv->bt_dev.m_dev[BT_SEQ]); PRINTM(CMD, "BT %s: SDIO resume\n", m_dev->name); mbt_hci_resume_dev(m_dev); sbi_wakeup_firmware(priv); /* enable FM event mask */ if ((priv->bt_dev.m_dev[FM_SEQ].dev_type == FM_TYPE) && test_bit(HCI_RUNNING, &(priv->bt_dev.m_dev[FM_SEQ].flags))) fm_set_intr_mask(priv, FM_DEFAULT_INTR_MASK); priv->adapter->hs_state = HS_DEACTIVATED; PRINTM(CMD, "BT:%s: HS DEACTIVATED in Resume!\n", m_dev->name); LEAVE(); return BT_STATUS_SUCCESS; }
/* * SDIO resume. * * Kernel needs to suspend all functions separately. Therefore all * registered functions must have drivers with suspend and resume * methods. Failing that the kernel simply removes the whole card. * * If already not resumed, this function turns on the traffic and * sends a host sleep cancel request to the firmware. */ static int mwifiex_sdio_resume(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; if (func) { pm_flag = sdio_get_host_pm_caps(func); card = sdio_get_drvdata(func); if (!card || !card->adapter) { pr_err("resume: invalid card or adapter\n"); return 0; } } else { pr_err("resume: sdio_func is not specified\n"); return 0; } adapter = card->adapter; if (!adapter->is_suspended) { dev_warn(adapter->dev, "device already resumed\n"); return 0; } adapter->is_suspended = false; /* Disable Host Sleep */ mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), MWIFIEX_ASYNC_CMD); return 0; }
static int rtw_sdio_resume(struct device *dev) { struct sdio_func *func =dev_to_sdio_func(dev); struct dvobj_priv *psdpriv = sdio_get_drvdata(func); _adapter *padapter = psdpriv->padapter; struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; int ret = 0; if(pwrpriv->bInternalAutoSuspend ){ ret = rtw_resume_process(padapter); } else { #ifdef CONFIG_RESUME_IN_WORKQUEUE rtw_resume_in_workqueue(pwrpriv); #elif defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) if(rtw_is_earlysuspend_registered(pwrpriv)) { //jeff: bypass resume here, do in late_resume pwrpriv->do_late_resume = _TRUE; } else { ret = rtw_resume_process(padapter); } #else // Normal resume process ret = rtw_resume_process(padapter); #endif //CONFIG_RESUME_IN_WORKQUEUE } return ret; }
static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) { int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); struct mmc_card *card = func->card; ret = pm_runtime_get_sync(&card->dev); if (ret) { /* * Runtime PM might be temporarily disabled, or the device * might have a positive reference counter. Make sure it is * really powered on. */ ret = mmc_power_restore_host(card->host); if (ret < 0) { pm_runtime_put_sync(&card->dev); goto out; } } sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); out: return ret; }
/** @brief This function handles client driver shutdown * * @param dev A pointer to device structure * @return N/A */ void woal_sdio_shutdown(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); moal_handle *handle = NULL; struct sdio_mmc_card *cardp; mlan_ds_hs_cfg hscfg; int timeout = 0; int i; ENTER(); PRINTM(MCMND, "<--- Enter woal_sdio_shutdown --->\n"); cardp = sdio_get_drvdata(func); if (!cardp || !cardp->handle) { PRINTM(MERROR, "Card or moal_handle structure is not valid\n"); LEAVE(); return; } handle = cardp->handle; for (i = 0; i < handle->priv_num; i++) netif_device_detach(handle->priv[i]->netdev); if (shutdown_hs) { memset(&hscfg, 0, sizeof(mlan_ds_hs_cfg)); hscfg.is_invoke_hostcmd = MFALSE; hscfg.conditions = SHUTDOWN_HOST_SLEEP_DEF_COND; hscfg.gap = SHUTDOWN_HOST_SLEEP_DEF_GAP; hscfg.gpio = SHUTDOWN_HOST_SLEEP_DEF_GPIO; if (woal_set_get_hs_params (woal_get_priv(handle, MLAN_BSS_ROLE_ANY), MLAN_ACT_SET, MOAL_IOCTL_WAIT, &hscfg) == MLAN_STATUS_FAILURE) { PRINTM(MERROR, "Fail to set HS parameter in shutdown: 0x%x 0x%x 0x%x\n", hscfg.conditions, hscfg.gap, hscfg.gpio); goto done; } /* Enable Host Sleep */ handle->hs_activate_wait_q_woken = MFALSE; memset(&hscfg, 0, sizeof(mlan_ds_hs_cfg)); hscfg.is_invoke_hostcmd = MTRUE; if (woal_set_get_hs_params (woal_get_priv(handle, MLAN_BSS_ROLE_ANY), MLAN_ACT_SET, MOAL_NO_WAIT, &hscfg) == MLAN_STATUS_FAILURE) { PRINTM(MERROR, "Request HS enable failed in shutdown\n"); goto done; } timeout = wait_event_interruptible_timeout (handle->hs_activate_wait_q, handle->hs_activate_wait_q_woken, HS_ACTIVE_TIMEOUT); if (handle->hs_activated == MTRUE) PRINTM(MMSG, "HS actived in shutdown\n"); else PRINTM(MMSG, "Fail to enable HS in shutdown\n"); } done: PRINTM(MCMND, "<--- Leave woal_sdio_shutdown --->\n"); LEAVE(); return; }
static int bcmsdh_sdmmc_suspend(struct device *dev) { #ifdef CUSTOMER_HW_PT // for Sleep Current struct sdio_func *func = dev_to_sdio_func(dev); int ret = 0; printk("%s: \n",__func__); ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (!ret) ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); return ret; #else struct sdio_func *func = dev_to_sdio_func(dev); printk("%s: called\n", __FUNCTION__); return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); #endif }
static int hifDeviceResume(struct device *dev) { HIF_DEVICE *device; A_STATUS status = A_OK; struct sdio_func *func = dev_to_sdio_func(dev); device = getHifDevice(func); status = HIFDoDeviceResume(device); return A_SUCCESS(status) ? 0 : status; }
static void wl1271_sdio_set_block_size(struct device *child, unsigned int blksz) { struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); struct sdio_func *func = dev_to_sdio_func(glue->dev); sdio_claim_host(func); sdio_set_block_size(func, blksz); sdio_release_host(func); }
static int brcmf_sdio_resume(struct device *dev) { struct brcmf_sdio_dev *sdiodev; struct sdio_func *func = dev_to_sdio_func(dev); sdiodev = dev_get_drvdata(&func->card->dev); brcmf_sdio_wdtmr_enable(sdiodev, true); atomic_set(&sdiodev->suspend, false); return 0; }
static int bcmsdh_sdmmc_suspend(struct device *pdev) { struct sdio_func *func = dev_to_sdio_func(pdev); mmc_pm_flag_t sdio_flags; int ret = 0; 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 /* defined(OOB_INTR_ONLY) */ sdio_flags = sdio_get_host_pm_caps(func); if (!(sdio_flags & MMC_PM_KEEP_POWER)) { sd_err(("can't keep power while host " "is suspended\n", __FUNCTION__)); ret = -EINVAL; goto out; } /* keep power while host suspended */ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) { sd_err(("error while trying to keep power\n", __FUNCTION__)); goto out; } dhd_mmc_suspend = TRUE; smp_mb(); out: return ret; }
static int bcmsdh_sdmmc_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); //+++ PZ2224_yikyu 20120315 for abnormal sleep current sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); return 0; //---- PZ2224_yikyu 20120315 for abnormal sleep current //return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); }
/** @brief This function handles client driver suspend * * @param dev A pointer to device structure * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ int woal_sdio_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); mmc_pm_flag_t pm_flags = 0; moal_handle *handle = NULL; struct sdio_mmc_card *cardp; int i; int ret = MLAN_STATUS_SUCCESS; int hs_actived = 0; ENTER(); if (func) { pm_flags = sdio_get_host_pm_caps(func); PRINTM(MCMND, "%s: suspend: PM flags = 0x%x\n", sdio_func_id(func), pm_flags); if (!(pm_flags & MMC_PM_KEEP_POWER)) { PRINTM(MERROR, "%s: cannot remain alive while host is suspended\n", sdio_func_id(func)); LEAVE(); return -ENOSYS; } cardp = sdio_get_drvdata(func); if (!cardp || !cardp->handle) { PRINTM(MERROR, "Card or moal_handle structure is not valid\n"); LEAVE(); return MLAN_STATUS_SUCCESS; } } else { PRINTM(MERROR, "sdio_func is not specified\n"); LEAVE(); return MLAN_STATUS_SUCCESS; } handle = cardp->handle; if (pm_keep_power) { /* Enable the Host Sleep */ hs_actived = woal_enable_hs(woal_get_priv(handle, MLAN_BSS_TYPE_ANY)); if (hs_actived) { PRINTM(MCMND, "suspend with MMC_PM_KEEP_POWER\n"); ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); } } /* Indicate device suspended */ handle->is_suspended = MTRUE; for (i = 0; i < handle->priv_num; i++) netif_carrier_off(handle->priv[i]->netdev); LEAVE(); return ret; }
static int wl1271_suspend(struct device *dev) { /* Tell MMC/SDIO core it's OK to power down the card * (if it isn't already), but not to remove it completely */ struct sdio_func *func = dev_to_sdio_func(dev); struct wl1271 *wl = sdio_get_drvdata(func); mmc_pm_flag_t sdio_flags; unsigned long flags; bool abort; int ret = 0; /* * if there is a pending irq work, we should abort the suspension. * (irq might come between mac80211 suspension and our suspension) * TODO: maybe remove it, since system will wake up anyway? */ spin_lock_irqsave(&wl->wl_lock, flags); abort = !!test_bit(WL1271_FLAG_PENDING_WORK, &wl->flags); spin_unlock_irqrestore(&wl->wl_lock, flags); if (abort) { wl1271_info("pending irq work - aborting suspend"); return -EBUSY; } /* * we need to look into wl to tell which suspend method to use. * we will have full power, ps mode, elp, and power off */ wl1271_info("%s: wow_enabled: %d", __func__, wl->wow_enabled); if (wl->wow_enabled) { sdio_flags = sdio_get_host_pm_caps(func); wl1271_info("suspend PM flags = 0x%x", sdio_flags); if (!(sdio_flags & MMC_PM_KEEP_POWER)) { wl1271_error("can't keep power while host " "is suspended"); goto power_off; } /* keep power while host suspended */ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) { wl1271_error("error while trying to keep power"); goto power_off; } /* release host */ sdio_release_host(func); } power_off: return 0; }
/** @brief This function handles client driver suspend * * @param dev A pointer to device structure * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ int bt_sdio_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); mmc_pm_flag_t pm_flags = 0; bt_private *priv = NULL; struct sdio_mmc_card *cardp; struct hci_dev *hcidev; ENTER(); if (func) { pm_flags = sdio_get_host_pm_caps(func); PRINTM(CMD, "%s: suspend: PM flags = 0x%x\n", sdio_func_id(func), pm_flags); if (!(pm_flags & MMC_PM_KEEP_POWER)) { PRINTM(ERROR, "%s: cannot remain alive while host is suspended\n", sdio_func_id(func)); return -ENOSYS; } cardp = sdio_get_drvdata(func); if (!cardp || !cardp->priv) { PRINTM(ERROR, "Card or priv structure is not valid\n"); LEAVE(); return BT_STATUS_SUCCESS; } } else { PRINTM(ERROR, "sdio_func is not specified\n"); LEAVE(); return BT_STATUS_SUCCESS; } PRINTM(CMD, "SDIO suspend\n"); priv = cardp->priv; if ((pm_keep_power) && (priv->adapter->hs_state != HS_ACTIVATED)) bt_enable_hs(priv); hcidev = priv->bt_dev.hcidev; hci_suspend_dev(hcidev); skb_queue_purge(&priv->adapter->tx_queue); LEAVE(); /* We will keep the power when hs enabled successfully */ if ((pm_keep_power) && (priv->adapter->hs_state == HS_ACTIVATED)) #ifdef MMC_PM_SKIP_RESUME_PROBE return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER | MMC_PM_SKIP_RESUME_PROBE); #else return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); #endif else return BT_STATUS_SUCCESS;
static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) { struct sdio_func *func = dev_to_sdio_func(glue->dev); struct mmc_card *card = func->card; sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); /* Let runtime PM know the card is powered off */ pm_runtime_put(&card->dev); return 0; }
static int wl1271_resume(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); struct wl1271 *wl = sdio_get_drvdata(func); wl1271_debug(DEBUG_MAC80211, "wl1271 resume"); if (wl->wow_enabled) { /* claim back host */ sdio_claim_host(func); } return 0; }
static int bcmsdh_sdmmc_resume(struct device *pdev) { struct sdio_func *func = dev_to_sdio_func(pdev); if (func->num != 2) return 0; dhd_mmc_suspend = FALSE; #if defined(OOB_INTR_ONLY) if (dhd_os_check_if_up(bcmsdh_get_drvdata())) bcmsdh_oob_intr_set(1); #endif smp_mb(); return 0; }
static int bcmsdh_sdmmc_resume(struct device *pdev) { #if defined(OOB_INTR_ONLY) struct sdio_func *func = dev_to_sdio_func(pdev); #endif sd_trace(("%s Enter\n", __FUNCTION__)); dhd_mmc_suspend = FALSE; #if defined(OOB_INTR_ONLY) if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata())) bcmsdh_oob_intr_set(1); #endif smp_mb(); return 0; }
/* * SDIO suspend. * * Kernel needs to suspend all functions separately. Therefore all * registered functions must have drivers with suspend and resume * methods. Failing that the kernel simply removes the whole card. * * If already not suspended, this function allocates and sends a host * sleep activate request to the firmware and turns off the traffic. */ static int mwifiex_sdio_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; int i; int ret = 0; if (func) { pm_flag = sdio_get_host_pm_caps(func); pr_debug("cmd: %s: suspend: PM flag = 0x%x\n", sdio_func_id(func), pm_flag); if (!(pm_flag & MMC_PM_KEEP_POWER)) { pr_err("%s: cannot remain alive while host is" " suspended\n", sdio_func_id(func)); return -ENOSYS; } card = sdio_get_drvdata(func); if (!card || !card->adapter) { pr_err("suspend: invalid card or adapter\n"); return 0; } } else { pr_err("suspend: sdio_func is not specified\n"); return 0; } adapter = card->adapter; /* Enable the Host Sleep */ if (!mwifiex_enable_hs(adapter)) { dev_err(adapter->dev, "cmd: failed to suspend\n"); return -EFAULT; } dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n"); ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); /* Indicate device suspended */ adapter->is_suspended = true; for (i = 0; i < adapter->priv_num; i++) netif_carrier_off(adapter->priv[i]->netdev); return ret; }
static int cw1200_sdio_suspend(struct device *dev) { int ret; struct sdio_func *func = dev_to_sdio_func(dev); struct hwbus_priv *self = sdio_get_drvdata(func); if (!cw1200_can_suspend(self->core)) return -EAGAIN; /* Notify SDIO that CW1200 will remain powered during suspend */ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) pr_err("Error setting SDIO pm flags: %i\n", ret); return ret; }
static int bcmsdio_sdio_resume(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); printk(KERN_ERR "%s: FUNC Start\n" , __func__); if (bcmsdio_resume_hldr) { bcmsdio_resume_hldr(func); printk(KERN_ERR "%s: Restore SDIO IRQ\n" , __func__); /* Restore SDIO IRQ */ bcmsdio_enable_sdio_irq(func, 1); } printk(KERN_ERR "%s: FUNC End\n" , __func__); return 0; }
static int bcmsdh_sdmmc_suspend(struct device *pdev) { struct sdio_func *func = dev_to_sdio_func(pdev); if (func->num != 2) return 0; if (dhd_os_check_wakelock(bcmsdh_get_drvdata())) return -EBUSY; #if defined(OOB_INTR_ONLY) bcmsdh_oob_intr_set(0); #endif dhd_mmc_suspend = TRUE; smp_mb(); return 0; }
static int bcmsdh_sdmmc_suspend(struct device *pdev) { int err; sdioh_info_t *sdioh; struct sdio_func *func = dev_to_sdio_func(pdev); mmc_pm_flag_t sdio_flags; sd_err(("%s +\n", __FUNCTION__)); if (func->num != 2) return 0; sdioh = sdio_get_drvdata(func); err = bcmsdh_suspend(sdioh->bcmsdh); if (err){ sd_err(("%s -\n", __FUNCTION__)); return err; } 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__)); sd_err(("%s -\n", __FUNCTION__)); return -EINVAL; } /* keep power while host suspended */ err = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (err) { sd_err(("%s: error while trying to keep power\n", __FUNCTION__)); sd_err(("%s -\n", __FUNCTION__)); return err; } #if defined(OOB_INTR_ONLY) #ifndef HW_WIFI_OOB_INT_SET bcmsdh_oob_intr_set(sdioh->bcmsdh, FALSE); #endif #endif dhd_mmc_suspend = TRUE; #ifdef HW_WIFI_WAKEUP_SRC_PARSE g_wifi_firstwake = TRUE; #endif smp_mb(); sd_err(("%s -\n", __FUNCTION__)); return 0; }
static int hifDeviceSuspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); A_STATUS status = A_OK; HIF_DEVICE *device; device = getHifDevice(func); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext); } if (status == A_OK) { int oldresetvalue = reset_sdio_on_unload; reset_sdio_on_unload = 1; hifDisableFunc(device, func); reset_sdio_on_unload = oldresetvalue; device->is_suspend = TRUE; } else if (status == A_EBUSY) { A_INT32 cnt = 10; A_UINT8 host_int_status; do { while (atomic_read(&device->irqHandling)) { /* wait until irq handler finished all the jobs */ schedule_timeout(HZ/10); } /* check if there is any pending irq due to force done */ host_int_status = 0; status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS, (A_UINT8 *)&host_int_status, sizeof(host_int_status), HIF_RD_SYNC_BYTE_INC, NULL); host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)) : 0; if (host_int_status) { schedule(); /* schedule for next dsrHandler */ } } while (host_int_status && --cnt > 0); if (host_int_status && cnt == 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__)); } #if 1 status = A_OK; /* assume that sdio host controller will take care the power of wifi chip */ #else return -EBUSY; /* Return -EBUSY if customer use all android patch of mmc stack provided by us */ #endif } return A_SUCCESS(status) ? 0 : status; }