Commit 894d6f40 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull spi fixes from Mark Brown:
 "A small collection of fixes for SPI, small mostly driver specific
  things plus a fix for module autoloading which hadn't been working
  properly for DT systems"

* tag 'spi-fix-v5.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: cadence-quadspi: Fix check condition for DTR ops
  spi: mediatek: Fix fifo transfer
  spi: imx: mx51-ecspi: Fix CONFIGREG delay comment
  spi: imx: mx51-ecspi: Fix low-speed CONFIGREG delay calculation
  spi: update modalias_show after of_device_uevent_modalias support
  spi: meson-spicc: fix memory leak in meson_spicc_remove
  spi: spi-mux: Add module info needed for autoloading
parents 4f1be396 0395be96
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -325,7 +325,15 @@ static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
	f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
	f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
	f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
	f_pdata->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr;

	/*
	 * For an op to be DTR, cmd phase along with every other non-empty
	 * phase should have dtr field set to 1. If an op phase has zero
	 * nbytes, ignore its dtr field; otherwise, check its dtr field.
	 */
	f_pdata->dtr = op->cmd.dtr &&
		       (!op->addr.nbytes || op->addr.dtr) &&
		       (!op->data.nbytes || op->data.dtr);

	switch (op->data.buswidth) {
	case 0:
@@ -1228,8 +1236,15 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem,
{
	bool all_true, all_false;

	all_true = op->cmd.dtr && op->addr.dtr && op->dummy.dtr &&
		   op->data.dtr;
	/*
	 * op->dummy.dtr is required for converting nbytes into ncycles.
	 * Also, don't check the dtr field of the op phase having zero nbytes.
	 */
	all_true = op->cmd.dtr &&
		   (!op->addr.nbytes || op->addr.dtr) &&
		   (!op->dummy.nbytes || op->dummy.dtr) &&
		   (!op->data.nbytes || op->data.dtr);

	all_false = !op->cmd.dtr && !op->addr.dtr && !op->dummy.dtr &&
		    !op->data.dtr;

+16 −2
Original line number Diff line number Diff line
@@ -505,7 +505,9 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
				      struct spi_message *msg)
{
	struct spi_device *spi = msg->spi;
	struct spi_transfer *xfer;
	u32 ctrl = MX51_ECSPI_CTRL_ENABLE;
	u32 min_speed_hz = ~0U;
	u32 testreg, delay;
	u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG);

@@ -577,9 +579,21 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
	 * be asserted before the SCLK polarity changes, which would disrupt
	 * the SPI communication as the device on the other end would consider
	 * the change of SCLK polarity as a clock tick already.
	 *
	 * Because spi_imx->spi_bus_clk is only set in bitbang prepare_message
	 * callback, iterate over all the transfers in spi_message, find the
	 * one with lowest bus frequency, and use that bus frequency for the
	 * delay calculation. In case all transfers have speed_hz == 0, then
	 * min_speed_hz is ~0 and the resulting delay is zero.
	 */
	delay = (2 * 1000000) / spi_imx->spi_bus_clk;
	if (likely(delay < 10))	/* SCLK is faster than 100 kHz */
	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
		if (!xfer->speed_hz)
			continue;
		min_speed_hz = min(xfer->speed_hz, min_speed_hz);
	}

	delay = (2 * 1000000) / min_speed_hz;
	if (likely(delay < 10))	/* SCLK is faster than 200 kHz */
		udelay(delay);
	else			/* SCLK is _very_ slow */
		usleep_range(delay, delay + 10);
+2 −0
Original line number Diff line number Diff line
@@ -785,6 +785,8 @@ static int meson_spicc_remove(struct platform_device *pdev)
	clk_disable_unprepare(spicc->core);
	clk_disable_unprepare(spicc->pclk);

	spi_master_put(spicc->master);

	return 0;
}

+5 −14
Original line number Diff line number Diff line
@@ -426,24 +426,15 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
	mtk_spi_prepare_transfer(master, xfer);
	mtk_spi_setup_packet(master);

	if (xfer->tx_buf) {
		cnt = xfer->len / 4;
	if (xfer->tx_buf)
		iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt);

	if (xfer->rx_buf)
		ioread32_rep(mdata->base + SPI_RX_DATA_REG, xfer->rx_buf, cnt);

		remainder = xfer->len % 4;
		if (remainder > 0) {
			reg_val = 0;
		if (xfer->tx_buf) {
			memcpy(&reg_val, xfer->tx_buf + (cnt * 4), remainder);
			writel(reg_val, mdata->base + SPI_TX_DATA_REG);
		}
		if (xfer->rx_buf) {
			reg_val = readl(mdata->base + SPI_RX_DATA_REG);
			memcpy(xfer->rx_buf + (cnt * 4), &reg_val, remainder);
		}
	}

	mtk_spi_enable_transfer(master);
+8 −0
Original line number Diff line number Diff line
@@ -167,10 +167,17 @@ static int spi_mux_probe(struct spi_device *spi)
	return ret;
}

static const struct spi_device_id spi_mux_id[] = {
	{ "spi-mux" },
	{ }
};
MODULE_DEVICE_TABLE(spi, spi_mux_id);

static const struct of_device_id spi_mux_of_match[] = {
	{ .compatible = "spi-mux" },
	{ }
};
MODULE_DEVICE_TABLE(of, spi_mux_of_match);

static struct spi_driver spi_mux_driver = {
	.probe  = spi_mux_probe,
@@ -178,6 +185,7 @@ static struct spi_driver spi_mux_driver = {
		.name   = "spi-mux",
		.of_match_table = spi_mux_of_match,
	},
	.id_table = spi_mux_id,
};

module_spi_driver(spi_mux_driver);
Loading