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

Commit 8f3972f7 authored by Jackson Chang's avatar Jackson Chang Committed by Greg Kroah-Hartman
Browse files

greybus: SDIO: Add runtime pm support



Modify SDIO greybus driver to support runtime PM framework.
To enable SDIO runtime PM, it needs to remove MMC_CAP_NEEDS_POLL
and add MMC_CAP2_CORE_RUNTIME_PM in set_host_caps().
The suspend function and resume function have been tested
with micron-sdio image by sysfs. SDIO functions work well
on suspend/resume.

Testing Done: Compiled and verified on EVT2.0 + Micron ARA
              SD module with USB connector

Signed-off-by: default avatarJackson Chang <chang_jackson@projectara.com>
Reviewed-by: default avatarRui Miguel Silva <rui.silva@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 591c4522
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -140,6 +140,10 @@ static inline void sysfs_remove_groups(struct kobject *kobj,
#define MMC_DDR52_DEFINED
#endif

#ifndef MMC_CAP2_CORE_RUNTIME_PM
#define MMC_CAP2_CORE_RUNTIME_PM	0
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
#define MMC_POWER_UNDEFINED_SUPPORTED
#endif
+27 −4
Original line number Diff line number Diff line
@@ -84,8 +84,8 @@ static void _gb_sdio_set_host_caps(struct gb_sdio_host *host, u32 r)
#endif
		((r & GB_SDIO_CAP_HS200_1_8V) ? MMC_CAP2_HS200_1_8V_SDR : 0);

	host->mmc->caps = caps | MMC_CAP_NEEDS_POLL;
	host->mmc->caps2 = caps2;
	host->mmc->caps = caps;
	host->mmc->caps2 = caps2 | MMC_CAP2_CORE_RUNTIME_PM;

	if (caps & MMC_CAP_NONREMOVABLE)
		host->card_present = true;
@@ -239,8 +239,18 @@ static int gb_sdio_request_handler(struct gb_operation *op)
static int gb_sdio_set_ios(struct gb_sdio_host *host,
			   struct gb_sdio_set_ios_request *request)
{
	return gb_operation_sync(host->connection, GB_SDIO_TYPE_SET_IOS,
				 request, sizeof(*request), NULL, 0);
	int ret;

	ret = gbphy_runtime_get_sync(host->gbphy_dev);
	if (ret)
		return ret;

	ret = gb_operation_sync(host->connection, GB_SDIO_TYPE_SET_IOS, request,
				sizeof(*request), NULL, 0);

	gbphy_runtime_put_autosuspend(host->gbphy_dev);

	return ret;
}

static int _gb_sdio_send(struct gb_sdio_host *host, struct mmc_data *data,
@@ -489,10 +499,15 @@ static void gb_sdio_mrq_work(struct work_struct *work)

	host = container_of(work, struct gb_sdio_host, mrqwork);

	ret = gbphy_runtime_get_sync(host->gbphy_dev);
	if (ret)
		return;

	mutex_lock(&host->lock);
	mrq = host->mrq;
	if (!mrq) {
		mutex_unlock(&host->lock);
		gbphy_runtime_put_autosuspend(host->gbphy_dev);
		dev_err(mmc_dev(host->mmc), "mmc request is NULL");
		return;
	}
@@ -528,6 +543,7 @@ static void gb_sdio_mrq_work(struct work_struct *work)
	host->mrq = NULL;
	mutex_unlock(&host->lock);
	mmc_request_done(host->mmc, mrq);
	gbphy_runtime_put_autosuspend(host->gbphy_dev);
}

static void gb_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -813,6 +829,8 @@ static int gb_sdio_probe(struct gbphy_device *gbphy_dev,
	ret = _gb_sdio_process_events(host, host->queued_events);
	host->queued_events = 0;

	gbphy_runtime_put_autosuspend(gbphy_dev);

	return ret;

exit_wq_destroy:
@@ -832,6 +850,11 @@ static void gb_sdio_remove(struct gbphy_device *gbphy_dev)
	struct gb_sdio_host *host = gb_gbphy_get_data(gbphy_dev);
	struct gb_connection *connection = host->connection;
	struct mmc_host *mmc;
	int ret;

	ret = gbphy_runtime_get_sync(gbphy_dev);
	if (ret)
		gbphy_runtime_get_noresume(gbphy_dev);

	mutex_lock(&host->lock);
	host->removed = true;