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

Pull spi fixes from Mark Brown:
"A few final fixes for v6.15, some driver fixes for the Freescale DSPI
driver pulled over from their vendor code and another instance of the
fixes Greg has been sending throughout the kernel for constification
of the bus_type in driver core match() functions"

* tag 'spi-fix-v6.15-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
spi: spi-fsl-dspi: Reset SR flags before sending a new message
spi: spi-fsl-dspi: Halt the module after a new message transfer
spi: spi-fsl-dspi: restrict register range for regmap access
spi: use container_of_cont() for to_spi_device()

Changed files
+46 -5
drivers
include
linux
spi
+45 -1
drivers/spi/spi-fsl-dspi.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0+ 2 2 // 3 3 // Copyright 2013 Freescale Semiconductor, Inc. 4 - // Copyright 2020 NXP 4 + // Copyright 2020-2025 NXP 5 5 // 6 6 // Freescale DSPI driver 7 7 // This file contains a driver for the Freescale DSPI ··· 62 62 #define SPI_SR_TFIWF BIT(18) 63 63 #define SPI_SR_RFDF BIT(17) 64 64 #define SPI_SR_CMDFFF BIT(16) 65 + #define SPI_SR_TXRXS BIT(30) 65 66 #define SPI_SR_CLEAR (SPI_SR_TCFQF | \ 66 67 SPI_SR_TFUF | SPI_SR_TFFF | \ 67 68 SPI_SR_CMDTCF | SPI_SR_SPEF | \ ··· 922 921 struct spi_transfer *transfer; 923 922 bool cs = false; 924 923 int status = 0; 924 + u32 val = 0; 925 + bool cs_change = false; 925 926 926 927 message->actual_length = 0; 928 + 929 + /* Put DSPI in running mode if halted. */ 930 + regmap_read(dspi->regmap, SPI_MCR, &val); 931 + if (val & SPI_MCR_HALT) { 932 + regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_HALT, 0); 933 + while (regmap_read(dspi->regmap, SPI_SR, &val) >= 0 && 934 + !(val & SPI_SR_TXRXS)) 935 + ; 936 + } 927 937 928 938 list_for_each_entry(transfer, &message->transfers, transfer_list) { 929 939 dspi->cur_transfer = transfer; ··· 965 953 dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; 966 954 } 967 955 956 + cs_change = transfer->cs_change; 968 957 dspi->tx = transfer->tx_buf; 969 958 dspi->rx = transfer->rx_buf; 970 959 dspi->len = transfer->len; ··· 974 961 regmap_update_bits(dspi->regmap, SPI_MCR, 975 962 SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, 976 963 SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); 964 + 965 + regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR); 977 966 978 967 spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, 979 968 dspi->progress, !dspi->irq); ··· 1001 986 1002 987 if (!(dspi->tx_cmd & SPI_PUSHR_CMD_CONT)) 1003 988 dspi_deassert_cs(spi, &cs); 989 + } 990 + 991 + if (status || !cs_change) { 992 + /* Put DSPI in stop mode */ 993 + regmap_update_bits(dspi->regmap, SPI_MCR, 994 + SPI_MCR_HALT, SPI_MCR_HALT); 995 + while (regmap_read(dspi->regmap, SPI_SR, &val) >= 0 && 996 + val & SPI_SR_TXRXS) 997 + ; 1004 998 } 1005 999 1006 1000 message->status = status; ··· 1191 1167 1192 1168 static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); 1193 1169 1170 + static const struct regmap_range dspi_yes_ranges[] = { 1171 + regmap_reg_range(SPI_MCR, SPI_MCR), 1172 + regmap_reg_range(SPI_TCR, SPI_CTAR(3)), 1173 + regmap_reg_range(SPI_SR, SPI_TXFR3), 1174 + regmap_reg_range(SPI_RXFR0, SPI_RXFR3), 1175 + regmap_reg_range(SPI_CTARE(0), SPI_CTARE(3)), 1176 + regmap_reg_range(SPI_SREX, SPI_SREX), 1177 + }; 1178 + 1179 + static const struct regmap_access_table dspi_access_table = { 1180 + .yes_ranges = dspi_yes_ranges, 1181 + .n_yes_ranges = ARRAY_SIZE(dspi_yes_ranges), 1182 + }; 1183 + 1194 1184 static const struct regmap_range dspi_volatile_ranges[] = { 1195 1185 regmap_reg_range(SPI_MCR, SPI_TCR), 1196 1186 regmap_reg_range(SPI_SR, SPI_SR), ··· 1222 1184 .reg_stride = 4, 1223 1185 .max_register = 0x88, 1224 1186 .volatile_table = &dspi_volatile_table, 1187 + .rd_table = &dspi_access_table, 1188 + .wr_table = &dspi_access_table, 1225 1189 }; 1226 1190 1227 1191 static const struct regmap_range dspi_xspi_volatile_ranges[] = { ··· 1245 1205 .reg_stride = 4, 1246 1206 .max_register = 0x13c, 1247 1207 .volatile_table = &dspi_xspi_volatile_table, 1208 + .rd_table = &dspi_access_table, 1209 + .wr_table = &dspi_access_table, 1248 1210 }, 1249 1211 { 1250 1212 .name = "pushr", ··· 1268 1226 mcr |= SPI_MCR_XSPI; 1269 1227 if (!spi_controller_is_target(dspi->ctlr)) 1270 1228 mcr |= SPI_MCR_HOST; 1229 + 1230 + mcr |= SPI_MCR_HALT; 1271 1231 1272 1232 regmap_write(dspi->regmap, SPI_MCR, mcr); 1273 1233 regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR);
+1 -4
include/linux/spi/spi.h
··· 249 249 static_assert((SPI_MODE_KERNEL_MASK & SPI_MODE_USER_MASK) == 0, 250 250 "SPI_MODE_USER_MASK & SPI_MODE_KERNEL_MASK must not overlap"); 251 251 252 - static inline struct spi_device *to_spi_device(const struct device *dev) 253 - { 254 - return dev ? container_of(dev, struct spi_device, dev) : NULL; 255 - } 252 + #define to_spi_device(__dev) container_of_const(__dev, struct spi_device, dev) 256 253 257 254 /* Most drivers won't need to care about device refcounting */ 258 255 static inline struct spi_device *spi_dev_get(struct spi_device *spi)