Ejemplo n.º 1
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 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;
}
Ejemplo n.º 3
0
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 	   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;
Ejemplo n.º 5
0
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;
}
static int brcmf_sdio_suspend(struct device *dev)
{
	mmc_pm_flag_t sdio_flags;
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
	int ret = 0;

	brcmf_dbg(SDIO, "\n");

	atomic_set(&sdiodev->suspend, true);

	sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
	if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
		brcmf_err("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_err("Failed to set pm_flags\n");
		return ret;
	}

	brcmf_sdio_wdtmr_enable(sdiodev, false);

	return ret;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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 	
}
Ejemplo n.º 9
0
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 	   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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
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 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;
}
Ejemplo n.º 14
0
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.
	 * due to some mmc layer issues, the system automatically
	 * powers us up on resume, which later cause issues when
	 * we try to restore_power again explicitly.
	 * workaround it by always asking to keep power. this is
	 * fine as the driver controls the chip power anyway.
	 * TODO: remove it when mmc issue is fixed.
	 */
	if (true || 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;
}
Ejemplo n.º 15
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 Enter\n", __FUNCTION__));
	if (func->num != 2)
		return 0;

	dhd_mmc_suspend = TRUE;
	sdioh = sdio_get_drvdata(func);
	err = bcmsdh_suspend(sdioh->bcmsdh);
	if (err) {
		dhd_mmc_suspend = FALSE;
		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__));
		dhd_mmc_suspend = FALSE;
		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__));
		dhd_mmc_suspend = FALSE;
		return err;
	}
#if defined(OOB_INTR_ONLY) && !defined(CUSTOMER_HW4)
	bcmsdh_oob_intr_set(sdioh->bcmsdh, FALSE);
#endif /* OOB_INTR_ONLY && !CUSTOMER_HW4 */
	smp_mb();

	return 0;
}
Ejemplo n.º 16
0
static int esp_sdio_suspend(struct device *dev)
{
    //#define dev_to_sdio_func(d)     container_of(d, struct sdio_func, dev)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
    struct sdio_func *func = dev_to_sdio_func(dev);
#else
    struct sdio_func *func = container_of(dev, struct sdio_func, dev);
#endif
	struct esp_sdio_ctrl *sctrl = sdio_get_drvdata(func);
	struct esp_pub *epub = sctrl->epub;	

        printk("%s", __func__);
#if 0
	sip_send_suspend_config(epub, 1);
#endif
	atomic_set(&epub->ps.state, ESP_PM_ON);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34))
    do{
        u32 sdio_flags = 0;
        int ret = 0;
        sdio_flags = sdio_get_host_pm_caps(func);

        if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
            printk("%s can't keep power while host is suspended\n", __func__);
        }

        /* keep power while host suspended */
        ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
        if (ret) {
                printk("%s error while trying to keep power\n", __func__);
        }
    }while(0);
#endif


        return 0;

}
Ejemplo n.º 17
0
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;
	int ret = 0;

	wl1271_debug(DEBUG_MAC80211, "wl1271 suspend. wow_enabled: %d",
		     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)) {
			wl1271_error("can't keep power while host "
				     "is suspended");
			ret = -EINVAL;
			goto out;
		}

		printk("\n\nSetting MMC_PM_KEEP_POWER\n");
		/* 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 out;
		}

		/* release host */
		sdio_release_host(func);
	}
out:
	return ret;
}
Ejemplo n.º 18
0
/**  @brief This function handles client driver suspend
 *
 *  @param dev      A pointer to device structure
 *  @return         MLAN_STATUS_SUCCESS or error code
 */
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, retry_num = 8;
	int ret = MLAN_STATUS_SUCCESS;
	int hs_actived = 0;
	mlan_ds_ps_info pm_info;

	ENTER();
	PRINTM(MCMND, "<--- Enter woal_sdio_suspend --->\n");
	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;
	}

	handle = cardp->handle;
	if (handle->is_suspended == MTRUE) {
		PRINTM(MWARN, "Device already suspended\n");
		LEAVE();
		return MLAN_STATUS_SUCCESS;
	}
	if (handle->fw_dump) {
		PRINTM(MMSG, "suspend not allowed while FW dump!");
		ret = -EBUSY;
		goto done;
	}
	handle->suspend_fail = MFALSE;
	memset(&pm_info, 0, sizeof(pm_info));
	for (i = 0; i < retry_num; i++) {
		if (MLAN_STATUS_SUCCESS ==
		    woal_get_pm_info(woal_get_priv(handle, MLAN_BSS_ROLE_ANY),
				     &pm_info)) {
			if (pm_info.is_suspend_allowed == MTRUE)
				break;
			else
				PRINTM(MMSG,
				       "Suspend not allowed and retry again\n");
		}
		woal_sched_timeout(100);
	}
	if (pm_info.is_suspend_allowed == MFALSE) {
		PRINTM(MMSG, "Suspend not allowed\n");
		ret = -EBUSY;
		goto done;
	}

	for (i = 0; i < handle->priv_num; i++)
		netif_device_detach(handle->priv[i]->netdev);

	if (pm_keep_power) {
		/* Enable the Host Sleep */
#ifdef MMC_PM_FUNC_SUSPENDED
		handle->suspend_notify_req = MTRUE;
#endif
		hs_actived =
			woal_enable_hs(woal_get_priv
				       (handle, MLAN_BSS_ROLE_ANY));
#ifdef MMC_PM_FUNC_SUSPENDED
		handle->suspend_notify_req = MFALSE;
#endif
		if (hs_actived) {
#ifdef MMC_PM_SKIP_RESUME_PROBE
			PRINTM(MCMND,
			       "suspend with MMC_PM_KEEP_POWER and MMC_PM_SKIP_RESUME_PROBE\n");
			ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER |
						     MMC_PM_SKIP_RESUME_PROBE);
#else
			PRINTM(MCMND, "suspend with MMC_PM_KEEP_POWER\n");
			ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
#endif
		} else {
			PRINTM(MMSG, "HS not actived, suspend fail!");
			handle->suspend_fail = MTRUE;
			for (i = 0; i < handle->priv_num; i++)
				netif_device_attach(handle->priv[i]->netdev);
			ret = -EBUSY;
			goto done;
		}
	}

	/* Indicate device suspended */
	handle->is_suspended = MTRUE;
done:
	PRINTM(MCMND, "<--- Leave woal_sdio_suspend --->\n");
	LEAVE();
	return ret;
}
Ejemplo n.º 19
0
static int __devinit wl1271_probe(struct sdio_func *func,
				  const struct sdio_device_id *id)
{
	struct ieee80211_hw *hw;
	const struct wl12xx_platform_data *wlan_data;
	struct wl1271 *wl;
	unsigned long irqflags;
	int ret;

	/* We are only able to handle the wlan function */
	if (func->num != 0x02)
		return -ENODEV;

	hw = wl1271_alloc_hw();
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	wl = hw->priv;

	wl->if_priv = func;
	wl->if_ops = &sdio_ops;

	/* Grab access to FN0 for ELP reg. */
	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;

	/* Use block mode for transferring over one block size of data */
	//func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;

	wlan_data = wl12xx_get_platform_data();
	if (IS_ERR(wlan_data)) {
		ret = PTR_ERR(wlan_data);
		wl1271_error("missing wlan platform data: %d", ret);
		goto out_free;
	}

	wl->irq = wlan_data->irq;
	if (wl->ref_clock < 0)
		wl->ref_clock = wlan_data->board_ref_clock;
	if (wl->tcxo_clock < 0)
		wl->tcxo_clock = wlan_data->board_tcxo_clock;
	wl->platform_quirks = wlan_data->platform_quirks;

	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
		irqflags = IRQF_TRIGGER_RISING;
	else
		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;

	ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
				   irqflags,
				   DRIVER_NAME, wl);
	if (ret < 0) {
		wl1271_error("request_irq() failed: %d", ret);
		goto out_free;
	}

	disable_irq(wl->irq);

	sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);

	ret = wl1271_init_ieee80211(wl);
	if (ret)
		goto out_irq;

	ret = wl1271_register_hw(wl);
	if (ret)
		goto out_irq;

	sdio_set_drvdata(func, wl);

	/* Tell PM core that we don't need the card to be powered now */
	pm_runtime_put_noidle(&func->dev);
	mmc_power_save_host(func->card->host);

	return 0;

 out_irq:
	free_irq(wl->irq, wl);

 out_free:
	wl1271_free_hw(wl);

	return ret;
}
Ejemplo n.º 20
0
/** @brief This function handles client driver suspend
 *
 *  @param dev	   A pointer to device structure
 *  @return        BT_STATUS_SUCCESS or other error no.
 */
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 m_dev *m_dev = NULL;

	ENTER();

	pm_flags = sdio_get_host_pm_caps(func);
	PRINTM(CMD, "BT: %s: suspend: PM flags = 0x%x\n", sdio_func_id(func),
	       pm_flags);
	if (!(pm_flags & MMC_PM_KEEP_POWER)) {
		PRINTM(ERROR,
		       "BT: %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, "BT: Card or priv structure is not valid\n");
		LEAVE();
		return BT_STATUS_SUCCESS;
	}

	priv = cardp->priv;

	if ((mbt_pm_keep_power) && (priv->adapter->hs_state != HS_ACTIVATED)) {
		/* disable 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_DISABLE_INTR_MASK);
		if (BT_STATUS_SUCCESS != bt_enable_hs(priv)) {
			PRINTM(CMD, "BT: HS not actived, suspend fail!\n");
			if (BT_STATUS_SUCCESS != bt_enable_hs(priv)) {
				PRINTM(CMD,
				       "BT: HS not actived the second time, force to suspend!\n");
			}
		}
	}
	m_dev = &(priv->bt_dev.m_dev[BT_SEQ]);
	PRINTM(CMD, "BT %s: SDIO suspend\n", m_dev->name);
	mbt_hci_suspend_dev(m_dev);
	skb_queue_purge(&priv->adapter->tx_queue);

	priv->adapter->is_suspended = TRUE;

	LEAVE();
	/* We will keep the power when hs enabled successfully */
	if ((mbt_pm_keep_power) && (priv->adapter->hs_state == HS_ACTIVATED)) {
#ifdef MMC_PM_SKIP_RESUME_PROBE
		PRINTM(CMD, "BT: suspend with MMC_PM_KEEP_POWER and "
		       "MMC_PM_SKIP_RESUME_PROBE\n");
		return sdio_set_host_pm_flags(func,
					      MMC_PM_KEEP_POWER |
					      MMC_PM_SKIP_RESUME_PROBE);
#else
		PRINTM(CMD, "BT: suspend with MMC_PM_KEEP_POWER\n");
		return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
#endif
	} else {
		PRINTM(CMD, "BT: suspend without MMC_PM_KEEP_POWER\n");
		return BT_STATUS_SUCCESS;
	}
}