|
@@ -166,9 +166,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)
|
|
@@ -504,21 +503,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);
|