4141#include <linux/clk.h>
4242#include <linux/cpufreq.h>
4343#include <linux/of.h>
44+ #include <linux/pm_runtime.h>
4445#include <asm/irq.h>
4546
4647/* UART name and device definitions */
@@ -1362,30 +1363,49 @@ static int apple_s5l_serial_startup(struct uart_port *port)
13621363
13631364/* power power management control */
13641365
1366+ static int __maybe_unused s3c24xx_serial_runtime_suspend (struct device * dev )
1367+ {
1368+ struct uart_port * port = dev_get_drvdata (dev );
1369+ struct s3c24xx_uart_port * ourport = to_ourport (port );
1370+ int timeout = 10000 ;
1371+
1372+ while (-- timeout && !s3c24xx_serial_txempty_nofifo (port ))
1373+ udelay (100 );
1374+
1375+ if (!IS_ERR (ourport -> baudclk ))
1376+ clk_disable_unprepare (ourport -> baudclk );
1377+
1378+ clk_disable_unprepare (ourport -> clk );
1379+ return 0 ;
1380+ };
1381+
1382+ static int __maybe_unused s3c24xx_serial_runtime_resume (struct device * dev )
1383+ {
1384+ struct uart_port * port = dev_get_drvdata (dev );
1385+ struct s3c24xx_uart_port * ourport = to_ourport (port );
1386+
1387+ clk_prepare_enable (ourport -> clk );
1388+
1389+ if (!IS_ERR (ourport -> baudclk ))
1390+ clk_prepare_enable (ourport -> baudclk );
1391+ return 0 ;
1392+ };
1393+
13651394static void s3c24xx_serial_pm (struct uart_port * port , unsigned int level ,
13661395 unsigned int old )
13671396{
13681397 struct s3c24xx_uart_port * ourport = to_ourport (port );
1369- int timeout = 10000 ;
13701398
13711399 ourport -> pm_level = level ;
13721400
13731401 switch (level ) {
1374- case 3 :
1375- while (-- timeout && !s3c24xx_serial_txempty_nofifo (port ))
1376- udelay (100 );
1377-
1378- if (!IS_ERR (ourport -> baudclk ))
1379- clk_disable_unprepare (ourport -> baudclk );
1380-
1381- clk_disable_unprepare (ourport -> clk );
1402+ case UART_PM_STATE_OFF :
1403+ pm_runtime_mark_last_busy (port -> dev );
1404+ pm_runtime_put_sync (port -> dev );
13821405 break ;
13831406
1384- case 0 :
1385- clk_prepare_enable (ourport -> clk );
1386-
1387- if (!IS_ERR (ourport -> baudclk ))
1388- clk_prepare_enable (ourport -> baudclk );
1407+ case UART_PM_STATE_ON :
1408+ pm_runtime_get_sync (port -> dev );
13891409 break ;
13901410 default :
13911411 dev_err (port -> dev , "s3c24xx_serial: unknown pm %d\n" , level );
@@ -2141,18 +2161,15 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
21412161 }
21422162 }
21432163
2164+ pm_runtime_get_noresume (& pdev -> dev );
2165+ pm_runtime_set_active (& pdev -> dev );
2166+ pm_runtime_enable (& pdev -> dev );
2167+
21442168 dev_dbg (& pdev -> dev , "%s: adding port\n" , __func__ );
21452169 uart_add_one_port (& s3c24xx_uart_drv , & ourport -> port );
21462170 platform_set_drvdata (pdev , & ourport -> port );
21472171
2148- /*
2149- * Deactivate the clock enabled in s3c24xx_serial_init_port here,
2150- * so that a potential re-enablement through the pm-callback overlaps
2151- * and keeps the clock enabled in this case.
2152- */
2153- clk_disable_unprepare (ourport -> clk );
2154- if (!IS_ERR (ourport -> baudclk ))
2155- clk_disable_unprepare (ourport -> baudclk );
2172+ pm_runtime_put_sync (& pdev -> dev );
21562173
21572174 probe_index ++ ;
21582175
@@ -2162,9 +2179,19 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
21622179static int s3c24xx_serial_remove (struct platform_device * dev )
21632180{
21642181 struct uart_port * port = s3c24xx_dev_to_port (& dev -> dev );
2182+ struct s3c24xx_uart_port * ourport = to_ourport (port );
21652183
21662184 if (port ) {
2185+ pm_runtime_get_sync (& dev -> dev );
21672186 uart_remove_one_port (& s3c24xx_uart_drv , port );
2187+
2188+ clk_disable_unprepare (ourport -> clk );
2189+ if (!IS_ERR (ourport -> baudclk ))
2190+ clk_disable_unprepare (ourport -> baudclk );
2191+
2192+ pm_runtime_disable (& dev -> dev );
2193+ pm_runtime_set_suspended (& dev -> dev );
2194+ pm_runtime_put_noidle (& dev -> dev );
21682195 }
21692196
21702197 uart_unregister_driver (& s3c24xx_uart_drv );
@@ -2173,8 +2200,8 @@ static int s3c24xx_serial_remove(struct platform_device *dev)
21732200}
21742201
21752202/* UART power management code */
2176- #ifdef CONFIG_PM_SLEEP
2177- static int s3c24xx_serial_suspend (struct device * dev )
2203+
2204+ static int __maybe_unused s3c24xx_serial_suspend (struct device * dev )
21782205{
21792206 struct uart_port * port = s3c24xx_dev_to_port (dev );
21802207
@@ -2184,7 +2211,7 @@ static int s3c24xx_serial_suspend(struct device *dev)
21842211 return 0 ;
21852212}
21862213
2187- static int s3c24xx_serial_resume (struct device * dev )
2214+ static int __maybe_unused s3c24xx_serial_resume (struct device * dev )
21882215{
21892216 struct uart_port * port = s3c24xx_dev_to_port (dev );
21902217 struct s3c24xx_uart_port * ourport = to_ourport (port );
@@ -2204,7 +2231,7 @@ static int s3c24xx_serial_resume(struct device *dev)
22042231 return 0 ;
22052232}
22062233
2207- static int s3c24xx_serial_resume_noirq (struct device * dev )
2234+ static int __maybe_unused s3c24xx_serial_resume_noirq (struct device * dev )
22082235{
22092236 struct uart_port * port = s3c24xx_dev_to_port (dev );
22102237 struct s3c24xx_uart_port * ourport = to_ourport (port );
@@ -2276,13 +2303,9 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
22762303static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
22772304 SET_SYSTEM_SLEEP_PM_OPS (s3c24xx_serial_suspend , s3c24xx_serial_resume )
22782305 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (NULL , s3c24xx_serial_resume_noirq )
2306+ SET_RUNTIME_PM_OPS (s3c24xx_serial_runtime_suspend ,
2307+ s3c24xx_serial_runtime_resume , NULL )
22792308};
2280- #define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops)
2281-
2282- #else /* !CONFIG_PM_SLEEP */
2283-
2284- #define SERIAL_SAMSUNG_PM_OPS NULL
2285- #endif /* CONFIG_PM_SLEEP */
22862309
22872310/* Console code */
22882311
@@ -2720,7 +2743,7 @@ static struct platform_driver samsung_serial_driver = {
27202743 .id_table = s3c24xx_serial_driver_ids ,
27212744 .driver = {
27222745 .name = "samsung-uart" ,
2723- .pm = SERIAL_SAMSUNG_PM_OPS ,
2746+ .pm = & s3c24xx_serial_pm_ops ,
27242747 .of_match_table = of_match_ptr (s3c24xx_uart_dt_match ),
27252748 },
27262749};
0 commit comments