aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Reichel <sre@kernel.org>2016-05-11 11:22:00 -0400
committerSebastian Reichel <sre@kernel.org>2016-06-27 18:40:03 -0400
commitad60db2f9fe3367e60a21fc0afe19999516f8b27 (patch)
treee20669ae89c608890fb67450d994153e5ebcd2b9
parent4e552310cdf0c81210b5fc9173f7cf497eeb9feb (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.c68
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 }
392out: 392out:
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;
531out: 533out:
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
681static void ssi_cleanup_queues(struct hsi_client *cl) 688static 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;