| From 1979636199980a01d5c3d302261c5b558a312c2a Mon Sep 17 00:00:00 2001 |
| From: Pi-Hsun Shih <pihsun@chromium.org> |
| Date: Fri, 14 Feb 2020 16:26:38 +0800 |
| Subject: [PATCH] platform/chrome: cros_ec_rpmsg: Fix race with host event |
| |
| commit f775ac78fcfc6bdc96bdda07029d11f2a5e84869 upstream. |
| |
| Host event can be sent by remoteproc by any time, and |
| cros_ec_rpmsg_callback would be called after cros_ec_rpmsg_create_ept. |
| But the cros_ec_device is initialized after that, which cause host event |
| handler to use cros_ec_device that are not initialized properly yet. |
| |
| Fix this by don't schedule host event handler before cros_ec_register |
| returns. Instead, remember that we have a pending host event, and |
| schedule host event handler after cros_ec_register. |
| |
| Fixes: 71cddb7097e2 ("platform/chrome: cros_ec_rpmsg: Fix race with host command when probe failed.") |
| Signed-off-by: Pi-Hsun Shih <pihsun@chromium.org> |
| Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/platform/chrome/cros_ec_rpmsg.c b/drivers/platform/chrome/cros_ec_rpmsg.c |
| index bec19d4814ab..641e5274ccde 100644 |
| --- a/drivers/platform/chrome/cros_ec_rpmsg.c |
| +++ b/drivers/platform/chrome/cros_ec_rpmsg.c |
| @@ -42,6 +42,8 @@ struct cros_ec_rpmsg { |
| struct completion xfer_ack; |
| struct work_struct host_event_work; |
| struct rpmsg_endpoint *ept; |
| + bool has_pending_host_event; |
| + bool probe_done; |
| }; |
| |
| /** |
| @@ -186,7 +188,14 @@ static int cros_ec_rpmsg_callback(struct rpmsg_device *rpdev, void *data, |
| memcpy(ec_dev->din, resp->data, len); |
| complete(&ec_rpmsg->xfer_ack); |
| } else if (resp->type == HOST_EVENT_MARK) { |
| - schedule_work(&ec_rpmsg->host_event_work); |
| + /* |
| + * If the host event is sent before cros_ec_register is |
| + * finished, queue the host event. |
| + */ |
| + if (ec_rpmsg->probe_done) |
| + schedule_work(&ec_rpmsg->host_event_work); |
| + else |
| + ec_rpmsg->has_pending_host_event = true; |
| } else { |
| dev_warn(ec_dev->dev, "rpmsg received invalid type = %d", |
| resp->type); |
| @@ -249,6 +258,11 @@ static int cros_ec_rpmsg_probe(struct rpmsg_device *rpdev) |
| return ret; |
| } |
| |
| + ec_rpmsg->probe_done = true; |
| + |
| + if (ec_rpmsg->has_pending_host_event) |
| + schedule_work(&ec_rpmsg->host_event_work); |
| + |
| return 0; |
| } |
| |
| -- |
| 2.7.4 |
| |