Commit 904a9802 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v3.19-3' of git://git.linaro.org/people/ulf.hansson/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC host:
   - sdhci-pci|acpi: Support some new IDs
   - sdhci: Fix sleep from atomic context
   - sdhci-pxav3: Prevent hang during ->probe()
   - sdhci: Disable re-tuning for HS400"

* tag 'mmc-v3.19-3' of git://git.linaro.org/people/ulf.hansson/mmc:
  mmc: sdhci-pci: Add support for Intel SPT
  mmc: sdhci-acpi: Add ACPI HID INT344D
  mmc: sdhci: Fix sleep in atomic after inserting SD card
  mmc: sdhci-pxav3: do the mbus window configuration after enabling clocks
  mmc: sdhci: Disable re-tuning for HS400
  mmc: sdhci: Simplify use of tuning timer
  mmc: sdhci: Add out_unlock to sdhci_execute_tuning
  mmc: sdhci: Tuning should not change max_blk_count
parents fb43bd08 1f7f2652
...@@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { ...@@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
{ "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd },
{ "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio },
{ "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio },
{ "INT344D" , NULL, &sdhci_acpi_slot_int_sdio },
{ "PNP0D40" }, { "PNP0D40" },
{ }, { },
}; };
...@@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = { ...@@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = {
{ "INT33BB" }, { "INT33BB" },
{ "INT33C6" }, { "INT33C6" },
{ "INT3436" }, { "INT3436" },
{ "INT344D" },
{ "PNP0D40" }, { "PNP0D40" },
{ }, { },
}; };
......
...@@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = { ...@@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = {
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc, .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc,
}, },
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_SPT_EMMC,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc,
},
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_SPT_SDIO,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio,
},
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_SPT_SD,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd,
},
{ {
.vendor = PCI_VENDOR_ID_O2, .vendor = PCI_VENDOR_ID_O2,
.device = PCI_DEVICE_ID_O2_8120, .device = PCI_DEVICE_ID_O2_8120,
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5 #define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5
#define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6 #define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6
#define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7 #define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7
#define PCI_DEVICE_ID_INTEL_SPT_EMMC 0x9d2b
#define PCI_DEVICE_ID_INTEL_SPT_SDIO 0x9d2c
#define PCI_DEVICE_ID_INTEL_SPT_SD 0x9d2d
/* /*
* PCI registers * PCI registers
......
...@@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) ...@@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
if (IS_ERR(host)) if (IS_ERR(host))
return PTR_ERR(host); return PTR_ERR(host);
if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
if (ret < 0)
goto err_mbus_win;
}
pltfm_host = sdhci_priv(host); pltfm_host = sdhci_priv(host);
pltfm_host->priv = pxa; pltfm_host->priv = pxa;
...@@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) ...@@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
if (!IS_ERR(pxa->clk_core)) if (!IS_ERR(pxa->clk_core))
clk_prepare_enable(pxa->clk_core); clk_prepare_enable(pxa->clk_core);
if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
if (ret < 0)
goto err_mbus_win;
}
/* enable 1/8V DDR capable */ /* enable 1/8V DDR capable */
host->mmc->caps |= MMC_CAP_1_8V_DDR; host->mmc->caps |= MMC_CAP_1_8V_DDR;
...@@ -396,11 +395,11 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) ...@@ -396,11 +395,11 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
err_of_parse: err_of_parse:
err_cd_req: err_cd_req:
err_mbus_win:
clk_disable_unprepare(pxa->clk_io); clk_disable_unprepare(pxa->clk_io);
if (!IS_ERR(pxa->clk_core)) if (!IS_ERR(pxa->clk_core))
clk_disable_unprepare(pxa->clk_core); clk_disable_unprepare(pxa->clk_core);
err_clk_get: err_clk_get:
err_mbus_win:
sdhci_pltfm_free(pdev); sdhci_pltfm_free(pdev);
return ret; return ret;
} }
......
...@@ -259,8 +259,6 @@ static void sdhci_reinit(struct sdhci_host *host) ...@@ -259,8 +259,6 @@ static void sdhci_reinit(struct sdhci_host *host)
del_timer_sync(&host->tuning_timer); del_timer_sync(&host->tuning_timer);
host->flags &= ~SDHCI_NEEDS_RETUNING; host->flags &= ~SDHCI_NEEDS_RETUNING;
host->mmc->max_blk_count =
(host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
} }
sdhci_enable_card_detection(host); sdhci_enable_card_detection(host);
} }
...@@ -1353,6 +1351,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) ...@@ -1353,6 +1351,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
sdhci_runtime_pm_get(host); sdhci_runtime_pm_get(host);
present = mmc_gpio_get_cd(host->mmc);
spin_lock_irqsave(&host->lock, flags); spin_lock_irqsave(&host->lock, flags);
WARN_ON(host->mrq != NULL); WARN_ON(host->mrq != NULL);
...@@ -1381,7 +1381,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) ...@@ -1381,7 +1381,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
* zero: cd-gpio is used, and card is removed * zero: cd-gpio is used, and card is removed
* one: cd-gpio is used, and card is present * one: cd-gpio is used, and card is present
*/ */
present = mmc_gpio_get_cd(host->mmc);
if (present < 0) { if (present < 0) {
/* If polling, assume that the card is always present. */ /* If polling, assume that the card is always present. */
if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
...@@ -1880,6 +1879,18 @@ static int sdhci_card_busy(struct mmc_host *mmc) ...@@ -1880,6 +1879,18 @@ static int sdhci_card_busy(struct mmc_host *mmc)
return !(present_state & SDHCI_DATA_LVL_MASK); return !(present_state & SDHCI_DATA_LVL_MASK);
} }
static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct sdhci_host *host = mmc_priv(mmc);
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
host->flags |= SDHCI_HS400_TUNING;
spin_unlock_irqrestore(&host->lock, flags);
return 0;
}
static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{ {
struct sdhci_host *host = mmc_priv(mmc); struct sdhci_host *host = mmc_priv(mmc);
...@@ -1887,10 +1898,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -1887,10 +1898,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
int tuning_loop_counter = MAX_TUNING_LOOP; int tuning_loop_counter = MAX_TUNING_LOOP;
int err = 0; int err = 0;
unsigned long flags; unsigned long flags;
unsigned int tuning_count = 0;
bool hs400_tuning;
sdhci_runtime_pm_get(host); sdhci_runtime_pm_get(host);
spin_lock_irqsave(&host->lock, flags); spin_lock_irqsave(&host->lock, flags);
hs400_tuning = host->flags & SDHCI_HS400_TUNING;
host->flags &= ~SDHCI_HS400_TUNING;
if (host->tuning_mode == SDHCI_TUNING_MODE_1)
tuning_count = host->tuning_count;
/* /*
* The Host Controller needs tuning only in case of SDR104 mode * The Host Controller needs tuning only in case of SDR104 mode
* and for SDR50 mode when Use Tuning for SDR50 is set in the * and for SDR50 mode when Use Tuning for SDR50 is set in the
...@@ -1899,8 +1918,20 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -1899,8 +1918,20 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
* tuning function has to be executed. * tuning function has to be executed.
*/ */
switch (host->timing) { switch (host->timing) {
/* HS400 tuning is done in HS200 mode */
case MMC_TIMING_MMC_HS400: case MMC_TIMING_MMC_HS400:
err = -EINVAL;
goto out_unlock;
case MMC_TIMING_MMC_HS200: case MMC_TIMING_MMC_HS200:
/*
* Periodic re-tuning for HS400 is not expected to be needed, so
* disable it here.
*/
if (hs400_tuning)
tuning_count = 0;
break;
case MMC_TIMING_UHS_SDR104: case MMC_TIMING_UHS_SDR104:
break; break;
...@@ -1911,9 +1942,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -1911,9 +1942,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
spin_unlock_irqrestore(&host->lock, flags); goto out_unlock;
sdhci_runtime_pm_put(host);
return 0;
} }
if (host->ops->platform_execute_tuning) { if (host->ops->platform_execute_tuning) {
...@@ -2037,24 +2066,11 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -2037,24 +2066,11 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
} }
out: out:
/*
* If this is the very first time we are here, we start the retuning
* timer. Since only during the first time, SDHCI_NEEDS_RETUNING
* flag won't be set, we check this condition before actually starting
* the timer.
*/
if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count &&
(host->tuning_mode == SDHCI_TUNING_MODE_1)) {
host->flags |= SDHCI_USING_RETUNING_TIMER;
mod_timer(&host->tuning_timer, jiffies +
host->tuning_count * HZ);
/* Tuning mode 1 limits the maximum data length to 4MB */
mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size;
} else if (host->flags & SDHCI_USING_RETUNING_TIMER) {
host->flags &= ~SDHCI_NEEDS_RETUNING; host->flags &= ~SDHCI_NEEDS_RETUNING;
/* Reload the new initial value for timer */
mod_timer(&host->tuning_timer, jiffies + if (tuning_count) {
host->tuning_count * HZ); host->flags |= SDHCI_USING_RETUNING_TIMER;
mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ);
} }
/* /*
...@@ -2070,6 +2086,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -2070,6 +2086,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
out_unlock:
spin_unlock_irqrestore(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
sdhci_runtime_pm_put(host); sdhci_runtime_pm_put(host);
...@@ -2110,15 +2127,18 @@ static void sdhci_card_event(struct mmc_host *mmc) ...@@ -2110,15 +2127,18 @@ static void sdhci_card_event(struct mmc_host *mmc)
{ {
struct sdhci_host *host = mmc_priv(mmc); struct sdhci_host *host = mmc_priv(mmc);
unsigned long flags; unsigned long flags;
int present;
/* First check if client has provided their own card event */ /* First check if client has provided their own card event */
if (host->ops->card_event) if (host->ops->card_event)
host->ops->card_event(host); host->ops->card_event(host);
present = sdhci_do_get_cd(host);
spin_lock_irqsave(&host->lock, flags); spin_lock_irqsave(&host->lock, flags);
/* Check host->mrq first in case we are runtime suspended */ /* Check host->mrq first in case we are runtime suspended */
if (host->mrq && !sdhci_do_get_cd(host)) { if (host->mrq && !present) {
pr_err("%s: Card removed during transfer!\n", pr_err("%s: Card removed during transfer!\n",
mmc_hostname(host->mmc)); mmc_hostname(host->mmc));
pr_err("%s: Resetting controller.\n", pr_err("%s: Resetting controller.\n",
...@@ -2142,6 +2162,7 @@ static const struct mmc_host_ops sdhci_ops = { ...@@ -2142,6 +2162,7 @@ static const struct mmc_host_ops sdhci_ops = {
.hw_reset = sdhci_hw_reset, .hw_reset = sdhci_hw_reset,
.enable_sdio_irq = sdhci_enable_sdio_irq, .enable_sdio_irq = sdhci_enable_sdio_irq,
.start_signal_voltage_switch = sdhci_start_signal_voltage_switch, .start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
.prepare_hs400_tuning = sdhci_prepare_hs400_tuning,
.execute_tuning = sdhci_execute_tuning, .execute_tuning = sdhci_execute_tuning,
.card_event = sdhci_card_event, .card_event = sdhci_card_event,
.card_busy = sdhci_card_busy, .card_busy = sdhci_card_busy,
...@@ -3260,8 +3281,9 @@ int sdhci_add_host(struct sdhci_host *host) ...@@ -3260,8 +3281,9 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->max_segs = SDHCI_MAX_SEGS; mmc->max_segs = SDHCI_MAX_SEGS;
/* /*
* Maximum number of sectors in one transfer. Limited by DMA boundary * Maximum number of sectors in one transfer. Limited by SDMA boundary
* size (512KiB). * size (512KiB). Note some tuning modes impose a 4MiB limit, but this
* is less anyway.
*/ */
mmc->max_req_size = 524288; mmc->max_req_size = 524288;
......
...@@ -137,6 +137,7 @@ struct sdhci_host { ...@@ -137,6 +137,7 @@ struct sdhci_host {
#define SDHCI_SDR104_NEEDS_TUNING (1<<10) /* SDR104/HS200 needs tuning */ #define SDHCI_SDR104_NEEDS_TUNING (1<<10) /* SDR104/HS200 needs tuning */
#define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */ #define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */
#define SDHCI_USE_64_BIT_DMA (1<<12) /* Use 64-bit DMA */ #define SDHCI_USE_64_BIT_DMA (1<<12) /* Use 64-bit DMA */
#define SDHCI_HS400_TUNING (1<<13) /* Tuning for HS400 */
unsigned int version; /* SDHCI spec. version */ unsigned int version; /* SDHCI spec. version */
......
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