Merge tag 'spi-fix-v7.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Merge commit. Changes below are compared with the first parent: aa211c7a.
Changes
4 files changed · +39 −6
| File | Status | Add | Del | Content |
|---|---|---|---|---|
| drivers/spi/spi-fsl-qspi.c | modified | +4 | −1 | View file |
| drivers/spi/spi-qpic-snand.c | modified | +0 | −4 | View file |
| drivers/spi/spi-virtio.c | modified | +1 | −1 | View file |
| drivers/spi/spi-zynqmp-gqspi.c | modified | +34 | −0 | View file |
drivers/spi/spi-fsl-qspi.c
View filediff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c
index 5735885..d2c2090 100644
--- a/drivers/spi/spi-fsl-qspi.c
+++ b/drivers/spi/spi-fsl-qspi.c
@@ -289,6 +289,7 @@ struct fsl_qspi {
struct pm_qos_request pm_qos_req;
struct device *dev;
int selected;
+ u32 selected_freq;
u32 memmap_phy;
};
@@ -551,7 +552,8 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi,
unsigned long rate = op->max_freq;
int ret;
- if (q->selected == spi_get_chipselect(spi, 0))
+ if (q->selected == spi_get_chipselect(spi, 0) &&
+ q->selected_freq == op->max_freq)
return;
if (needs_4x_clock(q))
@@ -571,6 +573,7 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi,
}
q->selected = spi_get_chipselect(spi, 0);
+ q->selected_freq = op->max_freq;
fsl_qspi_invalidate(q);
}
drivers/spi/spi-qpic-snand.c
View filediff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c
index 61b1f2e..05efe63 100644
--- a/drivers/spi/spi-qpic-snand.c
+++ b/drivers/spi/spi-qpic-snand.c
@@ -765,8 +765,6 @@ static int qcom_spi_read_cw_raw(struct qcom_nand_controller *snandc, u8 *data_bu
qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0);
qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
- qcom_write_reg_dma(snandc, &snandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0);
-
qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr,
NAND_ERASED_CW_DETECT_CFG, 1, 0);
qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set,
@@ -1104,8 +1102,6 @@ static void qcom_spi_config_page_write(struct qcom_nand_controller *snandc)
{
qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0);
qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
- qcom_write_reg_dma(snandc, &snandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG,
- 1, NAND_BAM_NEXT_SGL);
}
static void qcom_spi_config_cw_write(struct qcom_nand_controller *snandc)
drivers/spi/spi-virtio.c
View filediff --git a/drivers/spi/spi-virtio.c b/drivers/spi/spi-virtio.c
index 2256dfe..3e181bd 100644
--- a/drivers/spi/spi-virtio.c
+++ b/drivers/spi/spi-virtio.c
@@ -168,7 +168,7 @@ static int virtio_spi_transfer_one(struct spi_controller *ctrl,
/* Fill struct spi_transfer_head */
th->chip_select_id = spi_get_chipselect(spi, 0);
- th->bits_per_word = spi->bits_per_word;
+ th->bits_per_word = xfer->bits_per_word;
th->cs_change = xfer->cs_change;
th->tx_nbits = xfer->tx_nbits;
th->rx_nbits = xfer->rx_nbits;
drivers/spi/spi-zynqmp-gqspi.c
View filediff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index 4d55090..15e9d3e 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -1373,11 +1373,45 @@ static void zynqmp_qspi_remove(struct platform_device *pdev)
clk_disable_unprepare(xqspi->pclk);
}
+static void zynqmp_qspi_shutdown(struct platform_device *pdev)
+{
+ struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev);
+ int ret;
+
+ /*
+ * Stop the queue and reject any later transfer first, so the write
+ * below cannot cut into a message that is still being executed.
+ * Unlike ->suspend this cannot abort on error: a controller left
+ * mastering the bus is worse than a truncated transfer.
+ */
+ ret = spi_controller_suspend(xqspi->ctlr);
+ if (ret)
+ dev_warn(&pdev->dev, "could not stop the queue: %d\n", ret);
+
+ /*
+ * Only a runtime suspended controller can be left alone: its clocks
+ * are gated, so it cannot be mastering the bus, and its registers
+ * must not be accessed either. Any other answer means it may be
+ * running and has to be stopped. In particular, on a kernel built
+ * without runtime PM this returns -EINVAL, and there the clocks
+ * enabled in probe() are never gated at all.
+ */
+ ret = pm_runtime_get_if_in_use(&pdev->dev);
+ if (!ret)
+ return;
+
+ zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
+
+ if (ret > 0)
+ pm_runtime_put_noidle(&pdev->dev);
+}
+
MODULE_DEVICE_TABLE(of, zynqmp_qspi_of_match);
static struct platform_driver zynqmp_qspi_driver = {
.probe = zynqmp_qspi_probe,
.remove = zynqmp_qspi_remove,
+ .shutdown = zynqmp_qspi_shutdown,
.driver = {
.name = "zynqmp-qspi",
.of_match_table = zynqmp_qspi_of_match,