Add patches accepted for 2.6.26-rc1
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / releases / upstream / 2.6.26-rc1 / 0009-ACPI-thinkpad-acpi-add-sysfs-led-class-support-for.patch
blob70815d32b6267a58731249aea15a85dc39642903
1 From e306501d1c4ff610feaba74ac35dd13e470480e6 Mon Sep 17 00:00:00 2001
2 From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
3 Date: Sat, 26 Apr 2008 01:02:24 -0300
4 Subject: ACPI: thinkpad-acpi: add sysfs led class support for thinklight (v3.1)
6 Add a sysfs led class interface to the thinklight (light subdriver).
8 Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
9 Cc: Richard Purdie <rpurdie@rpsys.net>
10 Signed-off-by: Len Brown <len.brown@intel.com>
11 ---
12 Documentation/laptops/thinkpad-acpi.txt | 25 +++++++++++---
13 drivers/misc/thinkpad_acpi.c | 57 ++++++++++++++++++++++++++++++-
14 2 files changed, 76 insertions(+), 6 deletions(-)
16 diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
17 index a41bc89..af1f2bc 100644
18 --- a/Documentation/laptops/thinkpad-acpi.txt
19 +++ b/Documentation/laptops/thinkpad-acpi.txt
20 @@ -693,16 +693,31 @@ while others are still having problems. For more information:
22 https://bugs.freedesktop.org/show_bug.cgi?id=2000
24 -ThinkLight control -- /proc/acpi/ibm/light
25 -------------------------------------------
26 +ThinkLight control
27 +------------------
29 +procfs: /proc/acpi/ibm/light
30 +sysfs attributes: as per led class, for the "tpacpi::thinklight" led
32 +procfs notes:
34 -The current status of the ThinkLight can be found in this file. A few
35 -models which do not make the status available will show it as
36 -"unknown". The available commands are:
37 +The ThinkLight status can be read and set through the procfs interface. A
38 +few models which do not make the status available will show the ThinkLight
39 +status as "unknown". The available commands are:
41 echo on > /proc/acpi/ibm/light
42 echo off > /proc/acpi/ibm/light
44 +sysfs notes:
46 +The ThinkLight sysfs interface is documented by the led class
47 +documentation, in Documentation/leds-class.txt. The ThinkLight led name
48 +is "tpacpi::thinklight".
50 +Due to limitations in the sysfs led class, if the status of the thinklight
51 +cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
52 +It is impossible to know if the status returned through sysfs is valid.
54 Docking / undocking -- /proc/acpi/ibm/dock
55 ------------------------------------------
57 diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
58 index 5a3fb09..38a119b 100644
59 --- a/drivers/misc/thinkpad_acpi.c
60 +++ b/drivers/misc/thinkpad_acpi.c
61 @@ -3280,13 +3280,49 @@ static int light_set_status(int status)
62 return -ENXIO;
65 +static void light_set_status_worker(struct work_struct *work)
67 + struct tpacpi_led_classdev *data =
68 + container_of(work, struct tpacpi_led_classdev, work);
70 + if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
71 + light_set_status((data->new_brightness != LED_OFF));
74 +static void light_sysfs_set(struct led_classdev *led_cdev,
75 + enum led_brightness brightness)
77 + struct tpacpi_led_classdev *data =
78 + container_of(led_cdev,
79 + struct tpacpi_led_classdev,
80 + led_classdev);
81 + data->new_brightness = brightness;
82 + schedule_work(&data->work);
85 +static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
87 + return (light_get_status() == 1)? LED_FULL : LED_OFF;
90 +static struct tpacpi_led_classdev tpacpi_led_thinklight = {
91 + .led_classdev = {
92 + .name = "tpacpi::thinklight",
93 + .brightness_set = &light_sysfs_set,
94 + .brightness_get = &light_sysfs_get,
95 + }
96 +};
98 static int __init light_init(struct ibm_init_struct *iibm)
100 + int rc = 0;
102 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
104 TPACPI_ACPIHANDLE_INIT(ledb);
105 TPACPI_ACPIHANDLE_INIT(lght);
106 TPACPI_ACPIHANDLE_INIT(cmos);
107 + INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker);
109 /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
110 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
111 @@ -3300,7 +3336,25 @@ static int __init light_init(struct ibm_init_struct *iibm)
112 vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
113 str_supported(tp_features.light));
115 - return (tp_features.light)? 0 : 1;
116 + if (tp_features.light) {
117 + rc = led_classdev_register(&tpacpi_pdev->dev,
118 + &tpacpi_led_thinklight.led_classdev);
121 + if (rc < 0) {
122 + tp_features.light = 0;
123 + tp_features.light_status = 0;
124 + } else {
125 + rc = (tp_features.light)? 0 : 1;
127 + return rc;
130 +static void light_exit(void)
132 + led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);
133 + if (work_pending(&tpacpi_led_thinklight.work))
134 + flush_scheduled_work();
137 static int light_read(char *p)
138 @@ -3348,6 +3402,7 @@ static struct ibm_struct light_driver_data = {
139 .name = "light",
140 .read = light_read,
141 .write = light_write,
142 + .exit = light_exit,
145 /*************************************************************************
147 1.5.4.4