4040#include <linux/clk.h>
4141#include <linux/cpufreq.h>
4242#include <linux/of.h>
43+ #include <linux/pm_runtime.h>
4344#include <asm/irq.h>
4445
4546/* UART name and device definitions */
@@ -1360,30 +1361,49 @@ static int apple_s5l_serial_startup(struct uart_port *port)
13601361
13611362/* power power management control */
13621363
1364+ static int __maybe_unused s3c24xx_serial_runtime_suspend (struct device * dev )
1365+ {
1366+ struct uart_port * port = dev_get_drvdata (dev );
1367+ struct s3c24xx_uart_port * ourport = to_ourport (port );
1368+ int timeout = 10000 ;
1369+
1370+ while (-- timeout && !s3c24xx_serial_txempty_nofifo (port ))
1371+ udelay (100 );
1372+
1373+ if (!IS_ERR (ourport -> baudclk ))
1374+ clk_disable_unprepare (ourport -> baudclk );
1375+
1376+ clk_disable_unprepare (ourport -> clk );
1377+ return 0 ;
1378+ };
1379+
1380+ static int __maybe_unused s3c24xx_serial_runtime_resume (struct device * dev )
1381+ {
1382+ struct uart_port * port = dev_get_drvdata (dev );
1383+ struct s3c24xx_uart_port * ourport = to_ourport (port );
1384+
1385+ clk_prepare_enable (ourport -> clk );
1386+
1387+ if (!IS_ERR (ourport -> baudclk ))
1388+ clk_prepare_enable (ourport -> baudclk );
1389+ return 0 ;
1390+ };
1391+
13631392static void s3c24xx_serial_pm (struct uart_port * port , unsigned int level ,
13641393 unsigned int old )
13651394{
13661395 struct s3c24xx_uart_port * ourport = to_ourport (port );
1367- int timeout = 10000 ;
13681396
13691397 ourport -> pm_level = level ;
13701398
13711399 switch (level ) {
1372- case 3 :
1373- while (-- timeout && !s3c24xx_serial_txempty_nofifo (port ))
1374- udelay (100 );
1375-
1376- if (!IS_ERR (ourport -> baudclk ))
1377- clk_disable_unprepare (ourport -> baudclk );
1378-
1379- clk_disable_unprepare (ourport -> clk );
1400+ case UART_PM_STATE_OFF :
1401+ pm_runtime_mark_last_busy (port -> dev );
1402+ pm_runtime_put_sync (port -> dev );
13801403 break ;
13811404
1382- case 0 :
1383- clk_prepare_enable (ourport -> clk );
1384-
1385- if (!IS_ERR (ourport -> baudclk ))
1386- clk_prepare_enable (ourport -> baudclk );
1405+ case UART_PM_STATE_ON :
1406+ pm_runtime_get_sync (port -> dev );
13871407 break ;
13881408 default :
13891409 dev_err (port -> dev , "s3c24xx_serial: unknown pm %d\n" , level );
@@ -2129,18 +2149,15 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
21292149 }
21302150 }
21312151
2152+ pm_runtime_get_noresume (& pdev -> dev );
2153+ pm_runtime_set_active (& pdev -> dev );
2154+ pm_runtime_enable (& pdev -> dev );
2155+
21322156 dev_dbg (& pdev -> dev , "%s: adding port\n" , __func__ );
21332157 uart_add_one_port (& s3c24xx_uart_drv , & ourport -> port );
21342158 platform_set_drvdata (pdev , & ourport -> port );
21352159
2136- /*
2137- * Deactivate the clock enabled in s3c24xx_serial_init_port here,
2138- * so that a potential re-enablement through the pm-callback overlaps
2139- * and keeps the clock enabled in this case.
2140- */
2141- clk_disable_unprepare (ourport -> clk );
2142- if (!IS_ERR (ourport -> baudclk ))
2143- clk_disable_unprepare (ourport -> baudclk );
2160+ pm_runtime_put_sync (& pdev -> dev );
21442161
21452162 probe_index ++ ;
21462163
@@ -2150,9 +2167,19 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
21502167static int s3c24xx_serial_remove (struct platform_device * dev )
21512168{
21522169 struct uart_port * port = s3c24xx_dev_to_port (& dev -> dev );
2170+ struct s3c24xx_uart_port * ourport = to_ourport (port );
21532171
21542172 if (port ) {
2173+ pm_runtime_get_sync (& dev -> dev );
21552174 uart_remove_one_port (& s3c24xx_uart_drv , port );
2175+
2176+ clk_disable_unprepare (ourport -> clk );
2177+ if (!IS_ERR (ourport -> baudclk ))
2178+ clk_disable_unprepare (ourport -> baudclk );
2179+
2180+ pm_runtime_disable (& dev -> dev );
2181+ pm_runtime_set_suspended (& dev -> dev );
2182+ pm_runtime_put_noidle (& dev -> dev );
21562183 }
21572184
21582185 uart_unregister_driver (& s3c24xx_uart_drv );
@@ -2161,8 +2188,8 @@ static int s3c24xx_serial_remove(struct platform_device *dev)
21612188}
21622189
21632190/* UART power management code */
2164- #ifdef CONFIG_PM_SLEEP
2165- static int s3c24xx_serial_suspend (struct device * dev )
2191+
2192+ static int __maybe_unused s3c24xx_serial_suspend (struct device * dev )
21662193{
21672194 struct uart_port * port = s3c24xx_dev_to_port (dev );
21682195
@@ -2172,7 +2199,7 @@ static int s3c24xx_serial_suspend(struct device *dev)
21722199 return 0 ;
21732200}
21742201
2175- static int s3c24xx_serial_resume (struct device * dev )
2202+ static int __maybe_unused s3c24xx_serial_resume (struct device * dev )
21762203{
21772204 struct uart_port * port = s3c24xx_dev_to_port (dev );
21782205 struct s3c24xx_uart_port * ourport = to_ourport (port );
@@ -2192,7 +2219,7 @@ static int s3c24xx_serial_resume(struct device *dev)
21922219 return 0 ;
21932220}
21942221
2195- static int s3c24xx_serial_resume_noirq (struct device * dev )
2222+ static int __maybe_unused s3c24xx_serial_resume_noirq (struct device * dev )
21962223{
21972224 struct uart_port * port = s3c24xx_dev_to_port (dev );
21982225 struct s3c24xx_uart_port * ourport = to_ourport (port );
@@ -2262,16 +2289,14 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
22622289}
22632290
22642291static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
2292+ #ifdef CONFIG_PM_SLEEP
22652293 .suspend = s3c24xx_serial_suspend ,
22662294 .resume = s3c24xx_serial_resume ,
22672295 .resume_noirq = s3c24xx_serial_resume_noirq ,
2296+ #endif
2297+ SET_RUNTIME_PM_OPS (s3c24xx_serial_runtime_suspend ,
2298+ s3c24xx_serial_runtime_resume , NULL )
22682299};
2269- #define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops)
2270-
2271- #else /* !CONFIG_PM_SLEEP */
2272-
2273- #define SERIAL_SAMSUNG_PM_OPS NULL
2274- #endif /* CONFIG_PM_SLEEP */
22752300
22762301/* Console code */
22772302
@@ -2709,7 +2734,7 @@ static struct platform_driver samsung_serial_driver = {
27092734 .id_table = s3c24xx_serial_driver_ids ,
27102735 .driver = {
27112736 .name = "samsung-uart" ,
2712- .pm = SERIAL_SAMSUNG_PM_OPS ,
2737+ .pm = & s3c24xx_serial_pm_ops ,
27132738 .of_match_table = of_match_ptr (s3c24xx_uart_dt_match ),
27142739 },
27152740};
0 commit comments