summaryrefslogtreecommitdiff
path: root/common/usbc_intr_task.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/usbc_intr_task.c')
-rw-r--r--common/usbc_intr_task.c213
1 files changed, 0 insertions, 213 deletions
diff --git a/common/usbc_intr_task.c b/common/usbc_intr_task.c
deleted file mode 100644
index 0532645a35..0000000000
--- a/common/usbc_intr_task.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* High-priority interrupt tasks implementations */
-
-#include <stdint.h>
-
-#include "assert.h"
-#include "common.h"
-#include "compile_time_macros.h"
-#include "console.h"
-#include "ec_commands.h"
-#include "task.h"
-#include "tcpm/tcpm.h"
-#include "timer.h"
-#include "usb_pd.h"
-#include "usb_pd_tcpm.h"
-
-#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
-#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-
-/* Events for pd_interrupt_handler_task */
-#define PD_PROCESS_INTERRUPT BIT(0)
-
-/*
- * Theoretically, we may need to support up to 480 USB-PD packets per second for
- * intensive operations such as FW update over PD. This value has tested well
- * preventing watchdog resets with a single bad port partner plugged in.
- */
-#define ALERT_STORM_MAX_COUNT 480
-#define ALERT_STORM_INTERVAL SECOND
-
-static uint8_t pd_int_task_id[CONFIG_USB_PD_PORT_MAX_COUNT];
-
-void schedule_deferred_pd_interrupt(const int port)
-{
- /*
- * Don't set event to idle task if task id is 0. This happens when
- * not all the port have pd int task, the pd_int_task_id of port
- * that doesn't have pd int task is 0.
- */
- if (pd_int_task_id[port] != 0)
- task_set_event(pd_int_task_id[port], PD_PROCESS_INTERRUPT);
-}
-
-static struct {
- int count;
- timestamp_t time;
-} storm_tracker[CONFIG_USB_PD_PORT_MAX_COUNT];
-
-static void service_one_port(int port)
-{
- timestamp_t now;
-
- tcpc_alert(port);
-
- now = get_time();
- if (timestamp_expired(storm_tracker[port].time,
- &now)) {
- /* Reset timer into future */
- storm_tracker[port].time.val = now.val + ALERT_STORM_INTERVAL;
-
- /*
- * Start at 1 since we are processing an interrupt right
- * now
- */
- storm_tracker[port].count = 1;
- } else if (++storm_tracker[port].count > ALERT_STORM_MAX_COUNT) {
- CPRINTS("C%d: Interrupt storm detected."
- " Disabling port temporarily",
- port);
-
- pd_set_suspend(port, 1);
- pd_deferred_resume(port);
- }
-}
-
-__overridable void board_process_pd_alert(int port)
-{
-}
-
-/*
- * Main task entry point that handles PD interrupts for a single port. These
- * interrupts usually come from a TCPC, but may also come from PD-related chips
- * sharing the TCPC interrupt line.
- *
- * @param p The PD port number for which to handle interrupts (pointer is
- * reinterpreted as an integer directly).
- */
-void pd_interrupt_handler_task(void *p)
-{
- const int port = (int) ((intptr_t) p);
- const int port_mask = (PD_STATUS_TCPC_ALERT_0 << port);
-
- ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT);
-
- /*
- * If port does not exist, return
- */
- if (port >= board_get_usb_pd_port_count())
- return;
-
- pd_int_task_id[port] = task_get_current();
-
- while (1) {
- const int evt = task_wait_event(-1);
-
- if ((evt & PD_PROCESS_INTERRUPT) == 0)
- continue;
- /*
- * While the interrupt signal is asserted; we have more
- * work to do. This effectively makes the interrupt a
- * level-interrupt instead of an edge-interrupt without
- * having to enable/disable a real level-interrupt in
- * multiple locations.
- *
- * Also, if the port is disabled do not process
- * interrupts. Upon existing suspend, we schedule a
- * PD_PROCESS_INTERRUPT to check if we missed anything.
- */
- while ((tcpc_get_alert_status() & port_mask) &&
- pd_is_port_enabled(port)) {
-
- service_one_port(port);
- }
-
- board_process_pd_alert(port);
- }
-}
-
-/*
- * This code assumes port alert masks are adjacent to each other.
- */
-BUILD_ASSERT(PD_STATUS_TCPC_ALERT_3 == (PD_STATUS_TCPC_ALERT_0 << 3));
-
-/*
- * Shared TCPC interrupt handler. The function argument in ec.tasklist
- * is the mask of ports to handle. For example:
- *
- * BIT(USBC_PORT_C2) | BIT(USBC_PORT_C0)
- *
- * Note that this bitmask is 0-based while PD_STATUS_TCPC_ALERT_<port>
- * is not.
- */
-
-void pd_shared_alert_task(void *p)
-{
- const int sources_mask = (int) ((intptr_t) p);
- int want_alerts = 0;
- int port;
- int port_mask;
-
- CPRINTS("%s: port mask 0x%02x", __func__, sources_mask);
-
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port) {
- if ((sources_mask & BIT(port)) == 0)
- continue;
- if (!board_is_usb_pd_port_present(port))
- continue;
-
- port_mask = PD_STATUS_TCPC_ALERT_0 << port;
- want_alerts |= port_mask;
- pd_int_task_id[port] = task_get_current();
- }
-
- if (want_alerts == 0) {
- /*
- * None of the configured alert sources are available.
- */
- return;
- }
-
- while (1) {
- const int evt = task_wait_event(-1);
- int have_alerts;
-
- if ((evt & PD_PROCESS_INTERRUPT) == 0)
- continue;
-
- /*
- * While the interrupt signal is asserted; we have more
- * work to do. This effectively makes the interrupt a
- * level-interrupt instead of an edge-interrupt without
- * having to enable/disable a real level-interrupt in
- * multiple locations.
- *
- * Also, if the port is disabled do not process
- * interrupts. Upon existing suspend, we schedule a
- * PD_PROCESS_INTERRUPT to check if we missed anything.
- */
- do {
- have_alerts = tcpc_get_alert_status();
- have_alerts &= want_alerts;
-
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT;
- ++port) {
- port_mask = PD_STATUS_TCPC_ALERT_0 << port;
- if ((have_alerts & port_mask) == 0) {
- /* skip quiet port */
- continue;
- }
- if (!pd_is_port_enabled(port)) {
- /* filter out disabled port */
- have_alerts &= ~port_mask;
- continue;
- }
- service_one_port(port);
- }
- } while (have_alerts != 0);
- }
-}