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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJUs8eNAAoJEP4mhCVzWIwpwhoP/jVL+6bIHBXwv7w4Qim96Iww CjARBVaOGP4W1E7YrX6Ny5CGjkT0AtkEa6exuiWxRWw+fj120kPQ3sbQw4DMdQED l4Xb0yuXGP1n9xyCQi4TJVBj2rnm9PuXDjBpFYU8L450Cv7d/vC0t9yzzZIf8sdg OFAjfyueynZIc03ShLSfsuDu60EoBLyFrjI/smE9mUdQDfTDzUthtlSMMdavyshg F92TVZNIC3G3dHYtuKqsrzzgHcMrSypcZpGOgUxsMmW8qNlhnzLWHhZXB+GlJbse XKUgYVKWC3MyiZwTnaoO2LnZG7F+hdgsm0lUOLWsNcnWelJjdDNZkNNCoA7zefZh NjeXMM0v2TUej8AJpcV/7dUwJ18CiETWfbsrIy+quJp6yG/8V5WX2w5FpzR0Zzyn 72g2RqPNdWLfCd5En4KBroJQ/hKC9YCdy6RTjlKLW4dAu+moLekBgu6AaUs7OdyL c5FtG1GKp1T2XgBNA3Kw0bAIOYFDEDnMNY6d/seDwHZNUJp/1x3DweHKkZ7LKdX9 SgDo/vBtSjdZPZgbP0v9mZAp/0RDXCQL2VCPnMjI4MSSqKWF31iEoCG4BTCodZQ+ dHMChsQV0NpXrjgityiblSaYZiBrGJJiZBpyAjgxLuRUJN9EFg3bLPy4ybf7C5WK mzXszP/rlbOG114dY4I4 =hTJI -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
904a9802cd
@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
|
||||
{ "INT33BB" , "3" , &sdhci_acpi_slot_int_sd },
|
||||
{ "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio },
|
||||
{ "INT3436" , NULL, &sdhci_acpi_slot_int_sdio },
|
||||
{ "INT344D" , NULL, &sdhci_acpi_slot_int_sdio },
|
||||
{ "PNP0D40" },
|
||||
{ },
|
||||
};
|
||||
@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = {
|
||||
{ "INT33BB" },
|
||||
{ "INT33C6" },
|
||||
{ "INT3436" },
|
||||
{ "INT344D" },
|
||||
{ "PNP0D40" },
|
||||
{ },
|
||||
};
|
||||
|
@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = {
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.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,
|
||||
.device = PCI_DEVICE_ID_O2_8120,
|
||||
|
@ -21,6 +21,9 @@
|
||||
#define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5
|
||||
#define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6
|
||||
#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
|
||||
|
@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
|
||||
if (IS_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->priv = pxa;
|
||||
|
||||
@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
|
||||
if (!IS_ERR(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 */
|
||||
host->mmc->caps |= MMC_CAP_1_8V_DDR;
|
||||
|
||||
@ -396,11 +395,11 @@ err_add_host:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
err_of_parse:
|
||||
err_cd_req:
|
||||
err_mbus_win:
|
||||
clk_disable_unprepare(pxa->clk_io);
|
||||
if (!IS_ERR(pxa->clk_core))
|
||||
clk_disable_unprepare(pxa->clk_core);
|
||||
err_clk_get:
|
||||
err_mbus_win:
|
||||
sdhci_pltfm_free(pdev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -259,8 +259,6 @@ static void sdhci_reinit(struct sdhci_host *host)
|
||||
|
||||
del_timer_sync(&host->tuning_timer);
|
||||
host->flags &= ~SDHCI_NEEDS_RETUNING;
|
||||
host->mmc->max_blk_count =
|
||||
(host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
|
||||
}
|
||||
sdhci_enable_card_detection(host);
|
||||
}
|
||||
@ -1353,6 +1351,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
|
||||
sdhci_runtime_pm_get(host);
|
||||
|
||||
present = mmc_gpio_get_cd(host->mmc);
|
||||
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
WARN_ON(host->mrq != NULL);
|
||||
@ -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
|
||||
* one: cd-gpio is used, and card is present
|
||||
*/
|
||||
present = mmc_gpio_get_cd(host->mmc);
|
||||
if (present < 0) {
|
||||
/* If polling, assume that the card is always present. */
|
||||
if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
|
||||
@ -1880,6 +1879,18 @@ static int sdhci_card_busy(struct mmc_host *mmc)
|
||||
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)
|
||||
{
|
||||
struct sdhci_host *host = mmc_priv(mmc);
|
||||
@ -1887,10 +1898,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
int tuning_loop_counter = MAX_TUNING_LOOP;
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
unsigned int tuning_count = 0;
|
||||
bool hs400_tuning;
|
||||
|
||||
sdhci_runtime_pm_get(host);
|
||||
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
|
||||
* 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)
|
||||
* tuning function has to be executed.
|
||||
*/
|
||||
switch (host->timing) {
|
||||
/* HS400 tuning is done in HS200 mode */
|
||||
case MMC_TIMING_MMC_HS400:
|
||||
err = -EINVAL;
|
||||
goto out_unlock;
|
||||
|
||||
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:
|
||||
break;
|
||||
|
||||
@ -1911,9 +1942,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
sdhci_runtime_pm_put(host);
|
||||
return 0;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (host->ops->platform_execute_tuning) {
|
||||
@ -2037,24 +2066,11 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
}
|
||||
|
||||
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_NEEDS_RETUNING;
|
||||
|
||||
if (tuning_count) {
|
||||
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;
|
||||
/* Reload the new initial value for timer */
|
||||
mod_timer(&host->tuning_timer, jiffies +
|
||||
host->tuning_count * HZ);
|
||||
mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2070,6 +2086,7 @@ out:
|
||||
|
||||
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
|
||||
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
sdhci_runtime_pm_put(host);
|
||||
|
||||
@ -2110,15 +2127,18 @@ static void sdhci_card_event(struct mmc_host *mmc)
|
||||
{
|
||||
struct sdhci_host *host = mmc_priv(mmc);
|
||||
unsigned long flags;
|
||||
int present;
|
||||
|
||||
/* First check if client has provided their own card event */
|
||||
if (host->ops->card_event)
|
||||
host->ops->card_event(host);
|
||||
|
||||
present = sdhci_do_get_cd(host);
|
||||
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
/* 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",
|
||||
mmc_hostname(host->mmc));
|
||||
pr_err("%s: Resetting controller.\n",
|
||||
@ -2142,6 +2162,7 @@ static const struct mmc_host_ops sdhci_ops = {
|
||||
.hw_reset = sdhci_hw_reset,
|
||||
.enable_sdio_irq = sdhci_enable_sdio_irq,
|
||||
.start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
|
||||
.prepare_hs400_tuning = sdhci_prepare_hs400_tuning,
|
||||
.execute_tuning = sdhci_execute_tuning,
|
||||
.card_event = sdhci_card_event,
|
||||
.card_busy = sdhci_card_busy,
|
||||
@ -3260,8 +3281,9 @@ int sdhci_add_host(struct sdhci_host *host)
|
||||
mmc->max_segs = SDHCI_MAX_SEGS;
|
||||
|
||||
/*
|
||||
* Maximum number of sectors in one transfer. Limited by DMA boundary
|
||||
* size (512KiB).
|
||||
* Maximum number of sectors in one transfer. Limited by SDMA boundary
|
||||
* size (512KiB). Note some tuning modes impose a 4MiB limit, but this
|
||||
* is less anyway.
|
||||
*/
|
||||
mmc->max_req_size = 524288;
|
||||
|
||||
|
@ -137,6 +137,7 @@ struct sdhci_host {
|
||||
#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_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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user