Skip to contentSkip to conversation

Power Mangement Interfaces

PATCH In review Jordan Crouse 15 participants 126 messages Mar 30, 2007 – Jul 16, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hey all -

I'm happy to report that the OLPC power management effort is proceeding nicely. We have suspend to RAM functional, and the system is resuming back to the framebuffer console. We have the usual blips (USB), but those will be resolved in the fullness of time.

I am now turning my attention to handling wakeup events - in particular, events that we can set at run-time. My thoughts on the matter are detailed here:

http://wiki.laptop.org/go/Power_Management_Interface

I use the ACPI wakeup infrastructure as an example because a) it exists, and b) it works. However, it doesn't share nicely, and it is a /proc file, so I sat down and thought of a more /sysfs friendly and generic model. I did keep APCI in mind, figuring that if a generic framework was designed well enough, they could slowly transition over as well (which is why the ACPI list is CCed).

Comments are welcome.

Jordan

PS: If you have a XO machine, and you're interested in trying out power management for yourself, documentation and information is forthcoming. If you can't wait, pop in to #olpc on irc.freenode.net, and somebody there will help you get started.

Signature · 4 lines
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
#1 lore raw
Quoted 5 lines · Jordan Crouse

I am now turning my attention to handling wakeup events - in particular, events that we can set at run-time. My thoughts on the matter are detailed here:

http://wiki.laptop.org/go/Power_Management_Interface

Interesting. I thought about something like that a few days ago and it was pretty much identical to what you're saying there. Except I didn't write it down ;)

A few comments:

I think the sources file isn't really useful, a
grep -l 1 /sys/power/wakeup/*
should do.

About different possible states: I think each of those can have different possible wakeup sources, ACPI can afaik go to S4 and still be able to configure the wakeup sources. So I suppose this really needs to be something like /sys/power/wakeup/<state>/<event> then where <state> is one of (currently) "mem", "disk" and "standby". And then change the interface of pm_register_wakeup_source to include the state.

Also, I'm not sure I like the interface with the name of the wakeup event set by the platform driver. That will probably lead to inconsistencies, a centrally maintained file with items could be nicer.

About test mode: there is such a thing for suspend to disk. In fact, if you just want to test driver suspend you could use that. See the /sys/power/disk file.

johannes

#2 lore raw
Quoted 5 lines · Johannes Berg
Quoted 5 lines

I am now turning my attention to handling wakeup events - in particular, events that we can set at run-time. My thoughts on the matter are detailed here:

http://wiki.laptop.org/go/Power_Management_Interface

Hm, another thing. The RTC alarm wakeup event, wouldn't that require programming the time too? And if so, should that be done through the power interface to it?

johannes

#3 lore raw
Quoted 5 lines · Johannes Berg
Quoted 1 line · Johannes Berg
Quoted 1 line

I am now turning my attention to handling wakeup events - in

particular,

Quoted 8 lines
Quoted 4 lines
Quoted 4 lines

events that we can set at run-time. My thoughts on the matter are detailed here:

http://wiki.laptop.org/go/Power_Management_Interface

Hm, another thing. The RTC alarm wakeup event, wouldn't that require programming the time too? And if so, should that be done through the power interface to it?

I'd rather have a calendar app be the user interface to schedule wakeup via RTC..that way any alarm or events you schedule would also wakeup the system if it has gone into sleep mode.

Gopi

_______________________________________________
Devel mailing list
[email protected]
http://mailman.laptop.org/mailman/listinfo/devel

#4 lore raw
In reply to Johannes Berg
Quoted 5 lines · Johannes Berg
Quoted 1 line
Quoted 1 line

http://wiki.laptop.org/go/Power_Management_Interface

Hm, another thing. The RTC alarm wakeup event, wouldn't that require programming the time too? And if so, should that be done through the power interface to it?

Probably not - its pretty easy to set up the RTC alarm in your daemon before going to STR - those interfaces exist and are well known.

The missing part is being able to configure the wakeup event correctly.

Jordan

Signature · 4 lines
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
#5 lore raw
In reply to Johannes Berg
Quoted 3 lines · Johannes Berg

Hm, another thing. The RTC alarm wakeup event, wouldn't that require programming the time too? And if so, should that be done through the power interface to it?

There's already a cross-platform interface to RTC wakeup alarms; no new interface is needed (or desirable), much less one that requires any new or modified /sys/power/... files.

- Enable the wakeup event in /sys/devices/.../power/wakeup (alternate names include /sys/class/rtc/.../device/power/wakeup)

- Userspace can set the alarm using

* /dev/rtcX and one ioctl: RTC_WKALM_SET
* /dev/rtcX and two ioctls: RTC_ALM_SET, then RTC_AIE_ON
* /sys/class/rtc/.../wakealarm

That works on multiple systems already. I've just posted updates to make it work for "rtc-cmos" on the RTC list.

- Dave

#6 lore raw
In reply to Johannes Berg
Quoted 5 lines · Johannes Berg

On Fri, 2007-03-30 at 17:57 -0600, Jordan Crouse wrote:

I think the sources file isn't really useful, a
grep -l 1 /sys/power/wakeup/*
should do.

I was just trying to be friendly to folks who may be used to the ACPI method.

Quoted 10 lines

About different possible states: I think each of those can have different possible wakeup sources, ACPI can afaik go to S4 and still be able to configure the wakeup sources. So I suppose this really needs to be something like /sys/power/wakeup/<state>/<event> then where <state> is one of (currently) "mem", "disk" and "standby". And then change the interface of pm_register_wakeup_source to include the state.

Also, I'm not sure I like the interface with the name of the wakeup event set by the platform driver. That will probably lead to inconsistencies, a centrally maintained file with items could be nicer.

I considered that - but different platforms and PM methods may have radically different events (will WLAN ever be an event that any other x86 platform would use)?

So I thought it best that we allow the platform driver to provide the name, and then enforce consistancy from the developers.

Quoted 3 lines

About test mode: there is such a thing for suspend to disk. In fact, if you just want to test driver suspend you could use that. See the /sys/power/disk file.

Yeah - I stole the idea from there. That only works when you go down the suspend to disk path, though, and I wanted to make sure we were going down our own STR path. We go all the way into our sleep methods (in fact, I used it to catch an early bug where we were not restoring the stack correctly in the lowlevel resume function). I think there are other uses for the test mode that even extend into the firmware - consider a clocks on test method that goes as far as setting up the wake events, but never actually turn off the power rails.

Thanks for your comments.
Jordan

Signature · 4 lines
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
#7 lore raw

Hi!

Quoted 6 lines
Quoted 3 lines

I think the sources file isn't really useful, a
grep -l 1 /sys/power/wakeup/*
should do.

I was just trying to be friendly to folks who may be used to the ACPI method.

Kernel is not place to be friendly.

#echo PWRB > /proc/acpi/wakeup
#
#Which changes the PWRB line to this:
#
#PWRB 1 *disabled
#
#I like this interface - its clean and pretty intuitive. Two problems - #first, it is ACPI specific, so we can't share it, and secondly, it #doesn't fit in to the sysfs model (which is to return only one value #per file). An alternative would be something like this:

Was this april's fools joke? /proc/acpi/wakeup is a nightmare, not a clean interface.
Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#8 lore raw
In reply to Johannes Berg
Quoted 7 lines · Johannes Berg

On Fri, 2007-03-30 at 17:57 -0600, Jordan Crouse wrote:

About different possible states: I think each of those can have different possible wakeup sources, ACPI can afaik go to S4 and still be able to configure the wakeup sources. So I suppose this really needs to be something like /sys/power/wakeup/<state>/<event> then where <state> is one of (currently) "mem", "disk" and "standby".

Nobody has yet been able to demonstrate user benefit from exposing that level of complexity to userspace.

To the contrary, it seems enough to just expose a boolean flag saying whether a given device should try to be a wakeup event source. If the hardware won't allow that in the target system state, so be it; there's no way software can change that.

Quoted 2 lines

And then change the
interface of pm_register_wakeup_source to include the state.

We don't need such a new interface.

- Dave

#9 lore raw
Quoted 4 lines · David Brownell

To the contrary, it seems enough to just expose a boolean flag saying whether a given device should try to be a wakeup event source. If the hardware won't allow that in the target system state, so be it; there's no way software can change that.

Right. So that's the "wakeup" file for a given device.

How would I go about representing the lid as a device? It's an honest question, I'd actually like to do and replace the /proc/pmu/options file it but don't know where I should put it etc.

johannes

#10 lore raw
Quoted 4 lines · Johannes Berg

How would I go about representing the lid as a device? It's an honest question, I'd actually like to do and replace the /proc/pmu/options file it but don't know where I should put it etc.

I'm not sure I understand the question. ACPI has a special "acpi_device" node (not backed by any "real" device, PNPACPI etc) with a driver that hooks up to the input subsystem. Same is true for a couple other fixed function buttons. I'd expect non-ACPI platforms would do something very similar, except using platform_device and looking less cryptic.

As for hooking things up to the driver model wakeup event stuff, ACPI doesn't do that yet. I've got some patches in the works; it turns out to be easier than I'd expected (but then I'm just at the periphery of ACPI, and get to ignore AML etc).

- Dave

#11 lore raw
Quoted 5 lines · David Brownell

I'm not sure I understand the question. ACPI has a special "acpi_device" node (not backed by any "real" device, PNPACPI etc) with a driver that hooks up to the input subsystem. Same is true for a couple other fixed function buttons. I'd expect non-ACPI platforms would do something very similar, except using platform_device and looking less cryptic.

No, the thing is more: how would we represent the lid as a device in sysfs? Currently, our PMU only has a sysdev because it doesn't need more. Would you suggest doing a PMU-bus and than hanging "lid" off of that?

johannes

#12 lore raw
Quoted 10 lines · Johannes Berg
Quoted 5 lines · David Brownell

I'm not sure I understand the question. ACPI has a special "acpi_device" node (not backed by any "real" device, PNPACPI etc) with a driver that hooks up to the input subsystem. Same is true for a couple other fixed function buttons. I'd expect non-ACPI platforms would do something very similar, except using platform_device and looking less cryptic.

No, the thing is more: how would we represent the lid as a device in sysfs?

As a platform_device.

Quoted 3 lines

Currently, our PMU only has a sysdev because it doesn't need more. Would you suggest doing a PMU-bus and than hanging "lid" off of that?

Avoid doing a new bus_type unless you **really, really** need one.

- Dave

#13 lore raw
Quoted 4 lines · David Brownell
Quoted 2 lines

No, the thing is more: how would we represent the lid as a device in sysfs?

As a platform_device.

Ok. I think the bug in my original thinking is that all these things should be related somehow, but there's no reason the user needs to know that the lid and the power button are controlled by the same ASIC.

johannes

#14 lore raw
In reply to David Brownell
Quoted 6 lines · David Brownell
Quoted 4 lines · Johannes Berg

How would I go about representing the lid as a device? It's an honest question, I'd actually like to do and replace the /proc/pmu/options file it but don't know where I should put it etc.

Quoted 8 lines

I'm not sure I understand the question. ACPI has a special "acpi_device" node (not backed by any "real" device, PNPACPI etc) with a driver that hooks up to the input subsystem. Same is true for a couple other fixed function buttons. I'd expect non-ACPI platforms would do something very similar, except using platform_device and looking less cryptic.

As for hooking things up to the driver model wakeup event stuff, ACPI doesn't do that yet. I've got some patches in the works;

Good to know. Please add [email protected] to the cc list when you want to send them out. :>

Thanks,
Rui

#15 lore raw
In reply to Jordan Crouse
Quoted 5 lines · Jordan Crouse

Hey all -

I'm happy to report that the OLPC power management effort is proceeding nicely. We have suspend to RAM functional, and the system is resuming back to the framebuffer console.

Good to hear that. Now, if the same could be said for the *typical* PC platform, I'd be much happier!

Quoted 2 lines

We have the usual blips (USB), but
those will be resolved in the fullness of time.

USB once worked fine (I spent more than enough time testing it in all kinds of configs) but usbcore has changed a lot since then ... I hear that some of the root hub stuff got broken.

Quoted 5 lines

I am now turning my attention to handling wakeup events - in particular, events that we can set at run-time. My thoughts on the matter are detailed here:

http://wiki.laptop.org/go/Power_Management_Interface

You seem to be completely ignoring the /sys/devices/..../power/wakeup event attributes. Why?

Quoted 2 lines

I use the ACPI wakeup infrastructure as an example because a) it exists, and b) it works.

In my experience, (a) is true and (b) is very false.

Minimally, (b) is false because resuming from S1 or S3 sleep states doesn't generally work under Linux, regardless of the type of wakeup event. The recent IDEACPI patch made a big difference on at least one system though.

Another reason (b) is false is that it only handles built-in devices. Taking USB as an example, ACPI only knows about the root hubs ... but not the fact that a USB mouse or keyboard can be a wakeup event source. The /sys/devices/.../wakeup files manage those.

Quoted 5 lines

However, it doesn't share nicely, and it is a /proc
file, so I sat down and thought of a more /sysfs friendly and generic model. I did keep APCI in mind, figuring that if a generic framework was designed well enough, they could slowly transition over as well (which is why the ACPI list is CCed).

To the extent that Linux ever has a "plan of record", it's that ACPI will transition /proc/acpi/wakeup contents into /sys/devices/.../power/wakeup as part of removing the /proc/acpi stuff entirely.

That is: there *IS ALREADY* a generic framework for wakeup events, one that's already deployed ... and used for various devices.

As with most PM-related things on Linux, there's an issue with getting decent cross-platform support for it. However, that generic stuff does work on various embedded systems. Probably the best examples are ARM AT91 platforms ... where most of the devices (USB, MMC, CF, UART, more) can be trigger system wakeup events. In several cases that's just by enable_irq_wake() doing the right thing, and drivers knowing how to use that call, but in other cases (like USB) it's more involved than that.

- Dave

#16 lore raw
Quoted 3 lines · David Brownell

USB once worked fine (I spent more than enough time testing it in all kinds of configs) but usbcore has changed a lot since then ... I hear that some of the root hub stuff got broken.

Marcelo is working hard on the USB. I'm sure he wouldn't say no if you offered your particular expertise on the matter. :)

Quoted 9 lines
Quoted 6 lines

I am now turning my attention to handling wakeup events - in particular, events that we can set at run-time. My thoughts on the matter are detailed here:

http://wiki.laptop.org/go/Power_Management_Interface

You seem to be completely ignoring the /sys/devices/..../power/wakeup event attributes. Why?

Complete and total ignorance that they even existed. I guess I should
pay more attention to linux-pm then I do.. :(. My impression is that
this infrastructure allows the devices to configure themselves to wake up the system, but it doesn't seem to address enabling the system to allow those events to wake it. It is the latter that I am concerned about.

The Geode (and most other platforms, I presume) allows us to configure which wakeup events are actually allowed to wake the system. Currently, we are permanently enabling the power button as a wakeup source, but I want to eventually be able to pick and chose from any of our main wakeup sources:

* Power button
* RTC Alarm
* LID event (GPIO26)
* wake event from the EC (GPIO27)

Of the four, the only device that can actually be configured to do anything is the RTC alarm, and for that we would use the /sys/devices/../power/wakeup infrastructure, but we would still need something in place to allow the software to tell the hardware to enable the RTC event to wake the system.

I suppose we could just globally enable all sources, but that seems silly, seeing as though we do have very fine tuned control over the wake sources. I'm sure other platforms have this concern as well - what do they do?

Signature · 4 lines
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
#17 lore raw
Quoted 9 lines · Jordan Crouse
Quoted 2 lines · David Brownell

You seem to be completely ignoring the /sys/devices/..../power/wakeup event attributes. Why?

Complete and total ignorance that they even existed. I guess I should
pay more attention to linux-pm then I do.. :(. My impression is that
this infrastructure allows the devices to configure themselves to wake up the system,

Actually the model is that those files offer a per-device userspace policy knob, defaulting to "yes, this can wake the system up" (since otherwise such knobs will rarely be turned on!). That should be initialized before the device is registered.

Device driver responsibility is to check that setting in suspend() and do the appropriate juju; and undo it in resume(). Other than that, they don't "configure themselves".

Quoted 2 lines

but it doesn't seem to address enabling the system to
allow those events to wake it. It is the latter that I am concerned about.

That's a split responsibility. One part is in the device driver, since it's the only thing that can really understand the mechanism involved; for example, making sure the relevant device clocks are active, issuing the enable_irq_wake() calls, and so on. (PCI has its own magic.)

The other part is the platform code. On embedded hardware that's usually just calling device_init_wakeup() before registering the platform devices, and supporting enable_irq_wake(). On x86 that gets messy; ACPI is there, and PCI initialization can't set device_init_wakeup() because of conflicts with how PPC initializes PCI.

Quoted 10 lines

The Geode (and most other platforms, I presume) allows us to configure which wakeup events are actually allowed to wake the system. Currently, we are permanently enabling the power button as a wakeup source, but I want to eventually be able to pick and chose from any of our main wakeup sources:

* Power button
* RTC Alarm
* LID event (GPIO26)
* wake event from the EC (GPIO27)

Yes ...

Quoted 4 lines

Of the four, the only device that can actually be configured to do anything is the RTC alarm, and for that we would use the /sys/devices/../power/wakeup infrastructure, but we would still need something in place to allow the software to tell the hardware to enable the RTC event to wake the system.

As in "echo enabled > /sys/devices/.../power/wakeup" (to get the default), or "echo disabled > ..." to disable it. For PCs, with ACPI, that involves two patches I just posted to the RTC list (and CC'd Len on), and replacing the ancient/legacy/ACPI-only /proc/acpi/alarm interface.

Quoted 3 lines

I suppose we could just globally enable all sources, but that seems silly, seeing as though we do have very fine tuned control over the wake sources. I'm sure other platforms have this concern as well - what do they do?

Well, go look at the AT91 code and you'll see a fully worked example of how the /sys/devices/.../power/wakeup files work for pretty much every platform device (except the ethernet controller, where the driver doesn't support any kind of WOL right now).

* drivers/usb/host/ohci-at91.c ... remote wakeup supported, except in sleep states where the 48 MHz PLL is unavailable

* drivers/usb/gadget/at91_udc.c ... similarly

* drivers/pcmcia/at91_cf.c ... card detect GPIO or card IRQ can both be wakeup event sources

* GRR, drivers/mmc/at91_mci.c seems to have dropped the wakeup GPIO updates, that *WAS WORKING* but someone discarded that code.

* ... more, including UARTS

In general, not many platforms have general purpose wakeup event support yet. Lack of ACPI support -- and hence scarcity of models -- is a part of it, but another part is project that stopped after they got their four essential wakeup events to behave by hard-wiring the wake events in their custom board-specific code.

For example: in arch/arm/mach-pxa, grep for PWER (wakeup enable register). There's a patch pending to teach PXA how enable_irq_wake() should work (by updating PWER) -- an API that's been around for years! -- but until that merges, wakeup events on every PXA system get hard-wired in *_pm.c files that embed all kinds of limited-functionality grot. (No way for USB to wake those systems, as another example ... that code doesn't support any of the sleep states from which it can issue wakeups.)

- Dave

#18 lore raw
Quoted 5 lines · David Brownell

The other part is the platform code. On embedded hardware that's usually just calling device_init_wakeup() before registering the platform devices, and supporting enable_irq_wake(). On x86 that gets messy; ACPI is there, and PCI initialization can't set device_init_wakeup() because of conflicts with how PPC initializes PCI.

enable_irq_wake() looks like it integrates very well with the AT91, since it seems that there is a 1:1 mapping of interrupts to wakeup sources. The story is much more muddled for x86 - there is no direct mapping of interrupts to wakeup sources, and the PIC has nothing to do with handling wake events.

On the Geode, we have 17 possible wake sources, all of which are ORed together to form the SCI interrupt. Some of the events, like the RTC, UART, and USB wakeup sources are associated with devices that have their own interrupts, but there is no correlation between the RTC interrupt, for example, and enabling it as a wakeup source. It seems overly complex to try to map these to individual interrupts, and certainly seems wasteful to get the PIC involved in something it just doesn't understand.

Quoted 4 lines

As in "echo enabled > /sys/devices/.../power/wakeup" (to get the default), or "echo disabled > ..." to disable it. For PCs, with ACPI, that involves two patches I just posted to the RTC list (and CC'd Len on), and replacing the ancient/legacy/ACPI-only /proc/acpi/alarm interface.

The link is here for the interested:

http://groups.google.com/group/rtc-linux/browse_thread/thread/ae7fe3436e01e7fa

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and add hooks to the pm_ops for each individual PM system to handle the wakeups in whatever way they see fit, and we're there. It would be slightly more complex for AT91 and friends to match this (since they have the advantage of a 1:1 mapping right now), but in the long run, I think everybody would benefit.

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

Jordan

Signature · 4 lines
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
#19 lore raw
Quoted 9 lines · Jordan Crouse
Quoted 5 lines · David Brownell

The other part is the platform code. On embedded hardware that's usually just calling device_init_wakeup() before registering the platform devices, and supporting enable_irq_wake(). On x86 that gets messy; ACPI is there, and PCI initialization can't set device_init_wakeup() because of conflicts with how PPC initializes PCI.

enable_irq_wake() looks like it integrates very well with the AT91, since it seems that there is a 1:1 mapping of interrupts to wakeup sources.

The same is true for every embedded CPU I've had reason to look at.

Quoted 3 lines

The
story is much more muddled for x86 - there is no direct mapping of interrupts to wakeup sources, and the PIC has nothing to do with handling wake events.

Right. Plus there often seems to be an assumption that some "embedded (micro)controller" (EC) manages system bringup/wakeup/runtime.

Quoted 1 line

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

Quoted 6 lines

together to form the SCI interrupt. Some of the events, like the RTC, UART, and USB wakeup sources are associated with devices that have their own interrupts, but there is no correlation between the RTC interrupt, for example, and enabling it as a wakeup source. It seems overly complex to try to map these to individual interrupts, and certainly seems wasteful to get the PIC involved in something it just doesn't understand.

I concluded the same thing a while back: x86 PC platforms seem to have been architected to isolate PM concerns from runtime concerns. This is surely part of why "it only takes 35 Watts!!" counts as "low" power despite the decimal point being three or more digits left of where it should be!

I wonder what a 35 Watt cell phone would look like? :)

Quoted 8 lines
Quoted 4 lines

As in "echo enabled > /sys/devices/.../power/wakeup" (to get the default), or "echo disabled > ..." to disable it. For PCs, with ACPI, that involves two patches I just posted to the RTC list (and CC'd Len on), and replacing the ancient/legacy/ACPI-only /proc/acpi/alarm interface.

The link is here for the interested:

http://groups.google.com/group/rtc-linux/browse_thread/thread/ae7fe3436e01e7fa

There are two other messages that may be of interest too, including the one defining and calling the hooks implemented in that message; click on the list name to get the archives.

Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

Quoted 5 lines

add hooks to the pm_ops for each individual PM system to handle the wakeups in whatever way they see fit, and we're there. It would be slightly more complex for AT91 and friends to match this (since they have the advantage of a 1:1 mapping right now), but in the long run, I think everybody would benefit.

I guess I don't see why this isn't already sufficiently generic ...

As a rule, all those embedded drivers are platform-specific and have no need for more than a few enable_irq_wake() calls, in addition to whatever controller setup and clock management they do. Since they can't be very portable, they don't need to generalize such stuff.

And for PCI based things, pci_enable_wake() encapsulates everything that needs doing. Not that ACPI actually *does* anything yet! But the stuff that writing /proc/acpi/wakeup enables should happen in that routine ... and eventually PCI runtime wake events should work too. (So: no drivers would ever call ACPI directly, and they already have the generic call that ACPI should hook.)

That seems to cover most drivers in Linux, without a need for any new generic PM infrastructure. Did I overlook something important?

Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

- Dave

#20 lore raw
In reply to Jordan Crouse
Quoted 9 lines · Jordan Crouse
Quoted 5 lines · David Brownell

The other part is the platform code. On embedded hardware that's usually just calling device_init_wakeup() before registering the platform devices, and supporting enable_irq_wake(). On x86 that gets messy; ACPI is there, and PCI initialization can't set device_init_wakeup() because of conflicts with how PPC initializes PCI.

enable_irq_wake() looks like it integrates very well with the AT91, since it seems that there is a 1:1 mapping of interrupts to wakeup sources.

The same is true for every embedded CPU I've had reason to look at.

Quoted 3 lines

The
story is much more muddled for x86 - there is no direct mapping of interrupts to wakeup sources, and the PIC has nothing to do with handling wake events.

Right. Plus there often seems to be an assumption that some "embedded (micro)controller" (EC) manages system bringup/wakeup/runtime.

Quoted 1 line

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

Quoted 6 lines

together to form the SCI interrupt. Some of the events, like the RTC, UART, and USB wakeup sources are associated with devices that have their own interrupts, but there is no correlation between the RTC interrupt, for example, and enabling it as a wakeup source. It seems overly complex to try to map these to individual interrupts, and certainly seems wasteful to get the PIC involved in something it just doesn't understand.

I concluded the same thing a while back: x86 PC platforms seem to have been architected to isolate PM concerns from runtime concerns. This is surely part of why "it only takes 35 Watts!!" counts as "low" power despite the decimal point being three or more digits left of where it should be!

I wonder what a 35 Watt cell phone would look like? :)

Quoted 8 lines
Quoted 4 lines

As in "echo enabled > /sys/devices/.../power/wakeup" (to get the default), or "echo disabled > ..." to disable it. For PCs, with ACPI, that involves two patches I just posted to the RTC list (and CC'd Len on), and replacing the ancient/legacy/ACPI-only /proc/acpi/alarm interface.

The link is here for the interested:

http://groups.google.com/group/rtc-linux/browse_thread/thread/ae7fe3436e01e7fa

There are two other messages that may be of interest too, including the one defining and calling the hooks implemented in that message; click on the list name to get the archives.

Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

Quoted 5 lines

add hooks to the pm_ops for each individual PM system to handle the wakeups in whatever way they see fit, and we're there. It would be slightly more complex for AT91 and friends to match this (since they have the advantage of a 1:1 mapping right now), but in the long run, I think everybody would benefit.

I guess I don't see why this isn't already sufficiently generic ...

As a rule, all those embedded drivers are platform-specific and have no need for more than a few enable_irq_wake() calls, in addition to whatever controller setup and clock management they do. Since they can't be very portable, they don't need to generalize such stuff.

And for PCI based things, pci_enable_wake() encapsulates everything that needs doing. Not that ACPI actually *does* anything yet! But the stuff that writing /proc/acpi/wakeup enables should happen in that routine ... and eventually PCI runtime wake events should work too. (So: no drivers would ever call ACPI directly, and they already have the generic call that ACPI should hook.)

That seems to cover most drivers in Linux, without a need for any new generic PM infrastructure. Did I overlook something important?

Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

- Dave

#21 lore raw

A few of your comments made me wonder if I haven't been clear enough - despite this being an x86 platform, we are not using ACPI for power management, for a variety of reasons, including the fact that we have our own open source firmware and a very specific hardware platform So, for better or worse, we are implementing a new power management manger. Here is the code:

http://dev.laptop.org/git.do?p=olpc-2.6;a=blob;h=e6e19ac32a881be962db7190f2cb460e9f60a9da;hb=powermgmt;f=arch/i386/kernel/olpc-pm.c

Quoted 6 lines · David Brownell
Quoted 3 lines

The
story is much more muddled for x86 - there is no direct mapping of interrupts to wakeup sources, and the PIC has nothing to do with handling wake events.

Right. Plus there often seems to be an assumption that some "embedded (micro)controller" (EC) manages system bringup/wakeup/runtime.

Or, the southbridge, or in the case of the OLPC platform, both.

Quoted 7 lines
Quoted 2 lines

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

The silicon can handle wakeups from RTC, a sleep button, a power button, 8 GPIO groups, the USB controller (covering any and all USB events), UART1, UART2, SMbus and the PIC.

OLPC really only cares about 4 of those, because our only sleep state is ~S3, and the PIC, smbus, UARTs and USB are off in S3. We also only have the power button, and all the rest of the wakeup sources come from the GPIOs.

Quoted 4 lines
Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

I'm not saying inside ACPI - I'm saying at the driver level. Something like this (where name could be a string like ACPI does, but it would be more portable if it was a #define'ed value).

pm_set_event(name) {
pm_ops->set_event(name, 1);
}

pm_clear_event(name) {
pm_ops->set_event(name, state);
}

And then each subsystem that defines a struct pm_ops adds a set_event() that does the right thing.

In OLPC's case we would do something like this:

olpc_pm_set_event(name, state) {
	switch(name) {
		case PM_WAKEUP_RTC:
			pm1_wakeup |= (1 << 9);
			break;

			...
	}
}

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

Quoted 6 lines
Quoted 5 lines

add hooks to the pm_ops for each individual PM system to handle the wakeups in whatever way they see fit, and we're there. It would be slightly more complex for AT91 and friends to match this (since they have the advantage of a 1:1 mapping right now), but in the long run, I think everybody would benefit.

Quoted 6 lines

I guess I don't see why this isn't already sufficiently generic ...

As a rule, all those embedded drivers are platform-specific and have no need for more than a few enable_irq_wake() calls, in addition to whatever controller setup and clock management they do. Since they can't be very portable, they don't need to generalize such stuff.

enable_irq_wake() just doesn't work for x86, unfortunately. It seems to me to be more logical to move the wakeup intelligence to the PM subsystem, and then let that code distribute it to where it is needed. In the case of x86, the logic would stay in the PM method, for other processors, it might involve a call to the interrupt mapper.

Quoted 9 lines

And for PCI based things, pci_enable_wake() encapsulates everything that needs doing. Not that ACPI actually *does* anything yet! But the stuff that writing /proc/acpi/wakeup enables should happen in that routine ... and eventually PCI runtime wake events should work too. (So: no drivers would ever call ACPI directly, and they already have the generic call that ACPI should hook.)

That seems to cover most drivers in Linux, without a need for any new generic PM infrastructure. Did I overlook something important?

No, I don't think so - we're very close on agreeing here. I just don't know if enable_irq_wake() is the best way to provide the generic call. Moving it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

Quoted 11 lines
Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

Quoted 6 lines

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Jordan

Signature · 4 lines
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
#22 lore raw
Quoted 4 lines · Jordan Crouse

A few of your comments made me wonder if I haven't been clear enough - despite this being an x86 platform, we are not using ACPI for power management, for a variety of reasons, including the fact that we have our own open source firmware and a very specific hardware platform.

I probably should have known that, but no you weren't clear.

Quoted 4 lines

So, for better or worse, we are implementing a new power management manger. Here is the code:

http://dev.laptop.org/git.do?p=olpc-2.6;a=blob;h=e6e19ac32a881be962db7190f2cb460e9f60a9da;hb=powermgmt;f=arch/i386/kernel/olpc-pm.c

Does that work yet with CONFIG_NO_HZ, so that the system idle loop enters some "almost everyting is turned off" low power state? Or would that be something other than a "PM Manager"?

Quoted 7 lines
Quoted 6 lines
Quoted 1 line

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

Quoted 8 lines

The silicon can handle wakeups from RTC, a sleep button, a power button, 8 GPIO groups, the USB controller (covering any and all USB events), UART1, UART2, SMbus and the PIC.

OLPC really only cares about 4 of those, because our only sleep state is ~S3, and the PIC, smbus, UARTs and USB are off in S3. We also only have the power button, and all the rest of the wakeup sources come from the GPIOs.

So it's a slightly deeper "S3" than I've usually seen, but not by much.

And correct me if I'm wrong, but your RTC can work with "rtc-cmos", and the wake hooks I've posted (and which will be in the next MM release) sound like they'll work just fine (given OLPC-specific implementation, which is clearly not included in the code above).

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

I'm not saying inside ACPI - I'm saying at the driver level.

Whereas in that patch, the only ACPI calls were inside ACPI itself; and that driver only had a callback. FWIW that's the first time I've ever needed to have indirection on wakeup event handling ...

Quoted 8 lines

Something
like this (where name could be a string like ACPI does, but it would be more portable if it was a #define'ed value).

pm_set_event(name) {
   pm_ops->set_event(name, 1);
}
Quoted 6 lines
pm_clear_event(name) {
   pm_ops->set_event(name, state);
}

And then each subsystem that defines a struct pm_ops adds a set_event() that does the right thing.

What are the "1" and "state" values supposed to signify?

This does assume there's some fairly centralized definition of that "event" space. That seems awkward on chips that could have a few hundred wakeup events. (Example: 128 GPIOs, plus IRQs from several dozen on-chip controllers, just on the main SOC device ... plus the external events which may be multiplexed onto those event sources.) Yes, of course any given board will rarely have more than a couple dozen wake events; but still..

Evolving those systems doesn't work so well if they're highly centralized, since the next chip rev will change these controllers, add some, remove some ... very little of that code should change, but when everything is centralized that tends not to happen.

Quoted 7 lines

In OLPC's case we would do something like this:

olpc_pm_set_event(name, state) {
	switch(name) {
		case PM_WAKEUP_RTC:
			pm1_wakeup |= (1 << 9);
			break;

One big switch statement with potentialy hundreds of entries ... it'd be better to have callback functions associated with something, like maybe the device! (I'm not just saying that because that's how the cmos-rtc hook now works...)

Quoted 8 lines
			...
	}
}

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

With AT91 (and most ARMs) the wake events are normal IRQs, and the irq infrastructure already handles wake events cleanly. So I'd claim they don't _want_ to change something that's inexpensive, already deployed (training, code, testing, etc), and working.

So I hope you'll tolerate me if I view this as less of a "how do we get a generic solution" and more of a "how does _this_ x86-ish issue get solved cleanly".

Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

add hooks to the pm_ops for each individual PM system to handle the wakeups in whatever way they see fit, and we're there. It would be slightly more complex for AT91 and friends to match this (since they have the advantage of a 1:1 mapping right now), but in the long run, I think everybody would benefit.

Quoted 8 lines
Quoted 6 lines

I guess I don't see why this isn't already sufficiently generic ...

As a rule, all those embedded drivers are platform-specific and have no need for more than a few enable_irq_wake() calls, in addition to whatever controller setup and clock management they do. Since they can't be very portable, they don't need to generalize such stuff.

enable_irq_wake() just doesn't work for x86, unfortunately.

And it doesn't need to, either. Those drivers can't run on x86.

That's just one more mechanism -- like clk_enable()/clk_disable(), set_irq_type(), or generic GPIOs -- that isn't really available on x86, despite being fundamental on may other platforms.

Quoted 5 lines

It seems
to me to be more logical to move the wakeup intelligence to the PM subsystem, and then let that code distribute it to where it is needed. In the case of x86, the logic would stay in the PM method, for other processors, it might involve a call to the interrupt mapper.

But why should a "PM subsystem" be created to abstract something that already works just fine?

It'd make much more sense to me to come up with a good way to handle the x86 issues first, and only then think about whether to try making that work on other systems.

Quoted 7 lines
Quoted 7 lines

And for PCI based things, pci_enable_wake() encapsulates everything that needs doing. Not that ACPI actually *does* anything yet! But the stuff that writing /proc/acpi/wakeup enables should happen in that routine ... and eventually PCI runtime wake events should work too. (So: no drivers would ever call ACPI directly, and they already have the generic call that ACPI should hook.)

Quoted 5 lines
Quoted 2 lines

That seems to cover most drivers in Linux, without a need for any new generic PM infrastructure. Did I overlook something important?

No, I don't think so - we're very close on agreeing here. I just don't know if enable_irq_wake() is the best way to provide the generic call.

It's not, and I didn't propose doing that either.

Having all drivers try to use the same calls to manage wakeup mechanisms doesn't seem like the right model. When the mechanism is the same -- wakeup irqs, say -- then yes the calls should be the same. But when the mechanisms differ -- PCI PME# is very different from wakeup IRQS, only one per device etc -- then the calls can reasonably be different.

Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Quoted 18 lines
Quoted 11 lines
Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

Quoted 6 lines

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

My point above was that ACPI isn't yet integrating with the things it needs to be integrating with. If you're concerned about how to work with wakeup events in Linux, don't even bother looking at ACPI. Look at the embedded implementations; look at USB. AT91 is by far the cleanest and most complete (simplest hardware too!!), but some of the other systems (OMAP, PXA, SA1100, etc) also implement wakeup using board-specific code.

OLPC _could_ use that same "board-specific hacks" approach found in most embedded platforms. I'm glad you're thinking about how to avoid doing that.

- Dave

#23 lore raw
In reply to Jordan Crouse
Quoted 4 lines · Jordan Crouse

A few of your comments made me wonder if I haven't been clear enough - despite this being an x86 platform, we are not using ACPI for power management, for a variety of reasons, including the fact that we have our own open source firmware and a very specific hardware platform.

I probably should have known that, but no you weren't clear.

Quoted 4 lines

So, for better or worse, we are implementing a new power management manger. Here is the code:

http://dev.laptop.org/git.do?p=olpc-2.6;a=blob;h=e6e19ac32a881be962db7190f2cb460e9f60a9da;hb=powermgmt;f=arch/i386/kernel/olpc-pm.c

Does that work yet with CONFIG_NO_HZ, so that the system idle loop enters some "almost everyting is turned off" low power state? Or would that be something other than a "PM Manager"?

Quoted 7 lines
Quoted 6 lines
Quoted 1 line

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

Quoted 8 lines

The silicon can handle wakeups from RTC, a sleep button, a power button, 8 GPIO groups, the USB controller (covering any and all USB events), UART1, UART2, SMbus and the PIC.

OLPC really only cares about 4 of those, because our only sleep state is ~S3, and the PIC, smbus, UARTs and USB are off in S3. We also only have the power button, and all the rest of the wakeup sources come from the GPIOs.

So it's a slightly deeper "S3" than I've usually seen, but not by much.

And correct me if I'm wrong, but your RTC can work with "rtc-cmos", and the wake hooks I've posted (and which will be in the next MM release) sound like they'll work just fine (given OLPC-specific implementation, which is clearly not included in the code above).

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

I'm not saying inside ACPI - I'm saying at the driver level.

Whereas in that patch, the only ACPI calls were inside ACPI itself; and that driver only had a callback. FWIW that's the first time I've ever needed to have indirection on wakeup event handling ...

Quoted 8 lines

Something
like this (where name could be a string like ACPI does, but it would be more portable if it was a #define'ed value).

pm_set_event(name) {
   pm_ops->set_event(name, 1);
}
Quoted 6 lines
pm_clear_event(name) {
   pm_ops->set_event(name, state);
}

And then each subsystem that defines a struct pm_ops adds a set_event() that does the right thing.

What are the "1" and "state" values supposed to signify?

This does assume there's some fairly centralized definition of that "event" space. That seems awkward on chips that could have a few hundred wakeup events. (Example: 128 GPIOs, plus IRQs from several dozen on-chip controllers, just on the main SOC device ... plus the external events which may be multiplexed onto those event sources.) Yes, of course any given board will rarely have more than a couple dozen wake events; but still..

Evolving those systems doesn't work so well if they're highly centralized, since the next chip rev will change these controllers, add some, remove some ... very little of that code should change, but when everything is centralized that tends not to happen.

Quoted 7 lines

In OLPC's case we would do something like this:

olpc_pm_set_event(name, state) {
	switch(name) {
		case PM_WAKEUP_RTC:
			pm1_wakeup |= (1 << 9);
			break;

One big switch statement with potentialy hundreds of entries ... it'd be better to have callback functions associated with something, like maybe the device! (I'm not just saying that because that's how the cmos-rtc hook now works...)

Quoted 8 lines
			...
	}
}

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

With AT91 (and most ARMs) the wake events are normal IRQs, and the irq infrastructure already handles wake events cleanly. So I'd claim they don't _want_ to change something that's inexpensive, already deployed (training, code, testing, etc), and working.

So I hope you'll tolerate me if I view this as less of a "how do we get a generic solution" and more of a "how does _this_ x86-ish issue get solved cleanly".

Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

add hooks to the pm_ops for each individual PM system to handle the wakeups in whatever way they see fit, and we're there. It would be slightly more complex for AT91 and friends to match this (since they have the advantage of a 1:1 mapping right now), but in the long run, I think everybody would benefit.

Quoted 8 lines
Quoted 6 lines

I guess I don't see why this isn't already sufficiently generic ...

As a rule, all those embedded drivers are platform-specific and have no need for more than a few enable_irq_wake() calls, in addition to whatever controller setup and clock management they do. Since they can't be very portable, they don't need to generalize such stuff.

enable_irq_wake() just doesn't work for x86, unfortunately.

And it doesn't need to, either. Those drivers can't run on x86.

That's just one more mechanism -- like clk_enable()/clk_disable(), set_irq_type(), or generic GPIOs -- that isn't really available on x86, despite being fundamental on may other platforms.

Quoted 5 lines

It seems
to me to be more logical to move the wakeup intelligence to the PM subsystem, and then let that code distribute it to where it is needed. In the case of x86, the logic would stay in the PM method, for other processors, it might involve a call to the interrupt mapper.

But why should a "PM subsystem" be created to abstract something that already works just fine?

It'd make much more sense to me to come up with a good way to handle the x86 issues first, and only then think about whether to try making that work on other systems.

Quoted 7 lines
Quoted 7 lines

And for PCI based things, pci_enable_wake() encapsulates everything that needs doing. Not that ACPI actually *does* anything yet! But the stuff that writing /proc/acpi/wakeup enables should happen in that routine ... and eventually PCI runtime wake events should work too. (So: no drivers would ever call ACPI directly, and they already have the generic call that ACPI should hook.)

Quoted 5 lines
Quoted 2 lines

That seems to cover most drivers in Linux, without a need for any new generic PM infrastructure. Did I overlook something important?

No, I don't think so - we're very close on agreeing here. I just don't know if enable_irq_wake() is the best way to provide the generic call.

It's not, and I didn't propose doing that either.

Having all drivers try to use the same calls to manage wakeup mechanisms doesn't seem like the right model. When the mechanism is the same -- wakeup irqs, say -- then yes the calls should be the same. But when the mechanisms differ -- PCI PME# is very different from wakeup IRQS, only one per device etc -- then the calls can reasonably be different.

Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Quoted 18 lines
Quoted 11 lines
Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

Quoted 6 lines

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

My point above was that ACPI isn't yet integrating with the things it needs to be integrating with. If you're concerned about how to work with wakeup events in Linux, don't even bother looking at ACPI. Look at the embedded implementations; look at USB. AT91 is by far the cleanest and most complete (simplest hardware too!!), but some of the other systems (OMAP, PXA, SA1100, etc) also implement wakeup using board-specific code.

OLPC _could_ use that same "board-specific hacks" approach found in most embedded platforms. I'm glad you're thinking about how to avoid doing that.

- Dave

#24 lore raw
Quoted 9 lines · David Brownell
Quoted 5 lines

So, for better or worse, we are implementing a new power management manger. Here is the code:

http://dev.laptop.org/git.do?p=olpc-2.6;a=blob;h=e6e19ac32a881be962db7190f2cb460e9f60a9da;hb=powermgmt;f=arch/i386/kernel/olpc-pm.c

Does that work yet with CONFIG_NO_HZ, so that the system idle loop enters some "almost everyting is turned off" low power state? Or would that be something other than a "PM Manager"?

I think eventually we'll get into entering deeper states in the idle loop. For now, we're just going into the classic C1 / hlt state, which is actually quite thrifty on the Geode, due to automatic hardware clock gating that happens throughout the chip(s).

Quoted 16 lines
Quoted 7 lines
Quoted 6 lines
Quoted 1 line

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

Quoted 8 lines

The silicon can handle wakeups from RTC, a sleep button, a power button, 8 GPIO groups, the USB controller (covering any and all USB events), UART1, UART2, SMbus and the PIC.

OLPC really only cares about 4 of those, because our only sleep state is ~S3, and the PIC, smbus, UARTs and USB are off in S3. We also only have the power button, and all the rest of the wakeup sources come from the GPIOs.

Quoted 6 lines

So it's a slightly deeper "S3" than I've usually seen, but not by much.

And correct me if I'm wrong, but your RTC can work with "rtc-cmos", and the wake hooks I've posted (and which will be in the next MM release) sound like they'll work just fine (given OLPC-specific implementation, which is clearly not included in the code above).

Indeed, and thank you much for that work - we'll be sure to integrate it.

Quoted 10 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

I'm not saying inside ACPI - I'm saying at the driver level.

Whereas in that patch, the only ACPI calls were inside ACPI itself; and that driver only had a callback. FWIW that's the first time I've ever needed to have indirection on wakeup event handling ...

This is the first real "embedded" scenario to pop its head up in x86 land, up to this point, most of the boards have just been really weak desktops.

Quoted 4 lines
Quoted 3 lines

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

Quoted 8 lines

With AT91 (and most ARMs) the wake events are normal IRQs, and the irq infrastructure already handles wake events cleanly. So I'd claim they don't _want_ to change something that's inexpensive, already deployed (training, code, testing, etc), and working.

So I hope you'll tolerate me if I view this as less of a "how do we get a generic solution" and more of a "how does _this_ x86-ish issue get solved cleanly".

Thats fair. x86 does live in a different world then the other embedded chips. I think its reasonable for the x86 folks to get their story straight and then move on from there.

Quoted 8 lines
Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Thats fine - I am not sold on a "one call to rule them all", but I do want to avoid any #ifdef CONFIG_PM_ACPI #elsif CONFIG_OLPC_PM #else nonsense.

Quoted 15 lines
Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

My point above was that ACPI isn't yet integrating with the things it needs to be integrating with. If you're concerned about how to work with wakeup events in Linux, don't even bother looking at ACPI. Look at the embedded implementations; look at USB. AT91 is by far the cleanest and most complete (simplest hardware too!!), but some of the other systems (OMAP, PXA, SA1100, etc) also implement wakeup using board-specific code.

Quoted 3 lines

OLPC _could_ use that same "board-specific hacks" approach found in most embedded platforms. I'm glad you're thinking about how to avoid doing that.

We are keenly aware that we're committing a minor sin by implementing yet another PM interface for x86. But we believe that our heart is in the right place, and we are dedicated to doing the right thing, and trying our hardest not to contribute further to fragmenting the PM subsystem with implementation specific code. In many cases we're looking to help bring the others into the fold, especially our fellow x86 implementations that suffer from the same issues that we do.

I appreciate your comments, and the rtc-cmos code will go to good use.

Jordan

Signature · 4 lines
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
#25 lore raw
Quoted 11 lines · Jordan Crouse
Quoted 9 lines · David Brownell
Quoted 3 lines

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

With AT91 (and most ARMs) the wake events are normal IRQs, and the irq infrastructure already handles wake events cleanly. So I'd claim they don't _want_ to change something that's inexpensive, already deployed (training, code, testing, etc), and working.

Quoted 7 lines
Quoted 3 lines

So I hope you'll tolerate me if I view this as less of a "how do we get a generic solution" and more of a "how does _this_ x86-ish issue get solved cleanly".

Thats fair. x86 does live in a different world then the other embedded chips. I think its reasonable for the x86 folks to get their story straight and then move on from there.

And I think it's good that OLPC doesn't seem to be starved of the relevant lowlevel chip specs, so the "story" can be based on what the hardware needs, rather than only what ACPI allows.

Quoted 5 lines
Quoted 5 lines
Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

Quoted 7 lines
Quoted 3 lines

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Thats fine - I am not sold on a "one call to rule them all", but I do want to avoid any #ifdef CONFIG_PM_ACPI #elsif CONFIG_OLPC_PM #else nonsense.

Right. In terms of source code, per-device callbacks can encapsulate that neatly: OLPC won't use ACPI files, and vice versa. There may be cases where that approach isn't enough, but it should cover a bunch of the most important cases. (Maybe OLPC won't need any more ...)

Quoted 2 lines

We are keenly aware that we're committing a minor sin by implementing yet another PM interface for x86.

I couldn't call it a sin unless I thought that ACPI were a Goddess, to be worshipped at the altar of HP/Intel/Microsoft/Phoenix/Toshiba! Somehow, I don't think you'll find many people who think that ... ;)

Quoted 6 lines

But we believe that our heart is in the
right place, and we are dedicated to doing the right thing, and trying our hardest not to contribute further to fragmenting the PM subsystem with implementation specific code. In many cases we're looking to help bring the others into the fold, especially our fellow x86 implementations that suffer from the same issues that we do.

Implementation-specific stuff isn't really a problem except when sneaks out into general purpose code. At that point you want some abstractions to hide those platform details.

Yes, I suspect you could be a big help to non-ACPI implementors on x86.

Quoted 1 line

I appreciate your comments, and the rtc-cmos code will go to good use.

Good! RTCs are interesting to PM primarily because most platforms seem to offer some kind of "wake alarm" mechanism ... which means they're a fair test case for whether a cross-platform interface actually works!

- Dave

#26 lore raw
In reply to Jordan Crouse
Quoted 11 lines · Jordan Crouse
Quoted 9 lines · David Brownell
Quoted 3 lines

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

With AT91 (and most ARMs) the wake events are normal IRQs, and the irq infrastructure already handles wake events cleanly. So I'd claim they don't _want_ to change something that's inexpensive, already deployed (training, code, testing, etc), and working.

Quoted 7 lines
Quoted 3 lines

So I hope you'll tolerate me if I view this as less of a "how do we get a generic solution" and more of a "how does _this_ x86-ish issue get solved cleanly".

Thats fair. x86 does live in a different world then the other embedded chips. I think its reasonable for the x86 folks to get their story straight and then move on from there.

And I think it's good that OLPC doesn't seem to be starved of the relevant lowlevel chip specs, so the "story" can be based on what the hardware needs, rather than only what ACPI allows.

Quoted 5 lines
Quoted 5 lines
Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

Quoted 7 lines
Quoted 3 lines

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Thats fine - I am not sold on a "one call to rule them all", but I do want to avoid any #ifdef CONFIG_PM_ACPI #elsif CONFIG_OLPC_PM #else nonsense.

Right. In terms of source code, per-device callbacks can encapsulate that neatly: OLPC won't use ACPI files, and vice versa. There may be cases where that approach isn't enough, but it should cover a bunch of the most important cases. (Maybe OLPC won't need any more ...)

Quoted 2 lines

We are keenly aware that we're committing a minor sin by implementing yet another PM interface for x86.

I couldn't call it a sin unless I thought that ACPI were a Goddess, to be worshipped at the altar of HP/Intel/Microsoft/Phoenix/Toshiba! Somehow, I don't think you'll find many people who think that ... ;)

Quoted 6 lines

But we believe that our heart is in the
right place, and we are dedicated to doing the right thing, and trying our hardest not to contribute further to fragmenting the PM subsystem with implementation specific code. In many cases we're looking to help bring the others into the fold, especially our fellow x86 implementations that suffer from the same issues that we do.

Implementation-specific stuff isn't really a problem except when sneaks out into general purpose code. At that point you want some abstractions to hide those platform details.

Yes, I suspect you could be a big help to non-ACPI implementors on x86.

Quoted 1 line

I appreciate your comments, and the rtc-cmos code will go to good use.

Good! RTCs are interesting to PM primarily because most platforms seem to offer some kind of "wake alarm" mechanism ... which means they're a fair test case for whether a cross-platform interface actually works!

- Dave

#27 lore raw

rtc-cmos not supporting RTC_AIE?

In reply to Jordan Crouse
Quoted 113 lines · Jordan Crouse
Quoted 9 lines · David Brownell
Quoted 5 lines

So, for better or worse, we are implementing a new power management manger. Here is the code:

http://dev.laptop.org/git.do?p=olpc-2.6;a=blob;h=e6e19ac32a881be962db7190f2cb460e9f60a9da;hb=powermgmt;f=arch/i386/kernel/olpc-pm.c

Does that work yet with CONFIG_NO_HZ, so that the system idle loop enters some "almost everyting is turned off" low power state? Or would that be something other than a "PM Manager"?

I think eventually we'll get into entering deeper states in the idle loop. For now, we're just going into the classic C1 / hlt state, which is actually quite thrifty on the Geode, due to automatic hardware clock gating that happens throughout the chip(s).

Quoted 16 lines
Quoted 7 lines
Quoted 6 lines
Quoted 1 line

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

Quoted 8 lines

The silicon can handle wakeups from RTC, a sleep button, a power button, 8 GPIO groups, the USB controller (covering any and all USB events), UART1, UART2, SMbus and the PIC.

OLPC really only cares about 4 of those, because our only sleep state is ~S3, and the PIC, smbus, UARTs and USB are off in S3. We also only have the power button, and all the rest of the wakeup sources come from the GPIOs.

Quoted 6 lines

So it's a slightly deeper "S3" than I've usually seen, but not by much.

And correct me if I'm wrong, but your RTC can work with "rtc-cmos", and the wake hooks I've posted (and which will be in the next MM release) sound like they'll work just fine (given OLPC-specific implementation, which is clearly not included in the code above).

Indeed, and thank you much for that work - we'll be sure to integrate it.

Quoted 10 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

I'm not saying inside ACPI - I'm saying at the driver level.

Whereas in that patch, the only ACPI calls were inside ACPI itself; and that driver only had a callback. FWIW that's the first time I've ever needed to have indirection on wakeup event handling ...

This is the first real "embedded" scenario to pop its head up in x86 land, up to this point, most of the boards have just been really weak desktops.

Quoted 4 lines
Quoted 3 lines

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

Quoted 8 lines

With AT91 (and most ARMs) the wake events are normal IRQs, and the irq infrastructure already handles wake events cleanly. So I'd claim they don't _want_ to change something that's inexpensive, already deployed (training, code, testing, etc), and working.

So I hope you'll tolerate me if I view this as less of a "how do we get a generic solution" and more of a "how does _this_ x86-ish issue get solved cleanly".

Thats fair. x86 does live in a different world then the other embedded chips. I think its reasonable for the x86 folks to get their story straight and then move on from there.

Quoted 8 lines
Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Thats fine - I am not sold on a "one call to rule them all", but I do want to avoid any #ifdef CONFIG_PM_ACPI #elsif CONFIG_OLPC_PM #else nonsense.

Quoted 15 lines
Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

My point above was that ACPI isn't yet integrating with the things it needs to be integrating with. If you're concerned about how to work with wakeup events in Linux, don't even bother looking at ACPI. Look at the embedded implementations; look at USB. AT91 is by far the cleanest and most complete (simplest hardware too!!), but some of the other systems (OMAP, PXA, SA1100, etc) also implement wakeup using board-specific code.

Quoted 3 lines

OLPC _could_ use that same "board-specific hacks" approach found in most embedded platforms. I'm glad you're thinking about how to avoid doing that.

We are keenly aware that we're committing a minor sin by implementing yet another PM interface for x86. But we believe that our heart is in the right place, and we are dedicated to doing the right thing, and trying our hardest not to contribute further to fragmenting the PM subsystem with implementation specific code. In many cases we're looking to help bring the others into the fold, especially our fellow x86 implementations that suffer from the same issues that we do.

Quoted 1 line

I appreciate your comments, and the rtc-cmos code will go to good use.

David,

Is there any reason why programs using RTC_AIE/RTC_ALM_SET ioctls are unable to arm alarm irq's?

I'm aware of the new RTC_WKALM_SET... but shouldnt backward compatibility be kept?

The code seems to imply that its not supported anymore, however ioctl returns success but no alarm is fired (for instance alarm.enabled is set to 0):

        case RTC_ALM_SET:
                if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
                        return -EFAULT;

                alarm.enabled = 0;
                alarm.pending = 0;
                alarm.time.tm_wday = -1;
                alarm.time.tm_yday = -1;
                alarm.time.tm_isdst = -1;

Thanks

#28 lore raw

Re: rtc-cmos not supporting RTC_AIE?

Quoted 5 lines · Marcelo Tosatti

David,

Is there any reason why programs using RTC_AIE/RTC_ALM_SET ioctls are unable to arm alarm irq's?

The ALM_SET request never did! And I'm pretty sure AIE_ON does indeed set it ... the test cases use ALM_SET then AIE_ON, which is the "traditional" idiom (i.e. legacy drivers/char/rtc.c idiom).

Quoted 2 lines

I'm aware of the new RTC_WKALM_SET... but shouldnt backward compatibility be kept?

According to <linux/rtc.h> the ALM_SET ioctl takes an rtc_time, while WKALM_SET takes an rtc_wkalm ... which differs from the former by including the flag controlling wheter the alarm will be enabled (or not) when setting the alarm. (Model inherited from EFI.)

Quoted 4 lines

The code seems to imply that its not supported anymore, however ioctl returns success but no alarm is fired (for instance alarm.enabled is set to 0):

Quoted 9 lines
        case RTC_ALM_SET:
                if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
                        return -EFAULT;

                alarm.enabled = 0;
                alarm.pending = 0;
                alarm.time.tm_wday = -1;
                alarm.time.tm_yday = -1;
                alarm.time.tm_isdst = -1;

That code is generic RTC framework code (rtc-dev.c), and not code specific to rtc-cmos ... the comment immediately following that (2.6.22-rc7 and previous) should clarify many of the issues.

I think the current manpage does the same. (If it mentions the /dev/rtc0, /dev/rtc1, etc files, it should be current enough.)

What it does is just stuff the rtc_time into the expanded rtc_wkalm. The idea is that the RTC drivers only support one alarm-setting method, but the /dev/rtcN ioctl interface uses it in two modes:

- "legacy", up to 24 hours in the future, and requiring the alarm to be enabled later with AIE_ON;

- "EFI-style", into the arbitrary future, and bundling the flag saying whether to enable the alarm.

Since ALM_SET is the legacy mode, it requires separate AIE_ON (from the RTC driver directly). But RTC_WKALM_SET doesn't.

- Dave

#29 lore raw

Re: rtc-cmos not supporting RTC_AIE?

In reply to Marcelo Tosatti
Quoted 5 lines · Marcelo Tosatti

David,

Is there any reason why programs using RTC_AIE/RTC_ALM_SET ioctls are unable to arm alarm irq's?

The ALM_SET request never did! And I'm pretty sure AIE_ON does indeed set it ... the test cases use ALM_SET then AIE_ON, which is the "traditional" idiom (i.e. legacy drivers/char/rtc.c idiom).

Quoted 2 lines

I'm aware of the new RTC_WKALM_SET... but shouldnt backward compatibility be kept?

According to <linux/rtc.h> the ALM_SET ioctl takes an rtc_time, while WKALM_SET takes an rtc_wkalm ... which differs from the former by including the flag controlling wheter the alarm will be enabled (or not) when setting the alarm. (Model inherited from EFI.)

Quoted 4 lines

The code seems to imply that its not supported anymore, however ioctl returns success but no alarm is fired (for instance alarm.enabled is set to 0):

Quoted 9 lines
        case RTC_ALM_SET:
                if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
                        return -EFAULT;

                alarm.enabled = 0;
                alarm.pending = 0;
                alarm.time.tm_wday = -1;
                alarm.time.tm_yday = -1;
                alarm.time.tm_isdst = -1;

That code is generic RTC framework code (rtc-dev.c), and not code specific to rtc-cmos ... the comment immediately following that (2.6.22-rc7 and previous) should clarify many of the issues.

I think the current manpage does the same. (If it mentions the /dev/rtc0, /dev/rtc1, etc files, it should be current enough.)

What it does is just stuff the rtc_time into the expanded rtc_wkalm. The idea is that the RTC drivers only support one alarm-setting method, but the /dev/rtcN ioctl interface uses it in two modes:

- "legacy", up to 24 hours in the future, and requiring the alarm to be enabled later with AIE_ON;

- "EFI-style", into the arbitrary future, and bundling the flag saying whether to enable the alarm.

Since ALM_SET is the legacy mode, it requires separate AIE_ON (from the RTC driver directly). But RTC_WKALM_SET doesn't.

- Dave

#30 lore raw

Re: rtc-cmos not supporting RTC_AIE?

Quoted 11 lines · David Brownell
Quoted 5 lines · Marcelo Tosatti

David,

Is there any reason why programs using RTC_AIE/RTC_ALM_SET ioctls are unable to arm alarm irq's?

The ALM_SET request never did! And I'm pretty sure AIE_ON does indeed set it ... the test cases use ALM_SET then AIE_ON, which is the "traditional" idiom (i.e. legacy drivers/char/rtc.c idiom).

My point is that RTC_ALM_SET after RTC_AIE_ON works with drivers/char/rtc.c but not rtc-cmos:

        ret = ioctl(fd, RTC_AIE_ON);
        if (ret) {
                perror("ioctl RTC_AIE_ON");
                exit(0);
        }

        ret = ioctl(fd, RTC_ALM_SET, &rtctime);
        if (ret) {
                perror("ioctl RTC_ALM_SET");
                exit(0);
        }

I think its fine to consider such applications broken anyway?

Quoted 8 lines
Quoted 2 lines

I'm aware of the new RTC_WKALM_SET... but shouldnt backward compatibility be kept?

According to <linux/rtc.h> the ALM_SET ioctl takes an rtc_time, while WKALM_SET takes an rtc_wkalm ... which differs from the former by including the flag controlling wheter the alarm will be enabled (or not) when setting the alarm. (Model inherited from EFI.)

Right.

Quoted 38 lines
Quoted 5 lines

The code seems to imply that its not supported anymore, however ioctl returns success but no alarm is fired (for instance alarm.enabled is set to 0):

Quoted 9 lines
        case RTC_ALM_SET:
                if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
                        return -EFAULT;

                alarm.enabled = 0;
                alarm.pending = 0;
                alarm.time.tm_wday = -1;
                alarm.time.tm_yday = -1;
                alarm.time.tm_isdst = -1;

That code is generic RTC framework code (rtc-dev.c), and not code specific to rtc-cmos ... the comment immediately following that (2.6.22-rc7 and previous) should clarify many of the issues.

I think the current manpage does the same. (If it mentions the /dev/rtc0, /dev/rtc1, etc files, it should be current enough.)

What it does is just stuff the rtc_time into the expanded rtc_wkalm. The idea is that the RTC drivers only support one alarm-setting method, but the /dev/rtcN ioctl interface uses it in two modes:

- "legacy", up to 24 hours in the future, and requiring the alarm to be enabled later with AIE_ON;

- "EFI-style", into the arbitrary future, and bundling the flag saying whether to enable the alarm.

Since ALM_SET is the legacy mode, it requires separate AIE_ON (from the RTC driver directly). But RTC_WKALM_SET doesn't.

- Dave

#31 lore raw

Re: rtc-cmos not supporting RTC_AIE?

Quoted 15 lines · Marcelo Tosatti

My point is that RTC_ALM_SET after RTC_AIE_ON works with drivers/char/rtc.c but not rtc-cmos:

        ret = ioctl(fd, RTC_AIE_ON);
        if (ret) {
                perror("ioctl RTC_AIE_ON");
                exit(0);
        }

        ret = ioctl(fd, RTC_ALM_SET, &rtctime);
        if (ret) {
                perror("ioctl RTC_ALM_SET");
                exit(0);
        }
Quoted 1 line

I think its fine to consider such applications broken anyway?

I think so ... although that's unfortunately another difference between the legacy x86-mostly code and the newer RTC framework.

Unless enough folk strongly disagree, I'd say this is just something else to watch out for as part of converting. Not every quirk got carried forward.

- Dave

#32 lore raw

Re: rtc-cmos not supporting RTC_AIE?

Quoted 3 lines · David Brownell

I think so ... although that's unfortunately another difference between the legacy x86-mostly code and the newer RTC framework.

(sorry for hijacking the thread)

Is this the interface should stuff like HAL use to do:

* Suspend for 10 minutes
* auto wakeup and then hibernate.

I figure we can do a suspend setting the rtc using the ioctls and then we wakeup, and HAL has to know that we woke up from the alarm rather than from a lid event or keypress.

Is this something we can do (or should do) for OLPC and general ACPI?

Cheers guys.

Richard.

#33 lore raw

Re: Hibernate after alarm wakes from STR

Quoted 6 lines · Richard Hughes
Quoted 3 lines · David Brownell

I think so ... although that's unfortunately another difference between the legacy x86-mostly code and the newer RTC framework.

(sorry for hijacking the thread)

I changed $SUBJECT ...

Quoted 4 lines

Is this the interface should stuff like HAL use to do:

* Suspend for 10 minutes
* auto wakeup and then hibernate...

That is, "Suspend-to-RAM" or "standby"? Yes, assuming that works on this particular system. Arguably that would be a direction for cpuidle to think about too, but I think alarm-driven wakeup is more ready-to-use at this point.

Quoted 3 lines

I figure we can do a suspend setting the rtc using the ioctls and then we wakeup, and HAL has to know that we woke up from the alarm rather than from a lid event or keypress.

... although I don't know whether that particular distinction is made to userspace right now. ACPI provides a bit like that, and at least a few other systems can do something analagous.

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Quoted 1 line

Is this something we can do (or should do) for OLPC and general ACPI?

I'd certainly rather see laptops doing that than what they do now:
running the battery out, and needing filesystem recovery!!

- Dave

#34 lore raw

Re: Hibernate after alarm wakes from STR

Quoted 13 lines · David Brownell
Quoted 6 lines · Richard Hughes
Quoted 3 lines · David Brownell

I think so ... although that's unfortunately another difference between the legacy x86-mostly code and the newer RTC framework.

(sorry for hijacking the thread)

I changed $SUBJECT ...

Quoted 2 lines

Is this the interface should stuff like HAL use to do:

Quoted 12 lines
Quoted 2 lines

* Suspend for 10 minutes
* auto wakeup and then hibernate...

That is, "Suspend-to-RAM" or "standby"? Yes, assuming that works on this particular system. Arguably that would be a direction for cpuidle to think about too, but I think alarm-driven wakeup is more ready-to-use at this point.

Quoted 3 lines

I figure we can do a suspend setting the rtc using the ioctls and then we wakeup, and HAL has to know that we woke up from the alarm rather than from a lid event or keypress.

On OLPC hibernate would be suspend-to-disk, but we haven't done any testing with that yet. It would be necessary to check for available disk space before attempting it (or reserving space perhaps?).

Quoted 3 lines

... although I don't know whether that particular distinction is made to userspace right now. ACPI provides a bit like that, and at least a few other systems can do something analagous.

Yes, we can poke at registers to find that out.

Quoted 3 lines

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

What would be a nice interface? Perhaps an additional file under /sys/devices/.../power/wakeup_fired or something (only for devices with can_wakeup set).

Quoted 2 lines

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Then you check if the any key or other wakeup event has happened other than RTC... I don't see any problem with that.

Quoted 4 lines
Quoted 1 line

Is this something we can do (or should do) for OLPC and general ACPI?

I'd certainly rather see laptops doing that than what they do now:
running the battery out, and needing filesystem recovery!!

Yep.

#35 lore raw

Re: Hibernate after alarm wakes from STR

Quoted 10 lines · Marcelo Tosatti
Quoted 5 lines · David Brownell

On Sunday 08 July 2007, Richard Hughes wrote:

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

What would be a nice interface? Perhaps an additional file under /sys/devices/.../power/wakeup_fired or something (only for devices with can_wakeup set).

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

Quoted 5 lines
Quoted 2 lines

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Then you check if the any key or other wakeup event has happened other than RTC... I don't see any problem with that.

It might be best not to need to re-activate the whole system from STR though ... it ought to be possible to just power off, having already written the image to disk. Right?

Yes, there's all that stuff about how to quiesce the system properly, freezer/icebox/flamesuits/etc. Regardless, going from STR to fully operational and then hibernating would take time and energy that might not be available...

- Dave

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

Is this something we can do (or should do) for OLPC and general ACPI?

I'd certainly rather see laptops doing that than what they do now:
running the battery out, and needing filesystem recovery!!

Yep.

#36 lore raw

Re: Hibernate after alarm wakes from STR

In reply to Marcelo Tosatti
Quoted 10 lines · Marcelo Tosatti
Quoted 5 lines · David Brownell

On Sunday 08 July 2007, Richard Hughes wrote:

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

What would be a nice interface? Perhaps an additional file under /sys/devices/.../power/wakeup_fired or something (only for devices with can_wakeup set).

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

Quoted 5 lines
Quoted 2 lines

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Then you check if the any key or other wakeup event has happened other than RTC... I don't see any problem with that.

It might be best not to need to re-activate the whole system from STR though ... it ought to be possible to just power off, having already written the image to disk. Right?

Yes, there's all that stuff about how to quiesce the system properly, freezer/icebox/flamesuits/etc. Regardless, going from STR to fully operational and then hibernating would take time and energy that might not be available...

- Dave

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

Is this something we can do (or should do) for OLPC and general ACPI?

I'd certainly rather see laptops doing that than what they do now:
running the battery out, and needing filesystem recovery!!

Yep.

#37 lore raw

Re: Hibernate after alarm wakes from STR

Quoted 8 lines · David Brownell
Quoted 7 lines · Marcelo Tosatti
Quoted 5 lines · David Brownell

On Sunday 08 July 2007, Richard Hughes wrote:

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

Quoted 6 lines
Quoted 3 lines

What would be a nice interface? Perhaps an additional file under /sys/devices/.../power/wakeup_fired or something (only for devices with can_wakeup set).

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

Good plan.

Quoted 6 lines
Quoted 5 lines
Quoted 2 lines

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Then you check if the any key or other wakeup event has happened other than RTC... I don't see any problem with that.

Quoted 8 lines

It might be best not to need to re-activate the whole system from STR though ... it ought to be possible to just power off, having already written the image to disk. Right?

Yes, there's all that stuff about how to quiesce the system properly, freezer/icebox/flamesuits/etc. Regardless, going from STR to fully operational and then hibernating would take time and energy that might not be available...

Sure, although quick-suspend on a few minutes idle, slow hibernate-on-long idle is one of the biggest requested features of g-p-m.

Richard.

#38 lore raw

Re: Hibernate after alarm wakes from STR

In reply to David Brownell
Quoted 8 lines · David Brownell
Quoted 7 lines · Marcelo Tosatti
Quoted 5 lines · David Brownell

On Sunday 08 July 2007, Richard Hughes wrote:

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

Quoted 6 lines
Quoted 3 lines

What would be a nice interface? Perhaps an additional file under /sys/devices/.../power/wakeup_fired or something (only for devices with can_wakeup set).

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

Good plan.

Quoted 6 lines
Quoted 5 lines
Quoted 2 lines

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Then you check if the any key or other wakeup event has happened other than RTC... I don't see any problem with that.

Quoted 8 lines

It might be best not to need to re-activate the whole system from STR though ... it ought to be possible to just power off, having already written the image to disk. Right?

Yes, there's all that stuff about how to quiesce the system properly, freezer/icebox/flamesuits/etc. Regardless, going from STR to fully operational and then hibernating would take time and energy that might not be available...

Sure, although quick-suspend on a few minutes idle, slow hibernate-on-long idle is one of the biggest requested features of g-p-m.

Richard.

#39 lore raw

Re: Hibernate after alarm wakes from STR

In reply to David Brownell
Quoted 8 lines · David Brownell
Quoted 7 lines · Marcelo Tosatti
Quoted 5 lines · David Brownell

On Sunday 08 July 2007, Richard Hughes wrote:

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

Quoted 6 lines
Quoted 3 lines

What would be a nice interface? Perhaps an additional file under /sys/devices/.../power/wakeup_fired or something (only for devices with can_wakeup set).

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Quoted 9 lines
Quoted 5 lines
Quoted 2 lines

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Then you check if the any key or other wakeup event has happened other than RTC... I don't see any problem with that.

It might be best not to need to re-activate the whole system from STR though ... it ought to be possible to just power off, having already written the image to disk. Right?

Perhaps, yes...

Quoted 4 lines

Yes, there's all that stuff about how to quiesce the system properly, freezer/icebox/flamesuits/etc. Regardless, going from STR to fully operational and then hibernating would take time and energy that might not be available...

True, that needs to be taken into account.

Quoted 11 lines

- Dave

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

Is this something we can do (or should do) for OLPC and general ACPI?

I'd certainly rather see laptops doing that than what they do now:
running the battery out, and needing filesystem recovery!!

Yep.

#40 lore raw

Re: Hibernate after alarm wakes from STR

Quoted 7 lines · Marcelo Tosatti
Quoted 2 lines · David Brownell

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Actually I though I said that there would be races. Though come to think of it, one way they'd show up on a typical embedded system would be to have multiple wake IRQs pending ... you couldn't tell which one came first. (The typical case would be a single event, of course.) ACPI-ish systems would do that with GPEs and the magic "rtc woke" flag.

And then there are shared IRQ lines serving as wake sources. There could be three wake-enabled devices on that line (plus others that aren't wake-enabled); the drivers returning IRQ_HANDLED should likely be reported as having been wake sources, but not the ones returning IRQ_NONE ...

... so yes, systems might need to present multiple wake events.

Quoted 4 lines

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Better to have that node be a directory of links then, rather than a single link.

Note that I'm just throwing ideas out there. I suspect that in the general case it may not be easy to map from wake event to device, without infrastructure that's now missing.

- Dave

#41 lore raw

Re: Hibernate after alarm wakes from STR

In reply to Marcelo Tosatti
Quoted 7 lines · Marcelo Tosatti
Quoted 2 lines · David Brownell

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Actually I though I said that there would be races. Though come to think of it, one way they'd show up on a typical embedded system would be to have multiple wake IRQs pending ... you couldn't tell which one came first. (The typical case would be a single event, of course.) ACPI-ish systems would do that with GPEs and the magic "rtc woke" flag.

And then there are shared IRQ lines serving as wake sources. There could be three wake-enabled devices on that line (plus others that aren't wake-enabled); the drivers returning IRQ_HANDLED should likely be reported as having been wake sources, but not the ones returning IRQ_NONE ...

... so yes, systems might need to present multiple wake events.

Quoted 4 lines

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Better to have that node be a directory of links then, rather than a single link.

Note that I'm just throwing ideas out there. I suspect that in the general case it may not be easy to map from wake event to device, without infrastructure that's now missing.

- Dave

#42 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

Hi.

Quoted 28 lines · On Tuesday 10 July 2007 02:26:32 David Brownell wrote:
Quoted 7 lines · Marcelo Tosatti
Quoted 2 lines · David Brownell

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Actually I though I said that there would be races. Though come to think of it, one way they'd show up on a typical embedded system would be to have multiple wake IRQs pending ... you couldn't tell which one came first. (The typical case would be a single event, of course.) ACPI-ish systems would do that with GPEs and the magic "rtc woke" flag.

And then there are shared IRQ lines serving as wake sources. There could be three wake-enabled devices on that line (plus others that aren't wake-enabled); the drivers returning IRQ_HANDLED should likely be reported as having been wake sources, but not the ones returning IRQ_NONE ...

... so yes, systems might need to present multiple wake events.

Quoted 3 lines

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Quoted 8 lines
Quoted 1 line

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Better to have that node be a directory of links then, rather than a single link.

Note that I'm just throwing ideas out there. I suspect that in the general case it may not be easy to map from wake event to device, without infrastructure that's now missing.

FWIW, I've recently added code to Suspend2 to allow it to (optionally) set the RTC wake alarm when it's finished writing the image and check the lid switch when waking, entering a different sleep state if the lid switch is still closed. It achieves this by letting the user set the name of an rtc alarm to use (the 'rtc0' in /sys/class/rtc/rtc0/*) and of a button to use (lid/LID in /proc/acpi/button/lid/LID/*). It then opens the button directory's state file and the rtc directory's since_epoch and wakealarm files, and uses them to determine read the time since epoch and set the wakealarm and determine whether the lid button is still closed.

I don't really like the opening /proc and /sysfs files in this way - whatever solution you come up with, could you consider exposing some way for kernel code to do this more neatly?

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#43 lore raw

Re: Re: Hibernate after alarm wakes from STR

Quoted 40 lines · Nigel Cunningham

Hi.

Quoted 28 lines · On Tuesday 10 July 2007 02:26:32 David Brownell wrote:
Quoted 7 lines · Marcelo Tosatti
Quoted 2 lines · David Brownell

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Actually I though I said that there would be races. Though come to think of it, one way they'd show up on a typical embedded system would be to have multiple wake IRQs pending ... you couldn't tell which one came first. (The typical case would be a single event, of course.) ACPI-ish systems would do that with GPEs and the magic "rtc woke" flag.

And then there are shared IRQ lines serving as wake sources. There could be three wake-enabled devices on that line (plus others that aren't wake-enabled); the drivers returning IRQ_HANDLED should likely be reported as having been wake sources, but not the ones returning IRQ_NONE ...

... so yes, systems might need to present multiple wake events.

Quoted 3 lines

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Quoted 8 lines
Quoted 1 line

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Better to have that node be a directory of links then, rather than a single link.

Note that I'm just throwing ideas out there. I suspect that in the general case it may not be easy to map from wake event to device, without infrastructure that's now missing.

Quoted 9 lines

FWIW, I've recently added code to Suspend2 to allow it to (optionally) set the RTC wake alarm when it's finished writing the image and check the lid switch when waking, entering a different sleep state if the lid switch is still closed. It achieves this by letting the user set the name of an rtc alarm to use (the 'rtc0' in /sys/class/rtc/rtc0/*) and of a button to use (lid/LID in /proc/acpi/button/lid/LID/*). It then opens the button directory's state file and the rtc directory's since_epoch and wakealarm files, and uses them to determine read the time since epoch and set the wakealarm and determine whether the lid button is still closed.

Interesting...

Quoted 3 lines

I don't really like the opening /proc and /sysfs files in this way - whatever solution you come up with, could you consider exposing some way for kernel code to do this more neatly?

You're supposed to be able to use /sys/... files this way!

But that's not true of /proc/... files.

- Dave

#44 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

In reply to Nigel Cunningham
Quoted 40 lines · Nigel Cunningham

Hi.

Quoted 28 lines · On Tuesday 10 July 2007 02:26:32 David Brownell wrote:
Quoted 7 lines · Marcelo Tosatti
Quoted 2 lines · David Brownell

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Actually I though I said that there would be races. Though come to think of it, one way they'd show up on a typical embedded system would be to have multiple wake IRQs pending ... you couldn't tell which one came first. (The typical case would be a single event, of course.) ACPI-ish systems would do that with GPEs and the magic "rtc woke" flag.

And then there are shared IRQ lines serving as wake sources. There could be three wake-enabled devices on that line (plus others that aren't wake-enabled); the drivers returning IRQ_HANDLED should likely be reported as having been wake sources, but not the ones returning IRQ_NONE ...

... so yes, systems might need to present multiple wake events.

Quoted 3 lines

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Quoted 8 lines
Quoted 1 line

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Better to have that node be a directory of links then, rather than a single link.

Note that I'm just throwing ideas out there. I suspect that in the general case it may not be easy to map from wake event to device, without infrastructure that's now missing.

Quoted 9 lines

FWIW, I've recently added code to Suspend2 to allow it to (optionally) set the RTC wake alarm when it's finished writing the image and check the lid switch when waking, entering a different sleep state if the lid switch is still closed. It achieves this by letting the user set the name of an rtc alarm to use (the 'rtc0' in /sys/class/rtc/rtc0/*) and of a button to use (lid/LID in /proc/acpi/button/lid/LID/*). It then opens the button directory's state file and the rtc directory's since_epoch and wakealarm files, and uses them to determine read the time since epoch and set the wakealarm and determine whether the lid button is still closed.

Interesting...

Quoted 3 lines

I don't really like the opening /proc and /sysfs files in this way - whatever solution you come up with, could you consider exposing some way for kernel code to do this more neatly?

You're supposed to be able to use /sys/... files this way!

But that's not true of /proc/... files.

- Dave

#45 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

Hi.

Quoted 34 lines · On Wednesday 11 July 2007 02:51:03 David Brownell wrote:
Quoted 33 lines · Nigel Cunningham

Hi.

Quoted 30 lines · On Tuesday 10 July 2007 02:26:32 David Brownell wrote:
Quoted 7 lines · Marcelo Tosatti
Quoted 2 lines · David Brownell

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Actually I though I said that there would be races. Though come to think of it, one way they'd show up on a typical embedded system would be to have multiple wake IRQs pending ... you couldn't tell which one came first. (The typical case would be a single event, of course.) ACPI-ish systems would do that with GPEs and the magic "rtc woke" flag.

And then there are shared IRQ lines serving as wake sources. There could be three wake-enabled devices on that line (plus others that aren't wake-enabled); the drivers returning IRQ_HANDLED should likely be reported as having been wake sources, but not the ones returning IRQ_NONE ...

... so yes, systems might need to present multiple wake events.

Quoted 4 lines

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Quoted 8 lines
Quoted 8 lines
Quoted 6 lines

Better to have that node be a directory of links then, rather than a single link.

Note that I'm just throwing ideas out there. I suspect that in the general case it may not be easy to map from wake event to device, without infrastructure that's now missing.

FWIW, I've recently added code to Suspend2 to allow it to (optionally) set

the

Quoted 1 line
Quoted 1 line

RTC wake alarm when it's finished writing the image and check the lid

switch

Quoted 2 lines
Quoted 2 lines

when waking, entering a different sleep state if the lid switch is still closed. It achieves this by letting the user set the name of an rtc alarm

to

Quoted 2 lines
Quoted 2 lines

use (the 'rtc0' in /sys/class/rtc/rtc0/*) and of a button to use (lid/LID in /proc/acpi/button/lid/LID/*). It then opens the button directory's

state

Quoted 1 line
Quoted 1 line

file and the rtc directory's since_epoch and wakealarm files, and uses

them

Quoted 6 lines
Quoted 2 lines

to determine read the time since epoch and set the wakealarm and determine whether the lid button is still closed.

Interesting...

Quoted 1 line

I don't really like the opening /proc and /sysfs files in this way -

whatever

Quoted 6 lines
Quoted 2 lines

solution you come up with, could you consider exposing some way for kernel code to do this more neatly?

You're supposed to be able to use /sys/... files this way!

But that's not true of /proc/... files.

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the functionality without having to rely on userspace or do some sort of messy work to figure out how to access the lid button and so on.

Re proc files, are the button files already exposed under sysfs and I just don't know? If so, I'll happily shift to using them.

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#46 lore raw

Re: Re: Hibernate after alarm wakes from STR

Quoted 4 lines · Nigel Cunningham

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the functionality without having to rely on userspace or do some sort of messy work to figure out how to access the lid button and so on.

How are you going to shift into suspend to disk without going via userspace? It's quite plausible that people will want different configuration at that point (or, realistically, need a different set of workarounds...)

Signature · 1 line
Matthew Garrett | [email protected]
#47 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

In reply to Nigel Cunningham
Quoted 4 lines · Nigel Cunningham

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the functionality without having to rely on userspace or do some sort of messy work to figure out how to access the lid button and so on.

How are you going to shift into suspend to disk without going via userspace? It's quite plausible that people will want different configuration at that point (or, realistically, need a different set of workarounds...)

Signature · 1 line
Matthew Garrett | [email protected]
#48 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

Hi.

Quoted 3 lines · On Wednesday 11 July 2007 10:45:50 Matthew Garrett wrote:
Quoted 2 lines · Nigel Cunningham

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the

functionality

Quoted 1 line
Quoted 1 line

without having to rely on userspace or do some sort of messy work to

figure

Quoted 6 lines
Quoted 1 line

out how to access the lid button and so on.

How are you going to shift into suspend to disk without going via userspace? It's quite plausible that people will want different configuration at that point (or, realistically, need a different set of workarounds...)

This is done after writing the image, from kernel space. We do the suspend-to-ram, and if/when we wake from that, we look at the lid switch state before removing the image. If it's still closed, the kernel code powers down again (this time properly) without userspace ever seeing the light of day.

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#49 lore raw

Re: Re: Hibernate after alarm wakes from STR

Quoted 11 lines · Nigel Cunningham
Quoted 4 lines · On Wednesday 11 July 2007 10:45:50 Matthew Garrett wrote:

How are you going to shift into suspend to disk without going via userspace? It's quite plausible that people will want different configuration at that point (or, realistically, need a different set of workarounds...)

This is done after writing the image, from kernel space. We do the suspend-to-ram, and if/when we wake from that, we look at the lid switch state before removing the image. If it's still closed, the kernel code powers down again (this time properly) without userspace ever seeing the light of day.

Yes. I'm sort of struggling to see how this is done especially reliably
- if we have separate hibernation and suspend to ram pathways, which is executed in this scenario?

Signature · 1 line
Matthew Garrett | [email protected]
#50 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

In reply to Nigel Cunningham
Quoted 11 lines · Nigel Cunningham
Quoted 4 lines · On Wednesday 11 July 2007 10:45:50 Matthew Garrett wrote:

How are you going to shift into suspend to disk without going via userspace? It's quite plausible that people will want different configuration at that point (or, realistically, need a different set of workarounds...)

This is done after writing the image, from kernel space. We do the suspend-to-ram, and if/when we wake from that, we look at the lid switch state before removing the image. If it's still closed, the kernel code powers down again (this time properly) without userspace ever seeing the light of day.

Yes. I'm sort of struggling to see how this is done especially reliably
- if we have separate hibernation and suspend to ram pathways, which is executed in this scenario?

Signature · 1 line
Matthew Garrett | [email protected]
#51 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

Hi.

Quoted 10 lines · On Wednesday 11 July 2007 11:23:02 Matthew Garrett wrote:
Quoted 9 lines · Nigel Cunningham
Quoted 4 lines · On Wednesday 11 July 2007 10:45:50 Matthew Garrett wrote:

How are you going to shift into suspend to disk without going via userspace? It's quite plausible that people will want different configuration at that point (or, realistically, need a different set of workarounds...)

This is done after writing the image, from kernel space. We do the suspend-to-ram, and if/when we wake from that, we look at the lid switch state before removing the image. If it's still closed, the kernel code

powers

Quoted 6 lines
Quoted 2 lines

down again (this time properly) without userspace ever seeing the light of day.

Yes. I'm sort of struggling to see how this is done especially reliably
- if we have separate hibernation and suspend to ram pathways, which is executed in this scenario?

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to ram platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image, then suspend to ram, wake and continue working without running running out of battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run the pm_ops->finish after doing the atomic restore when resuming the image.

I haven't looked at what uswsusp does (I'm just looking at Suspend2 code above), but it will have similar issues as it also has support for suspending to ram after writing an image.

Regards,

Nigel

Signature · 5 lines
Nigel Cunningham
Christian Reformed Church of Cobden
103 Curdie Street, Cobden 3266, Victoria, Australia
Ph. +61 3 5595 1185 / +61 417 100 574
Communal Worship: 11 am Sunday.
#52 lore raw

Re: Re: Hibernate after alarm wakes from STR

Quoted 7 lines · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to ram platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image, then suspend to ram, wake and continue working without running running out of battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run the pm_ops->finish after doing the atomic restore when resuming the image.

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Signature · 1 line
Matthew Garrett | [email protected]
#53 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

In reply to Nigel Cunningham
Quoted 7 lines · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to ram platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image, then suspend to ram, wake and continue working without running running out of battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run the pm_ops->finish after doing the atomic restore when resuming the image.

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Signature · 1 line
Matthew Garrett | [email protected]
#54 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

Hi.

Quoted 10 lines · On Wednesday 11 July 2007 11:59:48 Matthew Garrett wrote:
Quoted 7 lines · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to ram platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image, then suspend to ram, wake and continue working without running running out of battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run the pm_ops->finish after doing the atomic restore when resuming the image.

Quoted 5 lines

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Yeah, we could redo and resave the atomic copy, but it doesn't seem to be necessary at the moment; it has been working reliably, regardless of which combination of events occurs. If/when I come across a case where we have problems, I'll give resaving the atomic copy a go.

(Thinks some more). Ah, I think we're already doing the right thing, if I'm recalling the order of actions right. If I'm remembering correctly, prior to the atomic copy, we do hibernation prep, then after the atomic copy, hibernation cleanup. Then, if suspending to ram, we do the prep/enter/cleanup after the image has finished writing. If we lose power from suspend to ram, it doesn't matter because we're just doing a normal resume then, with the hibernation cleanup post atomic restore machine the prep that was done prior to the atomic copy.

To summarise:

Hibernate + STR + full wake.
Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
STR cleanup
Remove hibernation image

Hibernate + STR + poweroff + hibernate resume:

Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
<power out> or <STR wake + power off> (STR prep/enter no longer matters) (Fresh boot)
Atomic restore
Hibernation cleanup (matching prep at start)
Remove hibernation image

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#55 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

Hi,

Quoted 46 lines · Nigel Cunningham

Hi.

Quoted 10 lines · On Wednesday 11 July 2007 11:59:48 Matthew Garrett wrote:
Quoted 7 lines · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to ram platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image, then suspend to ram, wake and continue working without running running out of battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run the pm_ops->finish after doing the atomic restore when resuming the image.

Quoted 5 lines

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Yeah, we could redo and resave the atomic copy, but it doesn't seem to be necessary at the moment; it has been working reliably, regardless of which combination of events occurs. If/when I come across a case where we have problems, I'll give resaving the atomic copy a go.

(Thinks some more). Ah, I think we're already doing the right thing, if I'm recalling the order of actions right. If I'm remembering correctly, prior to the atomic copy, we do hibernation prep, then after the atomic copy, hibernation cleanup. Then, if suspending to ram, we do the prep/enter/cleanup after the image has finished writing. If we lose power from suspend to ram, it doesn't matter because we're just doing a normal resume then, with the hibernation cleanup post atomic restore machine the prep that was done prior to the atomic copy.

To summarise:

Hibernate + STR + full wake.
Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
STR cleanup
Remove hibernation image

Hibernate + STR + poweroff + hibernate resume:

Quoted 10 lines

Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
<power out> or <STR wake + power off> (STR prep/enter no longer matters) (Fresh boot)
Atomic restore
Hibernation cleanup (matching prep at start)
Remove hibernation image

Yes, I think that this is the right ordering, but for some graphics adapters we need to do some tricks from the user space before 'STR prep' and after 'STR cleanup', which is theoretically possible with uswsusp.

Greetings,
Rafael

Signature · 1 line
"Premature optimization is the root of all evil." - Donald Knuth
#56 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

Hi.

Quoted 5 lines · On Wednesday 11 July 2007 20:09:04 Rafael J. Wysocki wrote:
Quoted 4 lines · Nigel Cunningham
Quoted 3 lines · On Wednesday 11 July 2007 11:59:48 Matthew Garrett wrote:
Quoted 1 line · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to

ram

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image,

then

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

suspend to ram, wake and continue working without running running out

of

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run

the

Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 1 line

pm_ops->finish after doing the atomic restore when resuming the image.

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Quoted 6 lines
Quoted 6 lines

Yeah, we could redo and resave the atomic copy, but it doesn't seem to be necessary at the moment; it has been working reliably, regardless of which combination of events occurs. If/when I come across a case where we have problems, I'll give resaving the atomic copy a go.

(Thinks some more). Ah, I think we're already doing the right thing, if

I'm

Quoted 1 line
Quoted 1 line

recalling the order of actions right. If I'm remembering correctly, prior

to

Quoted 2 lines
Quoted 2 lines

the atomic copy, we do hibernation prep, then after the atomic copy, hibernation cleanup. Then, if suspending to ram, we do the

prep/enter/cleanup

Quoted 1 line
Quoted 1 line

after the image has finished writing. If we lose power from suspend to

ram,

Quoted 2 lines
Quoted 2 lines

it doesn't matter because we're just doing a normal resume then, with the hibernation cleanup post atomic restore machine the prep that was done

prior

Quoted 26 lines
Quoted 15 lines

to the atomic copy.

To summarise:

Hibernate + STR + full wake.
Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
STR cleanup
Remove hibernation image

Hibernate + STR + poweroff + hibernate resume:

Quoted 10 lines

Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
<power out> or <STR wake + power off> (STR prep/enter no longer matters) (Fresh boot)
Atomic restore
Hibernation cleanup (matching prep at start)
Remove hibernation image

Quoted 3 lines

Yes, I think that this is the right ordering, but for some graphics adapters we need to do some tricks from the user space before 'STR prep' and after 'STR cleanup', which is theoretically possible with uswsusp.

Yeah. I haven't done it yet, but intend to implement that using userui.

Regards,

Nigel

Signature · 5 lines
Nigel Cunningham
Christian Reformed Church of Cobden
103 Curdie Street, Cobden 3266, Victoria, Australia
Ph. +61 3 5595 1185 / +61 417 100 574
Communal Worship: 11 am Sunday.
#57 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

Quoted 68 lines · Nigel Cunningham

Hi.

Quoted 5 lines · On Wednesday 11 July 2007 20:09:04 Rafael J. Wysocki wrote:
Quoted 4 lines · Nigel Cunningham
Quoted 3 lines · On Wednesday 11 July 2007 11:59:48 Matthew Garrett wrote:
Quoted 1 line · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to

ram

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image,

then

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

suspend to ram, wake and continue working without running running out

of

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run

the

Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 1 line

pm_ops->finish after doing the atomic restore when resuming the image.

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Quoted 6 lines
Quoted 6 lines

Yeah, we could redo and resave the atomic copy, but it doesn't seem to be necessary at the moment; it has been working reliably, regardless of which combination of events occurs. If/when I come across a case where we have problems, I'll give resaving the atomic copy a go.

(Thinks some more). Ah, I think we're already doing the right thing, if

I'm

Quoted 1 line
Quoted 1 line

recalling the order of actions right. If I'm remembering correctly, prior

to

Quoted 2 lines
Quoted 2 lines

the atomic copy, we do hibernation prep, then after the atomic copy, hibernation cleanup. Then, if suspending to ram, we do the

prep/enter/cleanup

Quoted 1 line
Quoted 1 line

after the image has finished writing. If we lose power from suspend to

ram,

Quoted 2 lines
Quoted 2 lines

it doesn't matter because we're just doing a normal resume then, with the hibernation cleanup post atomic restore machine the prep that was done

prior

Quoted 26 lines
Quoted 25 lines

to the atomic copy.

To summarise:

Hibernate + STR + full wake.
Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
STR cleanup
Remove hibernation image

Hibernate + STR + poweroff + hibernate resume:

Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
<power out> or <STR wake + power off> (STR prep/enter no longer matters) (Fresh boot)
Atomic restore
Hibernation cleanup (matching prep at start)
Remove hibernation image

Quoted 5 lines
Quoted 3 lines

Yes, I think that this is the right ordering, but for some graphics adapters we need to do some tricks from the user space before 'STR prep' and after 'STR cleanup', which is theoretically possible with uswsusp.

Yeah. I haven't done it yet, but intend to implement that using userui.

I thought of a hibernation daemon that could communicate with the hibernation thread via sysfs/kevent or something like this.

Greetings,
Rafael

Signature · 1 line
"Premature optimization is the root of all evil." - Donald Knuth
#58 lore raw

Re: Re: Hibernate after alarm wakes from STR

In reply to Nigel Cunningham
Quoted 68 lines · Nigel Cunningham

Hi.

Quoted 5 lines · On Wednesday 11 July 2007 20:09:04 Rafael J. Wysocki wrote:
Quoted 4 lines · Nigel Cunningham
Quoted 3 lines · On Wednesday 11 July 2007 11:59:48 Matthew Garrett wrote:
Quoted 1 line · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to

ram

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image,

then

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

suspend to ram, wake and continue working without running running out

of

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run

the

Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 1 line

pm_ops->finish after doing the atomic restore when resuming the image.

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Quoted 6 lines
Quoted 6 lines

Yeah, we could redo and resave the atomic copy, but it doesn't seem to be necessary at the moment; it has been working reliably, regardless of which combination of events occurs. If/when I come across a case where we have problems, I'll give resaving the atomic copy a go.

(Thinks some more). Ah, I think we're already doing the right thing, if

I'm

Quoted 1 line
Quoted 1 line

recalling the order of actions right. If I'm remembering correctly, prior

to

Quoted 2 lines
Quoted 2 lines

the atomic copy, we do hibernation prep, then after the atomic copy, hibernation cleanup. Then, if suspending to ram, we do the

prep/enter/cleanup

Quoted 1 line
Quoted 1 line

after the image has finished writing. If we lose power from suspend to

ram,

Quoted 2 lines
Quoted 2 lines

it doesn't matter because we're just doing a normal resume then, with the hibernation cleanup post atomic restore machine the prep that was done

prior

Quoted 26 lines
Quoted 25 lines

to the atomic copy.

To summarise:

Hibernate + STR + full wake.
Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
STR cleanup
Remove hibernation image

Hibernate + STR + poweroff + hibernate resume:

Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
<power out> or <STR wake + power off> (STR prep/enter no longer matters) (Fresh boot)
Atomic restore
Hibernation cleanup (matching prep at start)
Remove hibernation image

Quoted 5 lines
Quoted 3 lines

Yes, I think that this is the right ordering, but for some graphics adapters we need to do some tricks from the user space before 'STR prep' and after 'STR cleanup', which is theoretically possible with uswsusp.

Yeah. I haven't done it yet, but intend to implement that using userui.

I thought of a hibernation daemon that could communicate with the hibernation thread via sysfs/kevent or something like this.

Greetings,
Rafael

Signature · 1 line
"Premature optimization is the root of all evil." - Donald Knuth
#59 lore raw

Re: Re: Hibernate after alarm wakes from STR

In reply to Rafael J. Wysocki

Hi.

Quoted 5 lines · On Wednesday 11 July 2007 20:09:04 Rafael J. Wysocki wrote:
Quoted 4 lines · Nigel Cunningham
Quoted 3 lines · On Wednesday 11 July 2007 11:59:48 Matthew Garrett wrote:
Quoted 1 line · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to

ram

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image,

then

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

suspend to ram, wake and continue working without running running out

of

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run

the

Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 1 line

pm_ops->finish after doing the atomic restore when resuming the image.

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Quoted 6 lines
Quoted 6 lines

Yeah, we could redo and resave the atomic copy, but it doesn't seem to be necessary at the moment; it has been working reliably, regardless of which combination of events occurs. If/when I come across a case where we have problems, I'll give resaving the atomic copy a go.

(Thinks some more). Ah, I think we're already doing the right thing, if

I'm

Quoted 1 line
Quoted 1 line

recalling the order of actions right. If I'm remembering correctly, prior

to

Quoted 2 lines
Quoted 2 lines

the atomic copy, we do hibernation prep, then after the atomic copy, hibernation cleanup. Then, if suspending to ram, we do the

prep/enter/cleanup

Quoted 1 line
Quoted 1 line

after the image has finished writing. If we lose power from suspend to

ram,

Quoted 2 lines
Quoted 2 lines

it doesn't matter because we're just doing a normal resume then, with the hibernation cleanup post atomic restore machine the prep that was done

prior

Quoted 26 lines
Quoted 15 lines

to the atomic copy.

To summarise:

Hibernate + STR + full wake.
Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
STR cleanup
Remove hibernation image

Hibernate + STR + poweroff + hibernate resume:

Quoted 10 lines

Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
<power out> or <STR wake + power off> (STR prep/enter no longer matters) (Fresh boot)
Atomic restore
Hibernation cleanup (matching prep at start)
Remove hibernation image

Quoted 3 lines

Yes, I think that this is the right ordering, but for some graphics adapters we need to do some tricks from the user space before 'STR prep' and after 'STR cleanup', which is theoretically possible with uswsusp.

Yeah. I haven't done it yet, but intend to implement that using userui.

Regards,

Nigel

Signature · 5 lines
Nigel Cunningham
Christian Reformed Church of Cobden
103 Curdie Street, Cobden 3266, Victoria, Australia
Ph. +61 3 5595 1185 / +61 417 100 574
Communal Worship: 11 am Sunday.
#60 lore raw

Re: Re: Hibernate after alarm wakes from STR

In reply to Nigel Cunningham

Hi,

Quoted 46 lines · Nigel Cunningham

Hi.

Quoted 10 lines · On Wednesday 11 July 2007 11:59:48 Matthew Garrett wrote:
Quoted 7 lines · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to ram platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image, then suspend to ram, wake and continue working without running running out of battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run the pm_ops->finish after doing the atomic restore when resuming the image.

Quoted 5 lines

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Yeah, we could redo and resave the atomic copy, but it doesn't seem to be necessary at the moment; it has been working reliably, regardless of which combination of events occurs. If/when I come across a case where we have problems, I'll give resaving the atomic copy a go.

(Thinks some more). Ah, I think we're already doing the right thing, if I'm recalling the order of actions right. If I'm remembering correctly, prior to the atomic copy, we do hibernation prep, then after the atomic copy, hibernation cleanup. Then, if suspending to ram, we do the prep/enter/cleanup after the image has finished writing. If we lose power from suspend to ram, it doesn't matter because we're just doing a normal resume then, with the hibernation cleanup post atomic restore machine the prep that was done prior to the atomic copy.

To summarise:

Hibernate + STR + full wake.
Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
STR cleanup
Remove hibernation image

Hibernate + STR + poweroff + hibernate resume:

Quoted 10 lines

Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
<power out> or <STR wake + power off> (STR prep/enter no longer matters) (Fresh boot)
Atomic restore
Hibernation cleanup (matching prep at start)
Remove hibernation image

Yes, I think that this is the right ordering, but for some graphics adapters we need to do some tricks from the user space before 'STR prep' and after 'STR cleanup', which is theoretically possible with uswsusp.

Greetings,
Rafael

Signature · 1 line
"Premature optimization is the root of all evil." - Donald Knuth
#61 lore raw

Re: Re: Hibernate after alarm wakes from STR

In reply to Matthew Garrett

Hi.

Quoted 10 lines · On Wednesday 11 July 2007 11:59:48 Matthew Garrett wrote:
Quoted 7 lines · Nigel Cunningham

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to ram platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image, then suspend to ram, wake and continue working without running running out of battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run the pm_ops->finish after doing the atomic restore when resuming the image.

Quoted 5 lines

I'm not convinced this can work terribly well. It's not unlikely that hardware will need different state stored over different types of suspend. Can you separate out the saving of kernel memory and userspace memory, then resume/suspend/save the new kernel state without touching the userspace state?

Yeah, we could redo and resave the atomic copy, but it doesn't seem to be necessary at the moment; it has been working reliably, regardless of which combination of events occurs. If/when I come across a case where we have problems, I'll give resaving the atomic copy a go.

(Thinks some more). Ah, I think we're already doing the right thing, if I'm recalling the order of actions right. If I'm remembering correctly, prior to the atomic copy, we do hibernation prep, then after the atomic copy, hibernation cleanup. Then, if suspending to ram, we do the prep/enter/cleanup after the image has finished writing. If we lose power from suspend to ram, it doesn't matter because we're just doing a normal resume then, with the hibernation cleanup post atomic restore machine the prep that was done prior to the atomic copy.

To summarise:

Hibernate + STR + full wake.
Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
STR cleanup
Remove hibernation image

Hibernate + STR + poweroff + hibernate resume:

Hibernation prep
(Atomic copy)
Hibernation cleanup
STR prep
STR enter
<power out> or <STR wake + power off> (STR prep/enter no longer matters) (Fresh boot)
Atomic restore
Hibernation cleanup (matching prep at start)
Remove hibernation image

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#62 lore raw

Re: Re: Hibernate after alarm wakes from STR

In reply to Matthew Garrett

Hi.

Quoted 10 lines · On Wednesday 11 July 2007 11:23:02 Matthew Garrett wrote:
Quoted 9 lines · Nigel Cunningham
Quoted 4 lines · On Wednesday 11 July 2007 10:45:50 Matthew Garrett wrote:

How are you going to shift into suspend to disk without going via userspace? It's quite plausible that people will want different configuration at that point (or, realistically, need a different set of workarounds...)

This is done after writing the image, from kernel space. We do the suspend-to-ram, and if/when we wake from that, we look at the lid switch state before removing the image. If it's still closed, the kernel code

powers

Quoted 6 lines
Quoted 2 lines

down again (this time properly) without userspace ever seeing the light of day.

Yes. I'm sort of struggling to see how this is done especially reliably
- if we have separate hibernation and suspend to ram pathways, which is executed in this scenario?

Yeah, that is a bit confusing. At the moment, I'm doing the suspend to ram platform dependent preparation and cleanup in this scenario. That's definitely the right thing to do in the case where we write an image, then suspend to ram, wake and continue working without running running out of battery (writing the image is redundant in that case). Where we end up properly powering down after suspending to ram, I believe we don't run the pm_ops->finish after doing the atomic restore when resuming the image.

I haven't looked at what uswsusp does (I'm just looking at Suspend2 code above), but it will have similar issues as it also has support for suspending to ram after writing an image.

Regards,

Nigel

Signature · 5 lines
Nigel Cunningham
Christian Reformed Church of Cobden
103 Curdie Street, Cobden 3266, Victoria, Australia
Ph. +61 3 5595 1185 / +61 417 100 574
Communal Worship: 11 am Sunday.
#63 lore raw

Re: Re: Hibernate after alarm wakes from STR

In reply to Matthew Garrett

Hi.

Quoted 3 lines · On Wednesday 11 July 2007 10:45:50 Matthew Garrett wrote:
Quoted 2 lines · Nigel Cunningham

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the

functionality

Quoted 1 line
Quoted 1 line

without having to rely on userspace or do some sort of messy work to

figure

Quoted 6 lines
Quoted 1 line

out how to access the lid button and so on.

How are you going to shift into suspend to disk without going via userspace? It's quite plausible that people will want different configuration at that point (or, realistically, need a different set of workarounds...)

This is done after writing the image, from kernel space. We do the suspend-to-ram, and if/when we wake from that, we look at the lid switch state before removing the image. If it's still closed, the kernel code powers down again (this time properly) without userspace ever seeing the light of day.

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#64 lore raw

Re: Re: Hibernate after alarm wakes from STR

In reply to Nigel Cunningham
Quoted 4 lines · Nigel Cunningham

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the functionality without having to rely on userspace or do some sort of messy work to figure out how to access the lid button and so on.

Perhaps there should be a formal API to such buttons.

Quoted 2 lines

Re proc files, are the button files already exposed under sysfs and I just don't know? If so, I'll happily shift to using them.

ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ ls -l 
total 0
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 bus -> ../../../../bus/acpi/
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 driver -> ../../../../bus/acpi/drivers/button/
-r--r--r-- 1 root root 4096 2007-07-11 08:58 hid
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 input:event2 -> ../../../../class/input/input2/event2/
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 input:input2 -> ../../../../class/input/input2/
-r--r--r-- 1 root root 4096 2007-07-11 08:58 path
drwxr-xr-x 2 root root    0 2007-07-11 08:58 power/
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 subsystem -> ../../../../bus/acpi/
-rw-r--r-- 1 root root 4096 2007-07-11 08:58 uevent
db@ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ cat path
\_SB_.LID_
ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ 

If the generic kernel doesn't show that, then it's likely a consequence of a submitted-but-not-yet-merged patch.

- Dave

#65 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

In reply to Nigel Cunningham
Quoted 4 lines · Nigel Cunningham

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the functionality without having to rely on userspace or do some sort of messy work to figure out how to access the lid button and so on.

Perhaps there should be a formal API to such buttons.

Quoted 2 lines

Re proc files, are the button files already exposed under sysfs and I just don't know? If so, I'll happily shift to using them.

ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ ls -l 
total 0
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 bus -> ../../../../bus/acpi/
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 driver -> ../../../../bus/acpi/drivers/button/
-r--r--r-- 1 root root 4096 2007-07-11 08:58 hid
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 input:event2 -> ../../../../class/input/input2/event2/
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 input:input2 -> ../../../../class/input/input2/
-r--r--r-- 1 root root 4096 2007-07-11 08:58 path
drwxr-xr-x 2 root root    0 2007-07-11 08:58 power/
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 subsystem -> ../../../../bus/acpi/
-rw-r--r-- 1 root root 4096 2007-07-11 08:58 uevent
db@ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ cat path
\_SB_.LID_
ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ 

If the generic kernel doesn't show that, then it's likely a consequence of a submitted-but-not-yet-merged patch.

- Dave

#66 lore raw

Re: Re: Hibernate after alarm wakes from STR

Hi.

Quoted 3 lines · On Thursday 12 July 2007 02:04:33 David Brownell wrote:
Quoted 2 lines · Nigel Cunningham

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the

functionality

Quoted 1 line
Quoted 1 line

without having to rely on userspace or do some sort of messy work to

figure

Quoted 3 lines
Quoted 1 line

out how to access the lid button and so on.

Perhaps there should be a formal API to such buttons.

That would be good.

Quoted 7 lines
Quoted 2 lines

Re proc files, are the button files already exposed under sysfs and I just don't know? If so, I'll happily shift to using them.

ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ ls -l 
total 0
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 bus -> ../../../../bus/acpi/
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 

driver -> ../../../../bus/acpi/drivers/button/

Quoted 2 lines

-r--r--r-- 1 root root 4096 2007-07-11 08:58 hid
lrwxrwxrwx 1 root root 0 2007-07-11 08:58

input:event2 -> ../../../../class/input/input2/event2/

Quoted 1 line

lrwxrwxrwx 1 root root 0 2007-07-11 08:58

input:input2 -> ../../../../class/input/input2/

Quoted 3 lines

-r--r--r-- 1 root root 4096 2007-07-11 08:58 path
drwxr-xr-x 2 root root 0 2007-07-11 08:58 power/
lrwxrwxrwx 1 root root 0 2007-07-11 08:58

subsystem -> ../../../../bus/acpi/

Quoted 7 lines

-rw-r--r-- 1 root root 4096 2007-07-11 08:58 uevent

db@ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ cat path
\_SB_.LID_
ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ 

If the generic kernel doesn't show that, then it's likely a consequence of a submitted-but-not-yet-merged patch.

I have that too, but I can't seem to figure out which file contains the state of the button. Is there one?

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#67 lore raw

Re: [linux-pm] Re: Hibernate after alarm wakes from STR

In reply to David Brownell

Hi.

Quoted 3 lines · On Thursday 12 July 2007 02:04:33 David Brownell wrote:
Quoted 2 lines · Nigel Cunningham

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the

functionality

Quoted 1 line
Quoted 1 line

without having to rely on userspace or do some sort of messy work to

figure

Quoted 3 lines
Quoted 1 line

out how to access the lid button and so on.

Perhaps there should be a formal API to such buttons.

That would be good.

Quoted 7 lines
Quoted 2 lines

Re proc files, are the button files already exposed under sysfs and I just don't know? If so, I'll happily shift to using them.

ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ ls -l 
total 0
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 bus -> ../../../../bus/acpi/
lrwxrwxrwx 1 root root    0 2007-07-11 08:58 

driver -> ../../../../bus/acpi/drivers/button/

Quoted 2 lines

-r--r--r-- 1 root root 4096 2007-07-11 08:58 hid
lrwxrwxrwx 1 root root 0 2007-07-11 08:58

input:event2 -> ../../../../class/input/input2/event2/

Quoted 1 line

lrwxrwxrwx 1 root root 0 2007-07-11 08:58

input:input2 -> ../../../../class/input/input2/

Quoted 3 lines

-r--r--r-- 1 root root 4096 2007-07-11 08:58 path
drwxr-xr-x 2 root root 0 2007-07-11 08:58 power/
lrwxrwxrwx 1 root root 0 2007-07-11 08:58

subsystem -> ../../../../bus/acpi/

Quoted 7 lines

-rw-r--r-- 1 root root 4096 2007-07-11 08:58 uevent

db@ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ cat path
\_SB_.LID_
ascent:/sys/devices/acpi_system:00/device:00/PNP0C0D:00$ 

If the generic kernel doesn't show that, then it's likely a consequence of a submitted-but-not-yet-merged patch.

I have that too, but I can't seem to figure out which file contains the state of the button. Is there one?

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#68 lore raw

Re: Re: Hibernate after alarm wakes from STR

In reply to David Brownell

Hi.

Quoted 34 lines · On Wednesday 11 July 2007 02:51:03 David Brownell wrote:
Quoted 33 lines · Nigel Cunningham

Hi.

Quoted 30 lines · On Tuesday 10 July 2007 02:26:32 David Brownell wrote:
Quoted 7 lines · Marcelo Tosatti
Quoted 2 lines · David Brownell

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Actually I though I said that there would be races. Though come to think of it, one way they'd show up on a typical embedded system would be to have multiple wake IRQs pending ... you couldn't tell which one came first. (The typical case would be a single event, of course.) ACPI-ish systems would do that with GPEs and the magic "rtc woke" flag.

And then there are shared IRQ lines serving as wake sources. There could be three wake-enabled devices on that line (plus others that aren't wake-enabled); the drivers returning IRQ_HANDLED should likely be reported as having been wake sources, but not the ones returning IRQ_NONE ...

... so yes, systems might need to present multiple wake events.

Quoted 4 lines

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Quoted 8 lines
Quoted 8 lines
Quoted 6 lines

Better to have that node be a directory of links then, rather than a single link.

Note that I'm just throwing ideas out there. I suspect that in the general case it may not be easy to map from wake event to device, without infrastructure that's now missing.

FWIW, I've recently added code to Suspend2 to allow it to (optionally) set

the

Quoted 1 line
Quoted 1 line

RTC wake alarm when it's finished writing the image and check the lid

switch

Quoted 2 lines
Quoted 2 lines

when waking, entering a different sleep state if the lid switch is still closed. It achieves this by letting the user set the name of an rtc alarm

to

Quoted 2 lines
Quoted 2 lines

use (the 'rtc0' in /sys/class/rtc/rtc0/*) and of a button to use (lid/LID in /proc/acpi/button/lid/LID/*). It then opens the button directory's

state

Quoted 1 line
Quoted 1 line

file and the rtc directory's since_epoch and wakealarm files, and uses

them

Quoted 6 lines
Quoted 2 lines

to determine read the time since epoch and set the wakealarm and determine whether the lid button is still closed.

Interesting...

Quoted 1 line

I don't really like the opening /proc and /sysfs files in this way -

whatever

Quoted 6 lines
Quoted 2 lines

solution you come up with, could you consider exposing some way for kernel code to do this more neatly?

You're supposed to be able to use /sys/... files this way!

But that's not true of /proc/... files.

Yeah, the bit I consider to be ugly is opening the files from within the kernel, but it seemed to be necessary in order to provide the functionality without having to rely on userspace or do some sort of messy work to figure out how to access the lid button and so on.

Re proc files, are the button files already exposed under sysfs and I just don't know? If so, I'll happily shift to using them.

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#69 lore raw

Re: Re: Hibernate after alarm wakes from STR

In reply to David Brownell

Hi.

Quoted 28 lines · On Tuesday 10 July 2007 02:26:32 David Brownell wrote:
Quoted 7 lines · Marcelo Tosatti
Quoted 2 lines · David Brownell

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Actually I though I said that there would be races. Though come to think of it, one way they'd show up on a typical embedded system would be to have multiple wake IRQs pending ... you couldn't tell which one came first. (The typical case would be a single event, of course.) ACPI-ish systems would do that with GPEs and the magic "rtc woke" flag.

And then there are shared IRQ lines serving as wake sources. There could be three wake-enabled devices on that line (plus others that aren't wake-enabled); the drivers returning IRQ_HANDLED should likely be reported as having been wake sources, but not the ones returning IRQ_NONE ...

... so yes, systems might need to present multiple wake events.

Quoted 3 lines

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Quoted 8 lines
Quoted 1 line

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Better to have that node be a directory of links then, rather than a single link.

Note that I'm just throwing ideas out there. I suspect that in the general case it may not be easy to map from wake event to device, without infrastructure that's now missing.

FWIW, I've recently added code to Suspend2 to allow it to (optionally) set the RTC wake alarm when it's finished writing the image and check the lid switch when waking, entering a different sleep state if the lid switch is still closed. It achieves this by letting the user set the name of an rtc alarm to use (the 'rtc0' in /sys/class/rtc/rtc0/*) and of a button to use (lid/LID in /proc/acpi/button/lid/LID/*). It then opens the button directory's state file and the rtc directory's since_epoch and wakealarm files, and uses them to determine read the time since epoch and set the wakealarm and determine whether the lid button is still closed.

I don't really like the opening /proc and /sysfs files in this way - whatever solution you come up with, could you consider exposing some way for kernel code to do this more neatly?

Regards,

Nigel

Signature · 2 lines
See http://www.tuxonice.net for Howtos, FAQs, mailing
lists, wiki and bugzilla info.
#70 lore raw

Re: Hibernate after alarm wakes from STR

In reply to David Brownell
Quoted 8 lines · David Brownell
Quoted 7 lines · Marcelo Tosatti
Quoted 5 lines · David Brownell

On Sunday 08 July 2007, Richard Hughes wrote:

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

Quoted 6 lines
Quoted 3 lines

What would be a nice interface? Perhaps an additional file under /sys/devices/.../power/wakeup_fired or something (only for devices with can_wakeup set).

Better a /sys/power/wakeup_event (or whatever) that's more easily found. It could link to the device issuing the event.

As you mentioned, there might be two wakeup sources (RTC and power button for instance) or even more at the same time.

Do you think its fine to simply but the device separated by spaces in the wakeup_event file?

Sounds fine by me, but what about the one-value-per-file sysfs rule?

Quoted 9 lines
Quoted 5 lines
Quoted 2 lines

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Then you check if the any key or other wakeup event has happened other than RTC... I don't see any problem with that.

It might be best not to need to re-activate the whole system from STR though ... it ought to be possible to just power off, having already written the image to disk. Right?

Perhaps, yes...

Quoted 4 lines

Yes, there's all that stuff about how to quiesce the system properly, freezer/icebox/flamesuits/etc. Regardless, going from STR to fully operational and then hibernating would take time and energy that might not be available...

True, that needs to be taken into account.

Quoted 11 lines

- Dave

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

Is this something we can do (or should do) for OLPC and general ACPI?

I'd certainly rather see laptops doing that than what they do now:
running the battery out, and needing filesystem recovery!!

Yep.

#71 lore raw

Re: Hibernate after alarm wakes from STR

In reply to David Brownell
Quoted 13 lines · David Brownell
Quoted 6 lines · Richard Hughes
Quoted 3 lines · David Brownell

I think so ... although that's unfortunately another difference between the legacy x86-mostly code and the newer RTC framework.

(sorry for hijacking the thread)

I changed $SUBJECT ...

Quoted 2 lines

Is this the interface should stuff like HAL use to do:

Quoted 12 lines
Quoted 2 lines

* Suspend for 10 minutes
* auto wakeup and then hibernate...

That is, "Suspend-to-RAM" or "standby"? Yes, assuming that works on this particular system. Arguably that would be a direction for cpuidle to think about too, but I think alarm-driven wakeup is more ready-to-use at this point.

Quoted 3 lines

I figure we can do a suspend setting the rtc using the ioctls and then we wakeup, and HAL has to know that we woke up from the alarm rather than from a lid event or keypress.

On OLPC hibernate would be suspend-to-disk, but we haven't done any testing with that yet. It would be necessary to check for available disk space before attempting it (or reserving space perhaps?).

Quoted 3 lines

... although I don't know whether that particular distinction is made to userspace right now. ACPI provides a bit like that, and at least a few other systems can do something analagous.

Yes, we can poke at registers to find that out.

Quoted 3 lines

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

What would be a nice interface? Perhaps an additional file under /sys/devices/.../power/wakeup_fired or something (only for devices with can_wakeup set).

Quoted 2 lines

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Then you check if the any key or other wakeup event has happened other than RTC... I don't see any problem with that.

Quoted 4 lines
Quoted 1 line

Is this something we can do (or should do) for OLPC and general ACPI?

I'd certainly rather see laptops doing that than what they do now:
running the battery out, and needing filesystem recovery!!

Yep.

#72 lore raw

Re: Hibernate after alarm wakes from STR

In reply to Richard Hughes
Quoted 6 lines · Richard Hughes
Quoted 3 lines · David Brownell

I think so ... although that's unfortunately another difference between the legacy x86-mostly code and the newer RTC framework.

(sorry for hijacking the thread)

I changed $SUBJECT ...

Quoted 4 lines

Is this the interface should stuff like HAL use to do:

* Suspend for 10 minutes
* auto wakeup and then hibernate...

That is, "Suspend-to-RAM" or "standby"? Yes, assuming that works on this particular system. Arguably that would be a direction for cpuidle to think about too, but I think alarm-driven wakeup is more ready-to-use at this point.

Quoted 3 lines

I figure we can do a suspend setting the rtc using the ioctls and then we wakeup, and HAL has to know that we woke up from the alarm rather than from a lid event or keypress.

... although I don't know whether that particular distinction is made to userspace right now. ACPI provides a bit like that, and at least a few other systems can do something analagous.

That is, we may want to provide a bit more information about the specific event which triggered wakeup. I don't believe there is such an interface, in general.

Plus, the notion seems kind of racey to me. (If you press a key right while the wakealarm fires, you don't want hibernation..)

Quoted 1 line

Is this something we can do (or should do) for OLPC and general ACPI?

I'd certainly rather see laptops doing that than what they do now:
running the battery out, and needing filesystem recovery!!

- Dave

#73 lore raw

Re: rtc-cmos not supporting RTC_AIE?

In reply to David Brownell
Quoted 3 lines · David Brownell

I think so ... although that's unfortunately another difference between the legacy x86-mostly code and the newer RTC framework.

(sorry for hijacking the thread)

Is this the interface should stuff like HAL use to do:

* Suspend for 10 minutes
* auto wakeup and then hibernate.

I figure we can do a suspend setting the rtc using the ioctls and then we wakeup, and HAL has to know that we woke up from the alarm rather than from a lid event or keypress.

Is this something we can do (or should do) for OLPC and general ACPI?

Cheers guys.

Richard.

#74 lore raw

Re: rtc-cmos not supporting RTC_AIE?

In reply to Marcelo Tosatti
Quoted 15 lines · Marcelo Tosatti

My point is that RTC_ALM_SET after RTC_AIE_ON works with drivers/char/rtc.c but not rtc-cmos:

        ret = ioctl(fd, RTC_AIE_ON);
        if (ret) {
                perror("ioctl RTC_AIE_ON");
                exit(0);
        }

        ret = ioctl(fd, RTC_ALM_SET, &rtctime);
        if (ret) {
                perror("ioctl RTC_ALM_SET");
                exit(0);
        }
Quoted 1 line

I think its fine to consider such applications broken anyway?

I think so ... although that's unfortunately another difference between the legacy x86-mostly code and the newer RTC framework.

Unless enough folk strongly disagree, I'd say this is just something else to watch out for as part of converting. Not every quirk got carried forward.

- Dave

#75 lore raw

Re: rtc-cmos not supporting RTC_AIE?

In reply to David Brownell
Quoted 11 lines · David Brownell
Quoted 5 lines · Marcelo Tosatti

David,

Is there any reason why programs using RTC_AIE/RTC_ALM_SET ioctls are unable to arm alarm irq's?

The ALM_SET request never did! And I'm pretty sure AIE_ON does indeed set it ... the test cases use ALM_SET then AIE_ON, which is the "traditional" idiom (i.e. legacy drivers/char/rtc.c idiom).

My point is that RTC_ALM_SET after RTC_AIE_ON works with drivers/char/rtc.c but not rtc-cmos:

        ret = ioctl(fd, RTC_AIE_ON);
        if (ret) {
                perror("ioctl RTC_AIE_ON");
                exit(0);
        }

        ret = ioctl(fd, RTC_ALM_SET, &rtctime);
        if (ret) {
                perror("ioctl RTC_ALM_SET");
                exit(0);
        }

I think its fine to consider such applications broken anyway?

Quoted 8 lines
Quoted 2 lines

I'm aware of the new RTC_WKALM_SET... but shouldnt backward compatibility be kept?

According to <linux/rtc.h> the ALM_SET ioctl takes an rtc_time, while WKALM_SET takes an rtc_wkalm ... which differs from the former by including the flag controlling wheter the alarm will be enabled (or not) when setting the alarm. (Model inherited from EFI.)

Right.

Quoted 38 lines
Quoted 5 lines

The code seems to imply that its not supported anymore, however ioctl returns success but no alarm is fired (for instance alarm.enabled is set to 0):

Quoted 9 lines
        case RTC_ALM_SET:
                if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
                        return -EFAULT;

                alarm.enabled = 0;
                alarm.pending = 0;
                alarm.time.tm_wday = -1;
                alarm.time.tm_yday = -1;
                alarm.time.tm_isdst = -1;

That code is generic RTC framework code (rtc-dev.c), and not code specific to rtc-cmos ... the comment immediately following that (2.6.22-rc7 and previous) should clarify many of the issues.

I think the current manpage does the same. (If it mentions the /dev/rtc0, /dev/rtc1, etc files, it should be current enough.)

What it does is just stuff the rtc_time into the expanded rtc_wkalm. The idea is that the RTC drivers only support one alarm-setting method, but the /dev/rtcN ioctl interface uses it in two modes:

- "legacy", up to 24 hours in the future, and requiring the alarm to be enabled later with AIE_ON;

- "EFI-style", into the arbitrary future, and bundling the flag saying whether to enable the alarm.

Since ALM_SET is the legacy mode, it requires separate AIE_ON (from the RTC driver directly). But RTC_WKALM_SET doesn't.

- Dave

#76 lore raw

rtc-cmos not supporting RTC_AIE?

In reply to Jordan Crouse
Quoted 113 lines · Jordan Crouse
Quoted 9 lines · David Brownell
Quoted 5 lines

So, for better or worse, we are implementing a new power management manger. Here is the code:

http://dev.laptop.org/git.do?p=olpc-2.6;a=blob;h=e6e19ac32a881be962db7190f2cb460e9f60a9da;hb=powermgmt;f=arch/i386/kernel/olpc-pm.c

Does that work yet with CONFIG_NO_HZ, so that the system idle loop enters some "almost everyting is turned off" low power state? Or would that be something other than a "PM Manager"?

I think eventually we'll get into entering deeper states in the idle loop. For now, we're just going into the classic C1 / hlt state, which is actually quite thrifty on the Geode, due to automatic hardware clock gating that happens throughout the chip(s).

Quoted 16 lines
Quoted 7 lines
Quoted 6 lines
Quoted 1 line

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

Quoted 8 lines

The silicon can handle wakeups from RTC, a sleep button, a power button, 8 GPIO groups, the USB controller (covering any and all USB events), UART1, UART2, SMbus and the PIC.

OLPC really only cares about 4 of those, because our only sleep state is ~S3, and the PIC, smbus, UARTs and USB are off in S3. We also only have the power button, and all the rest of the wakeup sources come from the GPIOs.

Quoted 6 lines

So it's a slightly deeper "S3" than I've usually seen, but not by much.

And correct me if I'm wrong, but your RTC can work with "rtc-cmos", and the wake hooks I've posted (and which will be in the next MM release) sound like they'll work just fine (given OLPC-specific implementation, which is clearly not included in the code above).

Indeed, and thank you much for that work - we'll be sure to integrate it.

Quoted 10 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

I'm not saying inside ACPI - I'm saying at the driver level.

Whereas in that patch, the only ACPI calls were inside ACPI itself; and that driver only had a callback. FWIW that's the first time I've ever needed to have indirection on wakeup event handling ...

This is the first real "embedded" scenario to pop its head up in x86 land, up to this point, most of the boards have just been really weak desktops.

Quoted 4 lines
Quoted 3 lines

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

Quoted 8 lines

With AT91 (and most ARMs) the wake events are normal IRQs, and the irq infrastructure already handles wake events cleanly. So I'd claim they don't _want_ to change something that's inexpensive, already deployed (training, code, testing, etc), and working.

So I hope you'll tolerate me if I view this as less of a "how do we get a generic solution" and more of a "how does _this_ x86-ish issue get solved cleanly".

Thats fair. x86 does live in a different world then the other embedded chips. I think its reasonable for the x86 folks to get their story straight and then move on from there.

Quoted 8 lines
Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Thats fine - I am not sold on a "one call to rule them all", but I do want to avoid any #ifdef CONFIG_PM_ACPI #elsif CONFIG_OLPC_PM #else nonsense.

Quoted 15 lines
Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

My point above was that ACPI isn't yet integrating with the things it needs to be integrating with. If you're concerned about how to work with wakeup events in Linux, don't even bother looking at ACPI. Look at the embedded implementations; look at USB. AT91 is by far the cleanest and most complete (simplest hardware too!!), but some of the other systems (OMAP, PXA, SA1100, etc) also implement wakeup using board-specific code.

Quoted 3 lines

OLPC _could_ use that same "board-specific hacks" approach found in most embedded platforms. I'm glad you're thinking about how to avoid doing that.

We are keenly aware that we're committing a minor sin by implementing yet another PM interface for x86. But we believe that our heart is in the right place, and we are dedicated to doing the right thing, and trying our hardest not to contribute further to fragmenting the PM subsystem with implementation specific code. In many cases we're looking to help bring the others into the fold, especially our fellow x86 implementations that suffer from the same issues that we do.

Quoted 1 line

I appreciate your comments, and the rtc-cmos code will go to good use.

David,

Is there any reason why programs using RTC_AIE/RTC_ALM_SET ioctls are unable to arm alarm irq's?

I'm aware of the new RTC_WKALM_SET... but shouldnt backward compatibility be kept?

The code seems to imply that its not supported anymore, however ioctl returns success but no alarm is fired (for instance alarm.enabled is set to 0):

        case RTC_ALM_SET:
                if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
                        return -EFAULT;

                alarm.enabled = 0;
                alarm.pending = 0;
                alarm.time.tm_wday = -1;
                alarm.time.tm_yday = -1;
                alarm.time.tm_isdst = -1;

Thanks

#77 lore raw

PATCH 1/1 rtc-cmos: use cmos_rtc_board_info to determine wake_on callback

In reply to Jordan Crouse
Quoted 2 lines

From my understand ACPI fills a cmos_rtc_board_info with pointers for

wake_on/wake_off callbacks and registers that at dev->platform_data.

So use that to retrieve the callback pointers.

Am I missing something?

drivers/rtc/rtc-cmos.c +3 -2
index e24ea82..5bfab23 100644
@@ -549,6 +549,7 @@ #ifdef	CONFIG_PM
 static int cmos_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
+	struct cmos_rtc_board_info *board_info = dev->platform_data;
 	int		do_wake = device_may_wakeup(dev);
 	unsigned char	tmp;
 
@@ -572,8 +573,8 @@ static int cmos_suspend(struct device *d
 
 	if (tmp & RTC_AIE) {
 		cmos->enabled_wake = 1;
-		if (cmos->wake_on)
-			cmos->wake_on(dev);
+		if (board_info->wake_on)
+			board_info->wake_on(dev);
 		else
 			enable_irq_wake(cmos->irq);
 	}
#78 lore raw

Re: [PATCH] rtc-cmos: use cmos_rtc_board_info to determine wake_on callback

Quoted 7 lines · Marcelo Tosatti

From my understand ACPI fills a cmos_rtc_board_info with pointers for wake_on/wake_off callbacks and registers that at dev->platform_data.

So use that to retrieve the callback pointers.

Am I missing something?

This is retrieved already in the probe() routine, which does other board-specific setup that may be needed.

So this patch isn't needed. Or, in fact, correct ... both the wake_on() and wake_off() methods are required.

Quoted 24 lines
drivers/rtc/rtc-cmos.c +3 -2
index e24ea82..5bfab23 100644
@@ -549,6 +549,7 @@ #ifdef	CONFIG_PM
 static int cmos_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
+	struct cmos_rtc_board_info *board_info = dev->platform_data;
 	int		do_wake = device_may_wakeup(dev);
 	unsigned char	tmp;
 
@@ -572,8 +573,8 @@ static int cmos_suspend(struct device *d
 
 	if (tmp & RTC_AIE) {
 		cmos->enabled_wake = 1;
-		if (cmos->wake_on)
-			cmos->wake_on(dev);
+		if (board_info->wake_on)
+			board_info->wake_on(dev);
 		else
 			enable_irq_wake(cmos->irq);
 	}
#79 lore raw

Re: [PATCH] rtc-cmos: use cmos_rtc_board_info to determine wake_on callback

In reply to Marcelo Tosatti
Quoted 7 lines · Marcelo Tosatti

From my understand ACPI fills a cmos_rtc_board_info with pointers for wake_on/wake_off callbacks and registers that at dev->platform_data.

So use that to retrieve the callback pointers.

Am I missing something?

This is retrieved already in the probe() routine, which does other board-specific setup that may be needed.

So this patch isn't needed. Or, in fact, correct ... both the wake_on() and wake_off() methods are required.

Quoted 24 lines
drivers/rtc/rtc-cmos.c +3 -2
index e24ea82..5bfab23 100644
@@ -549,6 +549,7 @@ #ifdef	CONFIG_PM
 static int cmos_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
+	struct cmos_rtc_board_info *board_info = dev->platform_data;
 	int		do_wake = device_may_wakeup(dev);
 	unsigned char	tmp;
 
@@ -572,8 +573,8 @@ static int cmos_suspend(struct device *d
 
 	if (tmp & RTC_AIE) {
 		cmos->enabled_wake = 1;
-		if (cmos->wake_on)
-			cmos->wake_on(dev);
+		if (board_info->wake_on)
+			board_info->wake_on(dev);
 		else
 			enable_irq_wake(cmos->irq);
 	}
#80 lore raw

PATCH 1/1 rtc-cmos: use cmos_rtc_board_info to determine wake_on callback

In reply to Jordan Crouse
Quoted 2 lines

From my understand ACPI fills a cmos_rtc_board_info with pointers for

wake_on/wake_off callbacks and registers that at dev->platform_data.

So use that to retrieve the callback pointers.

Am I missing something?

drivers/rtc/rtc-cmos.c +3 -2
index e24ea82..5bfab23 100644
@@ -549,6 +549,7 @@ #ifdef	CONFIG_PM
 static int cmos_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
+	struct cmos_rtc_board_info *board_info = dev->platform_data;
 	int		do_wake = device_may_wakeup(dev);
 	unsigned char	tmp;
 
@@ -572,8 +573,8 @@ static int cmos_suspend(struct device *d
 
 	if (tmp & RTC_AIE) {
 		cmos->enabled_wake = 1;
-		if (cmos->wake_on)
-			cmos->wake_on(dev);
+		if (board_info->wake_on)
+			board_info->wake_on(dev);
 		else
 			enable_irq_wake(cmos->irq);
 	}
#81 lore raw

PATCH 1/1 OLPC rtc-cmos support

In reply to Jordan Crouse

Hi,

The following patch implements the hooks necessary for OLPC to use the rtc-cmos driver. This is necessary since we do not want CONFIG_PNP.

This makes it possible to control rtc wakeup via
/sys/devices/platform/rtc_cmos/power/wakeup.

Comments?

arch/i386/kernel/olpc-pm.c +92 -1
index 9599dbe..d92c54a 100644
@@ -11,6 +11,9 @@ #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/suspend.h>
 #include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
 #include <asm/olpc.h>
@@ -272,6 +275,8 @@ static int olpc_pm_enter(suspend_state_t
 	return 0;
 }
 
+static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
+
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -282,7 +287,7 @@ int asmlinkage olpc_do_sleep(u8 sleep_st
 
 	/* FIXME:  Set any other SCI events that we might want here */
 
-	outl((CS5536_PM_PWRBTN << 16) | 0xFFFF, acpi_base + PM1_STS);
+	outl((olpc_wakeup_mask << 16) | 0xFFFF, acpi_base + PM1_STS);
 
 	/* If we are in test mode, then just return (simulate a successful
 	   suspend/resume).  Otherwise, if we are doing the real thing,
@@ -549,6 +554,92 @@ static int __init olpc_pm_init(void)
 	return 0;
 }
 
+
+#if defined (CONFIG_RTC_DRV_CMOS) || defined (CONFIG_RTC_DRV_CMOS_MODULE)
+struct resource rtc_platform_resource[2] = {
+	{
+		.flags		= IORESOURCE_IO,
+		.start		= RTC_PORT(0),
+		.end		= RTC_PORT(0) + RTC_IO_EXTENT
+	},
+	{
+		.flags = IORESOURCE_IRQ,
+		.start = 8,
+		.end = 8,
+	},
+};
+
+struct resource rtc_platform_irq = {
+	.flags = IORESOURCE_IRQ,
+	.start = 8,
+	.end = 8,
+};
+
+static int olpc_add_rtc(void)
+{
+	struct platform_device *pd;
+
+	pd = platform_device_register_simple("rtc_cmos", -1,
+					     rtc_platform_resource, 2);
+	if (IS_ERR(pd)) 
+		return PTR_ERR(pd);
+
+	/* rtc-cmos only supports 24-hr mode */
+	CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_24H, RTC_CONTROL);
+
+	return 0;
+}
+arch_initcall(olpc_add_rtc);
+
+static struct cmos_rtc_board_info rtc_info;
+
+static void rtc_wake_on(struct device *dev)
+{
+	olpc_wakeup_mask |= CS5536_PM_RTC;
+}
+
+static void rtc_wake_off(struct device *dev)
+{
+	olpc_wakeup_mask &= ~(CS5536_PM_RTC);
+}
+
+static int rtc_match(struct device *dev, void *data)
+{
+	static const char *devname = { "rtc_cmos" };
+	struct rtc_device *rtcdev = to_rtc_device(dev);
+
+	if (!strcmp(devname, rtcdev->name))
+		return 1;
+
+	return 0;
+}
+
+static struct device * get_rtc_dev(void)
+{
+        return bus_find_device(&platform_bus_type, NULL, NULL, rtc_match);
+}
+
+static int olpc_rtc_init(void)
+{
+	struct device *dev = get_rtc_dev();
+
+	if (dev) {
+		rtc_info.rtc_day_alarm = 0;
+		rtc_info.rtc_mon_alarm = 0;
+		rtc_info.rtc_century = 0;
+		rtc_info.wake_on = rtc_wake_on;
+		rtc_info.wake_off = rtc_wake_off;
+
+		dev->platform_data = &rtc_info;
+
+		device_init_wakeup(dev, 1);
+	} else 
+		printk(KERN_ERR "no rtc\n");
+	return 0;
+}
+fs_initcall(olpc_rtc_init);
+#endif /* CONFIG_RTC_DRV_CMOS */
+
 static void olpc_pm_exit(void)
 {
 	/* Clear any pending events, and disable them */
#82 lore raw

Re: [PATCH] OLPC rtc-cmos support

Quoted 10 lines · Marcelo Tosatti

Hi,

The following patch implements the hooks necessary for OLPC to use the rtc-cmos driver. This is necessary since we do not want CONFIG_PNP.

This makes it possible to control rtc wakeup via
/sys/devices/platform/rtc_cmos/power/wakeup.

Comments?

Looks almost right ... though I'd have expected the RTC to support alarms more than just 24 hours into the future!

It's more complicated than necessary. It'd be much simpler to just declare a static platform_device with pre-initted platform_data. Then call device_init_wakeup() on that before calling the usual platform_device_register() routine.

That way you wouldn't need to have two different init sections just to set up one device, where one of them is spending most of its time working around the possibility that the other one failed. And you'd also pretty much eliminate the possibility that the (now) single init section fails. :)

- Dave

#83 lore raw

Re: [PATCH] OLPC rtc-cmos support

In reply to Marcelo Tosatti
Quoted 10 lines · Marcelo Tosatti

Hi,

The following patch implements the hooks necessary for OLPC to use the rtc-cmos driver. This is necessary since we do not want CONFIG_PNP.

This makes it possible to control rtc wakeup via
/sys/devices/platform/rtc_cmos/power/wakeup.

Comments?

Looks almost right ... though I'd have expected the RTC to support alarms more than just 24 hours into the future!

It's more complicated than necessary. It'd be much simpler to just declare a static platform_device with pre-initted platform_data. Then call device_init_wakeup() on that before calling the usual platform_device_register() routine.

That way you wouldn't need to have two different init sections just to set up one device, where one of them is spending most of its time working around the possibility that the other one failed. And you'd also pretty much eliminate the possibility that the (now) single init section fails. :)

- Dave

#84 lore raw

Re: [PATCH] OLPC rtc-cmos support

Quoted 20 lines · David Brownell
Quoted 10 lines · Marcelo Tosatti

Hi,

The following patch implements the hooks necessary for OLPC to use the rtc-cmos driver. This is necessary since we do not want CONFIG_PNP.

This makes it possible to control rtc wakeup via
/sys/devices/platform/rtc_cmos/power/wakeup.

Comments?

Looks almost right ... though I'd have expected the RTC to support alarms more than just 24 hours into the future!

It's more complicated than necessary. It'd be much simpler to just declare a static platform_device with pre-initted platform_data. Then call device_init_wakeup() on that before calling the usual platform_device_register() routine.

Quoted 5 lines

That way you wouldn't need to have two different init sections just to set up one device, where one of them is spending most of its time working around the possibility that the other one failed. And you'd also pretty much eliminate the possibility that the (now) single init section fails. :)

David,

Like this?

arch/i386/kernel/olpc-pm.c +65 -1
index 9599dbe..8072e68 100644
@@ -11,6 +11,9 @@ #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/suspend.h>
 #include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
 #include <asm/olpc.h>
@@ -272,6 +275,8 @@ static int olpc_pm_enter(suspend_state_t
 	return 0;
 }
 
+static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
+
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -282,7 +287,7 @@ int asmlinkage olpc_do_sleep(u8 sleep_st
 
 	/* FIXME:  Set any other SCI events that we might want here */
 
-	outl((CS5536_PM_PWRBTN << 16) | 0xFFFF, acpi_base + PM1_STS);
+	outl((olpc_wakeup_mask << 16) | 0xFFFF, acpi_base + PM1_STS);
 
 	/* If we are in test mode, then just return (simulate a successful
 	   suspend/resume).  Otherwise, if we are doing the real thing,
@@ -549,6 +554,65 @@ static int __init olpc_pm_init(void)
 	return 0;
 }
 
+
+#if defined (CONFIG_RTC_DRV_CMOS) || defined (CONFIG_RTC_DRV_CMOS_MODULE)
+struct resource rtc_platform_resource[2] = {
+	{
+		.flags		= IORESOURCE_IO,
+		.start		= RTC_PORT(0),
+		.end		= RTC_PORT(0) + RTC_IO_EXTENT
+	},
+	{
+		.flags = IORESOURCE_IRQ,
+		.start = 8,
+		.end = 8,
+	},
+};
+
+
+static struct cmos_rtc_board_info rtc_info;
+
+struct platform_device olpc_rtc_device = {
+	.name = "rtc_cmos",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(rtc_platform_resource),
+	.dev.platform_data = &rtc_info,
+	.resource = rtc_platform_resource,
+};
+
+struct resource rtc_platform_irq = {
+	.flags = IORESOURCE_IRQ,
+	.start = 8,
+	.end = 8,
+};
+
+static void rtc_wake_on(struct device *dev)
+{
+	olpc_wakeup_mask |= CS5536_PM_RTC;
+}
+
+static void rtc_wake_off(struct device *dev)
+{
+	olpc_wakeup_mask &= ~(CS5536_PM_RTC);
+}
+
+static int olpc_rtc_init(void)
+{
+	rtc_info.rtc_day_alarm = 0;
+	rtc_info.rtc_mon_alarm = 0;
+	rtc_info.rtc_century = 0;
+	rtc_info.wake_on = rtc_wake_on;
+	rtc_info.wake_off = rtc_wake_off;
+
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);
+
+	return 0;
+}
+fs_initcall(olpc_rtc_init);
+#endif /* CONFIG_RTC_DRV_CMOS */
+
 static void olpc_pm_exit(void)
 {
 	/* Clear any pending events, and disable them */
#85 lore raw

Re: [PATCH] OLPC rtc-cmos support

Quoted 1 line · Marcelo Tosatti

Like this?

Not quite ...

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 587

Quoted 5 lines
arch/i386/kernel/olpc-pm.c +5 -0
+struct resource rtc_platform_irq = {
+	.flags = IORESOURCE_IRQ,
+	.start = 8,
+	.end = 8,
+};

Unused, right?

Quoted 1 line

+static int olpc_rtc_init(void)

... should be marked __init ...

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 605

Quoted 6 lines
arch/i386/kernel/olpc-pm.c +6 -0
+{
+	rtc_info.rtc_day_alarm = 0;
+	rtc_info.rtc_mon_alarm = 0;
+	rtc_info.rtc_century = 0;
+	rtc_info.wake_on = rtc_wake_on;
+	rtc_info.wake_off = rtc_wake_off;

... that can all just be static init ...

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 609

Quoted 4 lines
arch/i386/kernel/olpc-pm.c +4 -0
+
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);

... do the init_wakeup before registering the device, so there can never be confusion about whether a probe() will see that part of device config ...

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 613

Quoted 4 lines
arch/i386/kernel/olpc-pm.c +4 -0
+
+	return 0;
+}
+fs_initcall(olpc_rtc_init);

... and try to register platform devices in arch_initcall(). Just to avoid potential confusion; that's where it's normally done, and I don't think you had a need to do it elsewhere.

- Dave

Quoted 6 lines
arch/i386/kernel/olpc-pm.c +2 -0
+#endif /* CONFIG_RTC_DRV_CMOS */
+
 static void olpc_pm_exit(void)
 {
 	/* Clear any pending events, and disable them */
#86 lore raw

Re: [PATCH] OLPC rtc-cmos support

Quoted 29 lines · David Brownell
Quoted 1 line · Marcelo Tosatti

Like this?

Not quite ...

Review

Quoted 5 lines
(quoted diff) +5 -0
+struct resource rtc_platform_irq = {
+	.flags = IORESOURCE_IRQ,
+	.start = 8,
+	.end = 8,
+};

Unused, right?

Quoted 1 line

+static int olpc_rtc_init(void)

... should be marked __init ...

Review

Quoted 6 lines
(quoted diff) +6 -0
+{
+	rtc_info.rtc_day_alarm = 0;
+	rtc_info.rtc_mon_alarm = 0;
+	rtc_info.rtc_century = 0;
+	rtc_info.wake_on = rtc_wake_on;
+	rtc_info.wake_off = rtc_wake_off;

... that can all just be static init ...

Quoted 8 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);

... do the init_wakeup before registering the device, so there can never be confusion about whether a probe() will see that part of device config ...

For some reason doing things in that order causes wake_on/wake_off to not be called...

Thanks again for the comments.

arch/i386/kernel/olpc-pm.c +59 -1
index 9599dbe..474be1a 100644
@@ -11,6 +11,9 @@ #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/suspend.h>
 #include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
 #include <asm/olpc.h>
@@ -272,6 +275,8 @@ static int olpc_pm_enter(suspend_state_t
 	return 0;
 }
 
+static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
+
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -282,7 +287,7 @@ int asmlinkage olpc_do_sleep(u8 sleep_st
 
 	/* FIXME:  Set any other SCI events that we might want here */
 
-	outl((CS5536_PM_PWRBTN << 16) | 0xFFFF, acpi_base + PM1_STS);
+	outl((olpc_wakeup_mask << 16) | 0xFFFF, acpi_base + PM1_STS);
 
 	/* If we are in test mode, then just return (simulate a successful
 	   suspend/resume).  Otherwise, if we are doing the real thing,
@@ -549,6 +554,59 @@ static int __init olpc_pm_init(void)
 	return 0;
 }
 
+
+#if defined (CONFIG_RTC_DRV_CMOS) || defined (CONFIG_RTC_DRV_CMOS_MODULE)
+struct resource rtc_platform_resource[2] = {
+	{
+		.flags		= IORESOURCE_IO,
+		.start		= RTC_PORT(0),
+		.end		= RTC_PORT(0) + RTC_IO_EXTENT
+	},
+	{
+		.flags = IORESOURCE_IRQ,
+		.start = 8,
+		.end = 8,
+	},
+};
+
+
+static void rtc_wake_on(struct device *dev)
+{
+	olpc_wakeup_mask |= CS5536_PM_RTC;
+}
+
+static void rtc_wake_off(struct device *dev)
+{
+	olpc_wakeup_mask &= ~(CS5536_PM_RTC);
+}
+
+static struct cmos_rtc_board_info rtc_info = {
+	.rtc_day_alarm = 0,
+	.rtc_mon_alarm = 0,
+	.rtc_century = 0,
+	.wake_on = rtc_wake_on,
+	.wake_off = rtc_wake_off,
+};
+
+struct platform_device olpc_rtc_device = {
+	.name = "rtc_cmos",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(rtc_platform_resource),
+	.dev.platform_data = &rtc_info,
+	.resource = rtc_platform_resource,
+};
+
+static int __init olpc_rtc_init(void)
+{
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);
+
+	return 0;
+}
+arch_initcall(olpc_rtc_init);
+#endif /* CONFIG_RTC_DRV_CMOS */
+
 static void olpc_pm_exit(void)
 {
 	/* Clear any pending events, and disable them */
#87 lore raw

Re: [PATCH] OLPC rtc-cmos support

Quoted 11 lines
Quoted 8 lines

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 603

Quoted 4 lines
arch/i386/kernel/olpc-pm.c +3 -0
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);

... do the init_wakeup before registering the device, so there can never be confusion about whether a probe() will see that part of device config ...

For some reason doing things in that order causes wake_on/wake_off to not be called...

I see ... because platform_device_register() will device_initialize() which clobbers that state, before doing platform_device_add(). I wonder what bugs are lurking thereby. :(

Quoted 1 line

Thanks again for the comments.

This last version looks clean and OK, so long as the driver registers after that arch_initcall().

Really, no day field in the alarm for that particular southbridge? Too bad. And a bit surprising ... I thought current versions of ACPI required the up-to-one-month enhancement to mc146818.

- Dave

#88 lore raw

Re: [PATCH] OLPC rtc-cmos support

In reply to Marcelo Tosatti
Quoted 11 lines
Quoted 8 lines

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 603

Quoted 4 lines
arch/i386/kernel/olpc-pm.c +3 -0
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);

... do the init_wakeup before registering the device, so there can never be confusion about whether a probe() will see that part of device config ...

For some reason doing things in that order causes wake_on/wake_off to not be called...

I see ... because platform_device_register() will device_initialize() which clobbers that state, before doing platform_device_add(). I wonder what bugs are lurking thereby. :(

Quoted 1 line

Thanks again for the comments.

This last version looks clean and OK, so long as the driver registers after that arch_initcall().

Really, no day field in the alarm for that particular southbridge? Too bad. And a bit surprising ... I thought current versions of ACPI required the up-to-one-month enhancement to mc146818.

- Dave

#89 lore raw

Re: [PATCH] OLPC rtc-cmos support

In reply to David Brownell
Quoted 29 lines · David Brownell
Quoted 1 line · Marcelo Tosatti

Like this?

Not quite ...

Review

Quoted 5 lines
(quoted diff) +5 -0
+struct resource rtc_platform_irq = {
+	.flags = IORESOURCE_IRQ,
+	.start = 8,
+	.end = 8,
+};

Unused, right?

Quoted 1 line

+static int olpc_rtc_init(void)

... should be marked __init ...

Review

Quoted 6 lines
(quoted diff) +6 -0
+{
+	rtc_info.rtc_day_alarm = 0;
+	rtc_info.rtc_mon_alarm = 0;
+	rtc_info.rtc_century = 0;
+	rtc_info.wake_on = rtc_wake_on;
+	rtc_info.wake_off = rtc_wake_off;

... that can all just be static init ...

Quoted 8 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);

... do the init_wakeup before registering the device, so there can never be confusion about whether a probe() will see that part of device config ...

For some reason doing things in that order causes wake_on/wake_off to not be called...

Thanks again for the comments.

arch/i386/kernel/olpc-pm.c +59 -1
index 9599dbe..474be1a 100644
@@ -11,6 +11,9 @@ #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/suspend.h>
 #include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
 #include <asm/olpc.h>
@@ -272,6 +275,8 @@ static int olpc_pm_enter(suspend_state_t
 	return 0;
 }
 
+static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
+
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -282,7 +287,7 @@ int asmlinkage olpc_do_sleep(u8 sleep_st
 
 	/* FIXME:  Set any other SCI events that we might want here */
 
-	outl((CS5536_PM_PWRBTN << 16) | 0xFFFF, acpi_base + PM1_STS);
+	outl((olpc_wakeup_mask << 16) | 0xFFFF, acpi_base + PM1_STS);
 
 	/* If we are in test mode, then just return (simulate a successful
 	   suspend/resume).  Otherwise, if we are doing the real thing,
@@ -549,6 +554,59 @@ static int __init olpc_pm_init(void)
 	return 0;
 }
 
+
+#if defined (CONFIG_RTC_DRV_CMOS) || defined (CONFIG_RTC_DRV_CMOS_MODULE)
+struct resource rtc_platform_resource[2] = {
+	{
+		.flags		= IORESOURCE_IO,
+		.start		= RTC_PORT(0),
+		.end		= RTC_PORT(0) + RTC_IO_EXTENT
+	},
+	{
+		.flags = IORESOURCE_IRQ,
+		.start = 8,
+		.end = 8,
+	},
+};
+
+
+static void rtc_wake_on(struct device *dev)
+{
+	olpc_wakeup_mask |= CS5536_PM_RTC;
+}
+
+static void rtc_wake_off(struct device *dev)
+{
+	olpc_wakeup_mask &= ~(CS5536_PM_RTC);
+}
+
+static struct cmos_rtc_board_info rtc_info = {
+	.rtc_day_alarm = 0,
+	.rtc_mon_alarm = 0,
+	.rtc_century = 0,
+	.wake_on = rtc_wake_on,
+	.wake_off = rtc_wake_off,
+};
+
+struct platform_device olpc_rtc_device = {
+	.name = "rtc_cmos",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(rtc_platform_resource),
+	.dev.platform_data = &rtc_info,
+	.resource = rtc_platform_resource,
+};
+
+static int __init olpc_rtc_init(void)
+{
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);
+
+	return 0;
+}
+arch_initcall(olpc_rtc_init);
+#endif /* CONFIG_RTC_DRV_CMOS */
+
 static void olpc_pm_exit(void)
 {
 	/* Clear any pending events, and disable them */
#90 lore raw

Re: [PATCH] OLPC rtc-cmos support

In reply to Marcelo Tosatti
Quoted 1 line · Marcelo Tosatti

Like this?

Not quite ...

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 587

Quoted 5 lines
arch/i386/kernel/olpc-pm.c +5 -0
+struct resource rtc_platform_irq = {
+	.flags = IORESOURCE_IRQ,
+	.start = 8,
+	.end = 8,
+};

Unused, right?

Quoted 1 line

+static int olpc_rtc_init(void)

... should be marked __init ...

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 605

Quoted 6 lines
arch/i386/kernel/olpc-pm.c +6 -0
+{
+	rtc_info.rtc_day_alarm = 0;
+	rtc_info.rtc_mon_alarm = 0;
+	rtc_info.rtc_century = 0;
+	rtc_info.wake_on = rtc_wake_on;
+	rtc_info.wake_off = rtc_wake_off;

... that can all just be static init ...

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 609

Quoted 4 lines
arch/i386/kernel/olpc-pm.c +4 -0
+
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);

... do the init_wakeup before registering the device, so there can never be confusion about whether a probe() will see that part of device config ...

arch/i386/kernel/olpc-pm.c static int __init olpc_pm_init(void) · line 613

Quoted 4 lines
arch/i386/kernel/olpc-pm.c +4 -0
+
+	return 0;
+}
+fs_initcall(olpc_rtc_init);

... and try to register platform devices in arch_initcall(). Just to avoid potential confusion; that's where it's normally done, and I don't think you had a need to do it elsewhere.

- Dave

Quoted 6 lines
arch/i386/kernel/olpc-pm.c +2 -0
+#endif /* CONFIG_RTC_DRV_CMOS */
+
 static void olpc_pm_exit(void)
 {
 	/* Clear any pending events, and disable them */
#91 lore raw

Re: [PATCH] OLPC rtc-cmos support

In reply to David Brownell
Quoted 20 lines · David Brownell
Quoted 10 lines · Marcelo Tosatti

Hi,

The following patch implements the hooks necessary for OLPC to use the rtc-cmos driver. This is necessary since we do not want CONFIG_PNP.

This makes it possible to control rtc wakeup via
/sys/devices/platform/rtc_cmos/power/wakeup.

Comments?

Looks almost right ... though I'd have expected the RTC to support alarms more than just 24 hours into the future!

It's more complicated than necessary. It'd be much simpler to just declare a static platform_device with pre-initted platform_data. Then call device_init_wakeup() on that before calling the usual platform_device_register() routine.

Quoted 5 lines

That way you wouldn't need to have two different init sections just to set up one device, where one of them is spending most of its time working around the possibility that the other one failed. And you'd also pretty much eliminate the possibility that the (now) single init section fails. :)

David,

Like this?

arch/i386/kernel/olpc-pm.c +65 -1
index 9599dbe..8072e68 100644
@@ -11,6 +11,9 @@ #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/suspend.h>
 #include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
 #include <asm/olpc.h>
@@ -272,6 +275,8 @@ static int olpc_pm_enter(suspend_state_t
 	return 0;
 }
 
+static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
+
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -282,7 +287,7 @@ int asmlinkage olpc_do_sleep(u8 sleep_st
 
 	/* FIXME:  Set any other SCI events that we might want here */
 
-	outl((CS5536_PM_PWRBTN << 16) | 0xFFFF, acpi_base + PM1_STS);
+	outl((olpc_wakeup_mask << 16) | 0xFFFF, acpi_base + PM1_STS);
 
 	/* If we are in test mode, then just return (simulate a successful
 	   suspend/resume).  Otherwise, if we are doing the real thing,
@@ -549,6 +554,65 @@ static int __init olpc_pm_init(void)
 	return 0;
 }
 
+
+#if defined (CONFIG_RTC_DRV_CMOS) || defined (CONFIG_RTC_DRV_CMOS_MODULE)
+struct resource rtc_platform_resource[2] = {
+	{
+		.flags		= IORESOURCE_IO,
+		.start		= RTC_PORT(0),
+		.end		= RTC_PORT(0) + RTC_IO_EXTENT
+	},
+	{
+		.flags = IORESOURCE_IRQ,
+		.start = 8,
+		.end = 8,
+	},
+};
+
+
+static struct cmos_rtc_board_info rtc_info;
+
+struct platform_device olpc_rtc_device = {
+	.name = "rtc_cmos",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(rtc_platform_resource),
+	.dev.platform_data = &rtc_info,
+	.resource = rtc_platform_resource,
+};
+
+struct resource rtc_platform_irq = {
+	.flags = IORESOURCE_IRQ,
+	.start = 8,
+	.end = 8,
+};
+
+static void rtc_wake_on(struct device *dev)
+{
+	olpc_wakeup_mask |= CS5536_PM_RTC;
+}
+
+static void rtc_wake_off(struct device *dev)
+{
+	olpc_wakeup_mask &= ~(CS5536_PM_RTC);
+}
+
+static int olpc_rtc_init(void)
+{
+	rtc_info.rtc_day_alarm = 0;
+	rtc_info.rtc_mon_alarm = 0;
+	rtc_info.rtc_century = 0;
+	rtc_info.wake_on = rtc_wake_on;
+	rtc_info.wake_off = rtc_wake_off;
+
+	(void)platform_device_register(&olpc_rtc_device);
+
+	device_init_wakeup(&olpc_rtc_device.dev, 1);
+
+	return 0;
+}
+fs_initcall(olpc_rtc_init);
+#endif /* CONFIG_RTC_DRV_CMOS */
+
 static void olpc_pm_exit(void)
 {
 	/* Clear any pending events, and disable them */
#92 lore raw

PATCH 1/1 OLPC rtc-cmos support

In reply to Jordan Crouse

Hi,

The following patch implements the hooks necessary for OLPC to use the rtc-cmos driver. This is necessary since we do not want CONFIG_PNP.

This makes it possible to control rtc wakeup via
/sys/devices/platform/rtc_cmos/power/wakeup.

Comments?

arch/i386/kernel/olpc-pm.c +92 -1
index 9599dbe..d92c54a 100644
@@ -11,6 +11,9 @@ #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/suspend.h>
 #include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
 #include <asm/olpc.h>
@@ -272,6 +275,8 @@ static int olpc_pm_enter(suspend_state_t
 	return 0;
 }
 
+static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
+
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -282,7 +287,7 @@ int asmlinkage olpc_do_sleep(u8 sleep_st
 
 	/* FIXME:  Set any other SCI events that we might want here */
 
-	outl((CS5536_PM_PWRBTN << 16) | 0xFFFF, acpi_base + PM1_STS);
+	outl((olpc_wakeup_mask << 16) | 0xFFFF, acpi_base + PM1_STS);
 
 	/* If we are in test mode, then just return (simulate a successful
 	   suspend/resume).  Otherwise, if we are doing the real thing,
@@ -549,6 +554,92 @@ static int __init olpc_pm_init(void)
 	return 0;
 }
 
+
+#if defined (CONFIG_RTC_DRV_CMOS) || defined (CONFIG_RTC_DRV_CMOS_MODULE)
+struct resource rtc_platform_resource[2] = {
+	{
+		.flags		= IORESOURCE_IO,
+		.start		= RTC_PORT(0),
+		.end		= RTC_PORT(0) + RTC_IO_EXTENT
+	},
+	{
+		.flags = IORESOURCE_IRQ,
+		.start = 8,
+		.end = 8,
+	},
+};
+
+struct resource rtc_platform_irq = {
+	.flags = IORESOURCE_IRQ,
+	.start = 8,
+	.end = 8,
+};
+
+static int olpc_add_rtc(void)
+{
+	struct platform_device *pd;
+
+	pd = platform_device_register_simple("rtc_cmos", -1,
+					     rtc_platform_resource, 2);
+	if (IS_ERR(pd)) 
+		return PTR_ERR(pd);
+
+	/* rtc-cmos only supports 24-hr mode */
+	CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_24H, RTC_CONTROL);
+
+	return 0;
+}
+arch_initcall(olpc_add_rtc);
+
+static struct cmos_rtc_board_info rtc_info;
+
+static void rtc_wake_on(struct device *dev)
+{
+	olpc_wakeup_mask |= CS5536_PM_RTC;
+}
+
+static void rtc_wake_off(struct device *dev)
+{
+	olpc_wakeup_mask &= ~(CS5536_PM_RTC);
+}
+
+static int rtc_match(struct device *dev, void *data)
+{
+	static const char *devname = { "rtc_cmos" };
+	struct rtc_device *rtcdev = to_rtc_device(dev);
+
+	if (!strcmp(devname, rtcdev->name))
+		return 1;
+
+	return 0;
+}
+
+static struct device * get_rtc_dev(void)
+{
+        return bus_find_device(&platform_bus_type, NULL, NULL, rtc_match);
+}
+
+static int olpc_rtc_init(void)
+{
+	struct device *dev = get_rtc_dev();
+
+	if (dev) {
+		rtc_info.rtc_day_alarm = 0;
+		rtc_info.rtc_mon_alarm = 0;
+		rtc_info.rtc_century = 0;
+		rtc_info.wake_on = rtc_wake_on;
+		rtc_info.wake_off = rtc_wake_off;
+
+		dev->platform_data = &rtc_info;
+
+		device_init_wakeup(dev, 1);
+	} else 
+		printk(KERN_ERR "no rtc\n");
+	return 0;
+}
+fs_initcall(olpc_rtc_init);
+#endif /* CONFIG_RTC_DRV_CMOS */
+
 static void olpc_pm_exit(void)
 {
 	/* Clear any pending events, and disable them */
#93 lore raw
In reply to David Brownell
Quoted 9 lines · David Brownell
Quoted 5 lines

So, for better or worse, we are implementing a new power management manger. Here is the code:

http://dev.laptop.org/git.do?p=olpc-2.6;a=blob;h=e6e19ac32a881be962db7190f2cb460e9f60a9da;hb=powermgmt;f=arch/i386/kernel/olpc-pm.c

Does that work yet with CONFIG_NO_HZ, so that the system idle loop enters some "almost everyting is turned off" low power state? Or would that be something other than a "PM Manager"?

I think eventually we'll get into entering deeper states in the idle loop. For now, we're just going into the classic C1 / hlt state, which is actually quite thrifty on the Geode, due to automatic hardware clock gating that happens throughout the chip(s).

Quoted 16 lines
Quoted 7 lines
Quoted 6 lines
Quoted 1 line

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

Quoted 8 lines

The silicon can handle wakeups from RTC, a sleep button, a power button, 8 GPIO groups, the USB controller (covering any and all USB events), UART1, UART2, SMbus and the PIC.

OLPC really only cares about 4 of those, because our only sleep state is ~S3, and the PIC, smbus, UARTs and USB are off in S3. We also only have the power button, and all the rest of the wakeup sources come from the GPIOs.

Quoted 6 lines

So it's a slightly deeper "S3" than I've usually seen, but not by much.

And correct me if I'm wrong, but your RTC can work with "rtc-cmos", and the wake hooks I've posted (and which will be in the next MM release) sound like they'll work just fine (given OLPC-specific implementation, which is clearly not included in the code above).

Indeed, and thank you much for that work - we'll be sure to integrate it.

Quoted 10 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

I'm not saying inside ACPI - I'm saying at the driver level.

Whereas in that patch, the only ACPI calls were inside ACPI itself; and that driver only had a callback. FWIW that's the first time I've ever needed to have indirection on wakeup event handling ...

This is the first real "embedded" scenario to pop its head up in x86 land, up to this point, most of the boards have just been really weak desktops.

Quoted 4 lines
Quoted 3 lines

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

Quoted 8 lines

With AT91 (and most ARMs) the wake events are normal IRQs, and the irq infrastructure already handles wake events cleanly. So I'd claim they don't _want_ to change something that's inexpensive, already deployed (training, code, testing, etc), and working.

So I hope you'll tolerate me if I view this as less of a "how do we get a generic solution" and more of a "how does _this_ x86-ish issue get solved cleanly".

Thats fair. x86 does live in a different world then the other embedded chips. I think its reasonable for the x86 folks to get their story straight and then move on from there.

Quoted 8 lines
Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Thats fine - I am not sold on a "one call to rule them all", but I do want to avoid any #ifdef CONFIG_PM_ACPI #elsif CONFIG_OLPC_PM #else nonsense.

Quoted 15 lines
Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

My point above was that ACPI isn't yet integrating with the things it needs to be integrating with. If you're concerned about how to work with wakeup events in Linux, don't even bother looking at ACPI. Look at the embedded implementations; look at USB. AT91 is by far the cleanest and most complete (simplest hardware too!!), but some of the other systems (OMAP, PXA, SA1100, etc) also implement wakeup using board-specific code.

Quoted 3 lines

OLPC _could_ use that same "board-specific hacks" approach found in most embedded platforms. I'm glad you're thinking about how to avoid doing that.

We are keenly aware that we're committing a minor sin by implementing yet another PM interface for x86. But we believe that our heart is in the right place, and we are dedicated to doing the right thing, and trying our hardest not to contribute further to fragmenting the PM subsystem with implementation specific code. In many cases we're looking to help bring the others into the fold, especially our fellow x86 implementations that suffer from the same issues that we do.

I appreciate your comments, and the rtc-cmos code will go to good use.

Jordan

Signature · 4 lines
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
#94 lore raw
In reply to David Brownell

Hi David,

Quoted 66 lines · David Brownell
Quoted 6 lines

It seems
to me to be more logical to move the wakeup intelligence to the PM subsystem, and then let that code distribute it to where it is needed. In the case of x86, the logic would stay in the PM method, for other processors, it might involve a call to the interrupt mapper.

But why should a "PM subsystem" be created to abstract something that already works just fine?

It'd make much more sense to me to come up with a good way to handle the x86 issues first, and only then think about whether to try making that work on other systems.

Quoted 7 lines
Quoted 7 lines

And for PCI based things, pci_enable_wake() encapsulates everything that needs doing. Not that ACPI actually *does* anything yet! But the stuff that writing /proc/acpi/wakeup enables should happen in that routine ... and eventually PCI runtime wake events should work too. (So: no drivers would ever call ACPI directly, and they already have the generic call that ACPI should hook.)

Quoted 5 lines
Quoted 2 lines

That seems to cover most drivers in Linux, without a need for any new generic PM infrastructure. Did I overlook something important?

No, I don't think so - we're very close on agreeing here. I just don't know if enable_irq_wake() is the best way to provide the generic call.

It's not, and I didn't propose doing that either.

Having all drivers try to use the same calls to manage wakeup mechanisms doesn't seem like the right model. When the mechanism is the same -- wakeup irqs, say -- then yes the calls should be the same. But when the mechanisms differ -- PCI PME# is very different from wakeup IRQS, only one per device etc -- then the calls can reasonably be different.

Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Quoted 18 lines
Quoted 17 lines
Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

Quoted 6 lines
Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

As you know we want user configuration of enabled wakeup events (unlike embedded platforms where this is hardcoded). It seems that the current interface available for that is /sys/devices/../power/wakeup hook (when !ACPI).

However there are several wakeup capable devices in OLPC which do not have drivers, thus no platform devices:

- power button
- lid

It seems that creating platform devices for these two just for the purpose of a having an interface for enabling wakeup events is overkill.

Given that, we probably want something similar to what was initially described in http://wiki.laptop.org/go/Power_Management_Interface ?

The downside of doing that is a non-unified interface: platform devices via /sys/devices/../power/wakeup and otherwise /sys/whatever/wakeup/source?

Quoted 17 lines

My point above was that ACPI isn't yet integrating with the things it needs to be integrating with. If you're concerned about how to work with wakeup events in Linux, don't even bother looking at ACPI. Look at the embedded implementations; look at USB. AT91 is by far the cleanest and most complete (simplest hardware too!!), but some of the other systems (OMAP, PXA, SA1100, etc) also implement wakeup using board-specific code.

OLPC _could_ use that same "board-specific hacks" approach found in most embedded platforms. I'm glad you're thinking about how to avoid doing that.

- Dave
_______________________________________________
Devel mailing list
[email protected]
http://mailman.laptop.org/mailman/listinfo/devel

#95 lore raw
Quoted 24 lines · Marcelo Tosatti
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

Quoted 6 lines
Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

As you know we want user configuration of enabled wakeup events (unlike embedded platforms where this is hardcoded). It seems that the current interface available for that is /sys/devices/../power/wakeup hook (when !ACPI).

Quoted 8 lines

However there are several wakeup capable devices in OLPC which do not have drivers, thus no platform devices:

- power button
- lid

It seems that creating platform devices for these two just for the purpose of a having an interface for enabling wakeup events is overkill.

I'll go ahead and disagree with that, I think a platform device is clearly the best way to go. It's the cleanest approach.

Signature · 1 line
Jens Axboe
#96 lore raw
In reply to Marcelo Tosatti
Quoted 24 lines · Marcelo Tosatti
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

Quoted 6 lines
Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

As you know we want user configuration of enabled wakeup events (unlike embedded platforms where this is hardcoded). It seems that the current interface available for that is /sys/devices/../power/wakeup hook (when !ACPI).

Quoted 8 lines

However there are several wakeup capable devices in OLPC which do not have drivers, thus no platform devices:

- power button
- lid

It seems that creating platform devices for these two just for the purpose of a having an interface for enabling wakeup events is overkill.

I'll go ahead and disagree with that, I think a platform device is clearly the best way to go. It's the cleanest approach.

Signature · 1 line
Jens Axboe
#97 lore raw
In reply to Marcelo Tosatti
Quoted 14 lines

As you know we want user configuration of enabled wakeup events (unlike embedded platforms where this is hardcoded). It seems that the current interface available for that is /sys/devices/../power/wakeup hook (when !ACPI).

However there are several wakeup capable devices in OLPC which do not have drivers, thus no platform devices:

- power button
- lid

It seems that creating platform devices for these two just for the purpose of a having an interface for enabling wakeup events is overkill.

Quoted 6 lines

Given that, we probably want something similar to what was initially described in http://wiki.laptop.org/go/Power_Management_Interface ?

The downside of doing that is a non-unified interface: platform devices via /sys/devices/../power/wakeup and otherwise /sys/whatever/wakeup/source?

Perhaps it is over kill, but is it really very expensive for handful of devices? I am curious as to others experiences here.

In hacks for embedded in the past I've sprinkled some extra device/bus registrations around to provide a common way to enable wake ups and idle states. I don't know that it was the best way to do it, but it could be made to work.

A dev structure is a handy thing to have around and provides symmetry. Having a sysfs entry provides for an easy way to set and test from user space. You can always export the function in the kernel also to get a secondary path to the function. All that seems nicer than adding ioctrls and the like per driver.

Regards,
Richard W.

#98 lore raw
In reply to Marcelo Tosatti
Quoted 8 lines · Marcelo Tosatti
Quoted 3 lines

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

As you know we want user configuration of enabled wakeup events (unlike embedded platforms where this is hardcoded). It seems that the current interface available for that is /sys/devices/../power/wakeup hook (when !ACPI).

And, when some issues get sorted, for ACPI too. Patches have circulated which make it all behave properly ... except for some platform-specific oddities that haven't gotten sorted out yet. (As I recall, there was one instance of the "EHCI wrongly issues wakeups" problems; and then the mess with PCI init sequence on powerpc vs most other systems.)

Quoted 8 lines

However there are several wakeup capable devices in OLPC which do not have drivers, thus no platform devices:

- power button
- lid

It seems that creating platform devices for these two just for the purpose of a having an interface for enabling wakeup events is overkill.

What Jens said. ;)

I'll disagree. Not just because ACPI already creates devices for those two cases, but because creating normal device nodes there is the Right Thing To Do. It's cheap, and won't surprise anyone.

Quoted 6 lines

Given that, we probably want something similar to what was initially described in http://wiki.laptop.org/go/Power_Management_Interface ?

The downside of doing that is a non-unified interface: platform devices via /sys/devices/../power/wakeup and otherwise /sys/whatever/wakeup/source?

That's exactly why "we" do *NOT* want something like what was sketched in that Wiki. Gratuitous divergence hurts ... and in this case, it's trivial to adopt that common solution (just add platform device, managed the usual way) and not diverge.

- Dave

#99 lore raw
In reply to Marcelo Tosatti
Quoted 8 lines · Marcelo Tosatti
Quoted 3 lines

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

As you know we want user configuration of enabled wakeup events (unlike embedded platforms where this is hardcoded). It seems that the current interface available for that is /sys/devices/../power/wakeup hook (when !ACPI).

And, when some issues get sorted, for ACPI too. Patches have circulated which make it all behave properly ... except for some platform-specific oddities that haven't gotten sorted out yet. (As I recall, there was one instance of the "EHCI wrongly issues wakeups" problems; and then the mess with PCI init sequence on powerpc vs most other systems.)

Quoted 8 lines

However there are several wakeup capable devices in OLPC which do not have drivers, thus no platform devices:

- power button
- lid

It seems that creating platform devices for these two just for the purpose of a having an interface for enabling wakeup events is overkill.

What Jens said. ;)

I'll disagree. Not just because ACPI already creates devices for those two cases, but because creating normal device nodes there is the Right Thing To Do. It's cheap, and won't surprise anyone.

Quoted 6 lines

Given that, we probably want something similar to what was initially described in http://wiki.laptop.org/go/Power_Management_Interface ?

The downside of doing that is a non-unified interface: platform devices via /sys/devices/../power/wakeup and otherwise /sys/whatever/wakeup/source?

That's exactly why "we" do *NOT* want something like what was sketched in that Wiki. Gratuitous divergence hurts ... and in this case, it's trivial to adopt that common solution (just add platform device, managed the usual way) and not diverge.

- Dave

#100 lore raw

PATCH 1/1 add powerbutton and lid platform devices

Jordan,

This allows configuration of powerbutton/lid events... Are the gpio_gpio_{clear,set} calls correct for enabling/disabling LID events?

What else do we want to support?

olpc-pm.c renamed from olpc-pm.c.orig +30 -5
@@ -54,6 +54,18 @@
 
 static int gpio_wake_events = 0;
 static int ebook_state = -1;
+static u16 olpc_wakeup_mask = 0;
+
+struct platform_device olpc_powerbutton_dev = {
+	.name = "powerbutton",
+	.id = 0,
+};
+
+struct platform_device olpc_lid_dev = {
+	.name = "lid",
+	.id = 0,
+};
+
 
 static void __init init_ebook_state(void)
 {
@@ -250,6 +262,16 @@
 	/* Save the MFGPT MSRs */
 	rdmsrl(MFGPT_IRQ_MSR, mfgpt_irq_msr);
 	rdmsrl(MFGPT_NR_MSR, mfgpt_nr_msr);
+
+	if (device_may_wakeup(&olpc_powerbutton_dev.dev))
+		olpc_wakeup_mask |= CS5536_PM_PWRBTN;
+	else
+		olpc_wakeup_mask &= ~(CS5536_PM_PWRBTN);
+
+	if (device_may_wakeup(&olpc_lid_dev.dev))
+		geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
+	else
+		geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
 }
 
 static int olpc_pm_enter(suspend_state_t pm_state)
@@ -275,8 +297,6 @@
 	return 0;
 }
 
-static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
-
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -596,15 +616,20 @@
 	.resource = rtc_platform_resource,
 };
 
-static int __init olpc_rtc_init(void)
+static int __init olpc_platform_init(void)
 {
 	(void)platform_device_register(&olpc_rtc_device);
-
 	device_init_wakeup(&olpc_rtc_device.dev, 1);
 
+	(void)platform_device_register(&olpc_powerbutton_dev);
+	device_init_wakeup(&olpc_powerbutton_dev.dev, 1);
+
+	(void)platform_device_register(&olpc_lid_dev);
+	device_init_wakeup(&olpc_lid_dev.dev, 1);
+
 	return 0;
 }
-arch_initcall(olpc_rtc_init);
+arch_initcall(olpc_platform_init);
 #endif /* CONFIG_RTC_DRV_CMOS */
 
 static void olpc_pm_exit(void)
#101 lore raw

PATCH 1/1 add powerbutton and lid platform devices

In reply to David Brownell

Jordan,

This allows configuration of powerbutton/lid events... Are the gpio_gpio_{clear,set} calls correct for enabling/disabling LID events?

What else do we want to support?

olpc-pm.c renamed from olpc-pm.c.orig +30 -5
@@ -54,6 +54,18 @@
 
 static int gpio_wake_events = 0;
 static int ebook_state = -1;
+static u16 olpc_wakeup_mask = 0;
+
+struct platform_device olpc_powerbutton_dev = {
+	.name = "powerbutton",
+	.id = 0,
+};
+
+struct platform_device olpc_lid_dev = {
+	.name = "lid",
+	.id = 0,
+};
+
 
 static void __init init_ebook_state(void)
 {
@@ -250,6 +262,16 @@
 	/* Save the MFGPT MSRs */
 	rdmsrl(MFGPT_IRQ_MSR, mfgpt_irq_msr);
 	rdmsrl(MFGPT_NR_MSR, mfgpt_nr_msr);
+
+	if (device_may_wakeup(&olpc_powerbutton_dev.dev))
+		olpc_wakeup_mask |= CS5536_PM_PWRBTN;
+	else
+		olpc_wakeup_mask &= ~(CS5536_PM_PWRBTN);
+
+	if (device_may_wakeup(&olpc_lid_dev.dev))
+		geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
+	else
+		geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
 }
 
 static int olpc_pm_enter(suspend_state_t pm_state)
@@ -275,8 +297,6 @@
 	return 0;
 }
 
-static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
-
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -596,15 +616,20 @@
 	.resource = rtc_platform_resource,
 };
 
-static int __init olpc_rtc_init(void)
+static int __init olpc_platform_init(void)
 {
 	(void)platform_device_register(&olpc_rtc_device);
-
 	device_init_wakeup(&olpc_rtc_device.dev, 1);
 
+	(void)platform_device_register(&olpc_powerbutton_dev);
+	device_init_wakeup(&olpc_powerbutton_dev.dev, 1);
+
+	(void)platform_device_register(&olpc_lid_dev);
+	device_init_wakeup(&olpc_lid_dev.dev, 1);
+
 	return 0;
 }
-arch_initcall(olpc_rtc_init);
+arch_initcall(olpc_platform_init);
 #endif /* CONFIG_RTC_DRV_CMOS */
 
 static void olpc_pm_exit(void)
#102 lore raw

Re: add powerbutton and lid platform devices

Quoted 7 lines · Marcelo Tosatti

Jordan,

This allows configuration of powerbutton/lid events... Are the gpio_gpio_{clear,set} calls correct for enabling/disabling LID events?

What else do we want to support?

The obvious ones would be RTC (but you already covered that), and SCI. But this is an excellent start.

Quoted 26 lines
olpc-pm.c renamed from olpc-pm.c.orig +13 -0
@@ -54,6 +54,18 @@
 
 static int gpio_wake_events = 0;
 static int ebook_state = -1;
+static u16 olpc_wakeup_mask = 0;
+
+struct platform_device olpc_powerbutton_dev = {
+	.name = "powerbutton",
+	.id = 0,
+};
+
+struct platform_device olpc_lid_dev = {
+	.name = "lid",
+	.id = 0,
+};
+
 
 static void __init init_ebook_state(void)
 {
@@ -250,6 +262,16 @@
 	/* Save the MFGPT MSRs */
 	rdmsrl(MFGPT_IRQ_MSR, mfgpt_irq_msr);
 	rdmsrl(MFGPT_NR_MSR, mfgpt_nr_msr);
+

olpc-pm.c line 275

Quoted 10 lines
olpc-pm.c renamed from olpc-pm.c.orig +9 -0
+	if (device_may_wakeup(&olpc_powerbutton_dev.dev))
+		olpc_wakeup_mask |= CS5536_PM_PWRBTN;
+	else
+		olpc_wakeup_mask &= ~(CS5536_PM_PWRBTN);
+
+	if (device_may_wakeup(&olpc_lid_dev.dev))
+		geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
+	else
+		geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
 }

As was already mentioned before, the clear and set clauses should be reversed.

You'll also need to get rid of

outl(1 << 31, acpi_base + PM_GPE0_EN);

in olpc_pm_enter() since that would have the undesired effect of eliminating the LID completely from the list of wakeup sources. We should leave the value of GPE0_EN the same through the lifetime of the system, and control the individual events through the event enable bit(s) as you have done above.

Quoted 19 lines
olpc-pm.c renamed from olpc-pm.c.orig +1 -4
 static int olpc_pm_enter(suspend_state_t pm_state)
@@ -275,8 +297,6 @@
 	return 0;
 }
 
-static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
-
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -596,15 +616,20 @@
 	.resource = rtc_platform_resource,
 };
 
-static int __init olpc_rtc_init(void)
+static int __init olpc_platform_init(void)
 {
 	(void)platform_device_register(&olpc_rtc_device);
-

olpc-pm.c line 631

Quoted 10 lines
olpc-pm.c renamed from olpc-pm.c.orig +6 -0
 	device_init_wakeup(&olpc_rtc_device.dev, 1);
 
+	(void)platform_device_register(&olpc_powerbutton_dev);
+	device_init_wakeup(&olpc_powerbutton_dev.dev, 1);
+
+	(void)platform_device_register(&olpc_lid_dev);
+	device_init_wakeup(&olpc_lid_dev.dev, 1);
+
 	return 0;
 }

I agree that the default setting for the power button should be to wake up, but I don't know about the lid. Imagine a scenario where somebody manually puts the machine to sleep and then shuts the lid. You wouldn't want the machine to turn back on when you lifted it. Lid behavior is so policy driven, I think we should leave it off by default, and let the power manager decide what to do.

Quoted 7 lines
olpc-pm.c renamed from olpc-pm.c.orig +1 -1
-arch_initcall(olpc_rtc_init);
+arch_initcall(olpc_platform_init);
 #endif /* CONFIG_RTC_DRV_CMOS */
 
 static void olpc_pm_exit(void)
Signature · 3 lines
Jordan Crouse
Systems Software Development Engineer 
Advanced Micro Devices, Inc.
#103 lore raw

Re: add powerbutton and lid platform devices

Quoted 4 lines · Jordan Crouse

I agree that the default setting for the power button should be to wake up, but I don't know about the lid. Imagine a scenario where somebody manually puts the machine to sleep and then shuts the lid. You wouldn't want the machine to turn back on when you lifted it.

I wouldn't want "echo mem > /sys/power/state" to
automagically cause the lid to act strangely...

Quoted 3 lines

Lid behavior is so policy
driven, I think we should leave it off by default, and let the power manager decide what to do.

What's this "power manager" component?

This policy is easily set through sysfs. It doesn't need a new component to make that decision.

- Dave

#104 lore raw

Re: add powerbutton and lid platform devices

Quoted 8 lines · David Brownell
Quoted 3 lines

Lid behavior is so policy
driven, I think we should leave it off by default, and let the power manager decide what to do.

What's this "power manager" component?

This policy is easily set through sysfs. It doesn't need a new component to make that decision.

I'm talking about OHM for userspace policy decisions. But you are correct. It all boils down to a single sysfs knob for the kernel. Nothing more is needed.

Jordan

Signature · 3 lines
Jordan Crouse
Systems Software Development Engineer 
Advanced Micro Devices, Inc.
#105 lore raw

Re: add powerbutton and lid platform devices

In reply to David Brownell
Quoted 8 lines · David Brownell
Quoted 3 lines

Lid behavior is so policy
driven, I think we should leave it off by default, and let the power manager decide what to do.

What's this "power manager" component?

This policy is easily set through sysfs. It doesn't need a new component to make that decision.

I'm talking about OHM for userspace policy decisions. But you are correct. It all boils down to a single sysfs knob for the kernel. Nothing more is needed.

Jordan

Signature · 3 lines
Jordan Crouse
Systems Software Development Engineer 
Advanced Micro Devices, Inc.
#106 lore raw

Re: add powerbutton and lid platform devices

In reply to David Brownell
Quoted 1 line · David Brownell

What's this "power manager" component?

At the moment we're using OHM, although it's got a few rough edges, it seems to do mostly what we need it to right now.

Quoted 2 lines

This policy is easily set through sysfs. It doesn't need a new component to make that decision.

Sure you do. What happens if you are right in the middle of a system update over wifi -- do you still want to suspend in that case? Or a bios flash? There has to be something higher level to unset or set the policy knobs in the kernel with the information from the system or session.

Richard.

#107 lore raw

Re: add powerbutton and lid platform devices

In reply to David Brownell
Quoted 1 line · David Brownell

What's this "power manager" component?

At the moment we're using OHM, although it's got a few rough edges, it seems to do mostly what we need it to right now.

Quoted 2 lines

This policy is easily set through sysfs. It doesn't need a new component to make that decision.

Sure you do. What happens if you are right in the middle of a system update over wifi -- do you still want to suspend in that case? Or a bios flash? There has to be something higher level to unset or set the policy knobs in the kernel with the information from the system or session.

Richard.

#108 lore raw

Re: add powerbutton and lid platform devices

In reply to Jordan Crouse
Quoted 4 lines · Jordan Crouse

I agree that the default setting for the power button should be to wake up, but I don't know about the lid. Imagine a scenario where somebody manually puts the machine to sleep and then shuts the lid. You wouldn't want the machine to turn back on when you lifted it.

I wouldn't want "echo mem > /sys/power/state" to
automagically cause the lid to act strangely...

Quoted 3 lines

Lid behavior is so policy
driven, I think we should leave it off by default, and let the power manager decide what to do.

What's this "power manager" component?

This policy is easily set through sysfs. It doesn't need a new component to make that decision.

- Dave

#109 lore raw

Re: add powerbutton and lid platform devices

In reply to Jordan Crouse
Quoted 4 lines · Jordan Crouse

I agree that the default setting for the power button should be to wake up, but I don't know about the lid. Imagine a scenario where somebody manually puts the machine to sleep and then shuts the lid. You wouldn't want the machine to turn back on when you lifted it.

Actually, that is what I'd want. I regularly do this on my thinkpad:
fn-f4 to sleep, watch the blinking lights and console messages until the screen turns off, then close the lid. I expect it to wake up when I open it again.
--scott

Signature · 1 line
                        ( http://cscott.net/ )
#110 lore raw

Re: add powerbutton and lid platform devices

In reply to Jordan Crouse
Quoted 4 lines · Jordan Crouse

I agree that the default setting for the power button should be to wake up, but I don't know about the lid. Imagine a scenario where somebody manually puts the machine to sleep and then shuts the lid. You wouldn't want the machine to turn back on when you lifted it.

Actually, that is what I'd want. I regularly do this on my thinkpad:
fn-f4 to sleep, watch the blinking lights and console messages until the screen turns off, then close the lid. I expect it to wake up when I open it again.
--scott

Signature · 1 line
                        ( http://cscott.net/ )
#111 lore raw

Re: add powerbutton and lid platform devices

In reply to Marcelo Tosatti
Quoted 7 lines · Marcelo Tosatti

Jordan,

This allows configuration of powerbutton/lid events... Are the gpio_gpio_{clear,set} calls correct for enabling/disabling LID events?

What else do we want to support?

The obvious ones would be RTC (but you already covered that), and SCI. But this is an excellent start.

Quoted 26 lines
olpc-pm.c renamed from olpc-pm.c.orig +13 -0
@@ -54,6 +54,18 @@
 
 static int gpio_wake_events = 0;
 static int ebook_state = -1;
+static u16 olpc_wakeup_mask = 0;
+
+struct platform_device olpc_powerbutton_dev = {
+	.name = "powerbutton",
+	.id = 0,
+};
+
+struct platform_device olpc_lid_dev = {
+	.name = "lid",
+	.id = 0,
+};
+
 
 static void __init init_ebook_state(void)
 {
@@ -250,6 +262,16 @@
 	/* Save the MFGPT MSRs */
 	rdmsrl(MFGPT_IRQ_MSR, mfgpt_irq_msr);
 	rdmsrl(MFGPT_NR_MSR, mfgpt_nr_msr);
+

olpc-pm.c line 275

Quoted 10 lines
olpc-pm.c renamed from olpc-pm.c.orig +9 -0
+	if (device_may_wakeup(&olpc_powerbutton_dev.dev))
+		olpc_wakeup_mask |= CS5536_PM_PWRBTN;
+	else
+		olpc_wakeup_mask &= ~(CS5536_PM_PWRBTN);
+
+	if (device_may_wakeup(&olpc_lid_dev.dev))
+		geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
+	else
+		geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
 }

As was already mentioned before, the clear and set clauses should be reversed.

You'll also need to get rid of

outl(1 << 31, acpi_base + PM_GPE0_EN);

in olpc_pm_enter() since that would have the undesired effect of eliminating the LID completely from the list of wakeup sources. We should leave the value of GPE0_EN the same through the lifetime of the system, and control the individual events through the event enable bit(s) as you have done above.

Quoted 19 lines
olpc-pm.c renamed from olpc-pm.c.orig +1 -4
 static int olpc_pm_enter(suspend_state_t pm_state)
@@ -275,8 +297,6 @@
 	return 0;
 }
 
-static u16 olpc_wakeup_mask = CS5536_PM_PWRBTN;
-
 int asmlinkage olpc_do_sleep(u8 sleep_state)
 {
 	void *pgd_addr = __va(read_cr3());
@@ -596,15 +616,20 @@
 	.resource = rtc_platform_resource,
 };
 
-static int __init olpc_rtc_init(void)
+static int __init olpc_platform_init(void)
 {
 	(void)platform_device_register(&olpc_rtc_device);
-

olpc-pm.c line 631

Quoted 10 lines
olpc-pm.c renamed from olpc-pm.c.orig +6 -0
 	device_init_wakeup(&olpc_rtc_device.dev, 1);
 
+	(void)platform_device_register(&olpc_powerbutton_dev);
+	device_init_wakeup(&olpc_powerbutton_dev.dev, 1);
+
+	(void)platform_device_register(&olpc_lid_dev);
+	device_init_wakeup(&olpc_lid_dev.dev, 1);
+
 	return 0;
 }

I agree that the default setting for the power button should be to wake up, but I don't know about the lid. Imagine a scenario where somebody manually puts the machine to sleep and then shuts the lid. You wouldn't want the machine to turn back on when you lifted it. Lid behavior is so policy driven, I think we should leave it off by default, and let the power manager decide what to do.

Quoted 7 lines
olpc-pm.c renamed from olpc-pm.c.orig +1 -1
-arch_initcall(olpc_rtc_init);
+arch_initcall(olpc_platform_init);
 #endif /* CONFIG_RTC_DRV_CMOS */
 
 static void olpc_pm_exit(void)
Signature · 3 lines
Jordan Crouse
Systems Software Development Engineer 
Advanced Micro Devices, Inc.
#112 lore raw
In reply to David Brownell

Hi David,

Quoted 66 lines · David Brownell
Quoted 6 lines

It seems
to me to be more logical to move the wakeup intelligence to the PM subsystem, and then let that code distribute it to where it is needed. In the case of x86, the logic would stay in the PM method, for other processors, it might involve a call to the interrupt mapper.

But why should a "PM subsystem" be created to abstract something that already works just fine?

It'd make much more sense to me to come up with a good way to handle the x86 issues first, and only then think about whether to try making that work on other systems.

Quoted 7 lines
Quoted 7 lines

And for PCI based things, pci_enable_wake() encapsulates everything that needs doing. Not that ACPI actually *does* anything yet! But the stuff that writing /proc/acpi/wakeup enables should happen in that routine ... and eventually PCI runtime wake events should work too. (So: no drivers would ever call ACPI directly, and they already have the generic call that ACPI should hook.)

Quoted 5 lines
Quoted 2 lines

That seems to cover most drivers in Linux, without a need for any new generic PM infrastructure. Did I overlook something important?

No, I don't think so - we're very close on agreeing here. I just don't know if enable_irq_wake() is the best way to provide the generic call.

It's not, and I didn't propose doing that either.

Having all drivers try to use the same calls to manage wakeup mechanisms doesn't seem like the right model. When the mechanism is the same -- wakeup irqs, say -- then yes the calls should be the same. But when the mechanisms differ -- PCI PME# is very different from wakeup IRQS, only one per device etc -- then the calls can reasonably be different.

Quoted 4 lines

Moving
it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

I guess that's where we disagree: you're assuming "one call to rule them all", where I'm thinking that IRQ calls should manage IRQs, PCI calls should manage PME#, and so on.

Quoted 18 lines
Quoted 17 lines
Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

Quoted 6 lines
Quoted 3 lines

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Since OLPC isn't using ACPI, it can be more like embedded Linux, and just Do The Right Thing ... create platform devices, etc. :)

As you know we want user configuration of enabled wakeup events (unlike embedded platforms where this is hardcoded). It seems that the current interface available for that is /sys/devices/../power/wakeup hook (when !ACPI).

However there are several wakeup capable devices in OLPC which do not have drivers, thus no platform devices:

- power button
- lid

It seems that creating platform devices for these two just for the purpose of a having an interface for enabling wakeup events is overkill.

Given that, we probably want something similar to what was initially described in http://wiki.laptop.org/go/Power_Management_Interface ?

The downside of doing that is a non-unified interface: platform devices via /sys/devices/../power/wakeup and otherwise /sys/whatever/wakeup/source?

Quoted 17 lines

My point above was that ACPI isn't yet integrating with the things it needs to be integrating with. If you're concerned about how to work with wakeup events in Linux, don't even bother looking at ACPI. Look at the embedded implementations; look at USB. AT91 is by far the cleanest and most complete (simplest hardware too!!), but some of the other systems (OMAP, PXA, SA1100, etc) also implement wakeup using board-specific code.

OLPC _could_ use that same "board-specific hacks" approach found in most embedded platforms. I'm glad you're thinking about how to avoid doing that.

- Dave
_______________________________________________
Devel mailing list
[email protected]
http://mailman.laptop.org/mailman/listinfo/devel

#113 lore raw
In reply to David Brownell

A few of your comments made me wonder if I haven't been clear enough - despite this being an x86 platform, we are not using ACPI for power management, for a variety of reasons, including the fact that we have our own open source firmware and a very specific hardware platform So, for better or worse, we are implementing a new power management manger. Here is the code:

http://dev.laptop.org/git.do?p=olpc-2.6;a=blob;h=e6e19ac32a881be962db7190f2cb460e9f60a9da;hb=powermgmt;f=arch/i386/kernel/olpc-pm.c

Quoted 6 lines · David Brownell
Quoted 3 lines

The
story is much more muddled for x86 - there is no direct mapping of interrupts to wakeup sources, and the PIC has nothing to do with handling wake events.

Right. Plus there often seems to be an assumption that some "embedded (micro)controller" (EC) manages system bringup/wakeup/runtime.

Or, the southbridge, or in the case of the OLPC platform, both.

Quoted 7 lines
Quoted 2 lines

On the Geode, we have 17 possible wake sources, all of which are ORed

What are those? You mentioned four before. (RTC alarm, two GPIOs, and the power button.) I'd guess various PCI devices can also issue wakeups. (And if USB is one of them, up to 126 USB devices hooked up to each USB host controller!)

The silicon can handle wakeups from RTC, a sleep button, a power button, 8 GPIO groups, the USB controller (covering any and all USB events), UART1, UART2, SMbus and the PIC.

OLPC really only cares about 4 of those, because our only sleep state is ~S3, and the PIC, smbus, UARTs and USB are off in S3. We also only have the power button, and all the rest of the wakeup sources come from the GPIOs.

Quoted 4 lines
Quoted 2 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and

Inside ACPI ... why?

I'm not saying inside ACPI - I'm saying at the driver level. Something like this (where name could be a string like ACPI does, but it would be more portable if it was a #define'ed value).

pm_set_event(name) {
pm_ops->set_event(name, 1);
}

pm_clear_event(name) {
pm_ops->set_event(name, state);
}

And then each subsystem that defines a struct pm_ops adds a set_event() that does the right thing.

In OLPC's case we would do something like this:

olpc_pm_set_event(name, state) {
	switch(name) {
		case PM_WAKEUP_RTC:
			pm1_wakeup |= (1 << 9);
			break;

			...
	}
}

And so forth. Like the AT91, we enable the wakeup events prior to suspending. I'm willing to bet that other PM methods like ACPI could pick this up pretty quickly too.

Quoted 6 lines
Quoted 5 lines

add hooks to the pm_ops for each individual PM system to handle the wakeups in whatever way they see fit, and we're there. It would be slightly more complex for AT91 and friends to match this (since they have the advantage of a 1:1 mapping right now), but in the long run, I think everybody would benefit.

Quoted 6 lines

I guess I don't see why this isn't already sufficiently generic ...

As a rule, all those embedded drivers are platform-specific and have no need for more than a few enable_irq_wake() calls, in addition to whatever controller setup and clock management they do. Since they can't be very portable, they don't need to generalize such stuff.

enable_irq_wake() just doesn't work for x86, unfortunately. It seems to me to be more logical to move the wakeup intelligence to the PM subsystem, and then let that code distribute it to where it is needed. In the case of x86, the logic would stay in the PM method, for other processors, it might involve a call to the interrupt mapper.

Quoted 9 lines

And for PCI based things, pci_enable_wake() encapsulates everything that needs doing. Not that ACPI actually *does* anything yet! But the stuff that writing /proc/acpi/wakeup enables should happen in that routine ... and eventually PCI runtime wake events should work too. (So: no drivers would ever call ACPI directly, and they already have the generic call that ACPI should hook.)

That seems to cover most drivers in Linux, without a need for any new generic PM infrastructure. Did I overlook something important?

No, I don't think so - we're very close on agreeing here. I just don't know if enable_irq_wake() is the best way to provide the generic call. Moving it into the PM infrastructure seems the best way to handle everybody equally, regardless of the relative intelligence or stupidity of their hardware implementation.

Quoted 11 lines
Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

Quoted 6 lines

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

I guess we'll probably have to do something similar for our OLPC PM code
- but thats the sort of platform specific fragmentation thing I was trying to avoid.

Jordan

Signature · 4 lines
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
#114 lore raw
In reply to David Brownell
Quoted 32 lines · David Brownell
Quoted 7 lines

This looks very good, and is pretty close to what I was proposing. Replace the acpi_*_event() calls with a generic pm_ infrastructure, and add hooks to the pm_ops for each individual PM system to handle the wakeups in whatever way they see fit, and we're there. It would be slightly more complex for AT91 and friends to match this (since they have the advantage of a 1:1 mapping right now), but in the long run, I think everybody would benefit.

I guess I don't see why this isn't already sufficiently generic ...

As a rule, all those embedded drivers are platform-specific and have no need for more than a few enable_irq_wake() calls, in addition to whatever controller setup and clock management they do. Since they can't be very portable, they don't need to generalize such stuff.

And for PCI based things, pci_enable_wake() encapsulates everything that needs doing. Not that ACPI actually *does* anything yet! But the stuff that writing /proc/acpi/wakeup enables should happen in that routine ... and eventually PCI runtime wake events should work too. (So: no drivers would ever call ACPI directly, and they already have the generic call that ACPI should hook.)

That seems to cover most drivers in Linux, without a need for any new generic PM infrastructure. Did I overlook something important?

Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

Quoted 5 lines

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

That's right.
This is meaningless now and we don't intend to use it in the future. If a device is also described in ACPI namespace, it should know its ACPI device node in sysfs.
Then when we want to enable/disable a deivce's wakeup ability, just goto the physical device node in sysfs. What we need is a hook offered by ACPI device driver.

Quoted 7 lines

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

Sorry to make you confused.
That's what we need to improve in the wish list. :)

Thanks,
Rui

#115 lore raw
Quoted 6 lines · Zhang Rui
Quoted 6 lines
Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

Quoted 7 lines
Quoted 4 lines

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

That's right.
This is meaningless now and we don't intend to use it in the future.

Why not? Exactly how do you anticipate ACPI exposing its wakeup capabilities, if it's not going to use the existing platform-neutral interface?

Quoted 2 lines

If a device is also described in ACPI namespace, it should know its ACPI device node in sysfs.

What about PCI or PNP devices that have "shadow" listings in ACPI?

Quoted 3 lines

Then when we want to enable/disable a deivce's wakeup ability, just goto the physical device node in sysfs. What we need is a hook offered by ACPI device driver.

I don't follow this at all. Most of the relevant devices have a PCI device driver, not an ACPI device driver. Surely you aren't proposing that PCI drivers should incorporate lots of ACPI-specific code (which won't be useful on non-ACPI platforms) before they start to work right?

For a PCI device driver, pci_enable_wake() is all the hook that it should ever need. If ACPI magic is needed, it should be called from inside that routine.

Quoted 9 lines
Quoted 6 lines

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

Sorry to make you confused.
That's what we need to improve in the wish list. :)

Do you mean the "ACPI 4.0" wishlist? Or the "Linux ACPI" wishlist?

- Dave

#116 lore raw
Quoted 4 lines · David Brownell

I don't follow this at all. Most of the relevant devices have a PCI device driver, not an ACPI device driver. Surely you aren't proposing that PCI drivers should incorporate lots of ACPI-specific code (which won't be useful on non-ACPI platforms) before they start to work right?

PCI devices have a handle to their ACPI object in platform_data, so it's easy enough to have generic code that interacts with both objects.

Quoted 3 lines

For a PCI device driver, pci_enable_wake() is all the hook that it should ever need. If ACPI magic is needed, it should be called from inside that routine.

Yeah, I don't see that being a problem.

Signature · 1 line
Matthew Garrett | [email protected]
#117 lore raw
Quoted 8 lines · Matthew Garrett
Quoted 4 lines · David Brownell

I don't follow this at all. Most of the relevant devices have a PCI device driver, not an ACPI device driver. Surely you aren't proposing that PCI drivers should incorporate lots of ACPI-specific code (which won't be useful on non-ACPI platforms) before they start to work right?

PCI devices have a handle to their ACPI object in platform_data,

Good to know. I was under the impression that was still in the planning stage, not yet the working/reliable stage. But I do see some ACPI code doing that; maybe I'll take more of a look.

Quoted 2 lines

so it's
easy enough to have generic code that interacts with both objects.

Well, not really "generic" if it knows about ACPI. But at least not device-specific.

Quoted 5 lines
Quoted 3 lines

For a PCI device driver, pci_enable_wake() is all the hook that it should ever need. If ACPI magic is needed, it should be called from inside that routine.

Yeah, I don't see that being a problem.

Except for not yet working that way! ;)

- Dave

#118 lore raw
In reply to Matthew Garrett
Quoted 8 lines · Matthew Garrett
Quoted 4 lines · David Brownell

I don't follow this at all. Most of the relevant devices have a PCI device driver, not an ACPI device driver. Surely you aren't proposing that PCI drivers should incorporate lots of ACPI-specific code (which won't be useful on non-ACPI platforms) before they start to work right?

PCI devices have a handle to their ACPI object in platform_data,

Good to know. I was under the impression that was still in the planning stage, not yet the working/reliable stage. But I do see some ACPI code doing that; maybe I'll take more of a look.

Quoted 2 lines

so it's
easy enough to have generic code that interacts with both objects.

Well, not really "generic" if it knows about ACPI. But at least not device-specific.

Quoted 5 lines
Quoted 3 lines

For a PCI device driver, pci_enable_wake() is all the hook that it should ever need. If ACPI magic is needed, it should be called from inside that routine.

Yeah, I don't see that being a problem.

Except for not yet working that way! ;)

- Dave

#119 lore raw
In reply to David Brownell
Quoted 4 lines · David Brownell

I don't follow this at all. Most of the relevant devices have a PCI device driver, not an ACPI device driver. Surely you aren't proposing that PCI drivers should incorporate lots of ACPI-specific code (which won't be useful on non-ACPI platforms) before they start to work right?

PCI devices have a handle to their ACPI object in platform_data, so it's easy enough to have generic code that interacts with both objects.

Quoted 3 lines

For a PCI device driver, pci_enable_wake() is all the hook that it should ever need. If ACPI magic is needed, it should be called from inside that routine.

Yeah, I don't see that being a problem.

Signature · 1 line
Matthew Garrett | [email protected]
#120 lore raw
In reply to David Brownell
Quoted 7 lines · David Brownell
Quoted 1 line · Zhang Rui

If a device is also described in ACPI namespace, it should know its

ACPI

Quoted 1 line

device node in sysfs.

What about PCI or PNP devices that have "shadow" listings in ACPI?

what do you mean "devices that have shadow listings in ACPI"? :) Sorry I'm not quite familiar with pci and pnp devices.

Quoted 8 lines
Quoted 1 line
Quoted 1 line

And while it seems that the three USB controllers on this system

show up

Quoted 1 line
Quoted 1 line

as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:

{01,02,03} I

Quoted 1 line
Quoted 1 line

have no idea which one is /sys/devices/pci0000:00/0000:00:02.2

versus

Quoted 1 line
Quoted 1 line

0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and

so

Quoted 9 lines
Quoted 1 line
Quoted 1 line

on (by reading "path"), but associating one with a PCI device

seems to

Quoted 4 lines
Quoted 1 line

involve pure guesswork.

Sorry to make you confused.
That's what we need to improve in the wish list. :)

Do you mean the "ACPI 4.0" wishlist? Or the "Linux ACPI" wishlist?

No, as part of the ACPI sysfs conversion work, it's just the things that are not finished now and I wish to do in the near future.

Thanks,
Rui

#121 lore raw
In reply to David Brownell
Quoted 7 lines · David Brownell
Quoted 1 line · Zhang Rui

If a device is also described in ACPI namespace, it should know its

ACPI

Quoted 1 line

device node in sysfs.

What about PCI or PNP devices that have "shadow" listings in ACPI?

what do you mean "devices that have shadow listings in ACPI"? :) Sorry I'm not quite familiar with pci and pnp devices.

Quoted 8 lines
Quoted 1 line
Quoted 1 line

And while it seems that the three USB controllers on this system

show up

Quoted 1 line
Quoted 1 line

as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:

{01,02,03} I

Quoted 1 line
Quoted 1 line

have no idea which one is /sys/devices/pci0000:00/0000:00:02.2

versus

Quoted 1 line
Quoted 1 line

0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and

so

Quoted 9 lines
Quoted 1 line
Quoted 1 line

on (by reading "path"), but associating one with a PCI device

seems to

Quoted 4 lines
Quoted 1 line

involve pure guesswork.

Sorry to make you confused.
That's what we need to improve in the wish list. :)

Do you mean the "ACPI 4.0" wishlist? Or the "Linux ACPI" wishlist?

No, as part of the ACPI sysfs conversion work, it's just the things that are not finished now and I wish to do in the near future.

Thanks,
Rui

#122 lore raw
In reply to Zhang Rui
Quoted 6 lines · Zhang Rui
Quoted 6 lines
Quoted 5 lines

The only other issue then, is how we could define and manage wakeup events for events that aren't associated with specific devices, like power button and lid events. We'll need some way to control those somewhere in sysfs - if not in /sys/power/wakeup like I had proposed, then somewhere under the platform or system hierarchy .

Quoted 7 lines
Quoted 4 lines

I see /sys/devices/acpi_system:00/button_power:00 on this system; and /sys/devices/acpi_system:00/device:00/PNP0C0D:00 has path \_SB_.LID_ ... such device nodes already exist, even though they're not really hooked up to anything much. Notably, their "wakeup" state is not initialized.

That's right.
This is meaningless now and we don't intend to use it in the future.

Why not? Exactly how do you anticipate ACPI exposing its wakeup capabilities, if it's not going to use the existing platform-neutral interface?

Quoted 2 lines

If a device is also described in ACPI namespace, it should know its ACPI device node in sysfs.

What about PCI or PNP devices that have "shadow" listings in ACPI?

Quoted 3 lines

Then when we want to enable/disable a deivce's wakeup ability, just goto the physical device node in sysfs. What we need is a hook offered by ACPI device driver.

I don't follow this at all. Most of the relevant devices have a PCI device driver, not an ACPI device driver. Surely you aren't proposing that PCI drivers should incorporate lots of ACPI-specific code (which won't be useful on non-ACPI platforms) before they start to work right?

For a PCI device driver, pci_enable_wake() is all the hook that it should ever need. If ACPI magic is needed, it should be called from inside that routine.

Quoted 9 lines
Quoted 6 lines

And while it seems that the three USB controllers on this system show up as /sys/devices/acpi_system:00/device:00/PNP0A03:00/device:{01,02,03} I have no idea which one is /sys/devices/pci0000:00/0000:00:02.2 versus 0000:00:02.1 or 0000:00:02.0 ... I know that USB0 is device:01 and so on (by reading "path"), but associating one with a PCI device seems to involve pure guesswork.

Sorry to make you confused.
That's what we need to improve in the wish list. :)

Do you mean the "ACPI 4.0" wishlist? Or the "Linux ACPI" wishlist?

- Dave

#123 lore raw
In reply to David Brownell
Quoted 19 lines
Quoted 10 lines

The Geode (and most other platforms, I presume) allows us to configure which wakeup events are actually allowed to wake the system. Currently, we are permanently enabling the power button as a wakeup source, but I want to eventually be able to pick and chose from any of our main wakeup sources:

* Power button
* RTC Alarm
* LID event (GPIO26)
* wake event from the EC (GPIO27)

Yes ...

Quoted 4 lines

Of the four, the only device that can actually be configured to do anything is the RTC alarm, and for that we would use the /sys/devices/../power/wakeup infrastructure, but we would still need something in place to allow the software to tell the hardware to enable the RTC event to wake the system.

Quoted 5 lines

As in "echo enabled > /sys/devices/.../power/wakeup" (to get the default), or "echo disabled > ..." to disable it. For PCs, with ACPI, that involves two patches I just posted to the RTC list (and CC'd Len on), and replacing the ancient/legacy/ACPI-only /proc/acpi/alarm interface.

That's great. :)
It would be better if you added [email protected] to the cc list.

Thanks,
Rui

#124 lore raw
In reply to Jordan Crouse
Quoted 7 lines · Jordan Crouse
Quoted 3 lines · David Brownell

USB once worked fine (I spent more than enough time testing it in all kinds of configs) but usbcore has changed a lot since then ... I hear that some of the root hub stuff got broken.

Marcelo is working hard on the USB. I'm sure he wouldn't say no if you offered your particular expertise on the matter. :)

Marcelo reported that he has USB working in his weekly report. I suspect you'll see patches shortly.
- Jim

Quoted 1 line
Signature · 2 lines
Jim Gettys
One Laptop Per Child
#125 lore raw
In reply to Jordan Crouse
Quoted 11 lines · Jordan Crouse

Hey all -

I'm happy to report that the OLPC power management effort is proceeding nicely. We have suspend to RAM functional, and the system is resuming back to the framebuffer console. We have the usual blips (USB), but those will be resolved in the fullness of time.

I am now turning my attention to handling wakeup events - in particular, events that we can set at run-time. My thoughts on the matter are detailed here:

Quoted 8 lines

http://wiki.laptop.org/go/Power_Management_Interface

I use the ACPI wakeup infrastructure as an example because a) it exists, and b) it works. However, it doesn't share nicely, and it is a /proc file, so I sat down and thought of a more /sysfs friendly and generic model. I did keep APCI in mind, figuring that if a generic framework was designed well enough, they could slowly transition over as well (which is why the ACPI list is CCed).

The ACPI sysfs conversion work is on the way. :)
And we'll develop a generic interface for wakeup events to replace /proc/acpi/wakeup.
Now a device may have two nodes in sysfs, one is the physical device node and another is the ACPI devices node. Take a PCI device for example, it's shown under /sys/devices/pci0000:00/...,
while /sys/devices/acpisystem:00/.../PNPOAO3:00/... stands for the same device. This is a mess.
And we will map the ACPI device node to the physical one, so that /sys/devices/pci0000:00/.../power/wakeup is the only one that we should take care of.
If we want to make it more friendly, we can add /sys/power/wakeup/ and create syslinks to all the devices that support wakeup attribute.

Thanks,
Rui