spi: Fixes for v6.12

Some driver specific fixes that came in during the merge window. Lorenzo
 Bianconi did some extra testing on the recently added arioha driver and
 found some issues, Alexander Dahl fixed some issues with signal delays
 in the Atmel QSPI driver and Jinjie Ruan has been fixing some nits with
 runtime PM cleanup.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmbz0NIACgkQJNaLcl1U
 h9B1KQf/fcq8ApnJCgD9EykeE9ekziI6PRwxc3XqI+DCws7CN2n4EbIsJxCeiygl
 d4vWcnBssQGxVv6IbSl3Vgqr6PSAxBxibpBgmANR0HJ8YLFjxoaDTk9ufnJevOEm
 pMgAtzvt3Ral1VwspKsz3puXEVoJaIoELfEQRB7D8XCX26ypD7+sZSN/AjMATp/N
 zla5mPjQfGIX7dOis1kaRCQ0ysxoEdZ9zsyFlGs+VZkFIhHbu3KTLhlfADruOa7k
 RKuVABAIJwqPz6Gew82xlh4hQPP+aecWNdwCSK6+4FZkZLgvUz2rx7evVj3U5+xd
 Hc3jQmoGnVMYqeuK4BC8T0frnlp6eA==
 =iJa9
 -----END PGP SIGNATURE-----

Merge tag 'spi-fix-v6.12-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "Some driver specific fixes that came in during the merge window.

  Lorenzo Bianconi did some extra testing on the recently added arioha
  driver and found some issues, Alexander Dahl fixed some issues with
  signal delays in the Atmel QSPI driver and Jinjie Ruan has been fixing
  some nits with runtime PM cleanup"

* tag 'spi-fix-v6.12-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: atmel-quadspi: Avoid overwriting delay register settings
  spi: airoha: remove read cache in airoha_snand_dirmap_read()
  spi: spi-fsl-lpspi: Undo runtime PM changes at driver exit time
  spi: atmel-quadspi: Undo runtime PM changes at driver exit time
  spi: airoha: fix airoha_snand_{write,read}_data data_len estimation
  spi: airoha: fix dirmap_{read,write} operations
This commit is contained in:
Linus Torvalds 2024-09-25 14:49:34 -07:00
commit fe29393877
3 changed files with 26 additions and 33 deletions

View File

@ -375,9 +375,9 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
* If the QSPI controller is set in regular SPI mode, set it in * If the QSPI controller is set in regular SPI mode, set it in
* Serial Memory Mode (SMM). * Serial Memory Mode (SMM).
*/ */
if (aq->mr != QSPI_MR_SMM) { if (!(aq->mr & QSPI_MR_SMM)) {
atmel_qspi_write(QSPI_MR_SMM, aq, QSPI_MR); aq->mr |= QSPI_MR_SMM;
aq->mr = QSPI_MR_SMM; atmel_qspi_write(aq->scr, aq, QSPI_MR);
} }
/* Clear pending interrupts */ /* Clear pending interrupts */
@ -501,7 +501,8 @@ static int atmel_qspi_setup(struct spi_device *spi)
if (ret < 0) if (ret < 0)
return ret; return ret;
aq->scr = QSPI_SCR_SCBR(scbr); aq->scr &= ~QSPI_SCR_SCBR_MASK;
aq->scr |= QSPI_SCR_SCBR(scbr);
atmel_qspi_write(aq->scr, aq, QSPI_SCR); atmel_qspi_write(aq->scr, aq, QSPI_SCR);
pm_runtime_mark_last_busy(ctrl->dev.parent); pm_runtime_mark_last_busy(ctrl->dev.parent);
@ -534,6 +535,7 @@ static int atmel_qspi_set_cs_timing(struct spi_device *spi)
if (ret < 0) if (ret < 0)
return ret; return ret;
aq->scr &= ~QSPI_SCR_DLYBS_MASK;
aq->scr |= QSPI_SCR_DLYBS(cs_setup); aq->scr |= QSPI_SCR_DLYBS(cs_setup);
atmel_qspi_write(aq->scr, aq, QSPI_SCR); atmel_qspi_write(aq->scr, aq, QSPI_SCR);
@ -549,8 +551,8 @@ static void atmel_qspi_init(struct atmel_qspi *aq)
atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR); atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR);
/* Set the QSPI controller by default in Serial Memory Mode */ /* Set the QSPI controller by default in Serial Memory Mode */
atmel_qspi_write(QSPI_MR_SMM, aq, QSPI_MR); aq->mr |= QSPI_MR_SMM;
aq->mr = QSPI_MR_SMM; atmel_qspi_write(aq->mr, aq, QSPI_MR);
/* Enable the QSPI controller */ /* Enable the QSPI controller */
atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR); atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR);
@ -721,6 +723,7 @@ static void atmel_qspi_remove(struct platform_device *pdev)
clk_unprepare(aq->pclk); clk_unprepare(aq->pclk);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev); pm_runtime_put_noidle(&pdev->dev);
} }

View File

@ -211,9 +211,6 @@ struct airoha_snand_dev {
u8 *txrx_buf; u8 *txrx_buf;
dma_addr_t dma_addr; dma_addr_t dma_addr;
u64 cur_page_num;
bool data_need_update;
}; };
struct airoha_snand_ctrl { struct airoha_snand_ctrl {
@ -405,7 +402,7 @@ static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd,
for (i = 0; i < len; i += data_len) { for (i = 0; i < len; i += data_len) {
int err; int err;
data_len = min(len, SPI_MAX_TRANSFER_SIZE); data_len = min(len - i, SPI_MAX_TRANSFER_SIZE);
err = airoha_snand_set_fifo_op(as_ctrl, cmd, data_len); err = airoha_snand_set_fifo_op(as_ctrl, cmd, data_len);
if (err) if (err)
return err; return err;
@ -427,7 +424,7 @@ static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, u8 *data,
for (i = 0; i < len; i += data_len) { for (i = 0; i < len; i += data_len) {
int err; int err;
data_len = min(len, SPI_MAX_TRANSFER_SIZE); data_len = min(len - i, SPI_MAX_TRANSFER_SIZE);
err = airoha_snand_set_fifo_op(as_ctrl, 0xc, data_len); err = airoha_snand_set_fifo_op(as_ctrl, 0xc, data_len);
if (err) if (err)
return err; return err;
@ -644,11 +641,6 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
u32 val, rd_mode; u32 val, rd_mode;
int err; int err;
if (!as_dev->data_need_update)
return len;
as_dev->data_need_update = false;
switch (op->cmd.opcode) { switch (op->cmd.opcode) {
case SPI_NAND_OP_READ_FROM_CACHE_DUAL: case SPI_NAND_OP_READ_FROM_CACHE_DUAL:
rd_mode = 1; rd_mode = 1;
@ -739,8 +731,13 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
if (err) if (err)
return err; return err;
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1, /*
SPI_NFI_READ_FROM_CACHE_DONE); * SPI_NFI_READ_FROM_CACHE_DONE bit must be written at the end
* of dirmap_read operation even if it is already set.
*/
err = regmap_write_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1,
SPI_NFI_READ_FROM_CACHE_DONE,
SPI_NFI_READ_FROM_CACHE_DONE);
if (err) if (err)
return err; return err;
@ -870,8 +867,13 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
if (err) if (err)
return err; return err;
err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1, /*
SPI_NFI_LOAD_TO_CACHE_DONE); * SPI_NFI_LOAD_TO_CACHE_DONE bit must be written at the end
* of dirmap_write operation even if it is already set.
*/
err = regmap_write_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1,
SPI_NFI_LOAD_TO_CACHE_DONE,
SPI_NFI_LOAD_TO_CACHE_DONE);
if (err) if (err)
return err; return err;
@ -885,23 +887,11 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
static int airoha_snand_exec_op(struct spi_mem *mem, static int airoha_snand_exec_op(struct spi_mem *mem,
const struct spi_mem_op *op) const struct spi_mem_op *op)
{ {
struct airoha_snand_dev *as_dev = spi_get_ctldata(mem->spi);
u8 data[8], cmd, opcode = op->cmd.opcode; u8 data[8], cmd, opcode = op->cmd.opcode;
struct airoha_snand_ctrl *as_ctrl; struct airoha_snand_ctrl *as_ctrl;
int i, err; int i, err;
as_ctrl = spi_controller_get_devdata(mem->spi->controller); as_ctrl = spi_controller_get_devdata(mem->spi->controller);
if (opcode == SPI_NAND_OP_PROGRAM_EXECUTE &&
op->addr.val == as_dev->cur_page_num) {
as_dev->data_need_update = true;
} else if (opcode == SPI_NAND_OP_PAGE_READ) {
if (!as_dev->data_need_update &&
op->addr.val == as_dev->cur_page_num)
return 0;
as_dev->data_need_update = true;
as_dev->cur_page_num = op->addr.val;
}
/* switch to manual mode */ /* switch to manual mode */
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
@ -986,7 +976,6 @@ static int airoha_snand_setup(struct spi_device *spi)
if (dma_mapping_error(as_ctrl->dev, as_dev->dma_addr)) if (dma_mapping_error(as_ctrl->dev, as_dev->dma_addr))
return -ENOMEM; return -ENOMEM;
as_dev->data_need_update = true;
spi_set_ctldata(spi, as_dev); spi_set_ctldata(spi, as_dev);
return 0; return 0;

View File

@ -986,6 +986,7 @@ static void fsl_lpspi_remove(struct platform_device *pdev)
fsl_lpspi_dma_exit(controller); fsl_lpspi_dma_exit(controller);
pm_runtime_dont_use_autosuspend(fsl_lpspi->dev);
pm_runtime_disable(fsl_lpspi->dev); pm_runtime_disable(fsl_lpspi->dev);
} }