Skip to content

Commit e32a83c

Browse files
Changqi Hugregkh
authored andcommitted
serial: 8250-mtk: modify mtk uart power and clock management
MTK uart design no need to control uart clock, so we just control bus clock in runtime function. Add uart clock used count to avoid repeatedly switching the clock. Signed-off-by: Changqi Hu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5a08a48 commit e32a83c

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

drivers/tty/serial/8250/8250_mtk.c

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */
3333
#define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */
3434
#define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */
35+
#define MTK_UART_DEBUG0 0x18
3536
#define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */
3637
#define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */
3738
#define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */
@@ -388,9 +389,18 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
388389
static int __maybe_unused mtk8250_runtime_suspend(struct device *dev)
389390
{
390391
struct mtk8250_data *data = dev_get_drvdata(dev);
392+
struct uart_8250_port *up = serial8250_get_port(data->line);
391393

392-
clk_disable_unprepare(data->uart_clk);
393-
clk_disable_unprepare(data->bus_clk);
394+
/* wait until UART in idle status */
395+
while
396+
(serial_in(up, MTK_UART_DEBUG0));
397+
398+
if (data->clk_count == 0U) {
399+
dev_dbg(dev, "%s clock count is 0\n", __func__);
400+
} else {
401+
clk_disable_unprepare(data->bus_clk);
402+
data->clk_count--;
403+
}
394404

395405
return 0;
396406
}
@@ -400,16 +410,16 @@ static int __maybe_unused mtk8250_runtime_resume(struct device *dev)
400410
struct mtk8250_data *data = dev_get_drvdata(dev);
401411
int err;
402412

403-
err = clk_prepare_enable(data->uart_clk);
404-
if (err) {
405-
dev_warn(dev, "Can't enable clock\n");
406-
return err;
407-
}
408-
409-
err = clk_prepare_enable(data->bus_clk);
410-
if (err) {
411-
dev_warn(dev, "Can't enable bus clock\n");
412-
return err;
413+
if (data->clk_count > 0U) {
414+
dev_dbg(dev, "%s clock count is %d\n", __func__,
415+
data->clk_count);
416+
} else {
417+
err = clk_prepare_enable(data->bus_clk);
418+
if (err) {
419+
dev_warn(dev, "Can't enable bus clock\n");
420+
return err;
421+
}
422+
data->clk_count++;
413423
}
414424

415425
return 0;
@@ -419,12 +429,14 @@ static void
419429
mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
420430
{
421431
if (!state)
422-
pm_runtime_get_sync(port->dev);
432+
if (!mtk8250_runtime_resume(port->dev))
433+
pm_runtime_get_sync(port->dev);
423434

424435
serial8250_do_pm(port, state, old);
425436

426437
if (state)
427-
pm_runtime_put_sync_suspend(port->dev);
438+
if (!pm_runtime_put_sync_suspend(port->dev))
439+
mtk8250_runtime_suspend(port->dev);
428440
}
429441

430442
#ifdef CONFIG_SERIAL_8250_DMA
@@ -501,6 +513,8 @@ static int mtk8250_probe(struct platform_device *pdev)
501513
if (!data)
502514
return -ENOMEM;
503515

516+
data->clk_count = 0;
517+
504518
if (pdev->dev.of_node) {
505519
err = mtk8250_probe_of(pdev, &uart.port, data);
506520
if (err)
@@ -533,6 +547,7 @@ static int mtk8250_probe(struct platform_device *pdev)
533547

534548
platform_set_drvdata(pdev, data);
535549

550+
pm_runtime_enable(&pdev->dev);
536551
err = mtk8250_runtime_resume(&pdev->dev);
537552
if (err)
538553
return err;
@@ -541,9 +556,6 @@ static int mtk8250_probe(struct platform_device *pdev)
541556
if (data->line < 0)
542557
return data->line;
543558

544-
pm_runtime_set_active(&pdev->dev);
545-
pm_runtime_enable(&pdev->dev);
546-
547559
data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1);
548560

549561
return 0;
@@ -556,11 +568,13 @@ static int mtk8250_remove(struct platform_device *pdev)
556568
pm_runtime_get_sync(&pdev->dev);
557569

558570
serial8250_unregister_port(data->line);
559-
mtk8250_runtime_suspend(&pdev->dev);
560571

561572
pm_runtime_disable(&pdev->dev);
562573
pm_runtime_put_noidle(&pdev->dev);
563574

575+
if (!pm_runtime_status_suspended(&pdev->dev))
576+
mtk8250_runtime_suspend(&pdev->dev);
577+
564578
return 0;
565579
}
566580

0 commit comments

Comments
 (0)