summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2014-06-18 11:14:05 -0700
committerLee Jones <lee.jones@linaro.org>2014-07-09 14:58:19 +0100
commit6db07b6336589ff480528173e41f8f6af3f0097f (patch)
tree306bf3f92d5bc8920c8ae668e3e8c93534351d85
parent5799f95a373a2752e5c732f531a6f40fe458b818 (diff)
mfd: cros_ec: Check result code from EC messages
Just because the host was able to talk to the EC doesn't mean that the EC was happy with what it was told. Errors in communincation are not the same as error messages from the EC itself. This change lets the EC report its errors separately. [dianders: Added common function to cros_ec.c] Signed-off-by: Bill Richardson <wfrichar@chromium.org> Signed-off-by: Doug Anderson <dianders@chromium.org> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/cros_ec.c18
-rw-r--r--drivers/mfd/cros_ec_i2c.c8
-rw-r--r--drivers/mfd/cros_ec_spi.c19
-rw-r--r--include/linux/mfd/cros_ec.h12
4 files changed, 39 insertions, 18 deletions
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index 4851ed2fbe31..83e30c663578 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -44,6 +44,24 @@ int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
}
EXPORT_SYMBOL(cros_ec_prepare_tx);
+int cros_ec_check_result(struct cros_ec_device *ec_dev,
+ struct cros_ec_command *msg)
+{
+ switch (msg->result) {
+ case EC_RES_SUCCESS:
+ return 0;
+ case EC_RES_IN_PROGRESS:
+ dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
+ msg->command);
+ return -EAGAIN;
+ default:
+ dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
+ msg->command, msg->result);
+ return 0;
+ }
+}
+EXPORT_SYMBOL(cros_ec_check_result);
+
static irqreturn_t ec_irq_thread(int irq, void *data)
{
struct cros_ec_device *ec_dev = data;
diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c
index 5bb32f5550b3..189e7d1d7742 100644
--- a/drivers/mfd/cros_ec_i2c.c
+++ b/drivers/mfd/cros_ec_i2c.c
@@ -92,12 +92,10 @@ static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev,
}
/* check response error code */
- if (i2c_msg[1].buf[0]) {
- dev_warn(ec_dev->dev, "command 0x%02x returned an error %d\n",
- msg->command, i2c_msg[1].buf[0]);
- ret = -EINVAL;
+ msg->result = i2c_msg[1].buf[0];
+ ret = cros_ec_check_result(ec_dev, msg);
+ if (ret)
goto done;
- }
/* copy response packet payload and compute checksum */
sum = in_buf[0] + in_buf[1];
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c
index 6e929b5f3bd3..da1da05cd546 100644
--- a/drivers/mfd/cros_ec_spi.c
+++ b/drivers/mfd/cros_ec_spi.c
@@ -285,21 +285,14 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
goto exit;
}
- /* check response error code */
ptr = ec_dev->din;
- if (ptr[0]) {
- if (ptr[0] == EC_RES_IN_PROGRESS) {
- dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
- ec_msg->command);
- ret = -EAGAIN;
- goto exit;
- }
- dev_warn(ec_dev->dev, "command 0x%02x returned an error %d\n",
- ec_msg->command, ptr[0]);
- debug_packet(ec_dev->dev, "in_err", ptr, len);
- ret = -EINVAL;
+
+ /* check response error code */
+ ec_msg->result = ptr[0];
+ ret = cros_ec_check_result(ec_dev, ec_msg);
+ if (ret)
goto exit;
- }
+
len = ptr[1];
sum = ptr[0] + ptr[1];
if (len > ec_msg->insize) {
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index 60c088055f3a..1f79f162abe4 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -143,6 +143,18 @@ int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
struct cros_ec_command *msg);
/**
+ * cros_ec_check_result - Check ec_msg->result
+ *
+ * This is used by ChromeOS EC drivers to check the ec_msg->result for
+ * errors and to warn about them.
+ *
+ * @ec_dev: EC device
+ * @msg: Message to check
+ */
+int cros_ec_check_result(struct cros_ec_device *ec_dev,
+ struct cros_ec_command *msg);
+
+/**
* cros_ec_remove - Remove a ChromeOS EC
*
* Call this to deregister a ChromeOS EC, then clean up any private data.