From e5f0dfa78ac77374a3f0817bf427a22f61494246 Mon Sep 17 00:00:00 2001 From: Vijaya Krishna Nivarthi Date: Thu, 8 Dec 2022 19:55:44 +0530 Subject: [PATCH 01/65] spi: spi-geni-qcom: Add support for SE DMA mode SE DMA mode can be used for larger transfers and FIFO mode for smaller transfers. Signed-off-by: Vijaya Krishna Nivarthi Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/1670509544-15977-1-git-send-email-quic_vnivarth@quicinc.com Signed-off-by: Mark Brown --- drivers/spi/spi-geni-qcom.c | 207 ++++++++++++++++++++++++++++-------- 1 file changed, 163 insertions(+), 44 deletions(-) diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index 4e83cc5b445d..e1b2e0b65779 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -87,6 +87,8 @@ struct spi_geni_master { struct completion cs_done; struct completion cancel_done; struct completion abort_done; + struct completion tx_reset_done; + struct completion rx_reset_done; unsigned int oversampling; spinlock_t lock; int irq; @@ -95,6 +97,8 @@ struct spi_geni_master { struct dma_chan *tx; struct dma_chan *rx; int cur_xfer_mode; + dma_addr_t tx_se_dma; + dma_addr_t rx_se_dma; }; static int get_spi_clk_cfg(unsigned int speed_hz, @@ -129,23 +133,27 @@ static int get_spi_clk_cfg(unsigned int speed_hz, return ret; } -static void handle_fifo_timeout(struct spi_master *spi, +static void handle_se_timeout(struct spi_master *spi, struct spi_message *msg) { struct spi_geni_master *mas = spi_master_get_devdata(spi); unsigned long time_left; struct geni_se *se = &mas->se; + const struct spi_transfer *xfer; spin_lock_irq(&mas->lock); reinit_completion(&mas->cancel_done); - writel(0, se->base + SE_GENI_TX_WATERMARK_REG); + if (mas->cur_xfer_mode == GENI_SE_FIFO) + writel(0, se->base + SE_GENI_TX_WATERMARK_REG); + + xfer = mas->cur_xfer; mas->cur_xfer = NULL; geni_se_cancel_m_cmd(se); spin_unlock_irq(&mas->lock); time_left = wait_for_completion_timeout(&mas->cancel_done, HZ); if (time_left) - return; + goto unmap_if_dma; spin_lock_irq(&mas->lock); reinit_completion(&mas->abort_done); @@ -162,6 +170,39 @@ static void handle_fifo_timeout(struct spi_master *spi, */ mas->abort_failed = true; } + +unmap_if_dma: + if (mas->cur_xfer_mode == GENI_SE_DMA) { + if (xfer) { + if (xfer->tx_buf && mas->tx_se_dma) { + spin_lock_irq(&mas->lock); + reinit_completion(&mas->tx_reset_done); + writel(1, se->base + SE_DMA_TX_FSM_RST); + spin_unlock_irq(&mas->lock); + time_left = wait_for_completion_timeout(&mas->tx_reset_done, HZ); + if (!time_left) + dev_err(mas->dev, "DMA TX RESET failed\n"); + geni_se_tx_dma_unprep(se, mas->tx_se_dma, xfer->len); + } + if (xfer->rx_buf && mas->rx_se_dma) { + spin_lock_irq(&mas->lock); + reinit_completion(&mas->rx_reset_done); + writel(1, se->base + SE_DMA_RX_FSM_RST); + spin_unlock_irq(&mas->lock); + time_left = wait_for_completion_timeout(&mas->rx_reset_done, HZ); + if (!time_left) + dev_err(mas->dev, "DMA RX RESET failed\n"); + geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len); + } + } else { + /* + * This can happen if a timeout happened and we had to wait + * for lock in this function because isr was holding the lock + * and handling transfer completion at that time. + */ + dev_warn(mas->dev, "Cancel/Abort on completed SPI transfer\n"); + } + } } static void handle_gpi_timeout(struct spi_master *spi, struct spi_message *msg) @@ -178,7 +219,8 @@ static void spi_geni_handle_err(struct spi_master *spi, struct spi_message *msg) switch (mas->cur_xfer_mode) { case GENI_SE_FIFO: - handle_fifo_timeout(spi, msg); + case GENI_SE_DMA: + handle_se_timeout(spi, msg); break; case GENI_GPI_DMA: handle_gpi_timeout(spi, msg); @@ -250,6 +292,8 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag) } mas->cs_flag = set_flag; + /* set xfer_mode to FIFO to complete cs_done in isr */ + mas->cur_xfer_mode = GENI_SE_FIFO; reinit_completion(&mas->cs_done); if (set_flag) geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0); @@ -260,7 +304,7 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag) time_left = wait_for_completion_timeout(&mas->cs_done, HZ); if (!time_left) { dev_warn(mas->dev, "Timeout setting chip select\n"); - handle_fifo_timeout(spi, NULL); + handle_se_timeout(spi, NULL); } exit: @@ -482,8 +526,12 @@ static bool geni_can_dma(struct spi_controller *ctlr, { struct spi_geni_master *mas = spi_master_get_devdata(slv->master); - /* check if dma is supported */ - return mas->cur_xfer_mode != GENI_SE_FIFO; + /* + * Return true if transfer needs to be mapped prior to + * calling transfer_one which is the case only for GPI_DMA. + * For SE_DMA mode, map/unmap is done in geni_se_*x_dma_prep. + */ + return mas->cur_xfer_mode == GENI_GPI_DMA; } static int spi_geni_prepare_message(struct spi_master *spi, @@ -494,6 +542,7 @@ static int spi_geni_prepare_message(struct spi_master *spi, switch (mas->cur_xfer_mode) { case GENI_SE_FIFO: + case GENI_SE_DMA: if (spi_geni_is_abort_still_pending(mas)) return -EBUSY; ret = setup_fifo_params(spi_msg->spi, spi); @@ -597,7 +646,7 @@ static int spi_geni_init(struct spi_geni_master *mas) break; } /* - * in case of failure to get dma channel, we can still do the + * in case of failure to get gpi dma channel, we can still do the * FIFO mode, so fallthrough */ dev_warn(mas->dev, "FIFO mode disabled, but couldn't get DMA, fall back to FIFO mode\n"); @@ -716,12 +765,12 @@ static void geni_spi_handle_rx(struct spi_geni_master *mas) mas->rx_rem_bytes -= rx_bytes; } -static void setup_fifo_xfer(struct spi_transfer *xfer, +static int setup_se_xfer(struct spi_transfer *xfer, struct spi_geni_master *mas, u16 mode, struct spi_master *spi) { u32 m_cmd = 0; - u32 len; + u32 len, fifo_size; struct geni_se *se = &mas->se; int ret; @@ -748,7 +797,7 @@ static void setup_fifo_xfer(struct spi_transfer *xfer, /* Speed and bits per word can be overridden per transfer */ ret = geni_spi_set_clock_and_bw(mas, xfer->speed_hz); if (ret) - return; + return ret; mas->tx_rem_bytes = 0; mas->rx_rem_bytes = 0; @@ -772,17 +821,50 @@ static void setup_fifo_xfer(struct spi_transfer *xfer, mas->rx_rem_bytes = xfer->len; } + /* Select transfer mode based on transfer length */ + fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits / mas->cur_bits_per_word; + mas->cur_xfer_mode = (len <= fifo_size) ? GENI_SE_FIFO : GENI_SE_DMA; + geni_se_select_mode(se, mas->cur_xfer_mode); + /* * Lock around right before we start the transfer since our * interrupt could come in at any time now. */ spin_lock_irq(&mas->lock); geni_se_setup_m_cmd(se, m_cmd, FRAGMENTATION); - if (m_cmd & SPI_TX_ONLY) { + + if (mas->cur_xfer_mode == GENI_SE_DMA) { + if (m_cmd & SPI_RX_ONLY) { + ret = geni_se_rx_dma_prep(se, xfer->rx_buf, + xfer->len, &mas->rx_se_dma); + if (ret) { + dev_err(mas->dev, "Failed to setup Rx dma %d\n", ret); + mas->rx_se_dma = 0; + goto unlock_and_return; + } + } + if (m_cmd & SPI_TX_ONLY) { + ret = geni_se_tx_dma_prep(se, (void *)xfer->tx_buf, + xfer->len, &mas->tx_se_dma); + if (ret) { + dev_err(mas->dev, "Failed to setup Tx dma %d\n", ret); + mas->tx_se_dma = 0; + if (m_cmd & SPI_RX_ONLY) { + /* Unmap rx buffer if duplex transfer */ + geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len); + mas->rx_se_dma = 0; + } + goto unlock_and_return; + } + } + } else if (m_cmd & SPI_TX_ONLY) { if (geni_spi_handle_tx(mas)) writel(mas->tx_wm, se->base + SE_GENI_TX_WATERMARK_REG); } + +unlock_and_return: spin_unlock_irq(&mas->lock); + return ret; } static int spi_geni_transfer_one(struct spi_master *spi, @@ -790,6 +872,7 @@ static int spi_geni_transfer_one(struct spi_master *spi, struct spi_transfer *xfer) { struct spi_geni_master *mas = spi_master_get_devdata(spi); + int ret; if (spi_geni_is_abort_still_pending(mas)) return -EBUSY; @@ -798,9 +881,12 @@ static int spi_geni_transfer_one(struct spi_master *spi, if (!xfer->len) return 0; - if (mas->cur_xfer_mode == GENI_SE_FIFO) { - setup_fifo_xfer(xfer, mas, slv->mode, spi); - return 1; + if (mas->cur_xfer_mode == GENI_SE_FIFO || mas->cur_xfer_mode == GENI_SE_DMA) { + ret = setup_se_xfer(xfer, mas, slv->mode, spi); + /* SPI framework expects +ve ret code to wait for transfer complete */ + if (!ret) + ret = 1; + return ret; } return setup_gsi_xfer(xfer, mas, slv, spi); } @@ -823,39 +909,70 @@ static irqreturn_t geni_spi_isr(int irq, void *data) spin_lock(&mas->lock); - if ((m_irq & M_RX_FIFO_WATERMARK_EN) || (m_irq & M_RX_FIFO_LAST_EN)) - geni_spi_handle_rx(mas); + if (mas->cur_xfer_mode == GENI_SE_FIFO) { + if ((m_irq & M_RX_FIFO_WATERMARK_EN) || (m_irq & M_RX_FIFO_LAST_EN)) + geni_spi_handle_rx(mas); - if (m_irq & M_TX_FIFO_WATERMARK_EN) - geni_spi_handle_tx(mas); + if (m_irq & M_TX_FIFO_WATERMARK_EN) + geni_spi_handle_tx(mas); - if (m_irq & M_CMD_DONE_EN) { - if (mas->cur_xfer) { + if (m_irq & M_CMD_DONE_EN) { + if (mas->cur_xfer) { + spi_finalize_current_transfer(spi); + mas->cur_xfer = NULL; + /* + * If this happens, then a CMD_DONE came before all the + * Tx buffer bytes were sent out. This is unusual, log + * this condition and disable the WM interrupt to + * prevent the system from stalling due an interrupt + * storm. + * + * If this happens when all Rx bytes haven't been + * received, log the condition. The only known time + * this can happen is if bits_per_word != 8 and some + * registers that expect xfer lengths in num spi_words + * weren't written correctly. + */ + if (mas->tx_rem_bytes) { + writel(0, se->base + SE_GENI_TX_WATERMARK_REG); + dev_err(mas->dev, "Premature done. tx_rem = %d bpw%d\n", + mas->tx_rem_bytes, mas->cur_bits_per_word); + } + if (mas->rx_rem_bytes) + dev_err(mas->dev, "Premature done. rx_rem = %d bpw%d\n", + mas->rx_rem_bytes, mas->cur_bits_per_word); + } else { + complete(&mas->cs_done); + } + } + } else if (mas->cur_xfer_mode == GENI_SE_DMA) { + const struct spi_transfer *xfer = mas->cur_xfer; + u32 dma_tx_status = readl_relaxed(se->base + SE_DMA_TX_IRQ_STAT); + u32 dma_rx_status = readl_relaxed(se->base + SE_DMA_RX_IRQ_STAT); + + if (dma_tx_status) + writel(dma_tx_status, se->base + SE_DMA_TX_IRQ_CLR); + if (dma_rx_status) + writel(dma_rx_status, se->base + SE_DMA_RX_IRQ_CLR); + if (dma_tx_status & TX_DMA_DONE) + mas->tx_rem_bytes = 0; + if (dma_rx_status & RX_DMA_DONE) + mas->rx_rem_bytes = 0; + if (dma_tx_status & TX_RESET_DONE) + complete(&mas->tx_reset_done); + if (dma_rx_status & RX_RESET_DONE) + complete(&mas->rx_reset_done); + if (!mas->tx_rem_bytes && !mas->rx_rem_bytes && xfer) { + if (xfer->tx_buf && mas->tx_se_dma) { + geni_se_tx_dma_unprep(se, mas->tx_se_dma, xfer->len); + mas->tx_se_dma = 0; + } + if (xfer->rx_buf && mas->rx_se_dma) { + geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len); + mas->rx_se_dma = 0; + } spi_finalize_current_transfer(spi); mas->cur_xfer = NULL; - /* - * If this happens, then a CMD_DONE came before all the - * Tx buffer bytes were sent out. This is unusual, log - * this condition and disable the WM interrupt to - * prevent the system from stalling due an interrupt - * storm. - * - * If this happens when all Rx bytes haven't been - * received, log the condition. The only known time - * this can happen is if bits_per_word != 8 and some - * registers that expect xfer lengths in num spi_words - * weren't written correctly. - */ - if (mas->tx_rem_bytes) { - writel(0, se->base + SE_GENI_TX_WATERMARK_REG); - dev_err(mas->dev, "Premature done. tx_rem = %d bpw%d\n", - mas->tx_rem_bytes, mas->cur_bits_per_word); - } - if (mas->rx_rem_bytes) - dev_err(mas->dev, "Premature done. rx_rem = %d bpw%d\n", - mas->rx_rem_bytes, mas->cur_bits_per_word); - } else { - complete(&mas->cs_done); } } @@ -949,6 +1066,8 @@ static int spi_geni_probe(struct platform_device *pdev) init_completion(&mas->cs_done); init_completion(&mas->cancel_done); init_completion(&mas->abort_done); + init_completion(&mas->tx_reset_done); + init_completion(&mas->rx_reset_done); spin_lock_init(&mas->lock); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, 250); From 54c467b314b6c2afeb7093d86886103392e3499c Mon Sep 17 00:00:00 2001 From: Vincent Tremblay Date: Mon, 26 Dec 2022 21:35:47 -0500 Subject: [PATCH 02/65] dt-bindings: trivial-devices: Add silabs,em3581 Add Silicon Labs EM3581 Zigbee SoC to trivial-devices. Signed-off-by: Vincent Tremblay Link: https://lore.kernel.org/r/20221227023550.569547-1-vincent@vtremblay.dev Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index f5c0a6283e61..5a3ccbce8c23 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -323,6 +323,8 @@ properties: - sensortek,stk8ba50 # SGX Sensortech VZ89X Sensors - sgx,vz89x + # Silicon Labs EM3581 Zigbee SoC with SPI interface + - silabs,em3581 # Relative Humidity and Temperature Sensors - silabs,si7020 # Skyworks SKY81452: Six-Channel White LED Driver with Touch Panel Bias Supply From c67d90e058550403a3e6f9b05bfcdcfa12b1815c Mon Sep 17 00:00:00 2001 From: Vincent Tremblay Date: Mon, 26 Dec 2022 21:35:48 -0500 Subject: [PATCH 03/65] spidev: Add Silicon Labs EM3581 device compatible Add compatible string for Silicon Labs EM3581 device. Signed-off-by: Vincent Tremblay Link: https://lore.kernel.org/r/20221227023550.569547-2-vincent@vtremblay.dev Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 6313e7d0cdf8..46f53ca03f8d 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -702,6 +702,7 @@ static const struct spi_device_id spidev_spi_ids[] = { { .name = "m53cpld" }, { .name = "spi-petra" }, { .name = "spi-authenta" }, + { .name = "em3581" }, {}, }; MODULE_DEVICE_TABLE(spi, spidev_spi_ids); @@ -728,6 +729,7 @@ static const struct of_device_id spidev_dt_ids[] = { { .compatible = "menlo,m53cpld", .data = &spidev_of_check }, { .compatible = "cisco,spi-petra", .data = &spidev_of_check }, { .compatible = "micron,spi-authenta", .data = &spidev_of_check }, + { .compatible = "silabs,em3581", .data = &spidev_of_check }, {}, }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); From f7879d677e76d0c4449fa1839f948d335795f334 Mon Sep 17 00:00:00 2001 From: Vincent Tremblay Date: Tue, 27 Dec 2022 09:10:07 -0500 Subject: [PATCH 04/65] dt-bindings: trivial-devices: Add silabs,si3210 Add Silicon Labs SI3210 to trivial devices. Signed-off-by: Vincent Tremblay Link: https://lore.kernel.org/r/20221227141011.111410-1-vincent@vtremblay.dev Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 5a3ccbce8c23..7da40dadfe2e 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -325,6 +325,8 @@ properties: - sgx,vz89x # Silicon Labs EM3581 Zigbee SoC with SPI interface - silabs,em3581 + # Silicon Labs SI3210 Programmable CMOS SLIC/CODEC with SPI interface + - silabs,si3210 # Relative Humidity and Temperature Sensors - silabs,si7020 # Skyworks SKY81452: Six-Channel White LED Driver with Touch Panel Bias Supply From 6c9d1fd52956c3148e847a214bae9102b1811de5 Mon Sep 17 00:00:00 2001 From: Vincent Tremblay Date: Tue, 27 Dec 2022 09:10:08 -0500 Subject: [PATCH 05/65] spidev: Add Silicon Labs SI3210 device compatible Add compatible string for Silicon Labs SI3210 device. Signed-off-by: Vincent Tremblay Link: https://lore.kernel.org/r/20221227141011.111410-2-vincent@vtremblay.dev Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 46f53ca03f8d..d8998d5e8483 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -703,6 +703,7 @@ static const struct spi_device_id spidev_spi_ids[] = { { .name = "spi-petra" }, { .name = "spi-authenta" }, { .name = "em3581" }, + { .name = "si3210" }, {}, }; MODULE_DEVICE_TABLE(spi, spidev_spi_ids); @@ -730,6 +731,7 @@ static const struct of_device_id spidev_dt_ids[] = { { .compatible = "cisco,spi-petra", .data = &spidev_of_check }, { .compatible = "micron,spi-authenta", .data = &spidev_of_check }, { .compatible = "silabs,em3581", .data = &spidev_of_check }, + { .compatible = "silabs,si3210", .data = &spidev_of_check }, {}, }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); From 26c48aea147cbf3dcec1df67d0684457ddf00fea Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 29 Dec 2022 18:38:35 +0800 Subject: [PATCH 06/65] spi: altera: switch to use modern name Change legacy name master/slave to modern name host/target or controller. No functional changed. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221229103837.4192759-2-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/spi/spi-altera-core.c | 30 +++++++++++++++--------------- drivers/spi/spi-altera-dfl.c | 2 +- drivers/spi/spi-altera-platform.c | 2 +- include/linux/spi/altera.h | 4 ++-- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/spi/spi-altera-core.c b/drivers/spi/spi-altera-core.c index de4d31c530d9..94fe6bf1b9a6 100644 --- a/drivers/spi/spi-altera-core.c +++ b/drivers/spi/spi-altera-core.c @@ -24,7 +24,7 @@ #define ALTERA_SPI_TXDATA 4 #define ALTERA_SPI_STATUS 8 #define ALTERA_SPI_CONTROL 12 -#define ALTERA_SPI_SLAVE_SEL 20 +#define ALTERA_SPI_TARGET_SEL 20 #define ALTERA_SPI_STATUS_ROE_MSK 0x8 #define ALTERA_SPI_STATUS_TOE_MSK 0x10 @@ -67,7 +67,7 @@ static int altr_spi_readl(struct altera_spi *hw, unsigned int reg, static inline struct altera_spi *altera_spi_to_hw(struct spi_device *sdev) { - return spi_master_get_devdata(sdev->master); + return spi_controller_get_devdata(sdev->controller); } static void altera_spi_set_cs(struct spi_device *spi, bool is_high) @@ -77,9 +77,9 @@ static void altera_spi_set_cs(struct spi_device *spi, bool is_high) if (is_high) { hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK; altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr); - altr_spi_writel(hw, ALTERA_SPI_SLAVE_SEL, 0); + altr_spi_writel(hw, ALTERA_SPI_TARGET_SEL, 0); } else { - altr_spi_writel(hw, ALTERA_SPI_SLAVE_SEL, + altr_spi_writel(hw, ALTERA_SPI_TARGET_SEL, BIT(spi->chip_select)); hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK; altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr); @@ -139,10 +139,10 @@ static void altera_spi_rx_word(struct altera_spi *hw) hw->count++; } -static int altera_spi_txrx(struct spi_master *master, +static int altera_spi_txrx(struct spi_controller *host, struct spi_device *spi, struct spi_transfer *t) { - struct altera_spi *hw = spi_master_get_devdata(master); + struct altera_spi *hw = spi_controller_get_devdata(host); u32 val; hw->tx = t->tx_buf; @@ -175,15 +175,15 @@ static int altera_spi_txrx(struct spi_master *master, altera_spi_rx_word(hw); } - spi_finalize_current_transfer(master); + spi_finalize_current_transfer(host); return 0; } irqreturn_t altera_spi_irq(int irq, void *dev) { - struct spi_master *master = dev; - struct altera_spi *hw = spi_master_get_devdata(master); + struct spi_controller *host = dev; + struct altera_spi *hw = spi_controller_get_devdata(host); altera_spi_rx_word(hw); @@ -194,20 +194,20 @@ irqreturn_t altera_spi_irq(int irq, void *dev) hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr); - spi_finalize_current_transfer(master); + spi_finalize_current_transfer(host); } return IRQ_HANDLED; } EXPORT_SYMBOL_GPL(altera_spi_irq); -void altera_spi_init_master(struct spi_master *master) +void altera_spi_init_host(struct spi_controller *host) { - struct altera_spi *hw = spi_master_get_devdata(master); + struct altera_spi *hw = spi_controller_get_devdata(host); u32 val; - master->transfer_one = altera_spi_txrx; - master->set_cs = altera_spi_set_cs; + host->transfer_one = altera_spi_txrx; + host->set_cs = altera_spi_set_cs; /* program defaults into the registers */ hw->imr = 0; /* disable spi interrupts */ @@ -217,6 +217,6 @@ void altera_spi_init_master(struct spi_master *master) if (val & ALTERA_SPI_STATUS_RRDY_MSK) altr_spi_readl(hw, ALTERA_SPI_RXDATA, &val); /* flush rxdata */ } -EXPORT_SYMBOL_GPL(altera_spi_init_master); +EXPORT_SYMBOL_GPL(altera_spi_init_host); MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi-altera-dfl.c b/drivers/spi/spi-altera-dfl.c index 596e181ae136..0b3302a29989 100644 --- a/drivers/spi/spi-altera-dfl.c +++ b/drivers/spi/spi-altera-dfl.c @@ -156,7 +156,7 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev) hw->irq = -EINVAL; - altera_spi_init_master(master); + altera_spi_init_host(master); err = devm_spi_register_master(dev, master); if (err) diff --git a/drivers/spi/spi-altera-platform.c b/drivers/spi/spi-altera-platform.c index 65147aae82a1..cde12c4b9cbc 100644 --- a/drivers/spi/spi-altera-platform.c +++ b/drivers/spi/spi-altera-platform.c @@ -107,7 +107,7 @@ static int altera_spi_probe(struct platform_device *pdev) } } - altera_spi_init_master(master); + altera_spi_init_host(master); /* irq is optional */ hw->irq = platform_get_irq(pdev, 0); diff --git a/include/linux/spi/altera.h b/include/linux/spi/altera.h index 2e2a622e56da..3b74c3750caf 100644 --- a/include/linux/spi/altera.h +++ b/include/linux/spi/altera.h @@ -14,7 +14,7 @@ /** * struct altera_spi_platform_data - Platform data of the Altera SPI driver - * @mode_bits: Mode bits of SPI master. + * @mode_bits: Mode bits of SPI host. * @num_chipselect: Number of chipselects. * @bits_per_word_mask: bitmask of supported bits_per_word for transfers. * @num_devices: Number of devices that shall be added when the driver @@ -46,5 +46,5 @@ struct altera_spi { }; extern irqreturn_t altera_spi_irq(int irq, void *dev); -extern void altera_spi_init_master(struct spi_master *master); +extern void altera_spi_init_host(struct spi_controller *host); #endif /* __LINUX_SPI_ALTERA_H */ From ec168190c1cace92cba22ffa2048e79f41ba5a13 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 29 Dec 2022 18:38:36 +0800 Subject: [PATCH 07/65] spi: spi-altera-dfl: switch to use modern name Change legacy name master to modern name host or controller. No functional changed. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221229103837.4192759-3-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/spi/spi-altera-dfl.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/spi/spi-altera-dfl.c b/drivers/spi/spi-altera-dfl.c index 0b3302a29989..5d6e08c12dff 100644 --- a/drivers/spi/spi-altera-dfl.c +++ b/drivers/spi/spi-altera-dfl.c @@ -104,20 +104,20 @@ static const struct regmap_config indirect_regbus_cfg = { .reg_read = indirect_bus_reg_read, }; -static void config_spi_master(void __iomem *base, struct spi_master *master) +static void config_spi_host(void __iomem *base, struct spi_controller *host) { u64 v; v = readq(base + SPI_CORE_PARAMETER); - master->mode_bits = SPI_CS_HIGH; + host->mode_bits = SPI_CS_HIGH; if (FIELD_GET(CLK_POLARITY, v)) - master->mode_bits |= SPI_CPOL; + host->mode_bits |= SPI_CPOL; if (FIELD_GET(CLK_PHASE, v)) - master->mode_bits |= SPI_CPHA; + host->mode_bits |= SPI_CPHA; - master->num_chipselect = FIELD_GET(NUM_CHIPSELECT, v); - master->bits_per_word_mask = + host->num_chipselect = FIELD_GET(NUM_CHIPSELECT, v); + host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, FIELD_GET(DATA_WIDTH, v)); } @@ -125,18 +125,18 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev) { struct spi_board_info board_info = { 0 }; struct device *dev = &dfl_dev->dev; - struct spi_master *master; + struct spi_controller *host; struct altera_spi *hw; void __iomem *base; int err; - master = devm_spi_alloc_master(dev, sizeof(struct altera_spi)); - if (!master) + host = devm_spi_alloc_host(dev, sizeof(struct altera_spi)); + if (!host) return -ENOMEM; - master->bus_num = -1; + host->bus_num = -1; - hw = spi_master_get_devdata(master); + hw = spi_controller_get_devdata(host); hw->dev = dev; @@ -145,10 +145,10 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev) if (IS_ERR(base)) return PTR_ERR(base); - config_spi_master(base, master); + config_spi_host(base, host); dev_dbg(dev, "%s cs %u bpm 0x%x mode 0x%x\n", __func__, - master->num_chipselect, master->bits_per_word_mask, - master->mode_bits); + host->num_chipselect, host->bits_per_word_mask, + host->mode_bits); hw->regmap = devm_regmap_init(dev, NULL, base, &indirect_regbus_cfg); if (IS_ERR(hw->regmap)) @@ -156,11 +156,11 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev) hw->irq = -EINVAL; - altera_spi_init_host(master); + altera_spi_init_host(host); - err = devm_spi_register_master(dev, master); + err = devm_spi_register_controller(dev, host); if (err) - return dev_err_probe(dev, err, "%s failed to register spi master\n", + return dev_err_probe(dev, err, "%s failed to register spi host\n", __func__); if (dfl_dev->revision == FME_FEATURE_REV_MAX10_SPI_N5010) @@ -172,7 +172,7 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev) board_info.bus_num = 0; board_info.chip_select = 0; - if (!spi_new_device(master, &board_info)) { + if (!spi_new_device(host, &board_info)) { dev_err(dev, "%s failed to create SPI device: %s\n", __func__, board_info.modalias); } From 02c9e5b768b26239be7459438275f8fc835e9dc4 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 29 Dec 2022 18:38:37 +0800 Subject: [PATCH 08/65] spi: spi-altera-platform: switch to use modern name Change legacy name master to modern name host or controller. No functional changed. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221229103837.4192759-4-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/spi/spi-altera-platform.c | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/spi/spi-altera-platform.c b/drivers/spi/spi-altera-platform.c index cde12c4b9cbc..72e7a0f21793 100644 --- a/drivers/spi/spi-altera-platform.c +++ b/drivers/spi/spi-altera-platform.c @@ -39,16 +39,16 @@ static int altera_spi_probe(struct platform_device *pdev) struct altera_spi_platform_data *pdata = dev_get_platdata(&pdev->dev); enum altera_spi_type type = ALTERA_SPI_TYPE_UNKNOWN; struct altera_spi *hw; - struct spi_master *master; + struct spi_controller *host; int err = -ENODEV; u16 i; - master = spi_alloc_master(&pdev->dev, sizeof(struct altera_spi)); - if (!master) + host = spi_alloc_host(&pdev->dev, sizeof(struct altera_spi)); + if (!host) return err; - /* setup the master state. */ - master->bus_num = -1; + /* setup the host state. */ + host->bus_num = -1; if (pdata) { if (pdata->num_chipselect > ALTERA_SPI_MAX_CS) { @@ -59,18 +59,18 @@ static int altera_spi_probe(struct platform_device *pdev) goto exit; } - master->num_chipselect = pdata->num_chipselect; - master->mode_bits = pdata->mode_bits; - master->bits_per_word_mask = pdata->bits_per_word_mask; + host->num_chipselect = pdata->num_chipselect; + host->mode_bits = pdata->mode_bits; + host->bits_per_word_mask = pdata->bits_per_word_mask; } else { - master->num_chipselect = 16; - master->mode_bits = SPI_CS_HIGH; - master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16); + host->num_chipselect = 16; + host->mode_bits = SPI_CS_HIGH; + host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16); } - master->dev.of_node = pdev->dev.of_node; + host->dev.of_node = pdev->dev.of_node; - hw = spi_master_get_devdata(master); + hw = spi_controller_get_devdata(host); hw->dev = &pdev->dev; if (platid) @@ -107,24 +107,24 @@ static int altera_spi_probe(struct platform_device *pdev) } } - altera_spi_init_host(master); + altera_spi_init_host(host); /* irq is optional */ hw->irq = platform_get_irq(pdev, 0); if (hw->irq >= 0) { err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0, - pdev->name, master); + pdev->name, host); if (err) goto exit; } - err = devm_spi_register_master(&pdev->dev, master); + err = devm_spi_register_controller(&pdev->dev, host); if (err) goto exit; if (pdata) { for (i = 0; i < pdata->num_devices; i++) { - if (!spi_new_device(master, pdata->devices + i)) + if (!spi_new_device(host, pdata->devices + i)) dev_warn(&pdev->dev, "unable to create SPI device: %s\n", pdata->devices[i].modalias); @@ -135,7 +135,7 @@ static int altera_spi_probe(struct platform_device *pdev) return 0; exit: - spi_master_put(master); + spi_controller_put(host); return err; } From dfce16722b9cb842a6f23500ee80b3d07b47bdd4 Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Mon, 2 Jan 2023 17:08:51 +0100 Subject: [PATCH 09/65] spi: pl022: Only use DT-specified DMA channels When a platform is booted with devicetree and does not provide a platform data structure, the driver creates one internally. enable_dma should not be set in this structure when creating it; the probe function will set it later if DMA channels are specified via the devicetree. Setting enable_dma = 1 when creating this internal platform data can lead to pl022_dma_probe() finding bogus DMA channels (since there is no channel filter specified) when no DMA channels are specified in the devicetree. Signed-off-by: Vincent Whitchurch Acked-by: Dhruva Gole Link: https://lore.kernel.org/r/20230102160852.3090202-1-vincent.whitchurch@axis.com Signed-off-by: Mark Brown --- drivers/spi/spi-pl022.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index e4484ace584e..a17ff839117f 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -2091,7 +2091,6 @@ pl022_platform_data_dt_get(struct device *dev) return NULL; pd->bus_id = -1; - pd->enable_dma = 1; of_property_read_u32(np, "pl022,autosuspend-delay", &pd->autosuspend_delay); pd->rt = of_property_read_bool(np, "pl022,rt"); From 5aede90a1f6d37c73395957a83b64a6a1cff6de4 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 30 Dec 2022 17:28:04 +0800 Subject: [PATCH 10/65] spi: ath79: switch to use modern name Change legacy name master/slave to modern name host/target or controller. No functional changed. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221230092806.1687340-2-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/spi/spi-ath79.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 607e7a49fb89..795e88dbef1b 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -58,7 +58,7 @@ static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned int reg, u32 val) static inline struct ath79_spi *ath79_spidev_to_sp(struct spi_device *spi) { - return spi_master_get_devdata(spi->master); + return spi_controller_get_devdata(spi->controller); } static inline void ath79_spi_delay(struct ath79_spi *sp, unsigned int nsecs) @@ -120,7 +120,7 @@ static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned int nsecs, else out = ioc & ~AR71XX_SPI_IOC_DO; - /* setup MSB (to slave) on trailing edge */ + /* setup MSB (to target) on trailing edge */ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out); ath79_spi_delay(sp, nsecs); ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK); @@ -168,28 +168,28 @@ static const struct spi_controller_mem_ops ath79_mem_ops = { static int ath79_spi_probe(struct platform_device *pdev) { - struct spi_master *master; + struct spi_controller *host; struct ath79_spi *sp; unsigned long rate; int ret; - master = spi_alloc_master(&pdev->dev, sizeof(*sp)); - if (master == NULL) { - dev_err(&pdev->dev, "failed to allocate spi master\n"); + host = spi_alloc_host(&pdev->dev, sizeof(*sp)); + if (host == NULL) { + dev_err(&pdev->dev, "failed to allocate spi host\n"); return -ENOMEM; } - sp = spi_master_get_devdata(master); - master->dev.of_node = pdev->dev.of_node; + sp = spi_controller_get_devdata(host); + host->dev.of_node = pdev->dev.of_node; platform_set_drvdata(pdev, sp); - master->use_gpio_descriptors = true; - master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); - master->flags = SPI_MASTER_GPIO_SS; - master->num_chipselect = 3; - master->mem_ops = &ath79_mem_ops; + host->use_gpio_descriptors = true; + host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); + host->flags = SPI_MASTER_GPIO_SS; + host->num_chipselect = 3; + host->mem_ops = &ath79_mem_ops; - sp->bitbang.master = master; + sp->bitbang.master = host; sp->bitbang.chipselect = ath79_spi_chipselect; sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0; sp->bitbang.flags = SPI_CS_HIGH; @@ -197,18 +197,18 @@ static int ath79_spi_probe(struct platform_device *pdev) sp->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sp->base)) { ret = PTR_ERR(sp->base); - goto err_put_master; + goto err_put_host; } sp->clk = devm_clk_get(&pdev->dev, "ahb"); if (IS_ERR(sp->clk)) { ret = PTR_ERR(sp->clk); - goto err_put_master; + goto err_put_host; } ret = clk_prepare_enable(sp->clk); if (ret) - goto err_put_master; + goto err_put_host; rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ); if (!rate) { @@ -231,8 +231,8 @@ static int ath79_spi_probe(struct platform_device *pdev) ath79_spi_disable(sp); err_clk_disable: clk_disable_unprepare(sp->clk); -err_put_master: - spi_master_put(sp->bitbang.master); +err_put_host: + spi_controller_put(host); return ret; } @@ -244,7 +244,7 @@ static int ath79_spi_remove(struct platform_device *pdev) spi_bitbang_stop(&sp->bitbang); ath79_spi_disable(sp); clk_disable_unprepare(sp->clk); - spi_master_put(sp->bitbang.master); + spi_controller_put(sp->bitbang.master); return 0; } From 90ce7e7aaa418ff6c59d1c30267ff086994669b4 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 30 Dec 2022 17:28:05 +0800 Subject: [PATCH 11/65] spi: a3700: switch to use modern name Change legacy name master to modern name host or controller. No functional changed. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221230092806.1687340-3-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/spi/spi-armada-3700.c | 98 +++++++++++++++++------------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c index 9df9fc40b783..4d554b948d71 100644 --- a/drivers/spi/spi-armada-3700.c +++ b/drivers/spi/spi-armada-3700.c @@ -100,7 +100,7 @@ #define A3700_SPI_CLK_CAPT_EDGE BIT(7) struct a3700_spi { - struct spi_master *master; + struct spi_controller *host; void __iomem *base; struct clk *clk; unsigned int irq; @@ -174,7 +174,7 @@ static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi, val |= A3700_SPI_ADDR_PIN; break; default: - dev_err(&a3700_spi->master->dev, "wrong pin mode %u", pin_mode); + dev_err(&a3700_spi->host->dev, "wrong pin mode %u", pin_mode); return -EINVAL; } @@ -278,7 +278,7 @@ static int a3700_spi_fifo_flush(struct a3700_spi *a3700_spi) static void a3700_spi_init(struct a3700_spi *a3700_spi) { - struct spi_master *master = a3700_spi->master; + struct spi_controller *host = a3700_spi->host; u32 val; int i; @@ -295,14 +295,14 @@ static void a3700_spi_init(struct a3700_spi *a3700_spi) /* Disable AUTO_CS and deactivate all chip-selects */ a3700_spi_auto_cs_unset(a3700_spi); - for (i = 0; i < master->num_chipselect; i++) + for (i = 0; i < host->num_chipselect; i++) a3700_spi_deactivate_cs(a3700_spi, i); /* Enable FIFO mode */ a3700_spi_fifo_mode_set(a3700_spi, true); /* Set SPI mode */ - a3700_spi_mode_set(a3700_spi, master->mode_bits); + a3700_spi_mode_set(a3700_spi, host->mode_bits); /* Reset counters */ spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, 0); @@ -315,11 +315,11 @@ static void a3700_spi_init(struct a3700_spi *a3700_spi) static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id) { - struct spi_master *master = dev_id; + struct spi_controller *host = dev_id; struct a3700_spi *a3700_spi; u32 cause; - a3700_spi = spi_master_get_devdata(master); + a3700_spi = spi_controller_get_devdata(host); /* Get interrupt causes */ cause = spireg_read(a3700_spi, A3700_SPI_INT_STAT_REG); @@ -344,7 +344,7 @@ static bool a3700_spi_wait_completion(struct spi_device *spi) unsigned int ctrl_reg; unsigned long timeout_jiffies; - a3700_spi = spi_master_get_devdata(spi->master); + a3700_spi = spi_controller_get_devdata(spi->controller); /* SPI interrupt is edge-triggered, which means an interrupt will * be generated only when detecting a specific status bit changed @@ -393,7 +393,7 @@ static bool a3700_spi_transfer_wait(struct spi_device *spi, { struct a3700_spi *a3700_spi; - a3700_spi = spi_master_get_devdata(spi->master); + a3700_spi = spi_controller_get_devdata(spi->controller); a3700_spi->wait_mask = bit_mask; return a3700_spi_wait_completion(spi); @@ -417,7 +417,7 @@ static void a3700_spi_transfer_setup(struct spi_device *spi, { struct a3700_spi *a3700_spi; - a3700_spi = spi_master_get_devdata(spi->master); + a3700_spi = spi_controller_get_devdata(spi->controller); a3700_spi_clock_set(a3700_spi, xfer->speed_hz); @@ -434,7 +434,7 @@ static void a3700_spi_transfer_setup(struct spi_device *spi, static void a3700_spi_set_cs(struct spi_device *spi, bool enable) { - struct a3700_spi *a3700_spi = spi_master_get_devdata(spi->master); + struct a3700_spi *a3700_spi = spi_controller_get_devdata(spi->controller); if (!enable) a3700_spi_activate_cs(a3700_spi, spi->chip_select); @@ -565,10 +565,10 @@ static void a3700_spi_transfer_abort_fifo(struct a3700_spi *a3700_spi) spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); } -static int a3700_spi_prepare_message(struct spi_master *master, +static int a3700_spi_prepare_message(struct spi_controller *host, struct spi_message *message) { - struct a3700_spi *a3700_spi = spi_master_get_devdata(master); + struct a3700_spi *a3700_spi = spi_controller_get_devdata(host); struct spi_device *spi = message->spi; int ret; @@ -588,11 +588,11 @@ static int a3700_spi_prepare_message(struct spi_master *master, return 0; } -static int a3700_spi_transfer_one_fifo(struct spi_master *master, +static int a3700_spi_transfer_one_fifo(struct spi_controller *host, struct spi_device *spi, struct spi_transfer *xfer) { - struct a3700_spi *a3700_spi = spi_master_get_devdata(master); + struct a3700_spi *a3700_spi = spi_controller_get_devdata(host); int ret = 0, timeout = A3700_SPI_TIMEOUT; unsigned int nbits = 0, byte_len; u32 val; @@ -732,16 +732,16 @@ static int a3700_spi_transfer_one_fifo(struct spi_master *master, error: a3700_spi_transfer_abort_fifo(a3700_spi); out: - spi_finalize_current_transfer(master); + spi_finalize_current_transfer(host); return ret; } -static int a3700_spi_transfer_one_full_duplex(struct spi_master *master, +static int a3700_spi_transfer_one_full_duplex(struct spi_controller *host, struct spi_device *spi, struct spi_transfer *xfer) { - struct a3700_spi *a3700_spi = spi_master_get_devdata(master); + struct a3700_spi *a3700_spi = spi_controller_get_devdata(host); u32 val; /* Disable FIFO mode */ @@ -777,27 +777,27 @@ static int a3700_spi_transfer_one_full_duplex(struct spi_master *master, } - spi_finalize_current_transfer(master); + spi_finalize_current_transfer(host); return 0; } -static int a3700_spi_transfer_one(struct spi_master *master, +static int a3700_spi_transfer_one(struct spi_controller *host, struct spi_device *spi, struct spi_transfer *xfer) { a3700_spi_transfer_setup(spi, xfer); if (xfer->tx_buf && xfer->rx_buf) - return a3700_spi_transfer_one_full_duplex(master, spi, xfer); + return a3700_spi_transfer_one_full_duplex(host, spi, xfer); - return a3700_spi_transfer_one_fifo(master, spi, xfer); + return a3700_spi_transfer_one_fifo(host, spi, xfer); } -static int a3700_spi_unprepare_message(struct spi_master *master, +static int a3700_spi_unprepare_message(struct spi_controller *host, struct spi_message *message) { - struct a3700_spi *a3700_spi = spi_master_get_devdata(master); + struct a3700_spi *a3700_spi = spi_controller_get_devdata(host); clk_disable(a3700_spi->clk); @@ -815,14 +815,14 @@ static int a3700_spi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *of_node = dev->of_node; - struct spi_master *master; + struct spi_controller *host; struct a3700_spi *spi; u32 num_cs = 0; int irq, ret = 0; - master = spi_alloc_master(dev, sizeof(*spi)); - if (!master) { - dev_err(dev, "master allocation failed\n"); + host = spi_alloc_host(dev, sizeof(*spi)); + if (!host) { + dev_err(dev, "host allocation failed\n"); ret = -ENOMEM; goto out; } @@ -833,23 +833,23 @@ static int a3700_spi_probe(struct platform_device *pdev) goto error; } - master->bus_num = pdev->id; - master->dev.of_node = of_node; - master->mode_bits = SPI_MODE_3; - master->num_chipselect = num_cs; - master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32); - master->prepare_message = a3700_spi_prepare_message; - master->transfer_one = a3700_spi_transfer_one; - master->unprepare_message = a3700_spi_unprepare_message; - master->set_cs = a3700_spi_set_cs; - master->mode_bits |= (SPI_RX_DUAL | SPI_TX_DUAL | + host->bus_num = pdev->id; + host->dev.of_node = of_node; + host->mode_bits = SPI_MODE_3; + host->num_chipselect = num_cs; + host->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32); + host->prepare_message = a3700_spi_prepare_message; + host->transfer_one = a3700_spi_transfer_one; + host->unprepare_message = a3700_spi_unprepare_message; + host->set_cs = a3700_spi_set_cs; + host->mode_bits |= (SPI_RX_DUAL | SPI_TX_DUAL | SPI_RX_QUAD | SPI_TX_QUAD); - platform_set_drvdata(pdev, master); + platform_set_drvdata(pdev, host); - spi = spi_master_get_devdata(master); + spi = spi_controller_get_devdata(host); - spi->master = master; + spi->host = host; spi->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(spi->base)) { @@ -878,23 +878,23 @@ static int a3700_spi_probe(struct platform_device *pdev) goto error; } - master->max_speed_hz = min_t(unsigned long, A3700_SPI_MAX_SPEED_HZ, + host->max_speed_hz = min_t(unsigned long, A3700_SPI_MAX_SPEED_HZ, clk_get_rate(spi->clk)); - master->min_speed_hz = DIV_ROUND_UP(clk_get_rate(spi->clk), + host->min_speed_hz = DIV_ROUND_UP(clk_get_rate(spi->clk), A3700_SPI_MAX_PRESCALE); a3700_spi_init(spi); ret = devm_request_irq(dev, spi->irq, a3700_spi_interrupt, 0, - dev_name(dev), master); + dev_name(dev), host); if (ret) { dev_err(dev, "could not request IRQ: %d\n", ret); goto error_clk; } - ret = devm_spi_register_master(dev, master); + ret = devm_spi_register_controller(dev, host); if (ret) { - dev_err(dev, "Failed to register master\n"); + dev_err(dev, "Failed to register host\n"); goto error_clk; } @@ -903,15 +903,15 @@ static int a3700_spi_probe(struct platform_device *pdev) error_clk: clk_unprepare(spi->clk); error: - spi_master_put(master); + spi_controller_put(host); out: return ret; } static int a3700_spi_remove(struct platform_device *pdev) { - struct spi_master *master = platform_get_drvdata(pdev); - struct a3700_spi *spi = spi_master_get_devdata(master); + struct spi_controller *host = platform_get_drvdata(pdev); + struct a3700_spi *spi = spi_controller_get_devdata(host); clk_unprepare(spi->clk); From 87384599a56f22bbfe6d91e23ef2c767541f2ad9 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 30 Dec 2022 17:28:06 +0800 Subject: [PATCH 12/65] spi: ar934x: switch to use modern name Change legacy name master to modern name host or controller. No functional changed. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221230092806.1687340-4-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/spi/spi-ar934x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-ar934x.c b/drivers/spi/spi-ar934x.c index ec7250c4c810..4a6ecaa0a9c9 100644 --- a/drivers/spi/spi-ar934x.c +++ b/drivers/spi/spi-ar934x.c @@ -61,7 +61,7 @@ static inline int ar934x_spi_clk_div(struct ar934x_spi *sp, unsigned int freq) static int ar934x_spi_setup(struct spi_device *spi) { - struct ar934x_spi *sp = spi_controller_get_devdata(spi->master); + struct ar934x_spi *sp = spi_controller_get_devdata(spi->controller); if ((spi->max_speed_hz == 0) || (spi->max_speed_hz > (sp->clk_freq / 2))) { @@ -74,10 +74,10 @@ static int ar934x_spi_setup(struct spi_device *spi) return 0; } -static int ar934x_spi_transfer_one_message(struct spi_controller *master, +static int ar934x_spi_transfer_one_message(struct spi_controller *ctlr, struct spi_message *m) { - struct ar934x_spi *sp = spi_controller_get_devdata(master); + struct ar934x_spi *sp = spi_controller_get_devdata(ctlr); struct spi_transfer *t = NULL; struct spi_device *spi = m->spi; unsigned long trx_done, trx_cur; @@ -150,7 +150,7 @@ static int ar934x_spi_transfer_one_message(struct spi_controller *master, msg_done: m->status = stat; - spi_finalize_current_message(master); + spi_finalize_current_message(ctlr); return 0; } @@ -183,7 +183,7 @@ static int ar934x_spi_probe(struct platform_device *pdev) if (ret) return ret; - ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*sp)); + ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*sp)); if (!ctlr) { dev_info(&pdev->dev, "failed to allocate spi controller\n"); ret = -ENOMEM; From 392af84bddcc96f1546a1ca4ffa71bccce95b897 Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Tue, 3 Jan 2023 16:22:10 +0100 Subject: [PATCH 13/65] spi: spi-loopback-test: Allow skipping delays A 100 ms delay is inserted between tests by default in order to "detect the individual tests when using a logic analyzer". However, such delays are unnecessary when using this module for automated regression testing, so allow them to be disabled with a module parameter. Signed-off-by: Vincent Whitchurch Link: https://lore.kernel.org/r/20230103152211.3034779-1-vincent.whitchurch@axis.com Signed-off-by: Mark Brown --- drivers/spi/spi-loopback-test.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index dd7de8fa37d0..313106eb8d40 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -71,6 +71,11 @@ module_param(check_ranges, int, 0644); MODULE_PARM_DESC(check_ranges, "checks rx_buffer pattern are valid"); +static unsigned int delay_ms = 100; +module_param(delay_ms, uint, 0644); +MODULE_PARM_DESC(delay_ms, + "delay between tests, in milliseconds (default: 100)"); + /* the actual tests to execute */ static struct spi_test spi_tests[] = { { @@ -1098,7 +1103,8 @@ int spi_test_run_tests(struct spi_device *spi, * detect the individual tests when using a logic analyzer * we also add scheduling to avoid potential spi_timeouts... */ - mdelay(100); + if (delay_ms) + mdelay(delay_ms); schedule(); } From f66804bf7665f9d2db04791496ba2c7f4173941c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jan 2023 09:19:53 +0100 Subject: [PATCH 14/65] dt-bindings: trivial-devices: Remove trailing whitespace Remove trailing whitespace that hurts my eyes. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/7c1b2700f3727e94600f5f7e10beef16f8dc64ed.1673425053.git.geert+renesas@glider.be Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/trivial-devices.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 7da40dadfe2e..b13f280f36fa 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -325,7 +325,7 @@ properties: - sgx,vz89x # Silicon Labs EM3581 Zigbee SoC with SPI interface - silabs,em3581 - # Silicon Labs SI3210 Programmable CMOS SLIC/CODEC with SPI interface + # Silicon Labs SI3210 Programmable CMOS SLIC/CODEC with SPI interface - silabs,si3210 # Relative Humidity and Temperature Sensors - silabs,si7020 From f276aacf5d2f7fb57e400db44c807ea3b9525fd6 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 13 Jan 2023 19:23:08 +0900 Subject: [PATCH 15/65] spi: Use a 32-bit DT property for spi-cs-setup-delay-ns 65us is not a reasonable maximum for this property, as some devices might need a much longer setup time (e.g. those driven by firmware on the other end). Plus, device tree property values are in 32-bit cells and smaller widths should not be used without good reason. Also move the logic to a helper function, since this will later be used to parse other CS delay properties too. Fixes: 33a2fde5f77b ("spi: Introduce spi-cs-setup-ns property") Signed-off-by: Janne Grunau Signed-off-by: Hector Martin Link: https://lore.kernel.org/r/20230113102309.18308-2-marcan@marcan.st Signed-off-by: Mark Brown --- drivers/spi/spi.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 15f174f4e056..3f33934f5429 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2220,11 +2220,26 @@ void spi_flush_queue(struct spi_controller *ctlr) /*-------------------------------------------------------------------------*/ #if defined(CONFIG_OF) +static void of_spi_parse_dt_cs_delay(struct device_node *nc, + struct spi_delay *delay, const char *prop) +{ + u32 value; + + if (!of_property_read_u32(nc, prop, &value)) { + if (value > U16_MAX) { + delay->value = DIV_ROUND_UP(value, 1000); + delay->unit = SPI_DELAY_UNIT_USECS; + } else { + delay->value = value; + delay->unit = SPI_DELAY_UNIT_NSECS; + } + } +} + static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, struct device_node *nc) { u32 value; - u16 cs_setup; int rc; /* Mode (clock phase/polarity/etc.) */ @@ -2310,10 +2325,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, if (!of_property_read_u32(nc, "spi-max-frequency", &value)) spi->max_speed_hz = value; - if (!of_property_read_u16(nc, "spi-cs-setup-delay-ns", &cs_setup)) { - spi->cs_setup.value = cs_setup; - spi->cs_setup.unit = SPI_DELAY_UNIT_NSECS; - } + /* Device CS delays */ + of_spi_parse_dt_cs_delay(nc, &spi->cs_setup, "spi-cs-setup-delay-ns"); return 0; } From 34f89f238c545d4fd0166e37c201d96c10443953 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 13 Jan 2023 19:23:09 +0900 Subject: [PATCH 16/65] spi: dt-bindings: Add hold/inactive CS delay peripheral properties These two properties complete the bindings for the Linux spi_device cs model, which includes cs_setup, cs_hold and cs_inactive delay values. Signed-off-by: Janne Grunau Reviewed-by: Rob Herring Signed-off-by: Hector Martin Link: https://lore.kernel.org/r/20230113102309.18308-3-marcan@marcan.st Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-peripheral-props.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml index 9a60c0664bbe..782a014b63a7 100644 --- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml +++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml @@ -49,6 +49,16 @@ properties: Delay in nanoseconds to be introduced by the controller after CS is asserted. + spi-cs-hold-delay-ns: + description: + Delay in nanoseconds to be introduced by the controller before CS is + de-asserted. + + spi-cs-inactive-delay-ns: + description: + Delay in nanoseconds to be introduced by the controller after CS is + de-asserted. + spi-rx-bus-width: description: Bus width to the SPI bus used for read transfers. From 5827b31d858e399e0ba9fbd33da7a39b31769e11 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 13 Jan 2023 19:23:10 +0900 Subject: [PATCH 17/65] spi: Parse hold/inactive CS delay values from the DT Now that we support parsing the setup time from the Device Tree, we can also easily support the remaining hold and inactive time delay values. Signed-off-by: Janne Grunau Signed-off-by: Hector Martin Link: https://lore.kernel.org/r/20230113102309.18308-4-marcan@marcan.st Signed-off-by: Mark Brown --- drivers/spi/spi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 3f33934f5429..fc4f6308efd8 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2327,6 +2327,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, /* Device CS delays */ of_spi_parse_dt_cs_delay(nc, &spi->cs_setup, "spi-cs-setup-delay-ns"); + of_spi_parse_dt_cs_delay(nc, &spi->cs_hold, "spi-cs-hold-delay-ns"); + of_spi_parse_dt_cs_delay(nc, &spi->cs_inactive, "spi-cs-inactive-delay-ns"); return 0; } From be5852457b7e85ad13b1bded9c97bed5ee1715a3 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 20 Jan 2023 08:56:51 +0100 Subject: [PATCH 18/65] spi: spidev: order compatibles alphabetically Bring some order to reduce possibilities of conflicts. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230120075651.153763-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index d8998d5e8483..898167f3b5af 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -722,14 +722,14 @@ static int spidev_of_check(struct device *dev) } static const struct of_device_id spidev_dt_ids[] = { - { .compatible = "rohm,dh2228fv", .data = &spidev_of_check }, - { .compatible = "lineartechnology,ltc2488", .data = &spidev_of_check }, - { .compatible = "semtech,sx1301", .data = &spidev_of_check }, - { .compatible = "lwn,bk4", .data = &spidev_of_check }, - { .compatible = "dh,dhcom-board", .data = &spidev_of_check }, - { .compatible = "menlo,m53cpld", .data = &spidev_of_check }, { .compatible = "cisco,spi-petra", .data = &spidev_of_check }, + { .compatible = "dh,dhcom-board", .data = &spidev_of_check }, + { .compatible = "lineartechnology,ltc2488", .data = &spidev_of_check }, + { .compatible = "lwn,bk4", .data = &spidev_of_check }, + { .compatible = "menlo,m53cpld", .data = &spidev_of_check }, { .compatible = "micron,spi-authenta", .data = &spidev_of_check }, + { .compatible = "rohm,dh2228fv", .data = &spidev_of_check }, + { .compatible = "semtech,sx1301", .data = &spidev_of_check }, { .compatible = "silabs,em3581", .data = &spidev_of_check }, { .compatible = "silabs,si3210", .data = &spidev_of_check }, {}, From 398b6b310ec85eef9d98df5963d5ded18aa92ad8 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 10 Jan 2023 21:18:03 +0800 Subject: [PATCH 19/65] spi: atmel: switch to use modern name Change legacy name master to modern name host or controller. No functional changed. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20230110131805.2827248-2-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 254 ++++++++++++++++++++-------------------- 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index c4f22d50dba5..5c5678f065f3 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -358,7 +358,7 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) u32 csr; /* Make sure clock polarity is correct */ - for (i = 0; i < spi->master->num_chipselect; i++) { + for (i = 0; i < spi->controller->num_chipselect; i++) { csr = spi_readl(as, CSR0 + 4 * i); if ((csr ^ cpol) & SPI_BIT(CPOL)) spi_writel(as, CSR0 + 4 * i, @@ -419,11 +419,11 @@ static inline bool atmel_spi_use_dma(struct atmel_spi *as, return as->use_dma && xfer->len >= DMA_MIN_BYTES; } -static bool atmel_spi_can_dma(struct spi_master *master, +static bool atmel_spi_can_dma(struct spi_controller *host, struct spi_device *spi, struct spi_transfer *xfer) { - struct atmel_spi *as = spi_master_get_devdata(master); + struct atmel_spi *as = spi_controller_get_devdata(host); if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) return atmel_spi_use_dma(as, xfer) && @@ -435,7 +435,7 @@ static bool atmel_spi_can_dma(struct spi_master *master, static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word) { - struct spi_master *master = platform_get_drvdata(as->pdev); + struct spi_controller *host = platform_get_drvdata(as->pdev); struct dma_slave_config slave_config; int err = 0; @@ -467,21 +467,21 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word) * So we'd rather write only one data at the time. Hence the transmit * path works the same whether FIFOs are available (and enabled) or not. */ - if (dmaengine_slave_config(master->dma_tx, &slave_config)) { + if (dmaengine_slave_config(host->dma_tx, &slave_config)) { dev_err(&as->pdev->dev, "failed to configure tx dma channel\n"); err = -EINVAL; } /* - * This driver configures the spi controller for master mode (MSTR bit + * This driver configures the spi controller for host mode (MSTR bit * set to '1' in the Mode Register). * So according to the datasheet, when FIFOs are available (and * enabled), the Receive FIFO operates in Single Data Mode. * So the receive path works the same whether FIFOs are available (and * enabled) or not. */ - if (dmaengine_slave_config(master->dma_rx, &slave_config)) { + if (dmaengine_slave_config(host->dma_rx, &slave_config)) { dev_err(&as->pdev->dev, "failed to configure rx dma channel\n"); err = -EINVAL; @@ -490,22 +490,22 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word) return err; } -static int atmel_spi_configure_dma(struct spi_master *master, +static int atmel_spi_configure_dma(struct spi_controller *host, struct atmel_spi *as) { struct device *dev = &as->pdev->dev; int err; - master->dma_tx = dma_request_chan(dev, "tx"); - if (IS_ERR(master->dma_tx)) { - err = PTR_ERR(master->dma_tx); + host->dma_tx = dma_request_chan(dev, "tx"); + if (IS_ERR(host->dma_tx)) { + err = PTR_ERR(host->dma_tx); dev_dbg(dev, "No TX DMA channel, DMA is disabled\n"); goto error_clear; } - master->dma_rx = dma_request_chan(dev, "rx"); - if (IS_ERR(master->dma_rx)) { - err = PTR_ERR(master->dma_rx); + host->dma_rx = dma_request_chan(dev, "rx"); + if (IS_ERR(host->dma_rx)) { + err = PTR_ERR(host->dma_rx); /* * No reason to check EPROBE_DEFER here since we have already * requested tx channel. @@ -520,45 +520,45 @@ static int atmel_spi_configure_dma(struct spi_master *master, dev_info(&as->pdev->dev, "Using %s (tx) and %s (rx) for DMA transfers\n", - dma_chan_name(master->dma_tx), - dma_chan_name(master->dma_rx)); + dma_chan_name(host->dma_tx), + dma_chan_name(host->dma_rx)); return 0; error: - if (!IS_ERR(master->dma_rx)) - dma_release_channel(master->dma_rx); - if (!IS_ERR(master->dma_tx)) - dma_release_channel(master->dma_tx); + if (!IS_ERR(host->dma_rx)) + dma_release_channel(host->dma_rx); + if (!IS_ERR(host->dma_tx)) + dma_release_channel(host->dma_tx); error_clear: - master->dma_tx = master->dma_rx = NULL; + host->dma_tx = host->dma_rx = NULL; return err; } -static void atmel_spi_stop_dma(struct spi_master *master) +static void atmel_spi_stop_dma(struct spi_controller *host) { - if (master->dma_rx) - dmaengine_terminate_all(master->dma_rx); - if (master->dma_tx) - dmaengine_terminate_all(master->dma_tx); + if (host->dma_rx) + dmaengine_terminate_all(host->dma_rx); + if (host->dma_tx) + dmaengine_terminate_all(host->dma_tx); } -static void atmel_spi_release_dma(struct spi_master *master) +static void atmel_spi_release_dma(struct spi_controller *host) { - if (master->dma_rx) { - dma_release_channel(master->dma_rx); - master->dma_rx = NULL; + if (host->dma_rx) { + dma_release_channel(host->dma_rx); + host->dma_rx = NULL; } - if (master->dma_tx) { - dma_release_channel(master->dma_tx); - master->dma_tx = NULL; + if (host->dma_tx) { + dma_release_channel(host->dma_tx); + host->dma_tx = NULL; } } /* This function is called by the DMA driver from tasklet context */ static void dma_callback(void *data) { - struct spi_master *master = data; - struct atmel_spi *as = spi_master_get_devdata(master); + struct spi_controller *host = data; + struct atmel_spi *as = spi_controller_get_devdata(host); if (is_vmalloc_addr(as->current_transfer->rx_buf) && IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) { @@ -571,13 +571,13 @@ static void dma_callback(void *data) /* * Next transfer using PIO without FIFO. */ -static void atmel_spi_next_xfer_single(struct spi_master *master, +static void atmel_spi_next_xfer_single(struct spi_controller *host, struct spi_transfer *xfer) { - struct atmel_spi *as = spi_master_get_devdata(master); + struct atmel_spi *as = spi_controller_get_devdata(host); unsigned long xfer_pos = xfer->len - as->current_remaining_bytes; - dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_pio\n"); + dev_vdbg(host->dev.parent, "atmel_spi_next_xfer_pio\n"); /* Make sure data is not remaining in RDR */ spi_readl(as, RDR); @@ -591,7 +591,7 @@ static void atmel_spi_next_xfer_single(struct spi_master *master, else spi_writel(as, TDR, *(u8 *)(xfer->tx_buf + xfer_pos)); - dev_dbg(master->dev.parent, + dev_dbg(host->dev.parent, " start pio xfer %p: len %u tx %p rx %p bitpw %d\n", xfer, xfer->len, xfer->tx_buf, xfer->rx_buf, xfer->bits_per_word); @@ -603,10 +603,10 @@ static void atmel_spi_next_xfer_single(struct spi_master *master, /* * Next transfer using PIO with FIFO. */ -static void atmel_spi_next_xfer_fifo(struct spi_master *master, +static void atmel_spi_next_xfer_fifo(struct spi_controller *host, struct spi_transfer *xfer) { - struct atmel_spi *as = spi_master_get_devdata(master); + struct atmel_spi *as = spi_controller_get_devdata(host); u32 current_remaining_data, num_data; u32 offset = xfer->len - as->current_remaining_bytes; const u16 *words = (const u16 *)((u8 *)xfer->tx_buf + offset); @@ -614,7 +614,7 @@ static void atmel_spi_next_xfer_fifo(struct spi_master *master, u16 td0, td1; u32 fifomr; - dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_fifo\n"); + dev_vdbg(host->dev.parent, "atmel_spi_next_xfer_fifo\n"); /* Compute the number of data to transfer in the current iteration */ current_remaining_data = ((xfer->bits_per_word > 8) ? @@ -658,7 +658,7 @@ static void atmel_spi_next_xfer_fifo(struct spi_master *master, num_data--; } - dev_dbg(master->dev.parent, + dev_dbg(host->dev.parent, " start fifo xfer %p: len %u tx %p rx %p bitpw %d\n", xfer, xfer->len, xfer->tx_buf, xfer->rx_buf, xfer->bits_per_word); @@ -673,32 +673,32 @@ static void atmel_spi_next_xfer_fifo(struct spi_master *master, /* * Next transfer using PIO. */ -static void atmel_spi_next_xfer_pio(struct spi_master *master, +static void atmel_spi_next_xfer_pio(struct spi_controller *host, struct spi_transfer *xfer) { - struct atmel_spi *as = spi_master_get_devdata(master); + struct atmel_spi *as = spi_controller_get_devdata(host); if (as->fifo_size) - atmel_spi_next_xfer_fifo(master, xfer); + atmel_spi_next_xfer_fifo(host, xfer); else - atmel_spi_next_xfer_single(master, xfer); + atmel_spi_next_xfer_single(host, xfer); } /* * Submit next transfer for DMA. */ -static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, +static int atmel_spi_next_xfer_dma_submit(struct spi_controller *host, struct spi_transfer *xfer, u32 *plen) { - struct atmel_spi *as = spi_master_get_devdata(master); - struct dma_chan *rxchan = master->dma_rx; - struct dma_chan *txchan = master->dma_tx; + struct atmel_spi *as = spi_controller_get_devdata(host); + struct dma_chan *rxchan = host->dma_rx; + struct dma_chan *txchan = host->dma_tx; struct dma_async_tx_descriptor *rxdesc; struct dma_async_tx_descriptor *txdesc; dma_cookie_t cookie; - dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_dma_submit\n"); + dev_vdbg(host->dev.parent, "atmel_spi_next_xfer_dma_submit\n"); /* Check that the channels are available */ if (!rxchan || !txchan) @@ -749,7 +749,7 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, if (!txdesc) goto err_dma; - dev_dbg(master->dev.parent, + dev_dbg(host->dev.parent, " start dma xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", xfer, xfer->len, xfer->tx_buf, (unsigned long long)xfer->tx_dma, xfer->rx_buf, (unsigned long long)xfer->rx_dma); @@ -759,7 +759,7 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, /* Put the callback on the RX transfer only, that should finish last */ rxdesc->callback = dma_callback; - rxdesc->callback_param = master; + rxdesc->callback_param = host; /* Submit and fire RX and TX with TX last so we're ready to read! */ cookie = rxdesc->tx_submit(rxdesc); @@ -775,12 +775,12 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, err_dma: spi_writel(as, IDR, SPI_BIT(OVRES)); - atmel_spi_stop_dma(master); + atmel_spi_stop_dma(host); err_exit: return -ENOMEM; } -static void atmel_spi_next_xfer_data(struct spi_master *master, +static void atmel_spi_next_xfer_data(struct spi_controller *host, struct spi_transfer *xfer, dma_addr_t *tx_dma, dma_addr_t *rx_dma, @@ -788,8 +788,8 @@ static void atmel_spi_next_xfer_data(struct spi_master *master, { *rx_dma = xfer->rx_dma + xfer->len - *plen; *tx_dma = xfer->tx_dma + xfer->len - *plen; - if (*plen > master->max_dma_len) - *plen = master->max_dma_len; + if (*plen > host->max_dma_len) + *plen = host->max_dma_len; } static int atmel_spi_set_xfer_speed(struct atmel_spi *as, @@ -844,17 +844,17 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as, * Submit next transfer for PDC. * lock is held, spi irq is blocked */ -static void atmel_spi_pdc_next_xfer(struct spi_master *master, +static void atmel_spi_pdc_next_xfer(struct spi_controller *host, struct spi_transfer *xfer) { - struct atmel_spi *as = spi_master_get_devdata(master); + struct atmel_spi *as = spi_controller_get_devdata(host); u32 len; dma_addr_t tx_dma, rx_dma; spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); len = as->current_remaining_bytes; - atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); + atmel_spi_next_xfer_data(host, xfer, &tx_dma, &rx_dma, &len); as->current_remaining_bytes -= len; spi_writel(as, RPR, rx_dma); @@ -865,7 +865,7 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, spi_writel(as, RCR, len); spi_writel(as, TCR, len); - dev_dbg(&master->dev, + dev_dbg(&host->dev, " start xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", xfer, xfer->len, xfer->tx_buf, (unsigned long long)xfer->tx_dma, xfer->rx_buf, @@ -873,7 +873,7 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, if (as->current_remaining_bytes) { len = as->current_remaining_bytes; - atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); + atmel_spi_next_xfer_data(host, xfer, &tx_dma, &rx_dma, &len); as->current_remaining_bytes -= len; spi_writel(as, RNPR, rx_dma); @@ -884,7 +884,7 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, spi_writel(as, RNCR, len); spi_writel(as, TNCR, len); - dev_dbg(&master->dev, + dev_dbg(&host->dev, " next xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", xfer, xfer->len, xfer->tx_buf, (unsigned long long)xfer->tx_dma, xfer->rx_buf, @@ -944,14 +944,14 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) return 0; } -static void atmel_spi_dma_unmap_xfer(struct spi_master *master, +static void atmel_spi_dma_unmap_xfer(struct spi_controller *host, struct spi_transfer *xfer) { if (xfer->tx_dma != INVALID_DMA_ADDRESS) - dma_unmap_single(master->dev.parent, xfer->tx_dma, + dma_unmap_single(host->dev.parent, xfer->tx_dma, xfer->len, DMA_TO_DEVICE); if (xfer->rx_dma != INVALID_DMA_ADDRESS) - dma_unmap_single(master->dev.parent, xfer->rx_dma, + dma_unmap_single(host->dev.parent, xfer->rx_dma, xfer->len, DMA_FROM_DEVICE); } @@ -1039,8 +1039,8 @@ atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer) static irqreturn_t atmel_spi_pio_interrupt(int irq, void *dev_id) { - struct spi_master *master = dev_id; - struct atmel_spi *as = spi_master_get_devdata(master); + struct spi_controller *host = dev_id; + struct atmel_spi *as = spi_controller_get_devdata(host); u32 status, pending, imr; struct spi_transfer *xfer; int ret = IRQ_NONE; @@ -1052,7 +1052,7 @@ atmel_spi_pio_interrupt(int irq, void *dev_id) if (pending & SPI_BIT(OVRES)) { ret = IRQ_HANDLED; spi_writel(as, IDR, SPI_BIT(OVRES)); - dev_warn(master->dev.parent, "overrun\n"); + dev_warn(host->dev.parent, "overrun\n"); /* * When we get an overrun, we disregard the current @@ -1097,8 +1097,8 @@ atmel_spi_pio_interrupt(int irq, void *dev_id) static irqreturn_t atmel_spi_pdc_interrupt(int irq, void *dev_id) { - struct spi_master *master = dev_id; - struct atmel_spi *as = spi_master_get_devdata(master); + struct spi_controller *host = dev_id; + struct atmel_spi *as = spi_controller_get_devdata(host); u32 status, pending, imr; int ret = IRQ_NONE; @@ -1152,12 +1152,12 @@ static int atmel_word_delay_csr(struct spi_device *spi, struct atmel_spi *as) static void initialize_native_cs_for_gpio(struct atmel_spi *as) { int i; - struct spi_master *master = platform_get_drvdata(as->pdev); + struct spi_controller *host = platform_get_drvdata(as->pdev); if (!as->native_cs_free) return; /* already initialized */ - if (!master->cs_gpiods) + if (!host->cs_gpiods) return; /* No CS GPIO */ /* @@ -1170,7 +1170,7 @@ static void initialize_native_cs_for_gpio(struct atmel_spi *as) i = 1; for (; i < 4; i++) - if (master->cs_gpiods[i]) + if (host->cs_gpiods[i]) as->native_cs_free |= BIT(i); if (as->native_cs_free) @@ -1186,7 +1186,7 @@ static int atmel_spi_setup(struct spi_device *spi) int chip_select; int word_delay_csr; - as = spi_master_get_devdata(spi->master); + as = spi_controller_get_devdata(spi->controller); /* see notes above re chipselect */ if (!spi->cs_gpiod && (spi->mode & SPI_CS_HIGH)) { @@ -1254,7 +1254,7 @@ static int atmel_spi_setup(struct spi_device *spi) static void atmel_spi_set_cs(struct spi_device *spi, bool enable) { - struct atmel_spi *as = spi_master_get_devdata(spi->master); + struct atmel_spi *as = spi_controller_get_devdata(spi->controller); /* the core doesn't really pass us enable/disable, but CS HIGH vs CS LOW * since we already have routines for activate/deactivate translate * high/low to active/inactive @@ -1269,7 +1269,7 @@ static void atmel_spi_set_cs(struct spi_device *spi, bool enable) } -static int atmel_spi_one_transfer(struct spi_master *master, +static int atmel_spi_one_transfer(struct spi_controller *host, struct spi_device *spi, struct spi_transfer *xfer) { @@ -1281,7 +1281,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, int ret; unsigned long dma_timeout; - as = spi_master_get_devdata(master); + as = spi_controller_get_devdata(host); asd = spi->controller_state; bits = (asd->csr >> 4) & 0xf; @@ -1295,7 +1295,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, * DMA map early, for performance (empties dcache ASAP) and * better fault reporting. */ - if ((!master->cur_msg->is_dma_mapped) + if ((!host->cur_msg->is_dma_mapped) && as->use_pdc) { if (atmel_spi_dma_map_xfer(as, xfer) < 0) return -ENOMEM; @@ -1311,11 +1311,11 @@ static int atmel_spi_one_transfer(struct spi_master *master, if (as->use_pdc) { atmel_spi_lock(as); - atmel_spi_pdc_next_xfer(master, xfer); + atmel_spi_pdc_next_xfer(host, xfer); atmel_spi_unlock(as); } else if (atmel_spi_use_dma(as, xfer)) { len = as->current_remaining_bytes; - ret = atmel_spi_next_xfer_dma_submit(master, + ret = atmel_spi_next_xfer_dma_submit(host, xfer, &len); if (ret) { dev_err(&spi->dev, @@ -1329,7 +1329,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, } } else { atmel_spi_lock(as); - atmel_spi_next_xfer_pio(master, xfer); + atmel_spi_next_xfer_pio(host, xfer); atmel_spi_unlock(as); } @@ -1346,7 +1346,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, if (as->done_status) { if (as->use_pdc) { - dev_warn(master->dev.parent, + dev_warn(host->dev.parent, "overrun (%u/%u remaining)\n", spi_readl(as, TCR), spi_readl(as, RCR)); @@ -1362,7 +1362,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, if (spi_readl(as, SR) & SPI_BIT(TXEMPTY)) break; if (!timeout) - dev_warn(master->dev.parent, + dev_warn(host->dev.parent, "timeout waiting for TXEMPTY"); while (spi_readl(as, SR) & SPI_BIT(RDRF)) spi_readl(as, RDR); @@ -1371,13 +1371,13 @@ static int atmel_spi_one_transfer(struct spi_master *master, spi_readl(as, SR); } else if (atmel_spi_use_dma(as, xfer)) { - atmel_spi_stop_dma(master); + atmel_spi_stop_dma(host); } } - if (!master->cur_msg->is_dma_mapped + if (!host->cur_msg->is_dma_mapped && as->use_pdc) - atmel_spi_dma_unmap_xfer(master, xfer); + atmel_spi_dma_unmap_xfer(host, xfer); if (as->use_pdc) atmel_spi_disable_pdc_transfer(as); @@ -1440,7 +1440,7 @@ static int atmel_spi_probe(struct platform_device *pdev) int irq; struct clk *clk; int ret; - struct spi_master *master; + struct spi_controller *host; struct atmel_spi *as; /* Select default pin state */ @@ -1459,29 +1459,29 @@ static int atmel_spi_probe(struct platform_device *pdev) return PTR_ERR(clk); /* setup spi core then atmel-specific driver state */ - master = spi_alloc_master(&pdev->dev, sizeof(*as)); - if (!master) + host = spi_alloc_host(&pdev->dev, sizeof(*as)); + if (!host) return -ENOMEM; /* the spi->mode bits understood by this driver: */ - master->use_gpio_descriptors = true; - master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; - master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); - master->dev.of_node = pdev->dev.of_node; - master->bus_num = pdev->id; - master->num_chipselect = 4; - master->setup = atmel_spi_setup; - master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX | + host->use_gpio_descriptors = true; + host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + host->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); + host->dev.of_node = pdev->dev.of_node; + host->bus_num = pdev->id; + host->num_chipselect = 4; + host->setup = atmel_spi_setup; + host->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX | SPI_MASTER_GPIO_SS); - master->transfer_one = atmel_spi_one_transfer; - master->set_cs = atmel_spi_set_cs; - master->cleanup = atmel_spi_cleanup; - master->auto_runtime_pm = true; - master->max_dma_len = SPI_MAX_DMA_XFER; - master->can_dma = atmel_spi_can_dma; - platform_set_drvdata(pdev, master); + host->transfer_one = atmel_spi_one_transfer; + host->set_cs = atmel_spi_set_cs; + host->cleanup = atmel_spi_cleanup; + host->auto_runtime_pm = true; + host->max_dma_len = SPI_MAX_DMA_XFER; + host->can_dma = atmel_spi_can_dma; + platform_set_drvdata(pdev, host); - as = spi_master_get_devdata(master); + as = spi_controller_get_devdata(host); spin_lock_init(&as->lock); @@ -1502,7 +1502,7 @@ static int atmel_spi_probe(struct platform_device *pdev) as->use_dma = false; as->use_pdc = false; if (as->caps.has_dma_support) { - ret = atmel_spi_configure_dma(master, as); + ret = atmel_spi_configure_dma(host, as); if (ret == 0) { as->use_dma = true; } else if (ret == -EPROBE_DEFER) { @@ -1532,7 +1532,7 @@ static int atmel_spi_probe(struct platform_device *pdev) } } if (!as->use_dma) - dev_info(master->dev.parent, + dev_info(host->dev.parent, " can not allocate dma coherent memory\n"); } @@ -1541,10 +1541,10 @@ static int atmel_spi_probe(struct platform_device *pdev) if (as->use_pdc) { ret = devm_request_irq(&pdev->dev, irq, atmel_spi_pdc_interrupt, - 0, dev_name(&pdev->dev), master); + 0, dev_name(&pdev->dev), host); } else { ret = devm_request_irq(&pdev->dev, irq, atmel_spi_pio_interrupt, - 0, dev_name(&pdev->dev), master); + 0, dev_name(&pdev->dev), host); } if (ret) goto out_unmap_regs; @@ -1569,7 +1569,7 @@ static int atmel_spi_probe(struct platform_device *pdev) pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - ret = devm_spi_register_master(&pdev->dev, master); + ret = devm_spi_register_controller(&pdev->dev, host); if (ret) goto out_free_dma; @@ -1585,28 +1585,28 @@ static int atmel_spi_probe(struct platform_device *pdev) pm_runtime_set_suspended(&pdev->dev); if (as->use_dma) - atmel_spi_release_dma(master); + atmel_spi_release_dma(host); spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ clk_disable_unprepare(clk); out_free_irq: out_unmap_regs: - spi_master_put(master); + spi_controller_put(host); return ret; } static int atmel_spi_remove(struct platform_device *pdev) { - struct spi_master *master = platform_get_drvdata(pdev); - struct atmel_spi *as = spi_master_get_devdata(master); + struct spi_controller *host = platform_get_drvdata(pdev); + struct atmel_spi *as = spi_controller_get_devdata(host); pm_runtime_get_sync(&pdev->dev); /* reset the hardware and block queue progress */ if (as->use_dma) { - atmel_spi_stop_dma(master); - atmel_spi_release_dma(master); + atmel_spi_stop_dma(host); + atmel_spi_release_dma(host); if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) { dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER, as->addr_tx_bbuf, @@ -1633,8 +1633,8 @@ static int atmel_spi_remove(struct platform_device *pdev) static int atmel_spi_runtime_suspend(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct atmel_spi *as = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct atmel_spi *as = spi_controller_get_devdata(host); clk_disable_unprepare(as->clk); pinctrl_pm_select_sleep_state(dev); @@ -1644,8 +1644,8 @@ static int atmel_spi_runtime_suspend(struct device *dev) static int atmel_spi_runtime_resume(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct atmel_spi *as = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct atmel_spi *as = spi_controller_get_devdata(host); pinctrl_pm_select_default_state(dev); @@ -1654,11 +1654,11 @@ static int atmel_spi_runtime_resume(struct device *dev) static int atmel_spi_suspend(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); + struct spi_controller *host = dev_get_drvdata(dev); int ret; /* Stop the queue running */ - ret = spi_master_suspend(master); + ret = spi_controller_suspend(host); if (ret) return ret; @@ -1670,8 +1670,8 @@ static int atmel_spi_suspend(struct device *dev) static int atmel_spi_resume(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct atmel_spi *as = spi_master_get_devdata(master); + struct spi_controller *host = dev_get_drvdata(dev); + struct atmel_spi *as = spi_controller_get_devdata(host); int ret; ret = clk_prepare_enable(as->clk); @@ -1689,7 +1689,7 @@ static int atmel_spi_resume(struct device *dev) } /* Start the queue running */ - return spi_master_resume(master); + return spi_controller_resume(host); } static const struct dev_pm_ops atmel_spi_pm_ops = { From 747d4e2c5f0e0469ad6055849f99516ca4b03e82 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 10 Jan 2023 21:18:04 +0800 Subject: [PATCH 20/65] spi: at91-usart: switch to use modern name Change legacy name master to modern name host or controller. No functional changed. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20230110131805.2827248-3-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/spi/spi-at91-usart.c | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c index 9cd738682aab..fab9d223e24a 100644 --- a/drivers/spi/spi-at91-usart.c +++ b/drivers/spi/spi-at91-usart.c @@ -38,7 +38,7 @@ #define US_CR_TXEN BIT(6) #define US_CR_TXDIS BIT(7) -#define US_MR_SPI_MASTER 0x0E +#define US_MR_SPI_HOST 0x0E #define US_MR_CHRL GENMASK(7, 6) #define US_MR_CPHA BIT(8) #define US_MR_CPOL BIT(16) @@ -61,7 +61,7 @@ #define US_OVRE_RXRDY_IRQS (US_IR_OVRE | US_IR_RXRDY) #define US_INIT \ - (US_MR_SPI_MASTER | US_MR_CHRL | US_MR_CLKO | US_MR_WRDBT) + (US_MR_SPI_HOST | US_MR_CHRL | US_MR_CLKO | US_MR_WRDBT) #define US_DMA_MIN_BYTES 16 #define US_DMA_TIMEOUT (msecs_to_jiffies(1000)) @@ -104,7 +104,7 @@ struct at91_usart_spi { static void dma_callback(void *data) { struct spi_controller *ctlr = data; - struct at91_usart_spi *aus = spi_master_get_devdata(ctlr); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr); at91_usart_spi_writel(aus, IER, US_IR_RXRDY); aus->current_rx_remaining_bytes = 0; @@ -115,7 +115,7 @@ static bool at91_usart_spi_can_dma(struct spi_controller *ctrl, struct spi_device *spi, struct spi_transfer *xfer) { - struct at91_usart_spi *aus = spi_master_get_devdata(ctrl); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctrl); return aus->use_dma && xfer->len >= US_DMA_MIN_BYTES; } @@ -216,7 +216,7 @@ static void at91_usart_spi_stop_dma(struct spi_controller *ctlr) static int at91_usart_spi_dma_transfer(struct spi_controller *ctlr, struct spi_transfer *xfer) { - struct at91_usart_spi *aus = spi_master_get_devdata(ctlr); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr); struct dma_chan *rxchan = ctlr->dma_rx; struct dma_chan *txchan = ctlr->dma_tx; struct dma_async_tx_descriptor *rxdesc; @@ -334,7 +334,7 @@ at91_usart_spi_set_xfer_speed(struct at91_usart_spi *aus, static irqreturn_t at91_usart_spi_interrupt(int irq, void *dev_id) { struct spi_controller *controller = dev_id; - struct at91_usart_spi *aus = spi_master_get_devdata(controller); + struct at91_usart_spi *aus = spi_controller_get_devdata(controller); spin_lock(&aus->lock); at91_usart_spi_read_status(aus); @@ -359,7 +359,7 @@ static irqreturn_t at91_usart_spi_interrupt(int irq, void *dev_id) static int at91_usart_spi_setup(struct spi_device *spi) { - struct at91_usart_spi *aus = spi_master_get_devdata(spi->controller); + struct at91_usart_spi *aus = spi_controller_get_devdata(spi->controller); u32 *ausd = spi->controller_state; unsigned int mr = at91_usart_spi_readl(aus, MR); @@ -399,7 +399,7 @@ static int at91_usart_spi_transfer_one(struct spi_controller *ctlr, struct spi_device *spi, struct spi_transfer *xfer) { - struct at91_usart_spi *aus = spi_master_get_devdata(ctlr); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr); unsigned long dma_timeout = 0; int ret = 0; @@ -444,7 +444,7 @@ static int at91_usart_spi_transfer_one(struct spi_controller *ctlr, static int at91_usart_spi_prepare_message(struct spi_controller *ctlr, struct spi_message *message) { - struct at91_usart_spi *aus = spi_master_get_devdata(ctlr); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr); struct spi_device *spi = message->spi; u32 *ausd = spi->controller_state; @@ -458,7 +458,7 @@ static int at91_usart_spi_prepare_message(struct spi_controller *ctlr, static int at91_usart_spi_unprepare_message(struct spi_controller *ctlr, struct spi_message *message) { - struct at91_usart_spi *aus = spi_master_get_devdata(ctlr); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr); at91_usart_spi_writel(aus, CR, US_RESET | US_DISABLE); at91_usart_spi_writel(aus, IDR, US_OVRE_RXRDY_IRQS); @@ -515,7 +515,7 @@ static int at91_usart_spi_probe(struct platform_device *pdev) return PTR_ERR(clk); ret = -ENOMEM; - controller = spi_alloc_master(&pdev->dev, sizeof(*aus)); + controller = spi_alloc_host(&pdev->dev, sizeof(*aus)); if (!controller) goto at91_usart_spi_probe_fail; @@ -539,7 +539,7 @@ static int at91_usart_spi_probe(struct platform_device *pdev) US_MAX_CLK_DIV); platform_set_drvdata(pdev, controller); - aus = spi_master_get_devdata(controller); + aus = spi_controller_get_devdata(controller); aus->dev = &pdev->dev; aus->regs = devm_ioremap_resource(&pdev->dev, regs); @@ -574,9 +574,9 @@ static int at91_usart_spi_probe(struct platform_device *pdev) spin_lock_init(&aus->lock); init_completion(&aus->xfer_completion); - ret = devm_spi_register_master(&pdev->dev, controller); + ret = devm_spi_register_controller(&pdev->dev, controller); if (ret) - goto at91_usart_fail_register_master; + goto at91_usart_fail_register_controller; dev_info(&pdev->dev, "AT91 USART SPI Controller version 0x%x at %pa (irq %d)\n", @@ -585,19 +585,19 @@ static int at91_usart_spi_probe(struct platform_device *pdev) return 0; -at91_usart_fail_register_master: +at91_usart_fail_register_controller: at91_usart_spi_release_dma(controller); at91_usart_fail_dma: clk_disable_unprepare(clk); at91_usart_spi_probe_fail: - spi_master_put(controller); + spi_controller_put(controller); return ret; } __maybe_unused static int at91_usart_spi_runtime_suspend(struct device *dev) { struct spi_controller *ctlr = dev_get_drvdata(dev); - struct at91_usart_spi *aus = spi_master_get_devdata(ctlr); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr); clk_disable_unprepare(aus->clk); pinctrl_pm_select_sleep_state(dev); @@ -608,7 +608,7 @@ __maybe_unused static int at91_usart_spi_runtime_suspend(struct device *dev) __maybe_unused static int at91_usart_spi_runtime_resume(struct device *dev) { struct spi_controller *ctrl = dev_get_drvdata(dev); - struct at91_usart_spi *aus = spi_master_get_devdata(ctrl); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctrl); pinctrl_pm_select_default_state(dev); @@ -633,7 +633,7 @@ __maybe_unused static int at91_usart_spi_suspend(struct device *dev) __maybe_unused static int at91_usart_spi_resume(struct device *dev) { struct spi_controller *ctrl = dev_get_drvdata(dev); - struct at91_usart_spi *aus = spi_master_get_devdata(ctrl); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctrl); int ret; if (!pm_runtime_suspended(dev)) { @@ -650,7 +650,7 @@ __maybe_unused static int at91_usart_spi_resume(struct device *dev) static int at91_usart_spi_remove(struct platform_device *pdev) { struct spi_controller *ctlr = platform_get_drvdata(pdev); - struct at91_usart_spi *aus = spi_master_get_devdata(ctlr); + struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr); at91_usart_spi_release_dma(ctlr); clk_disable_unprepare(aus->clk); From ccbc6554ed66dc37778b8ed823bcaaabfb1731cf Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 10 Jan 2023 21:18:05 +0800 Subject: [PATCH 21/65] spi: atmel-quadspi: switch to use modern name Change legacy name master to modern name host or controller. No functional changed. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20230110131805.2827248-4-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/spi/atmel-quadspi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c index 70637e46290a..f4632cb07495 100644 --- a/drivers/spi/atmel-quadspi.c +++ b/drivers/spi/atmel-quadspi.c @@ -406,7 +406,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) { - struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->master); + struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller); u32 sr, offset; int err; @@ -476,7 +476,7 @@ static const struct spi_controller_mem_ops atmel_qspi_mem_ops = { static int atmel_qspi_setup(struct spi_device *spi) { - struct spi_controller *ctrl = spi->master; + struct spi_controller *ctrl = spi->controller; struct atmel_qspi *aq = spi_controller_get_devdata(ctrl); unsigned long src_rate; u32 scbr; @@ -512,7 +512,7 @@ static int atmel_qspi_setup(struct spi_device *spi) static int atmel_qspi_set_cs_timing(struct spi_device *spi) { - struct spi_controller *ctrl = spi->master; + struct spi_controller *ctrl = spi->controller; struct atmel_qspi *aq = spi_controller_get_devdata(ctrl); unsigned long clk_rate; u32 cs_setup; @@ -582,7 +582,7 @@ static int atmel_qspi_probe(struct platform_device *pdev) struct resource *res; int irq, err = 0; - ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*aq)); + ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(*aq)); if (!ctrl) return -ENOMEM; From 025aea27732d3354b9bb797df8158a439f143bf4 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 20 Jan 2023 08:56:18 +0100 Subject: [PATCH 22/65] dt-bindings: trivial-devices: document SPI dev compatibles Document existing SPI dev compatibles. Cc: Mark Brown Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230120075618.153664-2-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/trivial-devices.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index b13f280f36fa..6d1dc1e2484a 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -65,6 +65,8 @@ properties: - capella,cm3232 # CM3323: Ambient Light Sensor - capella,cm3323 + # Cisco SPI Petra + - cisco,spi-petra # High-Precision Digital Thermometer - dallas,ds1631 # Total-Elapsed-Time Recorder with Alarm @@ -169,6 +171,8 @@ properties: - isil,isl29030 # Intersil ISL68137 Digital Output Configurable PWM Controller - isil,isl68137 + # Linear Technology LTC2488 + - lineartechnology,ltc2488 # 5 Bit Programmable, Pulse-Width Modulator - maxim,ds1050 # 10 kOhm digital potentiometer with I2C interface @@ -227,6 +231,8 @@ properties: - memsic,mxc6655 # Menlo on-board CPLD trivial SPI device - menlo,m53cpld + # Micron SPI NOR Authenta + - micron,spi-authenta # Microchip differential I2C ADC, 1 Channel, 18 bit - microchip,mcp3421 # Microchip differential I2C ADC, 2 Channel, 18 bit @@ -305,10 +311,14 @@ properties: - pulsedlight,lidar-lite-v2 # Renesas ISL29501 time-of-flight sensor - renesas,isl29501 + # Rohm DH2228FV + - rohm,dh2228fv # S524AD0XF1 (128K/256K-bit Serial EEPROM for Low Power) - samsung,24ad0xd1 # Samsung Exynos SoC SATA PHY I2C device - samsung,exynos-sataphy-i2c + # Semtech sx1301 baseband processor + - semtech,sx1301 # Sensirion low power multi-pixel gas sensor with I2C interface - sensirion,sgpc3 # Sensirion multi-pixel gas sensor with I2C interface From 99a7fa0e75a3a595a577fb5efa4b84a491f664a2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 24 Jan 2023 09:33:41 +0100 Subject: [PATCH 23/65] spi: dt-bindings: drop unneeded quotes Cleanup by removing unneeded quotes from refs and redundant blank lines. No functional impact except adjusting to preferred coding style. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Andrew Jeffery # aspeed Reviewed-by: Neil Armstrong # meson Reviewed-by: Patrice Chotard # st Reviewed-by: Heiko Stuebner # rockchip Reviewed-by: Serge Semin # synopsys Acked-by: Rob Herring Link: https://lore.kernel.org/r/20230124083342.34869-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- .../bindings/spi/allwinner,sun4i-a10-spi.yaml | 2 +- .../bindings/spi/allwinner,sun6i-a31-spi.yaml | 2 +- .../bindings/spi/amlogic,meson-gx-spicc.yaml | 6 +++--- .../bindings/spi/amlogic,meson6-spifc.yaml | 6 +++--- .../bindings/spi/aspeed,ast2600-fmc.yaml | 2 +- .../devicetree/bindings/spi/cdns,qspi-nor.yaml | 2 +- .../devicetree/bindings/spi/cdns,xspi.yaml | 6 +++--- .../bindings/spi/fsl,spi-fsl-qspi.yaml | 2 +- .../devicetree/bindings/spi/fsl-imx-cspi.yaml | 2 +- .../bindings/spi/mediatek,spi-mt65xx.yaml | 2 +- .../spi/mediatek,spi-slave-mt27xx.yaml | 2 +- .../bindings/spi/mikrotik,rb4xx-spi.yaml | 2 +- .../bindings/spi/mxicy,mx25f0a-spi.yaml | 2 +- .../devicetree/bindings/spi/mxs-spi.yaml | 2 +- .../bindings/spi/nvidia,tegra210-quad.yaml | 2 +- .../bindings/spi/qcom,spi-qcom-qspi.yaml | 5 ++--- .../bindings/spi/realtek,rtl-spi.yaml | 2 +- .../bindings/spi/snps,dw-apb-ssi.yaml | 2 +- .../devicetree/bindings/spi/spi-cadence.yaml | 2 +- .../devicetree/bindings/spi/spi-fsl-lpspi.yaml | 2 +- .../devicetree/bindings/spi/spi-gpio.yaml | 4 ++-- .../devicetree/bindings/spi/spi-mux.yaml | 4 ++-- .../devicetree/bindings/spi/spi-nxp-fspi.yaml | 2 +- .../devicetree/bindings/spi/spi-pl022.yaml | 18 +++++++++--------- .../devicetree/bindings/spi/spi-rockchip.yaml | 2 +- .../devicetree/bindings/spi/spi-sifive.yaml | 6 +++--- .../bindings/spi/spi-sunplus-sp7021.yaml | 2 +- .../devicetree/bindings/spi/spi-xilinx.yaml | 2 +- .../bindings/spi/spi-zynqmp-qspi.yaml | 2 +- .../devicetree/bindings/spi/sprd,spi-adi.yaml | 5 ++--- .../devicetree/bindings/spi/st,stm32-qspi.yaml | 2 +- .../devicetree/bindings/spi/st,stm32-spi.yaml | 2 +- .../bindings/spi/xlnx,zynq-qspi.yaml | 2 +- 33 files changed, 53 insertions(+), 55 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/allwinner,sun4i-a10-spi.yaml b/Documentation/devicetree/bindings/spi/allwinner,sun4i-a10-spi.yaml index f1176a28fd87..eb0567b2971a 100644 --- a/Documentation/devicetree/bindings/spi/allwinner,sun4i-a10-spi.yaml +++ b/Documentation/devicetree/bindings/spi/allwinner,sun4i-a10-spi.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Allwinner A10 SPI Controller allOf: - - $ref: "spi-controller.yaml" + - $ref: spi-controller.yaml maintainers: - Chen-Yu Tsai diff --git a/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml b/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml index 58b7056f4a70..acf218507d22 100644 --- a/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml +++ b/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Allwinner A31 SPI Controller allOf: - - $ref: "spi-controller.yaml" + - $ref: spi-controller.yaml maintainers: - Chen-Yu Tsai diff --git a/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml b/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml index 53eb6562b979..e5eca3a6f132 100644 --- a/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml +++ b/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml @@ -2,8 +2,8 @@ # Copyright 2019 BayLibre, SAS %YAML 1.2 --- -$id: "http://devicetree.org/schemas/spi/amlogic,meson-gx-spicc.yaml#" -$schema: "http://devicetree.org/meta-schemas/core.yaml#" +$id: http://devicetree.org/schemas/spi/amlogic,meson-gx-spicc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# title: Amlogic Meson SPI Communication Controller @@ -41,7 +41,7 @@ properties: maxItems: 2 allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml b/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml index ac3b2ec300ac..806043fed4d1 100644 --- a/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml +++ b/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml @@ -2,8 +2,8 @@ # Copyright 2019 BayLibre, SAS %YAML 1.2 --- -$id: "http://devicetree.org/schemas/spi/amlogic,meson6-spifc.yaml#" -$schema: "http://devicetree.org/meta-schemas/core.yaml#" +$id: http://devicetree.org/schemas/spi/amlogic,meson6-spifc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# title: Amlogic Meson SPI Flash Controller @@ -11,7 +11,7 @@ maintainers: - Neil Armstrong allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# description: | The Meson SPIFC is a controller optimized for communication with SPI diff --git a/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml b/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml index e6c817de3449..aae6fb139b5b 100644 --- a/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml +++ b/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml @@ -15,7 +15,7 @@ description: | SPI) of the AST2400, AST2500 and AST2600 SOCs. allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml index 4707294d8f59..9be4e2c5d1ee 100644 --- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml +++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml @@ -47,7 +47,7 @@ properties: cdns,fifo-depth: description: Size of the data FIFO in words. - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 enum: [ 128, 256 ] default: 128 diff --git a/Documentation/devicetree/bindings/spi/cdns,xspi.yaml b/Documentation/devicetree/bindings/spi/cdns,xspi.yaml index b8bb8a3dbf54..eb0f92468185 100644 --- a/Documentation/devicetree/bindings/spi/cdns,xspi.yaml +++ b/Documentation/devicetree/bindings/spi/cdns,xspi.yaml @@ -2,8 +2,8 @@ # Copyright 2020-21 Cadence %YAML 1.2 --- -$id: "http://devicetree.org/schemas/spi/cdns,xspi.yaml#" -$schema: "http://devicetree.org/meta-schemas/core.yaml#" +$id: http://devicetree.org/schemas/spi/cdns,xspi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# title: Cadence XSPI Controller @@ -16,7 +16,7 @@ description: | read/write access to slaves such as SPI-NOR flash. allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml b/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml index e58644558412..f2dd20370dbb 100644 --- a/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml @@ -10,7 +10,7 @@ maintainers: - Han Xu allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.yaml b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.yaml index 12cb76711000..2f593c7225e5 100644 --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.yaml +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.yaml @@ -10,7 +10,7 @@ maintainers: - Shawn Guo allOf: - - $ref: "/schemas/spi/spi-controller.yaml#" + - $ref: /schemas/spi/spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml index 8d2a6c084eab..b6249880c3f9 100644 --- a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml @@ -10,7 +10,7 @@ maintainers: - Leilk Liu allOf: - - $ref: "/schemas/spi/spi-controller.yaml#" + - $ref: /schemas/spi/spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml index 7977799a8ee1..d19c9f73978f 100644 --- a/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml @@ -10,7 +10,7 @@ maintainers: - Leilk Liu allOf: - - $ref: "/schemas/spi/spi-controller.yaml#" + - $ref: /schemas/spi/spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/mikrotik,rb4xx-spi.yaml b/Documentation/devicetree/bindings/spi/mikrotik,rb4xx-spi.yaml index 3fd0a8adfe9a..303f6dca89c0 100644 --- a/Documentation/devicetree/bindings/spi/mikrotik,rb4xx-spi.yaml +++ b/Documentation/devicetree/bindings/spi/mikrotik,rb4xx-spi.yaml @@ -11,7 +11,7 @@ maintainers: - Bert Vermeulen allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml b/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml index a3aa5e07c0e4..221fe6e2ef53 100644 --- a/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml +++ b/Documentation/devicetree/bindings/spi/mxicy,mx25f0a-spi.yaml @@ -10,7 +10,7 @@ maintainers: - Miquel Raynal allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/mxs-spi.yaml b/Documentation/devicetree/bindings/spi/mxs-spi.yaml index 51f8c664323e..e2512166c1cd 100644 --- a/Documentation/devicetree/bindings/spi/mxs-spi.yaml +++ b/Documentation/devicetree/bindings/spi/mxs-spi.yaml @@ -10,7 +10,7 @@ maintainers: - Marek Vasut allOf: - - $ref: "/schemas/spi/spi-controller.yaml#" + - $ref: /schemas/spi/spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml index 899100e783c9..9f78b2c06494 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml @@ -11,7 +11,7 @@ maintainers: - Jonathan Hunter allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml index b622bb7363ec..85e7770703bd 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml @@ -1,9 +1,8 @@ # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) - %YAML 1.2 --- -$id: "http://devicetree.org/schemas/spi/qcom,spi-qcom-qspi.yaml#" -$schema: "http://devicetree.org/meta-schemas/core.yaml#" +$id: http://devicetree.org/schemas/spi/qcom,spi-qcom-qspi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Quad Serial Peripheral Interface (QSPI) diff --git a/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml b/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml index 2f938c293f70..70330d945a70 100644 --- a/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml +++ b/Documentation/devicetree/bindings/spi/realtek,rtl-spi.yaml @@ -11,7 +11,7 @@ maintainers: - Birger Koblitz allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml index d33b72fabc5d..a132b5fc56e0 100644 --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml @@ -10,7 +10,7 @@ maintainers: - Mark Brown allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/spi-cadence.yaml b/Documentation/devicetree/bindings/spi/spi-cadence.yaml index 64bf4e621142..b0f83b5c2cdd 100644 --- a/Documentation/devicetree/bindings/spi/spi-cadence.yaml +++ b/Documentation/devicetree/bindings/spi/spi-cadence.yaml @@ -10,7 +10,7 @@ maintainers: - Michal Simek allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml index 94caa2b7e241..e91425012319 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml +++ b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml @@ -10,7 +10,7 @@ maintainers: - Anson Huang allOf: - - $ref: "/schemas/spi/spi-controller.yaml#" + - $ref: /schemas/spi/spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/spi-gpio.yaml b/Documentation/devicetree/bindings/spi/spi-gpio.yaml index f29b89076c99..9ce1df93d4c3 100644 --- a/Documentation/devicetree/bindings/spi/spi-gpio.yaml +++ b/Documentation/devicetree/bindings/spi/spi-gpio.yaml @@ -14,7 +14,7 @@ description: dedicated GPIO lines. allOf: - - $ref: "/schemas/spi/spi-controller.yaml#" + - $ref: /schemas/spi/spi-controller.yaml# properties: compatible: @@ -41,7 +41,7 @@ properties: num-chipselects: description: Number of chipselect lines. Should be <0> if a single device with no chip select is connected. - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 # Deprecated properties gpio-sck: false diff --git a/Documentation/devicetree/bindings/spi/spi-mux.yaml b/Documentation/devicetree/bindings/spi/spi-mux.yaml index 7ea79f6d33f3..fb2a6039928c 100644 --- a/Documentation/devicetree/bindings/spi/spi-mux.yaml +++ b/Documentation/devicetree/bindings/spi/spi-mux.yaml @@ -30,8 +30,8 @@ description: | +------------+ allOf: - - $ref: "/schemas/spi/spi-controller.yaml#" - - $ref: "/schemas/spi/spi-peripheral-props.yaml#" + - $ref: /schemas/spi/spi-controller.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# maintainers: - Chris Packham diff --git a/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml b/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml index 1b552c298277..a813c971ecf6 100644 --- a/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml +++ b/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml @@ -11,7 +11,7 @@ maintainers: - Kuldeep Singh allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/spi-pl022.yaml b/Documentation/devicetree/bindings/spi/spi-pl022.yaml index 0e382119c64f..91e540a92faf 100644 --- a/Documentation/devicetree/bindings/spi/spi-pl022.yaml +++ b/Documentation/devicetree/bindings/spi/spi-pl022.yaml @@ -10,7 +10,7 @@ maintainers: - Linus Walleij allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# # We need a select here so we don't match all nodes with 'arm,primecell' select: @@ -45,7 +45,7 @@ properties: description: delay in ms following transfer completion before the runtime power management system suspends the device. A setting of 0 indicates no delay and the device will be suspended immediately. - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 pl022,rt: description: indicates the controller should run the message pump with realtime @@ -81,7 +81,7 @@ patternProperties: properties: pl022,interface: description: SPI interface type - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 enum: - 0 # SPI - 1 # Texas Instruments Synchronous Serial Frame Format @@ -89,7 +89,7 @@ patternProperties: pl022,com-mode: description: Specifies the transfer mode - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 enum: - 0 # interrupt mode - 1 # polling mode @@ -98,30 +98,30 @@ patternProperties: pl022,rx-level-trig: description: Rx FIFO watermark level - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0 maximum: 4 pl022,tx-level-trig: description: Tx FIFO watermark level - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0 maximum: 4 pl022,ctrl-len: description: Microwire interface - Control length - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0x03 maximum: 0x1f pl022,wait-state: description: Microwire interface - Wait state - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 1] pl022,duplex: description: Microwire interface - Full/Half duplex - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 1] required: diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.yaml b/Documentation/devicetree/bindings/spi/spi-rockchip.yaml index 66e49947b703..e4941e9212d1 100644 --- a/Documentation/devicetree/bindings/spi/spi-rockchip.yaml +++ b/Documentation/devicetree/bindings/spi/spi-rockchip.yaml @@ -11,7 +11,7 @@ description: as flash and display controllers using the SPI communication interface. allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# maintainers: - Heiko Stuebner diff --git a/Documentation/devicetree/bindings/spi/spi-sifive.yaml b/Documentation/devicetree/bindings/spi/spi-sifive.yaml index 6e7e394fc1e4..5bffefb9c7eb 100644 --- a/Documentation/devicetree/bindings/spi/spi-sifive.yaml +++ b/Documentation/devicetree/bindings/spi/spi-sifive.yaml @@ -12,7 +12,7 @@ maintainers: - Palmer Dabbelt allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: @@ -51,14 +51,14 @@ properties: sifive,fifo-depth: description: Depth of hardware queues; defaults to 8 - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 enum: [8] default: 8 sifive,max-bits-per-word: description: Maximum bits per word; defaults to 8 - $ref: "/schemas/types.yaml#/definitions/uint32" + $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 1, 2, 3, 4, 5, 6, 7, 8] default: 8 diff --git a/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml b/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml index 3a58cf0f1ec8..69a463305274 100644 --- a/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml +++ b/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Sunplus sp7021 SPI controller allOf: - - $ref: "spi-controller.yaml" + - $ref: spi-controller.yaml maintainers: - Li-hao Kuo diff --git a/Documentation/devicetree/bindings/spi/spi-xilinx.yaml b/Documentation/devicetree/bindings/spi/spi-xilinx.yaml index bbb735603f29..6bd83836eded 100644 --- a/Documentation/devicetree/bindings/spi/spi-xilinx.yaml +++ b/Documentation/devicetree/bindings/spi/spi-xilinx.yaml @@ -10,7 +10,7 @@ maintainers: - Michal Simek allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/spi-zynqmp-qspi.yaml b/Documentation/devicetree/bindings/spi/spi-zynqmp-qspi.yaml index 546c416cdb55..20f77246d365 100644 --- a/Documentation/devicetree/bindings/spi/spi-zynqmp-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/spi-zynqmp-qspi.yaml @@ -10,7 +10,7 @@ maintainers: - Michal Simek allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml b/Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml index a3ab1a1f1eb4..903b06f88b1b 100644 --- a/Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml +++ b/Documentation/devicetree/bindings/spi/sprd,spi-adi.yaml @@ -1,9 +1,8 @@ # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) - %YAML 1.2 --- -$id: "http://devicetree.org/schemas/spi/sprd,spi-adi.yaml#" -$schema: "http://devicetree.org/meta-schemas/core.yaml#" +$id: http://devicetree.org/schemas/spi/sprd,spi-adi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# title: Spreadtrum ADI controller diff --git a/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml b/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml index 1eb17f7a4d86..8bba965a9ae6 100644 --- a/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml @@ -11,7 +11,7 @@ maintainers: - Patrice Chotard allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/st,stm32-spi.yaml b/Documentation/devicetree/bindings/spi/st,stm32-spi.yaml index 1cda15f91cc3..d35c6f7e2dd5 100644 --- a/Documentation/devicetree/bindings/spi/st,stm32-spi.yaml +++ b/Documentation/devicetree/bindings/spi/st,stm32-spi.yaml @@ -17,7 +17,7 @@ maintainers: - Fabrice Gasnier allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/spi/xlnx,zynq-qspi.yaml b/Documentation/devicetree/bindings/spi/xlnx,zynq-qspi.yaml index 1f1c40a9f320..83e8fb4a548d 100644 --- a/Documentation/devicetree/bindings/spi/xlnx,zynq-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/xlnx,zynq-qspi.yaml @@ -11,7 +11,7 @@ description: memory devices. allOf: - - $ref: "spi-controller.yaml#" + - $ref: spi-controller.yaml# maintainers: - Michal Simek From ee8d422c91d87ebe230769b2cb89f087e56b560a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 24 Jan 2023 09:33:42 +0100 Subject: [PATCH 24/65] spi: dt-bindings: cleanup examples - indentation, lowercase hex Cleanup examples: - use 4-space indentation (for cases when it is neither 4 not 2 space), - drop redundant blank lines, - use lowercase hex. No functional impact except adjusting to preferred coding style. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Geert Uytterhoeven # renesas Reviewed-by: Andrew Jeffery # aspeed Reviewed-by: Neil Armstrong # meson Link: https://lore.kernel.org/r/20230124083342.34869-2-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- .../bindings/spi/amlogic,meson-gx-spicc.yaml | 24 +-- .../bindings/spi/amlogic,meson6-spifc.yaml | 20 +-- .../bindings/spi/aspeed,ast2600-fmc.yaml | 24 +-- .../bindings/spi/brcm,spi-bcm-qspi.yaml | 154 +++++++++--------- .../bindings/spi/cdns,qspi-nor.yaml | 32 ++-- .../bindings/spi/nvidia,tegra210-quad.yaml | 40 ++--- .../bindings/spi/qcom,spi-qcom-qspi.yaml | 1 - .../devicetree/bindings/spi/renesas,rspi.yaml | 22 +-- .../bindings/spi/spi-sunplus-sp7021.yaml | 4 +- .../devicetree/bindings/spi/st,stm32-spi.yaml | 23 ++- 10 files changed, 171 insertions(+), 173 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml b/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml index e5eca3a6f132..4e28e6e9d8e0 100644 --- a/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml +++ b/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml @@ -100,17 +100,17 @@ unevaluatedProperties: false examples: - | spi@c1108d80 { - compatible = "amlogic,meson-gx-spicc"; - reg = <0xc1108d80 0x80>; - interrupts = <112>; - clocks = <&clk81>; - clock-names = "core"; - #address-cells = <1>; - #size-cells = <0>; + compatible = "amlogic,meson-gx-spicc"; + reg = <0xc1108d80 0x80>; + interrupts = <112>; + clocks = <&clk81>; + clock-names = "core"; + #address-cells = <1>; + #size-cells = <0>; - display@0 { - compatible = "lg,lg4573"; - spi-max-frequency = <1000000>; - reg = <0>; - }; + display@0 { + compatible = "lg,lg4573"; + spi-max-frequency = <1000000>; + reg = <0>; + }; }; diff --git a/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml b/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml index 806043fed4d1..8e769ccda97f 100644 --- a/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml +++ b/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml @@ -40,15 +40,15 @@ unevaluatedProperties: false examples: - | spi@c1108c80 { - compatible = "amlogic,meson6-spifc"; - reg = <0xc1108c80 0x80>; - clocks = <&clk81>; - #address-cells = <1>; - #size-cells = <0>; + compatible = "amlogic,meson6-spifc"; + reg = <0xc1108c80 0x80>; + clocks = <&clk81>; + #address-cells = <1>; + #size-cells = <0>; - flash: flash@0 { - compatible = "spansion,m25p80", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <40000000>; - }; + flash: flash@0 { + compatible = "spansion,m25p80", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + }; }; diff --git a/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml b/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml index aae6fb139b5b..57d932af4506 100644 --- a/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml +++ b/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml @@ -60,23 +60,23 @@ examples: interrupts = ; flash@0 { - reg = < 0 >; - compatible = "jedec,spi-nor"; - spi-max-frequency = <50000000>; - spi-rx-bus-width = <2>; + reg = < 0 >; + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + spi-rx-bus-width = <2>; }; flash@1 { - reg = < 1 >; - compatible = "jedec,spi-nor"; - spi-max-frequency = <50000000>; - spi-rx-bus-width = <2>; + reg = < 1 >; + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + spi-rx-bus-width = <2>; }; flash@2 { - reg = < 2 >; - compatible = "jedec,spi-nor"; - spi-max-frequency = <50000000>; - spi-rx-bus-width = <2>; + reg = < 2 >; + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + spi-rx-bus-width = <2>; }; }; diff --git a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.yaml b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.yaml index ec5873919170..28222aae3077 100644 --- a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.yaml @@ -99,98 +99,98 @@ required: examples: - | # BRCMSTB SoC: SPI Master (MSPI+BSPI) for SPI-NOR access spi@f03e3400 { - compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-bcm-qspi"; - reg = <0xf03e3400 0x188>, <0xf03e3200 0x50>, <0xf03e0920 0x4>; - reg-names = "mspi", "bspi", "cs_reg"; - interrupts = <0x5>, <0x6>, <0x1>, <0x2>, <0x3>, <0x4>, <0x0>; - interrupt-parent = <&gic>; - interrupt-names = "mspi_done", - "mspi_halted", - "spi_lr_fullness_reached", - "spi_lr_session_aborted", - "spi_lr_impatient", - "spi_lr_session_done", - "spi_lr_overread"; - clocks = <&hif_spi>; - #address-cells = <0x1>; - #size-cells = <0x0>; + compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-bcm-qspi"; + reg = <0xf03e3400 0x188>, <0xf03e3200 0x50>, <0xf03e0920 0x4>; + reg-names = "mspi", "bspi", "cs_reg"; + interrupts = <0x5>, <0x6>, <0x1>, <0x2>, <0x3>, <0x4>, <0x0>; + interrupt-parent = <&gic>; + interrupt-names = "mspi_done", + "mspi_halted", + "spi_lr_fullness_reached", + "spi_lr_session_aborted", + "spi_lr_impatient", + "spi_lr_session_done", + "spi_lr_overread"; + clocks = <&hif_spi>; + #address-cells = <0x1>; + #size-cells = <0x0>; - flash@0 { - #size-cells = <0x2>; - #address-cells = <0x2>; - compatible = "m25p80"; - reg = <0x0>; - spi-max-frequency = <0x2625a00>; - spi-cpol; - spi-cpha; - }; + flash@0 { + #size-cells = <0x2>; + #address-cells = <0x2>; + compatible = "m25p80"; + reg = <0x0>; + spi-max-frequency = <0x2625a00>; + spi-cpol; + spi-cpha; + }; }; - | # BRCMSTB SoC: MSPI master for any SPI device spi@f0416000 { - clocks = <&upg_fixed>; - compatible = "brcm,spi-brcmstb-mspi", "brcm,spi-bcm-qspi"; - reg = <0xf0416000 0x180>; - reg-names = "mspi"; - interrupts = <0x14>; - interrupt-parent = <&irq0_aon_intc>; - interrupt-names = "mspi_done"; - #address-cells = <1>; - #size-cells = <0>; + clocks = <&upg_fixed>; + compatible = "brcm,spi-brcmstb-mspi", "brcm,spi-bcm-qspi"; + reg = <0xf0416000 0x180>; + reg-names = "mspi"; + interrupts = <0x14>; + interrupt-parent = <&irq0_aon_intc>; + interrupt-names = "mspi_done"; + #address-cells = <1>; + #size-cells = <0>; }; - | # iProc SoC #include #include spi@18027200 { - compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi"; - reg = <0x18027200 0x184>, - <0x18027000 0x124>, - <0x1811c408 0x004>, - <0x180273a0 0x01c>; - reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg"; - interrupts = , - , - , - , - , - , - ; - interrupt-names = "mspi_done", - "mspi_halted", - "spi_lr_fullness_reached", - "spi_lr_session_aborted", - "spi_lr_impatient", - "spi_lr_session_done"; - clocks = <&iprocmed>; - num-cs = <2>; - #address-cells = <1>; - #size-cells = <0>; + compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi"; + reg = <0x18027200 0x184>, + <0x18027000 0x124>, + <0x1811c408 0x004>, + <0x180273a0 0x01c>; + reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg"; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "mspi_done", + "mspi_halted", + "spi_lr_fullness_reached", + "spi_lr_session_aborted", + "spi_lr_impatient", + "spi_lr_session_done"; + clocks = <&iprocmed>; + num-cs = <2>; + #address-cells = <1>; + #size-cells = <0>; }; - | # NS2 SoC #include #include spi@66470200 { - compatible = "brcm,spi-ns2-qspi", "brcm,spi-bcm-qspi"; - reg = <0x66470200 0x184>, - <0x66470000 0x124>, - <0x67017408 0x004>, - <0x664703a0 0x01c>; - reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg"; - interrupts = ; - interrupt-names = "spi_l1_intr"; - clocks = <&iprocmed>; - num-cs = <2>; - #address-cells = <1>; - #size-cells = <0>; + compatible = "brcm,spi-ns2-qspi", "brcm,spi-bcm-qspi"; + reg = <0x66470200 0x184>, + <0x66470000 0x124>, + <0x67017408 0x004>, + <0x664703a0 0x01c>; + reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg"; + interrupts = ; + interrupt-names = "spi_l1_intr"; + clocks = <&iprocmed>; + num-cs = <2>; + #address-cells = <1>; + #size-cells = <0>; - flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "m25p80"; - reg = <0x0>; - spi-max-frequency = <12500000>; - spi-cpol; - spi-cpha; - }; + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80"; + reg = <0x0>; + spi-max-frequency = <12500000>; + spi-cpol; + spi-cpha; + }; }; diff --git a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml index 9be4e2c5d1ee..5c01db128be0 100644 --- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml +++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml @@ -103,21 +103,21 @@ unevaluatedProperties: false examples: - | qspi: spi@ff705000 { - compatible = "cdns,qspi-nor"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0xff705000 0x1000>, - <0xffa00000 0x1000>; - interrupts = <0 151 4>; - clocks = <&qspi_clk>; - cdns,fifo-depth = <128>; - cdns,fifo-width = <4>; - cdns,trigger-address = <0x00000000>; - resets = <&rst 0x1>, <&rst 0x2>; - reset-names = "qspi", "qspi-ocp"; + compatible = "cdns,qspi-nor"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xff705000 0x1000>, + <0xffa00000 0x1000>; + interrupts = <0 151 4>; + clocks = <&qspi_clk>; + cdns,fifo-depth = <128>; + cdns,fifo-width = <4>; + cdns,trigger-address = <0x00000000>; + resets = <&rst 0x1>, <&rst 0x2>; + reset-names = "qspi", "qspi-ocp"; - flash@0 { - compatible = "jedec,spi-nor"; - reg = <0x0>; - }; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + }; }; diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml index 9f78b2c06494..9ae1611175f2 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml @@ -74,25 +74,25 @@ examples: #include #include spi@70410000 { - compatible = "nvidia,tegra210-qspi"; - reg = <0x70410000 0x1000>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&tegra_car TEGRA210_CLK_QSPI>, - <&tegra_car TEGRA210_CLK_QSPI_PM>; - clock-names = "qspi", "qspi_out"; - resets = <&tegra_car 211>; - dmas = <&apbdma 5>, <&apbdma 5>; - dma-names = "rx", "tx"; + compatible = "nvidia,tegra210-qspi"; + reg = <0x70410000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA210_CLK_QSPI>, + <&tegra_car TEGRA210_CLK_QSPI_PM>; + clock-names = "qspi", "qspi_out"; + resets = <&tegra_car 211>; + dmas = <&apbdma 5>, <&apbdma 5>; + dma-names = "rx", "tx"; - flash@0 { - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <104000000>; - spi-tx-bus-width = <2>; - spi-rx-bus-width = <2>; - nvidia,tx-clk-tap-delay = <0>; - nvidia,rx-clk-tap-delay = <0>; - }; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + nvidia,tx-clk-tap-delay = <0>; + nvidia,rx-clk-tap-delay = <0>; + }; }; diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml index 85e7770703bd..e94d915e28c8 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml @@ -87,7 +87,6 @@ examples: spi-tx-bus-width = <2>; spi-rx-bus-width = <2>; }; - }; }; ... diff --git a/Documentation/devicetree/bindings/spi/renesas,rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml index f45d3b75d6de..4d8ec69214c9 100644 --- a/Documentation/devicetree/bindings/spi/renesas,rspi.yaml +++ b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml @@ -141,15 +141,15 @@ examples: #include qspi: spi@e6b10000 { - compatible = "renesas,qspi-r8a7791", "renesas,qspi"; - reg = <0xe6b10000 0x2c>; - interrupts = ; - clocks = <&cpg CPG_MOD 917>; - dmas = <&dmac0 0x17>, <&dmac0 0x18>, <&dmac1 0x17>, <&dmac1 0x18>; - dma-names = "tx", "rx", "tx", "rx"; - power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; - resets = <&cpg 917>; - num-cs = <1>; - #address-cells = <1>; - #size-cells = <0>; + compatible = "renesas,qspi-r8a7791", "renesas,qspi"; + reg = <0xe6b10000 0x2c>; + interrupts = ; + clocks = <&cpg CPG_MOD 917>; + dmas = <&dmac0 0x17>, <&dmac0 0x18>, <&dmac1 0x17>, <&dmac1 0x18>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; + resets = <&cpg 917>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml b/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml index 69a463305274..edb5ba71af3a 100644 --- a/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml +++ b/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml @@ -59,9 +59,9 @@ unevaluatedProperties: false examples: - | #include - spi@9C002D80 { + spi@9c002d80 { compatible = "sunplus,sp7021-spi"; - reg = <0x9C002D80 0x80>, <0x9C002E00 0x80>; + reg = <0x9c002d80 0x80>, <0x9c002e00 0x80>; reg-names = "master", "slave"; interrupt-parent = <&intc>; interrupt-names = "dma_w", diff --git a/Documentation/devicetree/bindings/spi/st,stm32-spi.yaml b/Documentation/devicetree/bindings/spi/st,stm32-spi.yaml index d35c6f7e2dd5..9ca1a843c820 100644 --- a/Documentation/devicetree/bindings/spi/st,stm32-spi.yaml +++ b/Documentation/devicetree/bindings/spi/st,stm32-spi.yaml @@ -84,18 +84,17 @@ examples: #include #include spi@4000b000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "st,stm32h7-spi"; - reg = <0x4000b000 0x400>; - interrupts = ; - clocks = <&rcc SPI2_K>; - resets = <&rcc SPI2_R>; - dmas = <&dmamux1 0 39 0x400 0x05>, - <&dmamux1 1 40 0x400 0x05>; - dma-names = "rx", "tx"; - cs-gpios = <&gpioa 11 0>; - + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32h7-spi"; + reg = <0x4000b000 0x400>; + interrupts = ; + clocks = <&rcc SPI2_K>; + resets = <&rcc SPI2_R>; + dmas = <&dmamux1 0 39 0x400 0x05>, + <&dmamux1 1 40 0x400 0x05>; + dma-names = "rx", "tx"; + cs-gpios = <&gpioa 11 0>; }; ... From 22913a63b477c5f167012d4f1265d023a102c1fe Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 24 Jan 2023 15:35:02 -0800 Subject: [PATCH 25/65] spi: Kconfig: fix a spelling mistake & hyphenation Correct a spelling mistake (reported by codespell). Also hyphenate "8-bit". Signed-off-by: Randy Dunlap Cc: Mark Brown Cc: linux-spi@vger.kernel.org Link: https://lore.kernel.org/r/20230124233502.23330-1-rdunlap@infradead.org Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 3b1c0878bb85..df96a6c2e633 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -247,7 +247,7 @@ config SPI_CADENCE_XSPI Enable support for the Cadence XSPI Flash controller. Cadence XSPI is a specialized controller for connecting an SPI - Flash over upto 8bit wide bus. Enable this option if you have a + Flash over up to 8-bit wide bus. Enable this option if you have a device with a Cadence XSPI controller and want to access the Flash as an MTD device. From 0f6d2cee58f1ff2ebf66f0bceb113d79f66ecb07 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 26 Jan 2023 22:39:57 -0800 Subject: [PATCH 26/65] spi: correct spelling Correct spelling problems for Documentation/spi/ as reported by codespell. Signed-off-by: Randy Dunlap Link: https://lore.kernel.org/r/20230127064005.1558-28-rdunlap@infradead.org Signed-off-by: Mark Brown --- Documentation/spi/pxa2xx.rst | 12 ++++++------ Documentation/spi/spi-lm70llp.rst | 2 +- Documentation/spi/spi-summary.rst | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Documentation/spi/pxa2xx.rst b/Documentation/spi/pxa2xx.rst index 716f65d87d04..04f2a3856c40 100644 --- a/Documentation/spi/pxa2xx.rst +++ b/Documentation/spi/pxa2xx.rst @@ -141,15 +141,15 @@ field. Below is a sample configuration using the PXA255 NSSP. :: static struct pxa2xx_spi_chip cs8415a_chip_info = { - .tx_threshold = 8, /* SSP hardward FIFO threshold */ - .rx_threshold = 8, /* SSP hardward FIFO threshold */ + .tx_threshold = 8, /* SSP hardware FIFO threshold */ + .rx_threshold = 8, /* SSP hardware FIFO threshold */ .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */ .timeout = 235, /* See Intel documentation */ }; static struct pxa2xx_spi_chip cs8405a_chip_info = { - .tx_threshold = 8, /* SSP hardward FIFO threshold */ - .rx_threshold = 8, /* SSP hardward FIFO threshold */ + .tx_threshold = 8, /* SSP hardware FIFO threshold */ + .rx_threshold = 8, /* SSP hardware FIFO threshold */ .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */ .timeout = 235, /* See Intel documentation */ }; @@ -157,7 +157,7 @@ field. Below is a sample configuration using the PXA255 NSSP. static struct spi_board_info streetracer_spi_board_info[] __initdata = { { .modalias = "cs8415a", /* Name of spi_driver for this device */ - .max_speed_hz = 3686400, /* Run SSP as fast a possbile */ + .max_speed_hz = 3686400, /* Run SSP as fast a possible */ .bus_num = 2, /* Framework bus number */ .chip_select = 0, /* Framework chip select */ .platform_data = NULL; /* No spi_driver specific config */ @@ -166,7 +166,7 @@ field. Below is a sample configuration using the PXA255 NSSP. }, { .modalias = "cs8405a", /* Name of spi_driver for this device */ - .max_speed_hz = 3686400, /* Run SSP as fast a possbile */ + .max_speed_hz = 3686400, /* Run SSP as fast a possible */ .bus_num = 2, /* Framework bus number */ .chip_select = 1, /* Framework chip select */ .controller_data = &cs8405a_chip_info, /* Master chip config */ diff --git a/Documentation/spi/spi-lm70llp.rst b/Documentation/spi/spi-lm70llp.rst index 07631aef4343..0144e12d95bb 100644 --- a/Documentation/spi/spi-lm70llp.rst +++ b/Documentation/spi/spi-lm70llp.rst @@ -57,7 +57,7 @@ devices might share the same SI/SO pin. The bitbanger routine in this driver (lm70_txrx) is called back from the bound "hwmon/lm70" protocol driver through its sysfs hook, using a spi_write_then_read() call. It performs Mode 0 (SPI/Microwire) bitbanging. -The lm70 driver then inteprets the resulting digital temperature value +The lm70 driver then interprets the resulting digital temperature value and exports it through sysfs. A "gotcha": National Semiconductor's LM70 LLP eval board circuit schematic diff --git a/Documentation/spi/spi-summary.rst b/Documentation/spi/spi-summary.rst index aab5d07cb3d7..3c95ae322fb1 100644 --- a/Documentation/spi/spi-summary.rst +++ b/Documentation/spi/spi-summary.rst @@ -105,7 +105,7 @@ find isn't necessarily helpful. The four modes combine two mode bits: - CPHA indicates the clock phase used to sample data; CPHA=0 says sample on the leading edge, CPHA=1 means the trailing edge. - Since the signal needs to stablize before it's sampled, CPHA=0 + Since the signal needs to stabilize before it's sampled, CPHA=0 implies that its data is written half a clock before the first clock edge. The chipselect may have made it become available. From d4bde04318c0d33705e9a77d4c7df72f262011e0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 30 Jan 2023 15:01:40 +0100 Subject: [PATCH 27/65] spi: dw_bt1: fix MUX_MMIO dependencies Selecting a symbol with additional dependencies requires adding the same dependency here: WARNING: unmet direct dependencies detected for MUX_MMIO Depends on [n]: MULTIPLEXER [=y] && OF [=n] Selected by [y]: - SPI_DW_BT1 [=y] && SPI [=y] && SPI_MASTER [=y] && SPI_DESIGNWARE [=y] && (MIPS_BAIKAL_T1 || COMPILE_TEST [=y]) Drop the 'select' here to avoid the problem. Anyone using the dw-bt1 SPI driver should make sure they include the mux driver as well now. Fixes: 7218838109fe ("spi: dw-bt1: Fix undefined devm_mux_control_get symbol") Fixes: abf00907538e ("spi: dw: Add Baikal-T1 SPI Controller glue driver") Link: https://lore.kernel.org/all/20221218192523.c6vnfo26ua6xqf26@mobilestation/ Signed-off-by: Arnd Bergmann Reviewed-by: Serge Semin Link: https://lore.kernel.org/r/20230130140156.3620863-1-arnd@kernel.org Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index df96a6c2e633..87fc2bd16b72 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -295,7 +295,6 @@ config SPI_DW_BT1 tristate "Baikal-T1 SPI driver for DW SPI core" depends on MIPS_BAIKAL_T1 || COMPILE_TEST select MULTIPLEXER - select MUX_MMIO help Baikal-T1 SoC is equipped with three DW APB SSI-based MMIO SPI controllers. Two of them are pretty much normal: with IRQ, DMA, From 303feb3cc06ac0665d0ee9c1414941200e60e8a3 Mon Sep 17 00:00:00 2001 From: Amit Kumar Mahapatra Date: Fri, 20 Jan 2023 00:23:30 +0530 Subject: [PATCH 28/65] spi: Add APIs in spi core to set/get spi->chip_select and spi->cs_gpiod Supporting multi-cs in spi core and spi controller drivers would require the chip_select & cs_gpiod members of struct spi_device to be an array. But changing the type of these members to array would break the spi driver functionality. To make the transition smoother introduced four new APIs to get/set the spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and spi->cs_gpiod references in spi core with the API calls. While adding multi-cs support in further patches the chip_select & cs_gpiod members of the spi_device structure would be converted to arrays & the "idx" parameter of the APIs would be used as array index i.e., spi->chip_select[idx] & spi->cs_gpiod[idx] respectively. Suggested-by: Lars-Peter Clausen Signed-off-by: Amit Kumar Mahapatra Reviewed-by: Michal Simek Link: https://lore.kernel.org/r/20230119185342.2093323-2-amit.kumar-mahapatra@amd.com Signed-off-by: Mark Brown --- drivers/spi/spi.c | 45 ++++++++++++++++++++--------------------- include/linux/spi/spi.h | 20 ++++++++++++++++++ 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 3cc7bb4d03de..38421e831a7d 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -604,7 +604,7 @@ static void spi_dev_set_name(struct spi_device *spi) } dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->controller->dev), - spi->chip_select); + spi_get_chipselect(spi, 0)); } static int spi_dev_check(struct device *dev, void *data) @@ -613,7 +613,7 @@ static int spi_dev_check(struct device *dev, void *data) struct spi_device *new_spi = data; if (spi->controller == new_spi->controller && - spi->chip_select == new_spi->chip_select) + spi_get_chipselect(spi, 0) == spi_get_chipselect(new_spi, 0)) return -EBUSY; return 0; } @@ -638,7 +638,7 @@ static int __spi_add_device(struct spi_device *spi) status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check); if (status) { dev_err(dev, "chipselect %d already in use\n", - spi->chip_select); + spi_get_chipselect(spi, 0)); return status; } @@ -649,7 +649,7 @@ static int __spi_add_device(struct spi_device *spi) } if (ctlr->cs_gpiods) - spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select]; + spi_set_csgpiod(spi, 0, ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]); /* * Drivers may modify this initial i/o setup, but will @@ -692,8 +692,8 @@ int spi_add_device(struct spi_device *spi) int status; /* Chipselects are numbered 0..max; validate. */ - if (spi->chip_select >= ctlr->num_chipselect) { - dev_err(dev, "cs%d >= max %d\n", spi->chip_select, + if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) { + dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0), ctlr->num_chipselect); return -EINVAL; } @@ -714,8 +714,8 @@ static int spi_add_device_locked(struct spi_device *spi) struct device *dev = ctlr->dev.parent; /* Chipselects are numbered 0..max; validate. */ - if (spi->chip_select >= ctlr->num_chipselect) { - dev_err(dev, "cs%d >= max %d\n", spi->chip_select, + if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) { + dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0), ctlr->num_chipselect); return -EINVAL; } @@ -761,7 +761,7 @@ struct spi_device *spi_new_device(struct spi_controller *ctlr, WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias)); - proxy->chip_select = chip->chip_select; + spi_set_chipselect(proxy, 0, chip->chip_select); proxy->max_speed_hz = chip->max_speed_hz; proxy->mode = chip->mode; proxy->irq = chip->irq; @@ -970,24 +970,23 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) * Avoid calling into the driver (or doing delays) if the chip select * isn't actually changing from the last time this was called. */ - if (!force && ((enable && spi->controller->last_cs == spi->chip_select) || - (!enable && spi->controller->last_cs != spi->chip_select)) && + if (!force && ((enable && spi->controller->last_cs == spi_get_chipselect(spi, 0)) || + (!enable && spi->controller->last_cs != spi_get_chipselect(spi, 0))) && (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH))) return; trace_spi_set_cs(spi, activate); - spi->controller->last_cs = enable ? spi->chip_select : -1; + spi->controller->last_cs = enable ? spi_get_chipselect(spi, 0) : -1; spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH; - if ((spi->cs_gpiod || !spi->controller->set_cs_timing) && !activate) { + if ((spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) && !activate) spi_delay_exec(&spi->cs_hold, NULL); - } if (spi->mode & SPI_CS_HIGH) enable = !enable; - if (spi->cs_gpiod) { + if (spi_get_csgpiod(spi, 0)) { if (!(spi->mode & SPI_NO_CS)) { /* * Historically ACPI has no means of the GPIO polarity and @@ -1000,10 +999,10 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) * into account. */ if (has_acpi_companion(&spi->dev)) - gpiod_set_value_cansleep(spi->cs_gpiod, !enable); + gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), !enable); else /* Polarity handled by GPIO library */ - gpiod_set_value_cansleep(spi->cs_gpiod, activate); + gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), activate); } /* Some SPI masters need both GPIO CS & slave_select */ if ((spi->controller->flags & SPI_MASTER_GPIO_SS) && @@ -1013,7 +1012,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) spi->controller->set_cs(spi, !enable); } - if (spi->cs_gpiod || !spi->controller->set_cs_timing) { + if (spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) { if (activate) spi_delay_exec(&spi->cs_setup, NULL); else @@ -2304,7 +2303,7 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, nc, rc); return rc; } - spi->chip_select = value; + spi_set_chipselect(spi, 0, value); /* Device speed */ if (!of_property_read_u32(nc, "spi-max-frequency", &value)) @@ -2423,7 +2422,7 @@ struct spi_device *spi_new_ancillary_device(struct spi_device *spi, strscpy(ancillary->modalias, "dummy", sizeof(ancillary->modalias)); /* Use provided chip-select for ancillary device */ - ancillary->chip_select = chip_select; + spi_set_chipselect(ancillary, 0, chip_select); /* Take over SPI mode/speed from SPI main device */ ancillary->max_speed_hz = spi->max_speed_hz; @@ -2670,7 +2669,7 @@ struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, spi->mode |= lookup.mode; spi->irq = lookup.irq; spi->bits_per_word = lookup.bits_per_word; - spi->chip_select = lookup.chip_select; + spi_set_chipselect(spi, 0, lookup.chip_select); return spi; } @@ -3632,7 +3631,7 @@ static int spi_set_cs_timing(struct spi_device *spi) struct device *parent = spi->controller->dev.parent; int status = 0; - if (spi->controller->set_cs_timing && !spi->cs_gpiod) { + if (spi->controller->set_cs_timing && !spi_get_csgpiod(spi, 0)) { if (spi->controller->auto_runtime_pm) { status = pm_runtime_get_sync(parent); if (status < 0) { @@ -3837,7 +3836,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) * cs_change is set for each transfer. */ if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) || - spi->cs_gpiod)) { + spi_get_csgpiod(spi, 0))) { size_t maxsize; int ret; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 9a32495fbb1f..9b23a1d0dd0d 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -263,6 +263,26 @@ static inline void *spi_get_drvdata(struct spi_device *spi) return dev_get_drvdata(&spi->dev); } +static inline u8 spi_get_chipselect(struct spi_device *spi, u8 idx) +{ + return spi->chip_select; +} + +static inline void spi_set_chipselect(struct spi_device *spi, u8 idx, u8 chipselect) +{ + spi->chip_select = chipselect; +} + +static inline struct gpio_desc *spi_get_csgpiod(struct spi_device *spi, u8 idx) +{ + return spi->cs_gpiod; +} + +static inline void spi_set_csgpiod(struct spi_device *spi, u8 idx, struct gpio_desc *csgpiod) +{ + spi->cs_gpiod = csgpiod; +} + struct spi_message; /** From b4c58d540777124f31ab0cb37a14c6573438d381 Mon Sep 17 00:00:00 2001 From: Mauro Lima Date: Wed, 1 Feb 2023 17:54:54 -0300 Subject: [PATCH 29/65] spi: intel: Fix device private data and PR_NUM for Broxton controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some private data fields have to change from bxt_info to cnl_info. Here is the list of Device IDs with the respective documentation taken for validation: 0xa0a4 - Intel® 500 Series Chipset Family On-Package PCH 0x02a4 - Intel® 400 Series Chipset Family On-Package PCH 0x06a4 - Intel® 400 Series Chipset Family Platform Controller Hub 0x34a4 - Intel® 495 Chipset Family On-Package 0xa3a4 - Intel® B460 and H410 Chipset According to documentation Broxton controller type has five PR registers. Signed-off-by: Mauro Lima Acked-by: Mika Westerberg Link: https://lore.kernel.org/r/20230201205455.550308-2-mauro.lima@eclypsium.com Signed-off-by: Mark Brown --- drivers/spi/spi-intel-pci.c | 10 +++++----- drivers/spi/spi-intel.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c index f0d532ea40e8..10fa3a7fa4f5 100644 --- a/drivers/spi/spi-intel-pci.c +++ b/drivers/spi/spi-intel-pci.c @@ -60,12 +60,12 @@ static int intel_spi_pci_probe(struct pci_dev *pdev, } static const struct pci_device_id intel_spi_pci_ids[] = { - { PCI_VDEVICE(INTEL, 0x02a4), (unsigned long)&bxt_info }, - { PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x02a4), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x1bca), (unsigned long)&bxt_info }, - { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x38a4), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x43a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info }, @@ -75,11 +75,11 @@ static const struct pci_device_id intel_spi_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info }, - { PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&bxt_info }, + { PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xa1a4), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0xa224), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, - { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&bxt_info }, + { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info }, { }, }; MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids); diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c index f619212b0d5c..1052fb4b7973 100644 --- a/drivers/spi/spi-intel.c +++ b/drivers/spi/spi-intel.c @@ -104,7 +104,7 @@ #define BXT_PR 0x84 #define BXT_SSFSTS_CTL 0xa0 #define BXT_FREG_NUM 12 -#define BXT_PR_NUM 6 +#define BXT_PR_NUM 5 #define CNL_PR 0x84 #define CNL_FREG_NUM 6 From 7c62a2279b9e88f2cbfa3b92dc49c8b7806c56f8 Mon Sep 17 00:00:00 2001 From: Mauro Lima Date: Wed, 1 Feb 2023 17:54:55 -0300 Subject: [PATCH 30/65] spi: intel: Add support for controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Device IDs to the module table for the following controllers: - 9da4 Cannon Lake 300 Series On-Package - a2a4 200 Series/Z370 Chipset Family SPI Controller - 9d24 Intel® 200 Series Chipset Family (Including Intel® X299), Intel® Z370 Intel® H310C,B365, also Intel® B460 and H410 Chipset Platform Controller Hub Signed-off-by: Mauro Lima Acked-by: Mika Westerberg Link: https://lore.kernel.org/r/20230201205455.550308-3-mauro.lima@eclypsium.com Signed-off-by: Mark Brown --- drivers/spi/spi-intel-pci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c index 10fa3a7fa4f5..4d69e320d018 100644 --- a/drivers/spi/spi-intel-pci.c +++ b/drivers/spi/spi-intel-pci.c @@ -75,9 +75,12 @@ static const struct pci_device_id intel_spi_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0x9d24), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0x9da4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xa1a4), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0xa224), (unsigned long)&bxt_info }, + { PCI_VDEVICE(INTEL, 0xa2a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info }, { }, From 941811980df00161fe639c252dabe6488875887c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Feb 2023 17:47:38 +0300 Subject: [PATCH 31/65] spi: spidev: Fix double unlock in spidev_sync() This unlocks twice due to a merge issue. Fixes: 35bba23e6732 ("Merge remote-tracking branch 'spi/for-6.2' into spi-6.2") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/Y+ETCk7XKfAy8yWQ@kili Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index f836567c631b..5a038c667401 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -115,8 +115,6 @@ spidev_sync(struct spidev_data *spidev, struct spi_message *message) else status = spidev_sync_unlocked(spi, message); - mutex_unlock(&spidev->spi_lock); - mutex_unlock(&spidev->spi_lock); return status; } From 7db738b5fea4533fa217dfb05c506c15bd0964d9 Mon Sep 17 00:00:00 2001 From: Mauro Lima Date: Mon, 6 Feb 2023 15:31:43 -0300 Subject: [PATCH 32/65] spi: intel: Remove DANGEROUS tag from pci driver Modern CPUs exposes this controller as PCI device that only uses hardware sequencing capabilities which is safer than software sequencing. Leave the platform driver as *DANGEROUS* and update help text since most of these controllers are using software sequencing. Signed-off-by: Mauro Lima Acked-by: Mika Westerberg Link: https://lore.kernel.org/r/20230206183143.75274-2-mauro.lima@eclypsium.com Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 87fc2bd16b72..3a362c450cb6 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -447,7 +447,7 @@ config SPI_INTEL tristate config SPI_INTEL_PCI - tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)" + tristate "Intel PCH/PCU SPI flash PCI driver" depends on PCI depends on X86 || COMPILE_TEST depends on SPI_MEM @@ -455,8 +455,9 @@ config SPI_INTEL_PCI help This enables PCI support for the Intel PCH/PCU SPI controller in master mode. This controller is present in modern Intel hardware - and is used to hold BIOS and other persistent settings. Using - this driver it is possible to upgrade BIOS directly from Linux. + and is used to hold BIOS and other persistent settings. This + driver only supports hardware sequencing mode. Using this + driver it is possible to upgrade BIOS directly from Linux. Say N here unless you know what you are doing. Overwriting the SPI flash may render the system unbootable. @@ -471,10 +472,10 @@ config SPI_INTEL_PLATFORM select SPI_INTEL help This enables platform support for the Intel PCH/PCU SPI - controller in master mode. This controller is present in modern - Intel hardware and is used to hold BIOS and other persistent - settings. Using this driver it is possible to upgrade BIOS - directly from Linux. + controller in master mode that is used to hold BIOS and other + persistent settings. Most of these controllers are using + software sequencing mode. Using this driver it is possible to + upgrade BIOS directly from Linux. Say N here unless you know what you are doing. Overwriting the SPI flash may render the system unbootable. From fff948a44b44a628c81294af5498226cb66a2594 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Mon, 6 Feb 2023 22:58:12 -0800 Subject: [PATCH 33/65] spi: Convert bcm63xx-hsspi bindings to json-schema This is the preparation for updates on the bcm63xx hsspi driver. Convert the text based bindings to json-schema per new dts requirement. Signed-off-by: William Zhang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230207065826.285013-2-william.zhang@broadcom.com Signed-off-by: Mark Brown --- .../bindings/spi/brcm,bcm63xx-hsspi.yaml | 55 +++++++++++++++++++ .../bindings/spi/spi-bcm63xx-hsspi.txt | 33 ----------- 2 files changed, 55 insertions(+), 33 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml delete mode 100644 Documentation/devicetree/bindings/spi/spi-bcm63xx-hsspi.txt diff --git a/Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml b/Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml new file mode 100644 index 000000000000..3c646997e399 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/brcm,bcm63xx-hsspi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6328 High Speed SPI controller + +maintainers: + - Jonas Gorski + +properties: + compatible: + const: brcm,bcm6328-hsspi + + reg: + maxItems: 1 + + clocks: + items: + - description: SPI master reference clock + - description: SPI master pll clock + + clock-names: + items: + - const: hsspi + - const: pll + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + +allOf: + - $ref: spi-controller.yaml# + +unevaluatedProperties: false + +examples: + - | + spi@10001000 { + compatible = "brcm,bcm6328-hsspi"; + reg = <0x10001000 0x600>; + interrupts = <29>; + clocks = <&clkctl 9>, <&hsspi_pll>; + clock-names = "hsspi", "pll"; + num-cs = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/spi/spi-bcm63xx-hsspi.txt b/Documentation/devicetree/bindings/spi/spi-bcm63xx-hsspi.txt deleted file mode 100644 index 37b29ee13860..000000000000 --- a/Documentation/devicetree/bindings/spi/spi-bcm63xx-hsspi.txt +++ /dev/null @@ -1,33 +0,0 @@ -Binding for Broadcom BCM6328 High Speed SPI controller - -Required properties: -- compatible: must contain of "brcm,bcm6328-hsspi". -- reg: Base address and size of the controllers memory area. -- interrupts: Interrupt for the SPI block. -- clocks: phandles of the SPI clock and the PLL clock. -- clock-names: must be "hsspi", "pll". -- #address-cells: <1>, as required by generic SPI binding. -- #size-cells: <0>, also as required by generic SPI binding. - -Optional properties: -- num-cs: some controllers have less than 8 cs signals. Defaults to 8 - if absent. - -Child nodes as per the generic SPI binding. - -Example: - - spi@10001000 { - compatible = "brcm,bcm6328-hsspi"; - reg = <0x10001000 0x600>; - - interrupts = <29>; - - clocks = <&clkctl 9>, <&hsspi_pll>; - clock-names = "hsspi", "pll"; - - num-cs = <2>; - - #address-cells = <1>; - #size-cells = <0>; - }; From 0ba979f995324417fd773881bc5a39910a9f2362 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Mon, 6 Feb 2023 22:58:13 -0800 Subject: [PATCH 34/65] spi: Add bcmbca-hsspi controller bindings The new Broadcom Broadband BCMBCA SoCs includes a updated HSSPI controller. Add new compatible strings to differentiate the old and new controller while keeping MIPS based chip with the old compatible. Update property requirements for these two revisions of the controller. Also add myself and Kursad as the maintainers. Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230207065826.285013-3-william.zhang@broadcom.com Signed-off-by: Mark Brown --- .../bindings/spi/brcm,bcm63xx-hsspi.yaml | 97 +++++++++++++++++-- 1 file changed, 88 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml b/Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml index 3c646997e399..6554978583f8 100644 --- a/Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml +++ b/Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml @@ -4,17 +4,70 @@ $id: http://devicetree.org/schemas/spi/brcm,bcm63xx-hsspi.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Broadcom BCM6328 High Speed SPI controller +title: Broadcom Broadband SoC High Speed SPI controller maintainers: + - William Zhang + - Kursad Oney - Jonas Gorski +description: | + Broadcom Broadband SoC supports High Speed SPI master controller since the + early MIPS based chips such as BCM6328 and BCM63268. This initial rev 1.0 + controller was carried over to recent ARM based chips, such as BCM63138, + BCM4908 and BCM6858. The old MIPS based chip should continue to use the + brcm,bcm6328-hsspi compatible string. The recent ARM based chip is required to + use the brcm,bcmbca-hsspi-v1.0 as part of its compatible string list as + defined below to match the specific chip along with ip revision info. + + This rev 1.0 controller has a limitation that can not keep the chip select line + active between the SPI transfers within the same SPI message. This can + terminate the transaction to some SPI devices prematurely. The issue can be + worked around by either the controller's prepend mode or using the dummy chip + select workaround. Driver automatically picks the suitable mode based on + transfer type so it is transparent to the user. + + The newer SoCs such as BCM6756, BCM4912 and BCM6855 include an updated SPI + controller rev 1.1 that add the capability to allow the driver to control chip + select explicitly. This solves the issue in the old controller. + properties: compatible: - const: brcm,bcm6328-hsspi + oneOf: + - const: brcm,bcm6328-hsspi + - items: + - enum: + - brcm,bcm47622-hsspi + - brcm,bcm4908-hsspi + - brcm,bcm63138-hsspi + - brcm,bcm63146-hsspi + - brcm,bcm63148-hsspi + - brcm,bcm63158-hsspi + - brcm,bcm63178-hsspi + - brcm,bcm6846-hsspi + - brcm,bcm6856-hsspi + - brcm,bcm6858-hsspi + - brcm,bcm6878-hsspi + - const: brcm,bcmbca-hsspi-v1.0 + - items: + - enum: + - brcm,bcm4912-hsspi + - brcm,bcm6756-hsspi + - brcm,bcm6813-hsspi + - brcm,bcm6855-hsspi + - const: brcm,bcmbca-hsspi-v1.1 reg: - maxItems: 1 + items: + - description: main registers + - description: miscellaneous control registers + minItems: 1 + + reg-names: + items: + - const: hsspi + - const: spim-ctrl + minItems: 1 clocks: items: @@ -38,18 +91,44 @@ required: allOf: - $ref: spi-controller.yaml# + - if: + properties: + compatible: + contains: + enum: + - brcm,bcm6328-hsspi + - brcm,bcmbca-hsspi-v1.0 + then: + properties: + reg: + maxItems: 1 + reg-names: + maxItems: 1 + else: + properties: + reg: + minItems: 2 + maxItems: 2 + reg-names: + minItems: 2 + maxItems: 2 + required: + - reg-names unevaluatedProperties: false examples: - | - spi@10001000 { - compatible = "brcm,bcm6328-hsspi"; - reg = <0x10001000 0x600>; - interrupts = <29>; - clocks = <&clkctl 9>, <&hsspi_pll>; + #include + spi@ff801000 { + compatible = "brcm,bcm6756-hsspi", "brcm,bcmbca-hsspi-v1.1"; + reg = <0xff801000 0x1000>, + <0xff802610 0x4>; + reg-names = "hsspi", "spim-ctrl"; + interrupts = ; + clocks = <&hsspi>, <&hsspi_pll>; clock-names = "hsspi", "pll"; - num-cs = <2>; + num-cs = <8>; #address-cells = <1>; #size-cells = <0>; }; From 99d7428ac94bf67d6e9df81dd3b4bf3046196ad6 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Mon, 6 Feb 2023 22:58:16 -0800 Subject: [PATCH 35/65] spi: bcm63xx-hsspi: Add new compatible string support New compatible string brcm,bcmbca-hsspi-v1.0 is introduced based on dts document brcm,bcm63xx-hsspi.yaml. Add it to the driver to support this new binding. Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230207065826.285013-6-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index b871fd810d80..01d5acad4a1b 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -516,6 +516,7 @@ static SIMPLE_DEV_PM_OPS(bcm63xx_hsspi_pm_ops, bcm63xx_hsspi_suspend, static const struct of_device_id bcm63xx_hsspi_of_match[] = { { .compatible = "brcm,bcm6328-hsspi", }, + { .compatible = "brcm,bcmbca-hsspi-v1.0", }, { }, }; MODULE_DEVICE_TABLE(of, bcm63xx_hsspi_of_match); From 85a84a61699990db6a025b5073f337f49933a875 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Mon, 6 Feb 2023 22:58:17 -0800 Subject: [PATCH 36/65] spi: bcm63xx-hsspi: Endianness fix for ARM based SoC HSSPI controller uses big endian for the opcode in the message to the controller ping pong buffer. Use cpu_to_be16 to properly handle the endianness for both big and little endian host. Fixes: 142168eba9dc ("spi: bcm63xx-hsspi: add bcm63xx HSSPI driver") Signed-off-by: Kursad Oney Signed-off-by: William Zhang Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/20230207065826.285013-7-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index 01d5acad4a1b..a65a0ec67641 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -194,7 +194,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) tx += curr_step; } - __raw_writew(opcode | curr_step, bs->fifo); + __raw_writew((u16)cpu_to_be16(opcode | curr_step), bs->fifo); /* enable interrupt */ __raw_writel(HSSPI_PINGx_CMD_DONE(0), From 50a6620dd1fbc810476422a965b041f1839f8eac Mon Sep 17 00:00:00 2001 From: William Zhang Date: Mon, 6 Feb 2023 22:58:18 -0800 Subject: [PATCH 37/65] spi: bcm63xx-hsspi: Add polling mode support Polling mode provides better throughput in general by avoiding the interrupt overhead as the maximum data size one interrupt can handle is only 512 bytes. So switch to polling mode as the default mode but add a driver sysfs option wait_mode to allow user manually changing the mode at run time between interrupt and polling. Also add driver banner message when the driver is loaded successfully. When test on a Broadcom BCM47622(ARM A7 dual core) reference board with WINBOND W25N01GV SPI NAND chip at 100MHz SPI clock using the MTD speed test suite, it shows about 15% improvement on the write and 30% on the read: ** Interrupt mode ** mtd_speedtest: MTD device: 0 count: 16 mtd_speedtest: MTD device size 134217728, eraseblock size 131072, page size 2048, count of eraseblocks 1024, pages per eraseblock 64, OOB size 64 mtd_test: scanning for bad eraseblocks mtd_test: scanned 16 eraseblocks, 0 are bad mtd_speedtest: testing eraseblock write speed mtd_speedtest: eraseblock write speed is 3072 KiB/s mtd_speedtest: testing eraseblock read speed mtd_speedtest: eraseblock read speed is 6690 KiB/s mtd_speedtest: testing page write speed mtd_speedtest: page write speed is 3066 KiB/s mtd_speedtest: testing page read speed mtd_speedtest: page read speed is 6762 KiB/s mtd_speedtest: testing 2 page write speed mtd_speedtest: 2 page write speed is 3071 KiB/s mtd_speedtest: testing 2 page read speed mtd_speedtest: 2 page read speed is 6772 KiB/s ** Polling mode ** mtd_speedtest: MTD device: 0 count: 16 mtd_speedtest: MTD device size 134217728, eraseblock size 131072, page size 2048, count of eraseblocks 1024, pages per eraseblock 64, OOB size 64 mtd_test: scanning for bad eraseblocks mtd_test: scanned 16 eraseblocks, 0 are bad mtd_speedtest: testing eraseblock write speed mtd_speedtest: eraseblock write speed is 3542 KiB/s mtd_speedtest: testing eraseblock read speed mtd_speedtest: eraseblock read speed is 8825 KiB/s mtd_speedtest: testing page write speed mtd_speedtest: page write speed is 3563 KiB/s mtd_speedtest: testing page read speed mtd_speedtest: page read speed is 8787 KiB/s mtd_speedtest: testing 2 page write speed mtd_speedtest: 2 page write speed is 3572 KiB/s mtd_speedtest: testing 2 page read speed mtd_speedtest: 2 page read speed is 8806 KiB/s Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230207065826.285013-8-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 109 ++++++++++++++++++++++++++++---- 1 file changed, 98 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index a65a0ec67641..55cbe7deba08 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -57,6 +57,7 @@ #define PINGPONG_CMD_SS_SHIFT 12 #define HSSPI_PINGPONG_STATUS_REG(x) (0x84 + (x) * 0x40) +#define HSSPI_PINGPONG_STATUS_SRC_BUSY BIT(1) #define HSSPI_PROFILE_CLK_CTRL_REG(x) (0x100 + (x) * 0x20) #define CLK_CTRL_FREQ_CTRL_MASK 0x0000ffff @@ -96,11 +97,16 @@ #define HSSPI_SPI_MAX_CS 8 #define HSSPI_BUS_NUM 1 /* 0 is legacy SPI */ +#define HSSPI_POLL_STATUS_TIMEOUT_MS 100 + +#define HSSPI_WAIT_MODE_POLLING 0 +#define HSSPI_WAIT_MODE_INTR 1 +#define HSSPI_WAIT_MODE_MAX HSSPI_WAIT_MODE_INTR struct bcm63xx_hsspi { struct completion done; struct mutex bus_mutex; - + struct mutex msg_mutex; struct platform_device *pdev; struct clk *clk; struct clk *pll_clk; @@ -109,6 +115,52 @@ struct bcm63xx_hsspi { u32 speed_hz; u8 cs_polarity; + u32 wait_mode; +}; + +static ssize_t wait_mode_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct spi_controller *ctrl = dev_get_drvdata(dev); + struct bcm63xx_hsspi *bs = spi_master_get_devdata(ctrl); + + return sprintf(buf, "%d\n", bs->wait_mode); +} + +static ssize_t wait_mode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct spi_controller *ctrl = dev_get_drvdata(dev); + struct bcm63xx_hsspi *bs = spi_master_get_devdata(ctrl); + u32 val; + + if (kstrtou32(buf, 10, &val)) + return -EINVAL; + + if (val > HSSPI_WAIT_MODE_MAX) { + dev_warn(dev, "invalid wait mode %u\n", val); + return -EINVAL; + } + + mutex_lock(&bs->msg_mutex); + bs->wait_mode = val; + /* clear interrupt status to avoid spurious int on next transfer */ + if (val == HSSPI_WAIT_MODE_INTR) + __raw_writel(HSSPI_INT_CLEAR_ALL, bs->regs + HSSPI_INT_STATUS_REG); + mutex_unlock(&bs->msg_mutex); + + return count; +} + +static DEVICE_ATTR_RW(wait_mode); + +static struct attribute *bcm63xx_hsspi_attrs[] = { + &dev_attr_wait_mode.attr, + NULL, +}; + +static const struct attribute_group bcm63xx_hsspi_group = { + .attrs = bcm63xx_hsspi_attrs, }; static void bcm63xx_hsspi_set_cs(struct bcm63xx_hsspi *bs, unsigned int cs, @@ -163,6 +215,8 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) int step_size = HSSPI_BUFFER_LEN; const u8 *tx = t->tx_buf; u8 *rx = t->rx_buf; + u32 val; + unsigned long limit; bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz); bcm63xx_hsspi_set_cs(bs, spi->chip_select, true); @@ -197,8 +251,9 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) __raw_writew((u16)cpu_to_be16(opcode | curr_step), bs->fifo); /* enable interrupt */ - __raw_writel(HSSPI_PINGx_CMD_DONE(0), - bs->regs + HSSPI_INT_MASK_REG); + if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) + __raw_writel(HSSPI_PINGx_CMD_DONE(0), + bs->regs + HSSPI_INT_MASK_REG); /* start the transfer */ __raw_writel(!chip_select << PINGPONG_CMD_SS_SHIFT | @@ -206,9 +261,21 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) PINGPONG_COMMAND_START_NOW, bs->regs + HSSPI_PINGPONG_COMMAND_REG(0)); - if (wait_for_completion_timeout(&bs->done, HZ) == 0) { - dev_err(&bs->pdev->dev, "transfer timed out!\n"); - return -ETIMEDOUT; + if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) { + if (wait_for_completion_timeout(&bs->done, HZ) == 0) + goto err_timeout; + } else { + /* polling mode checks for status busy bit */ + limit = jiffies + msecs_to_jiffies(HSSPI_POLL_STATUS_TIMEOUT_MS); + while (!time_after(jiffies, limit)) { + val = __raw_readl(bs->regs + HSSPI_PINGPONG_STATUS_REG(0)); + if (val & HSSPI_PINGPONG_STATUS_SRC_BUSY) + cpu_relax(); + else + break; + } + if (val & HSSPI_PINGPONG_STATUS_SRC_BUSY) + goto err_timeout; } if (rx) { @@ -220,6 +287,10 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) } return 0; + +err_timeout: + dev_err(&bs->pdev->dev, "transfer timed out!\n"); + return -ETIMEDOUT; } static int bcm63xx_hsspi_setup(struct spi_device *spi) @@ -269,6 +340,7 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master, int dummy_cs; u32 reg; + mutex_lock(&bs->msg_mutex); /* This controller does not support keeping CS active during idle. * To work around this, we use the following ugly hack: * @@ -306,6 +378,7 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master, __raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG); mutex_unlock(&bs->bus_mutex); + mutex_unlock(&bs->msg_mutex); msg->status = status; spi_finalize_current_message(master); @@ -398,8 +471,10 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) bs->regs = regs; bs->speed_hz = rate; bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0)); + bs->wait_mode = HSSPI_WAIT_MODE_POLLING; mutex_init(&bs->bus_mutex); + mutex_init(&bs->msg_mutex); init_completion(&bs->done); master->dev.of_node = dev->of_node; @@ -434,21 +509,32 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) __raw_writel(reg | GLOBAL_CTRL_CLK_GATE_SSOFF, bs->regs + HSSPI_GLOBAL_CTRL_REG); - ret = devm_request_irq(dev, irq, bcm63xx_hsspi_interrupt, IRQF_SHARED, - pdev->name, bs); + if (irq > 0) { + ret = devm_request_irq(dev, irq, bcm63xx_hsspi_interrupt, IRQF_SHARED, + pdev->name, bs); - if (ret) - goto out_put_master; + if (ret) + goto out_put_master; + } pm_runtime_enable(&pdev->dev); + if (sysfs_create_group(&pdev->dev.kobj, &bcm63xx_hsspi_group)) { + dev_err(&pdev->dev, "couldn't register sysfs group\n"); + goto out_pm_disable; + } + /* register and we are done */ ret = devm_spi_register_master(dev, master); if (ret) - goto out_pm_disable; + goto out_sysgroup_disable; + + dev_info(dev, "Broadcom 63XX High Speed SPI Controller driver"); return 0; +out_sysgroup_disable: + sysfs_remove_group(&pdev->dev.kobj, &bcm63xx_hsspi_group); out_pm_disable: pm_runtime_disable(&pdev->dev); out_put_master: @@ -470,6 +556,7 @@ static int bcm63xx_hsspi_remove(struct platform_device *pdev) __raw_writel(0, bs->regs + HSSPI_INT_MASK_REG); clk_disable_unprepare(bs->pll_clk); clk_disable_unprepare(bs->clk); + sysfs_remove_group(&pdev->dev.kobj, &bcm63xx_hsspi_group); return 0; } From 2b1e19811a8ecc776d15da4ca89df48db6974d66 Mon Sep 17 00:00:00 2001 From: Xiangsheng Hou Date: Wed, 1 Feb 2023 10:09:17 +0800 Subject: [PATCH 38/65] spi: mtk-snfi: Change default page format to setup default setting Change default page format to setup default setting since the sector size 1024 on MT7986 will lead to probe fail. Signed-off-by: Xiangsheng Hou Link: https://lore.kernel.org/r/20230201020921.26712-2-xiangsheng.hou@mediatek.com Signed-off-by: Mark Brown --- drivers/spi/spi-mtk-snfi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/spi-mtk-snfi.c b/drivers/spi/spi-mtk-snfi.c index fa8412ba20e2..719fc6f53ab1 100644 --- a/drivers/spi/spi-mtk-snfi.c +++ b/drivers/spi/spi-mtk-snfi.c @@ -1430,8 +1430,7 @@ static int mtk_snand_probe(struct platform_device *pdev) // setup an initial page format for ops matching page_cache_op template // before ECC is called. - ret = mtk_snand_setup_pagefmt(ms, ms->caps->sector_size, - ms->caps->spare_sizes[0]); + ret = mtk_snand_setup_pagefmt(ms, SZ_2K, SZ_64); if (ret) { dev_err(ms->dev, "failed to set initial page format\n"); goto disable_clk; From e40fa328551dd67d14e5dc3e4ed82b5b770f027f Mon Sep 17 00:00:00 2001 From: Xiangsheng Hou Date: Wed, 1 Feb 2023 10:09:18 +0800 Subject: [PATCH 39/65] spi: mtk-snfi: Add optional nfi_hclk which is needed for MT7986 Add optional nfi_hclk which is needed for MT7986. Signed-off-by: Xiangsheng Hou Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230201020921.26712-3-xiangsheng.hou@mediatek.com Signed-off-by: Mark Brown --- drivers/spi/spi-mtk-snfi.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/spi/spi-mtk-snfi.c b/drivers/spi/spi-mtk-snfi.c index 719fc6f53ab1..85644308df23 100644 --- a/drivers/spi/spi-mtk-snfi.c +++ b/drivers/spi/spi-mtk-snfi.c @@ -297,6 +297,7 @@ struct mtk_snand { struct device *dev; struct clk *nfi_clk; struct clk *pad_clk; + struct clk *nfi_hclk; void __iomem *nfi_base; int irq; struct completion op_done; @@ -1339,7 +1340,16 @@ static int mtk_snand_enable_clk(struct mtk_snand *ms) dev_err(ms->dev, "unable to enable pad clk\n"); goto err1; } + ret = clk_prepare_enable(ms->nfi_hclk); + if (ret) { + dev_err(ms->dev, "unable to enable nfi hclk\n"); + goto err2; + } + return 0; + +err2: + clk_disable_unprepare(ms->pad_clk); err1: clk_disable_unprepare(ms->nfi_clk); return ret; @@ -1347,6 +1357,7 @@ static int mtk_snand_enable_clk(struct mtk_snand *ms) static void mtk_snand_disable_clk(struct mtk_snand *ms) { + clk_disable_unprepare(ms->nfi_hclk); clk_disable_unprepare(ms->pad_clk); clk_disable_unprepare(ms->nfi_clk); } @@ -1401,6 +1412,13 @@ static int mtk_snand_probe(struct platform_device *pdev) goto release_ecc; } + ms->nfi_hclk = devm_clk_get_optional(&pdev->dev, "nfi_hclk"); + if (IS_ERR(ms->nfi_hclk)) { + ret = PTR_ERR(ms->nfi_hclk); + dev_err(&pdev->dev, "unable to get nfi_hclk, err = %d\n", ret); + goto release_ecc; + } + ret = mtk_snand_enable_clk(ms); if (ret) goto release_ecc; From 1d36c99062bf4e809271cc534486342442508d4a Mon Sep 17 00:00:00 2001 From: Xiangsheng Hou Date: Wed, 1 Feb 2023 10:09:20 +0800 Subject: [PATCH 40/65] spi: mtk-snfi: Add snfi sample delay and read latency adjustment Add snfi sample delay and read latency adjustment which can get from dts property. Signed-off-by: Xiangsheng Hou Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230201020921.26712-5-xiangsheng.hou@mediatek.com Signed-off-by: Mark Brown --- drivers/spi/spi-mtk-snfi.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/spi/spi-mtk-snfi.c b/drivers/spi/spi-mtk-snfi.c index 85644308df23..f3f95eb37365 100644 --- a/drivers/spi/spi-mtk-snfi.c +++ b/drivers/spi/spi-mtk-snfi.c @@ -195,6 +195,8 @@ #define DATA_READ_MODE_X4 2 #define DATA_READ_MODE_DUAL 5 #define DATA_READ_MODE_QUAD 6 +#define DATA_READ_LATCH_LAT GENMASK(9, 8) +#define DATA_READ_LATCH_LAT_S 8 #define PG_LOAD_CUSTOM_EN BIT(7) #define DATARD_CUSTOM_EN BIT(6) #define CS_DESELECT_CYC_S 0 @@ -205,6 +207,9 @@ #define SNF_DLY_CTL3 0x548 #define SFCK_SAM_DLY_S 0 +#define SFCK_SAM_DLY GENMASK(5, 0) +#define SFCK_SAM_DLY_TOTAL 9 +#define SFCK_SAM_DLY_RANGE 47 #define SNF_STA_CTL1 0x550 #define CUS_PG_DONE BIT(28) @@ -1368,6 +1373,8 @@ static int mtk_snand_probe(struct platform_device *pdev) const struct of_device_id *dev_id; struct spi_controller *ctlr; struct mtk_snand *ms; + unsigned long spi_freq; + u32 val = 0; int ret; dev_id = of_match_node(mtk_snand_ids, np); @@ -1446,6 +1453,19 @@ static int mtk_snand_probe(struct platform_device *pdev) // switch to SNFI mode nfi_write32(ms, SNF_CFG, SPI_MODE); + ret = of_property_read_u32(np, "rx-sample-delay-ns", &val); + if (!ret) + nfi_rmw32(ms, SNF_DLY_CTL3, SFCK_SAM_DLY, + val * SFCK_SAM_DLY_RANGE / SFCK_SAM_DLY_TOTAL); + + ret = of_property_read_u32(np, "mediatek,rx-latch-latency-ns", &val); + if (!ret) { + spi_freq = clk_get_rate(ms->pad_clk); + val = DIV_ROUND_CLOSEST(val, NSEC_PER_SEC / spi_freq); + nfi_rmw32(ms, SNF_MISC_CTL, DATA_READ_LATCH_LAT, + val << DATA_READ_LATCH_LAT_S); + } + // setup an initial page format for ops matching page_cache_op template // before ECC is called. ret = mtk_snand_setup_pagefmt(ms, SZ_2K, SZ_64); From 8aa2ef233fa3b985ced1ed31b86fddddfd6be4b2 Mon Sep 17 00:00:00 2001 From: Xiangsheng Hou Date: Wed, 1 Feb 2023 10:09:19 +0800 Subject: [PATCH 41/65] spi: dt-bindings: mtk-snfi: Add compatible for MT7986 Add dt-bindings documentation of SPI NAND controller for MediaTek MT7986 SoC platform. And add optional nfi_hclk property which is needed for MT7986. Signed-off-by: Xiangsheng Hou Reviewed-by: Krzysztof Kozlowski Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230201020921.26712-4-xiangsheng.hou@mediatek.com Signed-off-by: Mark Brown --- .../bindings/spi/mediatek,spi-mtk-snfi.yaml | 51 +++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-snfi.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-snfi.yaml index 6e6e02c91780..bab23f1b11fd 100644 --- a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-snfi.yaml +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-snfi.yaml @@ -18,14 +18,12 @@ description: | using the accompanying ECC engine. There should be only one spi slave device following generic spi bindings. -allOf: - - $ref: /schemas/spi/spi-controller.yaml# - properties: compatible: enum: - mediatek,mt7622-snand - mediatek,mt7629-snand + - mediatek,mt7986-snand reg: items: @@ -36,14 +34,12 @@ properties: - description: NFI interrupt clocks: - items: - - description: clock used for the controller - - description: clock used for the SPI bus + minItems: 2 + maxItems: 3 clock-names: - items: - - const: nfi_clk - - const: pad_clk + minItems: 2 + maxItems: 3 nand-ecc-engine: description: device-tree node of the accompanying ECC engine. @@ -57,6 +53,43 @@ required: - clock-names - nand-ecc-engine +allOf: + - $ref: /schemas/spi/spi-controller.yaml# + - if: + properties: + compatible: + enum: + - mediatek,mt7622-snand + - mediatek,mt7629-snand + then: + properties: + clocks: + items: + - description: clock used for the controller + - description: clock used for the SPI bus + clock-names: + items: + - const: nfi_clk + - const: pad_clk + + - if: + properties: + compatible: + enum: + - mediatek,mt7986-snand + then: + properties: + clocks: + items: + - description: clock used for the controller + - description: clock used for the SPI bus + - description: clock used for the AHB bus + clock-names: + items: + - const: nfi_clk + - const: pad_clk + - const: nfi_hclk + unevaluatedProperties: false examples: From 351c02cb740472c659145b0027e77a3353e58185 Mon Sep 17 00:00:00 2001 From: Xiangsheng Hou Date: Wed, 1 Feb 2023 10:09:21 +0800 Subject: [PATCH 42/65] spi: dt-bindings: mtk-snfi: Add read latch latency property Add mediatek,rx-latch-latency-ns property which adjust data read latch latency in the unit of nanoseconds. Signed-off-by: Xiangsheng Hou Acked-by: Krzysztof Kozlowski Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230201020921.26712-6-xiangsheng.hou@mediatek.com Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/mediatek,spi-mtk-snfi.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-snfi.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-snfi.yaml index bab23f1b11fd..1e5e89a693c3 100644 --- a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-snfi.yaml +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-snfi.yaml @@ -45,6 +45,9 @@ properties: description: device-tree node of the accompanying ECC engine. $ref: /schemas/types.yaml#/definitions/phandle + mediatek,rx-latch-latency-ns: + description: Data read latch latency, unit is nanoseconds. + required: - compatible - reg From 2ea9b08a661274b9b7b182327bf6ffe29605d671 Mon Sep 17 00:00:00 2001 From: Mauro Lima Date: Fri, 10 Feb 2023 13:41:58 -0300 Subject: [PATCH 43/65] spi: intel: Update help text of PCI and Platform drivers Modern intel hardware uses controllers that work in hardware sequencing mode. In this mode, the controller exposes a subset of operations, like read, write and erase, making it easier and less error-prone for use. On the other hand, most of the controllers handled by the platform driver use software sequencing that exposes the entire set of operations i.e. exposes the low level SPI-NOR opcodes to the software for use. Update PCI and Platform help text with this information. Signed-off-by: Mauro Lima Acked-by: Mika Westerberg Link: https://lore.kernel.org/r/20230210164158.211065-1-mauro.lima@eclypsium.com Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 3a362c450cb6..db033d424bb5 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -454,13 +454,12 @@ config SPI_INTEL_PCI select SPI_INTEL help This enables PCI support for the Intel PCH/PCU SPI controller in - master mode. This controller is present in modern Intel hardware - and is used to hold BIOS and other persistent settings. This - driver only supports hardware sequencing mode. Using this - driver it is possible to upgrade BIOS directly from Linux. - - Say N here unless you know what you are doing. Overwriting the - SPI flash may render the system unbootable. + master mode. This controller is used to hold BIOS and other + persistent settings. Controllers present in modern Intel hardware + only work in hardware sequencing mode, this means that the + controller exposes a subset of operations that makes it safer to + use. Using this driver it is possible to upgrade BIOS directly + from Linux. To compile this driver as a module, choose M here: the module will be called spi-intel-pci. @@ -473,9 +472,10 @@ config SPI_INTEL_PLATFORM help This enables platform support for the Intel PCH/PCU SPI controller in master mode that is used to hold BIOS and other - persistent settings. Most of these controllers are using - software sequencing mode. Using this driver it is possible to - upgrade BIOS directly from Linux. + persistent settings. Most of these controllers work in + software sequencing mode, which means that the controller + exposes the low level SPI-NOR opcodes to the software. Using + this driver it is possible to upgrade BIOS directly from Linux. Say N here unless you know what you are doing. Overwriting the SPI flash may render the system unbootable. From 6e80133abeb09721ec4601de5b1e68be67135309 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 9 Feb 2023 12:02:39 -0800 Subject: [PATCH 44/65] spi: export spi_transfer_cs_change_delay_exec function For SPI controller that implements transfer_one_message, it needs to insert the delay that required by cs change event between the transfers. Add a wrapper for the local function _spi_transfer_cs_change_delay_exec and export it for SPI controller driver to use. Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230209200246.141520-9-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi.c | 7 +++++++ include/linux/spi/spi.h | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 21a8c3a8eee4..f4eb447c565d 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1483,6 +1483,13 @@ static void _spi_transfer_cs_change_delay(struct spi_message *msg, } } +void spi_transfer_cs_change_delay_exec(struct spi_message *msg, + struct spi_transfer *xfer) +{ + _spi_transfer_cs_change_delay(msg, xfer); +} +EXPORT_SYMBOL_GPL(spi_transfer_cs_change_delay_exec); + /* * spi_transfer_one_message - Default implementation of transfer_one_message() * diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 9b23a1d0dd0d..88cb2a1390ce 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -26,6 +26,7 @@ struct spi_controller; struct spi_transfer; struct spi_controller_mem_ops; struct spi_controller_mem_caps; +struct spi_message; /* * INTERFACES between SPI master-side drivers and SPI slave protocol handlers, @@ -119,6 +120,8 @@ struct spi_delay { extern int spi_delay_to_ns(struct spi_delay *_delay, struct spi_transfer *xfer); extern int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer); +extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg, + struct spi_transfer *xfer); /** * struct spi_device - Controller side proxy for an SPI slave device @@ -283,8 +286,6 @@ static inline void spi_set_csgpiod(struct spi_device *spi, u8 idx, struct gpio_d spi->cs_gpiod = csgpiod; } -struct spi_message; - /** * struct spi_driver - Host side "protocol" driver * @id_table: List of SPI devices supported by this driver From c00d5e93ea018786d98670fc1d0dab4c36c2217c Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 9 Feb 2023 12:02:40 -0800 Subject: [PATCH 45/65] spi: bcm63xx-hsspi: Handle cs_change correctly The kernel SPI interface includes the cs_change flag that alters how the CS behaves. If we're in the middle of transfers, it tells us to unselect the CS momentarily since the target device requires that. If we're at the end of a transfer, it tells us to keep the CS selected, perhaps because the next transfer is likely targeted to the same device. We implement this scheme in the HSSPI driver in this change. Prior to this change, the CS would toggle momentarily if cs_change was set for the last transfer. This can be ignored by some or most devices, but the Microchip TPM2 device does not ignore it. With the change, the behavior is corrected and the 'glitch' is eliminated. Signed-off-by: Kursad Oney Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230209200246.141520-10-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index 55cbe7deba08..af51488659b8 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -219,7 +219,8 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) unsigned long limit; bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz); - bcm63xx_hsspi_set_cs(bs, spi->chip_select, true); + if (!t->cs_off) + bcm63xx_hsspi_set_cs(bs, spi->chip_select, true); if (tx && rx) opcode = HSSPI_OP_READ_WRITE; @@ -338,7 +339,7 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master, struct spi_device *spi = msg->spi; int status = -EINVAL; int dummy_cs; - u32 reg; + bool keep_cs = false; mutex_lock(&bs->msg_mutex); /* This controller does not support keeping CS active during idle. @@ -367,16 +368,28 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master, spi_transfer_delay_exec(t); - if (t->cs_change) - bcm63xx_hsspi_set_cs(bs, spi->chip_select, false); + /* use existing cs change logic from spi_transfer_one_message */ + if (t->cs_change) { + if (list_is_last(&t->transfer_list, &msg->transfers)) { + keep_cs = true; + } else { + if (!t->cs_off) + bcm63xx_hsspi_set_cs(bs, spi->chip_select, false); + + spi_transfer_cs_change_delay_exec(msg, t); + + if (!list_next_entry(t, transfer_list)->cs_off) + bcm63xx_hsspi_set_cs(bs, spi->chip_select, true); + } + } else if (!list_is_last(&t->transfer_list, &msg->transfers) && + t->cs_off != list_next_entry(t, transfer_list)->cs_off) { + bcm63xx_hsspi_set_cs(bs, spi->chip_select, t->cs_off); + } } - mutex_lock(&bs->bus_mutex); - reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG); - reg &= ~GLOBAL_CTRL_CS_POLARITY_MASK; - reg |= bs->cs_polarity; - __raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG); - mutex_unlock(&bs->bus_mutex); + bcm63xx_hsspi_set_cs(bs, dummy_cs, false); + if (status || !keep_cs) + bcm63xx_hsspi_set_cs(bs, spi->chip_select, false); mutex_unlock(&bs->msg_mutex); msg->status = status; From 811ff802aaf878ebbbaeac0307a0164fa21e7d40 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 9 Feb 2023 12:02:41 -0800 Subject: [PATCH 46/65] spi: bcm63xx-hsspi: Fix multi-bit mode setting Currently the driver always sets the controller to dual data bit mode for both tx and rx data in the profile mode control register even for single data bit transfer. Luckily the opcode is set correctly according to SPI transfer data bit width so it does not actually cause issues. This change fixes the problem by setting tx and rx data bit mode field correctly according to the actual SPI transfer tx and rx data bit width. Fixes: 142168eba9dc ("spi: bcm63xx-hsspi: add bcm63xx HSSPI driver") Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230209200246.141520-11-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index af51488659b8..bc700649d270 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -215,7 +215,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) int step_size = HSSPI_BUFFER_LEN; const u8 *tx = t->tx_buf; u8 *rx = t->rx_buf; - u32 val; + u32 val = 0; unsigned long limit; bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz); @@ -233,11 +233,16 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) step_size -= HSSPI_OPCODE_LEN; if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) || - (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) + (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) { opcode |= HSSPI_OP_MULTIBIT; - __raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT | - 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff, + if (t->rx_nbits == SPI_NBITS_DUAL) + val |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT; + if (t->tx_nbits == SPI_NBITS_DUAL) + val |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT; + } + + __raw_writel(val | 0xff, bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); while (pending > 0) { From b7a82103f7c3a9168f0077e35688d4f9ce97294e Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 9 Feb 2023 12:02:42 -0800 Subject: [PATCH 47/65] spi: bcm63xx-hsspi: Add prepend mode support Due to the controller limitation to keep the chip select low during the bus idle time between the transfer, a dummy cs workaround was used when this driver was first upstreamed to the kernel. It basically picks the dummy cs as !actual_cs so typically dummy cs is 1 when most of the case only cs 0 is used in the board design. Then invert the polarity of both cs and tell the controller to start the transfers using dummy cs. Assuming both cs are active low before the inversion, effectively this keeps dummy cs high and actual cs low during the transfer and workaround the issue. This workaround implies that dummy cs 1 pin has to be set to chip selection function in the pinmux when the transfer clock is above 25MHz. The old chips likely have default pinmux set to chip select on the dummy cs pin so it works but this is not case for the new Broadband BCA chips and this workaround stop working. This is specifically an issue to support SPI NAND and SPI NOR flash because these flash devices can typically run at or above 100MHz. This patch utilizes the prepend feature of the controller to combine the multiple transfers in the same message to a single transfer when possible. This way there is no need to keep clock low between transfers and solve the issue without any hardware requirement. Multiple transfers within a SPI message may be combined into one transfer if the following are all true: * One or more half duplex write transfer in single bit mode * Optional full duplex read/write at the end * No delay and cs_change between transfers Most of the SPI device meets this requirements such as SPI NOR, SPI NAND flash, Broadcom SPI voice card and etc. For any SPI message that does not meet the above requirement to combine the transfers, we switch to original dummy cs mode but limit the clock rate to the safe 25MHz. This is the default auto transfer mode and it makes sure all the SPI message can be supported automatically under the hood. This patch also adds the driver sysfs node xfer_mode to provide the option for overriding the default auto mode and force it to dummy cs or prepend mode. Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230209200246.141520-12-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 361 ++++++++++++++++++++++++++++---- 1 file changed, 324 insertions(+), 37 deletions(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index bc700649d270..6a289deb5848 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -93,7 +93,11 @@ #define HSSPI_MAX_PREPEND_LEN 15 -#define HSSPI_MAX_SYNC_CLOCK 30000000 +/* + * Some chip require 30MHz but other require 25MHz. Use smaller value to cover + * both cases. + */ +#define HSSPI_MAX_SYNC_CLOCK 25000000 #define HSSPI_SPI_MAX_CS 8 #define HSSPI_BUS_NUM 1 /* 0 is legacy SPI */ @@ -103,6 +107,24 @@ #define HSSPI_WAIT_MODE_INTR 1 #define HSSPI_WAIT_MODE_MAX HSSPI_WAIT_MODE_INTR +/* + * Default transfer mode is auto. If the msg is prependable, use the prepend + * mode. If not, falls back to use the dummy cs workaround mode but limit the + * clock to 25MHz to make sure it works in all board design. + */ +#define HSSPI_XFER_MODE_AUTO 0 +#define HSSPI_XFER_MODE_PREPEND 1 +#define HSSPI_XFER_MODE_DUMMYCS 2 +#define HSSPI_XFER_MODE_MAX HSSPI_XFER_MODE_DUMMYCS + +#define bcm63xx_prepend_printk_on_checkfail(bs, fmt, ...) \ +do { \ + if (bs->xfer_mode == HSSPI_XFER_MODE_AUTO) \ + dev_dbg(&bs->pdev->dev, fmt, ##__VA_ARGS__); \ + else if (bs->xfer_mode == HSSPI_XFER_MODE_PREPEND) \ + dev_err(&bs->pdev->dev, fmt, ##__VA_ARGS__); \ +} while (0) + struct bcm63xx_hsspi { struct completion done; struct mutex bus_mutex; @@ -116,6 +138,9 @@ struct bcm63xx_hsspi { u32 speed_hz; u8 cs_polarity; u32 wait_mode; + u32 xfer_mode; + u32 prepend_cnt; + u8 *prepend_buf; }; static ssize_t wait_mode_show(struct device *dev, struct device_attribute *attr, @@ -154,8 +179,42 @@ static ssize_t wait_mode_store(struct device *dev, struct device_attribute *attr static DEVICE_ATTR_RW(wait_mode); +static ssize_t xfer_mode_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct spi_controller *ctrl = dev_get_drvdata(dev); + struct bcm63xx_hsspi *bs = spi_master_get_devdata(ctrl); + + return sprintf(buf, "%d\n", bs->xfer_mode); +} + +static ssize_t xfer_mode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct spi_controller *ctrl = dev_get_drvdata(dev); + struct bcm63xx_hsspi *bs = spi_master_get_devdata(ctrl); + u32 val; + + if (kstrtou32(buf, 10, &val)) + return -EINVAL; + + if (val > HSSPI_XFER_MODE_MAX) { + dev_warn(dev, "invalid xfer mode %u\n", val); + return -EINVAL; + } + + mutex_lock(&bs->msg_mutex); + bs->xfer_mode = val; + mutex_unlock(&bs->msg_mutex); + + return count; +} + +static DEVICE_ATTR_RW(xfer_mode); + static struct attribute *bcm63xx_hsspi_attrs[] = { &dev_attr_wait_mode.attr, + &dev_attr_xfer_mode.attr, NULL, }; @@ -163,6 +222,203 @@ static const struct attribute_group bcm63xx_hsspi_group = { .attrs = bcm63xx_hsspi_attrs, }; +static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs, + struct spi_device *spi, int hz); + +static size_t bcm63xx_hsspi_max_message_size(struct spi_device *spi) +{ + return HSSPI_BUFFER_LEN - HSSPI_OPCODE_LEN; +} + +static int bcm63xx_hsspi_wait_cmd(struct bcm63xx_hsspi *bs) +{ + unsigned long limit; + u32 reg = 0; + int rc = 0; + + if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) { + if (wait_for_completion_timeout(&bs->done, HZ) == 0) + rc = 1; + } else { + /* polling mode checks for status busy bit */ + limit = jiffies + msecs_to_jiffies(HSSPI_POLL_STATUS_TIMEOUT_MS); + + while (!time_after(jiffies, limit)) { + reg = __raw_readl(bs->regs + HSSPI_PINGPONG_STATUS_REG(0)); + if (reg & HSSPI_PINGPONG_STATUS_SRC_BUSY) + cpu_relax(); + else + break; + } + if (reg & HSSPI_PINGPONG_STATUS_SRC_BUSY) + rc = 1; + } + + if (rc) + dev_err(&bs->pdev->dev, "transfer timed out!\n"); + + return rc; +} + +static bool bcm63xx_prepare_prepend_transfer(struct spi_master *master, + struct spi_message *msg, + struct spi_transfer *t_prepend) +{ + + struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); + bool tx_only = false; + struct spi_transfer *t; + + /* + * Multiple transfers within a message may be combined into one transfer + * to the controller using its prepend feature. A SPI message is prependable + * only if the following are all true: + * 1. One or more half duplex write transfer in single bit mode + * 2. Optional full duplex read/write at the end + * 3. No delay and cs_change between transfers + */ + bs->prepend_cnt = 0; + list_for_each_entry(t, &msg->transfers, transfer_list) { + if ((spi_delay_to_ns(&t->delay, t) > 0) || t->cs_change) { + bcm63xx_prepend_printk_on_checkfail(bs, + "Delay or cs change not supported in prepend mode!\n"); + return false; + } + + tx_only = false; + if (t->tx_buf && !t->rx_buf) { + tx_only = true; + if (bs->prepend_cnt + t->len > + (HSSPI_BUFFER_LEN - HSSPI_OPCODE_LEN)) { + bcm63xx_prepend_printk_on_checkfail(bs, + "exceed max buf len, abort prepending transfers!\n"); + return false; + } + + if (t->tx_nbits > SPI_NBITS_SINGLE && + !list_is_last(&t->transfer_list, &msg->transfers)) { + bcm63xx_prepend_printk_on_checkfail(bs, + "multi-bit prepend buf not supported!\n"); + return false; + } + + if (t->tx_nbits == SPI_NBITS_SINGLE) { + memcpy(bs->prepend_buf + bs->prepend_cnt, t->tx_buf, t->len); + bs->prepend_cnt += t->len; + } + } else { + if (!list_is_last(&t->transfer_list, &msg->transfers)) { + bcm63xx_prepend_printk_on_checkfail(bs, + "rx/tx_rx transfer not supported when it is not last one!\n"); + return false; + } + } + + if (list_is_last(&t->transfer_list, &msg->transfers)) { + memcpy(t_prepend, t, sizeof(struct spi_transfer)); + + if (tx_only && t->tx_nbits == SPI_NBITS_SINGLE) { + /* + * if the last one is also a single bit tx only transfer, merge + * all of them into one single tx transfer + */ + t_prepend->len = bs->prepend_cnt; + t_prepend->tx_buf = bs->prepend_buf; + bs->prepend_cnt = 0; + } else { + /* + * if the last one is not a tx only transfer or dual tx xfer, all + * the previous transfers are sent through prepend bytes and + * make sure it does not exceed the max prepend len + */ + if (bs->prepend_cnt > HSSPI_MAX_PREPEND_LEN) { + bcm63xx_prepend_printk_on_checkfail(bs, + "exceed max prepend len, abort prepending transfers!\n"); + return false; + } + } + } + } + + return true; +} + +static int bcm63xx_hsspi_do_prepend_txrx(struct spi_device *spi, + struct spi_transfer *t) +{ + struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master); + unsigned int chip_select = spi->chip_select; + u16 opcode = 0; + const u8 *tx = t->tx_buf; + u8 *rx = t->rx_buf; + u32 reg = 0; + + /* + * shouldn't happen as we set the max_message_size in the probe. + * but check it again in case some driver does not honor the max size + */ + if (t->len + bs->prepend_cnt > (HSSPI_BUFFER_LEN - HSSPI_OPCODE_LEN)) { + dev_warn(&bs->pdev->dev, + "Prepend message large than fifo size len %d prepend %d\n", + t->len, bs->prepend_cnt); + return -EINVAL; + } + + bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz); + + if (tx && rx) + opcode = HSSPI_OP_READ_WRITE; + else if (tx) + opcode = HSSPI_OP_WRITE; + else if (rx) + opcode = HSSPI_OP_READ; + + if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) || + (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) { + opcode |= HSSPI_OP_MULTIBIT; + + if (t->rx_nbits == SPI_NBITS_DUAL) { + reg |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT; + reg |= bs->prepend_cnt << MODE_CTRL_MULTIDATA_RD_STRT_SHIFT; + } + if (t->tx_nbits == SPI_NBITS_DUAL) { + reg |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT; + reg |= bs->prepend_cnt << MODE_CTRL_MULTIDATA_WR_STRT_SHIFT; + } + } + + reg |= bs->prepend_cnt << MODE_CTRL_PREPENDBYTE_CNT_SHIFT; + __raw_writel(reg | 0xff, + bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); + + reinit_completion(&bs->done); + if (bs->prepend_cnt) + memcpy_toio(bs->fifo + HSSPI_OPCODE_LEN, bs->prepend_buf, + bs->prepend_cnt); + if (tx) + memcpy_toio(bs->fifo + HSSPI_OPCODE_LEN + bs->prepend_cnt, tx, + t->len); + + __raw_writew((u16)cpu_to_be16(opcode | t->len), bs->fifo); + /* enable interrupt */ + if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) + __raw_writel(HSSPI_PINGx_CMD_DONE(0), bs->regs + HSSPI_INT_MASK_REG); + + /* start the transfer */ + reg = chip_select << PINGPONG_CMD_SS_SHIFT | + chip_select << PINGPONG_CMD_PROFILE_SHIFT | + PINGPONG_COMMAND_START_NOW; + __raw_writel(reg, bs->regs + HSSPI_PINGPONG_COMMAND_REG(0)); + + if (bcm63xx_hsspi_wait_cmd(bs)) + return -ETIMEDOUT; + + if (rx) + memcpy_fromio(rx, bs->fifo, t->len); + + return 0; +} + static void bcm63xx_hsspi_set_cs(struct bcm63xx_hsspi *bs, unsigned int cs, bool active) { @@ -215,8 +471,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) int step_size = HSSPI_BUFFER_LEN; const u8 *tx = t->tx_buf; u8 *rx = t->rx_buf; - u32 val = 0; - unsigned long limit; + u32 reg = 0; bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz); if (!t->cs_off) @@ -237,12 +492,12 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) opcode |= HSSPI_OP_MULTIBIT; if (t->rx_nbits == SPI_NBITS_DUAL) - val |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT; + reg |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT; if (t->tx_nbits == SPI_NBITS_DUAL) - val |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT; + reg |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT; } - __raw_writel(val | 0xff, + __raw_writel(reg | 0xff, bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); while (pending > 0) { @@ -261,28 +516,13 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) __raw_writel(HSSPI_PINGx_CMD_DONE(0), bs->regs + HSSPI_INT_MASK_REG); - /* start the transfer */ - __raw_writel(!chip_select << PINGPONG_CMD_SS_SHIFT | - chip_select << PINGPONG_CMD_PROFILE_SHIFT | - PINGPONG_COMMAND_START_NOW, - bs->regs + HSSPI_PINGPONG_COMMAND_REG(0)); + reg = !chip_select << PINGPONG_CMD_SS_SHIFT | + chip_select << PINGPONG_CMD_PROFILE_SHIFT | + PINGPONG_COMMAND_START_NOW; + __raw_writel(reg, bs->regs + HSSPI_PINGPONG_COMMAND_REG(0)); - if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) { - if (wait_for_completion_timeout(&bs->done, HZ) == 0) - goto err_timeout; - } else { - /* polling mode checks for status busy bit */ - limit = jiffies + msecs_to_jiffies(HSSPI_POLL_STATUS_TIMEOUT_MS); - while (!time_after(jiffies, limit)) { - val = __raw_readl(bs->regs + HSSPI_PINGPONG_STATUS_REG(0)); - if (val & HSSPI_PINGPONG_STATUS_SRC_BUSY) - cpu_relax(); - else - break; - } - if (val & HSSPI_PINGPONG_STATUS_SRC_BUSY) - goto err_timeout; - } + if (bcm63xx_hsspi_wait_cmd(bs)) + return -ETIMEDOUT; if (rx) { memcpy_fromio(rx, bs->fifo, curr_step); @@ -293,10 +533,6 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) } return 0; - -err_timeout: - dev_err(&bs->pdev->dev, "transfer timed out!\n"); - return -ETIMEDOUT; } static int bcm63xx_hsspi_setup(struct spi_device *spi) @@ -336,18 +572,17 @@ static int bcm63xx_hsspi_setup(struct spi_device *spi) return 0; } -static int bcm63xx_hsspi_transfer_one(struct spi_master *master, +static int bcm63xx_hsspi_do_dummy_cs_txrx(struct spi_device *spi, struct spi_message *msg) { - struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); - struct spi_transfer *t; - struct spi_device *spi = msg->spi; + struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master); int status = -EINVAL; int dummy_cs; bool keep_cs = false; + struct spi_transfer *t; - mutex_lock(&bs->msg_mutex); - /* This controller does not support keeping CS active during idle. + /* + * This controller does not support keeping CS active during idle. * To work around this, we use the following ugly hack: * * a. Invert the target chip select's polarity so it will be active. @@ -365,6 +600,21 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master, bcm63xx_hsspi_set_cs(bs, dummy_cs, true); list_for_each_entry(t, &msg->transfers, transfer_list) { + /* + * We are here because one of reasons below: + * a. Message is not prependable and in default auto xfer mode. This mean + * we fallback to dummy cs mode at maximum 25MHz safe clock rate. + * b. User set to use the dummy cs mode. + */ + if (bs->xfer_mode == HSSPI_XFER_MODE_AUTO) { + if (t->speed_hz > HSSPI_MAX_SYNC_CLOCK) { + t->speed_hz = HSSPI_MAX_SYNC_CLOCK; + dev_warn_once(&bs->pdev->dev, + "Force to dummy cs mode. Reduce the speed to %dHz", + t->speed_hz); + } + } + status = bcm63xx_hsspi_do_txrx(spi, t); if (status) break; @@ -396,6 +646,35 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master, if (status || !keep_cs) bcm63xx_hsspi_set_cs(bs, spi->chip_select, false); + return status; +} + +static int bcm63xx_hsspi_transfer_one(struct spi_master *master, + struct spi_message *msg) +{ + struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); + struct spi_device *spi = msg->spi; + int status = -EINVAL; + bool prependable = false; + struct spi_transfer t_prepend; + + mutex_lock(&bs->msg_mutex); + + if (bs->xfer_mode != HSSPI_XFER_MODE_DUMMYCS) + prependable = bcm63xx_prepare_prepend_transfer(master, msg, &t_prepend); + + if (prependable) { + status = bcm63xx_hsspi_do_prepend_txrx(spi, &t_prepend); + msg->actual_length = (t_prepend.len + bs->prepend_cnt); + } else { + if (bs->xfer_mode == HSSPI_XFER_MODE_PREPEND) { + dev_err(&bs->pdev->dev, + "User sets prepend mode but msg not prependable! Abort transfer\n"); + status = -EINVAL; + } else + status = bcm63xx_hsspi_do_dummy_cs_txrx(spi, msg); + } + mutex_unlock(&bs->msg_mutex); msg->status = status; spi_finalize_current_message(master); @@ -490,6 +769,11 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) bs->speed_hz = rate; bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0)); bs->wait_mode = HSSPI_WAIT_MODE_POLLING; + bs->prepend_buf = devm_kzalloc(dev, HSSPI_BUFFER_LEN, GFP_KERNEL); + if (!bs->prepend_buf) { + ret = -ENOMEM; + goto out_put_master; + } mutex_init(&bs->bus_mutex); mutex_init(&bs->msg_mutex); @@ -508,6 +792,9 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) master->num_chipselect = num_cs; master->setup = bcm63xx_hsspi_setup; master->transfer_one_message = bcm63xx_hsspi_transfer_one; + master->max_transfer_size = bcm63xx_hsspi_max_message_size; + master->max_message_size = bcm63xx_hsspi_max_message_size; + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_RX_DUAL | SPI_TX_DUAL; master->bits_per_word_mask = SPI_BPW_MASK(8); From 76a85704cb917e3b25e00f02d5fd46e4e0a9077d Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 9 Feb 2023 12:02:43 -0800 Subject: [PATCH 48/65] spi: spi-mem: Allow controller supporting mem_ops without exec_op Currently exec_op is always required if controller driver provides mem_ops. But some controller such as bcm63xx-hsspi may only need to implement other operation like supports_op and use the default execution operation. This patch removes this restriction. Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230209200246.141520-13-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-mem.c | 2 +- drivers/spi/spi.c | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 0c79193d9697..701838b6f0c4 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -325,7 +325,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) if (!spi_mem_internal_supports_op(mem, op)) return -ENOTSUPP; - if (ctlr->mem_ops && !mem->spi->cs_gpiod) { + if (ctlr->mem_ops && ctlr->mem_ops->exec_op && !mem->spi->cs_gpiod) { ret = spi_mem_access_start(mem); if (ret) return ret; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index f4eb447c565d..91f71305817b 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3072,15 +3072,14 @@ static int spi_controller_check_ops(struct spi_controller *ctlr) * The controller may implement only the high-level SPI-memory like * operations if it does not support regular SPI transfers, and this is * valid use case. - * If ->mem_ops is NULL, we request that at least one of the - * ->transfer_xxx() method be implemented. + * If ->mem_ops or ->mem_ops->exec_op is NULL, we request that at least + * one of the ->transfer_xxx() method be implemented. */ - if (ctlr->mem_ops) { - if (!ctlr->mem_ops->exec_op) - return -EINVAL; - } else if (!ctlr->transfer && !ctlr->transfer_one && + if (!ctlr->mem_ops || (ctlr->mem_ops && !ctlr->mem_ops->exec_op)) { + if (!ctlr->transfer && !ctlr->transfer_one && !ctlr->transfer_one_message) { - return -EINVAL; + return -EINVAL; + } } return 0; From c6182a187b33cd00a763ac2490c0f5210b2c4742 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 9 Feb 2023 12:02:44 -0800 Subject: [PATCH 49/65] spi: bcm63xx-hsspi: Disable spi mem dual io read op support In general the controller supports SPI dual mode operation but the particular SPI flash dual io read op switches from single mode in cmd phase to dual mode in address and data phase. This is not compatible with prepend operation where cmd and address are sent out through the prepend buffer and they must use same the number of io pins. This patch disables these SPI flash dual io read ops through the mem_ops supports_op interface. This makes sure the SPI flash driver selects the compatible read ops at run time. Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230209200246.141520-14-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index 6a289deb5848..1e9e906d297c 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -682,6 +684,26 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master, return 0; } +static bool bcm63xx_hsspi_mem_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + if (!spi_mem_default_supports_op(mem, op)) + return false; + + /* Controller doesn't support spi mem dual io mode */ + if ((op->cmd.opcode == SPINOR_OP_READ_1_2_2) || + (op->cmd.opcode == SPINOR_OP_READ_1_2_2_4B) || + (op->cmd.opcode == SPINOR_OP_READ_1_2_2_DTR) || + (op->cmd.opcode == SPINOR_OP_READ_1_2_2_DTR_4B)) + return false; + + return true; +} + +static const struct spi_controller_mem_ops bcm63xx_hsspi_mem_ops = { + .supports_op = bcm63xx_hsspi_mem_supports_op, +}; + static irqreturn_t bcm63xx_hsspi_interrupt(int irq, void *dev_id) { struct bcm63xx_hsspi *bs = (struct bcm63xx_hsspi *)dev_id; @@ -779,6 +801,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) mutex_init(&bs->msg_mutex); init_completion(&bs->done); + master->mem_ops = &bcm63xx_hsspi_mem_ops; master->dev.of_node = dev->of_node; if (!dev->of_node) master->bus_num = HSSPI_BUS_NUM; From a38a2233f23b568ca06ca679fb2327447d6b0224 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 9 Feb 2023 12:02:45 -0800 Subject: [PATCH 50/65] spi: bcmbca-hsspi: Add driver for newer HSSPI controller The newer BCMBCA SoCs such as BCM6756, BCM4912 and BCM6855 include an updated SPI controller that add the capability to allow the driver to control chip select explicitly. Driver can control and keep cs low between the transfers natively. Hence the dummy cs workaround or prepend mode found in the bcm63xx-hsspi driver are no longer needed and this new driver is much cleaner. Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230209200246.141520-15-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 9 + drivers/spi/Makefile | 1 + drivers/spi/spi-bcmbca-hsspi.c | 651 +++++++++++++++++++++++++++++++++ 3 files changed, 661 insertions(+) create mode 100644 drivers/spi/spi-bcmbca-hsspi.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index db033d424bb5..2ede343fde42 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -199,6 +199,15 @@ config SPI_BCM_QSPI based platforms. This driver works for both SPI master for SPI NOR flash device as well as MSPI device. +config SPI_BCMBCA_HSSPI + tristate "Broadcom BCMBCA HS SPI controller driver" + depends on ARCH_BCMBCA || COMPILE_TEST + help + This enables support for the High Speed SPI controller present on + newer Broadcom BCMBCA SoCs. These SoCs include an updated SPI controller + that adds the capability to allow the driver to control chip select + explicitly. + config SPI_BITBANG tristate "Utilities for Bitbanging SPI masters" help diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index be9ba40ef8d0..fe92106447c3 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o obj-$(CONFIG_SPI_BCM2835AUX) += spi-bcm2835aux.o obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o +obj-$(CONFIG_SPI_BCMBCA_HSSPI) += spi-bcmbca-hsspi.o obj-$(CONFIG_SPI_BCM_QSPI) += spi-iproc-qspi.o spi-brcmstb-qspi.o spi-bcm-qspi.o obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o diff --git a/drivers/spi/spi-bcmbca-hsspi.c b/drivers/spi/spi-bcmbca-hsspi.c new file mode 100644 index 000000000000..d58033251c02 --- /dev/null +++ b/drivers/spi/spi-bcmbca-hsspi.c @@ -0,0 +1,651 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Broadcom BCMBCA High Speed SPI Controller driver + * + * Copyright 2000-2010 Broadcom Corporation + * Copyright 2012-2013 Jonas Gorski + * Copyright 2019-2022 Broadcom Ltd + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HSSPI_GLOBAL_CTRL_REG 0x0 +#define GLOBAL_CTRL_CS_POLARITY_SHIFT 0 +#define GLOBAL_CTRL_CS_POLARITY_MASK 0x000000ff +#define GLOBAL_CTRL_PLL_CLK_CTRL_SHIFT 8 +#define GLOBAL_CTRL_PLL_CLK_CTRL_MASK 0x0000ff00 +#define GLOBAL_CTRL_CLK_GATE_SSOFF BIT(16) +#define GLOBAL_CTRL_CLK_POLARITY BIT(17) +#define GLOBAL_CTRL_MOSI_IDLE BIT(18) + +#define HSSPI_GLOBAL_EXT_TRIGGER_REG 0x4 + +#define HSSPI_INT_STATUS_REG 0x8 +#define HSSPI_INT_STATUS_MASKED_REG 0xc +#define HSSPI_INT_MASK_REG 0x10 + +#define HSSPI_PINGx_CMD_DONE(i) BIT((i * 8) + 0) +#define HSSPI_PINGx_RX_OVER(i) BIT((i * 8) + 1) +#define HSSPI_PINGx_TX_UNDER(i) BIT((i * 8) + 2) +#define HSSPI_PINGx_POLL_TIMEOUT(i) BIT((i * 8) + 3) +#define HSSPI_PINGx_CTRL_INVAL(i) BIT((i * 8) + 4) + +#define HSSPI_INT_CLEAR_ALL 0xff001f1f + +#define HSSPI_PINGPONG_COMMAND_REG(x) (0x80 + (x) * 0x40) +#define PINGPONG_CMD_COMMAND_MASK 0xf +#define PINGPONG_COMMAND_NOOP 0 +#define PINGPONG_COMMAND_START_NOW 1 +#define PINGPONG_COMMAND_START_TRIGGER 2 +#define PINGPONG_COMMAND_HALT 3 +#define PINGPONG_COMMAND_FLUSH 4 +#define PINGPONG_CMD_PROFILE_SHIFT 8 +#define PINGPONG_CMD_SS_SHIFT 12 + +#define HSSPI_PINGPONG_STATUS_REG(x) (0x84 + (x) * 0x40) +#define HSSPI_PINGPONG_STATUS_SRC_BUSY BIT(1) + +#define HSSPI_PROFILE_CLK_CTRL_REG(x) (0x100 + (x) * 0x20) +#define CLK_CTRL_FREQ_CTRL_MASK 0x0000ffff +#define CLK_CTRL_SPI_CLK_2X_SEL BIT(14) +#define CLK_CTRL_ACCUM_RST_ON_LOOP BIT(15) +#define CLK_CTRL_CLK_POLARITY BIT(16) + +#define HSSPI_PROFILE_SIGNAL_CTRL_REG(x) (0x104 + (x) * 0x20) +#define SIGNAL_CTRL_LATCH_RISING BIT(12) +#define SIGNAL_CTRL_LAUNCH_RISING BIT(13) +#define SIGNAL_CTRL_ASYNC_INPUT_PATH BIT(16) + +#define HSSPI_PROFILE_MODE_CTRL_REG(x) (0x108 + (x) * 0x20) +#define MODE_CTRL_MULTIDATA_RD_STRT_SHIFT 8 +#define MODE_CTRL_MULTIDATA_WR_STRT_SHIFT 12 +#define MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT 16 +#define MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT 18 +#define MODE_CTRL_MODE_3WIRE BIT(20) +#define MODE_CTRL_PREPENDBYTE_CNT_SHIFT 24 + +#define HSSPI_FIFO_REG(x) (0x200 + (x) * 0x200) + +#define HSSPI_OP_MULTIBIT BIT(11) +#define HSSPI_OP_CODE_SHIFT 13 +#define HSSPI_OP_SLEEP (0 << HSSPI_OP_CODE_SHIFT) +#define HSSPI_OP_READ_WRITE (1 << HSSPI_OP_CODE_SHIFT) +#define HSSPI_OP_WRITE (2 << HSSPI_OP_CODE_SHIFT) +#define HSSPI_OP_READ (3 << HSSPI_OP_CODE_SHIFT) +#define HSSPI_OP_SETIRQ (4 << HSSPI_OP_CODE_SHIFT) + +#define HSSPI_BUFFER_LEN 512 +#define HSSPI_OPCODE_LEN 2 + +#define HSSPI_MAX_PREPEND_LEN 15 + +#define HSSPI_MAX_SYNC_CLOCK 30000000 + +#define HSSPI_SPI_MAX_CS 8 +#define HSSPI_BUS_NUM 1 /* 0 is legacy SPI */ +#define HSSPI_POLL_STATUS_TIMEOUT_MS 100 + +#define HSSPI_WAIT_MODE_POLLING 0 +#define HSSPI_WAIT_MODE_INTR 1 +#define HSSPI_WAIT_MODE_MAX HSSPI_WAIT_MODE_INTR + +#define SPIM_CTRL_CS_OVERRIDE_SEL_SHIFT 0 +#define SPIM_CTRL_CS_OVERRIDE_SEL_MASK 0xff +#define SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT 8 +#define SPIM_CTRL_CS_OVERRIDE_VAL_MASK 0xff + +struct bcmbca_hsspi { + struct completion done; + struct mutex bus_mutex; + struct mutex msg_mutex; + struct platform_device *pdev; + struct clk *clk; + struct clk *pll_clk; + void __iomem *regs; + void __iomem *spim_ctrl; + u8 __iomem *fifo; + u32 speed_hz; + u8 cs_polarity; + u32 wait_mode; +}; + +static ssize_t wait_mode_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct spi_controller *ctrl = dev_get_drvdata(dev); + struct bcmbca_hsspi *bs = spi_master_get_devdata(ctrl); + + return sprintf(buf, "%d\n", bs->wait_mode); +} + +static ssize_t wait_mode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct spi_controller *ctrl = dev_get_drvdata(dev); + struct bcmbca_hsspi *bs = spi_master_get_devdata(ctrl); + u32 val; + + if (kstrtou32(buf, 10, &val)) + return -EINVAL; + + if (val > HSSPI_WAIT_MODE_MAX) { + dev_warn(dev, "invalid wait mode %u\n", val); + return -EINVAL; + } + + mutex_lock(&bs->msg_mutex); + bs->wait_mode = val; + /* clear interrupt status to avoid spurious int on next transfer */ + if (val == HSSPI_WAIT_MODE_INTR) + __raw_writel(HSSPI_INT_CLEAR_ALL, bs->regs + HSSPI_INT_STATUS_REG); + mutex_unlock(&bs->msg_mutex); + + return count; +} + +static DEVICE_ATTR_RW(wait_mode); + +static struct attribute *bcmbca_hsspi_attrs[] = { + &dev_attr_wait_mode.attr, + NULL, +}; + +static const struct attribute_group bcmbca_hsspi_group = { + .attrs = bcmbca_hsspi_attrs, +}; + +static void bcmbca_hsspi_set_cs(struct bcmbca_hsspi *bs, unsigned int cs, + bool active) +{ + u32 reg; + + /* No cs orerriden needed for SS7 internal cs on pcm based voice dev */ + if (cs == 7) + return; + + mutex_lock(&bs->bus_mutex); + + reg = __raw_readl(bs->spim_ctrl); + if (active) + reg |= BIT(cs + SPIM_CTRL_CS_OVERRIDE_SEL_SHIFT); + else + reg &= ~BIT(cs + SPIM_CTRL_CS_OVERRIDE_SEL_SHIFT); + + __raw_writel(reg, bs->spim_ctrl); + + mutex_unlock(&bs->bus_mutex); +} + +static void bcmbca_hsspi_set_clk(struct bcmbca_hsspi *bs, + struct spi_device *spi, int hz) +{ + unsigned int profile = spi->chip_select; + u32 reg; + + reg = DIV_ROUND_UP(2048, DIV_ROUND_UP(bs->speed_hz, hz)); + __raw_writel(CLK_CTRL_ACCUM_RST_ON_LOOP | reg, + bs->regs + HSSPI_PROFILE_CLK_CTRL_REG(profile)); + + reg = __raw_readl(bs->regs + HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); + if (hz > HSSPI_MAX_SYNC_CLOCK) + reg |= SIGNAL_CTRL_ASYNC_INPUT_PATH; + else + reg &= ~SIGNAL_CTRL_ASYNC_INPUT_PATH; + __raw_writel(reg, bs->regs + HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); + + mutex_lock(&bs->bus_mutex); + /* setup clock polarity */ + reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG); + reg &= ~GLOBAL_CTRL_CLK_POLARITY; + if (spi->mode & SPI_CPOL) + reg |= GLOBAL_CTRL_CLK_POLARITY; + __raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG); + + mutex_unlock(&bs->bus_mutex); +} + +static int bcmbca_hsspi_wait_cmd(struct bcmbca_hsspi *bs, unsigned int cs) +{ + unsigned long limit; + u32 reg = 0; + int rc = 0; + + if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) { + if (wait_for_completion_timeout(&bs->done, HZ) == 0) + rc = 1; + } else { + limit = jiffies + msecs_to_jiffies(HSSPI_POLL_STATUS_TIMEOUT_MS); + + while (!time_after(jiffies, limit)) { + reg = __raw_readl(bs->regs + HSSPI_PINGPONG_STATUS_REG(0)); + if (reg & HSSPI_PINGPONG_STATUS_SRC_BUSY) + cpu_relax(); + else + break; + } + if (reg & HSSPI_PINGPONG_STATUS_SRC_BUSY) + rc = 1; + } + + if (rc) + dev_err(&bs->pdev->dev, "transfer timed out!\n"); + + return rc; +} + +static int bcmbca_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t, + struct spi_message *msg) +{ + struct bcmbca_hsspi *bs = spi_master_get_devdata(spi->master); + unsigned int chip_select = spi->chip_select; + u16 opcode = 0; + int pending = t->len; + int step_size = HSSPI_BUFFER_LEN; + const u8 *tx = t->tx_buf; + u8 *rx = t->rx_buf; + u32 reg = 0, cs_act = 0; + + bcmbca_hsspi_set_clk(bs, spi, t->speed_hz); + + if (tx && rx) + opcode = HSSPI_OP_READ_WRITE; + else if (tx) + opcode = HSSPI_OP_WRITE; + else if (rx) + opcode = HSSPI_OP_READ; + + if (opcode != HSSPI_OP_READ) + step_size -= HSSPI_OPCODE_LEN; + + if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) || + (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) { + opcode |= HSSPI_OP_MULTIBIT; + + if (t->rx_nbits == SPI_NBITS_DUAL) + reg |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT; + if (t->tx_nbits == SPI_NBITS_DUAL) + reg |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT; + } + + __raw_writel(reg | 0xff, + bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); + + while (pending > 0) { + int curr_step = min_t(int, step_size, pending); + + reinit_completion(&bs->done); + if (tx) { + memcpy_toio(bs->fifo + HSSPI_OPCODE_LEN, tx, curr_step); + tx += curr_step; + } + __raw_writew((u16)cpu_to_be16(opcode | curr_step), bs->fifo); + + /* enable interrupt */ + if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) + __raw_writel(HSSPI_PINGx_CMD_DONE(0), + bs->regs + HSSPI_INT_MASK_REG); + + if (!cs_act) { + /* must apply cs signal as close as the cmd starts */ + bcmbca_hsspi_set_cs(bs, chip_select, true); + cs_act = 1; + } + + reg = chip_select << PINGPONG_CMD_SS_SHIFT | + chip_select << PINGPONG_CMD_PROFILE_SHIFT | + PINGPONG_COMMAND_START_NOW; + __raw_writel(reg, bs->regs + HSSPI_PINGPONG_COMMAND_REG(0)); + + if (bcmbca_hsspi_wait_cmd(bs, spi->chip_select)) + return -ETIMEDOUT; + + pending -= curr_step; + + if (rx) { + memcpy_fromio(rx, bs->fifo, curr_step); + rx += curr_step; + } + } + + return 0; +} + +static int bcmbca_hsspi_setup(struct spi_device *spi) +{ + struct bcmbca_hsspi *bs = spi_master_get_devdata(spi->master); + u32 reg; + + reg = __raw_readl(bs->regs + + HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); + reg &= ~(SIGNAL_CTRL_LAUNCH_RISING | SIGNAL_CTRL_LATCH_RISING); + if (spi->mode & SPI_CPHA) + reg |= SIGNAL_CTRL_LAUNCH_RISING; + else + reg |= SIGNAL_CTRL_LATCH_RISING; + __raw_writel(reg, bs->regs + + HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); + + mutex_lock(&bs->bus_mutex); + reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG); + + if (spi->mode & SPI_CS_HIGH) + reg |= BIT(spi->chip_select); + else + reg &= ~BIT(spi->chip_select); + __raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG); + + if (spi->mode & SPI_CS_HIGH) + bs->cs_polarity |= BIT(spi->chip_select); + else + bs->cs_polarity &= ~BIT(spi->chip_select); + + reg = __raw_readl(bs->spim_ctrl); + reg &= ~BIT(spi->chip_select + SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT); + if (spi->mode & SPI_CS_HIGH) + reg |= BIT(spi->chip_select + SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT); + __raw_writel(reg, bs->spim_ctrl); + + mutex_unlock(&bs->bus_mutex); + + return 0; +} + +static int bcmbca_hsspi_transfer_one(struct spi_master *master, + struct spi_message *msg) +{ + struct bcmbca_hsspi *bs = spi_master_get_devdata(master); + struct spi_transfer *t; + struct spi_device *spi = msg->spi; + int status = -EINVAL; + bool keep_cs = false; + + mutex_lock(&bs->msg_mutex); + list_for_each_entry(t, &msg->transfers, transfer_list) { + status = bcmbca_hsspi_do_txrx(spi, t, msg); + if (status) + break; + + spi_transfer_delay_exec(t); + + if (t->cs_change) { + if (list_is_last(&t->transfer_list, &msg->transfers)) { + keep_cs = true; + } else { + if (!t->cs_off) + bcmbca_hsspi_set_cs(bs, spi->chip_select, false); + + spi_transfer_cs_change_delay_exec(msg, t); + + if (!list_next_entry(t, transfer_list)->cs_off) + bcmbca_hsspi_set_cs(bs, spi->chip_select, true); + } + } else if (!list_is_last(&t->transfer_list, &msg->transfers) && + t->cs_off != list_next_entry(t, transfer_list)->cs_off) { + bcmbca_hsspi_set_cs(bs, spi->chip_select, t->cs_off); + } + + msg->actual_length += t->len; + } + + mutex_unlock(&bs->msg_mutex); + + if (status || !keep_cs) + bcmbca_hsspi_set_cs(bs, spi->chip_select, false); + + msg->status = status; + spi_finalize_current_message(master); + + return 0; +} + +static irqreturn_t bcmbca_hsspi_interrupt(int irq, void *dev_id) +{ + struct bcmbca_hsspi *bs = (struct bcmbca_hsspi *)dev_id; + + if (__raw_readl(bs->regs + HSSPI_INT_STATUS_MASKED_REG) == 0) + return IRQ_NONE; + + __raw_writel(HSSPI_INT_CLEAR_ALL, bs->regs + HSSPI_INT_STATUS_REG); + __raw_writel(0, bs->regs + HSSPI_INT_MASK_REG); + + complete(&bs->done); + + return IRQ_HANDLED; +} + +static int bcmbca_hsspi_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct bcmbca_hsspi *bs; + struct resource *res_mem; + void __iomem *spim_ctrl; + void __iomem *regs; + struct device *dev = &pdev->dev; + struct clk *clk, *pll_clk = NULL; + int irq, ret; + u32 reg, rate, num_cs = HSSPI_SPI_MAX_CS; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsspi"); + if (!res_mem) + return -EINVAL; + regs = devm_ioremap_resource(dev, res_mem); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spim-ctrl"); + if (!res_mem) + return -EINVAL; + spim_ctrl = devm_ioremap_resource(dev, res_mem); + if (IS_ERR(spim_ctrl)) + return PTR_ERR(spim_ctrl); + + clk = devm_clk_get(dev, "hsspi"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + ret = clk_prepare_enable(clk); + if (ret) + return ret; + + rate = clk_get_rate(clk); + if (!rate) { + pll_clk = devm_clk_get(dev, "pll"); + + if (IS_ERR(pll_clk)) { + ret = PTR_ERR(pll_clk); + goto out_disable_clk; + } + + ret = clk_prepare_enable(pll_clk); + if (ret) + goto out_disable_clk; + + rate = clk_get_rate(pll_clk); + if (!rate) { + ret = -EINVAL; + goto out_disable_pll_clk; + } + } + + master = spi_alloc_master(&pdev->dev, sizeof(*bs)); + if (!master) { + ret = -ENOMEM; + goto out_disable_pll_clk; + } + + bs = spi_master_get_devdata(master); + bs->pdev = pdev; + bs->clk = clk; + bs->pll_clk = pll_clk; + bs->regs = regs; + bs->spim_ctrl = spim_ctrl; + bs->speed_hz = rate; + bs->fifo = (u8 __iomem *) (bs->regs + HSSPI_FIFO_REG(0)); + bs->wait_mode = HSSPI_WAIT_MODE_POLLING; + + mutex_init(&bs->bus_mutex); + mutex_init(&bs->msg_mutex); + init_completion(&bs->done); + + master->dev.of_node = dev->of_node; + if (!dev->of_node) + master->bus_num = HSSPI_BUS_NUM; + + of_property_read_u32(dev->of_node, "num-cs", &num_cs); + if (num_cs > 8) { + dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n", + num_cs); + num_cs = HSSPI_SPI_MAX_CS; + } + master->num_chipselect = num_cs; + master->setup = bcmbca_hsspi_setup; + master->transfer_one_message = bcmbca_hsspi_transfer_one; + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | + SPI_RX_DUAL | SPI_TX_DUAL; + master->bits_per_word_mask = SPI_BPW_MASK(8); + master->auto_runtime_pm = true; + + platform_set_drvdata(pdev, master); + + /* Initialize the hardware */ + __raw_writel(0, bs->regs + HSSPI_INT_MASK_REG); + + /* clean up any pending interrupts */ + __raw_writel(HSSPI_INT_CLEAR_ALL, bs->regs + HSSPI_INT_STATUS_REG); + + /* read out default CS polarities */ + reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG); + bs->cs_polarity = reg & GLOBAL_CTRL_CS_POLARITY_MASK; + __raw_writel(reg | GLOBAL_CTRL_CLK_GATE_SSOFF, + bs->regs + HSSPI_GLOBAL_CTRL_REG); + + if (irq > 0) { + ret = devm_request_irq(dev, irq, bcmbca_hsspi_interrupt, IRQF_SHARED, + pdev->name, bs); + if (ret) + goto out_put_master; + } + + pm_runtime_enable(&pdev->dev); + + if (sysfs_create_group(&pdev->dev.kobj, &bcmbca_hsspi_group)) { + dev_err(&pdev->dev, "couldn't register sysfs group\n"); + goto out_pm_disable; + } + + /* register and we are done */ + ret = devm_spi_register_master(dev, master); + if (ret) + goto out_sysgroup_disable; + + dev_info(dev, "Broadcom BCMBCA High Speed SPI Controller driver"); + + return 0; + +out_sysgroup_disable: + sysfs_remove_group(&pdev->dev.kobj, &bcmbca_hsspi_group); +out_pm_disable: + pm_runtime_disable(&pdev->dev); +out_put_master: + spi_master_put(master); +out_disable_pll_clk: + clk_disable_unprepare(pll_clk); +out_disable_clk: + clk_disable_unprepare(clk); + return ret; +} + +static int bcmbca_hsspi_remove(struct platform_device *pdev) +{ + struct spi_master *master = platform_get_drvdata(pdev); + struct bcmbca_hsspi *bs = spi_master_get_devdata(master); + + /* reset the hardware and block queue progress */ + __raw_writel(0, bs->regs + HSSPI_INT_MASK_REG); + clk_disable_unprepare(bs->pll_clk); + clk_disable_unprepare(bs->clk); + sysfs_remove_group(&pdev->dev.kobj, &bcmbca_hsspi_group); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int bcmbca_hsspi_suspend(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct bcmbca_hsspi *bs = spi_master_get_devdata(master); + + spi_master_suspend(master); + clk_disable_unprepare(bs->pll_clk); + clk_disable_unprepare(bs->clk); + + return 0; +} + +static int bcmbca_hsspi_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct bcmbca_hsspi *bs = spi_master_get_devdata(master); + int ret; + + ret = clk_prepare_enable(bs->clk); + if (ret) + return ret; + + if (bs->pll_clk) { + ret = clk_prepare_enable(bs->pll_clk); + if (ret) { + clk_disable_unprepare(bs->clk); + return ret; + } + } + + spi_master_resume(master); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(bcmbca_hsspi_pm_ops, bcmbca_hsspi_suspend, + bcmbca_hsspi_resume); + +static const struct of_device_id bcmbca_hsspi_of_match[] = { + { .compatible = "brcm,bcmbca-hsspi-v1.1", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, bcmbca_hsspi_of_match); + +static struct platform_driver bcmbca_hsspi_driver = { + .driver = { + .name = "bcmbca-hsspi", + .pm = &bcmbca_hsspi_pm_ops, + .of_match_table = bcmbca_hsspi_of_match, + }, + .probe = bcmbca_hsspi_probe, + .remove = bcmbca_hsspi_remove, +}; + +module_platform_driver(bcmbca_hsspi_driver); + +MODULE_ALIAS("platform:bcmbca_hsspi"); +MODULE_DESCRIPTION("Broadcom BCMBCA High Speed SPI Controller driver"); +MODULE_LICENSE("GPL"); From 80323599e33f9c19287a1a3707481fb157b27052 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 9 Feb 2023 12:02:46 -0800 Subject: [PATCH 51/65] MAINTAINERS: Add entry for Broadcom Broadband SoC HS SPI drivers The driver and device tree doc were originally authored by Jonas Gorski and it has been updated from Broadcom recently including the dts yaml file and a new driver for the updated controller. Add Jonas Gorski and Broadcom engineers William Zhang and Kursad Oney as the maintainers. Signed-off-by: William Zhang Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/20230209200246.141520-16-william.zhang@broadcom.com Signed-off-by: Mark Brown --- MAINTAINERS | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index f61eb221415b..c6a2c3175ea3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4299,6 +4299,18 @@ L: linux-kernel@vger.kernel.org S: Maintained F: drivers/phy/broadcom/phy-brcm-usb* +BROADCOM Broadband SoC High Speed SPI Controller DRIVER +M: William Zhang +M: Kursad Oney +M: Jonas Gorski +R: Broadcom internal kernel review list +L: linux-spi@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi-peripheral-props.yaml +F: Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml +F: drivers/spi/spi-bcm63xx-hsspi.c +F: drivers/spi/spi-bcmbca-hsspi.c + BROADCOM ETHERNET PHY DRIVERS M: Florian Fainelli R: Broadcom internal kernel review list From 2cca486cad4bf51da57cdad150697476a702ab69 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Fri, 10 Feb 2023 19:27:59 -0800 Subject: [PATCH 52/65] spi: bcm63xx-hsspi: bcmbca-hsspi: fix _be16 type usage sparse tool report warnings: drivers/spi/spi-bcm63xx-hsspi.c:197:31: sparse: sparse: cast from restricted __be16. The controller requires big endian 16 bit data. Define an intermediate u16 value and use __be16 piointer dereferncing for the data to avoid directly casting to u16 and sparse warning. Fixes: 85a84a616999 ("spi: bcm63xx-hsspi: Endianness fix for ARM based SoC") Reported-by: kernel test robot Link: https://lore.kernel.org/oe-kbuild-all/202302110438.sQwQnU54-lkp@intel.com/ Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230211032759.72967-1-william.zhang@broadcom.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 10 ++++++---- drivers/spi/spi-bcmbca-hsspi.c | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index 1e9e906d297c..68093c045e0b 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -350,7 +350,7 @@ static int bcm63xx_hsspi_do_prepend_txrx(struct spi_device *spi, { struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master); unsigned int chip_select = spi->chip_select; - u16 opcode = 0; + u16 opcode = 0, val; const u8 *tx = t->tx_buf; u8 *rx = t->rx_buf; u32 reg = 0; @@ -401,7 +401,8 @@ static int bcm63xx_hsspi_do_prepend_txrx(struct spi_device *spi, memcpy_toio(bs->fifo + HSSPI_OPCODE_LEN + bs->prepend_cnt, tx, t->len); - __raw_writew((u16)cpu_to_be16(opcode | t->len), bs->fifo); + *(__be16 *)(&val) = cpu_to_be16(opcode | t->len); + __raw_writew(val, bs->fifo); /* enable interrupt */ if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) __raw_writel(HSSPI_PINGx_CMD_DONE(0), bs->regs + HSSPI_INT_MASK_REG); @@ -468,7 +469,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) { struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master); unsigned int chip_select = spi->chip_select; - u16 opcode = 0; + u16 opcode = 0, val; int pending = t->len; int step_size = HSSPI_BUFFER_LEN; const u8 *tx = t->tx_buf; @@ -511,7 +512,8 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) tx += curr_step; } - __raw_writew((u16)cpu_to_be16(opcode | curr_step), bs->fifo); + *(__be16 *)(&val) = cpu_to_be16(opcode | curr_step); + __raw_writew(val, bs->fifo); /* enable interrupt */ if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) diff --git a/drivers/spi/spi-bcmbca-hsspi.c b/drivers/spi/spi-bcmbca-hsspi.c index d58033251c02..e255241319ab 100644 --- a/drivers/spi/spi-bcmbca-hsspi.c +++ b/drivers/spi/spi-bcmbca-hsspi.c @@ -252,7 +252,7 @@ static int bcmbca_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t, { struct bcmbca_hsspi *bs = spi_master_get_devdata(spi->master); unsigned int chip_select = spi->chip_select; - u16 opcode = 0; + u16 opcode = 0, val; int pending = t->len; int step_size = HSSPI_BUFFER_LEN; const u8 *tx = t->tx_buf; @@ -292,7 +292,9 @@ static int bcmbca_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t, memcpy_toio(bs->fifo + HSSPI_OPCODE_LEN, tx, curr_step); tx += curr_step; } - __raw_writew((u16)cpu_to_be16(opcode | curr_step), bs->fifo); + + *(__be16 *)(&val) = cpu_to_be16(opcode | curr_step); + __raw_writew(val, bs->fifo); /* enable interrupt */ if (bs->wait_mode == HSSPI_WAIT_MODE_INTR) From 937ca916bf4de427242fb78105a0089af0dd43b3 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Sun, 12 Feb 2023 12:50:54 -0800 Subject: [PATCH 53/65] MAINTAINERS: Remove file reference for Broadcom Broadband SoC HS SPI driver entry brcm,bcm63xx-hsspi-peripheral-props.yaml is not in use at least for now. Remove it from the maintainer entry. Fixes: 80323599e33f ("MAINTAINERS: Add entry for Broadcom Broadband SoC HS SPI drivers") Reported-by: kernel test robot https://lore.kernel.org/oe-kbuild-all/202302121840.GtduUT37-lkp@intel.com/ Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230212205054.26348-1-william.zhang@broadcom.com Signed-off-by: Mark Brown --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index c6a2c3175ea3..df1c71ca1a69 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4306,7 +4306,6 @@ M: Jonas Gorski R: Broadcom internal kernel review list L: linux-spi@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi-peripheral-props.yaml F: Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml F: drivers/spi/spi-bcm63xx-hsspi.c F: drivers/spi/spi-bcmbca-hsspi.c From d4f43a2d05faf7febb839edb2e9e8f85dfb9d2d2 Mon Sep 17 00:00:00 2001 From: Dhruva Gole Date: Wed, 25 Jan 2023 13:40:20 +0530 Subject: [PATCH 54/65] spi: cadence-quadspi: Reset CMD_CTRL Reg on cmd r/w completion If one leaves the CQSPI_REG_CMDCTRL in an unclean state this may cause issues in future command reads. This issue came to light when some flash reads in STIG mode were coming back dirty. Signed-off-by: Dhruva Gole Link: https://lore.kernel.org/r/20230125081023.1573712-2-d-gole@ti.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 676313e1bdad..6030da942c6e 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -549,6 +549,9 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata, memcpy(rxbuf, ®, read_len); } + /* Reset CMD_CTRL Reg once command read completes */ + writel(0, reg_base + CQSPI_REG_CMDCTRL); + return 0; } @@ -613,7 +616,12 @@ static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata, } } - return cqspi_exec_flash_cmd(cqspi, reg); + ret = cqspi_exec_flash_cmd(cqspi, reg); + + /* Reset CMD_CTRL Reg once command write completes */ + writel(0, reg_base + CQSPI_REG_CMDCTRL); + + return ret; } static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata, From e8c51b164355c1d519a4b8ad0873f131035d26b7 Mon Sep 17 00:00:00 2001 From: Dhruva Gole Date: Wed, 25 Jan 2023 13:40:21 +0530 Subject: [PATCH 55/65] spi: cadence-quadspi: Add flag for direct mode writes Create new flag inorder to avoid playing with use_direct_mode flag currently being used throughout the driver. Disable DAC write if auto polling is disabled or CQSPI_DISABLE_DAC_MODE is set. Signed-off-by: Dhruva Gole Link: https://lore.kernel.org/r/20230125081023.1573712-3-d-gole@ti.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 6030da942c6e..4bbf6e3ad34a 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -84,6 +84,7 @@ struct cqspi_st { u32 trigger_address; u32 wr_delay; bool use_direct_mode; + bool use_direct_mode_wr; struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT]; bool use_dma_read; u32 pd_dev_id; @@ -945,6 +946,12 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata, reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL); reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL; writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL); + /* + * DAC mode require auto polling as flash needs to be polled + * for write completion in case of bubble in SPI transaction + * due to slow CPU/DMA master. + */ + cqspi->use_direct_mode_wr = false; } reg = readl(reg_base + CQSPI_REG_SIZE); @@ -1230,7 +1237,7 @@ static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata, * data. */ if (!op->cmd.dtr && cqspi->use_direct_mode && - ((to + len) <= cqspi->ahb_size)) { + cqspi->use_direct_mode_wr && ((to + len) <= cqspi->ahb_size)) { memcpy_toio(cqspi->ahb_base + to, buf, len); return cqspi_wait_idle(cqspi); } @@ -1700,8 +1707,10 @@ static int cqspi_probe(struct platform_device *pdev) cqspi->master_ref_clk_hz); if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL) master->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL; - if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) + if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) { cqspi->use_direct_mode = true; + cqspi->use_direct_mode_wr = true; + } if (ddata->quirks & CQSPI_SUPPORT_EXTERNAL_DMA) cqspi->use_dma_read = true; if (ddata->quirks & CQSPI_NO_SUPPORT_WR_COMPLETION) From a8674ae02db232927385c2d0a063e10c0118f5ca Mon Sep 17 00:00:00 2001 From: Dhruva Gole Date: Wed, 25 Jan 2023 13:40:22 +0530 Subject: [PATCH 56/65] spi: cadence-quadspi: setup ADDR Bits in cmd reads Setup the Addr bit field while issuing register reads in STIG mode. This is needed for example flashes like cypress define in their transaction table that to read any register there is 1 cmd byte and a few more address bytes trailing the cmd byte. Absence of addr bytes will obviously fail to read correct data from flash register that maybe requested by flash driver because the controller doesn't even specify which address of the flash register the read is being requested from. Signed-off-by: Dhruva Gole Link: https://lore.kernel.org/r/20230125081023.1573712-4-d-gole@ti.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 4bbf6e3ad34a..a6d0f1b0bb49 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -532,6 +532,17 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata, /* 0 means 1 byte. */ reg |= (((n_rx - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) << CQSPI_REG_CMDCTRL_RD_BYTES_LSB); + + /* setup ADDR BIT field */ + if (op->addr.nbytes) { + reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB); + reg |= ((op->addr.nbytes - 1) & + CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) + << CQSPI_REG_CMDCTRL_ADD_BYTES_LSB; + + writel(op->addr.val, reg_base + CQSPI_REG_CMDADDRESS); + } + status = cqspi_exec_flash_cmd(cqspi, reg); if (status) return status; From d403fb6e76bf854ef0f7d84e797e51b9494788e0 Mon Sep 17 00:00:00 2001 From: Dhruva Gole Date: Wed, 25 Jan 2023 13:40:23 +0530 Subject: [PATCH 57/65] spi: cadence-quadspi: use STIG mode for small reads Fix the issue where some flash chips like cypress S25HS256T return the value of the same register over and over in DAC mode. For example in the TI K3-AM62x Processors refer [0] Technical Reference Manual there is a layer of digital logic in front of the QSPI/OSPI Drive when used in DAC mode. This is part of the Flash Subsystem (FSS) which provides access to external Flash devices. The FSS0_0_SYSCONFIG Register (Offset = 4h) has a BIT Field for OSPI_32B_DISABLE_MODE which has a Reset value = 0. This means, OSPI 32bit mode enabled by default. Thus, by default controller operates in 32 bit mode causing it to always align all data to 4 bytes from a 4byte aligned address. In some flash chips like cypress for example if we try to read some regs in DAC mode then it keeps sending the value of the first register that was requested and inorder to read the next reg, we have to stop and re-initiate a new transaction. This causes wrong register values to be read than what is desired when registers are read in DAC mode. Hence if the data.nbytes is very less then prefer STIG mode for such small reads. [0] https://www.ti.com/lit/ug/spruiv7a/spruiv7a.pdf Signed-off-by: Dhruva Gole Link: https://lore.kernel.org/r/20230125081023.1573712-5-d-gole@ti.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index a6d0f1b0bb49..2954c06a7f57 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1359,7 +1359,13 @@ static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op) cqspi_configure(f_pdata, mem->spi->max_speed_hz); if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) { - if (!op->addr.nbytes) + /* + * Performing reads in DAC mode forces to read minimum 4 bytes + * which is unsupported on some flash devices during register + * reads, prefer STIG mode for such small reads. + */ + if (!op->addr.nbytes || + op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX) return cqspi_command_read(f_pdata, op); return cqspi_read(f_pdata, op); From 9d77522b45246c3dc5950b9641aea49ce3c973d7 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 14 Feb 2023 11:34:50 +0100 Subject: [PATCH 58/65] spi: Reorder fields in 'struct spi_transfer' Group some variables based on their sizes to reduce hole and avoid padding. On x86_64, this shrinks the size from 144 to 128 bytes. Turn 'timestamped' into a bitfield so that it can be easily merged with some other bifields and move 'error'. This should have no real impact on memory allocation because 'struct spi_transfer' is mostly used on stack, but it can save a few cycles when the structure is initialized or copied. Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/93a051da85a895bc6003aedfb00a13e1c2fc6338.1676370870.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown --- drivers/spi/spi.c | 2 +- include/linux/spi/spi.h | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 91f71305817b..5866bf5813a4 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1927,7 +1927,7 @@ void spi_take_timestamp_post(struct spi_controller *ctlr, /* Capture the resolution of the timestamp */ xfer->ptp_sts_word_post = progress; - xfer->timestamped = true; + xfer->timestamped = 1; } EXPORT_SYMBOL_GPL(spi_take_timestamp_post); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 88cb2a1390ce..a08c20bd833b 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1022,6 +1022,9 @@ struct spi_transfer { void *rx_buf; unsigned len; +#define SPI_TRANS_FAIL_NO_START BIT(0) + u16 error; + dma_addr_t tx_dma; dma_addr_t rx_dma; struct sg_table tx_sg; @@ -1032,6 +1035,7 @@ struct spi_transfer { unsigned cs_change:1; unsigned tx_nbits:3; unsigned rx_nbits:3; + unsigned timestamped:1; #define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */ #define SPI_NBITS_DUAL 0x02 /* 2bits transfer */ #define SPI_NBITS_QUAD 0x04 /* 4bits transfer */ @@ -1048,12 +1052,7 @@ struct spi_transfer { struct ptp_system_timestamp *ptp_sts; - bool timestamped; - struct list_head transfer_list; - -#define SPI_TRANS_FAIL_NO_START BIT(0) - u16 error; }; /** From 7ec844a2c7535e4c4991e7e453baca85e156f7c1 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 13 Feb 2023 20:23:48 +0100 Subject: [PATCH 59/65] spi: spi-st-ssc: convert to DT schema Convert spi-st-ssc.txt into st,ssc-spi.yaml for the ST Microelectronics SSC SPI driver. Signed-off-by: Alain Volmat Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230213192349.17101-1-avolmat@me.com Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-st-ssc.txt | 40 ------------ .../devicetree/bindings/spi/st,ssc-spi.yaml | 61 +++++++++++++++++++ MAINTAINERS | 1 + 3 files changed, 62 insertions(+), 40 deletions(-) delete mode 100644 Documentation/devicetree/bindings/spi/spi-st-ssc.txt create mode 100644 Documentation/devicetree/bindings/spi/st,ssc-spi.yaml diff --git a/Documentation/devicetree/bindings/spi/spi-st-ssc.txt b/Documentation/devicetree/bindings/spi/spi-st-ssc.txt deleted file mode 100644 index 1bdc4709e474..000000000000 --- a/Documentation/devicetree/bindings/spi/spi-st-ssc.txt +++ /dev/null @@ -1,40 +0,0 @@ -STMicroelectronics SSC (SPI) Controller ---------------------------------------- - -Required properties: -- compatible : "st,comms-ssc4-spi" -- reg : Offset and length of the device's register set -- interrupts : The interrupt specifier -- clock-names : Must contain "ssc" -- clocks : Must contain an entry for each name in clock-names - See ../clk/* -- pinctrl-names : Uses "default", can use "sleep" if provided - See ../pinctrl/pinctrl-bindings.txt - -Optional properties: -- cs-gpios : List of GPIO chip selects - See ../spi/spi-bus.txt - -Child nodes represent devices on the SPI bus - See ../spi/spi-bus.txt - -Example: - spi@9840000 { - compatible = "st,comms-ssc4-spi"; - reg = <0x9840000 0x110>; - interrupts = ; - clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>; - clock-names = "ssc"; - pinctrl-0 = <&pinctrl_spi0_default>; - pinctrl-names = "default"; - cs-gpios = <&pio17 5 0>; - #address-cells = <1>; - #size-cells = <0>; - - st95hf@0{ - compatible = "st,st95hf"; - reg = <0>; - spi-max-frequency = <1000000>; - interrupts = <2 IRQ_TYPE_EDGE_FALLING>; - }; - }; diff --git a/Documentation/devicetree/bindings/spi/st,ssc-spi.yaml b/Documentation/devicetree/bindings/spi/st,ssc-spi.yaml new file mode 100644 index 000000000000..6a77cd3f5d6e --- /dev/null +++ b/Documentation/devicetree/bindings/spi/st,ssc-spi.yaml @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/st,ssc-spi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: STMicroelectronics SSC SPI Controller + +description: | + The STMicroelectronics SSC SPI controller can be found on STi platforms + and it used to communicate with external devices using the + Serial Peripheral Interface. + +maintainers: + - Patrice Chotard + +allOf: + - $ref: spi-controller.yaml# + +properties: + compatible: + const: st,comms-ssc4-spi + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: ssc + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + #include + spi@9840000 { + compatible = "st,comms-ssc4-spi"; + reg = <0x9840000 0x110>; + interrupts = ; + clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>; + clock-names = "ssc"; + pinctrl-0 = <&pinctrl_spi0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + }; + +... diff --git a/MAINTAINERS b/MAINTAINERS index df1c71ca1a69..daa33e7bb457 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2925,6 +2925,7 @@ M: Patrice Chotard L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained W: http://www.stlinux.com +F: Documentation/devicetree/bindings/spi/st,ssc-spi.yaml F: Documentation/devicetree/bindings/i2c/i2c-st.txt F: arch/arm/boot/dts/sti* F: arch/arm/mach-sti/ From 1dd46599f83ac5323a175d32955b1270e95cd11b Mon Sep 17 00:00:00 2001 From: Vadim Fedorenko Date: Tue, 14 Feb 2023 05:59:28 -0800 Subject: [PATCH 60/65] spi: xilinx: add force_irq for QSPI mode Xilinx PG158 page 80 [1] states that master transaction inhibit bit must be set to properly setup the transaction in QSPI mode. Add the force_irq flag to follow this sequence. [1] https://docs.xilinx.com/r/en-US/pg153-axi-quad-spi/Dual/Quad-SPI-Mode-Transactions Signed-off-by: Vadim Fedorenko Link: https://lore.kernel.org/r/20230214135928.1253205-1-vadfed@meta.com Signed-off-by: Mark Brown --- drivers/spi/spi-xilinx.c | 9 +++++++-- include/linux/spi/xilinx_spi.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 7377d3b81302..1411548f4255 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -83,7 +83,7 @@ struct xilinx_spi { void __iomem *regs; /* virt. address of the control registers */ int irq; - + bool force_irq; /* force irq to setup master inhibit */ u8 *rx_ptr; /* pointer in the Tx buffer */ const u8 *tx_ptr; /* pointer in the Rx buffer */ u8 bytes_per_word; @@ -248,7 +248,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) xspi->rx_ptr = t->rx_buf; remaining_words = t->len / xspi->bytes_per_word; - if (xspi->irq >= 0 && remaining_words > xspi->buffer_size) { + if (xspi->irq >= 0 && + (xspi->force_irq || remaining_words > xspi->buffer_size)) { u32 isr; use_irq = true; /* Inhibit irq to avoid spurious irqs on tx_empty*/ @@ -393,6 +394,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) struct resource *res; int ret, num_cs = 0, bits_per_word; struct spi_master *master; + bool force_irq = false; u32 tmp; u8 i; @@ -400,6 +402,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) if (pdata) { num_cs = pdata->num_chipselect; bits_per_word = pdata->bits_per_word; + force_irq = pdata->force_irq; } else { of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits", &num_cs); @@ -477,6 +480,8 @@ static int xilinx_spi_probe(struct platform_device *pdev) dev_name(&pdev->dev), xspi); if (ret) return ret; + + xspi->force_irq = force_irq; } /* SPI controller initializations */ diff --git a/include/linux/spi/xilinx_spi.h b/include/linux/spi/xilinx_spi.h index c15d69d28e68..3934ce789d87 100644 --- a/include/linux/spi/xilinx_spi.h +++ b/include/linux/spi/xilinx_spi.h @@ -15,6 +15,7 @@ struct xspi_platform_data { u8 bits_per_word; struct spi_board_info *devices; u8 num_devices; + bool force_irq; }; #endif /* __LINUX_SPI_XILINX_SPI_H */ From e6a0b671880207566e1ece983bf989dde60bc1d7 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 15 Feb 2023 14:01:28 +0100 Subject: [PATCH 61/65] spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one() wait_for_completion_timeout() never returns a <0 value. It returns either on timeout or a positive value (at least 1, or number of jiffies left till timeout) So, fix the error handling path and return -ETIMEDOUT should a timeout occur. Fixes: b0823ee35cf9 ("spi: Add spi driver for Socionext SynQuacer platform") Signed-off-by: Christophe JAILLET Acked-by: Jassi Brar Link: https://lore.kernel.org/r/c2040bf3cfa201fd8890cfab14fa5a701ffeca14.1676466072.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown --- drivers/spi/spi-synquacer.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c index 47cbe73137c2..dc188f9202c9 100644 --- a/drivers/spi/spi-synquacer.c +++ b/drivers/spi/spi-synquacer.c @@ -472,10 +472,9 @@ static int synquacer_spi_transfer_one(struct spi_master *master, read_fifo(sspi); } - if (status < 0) { - dev_err(sspi->dev, "failed to transfer. status: 0x%x\n", - status); - return status; + if (status == 0) { + dev_err(sspi->dev, "failed to transfer. Timeout.\n"); + return -ETIMEDOUT; } return 0; From 0696532e12524855fa8044590d374079f271f216 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 Feb 2023 17:05:32 +0300 Subject: [PATCH 62/65] spi: bcmbca-hsspi: Fix error code in probe() function This code accidentally returns success instead of a negative error code. Fixes: a38a2233f23b ("spi: bcmbca-hsspi: Add driver for newer HSSPI controller") Signed-off-by: Dan Carpenter Reviewed-by: Florian Fainelli Reviewed-by: William Zhang Link: https://lore.kernel.org/r/Y+zmrNJ9zjNQpzWq@kili Signed-off-by: Mark Brown --- drivers/spi/spi-bcmbca-hsspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcmbca-hsspi.c b/drivers/spi/spi-bcmbca-hsspi.c index e255241319ab..3f9e6131ad86 100644 --- a/drivers/spi/spi-bcmbca-hsspi.c +++ b/drivers/spi/spi-bcmbca-hsspi.c @@ -548,7 +548,8 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - if (sysfs_create_group(&pdev->dev.kobj, &bcmbca_hsspi_group)) { + ret = sysfs_create_group(&pdev->dev.kobj, &bcmbca_hsspi_group); + if (ret) { dev_err(&pdev->dev, "couldn't register sysfs group\n"); goto out_pm_disable; } From 97b7cea04f52c3263a74b945a4738f678181b117 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 Feb 2023 17:05:20 +0300 Subject: [PATCH 63/65] spi: bcm63xx-hsspi: fix error code in probe This code accidentally returns success instead of a negative error code. Fixes: 50a6620dd1fb ("spi: bcm63xx-hsspi: Add polling mode support") Signed-off-by: Dan Carpenter Reviewed-by: William Zhang Reviewed-by: Florian Fainelli Link: https://lore.kernel.org/r/Y+zmoGH6LubPhiI0@kili Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index 68093c045e0b..cd0a6478f5e7 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -849,7 +849,8 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - if (sysfs_create_group(&pdev->dev.kobj, &bcm63xx_hsspi_group)) { + ret = sysfs_create_group(&pdev->dev.kobj, &bcm63xx_hsspi_group); + if (ret) { dev_err(&pdev->dev, "couldn't register sysfs group\n"); goto out_pm_disable; } From a46ce4f884817c66d0dc303b663b53b37d2baa24 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 16 Feb 2023 13:30:14 +0100 Subject: [PATCH 64/65] spi: spidev: drop the incorrect notice from Kconfig The spidev interface has been de-facto stable for many years. This notice has been unchanged since 2007 and is incorrect so remove it. Signed-off-by: Bartosz Golaszewski Link: https://lore.kernel.org/r/20230216123014.110541-1-brgl@bgdev.pl Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 2ede343fde42..6fb17efb35f0 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -1175,9 +1175,6 @@ config SPI_SPIDEV help This supports user mode SPI protocol drivers. - Note that this application programming interface is EXPERIMENTAL - and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes. - config SPI_LOOPBACK_TEST tristate "spi loopback test framework support" depends on m From 7234d746a8339066313518bfa024fa03f363a55e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 17 Feb 2023 16:58:02 +0100 Subject: [PATCH 65/65] spi: dt-bindings: qcom,spi-qcom-qspi: document OPP and power-domains QSPI on Qualcomm SDM845, SC7180 and SC7280 SoCs uses OPP table (both in DTS and Linux driver) and is suuplied by CX power domain. Document missing properties to fix: sc7280-idp2.dtb: spi@88dc000: Unevaluated properties are not allowed ('operating-points-v2', 'power-domains' were unexpected) Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230217155802.848178-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml index e94d915e28c8..ee8f7ea907b0 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml @@ -52,6 +52,11 @@ properties: - const: qspi-config - const: qspi-memory + operating-points-v2: true + + power-domains: + maxItems: 1 + required: - compatible - reg