Skip to content

Commit 21b511d

Browse files
Sai Krishna Potthuribroonie
authored andcommitted
spi: spi-cadence: Fix SPI CS gets toggling sporadically
As part of unprepare_transfer_hardware, SPI controller will be disabled which will indirectly deassert the CS line. This will create a problem in some of the devices where message will be transferred with cs_change flag set(CS should not be deasserted). As per SPI controller implementation, if SPI controller is disabled then all output enables are inactive and all pins are set to input mode which means CS will go to default state high(deassert). This leads to an issue when core explicitly ask not to deassert the CS (cs_change = 1). This patch fix the above issue by checking the Slave select status bits from configuration register before disabling the SPI. Signed-off-by: Sai Krishna Potthuri <[email protected]> Signed-off-by: Amit Kumar Mahapatra <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent f2906aa commit 21b511d

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

drivers/spi/spi-cadence.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#define CDNS_SPI_BAUD_DIV_SHIFT 3 /* Baud rate divisor shift in CR */
7070
#define CDNS_SPI_SS_SHIFT 10 /* Slave Select field shift in CR */
7171
#define CDNS_SPI_SS0 0x1 /* Slave Select zero */
72+
#define CDNS_SPI_NOSS 0x3C /* No Slave select */
7273

7374
/*
7475
* SPI Interrupt Registers bit Masks
@@ -450,15 +451,20 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
450451
* @master: Pointer to the spi_master structure which provides
451452
* information about the controller.
452453
*
453-
* This function disables the SPI master controller.
454+
* This function disables the SPI master controller when no slave selected.
454455
*
455456
* Return: 0 always
456457
*/
457458
static int cdns_unprepare_transfer_hardware(struct spi_master *master)
458459
{
459460
struct cdns_spi *xspi = spi_master_get_devdata(master);
461+
u32 ctrl_reg;
460462

461-
cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
463+
/* Disable the SPI if slave is deselected */
464+
ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
465+
ctrl_reg = (ctrl_reg & CDNS_SPI_CR_SSCTRL) >> CDNS_SPI_SS_SHIFT;
466+
if (ctrl_reg == CDNS_SPI_NOSS)
467+
cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
462468

463469
return 0;
464470
}

0 commit comments

Comments
 (0)