Пример #1
0
/**
 *	mmc_suspend_host - suspend a host
 *	@host: mmc host
 *	@state: suspend mode (PM_SUSPEND_xxx)
 */
int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
{
	int err = 0;

	if (mmc_bus_needs_resume(host))
		return 0;

	if (host->caps & MMC_CAP_DISABLE)
		cancel_delayed_work(&host->disable);

	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
		if (host->bus_ops->suspend)
			err = host->bus_ops->suspend(host);
	}
	mmc_bus_put(host);

	if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
		mmc_power_off(host);

	return err;
}
Пример #2
0
/**
 *	mmc_suspend_host - suspend a host
 *	@host: mmc host
 */
int mmc_suspend_host(struct mmc_host *host)
{
	int err = 0;

	if (mmc_bus_needs_resume(host))
		return 0;

	if (host->caps & MMC_CAP_DISABLE)
		cancel_delayed_work(&host->disable);
	if (unlikely(cancel_delayed_work(&host->detect)))	{
		atomic_dec(&wakelock_refs);
	}
	mmc_flush_scheduled_work();

	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
		if (host->bus_ops->suspend)
			err = host->bus_ops->suspend(host);
		if (err == -ENOSYS || !host->bus_ops->resume) {
			/*
			 * We simply "remove" the card in this case.
			 * It will be redetected on resume.
			 */
			if (host->bus_ops->remove)
				host->bus_ops->remove(host);
			mmc_claim_host(host);
			mmc_detach_bus(host);
			mmc_release_host(host);
			host->pm_flags = 0;
			err = 0;
		}
	}
	mmc_bus_put(host);

	if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
		mmc_power_off(host);

	return err;
}
Пример #3
0
int mmc_resume_bus(struct mmc_host *host)
{
	unsigned long flags;
	int err = 0;

	if (!mmc_bus_needs_resume(host))
		return -EINVAL;

	printk("%s: Starting deferred resume\n", mmc_hostname(host));
	spin_lock_irqsave(&host->lock, flags);
	host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;
	host->rescan_disable = 0;
	spin_unlock_irqrestore(&host->lock, flags);

	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
		mmc_power_up(host);
		BUG_ON(!host->bus_ops->resume);
		err = host->bus_ops->resume(host);
	}

#ifdef CONFIG_MACH_P1
	if (!err) {
#endif /* CONFIG_MACH_P1 */
	if (host->bus_ops->detect && !host->bus_dead)
		host->bus_ops->detect(host);
#ifdef CONFIG_MACH_P1
	} else {
		printk(KERN_WARNING "%s: error %d during resume "
					"(card was removed?)\n",
					mmc_hostname(host), err);
	}
#endif /* CONFIG_MACH_P1 */

	mmc_bus_put(host);
	printk("%s: Deferred resume completed\n", mmc_hostname(host));
	return err;
}
Пример #4
0
int mmc_resume_bus(struct mmc_host *host)
{
	if (!mmc_bus_needs_resume(host))
		return -EINVAL;

	printk("%s: Starting deferred resume\n", mmc_hostname(host));
	host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;
	mmc_bus_get(host);
	if (host->bus_ops) {
		if (!host->bus_dead) {
		mmc_power_up(host);
		BUG_ON(!host->bus_ops->resume);
		host->bus_ops->resume(host);
	}

	if (host->bus_ops->detect && !host->bus_dead)
		host->bus_ops->detect(host);
	}

	mmc_bus_put(host);
	printk("%s: Deferred resume completed\n", mmc_hostname(host));
	return 0;
}
Пример #5
0
/**
 *	mmc_suspend_host - suspend a host
 *	@host: mmc host
 *	@state: suspend mode (PM_SUSPEND_xxx)
 */
int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
{
	int err = 0;

	if (mmc_bus_needs_resume(host))
		return 0;

	if (host->caps & MMC_CAP_DISABLE)
		cancel_delayed_work(&host->disable);
	cancel_delayed_work(&host->detect);
	mmc_flush_scheduled_work();

	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
		if (host->bus_ops->suspend)
			err = host->bus_ops->suspend(host);
		if (err == -ENOSYS || !host->bus_ops->resume) {
			/*
			 * We simply "remove" the card in this case.
			 * It will be redetected on resume.
			 */
			if (host->bus_ops->remove)
				host->bus_ops->remove(host);
			mmc_claim_host(host);
			mmc_detach_bus(host);
			mmc_release_host(host);
			err = 0;
		}
	}
	mmc_bus_put(host);
	mmc_flush_scheduled_work();

	if (!err)
		mmc_power_off(host);

	return err;
}
/**
 *	mmc_suspend_host - suspend a host
 *	@host: mmc host
 */
int mmc_suspend_host(struct mmc_host *host)
{
	int err = 0;

	if (mmc_bus_needs_resume(host))
		return 0;

	if (host->caps & MMC_CAP_DISABLE)
		cancel_delayed_work(&host->disable);
	cancel_delayed_work(&host->detect);
	mmc_flush_scheduled_work();

	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
		if (host->bus_ops->suspend)
			err = host->bus_ops->suspend(host);
	}
	mmc_bus_put(host);

#ifndef CONFIG_WILINK_NLCP 
	if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
#else
	if (!err && !mmc_card_keep_power(host))
#endif 	
		{
		if(suspend_debug)
			printk("P off  mmc \n");

		mmc_power_off(host);

		}

       if(host->nesting_cnt < 0)                    // Mahesh non line fetch patch
		host->nesting_cnt = 0;

	return err;
}
Пример #7
0
/**
 *	mmc_suspend_host - suspend a host
 *	@host: mmc host
 *	@state: suspend mode (PM_SUSPEND_xxx)
 */
int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
{
	int err = 0;

	if (mmc_bus_needs_resume(host))
		return 0;

	//B: Robert, 20101006, KB62_CR766 : Fix unexpectedly remove SD card issue
	cancel_delayed_work(&host->detect);
	mmc_flush_scheduled_work();
	//E: Robert, 20101006, KB62_CR766

	if (host->caps & MMC_CAP_DISABLE)
		cancel_delayed_work(&host->disable);

	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
		if (host->bus_ops->suspend)
			err = host->bus_ops->suspend(host);
		//B: Robert, 20101006, KB62_CR766 : Fix unexpectedly remove SD card issue
		if (!host->bus_ops->resume) {
			if (host->bus_ops->remove)
				host->bus_ops->remove(host);

			mmc_claim_host(host);
			mmc_detach_bus(host);
			mmc_release_host(host);
		}
		//E: Robert, 20101006, KB62_CR766
	}
	mmc_bus_put(host);

	if (!err)
		mmc_power_off(host);

	return err;
}
Пример #8
0
/**
 *	mmc_suspend_host - suspend a host
 *	@host: mmc host
 */
int mmc_suspend_host(struct mmc_host *host)
{
	int err = 0;

	if (mmc_bus_needs_resume(host))
		return 0;

	if (host->caps & MMC_CAP_DISABLE)
		cancel_delayed_work(&host->disable);
	cancel_delayed_work(&host->detect);
	mmc_flush_scheduled_work();

	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {

		/*
		 * A long response time is not acceptable for device drivers
		 * when doing suspend. Prevent mmc_claim_host in the suspend
		 * sequence, to potentially wait "forever" by trying to
		 * pre-claim the host.
		 *
		 * Skip try claim host for SDIO cards, doing so fixes deadlock
		 * conditions. The function driver suspend may again call into
		 * SDIO driver within a different context for enabling power
		 * save mode in the card and hence wait in mmc_claim_host
		 * causing deadlock.
		 */
		if (!(host->card && mmc_card_sdio(host->card)))
			if (!mmc_try_claim_host(host))
				err = -EBUSY;

		if (!err) {
			if (host->bus_ops->suspend)
				err = host->bus_ops->suspend(host);
			if (!(host->card && mmc_card_sdio(host->card)))
				mmc_do_release_host(host);

			if (err == -ENOSYS || !host->bus_ops->resume) {
				/*
				 * We simply "remove" the card in this case.
				 * It will be redetected on resume.
				 */
				if (host->bus_ops->remove)
					host->bus_ops->remove(host);
				mmc_claim_host(host);
				mmc_detach_bus(host);
				mmc_power_off(host);
				mmc_release_host(host);
				host->pm_flags = 0;
				err = 0;
			}
		}
	}
#ifdef CONFIG_PM_RUNTIME
	if (mmc_bus_manual_resume(host))
		host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME;
#endif
	mmc_bus_put(host);

	if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
		mmc_power_off(host);

	return err;
}
Пример #9
0
/* Do the card removal on suspend if card is assumed removeable
 * Do that in pm notifier while userspace isn't yet frozen, so we will be able
 * to sync the card.
 */
int mmc_pm_notify(struct notifier_block *notify_block,
					unsigned long mode, void *unused)
{
	struct mmc_host *host = container_of(
		notify_block, struct mmc_host, pm_notify);
	unsigned long flags;

	switch (mode) {
	case PM_HIBERNATION_PREPARE:
	case PM_SUSPEND_PREPARE:

		spin_lock_irqsave(&host->lock, flags);
		if (mmc_bus_needs_resume(host)) {
			spin_unlock_irqrestore(&host->lock, flags);
			break;
		}
		host->rescan_disable = 1;
		spin_unlock_irqrestore(&host->lock, flags);
		cancel_delayed_work_sync(&host->detect);

		if (!host->bus_ops || host->bus_ops->suspend)
			break;

		if (host->bus_ops->remove)
			host->bus_ops->remove(host);
		mmc_claim_host(host);
		mmc_detach_bus(host);
		mmc_release_host(host);
		break;

	case PM_POST_SUSPEND:
	case PM_POST_HIBERNATION:

		spin_lock_irqsave(&host->lock, flags);
		if (mmc_bus_manual_resume(host)) {
			spin_unlock_irqrestore(&host->lock, flags);
			break;
		}
		host->rescan_disable = 0;
		spin_unlock_irqrestore(&host->lock, flags);
#if defined(CONFIG_MACH_ACER_A4) || defined(CONFIG_MACH_ACER_A5)
		printk("*** %s: trigger polling\n", __func__);
		if (host && host->card && host->card->cis.vendor == ATHR_MANUF_CODE) {
			printk("*** %s: WIFI slot. Skip detect.\n", __func__);
			return 0;
		}
#endif
#if defined(CONFIG_MACH_ACER_A4)
		if (host && !strcmp(mmc_hostname(host), "mmc1")) {
			pr_info("*** %s: mmc1. Skip detect.\n", __func__);
			return 0;
		}
#endif
#if defined(CONFIG_MACH_ACER_A5)
		if (host && !strcmp(mmc_hostname(host), "mmc0")) {
			pr_info("*** %s: mmc0 slot. Skip detect.\n", __func__);
			return 0;
		}
		if (host && !strcmp(mmc_hostname(host), "mmc2")) {
			pr_info("*** %s: mmc2 slot. Skip detect.\n", __func__);
			return 0;
		}
#endif
		mmc_detect_change(host, 0);
	}

	return 0;
}