aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffy Chen <jeffy.chen@rock-chips.com>2017-06-28 00:38:43 -0400
committerMark Brown <broonie@kernel.org>2017-06-28 14:43:18 -0400
commitaa099382ac0cda27e10fa8f45bf91edea0d1d35e (patch)
tree53110fcb40c5e0a989fc4b084d9e2e2b7b344a7b
parentc863795c4c0787e5f885099e3b673e1433448b82 (diff)
spi: rockchip: Disable Runtime PM when chip select is asserted
The rockchip spi would stop driving pins when runtime suspended, which might break slave's xfer(for example cros_ec). Since we have pullups on those pins, we only need to care about this when the CS asserted. So let's keep the spi alive when chip select is asserted. Also use pm_runtime_put instead of pm_runtime_put_sync. Suggested-by: Doug Anderson <dianders@chromium.org> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-rockchip.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 52ea1605d4c6..0b4a52b3e1dc 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -25,6 +25,11 @@
25 25
26#define DRIVER_NAME "rockchip-spi" 26#define DRIVER_NAME "rockchip-spi"
27 27
28#define ROCKCHIP_SPI_CLR_BITS(reg, bits) \
29 writel_relaxed(readl_relaxed(reg) & ~(bits), reg)
30#define ROCKCHIP_SPI_SET_BITS(reg, bits) \
31 writel_relaxed(readl_relaxed(reg) | (bits), reg)
32
28/* SPI register offsets */ 33/* SPI register offsets */
29#define ROCKCHIP_SPI_CTRLR0 0x0000 34#define ROCKCHIP_SPI_CTRLR0 0x0000
30#define ROCKCHIP_SPI_CTRLR1 0x0004 35#define ROCKCHIP_SPI_CTRLR1 0x0004
@@ -149,6 +154,8 @@
149 */ 154 */
150#define ROCKCHIP_SPI_MAX_TRANLEN 0xffff 155#define ROCKCHIP_SPI_MAX_TRANLEN 0xffff
151 156
157#define ROCKCHIP_SPI_MAX_CS_NUM 2
158
152enum rockchip_ssi_type { 159enum rockchip_ssi_type {
153 SSI_MOTO_SPI = 0, 160 SSI_MOTO_SPI = 0,
154 SSI_TI_SSP, 161 SSI_TI_SSP,
@@ -193,6 +200,8 @@ struct rockchip_spi {
193 /* protect state */ 200 /* protect state */
194 spinlock_t lock; 201 spinlock_t lock;
195 202
203 bool cs_asserted[ROCKCHIP_SPI_MAX_CS_NUM];
204
196 u32 use_dma; 205 u32 use_dma;
197 struct sg_table tx_sg; 206 struct sg_table tx_sg;
198 struct sg_table rx_sg; 207 struct sg_table rx_sg;
@@ -264,37 +273,29 @@ static inline u32 rx_max(struct rockchip_spi *rs)
264 273
265static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) 274static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
266{ 275{
267 u32 ser;
268 struct spi_master *master = spi->master; 276 struct spi_master *master = spi->master;
269 struct rockchip_spi *rs = spi_master_get_devdata(master); 277 struct rockchip_spi *rs = spi_master_get_devdata(master);
278 bool cs_asserted = !enable;
270 279
271 pm_runtime_get_sync(rs->dev); 280 /* Return immediately for no-op */
281 if (cs_asserted == rs->cs_asserted[spi->chip_select])
282 return;
272 283
273 ser = readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & SER_MASK; 284 if (cs_asserted) {
285 /* Keep things powered as long as CS is asserted */
286 pm_runtime_get_sync(rs->dev);
274 287
275 /* 288 ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER,
276 * drivers/spi/spi.c: 289 BIT(spi->chip_select));
277 * static void spi_set_cs(struct spi_device *spi, bool enable) 290 } else {
278 * { 291 ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER,
279 * if (spi->mode & SPI_CS_HIGH) 292 BIT(spi->chip_select));
280 * enable = !enable;
281 *
282 * if (spi->cs_gpio >= 0)
283 * gpio_set_value(spi->cs_gpio, !enable);
284 * else if (spi->master->set_cs)
285 * spi->master->set_cs(spi, !enable);
286 * }
287 *
288 * Note: enable(rockchip_spi_set_cs) = !enable(spi_set_cs)
289 */
290 if (!enable)
291 ser |= 1 << spi->chip_select;
292 else
293 ser &= ~(1 << spi->chip_select);
294 293
295 writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER); 294 /* Drop reference from when we first asserted CS */
295 pm_runtime_put(rs->dev);
296 }
296 297
297 pm_runtime_put_sync(rs->dev); 298 rs->cs_asserted[spi->chip_select] = cs_asserted;
298} 299}
299 300
300static int rockchip_spi_prepare_message(struct spi_master *master, 301static int rockchip_spi_prepare_message(struct spi_master *master,
@@ -739,7 +740,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
739 master->auto_runtime_pm = true; 740 master->auto_runtime_pm = true;
740 master->bus_num = pdev->id; 741 master->bus_num = pdev->id;
741 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP; 742 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP;
742 master->num_chipselect = 2; 743 master->num_chipselect = ROCKCHIP_SPI_MAX_CS_NUM;
743 master->dev.of_node = pdev->dev.of_node; 744 master->dev.of_node = pdev->dev.of_node;
744 master->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8); 745 master->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
745 746