From f9f3ed0467fe2062c7916c892ecbcf00f957095a Mon Sep 17 00:00:00 2001 From: Jett Rink Date: Thu, 15 Nov 2018 13:03:57 -0700 Subject: usb-pd: preprocess pending interrupts after reset If the EC resets while the TCPC interrupt line is asserted and the board configures the interrupt as edge trigger (which is very common), then the interrupt line will never present and edge and the ISR will never get called. Preemptively checking for pending interrupts should prevent this. BRANCH=none BUG=b:119564103 TEST=test that ec reboot with hub attached no longer malfunctions. Change-Id: I77ca5815e2bdc94e3173a621aeac8620bf332613 Signed-off-by: Jett Rink Reviewed-on: https://chromium-review.googlesource.com/1337466 Reviewed-by: Aseda Aboagye --- common/usb_pd_protocol.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 988443aba1..20d713f628 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -2463,6 +2463,9 @@ static int pd_restart_tcpc(int port) #if defined(HAS_TASK_PD_INT_C0) || defined(HAS_TASK_PD_INT_C1) || \ defined(HAS_TASK_PD_INT_C2) +/* Used to conditionally compile code in main pd task. */ +#define HAS_DEFFERED_INTERRUPT_HANDLER + /* Events for pd_interrupt_handler_task */ #define PD_PROCESS_INTERRUPT (1<<0) @@ -2666,6 +2669,17 @@ void pd_task(void *u) charge_manager_update_dualrole(port, CAP_UNKNOWN); #endif +#ifdef HAS_DEFFERED_INTERRUPT_HANDLER + /* + * Since most boards configure the TCPC interrupt as edge + * and it is possible that the interrupt line was asserted between init + * and calling set_state, we need to process any pending interrupts now. + * Otherwise future interrupts will never fire because another edge + * never happens. Note this needs to happen after set_state() is called. + */ + schedule_deferred_pd_interrupt(port); +#endif + while (1) { #ifdef CONFIG_USB_PD_REV30 /* send any pending messages */ -- cgit v1.2.1