summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorCorentin Chary <corentincj@iksaif.net>2009-06-16 19:28:56 +0000
committerLen Brown <len.brown@intel.com>2009-06-24 01:31:21 -0400
commitb31d0fde89c905673ceed0404d5ae24f2261d7c7 (patch)
tree55d1208a733f5e8fc0c025edba9c3359815a7164 /drivers
parentb7b700d4a473d56103e87e341ad555e8a7cce06d (diff)
eeepc-laptop: cpufv updates
Limit cpufv input to acceptables values. Add an available_cpufv file to show available presets. Change cpufv ouput format from %d to %#x, it won't break compatibility with existing userspace tools, but it provide a more human readable output. Signed-off-by: Corentin Chary <corentincj@iksaif.net> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/eeepc-laptop.c77
1 files changed, 76 insertions, 1 deletions
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 73f3cb0fd76..4207b26ff99 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)
EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
-EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV);
+
+struct eeepc_cpufv {
+ int num;
+ int cur;
+};
+
+static int get_cpufv(struct eeepc_cpufv *c)
+{
+ c->cur = get_acpi(CM_ASL_CPUFV);
+ c->num = (c->cur >> 8) & 0xff;
+ c->cur &= 0xff;
+ if (c->cur < 0 || c->num <= 0 || c->num > 12)
+ return -ENODEV;
+ return 0;
+}
+
+static ssize_t show_available_cpufv(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct eeepc_cpufv c;
+ int i;
+ ssize_t len = 0;
+
+ if (get_cpufv(&c))
+ return -ENODEV;
+ for (i = 0; i < c.num; i++)
+ len += sprintf(buf + len, "%d ", i);
+ len += sprintf(buf + len, "\n");
+ return len;
+}
+
+static ssize_t show_cpufv(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct eeepc_cpufv c;
+
+ if (get_cpufv(&c))
+ return -ENODEV;
+ return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
+}
+
+static ssize_t store_cpufv(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct eeepc_cpufv c;
+ int rv, value;
+
+ if (get_cpufv(&c))
+ return -ENODEV;
+ rv = parse_arg(buf, count, &value);
+ if (rv < 0)
+ return rv;
+ if (!rv || value < 0 || value >= c.num)
+ return -EINVAL;
+ set_acpi(CM_ASL_CPUFV, value);
+ return rv;
+}
+
+static struct device_attribute dev_attr_cpufv = {
+ .attr = {
+ .name = "cpufv",
+ .mode = 0644 },
+ .show = show_cpufv,
+ .store = store_cpufv
+};
+
+static struct device_attribute dev_attr_available_cpufv = {
+ .attr = {
+ .name = "available_cpufv",
+ .mode = 0444 },
+ .show = show_available_cpufv
+};
static struct attribute *platform_attributes[] = {
&dev_attr_camera.attr,
&dev_attr_cardr.attr,
&dev_attr_disp.attr,
&dev_attr_cpufv.attr,
+ &dev_attr_available_cpufv.attr,
NULL
};