summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-fsl-dspi.c
AgeCommit message (Collapse)Author
2025-07-17spi: spi-fsl-dspi: Clear completion counter before initiating transferJames Clark
[ Upstream commit fa60c094c19b97e103d653f528f8d9c178b6a5f5 ] In target mode, extra interrupts can be received between the end of a transfer and halting the module if the host continues sending more data. If the interrupt from this occurs after the reinit_completion() then the completion counter is left at a non-zero value. The next unrelated transfer initiated by userspace will then complete immediately without waiting for the interrupt or writing to the RX buffer. Fix it by resetting the counter before the transfer so that lingering values are cleared. This is done after clearing the FIFOs and the status register but before the transfer is initiated, so no interrupts should be received at this point resulting in other race conditions. Fixes: 4f5ee75ea171 ("spi: spi-fsl-dspi: Replace interruptible wait queue with a simple completion") Signed-off-by: James Clark <james.clark@linaro.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20250627-james-nxp-spi-dma-v4-1-178dba20c120@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-07-17spi: spi-fsl-dspi: Fix interrupt-less DMA mode taking an XSPI code pathVladimir Oltean
[ Upstream commit 826b3a6a34619b934cdc33eeb961fcb99ce92c09 ] Interrupts are not necessary for DMA functionality, since the completion event is provided by the DMA driver. But if the driver fails to request the IRQ defined in the device tree, it will call dspi_poll which would make the driver hang waiting for data to become available in the RX FIFO. Fixes: c55be3059159 ("spi: spi-fsl-dspi: Use poll mode in case the platform IRQ is missing") Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Tested-by: Michael Walle <michael@walle.cc> Link: https://lore.kernel.org/r/20200318001603.9650-9-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org> Stable-dep-of: fa60c094c19b ("spi: spi-fsl-dspi: Clear completion counter before initiating transfer") Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-07-17spi: spi-fsl-dspi: Rename fifo_{read,write} and {tx,cmd}_fifo_writeVladimir Oltean
[ Upstream commit 547248fbed23f3cd2f6a5937b44fad60993640c4 ] These function names are very generic and it is easy to get confused. Rename them after the hardware register that they are accessing. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://lore.kernel.org/r/20200304220044.11193-6-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org> Stable-dep-of: fa60c094c19b ("spi: spi-fsl-dspi: Clear completion counter before initiating transfer") Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-06-04spi: spi-fsl-dspi: restrict register range for regmap accessLarisa Grigore
[ Upstream commit 283ae0c65e9c592f4a1ba4f31917f5e766da7f31 ] DSPI registers are NOT continuous, some registers are reserved and accessing them from userspace will trigger external abort, add regmap register access table to avoid below abort. For example on S32G: # cat /sys/kernel/debug/regmap/401d8000.spi/registers Internal error: synchronous external abort: 96000210 1 PREEMPT SMP ... Call trace: regmap_mmio_read32le+0x24/0x48 regmap_mmio_read+0x48/0x70 _regmap_bus_reg_read+0x38/0x48 _regmap_read+0x68/0x1b0 regmap_read+0x50/0x78 regmap_read_debugfs+0x120/0x338 Fixes: 1acbdeb92c87 ("spi/fsl-dspi: Convert to use regmap and add big-endian support") Co-developed-by: Xulin Sun <xulin.sun@windriver.com> Signed-off-by: Xulin Sun <xulin.sun@windriver.com> Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com> Signed-off-by: James Clark <james.clark@linaro.org> Link: https://patch.msgid.link/20250522-james-nxp-spi-v2-1-bea884630cfb@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-06-21spi: fsl-dspi: avoid SCK glitches with continuous transfersVladimir Oltean
[ Upstream commit c5c31fb71f16ba75bad4ade208abbae225305b65 ] The DSPI controller has configurable timing for (a) tCSC: the interval between the assertion of the chip select and the first clock edge (b) tASC: the interval between the last clock edge and the deassertion of the chip select What is a bit surprising, but is documented in the figure "Example of continuous transfer (CPHA=1, CONT=1)" in the datasheet, is that when the chip select stays asserted between multiple TX FIFO writes, the tCSC and tASC times still apply. With CONT=1, chip select remains asserted, but SCK takes a break and goes to the idle state for tASC + tCSC ns. In other words, the default values (of 0 and 0 ns) result in SCK glitches where the SCK transition to the idle state, as well as the SCK transition from the idle state, will have no delay in between, and it may appear that a SCK cycle has simply gone missing. The resulting timing violation might cause data corruption in many peripherals, as their chip select is asserted. The driver has device tree bindings for tCSC ("fsl,spi-cs-sck-delay") and tASC ("fsl,spi-sck-cs-delay"), but these are only specified to apply when the chip select toggles in the first place, and this timing characteristic depends on each peripheral. Many peripherals do not have explicit timing requirements, so many device trees do not have these properties present at all. Nonetheless, the lack of SCK glitches is a common sense requirement, and since the SCK stays in the idle state during transfers for tCSC+tASC ns, and that in itself should look like half a cycle, then let's ensure that tCSC and tASC are at least a quarter of a SCK period, such that their sum is at least half of one. Fixes: 95bf15f38641 ("spi: fsl-dspi: Add ~50ns delay between cs and sck") Reported-by: Lisa Chen (陈敏捷) <minjie.chen@geekplus.com> Debugged-by: Lisa Chen (陈敏捷) <minjie.chen@geekplus.com> Tested-by: Lisa Chen (陈敏捷) <minjie.chen@geekplus.com> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://lore.kernel.org/r/20230529223402.1199503-1-vladimir.oltean@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-06-21spi: spi-fsl-dspi: Remove unused chip->void_write_dataVladimir Oltean
[ Upstream commit 6d6af5796e5d9a88ae83c9c753023bba61deb18b ] This variable has been present since the initial submission of the driver, and held, for some reason, the value of zero, to be sent on the wire in the case there wasn't any TX buffer for the current transfer. Since quite a while now, however, it isn't doing anything at all. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://lore.kernel.org/r/20200304220044.11193-3-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org> Stable-dep-of: c5c31fb71f16 ("spi: fsl-dspi: avoid SCK glitches with continuous transfers") Signed-off-by: Sasha Levin <sashal@kernel.org>
2021-09-15spi: spi-fsl-dspi: Fix issue with uninitialized dma_slave_configTony Lindgren
[ Upstream commit 209ab223ad5b18e437289235e3bde12593b94ac4 ] Depending on the DMA driver being used, the struct dma_slave_config may need to be initialized to zero for the unused data. For example, we have three DMA drivers using src_port_window_size and dst_port_window_size. If these are left uninitialized, it can cause DMA failures. For spi-fsl-dspi, this is probably not currently an issue but is still good to fix though. Fixes: 90ba37033cb9 ("spi: spi-fsl-dspi: Add DMA support for Vybrid") Cc: Sanchayan Maity <maitysanchayan@gmail.com> Cc: Vladimir Oltean <vladimir.oltean@nxp.com> Cc: Peter Ujfalusi <peter.ujfalusi@gmail.com> Cc: Vinod Koul <vkoul@kernel.org> Signed-off-by: Tony Lindgren <tony@atomide.com> Acked-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://lore.kernel.org/r/20210810081727.19491-1-tony@atomide.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2021-06-03spi: spi-fsl-dspi: Fix a resource leak in an error handling pathChristophe JAILLET
commit 680ec0549a055eb464dce6ffb4bfb736ef87236e upstream. 'dspi_request_dma()' should be undone by a 'dspi_release_dma()' call in the error handling path of the probe function, as already done in the remove function Fixes: 90ba37033cb9 ("spi: spi-fsl-dspi: Add DMA support for Vybrid") Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/d51caaac747277a1099ba8dea07acd85435b857e.1620587472.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-07-22spi: spi-fsl-dspi: Fix lockup if device is shutdown during SPI transferKrzysztof Kozlowski
[ Upstream commit 3c525b69e8c1a9a6944e976603c7a1a713e728f9 ] During shutdown, the driver should unregister the SPI controller and stop the hardware. Otherwise the dspi_transfer_one_message() could wait on completion infinitely. Additionally, calling spi_unregister_controller() first in device shutdown reverse-matches the probe function, where SPI controller is registered at the end. Fixes: dc234825997e ("spi: spi-fsl-dspi: Adding shutdown hook") Reported-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com> Cc: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20200622110543.5035-2-krzk@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2020-07-16spi: spi-fsl-dspi: Fix lockup if device is removed during SPI transferKrzysztof Kozlowski
[ Upstream commit 7684580d45bd3d84ed9b453a4cadf7a9a5605a3f ] During device removal, the driver should unregister the SPI controller and stop the hardware. Otherwise the dspi_transfer_one_message() could wait on completion infinitely. Additionally, calling spi_unregister_controller() first in device removal reverse-matches the probe function, where SPI controller is registered at the end. Fixes: 05209f457069 ("spi: fsl-dspi: add missing clk_disable_unprepare() in dspi_remove()") Reported-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> Cc: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20200622110543.5035-1-krzk@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2020-07-16spi: spi-fsl-dspi: Adding shutdown hookPeng Ma
[ Upstream commit dc234825997ec6ff05980ca9e2204f4ac3f8d695 ] We need to ensure dspi controller could be stopped in order for kexec to start the next kernel. So add the shutdown operation support. Signed-off-by: Peng Ma <peng.ma@nxp.com> Link: https://lore.kernel.org/r/20200424061216.27445-1-peng.ma@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2020-07-09spi: spi-fsl-dspi: Fix external abort on interrupt in resume or exit pathsKrzysztof Kozlowski
commit 3d87b613d6a3c6f0980e877ab0895785a2dde581 upstream. If shared interrupt comes late, during probe error path or device remove (could be triggered with CONFIG_DEBUG_SHIRQ), the interrupt handler dspi_interrupt() will access registers with the clock being disabled. This leads to external abort on non-linefetch on Toradex Colibri VF50 module (with Vybrid VF5xx): $ echo 4002d000.spi > /sys/devices/platform/soc/40000000.bus/4002d000.spi/driver/unbind Unhandled fault: external abort on non-linefetch (0x1008) at 0x8887f02c Internal error: : 1008 [#1] ARM Hardware name: Freescale Vybrid VF5xx/VF6xx (Device Tree) Backtrace: (regmap_mmio_read32le) (regmap_mmio_read) (_regmap_bus_reg_read) (_regmap_read) (regmap_read) (dspi_interrupt) (free_irq) (devm_irq_release) (release_nodes) (devres_release_all) (device_release_driver_internal) The resource-managed framework should not be used for shared interrupt handling, because the interrupt handler might be called after releasing other resources and disabling clocks. Similar bug could happen during suspend - the shared interrupt handler could be invoked after suspending the device. Each device sharing this interrupt line should disable the IRQ during suspend so handler will be invoked only in following cases: 1. None suspended, 2. All devices resumed. Fixes: 349ad66c0ab0 ("spi:Add Freescale DSPI driver for Vybrid VF610 platform") Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com> Cc: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20200622110543.5035-3-krzk@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-04-17spi: spi-fsl-dspi: Replace interruptible wait queue with a simple completionVladimir Oltean
[ Upstream commit 4f5ee75ea1718a09149460b3df993f389a67b56a ] Currently the driver puts the process in interruptible sleep waiting for the interrupt train to finish transfer to/from the tx_buf and rx_buf. But exiting the process with ctrl-c may make the kernel panic: the wait_event_interruptible call will return -ERESTARTSYS, which a proper driver implementation is perhaps supposed to handle, but nonetheless this one doesn't, and aborts the transfer altogether. Actually when the task is interrupted, there is still a high chance that the dspi_interrupt is still triggering. And if dspi_transfer_one_message returns execution all the way to the spi_device driver, that can free the spi_message and spi_transfer structures, leaving the interrupts to access a freed tx_buf and rx_buf. hexdump -C /dev/mtd0 00000000 00 75 68 75 0a ff ff ff ff ff ff ff ff ff ff ff |.uhu............| 00000010 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| * ^C[ 38.495955] fsl-dspi 2120000.spi: Waiting for transfer to complete failed! [ 38.503097] spi_master spi2: failed to transfer one message from queue [ 38.509729] Unable to handle kernel paging request at virtual address ffff800095ab3377 [ 38.517676] Mem abort info: [ 38.520474] ESR = 0x96000045 [ 38.523533] EC = 0x25: DABT (current EL), IL = 32 bits [ 38.528861] SET = 0, FnV = 0 [ 38.531921] EA = 0, S1PTW = 0 [ 38.535067] Data abort info: [ 38.537952] ISV = 0, ISS = 0x00000045 [ 38.541797] CM = 0, WnR = 1 [ 38.544771] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000082621000 [ 38.551494] [ffff800095ab3377] pgd=00000020fffff003, p4d=00000020fffff003, pud=0000000000000000 [ 38.560229] Internal error: Oops: 96000045 [#1] PREEMPT SMP [ 38.565819] Modules linked in: [ 38.568882] CPU: 0 PID: 2729 Comm: hexdump Not tainted 5.6.0-rc4-next-20200306-00052-gd8730cdc8a0b-dirty #193 [ 38.578834] Hardware name: Kontron SMARC-sAL28 (Single PHY) on SMARC Eval 2.0 carrier (DT) [ 38.587129] pstate: 20000085 (nzCv daIf -PAN -UAO) [ 38.591941] pc : ktime_get_real_ts64+0x3c/0x110 [ 38.596487] lr : spi_take_timestamp_pre+0x40/0x90 [ 38.601203] sp : ffff800010003d90 [ 38.604525] x29: ffff800010003d90 x28: ffff80001200e000 [ 38.609854] x27: ffff800011da9000 x26: ffff002079c40400 [ 38.615184] x25: ffff8000117fe018 x24: ffff800011daa1a0 [ 38.620513] x23: ffff800015ab3860 x22: ffff800095ab3377 [ 38.625841] x21: 000000000000146e x20: ffff8000120c3000 [ 38.631170] x19: ffff0020795f6e80 x18: ffff800011da9948 [ 38.636498] x17: 0000000000000000 x16: 0000000000000000 [ 38.641826] x15: ffff800095ab3377 x14: 0720072007200720 [ 38.647155] x13: 0720072007200765 x12: 0775076507750771 [ 38.652483] x11: 0720076d076f0772 x10: 0000000000000040 [ 38.657812] x9 : ffff8000108e2100 x8 : ffff800011dcabe8 [ 38.663139] x7 : 0000000000000000 x6 : ffff800015ab3a60 [ 38.668468] x5 : 0000000007200720 x4 : ffff800095ab3377 [ 38.673796] x3 : 0000000000000000 x2 : 0000000000000ab0 [ 38.679125] x1 : ffff800011daa000 x0 : 0000000000000026 [ 38.684454] Call trace: [ 38.686905] ktime_get_real_ts64+0x3c/0x110 [ 38.691100] spi_take_timestamp_pre+0x40/0x90 [ 38.695470] dspi_fifo_write+0x58/0x2c0 [ 38.699315] dspi_interrupt+0xbc/0xd0 [ 38.702987] __handle_irq_event_percpu+0x78/0x2c0 [ 38.707706] handle_irq_event_percpu+0x3c/0x90 [ 38.712161] handle_irq_event+0x4c/0xd0 [ 38.716008] handle_fasteoi_irq+0xbc/0x170 [ 38.720115] generic_handle_irq+0x2c/0x40 [ 38.724135] __handle_domain_irq+0x68/0xc0 [ 38.728243] gic_handle_irq+0xc8/0x160 [ 38.732000] el1_irq+0xb8/0x180 [ 38.735149] spi_nor_spimem_read_data+0xe0/0x140 [ 38.739779] spi_nor_read+0xc4/0x120 [ 38.743364] mtd_read_oob+0xa8/0xc0 [ 38.746860] mtd_read+0x4c/0x80 [ 38.750007] mtdchar_read+0x108/0x2a0 [ 38.753679] __vfs_read+0x20/0x50 [ 38.757002] vfs_read+0xa4/0x190 [ 38.760237] ksys_read+0x6c/0xf0 [ 38.763471] __arm64_sys_read+0x20/0x30 [ 38.767319] el0_svc_common.constprop.3+0x90/0x160 [ 38.772125] do_el0_svc+0x28/0x90 [ 38.775449] el0_sync_handler+0x118/0x190 [ 38.779468] el0_sync+0x140/0x180 [ 38.782793] Code: 91000294 1400000f d50339bf f9405e80 (f90002c0) [ 38.788910] ---[ end trace 55da560db4d6bef7 ]--- [ 38.793540] Kernel panic - not syncing: Fatal exception in interrupt [ 38.799914] SMP: stopping secondary CPUs [ 38.803849] Kernel Offset: disabled [ 38.807344] CPU features: 0x10002,20006008 [ 38.811451] Memory Limit: none [ 38.814513] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]--- So it is clear that the "interruptible" part isn't handled correctly. When the process receives a signal, one could either attempt a clean abort (which appears to be difficult with this hardware) or just keep restarting the sleep until the wait queue really completes. But checking in a loop for -ERESTARTSYS is a bit too complicated for this driver, so just make the sleep uninterruptible, to avoid all that nonsense. The wait queue was actually restructured as a completion, after polling other drivers for the most "popular" approach. Fixes: 349ad66c0ab0 ("spi:Add Freescale DSPI driver for Vybrid VF610 platform") Reported-by: Michael Walle <michael@walle.cc> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Tested-by: Michael Walle <michael@walle.cc> Link: https://lore.kernel.org/r/20200318001603.9650-7-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2020-01-09spi: spi-fsl-dspi: Fix 16-bit word order in 32-bit XSPI modeVladimir Oltean
commit ca59d5a51690d5b9340343dc36792a252e9414ae upstream. When used in Extended SPI mode on LS1021A, the DSPI controller wants to have the least significant 16-bit word written first to the TX FIFO. In fact, the LS1021A reference manual says: 33.5.2.4.2 Draining the TX FIFO When Extended SPI Mode (DSPIx_MCR[XSPI]) is enabled, if the frame size of SPI Data to be transmitted is more than 16 bits, then it causes two Data entries to be popped from TX FIFO simultaneously which are transferred to the shift register. The first of the two popped entries forms the 16 least significant bits of the SPI frame to be transmitted. So given the following TX buffer: +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 | 0x7 | 0x8 | 0x9 | 0xa | 0xb | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 32-bit word 1 | 32-bit word 2 | 32-bit word 3 | +-----------------------+-----------------------+-----------------------+ The correct way that a little-endian system should transmit it on the wire when bits_per_word is 32 is: 0x03020100 0x07060504 0x0b0a0908 But it is actually transmitted as following, as seen with a scope: 0x01000302 0x05040706 0x09080b0a It appears that this patch has been submitted at least once before: https://lkml.org/lkml/2018/9/21/286 but in that case Chuanhua Han did not manage to explain the problem clearly enough and the patch did not get merged, leaving XSPI mode broken. Fixes: 8fcd151d2619 ("spi: spi-fsl-dspi: XSPI FIFO handling (in TCFQ mode)") Cc: Esben Haabendal <eha@deif.com> Cc: Chuanhua Han <chuanhua.han@nxp.com> Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20191228135536.14284-1-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-09-03spi: spi-fsl-dspi: Fix race condition in TCFQ/EOQ interruptVladimir Oltean
When the driver is working in TCFQ/EOQ mode (i.e. interacts with the SPI controller's FIFOs directly) the following sequence of operations happens: - The first byte of the tx buffer gets pushed to the TX FIFO (dspi->len gets decremented). This triggers the train of interrupts that handle the rest of the bytes. - The dspi_interrupt handles a TX confirmation event. It reads the newly available byte from the RX FIFO, checks the dspi->len exit condition, and if there's more to be done, it kicks off the next interrupt in the train by writing the next byte to the TX FIFO. Now the problem is that the wait queue is woken up one byte too early, because dspi->len becomes 0 as soon as the byte has been pushed into the TX FIFO. Its interrupt has not yet been processed and the RX byte has not been put from the FIFO into the buffer. Depending on the timing of the wait queue wakeup vs the handling of the last dspi_interrupt, it can happen that the main SPI message pump thread has already returned back into the spi_device driver. When the rx buffer is on stack (which it can be, because in this mode, the DSPI doesn't do DMA), the last interrupt will perform a memory write into an rx buffer that has been freed. This manifests as stack corruption. The solution is to only wake up the wait queue when dspi_rxtx says so, i.e. after it has processed the last TX confirmation interrupt and collected the last RX byte. Fixes: c55be3059159 ("spi: spi-fsl-dspi: Use poll mode in case the platform IRQ is missing") Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190903105708.32273-1-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-23spi: spi-fsl-dspi: Use poll mode in case the platform IRQ is missingVladimir Oltean
On platforms like LS1021A which use TCFQ mode, an interrupt needs to be processed after each byte is TXed/RXed. I tried to make the DSPI implementation on this SoC operate in other, more efficient modes (EOQ, DMA) but it looks like it simply isn't possible. Therefore allow the driver to operate in poll mode, to ease a bit of this absurd amount of IRQ load generated in TCFQ mode. Doing so reduces both the net time it takes to transmit a SPI message, as well as the inter-frame jitter that occurs while doing so. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190822211514.19288-5-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-23spi: spi-fsl-dspi: Remove impossible to reach error checkVladimir Oltean
dspi->devtype_data is under the total control of the driver. Therefore, a bad value is a driver bug and checking it at runtime (and during an ISR, at that!) is pointless. The second "else if" check is only for clarity (instead of a broader "else") in case other transfer modes are added in the future. But the printing is dead code and can be removed. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190822211514.19288-4-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-23spi: spi-fsl-dspi: Exit the ISR with IRQ_NONE when it's not oursVladimir Oltean
The DSPI interrupt can be shared between two controllers at least on the LX2160A. In that case, the driver for one controller might misbehave and consume the other's interrupt. Fix this by actually checking if any of the bits in the status register have been asserted. Fixes: 13aed2392741 ("spi: spi-fsl-dspi: use IRQF_SHARED mode to request IRQ") Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190822211514.19288-3-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-23spi: spi-fsl-dspi: Reduce indentation level in dspi_interruptVladimir Oltean
If the entire function depends on the SPI status register having the interrupt bits asserted, then just check it and exit early if those bits aren't set (such as in the case of the shared IRQ being triggered for the other peripheral). Cosmetic patch. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190822211514.19288-2-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Move dspi_interrupt above dspi_transfer_one_messageVladimir Oltean
The two functions are loosely coupled through dspi->waitq, but logically, dspi_transfer_one_message depends on dspi_interrupt in order to complete. Move its definition above it so the I/O functions are grouped closer together. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-13-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Fix typosVladimir Oltean
mask of -> mask off at and -> and Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-12-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Use reverse Christmas tree declaration orderVladimir Oltean
This patch puts variable declaration in the reverse order of their length for cosmetic purposes. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-11-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Replace legacy spi_master names with spi_controllerVladimir Oltean
This adapts the spi-fsl-dspi driver to the API changes introduced in commit 8caab75fd2c2 ("spi: Generalize SPI "master" to "controller""). Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-10-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Remove pointless assignment of master->transfer to NULLVladimir Oltean
Introduced in commit 9298bc727385 ("spi: spi-fsl-dspi: Remove spi-bitbang") for less than obvious reasons, this assignment is confusing and serves no purpose. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-9-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Remove unused initialization of 'ret' in dspi_probeVladimir Oltean
There is no code path for reaching 'return ret;' without it first being assigned to an error code. Therefore the initialization with 0 is pointless. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-8-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Reduce indentation in dspi_release_dma()Vladimir Oltean
There is no point in surrounding an entire function block in an if condition. Rather, exit early if the condition is false. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-7-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Change usage pattern of SPI_MCR_* and SPI_CTAR_* macrosVladimir Oltean
These are macros that accept 0 or 1 as argument (a boolean value). Their use encourages the abuse of complex ternary operations inside their argument list, which detracts from the code readability. Replace these with simple if-else statements. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-6-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Demistify magic value in SPI_SR_CLEARVladimir Oltean
This patch adds the field definitions for the SPI_SR register. The SPI status register is write-1-to-clear and this value is written at init time. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-5-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Use BIT() and GENMASK() macrosVladimir Oltean
Switch to using more idiomatic register field definitions, which makes it easier to look them up in the datasheet. Cosmetic patch. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-4-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Remove unused defines and includesVladimir Oltean
This is a cosmetic patch. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-3-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-20spi: spi-fsl-dspi: Fix code alignmentVladimir Oltean
This is a cosmetic patch that changes nothing except makes sure the code is aligned to the same column, which makes it easier to the eye. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Link: https://lore.kernel.org/r/20190818180115.31114-2-olteanv@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2019-08-02spi: Remove dev_err() usage after platform_get_irq()Stephen Boyd
We don't need dev_err() messages when platform_get_irq() fails now that platform_get_irq() prints an error message itself when something goes wrong. Let's remove these prints with a simple semantic patch. // <smpl> @@ expression ret; struct platform_device *E; @@ ret = ( platform_get_irq(E, ...) | platform_get_irq_byname(E, ...) ); if ( \( ret < 0 \| ret <= 0 \) ) { ( -if (ret != -EPROBE_DEFER) -{ ... -dev_err(...); -... } | ... -dev_err(...); ) ... } // </smpl> While we're here, remove braces on if statements that only have one statement (manually). Cc: Mark Brown <broonie@kernel.org> Cc: linux-spi@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20190730181557.90391-42-swboyd@chromium.org Signed-off-by: Mark Brown <broonie@kernel.org>
2019-02-20Merge branch 'for-5.0' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi into spi-5.1
2019-02-06spi: spi-fsl-dspi: Provide support for DSPI slave mode operation (Vybryd vf610)Lukasz Majewski
The NXP's Vybryd vf610 can work as a SPI slave device (the CS and clock signals are provided by master). It is possible to specify a single device to work in that mode. As we do use DMA for transferring data, the RX channel must be prepared for incoming data. Moreover, in slave mode we just set a subset of control fields in configuration registers (CTAR0, PUSHR). For testing the spidev_test program has been used. Test script for this patch can be found here: https://github.com/lmajewski/tests-spi/blob/master/tests/spi/spi_tests.sh Signed-off-by: Lukasz Majewski <lukma@denx.de> Signed-off-by: Mark Brown <broonie@kernel.org>
2019-01-07spi: fix initial SPI_SR value in spi-fsl-dspiAngelo Dureghello
On ColdFire mcf54418, using DSPI_DMA_MODE mode, spi transfers at first boot stage are not succeding: m25p80 spi0.1: unrecognized JEDEC id bytes: 00, 00, 00 The reason is the SPI_SR initial value set by the driver, that is not clearing (not setting to 1) the RF_DF flag. After a tour on the dspi hw modules that use this driver(Vybrid, ColdFire and ls1021a) a better init value for SR register has been set. Signed-off-by: Angelo Dureghello <angelo@sysam.it> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-11-05spi: spi-fsl-dspi: use IRQF_SHARED mode to request IRQChuanhua Han
Some SoC share one irq number between DSPI controllers. For example, on the LX2160 board, DSPI0 and DSPI1 share one irq number. In this case, only one DSPI controller can register successfully, and others will fail. Signed-off-by: Chuanhua Han <chuanhua.han@nxp.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-08-28spi: spi-fsl-dspi: fix broken DSPI_EOQ_MODEAngelo Dureghello
This patch fixes the dspi_eoq_write function used by the ColdFire mcf5441x family. The 16 bit cmd part must be re-set at each data transfer. Also, now that fifo_size variables are used for eoq_read/write, a proper fifo size must be set (16 slots for the ColdFire dspi module version). Signed-off-by: Angelo Dureghello <angelo@sysam.it> Acked-by: Esben Haabendal <esben@haabendal.dk> Signed-off-by: Mark Brown <broonie@kernel.org> Cc: stable@vger.kernel.org
2018-07-24spi: spi-fsl-dspi: Switch to SPDX identifierFabio Estevam
Adopt the SPDX license identifier headers to ease license compliance management. Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-07-17spi: spi-fsl-dspi: Fill actual_length when doing DMA transferAndrey Smirnov
Upper layer users of SPI device drivers may rely on 'actual_length', so it is important that information is correctly reported. One such example is spi_mem_exec_op() function that will fail if 'actual_length' of the data transferred is not what was requested. Add necessary code to populate 'actual_length. Cc: Mark Brown <broonie@kernel.org> Cc: Sanchayan Maity <maitysanchayan@gmail.com> Cc: Stefan Agner <stefan@agner.ch> Cc: cphealy@gmail.com Cc: linux-spi@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-07-02spi: spi-fsl-dspi: Fix imprecise abort on VF500 during probeKrzysztof Kozlowski
Registers of DSPI should not be accessed before enabling its clock. On Toradex Colibri VF50 on Iris carrier board this could be seen during bootup as imprecise abort: Unhandled fault: imprecise external abort (0x1c06) at 0x00000000 Internal error: : 1c06 [#1] ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper Not tainted 4.14.39-dirty #97 Hardware name: Freescale Vybrid VF5xx/VF6xx (Device Tree) Backtrace: [<804166a8>] (regmap_write) from [<80466b5c>] (dspi_probe+0x1f0/0x8dc) [<8046696c>] (dspi_probe) from [<8040107c>] (platform_drv_probe+0x54/0xb8) [<80401028>] (platform_drv_probe) from [<803ff53c>] (driver_probe_device+0x280/0x2f8) [<803ff2bc>] (driver_probe_device) from [<803ff674>] (__driver_attach+0xc0/0xc4) [<803ff5b4>] (__driver_attach) from [<803fd818>] (bus_for_each_dev+0x70/0xa4) [<803fd7a8>] (bus_for_each_dev) from [<803fee74>] (driver_attach+0x24/0x28) [<803fee50>] (driver_attach) from [<803fe980>] (bus_add_driver+0x1a0/0x218) [<803fe7e0>] (bus_add_driver) from [<803fffe8>] (driver_register+0x80/0x100) [<803fff68>] (driver_register) from [<80400fdc>] (__platform_driver_register+0x48/0x50) [<80400f94>] (__platform_driver_register) from [<8091cf7c>] (fsl_dspi_driver_init+0x1c/0x20) [<8091cf60>] (fsl_dspi_driver_init) from [<8010195c>] (do_one_initcall+0x4c/0x174) [<80101910>] (do_one_initcall) from [<80900e8c>] (kernel_init_freeable+0x144/0x1d8) [<80900d48>] (kernel_init_freeable) from [<805ff6a8>] (kernel_init+0x10/0x114) [<805ff698>] (kernel_init) from [<80107be8>] (ret_from_fork+0x14/0x2c) Cc: <stable@vger.kernel.org> Fixes: 5ee67b587a2b ("spi: dspi: clear SPI_SR before enable interrupt") Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-06-21spi: spi-fsl-dspi: Fix copy-paste error in dspi_probeGustavo A. R. Silva
It seems that the proper structure field to use in this particular case is *regmap_pushr* instead of regmap. Addresses-Coverity-ID: 1470126 ("Copy-paste error") Fixes: 58ba07ec79e6 ("spi: spi-fsl-dspi: Add support for XSPI mode registers") Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com> Acked-by: Esben Haabendal <eha@deif.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-06-20spi: spi-fsl-dspi: Enable extended SPI modeEsben Haabendal
Set the XSPI bit for devices configured for XSPI mode (currently LS1021A), and thereby switch to extended SPI mode, allowing for SPI transfers using from 4 to 32 bits per word instead of 4 to 16 bits per word. Signed-off-by: Esben Haabendal <eha@deif.com> Acked-by: Martin Hundebøll <martin@geanix.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-06-20spi: spi-fsl-dspi: Advertise 32 bit for XSPI modeEsben Haabendal
Signed-off-by: Esben Haabendal <eha@deif.com> Acked-by: Martin Hundebøll <martin@geanix.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-06-20spi: spi-fsl-dspi: XSPI FIFO handling (in TCFQ mode)Esben Haabendal
This implements handling of split CMD and TX FIFO queues for XSPI when running in TCFQ mode. It should be simple to add it to EOQ mode also. Currently, EOQ mode is only used with coldfire. So if coldfire DSPI supports XSPI, XSPI FIFO handling should be added to EOQ mode also. Signed-off-by: Esben Haabendal <eha@deif.com> Acked-by: Martin Hundebøll <martin@geanix.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-06-20spi: spi-fsl-dspi: Framesize control for XSPI modeEsben Haabendal
Signed-off-by: Esben Haabendal <eha@deif.com> Acked-by: Martin Hundebøll <martin@geanix.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-06-20spi: spi-fsl-dspi: Add support for XSPI mode registersEsben Haabendal
This prepares for adding support for extended SPI mode (XSPI), by extending the regmap with the extra SREX and CTAREx registers. An additional register map is made for allowing 16 bit access to CMD and TX FIFO of the PUSHR register separately, which is also needed for XSPI mode support. Signed-off-by: Esben Haabendal <eha@deif.com> Acked-by: Martin Hundebøll <martin@geanix.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-06-20Merge branch 'spi-4.18' into spi-4.19 for DSPI depMark Brown
2018-06-20spi: spi-fsl-dspi: Fixup regmap configurationEsben Haabendal
Mark volatile registers to avoid caching bugs. Note: SPI_MCR is marked volatile because of CLR_TXF and CLR_RXF bits. Signed-off-by: Esben Haabendal <eha@deif.com> Acked-by: Martin Hundebøll <martin@geanix.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-06-20spi: spi-fsl-dspi: Fix MCR register handlingEsben Haabendal
The MCR register is not changed, so initialize it in dspi_init(). The exception is the CLR_TXF and CLR_RXF bits, which should be written to before each transfer to make sure we start with empty FIFOs. With MCR register now configured as volatile, the regmap_update_bits will do a real read-modify-write cycle. Signed-off-by: Esben Haabendal <eha@deif.com> Acked-by: Martin Hundebøll <martin@geanix.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2018-06-20spi: spi-fsl-dspi: Support 4 to 16 bits per word transfersEsben Haabendal
This extends the driver with support for all SPI framesizes from 4 to 16 bits, and adds support for per transfer specific bits_per_word, while at the same time reducing code size and complexity. Signed-off-by: Esben Haabendal <eha@deif.com> Acked-by: Martin Hundebøll <martin@geanix.com> Signed-off-by: Mark Brown <broonie@kernel.org>