diff options
Diffstat (limited to 'drivers/platform/chrome')
-rw-r--r-- | drivers/platform/chrome/chromeos_pstore.c | 1 | ||||
-rw-r--r-- | drivers/platform/chrome/cros_ec_ishtp.c | 45 | ||||
-rw-r--r-- | drivers/platform/chrome/wilco_ec/debugfs.c | 7 |
3 files changed, 40 insertions, 13 deletions
diff --git a/drivers/platform/chrome/chromeos_pstore.c b/drivers/platform/chrome/chromeos_pstore.c index d13770785fb5..82dea8cb5da1 100644 --- a/drivers/platform/chrome/chromeos_pstore.c +++ b/drivers/platform/chrome/chromeos_pstore.c @@ -57,6 +57,7 @@ static struct ramoops_platform_data chromeos_ramoops_data = { .record_size = 0x40000, .console_size = 0x20000, .ftrace_size = 0x20000, + .pmsg_size = 0x20000, .dump_oops = 1, }; diff --git a/drivers/platform/chrome/cros_ec_ishtp.c b/drivers/platform/chrome/cros_ec_ishtp.c index 93a71e93a2f1..ed794a7ddba9 100644 --- a/drivers/platform/chrome/cros_ec_ishtp.c +++ b/drivers/platform/chrome/cros_ec_ishtp.c @@ -48,7 +48,8 @@ static const guid_t cros_ish_guid = struct header { u8 channel; u8 status; - u8 reserved[2]; + u8 token; + u8 reserved; } __packed; struct cros_ish_out_msg { @@ -90,6 +91,7 @@ static DECLARE_RWSEM(init_lock); * data exceeds this value, we log an error. * @size: Actual size of data received from firmware. * @error: 0 for success, negative error code for a failure in process_recv(). + * @token: Expected token for response that we are waiting on. * @received: Set to true on receiving a valid firmware response to host command * @wait_queue: Wait queue for host to wait for firmware response. */ @@ -98,6 +100,7 @@ struct response_info { size_t max_size; size_t size; int error; + u8 token; bool received; wait_queue_head_t wait_queue; }; @@ -162,6 +165,7 @@ static int ish_send(struct ishtp_cl_data *client_data, u8 *out_msg, size_t out_size, u8 *in_msg, size_t in_size) { + static u8 next_token; int rv; struct header *out_hdr = (struct header *)out_msg; struct ishtp_cl *cros_ish_cl = client_data->cros_ish_cl; @@ -174,8 +178,11 @@ static int ish_send(struct ishtp_cl_data *client_data, client_data->response.data = in_msg; client_data->response.max_size = in_size; client_data->response.error = 0; + client_data->response.token = next_token++; client_data->response.received = false; + out_hdr->token = client_data->response.token; + rv = ishtp_cl_send(cros_ish_cl, out_msg, out_size); if (rv) { dev_err(cl_data_to_dev(client_data), @@ -249,17 +256,23 @@ static void process_recv(struct ishtp_cl *cros_ish_cl, switch (in_msg->hdr.channel) { case CROS_EC_COMMAND: - /* Sanity check */ - if (!client_data->response.data) { + if (client_data->response.received) { dev_err(dev, - "Receiving buffer is null. Should be allocated by calling function\n"); - client_data->response.error = -EINVAL; - goto error_wake_up; + "Previous firmware message not yet processed\n"); + goto end_error; } - if (client_data->response.received) { + if (client_data->response.token != in_msg->hdr.token) { + dev_err_ratelimited(dev, + "Dropping old response token %d\n", + in_msg->hdr.token); + goto end_error; + } + + /* Sanity check */ + if (!client_data->response.data) { dev_err(dev, - "Previous firmware message not yet processed\n"); + "Receiving buffer is null. Should be allocated by calling function\n"); client_data->response.error = -EINVAL; goto error_wake_up; } @@ -289,21 +302,28 @@ static void process_recv(struct ishtp_cl *cros_ish_cl, memcpy(client_data->response.data, rb_in_proc->buffer.data, data_len); +error_wake_up: + /* Free the buffer since we copied data or didn't need it */ + ishtp_cl_io_rb_recycle(rb_in_proc); + rb_in_proc = NULL; + /* Set flag before waking up the caller */ client_data->response.received = true; -error_wake_up: + /* Wake the calling thread */ wake_up_interruptible(&client_data->response.wait_queue); break; case CROS_MKBP_EVENT: + /* Free the buffer. This is just an event without data */ + ishtp_cl_io_rb_recycle(rb_in_proc); + rb_in_proc = NULL; /* * Set timestamp from beginning of function since we actually * got an incoming MKBP event */ client_data->ec_dev->last_event_time = timestamp; - /* The event system doesn't send any data in buffer */ schedule_work(&client_data->work_ec_evt); break; @@ -313,8 +333,9 @@ error_wake_up: } end_error: - /* Free the buffer */ - ishtp_cl_io_rb_recycle(rb_in_proc); + /* Free the buffer if we already haven't */ + if (rb_in_proc) + ishtp_cl_io_rb_recycle(rb_in_proc); up_read(&init_lock); } diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c b/drivers/platform/chrome/wilco_ec/debugfs.c index df5a5f6c3ec6..a812788a0bdc 100644 --- a/drivers/platform/chrome/wilco_ec/debugfs.c +++ b/drivers/platform/chrome/wilco_ec/debugfs.c @@ -208,7 +208,12 @@ static int send_ec_cmd(struct wilco_ec_device *ec, u8 sub_cmd, u8 *out_val) */ static int h1_gpio_get(void *arg, u64 *val) { - return send_ec_cmd(arg, SUB_CMD_H1_GPIO, (u8 *)val); + int ret; + + ret = send_ec_cmd(arg, SUB_CMD_H1_GPIO, (u8 *)val); + if (ret == 0) + *val &= 0xFF; + return ret; } DEFINE_DEBUGFS_ATTRIBUTE(fops_h1_gpio, h1_gpio_get, NULL, "0x%02llx\n"); |