summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2021-07-27 16:34:13 -0600
committerCommit Bot <commit-bot@chromium.org>2021-09-16 18:15:32 +0000
commit5fc7d71623fe7da1faa78844f366888c926b877f (patch)
tree5a372cc719aa995f45b4c75448be307328d2e2c0
parentabc6c7ad71d85532db725198cecab0aa282e7b50 (diff)
downloadchrome-ec-5fc7d71623fe7da1faa78844f366888c926b877f.tar.gz
USB MUX: Add access locks
Currently, there are three separate tasks which can access the muxes at once (host command, PD, and chipset). As such, locking should help coordinate sets and gets to each port. BRANCH=None BUG=b:172222942 TEST=tast typec.Mode*.manual on voxel Signed-off-by: Diana Z <dzigterman@chromium.org> Change-Id: I003a2eee06e4b44241308d8b64da597bd17c8878 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3078413 Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r--driver/usb_mux/usb_mux.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/driver/usb_mux/usb_mux.c b/driver/usb_mux/usb_mux.c
index a362412995..c8904134fd 100644
--- a/driver/usb_mux/usb_mux.c
+++ b/driver/usb_mux/usb_mux.c
@@ -39,6 +39,9 @@ static uint32_t flags[CONFIG_USB_PD_PORT_MAX_COUNT];
/* Device initialized at least once */
#define USB_MUX_FLAG_INIT BIT(1)
+/* Coordinate mux accesses by-port among the tasks */
+static mutex_t mux_lock[CONFIG_USB_PD_PORT_MAX_COUNT];
+
enum mux_config_type {
USB_MUX_INIT,
USB_MUX_LOW_POWER,
@@ -48,6 +51,19 @@ enum mux_config_type {
USB_MUX_HPD_UPDATE,
};
+#ifdef CONFIG_ZEPHYR
+static int init_mux_mutex(const struct device *dev)
+{
+ int port;
+
+ ARG_UNUSED(dev);
+ for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++)
+ k_mutex_init(&mux_lock[port]);
+ return 0;
+}
+SYS_INIT(init_mux_mutex, POST_KERNEL, 50);
+#endif /* CONFIG_ZEPHYR */
+
/* Configure the MUX */
static int configure_mux(int port,
enum mux_config_type config,
@@ -77,6 +93,9 @@ static int configure_mux(int port,
const struct usb_mux_driver *drv = mux_ptr->driver;
bool ack_required = false;
+ /* Action time! Lock this mux */
+ mutex_lock(&mux_lock[port]);
+
switch (config) {
case USB_MUX_INIT:
if (drv && drv->init) {
@@ -143,6 +162,9 @@ static int configure_mux(int port,
}
+ /* Unlock before any host command waits */
+ mutex_unlock(&mux_lock[port]);
+
if (ack_required) {
/* This should only be called from the PD task */
assert(port == TASK_ID_TO_PD_PORT(task_get_current()));