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)
@@ -394,6 +399,8 @@ struct nxp_fspi {
394399 struct mutex lock ;
395400 struct pm_qos_request pm_qos_req ;
396401 int selected ;
402+ #define FSPI_NEED_INIT (1 << 0)
403+ int flags ;
397404};
398405
399406static inline int needs_ip_only (struct nxp_fspi * f )
@@ -927,6 +934,13 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
927934
928935 mutex_lock (& f -> lock );
929936
937+ err = pm_runtime_get_sync (f -> dev );
938+ if (err < 0 ) {
939+ mutex_unlock (& f -> lock );
940+ dev_err (f -> dev , "Failed to enable clock %d\n" , __LINE__ );
941+ return err ;
942+ }
943+
930944 /* Wait for controller being ready. */
931945 err = fspi_readl_poll_tout (f , f -> iobase + FSPI_STS0 ,
932946 FSPI_STS0_ARB_IDLE , 1 , POLL_TOUT , true);
@@ -955,8 +969,10 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
955969 /* Invalidate the data in the AHB buffer. */
956970 nxp_fspi_invalid (f );
957971
958- mutex_unlock (& f -> lock );
972+ pm_runtime_mark_last_busy (f -> dev );
973+ pm_runtime_put_autosuspend (f -> dev );
959974
975+ mutex_unlock (& f -> lock );
960976 return err ;
961977}
962978
@@ -1216,9 +1232,14 @@ static int nxp_fspi_probe(struct platform_device *pdev)
12161232 if (irq < 0 )
12171233 return dev_err_probe (dev , irq , "Failed to get irq source" );
12181234
1219- ret = nxp_fspi_clk_prep_enable (f );
1220- if (ret )
1221- return dev_err_probe (dev , ret , "Can't enable the clock\n" );
1235+ pm_runtime_enable (dev );
1236+ pm_runtime_set_autosuspend_delay (dev , FSPI_RPM_TIMEOUT );
1237+ pm_runtime_use_autosuspend (dev );
1238+
1239+ /* enable clock */
1240+ ret = pm_runtime_get_sync (f -> dev );
1241+ if (ret < 0 )
1242+ return dev_err_probe (dev , ret , "Failed to enable clock" );
12221243
12231244 /* Clear potential interrupts */
12241245 reg = fspi_readl (f , f -> iobase + FSPI_INTR );
@@ -1227,12 +1248,14 @@ static int nxp_fspi_probe(struct platform_device *pdev)
12271248
12281249 nxp_fspi_default_setup (f );
12291250
1251+ ret = pm_runtime_put_sync (dev );
1252+ if (ret < 0 )
1253+ return dev_err_probe (dev , ret , "Failed to disable clock" );
1254+
12301255 ret = devm_request_irq (dev , irq ,
12311256 nxp_fspi_irq_handler , 0 , pdev -> name , f );
1232- if (ret ) {
1233- nxp_fspi_clk_disable_unprep (f );
1257+ if (ret )
12341258 return dev_err_probe (dev , ret , "Failed to request irq\n" );
1235- }
12361259
12371260 devm_mutex_init (dev , & f -> lock );
12381261
@@ -1249,29 +1272,70 @@ static void nxp_fspi_remove(struct platform_device *pdev)
12491272{
12501273 struct nxp_fspi * f = platform_get_drvdata (pdev );
12511274
1275+ /* enable clock first since there is reigster access */
1276+ pm_runtime_get_sync (f -> dev );
1277+
12521278 /* disable the hardware */
12531279 fspi_writel (f , FSPI_MCR0_MDIS , f -> iobase + FSPI_MCR0 );
12541280
1281+ pm_runtime_disable (f -> dev );
1282+ pm_runtime_put_noidle (f -> dev );
12551283 nxp_fspi_clk_disable_unprep (f );
12561284
12571285 if (f -> ahb_addr )
12581286 iounmap (f -> ahb_addr );
12591287}
12601288
1261- static int nxp_fspi_suspend (struct device * dev )
1289+ static int nxp_fspi_runtime_suspend (struct device * dev )
12621290{
1291+ struct nxp_fspi * f = dev_get_drvdata (dev );
1292+
1293+ nxp_fspi_clk_disable_unprep (f );
1294+
12631295 return 0 ;
12641296}
12651297
1266- static int nxp_fspi_resume (struct device * dev )
1298+ static int nxp_fspi_runtime_resume (struct device * dev )
12671299{
12681300 struct nxp_fspi * f = dev_get_drvdata (dev );
1301+ int ret ;
12691302
1270- nxp_fspi_default_setup (f );
1303+ ret = nxp_fspi_clk_prep_enable (f );
1304+ if (ret )
1305+ return ret ;
12711306
1272- return 0 ;
1307+ if (f -> flags & FSPI_NEED_INIT ) {
1308+ nxp_fspi_default_setup (f );
1309+ ret = pinctrl_pm_select_default_state (dev );
1310+ if (ret )
1311+ dev_err (dev , "select flexspi default pinctrl failed!\n" );
1312+ f -> flags &= ~FSPI_NEED_INIT ;
1313+ }
1314+
1315+ return ret ;
12731316}
12741317
1318+ static int nxp_fspi_suspend (struct device * dev )
1319+ {
1320+ struct nxp_fspi * f = dev_get_drvdata (dev );
1321+ int ret ;
1322+
1323+ ret = pinctrl_pm_select_sleep_state (dev );
1324+ if (ret ) {
1325+ dev_err (dev , "select flexspi sleep pinctrl failed!\n" );
1326+ return ret ;
1327+ }
1328+
1329+ f -> flags |= FSPI_NEED_INIT ;
1330+
1331+ return pm_runtime_force_suspend (dev );
1332+ }
1333+
1334+ static const struct dev_pm_ops nxp_fspi_pm_ops = {
1335+ RUNTIME_PM_OPS (nxp_fspi_runtime_suspend , nxp_fspi_runtime_resume , NULL )
1336+ SYSTEM_SLEEP_PM_OPS (nxp_fspi_suspend , pm_runtime_force_resume )
1337+ };
1338+
12751339static const struct of_device_id nxp_fspi_dt_ids [] = {
12761340 { .compatible = "nxp,lx2160a-fspi" , .data = (void * )& lx2160a_data , },
12771341 { .compatible = "nxp,imx8mm-fspi" , .data = (void * )& imx8mm_data , },
@@ -1291,17 +1355,12 @@ static const struct acpi_device_id nxp_fspi_acpi_ids[] = {
12911355MODULE_DEVICE_TABLE (acpi , nxp_fspi_acpi_ids );
12921356#endif
12931357
1294- static const struct dev_pm_ops nxp_fspi_pm_ops = {
1295- .suspend = nxp_fspi_suspend ,
1296- .resume = nxp_fspi_resume ,
1297- };
1298-
12991358static struct platform_driver nxp_fspi_driver = {
13001359 .driver = {
13011360 .name = "nxp-fspi" ,
13021361 .of_match_table = nxp_fspi_dt_ids ,
13031362 .acpi_match_table = ACPI_PTR (nxp_fspi_acpi_ids ),
1304- .pm = & nxp_fspi_pm_ops ,
1363+ .pm = pm_ptr ( & nxp_fspi_pm_ops ) ,
13051364 },
13061365 .probe = nxp_fspi_probe ,
13071366 .remove = nxp_fspi_remove ,
0 commit comments