@@ -25,6 +25,9 @@ LOG_MODULE_REGISTER(mcux_flexcomm);
25
25
26
26
#include "i2c-priv.h"
27
27
28
+ #include <zephyr/pm/device.h>
29
+ #include <zephyr/pm/policy.h>
30
+
28
31
#define I2C_TRANSFER_TIMEOUT_MSEC \
29
32
COND_CODE_0(CONFIG_I2C_NXP_TRANSFER_TIMEOUT, (K_FOREVER), \
30
33
(K_MSEC(CONFIG_I2C_NXP_TRANSFER_TIMEOUT)))
@@ -154,6 +157,10 @@ static int mcux_flexcomm_transfer(const struct device *dev,
154
157
155
158
k_sem_take (& data -> lock , K_FOREVER );
156
159
160
+ #ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
161
+ pm_policy_device_power_lock_get (dev );
162
+ #endif
163
+
157
164
/* Iterate over all the messages */
158
165
for (int i = 0 ; i < num_msgs ; i ++ ) {
159
166
if (I2C_MSG_ADDR_10_BITS & msgs -> flags ) {
@@ -208,6 +215,10 @@ static int mcux_flexcomm_transfer(const struct device *dev,
208
215
msgs ++ ;
209
216
}
210
217
218
+ #ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
219
+ pm_policy_device_power_lock_put (dev );
220
+ #endif
221
+
211
222
k_sem_give (& data -> lock );
212
223
213
224
return ret ;
@@ -555,7 +566,7 @@ static void mcux_flexcomm_isr(const struct device *dev)
555
566
I2C_MasterTransferHandleIRQ (base , & data -> handle );
556
567
}
557
568
558
- static int mcux_flexcomm_init (const struct device * dev )
569
+ static int mcux_flexcomm_init_common (const struct device * dev )
559
570
{
560
571
const struct mcux_flexcomm_config * config = dev -> config ;
561
572
struct mcux_flexcomm_data * data = dev -> data ;
@@ -579,9 +590,6 @@ static int mcux_flexcomm_init(const struct device *dev)
579
590
return error ;
580
591
}
581
592
582
- k_sem_init (& data -> lock , 1 , 1 );
583
- k_sem_init (& data -> device_sync_sem , 0 , K_SEM_MAX_LIMIT );
584
-
585
593
if (!device_is_ready (config -> clock_dev )) {
586
594
LOG_ERR ("clock control device not ready" );
587
595
return - ENODEV ;
@@ -611,6 +619,37 @@ static int mcux_flexcomm_init(const struct device *dev)
611
619
return 0 ;
612
620
}
613
621
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
+
614
653
static DEVICE_API (i2c , mcux_flexcomm_driver_api ) = {
615
654
.configure = mcux_flexcomm_configure ,
616
655
.transfer = mcux_flexcomm_transfer ,
@@ -650,9 +689,10 @@ static DEVICE_API(i2c, mcux_flexcomm_driver_api) = {
650
689
.reset = RESET_DT_SPEC_INST_GET(id), \
651
690
}; \
652
691
static struct mcux_flexcomm_data mcux_flexcomm_data_##id; \
692
+ PM_DEVICE_DT_INST_DEFINE(id, i2c_mcux_flexcomm_pm_action); \
653
693
I2C_DEVICE_DT_INST_DEFINE(id, \
654
694
mcux_flexcomm_init, \
655
- NULL, \
695
+ PM_DEVICE_DT_INST_GET(id), \
656
696
&mcux_flexcomm_data_##id, \
657
697
&mcux_flexcomm_config_##id, \
658
698
POST_KERNEL, \
0 commit comments