@@ -25,6 +25,9 @@ LOG_MODULE_REGISTER(mcux_flexcomm);
2525
2626#include "i2c-priv.h"
2727
28+ #include <zephyr/pm/device.h>
29+ #include <zephyr/pm/policy.h>
30+
2831#define I2C_TRANSFER_TIMEOUT_MSEC \
2932 COND_CODE_0(CONFIG_I2C_NXP_TRANSFER_TIMEOUT, (K_FOREVER), \
3033 (K_MSEC(CONFIG_I2C_NXP_TRANSFER_TIMEOUT)))
@@ -154,6 +157,10 @@ static int mcux_flexcomm_transfer(const struct device *dev,
154157
155158 k_sem_take (& data -> lock , K_FOREVER );
156159
160+ #ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
161+ pm_policy_device_power_lock_get (dev );
162+ #endif
163+
157164 /* Iterate over all the messages */
158165 for (int i = 0 ; i < num_msgs ; i ++ ) {
159166 if (I2C_MSG_ADDR_10_BITS & msgs -> flags ) {
@@ -208,6 +215,10 @@ static int mcux_flexcomm_transfer(const struct device *dev,
208215 msgs ++ ;
209216 }
210217
218+ #ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
219+ pm_policy_device_power_lock_put (dev );
220+ #endif
221+
211222 k_sem_give (& data -> lock );
212223
213224 return ret ;
@@ -555,7 +566,7 @@ static void mcux_flexcomm_isr(const struct device *dev)
555566 I2C_MasterTransferHandleIRQ (base , & data -> handle );
556567}
557568
558- static int mcux_flexcomm_init (const struct device * dev )
569+ static int mcux_flexcomm_init_common (const struct device * dev )
559570{
560571 const struct mcux_flexcomm_config * config = dev -> config ;
561572 struct mcux_flexcomm_data * data = dev -> data ;
@@ -579,9 +590,6 @@ static int mcux_flexcomm_init(const struct device *dev)
579590 return error ;
580591 }
581592
582- k_sem_init (& data -> lock , 1 , 1 );
583- k_sem_init (& data -> device_sync_sem , 0 , K_SEM_MAX_LIMIT );
584-
585593 if (!device_is_ready (config -> clock_dev )) {
586594 LOG_ERR ("clock control device not ready" );
587595 return - ENODEV ;
@@ -611,6 +619,37 @@ static int mcux_flexcomm_init(const struct device *dev)
611619 return 0 ;
612620}
613621
622+ static int i2c_mcux_flexcomm_pm_action (const struct device * dev , enum pm_device_action action )
623+ {
624+ switch (action ) {
625+ case PM_DEVICE_ACTION_RESUME :
626+ break ;
627+ case PM_DEVICE_ACTION_SUSPEND :
628+ break ;
629+ case PM_DEVICE_ACTION_TURN_OFF :
630+ return 0 ;
631+ case PM_DEVICE_ACTION_TURN_ON :
632+ mcux_flexcomm_init_common (dev );
633+ return 0 ;
634+ default :
635+ return - ENOTSUP ;
636+ }
637+ return 0 ;
638+ }
639+
640+ static int mcux_flexcomm_init (const struct device * dev )
641+ {
642+ struct mcux_flexcomm_data * data = dev -> data ;
643+
644+ k_sem_init (& data -> lock , 1 , 1 );
645+ k_sem_init (& data -> device_sync_sem , 0 , K_SEM_MAX_LIMIT );
646+
647+ /* Rest of the init is done from the PM_DEVICE_TURN_ON action
648+ * which is invoked by pm_device_driver_init().
649+ */
650+ return pm_device_driver_init (dev , i2c_mcux_flexcomm_pm_action );
651+ }
652+
614653static DEVICE_API (i2c , mcux_flexcomm_driver_api ) = {
615654 .configure = mcux_flexcomm_configure ,
616655 .transfer = mcux_flexcomm_transfer ,
@@ -650,9 +689,10 @@ static DEVICE_API(i2c, mcux_flexcomm_driver_api) = {
650689 .reset = RESET_DT_SPEC_INST_GET(id), \
651690 }; \
652691 static struct mcux_flexcomm_data mcux_flexcomm_data_##id; \
692+ PM_DEVICE_DT_INST_DEFINE(id, i2c_mcux_flexcomm_pm_action); \
653693 I2C_DEVICE_DT_INST_DEFINE(id, \
654694 mcux_flexcomm_init, \
655- NULL, \
695+ PM_DEVICE_DT_INST_GET(id), \
656696 &mcux_flexcomm_data_##id, \
657697 &mcux_flexcomm_config_##id, \
658698 POST_KERNEL, \
0 commit comments