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

Commit 5c3b9bac authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc:
  mmc: sdhci: 8-bit bus width changes
  mmc: sdio: fix runtime PM anomalies by introducing MMC_CAP_POWER_OFF_CARD
  mmc: sdio: fix nasty oops in mmc_sdio_detect
  mmc: omap4: hsmmc: Fix improper card detection while booting
  mmc: fix rmmod race for hosts using card-detection polling
  mmc: sdhci: Fix crash on boot with C0 stepping Moorestown platforms
  mmc: sdhci-esdhc-imx: enable QUIRK_NO_MULTIBLOCK only for i.MX25 and i.MX35
  mmc: sdhci-esdhc-imx: fix timeout on i.MX's sdhci
  mmc: sdhci: Properly enable SDIO IRQ wakeups
  mmc: ushc: Return proper error code for ushc_probe()
  mmc: Fix printing of card DDR type
parents b127c6fb 15ec4461
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
/* Require clock free running */
#define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0)

/* Board design supports 8-bit data on SD/SDIO BUS */
#define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (1<<2)

/*
 * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI
 * @max_speed: the maximum speed supported
+1 −1
Original line number Diff line number Diff line
@@ -1559,7 +1559,7 @@ void mmc_stop_host(struct mmc_host *host)

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

	/* clear pm flags now and let card drivers set them as needed */
+6 −2
Original line number Diff line number Diff line
@@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
	struct mmc_card *oldcard)
{
	struct mmc_card *card;
	int err, ddr = MMC_SDR_MODE;
	int err, ddr = 0;
	u32 cid[4];
	unsigned int max_dtr;

@@ -562,7 +562,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
			       1 << bus_width, ddr);
			err = 0;
		} else {
			if (ddr)
				mmc_card_set_ddr_mode(card);
			else
				ddr = MMC_SDR_MODE;

			mmc_set_bus_width_ddr(card->host, bus_width, ddr);
		}
	}
+35 −16
Original line number Diff line number Diff line
@@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host)
	BUG_ON(!host->card);

	/* Make sure card is powered before detecting it */
	if (host->caps & MMC_CAP_POWER_OFF_CARD) {
		err = pm_runtime_get_sync(&host->card->dev);
		if (err < 0)
			goto out;
	}

	mmc_claim_host(host);

@@ -560,6 +562,20 @@ static void mmc_sdio_detect(struct mmc_host *host)

	mmc_release_host(host);

	/*
	 * Tell PM core it's OK to power off the card now.
	 *
	 * The _sync variant is used in order to ensure that the card
	 * is left powered off in case an error occurred, and the card
	 * is going to be removed.
	 *
	 * Since there is no specific reason to believe a new user
	 * is about to show up at this point, the _sync variant is
	 * desirable anyway.
	 */
	if (host->caps & MMC_CAP_POWER_OFF_CARD)
		pm_runtime_put_sync(&host->card->dev);

out:
	if (err) {
		mmc_sdio_remove(host);
@@ -568,9 +584,6 @@ out:
		mmc_detach_bus(host);
		mmc_release_host(host);
	}

	/* Tell PM core that we're done */
	pm_runtime_put(&host->card->dev);
}

/*
@@ -717,6 +730,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
		goto err;
	card = host->card;

	/*
	 * Enable runtime PM only if supported by host+card+board
	 */
	if (host->caps & MMC_CAP_POWER_OFF_CARD) {
		/*
		 * Let runtime PM core know our card is active
		 */
@@ -728,6 +745,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
		 * Enable runtime PM for this card
		 */
		pm_runtime_enable(&card->dev);
	}

	/*
	 * The number of functions on the card is encoded inside
@@ -745,8 +763,9 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
			goto remove;

		/*
		 * Enable Runtime PM for this func
		 * Enable Runtime PM for this func (if supported)
		 */
		if (host->caps & MMC_CAP_POWER_OFF_CARD)
			pm_runtime_enable(&card->sdio_func[i]->dev);
	}

+22 −11
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/pm_runtime.h>

#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdio_func.h>

#include "sdio_cis.h"
@@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev)
	 * it should call pm_runtime_put_noidle() in its probe routine and
	 * pm_runtime_get_noresume() in its remove routine.
	 */
	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
		ret = pm_runtime_get_sync(dev);
		if (ret < 0)
			goto out;
	}

	/* Set the default block size so the driver is sure it's something
	 * sensible. */
@@ -151,6 +154,7 @@ static int sdio_bus_probe(struct device *dev)
	return 0;

disable_runtimepm:
	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
		pm_runtime_put_noidle(dev);
out:
	return ret;
@@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev)
{
	struct sdio_driver *drv = to_sdio_driver(dev->driver);
	struct sdio_func *func = dev_to_sdio_func(dev);
	int ret;
	int ret = 0;

	/* Make sure card is powered before invoking ->remove() */
	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
		ret = pm_runtime_get_sync(dev);
		if (ret < 0)
			goto out;
	}

	drv->remove(func);

@@ -178,9 +184,11 @@ static int sdio_bus_remove(struct device *dev)
	}

	/* First, undo the increment made directly above */
	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
		pm_runtime_put_noidle(dev);

	/* Then undo the runtime PM settings in sdio_bus_probe() */
	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
		pm_runtime_put_noidle(dev);

out:
@@ -191,6 +199,8 @@ out:

static int sdio_bus_pm_prepare(struct device *dev)
{
	struct sdio_func *func = dev_to_sdio_func(dev);

	/*
	 * Resume an SDIO device which was suspended at run time at this
	 * point, in order to allow standard SDIO suspend/resume paths
@@ -212,6 +222,7 @@ static int sdio_bus_pm_prepare(struct device *dev)
	 * since there is little point in failing system suspend if a
	 * device can't be resumed.
	 */
	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
		pm_runtime_resume(dev);

	return 0;
Loading