|
@@ -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>
|
|
@@ -307,6 +309,7 @@ int __init hpet_enable(void)
|
|
|
out_nohpet:
|
|
|
iounmap(hpet_virt_address);
|
|
|
hpet_virt_address = NULL;
|
|
|
+ boot_hpet_disable = 1;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -521,3 +524,68 @@ 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;
|
|
|
+
|
|
|
+ if (!is_hpet_capable())
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ err = sysdev_class_register(&hpet_class);
|
|
|
+
|
|
|
+ if (!err) {
|
|
|
+ err = sysdev_register(&hpet_device);
|
|
|
+ if (err)
|
|
|
+ sysdev_class_unregister(&hpet_class);
|
|
|
+ }
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
+device_initcall(hpet_register_sysfs);
|
|
|
+
|
|
|
+#endif
|