diff options
author | Sebastian Reichel <sre@kernel.org> | 2016-05-11 11:22:00 -0400 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2016-06-27 18:40:03 -0400 |
commit | ad60db2f9fe3367e60a21fc0afe19999516f8b27 (patch) | |
tree | e20669ae89c608890fb67450d994153e5ebcd2b9 | |
parent | 4e552310cdf0c81210b5fc9173f7cf497eeb9feb (diff) |
HSI: omap_ssi_port: use rpm autosuspend API
Instead of immediately sending the SSI module to
sleep, wait some time in case of new incoming or
outgoing traffic.
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Tested-by: Pavel Machek <pavel@ucw.cz>
-rw-r--r-- | drivers/hsi/controllers/omap_ssi_port.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c index 7717c769c4dd..f95efabc27b0 100644 --- a/drivers/hsi/controllers/omap_ssi_port.c +++ b/drivers/hsi/controllers/omap_ssi_port.c | |||
@@ -126,7 +126,7 @@ static int ssi_debug_port_show(struct seq_file *m, void *p __maybe_unused) | |||
126 | seq_printf(m, "BUFFER_CH%d\t: 0x%08x\n", ch, | 126 | seq_printf(m, "BUFFER_CH%d\t: 0x%08x\n", ch, |
127 | readl(base + SSI_SSR_BUFFER_CH_REG(ch))); | 127 | readl(base + SSI_SSR_BUFFER_CH_REG(ch))); |
128 | } | 128 | } |
129 | pm_runtime_put_sync(omap_port->pdev); | 129 | pm_runtime_put_autosuspend(omap_port->pdev); |
130 | 130 | ||
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
@@ -150,7 +150,7 @@ static int ssi_div_get(void *data, u64 *val) | |||
150 | 150 | ||
151 | pm_runtime_get_sync(omap_port->pdev); | 151 | pm_runtime_get_sync(omap_port->pdev); |
152 | *val = readl(omap_port->sst_base + SSI_SST_DIVISOR_REG); | 152 | *val = readl(omap_port->sst_base + SSI_SST_DIVISOR_REG); |
153 | pm_runtime_put_sync(omap_port->pdev); | 153 | pm_runtime_put_autosuspend(omap_port->pdev); |
154 | 154 | ||
155 | return 0; | 155 | return 0; |
156 | } | 156 | } |
@@ -166,7 +166,7 @@ static int ssi_div_set(void *data, u64 val) | |||
166 | pm_runtime_get_sync(omap_port->pdev); | 166 | pm_runtime_get_sync(omap_port->pdev); |
167 | writel(val, omap_port->sst_base + SSI_SST_DIVISOR_REG); | 167 | writel(val, omap_port->sst_base + SSI_SST_DIVISOR_REG); |
168 | omap_port->sst.divisor = val; | 168 | omap_port->sst.divisor = val; |
169 | pm_runtime_put_sync(omap_port->pdev); | 169 | pm_runtime_put_autosuspend(omap_port->pdev); |
170 | 170 | ||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
@@ -245,7 +245,7 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch) | |||
245 | 245 | ||
246 | if (!pm_runtime_active(omap_port->pdev)) { | 246 | if (!pm_runtime_active(omap_port->pdev)) { |
247 | dev_warn(&port->device, "ssi_start_dma called without runtime PM!\n"); | 247 | dev_warn(&port->device, "ssi_start_dma called without runtime PM!\n"); |
248 | pm_runtime_put(omap_port->pdev); | 248 | pm_runtime_put_autosuspend(omap_port->pdev); |
249 | return -EREMOTEIO; | 249 | return -EREMOTEIO; |
250 | } | 250 | } |
251 | 251 | ||
@@ -254,7 +254,7 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch) | |||
254 | DMA_FROM_DEVICE); | 254 | DMA_FROM_DEVICE); |
255 | if (err < 0) { | 255 | if (err < 0) { |
256 | dev_dbg(&ssi->device, "DMA map SG failed !\n"); | 256 | dev_dbg(&ssi->device, "DMA map SG failed !\n"); |
257 | pm_runtime_put(omap_port->pdev); | 257 | pm_runtime_put_autosuspend(omap_port->pdev); |
258 | return err; | 258 | return err; |
259 | } | 259 | } |
260 | csdp = SSI_DST_BURST_4x32_BIT | SSI_DST_MEMORY_PORT | | 260 | csdp = SSI_DST_BURST_4x32_BIT | SSI_DST_MEMORY_PORT | |
@@ -271,7 +271,7 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch) | |||
271 | DMA_TO_DEVICE); | 271 | DMA_TO_DEVICE); |
272 | if (err < 0) { | 272 | if (err < 0) { |
273 | dev_dbg(&ssi->device, "DMA map SG failed !\n"); | 273 | dev_dbg(&ssi->device, "DMA map SG failed !\n"); |
274 | pm_runtime_put(omap_port->pdev); | 274 | pm_runtime_put_autosuspend(omap_port->pdev); |
275 | return err; | 275 | return err; |
276 | } | 276 | } |
277 | csdp = SSI_SRC_BURST_4x32_BIT | SSI_SRC_MEMORY_PORT | | 277 | csdp = SSI_SRC_BURST_4x32_BIT | SSI_SRC_MEMORY_PORT | |
@@ -317,7 +317,7 @@ static int ssi_start_pio(struct hsi_msg *msg) | |||
317 | 317 | ||
318 | if (!pm_runtime_active(omap_port->pdev)) { | 318 | if (!pm_runtime_active(omap_port->pdev)) { |
319 | dev_warn(&port->device, "ssi_start_pio called without runtime PM!\n"); | 319 | dev_warn(&port->device, "ssi_start_pio called without runtime PM!\n"); |
320 | pm_runtime_put(omap_port->pdev); | 320 | pm_runtime_put_autosuspend(omap_port->pdev); |
321 | return -EREMOTEIO; | 321 | return -EREMOTEIO; |
322 | } | 322 | } |
323 | 323 | ||
@@ -332,7 +332,7 @@ static int ssi_start_pio(struct hsi_msg *msg) | |||
332 | msg->ttype ? "write" : "read"); | 332 | msg->ttype ? "write" : "read"); |
333 | val |= readl(omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0)); | 333 | val |= readl(omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0)); |
334 | writel(val, omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0)); | 334 | writel(val, omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0)); |
335 | pm_runtime_put(omap_port->pdev); | 335 | pm_runtime_put_autosuspend(omap_port->pdev); |
336 | msg->actual_len = 0; | 336 | msg->actual_len = 0; |
337 | msg->status = HSI_STATUS_PROCEEDING; | 337 | msg->status = HSI_STATUS_PROCEEDING; |
338 | 338 | ||
@@ -390,7 +390,8 @@ static int ssi_async_break(struct hsi_msg *msg) | |||
390 | spin_unlock_bh(&omap_port->lock); | 390 | spin_unlock_bh(&omap_port->lock); |
391 | } | 391 | } |
392 | out: | 392 | out: |
393 | pm_runtime_put(omap_port->pdev); | 393 | pm_runtime_mark_last_busy(omap_port->pdev); |
394 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
394 | 395 | ||
395 | return err; | 396 | return err; |
396 | } | 397 | } |
@@ -428,7 +429,8 @@ static int ssi_async(struct hsi_msg *msg) | |||
428 | msg->status = HSI_STATUS_ERROR; | 429 | msg->status = HSI_STATUS_ERROR; |
429 | } | 430 | } |
430 | spin_unlock_bh(&omap_port->lock); | 431 | spin_unlock_bh(&omap_port->lock); |
431 | pm_runtime_put(omap_port->pdev); | 432 | pm_runtime_mark_last_busy(omap_port->pdev); |
433 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
432 | dev_dbg(&port->device, "msg status %d ttype %d ch %d\n", | 434 | dev_dbg(&port->device, "msg status %d ttype %d ch %d\n", |
433 | msg->status, msg->ttype, msg->channel); | 435 | msg->status, msg->ttype, msg->channel); |
434 | 436 | ||
@@ -530,7 +532,8 @@ static int ssi_setup(struct hsi_client *cl) | |||
530 | omap_port->ssr.mode = cl->rx_cfg.mode; | 532 | omap_port->ssr.mode = cl->rx_cfg.mode; |
531 | out: | 533 | out: |
532 | spin_unlock_bh(&omap_port->lock); | 534 | spin_unlock_bh(&omap_port->lock); |
533 | pm_runtime_put(omap_port->pdev); | 535 | pm_runtime_mark_last_busy(omap_port->pdev); |
536 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
534 | 537 | ||
535 | return err; | 538 | return err; |
536 | } | 539 | } |
@@ -561,7 +564,7 @@ static int ssi_flush(struct hsi_client *cl) | |||
561 | continue; | 564 | continue; |
562 | writew_relaxed(0, omap_ssi->gdd + SSI_GDD_CCR_REG(i)); | 565 | writew_relaxed(0, omap_ssi->gdd + SSI_GDD_CCR_REG(i)); |
563 | if (msg->ttype == HSI_MSG_READ) | 566 | if (msg->ttype == HSI_MSG_READ) |
564 | pm_runtime_put(omap_port->pdev); | 567 | pm_runtime_put_autosuspend(omap_port->pdev); |
565 | omap_ssi->gdd_trn[i].msg = NULL; | 568 | omap_ssi->gdd_trn[i].msg = NULL; |
566 | } | 569 | } |
567 | /* Flush all SST buffers */ | 570 | /* Flush all SST buffers */ |
@@ -585,7 +588,7 @@ static int ssi_flush(struct hsi_client *cl) | |||
585 | for (i = 0; i < omap_port->channels; i++) { | 588 | for (i = 0; i < omap_port->channels; i++) { |
586 | /* Release write clocks */ | 589 | /* Release write clocks */ |
587 | if (!list_empty(&omap_port->txqueue[i])) | 590 | if (!list_empty(&omap_port->txqueue[i])) |
588 | pm_runtime_put(omap_port->pdev); | 591 | pm_runtime_put_autosuspend(omap_port->pdev); |
589 | ssi_flush_queue(&omap_port->txqueue[i], NULL); | 592 | ssi_flush_queue(&omap_port->txqueue[i], NULL); |
590 | ssi_flush_queue(&omap_port->rxqueue[i], NULL); | 593 | ssi_flush_queue(&omap_port->rxqueue[i], NULL); |
591 | } | 594 | } |
@@ -595,7 +598,8 @@ static int ssi_flush(struct hsi_client *cl) | |||
595 | pinctrl_pm_select_default_state(omap_port->pdev); | 598 | pinctrl_pm_select_default_state(omap_port->pdev); |
596 | 599 | ||
597 | spin_unlock_bh(&omap_port->lock); | 600 | spin_unlock_bh(&omap_port->lock); |
598 | pm_runtime_put(omap_port->pdev); | 601 | pm_runtime_mark_last_busy(omap_port->pdev); |
602 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
599 | 603 | ||
600 | return 0; | 604 | return 0; |
601 | } | 605 | } |
@@ -649,7 +653,9 @@ static int ssi_stop_tx(struct hsi_client *cl) | |||
649 | writel(SSI_WAKE(0), omap_ssi->sys + SSI_CLEAR_WAKE_REG(port->num)); | 653 | writel(SSI_WAKE(0), omap_ssi->sys + SSI_CLEAR_WAKE_REG(port->num)); |
650 | spin_unlock_bh(&omap_port->wk_lock); | 654 | spin_unlock_bh(&omap_port->wk_lock); |
651 | 655 | ||
652 | pm_runtime_put(omap_port->pdev); /* Release clocks */ | 656 | pm_runtime_mark_last_busy(omap_port->pdev); |
657 | pm_runtime_put_autosuspend(omap_port->pdev); /* Release clocks */ | ||
658 | |||
653 | 659 | ||
654 | return 0; | 660 | return 0; |
655 | } | 661 | } |
@@ -675,7 +681,8 @@ static void ssi_transfer(struct omap_ssi_port *omap_port, | |||
675 | } | 681 | } |
676 | } | 682 | } |
677 | spin_unlock_bh(&omap_port->lock); | 683 | spin_unlock_bh(&omap_port->lock); |
678 | pm_runtime_put(omap_port->pdev); | 684 | pm_runtime_mark_last_busy(omap_port->pdev); |
685 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
679 | } | 686 | } |
680 | 687 | ||
681 | static void ssi_cleanup_queues(struct hsi_client *cl) | 688 | static void ssi_cleanup_queues(struct hsi_client *cl) |
@@ -704,7 +711,8 @@ static void ssi_cleanup_queues(struct hsi_client *cl) | |||
704 | txbufstate |= (1 << i); | 711 | txbufstate |= (1 << i); |
705 | status |= SSI_DATAACCEPT(i); | 712 | status |= SSI_DATAACCEPT(i); |
706 | /* Release the clocks writes, also GDD ones */ | 713 | /* Release the clocks writes, also GDD ones */ |
707 | pm_runtime_put(omap_port->pdev); | 714 | pm_runtime_mark_last_busy(omap_port->pdev); |
715 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
708 | } | 716 | } |
709 | ssi_flush_queue(&omap_port->txqueue[i], cl); | 717 | ssi_flush_queue(&omap_port->txqueue[i], cl); |
710 | } | 718 | } |
@@ -758,8 +766,10 @@ static void ssi_cleanup_gdd(struct hsi_controller *ssi, struct hsi_client *cl) | |||
758 | * Clock references for write will be handled in | 766 | * Clock references for write will be handled in |
759 | * ssi_cleanup_queues | 767 | * ssi_cleanup_queues |
760 | */ | 768 | */ |
761 | if (msg->ttype == HSI_MSG_READ) | 769 | if (msg->ttype == HSI_MSG_READ) { |
762 | pm_runtime_put(omap_port->pdev); | 770 | pm_runtime_mark_last_busy(omap_port->pdev); |
771 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
772 | } | ||
763 | omap_ssi->gdd_trn[i].msg = NULL; | 773 | omap_ssi->gdd_trn[i].msg = NULL; |
764 | } | 774 | } |
765 | tmp = readl_relaxed(omap_ssi->sys + SSI_GDD_MPU_IRQ_ENABLE_REG); | 775 | tmp = readl_relaxed(omap_ssi->sys + SSI_GDD_MPU_IRQ_ENABLE_REG); |
@@ -807,7 +817,7 @@ static int ssi_release(struct hsi_client *cl) | |||
807 | WARN_ON(omap_port->wk_refcount != 0); | 817 | WARN_ON(omap_port->wk_refcount != 0); |
808 | } | 818 | } |
809 | spin_unlock_bh(&omap_port->lock); | 819 | spin_unlock_bh(&omap_port->lock); |
810 | pm_runtime_put(omap_port->pdev); | 820 | pm_runtime_put_sync(omap_port->pdev); |
811 | 821 | ||
812 | return 0; | 822 | return 0; |
813 | } | 823 | } |
@@ -954,7 +964,8 @@ static void ssi_pio_complete(struct hsi_port *port, struct list_head *queue) | |||
954 | reg = readl(omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0)); | 964 | reg = readl(omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0)); |
955 | if (msg->ttype == HSI_MSG_WRITE) { | 965 | if (msg->ttype == HSI_MSG_WRITE) { |
956 | /* Release clocks for write transfer */ | 966 | /* Release clocks for write transfer */ |
957 | pm_runtime_put(omap_port->pdev); | 967 | pm_runtime_mark_last_busy(omap_port->pdev); |
968 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
958 | } | 969 | } |
959 | reg &= ~val; | 970 | reg &= ~val; |
960 | writel_relaxed(reg, omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0)); | 971 | writel_relaxed(reg, omap_ssi->sys + SSI_MPU_ENABLE_REG(port->num, 0)); |
@@ -998,7 +1009,9 @@ static irqreturn_t ssi_pio_thread(int irq, void *ssi_port) | |||
998 | /* TODO: sleep if we retry? */ | 1009 | /* TODO: sleep if we retry? */ |
999 | } while (status_reg); | 1010 | } while (status_reg); |
1000 | 1011 | ||
1001 | pm_runtime_put(omap_port->pdev); | 1012 | pm_runtime_mark_last_busy(omap_port->pdev); |
1013 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
1014 | |||
1002 | return IRQ_HANDLED; | 1015 | return IRQ_HANDLED; |
1003 | } | 1016 | } |
1004 | 1017 | ||
@@ -1032,8 +1045,10 @@ static irqreturn_t ssi_wake_thread(int irq __maybe_unused, void *ssi_port) | |||
1032 | omap_ssi->sys + SSI_CLEAR_WAKE_REG(port->num)); | 1045 | omap_ssi->sys + SSI_CLEAR_WAKE_REG(port->num)); |
1033 | } | 1046 | } |
1034 | hsi_event(port, HSI_EVENT_STOP_RX); | 1047 | hsi_event(port, HSI_EVENT_STOP_RX); |
1035 | if (test_and_clear_bit(SSI_WAKE_EN, &omap_port->flags)) | 1048 | if (test_and_clear_bit(SSI_WAKE_EN, &omap_port->flags)) { |
1036 | pm_runtime_put_sync(omap_port->pdev); | 1049 | pm_runtime_mark_last_busy(omap_port->pdev); |
1050 | pm_runtime_put_autosuspend(omap_port->pdev); | ||
1051 | } | ||
1037 | } | 1052 | } |
1038 | 1053 | ||
1039 | return IRQ_HANDLED; | 1054 | return IRQ_HANDLED; |
@@ -1222,6 +1237,9 @@ static int ssi_port_probe(struct platform_device *pd) | |||
1222 | omap_port->dev = &port->device; | 1237 | omap_port->dev = &port->device; |
1223 | 1238 | ||
1224 | pm_runtime_irq_safe(omap_port->pdev); | 1239 | pm_runtime_irq_safe(omap_port->pdev); |
1240 | |||
1241 | pm_runtime_use_autosuspend(omap_port->pdev); | ||
1242 | pm_runtime_set_autosuspend_delay(omap_port->pdev, 250); | ||
1225 | pm_runtime_enable(omap_port->pdev); | 1243 | pm_runtime_enable(omap_port->pdev); |
1226 | 1244 | ||
1227 | #ifdef CONFIG_DEBUG_FS | 1245 | #ifdef CONFIG_DEBUG_FS |
@@ -1266,6 +1284,8 @@ static int ssi_port_remove(struct platform_device *pd) | |||
1266 | 1284 | ||
1267 | omap_ssi->port[omap_port->port_id] = NULL; | 1285 | omap_ssi->port[omap_port->port_id] = NULL; |
1268 | platform_set_drvdata(pd, NULL); | 1286 | platform_set_drvdata(pd, NULL); |
1287 | |||
1288 | pm_runtime_dont_use_autosuspend(&pd->dev); | ||
1269 | pm_runtime_disable(&pd->dev); | 1289 | pm_runtime_disable(&pd->dev); |
1270 | 1290 | ||
1271 | return 0; | 1291 | return 0; |