On Wednesday 28 March 2007 18:38:48 Linus Torvalds wrote: > > On Wed, 28 Mar 2007, Maxim wrote: > > > > Now I don't have a clue how to set those bits if only HPET is used as clock source because now clocksources > > don't have _any_ resume hook. > > One thing that drives me wild about that "clocksource resume" thing is > that it seems to think that clocksources are somehow different from any > other system devices.. > > Why isn't the HPET considered a "device", and has it's own *device* > "suspend" and "resume"? Why do we seem to think that only "set_mode()" > etc should wake up clock sources? > > It's a *device*, dammit. It should save and resume like one (probably as a > system device). The "set_mode()" etc stuff is at a completely different > (higher) conceptual level. > > Thomas? It does seem like Maxim has hit the nail on the head (at least > partly) on the HPET timer resume problems.. > > Linus > Hi, I am sending here a patch that as was discussed here adds hpet to list of system devices and adds suspend/resume hooks this way. I tested it and it works fine. --- Add suspend/resume support for HPET Signed-off-by: Maxim Levitsky <maximlevitsky@xxxxxxxxx> --- arch/i386/kernel/hpet.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 64 insertions(+), 0 deletions(-) diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c index 0fd9fba..ac41476 100644 --- a/arch/i386/kernel/hpet.c +++ b/arch/i386/kernel/hpet.c @@ -3,6 +3,8 @@ #include <linux/errno.h> #include <linux/hpet.h> #include <linux/init.h> +#include <linux/sysdev.h> +#include <linux/pm.h> #include <asm/hpet.h> #include <asm/io.h> @@ -524,3 +526,65 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } #endif + + +/* + * Suspend/resume part + */ + +#ifdef CONFIG_PM + +static int hpet_suspend(struct sys_device *sys_device, pm_message_t state) +{ + unsigned long cfg = hpet_readl(HPET_CFG); + + cfg &= ~(HPET_CFG_ENABLE|HPET_CFG_LEGACY); + hpet_writel(cfg, HPET_CFG); + + return 0; +} + +static int hpet_resume(struct sys_device *sys_device) +{ + unsigned int id; + + hpet_start_counter(); + + id = hpet_readl(HPET_ID); + + if (id & HPET_ID_LEGSUP) + hpet_enable_int(); + + return 0; +} + +static struct sysdev_class hpet_class = { + set_kset_name("hpet"), + .suspend = hpet_suspend, + .resume = hpet_resume, +}; + +static struct sys_device hpet_device = { + .id = 0, + .cls = &hpet_class, +}; + + +static __init int hpet_register_sysfs(void) +{ + int err; + + err = sysdev_class_register(&hpet_class); + + if (!err) { + sysdev_register(&hpet_device); + if (err) + sysdev_class_unregister(&hpet_class); + } + + return err; +} + +device_initcall(hpet_register_sysfs); + +#endif -- 1.4.4.2 - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html