diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-05-26 18:05:23 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-05-26 18:05:23 -0400 |
commit | 0775a60aca2375ea5598741b30d13fe6d3f15617 (patch) | |
tree | ba7cf639955af770f02b72ab80805ae10b43fd10 /kernel | |
parent | f42a9813fbf930fea3bdd0524dcb43c7feb0c977 (diff) |
PM: Fix PM QOS's user mode interface to work with ASCII input
Make pm_qos_power_write() accept values passed to it in the ASCII hex
format either with or without an ending newline.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Mark Gross <markgross@thegnar.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/pm_qos_params.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 0da058bff8eb..68df076fec5d 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
41 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/kernel.h> | ||
43 | 44 | ||
44 | #include <linux/uaccess.h> | 45 | #include <linux/uaccess.h> |
45 | 46 | ||
@@ -404,24 +405,36 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, | |||
404 | size_t count, loff_t *f_pos) | 405 | size_t count, loff_t *f_pos) |
405 | { | 406 | { |
406 | s32 value; | 407 | s32 value; |
407 | int x; | ||
408 | char ascii_value[11]; | ||
409 | struct pm_qos_request_list *pm_qos_req; | 408 | struct pm_qos_request_list *pm_qos_req; |
410 | 409 | ||
411 | if (count == sizeof(s32)) { | 410 | if (count == sizeof(s32)) { |
412 | if (copy_from_user(&value, buf, sizeof(s32))) | 411 | if (copy_from_user(&value, buf, sizeof(s32))) |
413 | return -EFAULT; | 412 | return -EFAULT; |
414 | } else if (count == 11) { /* len('0x12345678/0') */ | 413 | } else if (count <= 11) { /* ASCII perhaps? */ |
415 | if (copy_from_user(ascii_value, buf, 11)) | 414 | char ascii_value[11]; |
415 | unsigned long int ulval; | ||
416 | int ret; | ||
417 | |||
418 | if (copy_from_user(ascii_value, buf, count)) | ||
416 | return -EFAULT; | 419 | return -EFAULT; |
417 | if (strlen(ascii_value) != 10) | 420 | |
418 | return -EINVAL; | 421 | if (count > 10) { |
419 | x = sscanf(ascii_value, "%x", &value); | 422 | if (ascii_value[10] == '\n') |
420 | if (x != 1) | 423 | ascii_value[10] = '\0'; |
424 | else | ||
425 | return -EINVAL; | ||
426 | } else { | ||
427 | ascii_value[count] = '\0'; | ||
428 | } | ||
429 | ret = strict_strtoul(ascii_value, 16, &ulval); | ||
430 | if (ret) { | ||
431 | pr_debug("%s, 0x%lx, 0x%x\n", ascii_value, ulval, ret); | ||
421 | return -EINVAL; | 432 | return -EINVAL; |
422 | pr_debug("%s, %d, 0x%x\n", ascii_value, x, value); | 433 | } |
423 | } else | 434 | value = (s32)lower_32_bits(ulval); |
435 | } else { | ||
424 | return -EINVAL; | 436 | return -EINVAL; |
437 | } | ||
425 | 438 | ||
426 | pm_qos_req = filp->private_data; | 439 | pm_qos_req = filp->private_data; |
427 | pm_qos_update_request(pm_qos_req, value); | 440 | pm_qos_update_request(pm_qos_req, value); |