Skip to content

Commit 063d6a4

Browse files
committed
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
2 parents d67f2ec + f0c393e commit 063d6a4

File tree

6 files changed

+123
-63
lines changed

6 files changed

+123
-63
lines changed

drivers/mmc/core/sdio_ops.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
121121
struct sg_table sgtable;
122122
unsigned int nents, left_size, i;
123123
unsigned int seg_size = card->host->max_seg_size;
124+
int err;
124125

125126
WARN_ON(blksz == 0);
126127

@@ -170,28 +171,32 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
170171

171172
mmc_set_data_timeout(&data, card);
172173

173-
mmc_wait_for_req(card->host, &mrq);
174+
mmc_pre_req(card->host, &mrq);
174175

175-
if (nents > 1)
176-
sg_free_table(&sgtable);
176+
mmc_wait_for_req(card->host, &mrq);
177177

178178
if (cmd.error)
179-
return cmd.error;
180-
if (data.error)
181-
return data.error;
182-
183-
if (mmc_host_is_spi(card->host)) {
179+
err = cmd.error;
180+
else if (data.error)
181+
err = data.error;
182+
else if (mmc_host_is_spi(card->host))
184183
/* host driver already reported errors */
185-
} else {
186-
if (cmd.resp[0] & R5_ERROR)
187-
return -EIO;
188-
if (cmd.resp[0] & R5_FUNCTION_NUMBER)
189-
return -EINVAL;
190-
if (cmd.resp[0] & R5_OUT_OF_RANGE)
191-
return -ERANGE;
192-
}
184+
err = 0;
185+
else if (cmd.resp[0] & R5_ERROR)
186+
err = -EIO;
187+
else if (cmd.resp[0] & R5_FUNCTION_NUMBER)
188+
err = -EINVAL;
189+
else if (cmd.resp[0] & R5_OUT_OF_RANGE)
190+
err = -ERANGE;
191+
else
192+
err = 0;
193193

194-
return 0;
194+
mmc_post_req(card->host, &mrq, err);
195+
196+
if (nents > 1)
197+
sg_free_table(&sgtable);
198+
199+
return err;
195200
}
196201

197202
int sdio_reset(struct mmc_host *host)

drivers/mmc/host/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ config MMC_GOLDFISH
602602

603603
config MMC_SPI
604604
tristate "MMC/SD/SDIO over SPI"
605-
depends on SPI_MASTER && HAS_DMA
605+
depends on SPI_MASTER
606606
select CRC7
607607
select CRC_ITU_T
608608
help

drivers/mmc/host/mmc_spi.c

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,52 @@ mmc_spi_detect_irq(int irq, void *mmc)
12781278
return IRQ_HANDLED;
12791279
}
12801280

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+
12811327
static int mmc_spi_probe(struct spi_device *spi)
12821328
{
12831329
void *ones;
@@ -1374,23 +1420,9 @@ static int mmc_spi_probe(struct spi_device *spi)
13741420
if (!host->data)
13751421
goto fail_nobuf1;
13761422

1377-
if (spi->master->dev.parent->dma_mask) {
1378-
struct device *dev = spi->master->dev.parent;
1379-
1380-
host->dma_dev = dev;
1381-
host->ones_dma = dma_map_single(dev, ones,
1382-
MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
1383-
if (dma_mapping_error(dev, host->ones_dma))
1384-
goto fail_ones_dma;
1385-
host->data_dma = dma_map_single(dev, host->data,
1386-
sizeof(*host->data), DMA_BIDIRECTIONAL);
1387-
if (dma_mapping_error(dev, host->data_dma))
1388-
goto fail_data_dma;
1389-
1390-
dma_sync_single_for_cpu(host->dma_dev,
1391-
host->data_dma, sizeof(*host->data),
1392-
DMA_BIDIRECTIONAL);
1393-
}
1423+
status = mmc_spi_dma_alloc(host);
1424+
if (status)
1425+
goto fail_dma;
13941426

13951427
/* setup message for status/busy readback */
13961428
spi_message_init(&host->readback);
@@ -1458,20 +1490,12 @@ static int mmc_spi_probe(struct spi_device *spi)
14581490
fail_add_host:
14591491
mmc_remove_host(mmc);
14601492
fail_glue_init:
1461-
if (host->dma_dev)
1462-
dma_unmap_single(host->dma_dev, host->data_dma,
1463-
sizeof(*host->data), DMA_BIDIRECTIONAL);
1464-
fail_data_dma:
1465-
if (host->dma_dev)
1466-
dma_unmap_single(host->dma_dev, host->ones_dma,
1467-
MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
1468-
fail_ones_dma:
1493+
mmc_spi_dma_free(host);
1494+
fail_dma:
14691495
kfree(host->data);
1470-
14711496
fail_nobuf1:
14721497
mmc_free_host(mmc);
14731498
mmc_spi_put_pdata(spi);
1474-
14751499
nomem:
14761500
kfree(ones);
14771501
return status;
@@ -1489,13 +1513,7 @@ static int mmc_spi_remove(struct spi_device *spi)
14891513

14901514
mmc_remove_host(mmc);
14911515

1492-
if (host->dma_dev) {
1493-
dma_unmap_single(host->dma_dev, host->ones_dma,
1494-
MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
1495-
dma_unmap_single(host->dma_dev, host->data_dma,
1496-
sizeof(*host->data), DMA_BIDIRECTIONAL);
1497-
}
1498-
1516+
mmc_spi_dma_free(host);
14991517
kfree(host->data);
15001518
kfree(host->ones);
15011519

drivers/mmc/host/sdhci-acpi.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -551,12 +551,18 @@ static int amd_select_drive_strength(struct mmc_card *card,
551551
return MMC_SET_DRIVER_TYPE_A;
552552
}
553553

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)
555555
{
556+
struct sdhci_acpi_host *acpi_host = sdhci_priv(host);
557+
struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host);
558+
556559
/* AMD Platform requires dll setting */
557560
sdhci_writel(host, 0x40003210, SDHCI_AMD_RESET_DLL_REGISTER);
558561
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;
560566
}
561567

562568
/*
@@ -596,10 +602,8 @@ static void amd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
596602

597603
/* DLL is only required for HS400 */
598604
if (host->timing == MMC_TIMING_MMC_HS400 &&
599-
!amd_host->dll_enabled) {
600-
sdhci_acpi_amd_hs400_dll(host);
601-
amd_host->dll_enabled = true;
602-
}
605+
!amd_host->dll_enabled)
606+
sdhci_acpi_amd_hs400_dll(host, true);
603607
}
604608
}
605609

@@ -620,10 +624,23 @@ static int amd_sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
620624
return err;
621625
}
622626

627+
static void amd_sdhci_reset(struct sdhci_host *host, u8 mask)
628+
{
629+
struct sdhci_acpi_host *acpi_host = sdhci_priv(host);
630+
struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host);
631+
632+
if (mask & SDHCI_RESET_ALL) {
633+
amd_host->tuned_clock = false;
634+
sdhci_acpi_amd_hs400_dll(host, false);
635+
}
636+
637+
sdhci_reset(host, mask);
638+
}
639+
623640
static const struct sdhci_ops sdhci_acpi_ops_amd = {
624641
.set_clock = sdhci_set_clock,
625642
.set_bus_width = sdhci_set_bus_width,
626-
.reset = sdhci_reset,
643+
.reset = amd_sdhci_reset,
627644
.set_uhs_signaling = sdhci_set_uhs_signaling,
628645
};
629646

drivers/mmc/host/sdhci-msm.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ static void sdhci_msm_set_cdr(struct sdhci_host *host, bool enable)
11661166
static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode)
11671167
{
11681168
struct sdhci_host *host = mmc_priv(mmc);
1169-
int tuning_seq_cnt = 3;
1169+
int tuning_seq_cnt = 10;
11701170
u8 phase, tuned_phases[16], tuned_phase_cnt = 0;
11711171
int rc;
11721172
struct mmc_ios ios = host->mmc->ios;
@@ -1222,6 +1222,22 @@ static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode)
12221222
} while (++phase < ARRAY_SIZE(tuned_phases));
12231223

12241224
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+
12251241
rc = msm_find_most_appropriate_phase(host, tuned_phases,
12261242
tuned_phase_cnt);
12271243
if (rc < 0)

drivers/mmc/host/sdhci-of-esdhc.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct sdhci_esdhc {
8181
bool quirk_tuning_erratum_type2;
8282
bool quirk_ignore_data_inhibit;
8383
bool quirk_delay_before_data_reset;
84+
bool quirk_trans_complete_erratum;
8485
bool in_sw_tuning;
8586
unsigned int peripheral_clock;
8687
const struct esdhc_clk_fixup *clk_fixup;
@@ -1177,10 +1178,11 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host,
11771178

11781179
static u32 esdhc_irq(struct sdhci_host *host, u32 intmask)
11791180
{
1181+
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1182+
struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
11801183
u32 command;
11811184

1182-
if (of_find_compatible_node(NULL, NULL,
1183-
"fsl,p2020-esdhc")) {
1185+
if (esdhc->quirk_trans_complete_erratum) {
11841186
command = SDHCI_GET_CMD(sdhci_readw(host,
11851187
SDHCI_COMMAND));
11861188
if (command == MMC_WRITE_MULTIPLE_BLOCK &&
@@ -1334,8 +1336,10 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
13341336
esdhc->clk_fixup = match->data;
13351337
np = pdev->dev.of_node;
13361338

1337-
if (of_device_is_compatible(np, "fsl,p2020-esdhc"))
1339+
if (of_device_is_compatible(np, "fsl,p2020-esdhc")) {
13381340
esdhc->quirk_delay_before_data_reset = true;
1341+
esdhc->quirk_trans_complete_erratum = true;
1342+
}
13391343

13401344
clk = of_clk_get(np, 0);
13411345
if (!IS_ERR(clk)) {

0 commit comments

Comments
 (0)