Skip to content

Commit d26143b

Browse files
committed
Merge tag 'spi-fix-v6.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fixes from Mark Brown: "We've got more fixes here for the Cadence QSPI controller, this time fixing some issues that come up when working with slower flashes on some platforms plus a general race condition. We also add support for the Allwinner A523, this is just some new compatibles" * tag 'spi-fix-v6.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi: cadence-quadspi: Improve CQSPI_SLOW_SRAM quirk if flash is slow spi: cadence-quadspi: Prevent lost complete() call during indirect read spi: sun6i: Support A523's SPI controllers spi: dt-bindings: sun6i: Add compatibles for A523's SPI controllers
2 parents 651df41 + b005d61 commit d26143b

3 files changed

Lines changed: 22 additions & 16 deletions

File tree

Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ properties:
1717
compatible:
1818
oneOf:
1919
- const: allwinner,sun50i-r329-spi
20+
- const: allwinner,sun55i-a523-spi
2021
- const: allwinner,sun6i-a31-spi
2122
- const: allwinner,sun8i-h3-spi
2223
- items:
@@ -35,6 +36,9 @@ properties:
3536
- const: allwinner,sun20i-d1-spi-dbi
3637
- const: allwinner,sun50i-r329-spi-dbi
3738
- const: allwinner,sun50i-r329-spi
39+
- items:
40+
- const: allwinner,sun55i-a523-spi-dbi
41+
- const: allwinner,sun55i-a523-spi
3842

3943
reg:
4044
maxItems: 1

drivers/spi/spi-cadence-quadspi.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,9 @@ struct cqspi_driver_platdata {
300300
CQSPI_REG_IRQ_IND_SRAM_FULL | \
301301
CQSPI_REG_IRQ_IND_COMP)
302302

303+
#define CQSPI_IRQ_MASK_RD_SLOW_SRAM (CQSPI_REG_IRQ_WATERMARK | \
304+
CQSPI_REG_IRQ_IND_COMP)
305+
303306
#define CQSPI_IRQ_MASK_WR (CQSPI_REG_IRQ_IND_COMP | \
304307
CQSPI_REG_IRQ_WATERMARK | \
305308
CQSPI_REG_IRQ_UNDERFLOW)
@@ -381,7 +384,7 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void *dev)
381384
else if (!cqspi->slow_sram)
382385
irq_status &= CQSPI_IRQ_MASK_RD | CQSPI_IRQ_MASK_WR;
383386
else
384-
irq_status &= CQSPI_REG_IRQ_WATERMARK | CQSPI_IRQ_MASK_WR;
387+
irq_status &= CQSPI_IRQ_MASK_RD_SLOW_SRAM | CQSPI_IRQ_MASK_WR;
385388

386389
if (irq_status)
387390
complete(&cqspi->transfer_complete);
@@ -757,7 +760,7 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
757760
*/
758761

759762
if (use_irq && cqspi->slow_sram)
760-
writel(CQSPI_REG_IRQ_WATERMARK, reg_base + CQSPI_REG_IRQMASK);
763+
writel(CQSPI_IRQ_MASK_RD_SLOW_SRAM, reg_base + CQSPI_REG_IRQMASK);
761764
else if (use_irq)
762765
writel(CQSPI_IRQ_MASK_RD, reg_base + CQSPI_REG_IRQMASK);
763766
else
@@ -769,17 +772,19 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
769772
readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */
770773

771774
while (remaining > 0) {
775+
ret = 0;
772776
if (use_irq &&
773777
!wait_for_completion_timeout(&cqspi->transfer_complete,
774778
msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
775779
ret = -ETIMEDOUT;
776780

777781
/*
778-
* Disable all read interrupts until
779-
* we are out of "bytes to read"
782+
* Prevent lost interrupt and race condition by reinitializing early.
783+
* A spurious wakeup and another wait cycle can occur here,
784+
* which is preferable to waiting until timeout if interrupt is lost.
780785
*/
781-
if (cqspi->slow_sram)
782-
writel(0x0, reg_base + CQSPI_REG_IRQMASK);
786+
if (use_irq)
787+
reinit_completion(&cqspi->transfer_complete);
783788

784789
bytes_to_read = cqspi_get_rd_sram_level(cqspi);
785790

@@ -811,12 +816,6 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
811816
remaining -= bytes_to_read;
812817
bytes_to_read = cqspi_get_rd_sram_level(cqspi);
813818
}
814-
815-
if (use_irq && remaining > 0) {
816-
reinit_completion(&cqspi->transfer_complete);
817-
if (cqspi->slow_sram)
818-
writel(CQSPI_REG_IRQ_WATERMARK, reg_base + CQSPI_REG_IRQMASK);
819-
}
820819
}
821820

822821
/* Check indirect done status */

drivers/spi/spi-sun6i.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -795,10 +795,13 @@ static const struct sun6i_spi_cfg sun50i_r329_spi_cfg = {
795795
static const struct of_device_id sun6i_spi_match[] = {
796796
{ .compatible = "allwinner,sun6i-a31-spi", .data = &sun6i_a31_spi_cfg },
797797
{ .compatible = "allwinner,sun8i-h3-spi", .data = &sun8i_h3_spi_cfg },
798-
{
799-
.compatible = "allwinner,sun50i-r329-spi",
800-
.data = &sun50i_r329_spi_cfg
801-
},
798+
{ .compatible = "allwinner,sun50i-r329-spi", .data = &sun50i_r329_spi_cfg },
799+
/*
800+
* A523's SPI controller has a combined RX buffer + FIFO counter
801+
* at offset 0x400, instead of split buffer count in FIFO status
802+
* register. But in practice we only care about the FIFO level.
803+
*/
804+
{ .compatible = "allwinner,sun55i-a523-spi", .data = &sun50i_r329_spi_cfg },
802805
{}
803806
};
804807
MODULE_DEVICE_TABLE(of, sun6i_spi_match);

0 commit comments

Comments
 (0)