Skip to content

Commit 7351a87

Browse files
committed
Merge tag 'mmc-v6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC fixes from Ulf Hansson: "MMC core: - Prevent splat from warning when setting maximum DMA segment MMC host: - mvsdio: Drop sg_miter support for PIO as it didn't work - sdhci-of-dwcmshc: Prevent stale interrupt for the T-Head 1520 variant" * tag 'mmc-v6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: sdhci-of-dwcmshc: Prevent stale command interrupt handling Revert "mmc: mvsdio: Use sg_miter for PIO" mmc: core: Only set maximum DMA segment size if DMA is supported
2 parents 3700dc9 + 27e8fe0 commit 7351a87

File tree

3 files changed

+28
-54
lines changed

3 files changed

+28
-54
lines changed

drivers/mmc/core/queue.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ static struct gendisk *mmc_alloc_disk(struct mmc_queue *mq,
388388

389389
blk_queue_rq_timeout(mq->queue, 60 * HZ);
390390

391-
dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue));
391+
if (mmc_dev(host)->dma_parms)
392+
dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue));
392393

393394
INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler);
394395
INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work);

drivers/mmc/host/mvsdio.c

Lines changed: 18 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ struct mvsd_host {
3838
unsigned int xfer_mode;
3939
unsigned int intr_en;
4040
unsigned int ctrl;
41-
bool use_pio;
42-
struct sg_mapping_iter sg_miter;
4341
unsigned int pio_size;
42+
void *pio_ptr;
4443
unsigned int sg_frags;
4544
unsigned int ns_per_clk;
4645
unsigned int clock;
@@ -115,18 +114,11 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
115114
* data when the buffer is not aligned on a 64 byte
116115
* boundary.
117116
*/
118-
unsigned int miter_flags = SG_MITER_ATOMIC; /* Used from IRQ */
119-
120-
if (data->flags & MMC_DATA_READ)
121-
miter_flags |= SG_MITER_TO_SG;
122-
else
123-
miter_flags |= SG_MITER_FROM_SG;
124-
125117
host->pio_size = data->blocks * data->blksz;
126-
sg_miter_start(&host->sg_miter, data->sg, data->sg_len, miter_flags);
118+
host->pio_ptr = sg_virt(data->sg);
127119
if (!nodma)
128-
dev_dbg(host->dev, "fallback to PIO for data\n");
129-
host->use_pio = true;
120+
dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n",
121+
host->pio_ptr, host->pio_size);
130122
return 1;
131123
} else {
132124
dma_addr_t phys_addr;
@@ -137,7 +129,6 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
137129
phys_addr = sg_dma_address(data->sg);
138130
mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff);
139131
mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16);
140-
host->use_pio = false;
141132
return 0;
142133
}
143134
}
@@ -297,8 +288,8 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
297288
{
298289
void __iomem *iobase = host->base;
299290

300-
if (host->use_pio) {
301-
sg_miter_stop(&host->sg_miter);
291+
if (host->pio_ptr) {
292+
host->pio_ptr = NULL;
302293
host->pio_size = 0;
303294
} else {
304295
dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
@@ -353,12 +344,9 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
353344
static irqreturn_t mvsd_irq(int irq, void *dev)
354345
{
355346
struct mvsd_host *host = dev;
356-
struct sg_mapping_iter *sgm = &host->sg_miter;
357347
void __iomem *iobase = host->base;
358348
u32 intr_status, intr_done_mask;
359349
int irq_handled = 0;
360-
u16 *p;
361-
int s;
362350

363351
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
364352
dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n",
@@ -382,36 +370,15 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
382370
spin_lock(&host->lock);
383371

384372
/* PIO handling, if needed. Messy business... */
385-
if (host->use_pio) {
386-
/*
387-
* As we set sgm->consumed this always gives a valid buffer
388-
* position.
389-
*/
390-
if (!sg_miter_next(sgm)) {
391-
/* This should not happen */
392-
dev_err(host->dev, "ran out of scatter segments\n");
393-
spin_unlock(&host->lock);
394-
host->intr_en &=
395-
~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W |
396-
MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
397-
mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
398-
return IRQ_HANDLED;
399-
}
400-
p = sgm->addr;
401-
s = sgm->length;
402-
if (s > host->pio_size)
403-
s = host->pio_size;
404-
}
405-
406-
if (host->use_pio &&
373+
if (host->pio_size &&
407374
(intr_status & host->intr_en &
408375
(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
409-
376+
u16 *p = host->pio_ptr;
377+
int s = host->pio_size;
410378
while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
411379
readsw(iobase + MVSD_FIFO, p, 16);
412380
p += 16;
413381
s -= 32;
414-
sgm->consumed += 32;
415382
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
416383
}
417384
/*
@@ -424,21 +391,17 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
424391
put_unaligned(mvsd_read(MVSD_FIFO), p++);
425392
put_unaligned(mvsd_read(MVSD_FIFO), p++);
426393
s -= 4;
427-
sgm->consumed += 4;
428394
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
429395
}
430396
if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) {
431397
u16 val[2] = {0, 0};
432398
val[0] = mvsd_read(MVSD_FIFO);
433399
val[1] = mvsd_read(MVSD_FIFO);
434400
memcpy(p, ((void *)&val) + 4 - s, s);
435-
sgm->consumed += s;
436401
s = 0;
437402
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
438403
}
439-
/* PIO transfer done */
440-
host->pio_size -= sgm->consumed;
441-
if (host->pio_size == 0) {
404+
if (s == 0) {
442405
host->intr_en &=
443406
~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
444407
mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
@@ -450,10 +413,14 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
450413
}
451414
dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
452415
s, intr_status, mvsd_read(MVSD_HW_STATE));
416+
host->pio_ptr = p;
417+
host->pio_size = s;
453418
irq_handled = 1;
454-
} else if (host->use_pio &&
419+
} else if (host->pio_size &&
455420
(intr_status & host->intr_en &
456421
(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
422+
u16 *p = host->pio_ptr;
423+
int s = host->pio_size;
457424
/*
458425
* The TX_FIFO_8W bit is unreliable. When set, bursting
459426
* 16 halfwords all at once in the FIFO drops data. Actually
@@ -464,7 +431,6 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
464431
mvsd_write(MVSD_FIFO, get_unaligned(p++));
465432
mvsd_write(MVSD_FIFO, get_unaligned(p++));
466433
s -= 4;
467-
sgm->consumed += 4;
468434
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
469435
}
470436
if (s < 4) {
@@ -473,20 +439,19 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
473439
memcpy(((void *)&val) + 4 - s, p, s);
474440
mvsd_write(MVSD_FIFO, val[0]);
475441
mvsd_write(MVSD_FIFO, val[1]);
476-
sgm->consumed += s;
477442
s = 0;
478443
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
479444
}
480-
/* PIO transfer done */
481-
host->pio_size -= sgm->consumed;
482-
if (host->pio_size == 0) {
445+
if (s == 0) {
483446
host->intr_en &=
484447
~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
485448
mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
486449
}
487450
}
488451
dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
489452
s, intr_status, mvsd_read(MVSD_HW_STATE));
453+
host->pio_ptr = p;
454+
host->pio_size = s;
490455
irq_handled = 1;
491456
}
492457

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,14 @@ static void th1520_sdhci_reset(struct sdhci_host *host, u8 mask)
852852

853853
sdhci_reset(host, mask);
854854

855+
/* The T-Head 1520 SoC does not comply with the SDHCI specification
856+
* regarding the "Software Reset for CMD line should clear 'Command
857+
* Complete' in the Normal Interrupt Status Register." Clear the bit
858+
* here to compensate for this quirk.
859+
*/
860+
if (mask & SDHCI_RESET_CMD)
861+
sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
862+
855863
if (priv->flags & FLAG_IO_FIXED_1V8) {
856864
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
857865
if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) {

0 commit comments

Comments
 (0)