summaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorBenson Leung <bleung@chromium.org>2018-04-11 01:29:14 -0400
committerBenson Leung <bleung@chromium.org>2018-04-11 01:30:34 -0400
commitc171d3b8a67e08884d915ffbb1dbc475747d7df2 (patch)
treed2061a569bffc691e9dde9c994e1889f5658bd9d /drivers/platform
parent72655f6cf7fe04b867776bb7120fbdb84dee4f61 (diff)
parentc1d1e91aff3d1183d6b16a282c2575e3e006cee4 (diff)
Merge remote-tracking branch 'origin/ib-chrome-platform-cros-ec-sysfs-debugfs-for-v4.17' into working-branch-for-4.17
Merging Enric's cros-ec sysfs and debugfs fixes from immutable branch. Signed-off-by: Benson Leung <bleung@chromium.org>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/chrome/cros_ec_debugfs.c76
-rw-r--r--drivers/platform/chrome/cros_ec_sysfs.c141
2 files changed, 176 insertions, 41 deletions
diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c
index 0e88e18362c1..cc265ed8deb7 100644
--- a/drivers/platform/chrome/cros_ec_debugfs.c
+++ b/drivers/platform/chrome/cros_ec_debugfs.c
@@ -211,6 +211,58 @@ static int cros_ec_console_log_release(struct inode *inode, struct file *file)
211 return 0; 211 return 0;
212} 212}
213 213
214static ssize_t cros_ec_pdinfo_read(struct file *file,
215 char __user *user_buf,
216 size_t count,
217 loff_t *ppos)
218{
219 char read_buf[EC_USB_PD_MAX_PORTS * 40], *p = read_buf;
220 struct cros_ec_debugfs *debug_info = file->private_data;
221 struct cros_ec_device *ec_dev = debug_info->ec->ec_dev;
222 struct {
223 struct cros_ec_command msg;
224 union {
225 struct ec_response_usb_pd_control_v1 resp;
226 struct ec_params_usb_pd_control params;
227 };
228 } __packed ec_buf;
229 struct cros_ec_command *msg;
230 struct ec_response_usb_pd_control_v1 *resp;
231 struct ec_params_usb_pd_control *params;
232 int i;
233
234 msg = &ec_buf.msg;
235 params = (struct ec_params_usb_pd_control *)msg->data;
236 resp = (struct ec_response_usb_pd_control_v1 *)msg->data;
237
238 msg->command = EC_CMD_USB_PD_CONTROL;
239 msg->version = 1;
240 msg->insize = sizeof(*resp);
241 msg->outsize = sizeof(*params);
242
243 /*
244 * Read status from all PD ports until failure, typically caused
245 * by attempting to read status on a port that doesn't exist.
246 */
247 for (i = 0; i < EC_USB_PD_MAX_PORTS; ++i) {
248 params->port = i;
249 params->role = 0;
250 params->mux = 0;
251 params->swap = 0;
252
253 if (cros_ec_cmd_xfer_status(ec_dev, msg) < 0)
254 break;
255
256 p += scnprintf(p, sizeof(read_buf) + read_buf - p,
257 "p%d: %s en:%.2x role:%.2x pol:%.2x\n", i,
258 resp->state, resp->enabled, resp->role,
259 resp->polarity);
260 }
261
262 return simple_read_from_buffer(user_buf, count, ppos,
263 read_buf, p - read_buf);
264}
265
214const struct file_operations cros_ec_console_log_fops = { 266const struct file_operations cros_ec_console_log_fops = {
215 .owner = THIS_MODULE, 267 .owner = THIS_MODULE,
216 .open = cros_ec_console_log_open, 268 .open = cros_ec_console_log_open,
@@ -220,6 +272,13 @@ const struct file_operations cros_ec_console_log_fops = {
220 .release = cros_ec_console_log_release, 272 .release = cros_ec_console_log_release,
221}; 273};
222 274
275const struct file_operations cros_ec_pdinfo_fops = {
276 .owner = THIS_MODULE,
277 .open = simple_open,
278 .read = cros_ec_pdinfo_read,
279 .llseek = default_llseek,
280};
281
223static int ec_read_version_supported(struct cros_ec_dev *ec) 282static int ec_read_version_supported(struct cros_ec_dev *ec)
224{ 283{
225 struct ec_params_get_cmd_versions_v1 *params; 284 struct ec_params_get_cmd_versions_v1 *params;
@@ -288,7 +347,7 @@ static int cros_ec_create_console_log(struct cros_ec_debugfs *debug_info)
288 init_waitqueue_head(&debug_info->log_wq); 347 init_waitqueue_head(&debug_info->log_wq);
289 348
290 if (!debugfs_create_file("console_log", 349 if (!debugfs_create_file("console_log",
291 S_IFREG | S_IRUGO, 350 S_IFREG | 0444,
292 debug_info->dir, 351 debug_info->dir,
293 debug_info, 352 debug_info,
294 &cros_ec_console_log_fops)) 353 &cros_ec_console_log_fops))
@@ -341,7 +400,7 @@ static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info)
341 debug_info->panicinfo_blob.size = ret; 400 debug_info->panicinfo_blob.size = ret;
342 401
343 if (!debugfs_create_blob("panicinfo", 402 if (!debugfs_create_blob("panicinfo",
344 S_IFREG | S_IRUGO, 403 S_IFREG | 0444,
345 debug_info->dir, 404 debug_info->dir,
346 &debug_info->panicinfo_blob)) { 405 &debug_info->panicinfo_blob)) {
347 ret = -ENOMEM; 406 ret = -ENOMEM;
@@ -355,6 +414,15 @@ free:
355 return ret; 414 return ret;
356} 415}
357 416
417static int cros_ec_create_pdinfo(struct cros_ec_debugfs *debug_info)
418{
419 if (!debugfs_create_file("pdinfo", 0444, debug_info->dir, debug_info,
420 &cros_ec_pdinfo_fops))
421 return -ENOMEM;
422
423 return 0;
424}
425
358int cros_ec_debugfs_init(struct cros_ec_dev *ec) 426int cros_ec_debugfs_init(struct cros_ec_dev *ec)
359{ 427{
360 struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev); 428 struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev);
@@ -379,6 +447,10 @@ int cros_ec_debugfs_init(struct cros_ec_dev *ec)
379 if (ret) 447 if (ret)
380 goto remove_debugfs; 448 goto remove_debugfs;
381 449
450 ret = cros_ec_create_pdinfo(debug_info);
451 if (ret)
452 goto remove_debugfs;
453
382 ec->debug_info = debug_info; 454 ec->debug_info = debug_info;
383 455
384 return 0; 456 return 0;
diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c
index da0a719d32f7..5a6db3fe213a 100644
--- a/drivers/platform/chrome/cros_ec_sysfs.c
+++ b/drivers/platform/chrome/cros_ec_sysfs.c
@@ -34,10 +34,12 @@
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/uaccess.h> 35#include <linux/uaccess.h>
36 36
37#define to_cros_ec_dev(dev) container_of(dev, struct cros_ec_dev, class_dev)
38
37/* Accessor functions */ 39/* Accessor functions */
38 40
39static ssize_t show_ec_reboot(struct device *dev, 41static ssize_t reboot_show(struct device *dev,
40 struct device_attribute *attr, char *buf) 42 struct device_attribute *attr, char *buf)
41{ 43{
42 int count = 0; 44 int count = 0;
43 45
@@ -48,9 +50,9 @@ static ssize_t show_ec_reboot(struct device *dev,
48 return count; 50 return count;
49} 51}
50 52
51static ssize_t store_ec_reboot(struct device *dev, 53static ssize_t reboot_store(struct device *dev,
52 struct device_attribute *attr, 54 struct device_attribute *attr,
53 const char *buf, size_t count) 55 const char *buf, size_t count)
54{ 56{
55 static const struct { 57 static const struct {
56 const char * const str; 58 const char * const str;
@@ -70,8 +72,7 @@ static ssize_t store_ec_reboot(struct device *dev,
70 int got_cmd = 0, offset = 0; 72 int got_cmd = 0, offset = 0;
71 int i; 73 int i;
72 int ret; 74 int ret;
73 struct cros_ec_dev *ec = container_of(dev, 75 struct cros_ec_dev *ec = to_cros_ec_dev(dev);
74 struct cros_ec_dev, class_dev);
75 76
76 msg = kmalloc(sizeof(*msg) + sizeof(*param), GFP_KERNEL); 77 msg = kmalloc(sizeof(*msg) + sizeof(*param), GFP_KERNEL);
77 if (!msg) 78 if (!msg)
@@ -114,22 +115,16 @@ static ssize_t store_ec_reboot(struct device *dev,
114 msg->command = EC_CMD_REBOOT_EC + ec->cmd_offset; 115 msg->command = EC_CMD_REBOOT_EC + ec->cmd_offset;
115 msg->outsize = sizeof(*param); 116 msg->outsize = sizeof(*param);
116 msg->insize = 0; 117 msg->insize = 0;
117 ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 118 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
118 if (ret < 0) { 119 if (ret < 0)
119 count = ret; 120 count = ret;
120 goto exit;
121 }
122 if (msg->result != EC_RES_SUCCESS) {
123 dev_dbg(ec->dev, "EC result %d\n", msg->result);
124 count = -EINVAL;
125 }
126exit: 121exit:
127 kfree(msg); 122 kfree(msg);
128 return count; 123 return count;
129} 124}
130 125
131static ssize_t show_ec_version(struct device *dev, 126static ssize_t version_show(struct device *dev,
132 struct device_attribute *attr, char *buf) 127 struct device_attribute *attr, char *buf)
133{ 128{
134 static const char * const image_names[] = {"unknown", "RO", "RW"}; 129 static const char * const image_names[] = {"unknown", "RO", "RW"};
135 struct ec_response_get_version *r_ver; 130 struct ec_response_get_version *r_ver;
@@ -138,8 +133,7 @@ static ssize_t show_ec_version(struct device *dev,
138 struct cros_ec_command *msg; 133 struct cros_ec_command *msg;
139 int ret; 134 int ret;
140 int count = 0; 135 int count = 0;
141 struct cros_ec_dev *ec = container_of(dev, 136 struct cros_ec_dev *ec = to_cros_ec_dev(dev);
142 struct cros_ec_dev, class_dev);
143 137
144 msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL); 138 msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL);
145 if (!msg) 139 if (!msg)
@@ -150,17 +144,11 @@ static ssize_t show_ec_version(struct device *dev,
150 msg->command = EC_CMD_GET_VERSION + ec->cmd_offset; 144 msg->command = EC_CMD_GET_VERSION + ec->cmd_offset;
151 msg->insize = sizeof(*r_ver); 145 msg->insize = sizeof(*r_ver);
152 msg->outsize = 0; 146 msg->outsize = 0;
153 ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 147 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
154 if (ret < 0) { 148 if (ret < 0) {
155 count = ret; 149 count = ret;
156 goto exit; 150 goto exit;
157 } 151 }
158 if (msg->result != EC_RES_SUCCESS) {
159 count = scnprintf(buf, PAGE_SIZE,
160 "ERROR: EC returned %d\n", msg->result);
161 goto exit;
162 }
163
164 r_ver = (struct ec_response_get_version *)msg->data; 152 r_ver = (struct ec_response_get_version *)msg->data;
165 /* Strings should be null-terminated, but let's be sure. */ 153 /* Strings should be null-terminated, but let's be sure. */
166 r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0'; 154 r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0';
@@ -237,14 +225,13 @@ exit:
237 return count; 225 return count;
238} 226}
239 227
240static ssize_t show_ec_flashinfo(struct device *dev, 228static ssize_t flashinfo_show(struct device *dev,
241 struct device_attribute *attr, char *buf) 229 struct device_attribute *attr, char *buf)
242{ 230{
243 struct ec_response_flash_info *resp; 231 struct ec_response_flash_info *resp;
244 struct cros_ec_command *msg; 232 struct cros_ec_command *msg;
245 int ret; 233 int ret;
246 struct cros_ec_dev *ec = container_of(dev, 234 struct cros_ec_dev *ec = to_cros_ec_dev(dev);
247 struct cros_ec_dev, class_dev);
248 235
249 msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL); 236 msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL);
250 if (!msg) 237 if (!msg)
@@ -255,14 +242,9 @@ static ssize_t show_ec_flashinfo(struct device *dev,
255 msg->command = EC_CMD_FLASH_INFO + ec->cmd_offset; 242 msg->command = EC_CMD_FLASH_INFO + ec->cmd_offset;
256 msg->insize = sizeof(*resp); 243 msg->insize = sizeof(*resp);
257 msg->outsize = 0; 244 msg->outsize = 0;
258 ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 245 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
259 if (ret < 0) 246 if (ret < 0)
260 goto exit; 247 goto exit;
261 if (msg->result != EC_RES_SUCCESS) {
262 ret = scnprintf(buf, PAGE_SIZE,
263 "ERROR: EC returned %d\n", msg->result);
264 goto exit;
265 }
266 248
267 resp = (struct ec_response_flash_info *)msg->data; 249 resp = (struct ec_response_flash_info *)msg->data;
268 250
@@ -276,21 +258,102 @@ exit:
276 return ret; 258 return ret;
277} 259}
278 260
261/* Keyboard wake angle control */
262static ssize_t kb_wake_angle_show(struct device *dev,
263 struct device_attribute *attr, char *buf)
264{
265 struct cros_ec_dev *ec = to_cros_ec_dev(dev);
266 struct ec_response_motion_sense *resp;
267 struct ec_params_motion_sense *param;
268 struct cros_ec_command *msg;
269 int ret;
270
271 msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL);
272 if (!msg)
273 return -ENOMEM;
274
275 param = (struct ec_params_motion_sense *)msg->data;
276 msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
277 msg->version = 2;
278 param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE;
279 param->kb_wake_angle.data = EC_MOTION_SENSE_NO_VALUE;
280 msg->outsize = sizeof(*param);
281 msg->insize = sizeof(*resp);
282
283 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
284 if (ret < 0)
285 goto exit;
286
287 resp = (struct ec_response_motion_sense *)msg->data;
288 ret = scnprintf(buf, PAGE_SIZE, "%d\n", resp->kb_wake_angle.ret);
289exit:
290 kfree(msg);
291 return ret;
292}
293
294static ssize_t kb_wake_angle_store(struct device *dev,
295 struct device_attribute *attr,
296 const char *buf, size_t count)
297{
298 struct cros_ec_dev *ec = to_cros_ec_dev(dev);
299 struct ec_params_motion_sense *param;
300 struct cros_ec_command *msg;
301 u16 angle;
302 int ret;
303
304 ret = kstrtou16(buf, 0, &angle);
305 if (ret)
306 return ret;
307
308 msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL);
309 if (!msg)
310 return -ENOMEM;
311
312 param = (struct ec_params_motion_sense *)msg->data;
313 msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
314 msg->version = 2;
315 param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE;
316 param->kb_wake_angle.data = angle;
317 msg->outsize = sizeof(*param);
318 msg->insize = sizeof(struct ec_response_motion_sense);
319
320 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
321 kfree(msg);
322 if (ret < 0)
323 return ret;
324 return count;
325}
326
279/* Module initialization */ 327/* Module initialization */
280 328
281static DEVICE_ATTR(reboot, S_IWUSR | S_IRUGO, show_ec_reboot, store_ec_reboot); 329static DEVICE_ATTR_RW(reboot);
282static DEVICE_ATTR(version, S_IRUGO, show_ec_version, NULL); 330static DEVICE_ATTR_RO(version);
283static DEVICE_ATTR(flashinfo, S_IRUGO, show_ec_flashinfo, NULL); 331static DEVICE_ATTR_RO(flashinfo);
332static DEVICE_ATTR_RW(kb_wake_angle);
284 333
285static struct attribute *__ec_attrs[] = { 334static struct attribute *__ec_attrs[] = {
335 &dev_attr_kb_wake_angle.attr,
286 &dev_attr_reboot.attr, 336 &dev_attr_reboot.attr,
287 &dev_attr_version.attr, 337 &dev_attr_version.attr,
288 &dev_attr_flashinfo.attr, 338 &dev_attr_flashinfo.attr,
289 NULL, 339 NULL,
290}; 340};
291 341
342static umode_t cros_ec_ctrl_visible(struct kobject *kobj,
343 struct attribute *a, int n)
344{
345 struct device *dev = container_of(kobj, struct device, kobj);
346 struct cros_ec_dev *ec = to_cros_ec_dev(dev);
347
348 if (a == &dev_attr_kb_wake_angle.attr && !ec->has_kb_wake_angle)
349 return 0;
350
351 return a->mode;
352}
353
292struct attribute_group cros_ec_attr_group = { 354struct attribute_group cros_ec_attr_group = {
293 .attrs = __ec_attrs, 355 .attrs = __ec_attrs,
356 .is_visible = cros_ec_ctrl_visible,
294}; 357};
295EXPORT_SYMBOL(cros_ec_attr_group); 358EXPORT_SYMBOL(cros_ec_attr_group);
296 359