aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKeng-Yu Lin <keng-yu.lin@canonical.com>2010-09-27 23:43:31 -0400
committerMatthew Garrett <mjg@redhat.com>2010-10-21 09:36:49 -0400
commit037accfa14b28ecf49d9060063929c4b4cde373f (patch)
tree5efaeb97e507105dd08e19367ea3574274e2b0bc /drivers
parentc64eefd48c44fa8145ad1f96edabf4a053fffc49 (diff)
dell-laptop: Add debugfs support
Export the status of RF killswitch through debugfs. The killswitch status is obtained by the SMI to BIOS. Exporting this status through debugfs can help identify the issue with the misbehaving firmware. Signed-off-by: Keng-Yu Lin <keng-yu.lin@canonical.com> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/dell-laptop.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 4413975912e0..cf8a89a0d8f5 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -25,6 +25,8 @@
25#include <linux/mm.h> 25#include <linux/mm.h>
26#include <linux/i8042.h> 26#include <linux/i8042.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/debugfs.h>
29#include <linux/seq_file.h>
28#include "../../firmware/dcdbas.h" 30#include "../../firmware/dcdbas.h"
29 31
30#define BRIGHTNESS_TOKEN 0x7d 32#define BRIGHTNESS_TOKEN 0x7d
@@ -325,6 +327,75 @@ static const struct rfkill_ops dell_rfkill_ops = {
325 .query = dell_rfkill_query, 327 .query = dell_rfkill_query,
326}; 328};
327 329
330static struct dentry *dell_laptop_dir;
331
332static int dell_debugfs_show(struct seq_file *s, void *data)
333{
334 int status;
335
336 get_buffer();
337 dell_send_request(buffer, 17, 11);
338 status = buffer->output[1];
339 release_buffer();
340
341 seq_printf(s, "status:\t0x%X\n", status);
342 seq_printf(s, "Bit 0 : Hardware switch supported: %lu\n",
343 status & BIT(0));
344 seq_printf(s, "Bit 1 : Wifi locator supported: %lu\n",
345 (status & BIT(1)) >> 1);
346 seq_printf(s, "Bit 2 : Wifi is supported: %lu\n",
347 (status & BIT(2)) >> 2);
348 seq_printf(s, "Bit 3 : Bluetooth is supported: %lu\n",
349 (status & BIT(3)) >> 3);
350 seq_printf(s, "Bit 4 : WWAN is supported: %lu\n",
351 (status & BIT(4)) >> 4);
352 seq_printf(s, "Bit 5 : Wireless keyboard supported: %lu\n",
353 (status & BIT(5)) >> 5);
354 seq_printf(s, "Bit 8 : Wifi is installed: %lu\n",
355 (status & BIT(8)) >> 8);
356 seq_printf(s, "Bit 9 : Bluetooth is installed: %lu\n",
357 (status & BIT(9)) >> 9);
358 seq_printf(s, "Bit 10: WWAN is installed: %lu\n",
359 (status & BIT(10)) >> 10);
360 seq_printf(s, "Bit 16: Hardware switch is on: %lu\n",
361 (status & BIT(16)) >> 16);
362 seq_printf(s, "Bit 17: Wifi is blocked: %lu\n",
363 (status & BIT(17)) >> 17);
364 seq_printf(s, "Bit 18: Bluetooth is blocked: %lu\n",
365 (status & BIT(18)) >> 18);
366 seq_printf(s, "Bit 19: WWAN is blocked: %lu\n",
367 (status & BIT(19)) >> 19);
368
369 seq_printf(s, "\nhwswitch_state:\t0x%X\n", hwswitch_state);
370 seq_printf(s, "Bit 0 : Wifi controlled by switch: %lu\n",
371 hwswitch_state & BIT(0));
372 seq_printf(s, "Bit 1 : Bluetooth controlled by switch: %lu\n",
373 (hwswitch_state & BIT(1)) >> 1);
374 seq_printf(s, "Bit 2 : WWAN controlled by switch: %lu\n",
375 (hwswitch_state & BIT(2)) >> 2);
376 seq_printf(s, "Bit 7 : Wireless switch config locked: %lu\n",
377 (hwswitch_state & BIT(7)) >> 7);
378 seq_printf(s, "Bit 8 : Wifi locator enabled: %lu\n",
379 (hwswitch_state & BIT(8)) >> 8);
380 seq_printf(s, "Bit 15: Wifi locator setting locked: %lu\n",
381 (hwswitch_state & BIT(15)) >> 15);
382
383 return 0;
384}
385
386static int dell_debugfs_open(struct inode *inode, struct file *file)
387{
388 return single_open(file, dell_debugfs_show, inode->i_private);
389}
390
391static const struct file_operations dell_debugfs_fops = {
392 .owner = THIS_MODULE,
393 .open = dell_debugfs_open,
394 .read = seq_read,
395 .llseek = seq_lseek,
396 .release = single_release,
397};
398
328static void dell_update_rfkill(struct work_struct *ignored) 399static void dell_update_rfkill(struct work_struct *ignored)
329{ 400{
330 if (wifi_rfkill) 401 if (wifi_rfkill)
@@ -556,6 +627,11 @@ static int __init dell_init(void)
556 goto fail_filter; 627 goto fail_filter;
557 } 628 }
558 629
630 dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL);
631 if (dell_laptop_dir != NULL)
632 debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL,
633 &dell_debugfs_fops);
634
559#ifdef CONFIG_ACPI 635#ifdef CONFIG_ACPI
560 /* In the event of an ACPI backlight being available, don't 636 /* In the event of an ACPI backlight being available, don't
561 * register the platform controller. 637 * register the platform controller.
@@ -615,6 +691,7 @@ fail_platform_driver:
615 691
616static void __exit dell_exit(void) 692static void __exit dell_exit(void)
617{ 693{
694 debugfs_remove_recursive(dell_laptop_dir);
618 i8042_remove_filter(dell_laptop_i8042_filter); 695 i8042_remove_filter(dell_laptop_i8042_filter);
619 cancel_delayed_work_sync(&dell_rfkill_work); 696 cancel_delayed_work_sync(&dell_rfkill_work);
620 backlight_device_unregister(dell_backlight_device); 697 backlight_device_unregister(dell_backlight_device);