Skip to content

Commit 53b48f6

Browse files
committed
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
2 parents e5d5d23 + 1991a45 commit 53b48f6

File tree

5 files changed

+70
-33
lines changed

5 files changed

+70
-33
lines changed

Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,18 @@ properties:
2020
- enum:
2121
- fsl,imx7ulp-spi
2222
- fsl,imx8qxp-spi
23+
- nxp,s32g2-lpspi
2324
- items:
2425
- enum:
2526
- fsl,imx8ulp-spi
2627
- fsl,imx93-spi
2728
- fsl,imx94-spi
2829
- fsl,imx95-spi
2930
- const: fsl,imx7ulp-spi
31+
- items:
32+
- const: nxp,s32g3-lpspi
33+
- const: nxp,s32g2-lpspi
34+
3035
reg:
3136
maxItems: 1
3237

drivers/spi/spi-cadence-quadspi.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ struct cqspi_st {
108108

109109
bool is_jh7110; /* Flag for StarFive JH7110 SoC */
110110
bool disable_stig_mode;
111+
refcount_t refcount;
112+
refcount_t inflight_ops;
111113

112114
const struct cqspi_driver_platdata *ddata;
113115
};
@@ -735,6 +737,9 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
735737
u8 *rxbuf_end = rxbuf + n_rx;
736738
int ret = 0;
737739

740+
if (!refcount_read(&cqspi->refcount))
741+
return -ENODEV;
742+
738743
writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
739744
writel(remaining, reg_base + CQSPI_REG_INDIRECTRDBYTES);
740745

@@ -1071,6 +1076,9 @@ static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata,
10711076
unsigned int write_bytes;
10721077
int ret;
10731078

1079+
if (!refcount_read(&cqspi->refcount))
1080+
return -ENODEV;
1081+
10741082
writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR);
10751083
writel(remaining, reg_base + CQSPI_REG_INDIRECTWRBYTES);
10761084

@@ -1461,19 +1469,36 @@ static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
14611469
struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller);
14621470
struct device *dev = &cqspi->pdev->dev;
14631471

1472+
if (refcount_read(&cqspi->inflight_ops) == 0)
1473+
return -ENODEV;
1474+
14641475
ret = pm_runtime_resume_and_get(dev);
14651476
if (ret) {
14661477
dev_err(&mem->spi->dev, "resume failed with %d\n", ret);
14671478
return ret;
14681479
}
14691480

1481+
if (!refcount_read(&cqspi->refcount))
1482+
return -EBUSY;
1483+
1484+
refcount_inc(&cqspi->inflight_ops);
1485+
1486+
if (!refcount_read(&cqspi->refcount)) {
1487+
if (refcount_read(&cqspi->inflight_ops))
1488+
refcount_dec(&cqspi->inflight_ops);
1489+
return -EBUSY;
1490+
}
1491+
14701492
ret = cqspi_mem_process(mem, op);
14711493

14721494
pm_runtime_put_autosuspend(dev);
14731495

14741496
if (ret)
14751497
dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
14761498

1499+
if (refcount_read(&cqspi->inflight_ops) > 1)
1500+
refcount_dec(&cqspi->inflight_ops);
1501+
14771502
return ret;
14781503
}
14791504

@@ -1925,6 +1950,9 @@ static int cqspi_probe(struct platform_device *pdev)
19251950
}
19261951
}
19271952

1953+
refcount_set(&cqspi->refcount, 1);
1954+
refcount_set(&cqspi->inflight_ops, 1);
1955+
19281956
ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
19291957
pdev->name, cqspi);
19301958
if (ret) {
@@ -1987,6 +2015,11 @@ static void cqspi_remove(struct platform_device *pdev)
19872015
{
19882016
struct cqspi_st *cqspi = platform_get_drvdata(pdev);
19892017

2018+
refcount_set(&cqspi->refcount, 0);
2019+
2020+
if (!refcount_dec_and_test(&cqspi->inflight_ops))
2021+
cqspi_wait_idle(cqspi);
2022+
19902023
spi_unregister_controller(cqspi->host);
19912024
cqspi_controller_enable(cqspi, 0);
19922025

drivers/spi/spi-fsl-lpspi.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
// Freescale i.MX7ULP LPSPI driver
44
//
55
// Copyright 2016 Freescale Semiconductor, Inc.
6-
// Copyright 2018 NXP Semiconductors
6+
// Copyright 2018, 2023, 2025 NXP
77

8+
#include <linux/bitfield.h>
89
#include <linux/clk.h>
910
#include <linux/completion.h>
1011
#include <linux/delay.h>
@@ -70,7 +71,7 @@
7071
#define DER_TDDE BIT(0)
7172
#define CFGR1_PCSCFG BIT(27)
7273
#define CFGR1_PINCFG (BIT(24)|BIT(25))
73-
#define CFGR1_PCSPOL BIT(8)
74+
#define CFGR1_PCSPOL_MASK GENMASK(11, 8)
7475
#define CFGR1_NOSTALL BIT(3)
7576
#define CFGR1_HOST BIT(0)
7677
#define FSR_TXCOUNT (0xFF)
@@ -82,8 +83,11 @@
8283
#define TCR_RXMSK BIT(19)
8384
#define TCR_TXMSK BIT(18)
8485

86+
#define SR_CLEAR_MASK GENMASK(13, 8)
87+
8588
struct fsl_lpspi_devtype_data {
86-
u8 prescale_max;
89+
u8 prescale_max : 3; /* 0 == no limit */
90+
bool query_hw_for_num_cs : 1;
8791
};
8892

8993
struct lpspi_config {
@@ -129,20 +133,26 @@ struct fsl_lpspi_data {
129133
};
130134

131135
/*
132-
* ERR051608 fixed or not:
133-
* https://www.nxp.com/docs/en/errata/i.MX93_1P87f.pdf
136+
* Devices with ERR051608 have a max TCR_PRESCALE value of 1, otherwise there is
137+
* no prescale limit: https://www.nxp.com/docs/en/errata/i.MX93_1P87f.pdf
134138
*/
135-
static struct fsl_lpspi_devtype_data imx93_lpspi_devtype_data = {
139+
static const struct fsl_lpspi_devtype_data imx93_lpspi_devtype_data = {
136140
.prescale_max = 1,
141+
.query_hw_for_num_cs = true,
142+
};
143+
144+
static const struct fsl_lpspi_devtype_data imx7ulp_lpspi_devtype_data = {
145+
/* All defaults */
137146
};
138147

139-
static struct fsl_lpspi_devtype_data imx7ulp_lpspi_devtype_data = {
140-
.prescale_max = 7,
148+
static const struct fsl_lpspi_devtype_data s32g_lpspi_devtype_data = {
149+
.query_hw_for_num_cs = true,
141150
};
142151

143152
static const struct of_device_id fsl_lpspi_dt_ids[] = {
144153
{ .compatible = "fsl,imx7ulp-spi", .data = &imx7ulp_lpspi_devtype_data,},
145154
{ .compatible = "fsl,imx93-spi", .data = &imx93_lpspi_devtype_data,},
155+
{ .compatible = "nxp,s32g2-lpspi", .data = &s32g_lpspi_devtype_data,},
146156
{ /* sentinel */ }
147157
};
148158
MODULE_DEVICE_TABLE(of, fsl_lpspi_dt_ids);
@@ -321,7 +331,7 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
321331
int scldiv;
322332

323333
perclk_rate = clk_get_rate(fsl_lpspi->clk_per);
324-
prescale_max = fsl_lpspi->devtype_data->prescale_max;
334+
prescale_max = fsl_lpspi->devtype_data->prescale_max ?: 7;
325335

326336
if (!config.speed_hz) {
327337
dev_err(fsl_lpspi->dev,
@@ -423,7 +433,9 @@ static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
423433
else
424434
temp = CFGR1_PINCFG;
425435
if (fsl_lpspi->config.mode & SPI_CS_HIGH)
426-
temp |= CFGR1_PCSPOL;
436+
temp |= FIELD_PREP(CFGR1_PCSPOL_MASK,
437+
BIT(fsl_lpspi->config.chip_select));
438+
427439
writel(temp, fsl_lpspi->base + IMX7ULP_CFGR1);
428440

429441
temp = readl(fsl_lpspi->base + IMX7ULP_CR);
@@ -532,14 +544,13 @@ static int fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
532544
fsl_lpspi_intctrl(fsl_lpspi, 0);
533545
}
534546

535-
/* W1C for all flags in SR */
536-
temp = 0x3F << 8;
537-
writel(temp, fsl_lpspi->base + IMX7ULP_SR);
538-
539547
/* Clear FIFO and disable module */
540548
temp = CR_RRF | CR_RTF;
541549
writel(temp, fsl_lpspi->base + IMX7ULP_CR);
542550

551+
/* W1C for all flags in SR */
552+
writel(SR_CLEAR_MASK, fsl_lpspi->base + IMX7ULP_SR);
553+
543554
return 0;
544555
}
545556

@@ -730,12 +741,10 @@ static int fsl_lpspi_pio_transfer(struct spi_controller *controller,
730741
fsl_lpspi_write_tx_fifo(fsl_lpspi);
731742

732743
ret = fsl_lpspi_wait_for_completion(controller);
733-
if (ret)
734-
return ret;
735744

736745
fsl_lpspi_reset(fsl_lpspi);
737746

738-
return 0;
747+
return ret;
739748
}
740749

741750
static int fsl_lpspi_transfer_one(struct spi_controller *controller,
@@ -785,7 +794,7 @@ static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id)
785794
if (temp_SR & SR_MBF ||
786795
readl(fsl_lpspi->base + IMX7ULP_FSR) & FSR_TXCOUNT) {
787796
writel(SR_FCF, fsl_lpspi->base + IMX7ULP_SR);
788-
fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE);
797+
fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE | (temp_IER & IER_TDIE));
789798
return IRQ_HANDLED;
790799
}
791800

@@ -930,7 +939,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
930939
fsl_lpspi->rxfifosize = 1 << ((temp >> 8) & 0x0f);
931940
if (of_property_read_u32((&pdev->dev)->of_node, "num-cs",
932941
&num_cs)) {
933-
if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx93-spi"))
942+
if (devtype_data->query_hw_for_num_cs)
934943
num_cs = ((temp >> 16) & 0xf);
935944
else
936945
num_cs = 1;

drivers/spi/spi-microchip-core-qspi.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,6 @@ static int mchp_coreqspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *o
531531

532532
static bool mchp_coreqspi_supports_op(struct spi_mem *mem, const struct spi_mem_op *op)
533533
{
534-
struct mchp_coreqspi *qspi = spi_controller_get_devdata(mem->spi->controller);
535-
unsigned long clk_hz;
536-
u32 baud_rate_val;
537-
538534
if (!spi_mem_default_supports_op(mem, op))
539535
return false;
540536

@@ -557,14 +553,6 @@ static bool mchp_coreqspi_supports_op(struct spi_mem *mem, const struct spi_mem_
557553
return false;
558554
}
559555

560-
clk_hz = clk_get_rate(qspi->clk);
561-
if (!clk_hz)
562-
return false;
563-
564-
baud_rate_val = DIV_ROUND_UP(clk_hz, 2 * op->max_freq);
565-
if (baud_rate_val > MAX_DIVIDER || baud_rate_val < MIN_DIVIDER)
566-
return false;
567-
568556
return true;
569557
}
570558

drivers/spi/spi-qpic-snand.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,11 +1615,13 @@ static int qcom_spi_probe(struct platform_device *pdev)
16151615
ret = spi_register_controller(ctlr);
16161616
if (ret) {
16171617
dev_err(&pdev->dev, "spi_register_controller failed.\n");
1618-
goto err_spi_init;
1618+
goto err_register_controller;
16191619
}
16201620

16211621
return 0;
16221622

1623+
err_register_controller:
1624+
nand_ecc_unregister_on_host_hw_engine(&snandc->qspi->ecc_eng);
16231625
err_spi_init:
16241626
qcom_nandc_unalloc(snandc);
16251627
err_snand_alloc:
@@ -1641,7 +1643,7 @@ static void qcom_spi_remove(struct platform_device *pdev)
16411643
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
16421644

16431645
spi_unregister_controller(ctlr);
1644-
1646+
nand_ecc_unregister_on_host_hw_engine(&snandc->qspi->ecc_eng);
16451647
qcom_nandc_unalloc(snandc);
16461648

16471649
clk_disable_unprepare(snandc->aon_clk);

0 commit comments

Comments
 (0)