Exemplo n.º 1
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;
    mbt_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;
Exemplo n.º 2
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;
	}
}