diff options
| -rw-r--r-- | drivers/platform/x86/eeepc-laptop.c | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 73f3cb0fd76c..4207b26ff990 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
| @@ -392,13 +392,88 @@ static ssize_t show_sys_acpi(int cm, char *buf) | |||
| 392 | EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); | 392 | EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); |
| 393 | EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); | 393 | EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); |
| 394 | EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); | 394 | EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); |
| 395 | EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV); | 395 | |
| 396 | struct eeepc_cpufv { | ||
| 397 | int num; | ||
| 398 | int cur; | ||
| 399 | }; | ||
| 400 | |||
| 401 | static int get_cpufv(struct eeepc_cpufv *c) | ||
| 402 | { | ||
| 403 | c->cur = get_acpi(CM_ASL_CPUFV); | ||
| 404 | c->num = (c->cur >> 8) & 0xff; | ||
| 405 | c->cur &= 0xff; | ||
| 406 | if (c->cur < 0 || c->num <= 0 || c->num > 12) | ||
| 407 | return -ENODEV; | ||
| 408 | return 0; | ||
| 409 | } | ||
| 410 | |||
| 411 | static ssize_t show_available_cpufv(struct device *dev, | ||
| 412 | struct device_attribute *attr, | ||
| 413 | char *buf) | ||
| 414 | { | ||
| 415 | struct eeepc_cpufv c; | ||
| 416 | int i; | ||
| 417 | ssize_t len = 0; | ||
| 418 | |||
| 419 | if (get_cpufv(&c)) | ||
| 420 | return -ENODEV; | ||
| 421 | for (i = 0; i < c.num; i++) | ||
| 422 | len += sprintf(buf + len, "%d ", i); | ||
| 423 | len += sprintf(buf + len, "\n"); | ||
| 424 | return len; | ||
| 425 | } | ||
| 426 | |||
| 427 | static ssize_t show_cpufv(struct device *dev, | ||
| 428 | struct device_attribute *attr, | ||
| 429 | char *buf) | ||
| 430 | { | ||
| 431 | struct eeepc_cpufv c; | ||
| 432 | |||
| 433 | if (get_cpufv(&c)) | ||
| 434 | return -ENODEV; | ||
| 435 | return sprintf(buf, "%#x\n", (c.num << 8) | c.cur); | ||
| 436 | } | ||
| 437 | |||
| 438 | static ssize_t store_cpufv(struct device *dev, | ||
| 439 | struct device_attribute *attr, | ||
| 440 | const char *buf, size_t count) | ||
| 441 | { | ||
| 442 | struct eeepc_cpufv c; | ||
| 443 | int rv, value; | ||
| 444 | |||
| 445 | if (get_cpufv(&c)) | ||
| 446 | return -ENODEV; | ||
| 447 | rv = parse_arg(buf, count, &value); | ||
| 448 | if (rv < 0) | ||
| 449 | return rv; | ||
| 450 | if (!rv || value < 0 || value >= c.num) | ||
| 451 | return -EINVAL; | ||
| 452 | set_acpi(CM_ASL_CPUFV, value); | ||
| 453 | return rv; | ||
| 454 | } | ||
| 455 | |||
| 456 | static struct device_attribute dev_attr_cpufv = { | ||
| 457 | .attr = { | ||
| 458 | .name = "cpufv", | ||
| 459 | .mode = 0644 }, | ||
| 460 | .show = show_cpufv, | ||
| 461 | .store = store_cpufv | ||
| 462 | }; | ||
| 463 | |||
| 464 | static struct device_attribute dev_attr_available_cpufv = { | ||
| 465 | .attr = { | ||
| 466 | .name = "available_cpufv", | ||
| 467 | .mode = 0444 }, | ||
| 468 | .show = show_available_cpufv | ||
| 469 | }; | ||
| 396 | 470 | ||
| 397 | static struct attribute *platform_attributes[] = { | 471 | static struct attribute *platform_attributes[] = { |
| 398 | &dev_attr_camera.attr, | 472 | &dev_attr_camera.attr, |
| 399 | &dev_attr_cardr.attr, | 473 | &dev_attr_cardr.attr, |
| 400 | &dev_attr_disp.attr, | 474 | &dev_attr_disp.attr, |
| 401 | &dev_attr_cpufv.attr, | 475 | &dev_attr_cpufv.attr, |
| 476 | &dev_attr_available_cpufv.attr, | ||
| 402 | NULL | 477 | NULL |
| 403 | }; | 478 | }; |
| 404 | 479 | ||
