diff options
author | Ko_Ko <Ko_Ko@compal.corp-partner.google.com> | 2020-11-24 19:09:30 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-12-01 04:10:29 +0000 |
commit | 6e61e71e8770f3f92848d02f9075a974b4146ffd (patch) | |
tree | f8cc5cb38247297cd063f2d92320c2547ea48c1a /board/madoo/board.c | |
parent | d8ba7887892ac541f5beccaa2f50e35b1176462b (diff) | |
download | chrome-ec-6e61e71e8770f3f92848d02f9075a974b4146ffd.tar.gz |
Madoo: Improve shared interrupt line behavior
When interrupts are interleaved from the TCPC and charger, we can get
into a state where the interrupt line for the board ends up stuck low.
Improve on this situation by setting a deferred function to check on the
interrupt line after we get a signal in, and notify chips on that line
there may be more to process.
BRANCH=None
BUG=b:173345295
TEST=on madoo, plug in powered PD hub to C1, generating interrupts
from both the charger and TCPC and verify C1 interrupt line goes high
once connection is ready
Signed-off-by: Ko_Ko <Ko_Ko@compal.corp-partner.google.com>
Change-Id: I3d29df28f94cb6c352adf05b9204ab4ff52a9726
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2557758
Reviewed-by: Henry Sun <henrysun@google.com>
Reviewed-by: Diana Z <dzigterman@chromium.org>
Commit-Queue: Ko Ko <ko_ko@compal.corp-partner.google.com>
Tested-by: Ko Ko <ko_ko@compal.corp-partner.google.com>
Diffstat (limited to 'board/madoo/board.c')
-rw-r--r-- | board/madoo/board.c | 80 |
1 files changed, 69 insertions, 11 deletions
diff --git a/board/madoo/board.c b/board/madoo/board.c index 390b6bf5c6..520cdea17d 100644 --- a/board/madoo/board.c +++ b/board/madoo/board.c @@ -49,33 +49,82 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) -static void tcpc_alert_event(enum gpio_signal s) -{ - int port = (s == GPIO_USB_C0_INT_ODL) ? 0 : 1; +#define INT_RECHECK_US 5000 - schedule_deferred_pd_interrupt(port); -} +/* C0 interrupt line shared by BC 1.2 and charger */ +static void check_c0_line(void); +DECLARE_DEFERRED(check_c0_line); -static void usb_c0_interrupt(enum gpio_signal s) +static void notify_c0_chips(void) { /* * The interrupt line is shared between the TCPC and BC 1.2 detection * chip. Therefore we'll need to check both ICs. */ - tcpc_alert_event(s); + schedule_deferred_pd_interrupt(0); task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12, 0); } -static void sub_usb_c1_interrupt(enum gpio_signal s) +static void check_c0_line(void) { /* - * The interrupt line is shared between the TCPC and BC 1.2 detection - * chip. Therefore we'll need to check both ICs. + * If line is still being held low, see if there's more to process from + * one of the chips */ - tcpc_alert_event(s); + if (!gpio_get_level(GPIO_USB_C0_INT_ODL)) { + notify_c0_chips(); + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); + } +} + +static void usb_c0_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c0_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c0_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); + +} + +/* C1 interrupt line shared by BC 1.2, TCPC, and charger */ +static void check_c1_line(void); +DECLARE_DEFERRED(check_c1_line); + +static void notify_c1_chips(void) +{ + schedule_deferred_pd_interrupt(1); task_set_event(TASK_ID_USB_CHG_P1, USB_CHG_EVENT_BC12, 0); } +static void check_c1_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips. + */ + if (!gpio_get_level(GPIO_USB_C1_INT_ODL)) { + notify_c1_chips(); + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); + } +} + +static void sub_usb_c1_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c1_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c1_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); + +} + static void c0_ccsbu_ovp_interrupt(enum gpio_signal s) { cprints(CC_USBPD, "C0: CC OVP, SBU OVP, or thermal event"); @@ -128,6 +177,15 @@ void board_init(void) /* Enable gpio interrupt for base accelgyro sensor */ gpio_enable_interrupt(GPIO_BASE_SIXAXIS_INT_L); + /* + * If interrupt lines are already low, schedule them to be processed + * after inits are completed. + */ + if (!gpio_get_level(GPIO_USB_C0_INT_ODL)) + hook_call_deferred(&check_c0_line_data, 0); + if (!gpio_get_level(GPIO_USB_C1_INT_ODL)) + hook_call_deferred(&check_c1_line_data, 0); + /* Turn on 5V if the system is on, otherwise turn it off. */ on = chipset_in_state(CHIPSET_STATE_ON | CHIPSET_STATE_ANY_SUSPEND | CHIPSET_STATE_SOFT_OFF); |