提交 9ce20788 编写于 作者: L Linus Torvalds

Merge tag 'mmc-v4.16-rc4' 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.16-rc7:

  MMC host:

   - dw_mmc: Fix the suspend/resume issue for Exynos5433

   - dw_mmc: Fix the DTO/CTO timeout overflow calculation for 32-bit
     systems

   - dw_mmc: Make PIO mode work when failing with idmac when
     dw_mci_reset occurs

   - sdhci-acpi: Re-allow IRQ 0 to fix broken probe

  MMC core:

   - Update EXT_CSD caches to correctly switch partition for ioctl calls

   - Fix tracepoint print of blk_addr and blksz

   - Disable HPI on broken Micron (Numonyx) eMMC cards"

* tag 'mmc-v4.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci-acpi: Fix IRQ 0
  mmc: dw_mmc: fix falling from idmac to PIO mode when dw_mci_reset occurs
  mmc: core: Fix tracepoint print of blk_addr and blksz
  mmc: core: Disable HPI for certain Micron (Numonyx) eMMC cards
  mmc: dw_mmc: exynos: fix the suspend/resume issue for exynos5433
  mmc: block: fix updating ext_csd caches on ioctl call
  mmc: dw_mmc: Fix the DTO/CTO timeout overflow calculation for 32-bit systems
...@@ -72,6 +72,7 @@ MODULE_ALIAS("mmc:block"); ...@@ -72,6 +72,7 @@ MODULE_ALIAS("mmc:block");
#define MMC_BLK_TIMEOUT_MS (10 * 1000) #define MMC_BLK_TIMEOUT_MS (10 * 1000)
#define MMC_SANITIZE_REQ_TIMEOUT 240000 #define MMC_SANITIZE_REQ_TIMEOUT 240000
#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)
#define MMC_EXTRACT_VALUE_FROM_ARG(x) ((x & 0x0000FF00) >> 8)
#define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \ #define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \
(rq_data_dir(req) == WRITE)) (rq_data_dir(req) == WRITE))
...@@ -586,6 +587,24 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, ...@@ -586,6 +587,24 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
return data.error; return data.error;
} }
/*
* Make sure the cache of the PARTITION_CONFIG register and
* PARTITION_ACCESS bits is updated in case the ioctl ext_csd write
* changed it successfully.
*/
if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_PART_CONFIG) &&
(cmd.opcode == MMC_SWITCH)) {
struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev);
u8 value = MMC_EXTRACT_VALUE_FROM_ARG(cmd.arg);
/*
* Update cache so the next mmc_blk_part_switch call operates
* on up-to-date data.
*/
card->ext_csd.part_config = value;
main_md->part_curr = value & EXT_CSD_PART_CONFIG_ACC_MASK;
}
/* /*
* According to the SD specs, some commands require a delay after * According to the SD specs, some commands require a delay after
* issuing the command. * issuing the command.
......
...@@ -82,6 +82,7 @@ struct mmc_fixup { ...@@ -82,6 +82,7 @@ struct mmc_fixup {
#define CID_MANFID_APACER 0x27 #define CID_MANFID_APACER 0x27
#define CID_MANFID_KINGSTON 0x70 #define CID_MANFID_KINGSTON 0x70
#define CID_MANFID_HYNIX 0x90 #define CID_MANFID_HYNIX 0x90
#define CID_MANFID_NUMONYX 0xFE
#define END_FIXUP { NULL } #define END_FIXUP { NULL }
......
...@@ -109,6 +109,12 @@ static const struct mmc_fixup mmc_ext_csd_fixups[] = { ...@@ -109,6 +109,12 @@ static const struct mmc_fixup mmc_ext_csd_fixups[] = {
*/ */
MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX, MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX,
0x014a, add_quirk, MMC_QUIRK_BROKEN_HPI, 5), 0x014a, add_quirk, MMC_QUIRK_BROKEN_HPI, 5),
/*
* Certain Micron (Numonyx) eMMC 4.5 cards might get broken when HPI
* feature is used so disable the HPI feature for such buggy cards.
*/
MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_NUMONYX,
0x014e, add_quirk, MMC_QUIRK_BROKEN_HPI, 6),
END_FIXUP END_FIXUP
}; };
......
...@@ -165,9 +165,15 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) ...@@ -165,9 +165,15 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
static int dw_mci_exynos_runtime_resume(struct device *dev) static int dw_mci_exynos_runtime_resume(struct device *dev)
{ {
struct dw_mci *host = dev_get_drvdata(dev); struct dw_mci *host = dev_get_drvdata(dev);
int ret;
ret = dw_mci_runtime_resume(dev);
if (ret)
return ret;
dw_mci_exynos_config_smu(host); dw_mci_exynos_config_smu(host);
return dw_mci_runtime_resume(dev);
return ret;
} }
/** /**
......
...@@ -413,7 +413,9 @@ static inline void dw_mci_set_cto(struct dw_mci *host) ...@@ -413,7 +413,9 @@ static inline void dw_mci_set_cto(struct dw_mci *host)
cto_div = (mci_readl(host, CLKDIV) & 0xff) * 2; cto_div = (mci_readl(host, CLKDIV) & 0xff) * 2;
if (cto_div == 0) if (cto_div == 0)
cto_div = 1; cto_div = 1;
cto_ms = DIV_ROUND_UP(MSEC_PER_SEC * cto_clks * cto_div, host->bus_hz);
cto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * cto_clks * cto_div,
host->bus_hz);
/* add a bit spare time */ /* add a bit spare time */
cto_ms += 10; cto_ms += 10;
...@@ -562,6 +564,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) ...@@ -562,6 +564,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
(sizeof(struct idmac_desc_64addr) * (sizeof(struct idmac_desc_64addr) *
(i + 1))) >> 32; (i + 1))) >> 32;
/* Initialize reserved and buffer size fields to "0" */ /* Initialize reserved and buffer size fields to "0" */
p->des0 = 0;
p->des1 = 0; p->des1 = 0;
p->des2 = 0; p->des2 = 0;
p->des3 = 0; p->des3 = 0;
...@@ -584,6 +587,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) ...@@ -584,6 +587,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
i++, p++) { i++, p++) {
p->des3 = cpu_to_le32(host->sg_dma + p->des3 = cpu_to_le32(host->sg_dma +
(sizeof(struct idmac_desc) * (i + 1))); (sizeof(struct idmac_desc) * (i + 1)));
p->des0 = 0;
p->des1 = 0; p->des1 = 0;
} }
...@@ -1799,8 +1803,8 @@ static bool dw_mci_reset(struct dw_mci *host) ...@@ -1799,8 +1803,8 @@ static bool dw_mci_reset(struct dw_mci *host)
} }
if (host->use_dma == TRANS_MODE_IDMAC) if (host->use_dma == TRANS_MODE_IDMAC)
/* It is also recommended that we reset and reprogram idmac */ /* It is also required that we reinit idmac */
dw_mci_idmac_reset(host); dw_mci_idmac_init(host);
ret = true; ret = true;
...@@ -1948,8 +1952,9 @@ static void dw_mci_set_drto(struct dw_mci *host) ...@@ -1948,8 +1952,9 @@ static void dw_mci_set_drto(struct dw_mci *host)
drto_div = (mci_readl(host, CLKDIV) & 0xff) * 2; drto_div = (mci_readl(host, CLKDIV) & 0xff) * 2;
if (drto_div == 0) if (drto_div == 0)
drto_div = 1; drto_div = 1;
drto_ms = DIV_ROUND_UP(MSEC_PER_SEC * drto_clks * drto_div,
host->bus_hz); drto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * drto_clks * drto_div,
host->bus_hz);
/* add a bit spare time */ /* add a bit spare time */
drto_ms += 10; drto_ms += 10;
......
...@@ -680,7 +680,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev) ...@@ -680,7 +680,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
host->hw_name = "ACPI"; host->hw_name = "ACPI";
host->ops = &sdhci_acpi_ops_dflt; host->ops = &sdhci_acpi_ops_dflt;
host->irq = platform_get_irq(pdev, 0); host->irq = platform_get_irq(pdev, 0);
if (host->irq <= 0) { if (host->irq < 0) {
err = -EINVAL; err = -EINVAL;
goto err_free; goto err_free;
} }
......
...@@ -86,8 +86,8 @@ TRACE_EVENT(mmc_request_start, ...@@ -86,8 +86,8 @@ TRACE_EVENT(mmc_request_start,
__entry->stop_flags, __entry->stop_retries, __entry->stop_flags, __entry->stop_retries,
__entry->sbc_opcode, __entry->sbc_arg, __entry->sbc_opcode, __entry->sbc_arg,
__entry->sbc_flags, __entry->sbc_retries, __entry->sbc_flags, __entry->sbc_retries,
__entry->blocks, __entry->blk_addr, __entry->blocks, __entry->blksz,
__entry->blksz, __entry->data_flags, __entry->tag, __entry->blk_addr, __entry->data_flags, __entry->tag,
__entry->can_retune, __entry->doing_retune, __entry->can_retune, __entry->doing_retune,
__entry->retune_now, __entry->need_retune, __entry->retune_now, __entry->need_retune,
__entry->hold_retune, __entry->retune_period) __entry->hold_retune, __entry->retune_period)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册