mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
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 -----BEGIN PGP SIGNATURE----- iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmcI+WUXHHVsZi5oYW5z c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCk8NxAAh5FTy5hDHcARYD9S1RQg/Q46 X5obeuH9nPrpvxugTWQ8Cw65o70a1nX0AfJVefnw8yhBda+iCXIspqKAKZgBid7i L6jB2K54jSDxHslee6WeGwPH1Zr/XyEIrW59D2GxIcAK30eaDhzEI7C0gMh6uJbI ZsqeJnd1bQU2r+x4P5BPtSkg/bd0vEbMEDavx7B4suSPcVDkip8hYIH3Iv+SXz+U IE5VfDho3TlaOX1O+naM8RZnXEP6GJBkaCxwVyF2QUHFIXCqbdKtQBcWirc9zcaC MgMIeAX4VBeGNe1xolcGJc8iRRpMHw1rGL5tnMsPkBfku44UbWylAlvi1zZNEdnE DuPG1OGiJdrAUIP7pFGtpycNXMP7x6vqaE2vGhrK231kPYL3Tvs9ZoAu+D+0XPEX wSy/BHgGSmN2NnCpkuhfnxr4QU9DtPcl1oOfPwen28Y6v/FYNc76IQrMzwSj6o+y ZvTUyol5O+HBhTfM/iYlJqCORKM2uNbpkV0Fp6PTUY5Z/pmZJX4aZ1uJgLYApqcS uuqKwR7Avxlp4eKBbGGhvwlD1r1hvfCF/eQJv0Mh6rF+/PUIBNricPGgi2pLkWNB JKnLOgiceKHHq4mxLp2quxomKg5MyawZhbBn1/v3o7JRUavw+GZtIqhqjZE0B2EL +ewX+PXGqk1XMJvhB8Y= =dlxF -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
7351a8793d
@ -388,7 +388,8 @@ static struct gendisk *mmc_alloc_disk(struct mmc_queue *mq,
|
||||
|
||||
blk_queue_rq_timeout(mq->queue, 60 * HZ);
|
||||
|
||||
dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue));
|
||||
if (mmc_dev(host)->dma_parms)
|
||||
dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue));
|
||||
|
||||
INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler);
|
||||
INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work);
|
||||
|
@ -38,9 +38,8 @@ struct mvsd_host {
|
||||
unsigned int xfer_mode;
|
||||
unsigned int intr_en;
|
||||
unsigned int ctrl;
|
||||
bool use_pio;
|
||||
struct sg_mapping_iter sg_miter;
|
||||
unsigned int pio_size;
|
||||
void *pio_ptr;
|
||||
unsigned int sg_frags;
|
||||
unsigned int ns_per_clk;
|
||||
unsigned int clock;
|
||||
@ -115,18 +114,11 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
|
||||
* data when the buffer is not aligned on a 64 byte
|
||||
* boundary.
|
||||
*/
|
||||
unsigned int miter_flags = SG_MITER_ATOMIC; /* Used from IRQ */
|
||||
|
||||
if (data->flags & MMC_DATA_READ)
|
||||
miter_flags |= SG_MITER_TO_SG;
|
||||
else
|
||||
miter_flags |= SG_MITER_FROM_SG;
|
||||
|
||||
host->pio_size = data->blocks * data->blksz;
|
||||
sg_miter_start(&host->sg_miter, data->sg, data->sg_len, miter_flags);
|
||||
host->pio_ptr = sg_virt(data->sg);
|
||||
if (!nodma)
|
||||
dev_dbg(host->dev, "fallback to PIO for data\n");
|
||||
host->use_pio = true;
|
||||
dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n",
|
||||
host->pio_ptr, host->pio_size);
|
||||
return 1;
|
||||
} else {
|
||||
dma_addr_t phys_addr;
|
||||
@ -137,7 +129,6 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
|
||||
phys_addr = sg_dma_address(data->sg);
|
||||
mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff);
|
||||
mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16);
|
||||
host->use_pio = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -297,8 +288,8 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
|
||||
{
|
||||
void __iomem *iobase = host->base;
|
||||
|
||||
if (host->use_pio) {
|
||||
sg_miter_stop(&host->sg_miter);
|
||||
if (host->pio_ptr) {
|
||||
host->pio_ptr = NULL;
|
||||
host->pio_size = 0;
|
||||
} else {
|
||||
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,
|
||||
static irqreturn_t mvsd_irq(int irq, void *dev)
|
||||
{
|
||||
struct mvsd_host *host = dev;
|
||||
struct sg_mapping_iter *sgm = &host->sg_miter;
|
||||
void __iomem *iobase = host->base;
|
||||
u32 intr_status, intr_done_mask;
|
||||
int irq_handled = 0;
|
||||
u16 *p;
|
||||
int s;
|
||||
|
||||
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
|
||||
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)
|
||||
spin_lock(&host->lock);
|
||||
|
||||
/* PIO handling, if needed. Messy business... */
|
||||
if (host->use_pio) {
|
||||
/*
|
||||
* As we set sgm->consumed this always gives a valid buffer
|
||||
* position.
|
||||
*/
|
||||
if (!sg_miter_next(sgm)) {
|
||||
/* This should not happen */
|
||||
dev_err(host->dev, "ran out of scatter segments\n");
|
||||
spin_unlock(&host->lock);
|
||||
host->intr_en &=
|
||||
~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W |
|
||||
MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
|
||||
mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
p = sgm->addr;
|
||||
s = sgm->length;
|
||||
if (s > host->pio_size)
|
||||
s = host->pio_size;
|
||||
}
|
||||
|
||||
if (host->use_pio &&
|
||||
if (host->pio_size &&
|
||||
(intr_status & host->intr_en &
|
||||
(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
|
||||
|
||||
u16 *p = host->pio_ptr;
|
||||
int s = host->pio_size;
|
||||
while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
|
||||
readsw(iobase + MVSD_FIFO, p, 16);
|
||||
p += 16;
|
||||
s -= 32;
|
||||
sgm->consumed += 32;
|
||||
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
|
||||
}
|
||||
/*
|
||||
@ -424,7 +391,6 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
|
||||
put_unaligned(mvsd_read(MVSD_FIFO), p++);
|
||||
put_unaligned(mvsd_read(MVSD_FIFO), p++);
|
||||
s -= 4;
|
||||
sgm->consumed += 4;
|
||||
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
|
||||
}
|
||||
if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) {
|
||||
@ -432,13 +398,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
|
||||
val[0] = mvsd_read(MVSD_FIFO);
|
||||
val[1] = mvsd_read(MVSD_FIFO);
|
||||
memcpy(p, ((void *)&val) + 4 - s, s);
|
||||
sgm->consumed += s;
|
||||
s = 0;
|
||||
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
|
||||
}
|
||||
/* PIO transfer done */
|
||||
host->pio_size -= sgm->consumed;
|
||||
if (host->pio_size == 0) {
|
||||
if (s == 0) {
|
||||
host->intr_en &=
|
||||
~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
|
||||
mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
|
||||
@ -450,10 +413,14 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
|
||||
}
|
||||
dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
|
||||
s, intr_status, mvsd_read(MVSD_HW_STATE));
|
||||
host->pio_ptr = p;
|
||||
host->pio_size = s;
|
||||
irq_handled = 1;
|
||||
} else if (host->use_pio &&
|
||||
} else if (host->pio_size &&
|
||||
(intr_status & host->intr_en &
|
||||
(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
|
||||
u16 *p = host->pio_ptr;
|
||||
int s = host->pio_size;
|
||||
/*
|
||||
* The TX_FIFO_8W bit is unreliable. When set, bursting
|
||||
* 16 halfwords all at once in the FIFO drops data. Actually
|
||||
@ -464,7 +431,6 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
|
||||
mvsd_write(MVSD_FIFO, get_unaligned(p++));
|
||||
mvsd_write(MVSD_FIFO, get_unaligned(p++));
|
||||
s -= 4;
|
||||
sgm->consumed += 4;
|
||||
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
|
||||
}
|
||||
if (s < 4) {
|
||||
@ -473,13 +439,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
|
||||
memcpy(((void *)&val) + 4 - s, p, s);
|
||||
mvsd_write(MVSD_FIFO, val[0]);
|
||||
mvsd_write(MVSD_FIFO, val[1]);
|
||||
sgm->consumed += s;
|
||||
s = 0;
|
||||
intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
|
||||
}
|
||||
/* PIO transfer done */
|
||||
host->pio_size -= sgm->consumed;
|
||||
if (host->pio_size == 0) {
|
||||
if (s == 0) {
|
||||
host->intr_en &=
|
||||
~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
|
||||
mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
|
||||
@ -487,6 +450,8 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
|
||||
}
|
||||
dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
|
||||
s, intr_status, mvsd_read(MVSD_HW_STATE));
|
||||
host->pio_ptr = p;
|
||||
host->pio_size = s;
|
||||
irq_handled = 1;
|
||||
}
|
||||
|
||||
|
@ -852,6 +852,14 @@ static void th1520_sdhci_reset(struct sdhci_host *host, u8 mask)
|
||||
|
||||
sdhci_reset(host, mask);
|
||||
|
||||
/* The T-Head 1520 SoC does not comply with the SDHCI specification
|
||||
* regarding the "Software Reset for CMD line should clear 'Command
|
||||
* Complete' in the Normal Interrupt Status Register." Clear the bit
|
||||
* here to compensate for this quirk.
|
||||
*/
|
||||
if (mask & SDHCI_RESET_CMD)
|
||||
sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
|
||||
|
||||
if (priv->flags & FLAG_IO_FIXED_1V8) {
|
||||
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
|
||||
if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) {
|
||||
|
Loading…
Reference in New Issue
Block a user