mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-29 14:05:19 +08:00
spi: Fixes for v6.7
A few bigger things here, the main one being that there were changes to the atmel driver in this cycle which made it possible to kill transfers being used for filesystem I/O which turned out to be very disruptive, the series of patches here undoes that and hardens things up further. There's also a few smaller driver specific changes, the main one being to revert a change that duplicted delays. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmWASuIACgkQJNaLcl1U h9BEJQf/S3NWQvQPZ+k3YofQuvepPx7LfBDwJXcfHFqXXabjeNHZfQyftrWpik3s KAGqRhZdQyw8Q2aMiL8/2uXPf8uihuZNoVEbMNd2IHHE2q7uIRdR92E1sf912VaO T5yQPfVAJo6PthaSYAPGyhsPTPbvSWwgh1sMkHAdfITTKPHniQWVb9Bt1k+S0c6b xerBN/Jg9nX5+2WgnfA9fznD8+o0H+MF9bSudmDqdCjgXr59bmJccZHm/aasU0zq ELaqbYt2sTIpiRmvkuTWQ2dGrNdnuCQOkP3OFvzAsF4JCWUADPtFtMi1HHIkygdK q+L/M55OvJdUsXHLAtlqMEWW7ne2ZA== =l4ac -----END PGP SIGNATURE----- Merge tag 'spi-fix-v6.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi Pull spi fixes from Mark Brown: "A few bigger things here, the main one being that there were changes to the atmel driver in this cycle which made it possible to kill transfers being used for filesystem I/O which turned out to be very disruptive, the series of patches here undoes that and hardens things up further. There's also a few smaller driver specific changes, the main one being to revert a change that duplicted delays" * tag 'spi-fix-v6.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi: atmel: Fix clock issue when using devices with different polarities spi: spi-imx: correctly configure burst length when using dma spi: cadence: revert "Add SPI transfer delays" spi: atmel: Prevent spi transfers from being killed spi: atmel: Drop unused defines spi: atmel: Do not cancel a transfer upon any signal
This commit is contained in:
commit
26d6084791
@ -22,6 +22,7 @@
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <trace/events/spi.h>
|
||||
|
||||
/* SPI register offsets */
|
||||
@ -233,9 +234,6 @@
|
||||
*/
|
||||
#define DMA_MIN_BYTES 16
|
||||
|
||||
#define SPI_DMA_MIN_TIMEOUT (msecs_to_jiffies(1000))
|
||||
#define SPI_DMA_TIMEOUT_PER_10K (msecs_to_jiffies(4))
|
||||
|
||||
#define AUTOSUSPEND_TIMEOUT 2000
|
||||
|
||||
struct atmel_spi_caps {
|
||||
@ -279,6 +277,7 @@ struct atmel_spi {
|
||||
bool keep_cs;
|
||||
|
||||
u32 fifo_size;
|
||||
bool last_polarity;
|
||||
u8 native_cs_free;
|
||||
u8 native_cs_for_gpio;
|
||||
};
|
||||
@ -291,6 +290,22 @@ struct atmel_spi_device {
|
||||
#define SPI_MAX_DMA_XFER 65535 /* true for both PDC and DMA */
|
||||
#define INVALID_DMA_ADDRESS 0xffffffff
|
||||
|
||||
/*
|
||||
* This frequency can be anything supported by the controller, but to avoid
|
||||
* unnecessary delay, the highest possible frequency is chosen.
|
||||
*
|
||||
* This frequency is the highest possible which is not interfering with other
|
||||
* chip select registers (see Note for Serial Clock Bit Rate configuration in
|
||||
* Atmel-11121F-ATARM-SAMA5D3-Series-Datasheet_02-Feb-16, page 1283)
|
||||
*/
|
||||
#define DUMMY_MSG_FREQUENCY 0x02
|
||||
/*
|
||||
* 8 bits is the minimum data the controller is capable of sending.
|
||||
*
|
||||
* This message can be anything as it should not be treated by any SPI device.
|
||||
*/
|
||||
#define DUMMY_MSG 0xAA
|
||||
|
||||
/*
|
||||
* Version 2 of the SPI controller has
|
||||
* - CR.LASTXFER
|
||||
@ -304,6 +319,43 @@ static bool atmel_spi_is_v2(struct atmel_spi *as)
|
||||
return as->caps.is_spi2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a dummy message.
|
||||
*
|
||||
* This is sometimes needed when using a CS GPIO to force clock transition when
|
||||
* switching between devices with different polarities.
|
||||
*/
|
||||
static void atmel_spi_send_dummy(struct atmel_spi *as, struct spi_device *spi, int chip_select)
|
||||
{
|
||||
u32 status;
|
||||
u32 csr;
|
||||
|
||||
/*
|
||||
* Set a clock frequency to allow sending message on SPI bus.
|
||||
* The frequency here can be anything, but is needed for
|
||||
* the controller to send the data.
|
||||
*/
|
||||
csr = spi_readl(as, CSR0 + 4 * chip_select);
|
||||
csr = SPI_BFINS(SCBR, DUMMY_MSG_FREQUENCY, csr);
|
||||
spi_writel(as, CSR0 + 4 * chip_select, csr);
|
||||
|
||||
/*
|
||||
* Read all data coming from SPI bus, needed to be able to send
|
||||
* the message.
|
||||
*/
|
||||
spi_readl(as, RDR);
|
||||
while (spi_readl(as, SR) & SPI_BIT(RDRF)) {
|
||||
spi_readl(as, RDR);
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
spi_writel(as, TDR, DUMMY_MSG);
|
||||
|
||||
readl_poll_timeout_atomic(as->regs + SPI_SR, status,
|
||||
(status & SPI_BIT(TXEMPTY)), 1, 1000);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby
|
||||
* they assume that spi slave device state will not change on deselect, so
|
||||
@ -320,11 +372,17 @@ static bool atmel_spi_is_v2(struct atmel_spi *as)
|
||||
* Master on Chip Select 0.") No workaround exists for that ... so for
|
||||
* nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH,
|
||||
* and (c) will trigger that first erratum in some cases.
|
||||
*
|
||||
* When changing the clock polarity, the SPI controller waits for the next
|
||||
* transmission to enforce the default clock state. This may be an issue when
|
||||
* using a GPIO as Chip Select: the clock level is applied only when the first
|
||||
* packet is sent, once the CS has already been asserted. The workaround is to
|
||||
* avoid this by sending a first (dummy) message before toggling the CS state.
|
||||
*/
|
||||
|
||||
static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
|
||||
{
|
||||
struct atmel_spi_device *asd = spi->controller_state;
|
||||
bool new_polarity;
|
||||
int chip_select;
|
||||
u32 mr;
|
||||
|
||||
@ -353,6 +411,25 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
|
||||
}
|
||||
|
||||
mr = spi_readl(as, MR);
|
||||
|
||||
/*
|
||||
* Ensures the clock polarity is valid before we actually
|
||||
* assert the CS to avoid spurious clock edges to be
|
||||
* processed by the spi devices.
|
||||
*/
|
||||
if (spi_get_csgpiod(spi, 0)) {
|
||||
new_polarity = (asd->csr & SPI_BIT(CPOL)) != 0;
|
||||
if (new_polarity != as->last_polarity) {
|
||||
/*
|
||||
* Need to disable the GPIO before sending the dummy
|
||||
* message because it is already set by the spi core.
|
||||
*/
|
||||
gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), 0);
|
||||
atmel_spi_send_dummy(as, spi, chip_select);
|
||||
as->last_polarity = new_polarity;
|
||||
gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
|
||||
int i;
|
||||
@ -1336,12 +1413,10 @@ static int atmel_spi_one_transfer(struct spi_controller *host,
|
||||
}
|
||||
|
||||
dma_timeout = msecs_to_jiffies(spi_controller_xfer_timeout(host, xfer));
|
||||
ret_timeout = wait_for_completion_interruptible_timeout(&as->xfer_completion,
|
||||
dma_timeout);
|
||||
if (ret_timeout <= 0) {
|
||||
dev_err(&spi->dev, "spi transfer %s\n",
|
||||
!ret_timeout ? "timeout" : "canceled");
|
||||
as->done_status = ret_timeout < 0 ? ret_timeout : -EIO;
|
||||
ret_timeout = wait_for_completion_timeout(&as->xfer_completion, dma_timeout);
|
||||
if (!ret_timeout) {
|
||||
dev_err(&spi->dev, "spi transfer timeout\n");
|
||||
as->done_status = -EIO;
|
||||
}
|
||||
|
||||
if (as->done_status)
|
||||
|
@ -451,7 +451,6 @@ static int cdns_transfer_one(struct spi_controller *ctlr,
|
||||
udelay(10);
|
||||
|
||||
cdns_spi_process_fifo(xspi, xspi->tx_fifo_depth, 0);
|
||||
spi_transfer_delay_exec(transfer);
|
||||
|
||||
cdns_spi_write(xspi, CDNS_SPI_IER, CDNS_SPI_IXR_DEFAULT);
|
||||
return transfer->len;
|
||||
|
@ -659,11 +659,18 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx,
|
||||
ctrl |= (spi_imx->target_burst * 8 - 1)
|
||||
<< MX51_ECSPI_CTRL_BL_OFFSET;
|
||||
else {
|
||||
if (spi_imx->count >= 512)
|
||||
ctrl |= 0xFFF << MX51_ECSPI_CTRL_BL_OFFSET;
|
||||
else
|
||||
ctrl |= (spi_imx->count * spi_imx->bits_per_word - 1)
|
||||
if (spi_imx->usedma) {
|
||||
ctrl |= (spi_imx->bits_per_word *
|
||||
spi_imx_bytes_per_word(spi_imx->bits_per_word) - 1)
|
||||
<< MX51_ECSPI_CTRL_BL_OFFSET;
|
||||
} else {
|
||||
if (spi_imx->count >= MX51_ECSPI_CTRL_MAX_BURST)
|
||||
ctrl |= (MX51_ECSPI_CTRL_MAX_BURST - 1)
|
||||
<< MX51_ECSPI_CTRL_BL_OFFSET;
|
||||
else
|
||||
ctrl |= (spi_imx->count * spi_imx->bits_per_word - 1)
|
||||
<< MX51_ECSPI_CTRL_BL_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
/* set clock speed */
|
||||
|
Loading…
Reference in New Issue
Block a user