summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@chromium.org>2019-12-27 12:58:42 -0700
committerCommit Bot <commit-bot@chromium.org>2020-06-30 14:58:31 +0000
commit4a17980ccaf4e09c86110d42beae8aba2f62706c (patch)
tree73b2c061fea86c00d5b0f7a54a1976ca90b80a2a
parentc1af772cca33ddc4bc51e1b1b5127ab6133f5cb6 (diff)
downloadchrome-ec-4a17980ccaf4e09c86110d42beae8aba2f62706c.tar.gz
aoz1380: ignore false positive over current/temp
AOZ1380 can issue an over current/temperature interrupt when we disconnect as source or sink. Ignoring it recovers the issue without having to alert the USB PD stack. If the interrupts hits a second time, don't ignore it. BUG=b:147359722 BRANCH=none TEST=connect/disconnect charger to AOZ1380 attached port Change-Id: I2d3250de91c3607431c64c0a5eaeafa759abdcc0 Signed-off-by: Denis Brockus <dbrockus@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1984040 Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2224684 Reviewed-by: Diana Z <dzigterman@chromium.org> Tested-by: David Huang <david.huang@quanta.corp-partner.google.com> Commit-Queue: Diana Z <dzigterman@chromium.org>
-rw-r--r--driver/ppc/aoz1380.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/driver/ppc/aoz1380.c b/driver/ppc/aoz1380.c
index 708d488e94..990bd41a73 100644
--- a/driver/ppc/aoz1380.c
+++ b/driver/ppc/aoz1380.c
@@ -11,6 +11,7 @@
* controlled PPC chips that are similar to the AOZ1380
*/
+#include "atomic.h"
#include "common.h"
#include "console.h"
#include "driver/ppc/aoz1380.h"
@@ -27,7 +28,12 @@
static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */
#define AOZ1380_FLAGS_SOURCE_ENABLED BIT(0)
-static uint8_t flags[CONFIG_USB_PD_PORT_MAX_COUNT];
+#define AOZ1380_FLAGS_SINK_ENABLED BIT(1)
+#define AOZ1380_FLAGS_INT_ON_DISCONNECT BIT(2)
+static uint32_t flags[CONFIG_USB_PD_PORT_MAX_COUNT];
+
+#define AOZ1380_SET_FLAG(port, flag) atomic_or(&flags[port], (flag))
+#define AOZ1380_CLR_FLAG(port, flag) atomic_clear(&flags[port], (flag))
static int aoz1380_init(int port)
{
@@ -41,8 +47,20 @@ static int aoz1380_vbus_sink_enable(int port, int enable)
int rv;
rv = tcpm_set_snk_ctrl(port, enable);
+ if (rv)
+ return rv;
+
+ /*
+ * On enable, we want to indicate connection as a SINK.
+ * On disable, clear SINK and that we have interrupted.
+ */
+ if (enable)
+ AOZ1380_SET_FLAG(port, AOZ1380_FLAGS_SINK_ENABLED);
+ else
+ AOZ1380_CLR_FLAG(port, (AOZ1380_FLAGS_SINK_ENABLED |
+ AOZ1380_FLAGS_INT_ON_DISCONNECT));
- return rv;
+ return EC_SUCCESS;
}
static int aoz1380_vbus_source_enable(int port, int enable)
@@ -53,12 +71,17 @@ static int aoz1380_vbus_source_enable(int port, int enable)
if (rv)
return rv;
+ /*
+ * On enable, we want to indicate connection as a SOURCE.
+ * On disable, clear SOURCE and that we have interrupted.
+ */
if (enable)
- flags[port] |= AOZ1380_FLAGS_SOURCE_ENABLED;
+ AOZ1380_SET_FLAG(port, AOZ1380_FLAGS_SOURCE_ENABLED);
else
- flags[port] &= ~AOZ1380_FLAGS_SOURCE_ENABLED;
+ AOZ1380_CLR_FLAG(port, (AOZ1380_FLAGS_SOURCE_ENABLED |
+ AOZ1380_FLAGS_INT_ON_DISCONNECT));
- return rv;
+ return EC_SUCCESS;
}
static int aoz1380_is_sourcing_vbus(int port)
@@ -78,14 +101,32 @@ static int aoz1380_set_vbus_source_current_limit(int port,
* This device only has a single over current/temperature interrupt.
* TODO(b/141939343) Determine how to clear the interrupt
* TODO(b/142076004) Test this to verify we shut off vbus current
+ * TODO(b/147359722) Verify correct fault functionality
*/
static void aoz1380_handle_interrupt(int port)
{
/*
- * This is a over current/temperature condition
+ * We can get a false positive on disconnect that we
+ * had an over current/temperature event when we are no
+ * longer connected as sink or source. Ignore it if
+ * that is the case.
*/
- CPRINTS("C%d: PPC detected Vbus overcurrent/temperature!", port);
- pd_handle_overcurrent(port);
+ if (flags[port] != 0) {
+ /*
+ * This is a over current/temperature condition
+ */
+ CPRINTS("C%d PPC Vbus overcurrent/temperature", port);
+ pd_handle_overcurrent(port);
+ } else {
+ /*
+ * Just in case there is a condition that we will
+ * continue an interrupt storm, track that we have
+ * already been here once and will take the other
+ * path if we do this again before setting the
+ * sink/source as enabled or disabled again.
+ */
+ AOZ1380_SET_FLAG(port, AOZ1380_FLAGS_INT_ON_DISCONNECT);
+ }
}
static void aoz1380_irq_deferred(void)