Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e302345 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: core: Add deferred bus resume policy."

parents 249fad2f 80e49510
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -166,6 +166,8 @@ static int mmc_bus_suspend(struct device *dev)
			return ret;
	}

	if (mmc_bus_needs_resume(host))
		return 0;
	ret = host->bus_ops->suspend(host);
	return ret;
}
@@ -177,11 +179,17 @@ static int mmc_bus_resume(struct device *dev)
	struct mmc_host *host = card->host;
	int ret;

	if (host->bus_resume_flags & MMC_BUSRESUME_MANUAL_RESUME) {
		host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME;
		goto skip_full_resume;
	}

	ret = host->bus_ops->resume(host);
	if (ret)
		pr_warn("%s: error %d during resume (card was removed?)\n",
			mmc_hostname(host), ret);

skip_full_resume:
	if (dev->driver && drv->resume)
		ret = drv->resume(card);

@@ -195,6 +203,9 @@ static int mmc_runtime_suspend(struct device *dev)
	struct mmc_card *card = mmc_dev_to_card(dev);
	struct mmc_host *host = card->host;

	if (mmc_bus_needs_resume(host))
		return 0;

	return host->bus_ops->runtime_suspend(host);
}

@@ -203,6 +214,9 @@ static int mmc_runtime_resume(struct device *dev)
	struct mmc_card *card = mmc_dev_to_card(dev);
	struct mmc_host *host = card->host;

	if (mmc_bus_needs_resume(host))
		host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;

	return host->bus_ops->runtime_resume(host);
}

+23 −0
Original line number Diff line number Diff line
@@ -2762,6 +2762,29 @@ static inline void mmc_bus_put(struct mmc_host *host)
	spin_unlock_irqrestore(&host->lock, flags);
}

int mmc_resume_bus(struct mmc_host *host)
{
	if (!mmc_bus_needs_resume(host))
		return -EINVAL;

	pr_debug("%s: Starting deferred resume\n", mmc_hostname(host));
	host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;
	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead && host->card) {
		mmc_power_up(host, host->card->ocr);
		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);
	pr_debug("%s: Deferred resume completed\n", mmc_hostname(host));
	return 0;
}
EXPORT_SYMBOL(mmc_resume_bus);

/*
 * Assign a mmc bus handler to a host. Only one bus handler may control a
 * host at any given time.
+16 −0
Original line number Diff line number Diff line
@@ -497,6 +497,10 @@ struct mmc_host {
	const struct mmc_bus_ops *bus_ops;	/* current bus driver */
	unsigned int		bus_refs;	/* reference counter */

	unsigned int		bus_resume_flags;
#define MMC_BUSRESUME_MANUAL_RESUME	(1 << 0)
#define MMC_BUSRESUME_NEEDS_RESUME	(1 << 1)

	unsigned int		sdio_irqs;
	struct task_struct	*sdio_irq_thread;
	bool			sdio_irq_pending;
@@ -600,6 +604,18 @@ static inline void *mmc_cmdq_private(struct mmc_host *host)
#define mmc_dev(x)	((x)->parent)
#define mmc_classdev(x)	(&(x)->class_dev)
#define mmc_hostname(x)	(dev_name(&(x)->class_dev))
#define mmc_bus_needs_resume(host) ((host)->bus_resume_flags & \
				    MMC_BUSRESUME_NEEDS_RESUME)

static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual)
{
	if (manual)
		host->bus_resume_flags |= MMC_BUSRESUME_MANUAL_RESUME;
	else
		host->bus_resume_flags &= ~MMC_BUSRESUME_MANUAL_RESUME;
}

extern int mmc_resume_bus(struct mmc_host *host);

int mmc_power_save_host(struct mmc_host *host);
int mmc_power_restore_host(struct mmc_host *host);