The cros_ec requires CS line to be active after last message. But the CS would be toggled when powering off/on rockchip spi, which breaks ec xfer. Keep spi alive after CS asserted to prevent that. Suggested-by: Doug Anderson <dianders@xxxxxxxxxxxx> Signed-off-by: Jeffy Chen <jeffy.chen@xxxxxxxxxxxxxx> --- drivers/spi/spi-rockchip.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index acf31f3..df016a1 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -264,7 +264,7 @@ static inline u32 rx_max(struct rockchip_spi *rs) static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) { - u32 ser; + u32 ser, new_ser; struct spi_master *master = spi->master; struct rockchip_spi *rs = spi_master_get_devdata(master); @@ -288,13 +288,25 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) * Note: enable(rockchip_spi_set_cs) = !enable(spi_set_cs) */ if (!enable) - ser |= 1 << spi->chip_select; + new_ser = ser | BIT(spi->chip_select); else - ser &= ~(1 << spi->chip_select); + new_ser = ser & ~BIT(spi->chip_select); - writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER); + if (new_ser == ser) + goto out; - pm_runtime_put_sync(rs->dev); + writel_relaxed(new_ser, rs->regs + ROCKCHIP_SPI_SER); + + /* + * The rockchip spi would stop driving CS when power down. + * So we need to keep it alive after CS asserted + */ + if (!enable) + return; + pm_runtime_put(rs->dev); + +out: + pm_runtime_put(rs->dev); } static int rockchip_spi_prepare_message(struct spi_master *master, -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html