mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 23:52:08 +02:00
spi: Fixes for v6.15
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. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmgySG0ACgkQJNaLcl1U h9ClEQf/ViohgWBL0RLAsPdqyfTvSvhLS87V5ze4LWRmzNSYkwUQcGx0fx3QjRCl ekZyzHUUzsFY/6yHlgZ8KaP2kgHBtuNc4l4Kefpnmen6GFCOsFjaw6X/3WHkxmLN kJOuMjNr4p4he1X0tUE5yZfAqWs2QdsZ91unfx8DejvHV0nzlaqjCp0yaJQEcnAx KPx1pkC9Lj9F+SPh2hs2bJeHLkIUmyj6ZRbqhQk4BYGdKTiGpAo7FclmVDjWiztZ uWZ3Auzsyd6d0z74RkR95SZHQFmwABzvYoz7/LtMw0QK6MCDq6FAlVuYAi7Rc6OJ GkmS9ERJsEGdflfDg0JMYG1wTtiawQ== =7jIv -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
95a9580d58
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
//
|
||||
// Copyright 2013 Freescale Semiconductor, Inc.
|
||||
// Copyright 2020 NXP
|
||||
// Copyright 2020-2025 NXP
|
||||
//
|
||||
// Freescale DSPI driver
|
||||
// This file contains a driver for the Freescale DSPI
|
||||
|
|
@ -62,6 +62,7 @@
|
|||
#define SPI_SR_TFIWF BIT(18)
|
||||
#define SPI_SR_RFDF BIT(17)
|
||||
#define SPI_SR_CMDFFF BIT(16)
|
||||
#define SPI_SR_TXRXS BIT(30)
|
||||
#define SPI_SR_CLEAR (SPI_SR_TCFQF | \
|
||||
SPI_SR_TFUF | SPI_SR_TFFF | \
|
||||
SPI_SR_CMDTCF | SPI_SR_SPEF | \
|
||||
|
|
@ -921,9 +922,20 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
|
|||
struct spi_transfer *transfer;
|
||||
bool cs = false;
|
||||
int status = 0;
|
||||
u32 val = 0;
|
||||
bool cs_change = false;
|
||||
|
||||
message->actual_length = 0;
|
||||
|
||||
/* Put DSPI in running mode if halted. */
|
||||
regmap_read(dspi->regmap, SPI_MCR, &val);
|
||||
if (val & SPI_MCR_HALT) {
|
||||
regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_HALT, 0);
|
||||
while (regmap_read(dspi->regmap, SPI_SR, &val) >= 0 &&
|
||||
!(val & SPI_SR_TXRXS))
|
||||
;
|
||||
}
|
||||
|
||||
list_for_each_entry(transfer, &message->transfers, transfer_list) {
|
||||
dspi->cur_transfer = transfer;
|
||||
dspi->cur_msg = message;
|
||||
|
|
@ -953,6 +965,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
|
|||
dspi->tx_cmd |= SPI_PUSHR_CMD_CONT;
|
||||
}
|
||||
|
||||
cs_change = transfer->cs_change;
|
||||
dspi->tx = transfer->tx_buf;
|
||||
dspi->rx = transfer->rx_buf;
|
||||
dspi->len = transfer->len;
|
||||
|
|
@ -962,6 +975,8 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
|
|||
SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
|
||||
SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
|
||||
|
||||
regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR);
|
||||
|
||||
spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer,
|
||||
dspi->progress, !dspi->irq);
|
||||
|
||||
|
|
@ -988,6 +1003,15 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
|
|||
dspi_deassert_cs(spi, &cs);
|
||||
}
|
||||
|
||||
if (status || !cs_change) {
|
||||
/* Put DSPI in stop mode */
|
||||
regmap_update_bits(dspi->regmap, SPI_MCR,
|
||||
SPI_MCR_HALT, SPI_MCR_HALT);
|
||||
while (regmap_read(dspi->regmap, SPI_SR, &val) >= 0 &&
|
||||
val & SPI_SR_TXRXS)
|
||||
;
|
||||
}
|
||||
|
||||
message->status = status;
|
||||
spi_finalize_current_message(ctlr);
|
||||
|
||||
|
|
@ -1167,6 +1191,20 @@ static int dspi_resume(struct device *dev)
|
|||
|
||||
static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume);
|
||||
|
||||
static const struct regmap_range dspi_yes_ranges[] = {
|
||||
regmap_reg_range(SPI_MCR, SPI_MCR),
|
||||
regmap_reg_range(SPI_TCR, SPI_CTAR(3)),
|
||||
regmap_reg_range(SPI_SR, SPI_TXFR3),
|
||||
regmap_reg_range(SPI_RXFR0, SPI_RXFR3),
|
||||
regmap_reg_range(SPI_CTARE(0), SPI_CTARE(3)),
|
||||
regmap_reg_range(SPI_SREX, SPI_SREX),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table dspi_access_table = {
|
||||
.yes_ranges = dspi_yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(dspi_yes_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_range dspi_volatile_ranges[] = {
|
||||
regmap_reg_range(SPI_MCR, SPI_TCR),
|
||||
regmap_reg_range(SPI_SR, SPI_SR),
|
||||
|
|
@ -1184,6 +1222,8 @@ static const struct regmap_config dspi_regmap_config = {
|
|||
.reg_stride = 4,
|
||||
.max_register = 0x88,
|
||||
.volatile_table = &dspi_volatile_table,
|
||||
.rd_table = &dspi_access_table,
|
||||
.wr_table = &dspi_access_table,
|
||||
};
|
||||
|
||||
static const struct regmap_range dspi_xspi_volatile_ranges[] = {
|
||||
|
|
@ -1205,6 +1245,8 @@ static const struct regmap_config dspi_xspi_regmap_config[] = {
|
|||
.reg_stride = 4,
|
||||
.max_register = 0x13c,
|
||||
.volatile_table = &dspi_xspi_volatile_table,
|
||||
.rd_table = &dspi_access_table,
|
||||
.wr_table = &dspi_access_table,
|
||||
},
|
||||
{
|
||||
.name = "pushr",
|
||||
|
|
@ -1227,6 +1269,8 @@ static int dspi_init(struct fsl_dspi *dspi)
|
|||
if (!spi_controller_is_target(dspi->ctlr))
|
||||
mcr |= SPI_MCR_HOST;
|
||||
|
||||
mcr |= SPI_MCR_HALT;
|
||||
|
||||
regmap_write(dspi->regmap, SPI_MCR, mcr);
|
||||
regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR);
|
||||
|
||||
|
|
|
|||
|
|
@ -249,10 +249,7 @@ struct spi_device {
|
|||
static_assert((SPI_MODE_KERNEL_MASK & SPI_MODE_USER_MASK) == 0,
|
||||
"SPI_MODE_USER_MASK & SPI_MODE_KERNEL_MASK must not overlap");
|
||||
|
||||
static inline struct spi_device *to_spi_device(const struct device *dev)
|
||||
{
|
||||
return dev ? container_of(dev, struct spi_device, dev) : NULL;
|
||||
}
|
||||
#define to_spi_device(__dev) container_of_const(__dev, struct spi_device, dev)
|
||||
|
||||
/* Most drivers won't need to care about device refcounting */
|
||||
static inline struct spi_device *spi_dev_get(struct spi_device *spi)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user