diff options
author | Diana Z <dzigterman@chromium.org> | 2020-05-11 17:05:19 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-05-15 23:02:01 +0000 |
commit | a8638087604a975980cb0379558f4f80b8d33eea (patch) | |
tree | e82931d1dc68f1f7c120fd41ba99600722776404 | |
parent | 58cf4513afaedd96561fc4a2b62e324a9f4e3707 (diff) | |
download | chrome-ec-a8638087604a975980cb0379558f4f80b8d33eea.tar.gz |
Waddledee: 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:143166332
TEST=on waddledee, 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: Diana Z <dzigterman@chromium.org>
Change-Id: I4eda56d656a309f7aa762bba6476bb3c981e4bc7
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2197949
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r-- | board/waddledee/board.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/board/waddledee/board.c b/board/waddledee/board.c index 7699c99b3a..7404a0a272 100644 --- a/board/waddledee/board.c +++ b/board/waddledee/board.c @@ -41,21 +41,77 @@ #define CPRINTUSB(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define INT_RECHECK_US 5000 + /* C0 interrupt line shared by BC 1.2 and charger */ -static void usb_c0_interrupt(enum gpio_signal s) +static void check_c0_line(void); +DECLARE_DEFERRED(check_c0_line); + +static void notify_c0_chips(void) { task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12, 0); sm5803_interrupt(0); } +static void check_c0_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_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 usb_c1_interrupt(enum gpio_signal s) +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); sm5803_interrupt(1); } +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 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"); |