Bug 3241

Summary: ac module not being notified of power status change
Product: ACPI Reporter: Christian Lupien (lupien)
Component: BIOSAssignee: Vladimir Lebedev (vladimir.p.lebedev)
Status: CLOSED CODE_FIX    
Severity: normal CC: acpi-bugzilla, brewt-bugzilla.kernel.org, bricem13, gurkan.vural
Priority: P2    
Hardware: i386   
OS: Linux   
Kernel Version: 2.6.7 Subsystem:
Regression: --- Bisected commit-id:
Attachments: Here is the patch again as an attachment
device/bus events are added to ac/battery notification method
Version for 2.6.17, ac adapter
Version for 2.6.17, battery

Description Christian Lupien 2004-08-19 01:26:39 UTC
Distribution:  Fedora-Core-2
Hardware Environment: Gateway Laptop Solo 9550
Software Environment: official 2.6.7 kernel + swsusp2 + acpi-20040326
Problem Description: On my laptop, changes in the ac status is not reported. No
event is produced. The ac status is read properly, and when read produces the
proper change (lcd light intensity changed according to ac status).

I tracked down and fixed the problem:
My dsdt uses Notify (\_SB.ACAD, 0x00) to notify the os of AC power status changes. 
The current notify handler (acpi_ev_queue_notify_request in events/evmisc.c) use
the notify value to decide upon an device or system event handler (.

Now the AC handler is a device but because of the notify value of 0 (bus check)
it will not be called. Even if it was called it only handles notify values of
0x80.

A fix for this would be to chnage my dsdt to use Notify (\_SB.ACAD, 0x80)
instead. But I found another way by modifying the ac.c module. I register the
handler for system and device and habdle the bus_check value. This might be
usefull to others in case other peoples dsdt have a similar problem. 

I don't know if this is a problem seen in many dsdt, but this should fix this
type of problems and I don't think it will have any side effect.

Here is the patch:
--- ac.c.orig   2004-08-15 14:34:03.000000000 -0400
+++ ac.c        2004-08-15 14:37:43.000000000 -0400
@@ -219,6 +219,7 @@
  
        switch (event) {
        case ACPI_AC_NOTIFY_STATUS:
+       case ACPI_NOTIFY_BUS_CHECK:
                acpi_ac_get_state(ac);
                acpi_bus_generate_event(device, event, (u32) ac->state);
                break;
@@ -272,6 +273,15 @@
                goto end;
        }
  
+       status = acpi_install_notify_handler(ac->handle,
+               ACPI_SYSTEM_NOTIFY, acpi_ac_notify, ac);
+       if (ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                       "Error installing system notify handler\n"));
+               result = -ENODEV;
+               goto end;
+       }
+
        printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
                acpi_device_name(device), acpi_device_bid(device),
                ac->state?"on-line":"off-line");
@@ -307,6 +317,12 @@
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                        "Error removing notify handler\n"));
  
+       status = acpi_remove_notify_handler(ac->handle,
+               ACPI_SYSTEM_NOTIFY, acpi_ac_notify);
+       if (ACPI_FAILURE(status))
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                       "Error removing system notify handler\n"));
+
        acpi_ac_remove_fs(device);
  
        kfree(ac);
Comment 1 Christian Lupien 2004-08-19 01:28:03 UTC
Created attachment 3527 [details]
Here is the patch again as an attachment
Comment 2 Adrian Yee 2004-09-05 18:40:30 UTC
That patch also works on my Fujitsu S6010 notebook, except I had to add to the
patch a bit to get it to correctly get the ac offline event.  My notebook seems
to do a device check instead of a bus check on ac offline (but does a bus check
on ac online).  I don't know much about the acpi internals, so I don't know if
this is correct behaviour or what.  All I did was add ACPI_NOTIFY_DEVICE_CHECK
to the case statement.

The relevant part of my dsdt:
Method (ACHK, 0, NotSerialized)
{
    Store (ACPW, Local0)
    If (LNot (LEqual (Local0, ACPS)))
    {
        Sleep (0x28)
        If (Local0)
        {
            Notify (\_SB.AC, Zero)
        }
        Else
        {
            Notify (\_SB.AC, One)
        }

        Store (Zero, DVID)
        Store (0x8D, CMD)
        Store (Zero, SSMI)
        Notify (\_PR.CPU0, 0x80)
        Store (Local0, ACPS)
    }
}

PS: anyone have a clue why it would make that CPU0 notify?
Comment 3 Len Brown 2005-08-03 18:38:05 UTC
> Notify (\_PR.CPU0, 0x80)

This is the BIOS telling the OS to re-evaluate _PPC,
presumably because it is advertising different processor
performance states.
Comment 4 Vladimir Lebedev 2005-12-23 05:37:01 UTC
Created attachment 6886 [details]
device/bus events are added to ac/battery notification method


This checked on my laptop.
Comment 5 Vladimir Lebedev 2005-12-23 05:40:04 UTC
*** Bug 5362 has been marked as a duplicate of this bug. ***
Comment 6 Vladimir Lebedev 2006-06-27 04:37:54 UTC
Created attachment 8420 [details]
Version for 2.6.17, ac adapter
Comment 7 Vladimir Lebedev 2006-06-27 04:41:08 UTC
Created attachment 8421 [details]
Version for 2.6.17, battery
Comment 8 Vladimir Lebedev 2006-06-27 04:49:36 UTC
Please use the patches from comments #6 & #7 instead of patch from comment #4 -
 patch is obsolete.

Comment 9 Len Brown 2006-07-01 09:13:40 UTC
applied patch in comment #6 and patch in comment #7 to acpi-test  
Comment 10 Len Brown 2006-07-05 17:36:40 UTC
*** Bug 5305 has been marked as a duplicate of this bug. ***
Comment 11 Len Brown 2006-07-05 17:54:27 UTC
shipped at linux-2.6.17-git25 in time for 2.6.18-rc1