acer-wmi: Add debugfs file for device detection
authorCarlos Corbacho <carlos@strangeworlds.co.uk>
Sat, 21 Jun 2008 08:09:53 +0000 (09:09 +0100)
committerAndi Kleen <andi@basil.nowhere.org>
Wed, 16 Jul 2008 21:27:02 +0000 (23:27 +0200)
Add a debugfs file for showing the full results of the method we use to
detect devices on WMID laptops.

This should be useful in the case that a Linux user gets an Acer laptop
with 3G support (and/ or people who enjoy ripping their wireless cards out)
so we can get some feedback on how this value changes in these cases.

(At the moment, we always enable the wireless and 3G control. In the case
of the former, this is fairly safe. In the case of the latter though,
trying to toggle this device if it doesn't exist on a laptop causes ACPI
warnings/ errors).

To summarise: If you have an Acer laptop with a built in 3G card, please
report back the value from this file.

Signed-off-by: Carlos Corbacho <carlos@strangeworlds.co.uk>
Signed-off-by: Len Brown <len.brown@intel.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
drivers/misc/acer-wmi.c

index dd0b8d8b5bd96fa51e5035b83f0f75b8a3e793ed..d8b8574e303c46ade8cad89dec64f09a9cf582ba 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
 #include <linux/i8042.h>
+#include <linux/debugfs.h>
 
 #include <acpi/acpi_drivers.h>
 
@@ -152,6 +153,12 @@ struct acer_data {
        int brightness;
 };
 
+struct acer_debug {
+       struct dentry *root;
+       struct dentry *devices;
+       u32 wmid_devices;
+};
+
 /* Each low-level interface must define at least some of the following */
 struct wmi_interface {
        /* The WMI device type */
@@ -162,6 +169,9 @@ struct wmi_interface {
 
        /* Private data for the current interface */
        struct acer_data data;
+
+       /* debugfs entries associated with this interface */
+       struct acer_debug debug;
 };
 
 /* The static interface pointer, points to the currently detected interface */
@@ -955,6 +965,28 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
 static DEVICE_ATTR(interface, S_IWUGO | S_IRUGO | S_IWUSR,
        show_interface, NULL);
 
+/*
+ * debugfs functions
+ */
+static u32 get_wmid_devices(void)
+{
+       struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
+       union acpi_object *obj;
+       acpi_status status;
+
+       status = wmi_query_block(WMID_GUID2, 1, &out);
+       if (ACPI_FAILURE(status))
+               return 0;
+
+       obj = (union acpi_object *) out.pointer;
+       if (obj && obj->type == ACPI_TYPE_BUFFER &&
+               obj->buffer.length == sizeof(u32)) {
+               return *((u32 *) obj->buffer.pointer);
+       } else {
+               return 0;
+       }
+}
+
 /*
  * Platform device
  */
@@ -1114,6 +1146,33 @@ error_sysfs:
        return retval;
 }
 
+static void remove_debugfs(void)
+{
+       debugfs_remove(interface->debug.devices);
+       debugfs_remove(interface->debug.root);
+}
+
+static int create_debugfs(void)
+{
+       interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
+       if (!interface->debug.root) {
+               printk(ACER_ERR "Failed to create debugfs directory");
+               return -ENOMEM;
+       }
+
+       interface->debug.devices = debugfs_create_u32("devices", S_IRUGO,
+                                       interface->debug.root,
+                                       &interface->debug.wmid_devices);
+       if (!interface->debug.devices)
+               goto error_debugfs;
+
+       return 0;
+
+error_debugfs:
+               remove_debugfs();
+       return -ENOMEM;
+}
+
 static int __init acer_wmi_init(void)
 {
        int err;
@@ -1173,6 +1232,13 @@ static int __init acer_wmi_init(void)
        if (err)
                return err;
 
+       if (wmi_has_guid(WMID_GUID2)) {
+               interface->debug.wmid_devices = get_wmid_devices();
+               err = create_debugfs();
+               if (err)
+                       return err;
+       }
+
        /* Override any initial settings with values from the commandline */
        acer_commandline_init();