@@ -63,23 +63,64 @@ struct shi_it8xxx2_cfg {
6363 const struct gpio_dt_spec cs ;
6464};
6565
66+ enum shi_ite_pm_policy_state_flag {
67+ SHI_ITE_PM_POLICY_FLAG ,
68+ SHI_ITE_PM_POLICY_FLAG_COUNT ,
69+ };
70+
6671struct shi_it8xxx2_data {
6772 /* Peripheral data */
6873 struct ec_host_cmd_rx_ctx * rx_ctx ;
6974 struct ec_host_cmd_tx_buf * tx ;
7075 struct gpio_callback cs_cb ;
76+ struct k_work_delayable cs_off_put ;
7177 /* Current state */
7278 enum shi_state_machine shi_state ;
7379 /* Buffers */
7480 uint8_t in_msg [SPI_RX_MAX_FIFO_SIZE ] __aligned (4 );
7581 uint8_t out_msg [SPI_TX_MAX_FIFO_SIZE ] __aligned (4 );
82+ ATOMIC_DEFINE (pm_policy_state_flag , SHI_ITE_PM_POLICY_FLAG_COUNT );
7683};
7784
7885struct ec_host_cmd_shi_ite_ctx {
7986 /* SHI device instance */
8087 const struct device * dev ;
8188};
8289
90+ static void shi_ite_pm_policy_state_lock_get (struct shi_it8xxx2_data * data ,
91+ enum shi_ite_pm_policy_state_flag flag )
92+ {
93+ if (atomic_test_and_set_bit (data -> pm_policy_state_flag , flag ) == 0 ) {
94+ pm_policy_state_lock_get (PM_STATE_STANDBY , PM_ALL_SUBSTATES );
95+ k_work_reschedule (& data -> cs_off_put , K_SECONDS (3 ));
96+ }
97+ }
98+
99+ static void shi_ite_pm_policy_state_lock_put (struct shi_it8xxx2_data * data ,
100+ enum shi_ite_pm_policy_state_flag flag )
101+ {
102+ if (atomic_test_and_clear_bit (data -> pm_policy_state_flag , flag ) == 1 ) {
103+ pm_policy_state_lock_put (PM_STATE_STANDBY , PM_ALL_SUBSTATES );
104+ k_work_cancel_delayable (& data -> cs_off_put );
105+ }
106+ }
107+
108+ /*
109+ * When AP is In S0 state, AP assert CS of SPI for a new command transaction.
110+ * Under the condition, SoC will not enter deep sleep until AP de-assert the CS.
111+ * But If AP is powered off (G3 state) CS will go low (assert CS).
112+ * This assertion will prevent SoC from entering deep sleep but the assertion
113+ * is not for starting a new command transaction.
114+ * This handler is used to resolve the situation.
115+ */
116+ static void cs_off_put_handler (struct k_work * item )
117+ {
118+ struct k_work_delayable * dwork = k_work_delayable_from_work (item );
119+ struct shi_it8xxx2_data * data = CONTAINER_OF (dwork , struct shi_it8xxx2_data , cs_off_put );
120+
121+ shi_ite_pm_policy_state_lock_put (data , SHI_ITE_PM_POLICY_FLAG );
122+ }
123+
83124static const uint8_t out_preamble [EC_SHI_PREAMBLE_LENGTH ] = {
84125 EC_SHI_PROCESSING ,
85126 EC_SHI_PROCESSING ,
@@ -293,7 +334,7 @@ static void shi_ite_int_handler(const struct device *dev)
293334 /* CS# is deasserted, so write clear all slave status */
294335 IT83XX_SPI_ISR = 0xff ;
295336 /* Allow the MCU to go into lower power mode */
296- pm_policy_state_lock_put ( PM_STATE_STANDBY , PM_ALL_SUBSTATES );
337+ shi_ite_pm_policy_state_lock_put ( data , SHI_ITE_PM_POLICY_FLAG );
297338 }
298339
299340 /*
@@ -319,7 +360,7 @@ void shi_ite_cs_callback(const struct device *port, struct gpio_callback *cb, gp
319360 }
320361
321362 /* Prevent the MCU from sleeping during the transmission */
322- pm_policy_state_lock_get ( PM_STATE_STANDBY , PM_ALL_SUBSTATES );
363+ shi_ite_pm_policy_state_lock_get ( data , SHI_ITE_PM_POLICY_FLAG );
323364
324365 /* Move to processing state */
325366 shi_ite_set_state (data , SHI_STATE_PROCESSING );
@@ -436,6 +477,8 @@ static int shi_ite_init(const struct device *dev)
436477 return - EINVAL ;
437478 }
438479
480+ k_work_init_delayable (& data -> cs_off_put , cs_off_put_handler );
481+
439482 pm_device_init_suspended (dev );
440483 return pm_device_runtime_enable (dev );
441484}
0 commit comments