3434#include <linux/module.h>
3535#include <linux/of.h>
3636#include <linux/platform_device.h>
37+ #include <linux/pm_runtime.h>
3738#include <linux/serial.h>
3839#include <linux/serial_core.h>
3940#include <linux/serial_s3c.h>
@@ -1294,30 +1295,49 @@ static int apple_s5l_serial_startup(struct uart_port *port)
12941295 return ret ;
12951296}
12961297
1298+ static int __maybe_unused s3c24xx_serial_runtime_suspend (struct device * dev )
1299+ {
1300+ struct uart_port * port = dev_get_drvdata (dev );
1301+ struct s3c24xx_uart_port * ourport = to_ourport (port );
1302+ int timeout = 10000 ;
1303+
1304+ while (-- timeout && !s3c24xx_serial_txempty_nofifo (port ))
1305+ udelay (100 );
1306+
1307+ if (!IS_ERR (ourport -> baudclk ))
1308+ clk_disable_unprepare (ourport -> baudclk );
1309+
1310+ clk_disable_unprepare (ourport -> clk );
1311+ return 0 ;
1312+ };
1313+
1314+ static int __maybe_unused s3c24xx_serial_runtime_resume (struct device * dev )
1315+ {
1316+ struct uart_port * port = dev_get_drvdata (dev );
1317+ struct s3c24xx_uart_port * ourport = to_ourport (port );
1318+
1319+ clk_prepare_enable (ourport -> clk );
1320+
1321+ if (!IS_ERR (ourport -> baudclk ))
1322+ clk_prepare_enable (ourport -> baudclk );
1323+ return 0 ;
1324+ };
1325+
12971326static void s3c24xx_serial_pm (struct uart_port * port , unsigned int level ,
12981327 unsigned int old )
12991328{
13001329 struct s3c24xx_uart_port * ourport = to_ourport (port );
1301- int timeout = 10000 ;
13021330
13031331 ourport -> pm_level = level ;
13041332
13051333 switch (level ) {
1306- case 3 :
1307- while (-- timeout && !s3c24xx_serial_txempty_nofifo (port ))
1308- udelay (100 );
1309-
1310- if (!IS_ERR (ourport -> baudclk ))
1311- clk_disable_unprepare (ourport -> baudclk );
1312-
1313- clk_disable_unprepare (ourport -> clk );
1334+ case UART_PM_STATE_OFF :
1335+ pm_runtime_mark_last_busy (port -> dev );
1336+ pm_runtime_put_sync (port -> dev );
13141337 break ;
13151338
1316- case 0 :
1317- clk_prepare_enable (ourport -> clk );
1318-
1319- if (!IS_ERR (ourport -> baudclk ))
1320- clk_prepare_enable (ourport -> baudclk );
1339+ case UART_PM_STATE_ON :
1340+ pm_runtime_get_sync (port -> dev );
13211341 break ;
13221342 default :
13231343 dev_err (port -> dev , "s3c24xx_serial: unknown pm %d\n" , level );
@@ -2040,18 +2060,15 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
20402060 }
20412061 }
20422062
2063+ pm_runtime_get_noresume (& pdev -> dev );
2064+ pm_runtime_set_active (& pdev -> dev );
2065+ pm_runtime_enable (& pdev -> dev );
2066+
20432067 dev_dbg (& pdev -> dev , "%s: adding port\n" , __func__ );
20442068 uart_add_one_port (& s3c24xx_uart_drv , & ourport -> port );
20452069 platform_set_drvdata (pdev , & ourport -> port );
20462070
2047- /*
2048- * Deactivate the clock enabled in s3c24xx_serial_init_port here,
2049- * so that a potential re-enablement through the pm-callback overlaps
2050- * and keeps the clock enabled in this case.
2051- */
2052- clk_disable_unprepare (ourport -> clk );
2053- if (!IS_ERR (ourport -> baudclk ))
2054- clk_disable_unprepare (ourport -> baudclk );
2071+ pm_runtime_put_sync (& pdev -> dev );
20552072
20562073 probe_index ++ ;
20572074
@@ -2061,16 +2078,26 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
20612078static void s3c24xx_serial_remove (struct platform_device * dev )
20622079{
20632080 struct uart_port * port = s3c24xx_dev_to_port (& dev -> dev );
2081+ struct s3c24xx_uart_port * ourport = to_ourport (port );
20642082
20652083 if (port )
2084+ pm_runtime_get_sync (& dev -> dev );
20662085 uart_remove_one_port (& s3c24xx_uart_drv , port );
20672086
2087+ clk_disable_unprepare (ourport -> clk );
2088+ if (!IS_ERR (ourport -> baudclk ))
2089+ clk_disable_unprepare (ourport -> baudclk );
2090+
2091+ pm_runtime_disable (& dev -> dev );
2092+ pm_runtime_set_suspended (& dev -> dev );
2093+ pm_runtime_put_noidle (& dev -> dev );
2094+
20682095 uart_unregister_driver (& s3c24xx_uart_drv );
20692096}
20702097
20712098/* UART power management code */
2072- #ifdef CONFIG_PM_SLEEP
2073- static int s3c24xx_serial_suspend (struct device * dev )
2099+
2100+ static int __maybe_unused s3c24xx_serial_suspend (struct device * dev )
20742101{
20752102 struct uart_port * port = s3c24xx_dev_to_port (dev );
20762103
@@ -2080,7 +2107,7 @@ static int s3c24xx_serial_suspend(struct device *dev)
20802107 return 0 ;
20812108}
20822109
2083- static int s3c24xx_serial_resume (struct device * dev )
2110+ static int __maybe_unused s3c24xx_serial_resume (struct device * dev )
20842111{
20852112 struct uart_port * port = s3c24xx_dev_to_port (dev );
20862113 struct s3c24xx_uart_port * ourport = to_ourport (port );
@@ -2100,7 +2127,7 @@ static int s3c24xx_serial_resume(struct device *dev)
21002127 return 0 ;
21012128}
21022129
2103- static int s3c24xx_serial_resume_noirq (struct device * dev )
2130+ static int __maybe_unused s3c24xx_serial_resume_noirq (struct device * dev )
21042131{
21052132 struct uart_port * port = s3c24xx_dev_to_port (dev );
21062133 struct s3c24xx_uart_port * ourport = to_ourport (port );
@@ -2172,13 +2199,9 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
21722199static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
21732200 SET_SYSTEM_SLEEP_PM_OPS (s3c24xx_serial_suspend , s3c24xx_serial_resume )
21742201 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (NULL , s3c24xx_serial_resume_noirq )
2202+ SET_RUNTIME_PM_OPS (s3c24xx_serial_runtime_suspend ,
2203+ s3c24xx_serial_runtime_resume , NULL )
21752204};
2176- #define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops)
2177-
2178- #else /* !CONFIG_PM_SLEEP */
2179-
2180- #define SERIAL_SAMSUNG_PM_OPS NULL
2181- #endif /* CONFIG_PM_SLEEP */
21822205
21832206/* Console code */
21842207
@@ -2653,7 +2676,7 @@ static struct platform_driver samsung_serial_driver = {
26532676 .id_table = s3c24xx_serial_driver_ids ,
26542677 .driver = {
26552678 .name = "samsung-uart" ,
2656- .pm = SERIAL_SAMSUNG_PM_OPS ,
2679+ .pm = & s3c24xx_serial_pm_ops ,
26572680 .of_match_table = of_match_ptr (s3c24xx_uart_dt_match ),
26582681 },
26592682};
0 commit comments