Skip to content

Commit eb72c98

Browse files
committed
fwk: fix check ac port race condition
We used the cypd_write_reg8_wait_ack() to check the ac port. Needs to disable the interrupt and increase the wait time to avoid the interrupt handler clearing the event Signed-off-by: Josh-Tsai <josh_tsai@compal.com>
1 parent dea005a commit eb72c98

2 files changed

Lines changed: 42 additions & 33 deletions

File tree

board/hx30/cypress5525.c

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ static int pd_port0_1_5A;
9595
static int pd_port1_1_5A;
9696
static int pd_port2_1_5A;
9797
static int pd_port3_1_5A;
98-
static int ac_port = -1;
9998

10099
void set_pd_fw_update(bool update)
101100
{
@@ -225,7 +224,7 @@ int cyp5225_wait_for_ack(int controller, int timeout_us)
225224
}
226225

227226

228-
int cypd_write_reg8_wait_ack(int controller, int reg, int data)
227+
int cypd_write_reg8_wait_ack(int controller, int reg, int data, int delay_ms)
229228
{
230229
int rv = EC_SUCCESS;
231230
int intr_status;
@@ -234,33 +233,31 @@ int cypd_write_reg8_wait_ack(int controller, int reg, int data)
234233
if (rv != EC_SUCCESS)
235234
CPRINTS("Write Reg8 0x%x fail!", reg);
236235

237-
if (cyp5225_wait_for_ack(controller, 100*MSEC) != EC_SUCCESS) {
236+
if (cyp5225_wait_for_ack(controller, delay_ms * MSEC) != EC_SUCCESS) {
238237
CPRINTS("%s timeout on interrupt", __func__);
239238
return EC_ERROR_INVAL;
240239
}
241240
rv = cypd_get_int(controller, &intr_status);
242241
if (rv != EC_SUCCESS)
243242
return rv;
244243
if (intr_status & CYP5525_DEV_INTR) {
245-
CPRINTS("data = %d", data);
244+
CPRINTS("data = 0x%04x", data);
246245
if (data == CYP5525_AC_AT_PORT) {
247246
rv = cypd_read_reg8(controller, CYP5525_RESPONSE_REG, &event);
248-
CPRINTS("event = %d", event);
247+
CPRINTS("event = 0x%04x", event);
249248
if (rv != EC_SUCCESS)
250249
CPRINTS("fail to read response");
251250
switch (event) {
252251
case CYPD_RESPONSE_AC_AT_P0:
253-
ac_port = (controller * 2) + 0;
252+
pd_port_states[(controller * 2) + 0].ac_port = 1;
254253
break;
255254
case CYPD_RESPONSE_AC_AT_P1:
256-
ac_port = (controller * 2) + 1;
255+
pd_port_states[(controller * 2) + 1].ac_port = 1;
257256
break;
258257
case CYPD_RESPONSE_NO_AC:
259258
case CYPD_RESPONSE_EC_MODE:
260-
ac_port = -1;
261259
break;
262260
}
263-
CPRINTS("ac_port = %d", ac_port);
264261
} else
265262
CPRINTS("unknown event");
266263
cypd_clear_int(controller, CYP5525_DEV_INTR);
@@ -296,11 +293,11 @@ int cypd_set_power_state(int power_state, int controller)
296293
CPRINTS("C%d, %s pwr state %d", controller, __func__, power_state);
297294

298295
if (controller < 2)
299-
rv = cypd_write_reg8_wait_ack(controller, CYP5525_SYS_PWR_STATE, power_state);
296+
rv = cypd_write_reg8_wait_ack(controller, CYP5525_SYS_PWR_STATE, power_state, 100);
300297
else {
301298
for (i = 0; i < PD_CHIP_COUNT; i++) {
302299

303-
rv = cypd_write_reg8_wait_ack(i, CYP5525_SYS_PWR_STATE, power_state);
300+
rv = cypd_write_reg8_wait_ack(i, CYP5525_SYS_PWR_STATE, power_state, 100);
304301
if (rv != EC_SUCCESS)
305302
break;
306303
}
@@ -314,6 +311,13 @@ void cypd_charger_init_complete(void)
314311
charger_init_ok = 1;
315312
}
316313

314+
void cypd_update_ac_status(int controller)
315+
{
316+
CPRINTS("Check C%d AC status!", controller);
317+
if (cypd_write_reg8_wait_ack(controller,
318+
CYP5525_CUST_C_CTRL_CONTROL_REG, CYP5525_AC_AT_PORT, 200))
319+
CPRINTS("CYPD Read AC status fail");
320+
}
317321

318322
int cypd_update_power_status(int controller)
319323
{
@@ -329,10 +333,10 @@ int cypd_update_power_status(int controller)
329333

330334
CPRINTS("C%d, %s power_stat 0x%x", controller, __func__, power_stat);
331335
if (controller < 2) {
332-
rv = cypd_write_reg8_wait_ack(controller, CYP5525_POWER_STAT, power_stat);
336+
rv = cypd_write_reg8_wait_ack(controller, CYP5525_POWER_STAT, power_stat, 100);
333337
} else {
334338
for (i = 0; i < PD_CHIP_COUNT; i++) {
335-
rv = cypd_write_reg8_wait_ack(i, CYP5525_POWER_STAT, power_stat);
339+
rv = cypd_write_reg8_wait_ack(i, CYP5525_POWER_STAT, power_stat, 100);
336340
if (rv != EC_SUCCESS)
337341
break;
338342
}
@@ -452,7 +456,7 @@ void cypd_set_error_recovery(void)
452456
* GRL FV 3.1.2.3.
453457
* 0xC0 means no recovery.
454458
*/
455-
cypd_write_reg8_wait_ack(i, CYP5525_SYS_PWR_STATE, 0xC0);
459+
cypd_write_reg8_wait_ack(i, CYP5525_SYS_PWR_STATE, 0xC0, 100);
456460
}
457461
}
458462

@@ -1120,20 +1124,25 @@ void cypd_handle_state(int controller)
11201124
case CYP5525_STATE_APP_SETUP:
11211125
gpio_disable_interrupt(pd_chip_config[controller].gpio);
11221126
cyp5525_get_version(controller);
1123-
cypd_write_reg8_wait_ack(controller, CYP5225_USER_MAINBOARD_VERSION, board_get_version());
1127+
cypd_write_reg8_wait_ack(controller, CYP5225_USER_MAINBOARD_VERSION,
1128+
board_get_version(), 100);
11241129
/* We should update the power status and system power state by pd chip at initial*/
11251130
cypd_update_power_status(controller);
11261131

11271132
cypd_set_power_state(CYP5525_POWERSTATE_S5, controller);
11281133

11291134

11301135
cyp5525_setup(controller);
1136+
1137+
/* After cypd setup complete, check the AC status */
1138+
cypd_update_ac_status(controller);
1139+
11311140
cypd_update_port_state(controller, 0);
11321141
cypd_update_port_state(controller, 1);
11331142

11341143
cyp5525_ucsi_startup(controller);
1135-
gpio_enable_interrupt(pd_chip_config[controller].gpio);
11361144
update_system_power_state(controller);
1145+
gpio_enable_interrupt(pd_chip_config[controller].gpio);
11371146

11381147
CPRINTS("CYPD %d Ready!", controller);
11391148
pd_chip_config[controller].state = CYP5525_STATE_READY;
@@ -1555,8 +1564,10 @@ void cypd_release_port(int controller, int port)
15551564
int port_idx = (controller << 1) + port;
15561565

15571566
/* if port disconnect should set RP and PDO to default */
1558-
cypd_write_reg8_wait_ack(controller, CYP5525_PD_CONTROL_REG(port), CYPD_PD_CMD_SET_TYPEC_1_5A);
1559-
cypd_write_reg8_wait_ack(controller, CYP5525_SELECT_SOURCE_PDO_REG(port), CYPD_PD_CMD_SET_TYPEC_3A);
1567+
cypd_write_reg8_wait_ack(controller, CYP5525_PD_CONTROL_REG(port),
1568+
CYPD_PD_CMD_SET_TYPEC_1_5A, 100);
1569+
cypd_write_reg8_wait_ack(controller, CYP5525_SELECT_SOURCE_PDO_REG(port),
1570+
CYPD_PD_CMD_SET_TYPEC_3A, 100);
15601571

15611572
if (cypd_port_3a_status(controller, port)) {
15621573
pd_3a_set = 0;
@@ -1775,23 +1786,20 @@ DECLARE_DEFERRED(update_power_limit_deferred);
17751786

17761787
int check_power_on_port(void)
17771788
{
1778-
int rv;
1779-
1789+
int port;
17801790
/* only read CYPD when it ready */
1781-
if (pd_chip_config[0].state != CYP5525_STATE_READY)
1782-
return -1;
1791+
if (!(pd_chip_config[0].state == CYP5525_STATE_READY &&
1792+
pd_chip_config[1].state == CYP5525_STATE_READY)) {
1793+
CPRINTS("CYPD not ready, just delay 100ms to wait");
1794+
usleep(100 * MSEC);
1795+
}
17831796

1784-
CPRINTS("READ C0");
1785-
rv = cypd_write_reg8_wait_ack(0, CYP5525_CUST_C_CTRL_CONTROL_REG, CYP5525_AC_AT_PORT);
1786-
if (rv != EC_SUCCESS)
1787-
return -1;
1788-
if (ac_port >= 0)
1789-
return ac_port;
1790-
CPRINTS("READ C1");
1791-
rv = cypd_write_reg8_wait_ack(1, CYP5525_CUST_C_CTRL_CONTROL_REG, CYP5525_AC_AT_PORT);
1792-
if (rv != EC_SUCCESS)
1793-
return -1;
1794-
return ac_port;
1797+
for (port = 0; port < PD_PORT_COUNT; port++)
1798+
if (pd_port_states[port].ac_port == 1)
1799+
return port;
1800+
1801+
/* if no ac port is checked return -1 */
1802+
return -1;
17951803
}
17961804

17971805
/**

board/hx30/cypress5525.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ struct pd_port_current_state_t {
359359
enum cyp5525_port_state port_state;
360360
int voltage;
361361
int current;
362+
int ac_port;
362363
enum cypd_c_state c_state; /* What device is attached on the other side */
363364
uint8_t pd_state;
364365
uint8_t cc;

0 commit comments

Comments
 (0)