]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
spi: spi-nxp-fspi: re-config the clock rate when operation require new clock rate
authorHaibo Chen <haibo.chen@nxp.com>
Mon, 22 Sep 2025 08:47:13 +0000 (16:47 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Oct 2025 13:10:26 +0000 (14:10 +0100)
[ Upstream commit a89103f67112453fa36c9513e951c19eed9d2d92 ]

Current operation contain the max_freq, so new coming operation may use
new clock rate, need to re-config the clock rate to match the requirement.

Fixes: 26851cf65ffc ("spi: nxp-fspi: Support per spi-mem operation frequency switches")
Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
Link: https://patch.msgid.link/20250922-fspi-fix-v1-1-ff4315359d31@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/spi/spi-nxp-fspi.c

index 7cbe774f1f39bb120ac40f61c419861009713867..542d6f57c1aef71a7f493827062e019605f8e4a6 100644 (file)
@@ -402,6 +402,8 @@ struct nxp_fspi {
 #define FSPI_NEED_INIT         BIT(0)
 #define FSPI_DTR_MODE          BIT(1)
        int flags;
+       /* save the previous operation clock rate */
+       unsigned long pre_op_rate;
 };
 
 static inline int needs_ip_only(struct nxp_fspi *f)
@@ -757,11 +759,17 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
        uint64_t size_kb;
 
        /*
-        * Return, if previously selected target device is same as current
-        * requested target device. Also the DTR or STR mode do not change.
+        * Return when following condition all meet,
+        * 1, if previously selected target device is same as current
+        *    requested target device.
+        * 2, the DTR or STR mode do not change.
+        * 3, previous operation max rate equals current one.
+        *
+        * For other case, need to re-config.
         */
        if ((f->selected == spi_get_chipselect(spi, 0)) &&
-           (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr))
+           (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr) &&
+           (f->pre_op_rate == op->max_freq))
                return;
 
        /* Reset FLSHxxCR0 registers */
@@ -807,6 +815,8 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
        if (rate > 100000000)
                nxp_fspi_dll_calibration(f);
 
+       f->pre_op_rate = op->max_freq;
+
        f->selected = spi_get_chipselect(spi, 0);
 }