Skip to content

Commit 3aa98b5

Browse files
authored
Merge pull request #577 from FrameworkComputer/fwk.fix_check_ac_port_race_condition
fwk: fix check ac port race condition
2 parents dea005a + e1ef488 commit 3aa98b5

3 files changed

Lines changed: 46 additions & 44 deletions

File tree

board/hx30/cypress5525.c

Lines changed: 44 additions & 43 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,35 +233,33 @@ 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;
243+
244244
if (intr_status & CYP5525_DEV_INTR) {
245-
CPRINTS("data = %d", data);
246245
if (data == CYP5525_AC_AT_PORT) {
247246
rv = cypd_read_reg8(controller, CYP5525_RESPONSE_REG, &event);
248-
CPRINTS("event = %d", event);
249247
if (rv != EC_SUCCESS)
250248
CPRINTS("fail to read response");
251249
switch (event) {
252250
case CYPD_RESPONSE_AC_AT_P0:
253-
ac_port = (controller * 2) + 0;
251+
pd_port_states[(controller * 2) + 0].ac_port = 1;
254252
break;
255253
case CYPD_RESPONSE_AC_AT_P1:
256-
ac_port = (controller * 2) + 1;
254+
pd_port_states[(controller * 2) + 1].ac_port = 1;
257255
break;
258256
case CYPD_RESPONSE_NO_AC:
259257
case CYPD_RESPONSE_EC_MODE:
260-
ac_port = -1;
261258
break;
259+
default:
260+
CPRINTS("Check AC get unknown event 0x%04x", event);
262261
}
263-
CPRINTS("ac_port = %d", ac_port);
264-
} else
265-
CPRINTS("unknown event");
262+
}
266263
cypd_clear_int(controller, CYP5525_DEV_INTR);
267264
}
268265
usleep(50);
@@ -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
/**
@@ -1805,16 +1813,13 @@ int check_power_on_port(void)
18051813
static int prev_charge_port = -1;
18061814
int board_set_active_charge_port(int charge_port)
18071815
{
1808-
CPRINTS("start change port = %d, prev_charge_port = %d", charge_port, prev_charge_port);
1809-
18101816
/* if no battery, EC should not control C_CTRL */
18111817
if (board_batt_is_present() != BP_YES) {
18121818
/* check if CYPD ready */
18131819
if (charge_port == -1)
18141820
return EC_ERROR_TRY_AGAIN;
18151821

18161822
/* store current port and update power limit */
1817-
CPRINTS("No batt, no change");
18181823
prev_charge_port = charge_port;
18191824
hook_call_deferred(&update_power_limit_deferred_data, 100 * MSEC);
18201825
CPRINTS("Updating %s port %d", __func__, charge_port);
@@ -1824,7 +1829,7 @@ int board_set_active_charge_port(int charge_port)
18241829
/* port need change, stop all power and ready to switch. */
18251830
if (prev_charge_port != -1 && prev_charge_port != charge_port) {
18261831
update_soc_power_limit(false, true);
1827-
CPRINTS("all off");
1832+
CPRINTS("Disable all type-c port to change the charger port");
18281833
cypd_write_reg8(0, CYP5525_CUST_C_CTRL_CONTROL_REG, CYP5525_P0P1_TURN_OFF_C_CTRL);
18291834
cypd_write_reg8(1, CYP5525_CUST_C_CTRL_CONTROL_REG, CYP5525_P0P1_TURN_OFF_C_CTRL);
18301835
usleep(250*MSEC);
@@ -1836,15 +1841,11 @@ int board_set_active_charge_port(int charge_port)
18361841
if (charge_port >=0 ) {
18371842
int pd_controller = (charge_port & 0x02) >> 1;
18381843
int pd_port = charge_port & 0x01;
1839-
1840-
CPRINTS("force off ctrler = %d", (~pd_controller) & 0x01);
18411844
cypd_write_reg8((~pd_controller) & 0x01, CYP5525_CUST_C_CTRL_CONTROL_REG,
18421845
CYP5525_P0P1_TURN_OFF_C_CTRL);
1843-
CPRINTS("choose p %d, ctrler = %d, p = %d", charge_port, pd_controller, pd_port);
18441846
cypd_write_reg8(pd_controller, CYP5525_CUST_C_CTRL_CONTROL_REG,
18451847
pd_port ? CYP5525_P0_OFF_P1_CY : CYP5525_P0_CY_P1_OFF);
18461848
} else {
1847-
CPRINTS("else = %d, set all ports auto", charge_port);
18481849
cypd_write_reg8(0, CYP5525_CUST_C_CTRL_CONTROL_REG, CYP5525_P0P1_TURN_OFF_C_CTRL);
18491850
cypd_write_reg8(1, CYP5525_CUST_C_CTRL_CONTROL_REG, CYP5525_P0P1_TURN_OFF_C_CTRL);
18501851
}

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;

common/charge_manager.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ static void charge_manager_get_best_charge_port(int *new_port,
579579
/* If system initially power on w/o dc, CYPD will control C_CTRL */
580580
if ((charge_port == CHARGE_SUPPLIER_NONE) && (board_batt_is_present() != BP_YES)) {
581581
*new_port = check_power_on_port();
582-
CPRINTS("NO DC, choose AC by CYPD: %d", *new_port);
582+
CPRINTS("AC only power on port %d", *new_port);
583583
*new_supplier = CHARGE_SUPPLIER_PD;
584584
if (*new_port == -1)
585585
*new_supplier = CHARGE_SUPPLIER_NONE;

0 commit comments

Comments
 (0)