* [PATCH 01/14] ACPI: thinkpad-acpi: BIOS backlight mode helper (v2.1)
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 02/14] ACPI: thinkpad-acpi: warn once about weird hotkey masks Henrique de Moraes Holschuh
` (13 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown
Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh,
Matthew Garrett, Thomas Renninger
Lenovo ThinkPads with generic ACPI backlight level control can be easily
set to react to keyboard brightness key presses in a more predictable way
than what they do when in "DOS / bootloader" mode after Linux brings
up the ACPI interface.
The switch to the ACPI backlight mode in the firmware is designed to be
safe to use only as an one way trapdoor. One is not to force the firmware
to switch back to "DOS/bootloader" mode except by rebooting. The mode
switch itself is performed by calling any of the ACPI _BCL methods at least
once.
When in ACPI mode, the backlight firmware just issues (standard) events for
the brightness up/down hot key presses along with the non-standard HKEY
events which thinkpad-acpi traps, and doesn't touch the hardware.
thinkpad-acpi will:
1. Place the ThinkPad firmware in ACPI backlight control mode
if one is available
2. Suppress HKEY backlight change notifications by default
to avoid double-reporting when ACPI video is loaded when
the ThinkPad is in ACPI backlight control mode
3. Urge the user to load the ACPI video driver
The user is free to use either the ACPI video driver to get the brightness
key events, or to override the thinkpad-acpi default hotkey mask to get
them from thinkpad-acpi as well (this will result in duplicate events if
ACPI video is loaded, so let's hope distros won't screw this up).
Provided userspace is sane, all should work (and *keep* working), which is
more that can be said about the non-ACPI mode of the new Lenovo ThinkPad
BIOSes when coupled to current userspace and X.org drivers.
Full guidelines for backlight hot key reporting and use of the
thinkpad-acpi backlight interface have been added to the documentation.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Thomas Renninger <trenn@suse.de>
---
Documentation/laptops/thinkpad-acpi.txt | 50 +++++++
drivers/misc/thinkpad_acpi.c | 238 +++++++++++++++++--------------
2 files changed, 183 insertions(+), 105 deletions(-)
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 76cb428..a77da28 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -571,6 +571,47 @@ netlink interface and the input layer interface, and don't bother at all
with hotkey_report_mode.
+Brightness hotkey notes:
+
+These are the current sane choices for brightness key mapping in
+thinkpad-acpi:
+
+For IBM and Lenovo models *without* ACPI backlight control (the ones on
+which thinkpad-acpi will autoload its backlight interface by default,
+and on which ACPI video does not export a backlight interface):
+
+1. Don't enable or map the brightness hotkeys in thinkpad-acpi, as
+ these older firmware versions unfortunately won't respect the hotkey
+ mask for brightness keys anyway, and always reacts to them. This
+ usually work fine, unless X.org drivers are doing something to block
+ the BIOS. In that case, use (3) below. This is the default mode of
+ operation.
+
+2. Enable the hotkeys, but map them to something else that is NOT
+ KEY_BRIGHTNESS_UP/DOWN or any other keycode that would cause
+ userspace to try to change the backlight level, and use that as an
+ on-screen-display hint.
+
+3. IF AND ONLY IF X.org drivers find a way to block the firmware from
+ automatically changing the brightness, enable the hotkeys and map
+ them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN, and feed that to
+ something that calls xbacklight. thinkpad-acpi will not be able to
+ change brightness in that case either, so you should disable its
+ backlight interface.
+
+For Lenovo models *with* ACPI backlight control:
+
+1. Load up ACPI video and use that. ACPI video will report ACPI
+ events for brightness change keys. Do not mess with thinkpad-acpi
+ defaults in this case. thinkpad-acpi should not have anything to do
+ with backlight events in a scenario where ACPI video is loaded:
+ brightness hotkeys must be disabled, and the backlight interface is
+ to be kept disabled as well. This is the default mode of operation.
+
+2. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi,
+ and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process
+ these keys on userspace somehow (e.g. by calling xbacklight).
+
Bluetooth
---------
@@ -1090,6 +1131,15 @@ it there will be the following attributes:
dim the display.
+WARNING:
+
+ Whatever you do, do NOT ever call thinkpad-acpi backlight-level change
+ interface and the ACPI-based backlight level change interface
+ (available on newer BIOSes, and driven by the Linux ACPI video driver)
+ at the same time. The two will interact in bad ways, do funny things,
+ and maybe reduce the life of the backlight lamps by needlessly kicking
+ its level up and down at every change.
+
Volume control -- /proc/acpi/ibm/volume
---------------------------------------
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 6cb7812..2c85a2e 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -225,6 +225,7 @@ static struct {
u32 light:1;
u32 light_status:1;
u32 bright_16levels:1;
+ u32 bright_acpimode:1;
u32 wan:1;
u32 fan_ctrl_status_undef:1;
u32 input_device_registered:1;
@@ -807,6 +808,80 @@ static int parse_strtoul(const char *buf,
return 0;
}
+static int __init tpacpi_query_bcl_levels(acpi_handle handle)
+{
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ int rc;
+
+ if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
+ obj = (union acpi_object *)buffer.pointer;
+ if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
+ printk(TPACPI_ERR "Unknown _BCL data, "
+ "please report this to %s\n", TPACPI_MAIL);
+ rc = 0;
+ } else {
+ rc = obj->package.count;
+ }
+ } else {
+ return 0;
+ }
+
+ kfree(buffer.pointer);
+ return rc;
+}
+
+static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
+ u32 lvl, void *context, void **rv)
+{
+ char name[ACPI_PATH_SEGMENT_LENGTH];
+ struct acpi_buffer buffer = { sizeof(name), &name };
+
+ if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
+ !strncmp("_BCL", name, sizeof(name) - 1)) {
+ BUG_ON(!rv || !*rv);
+ **(int **)rv = tpacpi_query_bcl_levels(handle);
+ return AE_CTRL_TERMINATE;
+ } else {
+ return AE_OK;
+ }
+}
+
+/*
+ * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
+ */
+static int __init tpacpi_check_std_acpi_brightness_support(void)
+{
+ int status;
+ int bcl_levels = 0;
+ void *bcl_ptr = &bcl_levels;
+
+ if (!vid_handle) {
+ TPACPI_ACPIHANDLE_INIT(vid);
+ }
+ if (!vid_handle)
+ return 0;
+
+ /*
+ * Search for a _BCL method, and execute it. This is safe on all
+ * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
+ * BIOS in ACPI backlight control mode. We do NOT have to care
+ * about calling the _BCL method in an enabled video device, any
+ * will do for our purposes.
+ */
+
+ status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
+ tpacpi_acpi_walk_find_bcl, NULL,
+ &bcl_ptr);
+
+ if (ACPI_SUCCESS(status) && bcl_levels > 2) {
+ tp_features.bright_acpimode = 1;
+ return (bcl_levels - 2);
+ }
+
+ return 0;
+}
+
/*************************************************************************
* thinkpad-acpi driver attributes
*/
@@ -1887,6 +1962,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
KEY_UNKNOWN, /* 0x0D: FN+INSERT */
KEY_UNKNOWN, /* 0x0E: FN+DELETE */
+ /* These either have to go through ACPI video, or
+ * act like in the IBM ThinkPads, so don't ever
+ * enable them by default */
KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
KEY_RESERVED, /* 0x10: FN+END (brightness down) */
@@ -2091,6 +2169,32 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit);
}
+ /* Do not issue duplicate brightness change events to
+ * userspace */
+ if (!tp_features.bright_acpimode)
+ /* update bright_acpimode... */
+ tpacpi_check_std_acpi_brightness_support();
+
+ if (tp_features.bright_acpimode) {
+ printk(TPACPI_INFO
+ "This ThinkPad has standard ACPI backlight "
+ "brightness control, supported by the ACPI "
+ "video driver\n");
+ printk(TPACPI_NOTICE
+ "Disabling thinkpad-acpi brightness events "
+ "by default...\n");
+
+ /* The hotkey_reserved_mask change below is not
+ * necessary while the keys are at KEY_RESERVED in the
+ * default map, but better safe than sorry, leave it
+ * here as a marker of what we have to do, especially
+ * when we finally become able to set this at runtime
+ * on response to X.org requests */
+ hotkey_reserved_mask |=
+ (1 << TP_ACPI_HOTKEYSCAN_FNHOME)
+ | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
+ }
+
dbg_printk(TPACPI_DBG_INIT,
"enabling hot key handling\n");
res = hotkey_status_set(1);
@@ -4273,100 +4377,6 @@ static struct backlight_ops ibm_backlight_data = {
/* --------------------------------------------------------------------- */
-static int __init tpacpi_query_bcll_levels(acpi_handle handle)
-{
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- int rc;
-
- if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
- obj = (union acpi_object *)buffer.pointer;
- if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
- printk(TPACPI_ERR "Unknown BCLL data, "
- "please report this to %s\n", TPACPI_MAIL);
- rc = 0;
- } else {
- rc = obj->package.count;
- }
- } else {
- return 0;
- }
-
- kfree(buffer.pointer);
- return rc;
-}
-
-static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl,
- void *context, void **rv)
-{
- char name[ACPI_PATH_SEGMENT_LENGTH];
- struct acpi_buffer buffer = { sizeof(name), &name };
-
- if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
- !strncmp("BCLL", name, sizeof(name) - 1)) {
- if (tpacpi_query_bcll_levels(handle) == 16) {
- *rv = handle;
- return AE_CTRL_TERMINATE;
- } else {
- return AE_OK;
- }
- } else {
- return AE_OK;
- }
-}
-
-static int __init brightness_check_levels(void)
-{
- int status;
- void *found_node = NULL;
-
- if (!vid_handle) {
- TPACPI_ACPIHANDLE_INIT(vid);
- }
- if (!vid_handle)
- return 0;
-
- /* Search for a BCLL package with 16 levels */
- status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3,
- brightness_find_bcll, NULL,
- &found_node);
-
- return (ACPI_SUCCESS(status) && found_node != NULL);
-}
-
-static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl,
- void *context, void **rv)
-{
- char name[ACPI_PATH_SEGMENT_LENGTH];
- struct acpi_buffer buffer = { sizeof(name), &name };
-
- if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
- !strncmp("_BCL", name, sizeof(name) - 1)) {
- *rv = handle;
- return AE_CTRL_TERMINATE;
- } else {
- return AE_OK;
- }
-}
-
-static int __init brightness_check_std_acpi_support(void)
-{
- int status;
- void *found_node = NULL;
-
- if (!vid_handle) {
- TPACPI_ACPIHANDLE_INIT(vid);
- }
- if (!vid_handle)
- return 0;
-
- /* Search for a _BCL method, but don't execute it */
- status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
- brightness_find_bcl, NULL, &found_node);
-
- return (ACPI_SUCCESS(status) && found_node != NULL);
-}
-
static int __init brightness_init(struct ibm_init_struct *iibm)
{
int b;
@@ -4375,13 +4385,19 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
mutex_init(&brightness_mutex);
- if (!brightness_enable) {
- dbg_printk(TPACPI_DBG_INIT,
- "brightness support disabled by "
- "module parameter\n");
- return 1;
- } else if (brightness_enable > 1) {
- if (brightness_check_std_acpi_support()) {
+ /*
+ * We always attempt to detect acpi support, so as to switch
+ * Lenovo Vista BIOS to ACPI brightness mode even if we are not
+ * going to publish a backlight interface
+ */
+ b = tpacpi_check_std_acpi_brightness_support();
+ if (b > 0) {
+ if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
+ printk(TPACPI_NOTICE
+ "Lenovo BIOS switched to ACPI backlight "
+ "control mode\n");
+ }
+ if (brightness_enable > 1) {
printk(TPACPI_NOTICE
"standard ACPI backlight interface "
"available, not loading native one...\n");
@@ -4389,6 +4405,22 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
}
}
+ if (!brightness_enable) {
+ dbg_printk(TPACPI_DBG_INIT,
+ "brightness support disabled by "
+ "module parameter\n");
+ return 1;
+ }
+
+ if (b > 16) {
+ printk(TPACPI_ERR
+ "Unsupported brightness interface, "
+ "please contact %s\n", TPACPI_MAIL);
+ return 1;
+ }
+ if (b == 16)
+ tp_features.bright_16levels = 1;
+
if (!brightness_mode) {
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
brightness_mode = 2;
@@ -4402,10 +4434,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
if (brightness_mode > 3)
return -EINVAL;
- tp_features.bright_16levels =
- thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO &&
- brightness_check_levels();
-
b = brightness_get(NULL);
if (b < 0)
return 1;
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 02/14] ACPI: thinkpad-acpi: warn once about weird hotkey masks
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 01/14] ACPI: thinkpad-acpi: BIOS backlight mode helper (v2.1) Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 03/14] ACPI: thinkpad-acpi: enhance box identification output (v2) Henrique de Moraes Holschuh
` (12 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh
thinkpad-acpi knows for a while now how to best program the hotkeys by
default, and always enable them by default. Unfortunately, this
information has not filtered down everywhere it needs to, yet. Notably,
old ibm-acpi documentation and most "thinkpad setup guides" will have wrong
information on this area.
Warn the local admin once whenever any of the following patterns are met:
1. Attempts to set hotkey mask to 0xffff (artifact from docs and config
for the old ibm-acpi driver and behaviour). This mask makes no
real-world sense;
2. Attempts to set hotkey mask to 0xffffffff, which means the user is
trying to just have "everything work" without even reading the
documentation, or that we need to get a bug report, because there
is a new thinkpad out there with new exciting hot keys :-)
3. Attempts to set hotkey mask to 0xffffff, which is almost never the
correct way to set up volume and brightness event reporting (and with
the current state-of-the-art, it is known to never be right way to do
it).
The driver will perform any and all requested operations, though,
regardless of any warnings. I hope these warnings can be removed one or
two years from now.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
drivers/misc/thinkpad_acpi.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 2c85a2e..cd263c5 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -237,6 +237,10 @@ static struct {
u32 hotkey_poll_active:1;
} tp_features;
+static struct {
+ u16 hotkey_mask_ff:1;
+} tp_warned;
+
struct thinkpad_id_data {
unsigned int vendor; /* ThinkPad vendor:
* PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
@@ -1182,6 +1186,19 @@ static int hotkey_mask_set(u32 mask)
int rc = 0;
if (tp_features.hotkey_mask) {
+ if (!tp_warned.hotkey_mask_ff &&
+ (mask == 0xffff || mask == 0xffffff ||
+ mask == 0xffffffff)) {
+ tp_warned.hotkey_mask_ff = 1;
+ printk(TPACPI_NOTICE
+ "setting the hotkey mask to 0x%08x is likely "
+ "not the best way to go about it\n", mask);
+ printk(TPACPI_NOTICE
+ "please consider using the driver defaults, "
+ "and refer to up-to-date thinkpad-acpi "
+ "documentation\n");
+ }
+
HOTKEY_CONFIG_CRITICAL_START
for (i = 0; i < 32; i++) {
u32 m = 1 << i;
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 03/14] ACPI: thinkpad-acpi: enhance box identification output (v2)
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 01/14] ACPI: thinkpad-acpi: BIOS backlight mode helper (v2.1) Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 02/14] ACPI: thinkpad-acpi: warn once about weird hotkey masks Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 04/14] ACPI: thinkpad-acpi: rate-limit CMOS/EC unsynced error messages Henrique de Moraes Holschuh
` (11 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh
During initialization, thinkpad-acpi outputs some messages to make sure
releavant box identification information is easily available in-line with
the rest of the driver messages.
Enhance those messages to output the alfanumeric model number as well.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
drivers/misc/thinkpad_acpi.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index cd263c5..601dbe8 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -251,7 +251,8 @@ struct thinkpad_id_data {
u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */
u16 ec_model;
- char *model_str;
+ char *model_str; /* ThinkPad T43 */
+ char *nummodel_str; /* 9384A9C for a 9384-A9C model */
};
static struct thinkpad_id_data thinkpad_id;
@@ -988,12 +989,14 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
thinkpad_id.ec_version_str : "unknown");
if (thinkpad_id.vendor && thinkpad_id.model_str)
- printk(TPACPI_INFO "%s %s\n",
+ printk(TPACPI_INFO "%s %s, model %s\n",
(thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
"IBM" : ((thinkpad_id.vendor ==
PCI_VENDOR_ID_LENOVO) ?
"Lenovo" : "Unknown vendor"),
- thinkpad_id.model_str);
+ thinkpad_id.model_str,
+ (thinkpad_id.nummodel_str) ?
+ thinkpad_id.nummodel_str : "unknown");
return 0;
}
@@ -5875,6 +5878,9 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
kfree(tp->model_str);
tp->model_str = NULL;
}
+
+ tp->nummodel_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_NAME),
+ GFP_KERNEL);
}
static int __init probe_for_thinkpad(void)
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 04/14] ACPI: thinkpad-acpi: rate-limit CMOS/EC unsynced error messages
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (2 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 03/14] ACPI: thinkpad-acpi: enhance box identification output (v2) Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 05/14] ACPI: thinkpad-acpi: fix brightness dimming control bug Henrique de Moraes Holschuh
` (10 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown
Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh,
Joerg Platte
If userspace applications mess with the CMOS NVRAM, or something causes
both the ACPI firmware and thinkpad-acpi to try to change the brightness at
the same time, it is possible to have the CMOS and EC registers for the
current brightness go out of sync.
Should that happen, thinkpad-acpi could be really obnoxious when using a
brightness_mode of 3 (both EC and CMOS). Instead of complaining a massive
number of times, make sure to complain only once until EC and CMOS are back
in sync.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Joerg Platte <lists@naasa.net>
---
drivers/misc/thinkpad_acpi.c | 22 +++++++++++++++-------
1 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 601dbe8..7dc6b73 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -239,6 +239,7 @@ static struct {
static struct {
u16 hotkey_mask_ff:1;
+ u16 bright_cmos_ec_unsync:1;
} tp_warned;
struct thinkpad_id_data {
@@ -4323,13 +4324,20 @@ static int brightness_get(struct backlight_device *bd)
level = lcmos;
}
- if (brightness_mode == 3 && lec != lcmos) {
- printk(TPACPI_ERR
- "CMOS NVRAM (%u) and EC (%u) do not agree "
- "on display brightness level\n",
- (unsigned int) lcmos,
- (unsigned int) lec);
- return -EIO;
+ if (brightness_mode == 3) {
+ if (lec == lcmos)
+ tp_warned.bright_cmos_ec_unsync = 0;
+ else {
+ if (!tp_warned.bright_cmos_ec_unsync) {
+ printk(TPACPI_ERR
+ "CMOS NVRAM (%u) and EC (%u) do not "
+ "agree on display brightness level\n",
+ (unsigned int) lcmos,
+ (unsigned int) lec);
+ tp_warned.bright_cmos_ec_unsync = 1;
+ }
+ return -EIO;
+ }
}
return level;
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 05/14] ACPI: thinkpad-acpi: fix brightness dimming control bug
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (3 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 04/14] ACPI: thinkpad-acpi: rate-limit CMOS/EC unsynced error messages Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 06/14] ACPI: thinkpad-acpi: claim tpacpi as an official short handle (v1.1) Henrique de Moraes Holschuh
` (9 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh
ibm-acpi and thinkpad-acpi did not know about bit 5 of the EC backlight
level control register (EC 0x31), so it was always forced to zero on
any writes.
This would disable the BIOS option to *not* use a dimmer backlight level
scale while on battery, and who knows what else (there are two other
control bits of unknown function).
Bit 5 controls the "reduce backlight levels when on battery" optional
functionality (active low). Bits 6 and 7 are better left alone as well,
instead of being forced to zero.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
drivers/misc/thinkpad_acpi.c | 64 ++++++++++++++++++++++++++++++++----------
1 files changed, 49 insertions(+), 15 deletions(-)
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 7dc6b73..5e25abc 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -4295,8 +4295,16 @@ static struct ibm_struct ecdump_driver_data = {
#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
+enum {
+ TP_EC_BACKLIGHT = 0x31,
+
+ /* TP_EC_BACKLIGHT bitmasks */
+ TP_EC_BACKLIGHT_LVLMSK = 0x1F,
+ TP_EC_BACKLIGHT_CMDMSK = 0xE0,
+ TP_EC_BACKLIGHT_MAPSW = 0x20,
+};
+
static struct backlight_device *ibm_backlight_device;
-static int brightness_offset = 0x31;
static int brightness_mode;
static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
@@ -4305,16 +4313,24 @@ static struct mutex brightness_mutex;
/*
* ThinkPads can read brightness from two places: EC 0x31, or
* CMOS NVRAM byte 0x5E, bits 0-3.
+ *
+ * EC 0x31 has the following layout
+ * Bit 7: unknown function
+ * Bit 6: unknown function
+ * Bit 5: Z: honour scale changes, NZ: ignore scale changes
+ * Bit 4: must be set to zero to avoid problems
+ * Bit 3-0: backlight brightness level
+ *
+ * brightness_get_raw returns status data in the EC 0x31 layout
*/
-static int brightness_get(struct backlight_device *bd)
+static int brightness_get_raw(int *status)
{
u8 lec = 0, lcmos = 0, level = 0;
if (brightness_mode & 1) {
- if (!acpi_ec_read(brightness_offset, &lec))
+ if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
return -EIO;
- lec &= (tp_features.bright_16levels)? 0x0f : 0x07;
- level = lec;
+ level = lec & TP_EC_BACKLIGHT_LVLMSK;
};
if (brightness_mode & 2) {
lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
@@ -4325,6 +4341,8 @@ static int brightness_get(struct backlight_device *bd)
}
if (brightness_mode == 3) {
+ *status = lec; /* Prefer EC, CMOS is just a backing store */
+ lec &= TP_EC_BACKLIGHT_LVLMSK;
if (lec == lcmos)
tp_warned.bright_cmos_ec_unsync = 0;
else {
@@ -4338,9 +4356,11 @@ static int brightness_get(struct backlight_device *bd)
}
return -EIO;
}
+ } else {
+ *status = level;
}
- return level;
+ return 0;
}
/* May return EINTR which can always be mapped to ERESTARTSYS */
@@ -4348,19 +4368,22 @@ static int brightness_set(int value)
{
int cmos_cmd, inc, i, res;
int current_value;
+ int command_bits;
- if (value > ((tp_features.bright_16levels)? 15 : 7))
+ if (value > ((tp_features.bright_16levels)? 15 : 7) ||
+ value < 0)
return -EINVAL;
res = mutex_lock_interruptible(&brightness_mutex);
if (res < 0)
return res;
- current_value = brightness_get(NULL);
- if (current_value < 0) {
- res = current_value;
+ res = brightness_get_raw(¤t_value);
+ if (res < 0)
goto errout;
- }
+
+ command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
+ current_value &= TP_EC_BACKLIGHT_LVLMSK;
cmos_cmd = value > current_value ?
TP_CMOS_BRIGHTNESS_UP :
@@ -4375,7 +4398,8 @@ static int brightness_set(int value)
goto errout;
}
if ((brightness_mode & 1) &&
- !acpi_ec_write(brightness_offset, i + inc)) {
+ !acpi_ec_write(TP_EC_BACKLIGHT,
+ (i + inc) | command_bits)) {
res = -EIO;
goto errout;;
}
@@ -4398,6 +4422,17 @@ static int brightness_update_status(struct backlight_device *bd)
bd->props.brightness : 0);
}
+static int brightness_get(struct backlight_device *bd)
+{
+ int status, res;
+
+ res = brightness_get_raw(&status);
+ if (res < 0)
+ return 0; /* FIXME: teach backlight about error handling */
+
+ return status & TP_EC_BACKLIGHT_LVLMSK;
+}
+
static struct backlight_ops ibm_backlight_data = {
.get_brightness = brightness_get,
.update_status = brightness_update_status,
@@ -4462,8 +4497,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
if (brightness_mode > 3)
return -EINVAL;
- b = brightness_get(NULL);
- if (b < 0)
+ if (brightness_get_raw(&b) < 0)
return 1;
if (tp_features.bright_16levels)
@@ -4481,7 +4515,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
ibm_backlight_device->props.max_brightness =
(tp_features.bright_16levels)? 15 : 7;
- ibm_backlight_device->props.brightness = b;
+ ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
backlight_update_status(ibm_backlight_device);
return 0;
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 06/14] ACPI: thinkpad-acpi: claim tpacpi as an official short handle (v1.1)
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (4 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 05/14] ACPI: thinkpad-acpi: fix brightness dimming control bug Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 07/14] ACPI: thinkpad-acpi: prepare light and LED for sysfs support Henrique de Moraes Holschuh
` (8 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh
Unfortunately, a lot of stuff in the kernel has size limitations, so
"thinkpad-acpi" ends up eating up too much real estate. We were using
"tpacpi" in symbols already, but this shorthand was not visible to
userland.
Document that the driver will use tpacpi as a short hand where necessary,
and use it to name the kernel thread for NVRAM polling (now named
"ktpacpi_nvramd").
Also, register a module alias with the shorthand. One can refer to the
module using the shorthand name.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
Documentation/laptops/thinkpad-acpi.txt | 5 +++++
drivers/misc/thinkpad_acpi.c | 8 ++++++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index a77da28..a41bc89 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -18,6 +18,11 @@ This driver used to be named ibm-acpi until kernel 2.6.21 and release
moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel
2.6.22, and release 0.14.
+The driver is named "thinkpad-acpi". In some places, like module
+names, "thinkpad_acpi" is used because of userspace issues.
+
+"tpacpi" is used as a shorthand where "thinkpad-acpi" would be too
+long due to length limitations on some Linux kernel versions.
Status
------
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 5e25abc..2b73dfa 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -133,8 +133,11 @@ enum {
#define TPACPI_PROC_DIR "ibm"
#define TPACPI_ACPI_EVENT_PREFIX "ibm"
#define TPACPI_DRVR_NAME TPACPI_FILE
+#define TPACPI_DRVR_SHORTNAME "tpacpi"
#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon"
+#define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd"
+
#define TPACPI_MAX_ACPI_ARGS 3
/* Debugging */
@@ -1523,8 +1526,7 @@ static void hotkey_poll_setup(int may_warn)
(tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) {
if (!tpacpi_hotkey_task) {
tpacpi_hotkey_task = kthread_run(hotkey_kthread,
- NULL,
- TPACPI_FILE "d");
+ NULL, TPACPI_NVRAM_KTHREAD_NAME);
if (IS_ERR(tpacpi_hotkey_task)) {
tpacpi_hotkey_task = NULL;
printk(TPACPI_ERR
@@ -6316,6 +6318,8 @@ static int __init thinkpad_acpi_module_init(void)
/* Please remove this in year 2009 */
MODULE_ALIAS("ibm_acpi");
+MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
+
/*
* DMI matching for module autoloading
*
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 07/14] ACPI: thinkpad-acpi: prepare light and LED for sysfs support
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (5 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 06/14] ACPI: thinkpad-acpi: claim tpacpi as an official short handle (v1.1) Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 08/14] ACPI: thinkpad-acpi: add sysfs led class support for thinklight (v3.1) Henrique de Moraes Holschuh
` (7 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh
Do some preparatory work to add sysfs support to the thinklight and
thinkpad leds driver.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
drivers/misc/Kconfig | 2 +
drivers/misc/thinkpad_acpi.c | 191 ++++++++++++++++++++++++++++++------------
2 files changed, 138 insertions(+), 55 deletions(-)
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 297a48f..3a5d769 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -245,6 +245,8 @@ config THINKPAD_ACPI
select HWMON
select NVRAM
depends on INPUT
+ select NEW_LEDS
+ select LEDS_CLASS
---help---
This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
support for Fn-Fx key combinations, Bluetooth control, video
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 2b73dfa..5a3fb09 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -67,6 +67,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/input.h>
+#include <linux/leds.h>
#include <asm/uaccess.h>
#include <linux/dmi.h>
@@ -85,6 +86,8 @@
#define TP_CMOS_VOLUME_MUTE 2
#define TP_CMOS_BRIGHTNESS_UP 4
#define TP_CMOS_BRIGHTNESS_DOWN 5
+#define TP_CMOS_THINKLIGHT_ON 12
+#define TP_CMOS_THINKLIGHT_OFF 13
/* NVRAM Addresses */
enum tp_nvram_addr {
@@ -269,6 +272,13 @@ static enum {
static int experimental;
static u32 dbg_level;
+/* Special LED class that can defer work */
+struct tpacpi_led_classdev {
+ struct led_classdev led_classdev;
+ struct work_struct work;
+ enum led_brightness new_brightness;
+};
+
/****************************************************************************
****************************************************************************
*
@@ -3237,6 +3247,39 @@ static struct ibm_struct video_driver_data = {
TPACPI_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */
TPACPI_HANDLE(ledb, ec, "LEDB"); /* G4x */
+static int light_get_status(void)
+{
+ int status = 0;
+
+ if (tp_features.light_status) {
+ if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
+ return -EIO;
+ return (!!status);
+ }
+
+ return -ENXIO;
+}
+
+static int light_set_status(int status)
+{
+ int rc;
+
+ if (tp_features.light) {
+ if (cmos_handle) {
+ rc = acpi_evalf(cmos_handle, NULL, NULL, "vd",
+ (status)?
+ TP_CMOS_THINKLIGHT_ON :
+ TP_CMOS_THINKLIGHT_OFF);
+ } else {
+ rc = acpi_evalf(lght_handle, NULL, NULL, "vd",
+ (status)? 1 : 0);
+ }
+ return (rc)? 0 : -EIO;
+ }
+
+ return -ENXIO;
+}
+
static int __init light_init(struct ibm_init_struct *iibm)
{
vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
@@ -3263,7 +3306,7 @@ static int __init light_init(struct ibm_init_struct *iibm)
static int light_read(char *p)
{
int len = 0;
- int status = 0;
+ int status;
if (!tp_features.light) {
len += sprintf(p + len, "status:\t\tnot supported\n");
@@ -3271,8 +3314,9 @@ static int light_read(char *p)
len += sprintf(p + len, "status:\t\tunknown\n");
len += sprintf(p + len, "commands:\ton, off\n");
} else {
- if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
- return -EIO;
+ status = light_get_status();
+ if (status < 0)
+ return status;
len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
len += sprintf(p + len, "commands:\ton, off\n");
}
@@ -3282,31 +3326,22 @@ static int light_read(char *p)
static int light_write(char *buf)
{
- int cmos_cmd, lght_cmd;
char *cmd;
- int success;
+ int newstatus = 0;
if (!tp_features.light)
return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "on") == 0) {
- cmos_cmd = 0x0c;
- lght_cmd = 1;
+ newstatus = 1;
} else if (strlencmp(cmd, "off") == 0) {
- cmos_cmd = 0x0d;
- lght_cmd = 0;
+ newstatus = 0;
} else
return -EINVAL;
-
- success = cmos_handle ?
- acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) :
- acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd);
- if (!success)
- return -EIO;
}
- return 0;
+ return light_set_status(newstatus);
}
static struct ibm_struct light_driver_data = {
@@ -3710,6 +3745,12 @@ enum { /* For TPACPI_LED_OLD */
TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */
};
+enum led_status_t {
+ TPACPI_LED_OFF = 0,
+ TPACPI_LED_ON,
+ TPACPI_LED_BLINK,
+};
+
static enum led_access_mode led_supported;
TPACPI_HANDLE(led, ec, "SLED", /* 570 */
@@ -3718,6 +3759,69 @@ TPACPI_HANDLE(led, ec, "SLED", /* 570 */
"LED", /* all others */
); /* R30, R31 */
+static int led_get_status(unsigned int led)
+{
+ int status;
+
+ switch (led_supported) {
+ case TPACPI_LED_570:
+ if (!acpi_evalf(ec_handle,
+ &status, "GLED", "dd", 1 << led))
+ return -EIO;
+ return (status == 0)?
+ TPACPI_LED_OFF :
+ ((status == 1)?
+ TPACPI_LED_ON :
+ TPACPI_LED_BLINK);
+ default:
+ return -ENXIO;
+ }
+
+ /* not reached */
+}
+
+static int led_set_status(unsigned int led, enum led_status_t ledstatus)
+{
+ /* off, on, blink. Index is led_status_t */
+ static const int const led_sled_arg1[] = { 0, 1, 3 };
+ static const int const led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */
+ static const int const led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */
+ static const int const led_led_arg1[] = { 0, 0x80, 0xc0 };
+
+ int rc = 0;
+
+ switch (led_supported) {
+ case TPACPI_LED_570:
+ /* 570 */
+ led = 1 << led;
+ if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
+ led, led_sled_arg1[ledstatus]))
+ rc = -EIO;
+ break;
+ case TPACPI_LED_OLD:
+ /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
+ led = 1 << led;
+ rc = ec_write(TPACPI_LED_EC_HLMS, led);
+ if (rc >= 0)
+ rc = ec_write(TPACPI_LED_EC_HLBL,
+ led * led_exp_hlbl[ledstatus]);
+ if (rc >= 0)
+ rc = ec_write(TPACPI_LED_EC_HLCL,
+ led * led_exp_hlcl[ledstatus]);
+ break;
+ case TPACPI_LED_NEW:
+ /* all others */
+ if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
+ led, led_led_arg1[ledstatus]))
+ rc = -EIO;
+ break;
+ default:
+ rc = -ENXIO;
+ }
+
+ return rc;
+}
+
static int __init led_init(struct ibm_init_struct *iibm)
{
vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
@@ -3743,7 +3847,9 @@ static int __init led_init(struct ibm_init_struct *iibm)
return (led_supported != TPACPI_LED_NONE)? 0 : 1;
}
-#define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking"))
+#define str_led_status(s) \
+ ((s) == TPACPI_LED_OFF ? "off" : \
+ ((s) == TPACPI_LED_ON ? "on" : "blinking"))
static int led_read(char *p)
{
@@ -3759,11 +3865,11 @@ static int led_read(char *p)
/* 570 */
int i, status;
for (i = 0; i < 8; i++) {
- if (!acpi_evalf(ec_handle,
- &status, "GLED", "dd", 1 << i))
+ status = led_get_status(i);
+ if (status < 0)
return -EIO;
len += sprintf(p + len, "%d:\t\t%s\n",
- i, led_status(status));
+ i, str_led_status(status));
}
}
@@ -3773,16 +3879,11 @@ static int led_read(char *p)
return len;
}
-/* off, on, blink */
-static const int led_sled_arg1[] = { 0, 1, 3 };
-static const int led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */
-static const int led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */
-static const int led_led_arg1[] = { 0, 0x80, 0xc0 };
-
static int led_write(char *buf)
{
char *cmd;
- int led, ind, ret;
+ int led, rc;
+ enum led_status_t s;
if (!led_supported)
return -ENODEV;
@@ -3792,38 +3893,18 @@ static int led_write(char *buf)
return -EINVAL;
if (strstr(cmd, "off")) {
- ind = 0;
+ s = TPACPI_LED_OFF;
} else if (strstr(cmd, "on")) {
- ind = 1;
+ s = TPACPI_LED_ON;
} else if (strstr(cmd, "blink")) {
- ind = 2;
- } else
- return -EINVAL;
-
- if (led_supported == TPACPI_LED_570) {
- /* 570 */
- led = 1 << led;
- if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
- led, led_sled_arg1[ind]))
- return -EIO;
- } else if (led_supported == TPACPI_LED_OLD) {
- /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
- led = 1 << led;
- ret = ec_write(TPACPI_LED_EC_HLMS, led);
- if (ret >= 0)
- ret = ec_write(TPACPI_LED_EC_HLBL,
- led * led_exp_hlbl[ind]);
- if (ret >= 0)
- ret = ec_write(TPACPI_LED_EC_HLCL,
- led * led_exp_hlcl[ind]);
- if (ret < 0)
- return ret;
+ s = TPACPI_LED_BLINK;
} else {
- /* all others */
- if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
- led, led_led_arg1[ind]))
- return -EIO;
+ return -EINVAL;
}
+
+ rc = led_set_status(led, s);
+ if (rc < 0)
+ return rc;
}
return 0;
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 08/14] ACPI: thinkpad-acpi: add sysfs led class support for thinklight (v3.1)
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (6 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 07/14] ACPI: thinkpad-acpi: prepare light and LED for sysfs support Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 09/14] ACPI: thinkpad-acpi: add sysfs led class support to thinkpad leds (v3.2) Henrique de Moraes Holschuh
` (6 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown
Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh,
Richard Purdie
Add a sysfs led class interface to the thinklight (light subdriver).
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Richard Purdie <rpurdie@rpsys.net>
---
Documentation/laptops/thinkpad-acpi.txt | 25 +++++++++++---
drivers/misc/thinkpad_acpi.c | 57 ++++++++++++++++++++++++++++++-
2 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index a41bc89..af1f2bc 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -693,16 +693,31 @@ while others are still having problems. For more information:
https://bugs.freedesktop.org/show_bug.cgi?id=2000
-ThinkLight control -- /proc/acpi/ibm/light
-------------------------------------------
+ThinkLight control
+------------------
+
+procfs: /proc/acpi/ibm/light
+sysfs attributes: as per led class, for the "tpacpi::thinklight" led
+
+procfs notes:
-The current status of the ThinkLight can be found in this file. A few
-models which do not make the status available will show it as
-"unknown". The available commands are:
+The ThinkLight status can be read and set through the procfs interface. A
+few models which do not make the status available will show the ThinkLight
+status as "unknown". The available commands are:
echo on > /proc/acpi/ibm/light
echo off > /proc/acpi/ibm/light
+sysfs notes:
+
+The ThinkLight sysfs interface is documented by the led class
+documentation, in Documentation/leds-class.txt. The ThinkLight led name
+is "tpacpi::thinklight".
+
+Due to limitations in the sysfs led class, if the status of the thinklight
+cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
+It is impossible to know if the status returned through sysfs is valid.
+
Docking / undocking -- /proc/acpi/ibm/dock
------------------------------------------
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 5a3fb09..38a119b 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -3280,13 +3280,49 @@ static int light_set_status(int status)
return -ENXIO;
}
+static void light_set_status_worker(struct work_struct *work)
+{
+ struct tpacpi_led_classdev *data =
+ container_of(work, struct tpacpi_led_classdev, work);
+
+ if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
+ light_set_status((data->new_brightness != LED_OFF));
+}
+
+static void light_sysfs_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct tpacpi_led_classdev *data =
+ container_of(led_cdev,
+ struct tpacpi_led_classdev,
+ led_classdev);
+ data->new_brightness = brightness;
+ schedule_work(&data->work);
+}
+
+static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
+{
+ return (light_get_status() == 1)? LED_FULL : LED_OFF;
+}
+
+static struct tpacpi_led_classdev tpacpi_led_thinklight = {
+ .led_classdev = {
+ .name = "tpacpi::thinklight",
+ .brightness_set = &light_sysfs_set,
+ .brightness_get = &light_sysfs_get,
+ }
+};
+
static int __init light_init(struct ibm_init_struct *iibm)
{
+ int rc = 0;
+
vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
TPACPI_ACPIHANDLE_INIT(ledb);
TPACPI_ACPIHANDLE_INIT(lght);
TPACPI_ACPIHANDLE_INIT(cmos);
+ INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker);
/* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
@@ -3300,7 +3336,25 @@ static int __init light_init(struct ibm_init_struct *iibm)
vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
str_supported(tp_features.light));
- return (tp_features.light)? 0 : 1;
+ if (tp_features.light) {
+ rc = led_classdev_register(&tpacpi_pdev->dev,
+ &tpacpi_led_thinklight.led_classdev);
+ }
+
+ if (rc < 0) {
+ tp_features.light = 0;
+ tp_features.light_status = 0;
+ } else {
+ rc = (tp_features.light)? 0 : 1;
+ }
+ return rc;
+}
+
+static void light_exit(void)
+{
+ led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);
+ if (work_pending(&tpacpi_led_thinklight.work))
+ flush_scheduled_work();
}
static int light_read(char *p)
@@ -3348,6 +3402,7 @@ static struct ibm_struct light_driver_data = {
.name = "light",
.read = light_read,
.write = light_write,
+ .exit = light_exit,
};
/*************************************************************************
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 09/14] ACPI: thinkpad-acpi: add sysfs led class support to thinkpad leds (v3.2)
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (7 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 08/14] ACPI: thinkpad-acpi: add sysfs led class support for thinklight (v3.1) Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 10/14] ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation Henrique de Moraes Holschuh
` (5 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown
Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh,
Richard Purdie
Add a sysfs led class interface to the led subdriver.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Richard Purdie <rpurdie@rpsys.net>
---
Documentation/laptops/thinkpad-acpi.txt | 47 +++++++++--
drivers/misc/thinkpad_acpi.c | 136 ++++++++++++++++++++++++++++++-
2 files changed, 176 insertions(+), 7 deletions(-)
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index af1f2bc..73b80a7 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -876,28 +876,63 @@ The cmos command interface is prone to firmware split-brain problems, as
in newer ThinkPads it is just a compatibility layer. Do not use it, it is
exported just as a debug tool.
-LED control -- /proc/acpi/ibm/led
----------------------------------
+LED control
+-----------
-Some of the LED indicators can be controlled through this feature. The
-available commands are:
+procfs: /proc/acpi/ibm/led
+sysfs attributes: as per led class, see below for names
+
+Some of the LED indicators can be controlled through this feature. On
+some older ThinkPad models, it is possible to query the status of the
+LED indicators as well. Newer ThinkPads cannot query the real status
+of the LED indicators.
+
+procfs notes:
+
+The available commands are:
echo '<led number> on' >/proc/acpi/ibm/led
echo '<led number> off' >/proc/acpi/ibm/led
echo '<led number> blink' >/proc/acpi/ibm/led
The <led number> range is 0 to 7. The set of LEDs that can be
-controlled varies from model to model. Here is the mapping on the X40:
+controlled varies from model to model. Here is the common ThinkPad
+mapping:
0 - power
1 - battery (orange)
2 - battery (green)
- 3 - UltraBase
+ 3 - UltraBase/dock
4 - UltraBay
+ 5 - UltraBase battery slot
+ 6 - (unknown)
7 - standby
All of the above can be turned on and off and can be made to blink.
+sysfs notes:
+
+The ThinkPad LED sysfs interface is described in detail by the led class
+documentation, in Documentation/leds-class.txt.
+
+The leds are named (in LED ID order, from 0 to 7):
+"tpacpi::power", "tpacpi:orange:batt", "tpacpi:green:batt",
+"tpacpi::dock_active", "tpacpi::bay_active", "tpacpi::dock_batt",
+"tpacpi::unknown_led", "tpacpi::standby".
+
+Due to limitations in the sysfs led class, if the status of the LED
+indicators cannot be read due to an error, thinkpad-acpi will report it as
+a brightness of zero (same as LED off).
+
+If the thinkpad firmware doesn't support reading the current status,
+trying to read the current LED brightness will just return whatever
+brightness was last written to that attribute.
+
+These LEDs can blink using hardware acceleration. To request that a
+ThinkPad indicator LED should blink in hardware accelerated mode, use the
+"timer" trigger, and leave the delay_on and delay_off parameters set to
+zero (to request hardware acceleration autodetection).
+
ACPI sounds -- /proc/acpi/ibm/beep
----------------------------------
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 38a119b..2ab3633 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -277,6 +277,7 @@ struct tpacpi_led_classdev {
struct led_classdev led_classdev;
struct work_struct work;
enum led_brightness new_brightness;
+ unsigned int led;
};
/****************************************************************************
@@ -3814,20 +3815,38 @@ TPACPI_HANDLE(led, ec, "SLED", /* 570 */
"LED", /* all others */
); /* R30, R31 */
+#define TPACPI_LED_NUMLEDS 8
+static struct tpacpi_led_classdev *tpacpi_leds;
+static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS];
+static const char const *tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
+ /* there's a limit of 19 chars + NULL before 2.6.26 */
+ "tpacpi::power",
+ "tpacpi:orange:batt",
+ "tpacpi:green:batt",
+ "tpacpi::dock_active",
+ "tpacpi::bay_active",
+ "tpacpi::dock_batt",
+ "tpacpi::unknown_led",
+ "tpacpi::standby",
+};
+
static int led_get_status(unsigned int led)
{
int status;
+ enum led_status_t led_s;
switch (led_supported) {
case TPACPI_LED_570:
if (!acpi_evalf(ec_handle,
&status, "GLED", "dd", 1 << led))
return -EIO;
- return (status == 0)?
+ led_s = (status == 0)?
TPACPI_LED_OFF :
((status == 1)?
TPACPI_LED_ON :
TPACPI_LED_BLINK);
+ tpacpi_led_state_cache[led] = led_s;
+ return led_s;
default:
return -ENXIO;
}
@@ -3874,11 +3893,96 @@ static int led_set_status(unsigned int led, enum led_status_t ledstatus)
rc = -ENXIO;
}
+ if (!rc)
+ tpacpi_led_state_cache[led] = ledstatus;
+
return rc;
}
+static void led_sysfs_set_status(unsigned int led,
+ enum led_brightness brightness)
+{
+ led_set_status(led,
+ (brightness == LED_OFF) ?
+ TPACPI_LED_OFF :
+ (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ?
+ TPACPI_LED_BLINK : TPACPI_LED_ON);
+}
+
+static void led_set_status_worker(struct work_struct *work)
+{
+ struct tpacpi_led_classdev *data =
+ container_of(work, struct tpacpi_led_classdev, work);
+
+ if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
+ led_sysfs_set_status(data->led, data->new_brightness);
+}
+
+static void led_sysfs_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct tpacpi_led_classdev *data = container_of(led_cdev,
+ struct tpacpi_led_classdev, led_classdev);
+
+ data->new_brightness = brightness;
+ schedule_work(&data->work);
+}
+
+static int led_sysfs_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ struct tpacpi_led_classdev *data = container_of(led_cdev,
+ struct tpacpi_led_classdev, led_classdev);
+
+ /* Can we choose the flash rate? */
+ if (*delay_on == 0 && *delay_off == 0) {
+ /* yes. set them to the hardware blink rate (1 Hz) */
+ *delay_on = 500; /* ms */
+ *delay_off = 500; /* ms */
+ } else if ((*delay_on != 500) || (*delay_off != 500))
+ return -EINVAL;
+
+ data->new_brightness = TPACPI_LED_BLINK;
+ schedule_work(&data->work);
+
+ return 0;
+}
+
+static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev)
+{
+ int rc;
+
+ struct tpacpi_led_classdev *data = container_of(led_cdev,
+ struct tpacpi_led_classdev, led_classdev);
+
+ rc = led_get_status(data->led);
+
+ if (rc == TPACPI_LED_OFF || rc < 0)
+ rc = LED_OFF; /* no error handling in led class :( */
+ else
+ rc = LED_FULL;
+
+ return rc;
+}
+
+static void led_exit(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
+ if (tpacpi_leds[i].led_classdev.name)
+ led_classdev_unregister(&tpacpi_leds[i].led_classdev);
+ }
+
+ kfree(tpacpi_leds);
+ tpacpi_leds = NULL;
+}
+
static int __init led_init(struct ibm_init_struct *iibm)
{
+ unsigned int i;
+ int rc;
+
vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
TPACPI_ACPIHANDLE_INIT(led);
@@ -3899,6 +4003,35 @@ static int __init led_init(struct ibm_init_struct *iibm)
vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
str_supported(led_supported), led_supported);
+ tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS,
+ GFP_KERNEL);
+ if (!tpacpi_leds) {
+ printk(TPACPI_ERR "Out of memory for LED data\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
+ tpacpi_leds[i].led = i;
+
+ tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
+ tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
+ if (led_supported == TPACPI_LED_570)
+ tpacpi_leds[i].led_classdev.brightness_get =
+ &led_sysfs_get;
+
+ tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
+
+ INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
+
+ rc = led_classdev_register(&tpacpi_pdev->dev,
+ &tpacpi_leds[i].led_classdev);
+ if (rc < 0) {
+ tpacpi_leds[i].led_classdev.name = NULL;
+ led_exit();
+ return rc;
+ }
+ }
+
return (led_supported != TPACPI_LED_NONE)? 0 : 1;
}
@@ -3969,6 +4102,7 @@ static struct ibm_struct led_driver_data = {
.name = "led",
.read = led_read,
.write = led_write,
+ .exit = led_exit,
};
/*************************************************************************
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 10/14] ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (8 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 09/14] ACPI: thinkpad-acpi: add sysfs led class support to thinkpad leds (v3.2) Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:06 ` Randy Dunlap
2008-04-26 4:02 ` [PATCH 11/14] ACPI: thinkpad-acpi: fluff really minor fix Henrique de Moraes Holschuh
` (4 subsequent siblings)
14 siblings, 1 reply; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown
Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh,
Randy Dunlap
Change all occourences of the "led" word to full uppercase in user
documentation.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Randy Dunlap <randy.dunlap@oracle.com>
---
Documentation/laptops/thinkpad-acpi.txt | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 73b80a7..947b726 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -697,7 +697,7 @@ ThinkLight control
------------------
procfs: /proc/acpi/ibm/light
-sysfs attributes: as per led class, for the "tpacpi::thinklight" led
+sysfs attributes: as per LED class, for the "tpacpi::thinklight" LED
procfs notes:
@@ -710,11 +710,11 @@ status as "unknown". The available commands are:
sysfs notes:
-The ThinkLight sysfs interface is documented by the led class
-documentation, in Documentation/leds-class.txt. The ThinkLight led name
+The ThinkLight sysfs interface is documented by the LED class
+documentation, in Documentation/leds-class.txt. The ThinkLight LED name
is "tpacpi::thinklight".
-Due to limitations in the sysfs led class, if the status of the thinklight
+Due to limitations in the sysfs LED class, if the status of the thinklight
cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
It is impossible to know if the status returned through sysfs is valid.
@@ -880,7 +880,7 @@ LED control
-----------
procfs: /proc/acpi/ibm/led
-sysfs attributes: as per led class, see below for names
+sysfs attributes: as per LED class, see below for names
Some of the LED indicators can be controlled through this feature. On
some older ThinkPad models, it is possible to query the status of the
@@ -891,11 +891,11 @@ procfs notes:
The available commands are:
- echo '<led number> on' >/proc/acpi/ibm/led
- echo '<led number> off' >/proc/acpi/ibm/led
- echo '<led number> blink' >/proc/acpi/ibm/led
+ echo '<LED number> on' >/proc/acpi/ibm/led
+ echo '<LED number> off' >/proc/acpi/ibm/led
+ echo '<LED number> blink' >/proc/acpi/ibm/led
-The <led number> range is 0 to 7. The set of LEDs that can be
+The <LED number> range is 0 to 7. The set of LEDs that can be
controlled varies from model to model. Here is the common ThinkPad
mapping:
@@ -912,7 +912,7 @@ All of the above can be turned on and off and can be made to blink.
sysfs notes:
-The ThinkPad LED sysfs interface is described in detail by the led class
+The ThinkPad LED sysfs interface is described in detail by the LED class
documentation, in Documentation/leds-class.txt.
The leds are named (in LED ID order, from 0 to 7):
@@ -920,7 +920,7 @@ The leds are named (in LED ID order, from 0 to 7):
"tpacpi::dock_active", "tpacpi::bay_active", "tpacpi::dock_batt",
"tpacpi::unknown_led", "tpacpi::standby".
-Due to limitations in the sysfs led class, if the status of the LED
+Due to limitations in the sysfs LED class, if the status of the LED
indicators cannot be read due to an error, thinkpad-acpi will report it as
a brightness of zero (same as LED off).
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH 10/14] ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation
2008-04-26 4:02 ` [PATCH 10/14] ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation Henrique de Moraes Holschuh
@ 2008-04-26 4:06 ` Randy Dunlap
0 siblings, 0 replies; 18+ messages in thread
From: Randy Dunlap @ 2008-04-26 4:06 UTC (permalink / raw)
To: Henrique de Moraes Holschuh; +Cc: Len Brown, ibm-acpi-devel, linux-acpi
Henrique de Moraes Holschuh wrote:
> Change all occourences of the "led" word to full uppercase in user
> documentation.
>
> Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
> Cc: Randy Dunlap <randy.dunlap@oracle.com>
Thank you.
Acked-by: Randy Dunlap <randy.dunlap@oracle.com>
> ---
> Documentation/laptops/thinkpad-acpi.txt | 22 +++++++++++-----------
> 1 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
> index 73b80a7..947b726 100644
> --- a/Documentation/laptops/thinkpad-acpi.txt
> +++ b/Documentation/laptops/thinkpad-acpi.txt
> @@ -697,7 +697,7 @@ ThinkLight control
> ------------------
>
> procfs: /proc/acpi/ibm/light
> -sysfs attributes: as per led class, for the "tpacpi::thinklight" led
> +sysfs attributes: as per LED class, for the "tpacpi::thinklight" LED
>
> procfs notes:
>
> @@ -710,11 +710,11 @@ status as "unknown". The available commands are:
>
> sysfs notes:
>
> -The ThinkLight sysfs interface is documented by the led class
> -documentation, in Documentation/leds-class.txt. The ThinkLight led name
> +The ThinkLight sysfs interface is documented by the LED class
> +documentation, in Documentation/leds-class.txt. The ThinkLight LED name
> is "tpacpi::thinklight".
>
> -Due to limitations in the sysfs led class, if the status of the thinklight
> +Due to limitations in the sysfs LED class, if the status of the thinklight
> cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
> It is impossible to know if the status returned through sysfs is valid.
>
> @@ -880,7 +880,7 @@ LED control
> -----------
>
> procfs: /proc/acpi/ibm/led
> -sysfs attributes: as per led class, see below for names
> +sysfs attributes: as per LED class, see below for names
>
> Some of the LED indicators can be controlled through this feature. On
> some older ThinkPad models, it is possible to query the status of the
> @@ -891,11 +891,11 @@ procfs notes:
>
> The available commands are:
>
> - echo '<led number> on' >/proc/acpi/ibm/led
> - echo '<led number> off' >/proc/acpi/ibm/led
> - echo '<led number> blink' >/proc/acpi/ibm/led
> + echo '<LED number> on' >/proc/acpi/ibm/led
> + echo '<LED number> off' >/proc/acpi/ibm/led
> + echo '<LED number> blink' >/proc/acpi/ibm/led
>
> -The <led number> range is 0 to 7. The set of LEDs that can be
> +The <LED number> range is 0 to 7. The set of LEDs that can be
> controlled varies from model to model. Here is the common ThinkPad
> mapping:
>
> @@ -912,7 +912,7 @@ All of the above can be turned on and off and can be made to blink.
>
> sysfs notes:
>
> -The ThinkPad LED sysfs interface is described in detail by the led class
> +The ThinkPad LED sysfs interface is described in detail by the LED class
> documentation, in Documentation/leds-class.txt.
>
> The leds are named (in LED ID order, from 0 to 7):
> @@ -920,7 +920,7 @@ The leds are named (in LED ID order, from 0 to 7):
> "tpacpi::dock_active", "tpacpi::bay_active", "tpacpi::dock_batt",
> "tpacpi::unknown_led", "tpacpi::standby".
>
> -Due to limitations in the sysfs led class, if the status of the LED
> +Due to limitations in the sysfs LED class, if the status of the LED
> indicators cannot be read due to an error, thinkpad-acpi will report it as
> a brightness of zero (same as LED off).
>
--
~Randy
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 11/14] ACPI: thinkpad-acpi: fluff really minor fix
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (9 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 10/14] ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 12/14] ACPI: thinkpad-acpi: use a private workqueue Henrique de Moraes Holschuh
` (3 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh
Fix a minor (nano?) thing that bothered me at exactly at the wrong time.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
drivers/misc/thinkpad_acpi.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 2ab3633..f471b46 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -3881,7 +3881,7 @@ static int led_set_status(unsigned int led, enum led_status_t ledstatus)
led * led_exp_hlbl[ledstatus]);
if (rc >= 0)
rc = ec_write(TPACPI_LED_EC_HLCL,
- led * led_exp_hlcl[ledstatus]);
+ led * led_exp_hlcl[ledstatus]);
break;
case TPACPI_LED_NEW:
/* all others */
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 12/14] ACPI: thinkpad-acpi: use a private workqueue
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (10 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 11/14] ACPI: thinkpad-acpi: fluff really minor fix Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 13/14] ACPI: thinkpad-acpi: fix selects in Kconfig Henrique de Moraes Holschuh
` (2 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh
Switch all task workers to a private thinkpad-acpi workqueue.
This way, we don't risk causing trouble for other tasks scheduled to the
default work queue, as our workers end up needing to access the ACPI EC,
run ACPI AML code, trigger SMI traps... and none of those are exactly known
to be fast, simple operations.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
drivers/misc/thinkpad_acpi.c | 26 +++++++++++++++++++-------
1 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index f471b46..d5c08c0 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -140,6 +140,7 @@ enum {
#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon"
#define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd"
+#define TPACPI_WORKQUEUE_NAME "ktpacpid"
#define TPACPI_MAX_ACPI_ARGS 3
@@ -272,6 +273,8 @@ static enum {
static int experimental;
static u32 dbg_level;
+static struct workqueue_struct *tpacpi_wq;
+
/* Special LED class that can defer work */
struct tpacpi_led_classdev {
struct led_classdev led_classdev;
@@ -3298,7 +3301,7 @@ static void light_sysfs_set(struct led_classdev *led_cdev,
struct tpacpi_led_classdev,
led_classdev);
data->new_brightness = brightness;
- schedule_work(&data->work);
+ queue_work(tpacpi_wq, &data->work);
}
static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
@@ -3355,7 +3358,7 @@ static void light_exit(void)
{
led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);
if (work_pending(&tpacpi_led_thinklight.work))
- flush_scheduled_work();
+ flush_workqueue(tpacpi_wq);
}
static int light_read(char *p)
@@ -3925,7 +3928,7 @@ static void led_sysfs_set(struct led_classdev *led_cdev,
struct tpacpi_led_classdev, led_classdev);
data->new_brightness = brightness;
- schedule_work(&data->work);
+ queue_work(tpacpi_wq, &data->work);
}
static int led_sysfs_blink_set(struct led_classdev *led_cdev,
@@ -3943,7 +3946,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev,
return -EINVAL;
data->new_brightness = TPACPI_LED_BLINK;
- schedule_work(&data->work);
+ queue_work(tpacpi_wq, &data->work);
return 0;
}
@@ -5408,11 +5411,11 @@ static void fan_watchdog_reset(void)
if (fan_watchdog_maxinterval > 0 &&
tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
fan_watchdog_active = 1;
- if (!schedule_delayed_work(&fan_watchdog_task,
+ if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task,
msecs_to_jiffies(fan_watchdog_maxinterval
* 1000))) {
printk(TPACPI_ERR
- "failed to schedule the fan watchdog, "
+ "failed to queue the fan watchdog, "
"watchdog will not trigger\n");
}
} else
@@ -5782,7 +5785,7 @@ static void fan_exit(void)
&driver_attr_fan_watchdog);
cancel_delayed_work(&fan_watchdog_task);
- flush_scheduled_work();
+ flush_workqueue(tpacpi_wq);
}
static int fan_read(char *p)
@@ -6436,6 +6439,9 @@ static void thinkpad_acpi_module_exit(void)
if (proc_dir)
remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
+ if (tpacpi_wq)
+ destroy_workqueue(tpacpi_wq);
+
kfree(thinkpad_id.bios_version_str);
kfree(thinkpad_id.ec_version_str);
kfree(thinkpad_id.model_str);
@@ -6466,6 +6472,12 @@ static int __init thinkpad_acpi_module_init(void)
TPACPI_ACPIHANDLE_INIT(ecrd);
TPACPI_ACPIHANDLE_INIT(ecwr);
+ tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME);
+ if (!tpacpi_wq) {
+ thinkpad_acpi_module_exit();
+ return -ENOMEM;
+ }
+
proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);
if (!proc_dir) {
printk(TPACPI_ERR
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 13/14] ACPI: thinkpad-acpi: fix selects in Kconfig
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (11 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 12/14] ACPI: thinkpad-acpi: use a private workqueue Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-26 4:02 ` [PATCH 14/14] ACPI: thinkpad-acpi: bump up version to 0.20 Henrique de Moraes Holschuh
2008-04-29 9:08 ` [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Len Brown
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh
Add missing select for BACKLIGHT_LCD_SUPPORT, as select doesn't select the
dependencies of a symbol for us.
Also, "select INPUT" in Kconfig. We are not an Input device, nor are we
anywhere close to the input subsystem in the Kconfig tree, so using
"depends on INPUT" is not user-friendly at all.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
drivers/misc/Kconfig | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 3a5d769..2e21794 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -241,10 +241,11 @@ config SONYPI_COMPAT
config THINKPAD_ACPI
tristate "ThinkPad ACPI Laptop Extras"
depends on X86 && ACPI
+ select BACKLIGHT_LCD_SUPPORT
select BACKLIGHT_CLASS_DEVICE
select HWMON
select NVRAM
- depends on INPUT
+ select INPUT
select NEW_LEDS
select LEDS_CLASS
---help---
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 14/14] ACPI: thinkpad-acpi: bump up version to 0.20
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (12 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 13/14] ACPI: thinkpad-acpi: fix selects in Kconfig Henrique de Moraes Holschuh
@ 2008-04-26 4:02 ` Henrique de Moraes Holschuh
2008-04-29 9:08 ` [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Len Brown
14 siblings, 0 replies; 18+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-04-26 4:02 UTC (permalink / raw)
To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi, Henrique de Moraes Holschuh
Full LED sysfs support, and the rest of the assorted minor fixes and
enhancements are a good reason to checkpoint a new version...
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
Documentation/laptops/thinkpad-acpi.txt | 4 ++--
drivers/misc/thinkpad_acpi.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 947b726..01c6c3d 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -1,7 +1,7 @@
ThinkPad ACPI Extras Driver
- Version 0.19
- January 06th, 2008
+ Version 0.20
+ April 09th, 2008
Borislav Deianov <borislav@users.sf.net>
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index d5c08c0..d29ad2e 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -21,7 +21,7 @@
* 02110-1301, USA.
*/
-#define TPACPI_VERSION "0.19"
+#define TPACPI_VERSION "0.20"
#define TPACPI_SYSFS_VERSION 0x020200
/*
--
1.5.4.4
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2)
2008-04-26 4:02 [GIT PATCH] thinkpad-acpi queue for the 2.6.26 merge window (v2) Henrique de Moraes Holschuh
` (13 preceding siblings ...)
2008-04-26 4:02 ` [PATCH 14/14] ACPI: thinkpad-acpi: bump up version to 0.20 Henrique de Moraes Holschuh
@ 2008-04-29 9:08 ` Len Brown
[not found] ` <200804290508.01452.lenb-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
14 siblings, 1 reply; 18+ messages in thread
From: Len Brown @ 2008-04-29 9:08 UTC (permalink / raw)
To: Henrique de Moraes Holschuh; +Cc: ibm-acpi-devel, linux-acpi
Wups,
looks like I still have v1 in my tree -- will fix.
-Len
On Saturday 26 April 2008, Henrique de Moraes Holschuh wrote:
> Len,
>
> This patchset has my current thinkpad-acpi queue. The target is 2.6.26's
> merge window.
>
> Some of the thinkpad-acpi patches require patches from Richard Purdie's LED
> tree that have been recently merged in mainline.
>
> As usual, the patch set is available at:
> git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git for-upstream/acpi-test
>
> Shortlog:
>
> Henrique de Moraes Holschuh (14):
> ACPI: thinkpad-acpi: BIOS backlight mode helper (v2.1)
> ACPI: thinkpad-acpi: warn once about weird hotkey masks
> ACPI: thinkpad-acpi: enhance box identification output (v2)
> ACPI: thinkpad-acpi: rate-limit CMOS/EC unsynced error messages
> ACPI: thinkpad-acpi: fix brightness dimming control bug
> ACPI: thinkpad-acpi: claim tpacpi as an official short handle (v1.1)
> ACPI: thinkpad-acpi: prepare light and LED for sysfs support
> ACPI: thinkpad-acpi: add sysfs led class support for thinklight (v3.1)
> ACPI: thinkpad-acpi: add sysfs led class support to thinkpad leds (v3.2)
> ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation
> ACPI: thinkpad-acpi: fluff really minor fix
> ACPI: thinkpad-acpi: use a private workqueue
> ACPI: thinkpad-acpi: fix selects in Kconfig
> ACPI: thinkpad-acpi: bump up version to 0.20
>
> Please merge the thinkpad-acpi changesets for acpi-test, for submission in
> the currently open mainline merge window.
>
^ permalink raw reply [flat|nested] 18+ messages in thread