vserver 1.9.3
[linux-2.6.git] / arch / i386 / kernel / time_hpet.c
index a281711..52fc526 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/config.h>
 
 #include <asm/hpet.h>
+#include <linux/hpet.h>
 
 unsigned long hpet_period;     /* fsecs / HPET clock */
 unsigned long hpet_tick;       /* hpet clks count per tick */
@@ -28,7 +29,7 @@ unsigned long hpet_address;   /* hpet memory map physical address */
 
 static int use_hpet;           /* can be used for runtime check of hpet */
 static int boot_hpet_disable;  /* boottime override for HPET timer */
-static unsigned long hpet_virt_address;        /* hpet kernel virtual address */
+static void __iomem * hpet_virt_address;       /* hpet kernel virtual address */
 
 #define FSEC_TO_USEC (1000000000UL)
 
@@ -75,8 +76,7 @@ int __init hpet_enable(void)
        if (!hpet_address) {
                return -1;
        }
-       hpet_virt_address = (unsigned long) ioremap_nocache(hpet_address,
-                                                           HPET_MMAP_SIZE);
+       hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE);
        /*
         * Read the period, compute tick and quotient.
         */
@@ -135,6 +135,50 @@ int __init hpet_enable(void)
        hpet_writel(cfg, HPET_CFG);
 
        use_hpet = 1;
+
+#ifdef CONFIG_HPET
+       {
+               struct hpet_data        hd;
+               unsigned int            ntimer;
+
+               memset(&hd, 0, sizeof (hd));
+
+               ntimer = hpet_readl(HPET_ID);
+               ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
+               ntimer++;
+
+               /*
+                * Register with driver.
+                * Timer0 and Timer1 is used by platform.
+                */
+               hd.hd_address = hpet_virt_address;
+               hd.hd_nirqs = ntimer;
+               hd.hd_flags = HPET_DATA_PLATFORM;
+               hpet_reserve_timer(&hd, 0);
+#ifdef CONFIG_HPET_EMULATE_RTC
+               hpet_reserve_timer(&hd, 1);
+#endif
+               hd.hd_irq[0] = HPET_LEGACY_8254;
+               hd.hd_irq[1] = HPET_LEGACY_RTC;
+               if (ntimer > 2) {
+                       struct hpet __iomem     *hpet;
+                       struct hpet_timer __iomem *timer;
+                       int                     i;
+
+                       hpet = hpet_virt_address;
+
+                       for (i = 2, timer = &hpet->hpet_timers[2]; i < ntimer;
+                               timer++, i++)
+                               hd.hd_irq[i] = (timer->hpet_config &
+                                       Tn_INT_ROUTE_CNF_MASK) >>
+                                       Tn_INT_ROUTE_CNF_SHIFT;
+
+               }
+
+               hpet_alloc(&hd);
+       }
+#endif
+
 #ifdef CONFIG_X86_LOCAL_APIC
        wait_timer_tick = wait_hpet_tick;
 #endif