Skip to content

Commit 5b35746

Browse files
Linus Walleijstorulf
authored andcommitted
Revert "mmc: mvsdio: Use sg_miter for PIO"
This reverts commit 2761822. When testing on real hardware the patch does not work. Revert, try to acquire real hardware, and retry. These systems typically don't have highmem anyway so the impact is likely zero. Cc: [email protected] Reported-by: Charlie <[email protected]> Signed-off-by: Linus Walleij <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent c26339f commit 5b35746

File tree

1 file changed

+18
-53
lines changed

1 file changed

+18
-53
lines changed

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

0 commit comments

Comments
 (0)