mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
spi: fsl-qspi: Reprogram the clock rate when the operation frequency changes
fsl_qspi_select_mem() returns early when the chip select has not changed,
which happens before it reaches clk_set_rate(). Since the rate is now
taken from the spi-mem operation rather than from the SPI device, the
controller honours op->max_freq exactly once per chip select and ignores
it for every operation after that.
q->selected is only reset to -1 in fsl_qspi_default_setup(), i.e. at probe
and on resume, so on the common single chip select board the very first
operation latches a rate that all subsequent operations inherit, whatever
frequency they asked for.
This results in operations being issued with the wrong frequency.
Cache the operation frequency the clock was programmed for next to the
selected chip select, and redo the clock setup when either changes.
Fixes: 2438db5253 ("spi: fsl-qspi: Support per spi-mem operation frequency switches")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Acked-by: Han Xu <han.xu@nxp.com>
Link: https://patch.msgid.link/20260917-fsl-qspi-freq-op-fix-v1-1-5fbe6b02f738@kontron.de
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
e922bad8b2
commit
3d743adf09
|
|
@ -289,6 +289,7 @@ struct fsl_qspi {
|
|||
struct pm_qos_request pm_qos_req;
|
||||
struct device *dev;
|
||||
int selected;
|
||||
u32 selected_freq;
|
||||
u32 memmap_phy;
|
||||
};
|
||||
|
||||
|
|
@ -551,7 +552,8 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi,
|
|||
unsigned long rate = op->max_freq;
|
||||
int ret;
|
||||
|
||||
if (q->selected == spi_get_chipselect(spi, 0))
|
||||
if (q->selected == spi_get_chipselect(spi, 0) &&
|
||||
q->selected_freq == op->max_freq)
|
||||
return;
|
||||
|
||||
if (needs_4x_clock(q))
|
||||
|
|
@ -571,6 +573,7 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi,
|
|||
}
|
||||
|
||||
q->selected = spi_get_chipselect(spi, 0);
|
||||
q->selected_freq = op->max_freq;
|
||||
|
||||
fsl_qspi_invalidate(q);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user