include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / char / hpet.c
index 2908a0e..9ded667 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/seq_file.h>
 #include <linux/bitops.h>
 #include <linux/clocksource.h>
+#include <linux/slab.h>
 
 #include <asm/current.h>
 #include <asm/uaccess.h>
@@ -46,7 +47,7 @@
 /*
  * The High Precision Event Timer driver.
  * This driver is closely modelled after the rtc.c driver.
- * http://www.intel.com/hardwaredesign/hpetspec.htm
+ * http://www.intel.com/hardwaredesign/hpetspec_1.pdf
  */
 #define        HPET_USER_FREQ  (64)
 #define        HPET_DRIFT      (500)
@@ -72,7 +73,7 @@ static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
 #ifdef CONFIG_IA64
 static void __iomem *hpet_mctr;
 
-static cycle_t read_hpet(void)
+static cycle_t read_hpet(struct clocksource *cs)
 {
        return (cycle_t)read_counter((void __iomem *)hpet_mctr);
 }
@@ -166,9 +167,8 @@ static irqreturn_t hpet_interrupt(int irq, void *data)
                unsigned long m, t;
 
                t = devp->hd_ireqfreq;
-               m = read_counter(&devp->hd_hpet->hpet_mc);
-               write_counter(t + m + devp->hd_hpets->hp_delta,
-                             &devp->hd_timer->hpet_compare);
+               m = read_counter(&devp->hd_timer->hpet_compare);
+               write_counter(t + m, &devp->hd_timer->hpet_compare);
        }
 
        if (devp->hd_flags & HPET_SHARED_IRQ)
@@ -216,15 +216,13 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
        else
                v &= ~0xffff;
 
-       for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
-               irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
-
-               if (irq >= NR_IRQS) {
+       for_each_set_bit(irq, &v, HPET_MAX_IRQ) {
+               if (irq >= nr_irqs) {
                        irq = HPET_MAX_IRQ;
                        break;
                }
 
-               gsi = acpi_register_gsi(irq, ACPI_LEVEL_SENSITIVE,
+               gsi = acpi_register_gsi(NULL, irq, ACPI_LEVEL_SENSITIVE,
                                        ACPI_ACTIVE_LOW);
                if (gsi > 0)
                        break;
@@ -427,9 +425,6 @@ static int hpet_release(struct inode *inode, struct file *file)
        if (irq)
                free_irq(irq, devp);
 
-       if (file->f_flags & FASYNC)
-               hpet_fasync(-1, file, 0);
-
        file->private_data = NULL;
        return 0;
 }
@@ -507,21 +502,25 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
        g = v | Tn_32MODE_CNF_MASK | Tn_INT_ENB_CNF_MASK;
 
        if (devp->hd_flags & HPET_PERIODIC) {
-               write_counter(t, &timer->hpet_compare);
                g |= Tn_TYPE_CNF_MASK;
-               v |= Tn_TYPE_CNF_MASK;
-               writeq(v, &timer->hpet_config);
-               v |= Tn_VAL_SET_CNF_MASK;
+               v |= Tn_TYPE_CNF_MASK | Tn_VAL_SET_CNF_MASK;
                writeq(v, &timer->hpet_config);
                local_irq_save(flags);
 
-               /* NOTE:  what we modify here is a hidden accumulator
+               /*
+                * NOTE: First we modify the hidden accumulator
                 * register supported by periodic-capable comparators.
                 * We never want to modify the (single) counter; that
-                * would affect all the comparators.
+                * would affect all the comparators. The value written
+                * is the counter value when the first interrupt is due.
                 */
                m = read_counter(&hpet->hpet_mc);
                write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
+               /*
+                * Then we modify the comparator, indicating the period
+                * for subsequent interrupt.
+                */
+               write_counter(t, &timer->hpet_compare);
        } else {
                local_irq_save(flags);
                m = read_counter(&hpet->hpet_mc);
@@ -675,36 +674,33 @@ static int hpet_is_known(struct hpet_data *hdp)
 
 static ctl_table hpet_table[] = {
        {
-        .ctl_name = CTL_UNNUMBERED,
         .procname = "max-user-freq",
         .data = &hpet_max_freq,
         .maxlen = sizeof(int),
         .mode = 0644,
-        .proc_handler = &proc_dointvec,
+        .proc_handler = proc_dointvec,
         },
-       {.ctl_name = 0}
+       {}
 };
 
 static ctl_table hpet_root[] = {
        {
-        .ctl_name = CTL_UNNUMBERED,
         .procname = "hpet",
         .maxlen = 0,
         .mode = 0555,
         .child = hpet_table,
         },
-       {.ctl_name = 0}
+       {}
 };
 
 static ctl_table dev_root[] = {
        {
-        .ctl_name = CTL_DEV,
         .procname = "dev",
         .maxlen = 0,
         .mode = 0555,
         .child = hpet_root,
         },
-       {.ctl_name = 0}
+       {}
 };
 
 static struct ctl_table_header *sysctl_header;
@@ -716,7 +712,7 @@ static struct ctl_table_header *sysctl_header;
  */
 #define        TICK_CALIBRATE  (1000UL)
 
-static unsigned long hpet_calibrate(struct hpets *hpetp)
+static unsigned long __hpet_calibrate(struct hpets *hpetp)
 {
        struct hpet_timer __iomem *timer = NULL;
        unsigned long t, m, count, i, flags, start;
@@ -753,6 +749,26 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
        return (m - start) / i;
 }
 
+static unsigned long hpet_calibrate(struct hpets *hpetp)
+{
+       unsigned long ret = -1;
+       unsigned long tmp;
+
+       /*
+        * Try to calibrate until return value becomes stable small value.
+        * If SMI interruption occurs in calibration loop, the return value
+        * will be big. This avoids its impact.
+        */
+       for ( ; ; ) {
+               tmp = __hpet_calibrate(hpetp);
+               if (ret <= tmp)
+                       break;
+               ret = tmp;
+       }
+
+       return ret;
+}
+
 int hpet_alloc(struct hpet_data *hdp)
 {
        u64 cap, mcfg;
@@ -897,8 +913,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
                hdp->hd_address = ioremap(addr.minimum, addr.address_length);
 
                if (hpet_is_known(hdp)) {
-                       printk(KERN_DEBUG "%s: 0x%lx is busy\n",
-                               __func__, hdp->hd_phys_address);
                        iounmap(hdp->hd_address);
                        return AE_ALREADY_EXISTS;
                }
@@ -914,8 +928,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
                                                HPET_RANGE_SIZE);
 
                if (hpet_is_known(hdp)) {
-                       printk(KERN_DEBUG "%s: 0x%lx is busy\n",
-                               __func__, hdp->hd_phys_address);
                        iounmap(hdp->hd_address);
                        return AE_ALREADY_EXISTS;
                }
@@ -926,7 +938,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
                irqp = &res->data.extended_irq;
 
                for (i = 0; i < irqp->interrupt_count; i++) {
-                       irq = acpi_register_gsi(irqp->interrupts[i],
+                       irq = acpi_register_gsi(NULL, irqp->interrupts[i],
                                      irqp->triggering, irqp->polarity);
                        if (irq < 0)
                                return AE_ERROR;