summaryrefslogtreecommitdiff
path: root/board/madoo/board.c
diff options
context:
space:
mode:
authorKo_Ko <Ko_Ko@compal.corp-partner.google.com>2020-11-24 19:09:30 +0800
committerCommit Bot <commit-bot@chromium.org>2020-12-01 04:10:29 +0000
commit6e61e71e8770f3f92848d02f9075a974b4146ffd (patch)
treef8cc5cb38247297cd063f2d92320c2547ea48c1a /board/madoo/board.c
parentd8ba7887892ac541f5beccaa2f50e35b1176462b (diff)
downloadchrome-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.c80
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);