Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod
members of struct spi_device to be an array. But changing the type of these
members to array would break the spi driver functionality. To make the
transition smoother introduced four new APIs to get/set the
spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and
spi->cs_gpiod references with get or set API calls.
While adding multi-cs support in further patches the chip_select & cs_gpiod
members of the spi_device structure would be converted to arrays & the
"idx" parameter of the APIs would be used as array index i.e.,
spi->chip_select[idx] & spi->cs_gpiod[idx] respectively.
Signed-off-by: Amit Kumar Mahapatra <amit.kumar-mahapatra@amd.com>
Acked-by: Heiko Stuebner <heiko@sntech.de> # Rockchip drivers
Reviewed-by: Michal Simek <michal.simek@amd.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org> # Aspeed driver
Reviewed-by: Dhruva Gole <d-gole@ti.com> # SPI Cadence QSPI
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com> # spi-stm32-qspi
Acked-by: William Zhang <william.zhang@broadcom.com> # bcm63xx-hsspi driver
Reviewed-by: Serge Semin <fancer.lancer@gmail.com> # DW SSI part
Link: https://lore.kernel.org/r/167847070432.26.15076794204368669839@mailman-core.alsa-project.org
Signed-off-by: Mark Brown <broonie@kernel.org>
The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is (mostly) ignored
and this typically results in resource leaks. To improve here there is a
quest to make the remove callback return void. In the first step of this
quest all drivers are converted to .remove_new() which already returns
void.
Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20230303172041.2103336-26-u.kleine-koenig@pengutronix.de
Signed-off-by: Mark Brown <broonie@kernel.org>
The 'delay_usecs' field is being removed from the spi_transfer struct.
This change removes it from the SPI FSL ESPI driver.
Signed-off-by: Alexandru Ardelean <aardelean@deviqon.com>
Link: https://lore.kernel.org/r/20210308145502.1075689-9-aardelean@deviqon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The SPIE register contains counts for the TX FIFO so any time the irq
handler was invoked we would attempt to process the RX/TX fifos. Use the
SPIM value to mask the events so that we only process interrupts that
were expected.
This was a latent issue exposed by commit 3282a3da25 ("powerpc/64:
Implement soft interrupt replay in C").
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Link: https://lore.kernel.org/r/20200904002812.7300-1-chris.packham@alliedtelesis.co.nz
Signed-off-by: Mark Brown <broonie@kernel.org>
The register offset is already included in the device name so even prior
%p values being hashed printing the base was redundant. Remove the %p
from the dev_info() output.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Link: https://lore.kernel.org/r/20200825050856.29616-1-chris.packham@alliedtelesis.co.nz
Reviewed-by: Fabio Estevam <festevam@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
For many places in the spi drivers, using the new `spi_transfer_delay`
helper is straightforward.
It's just replacing:
```
if (t->delay_usecs)
udelay(t->delay_usecs);
```
with `spi_transfer_delay(t)` which handles both `delay_usecs` and the new
`delay` field.
This change replaces in all places (in the spi drivers) where this change
is simple.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Link: https://lore.kernel.org/r/20190926105147.7839-10-alexandru.ardelean@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The way the max delay is computed for this controller, it looks like it is
searching for the max delay from an SPI message a using that.
No idea if this is valid. But this change should support both `delay_usecs`
and the new `delay` data which is of `spi_delay` type.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Link: https://lore.kernel.org/r/20190926105147.7839-17-alexandru.ardelean@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Based on 1 normalized pattern(s):
this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license as published by
the free software foundation either version 2 of the license or at
your option any later version
extracted by the scancode license scanner the SPDX license identifier
GPL-2.0-or-later
has been chosen to replace the boilerplate/reference in 3029 file(s).
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
spi_controller_{suspend,resume}() already prints an error message on
failure, so there is no need to repeat this in individual drivers.
Note: spi_master_{suspend,resume}() is an alias for
spi_controller_{suspend,resume}().
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Reviewed-by: Daniel Mack <daniel@zonque.org>
Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Log RX and TX fifo counters when a transfer is done and these are not
zero.
Signed-off-by: Tiago Brusamarello <tiago.brusamarello@datacom.ind.br>
Signed-off-by: Mark Brown <broonie@kernel.org>
fsl_espi_read_reg16 / fsl_espi_write_reg16 are supposed to read / write
big endian values. Therefore ioread16be / iowrite16be have to be used.
Fixes: 0582343284 ("eliminate need for linearization when writing to hardware")
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
After introducing direct transfers between hardware and transfer
buffers remove all code which is unused now.
This includes getting rid of the 64k linearization buffer.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Eliminate need for linearization when reading from the hardware and
write to the transfer buffers directly.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Eliminate need for linearization when writing to the hardware and
read from the transfer buffers directly.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Determine need for byte swap only once and store it in new member
swab in struct fsl_espi.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
ESPI has a max and min supported SPI frequency, determined by the
clock divider range. Set master->min_speed_hz/max_speed_hz to inform
the SPI core about these limits.
Then the SPI core handles cases where a transfer requests a frequency
outside the supported range.
So far the driver simply set the lowest supported frequency if the
requested frequency was below the supported range. This is not
necessarily an appropriate action as the device might not support
frequencies greater than the requested one.
With this patch the SPI core will reject transfers requesting a
too low frequency.
The check in fsl_espi_setup can be removed because the SPI core sets
spi->max_speed_hz to master->max_speed_hz if it's not set already.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
After having removed all code dependencies we can make fsl-espi
completely independent of fsl-lib now.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Only few members of struct mpc8xxx_spi are relevant for fsl-espi.
Therefore replace it with a ESPI-specific struct fsl_espi.
Replace variable names mpc8xxx_spi and mspi with espi.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The register initialization is the same in fsl_espi_probe and in
of_fsl_espi_resume. Therefore factor it out into fsl_espi_init_regs.
It was actually a bug that CSMODE_BEF and CSMODE_AFT were not set
in of_fsl_espi_resume. Seems like nobody ever used values other
than zero for these parameters.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Very little from struct spi_mpc8xxx_cs is relevant for fsl-espi.
Therefore replace it with struct fsl_espi_cs.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Very little of the library functions mpc8xxx_spi_probe and
of_mpc8xxx_spi_probe is relevant for fsl-espi.
Therefore migrate the relevant parts to fsl-espi (considering
that get_brgfreq() always returns -1 on systems with ESPI)
and remove use of these functions.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
There's no need to access mpc8xxx_spi->irq, we can use function
parameter irq directly.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Change the check to access property "mode" directly.
This allows us to get rid of mpc8xxx_spi->flags in a subsequent
patch in this patch series as it's used nowhere else.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Use master->num_chipselect directly instead of pdata->max_chipselect.
In this context let of_fsl_espi_get_chipselects return max_chipselect.
This change allows us to get rid of struct fsl_spi_platform_data
completely in the fsl-espi driver.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Don't set pdata->cs_control as it's nowhere used in fsl-espi and fsl-lib.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Remove pdata->initial_spmode as it is nowhere set.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This patch adds support for dual output read mode.
It was successfully tested on a P1014-based device with S25FL128S
SPINOR flash. With 50MHz SPI clock the read rate is 11MByte/s.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This patch adds support for ESPI RXSKIP mode. This mode is optimized
for flash reads:
- sends a number of bytes and then reads a number of bytes
- shifts out zeros automatically when reading
Supporting RXSKIP mode is a prerequisite for supporting dual output
read mode.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
There's no need to bother the chip if the mode doesn't change.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Resetting the chip to a default transfer mode after each transfer
doesn't provide any benefit. Therefore remove this call.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
According to NXP ESPI datasheet, the SPI clock rate is:
spi_clk = System_Clock / ( 2 * DIV16 * ( 1 + PM ) )
Where System_Clock is the platform clock divided by 2,
DIV16 may be 1 or 16, and PM is a 4 bits integer (0 to 15).
Isolating PM on the expression, we get:
PM = (System_Clock / ( 2 * DIV16 * spi_clk ) ) - 1
Where System_Clock = mpc8xxx_spi->spibrg / 2, spi_clk = hz,
and DIV16 = 1 or DIV16 = 16. So,
PM = (mpc8xxx_spi->spibrg / ( 4 * hz) ) - 1
or
PM = (mpc8xxx_spi->spibrg / ( 16 * 4 * hz) ) - 1
Current spi-fsl-espi driver can't configure the HW for all
supported clock rates. It filters out clock rates for PM = 0
and PM = 1.
This patch allows all range of supported clock rates to be
configured on the ESPI controller.
Signed-off-by: Paulo Zaneti <paulo.zaneti@datacom.ind.br>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
spin_lock is used to obtain the spinlock, so spin_unlock
has to be used here.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Currently the driver polls in the ISR for enough bytes in the RX FIFO.
An ISR should never do this.
Change it to read as much as possible whenever the ISR is called.
This also allows to significantly simplify the code.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
So far an interrupt is triggered whenever there's at least one byte
in the RX FIFO. This results in a unnecessarily high number of
interrupts.
Change this to generate an interrupt if
- RX FIFO is half full (except if all bytes to read fit into the
RX FIFO anyway)
- end of transfer has been reached
This way the number of interrupts can be significantly reduced.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Extend and improve transfer error handling
- in case of timeout report also number of remaining rx bytes
- in case of timeout return ETIMEDOUT instead of EMSGSIZE
- add sanity checks after all bytes have been sent / read:
- check that HW has flag SPIE_DON set
- check that RX / TX FIFO are empty
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The ESPI spec mentions no requirement to turn off the ESPI unit prior
to changing the mode. Most likely the ESPI unit is only turned off to
clear the FIFO's as before this patch series single bytes could
remain in the TX FIFO after transfer end.
Therefore remove disabling / re-enabling the ESPI unit.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Now that we introduced element tx_len in struct mpc8xxx_spi let's
rename element len to rx_len as it actually is the number of bytes to
receive. In addition make it unsigned.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This change addresses two issues:
- If the TX FIFO is full the ISR polls until there's free space again.
An ISR should never wait for something.
- Currently the number of bytes to transfer is rounded up to the next
multiple of 4. For most transfers therefore few bytes remain in the
TX FIFO after end of transfer.
This would cause the next transfer to fail and as a workaround the
ESPI block is disabled / re-enabled in fsl_espi_change_mode.
This seems to clear the FIFO's (although it's not mentioned in the
spec).
With this change the TX FIFO is filled as much as possible initially
and whenever the ISR is called. Also the exact number of bytes is
transferred.
The spinlock protects against a potential race if the first interrupt
occurs whilst the TX FIFO is still being initially filled.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
SPI_QE_CPU_MODE doesn't exist for ESPI and is set by of_mpc8xxx_spi_probe
based on DT property "mode". This property is not defined for ESPI,
see Documentation/devicetree/bindings/spi/fsl-spi.txt.
So print an error message and bail out if SPI_QE_CPU_MODE is set.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Commit 5c0ba57744 ("spi: fsl-espi: avoid processing uninitalized
data on error") applied fine to stable but caused a merge conflict
on next. This patch fixes that.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
When we get a spurious interrupt in fsl_espi_irq, we end up
processing four uninitalized bytes of data, as shown in this
warning message:
drivers/spi/spi-fsl-espi.c: In function 'fsl_espi_irq':
drivers/spi/spi-fsl-espi.c:462:4: warning: 'rx_data' may be used uninitialized in this function [-Wmaybe-uninitialized]
This adds another check so we skip the data in this case.
Fixes: 6319a68011 ("spi/fsl-espi: avoid infinite loops on fsl_espi_cpu_irq()")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
The code in fsl_espi_tx_buf_lsb and parts of fsl_espi_setup_transfer
look very weird and don't reflect the ESPI spec.
ESPI stores values with <= 8 bit word size right justified as 8 bit
value and values with > 8 bit word size right justified as 16 bit
value. Therefore no such shifting is needed.
Only case MSB-first with 8 bit word size is correctly handled,
and most likely nobody ever used this driver with a different config.
On ESPI only the case LSB-first with word size > 8 bit needs a
special handling. In this case a little endian 16 bit value has
to be written to the TX FIFO what requires a byte swap as the
host system is big endian.
The same applies to reading from the RX FIFO.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
According to the ESPI spec MSB-first transfers are supported for
word size 8 and 16 only.
Check for this and reject MSB-first transfers with other word sizes.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
of_property_read_u32 is better here than generic of_get_property:
- implicit endianness conversion if needed
- implicit checking of size of property
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The return value of fsl_espi_probe (currently struct spi_master *)
is just used for checking whether an error occurred.
Change the return value type to int and simplify the code.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>