aboutsummaryrefslogtreecommitdiff
path: root/drivers/platform/chrome
diff options
context:
space:
mode:
authorGravatar Prashant Malani <pmalani@chromium.org> 2020-06-29 14:13:27 -0700
committerGravatar Enric Balletbo i Serra <enric.balletbo@collabora.com> 2020-06-30 16:35:08 +0200
commit83cbc69df8b8ec598ff8ca7629be34a50274e5b5 (patch)
tree827b0ec6ea761fda394dee2d23698a918f28b55b /drivers/platform/chrome
parentplatform/chrome: cros_ec_typec: Add a dependency on USB_ROLE_SWITCH (diff)
downloadlinux-83cbc69df8b8ec598ff8ca7629be34a50274e5b5.tar.gz
linux-83cbc69df8b8ec598ff8ca7629be34a50274e5b5.tar.bz2
linux-83cbc69df8b8ec598ff8ca7629be34a50274e5b5.zip
platform/chrome: cros_ec_typec: Use workqueue for port update
Use a work queue to call the port update routines, instead of doing it directly in the PD notifier callback. This will prevent other drivers with PD notifier callbacks from being blocked on the port update routine completing. Signed-off-by: Prashant Malani <pmalani@chromium.org> Reviewed-by: Guenter Roeck <groeck@chromium.org> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Diffstat (limited to 'drivers/platform/chrome')
-rw-r--r--drivers/platform/chrome/cros_ec_typec.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index 0c041b79cbba..9901bf2a96c2 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -58,6 +58,7 @@ struct cros_typec_data {
/* Array of ports, indexed by port number. */
struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
struct notifier_block nb;
+ struct work_struct port_work;
};
static int cros_typec_parse_port_props(struct typec_capability *cap,
@@ -619,11 +620,9 @@ static int cros_typec_get_cmd_version(struct cros_typec_data *typec)
return 0;
}
-static int cros_ec_typec_event(struct notifier_block *nb,
- unsigned long host_event, void *_notify)
+static void cros_typec_port_work(struct work_struct *work)
{
- struct cros_typec_data *typec = container_of(nb, struct cros_typec_data,
- nb);
+ struct cros_typec_data *typec = container_of(work, struct cros_typec_data, port_work);
int ret, i;
for (i = 0; i < typec->num_ports; i++) {
@@ -631,6 +630,14 @@ static int cros_ec_typec_event(struct notifier_block *nb,
if (ret < 0)
dev_warn(typec->dev, "Update failed for port: %d\n", i);
}
+}
+
+static int cros_ec_typec_event(struct notifier_block *nb,
+ unsigned long host_event, void *_notify)
+{
+ struct cros_typec_data *typec = container_of(nb, struct cros_typec_data, nb);
+
+ schedule_work(&typec->port_work);
return NOTIFY_OK;
}
@@ -689,6 +696,12 @@ static int cros_typec_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
+ INIT_WORK(&typec->port_work, cros_typec_port_work);
+
+ /*
+ * Safe to call port update here, since we haven't registered the
+ * PD notifier yet.
+ */
for (i = 0; i < typec->num_ports; i++) {
ret = cros_typec_port_update(typec, i);
if (ret < 0)