aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/hpet.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/hpet.c')
-rw-r--r--drivers/char/hpet.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 4a9f3492b921..70a770ac0138 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -166,9 +166,8 @@ static irqreturn_t hpet_interrupt(int irq, void *data)
166 unsigned long m, t; 166 unsigned long m, t;
167 167
168 t = devp->hd_ireqfreq; 168 t = devp->hd_ireqfreq;
169 m = read_counter(&devp->hd_hpet->hpet_mc); 169 m = read_counter(&devp->hd_timer->hpet_compare);
170 write_counter(t + m + devp->hd_hpets->hp_delta, 170 write_counter(t + m, &devp->hd_timer->hpet_compare);
171 &devp->hd_timer->hpet_compare);
172 } 171 }
173 172
174 if (devp->hd_flags & HPET_SHARED_IRQ) 173 if (devp->hd_flags & HPET_SHARED_IRQ)
@@ -504,21 +503,25 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
504 g = v | Tn_32MODE_CNF_MASK | Tn_INT_ENB_CNF_MASK; 503 g = v | Tn_32MODE_CNF_MASK | Tn_INT_ENB_CNF_MASK;
505 504
506 if (devp->hd_flags & HPET_PERIODIC) { 505 if (devp->hd_flags & HPET_PERIODIC) {
507 write_counter(t, &timer->hpet_compare);
508 g |= Tn_TYPE_CNF_MASK; 506 g |= Tn_TYPE_CNF_MASK;
509 v |= Tn_TYPE_CNF_MASK; 507 v |= Tn_TYPE_CNF_MASK | Tn_VAL_SET_CNF_MASK;
510 writeq(v, &timer->hpet_config);
511 v |= Tn_VAL_SET_CNF_MASK;
512 writeq(v, &timer->hpet_config); 508 writeq(v, &timer->hpet_config);
513 local_irq_save(flags); 509 local_irq_save(flags);
514 510
515 /* NOTE: what we modify here is a hidden accumulator 511 /*
512 * NOTE: First we modify the hidden accumulator
516 * register supported by periodic-capable comparators. 513 * register supported by periodic-capable comparators.
517 * We never want to modify the (single) counter; that 514 * We never want to modify the (single) counter; that
518 * would affect all the comparators. 515 * would affect all the comparators. The value written
516 * is the counter value when the first interrupt is due.
519 */ 517 */
520 m = read_counter(&hpet->hpet_mc); 518 m = read_counter(&hpet->hpet_mc);
521 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); 519 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
520 /*
521 * Then we modify the comparator, indicating the period
522 * for subsequent interrupt.
523 */
524 write_counter(t, &timer->hpet_compare);
522 } else { 525 } else {
523 local_irq_save(flags); 526 local_irq_save(flags);
524 m = read_counter(&hpet->hpet_mc); 527 m = read_counter(&hpet->hpet_mc);