[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1498446606-5529-1-git-send-email-jeffy.chen@rock-chips.com>
Date: Mon, 26 Jun 2017 11:10:06 +0800
From: Jeffy Chen <jeffy.chen@...k-chips.com>
To: linux-kernel@...r.kernel.org, broonie@...nel.org
Cc: briannorris@...omium.org, dianders@...omium.org, heiko@...ech.de,
Jeffy Chen <jeffy.chen@...k-chips.com>,
linux-spi@...r.kernel.org, linux-rockchip@...ts.infradead.org,
linux-arm-kernel@...ts.infradead.org
Subject: [PATCH] spi: rockchip: Keep master alive when CS asserted
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@...omium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@...k-chips.com>
---
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
Powered by blists - more mailing lists