Commit 4039974f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull spi fixes from Mark Brown:
 "A bunch of driver specific fixes, plus a fix for spi-mem's status
  polling for devices that use GPIO chip selects and a DT bindings
  examples fix that helps with the validation work"

* tag 'spi-fix-v5.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: rockchip: Unmask IRQ at the final to avoid preemption
  spi: dt-bindings: Fix unevaluatedProperties warnings in examples
  spi: spi-mem: Fix spi_mem_poll_status()
  spi: cadence: Detect transmit FIFO depth
  spi: spi-cadence: Fix SPI CS gets toggling sporadically
parents bed05181 419bc8f6
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -47,6 +47,5 @@ examples:
        clocks = <&clkcfg CLK_SPI0>;
        interrupt-parent = <&plic>;
        interrupts = <54>;
        spi-max-frequency = <25000000>;
    };
...
+0 −1
Original line number Diff line number Diff line
@@ -110,7 +110,6 @@ examples:
        pinctrl-names = "default";
        pinctrl-0 = <&qup_spi1_default>;
        interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
        spi-max-frequency = <50000000>;
        #address-cells = <1>;
        #size-cells = <0>;
    };
+31 −6
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@
#define CDNS_SPI_BAUD_DIV_SHIFT		3 /* Baud rate divisor shift in CR */
#define CDNS_SPI_SS_SHIFT		10 /* Slave Select field shift in CR */
#define CDNS_SPI_SS0			0x1 /* Slave Select zero */
#define CDNS_SPI_NOSS			0x3C /* No Slave select */

/*
 * SPI Interrupt Registers bit Masks
@@ -92,9 +93,6 @@
#define CDNS_SPI_ER_ENABLE	0x00000001 /* SPI Enable Bit Mask */
#define CDNS_SPI_ER_DISABLE	0x0 /* SPI Disable Bit Mask */

/* SPI FIFO depth in bytes */
#define CDNS_SPI_FIFO_DEPTH	128

/* Default number of chip select lines */
#define CDNS_SPI_DEFAULT_NUM_CS		4

@@ -110,6 +108,7 @@
 * @rx_bytes:		Number of bytes requested
 * @dev_busy:		Device busy flag
 * @is_decoded_cs:	Flag for decoder property set or not
 * @tx_fifo_depth:	Depth of the TX FIFO
 */
struct cdns_spi {
	void __iomem *regs;
@@ -123,6 +122,7 @@ struct cdns_spi {
	int rx_bytes;
	u8 dev_busy;
	u32 is_decoded_cs;
	unsigned int tx_fifo_depth;
};

/* Macros for the SPI controller read/write */
@@ -304,7 +304,7 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi)
{
	unsigned long trans_cnt = 0;

	while ((trans_cnt < CDNS_SPI_FIFO_DEPTH) &&
	while ((trans_cnt < xspi->tx_fifo_depth) &&
	       (xspi->tx_bytes > 0)) {

		/* When xspi in busy condition, bytes may send failed,
@@ -450,19 +450,42 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
 * @master:	Pointer to the spi_master structure which provides
 *		information about the controller.
 *
 * This function disables the SPI master controller.
 * This function disables the SPI master controller when no slave selected.
 *
 * Return:	0 always
 */
static int cdns_unprepare_transfer_hardware(struct spi_master *master)
{
	struct cdns_spi *xspi = spi_master_get_devdata(master);
	u32 ctrl_reg;

	/* Disable the SPI if slave is deselected */
	ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
	ctrl_reg = (ctrl_reg & CDNS_SPI_CR_SSCTRL) >>  CDNS_SPI_SS_SHIFT;
	if (ctrl_reg == CDNS_SPI_NOSS)
		cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);

	return 0;
}

/**
 * cdns_spi_detect_fifo_depth - Detect the FIFO depth of the hardware
 * @xspi:	Pointer to the cdns_spi structure
 *
 * The depth of the TX FIFO is a synthesis configuration parameter of the SPI
 * IP. The FIFO threshold register is sized so that its maximum value can be the
 * FIFO size - 1. This is used to detect the size of the FIFO.
 */
static void cdns_spi_detect_fifo_depth(struct cdns_spi *xspi)
{
	/* The MSBs will get truncated giving us the size of the FIFO */
	cdns_spi_write(xspi, CDNS_SPI_THLD, 0xffff);
	xspi->tx_fifo_depth = cdns_spi_read(xspi, CDNS_SPI_THLD) + 1;

	/* Reset to default */
	cdns_spi_write(xspi, CDNS_SPI_THLD, 0x1);
}

/**
 * cdns_spi_probe - Probe method for the SPI driver
 * @pdev:	Pointer to the platform_device structure
@@ -535,6 +558,8 @@ static int cdns_spi_probe(struct platform_device *pdev)
	if (ret < 0)
		xspi->is_decoded_cs = 0;

	cdns_spi_detect_fifo_depth(xspi);

	/* SPI controller initializations */
	cdns_spi_init_hw(xspi);

+1 −1
Original line number Diff line number Diff line
@@ -808,7 +808,7 @@ int spi_mem_poll_status(struct spi_mem *mem,
	    op->data.dir != SPI_MEM_DATA_IN)
		return -EINVAL;

	if (ctlr->mem_ops && ctlr->mem_ops->poll_status) {
	if (ctlr->mem_ops && ctlr->mem_ops->poll_status && !mem->spi->cs_gpiod) {
		ret = spi_mem_access_start(mem);
		if (ret)
			return ret;
+7 −4
Original line number Diff line number Diff line
@@ -381,15 +381,18 @@ static int rockchip_spi_prepare_irq(struct rockchip_spi *rs,
	rs->tx_left = rs->tx ? xfer->len / rs->n_bytes : 0;
	rs->rx_left = xfer->len / rs->n_bytes;

	if (rs->cs_inactive)
		writel_relaxed(INT_RF_FULL | INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR);
	else
		writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR);
	writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);

	spi_enable_chip(rs, true);

	if (rs->tx_left)
		rockchip_spi_pio_writer(rs);

	if (rs->cs_inactive)
		writel_relaxed(INT_RF_FULL | INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR);
	else
		writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR);

	/* 1 means the transfer is in progress */
	return 1;
}