Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'spi-fix-v6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
"The largest batch of fixes here is a series of fixes for the Freescale
LPSPI driver which James Clark pulled out of their BSP while looking
at support for the NXP S32G version of the controller.

The majority of this turned out to be bug fixes that affect existing
systems with the actual S32G support being just a small quirk that
would be unremarkable by itself, the whole series has had a good
amount of testing and review and the individual patches are all pretty
straightforward by themselves.

We also have a few other driver specific fixes, including a relatively
large but simple one for the Cadence QuadSPI driver"

* tag 'spi-fix-v6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
spi: spi-qpic-snand: unregister ECC engine on probe error and device remove
spi: cadence-quadspi: Implement refcount to handle unbind during busy
spi: spi-fsl-lpspi: Add compatible for S32G
spi: spi-fsl-lpspi: Parameterize reading num-cs from hardware
spi: spi-fsl-lpspi: Treat prescale_max == 0 as no erratum
spi: spi-fsl-lpspi: Constify devtype datas
dt-bindings: lpspi: Document support for S32G
spi: spi-fsl-lpspi: Clear status register after disabling the module
spi: spi-fsl-lpspi: Reset FIFO and disable module on transfer abort
spi: spi-fsl-lpspi: Set correct chip-select polarity bit
spi: spi-fsl-lpspi: Fix transmissions when using CONT
spi: microchip-core-qspi: stop checking viability of op->max_freq in supports_op callback

+70 -33
+5
Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml
··· 20 20 - enum: 21 21 - fsl,imx7ulp-spi 22 22 - fsl,imx8qxp-spi 23 + - nxp,s32g2-lpspi 23 24 - items: 24 25 - enum: 25 26 - fsl,imx8ulp-spi ··· 28 27 - fsl,imx94-spi 29 28 - fsl,imx95-spi 30 29 - const: fsl,imx7ulp-spi 30 + - items: 31 + - const: nxp,s32g3-lpspi 32 + - const: nxp,s32g2-lpspi 33 + 31 34 reg: 32 35 maxItems: 1 33 36
+33
drivers/spi/spi-cadence-quadspi.c
··· 108 108 109 109 bool is_jh7110; /* Flag for StarFive JH7110 SoC */ 110 110 bool disable_stig_mode; 111 + refcount_t refcount; 112 + refcount_t inflight_ops; 111 113 112 114 const struct cqspi_driver_platdata *ddata; 113 115 }; ··· 737 735 u8 *rxbuf_end = rxbuf + n_rx; 738 736 int ret = 0; 739 737 738 + if (!refcount_read(&cqspi->refcount)) 739 + return -ENODEV; 740 + 740 741 writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR); 741 742 writel(remaining, reg_base + CQSPI_REG_INDIRECTRDBYTES); 742 743 ··· 1075 1070 unsigned int remaining = n_tx; 1076 1071 unsigned int write_bytes; 1077 1072 int ret; 1073 + 1074 + if (!refcount_read(&cqspi->refcount)) 1075 + return -ENODEV; 1078 1076 1079 1077 writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR); 1080 1078 writel(remaining, reg_base + CQSPI_REG_INDIRECTWRBYTES); ··· 1469 1461 struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller); 1470 1462 struct device *dev = &cqspi->pdev->dev; 1471 1463 1464 + if (refcount_read(&cqspi->inflight_ops) == 0) 1465 + return -ENODEV; 1466 + 1472 1467 ret = pm_runtime_resume_and_get(dev); 1473 1468 if (ret) { 1474 1469 dev_err(&mem->spi->dev, "resume failed with %d\n", ret); 1475 1470 return ret; 1471 + } 1472 + 1473 + if (!refcount_read(&cqspi->refcount)) 1474 + return -EBUSY; 1475 + 1476 + refcount_inc(&cqspi->inflight_ops); 1477 + 1478 + if (!refcount_read(&cqspi->refcount)) { 1479 + if (refcount_read(&cqspi->inflight_ops)) 1480 + refcount_dec(&cqspi->inflight_ops); 1481 + return -EBUSY; 1476 1482 } 1477 1483 1478 1484 ret = cqspi_mem_process(mem, op); ··· 1495 1473 1496 1474 if (ret) 1497 1475 dev_err(&mem->spi->dev, "operation failed with %d\n", ret); 1476 + 1477 + if (refcount_read(&cqspi->inflight_ops) > 1) 1478 + refcount_dec(&cqspi->inflight_ops); 1498 1479 1499 1480 return ret; 1500 1481 } ··· 1950 1925 } 1951 1926 } 1952 1927 1928 + refcount_set(&cqspi->refcount, 1); 1929 + refcount_set(&cqspi->inflight_ops, 1); 1930 + 1953 1931 ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0, 1954 1932 pdev->name, cqspi); 1955 1933 if (ret) { ··· 2014 1986 static void cqspi_remove(struct platform_device *pdev) 2015 1987 { 2016 1988 struct cqspi_st *cqspi = platform_get_drvdata(pdev); 1989 + 1990 + refcount_set(&cqspi->refcount, 0); 1991 + 1992 + if (!refcount_dec_and_test(&cqspi->inflight_ops)) 1993 + cqspi_wait_idle(cqspi); 2017 1994 2018 1995 spi_unregister_controller(cqspi->host); 2019 1996 cqspi_controller_enable(cqspi, 0);
+28 -19
drivers/spi/spi-fsl-lpspi.c
··· 3 3 // Freescale i.MX7ULP LPSPI driver 4 4 // 5 5 // Copyright 2016 Freescale Semiconductor, Inc. 6 - // Copyright 2018 NXP Semiconductors 6 + // Copyright 2018, 2023, 2025 NXP 7 7 8 + #include <linux/bitfield.h> 8 9 #include <linux/clk.h> 9 10 #include <linux/completion.h> 10 11 #include <linux/delay.h> ··· 71 70 #define DER_TDDE BIT(0) 72 71 #define CFGR1_PCSCFG BIT(27) 73 72 #define CFGR1_PINCFG (BIT(24)|BIT(25)) 74 - #define CFGR1_PCSPOL BIT(8) 73 + #define CFGR1_PCSPOL_MASK GENMASK(11, 8) 75 74 #define CFGR1_NOSTALL BIT(3) 76 75 #define CFGR1_HOST BIT(0) 77 76 #define FSR_TXCOUNT (0xFF) ··· 83 82 #define TCR_RXMSK BIT(19) 84 83 #define TCR_TXMSK BIT(18) 85 84 85 + #define SR_CLEAR_MASK GENMASK(13, 8) 86 + 86 87 struct fsl_lpspi_devtype_data { 87 - u8 prescale_max; 88 + u8 prescale_max : 3; /* 0 == no limit */ 89 + bool query_hw_for_num_cs : 1; 88 90 }; 89 91 90 92 struct lpspi_config { ··· 133 129 }; 134 130 135 131 /* 136 - * ERR051608 fixed or not: 137 - * https://www.nxp.com/docs/en/errata/i.MX93_1P87f.pdf 132 + * Devices with ERR051608 have a max TCR_PRESCALE value of 1, otherwise there is 133 + * no prescale limit: https://www.nxp.com/docs/en/errata/i.MX93_1P87f.pdf 138 134 */ 139 - static struct fsl_lpspi_devtype_data imx93_lpspi_devtype_data = { 135 + static const struct fsl_lpspi_devtype_data imx93_lpspi_devtype_data = { 140 136 .prescale_max = 1, 137 + .query_hw_for_num_cs = true, 141 138 }; 142 139 143 - static struct fsl_lpspi_devtype_data imx7ulp_lpspi_devtype_data = { 144 - .prescale_max = 7, 140 + static const struct fsl_lpspi_devtype_data imx7ulp_lpspi_devtype_data = { 141 + /* All defaults */ 142 + }; 143 + 144 + static const struct fsl_lpspi_devtype_data s32g_lpspi_devtype_data = { 145 + .query_hw_for_num_cs = true, 145 146 }; 146 147 147 148 static const struct of_device_id fsl_lpspi_dt_ids[] = { 148 149 { .compatible = "fsl,imx7ulp-spi", .data = &imx7ulp_lpspi_devtype_data,}, 149 150 { .compatible = "fsl,imx93-spi", .data = &imx93_lpspi_devtype_data,}, 151 + { .compatible = "nxp,s32g2-lpspi", .data = &s32g_lpspi_devtype_data,}, 150 152 { /* sentinel */ } 151 153 }; 152 154 MODULE_DEVICE_TABLE(of, fsl_lpspi_dt_ids); ··· 331 321 int scldiv; 332 322 333 323 perclk_rate = clk_get_rate(fsl_lpspi->clk_per); 334 - prescale_max = fsl_lpspi->devtype_data->prescale_max; 324 + prescale_max = fsl_lpspi->devtype_data->prescale_max ?: 7; 335 325 336 326 if (!config.speed_hz) { 337 327 dev_err(fsl_lpspi->dev, ··· 433 423 else 434 424 temp = CFGR1_PINCFG; 435 425 if (fsl_lpspi->config.mode & SPI_CS_HIGH) 436 - temp |= CFGR1_PCSPOL; 426 + temp |= FIELD_PREP(CFGR1_PCSPOL_MASK, 427 + BIT(fsl_lpspi->config.chip_select)); 428 + 437 429 writel(temp, fsl_lpspi->base + IMX7ULP_CFGR1); 438 430 439 431 temp = readl(fsl_lpspi->base + IMX7ULP_CR); ··· 544 532 fsl_lpspi_intctrl(fsl_lpspi, 0); 545 533 } 546 534 547 - /* W1C for all flags in SR */ 548 - temp = 0x3F << 8; 549 - writel(temp, fsl_lpspi->base + IMX7ULP_SR); 550 - 551 535 /* Clear FIFO and disable module */ 552 536 temp = CR_RRF | CR_RTF; 553 537 writel(temp, fsl_lpspi->base + IMX7ULP_CR); 538 + 539 + /* W1C for all flags in SR */ 540 + writel(SR_CLEAR_MASK, fsl_lpspi->base + IMX7ULP_SR); 554 541 555 542 return 0; 556 543 } ··· 741 730 fsl_lpspi_write_tx_fifo(fsl_lpspi); 742 731 743 732 ret = fsl_lpspi_wait_for_completion(controller); 744 - if (ret) 745 - return ret; 746 733 747 734 fsl_lpspi_reset(fsl_lpspi); 748 735 749 - return 0; 736 + return ret; 750 737 } 751 738 752 739 static int fsl_lpspi_transfer_one(struct spi_controller *controller, ··· 794 785 if (temp_SR & SR_MBF || 795 786 readl(fsl_lpspi->base + IMX7ULP_FSR) & FSR_TXCOUNT) { 796 787 writel(SR_FCF, fsl_lpspi->base + IMX7ULP_SR); 797 - fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE); 788 + fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE | (temp_IER & IER_TDIE)); 798 789 return IRQ_HANDLED; 799 790 } 800 791 ··· 939 930 fsl_lpspi->rxfifosize = 1 << ((temp >> 8) & 0x0f); 940 931 if (of_property_read_u32((&pdev->dev)->of_node, "num-cs", 941 932 &num_cs)) { 942 - if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx93-spi")) 933 + if (devtype_data->query_hw_for_num_cs) 943 934 num_cs = ((temp >> 16) & 0xf); 944 935 else 945 936 num_cs = 1;
-12
drivers/spi/spi-microchip-core-qspi.c
··· 531 531 532 532 static bool mchp_coreqspi_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) 533 533 { 534 - struct mchp_coreqspi *qspi = spi_controller_get_devdata(mem->spi->controller); 535 - unsigned long clk_hz; 536 - u32 baud_rate_val; 537 - 538 534 if (!spi_mem_default_supports_op(mem, op)) 539 535 return false; 540 536 ··· 552 556 if (op->data.dir == SPI_MEM_DATA_OUT) 553 557 return false; 554 558 } 555 - 556 - clk_hz = clk_get_rate(qspi->clk); 557 - if (!clk_hz) 558 - return false; 559 - 560 - baud_rate_val = DIV_ROUND_UP(clk_hz, 2 * op->max_freq); 561 - if (baud_rate_val > MAX_DIVIDER || baud_rate_val < MIN_DIVIDER) 562 - return false; 563 559 564 560 return true; 565 561 }
+4 -2
drivers/spi/spi-qpic-snand.c
··· 1615 1615 ret = spi_register_controller(ctlr); 1616 1616 if (ret) { 1617 1617 dev_err(&pdev->dev, "spi_register_controller failed.\n"); 1618 - goto err_spi_init; 1618 + goto err_register_controller; 1619 1619 } 1620 1620 1621 1621 return 0; 1622 1622 1623 + err_register_controller: 1624 + nand_ecc_unregister_on_host_hw_engine(&snandc->qspi->ecc_eng); 1623 1625 err_spi_init: 1624 1626 qcom_nandc_unalloc(snandc); 1625 1627 err_snand_alloc: ··· 1643 1641 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1644 1642 1645 1643 spi_unregister_controller(ctlr); 1646 - 1644 + nand_ecc_unregister_on_host_hw_engine(&snandc->qspi->ecc_eng); 1647 1645 qcom_nandc_unalloc(snandc); 1648 1646 1649 1647 clk_disable_unprepare(snandc->aon_clk);