20
20
#include <linux/of_irq.h>
21
21
#include <linux/of_address.h>
22
22
#include <linux/platform_device.h>
23
+ #include <linux/pm_runtime.h>
23
24
#include <linux/spi/spi.h>
24
25
#include <linux/spinlock.h>
25
26
#include <linux/workqueue.h>
135
136
#define GQSPI_DMA_UNALIGN 0x3
136
137
#define GQSPI_DEFAULT_NUM_CS 1 /* Default number of chip selects */
137
138
139
+ #define SPI_AUTOSUSPEND_TIMEOUT 3000
138
140
enum mode_type {GQSPI_MODE_IO , GQSPI_MODE_DMA };
139
141
140
142
/**
@@ -356,21 +358,9 @@ static void zynqmp_qspi_copy_read_data(struct zynqmp_qspi *xqspi,
356
358
static int zynqmp_prepare_transfer_hardware (struct spi_master * master )
357
359
{
358
360
struct zynqmp_qspi * xqspi = spi_master_get_devdata (master );
359
- int ret ;
360
-
361
- ret = clk_enable (xqspi -> refclk );
362
- if (ret )
363
- return ret ;
364
-
365
- ret = clk_enable (xqspi -> pclk );
366
- if (ret )
367
- goto clk_err ;
368
361
369
362
zynqmp_gqspi_write (xqspi , GQSPI_EN_OFST , GQSPI_EN_MASK );
370
363
return 0 ;
371
- clk_err :
372
- clk_disable (xqspi -> refclk );
373
- return ret ;
374
364
}
375
365
376
366
/**
@@ -387,8 +377,6 @@ static int zynqmp_unprepare_transfer_hardware(struct spi_master *master)
387
377
struct zynqmp_qspi * xqspi = spi_master_get_devdata (master );
388
378
389
379
zynqmp_gqspi_write (xqspi , GQSPI_EN_OFST , 0x0 );
390
- clk_disable (xqspi -> refclk );
391
- clk_disable (xqspi -> pclk );
392
380
return 0 ;
393
381
}
394
382
@@ -959,11 +947,67 @@ static int __maybe_unused zynqmp_qspi_resume(struct device *dev)
959
947
960
948
spi_master_resume (master );
961
949
950
+ clk_disable (xqspi -> refclk );
951
+ clk_disable (xqspi -> pclk );
962
952
return 0 ;
963
953
}
964
954
965
- static SIMPLE_DEV_PM_OPS (zynqmp_qspi_dev_pm_ops , zynqmp_qspi_suspend ,
966
- zynqmp_qspi_resume ) ;
955
+ /**
956
+ * zynqmp_runtime_suspend - Runtime suspend method for the SPI driver
957
+ * @dev: Address of the platform_device structure
958
+ *
959
+ * This function disables the clocks
960
+ *
961
+ * Return: Always 0
962
+ */
963
+ static int __maybe_unused zynqmp_runtime_suspend (struct device * dev )
964
+ {
965
+ struct platform_device * pdev = to_platform_device (dev );
966
+ struct spi_master * master = platform_get_drvdata (pdev );
967
+ struct zynqmp_qspi * xqspi = spi_master_get_devdata (master );
968
+
969
+ clk_disable (xqspi -> refclk );
970
+ clk_disable (xqspi -> pclk );
971
+
972
+ return 0 ;
973
+ }
974
+
975
+ /**
976
+ * zynqmp_runtime_resume - Runtime resume method for the SPI driver
977
+ * @dev: Address of the platform_device structure
978
+ *
979
+ * This function enables the clocks
980
+ *
981
+ * Return: 0 on success and error value on error
982
+ */
983
+ static int __maybe_unused zynqmp_runtime_resume (struct device * dev )
984
+ {
985
+ struct platform_device * pdev = to_platform_device (dev );
986
+ struct spi_master * master = platform_get_drvdata (pdev );
987
+ struct zynqmp_qspi * xqspi = spi_master_get_devdata (master );
988
+ int ret ;
989
+
990
+ ret = clk_enable (xqspi -> pclk );
991
+ if (ret ) {
992
+ dev_err (dev , "Cannot enable APB clock.\n" );
993
+ return ret ;
994
+ }
995
+
996
+ ret = clk_enable (xqspi -> refclk );
997
+ if (ret ) {
998
+ dev_err (dev , "Cannot enable device clock.\n" );
999
+ clk_disable (xqspi -> pclk );
1000
+ return ret ;
1001
+ }
1002
+
1003
+ return 0 ;
1004
+ }
1005
+
1006
+ static const struct dev_pm_ops zynqmp_qspi_dev_pm_ops = {
1007
+ SET_RUNTIME_PM_OPS (zynqmp_runtime_suspend ,
1008
+ zynqmp_runtime_resume , NULL )
1009
+ SET_SYSTEM_SLEEP_PM_OPS (zynqmp_qspi_suspend , zynqmp_qspi_resume )
1010
+ };
967
1011
968
1012
/**
969
1013
* zynqmp_qspi_probe: Probe method for the QSPI driver
@@ -1023,9 +1067,15 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
1023
1067
goto clk_dis_pclk ;
1024
1068
}
1025
1069
1070
+ pm_runtime_use_autosuspend (& pdev -> dev );
1071
+ pm_runtime_set_autosuspend_delay (& pdev -> dev , SPI_AUTOSUSPEND_TIMEOUT );
1072
+ pm_runtime_set_active (& pdev -> dev );
1073
+ pm_runtime_enable (& pdev -> dev );
1026
1074
/* QSPI controller initializations */
1027
1075
zynqmp_qspi_init_hw (xqspi );
1028
1076
1077
+ pm_runtime_mark_last_busy (& pdev -> dev );
1078
+ pm_runtime_put_autosuspend (& pdev -> dev );
1029
1079
xqspi -> irq = platform_get_irq (pdev , 0 );
1030
1080
if (xqspi -> irq <= 0 ) {
1031
1081
ret = - ENXIO ;
@@ -1063,6 +1113,8 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
1063
1113
return 0 ;
1064
1114
1065
1115
clk_dis_all :
1116
+ pm_runtime_set_suspended (& pdev -> dev );
1117
+ pm_runtime_disable (& pdev -> dev );
1066
1118
clk_disable_unprepare (xqspi -> refclk );
1067
1119
clk_dis_pclk :
1068
1120
clk_disable_unprepare (xqspi -> pclk );
@@ -1090,6 +1142,8 @@ static int zynqmp_qspi_remove(struct platform_device *pdev)
1090
1142
zynqmp_gqspi_write (xqspi , GQSPI_EN_OFST , 0x0 );
1091
1143
clk_disable_unprepare (xqspi -> refclk );
1092
1144
clk_disable_unprepare (xqspi -> pclk );
1145
+ pm_runtime_set_suspended (& pdev -> dev );
1146
+ pm_runtime_disable (& pdev -> dev );
1093
1147
1094
1148
spi_unregister_master (master );
1095
1149
0 commit comments