summaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
Diffstat (limited to 'driver')
-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()));