19
19
#include <linux/of_device.h>
20
20
#include <linux/of_dma.h>
21
21
#include <linux/pinctrl/consumer.h>
22
+ #include <linux/pm_runtime.h>
22
23
#include <linux/serial_core.h>
23
24
#include <linux/slab.h>
24
25
#include <linux/tty_flip.h>
233
234
234
235
/* Rx DMA timeout in ms, which is used to calculate Rx ring buffer size */
235
236
#define DMA_RX_TIMEOUT (10)
237
+ #define UART_AUTOSUSPEND_TIMEOUT 3000
236
238
237
239
#define DRIVER_NAME "fsl-lpuart"
238
240
#define DEV_NAME "ttyLP"
@@ -793,6 +795,20 @@ static void lpuart32_start_tx(struct uart_port *port)
793
795
}
794
796
}
795
797
798
+ static void
799
+ lpuart_uart_pm (struct uart_port * port , unsigned int state , unsigned int oldstate )
800
+ {
801
+ switch (state ) {
802
+ case UART_PM_STATE_OFF :
803
+ pm_runtime_mark_last_busy (port -> dev );
804
+ pm_runtime_put_autosuspend (port -> dev );
805
+ break ;
806
+ default :
807
+ pm_runtime_get_sync (port -> dev );
808
+ break ;
809
+ }
810
+ }
811
+
796
812
/* return TIOCSER_TEMT when transmitter is not busy */
797
813
static unsigned int lpuart_tx_empty (struct uart_port * port )
798
814
{
@@ -2229,6 +2245,7 @@ static const struct uart_ops lpuart_pops = {
2229
2245
.startup = lpuart_startup ,
2230
2246
.shutdown = lpuart_shutdown ,
2231
2247
.set_termios = lpuart_set_termios ,
2248
+ .pm = lpuart_uart_pm ,
2232
2249
.type = lpuart_type ,
2233
2250
.request_port = lpuart_request_port ,
2234
2251
.release_port = lpuart_release_port ,
@@ -2253,6 +2270,7 @@ static const struct uart_ops lpuart32_pops = {
2253
2270
.startup = lpuart32_startup ,
2254
2271
.shutdown = lpuart32_shutdown ,
2255
2272
.set_termios = lpuart32_set_termios ,
2273
+ .pm = lpuart_uart_pm ,
2256
2274
.type = lpuart_type ,
2257
2275
.request_port = lpuart_request_port ,
2258
2276
.release_port = lpuart_release_port ,
@@ -2733,6 +2751,11 @@ static int lpuart_probe(struct platform_device *pdev)
2733
2751
handler = lpuart_int ;
2734
2752
}
2735
2753
2754
+ pm_runtime_use_autosuspend (& pdev -> dev );
2755
+ pm_runtime_set_autosuspend_delay (& pdev -> dev , UART_AUTOSUSPEND_TIMEOUT );
2756
+ pm_runtime_set_active (& pdev -> dev );
2757
+ pm_runtime_enable (& pdev -> dev );
2758
+
2736
2759
ret = lpuart_global_reset (sport );
2737
2760
if (ret )
2738
2761
goto failed_reset ;
@@ -2757,6 +2780,9 @@ static int lpuart_probe(struct platform_device *pdev)
2757
2780
failed_attach_port :
2758
2781
failed_get_rs485 :
2759
2782
failed_reset :
2783
+ pm_runtime_disable (& pdev -> dev );
2784
+ pm_runtime_set_suspended (& pdev -> dev );
2785
+ pm_runtime_dont_use_autosuspend (& pdev -> dev );
2760
2786
lpuart_disable_clks (sport );
2761
2787
return ret ;
2762
2788
}
@@ -2775,9 +2801,30 @@ static int lpuart_remove(struct platform_device *pdev)
2775
2801
if (sport -> dma_rx_chan )
2776
2802
dma_release_channel (sport -> dma_rx_chan );
2777
2803
2804
+ pm_runtime_disable (& pdev -> dev );
2805
+ pm_runtime_set_suspended (& pdev -> dev );
2806
+ pm_runtime_dont_use_autosuspend (& pdev -> dev );
2778
2807
return 0 ;
2779
2808
}
2780
2809
2810
+ static int __maybe_unused lpuart_runtime_suspend (struct device * dev )
2811
+ {
2812
+ struct platform_device * pdev = to_platform_device (dev );
2813
+ struct lpuart_port * sport = platform_get_drvdata (pdev );
2814
+
2815
+ lpuart_disable_clks (sport );
2816
+
2817
+ return 0 ;
2818
+ };
2819
+
2820
+ static int __maybe_unused lpuart_runtime_resume (struct device * dev )
2821
+ {
2822
+ struct platform_device * pdev = to_platform_device (dev );
2823
+ struct lpuart_port * sport = platform_get_drvdata (pdev );
2824
+
2825
+ return lpuart_enable_clks (sport );
2826
+ };
2827
+
2781
2828
static void serial_lpuart_enable_wakeup (struct lpuart_port * sport , bool on )
2782
2829
{
2783
2830
unsigned int val , baud ;
@@ -2923,6 +2970,10 @@ static int __maybe_unused lpuart_suspend(struct device *dev)
2923
2970
sport -> dma_tx_in_progress = false;
2924
2971
dmaengine_terminate_all (sport -> dma_tx_chan );
2925
2972
}
2973
+ } else if (pm_runtime_active (sport -> port .dev )) {
2974
+ lpuart_disable_clks (sport );
2975
+ pm_runtime_disable (sport -> port .dev );
2976
+ pm_runtime_set_suspended (sport -> port .dev );
2926
2977
}
2927
2978
2928
2979
return 0 ;
@@ -2957,12 +3008,19 @@ static void lpuart_console_fixup(struct lpuart_port *sport)
2957
3008
static int __maybe_unused lpuart_resume (struct device * dev )
2958
3009
{
2959
3010
struct lpuart_port * sport = dev_get_drvdata (dev );
3011
+ int ret ;
2960
3012
2961
3013
if (lpuart_uport_is_active (sport )) {
2962
3014
if (lpuart_is_32 (sport ))
2963
3015
lpuart32_hw_setup (sport );
2964
3016
else
2965
3017
lpuart_hw_setup (sport );
3018
+ } else if (pm_runtime_active (sport -> port .dev )) {
3019
+ ret = lpuart_enable_clks (sport );
3020
+ if (ret )
3021
+ return ret ;
3022
+ pm_runtime_set_active (sport -> port .dev );
3023
+ pm_runtime_enable (sport -> port .dev );
2966
3024
}
2967
3025
2968
3026
lpuart_console_fixup (sport );
@@ -2972,6 +3030,8 @@ static int __maybe_unused lpuart_resume(struct device *dev)
2972
3030
}
2973
3031
2974
3032
static const struct dev_pm_ops lpuart_pm_ops = {
3033
+ SET_RUNTIME_PM_OPS (lpuart_runtime_suspend ,
3034
+ lpuart_runtime_resume , NULL )
2975
3035
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (lpuart_suspend_noirq ,
2976
3036
lpuart_resume_noirq )
2977
3037
SET_SYSTEM_SLEEP_PM_OPS (lpuart_suspend , lpuart_resume )
0 commit comments