mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-09 15:24:32 +08:00
spi: fsl-spi: Re-organise transfer bits_per_word adaptation
(backported from upstream 8a5299a127
)
For different reasons, fsl-spi driver performs bits_per_word
modifications for different reasons:
- On CPU mode, to minimise amount of interrupts
- On CPM/QE mode to work around controller byte order
For CPU mode that's done in fsl_spi_prepare_message() while
for CPM mode that's done in fsl_spi_setup_transfer().
Reunify all of it in fsl_spi_prepare_message(), and catch
impossible cases early through master's bits_per_word_mask
instead of returning EINVAL later.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Link: https://lore.kernel.org/r/0ce96fe96e8b07cba0613e4097cfd94d09b8919a.1680371809.git.christophe.leroy@csgroup.eu
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
381e55bffe
commit
28ffe8c846
@ -203,26 +203,6 @@ static int mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs,
|
||||
return bits_per_word;
|
||||
}
|
||||
|
||||
static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs,
|
||||
struct spi_device *spi,
|
||||
int bits_per_word)
|
||||
{
|
||||
/* CPM/QE uses Little Endian for words > 8
|
||||
* so transform 16 and 32 bits words into 8 bits
|
||||
* Unfortnatly that doesn't work for LSB so
|
||||
* reject these for now */
|
||||
/* Note: 32 bits word, LSB works iff
|
||||
* tfcr/rfcr is set to CPMFCR_GBL */
|
||||
if (spi->mode & SPI_LSB_FIRST &&
|
||||
bits_per_word > 8)
|
||||
return -EINVAL;
|
||||
if (bits_per_word <= 8)
|
||||
return bits_per_word;
|
||||
if (bits_per_word == 16 || bits_per_word == 32)
|
||||
return 8; /* pretend its 8 bits */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int fsl_spi_setup_transfer(struct spi_device *spi,
|
||||
struct spi_transfer *t)
|
||||
{
|
||||
@ -250,9 +230,6 @@ static int fsl_spi_setup_transfer(struct spi_device *spi,
|
||||
bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi,
|
||||
mpc8xxx_spi,
|
||||
bits_per_word);
|
||||
else
|
||||
bits_per_word = mspi_apply_qe_mode_quirks(cs, spi,
|
||||
bits_per_word);
|
||||
|
||||
if (bits_per_word < 0)
|
||||
return bits_per_word;
|
||||
@ -370,14 +347,27 @@ static int fsl_spi_do_one_msg(struct spi_master *master,
|
||||
* In CPU mode, optimize large byte transfers to use larger
|
||||
* bits_per_word values to reduce number of interrupts taken.
|
||||
*/
|
||||
if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
|
||||
list_for_each_entry(t, &m->transfers, transfer_list) {
|
||||
list_for_each_entry(t, &m->transfers, transfer_list) {
|
||||
if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
|
||||
if (t->len < 256 || t->bits_per_word != 8)
|
||||
continue;
|
||||
if ((t->len & 3) == 0)
|
||||
t->bits_per_word = 32;
|
||||
else if ((t->len & 1) == 0)
|
||||
t->bits_per_word = 16;
|
||||
} else {
|
||||
/*
|
||||
* CPM/QE uses Little Endian for words > 8
|
||||
* so transform 16 and 32 bits words into 8 bits
|
||||
* Unfortnatly that doesn't work for LSB so
|
||||
* reject these for now
|
||||
* Note: 32 bits word, LSB works iff
|
||||
* tfcr/rfcr is set to CPMFCR_GBL
|
||||
*/
|
||||
if (m->spi->mode & SPI_LSB_FIRST && t->bits_per_word > 8)
|
||||
return -EINVAL;
|
||||
if (t->bits_per_word == 16 || t->bits_per_word == 32)
|
||||
t->bits_per_word = 8; /* pretend its 8 bits */
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,8 +625,14 @@ static struct spi_master *fsl_spi_probe(struct device *dev,
|
||||
if (mpc8xxx_spi->type == TYPE_GRLIB)
|
||||
fsl_spi_grlib_probe(dev);
|
||||
|
||||
master->bits_per_word_mask =
|
||||
(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)) &
|
||||
if (mpc8xxx_spi->flags & SPI_CPM_MODE)
|
||||
master->bits_per_word_mask =
|
||||
(SPI_BPW_RANGE_MASK(4, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32));
|
||||
else
|
||||
master->bits_per_word_mask =
|
||||
(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32));
|
||||
|
||||
master->bits_per_word_mask &=
|
||||
SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word);
|
||||
|
||||
if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE)
|
||||
|
Loading…
Reference in New Issue
Block a user