lkml.org 
[lkml]   [2022]   [Jun]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.14 01/17] spi: spi-cadence: Fix SPI CS gets toggling sporadically
    Date
    From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri@xilinx.com>

    [ Upstream commit 21b511ddee09a78909035ec47a6a594349fe3296 ]

    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 <lakshmi.sai.krishna.potthuri@xilinx.com>
    Signed-off-by: Amit Kumar Mahapatra <amit.kumar-mahapatra@xilinx.com>
    Link: https://lore.kernel.org/r/20220606062525.18447-1-amit.kumar-mahapatra@xilinx.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/spi/spi-cadence.c | 10 ++++++++--
    1 file changed, 8 insertions(+), 2 deletions(-)

    diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
    index d9aeb9efa7aa..810f92a0ef7c 100644
    --- a/drivers/spi/spi-cadence.c
    +++ b/drivers/spi/spi-cadence.c
    @@ -73,6 +73,7 @@
    #define CDNS_SPI_BAUD_DIV_SHIFT 3 /* Baud rate divisor shift in CR */
    #define CDNS_SPI_SS_SHIFT 10 /* Slave Select field shift in CR */
    #define CDNS_SPI_SS0 0x1 /* Slave Select zero */
    +#define CDNS_SPI_NOSS 0x3C /* No Slave select */

    /*
    * SPI Interrupt Registers bit Masks
    @@ -457,15 +458,20 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
    * @master: Pointer to the spi_master structure which provides
    * information about the controller.
    *
    - * This function disables the SPI master controller.
    + * This function disables the SPI master controller when no slave selected.
    *
    * Return: 0 always
    */
    static int cdns_unprepare_transfer_hardware(struct spi_master *master)
    {
    struct cdns_spi *xspi = spi_master_get_devdata(master);
    + u32 ctrl_reg;

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

    return 0;
    }
    --
    2.35.1
    \
     
     \ /
      Last update: 2022-06-28 04:35    [W:4.264 / U:0.288 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site