ACPI patches for 2.6.26
Subsystems (10)
Len Brown
reviewerHere is the current queue for 2.6.26.
It is available in the git tree:git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git release
as well as a consolidated plain patch:
ftp://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/patches/release/2.6.25/acpi-release-20080321-2.6.25.diff.gz
I've excluded the ACPICA series and the PNP series from this patch-bomb, as you've recently seen them and they're unchanged since you did.
thanks,
-Len
Len Brown
reviewerPATCH 1/171 ACPI: crosslink ACPI and "real" device nodes
From: David Brownell <[email protected]>
Add cross-links between ACPI device and "real" devices in sysfs, exposing otherwise-hidden interrelationships between the various device nodes for ACPI stuff. As a representative example, one hardware device is exposed as two logical devices (PNP and ACPI):
.../pnp0/00:06/ .../LNXSYSTM:00/device:00/PNP0A03:00/device:15/PNP0B00:00/
The PNP device gets a "firmware_node" link pointing to the ACPI device, and is what a Linux device driver binds to. The ACPI device has instead a "physical_node" link pointing back to the PNP device. Other firmware frameworks, like OpenFirmware, could do the same thing to couple their firmware tables to the rest of the system.
(Based on a patch from Zhang Rui. This version is modified to not depend on the patch makig ACPI initialize driver model wakeup flags.)
--- drivers/acpi/glue.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)
drivers/acpi/glue.c +20 -0
@@ -142,6 +142,7 @@ EXPORT_SYMBOL(acpi_get_physical_device);static int acpi_bind_one (struct device *dev,acpi_handle handle) { +struct acpi_device *acpi_dev;acpi_status status;if (dev->archdata.acpi_handle) {
@@ -157,6 +158,16 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) } dev->archdata.acpi_handle = handle; + status =acpi_bus_get_device (handle, &acpi_dev); +if (!ACPI_FAILURE (status)) { +int ret; + + ret =sysfs_create_link (&dev->kobj, &acpi_dev->dev.kobj, +"firmware_node" ); + ret =sysfs_create_link (&acpi_dev->dev.kobj, &dev->kobj, +"physical_node" ); + } +return 0 ; }
@@ -165,8 +176,17 @@ static int acpi_unbind_one(struct device *dev)if (!dev->archdata.acpi_handle)return 0 ;if (dev ==acpi_get_physical_device (dev->archdata.acpi_handle)) { +struct acpi_device *acpi_dev; +/* acpi_get_physical_device increase refcnt by one */ put_device (dev); + +if (!acpi_bus_get_device (dev->archdata.acpi_handle, + &acpi_dev)) { +sysfs_remove_link (&dev->kobj,"firmware_node" ); +sysfs_remove_link (&acpi_dev->dev.kobj,"physical_node" ); + } +acpi_detach_data (dev->archdata.acpi_handle, acpi_glue_data_handler); dev->archdata.acpi_handle =NULL ;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 2/171 ACPI: EC: Restore udelay in poll mode
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
This fixes keyboard event handling on some systems.
Note that this delay was thought unnecessary, and removed
from linux-2.6.20 with 50c1e1138cb94f6aca0f8555777edbcefe0324e2 'ACPI: ec: Drop udelay() from poll mode. Loop by reading status field instead.'
--- drivers/acpi/ec.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/acpi/ec.c +2 -0
@@ -73,6 +73,7 @@ enum ec_event {#define ACPI_EC_DELAY 500/* Wait 500ms max. during EC ops */ #define ACPI_EC_UDELAY_GLK 1000/* Wait 1ms max. to get global lock */ +#define ACPI_EC_UDELAY 100/* Wait 100us before polling EC again */ enum {EC_FLAGS_WAIT_GPE =0 ,/* Don't check status until GPE arrives */
@@ -227,6 +228,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)while (time_before (jiffies, delay)) {if (acpi_ec_check_status (ec, event)) goto end; +udelay (ACPI_EC_UDELAY ); } } pr_err(PREFIX "acpi_ec_wait timeout,"
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 3/171 ACPI: EC: Add poll timer
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
If we can not use interrupt mode of EC for some reason, start polling EC for events periodically.
--- drivers/acpi/ec.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 files changed, 39 insertions(+), 4 deletions(-)
drivers/acpi/ec.c +39 -4
@@ -84,6 +84,7 @@ enum {EC_FLAGS_NO_WDATA_GPE ,/* Don't expect WDATA GPE event */ EC_FLAGS_WDATA ,/* Data is being written */ EC_FLAGS_NO_OBF1_GPE ,/* Don't expect GPE before read */ + EC_FLAGS_RESCHEDULE_POLL /* Re-schedule poll */ };static int acpi_ec_remove (struct acpi_device *device,int type);
@@ -130,6 +131,7 @@ static struct acpi_ec {struct mutex lock;wait_queue_head_t wait;struct list_head list; +struct delayed_work work;u8 handlers_installed; } *boot_ec, *first_ec;
@@ -178,6 +180,20 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)return 0 ; } +static void ec_schedule_ec_poll (struct acpi_ec *ec) +{ +if (test_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags)) +schedule_delayed_work (&ec->work, +msecs_to_jiffies (ACPI_EC_DELAY )); +} + +static void ec_switch_to_poll_mode (struct acpi_ec *ec) +{ +clear_bit (EC_FLAGS_GPE_MODE , &ec->flags); +acpi_disable_gpe (NULL , ec->gpe,ACPI_NOT_ISR ); +set_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags); +} +static int acpi_ec_wait (struct acpi_ec *ec,enum ec_event event,int force_poll) {int ret =0 ;
@@ -218,7 +234,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)if (printk_ratelimit ())pr_info (PREFIX "missing confirmations, " "switch off interrupt mode.\n" ); -clear_bit (EC_FLAGS_GPE_MODE , &ec->flags); +ec_switch_to_poll_mode (ec); +ec_schedule_ec_poll (ec); } goto end; }
@@ -529,28 +546,37 @@ static u32 acpi_ec_gpe_handler(void *data) {acpi_status status =AE_OK ;struct acpi_ec *ec = data; +u8 state =acpi_ec_read_status (ec);pr_debug (PREFIX "~~~> interrupt\n" );clear_bit (EC_FLAGS_WAIT_GPE , &ec->flags);if (test_bit (EC_FLAGS_GPE_MODE , &ec->flags))wake_up (&ec->wait); -if (acpi_ec_read_status (ec) &ACPI_EC_FLAG_SCI ) { +if (state &ACPI_EC_FLAG_SCI ) {if (!test_and_set_bit (EC_FLAGS_QUERY_PENDING , &ec->flags)) status =acpi_os_execute (OSL_EC_BURST_HANDLER , acpi_ec_gpe_query, ec); - }else if (unlikely (!test_bit (EC_FLAGS_GPE_MODE , &ec->flags))) { + }else if (!test_bit (EC_FLAGS_GPE_MODE , &ec->flags) && +in_interrupt ()) {/* this is non-query, must be confirmation */ if (printk_ratelimit ())pr_info (PREFIX "non-query interrupt received," " switching to interrupt mode\n" );set_bit (EC_FLAGS_GPE_MODE , &ec->flags); +clear_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags); } - +ec_schedule_ec_poll (ec);return ACPI_SUCCESS (status) ?ACPI_INTERRUPT_HANDLED :ACPI_INTERRUPT_NOT_HANDLED ; } +static void do_ec_poll (struct work_struct *work) +{ + struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work); + (void )acpi_ec_gpe_handler (ec); +} +/* -------------------------------------------------------------------------- Address Space Management -------------------------------------------------------------------------- */
@@ -711,6 +737,7 @@ static struct acpi_ec *make_acpi_ec(void)mutex_init (&ec->lock);init_waitqueue_head (&ec->wait);INIT_LIST_HEAD (&ec->list); +INIT_DELAYED_WORK_DEFERRABLE (&ec->work, do_ec_poll);return ec; }
@@ -752,8 +779,15 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)return AE_CTRL_TERMINATE ; } +static void ec_poll_stop (struct acpi_ec *ec) +{ +clear_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags); +cancel_delayed_work (&ec->work); +} +static void ec_remove_handlers (struct acpi_ec *ec) { +ec_poll_stop (ec);if (ACPI_FAILURE (acpi_remove_address_space_handler (ec->handle,ACPI_ADR_SPACE_EC , &acpi_ec_space_handler)))pr_err (PREFIX "failed to remove space handler\n" );
@@ -899,6 +933,7 @@ static int acpi_ec_start(struct acpi_device *device)/* EC is fully operational, allow queries */ clear_bit (EC_FLAGS_QUERY_PENDING , &ec->flags); +ec_schedule_ec_poll (ec);return ret; }
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 4/171 ACPI: EC: Improve debug output
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/ec.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
drivers/acpi/ec.c +4 -4
@@ -248,9 +248,9 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)udelay (ACPI_EC_UDELAY ); } } -pr_err (PREFIX "acpi_ec_wait timeout," -" status = %d, expect_event = %d\n" , -acpi_ec_read_status (ec), event); +pr_err (PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n" , +acpi_ec_read_status (ec), + (event ==ACPI_EC_EVENT_OBF_1 ) ?"\"b0=1\"" :"\"b1=0\"" ); ret = -ETIME ; end:clear_bit (EC_FLAGS_ADDRESS , &ec->flags);
@@ -264,8 +264,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, {int result =0 ;set_bit (EC_FLAGS_WAIT_GPE , &ec->flags); -acpi_ec_write_cmd (ec, command);pr_debug (PREFIX "transaction start\n" ); +acpi_ec_write_cmd (ec, command);for (; wdata_len >0 ; --wdata_len) { result =acpi_ec_wait (ec,ACPI_EC_EVENT_IBF_0 , force_poll);if (result) {
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 5/171 ACPI: EC: Replace broken controller workarounds with poll mode.
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/ec.c | 61 ++++++++++------------------------------------------ 1 files changed, 12 insertions(+), 49 deletions(-)
drivers/acpi/ec.c +12 -49
@@ -79,11 +79,7 @@ enum {EC_FLAGS_WAIT_GPE =0 ,/* Don't check status until GPE arrives */ EC_FLAGS_QUERY_PENDING ,/* Query is pending */ EC_FLAGS_GPE_MODE ,/* Expect GPE to be sent for status change */ -EC_FLAGS_NO_ADDRESS_GPE ,/* Expect GPE only for non-address event */ -EC_FLAGS_ADDRESS ,/* Address is being written */ -EC_FLAGS_NO_WDATA_GPE ,/* Don't expect WDATA GPE event */ -EC_FLAGS_WDATA ,/* Data is being written */ -EC_FLAGS_NO_OBF1_GPE ,/* Don't expect GPE before read */ +EC_FLAGS_NO_GPE ,/* Don't use GPE mode */ EC_FLAGS_RESCHEDULE_POLL /* Re-schedule poll */ };
@@ -189,6 +185,7 @@ static void ec_schedule_ec_poll(struct acpi_ec *ec)static void ec_switch_to_poll_mode (struct acpi_ec *ec) { +set_bit (EC_FLAGS_NO_GPE , &ec->flags);clear_bit (EC_FLAGS_GPE_MODE , &ec->flags);acpi_disable_gpe (NULL , ec->gpe,ACPI_NOT_ISR );set_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags);
@@ -196,65 +193,34 @@ static void ec_switch_to_poll_mode(struct acpi_ec *ec)static int acpi_ec_wait (struct acpi_ec *ec,enum ec_event event,int force_poll) { -int ret =0 ; - -if (unlikely (event ==ACPI_EC_EVENT_OBF_1 && -test_bit (EC_FLAGS_NO_OBF1_GPE , &ec->flags))) - force_poll =1 ; -if (unlikely (test_bit (EC_FLAGS_ADDRESS , &ec->flags) && -test_bit (EC_FLAGS_NO_ADDRESS_GPE , &ec->flags))) - force_poll =1 ; -if (unlikely (test_bit (EC_FLAGS_WDATA , &ec->flags) && -test_bit (EC_FLAGS_NO_WDATA_GPE , &ec->flags))) - force_poll =1 ;if (likely (test_bit (EC_FLAGS_GPE_MODE , &ec->flags)) &&likely (!force_poll)) {if (wait_event_timeout (ec->wait,acpi_ec_check_status (ec, event),msecs_to_jiffies (ACPI_EC_DELAY ))) - goto end; +return 0 ;clear_bit (EC_FLAGS_WAIT_GPE , &ec->flags);if (acpi_ec_check_status (ec, event)) { -if (event ==ACPI_EC_EVENT_OBF_1 ) { -/* miss OBF_1 GPE, don't expect it */ -pr_info (PREFIX "missing OBF confirmation, " -"don't expect it any longer.\n" ); -set_bit (EC_FLAGS_NO_OBF1_GPE , &ec->flags); - }else if (test_bit (EC_FLAGS_ADDRESS , &ec->flags)) { -/* miss address GPE, don't expect it anymore */ -pr_info (PREFIX "missing address confirmation, " -"don't expect it any longer.\n" ); -set_bit (EC_FLAGS_NO_ADDRESS_GPE , &ec->flags); - }else if (test_bit (EC_FLAGS_WDATA , &ec->flags)) { -/* miss write data GPE, don't expect it */ -pr_info (PREFIX "missing write data confirmation, " -"don't expect it any longer.\n" ); -set_bit (EC_FLAGS_NO_WDATA_GPE , &ec->flags); - }else { -/* missing GPEs, switch back to poll mode */ -if (printk_ratelimit ()) -pr_info (PREFIX "missing confirmations, " +/* missing GPEs, switch back to poll mode */ +if (printk_ratelimit ()) +pr_info (PREFIX "missing confirmations, " "switch off interrupt mode.\n" ); -ec_switch_to_poll_mode (ec); -ec_schedule_ec_poll (ec); - } - goto end; +ec_switch_to_poll_mode (ec); +ec_schedule_ec_poll (ec); +return 0 ; } }else {unsigned long delay = jiffies +msecs_to_jiffies (ACPI_EC_DELAY );clear_bit (EC_FLAGS_WAIT_GPE , &ec->flags);while (time_before (jiffies, delay)) {if (acpi_ec_check_status (ec, event)) - goto end; +return 0 ;udelay (ACPI_EC_UDELAY ); } }pr_err (PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n" ,acpi_ec_read_status (ec), (event ==ACPI_EC_EVENT_OBF_1 ) ?"\"b0=1\"" :"\"b1=0\"" ); - ret = -ETIME ; - end: -clear_bit (EC_FLAGS_ADDRESS , &ec->flags); -return ret; +return -ETIME ; } static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
@@ -273,15 +239,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, "write_cmd timeout, command = %d\n", command); goto end; } -/* mark the address byte written to EC */ -if (rdata_len + wdata_len >1 ) -set_bit (EC_FLAGS_ADDRESS , &ec->flags);set_bit (EC_FLAGS_WAIT_GPE , &ec->flags);acpi_ec_write_data (ec, *(wdata++)); }if (!rdata_len) { -set_bit (EC_FLAGS_WDATA , &ec->flags); result =acpi_ec_wait (ec,ACPI_EC_EVENT_IBF_0 , force_poll);if (result) { pr_err(PREFIX
@@ -558,6 +520,7 @@ static u32 acpi_ec_gpe_handler(void *data) status =acpi_os_execute (OSL_EC_BURST_HANDLER , acpi_ec_gpe_query, ec); }else if (!test_bit (EC_FLAGS_GPE_MODE , &ec->flags) && + !test_bit (EC_FLAGS_NO_GPE , &ec->flags) &&in_interrupt ()) {/* this is non-query, must be confirmation */ if (printk_ratelimit ())
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 6/171 ACPI: EC: Switch off GPE mode during suspend/resume
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/ec.c | 60 +++++++++++++++++++++++++++++++++------------------- 1 files changed, 38 insertions(+), 22 deletions(-)
drivers/acpi/ec.c +38 -22
@@ -83,28 +83,6 @@ enum { EC_FLAGS_RESCHEDULE_POLL /* Re-schedule poll */ }; -static int acpi_ec_remove (struct acpi_device *device,int type); -static int acpi_ec_start (struct acpi_device *device); -static int acpi_ec_stop (struct acpi_device *device,int type); -static int acpi_ec_add (struct acpi_device *device); - -static const struct acpi_device_id ec_device_ids[] = { - {"PNP0C09" ,0 }, - {"" ,0 }, -}; - -static struct acpi_driver acpi_ec_driver = { - .name ="ec" , - .class =ACPI_EC_CLASS , - .ids = ec_device_ids, - .ops = { - .add = acpi_ec_add, - .remove = acpi_ec_remove, - .start = acpi_ec_start, - .stop = acpi_ec_stop, - }, -}; -/* If we find an EC via the ECDT, we need to keep a ptr to its context */ /* External interfaces use first EC only, so remember */ typedef int (*acpi_ec_query_func ) (void *data);
@@ -924,6 +902,11 @@ int __init acpi_boot_ec_enable(void)return -EFAULT ; } +static const struct acpi_device_id ec_device_ids[] = { + {"PNP0C09" ,0 }, + {"" ,0 }, +}; +int __init acpi_ec_ecdt_probe (void ) {int ret;
@@ -973,6 +956,39 @@ int __init acpi_ec_ecdt_probe(void)return -ENODEV ; } +static int acpi_ec_suspend (struct acpi_device *device,pm_message_t state) +{ +struct acpi_ec *ec =acpi_driver_data (device); +/* Stop using GPE */ +set_bit (EC_FLAGS_NO_GPE , &ec->flags); +clear_bit (EC_FLAGS_GPE_MODE , &ec->flags); +acpi_disable_gpe (NULL , ec->gpe,ACPI_NOT_ISR ); +return 0 ; +} + +static int acpi_ec_resume (struct acpi_device *device) +{ +struct acpi_ec *ec =acpi_driver_data (device); +/* Enable use of GPE back */ +clear_bit (EC_FLAGS_NO_GPE , &ec->flags); +acpi_enable_gpe (NULL , ec->gpe,ACPI_NOT_ISR ); +return 0 ; +} + +static struct acpi_driver acpi_ec_driver = { + .name ="ec" , + .class =ACPI_EC_CLASS , + .ids = ec_device_ids, + .ops = { + .add = acpi_ec_add, + .remove = acpi_ec_remove, + .start = acpi_ec_start, + .stop = acpi_ec_stop, + .suspend = acpi_ec_suspend, + .resume = acpi_ec_resume, + }, +}; +static int __init acpi_ec_init (void ) {int result =0 ;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 7/171 ACPI: EC: Detect irq storm
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
Problem seems to be that hw fails to clear GPE after we service it and write 1 into corresponding bit. Thus, as soon as we get interrupts enabled again, we receive a new one. Google gives too many results for "acer interrupt storm" for this being one-broken-machine case.
Reference: http://bugzilla.kernel.org/show_bug.cgi?id=9998
--- drivers/acpi/ec.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
drivers/acpi/ec.c +11 -0
@@ -106,6 +106,7 @@ static struct acpi_ec {wait_queue_head_t wait;struct list_head list;struct delayed_work work; +atomic_t irq_count;u8 handlers_installed; } *boot_ec, *first_ec;
@@ -171,6 +172,7 @@ static void ec_switch_to_poll_mode(struct acpi_ec *ec)static int acpi_ec_wait (struct acpi_ec *ec,enum ec_event event,int force_poll) { +atomic_set (&ec->irq_count,0 );if (likely (test_bit (EC_FLAGS_GPE_MODE , &ec->flags)) &&likely (!force_poll)) { if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
@@ -489,6 +491,12 @@ static u32 acpi_ec_gpe_handler(void *data)u8 state =acpi_ec_read_status (ec);pr_debug (PREFIX "~~~> interrupt\n" ); +atomic_inc (&ec->irq_count); +if (atomic_read (&ec->irq_count) >5 ) { +pr_err (PREFIX "GPE storm detected, disabling EC GPE\n" ); +ec_switch_to_poll_mode (ec); + goto end; + }clear_bit (EC_FLAGS_WAIT_GPE , &ec->flags);if (test_bit (EC_FLAGS_GPE_MODE , &ec->flags))wake_up (&ec->wait);
@@ -507,6 +515,7 @@ static u32 acpi_ec_gpe_handler(void *data)set_bit (EC_FLAGS_GPE_MODE , &ec->flags);clear_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags); } +end:ec_schedule_ec_poll (ec);return ACPI_SUCCESS (status) ?ACPI_INTERRUPT_HANDLED :ACPI_INTERRUPT_NOT_HANDLED ;
@@ -515,6 +524,7 @@ static u32 acpi_ec_gpe_handler(void *data)static void do_ec_poll (struct work_struct *work) { struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work); +atomic_set (&ec->irq_count,0 ); (void )acpi_ec_gpe_handler (ec); }
@@ -679,6 +689,7 @@ static struct acpi_ec *make_acpi_ec(void)init_waitqueue_head (&ec->wait);INIT_LIST_HEAD (&ec->list);INIT_DELAYED_WORK_DEFERRABLE (&ec->work, do_ec_poll); +atomic_set (&ec->irq_count,0 );return ec; }
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 8/171 ACPI: EC: Use default setup handler
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/ec.c | 16 +--------------- 1 files changed, 1 insertions(+), 15 deletions(-)
drivers/acpi/ec.c +1 -15
@@ -533,20 +533,6 @@ static void do_ec_poll(struct work_struct *work)-------------------------------------------------------------------------- */ static acpi_status -acpi_ec_space_setup (acpi_handle region_handle, -u32 function,void *handler_context,void **return_context) -{ -/* -* The EC object is in the handler context and is needed -* when calling the acpi_ec_space_handler. -*/ - *return_context = (function !=ACPI_REGION_DEACTIVATE ) ? - handler_context :NULL ; - -return AE_OK ; -} - -static acpi_status acpi_ec_space_handler (u32 function,acpi_physical_address address,u32 bits,acpi_integer *value,void *handler_context,void *region_context)
@@ -858,7 +844,7 @@ static int ec_install_handlers(struct acpi_ec *ec) status =acpi_install_address_space_handler (ec->handle,ACPI_ADR_SPACE_EC , &acpi_ec_space_handler, - &acpi_ec_space_setup, ec); +NULL , ec);if (ACPI_FAILURE (status)) {acpi_remove_gpe_handler (NULL , ec->gpe, &acpi_ec_gpe_handler);return -ENODEV ;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 9/171 ACPI: EC: Don't delete boot EC
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/ec.c | 43 +++++++++++++++++++------------------------ 1 files changed, 19 insertions(+), 24 deletions(-)
drivers/acpi/ec.c +19 -24
@@ -708,9 +708,6 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) status =acpi_evaluate_integer (handle,"_GPE" ,NULL , &ec->gpe);if (ACPI_FAILURE (status))return status; -/* Find and register all query methods */ -acpi_walk_namespace (ACPI_TYPE_METHOD , handle,1 , - acpi_ec_register_query_methods, ec,NULL );/* Use the global lock for all EC transactions? */ acpi_evaluate_integer (handle,"_GLK" ,NULL , &ec->global_lock); ec->handle = handle;
@@ -745,31 +742,28 @@ static int acpi_ec_add(struct acpi_device *device)strcpy (acpi_device_class (device),ACPI_EC_CLASS );/* Check for boot EC */ -if (boot_ec) { -if (boot_ec->handle == device->handle) { -/* Pre-loaded EC from DSDT, just move pointer */ - ec = boot_ec; - boot_ec =NULL ; - goto end; - }else if (boot_ec->handle ==ACPI_ROOT_OBJECT ) { -/* ECDT-based EC, time to shut it down */ -ec_remove_handlers (boot_ec); -kfree (boot_ec); - first_ec = boot_ec =NULL ; +if (boot_ec && + (boot_ec->handle == device->handle || + boot_ec->handle ==ACPI_ROOT_OBJECT )) { + ec = boot_ec; + boot_ec =NULL ; + }else { + ec =make_acpi_ec (); +if (!ec) +return -ENOMEM ; +if (ec_parse_device (device->handle,0 , ec,NULL ) != +AE_CTRL_TERMINATE ) { +kfree (ec); +return -EINVAL ; } } - ec =make_acpi_ec (); -if (!ec) -return -ENOMEM ; - -if (ec_parse_device (device->handle,0 , ec,NULL ) != -AE_CTRL_TERMINATE ) { -kfree (ec); -return -EINVAL ; - } ec->handle = device->handle; - end: + +/* Find and register all query methods */ +acpi_walk_namespace (ACPI_TYPE_METHOD , ec->handle,1 , + acpi_ec_register_query_methods, ec,NULL ); +if (!first_ec) first_ec = ec;acpi_driver_data (device) = ec;
@@ -924,6 +918,7 @@ int __init acpi_ec_ecdt_probe(void) boot_ec->data_addr = ecdt_ptr->data.address; boot_ec->gpe = ecdt_ptr->gpe; boot_ec->handle =ACPI_ROOT_OBJECT ; +acpi_get_handle (ACPI_ROOT_OBJECT , ecdt_ptr->id, &boot_ec->handle); }else {/* This workaround is needed only on some broken machines, * which require early EC, but fail to provide ECDT */
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 10/171 ACPI : Disable the device's ability to wake the sleeping system in the boot phase
In reply to Len BrownFrom: Zhao Yakui <[email protected]>
In some machines some GPE is shared by several ACPI devices, for example:
sleep button, keyboard, mouse. At the same time one of them is non-wake(runtime) device and the other are wake devices. In such case OSPM should call the _PSW object to disable the device's ability to wake the sleeping system in the boot phase.
Otherwise there will be ACPI interrupt flood triggered by the GPE input.
The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. So it is necessary to call _DSW object first. Only when it is not present will the _PSW object used.
http://bugzilla.kernel.org/show_bug.cgi?id=10224
--- drivers/acpi/scan.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 42 insertions(+), 1 deletions(-)
drivers/acpi/scan.c +42 -1
@@ -692,6 +692,9 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)acpi_status status =0 ;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };union acpi_object *package =NULL ; +union acpi_object in_arg[3 ]; +struct acpi_object_list arg_list = {3 , in_arg }; +acpi_status psw_status =AE_OK ;struct acpi_device_id button_device_ids[] = { {"PNP0C0D" ,0 },
@@ -700,7 +703,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) {"", 0}, }; -/* _PRW */ status =acpi_evaluate_object (device->handle,"_PRW" ,NULL , &buffer);if (ACPI_FAILURE (status)) {
@@ -718,6 +720,45 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)kfree (buffer.pointer); device->wakeup.flags.valid =1 ; +/* Call _PSW/_DSW object to disable its ability to wake the sleeping +* system for the ACPI device with the _PRW object. +* The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. +* So it is necessary to call _DSW object first. Only when it is not +* present will the _PSW object used. +*/ +/* +* Three agruments are needed for the _DSW object. +* Argument 0: enable/disable the wake capabilities +* When _DSW object is called to disable the wake capabilities, maybe +* the first argument is filled. The value of the other two agruments +* is meaningless. +*/ + in_arg[0 ].type =ACPI_TYPE_INTEGER ; + in_arg[0 ].integer.value =0 ; + in_arg[1 ].type =ACPI_TYPE_INTEGER ; + in_arg[1 ].integer.value =0 ; + in_arg[2 ].type =ACPI_TYPE_INTEGER ; + in_arg[2 ].integer.value =0 ; + psw_status =acpi_evaluate_object (device->handle,"_DSW" , + &arg_list,NULL ); +if (ACPI_FAILURE (psw_status) && (psw_status !=AE_NOT_FOUND )) +ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"error in evaluate _DSW\n" )); +/* +* When the _DSW object is not present, OSPM will call _PSW object. +*/ +if (psw_status ==AE_NOT_FOUND ) { +/* +* Only one agruments is required for the _PSW object. +* agrument 0: enable/disable the wake capabilities +*/ + arg_list.count =1 ; + in_arg[0 ].integer.value =0 ; + psw_status =acpi_evaluate_object (device->handle,"_PSW" , + &arg_list,NULL ); +if (ACPI_FAILURE (psw_status) && (psw_status !=AE_NOT_FOUND )) +ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"error in " +"evaluate _PSW\n" )); + }/* Power button, Lid switch always enable wakeup */ if (!acpi_match_device_ids (device, button_device_ids)) device->wakeup.flags.run_wake =1 ;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 11/171 #if 0 acpi/bay.c:eject_removable_drive()
In reply to Len BrownFrom: Adrian Bunk <[email protected]>
This patch #if 0's the unused eject_removable_drive().
--- drivers/acpi/bay.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/acpi/bay.c +2 -0
@@ -201,6 +201,7 @@ static int is_ejectable_bay(acpi_handle handle)return 0 ; } +#if 0 /** * eject_removable_drive - try to eject this drive * @dev : the device structure of the drive
@@ -225,6 +226,7 @@ int eject_removable_drive(struct device *dev) return 0; }EXPORT_SYMBOL_GPL (eject_removable_drive); +#endif /* 0 */ static int acpi_bay_add_fs (struct bay *bay) {
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 12/171 PM: Remove legacy PM
In reply to Len BrownFrom: Pavel Machek <[email protected]>
AFAICT pm_send_all is a nop when noone uses pm_register...
Hmm.. can we just force CONFIG_PM_LEGACY=n, and see what happens?
Or maybe this is better idea? It may break build somewhere, but it should be easy to fix... (it builds here, i386 and x86-64).
--- arch/frv/kernel/pm.c | 8 -- arch/mips/au1000/common/power.c | 17 +--- arch/x86/kernel/apm_32.c | 15 --- kernel/power/Kconfig | 10 -- kernel/power/Makefile | 1 - kernel/power/pm.c | 205 --------------------------------------- 6 files changed, 2 insertions(+), 254 deletions(-) delete mode 100644 kernel/power/pm.c
arch/frv/kernel/pm.c +0 -8
@@ -163,14 +163,11 @@ static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp,if ((mode !=1 ) && (mode !=5 ))return -EINVAL ; - retval =pm_send_all (PM_SUSPEND , (void *)3 ); -if (retval ==0 ) {if (mode ==5 ) retval =pm_do_bus_sleep ();else retval =pm_do_suspend (); -pm_send_all (PM_RESUME , (void *)0 ); }return retval;
@@ -183,9 +180,6 @@ static int try_set_cmode(int new_cmode)if (!(clock_cmodes_permitted & (1 <<new_cmode)))return -EINVAL ; -/* tell all the drivers we're suspending */ -pm_send_all (PM_SUSPEND , (void *)3 ); -/* now change cmode */ local_irq_disable ();frv_dma_pause_all ();
@@ -201,8 +195,6 @@ static int try_set_cmode(int new_cmode)frv_dma_resume_all ();local_irq_enable (); -/* tell all the drivers we're resuming */ -pm_send_all (PM_RESUME , (void *)0 );return 0 ; }
arch/mips/au1000/common/power.c +2 -15
@@ -258,7 +258,6 @@ int au_sleep(void)static int pm_do_sleep (ctl_table * ctl,int write,struct file *file,void __user *buffer,size_t * len,loff_t *ppos) { -int retval =0 ;#ifdef SLEEP_TEST_TIMEOUT #define TMPBUFLEN2 16char buf[TMPBUFLEN2 ], *p;
@@ -278,33 +277,21 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, p = buf; sleep_ticks =simple_strtoul (p, &p,0 );#endif - retval =pm_send_all (PM_SUSPEND , (void *)2 ); - -if (retval) -return retval;au_sleep (); - retval =pm_send_all (PM_RESUME , (void *)0 ); } -return retval; +return 0 ; }static int pm_do_suspend (ctl_table * ctl,int write,struct file *file,void __user *buffer,size_t * len,loff_t *ppos) { -int retval =0 ; -if (!write) { *len =0 ; }else { - retval =pm_send_all (PM_SUSPEND , (void *)2 ); -if (retval) -return retval; suspend_mode =1 ; - - retval =pm_send_all (PM_RESUME , (void *)0 ); } -return retval; +return 0 ; }
arch/x86/kernel/apm_32.c +0 -15
@@ -1189,19 +1189,6 @@ static int suspend(int vetoable)int err;struct apm_user *as; -if (pm_send_all (PM_SUSPEND , (void *)3 )) { -/* Vetoed */ -if (vetoable) { -if (apm_info.connection_version >0x100 ) -set_system_power_state (APM_STATE_REJECT ); - err = -EBUSY ; - ignore_sys_suspend =0 ; -printk (KERN_WARNING "apm: suspend was vetoed.\n" ); - goto out; - } -printk (KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n" ); - } -device_suspend (PMSG_SUSPEND );local_irq_disable ();device_power_down (PMSG_SUSPEND );
@@ -1224,7 +1211,6 @@ static int suspend(int vetoable)device_power_up ();local_irq_enable ();device_resume (); -pm_send_all (PM_RESUME , (void *)0 );queue_event (APM_NORMAL_RESUME ,NULL ); out:spin_lock (&user_list_lock);
@@ -1337,7 +1323,6 @@ static void check_events(void)if ((event !=APM_NORMAL_RESUME ) || (ignore_normal_resume ==0 )) {device_resume (); -pm_send_all (PM_RESUME , (void *)0 );queue_event (event,NULL ); } ignore_normal_resume =0 ;
kernel/power/Kconfig +0 -10
@@ -19,16 +19,6 @@ config PM will issue the hlt instruction if nothing is to be done, thereby sending the processor to sleep and saving power. -config PM_LEGACY - bool "Legacy Power Management API (DEPRECATED)" - depends on PM - default n - ---help--- - Support for pm_register() and friends. This old API is obsoleted - by the driver model. - - If unsure, say N. - config PM_DEBUG bool "Power Management Debug Support" depends on PM
kernel/power/Makefile +0 -1
@@ -4,7 +4,6 @@ EXTRA_CFLAGS += -DDEBUG endif obj-y := main.o -obj-$(CONFIG_PM_LEGACY) += pm.o obj-$(CONFIG_PM_SLEEP) += process.o console.o obj-$(CONFIG_HIBERNATION) += swsusp.o disk.o snapshot.o swap.o user.o
kernel/power/pm.c deleted +0 -205
205 lines not on this page · raw message
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 13/171 PM: arch/x86/kernel/apm_32.c: fix build warning
In reply to Len BrownFrom: Andrew Morton <[email protected]>
arch/x86/kernel/apm_32.c:1215: warning: label 'out' defined but not used
--- arch/x86/kernel/apm_32.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)
arch/x86/kernel/apm_32.c +0 -1
@@ -1212,7 +1212,6 @@ static int suspend(int vetoable)local_irq_enable ();device_resume ();queue_event (APM_NORMAL_RESUME ,NULL ); - out:spin_lock (&user_list_lock);for (as = user_list; as !=NULL ; as = as->next) { as->suspend_wait =0 ;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 14/171 MIPS Alchemy: Crapectomy after removal of pm_send_all calls.
In reply to Len BrownFrom: Ralf Baechle <[email protected]>
--- arch/mips/au1000/common/power.c | 20 -------------------- 1 files changed, 0 insertions(+), 20 deletions(-)
arch/mips/au1000/common/power.c +0 -20
@@ -283,18 +283,6 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,return 0 ; } -static int pm_do_suspend (ctl_table * ctl,int write,struct file *file, -void __user *buffer,size_t * len,loff_t *ppos) -{ -if (!write) { - *len =0 ; - }else { - suspend_mode =1 ; - } -return 0 ; -} - -static int pm_do_freq (ctl_table * ctl,int write,struct file *file,void __user *buffer,size_t * len,loff_t *ppos) {
@@ -408,14 +396,6 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,static struct ctl_table pm_table[] = { { - .ctl_name =CTL_UNNUMBERED , - .procname ="suspend" , - .data =NULL , - .maxlen =0 , - .mode =0600 , - .proc_handler = &pm_do_suspend - }, - { .ctl_name =CTL_UNNUMBERED , .procname ="sleep" , .data =NULL ,
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 85/171 eeepc-laptop: add base driver
In reply to Len BrownFrom: Eric Cooper <[email protected]>
This patch is based on Eric Cooper's work to clean the original asus_acpi given by Asus. It's a platform driver (/sys/devices/platform/eeepc/) wich support:
- hotkeys - wlan on/off - camera on/off - cardr on/off
--- drivers/misc/Kconfig | 11 + drivers/misc/Makefile | 3 +- drivers/misc/eeepc-laptop.c | 442 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 455 insertions(+), 1 deletions(-) create mode 100644 drivers/misc/eeepc-laptop.c
drivers/misc/Kconfig +11 -0
@@ -327,4 +327,15 @@ config ENCLOSURE_SERVICES driver (SCSI/ATA) which supports enclosures or a SCSI enclosure device (SES) to use these services. +config EEEPC_LAPTOP + tristate "Eee PC Hotkey Driver (EXPERIMENTAL)" + depends on X86 + depends on ACPI + depends on EXPERIMENTAL + ---help--- + This driver supports the Fn-Fx keys on Eee PC laptops. + It also adds the ability to switch camera/wlan on/off. + + If you have an Eee PC laptop, say Y or M here. + endif # MISC_DEVICES
drivers/misc/Makefile +2 -1
@@ -7,7 +7,8 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_ACER_WMI) += acer-wmi.o -obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o +obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o +obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
drivers/misc/eeepc-laptop.c new file +442 -0
442 lines not on this page · raw message
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 86/171 eeepc-laptop: add backlight
In reply to Len BrownFrom: Corentin Chary <[email protected]>
Add backlight class support to the eeepc-laptop driver.
--- drivers/misc/Kconfig | 1 + drivers/misc/eeepc-laptop.c | 77 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 0 deletions(-)
drivers/misc/Kconfig +1 -0
@@ -331,6 +331,7 @@ config EEEPC_LAPTOP tristate "Eee PC Hotkey Driver (EXPERIMENTAL)" depends on X86 depends on ACPI + depends on BACKLIGHT_CLASS_DEVICE depends on EXPERIMENTAL ---help--- This driver supports the Fn-Fx keys on Eee PC laptops.
drivers/misc/eeepc-laptop.c +77 -0
139 lines not on this page · raw message
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 87/171 eeepc-laptop: add hwmon fan control
In reply to Len BrownFrom: Corentin Chary <[email protected]>
Adds an hwmon interface to control the fan.
--- drivers/misc/Kconfig | 1 + drivers/misc/eeepc-laptop.c | 147 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 0 deletions(-)
drivers/misc/Kconfig +1 -0
@@ -332,6 +332,7 @@ config EEEPC_LAPTOP depends on X86 depends on ACPI depends on BACKLIGHT_CLASS_DEVICE + depends on HWMON depends on EXPERIMENTAL ---help--- This driver supports the Fn-Fx keys on Eee PC laptops.
drivers/misc/eeepc-laptop.c +147 -0
198 lines not on this page · raw message
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 88/171 eeepc-laptop: MAINTAINERS entry
In reply to Len BrownFrom: Corentin CHARY <[email protected]>
--- MAINTAINERS | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
MAINTAINERS +7 -0
@@ -1523,6 +1523,13 @@ L: [email protected] W: bluesmoke.sourceforge.net S: Maintained +EEEPC LAPTOP EXTRAS DRIVER +P: Corentin Chary +M: [email protected] +L: [email protected] +W: http://sourceforge.net/projects/acpi4asus +S: Maintained + EEPRO100 NETWORK DRIVER P: Andrey V. Savochkin M: [email protected]
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 89/171 ACPI: re-name acpi_pm_ops to acpi_suspend_ops
In reply to Len BrownFrom: Len Brown <[email protected]>
... as they are platform_suspend_ops after all.
cosmetic re-name only, no functional change.
--- drivers/acpi/sleep/main.c | 42 +++++++++++++++++++++--------------------- 1 files changed, 21 insertions(+), 21 deletions(-)
drivers/acpi/sleep/main.c +21 -21
@@ -51,7 +51,7 @@ static int acpi_sleep_prepare(u32 acpi_state) }#ifdef CONFIG_SUSPEND -static struct platform_suspend_ops acpi_pm_ops; +static struct platform_suspend_ops acpi_suspend_ops;extern void do_suspend_lowlevel (void );
@@ -65,11 +65,11 @@ static u32 acpi_suspend_states[] = {static int init_8259A_after_S1;/** -* acpi_pm_begin - Set the target system sleep state to the state +* acpi_suspend_begin - Set the target system sleep state to the state * associated with given @pm_state, if supported. */ -static int acpi_pm_begin (suspend_state_t pm_state) +static int acpi_suspend_begin (suspend_state_t pm_state) {u32 acpi_state = acpi_suspend_states[pm_state];int error =0 ;
@@ -85,13 +85,13 @@ static int acpi_pm_begin(suspend_state_t pm_state) }/** -* acpi_pm_prepare - Do preliminary suspend work. +* acpi_suspend_prepare - Do preliminary suspend work. * * If necessary, set the firmware waking vector and do arch-specific * nastiness to get the wakeup code to the waking vector. */ -static int acpi_pm_prepare (void ) +static int acpi_suspend_prepare (void ) {int error =acpi_sleep_prepare (acpi_target_sleep_state);
@@ -104,7 +104,7 @@ static int acpi_pm_prepare(void) }/** -* acpi_pm_enter - Actually enter a sleep state. +* acpi_suspend_enter - Actually enter a sleep state. * @pm_state: ignored * * Flush caches and go to sleep. For STR we have to call arch-specific
@@ -112,7 +112,7 @@ static int acpi_pm_prepare(void)* It's unfortunate, but it works. Please fix if you're feeling frisky. */ -static int acpi_pm_enter (suspend_state_t pm_state) +static int acpi_suspend_enter (suspend_state_t pm_state) {acpi_status status =AE_OK ;unsigned long flags =0 ;
@@ -169,13 +169,13 @@ static int acpi_pm_enter(suspend_state_t pm_state) }/** -* acpi_pm_finish - Instruct the platform to leave a sleep state. +* acpi_suspend_finish - Instruct the platform to leave a sleep state. * * This is called after we wake back up (or if entering the sleep state * failed). */ -static void acpi_pm_finish (void ) +static void acpi_suspend_finish (void ) {u32 acpi_state = acpi_target_sleep_state;
@@ -196,19 +196,19 @@ static void acpi_pm_finish(void) }/** -* acpi_pm_end - Finish up suspend sequence. +* acpi_suspend_end - Finish up suspend sequence. */ -static void acpi_pm_end (void ) +static void acpi_suspend_end (void ) {/* -* This is necessary in case acpi_pm_finish() is not called during a +* This is necessary in case acpi_suspend_finish() is not called during a * failing transition to a sleep state. */ acpi_target_sleep_state =ACPI_STATE_S0 ; } -static int acpi_pm_state_valid (suspend_state_t pm_state) +static int acpi_suspend_state_valid (suspend_state_t pm_state) {u32 acpi_state;
@@ -224,13 +224,13 @@ static int acpi_pm_state_valid(suspend_state_t pm_state) } } -static struct platform_suspend_ops acpi_pm_ops = { - .valid = acpi_pm_state_valid, - .begin = acpi_pm_begin, - .prepare = acpi_pm_prepare, - .enter = acpi_pm_enter, - .finish = acpi_pm_finish, - .end = acpi_pm_end, +static struct platform_suspend_ops acpi_suspend_ops = { + .valid = acpi_suspend_state_valid, + .begin = acpi_suspend_begin, + .prepare = acpi_suspend_prepare, + .enter = acpi_suspend_enter, + .finish = acpi_suspend_finish, + .end = acpi_suspend_end, };/*
@@ -492,7 +492,7 @@ int __init acpi_sleep_init(void) } } -suspend_set_ops (&acpi_pm_ops); +suspend_set_ops (&acpi_suspend_ops);#endif #ifdef CONFIG_HIBERNATION
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 91/171 ACPI: GPE enabling should happen after EC installation
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
GPE could try to access EC region, so should not be enabled before EC is installed
http://bugzilla.kernel.org/show_bug.cgi?id=9916
--- drivers/acpi/utilities/utxface.c | 35 +++++++++++++++++------------------ 1 files changed, 17 insertions(+), 18 deletions(-)
drivers/acpi/utilities/utxface.c +17 -18
@@ -192,24 +192,6 @@ acpi_status acpi_enable_subsystem(u32 flags) } } -/* -* Complete the GPE initialization for the GPE blocks defined in the FADT -* (GPE block 0 and 1). -* -* Note1: This is where the _PRW methods are executed for the GPEs. These -* methods can only be executed after the SCI and Global Lock handlers are -* installed and initialized. -* -* Note2: Currently, there seems to be no need to run the _REG methods -* before execution of the _PRW methods and enabling of the GPEs. -*/ -if (!(flags &ACPI_NO_EVENT_INIT )) { - status =acpi_ev_install_fadt_gpes (); -if (ACPI_FAILURE (status)) { -return (status); - } - } -return_ACPI_STATUS (status); }
@@ -280,6 +262,23 @@ acpi_status acpi_initialize_objects(u32 flags) }/* +* Complete the GPE initialization for the GPE blocks defined in the FADT +* (GPE block 0 and 1). +* +* Note1: This is where the _PRW methods are executed for the GPEs. These +* methods can only be executed after the SCI and Global Lock handlers are +* installed and initialized. +* +* Note2: Currently, there seems to be no need to run the _REG methods +* before execution of the _PRW methods and enabling of the GPEs. +*/ +if (!(flags &ACPI_NO_EVENT_INIT )) { + status =acpi_ev_install_fadt_gpes (); +if (ACPI_FAILURE (status)) +return (status); + } + +/* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- * thus wasting non-paged memory.
Signature · 1 line
1.5.5.1.99.gf0ec4
Re: [PATCH 091/171] ACPI: GPE enabling should happen after EC installation
Quoted 4 lines · Len Brown
From: Alexey Starikovskiy <[email protected]>
GPE could try to access EC region, so should not be enabled before EC is installed
It is caused by broken bios if GPE method tries to access EC region before EC is initialized correctly. It is more appropriate to fix this issue by upgrading bios rather than by the patch.
And this patch will cause some potential problems.
In the course of GPE event initialization the GPE will be set as RUN_TIME and deferred to be enabled.(Only update the GPE enable mask and not write the GPE register). And when the acpi_ev_install_fadt_gpes is called, some GPEs will be changed from the RUN_TIME to WAKEUP and only RUNTIME GPEs are enabled.(GPE register will be accessed).
If acpi_ev_install_fadt_gpe is called after EC is stalled, the acpi_enable_gpe will be called , in which some GPEs will be also enabled. In fact these are the WAKUP GPEs and shouldn't be enabled. Maybe this will bring some potential problems.
Best regards.
Yakui
Quoted 61 lines
http://bugzilla.kernel.org/show_bug.cgi?id=9916
Signed-off-by Alexey Starikovskiy <[email protected]>Signed-off-by Len Brown <[email protected]>--- drivers/acpi/utilities/utxface.c | 35 +++++++++++++++++------------------ 1 files changed, 17 insertions(+), 18 deletions(-)drivers/acpi/utilities/utxface.c +17
-18@@ -192,24 +192,6 @@ acpi_status acpi_enable_subsystem(u32 flags) } } -/* -* Complete the GPE initialization for the GPE blocks defined in the FADT -* (GPE block 0 and 1). -* -* Note1: This is where the _PRW methods are executed for the GPEs. These -* methods can only be executed after the SCI and Global Lock handlers are -* installed and initialized. -* -* Note2: Currently, there seems to be no need to run the _REG methods -* before execution of the _PRW methods and enabling of the GPEs. -*/ -if (!(flags &ACPI_NO_EVENT_INIT )) { - status =acpi_ev_install_fadt_gpes (); -if (ACPI_FAILURE (status)) { -return (status); - } - } -return_ACPI_STATUS (status); }@@ -280,6 +262,23 @@ acpi_status acpi_initialize_objects(u32 flags) }/* +* Complete the GPE initialization for the GPE blocks defined in the FADT +* (GPE block 0 and 1). +* +* Note1: This is where the _PRW methods are executed for the GPEs. These +* methods can only be executed after the SCI and Global Lock handlers are +* installed and initialized. +* +* Note2: Currently, there seems to be no need to run the _REG methods +* before execution of the _PRW methods and enabling of the GPEs. +*/ +if (!(flags &ACPI_NO_EVENT_INIT )) { + status =acpi_ev_install_fadt_gpes (); +if (ACPI_FAILURE (status)) +return (status); + } + +/* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- * thus wasting non-paged memory.
Re: [PATCH 091/171] ACPI: GPE enabling should happen after EC installation
Quoted 10 lines · On Wednesday 30 April 2008 11:25:34 Zhao Yakui wrote:
Quoted 4 lines · Len Brown
From: Alexey Starikovskiy <[email protected]>
GPE could try to access EC region, so should not be enabled before EC is installed
It is caused by broken bios if GPE method tries to access EC region before EC is initialized correctly. It is more appropriate to fix this issue by upgrading bios rather than by the patch.
And this patch will cause some potential problems.
1) Does the BIOS in question work under Windows?
2) Does the system in question require a BIOS upgrade under Windows for this issue?
If the answer to both of those is 'no', then the answer is that it's a Linux bug, and a patch of some description is appropriate.
Just because there are crappy BIOS's out there, and we'd rather not put in nasty fixes, doesn't mean that we shouldn't.
-Carlos
Signature · 3 lines
E-Mail: [email protected] Web: strangeworlds.co.uk GPG Key ID: 0x23EE722D
Re: [PATCH 091/171] ACPI: GPE enabling should happen after EC installation
Quoted 7 lines · On Wednesday 30 April 2008 07:58:53 Carlos Corbacho wrote:
Quoted 6 lines · On Wednesday 30 April 2008 11:25:34 Zhao Yakui wrote:
Quoted 4 lines · Len Brown
From: Alexey Starikovskiy <[email protected]>
GPE could try to access EC region, so should not be enabled before EC is installed
Quoted 6 lines
Quoted 4 lines
It is caused by broken bios if GPE method tries to access EC region before EC is initialized correctly. It is more appropriate to fix this issue by upgrading bios rather than by the patch.
And this patch will cause some potential problems.1) Does the BIOS in question work under Windows?
^^^
that should be 'not work'
Quoted 8 lines
2) Does the system in question require a BIOS upgrade under Windows for this issue?
If the answer to both of those is 'no', then the answer is that it's a Linux bug, and a patch of some description is appropriate.
Just because there are crappy BIOS's out there, and we'd rather not put in nasty fixes, doesn't mean that we shouldn't.
-Carlos
Signature · 3 lines
E-Mail: [email protected] Web: strangeworlds.co.uk GPG Key ID: 0x23EE722D
Re: [PATCH 091/171] ACPI: GPE enabling should happen after EC installation
Quoted 13 lines · Carlos Corbacho
Quoted 12 lines · On Wednesday 30 April 2008 07:58:53 Carlos Corbacho wrote:
Quoted 10 lines · On Wednesday 30 April 2008 11:25:34 Zhao Yakui wrote:
Quoted 4 lines · Len Brown
From: Alexey Starikovskiy <[email protected]>
GPE could try to access EC region, so should not be enabled before EC is installed
It is caused by broken bios if GPE method tries to access EC region before EC is initialized correctly. It is more appropriate to fix this issue by upgrading bios rather than by the patch.
And this patch will cause some potential problems.
Quoted 4 lines
Quoted 1 line
1) Does the BIOS in question work under Windows?
^^^
that should be 'not work'
For the laptop in bug 9916:
Windows can work on the BIOS in question. In fact only warning message is printed for Linux and it won't break anything. (Maybe the warning message also exists on windows. But we can't see them.)
Quoted 4 lines
Quoted 4 lines
2) Does the system in question require a BIOS upgrade under Windows for this issue?
After the BIOS is upgraded, the warning message disappears on Linux. It is very lucky that we have such a laptop. After the bios is upgraded, the warning message disappears.
Quoted 8 lines
Quoted 5 lines
If the answer to both of those is 'no', then the answer is that it's a Linux bug, and a patch of some description is appropriate.
Just because there are crappy BIOS's out there, and we'd rather not put in nasty fixes, doesn't mean that we shouldn't.
-Carlos
Re: [PATCH 091/171] ACPI: GPE enabling should happen after EC installation
Quoted 12 lines · Zhao Yakui
Quoted 11 lines · Carlos Corbacho
Quoted 10 lines · On Wednesday 30 April 2008 07:58:53 Carlos Corbacho wrote:
Quoted 9 lines · On Wednesday 30 April 2008 11:25:34 Zhao Yakui wrote:
Quoted 4 lines · Len Brown
From: Alexey Starikovskiy <[email protected]>
GPE could try to access EC region, so should not be enabled before EC is installed
It is caused by broken bios if GPE method tries to access EC region before EC is initialized correctly. It is more appropriate to fix this issue by upgrading bios rather than by the patch.
And this patch will cause some potential problems.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
1) Does the BIOS in question work under Windows?
^^^
that should be 'not work'For the laptop in bug 9916:
Windows can work on the BIOS in question. In fact only warning message is printed for Linux and it won't break anything. (Maybe the warning message also exists on windows. But we can't see them.)
This is generally a stupid idea to enable interrupt before you have handler for it ready, even if you are able to _survive_ unhandled interrupt.
Your other issue about WAKE GPEs, which could be wrongly enabled, could be solved by moving WAKE GPE init closer to RUNTIME GPE one:
Regards,
Alex.
drivers/acpi/events/evgpeblk.c +0 -0
@@ -940,6 +940,27 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
acpi_ev_save_method_info, gpe_block, NULL);
+ /*
+ * Runtime option: Should wake GPEs be enabled at runtime? The default
+ * is no, they should only be enabled just as the machine goes to sleep.
+ */
+ if (acpi_gbl_leave_wake_gpes_disabled) {
+ /*
+ * Differentiate runtime vs wake GPEs, via the _PRW control methods.
+ * Each GPE that has one or more _PRWs that reference it is by
+ * definition a wake GPE and will not be enabled while the machine
+ * is running.
+ */
+ gpe_info.gpe_block = gpe_block;
+ gpe_info.gpe_device = gpe_device;
+
+ status =
+ acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
+ acpi_ev_match_prw_and_gpe, &gpe_info,
+ NULL);
+ }
+
/* Return the new block */
if (return_gpe_block) {
@@ -995,27 +1016,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
}
/*- * Runtime option: Should wake GPEs be enabled at runtime? The default
- * is no, they should only be enabled just as the machine goes to sleep.
- */
- if (acpi_gbl_leave_wake_gpes_disabled) {
- /*
- * Differentiate runtime vs wake GPEs, via the _PRW control methods.
- * Each GPE that has one or more _PRWs that reference it is by
- * definition a wake GPE and will not be enabled while the machine
- * is running.
- */
- gpe_info.gpe_block = gpe_block;
- gpe_info.gpe_device = gpe_device;
-
- status =
- acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - acpi_ev_match_prw_and_gpe, &gpe_info, - NULL);
- }
-
- /*
* Enable all GPEs in this block that have these attributes:
* 1) are "runtime" or "run/wake" GPEs, and
* 2) have a corresponding _Lxx or _Exx method
Re: [PATCH 091/171] ACPI: GPE enabling should happen after EC installation
Quoted 20 lines · Alexey Starikovskiy
Quoted 12 lines · Zhao Yakui
Quoted 11 lines · Carlos Corbacho
Quoted 10 lines · On Wednesday 30 April 2008 07:58:53 Carlos Corbacho wrote:
Quoted 9 lines · On Wednesday 30 April 2008 11:25:34 Zhao Yakui wrote:
Quoted 4 lines · Len Brown
From: Alexey Starikovskiy <[email protected]>
GPE could try to access EC region, so should not be enabled before EC is installed
It is caused by broken bios if GPE method tries to access EC region before EC is initialized correctly. It is more appropriate to fix this issue by upgrading bios rather than by the patch.
And this patch will cause some potential problems.Quoted 7 lines
Quoted 3 lines
Quoted 1 line
1) Does the BIOS in question work under Windows?
^^^
that should be 'not work'For the laptop in bug 9916:
Windows can work on the BIOS in question. In fact only warning message is printed for Linux and it won't break anything. (Maybe the warning message also exists on windows. But we can't see them.)
Quoted 5 lines
This is generally a stupid idea to enable interrupt before you have handler for it ready, even if you are able to _survive_ unhandled interrupt.
Your other issue about WAKE GPEs, which could be wrongly enabled, could be solved by moving WAKE GPE init closer to RUNTIME GPE one:
Thanks for the so quick response.
The following patch can solve the issue about the WAKE GPEs.
But after the patch is applied, it seems that we make a lot of changes about the GPE initialization flowchart in ACPICA. Will these be easily accepted by ACPICA author?
At the same time some RUNTIME GPEs will be enabled twice. When acpi_enable_gpe is called in the course of EC installation, some RUNTIME GPEs will also be enabled. In fact when the acpi_ev_install_fadt_gpes is called, all the RUNTIME GPEs will be enabled. In such case it brings that some RUNTIME GPEs are enabled twice. Of course the patch should work fine if it is safe to enable RUNTTME GPEs twice.
Best regards.
Yakui
Quoted 66 lines
Regards,
Alex.drivers/acpi/events/evgpeblk.c +21
-21@@ -940,6 +940,27 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, acpi_ev_save_method_info, gpe_block, NULL); +/* +* Runtime option: Should wake GPEs be enabled at runtime? The default +* is no, they should only be enabled just as the machine goes to sleep. +*/ +if (acpi_gbl_leave_wake_gpes_disabled) { +/* +* Differentiate runtime vs wake GPEs, via the _PRW control methods. +* Each GPE that has one or more _PRWs that reference it is by +* definition a wake GPE and will not be enabled while the machine +* is running. +*/ + gpe_info.gpe_block = gpe_block; + gpe_info.gpe_device = gpe_device; + + status = +acpi_ns_walk_namespace (ACPI_TYPE_DEVICE ,ACPI_ROOT_OBJECT , +ACPI_UINT32_MAX ,ACPI_NS_WALK_UNLOCK , + acpi_ev_match_prw_and_gpe, &gpe_info, +NULL ); + } +/* Return the new block */ if (return_gpe_block) {@@ -995,27 +1016,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, }/* -* Runtime option: Should wake GPEs be enabled at runtime? The default -* is no, they should only be enabled just as the machine goes to sleep. -*/ -if (acpi_gbl_leave_wake_gpes_disabled) { -/* -* Differentiate runtime vs wake GPEs, via the _PRW control methods. -* Each GPE that has one or more _PRWs that reference it is by -* definition a wake GPE and will not be enabled while the machine -* is running. -*/ - gpe_info.gpe_block = gpe_block; - gpe_info.gpe_device = gpe_device; - - status = -acpi_ns_walk_namespace (ACPI_TYPE_DEVICE ,ACPI_ROOT_OBJECT , -ACPI_UINT32_MAX ,ACPI_NS_WALK_UNLOCK , - acpi_ev_match_prw_and_gpe, &gpe_info, -NULL ); - } - -/* * Enable all GPEs in this block that have these attributes: * 1) are "runtime" or "run/wake" GPEs, and * 2) have a corresponding _Lxx or _Exx method
Re: [PATCH 091/171] ACPI: GPE enabling should happen after EC installation
Quoted 2 lines · Zhao Yakui
But after the patch is applied, it seems that we make a lot of changes about the GPE initialization flowchart in ACPICA.
And this flowchart is cast in stone?
Quoted 1 line
Will these be easily accepted by ACPICA author?
You should probably ask him, not me. We are talking Bob Moore here, yes? Why don't you add CC to him if you are worried?
Quoted 6 lines
At the same time some RUNTIME GPEs will be enabled twice. When
acpi_enable_gpeis called in the course of EC installation, some RUNTIME GPEs will also be enabled. In fact when theacpi_ev_install_fadt_gpesis called, all the RUNTIME GPEs will be enabled. In such case it brings that some RUNTIME GPEs are enabled twice. Of course the patch should work fine if it is safe to enable RUNTTME GPEs twice.
Please advise me, how we are not enabling them twice if EC init happens after? The same acpi_enable_gpe will be called from it.
Regards,
Alex.
Re: [PATCH 091/171] ACPI: GPE enabling should happen after EC installation
Quoted 4 lines · Alexey Starikovskiy
Quoted 2 lines · Zhao Yakui
But after the patch is applied, it seems that we make a lot of changes about the GPE initialization flowchart in ACPICA.
And this flowchart is cast in stone?
After the two patches are applied, the issue in bug9916 can be fixed. But in fact the issue in bug9916 is related with bios.
In the L02 method the _PSR object of AC will be accessed.
Quoted 4 lines
Method (
_PSR, 0, NotSerialized){ Return (HPAC) }
HPAC is defined in EC OperationRegion. IMO Whether the HPAC can be
accessed should be determined by the flag of H8DR, which indicates whether the EC operation region can be accessed. (1 means that EC opregion can be accessed. 0 means that EC opregion can't be accessed.)
It seems that this is an obvious bios bug. It is more appropriate to
fix this issue by upgrading bios.
IMO it is unnecessary to make a lot of changes about GPE
initialization flowchart for the obvious bios bug.
At the same time it is very luck that there exists ECDT table on the
laptop of bug9916. And after the two patches are applied, the GPE can be enabled after EC installation. But if the ECDT table doesn't exist(EC device has no _INI object in DSDT table), it seems that GPE enabling still happens before EC installation.
Quoted 3 lines
Quoted 1 line
Will these be easily accepted by ACPICA author?
You should probably ask him, not me. We are talking Bob Moore here, yes? Why don't you add CC to him if you are worried?
CC Bob and Lin Ming to see this issue.
Quoted 12 lines
Quoted 6 lines
At the same time some RUNTIME GPEs will be enabled twice. When
acpi_enable_gpeis called in the course of EC installation, some RUNTIME GPEs will also be enabled. In fact when theacpi_ev_install_fadt_gpesis called, all the RUNTIME GPEs will be enabled. In such case it brings that some RUNTIME GPEs are enabled twice. Of course the patch should work fine if it is safe to enable RUNTTME GPEs twice.Please advise me, how we are not enabling them twice if EC init happens after? The same
acpi_enable_gpewill be called from it.Regards,
Alex.
Re: [PATCH 091/171] ACPI: GPE enabling should happen after EC installation
In reply to Carlos CorbachoQuoted 12 lines · Carlos Corbacho
Quoted 10 lines · On Wednesday 30 April 2008 11:25:34 Zhao Yakui wrote:
Quoted 4 lines · Len Brown
From: Alexey Starikovskiy <[email protected]>
GPE could try to access EC region, so should not be enabled before EC is installed
It is caused by broken bios if GPE method tries to access EC region before EC is initialized correctly. It is more appropriate to fix this issue by upgrading bios rather than by the patch.
And this patch will cause some potential problems.
Quoted 6 lines
1) Does the BIOS in question work under Windows?
2) Does the system in question require a BIOS upgrade under Windows for this issue?If the answer to both of those is 'no', then the answer is that it's a Linux bug, and a patch of some description is appropriate.
3) Did the vendor issue an O.S. "driver workaround"? If so, it means we add a *quirk*, and not that we hose ACPI for everyone else.
Quoted 2 lines
Just because there are crappy BIOS's out there, and we'd rather not put in nasty fixes, doesn't mean that we shouldn't.
But it means we need to limit the damage these nasty fixes can do to others.
Signature · 4 lines
"One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
Len Brown
reviewerPATCH 92/171 2.6.25 regression: powertop says 120K wakeups/sec
In reply to Len BrownFrom: Venkatesh Pallipadi <[email protected]>
Patch to fix huge number of wakeups reported due to recent changes in processor_idle.c. The problem was that the entry_method determination was broken due to one of the recent commits (bc71bec91f987) causing C1 entry to not to go to halt.
http://lkml.org/lkml/2008/3/22/124
--- drivers/acpi/processor_idle.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
drivers/acpi/processor_idle.c +4 -0
@@ -848,6 +848,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr)/* all processors need to support C1 */ pr->power.states[ACPI_STATE_C1 ].type =ACPI_STATE_C1 ; pr->power.states[ACPI_STATE_C1 ].valid =1 ; + pr->power.states[ACPI_STATE_C1 ].entry_method =ACPI_CSTATE_HALT ; }/* the C0 state only exists as a filler in our array */ pr->power.states[ACPI_STATE_C0 ].valid =1 ;
@@ -960,6 +961,9 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) cx.address); } +if (cx.type ==ACPI_STATE_C1 ) { + cx.valid =1 ; + } obj = &(element->package.elements[2 ]);if (obj->type !=ACPI_TYPE_INTEGER )
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 93/171 flush kacpi_notify_wq before removing notify handler
In reply to Len BrownFrom: Zhang Rui <[email protected]>
Flush kacpi_notify_wq before notify handler is removed, this can fix a bug which the deferred notify handler is executed after the notify_handler has already been removed.
http://bugzilla.kernel.org/show_bug.cgi?id=9772
--- drivers/acpi/osl.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/acpi/osl.c +1 -0
@@ -742,6 +742,7 @@ EXPORT_SYMBOL(acpi_os_execute);void acpi_os_wait_events_complete (void *context) {flush_workqueue (kacpid_wq); +flush_workqueue (kacpi_notify_wq); }EXPORT_SYMBOL (acpi_os_wait_events_complete);
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 94/171 thermal: add the support for building the generic thermal as a module
In reply to Len BrownFrom: Zhang Rui <[email protected]>
Build the generic thermal driver as module "thermal_sys".
Make ACPI thermal, video, processor and fan SELECT the generic thermal driver, as these drivers rely on it to build the sysfs I/F.
--- drivers/acpi/Kconfig | 3 +++ drivers/misc/Kconfig | 1 + drivers/thermal/Kconfig | 4 ++-- drivers/thermal/Makefile | 3 ++- drivers/thermal/thermal.c | 2 +- include/linux/thermal.h | 14 -------------- 6 files changed, 9 insertions(+), 18 deletions(-)
drivers/acpi/Kconfig +3 -0
@@ -140,6 +140,7 @@ config ACPI_VIDEO tristate "Video" depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL depends on INPUT + select THERMAL help This driver implement the ACPI Extensions For Display Adapters for integrated graphics devices on motherboard, as specified in
@@ -151,6 +152,7 @@ config ACPI_VIDEO config ACPI_FAN tristate "Fan" + select THERMAL default y help This driver adds support for ACPI fan devices, allowing user-mode
@@ -172,6 +174,7 @@ config ACPI_BAY config ACPI_PROCESSOR tristate "Processor" + select THERMAL default y help This driver installs ACPI as the idle handler for Linux, and uses
drivers/misc/Kconfig +1 -0
@@ -344,6 +344,7 @@ config ATMEL_SSC config INTEL_MENLOW tristate "Thermal Management driver for Intel menlow platform" depends on ACPI_THERMAL + select THERMAL depends on X86 ---help--- ACPI thermal management enhancement driver on
drivers/thermal/Kconfig +2 -2
@@ -3,7 +3,7 @@ # menuconfig THERMAL - bool "Generic Thermal sysfs driver" + tristate "Generic Thermal sysfs driver" help Generic Thermal Sysfs driver offers a generic mechanism for thermal management. Usually it's made up of one or more thermal
@@ -11,4 +11,4 @@ menuconfig THERMAL Each thermal zone contains its own temperature, trip points, cooling devices. All platforms with ACPI thermal support can use this driver. - If you want this support, you should say Y here. + If you want this support, you should say Y or M here.
drivers/thermal/Makefile +2 -1
@@ -2,4 +2,5 @@ # Makefile for sensor chip drivers. # -obj-$(CONFIG_THERMAL) += thermal.o +thermal_sys-objs += thermal.o +obj-$(CONFIG_THERMAL) += thermal_sys.o
drivers/thermal/thermal.c +1 -1
@@ -31,7 +31,7 @@#include <linux/thermal.h> #include <linux/spinlock.h> -MODULE_AUTHOR("Zhang Rui") +MODULE_AUTHOR ("Zhang Rui" );MODULE_DESCRIPTION ("Generic thermal management sysfs support" );MODULE_LICENSE ("GPL" );
include/linux/thermal.h +0 -14
@@ -88,24 +88,10 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, struct thermal_cooling_device *);int thermal_zone_unbind_cooling_device (struct thermal_zone_device *,int ,struct thermal_cooling_device *); - -#ifdef CONFIG_THERMAL struct thermal_cooling_device *thermal_cooling_device_register (char *,void *,struct thermal_cooling_device_ops *);void thermal_cooling_device_unregister (struct thermal_cooling_device *); -#else -static inline struct thermal_cooling_device -*thermal_cooling_device_register (char *c,void *v, -struct thermal_cooling_device_ops *t) -{ -return NULL ; -} -static inline -void thermal_cooling_device_unregister (struct thermal_cooling_device *t) -{ -}; -#endif #endif /* __THERMAL_H__ */
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 95/171 thermal: add new get_crit_temp callback
In reply to Len BrownFrom: Zhang, Rui <[email protected]>
Add a new callback so that the generic thermal can get the critical trip point info of a thermal zone,
which is needed for building the tempX_crit hwmon sysfs attribute.
--- drivers/acpi/thermal.c | 13 +++++++++++++ include/linux/thermal.h | 1 + 2 files changed, 14 insertions(+), 0 deletions(-)
drivers/acpi/thermal.c +13 -0
@@ -1012,6 +1012,18 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,return -EINVAL ; } +static int thermal_get_crit_temp (struct thermal_zone_device *thermal, +unsigned long *temperature) { +struct acpi_thermal *tz = thermal->devdata; + +if (tz->trips.critical.flags.valid) { + *temperature =KELVIN_TO_MILLICELSIUS ( + tz->trips.critical.temperature); +return 0 ; + }else +return -EINVAL ; +} +typedef int (*cb )(struct thermal_zone_device *,int ,struct thermal_cooling_device *); static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1103,6 +1115,7 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = { .set_mode = thermal_set_mode, .get_trip_type = thermal_get_trip_type, .get_trip_temp = thermal_get_trip_temp, + .get_crit_temp = thermal_get_crit_temp, };static int acpi_thermal_register_thermal_zone (struct acpi_thermal *tz)
include/linux/thermal.h +1 -0
@@ -41,6 +41,7 @@ struct thermal_zone_device_ops {int (*set_mode) (struct thermal_zone_device *,const char *);int (*get_trip_type) (struct thermal_zone_device *,int ,char *);int (*get_trip_temp) (struct thermal_zone_device *,int ,char *); +int (*get_crit_temp) (struct thermal_zone_device *,unsigned long *); };struct thermal_cooling_device_ops {
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 96/171 thermal: add hwmon sysfs I/F
In reply to Len BrownFrom: Zhang Rui <[email protected]>
Add hwmon sys I/F for generic thermal driver.
Note: we have one hwmon class device for EACH TYPE of the thermal zone device.
--- drivers/thermal/thermal.c | 163 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/thermal.h | 24 +++++++ 2 files changed, 187 insertions(+), 0 deletions(-)
drivers/thermal/thermal.c +163 -0
@@ -295,6 +295,164 @@ thermal_cooling_device_trip_point_show(struct device *dev,/* Device management */ +#if defined(CONFIG_HWMON ) || \ + (defined(CONFIG_HWMON_MODULE ) && defined(CONFIG_THERMAL_MODULE )) +/* hwmon sys I/F */ +#include <linux/hwmon.h> +static LIST_HEAD (thermal_hwmon_list); + +static ssize_t +name_show (struct device *dev,struct device_attribute *attr,char *buf) +{ +struct thermal_hwmon_device *hwmon = dev->driver_data; +return sprintf (buf,"%s\n" , hwmon->type); +} +static DEVICE_ATTR(name, 0444, name_show, NULL); + +static ssize_t +temp_input_show (struct device *dev,struct device_attribute *attr,char *buf) +{ +struct thermal_hwmon_attr *hwmon_attr + = container_of(attr, struct thermal_hwmon_attr, attr); +struct thermal_zone_device *tz + = container_of(hwmon_attr, struct thermal_zone_device, + temp_input); + +return tz->ops->get_temp (tz, buf); +} + +static ssize_t +temp_crit_show (struct device *dev,struct device_attribute *attr, +char *buf) +{ +struct thermal_hwmon_attr *hwmon_attr + = container_of(attr, struct thermal_hwmon_attr, attr); +struct thermal_zone_device *tz + = container_of(hwmon_attr, struct thermal_zone_device, + temp_crit); + +return tz->ops->get_trip_temp (tz,0 , buf); +} + + +static int +thermal_add_hwmon_sysfs (struct thermal_zone_device *tz) +{ +struct thermal_hwmon_device *hwmon; +int new_hwmon_device =1 ; +int result; + +mutex_lock (&thermal_list_lock); +list_for_each_entry (hwmon, &thermal_hwmon_list, node) +if (!strcmp (hwmon->type, tz->type)) { + new_hwmon_device =0 ; +mutex_unlock (&thermal_list_lock); + goto register_sys_interface; + } +mutex_unlock (&thermal_list_lock); + + hwmon =kzalloc (sizeof (struct thermal_hwmon_device ),GFP_KERNEL ); +if (!hwmon) +return -ENOMEM ; + +INIT_LIST_HEAD (&hwmon->tz_list); +strlcpy (hwmon->type, tz->type,THERMAL_NAME_LENGTH ); + hwmon->device =hwmon_device_register (NULL ); +if (IS_ERR (hwmon->device)) { + result =PTR_ERR (hwmon->device); + goto free_mem; + } + hwmon->device->driver_data = hwmon; + result =device_create_file (hwmon->device, &dev_attr_name); +if (result) + goto unregister_hwmon_device; + + register_sys_interface: + tz->hwmon = hwmon; + hwmon->count++; + +snprintf (tz->temp_input.name,THERMAL_NAME_LENGTH , +"temp%d_input" , hwmon->count); + tz->temp_input.attr.attr.name = tz->temp_input.name; + tz->temp_input.attr.attr.mode =0444 ; + tz->temp_input.attr.show = temp_input_show; + result =device_create_file (hwmon->device, &tz->temp_input.attr); +if (result) + goto unregister_hwmon_device; + +if (tz->ops->get_crit_temp) { +unsigned long temperature; +if (!tz->ops->get_crit_temp (tz, &temperature)) { +snprintf (tz->temp_crit.name,THERMAL_NAME_LENGTH , +"temp%d_crit" , hwmon->count); + tz->temp_crit.attr.attr.name = tz->temp_crit.name; + tz->temp_crit.attr.attr.mode =0444 ; + tz->temp_crit.attr.show = temp_crit_show; + result =device_create_file (hwmon->device, + &tz->temp_crit.attr); +if (result) + goto unregister_hwmon_device; + } + } + +mutex_lock (&thermal_list_lock); +if (new_hwmon_device) +list_add_tail (&hwmon->node, &thermal_hwmon_list); +list_add_tail (&tz->hwmon_node, &hwmon->tz_list); +mutex_unlock (&thermal_list_lock); + +return 0 ; + + unregister_hwmon_device: +device_remove_file (hwmon->device, &tz->temp_crit.attr); +device_remove_file (hwmon->device, &tz->temp_input.attr); +if (new_hwmon_device) { +device_remove_file (hwmon->device, &dev_attr_name); +hwmon_device_unregister (hwmon->device); + } + free_mem: +if (new_hwmon_device) +kfree (hwmon); + +return result; +} + +static void +thermal_remove_hwmon_sysfs (struct thermal_zone_device *tz) +{ +struct thermal_hwmon_device *hwmon = tz->hwmon; + + tz->hwmon =NULL ; +device_remove_file (hwmon->device, &tz->temp_input.attr); +device_remove_file (hwmon->device, &tz->temp_crit.attr); + +mutex_lock (&thermal_list_lock); +list_del (&tz->hwmon_node); +if (!list_empty (&hwmon->tz_list)) { +mutex_unlock (&thermal_list_lock); +return ; + } +list_del (&hwmon->node); +mutex_unlock (&thermal_list_lock); + +device_remove_file (hwmon->device, &dev_attr_name); +hwmon_device_unregister (hwmon->device); +kfree (hwmon); +} +#else +static int +thermal_add_hwmon_sysfs (struct thermal_zone_device *tz) +{ +return 0 ; +} + +static void +thermal_remove_hwmon_sysfs (struct thermal_zone_device *tz) +{ +} +#endif + +/** * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone * @tz: thermal zone device
@@ -642,6 +800,10 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, goto unregister; } + result =thermal_add_hwmon_sysfs (tz); +if (result) + goto unregister; +mutex_lock (&thermal_list_lock);list_add_tail (&tz->node, &thermal_tz_list);if (ops->bind)
@@ -700,6 +862,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)for (count =0 ; count < tz->trips; count++)TRIP_POINT_ATTR_REMOVE (&tz->device, count); +thermal_remove_hwmon_sysfs (tz);release_idr (&thermal_tz_idr, &thermal_idr_lock, tz->id);idr_destroy (&tz->idr);mutex_destroy (&tz->lock);
include/linux/thermal.h +24 -0
@@ -66,6 +66,23 @@ struct thermal_cooling_device { ((long)t-2732+5)/10 : ((long)t-2732-5)/10)#define CELSIUS_TO_KELVIN (t) ((t)*10+2732) +#if defined(CONFIG_HWMON ) || \ + (defined(CONFIG_HWMON_MODULE ) && defined(CONFIG_THERMAL_MODULE )) +/* thermal zone devices with the same type share one hwmon device */ +struct thermal_hwmon_device { +char type[THERMAL_NAME_LENGTH ]; +struct device *device; +int count; +struct list_head tz_list; +struct list_head node; +}; + +struct thermal_hwmon_attr { +struct device_attribute attr; +char name[16 ]; +}; +#endif +struct thermal_zone_device {int id;char type[THERMAL_NAME_LENGTH ];
@@ -77,6 +94,13 @@ struct thermal_zone_device {struct idr idr;struct mutex lock;/* protect cooling devices list */ struct list_head node; +#if defined(CONFIG_HWMON ) || \ + (defined(CONFIG_HWMON_MODULE ) && defined(CONFIG_THERMAL_MODULE )) +struct list_head hwmon_node; +struct thermal_hwmon_device *hwmon; +struct thermal_hwmon_attr temp_input;/* hwmon sys attr */ +struct thermal_hwmon_attr temp_crit;/* hwmon sys attr */ +#endif }; struct thermal_zone_device *thermal_zone_device_register(char *, int, void *,
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 97/171 thermal: update the documentation
In reply to Len BrownFrom: Zhang Rui <[email protected]>
Update the documentation for the thermal driver hwmon sys I/F.
Change the ACPI thermal zone type to be consistent with hwmon.
--- Documentation/thermal/sysfs-api.txt | 33 +++++++++++++++++++++++++++------ drivers/acpi/thermal.c | 2 +- 2 files changed, 28 insertions(+), 7 deletions(-)
Documentation/thermal/sysfs-api.txt +27 -6
@@ -108,10 +108,12 @@ and throttle appropriate devices. RO read only value RW read/write value -All thermal sysfs attributes will be represented under /sys/class/thermal +Thermal sysfs attributes will be represented under /sys/class/thermal. +Hwmon sysfs I/F extension is also available under /sys/class/hwmon +if hwmon is compiled in or built as a module. Thermal zone device sys I/F, created once it's registered: -|thermal_zone[0-*]: +/sys/class/thermal/thermal_zone[0-*]: |-----type: Type of the thermal zone |-----temp: Current temperature |-----mode: Working mode of the thermal zone
@@ -119,7 +121,7 @@ Thermal zone device sys I/F, created once it's registered: |-----trip_point_[0-*]_type: Trip point type Thermal cooling device sys I/F, created once it's registered: -|cooling_device[0-*]: +/sys/class/thermal/cooling_device[0-*]: |-----type : Type of the cooling device(processor/fan/...) |-----max_state: Maximum cooling state of the cooling device |-----cur_state: Current cooling state of the cooling device
@@ -130,10 +132,19 @@ They represent the relationship between a thermal zone and its associated coolin They are created/removed for each thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful execution. -|thermal_zone[0-*] +/sys/class/thermal/thermal_zone[0-*] |-----cdev[0-*]: The [0-*]th cooling device in the current thermal zone |-----cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with +Besides the thermal zone device sysfs I/F and cooling device sysfs I/F, +the generic thermal driver also creates a hwmon sysfs I/F for each _type_ of +thermal zone device. E.g. the generic thermal driver registers one hwmon class device +and build the associated hwmon sysfs I/F for all the registered ACPI thermal zones. +/sys/class/hwmon/hwmon[0-*]: + |-----name: The type of the thermal zone devices. + |-----temp[1-*]_input: The current temperature of thermal zone [1-*]. + |-----temp[1-*]_critical: The critical trip point of thermal zone [1-*]. +Please read Documentation/hwmon/sysfs-interface for additional information. *************************** * Thermal zone attributes *
@@ -141,7 +152,10 @@ thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful e type Strings which represent the thermal zone type. This is given by thermal zone driver as part of registration. - Eg: "ACPI thermal zone" indicates it's a ACPI thermal device + Eg: "acpitz" indicates it's an ACPI thermal device. + In order to keep it consistent with hwmon sys attribute, + this should be a short, lowercase string, + not containing spaces nor dashes. RO Required
@@ -218,7 +232,7 @@ the sys I/F structure will be built like this: /sys/class/thermal: |thermal_zone1: - |-----type: ACPI thermal zone + |-----type: acpitz |-----temp: 37000 |-----mode: kernel |-----trip_point_0_temp: 100000
@@ -243,3 +257,10 @@ the sys I/F structure will be built like this: |-----type: Fan |-----max_state: 2 |-----cur_state: 0 + +/sys/class/hwmon: + +|hwmon0: + |-----name: acpitz + |-----temp1_input: 37000 + |-----temp1_crit: 100000
drivers/acpi/thermal.c +1 -1
@@ -1136,7 +1136,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)for (i =0 ; i <ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid; i++, trips++); - tz->thermal_zone =thermal_zone_device_register ("ACPI thermal zone" , + tz->thermal_zone =thermal_zone_device_register ("acpitz" , trips, tz, &acpi_thermal_zone_ops);if (IS_ERR (tz->thermal_zone))return -ENODEV ;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 98/171 ACPI: elide a non-zero test on a result that is never 0
In reply to Len BrownFrom: Julia Lawall <[email protected]>
thermal_cooling_device_register used to return NULL if THERMAL is "n". As the ACPI fan, processor and video drivers SELECT the generic thermal in PATCH 01, this is not a problem any more.
--- drivers/acpi/fan.c | 35 +++++++++++++++++------------------ drivers/acpi/processor_core.c | 31 +++++++++++++++---------------- drivers/acpi/video.c | 28 +++++++++++++--------------- drivers/misc/intel_menlow.c | 23 +++++++++-------------- 4 files changed, 54 insertions(+), 63 deletions(-)
drivers/acpi/fan.c +17 -18
@@ -260,24 +260,23 @@ static int acpi_fan_add(struct acpi_device *device) result =PTR_ERR (cdev); goto end; } -if (cdev) { - printk(KERN_INFO PREFIX -"%s is registered as cooling_device%d\n" , - device->dev.bus_id, cdev->id); - -acpi_driver_data (device) = cdev; - result =sysfs_create_link (&device->dev.kobj, - &cdev->device.kobj, -"thermal_cooling" ); -if (result) -return result; - - result =sysfs_create_link (&cdev->device.kobj, - &device->dev.kobj, -"device" ); -if (result) -return result; - } + + printk(KERN_INFO PREFIX +"%s is registered as cooling_device%d\n" , + device->dev.bus_id, cdev->id); + +acpi_driver_data (device) = cdev; + result =sysfs_create_link (&device->dev.kobj, + &cdev->device.kobj, +"thermal_cooling" ); +if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); + + result =sysfs_create_link (&cdev->device.kobj, + &device->dev.kobj, +"device" ); +if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); result =acpi_fan_add_fs (device);if (result)
drivers/acpi/processor_core.c +15 -16
@@ -674,22 +674,21 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) result =PTR_ERR (pr->cdev); goto end; } -if (pr->cdev) { - printk(KERN_INFO PREFIX -"%s is registered as cooling_device%d\n" , - device->dev.bus_id, pr->cdev->id); - - result =sysfs_create_link (&device->dev.kobj, - &pr->cdev->device.kobj, -"thermal_cooling" ); -if (result) -return result; - result =sysfs_create_link (&pr->cdev->device.kobj, - &device->dev.kobj, -"device" ); -if (result) -return result; - } + + printk(KERN_INFO PREFIX +"%s is registered as cooling_device%d\n" , + device->dev.bus_id, pr->cdev->id); + + result =sysfs_create_link (&device->dev.kobj, + &pr->cdev->device.kobj, +"thermal_cooling" ); +if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); + result =sysfs_create_link (&pr->cdev->device.kobj, + &device->dev.kobj, +"device" ); +if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n");if (pr->flags.throttling) { printk(KERN_INFO PREFIX "%s [%s] (supports",
drivers/acpi/video.c +13 -15
@@ -734,21 +734,19 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)if (IS_ERR (device->cdev))return ; -if (device->cdev) { - printk(KERN_INFO PREFIX -"%s is registered as cooling_device%d\n" , - device->dev->dev.bus_id, device->cdev->id); - result =sysfs_create_link (&device->dev->dev.kobj, - &device->cdev->device.kobj, -"thermal_cooling" ); -if (result) - printk(KERN_ERR PREFIX "Create sysfs link\n"); - result =sysfs_create_link (&device->cdev->device.kobj, - &device->dev->dev.kobj, -"device" ); -if (result) - printk(KERN_ERR PREFIX "Create sysfs link\n"); - } + printk(KERN_INFO PREFIX +"%s is registered as cooling_device%d\n" , + device->dev->dev.bus_id, device->cdev->id); + result =sysfs_create_link (&device->dev->dev.kobj, + &device->cdev->device.kobj, +"thermal_cooling" ); +if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); + result =sysfs_create_link (&device->cdev->device.kobj, + &device->dev->dev.kobj,"device" ); +if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); + }if (device->cap._DCS && device->cap._DSS){static int count =0 ;
drivers/misc/intel_menlow.c +9 -14
@@ -175,20 +175,15 @@ static int intel_menlow_memory_add(struct acpi_device *device) goto end; } -if (cdev) { -acpi_driver_data (device) = cdev; - result =sysfs_create_link (&device->dev.kobj, - &cdev->device.kobj,"thermal_cooling" ); -if (result) - goto unregister; - - result =sysfs_create_link (&cdev->device.kobj, - &device->dev.kobj,"device" ); -if (result) { -sysfs_remove_link (&device->dev.kobj,"thermal_cooling" ); - goto unregister; - } - } +acpi_driver_data (device) = cdev; + result =sysfs_create_link (&device->dev.kobj, + &cdev->device.kobj,"thermal_cooling" ); +if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); + result =sysfs_create_link (&cdev->device.kobj, + &device->dev.kobj,"device" ); +if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); end:return result;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 99/171 ACPI: update thermal temperature
In reply to Len BrownFrom: Zhang, Rui <[email protected]>
Fix the problem that thermal_get_temp returns the cached value, which causes the temperature in generic thermal never updates.
--- drivers/acpi/thermal.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
drivers/acpi/thermal.c +5 -0
@@ -884,10 +884,15 @@ static void acpi_thermal_check(void *data)static int thermal_get_temp (struct thermal_zone_device *thermal,char *buf) {struct acpi_thermal *tz = thermal->devdata; +int result;if (!tz)return -EINVAL ; + result =acpi_thermal_get_temperature (tz); +if (result) +return result; +return sprintf (buf,"%ld\n" ,KELVIN_TO_MILLICELSIUS (tz->temperature)); }
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 100/171 thermal: re-name thermal.c to thermal_sys.c
In reply to Len BrownFrom: Len Brown <[email protected]>
thermal_sys was already the name of the resulting module, and it is built from this one source file.
--- drivers/thermal/Makefile | 1 - drivers/thermal/thermal.c | 899 ----------------------------------------- drivers/thermal/thermal_sys.c | 899 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 899 insertions(+), 900 deletions(-) delete mode 100644 drivers/thermal/thermal.c create mode 100644 drivers/thermal/thermal_sys.c
drivers/thermal/Makefile +0 -1
@@ -2,5 +2,4 @@ # Makefile for sensor chip drivers. # -thermal_sys-objs += thermal.o obj-$(CONFIG_THERMAL) += thermal_sys.o
drivers/thermal/thermal.c deleted +0 -899
899 lines not on this page · raw message
drivers/thermal/thermal_sys.c new file +899 -0
899 lines not on this page · raw message
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 156/171 ACPI: thinkpad-acpi: BIOS backlight mode helper (v2)
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
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.
--- Documentation/laptops/thinkpad-acpi.txt | 49 +++++++ drivers/misc/thinkpad_acpi.c | 238 +++++++++++++++++-------------- 2 files changed, 182 insertions(+), 105 deletions(-)
Documentation/laptops/thinkpad-acpi.txt +49 -0
@@ -571,6 +571,46 @@ 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 is 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 finds 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 +1130,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 ---------------------------------------
drivers/misc/thinkpad_acpi.c +133 -105
286 lines not on this page · raw message
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 157/171 ACPI: thinkpad-acpi: warn once about weird hotkey masks
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
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.
--- drivers/misc/thinkpad_acpi.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-)
drivers/misc/thinkpad_acpi.c +17 -0
@@ -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;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 158/171 ACPI: thinkpad-acpi: enhance box identification output
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
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.
--- drivers/misc/thinkpad_acpi.c | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-)
drivers/misc/thinkpad_acpi.c +8 -3
@@ -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,13 @@ 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);return 0 ; }
@@ -5875,6 +5877,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 )
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 159/171 ACPI: thinkpad-acpi: rate-limit CMOS/EC unsynced error messages
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
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.
--- drivers/misc/thinkpad_acpi.c | 22 +++++++++++++++------- 1 files changed, 15 insertions(+), 7 deletions(-)
drivers/misc/thinkpad_acpi.c +15 -7
@@ -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 {
@@ -4322,13 +4323,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;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 160/171 ACPI: thinkpad-acpi: fix brightness dimming control bug
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
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.
--- drivers/misc/thinkpad_acpi.c | 64 ++++++++++++++++++++++++++++++++---------- 1 files changed, 49 insertions(+), 15 deletions(-)
drivers/misc/thinkpad_acpi.c +49 -15
@@ -4294,8 +4294,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 */
@@ -4304,16 +4312,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)
@@ -4324,6 +4340,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 {
@@ -4337,9 +4355,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 */
@@ -4347,19 +4367,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 :
@@ -4374,7 +4397,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;; }
@@ -4397,6 +4421,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,
@@ -4461,8 +4496,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)
@@ -4480,7 +4514,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 ;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 161/171 ACPI: thinkpad-acpi: claim tpacpi as an official short handle
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
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.
--- Documentation/laptops/thinkpad-acpi.txt | 5 +++++ drivers/misc/thinkpad_acpi.c | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-)
Documentation/laptops/thinkpad-acpi.txt +5 -0
@@ -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 lenght limitations on some Linux kernel versions. Status ------
drivers/misc/thinkpad_acpi.c +6 -2
@@ -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 */
@@ -1522,8 +1525,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
@@ -6315,6 +6317,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 *
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 162/171 ACPI: thinkpad-acpi: prepare light and LED for sysfs support
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Do some preparatory work to add sysfs support to the thinklight and thinkpad leds driver.
--- drivers/misc/Kconfig | 2 + drivers/misc/thinkpad_acpi.c | 191 ++++++++++++++++++++++++++++++------------ 2 files changed, 138 insertions(+), 55 deletions(-)
drivers/misc/Kconfig +2 -0
@@ -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
drivers/misc/thinkpad_acpi.c +136 -55
290 lines not on this page · raw message
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 163/171 ACPI: thinkpad-acpi: add sysfs led class support for thinklight (v3.1)
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Add a sysfs led class interface to the thinklight (light subdriver).
--- Documentation/laptops/thinkpad-acpi.txt | 25 +++++++++++--- drivers/misc/thinkpad_acpi.c | 57 ++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 6 deletions(-)
Documentation/laptops/thinkpad-acpi.txt +20 -5
@@ -692,16 +692,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 ------------------------------------------
drivers/misc/thinkpad_acpi.c +56 -1
82 lines not on this page · raw message
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 164/171 ACPI: thinkpad-acpi: add sysfs led class support to thinkpad leds (v3.1)
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Add a sysfs led class interface to the led subdriver.
--- Documentation/laptops/thinkpad-acpi.txt | 47 +++++++++-- drivers/misc/thinkpad_acpi.c | 136 ++++++++++++++++++++++++++++++- 2 files changed, 176 insertions(+), 7 deletions(-)
Documentation/laptops/thinkpad-acpi.txt +41 -6
@@ -875,28 +875,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 to7): +"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 ----------------------------------
drivers/misc/thinkpad_acpi.c +135 -1
184 lines not on this page · raw message
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 165/171 ACPI: thinkpad-acpi: fluff really minor fix
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Fix a minor (nano?) thing that bothered me at exactly at the wrong time.
--- drivers/misc/thinkpad_acpi.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/misc/thinkpad_acpi.c +1 -1
@@ -3880,7 +3880,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 */
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 166/171 ACPI: thinkpad-acpi: use a private workqueue
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
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.
--- drivers/misc/thinkpad_acpi.c | 26 +++++++++++++++++++------- 1 files changed, 19 insertions(+), 7 deletions(-)
drivers/misc/thinkpad_acpi.c +19 -7
@@ -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;
@@ -3297,7 +3300,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)
@@ -3354,7 +3357,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)
@@ -3924,7 +3927,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,
@@ -3942,7 +3945,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 ; }
@@ -5407,11 +5410,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
@@ -5781,7 +5784,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)
@@ -6435,6 +6438,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);
@@ -6465,6 +6471,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
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 167/171 ACPI: thinkpad-acpi: fix selects in Kconfig
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
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.
--- drivers/misc/Kconfig | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/misc/Kconfig +2 -1
@@ -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---
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 168/171 ACPI: thinkpad-acpi: bump up version to 0.20
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Full LED sysfs support, and the rest of the assorted minor fixes and enhancements are a good reason to checkpoint a new version...
--- Documentation/laptops/thinkpad-acpi.txt | 4 ++-- drivers/misc/thinkpad_acpi.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
Documentation/laptops/thinkpad-acpi.txt +2 -2
@@ -1,7 +1,7 @@ ThinkPad ACPI Extras Driver - Version 0.19 - January 06th, 2008 + Version 0.20 + April 09th, 2008 Borislav Deianov <[email protected]> Henrique de Moraes Holschuh <[email protected]>
drivers/misc/thinkpad_acpi.c +1 -1
@@ -21,7 +21,7 @@* 02110-1301, USA. */ -#define TPACPI_VERSION "0.19" +#define TPACPI_VERSION "0.20"#define TPACPI_SYSFS_VERSION 0x020200/*
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 170/171 ACPI: check a return value correctly in acpi_power_get_context()
In reply to Len BrownFrom: Li Zefan <[email protected]>
We should check *resource != NULL rather than resource != NULL, which will be always true.
--- drivers/acpi/power.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/acpi/power.c +1 -1
@@ -121,7 +121,7 @@ acpi_power_get_context(acpi_handle handle, } *resource =acpi_driver_data (device); -if (!resource) +if (!*resource)return -ENODEV ;return 0 ;
Signature · 1 line
1.5.5.1.99.gf0ec4
Len Brown
reviewerPATCH 171/171 thinkpad_acpi: fix possible NULL pointer dereference if kstrdup failed
In reply to Len BrownFrom: Cyrill Gorcunov <[email protected]>
--- drivers/misc/thinkpad_acpi.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/misc/thinkpad_acpi.c +1 -1
@@ -5826,7 +5826,7 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) tp->model_str =kstrdup (dmi_get_system_info (DMI_PRODUCT_VERSION ),GFP_KERNEL ); -if (strnicmp (tp->model_str,"ThinkPad" ,8 ) !=0 ) { +if (tp->model_str &&strnicmp (tp->model_str,"ThinkPad" ,8 ) !=0 ) {kfree (tp->model_str); tp->model_str =NULL ; }
Signature · 1 line
1.5.5.1.99.gf0ec4