diff options
-rw-r--r-- | drivers/spi/spi-rockchip.c | 51 |
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 | |||
152 | enum rockchip_ssi_type { | 159 | enum 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 | ||
265 | static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) | 274 | static 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 | ||
300 | static int rockchip_spi_prepare_message(struct spi_master *master, | 301 | static 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 | ||