4848#include <linux/mutex.h>
4949#include <linux/of.h>
5050#include <linux/platform_device.h>
51+ #include <linux/pinctrl/consumer.h>
52+ #include <linux/pm_runtime.h>
5153#include <linux/pm_qos.h>
5254#include <linux/regmap.h>
5355#include <linux/sizes.h>
5759#include <linux/spi/spi.h>
5860#include <linux/spi/spi-mem.h>
5961
62+ /* runtime pm timeout */
63+ #define FSPI_RPM_TIMEOUT 50 /* 50ms */
64+
6065/* Registers used by the driver */
6166#define FSPI_MCR0 0x00
6267#define FSPI_MCR0_AHB_TIMEOUT (x ) ((x) << 24)
@@ -396,6 +401,8 @@ struct nxp_fspi {
396401 struct mutex lock ;
397402 struct pm_qos_request pm_qos_req ;
398403 int selected ;
404+ #define FSPI_NEED_INIT (1 << 0)
405+ int flags ;
399406};
400407
401408static inline int needs_ip_only (struct nxp_fspi * f )
@@ -935,6 +942,13 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
935942
936943 mutex_lock (& f -> lock );
937944
945+ err = pm_runtime_get_sync (f -> dev );
946+ if (err < 0 ) {
947+ mutex_unlock (& f -> lock );
948+ dev_err (f -> dev , "Failed to enable clock %d\n" , __LINE__ );
949+ return err ;
950+ }
951+
938952 /* Wait for controller being ready. */
939953 err = fspi_readl_poll_tout (f , f -> iobase + FSPI_STS0 ,
940954 FSPI_STS0_ARB_IDLE , 1 , POLL_TOUT , true);
@@ -963,8 +977,10 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
963977 /* Invalidate the data in the AHB buffer. */
964978 nxp_fspi_invalid (f );
965979
966- mutex_unlock (& f -> lock );
980+ pm_runtime_mark_last_busy (f -> dev );
981+ pm_runtime_put_autosuspend (f -> dev );
967982
983+ mutex_unlock (& f -> lock );
968984 return err ;
969985}
970986
@@ -1231,9 +1247,14 @@ static int nxp_fspi_probe(struct platform_device *pdev)
12311247 if (irq < 0 )
12321248 return dev_err_probe (dev , irq , "Failed to get irq source" );
12331249
1234- ret = nxp_fspi_clk_prep_enable (f );
1235- if (ret )
1236- return dev_err_probe (dev , ret , "Can't enable the clock\n" );
1250+ pm_runtime_enable (dev );
1251+ pm_runtime_set_autosuspend_delay (dev , FSPI_RPM_TIMEOUT );
1252+ pm_runtime_use_autosuspend (dev );
1253+
1254+ /* enable clock */
1255+ ret = pm_runtime_get_sync (f -> dev );
1256+ if (ret < 0 )
1257+ return dev_err_probe (dev , ret , "Failed to enable clock" );
12371258
12381259 /* Clear potential interrupts */
12391260 reg = fspi_readl (f , f -> iobase + FSPI_INTR );
@@ -1242,12 +1263,14 @@ static int nxp_fspi_probe(struct platform_device *pdev)
12421263
12431264 nxp_fspi_default_setup (f );
12441265
1266+ ret = pm_runtime_put_sync (dev );
1267+ if (ret < 0 )
1268+ return dev_err_probe (dev , ret , "Failed to disable clock" );
1269+
12451270 ret = devm_request_irq (dev , irq ,
12461271 nxp_fspi_irq_handler , 0 , pdev -> name , f );
1247- if (ret ) {
1248- nxp_fspi_clk_disable_unprep (f );
1272+ if (ret )
12491273 return dev_err_probe (dev , ret , "Failed to request irq\n" );
1250- }
12511274
12521275 ret = devm_mutex_init (dev , & f -> lock );
12531276 if (ret )
@@ -1271,29 +1294,70 @@ static void nxp_fspi_remove(struct platform_device *pdev)
12711294{
12721295 struct nxp_fspi * f = platform_get_drvdata (pdev );
12731296
1297+ /* enable clock first since there is reigster access */
1298+ pm_runtime_get_sync (f -> dev );
1299+
12741300 /* disable the hardware */
12751301 fspi_writel (f , FSPI_MCR0_MDIS , f -> iobase + FSPI_MCR0 );
12761302
1303+ pm_runtime_disable (f -> dev );
1304+ pm_runtime_put_noidle (f -> dev );
12771305 nxp_fspi_clk_disable_unprep (f );
12781306
12791307 if (f -> ahb_addr )
12801308 iounmap (f -> ahb_addr );
12811309}
12821310
1283- static int nxp_fspi_suspend (struct device * dev )
1311+ static int nxp_fspi_runtime_suspend (struct device * dev )
12841312{
1313+ struct nxp_fspi * f = dev_get_drvdata (dev );
1314+
1315+ nxp_fspi_clk_disable_unprep (f );
1316+
12851317 return 0 ;
12861318}
12871319
1288- static int nxp_fspi_resume (struct device * dev )
1320+ static int nxp_fspi_runtime_resume (struct device * dev )
12891321{
12901322 struct nxp_fspi * f = dev_get_drvdata (dev );
1323+ int ret ;
12911324
1292- nxp_fspi_default_setup (f );
1325+ ret = nxp_fspi_clk_prep_enable (f );
1326+ if (ret )
1327+ return ret ;
12931328
1294- return 0 ;
1329+ if (f -> flags & FSPI_NEED_INIT ) {
1330+ nxp_fspi_default_setup (f );
1331+ ret = pinctrl_pm_select_default_state (dev );
1332+ if (ret )
1333+ dev_err (dev , "select flexspi default pinctrl failed!\n" );
1334+ f -> flags &= ~FSPI_NEED_INIT ;
1335+ }
1336+
1337+ return ret ;
12951338}
12961339
1340+ static int nxp_fspi_suspend (struct device * dev )
1341+ {
1342+ struct nxp_fspi * f = dev_get_drvdata (dev );
1343+ int ret ;
1344+
1345+ ret = pinctrl_pm_select_sleep_state (dev );
1346+ if (ret ) {
1347+ dev_err (dev , "select flexspi sleep pinctrl failed!\n" );
1348+ return ret ;
1349+ }
1350+
1351+ f -> flags |= FSPI_NEED_INIT ;
1352+
1353+ return pm_runtime_force_suspend (dev );
1354+ }
1355+
1356+ static const struct dev_pm_ops nxp_fspi_pm_ops = {
1357+ RUNTIME_PM_OPS (nxp_fspi_runtime_suspend , nxp_fspi_runtime_resume , NULL )
1358+ SYSTEM_SLEEP_PM_OPS (nxp_fspi_suspend , pm_runtime_force_resume )
1359+ };
1360+
12971361static const struct of_device_id nxp_fspi_dt_ids [] = {
12981362 { .compatible = "nxp,lx2160a-fspi" , .data = (void * )& lx2160a_data , },
12991363 { .compatible = "nxp,imx8mm-fspi" , .data = (void * )& imx8mm_data , },
@@ -1313,17 +1377,12 @@ static const struct acpi_device_id nxp_fspi_acpi_ids[] = {
13131377MODULE_DEVICE_TABLE (acpi , nxp_fspi_acpi_ids );
13141378#endif
13151379
1316- static const struct dev_pm_ops nxp_fspi_pm_ops = {
1317- .suspend = nxp_fspi_suspend ,
1318- .resume = nxp_fspi_resume ,
1319- };
1320-
13211380static struct platform_driver nxp_fspi_driver = {
13221381 .driver = {
13231382 .name = "nxp-fspi" ,
13241383 .of_match_table = nxp_fspi_dt_ids ,
13251384 .acpi_match_table = ACPI_PTR (nxp_fspi_acpi_ids ),
1326- .pm = & nxp_fspi_pm_ops ,
1385+ .pm = pm_ptr ( & nxp_fspi_pm_ops ) ,
13271386 },
13281387 .probe = nxp_fspi_probe ,
13291388 .remove_new = nxp_fspi_remove ,
0 commit comments