aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/chrome/cros_ec_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/chrome/cros_ec_sysfs.c')
-rw-r--r--drivers/platform/chrome/cros_ec_sysfs.c178
1 files changed, 102 insertions, 76 deletions
diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c
index fb62ab6cc659..f3baf9973989 100644
--- a/drivers/platform/chrome/cros_ec_sysfs.c
+++ b/drivers/platform/chrome/cros_ec_sysfs.c
@@ -29,6 +29,7 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/printk.h> 31#include <linux/printk.h>
32#include <linux/slab.h>
32#include <linux/stat.h> 33#include <linux/stat.h>
33#include <linux/types.h> 34#include <linux/types.h>
34#include <linux/uaccess.h> 35#include <linux/uaccess.h>
@@ -66,13 +67,19 @@ static ssize_t store_ec_reboot(struct device *dev,
66 {"hibernate", EC_REBOOT_HIBERNATE, 0}, 67 {"hibernate", EC_REBOOT_HIBERNATE, 0},
67 {"at-shutdown", -1, EC_REBOOT_FLAG_ON_AP_SHUTDOWN}, 68 {"at-shutdown", -1, EC_REBOOT_FLAG_ON_AP_SHUTDOWN},
68 }; 69 };
69 struct cros_ec_command msg = { 0 }; 70 struct cros_ec_command *msg;
70 struct ec_params_reboot_ec *param = 71 struct ec_params_reboot_ec *param;
71 (struct ec_params_reboot_ec *)msg.outdata;
72 int got_cmd = 0, offset = 0; 72 int got_cmd = 0, offset = 0;
73 int i; 73 int i;
74 int ret; 74 int ret;
75 struct cros_ec_device *ec = dev_get_drvdata(dev); 75 struct cros_ec_dev *ec = container_of(dev,
76 struct cros_ec_dev, class_dev);
77
78 msg = kmalloc(sizeof(*msg) + sizeof(*param), GFP_KERNEL);
79 if (!msg)
80 return -ENOMEM;
81
82 param = (struct ec_params_reboot_ec *)msg->data;
76 83
77 param->flags = 0; 84 param->flags = 0;
78 while (1) { 85 while (1) {
@@ -100,19 +107,26 @@ static ssize_t store_ec_reboot(struct device *dev,
100 offset++; 107 offset++;
101 } 108 }
102 109
103 if (!got_cmd) 110 if (!got_cmd) {
104 return -EINVAL; 111 count = -EINVAL;
105 112 goto exit;
106 msg.command = EC_CMD_REBOOT_EC;
107 msg.outsize = sizeof(param);
108 ret = cros_ec_cmd_xfer(ec, &msg);
109 if (ret < 0)
110 return ret;
111 if (msg.result != EC_RES_SUCCESS) {
112 dev_dbg(ec->dev, "EC result %d\n", msg.result);
113 return -EINVAL;
114 } 113 }
115 114
115 msg->version = 0;
116 msg->command = EC_CMD_REBOOT_EC + ec->cmd_offset;
117 msg->outsize = sizeof(*param);
118 msg->insize = 0;
119 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
120 if (ret < 0) {
121 count = ret;
122 goto exit;
123 }
124 if (msg->result != EC_RES_SUCCESS) {
125 dev_dbg(ec->dev, "EC result %d\n", msg->result);
126 count = -EINVAL;
127 }
128exit:
129 kfree(msg);
116 return count; 130 return count;
117} 131}
118 132
@@ -123,22 +137,33 @@ static ssize_t show_ec_version(struct device *dev,
123 struct ec_response_get_version *r_ver; 137 struct ec_response_get_version *r_ver;
124 struct ec_response_get_chip_info *r_chip; 138 struct ec_response_get_chip_info *r_chip;
125 struct ec_response_board_version *r_board; 139 struct ec_response_board_version *r_board;
126 struct cros_ec_command msg = { 0 }; 140 struct cros_ec_command *msg;
127 int ret; 141 int ret;
128 int count = 0; 142 int count = 0;
129 struct cros_ec_device *ec = dev_get_drvdata(dev); 143 struct cros_ec_dev *ec = container_of(dev,
144 struct cros_ec_dev, class_dev);
145
146 msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL);
147 if (!msg)
148 return -ENOMEM;
130 149
131 /* Get versions. RW may change. */ 150 /* Get versions. RW may change. */
132 msg.command = EC_CMD_GET_VERSION; 151 msg->version = 0;
133 msg.insize = sizeof(*r_ver); 152 msg->command = EC_CMD_GET_VERSION + ec->cmd_offset;
134 ret = cros_ec_cmd_xfer(ec, &msg); 153 msg->insize = sizeof(*r_ver);
135 if (ret < 0) 154 msg->outsize = 0;
136 return ret; 155 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
137 if (msg.result != EC_RES_SUCCESS) 156 if (ret < 0) {
138 return scnprintf(buf, PAGE_SIZE, 157 count = ret;
139 "ERROR: EC returned %d\n", msg.result); 158 goto exit;
159 }
160 if (msg->result != EC_RES_SUCCESS) {
161 count = scnprintf(buf, PAGE_SIZE,
162 "ERROR: EC returned %d\n", msg->result);
163 goto exit;
164 }
140 165
141 r_ver = (struct ec_response_get_version *)msg.indata; 166 r_ver = (struct ec_response_get_version *)msg->data;
142 /* Strings should be null-terminated, but let's be sure. */ 167 /* Strings should be null-terminated, but let's be sure. */
143 r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0'; 168 r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0';
144 r_ver->version_string_rw[sizeof(r_ver->version_string_rw) - 1] = '\0'; 169 r_ver->version_string_rw[sizeof(r_ver->version_string_rw) - 1] = '\0';
@@ -152,33 +177,33 @@ static ssize_t show_ec_version(struct device *dev,
152 image_names[r_ver->current_image] : "?")); 177 image_names[r_ver->current_image] : "?"));
153 178
154 /* Get build info. */ 179 /* Get build info. */
155 msg.command = EC_CMD_GET_BUILD_INFO; 180 msg->command = EC_CMD_GET_BUILD_INFO + ec->cmd_offset;
156 msg.insize = sizeof(msg.indata); 181 msg->insize = EC_HOST_PARAM_SIZE;
157 ret = cros_ec_cmd_xfer(ec, &msg); 182 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
158 if (ret < 0) 183 if (ret < 0)
159 count += scnprintf(buf + count, PAGE_SIZE - count, 184 count += scnprintf(buf + count, PAGE_SIZE - count,
160 "Build info: XFER ERROR %d\n", ret); 185 "Build info: XFER ERROR %d\n", ret);
161 else if (msg.result != EC_RES_SUCCESS) 186 else if (msg->result != EC_RES_SUCCESS)
162 count += scnprintf(buf + count, PAGE_SIZE - count, 187 count += scnprintf(buf + count, PAGE_SIZE - count,
163 "Build info: EC error %d\n", msg.result); 188 "Build info: EC error %d\n", msg->result);
164 else { 189 else {
165 msg.indata[sizeof(msg.indata) - 1] = '\0'; 190 msg->data[sizeof(msg->data) - 1] = '\0';
166 count += scnprintf(buf + count, PAGE_SIZE - count, 191 count += scnprintf(buf + count, PAGE_SIZE - count,
167 "Build info: %s\n", msg.indata); 192 "Build info: %s\n", msg->data);
168 } 193 }
169 194
170 /* Get chip info. */ 195 /* Get chip info. */
171 msg.command = EC_CMD_GET_CHIP_INFO; 196 msg->command = EC_CMD_GET_CHIP_INFO + ec->cmd_offset;
172 msg.insize = sizeof(*r_chip); 197 msg->insize = sizeof(*r_chip);
173 ret = cros_ec_cmd_xfer(ec, &msg); 198 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
174 if (ret < 0) 199 if (ret < 0)
175 count += scnprintf(buf + count, PAGE_SIZE - count, 200 count += scnprintf(buf + count, PAGE_SIZE - count,
176 "Chip info: XFER ERROR %d\n", ret); 201 "Chip info: XFER ERROR %d\n", ret);
177 else if (msg.result != EC_RES_SUCCESS) 202 else if (msg->result != EC_RES_SUCCESS)
178 count += scnprintf(buf + count, PAGE_SIZE - count, 203 count += scnprintf(buf + count, PAGE_SIZE - count,
179 "Chip info: EC error %d\n", msg.result); 204 "Chip info: EC error %d\n", msg->result);
180 else { 205 else {
181 r_chip = (struct ec_response_get_chip_info *)msg.indata; 206 r_chip = (struct ec_response_get_chip_info *)msg->data;
182 207
183 r_chip->vendor[sizeof(r_chip->vendor) - 1] = '\0'; 208 r_chip->vendor[sizeof(r_chip->vendor) - 1] = '\0';
184 r_chip->name[sizeof(r_chip->name) - 1] = '\0'; 209 r_chip->name[sizeof(r_chip->name) - 1] = '\0';
@@ -192,23 +217,25 @@ static ssize_t show_ec_version(struct device *dev,
192 } 217 }
193 218
194 /* Get board version */ 219 /* Get board version */
195 msg.command = EC_CMD_GET_BOARD_VERSION; 220 msg->command = EC_CMD_GET_BOARD_VERSION + ec->cmd_offset;
196 msg.insize = sizeof(*r_board); 221 msg->insize = sizeof(*r_board);
197 ret = cros_ec_cmd_xfer(ec, &msg); 222 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
198 if (ret < 0) 223 if (ret < 0)
199 count += scnprintf(buf + count, PAGE_SIZE - count, 224 count += scnprintf(buf + count, PAGE_SIZE - count,
200 "Board version: XFER ERROR %d\n", ret); 225 "Board version: XFER ERROR %d\n", ret);
201 else if (msg.result != EC_RES_SUCCESS) 226 else if (msg->result != EC_RES_SUCCESS)
202 count += scnprintf(buf + count, PAGE_SIZE - count, 227 count += scnprintf(buf + count, PAGE_SIZE - count,
203 "Board version: EC error %d\n", msg.result); 228 "Board version: EC error %d\n", msg->result);
204 else { 229 else {
205 r_board = (struct ec_response_board_version *)msg.indata; 230 r_board = (struct ec_response_board_version *)msg->data;
206 231
207 count += scnprintf(buf + count, PAGE_SIZE - count, 232 count += scnprintf(buf + count, PAGE_SIZE - count,
208 "Board version: %d\n", 233 "Board version: %d\n",
209 r_board->board_version); 234 r_board->board_version);
210 } 235 }
211 236
237exit:
238 kfree(msg);
212 return count; 239 return count;
213} 240}
214 241
@@ -216,27 +243,39 @@ static ssize_t show_ec_flashinfo(struct device *dev,
216 struct device_attribute *attr, char *buf) 243 struct device_attribute *attr, char *buf)
217{ 244{
218 struct ec_response_flash_info *resp; 245 struct ec_response_flash_info *resp;
219 struct cros_ec_command msg = { 0 }; 246 struct cros_ec_command *msg;
220 int ret; 247 int ret;
221 struct cros_ec_device *ec = dev_get_drvdata(dev); 248 struct cros_ec_dev *ec = container_of(dev,
249 struct cros_ec_dev, class_dev);
250
251 msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL);
252 if (!msg)
253 return -ENOMEM;
222 254
223 /* The flash info shouldn't ever change, but ask each time anyway. */ 255 /* The flash info shouldn't ever change, but ask each time anyway. */
224 msg.command = EC_CMD_FLASH_INFO; 256 msg->version = 0;
225 msg.insize = sizeof(*resp); 257 msg->command = EC_CMD_FLASH_INFO + ec->cmd_offset;
226 ret = cros_ec_cmd_xfer(ec, &msg); 258 msg->insize = sizeof(*resp);
259 msg->outsize = 0;
260 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
227 if (ret < 0) 261 if (ret < 0)
228 return ret; 262 goto exit;
229 if (msg.result != EC_RES_SUCCESS) 263 if (msg->result != EC_RES_SUCCESS) {
230 return scnprintf(buf, PAGE_SIZE, 264 ret = scnprintf(buf, PAGE_SIZE,
231 "ERROR: EC returned %d\n", msg.result); 265 "ERROR: EC returned %d\n", msg->result);
232 266 goto exit;
233 resp = (struct ec_response_flash_info *)msg.indata; 267 }
234 268
235 return scnprintf(buf, PAGE_SIZE, 269 resp = (struct ec_response_flash_info *)msg->data;
236 "FlashSize %d\nWriteSize %d\n" 270
237 "EraseSize %d\nProtectSize %d\n", 271 ret = scnprintf(buf, PAGE_SIZE,
238 resp->flash_size, resp->write_block_size, 272 "FlashSize %d\nWriteSize %d\n"
239 resp->erase_block_size, resp->protect_block_size); 273 "EraseSize %d\nProtectSize %d\n",
274 resp->flash_size, resp->write_block_size,
275 resp->erase_block_size, resp->protect_block_size);
276exit:
277 kfree(msg);
278 return ret;
240} 279}
241 280
242/* Module initialization */ 281/* Module initialization */
@@ -252,20 +291,7 @@ static struct attribute *__ec_attrs[] = {
252 NULL, 291 NULL,
253}; 292};
254 293
255static struct attribute_group ec_attr_group = { 294struct attribute_group cros_ec_attr_group = {
256 .attrs = __ec_attrs, 295 .attrs = __ec_attrs,
257}; 296};
258 297
259void ec_dev_sysfs_init(struct cros_ec_device *ec)
260{
261 int error;
262
263 error = sysfs_create_group(&ec->vdev->kobj, &ec_attr_group);
264 if (error)
265 pr_warn("failed to create group: %d\n", error);
266}
267
268void ec_dev_sysfs_remove(struct cros_ec_device *ec)
269{
270 sysfs_remove_group(&ec->vdev->kobj, &ec_attr_group);
271}