diff options
author | Edward Hill <ecgh@chromium.org> | 2020-07-22 20:29:57 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-07-24 02:02:08 +0000 |
commit | 3a31737877176ac8fb0effb2a9cf8c8a78d61cb1 (patch) | |
tree | a6571a63bc0ce92ae06f794a06f33e4995462e4f /driver/usb_mux/amd_fp5.c | |
parent | 73745ba8e0ea7725fc40a60356b40f146ff9673b (diff) | |
download | chrome-ec-3a31737877176ac8fb0effb2a9cf8c8a78d61cb1.tar.gz |
zork: Restore AP mux setting after reboot
BUG=b:158960403
BRANCH=none
TEST=USB3 works after AP reboot
Signed-off-by: Edward Hill <ecgh@chromium.org>
Change-Id: Ia6ec65ad38933106e183747e78827d564be5aefd
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2314033
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'driver/usb_mux/amd_fp5.c')
-rw-r--r-- | driver/usb_mux/amd_fp5.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/driver/usb_mux/amd_fp5.c b/driver/usb_mux/amd_fp5.c index ecba47851f..92c7e682a4 100644 --- a/driver/usb_mux/amd_fp5.c +++ b/driver/usb_mux/amd_fp5.c @@ -8,9 +8,14 @@ #include "amd_fp5.h" #include "chipset.h" #include "common.h" +#include "hooks.h" #include "i2c.h" +#include "queue.h" +#include "timer.h" #include "usb_mux.h" +static mux_state_t saved_mux_state[CONFIG_USB_PD_PORT_MAX_COUNT]; + static inline int amd_fp5_mux_read(const struct usb_mux *me, uint8_t *val) { uint8_t buf[3] = { 0 }; @@ -41,6 +46,8 @@ static int amd_fp5_set_mux(const struct usb_mux *me, mux_state_t mux_state) { uint8_t val = 0; + saved_mux_state[me->usb_port] = mux_state; + /* * This MUX is on the FP5 SoC. If that device is not powered then * we either have to complain that it is not powered or if we were @@ -114,8 +121,36 @@ static int amd_fp5_get_mux(const struct usb_mux *me, mux_state_t *mux_state) return EC_SUCCESS; } +static struct queue const chipset_reset_queue + = QUEUE_NULL(CONFIG_USB_PD_PORT_MAX_COUNT, struct usb_mux *); + +static void amd_fp5_chipset_reset_delay(void) +{ + struct usb_mux *me; + int rv; + + while (queue_remove_unit(&chipset_reset_queue, &me)) { + rv = amd_fp5_set_mux(me, saved_mux_state[me->usb_port]); + if (rv) + ccprints("C%d restore mux rv:%d", me->usb_port, rv); + } +} +DECLARE_DEFERRED(amd_fp5_chipset_reset_delay); + +/* + * The AP's internal USB-C mux is reset when AP resets, so wait for + * it to be ready and then restore the previous setting. + */ +static int amd_fp5_chipset_reset(const struct usb_mux *me) +{ + queue_add_unit(&chipset_reset_queue, &me); + hook_call_deferred(&amd_fp5_chipset_reset_delay_data, 200 * MSEC); + return EC_SUCCESS; +} + const struct usb_mux_driver amd_fp5_usb_mux_driver = { .init = &amd_fp5_init, .set = &amd_fp5_set_mux, .get = &amd_fp5_get_mux, + .chipset_reset = &amd_fp5_chipset_reset, }; |