Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'mmc-v5.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
"MMC core:
- sdio: Restore ~20% performance drop for SDHCI drivers, by using
mmc_pre_req() and mmc_post_req() for SDIO requests.

MMC host:
- sdhci-of-esdhc: Fix support for erratum eSDHC7
- mmc_spi: Allow the driver to be built when CONFIG_HAS_DMA is unset
- sdhci-msm: Use retries to fix tuning
- sdhci-acpi: Fix resume for eMMC HS400 mode"

* tag 'mmc-v5.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
mmc: sdio: Use mmc_pre_req() / mmc_post_req()
mmc: sdhci-of-esdhc: Don't walk device-tree on every interrupt
mmc: mmc_spi: Allow the driver to be built when CONFIG_HAS_DMA is unset
mmc: sdhci-msm: Add retries when all tuning phases are found valid
mmc: sdhci-acpi: Clear amd_sdhci_host on reset

+123 -63
+22 -17
drivers/mmc/core/sdio_ops.c
··· 121 121 struct sg_table sgtable; 122 122 unsigned int nents, left_size, i; 123 123 unsigned int seg_size = card->host->max_seg_size; 124 + int err; 124 125 125 126 WARN_ON(blksz == 0); 126 127 ··· 171 170 172 171 mmc_set_data_timeout(&data, card); 173 172 173 + mmc_pre_req(card->host, &mrq); 174 + 174 175 mmc_wait_for_req(card->host, &mrq); 176 + 177 + if (cmd.error) 178 + err = cmd.error; 179 + else if (data.error) 180 + err = data.error; 181 + else if (mmc_host_is_spi(card->host)) 182 + /* host driver already reported errors */ 183 + err = 0; 184 + else if (cmd.resp[0] & R5_ERROR) 185 + err = -EIO; 186 + else if (cmd.resp[0] & R5_FUNCTION_NUMBER) 187 + err = -EINVAL; 188 + else if (cmd.resp[0] & R5_OUT_OF_RANGE) 189 + err = -ERANGE; 190 + else 191 + err = 0; 192 + 193 + mmc_post_req(card->host, &mrq, err); 175 194 176 195 if (nents > 1) 177 196 sg_free_table(&sgtable); 178 197 179 - if (cmd.error) 180 - return cmd.error; 181 - if (data.error) 182 - return data.error; 183 - 184 - if (mmc_host_is_spi(card->host)) { 185 - /* host driver already reported errors */ 186 - } else { 187 - if (cmd.resp[0] & R5_ERROR) 188 - return -EIO; 189 - if (cmd.resp[0] & R5_FUNCTION_NUMBER) 190 - return -EINVAL; 191 - if (cmd.resp[0] & R5_OUT_OF_RANGE) 192 - return -ERANGE; 193 - } 194 - 195 - return 0; 198 + return err; 196 199 } 197 200 198 201 int sdio_reset(struct mmc_host *host)
+1 -1
drivers/mmc/host/Kconfig
··· 602 602 603 603 config MMC_SPI 604 604 tristate "MMC/SD/SDIO over SPI" 605 - depends on SPI_MASTER && HAS_DMA 605 + depends on SPI_MASTER 606 606 select CRC7 607 607 select CRC_ITU_T 608 608 help
+52 -34
drivers/mmc/host/mmc_spi.c
··· 1278 1278 return IRQ_HANDLED; 1279 1279 } 1280 1280 1281 + #ifdef CONFIG_HAS_DMA 1282 + static int mmc_spi_dma_alloc(struct mmc_spi_host *host) 1283 + { 1284 + struct spi_device *spi = host->spi; 1285 + struct device *dev; 1286 + 1287 + if (!spi->master->dev.parent->dma_mask) 1288 + return 0; 1289 + 1290 + dev = spi->master->dev.parent; 1291 + 1292 + host->ones_dma = dma_map_single(dev, host->ones, MMC_SPI_BLOCKSIZE, 1293 + DMA_TO_DEVICE); 1294 + if (dma_mapping_error(dev, host->ones_dma)) 1295 + return -ENOMEM; 1296 + 1297 + host->data_dma = dma_map_single(dev, host->data, sizeof(*host->data), 1298 + DMA_BIDIRECTIONAL); 1299 + if (dma_mapping_error(dev, host->data_dma)) { 1300 + dma_unmap_single(dev, host->ones_dma, MMC_SPI_BLOCKSIZE, 1301 + DMA_TO_DEVICE); 1302 + return -ENOMEM; 1303 + } 1304 + 1305 + dma_sync_single_for_cpu(dev, host->data_dma, sizeof(*host->data), 1306 + DMA_BIDIRECTIONAL); 1307 + 1308 + host->dma_dev = dev; 1309 + return 0; 1310 + } 1311 + 1312 + static void mmc_spi_dma_free(struct mmc_spi_host *host) 1313 + { 1314 + if (!host->dma_dev) 1315 + return; 1316 + 1317 + dma_unmap_single(host->dma_dev, host->ones_dma, MMC_SPI_BLOCKSIZE, 1318 + DMA_TO_DEVICE); 1319 + dma_unmap_single(host->dma_dev, host->data_dma, sizeof(*host->data), 1320 + DMA_BIDIRECTIONAL); 1321 + } 1322 + #else 1323 + static inline mmc_spi_dma_alloc(struct mmc_spi_host *host) { return 0; } 1324 + static inline void mmc_spi_dma_free(struct mmc_spi_host *host) {} 1325 + #endif 1326 + 1281 1327 static int mmc_spi_probe(struct spi_device *spi) 1282 1328 { 1283 1329 void *ones; ··· 1420 1374 if (!host->data) 1421 1375 goto fail_nobuf1; 1422 1376 1423 - if (spi->master->dev.parent->dma_mask) { 1424 - struct device *dev = spi->master->dev.parent; 1425 - 1426 - host->dma_dev = dev; 1427 - host->ones_dma = dma_map_single(dev, ones, 1428 - MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE); 1429 - if (dma_mapping_error(dev, host->ones_dma)) 1430 - goto fail_ones_dma; 1431 - host->data_dma = dma_map_single(dev, host->data, 1432 - sizeof(*host->data), DMA_BIDIRECTIONAL); 1433 - if (dma_mapping_error(dev, host->data_dma)) 1434 - goto fail_data_dma; 1435 - 1436 - dma_sync_single_for_cpu(host->dma_dev, 1437 - host->data_dma, sizeof(*host->data), 1438 - DMA_BIDIRECTIONAL); 1439 - } 1377 + status = mmc_spi_dma_alloc(host); 1378 + if (status) 1379 + goto fail_dma; 1440 1380 1441 1381 /* setup message for status/busy readback */ 1442 1382 spi_message_init(&host->readback); ··· 1490 1458 fail_add_host: 1491 1459 mmc_remove_host(mmc); 1492 1460 fail_glue_init: 1493 - if (host->dma_dev) 1494 - dma_unmap_single(host->dma_dev, host->data_dma, 1495 - sizeof(*host->data), DMA_BIDIRECTIONAL); 1496 - fail_data_dma: 1497 - if (host->dma_dev) 1498 - dma_unmap_single(host->dma_dev, host->ones_dma, 1499 - MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE); 1500 - fail_ones_dma: 1461 + mmc_spi_dma_free(host); 1462 + fail_dma: 1501 1463 kfree(host->data); 1502 - 1503 1464 fail_nobuf1: 1504 1465 mmc_free_host(mmc); 1505 1466 mmc_spi_put_pdata(spi); 1506 - 1507 1467 nomem: 1508 1468 kfree(ones); 1509 1469 return status; ··· 1513 1489 1514 1490 mmc_remove_host(mmc); 1515 1491 1516 - if (host->dma_dev) { 1517 - dma_unmap_single(host->dma_dev, host->ones_dma, 1518 - MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE); 1519 - dma_unmap_single(host->dma_dev, host->data_dma, 1520 - sizeof(*host->data), DMA_BIDIRECTIONAL); 1521 - } 1522 - 1492 + mmc_spi_dma_free(host); 1523 1493 kfree(host->data); 1524 1494 kfree(host->ones); 1525 1495
+24 -7
drivers/mmc/host/sdhci-acpi.c
··· 551 551 return MMC_SET_DRIVER_TYPE_A; 552 552 } 553 553 554 - static void sdhci_acpi_amd_hs400_dll(struct sdhci_host *host) 554 + static void sdhci_acpi_amd_hs400_dll(struct sdhci_host *host, bool enable) 555 555 { 556 + struct sdhci_acpi_host *acpi_host = sdhci_priv(host); 557 + struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host); 558 + 556 559 /* AMD Platform requires dll setting */ 557 560 sdhci_writel(host, 0x40003210, SDHCI_AMD_RESET_DLL_REGISTER); 558 561 usleep_range(10, 20); 559 - sdhci_writel(host, 0x40033210, SDHCI_AMD_RESET_DLL_REGISTER); 562 + if (enable) 563 + sdhci_writel(host, 0x40033210, SDHCI_AMD_RESET_DLL_REGISTER); 564 + 565 + amd_host->dll_enabled = enable; 560 566 } 561 567 562 568 /* ··· 602 596 603 597 /* DLL is only required for HS400 */ 604 598 if (host->timing == MMC_TIMING_MMC_HS400 && 605 - !amd_host->dll_enabled) { 606 - sdhci_acpi_amd_hs400_dll(host); 607 - amd_host->dll_enabled = true; 608 - } 599 + !amd_host->dll_enabled) 600 + sdhci_acpi_amd_hs400_dll(host, true); 609 601 } 610 602 } 611 603 ··· 624 620 return err; 625 621 } 626 622 623 + static void amd_sdhci_reset(struct sdhci_host *host, u8 mask) 624 + { 625 + struct sdhci_acpi_host *acpi_host = sdhci_priv(host); 626 + struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host); 627 + 628 + if (mask & SDHCI_RESET_ALL) { 629 + amd_host->tuned_clock = false; 630 + sdhci_acpi_amd_hs400_dll(host, false); 631 + } 632 + 633 + sdhci_reset(host, mask); 634 + } 635 + 627 636 static const struct sdhci_ops sdhci_acpi_ops_amd = { 628 637 .set_clock = sdhci_set_clock, 629 638 .set_bus_width = sdhci_set_bus_width, 630 - .reset = sdhci_reset, 639 + .reset = amd_sdhci_reset, 631 640 .set_uhs_signaling = sdhci_set_uhs_signaling, 632 641 }; 633 642
+17 -1
drivers/mmc/host/sdhci-msm.c
··· 1166 1166 static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode) 1167 1167 { 1168 1168 struct sdhci_host *host = mmc_priv(mmc); 1169 - int tuning_seq_cnt = 3; 1169 + int tuning_seq_cnt = 10; 1170 1170 u8 phase, tuned_phases[16], tuned_phase_cnt = 0; 1171 1171 int rc; 1172 1172 struct mmc_ios ios = host->mmc->ios; ··· 1222 1222 } while (++phase < ARRAY_SIZE(tuned_phases)); 1223 1223 1224 1224 if (tuned_phase_cnt) { 1225 + if (tuned_phase_cnt == ARRAY_SIZE(tuned_phases)) { 1226 + /* 1227 + * All phases valid is _almost_ as bad as no phases 1228 + * valid. Probably all phases are not really reliable 1229 + * but we didn't detect where the unreliable place is. 1230 + * That means we'll essentially be guessing and hoping 1231 + * we get a good phase. Better to try a few times. 1232 + */ 1233 + dev_dbg(mmc_dev(mmc), "%s: All phases valid; try again\n", 1234 + mmc_hostname(mmc)); 1235 + if (--tuning_seq_cnt) { 1236 + tuned_phase_cnt = 0; 1237 + goto retry; 1238 + } 1239 + } 1240 + 1225 1241 rc = msm_find_most_appropriate_phase(host, tuned_phases, 1226 1242 tuned_phase_cnt); 1227 1243 if (rc < 0)
+7 -3
drivers/mmc/host/sdhci-of-esdhc.c
··· 81 81 bool quirk_tuning_erratum_type2; 82 82 bool quirk_ignore_data_inhibit; 83 83 bool quirk_delay_before_data_reset; 84 + bool quirk_trans_complete_erratum; 84 85 bool in_sw_tuning; 85 86 unsigned int peripheral_clock; 86 87 const struct esdhc_clk_fixup *clk_fixup; ··· 1178 1177 1179 1178 static u32 esdhc_irq(struct sdhci_host *host, u32 intmask) 1180 1179 { 1180 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 1181 + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 1181 1182 u32 command; 1182 1183 1183 - if (of_find_compatible_node(NULL, NULL, 1184 - "fsl,p2020-esdhc")) { 1184 + if (esdhc->quirk_trans_complete_erratum) { 1185 1185 command = SDHCI_GET_CMD(sdhci_readw(host, 1186 1186 SDHCI_COMMAND)); 1187 1187 if (command == MMC_WRITE_MULTIPLE_BLOCK && ··· 1336 1334 esdhc->clk_fixup = match->data; 1337 1335 np = pdev->dev.of_node; 1338 1336 1339 - if (of_device_is_compatible(np, "fsl,p2020-esdhc")) 1337 + if (of_device_is_compatible(np, "fsl,p2020-esdhc")) { 1340 1338 esdhc->quirk_delay_before_data_reset = true; 1339 + esdhc->quirk_trans_complete_erratum = true; 1340 + } 1341 1341 1342 1342 clk = of_clk_get(np, 0); 1343 1343 if (!IS_ERR(clk)) {