diff options
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/cros_ec.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index c53804a1451d..fc0c81ef04ff 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c | |||
@@ -23,6 +23,9 @@ | |||
23 | #include <linux/mfd/core.h> | 23 | #include <linux/mfd/core.h> |
24 | #include <linux/mfd/cros_ec.h> | 24 | #include <linux/mfd/cros_ec.h> |
25 | #include <linux/mfd/cros_ec_commands.h> | 25 | #include <linux/mfd/cros_ec_commands.h> |
26 | #include <linux/delay.h> | ||
27 | |||
28 | #define EC_COMMAND_RETRIES 50 | ||
26 | 29 | ||
27 | int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, | 30 | int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, |
28 | struct cros_ec_command *msg) | 31 | struct cros_ec_command *msg) |
@@ -69,6 +72,36 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, | |||
69 | 72 | ||
70 | mutex_lock(&ec_dev->lock); | 73 | mutex_lock(&ec_dev->lock); |
71 | ret = ec_dev->cmd_xfer(ec_dev, msg); | 74 | ret = ec_dev->cmd_xfer(ec_dev, msg); |
75 | if (msg->result == EC_RES_IN_PROGRESS) { | ||
76 | int i; | ||
77 | struct cros_ec_command status_msg; | ||
78 | struct ec_response_get_comms_status status; | ||
79 | |||
80 | status_msg.version = 0; | ||
81 | status_msg.command = EC_CMD_GET_COMMS_STATUS; | ||
82 | status_msg.outdata = NULL; | ||
83 | status_msg.outsize = 0; | ||
84 | status_msg.indata = (uint8_t *)&status; | ||
85 | status_msg.insize = sizeof(status); | ||
86 | |||
87 | /* | ||
88 | * Query the EC's status until it's no longer busy or | ||
89 | * we encounter an error. | ||
90 | */ | ||
91 | for (i = 0; i < EC_COMMAND_RETRIES; i++) { | ||
92 | usleep_range(10000, 11000); | ||
93 | |||
94 | ret = ec_dev->cmd_xfer(ec_dev, &status_msg); | ||
95 | if (ret < 0) | ||
96 | break; | ||
97 | |||
98 | msg->result = status_msg.result; | ||
99 | if (status_msg.result != EC_RES_SUCCESS) | ||
100 | break; | ||
101 | if (!(status.flags & EC_COMMS_STATUS_PROCESSING)) | ||
102 | break; | ||
103 | } | ||
104 | } | ||
72 | mutex_unlock(&ec_dev->lock); | 105 | mutex_unlock(&ec_dev->lock); |
73 | 106 | ||
74 | return ret; | 107 | return ret; |