Commit 8145f373 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v4.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "A couple of mmc fixes intended for v4.13-rc4.

  MMC core:
   - Fix NULL pointer dereference for block I/O during hotplug

  MMC host:
   - sdhci-of-at91: Fix card detect for non-removable cards"

* tag 'mmc-v4.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: block: bypass the queue even if usage is present for hotplug
  mmc: sdhci-of-at91: force card detect value for non removable devices
parents 47d47585 7c84b8b4
...@@ -2170,6 +2170,7 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md) ...@@ -2170,6 +2170,7 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
* from being accepted. * from being accepted.
*/ */
card = md->queue.card; card = md->queue.card;
queue_flag_set(QUEUE_FLAG_BYPASS, md->queue.queue);
blk_set_queue_dying(md->queue.queue); blk_set_queue_dying(md->queue.queue);
mmc_cleanup_queue(&md->queue); mmc_cleanup_queue(&md->queue);
if (md->disk->flags & GENHD_FL_UP) { if (md->disk->flags & GENHD_FL_UP) {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#define SDMMC_MC1R 0x204 #define SDMMC_MC1R 0x204
#define SDMMC_MC1R_DDR BIT(3) #define SDMMC_MC1R_DDR BIT(3)
#define SDMMC_MC1R_FCD BIT(7)
#define SDMMC_CACR 0x230 #define SDMMC_CACR 0x230
#define SDMMC_CACR_CAPWREN BIT(0) #define SDMMC_CACR_CAPWREN BIT(0)
#define SDMMC_CACR_KEY (0x46 << 8) #define SDMMC_CACR_KEY (0x46 << 8)
...@@ -43,6 +44,15 @@ struct sdhci_at91_priv { ...@@ -43,6 +44,15 @@ struct sdhci_at91_priv {
struct clk *mainck; struct clk *mainck;
}; };
static void sdhci_at91_set_force_card_detect(struct sdhci_host *host)
{
u8 mc1r;
mc1r = readb(host->ioaddr + SDMMC_MC1R);
mc1r |= SDMMC_MC1R_FCD;
writeb(mc1r, host->ioaddr + SDMMC_MC1R);
}
static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock) static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
{ {
u16 clk; u16 clk;
...@@ -110,10 +120,18 @@ void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, unsigned int timing) ...@@ -110,10 +120,18 @@ void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, unsigned int timing)
sdhci_set_uhs_signaling(host, timing); sdhci_set_uhs_signaling(host, timing);
} }
static void sdhci_at91_reset(struct sdhci_host *host, u8 mask)
{
sdhci_reset(host, mask);
if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
sdhci_at91_set_force_card_detect(host);
}
static const struct sdhci_ops sdhci_at91_sama5d2_ops = { static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
.set_clock = sdhci_at91_set_clock, .set_clock = sdhci_at91_set_clock,
.set_bus_width = sdhci_set_bus_width, .set_bus_width = sdhci_set_bus_width,
.reset = sdhci_reset, .reset = sdhci_at91_reset,
.set_uhs_signaling = sdhci_at91_set_uhs_signaling, .set_uhs_signaling = sdhci_at91_set_uhs_signaling,
.set_power = sdhci_at91_set_power, .set_power = sdhci_at91_set_power,
}; };
...@@ -324,6 +342,21 @@ static int sdhci_at91_probe(struct platform_device *pdev) ...@@ -324,6 +342,21 @@ static int sdhci_at91_probe(struct platform_device *pdev)
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
} }
/*
* If the device attached to the MMC bus is not removable, it is safer
* to set the Force Card Detect bit. People often don't connect the
* card detect signal and use this pin for another purpose. If the card
* detect pin is not muxed to SDHCI controller, a default value is
* used. This value can be different from a SoC revision to another
* one. Problems come when this default value is not card present. To
* avoid this case, if the device is non removable then the card
* detection procedure using the SDMCC_CD signal is bypassed.
* This bit is reset when a software reset for all command is performed
* so we need to implement our own reset function to set back this bit.
*/
if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
sdhci_at91_set_force_card_detect(host);
pm_runtime_put_autosuspend(&pdev->dev); pm_runtime_put_autosuspend(&pdev->dev);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment