Commit d26143bb authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 651df419 b005d618
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ properties:
  compatible:
    oneOf:
      - const: allwinner,sun50i-r329-spi
      - const: allwinner,sun55i-a523-spi
      - const: allwinner,sun6i-a31-spi
      - const: allwinner,sun8i-h3-spi
      - items:
@@ -35,6 +36,9 @@ properties:
          - const: allwinner,sun20i-d1-spi-dbi
          - const: allwinner,sun50i-r329-spi-dbi
          - const: allwinner,sun50i-r329-spi
      - items:
          - const: allwinner,sun55i-a523-spi-dbi
          - const: allwinner,sun55i-a523-spi

  reg:
    maxItems: 1
+11 −12
Original line number Diff line number Diff line
@@ -300,6 +300,9 @@ struct cqspi_driver_platdata {
					 CQSPI_REG_IRQ_IND_SRAM_FULL	| \
					 CQSPI_REG_IRQ_IND_COMP)

#define CQSPI_IRQ_MASK_RD_SLOW_SRAM	(CQSPI_REG_IRQ_WATERMARK	| \
					 CQSPI_REG_IRQ_IND_COMP)

#define CQSPI_IRQ_MASK_WR		(CQSPI_REG_IRQ_IND_COMP		| \
					 CQSPI_REG_IRQ_WATERMARK	| \
					 CQSPI_REG_IRQ_UNDERFLOW)
@@ -381,7 +384,7 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void *dev)
	else if (!cqspi->slow_sram)
		irq_status &= CQSPI_IRQ_MASK_RD | CQSPI_IRQ_MASK_WR;
	else
		irq_status &= CQSPI_REG_IRQ_WATERMARK | CQSPI_IRQ_MASK_WR;
		irq_status &= CQSPI_IRQ_MASK_RD_SLOW_SRAM | CQSPI_IRQ_MASK_WR;

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

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

	while (remaining > 0) {
		ret = 0;
		if (use_irq &&
		    !wait_for_completion_timeout(&cqspi->transfer_complete,
						 msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
			ret = -ETIMEDOUT;

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

		bytes_to_read = cqspi_get_rd_sram_level(cqspi);

@@ -811,12 +816,6 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
			remaining -= bytes_to_read;
			bytes_to_read = cqspi_get_rd_sram_level(cqspi);
		}

		if (use_irq && remaining > 0) {
			reinit_completion(&cqspi->transfer_complete);
			if (cqspi->slow_sram)
				writel(CQSPI_REG_IRQ_WATERMARK, reg_base + CQSPI_REG_IRQMASK);
		}
	}

	/* Check indirect done status */
+7 −4
Original line number Diff line number Diff line
@@ -795,10 +795,13 @@ static const struct sun6i_spi_cfg sun50i_r329_spi_cfg = {
static const struct of_device_id sun6i_spi_match[] = {
	{ .compatible = "allwinner,sun6i-a31-spi", .data = &sun6i_a31_spi_cfg },
	{ .compatible = "allwinner,sun8i-h3-spi",  .data = &sun8i_h3_spi_cfg },
	{
		.compatible = "allwinner,sun50i-r329-spi",
		.data = &sun50i_r329_spi_cfg
	},
	{ .compatible = "allwinner,sun50i-r329-spi", .data = &sun50i_r329_spi_cfg },
	/*
	 * A523's SPI controller has a combined RX buffer + FIFO counter
	 * at offset 0x400, instead of split buffer count in FIFO status
	 * register. But in practice we only care about the FIFO level.
	 */
	{ .compatible = "allwinner,sun55i-a523-spi", .data = &sun50i_r329_spi_cfg },
	{}
};
MODULE_DEVICE_TABLE(of, sun6i_spi_match);