This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / char / hpet.c
1 /*
2  * Intel & MS High Precision Event Timer Implementation.
3  * Contributors:
4  *      Venki Pallipadi
5  *      Bob Picco
6  */
7
8 #include <linux/config.h>
9 #include <linux/interrupt.h>
10 #include <linux/module.h>
11 #include <linux/kernel.h>
12 #include <linux/types.h>
13 #include <linux/miscdevice.h>
14 #include <linux/major.h>
15 #include <linux/ioport.h>
16 #include <linux/fcntl.h>
17 #include <linux/init.h>
18 #include <linux/poll.h>
19 #include <linux/proc_fs.h>
20 #include <linux/spinlock.h>
21 #include <linux/sysctl.h>
22 #include <linux/wait.h>
23 #include <linux/bcd.h>
24 #include <linux/seq_file.h>
25
26 #include <asm/current.h>
27 #include <asm/uaccess.h>
28 #include <asm/system.h>
29 #include <asm/io.h>
30 #include <asm/irq.h>
31 #include <asm/bitops.h>
32 #include <asm/div64.h>
33
34 #include <linux/acpi.h>
35 #include <acpi/acpi_bus.h>
36 #include <linux/hpet.h>
37
38 /*
39  * The High Precision Event Timer driver.
40  * This driver is closely modelled after the rtc.c driver.
41  * http://www.intel.com/labs/platcomp/hpet/hpetspec.htm
42  */
43 #define HPET_USER_FREQ  (64)
44 #define HPET_DRIFT      (500)
45
46 static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
47
48 /* A lock for concurrent access by app and isr hpet activity. */
49 static spinlock_t hpet_lock = SPIN_LOCK_UNLOCKED;
50 /* A lock for concurrent intermodule access to hpet and isr hpet activity. */
51 static spinlock_t hpet_task_lock = SPIN_LOCK_UNLOCKED;
52
53 struct hpet_dev {
54         struct hpets *hd_hpets;
55         struct hpet *hd_hpet;
56         struct hpet_timer *hd_timer;
57         unsigned long hd_ireqfreq;
58         unsigned long hd_irqdata;
59         wait_queue_head_t hd_waitqueue;
60         struct fasync_struct *hd_async_queue;
61         struct hpet_task *hd_task;
62         unsigned int hd_flags;
63         unsigned int hd_irq;
64         unsigned int hd_hdwirq;
65 };
66
67 struct hpets {
68         struct hpets *hp_next;
69         struct hpet *hp_hpet;
70         unsigned long hp_period;
71         unsigned long hp_delta;
72         unsigned int hp_ntimer;
73         unsigned int hp_which;
74         struct hpet_dev hp_dev[1];
75 };
76
77 static struct hpets *hpets;
78
79 #define HPET_OPEN               0x0001
80 #define HPET_IE                 0x0002  /* interrupt enabled */
81 #define HPET_PERIODIC           0x0004
82
83 #if BITS_PER_LONG == 64
84 #define write_counter(V, MC)    writeq(V, MC)
85 #define read_counter(MC)        readq(MC)
86 #else
87 #define write_counter(V, MC)    writel(V, MC)
88 #define read_counter(MC)        readl(MC)
89 #endif
90
91 #ifndef readq
92 static unsigned long long __inline readq(void *addr)
93 {
94         return readl(addr) | (((unsigned long long)readl(addr + 4)) << 32LL);
95 }
96 #endif
97
98 #ifndef writeq
99 static void __inline writeq(unsigned long long v, void *addr)
100 {
101         writel(v & 0xffffffff, addr);
102         writel(v >> 32, addr + 4);
103 }
104 #endif
105
106 static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs)
107 {
108         struct hpet_dev *devp;
109         unsigned long isr;
110
111         devp = data;
112
113         spin_lock(&hpet_lock);
114         devp->hd_irqdata++;
115
116         /*
117          * For non-periodic timers, increment the accumulator.
118          * This has the effect of treating non-periodic like periodic.
119          */
120         if ((devp->hd_flags & (HPET_IE | HPET_PERIODIC)) == HPET_IE) {
121                 unsigned long m, t;
122
123                 t = devp->hd_ireqfreq;
124                 m = read_counter(&devp->hd_hpet->hpet_mc);
125                 write_counter(t + m + devp->hd_hpets->hp_delta,
126                               &devp->hd_timer->hpet_compare);
127         }
128
129         isr = (1 << (devp - devp->hd_hpets->hp_dev));
130         writeq(isr, &devp->hd_hpet->hpet_isr);
131         spin_unlock(&hpet_lock);
132
133         spin_lock(&hpet_task_lock);
134         if (devp->hd_task)
135                 devp->hd_task->ht_func(devp->hd_task->ht_data);
136         spin_unlock(&hpet_task_lock);
137
138         wake_up_interruptible(&devp->hd_waitqueue);
139
140         kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN);
141
142         return IRQ_HANDLED;
143 }
144
145 static int hpet_open(struct inode *inode, struct file *file)
146 {
147         struct hpet_dev *devp;
148         struct hpets *hpetp;
149         int i;
150
151         spin_lock_irq(&hpet_lock);
152
153         for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
154                 for (i = 0; i < hpetp->hp_ntimer; i++)
155                         if (hpetp->hp_dev[i].hd_flags & HPET_OPEN
156                             || hpetp->hp_dev[i].hd_task)
157                                 continue;
158                         else {
159                                 devp = &hpetp->hp_dev[i];
160                                 break;
161                         }
162
163         if (!devp) {
164                 spin_unlock_irq(&hpet_lock);
165                 return -EBUSY;
166         }
167
168         file->private_data = devp;
169         devp->hd_irqdata = 0;
170         devp->hd_flags |= HPET_OPEN;
171         spin_unlock_irq(&hpet_lock);
172
173         return 0;
174 }
175
176 static ssize_t
177 hpet_read(struct file *file, char *buf, size_t count, loff_t * ppos)
178 {
179         DECLARE_WAITQUEUE(wait, current);
180         unsigned long data;
181         ssize_t retval;
182         struct hpet_dev *devp;
183
184         devp = file->private_data;
185         if (!devp->hd_ireqfreq)
186                 return -EIO;
187
188         if (count < sizeof(unsigned long))
189                 return -EINVAL;
190
191         add_wait_queue(&devp->hd_waitqueue, &wait);
192
193         do {
194                 __set_current_state(TASK_INTERRUPTIBLE);
195
196                 spin_lock_irq(&hpet_lock);
197                 data = devp->hd_irqdata;
198                 devp->hd_irqdata = 0;
199                 spin_unlock_irq(&hpet_lock);
200
201                 if (data)
202                         break;
203                 else if (file->f_flags & O_NONBLOCK) {
204                         retval = -EAGAIN;
205                         goto out;
206                 } else if (signal_pending(current)) {
207                         retval = -ERESTARTSYS;
208                         goto out;
209                 }
210
211                 schedule();
212
213         } while (1);
214
215         retval = put_user(data, (unsigned long *)buf);
216         if (!retval)
217                 retval = sizeof(unsigned long);
218       out:
219         current->state = TASK_RUNNING;
220         remove_wait_queue(&devp->hd_waitqueue, &wait);
221
222         return retval;
223 }
224
225 static unsigned int hpet_poll(struct file *file, poll_table * wait)
226 {
227         unsigned long v;
228         struct hpet_dev *devp;
229
230         devp = file->private_data;
231
232         if (!devp->hd_ireqfreq)
233                 return 0;
234
235         poll_wait(file, &devp->hd_waitqueue, wait);
236
237         spin_lock_irq(&hpet_lock);
238         v = devp->hd_irqdata;
239         spin_unlock_irq(&hpet_lock);
240
241         if (v != 0)
242                 return POLLIN | POLLRDNORM;
243
244         return 0;
245 }
246
247 static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
248 {
249 #ifdef  CONFIG_HPET_NOMMAP
250         return -ENOSYS;
251 #else
252         struct hpet_dev *devp;
253         unsigned long addr;
254
255         if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff)
256                 return -EINVAL;
257
258         if (vma->vm_flags & VM_WRITE)
259                 return -EPERM;
260
261         devp = file->private_data;
262         addr = (unsigned long)devp->hd_hpet;
263
264         if (addr & (PAGE_SIZE - 1))
265                 return -ENOSYS;
266
267         vma->vm_flags |= VM_IO;
268         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
269         addr = __pa(addr);
270
271         if (remap_page_range
272             (vma, vma->vm_start, addr, PAGE_SIZE, vma->vm_page_prot)) {
273                 printk(KERN_ERR "remap_page_range failed in hpet.c\n");
274                 return -EAGAIN;
275         }
276
277         return 0;
278 #endif
279 }
280
281 static int hpet_fasync(int fd, struct file *file, int on)
282 {
283         struct hpet_dev *devp;
284
285         devp = file->private_data;
286
287         if (fasync_helper(fd, file, on, &devp->hd_async_queue) >= 0)
288                 return 0;
289         else
290                 return -EIO;
291 }
292
293 static int hpet_release(struct inode *inode, struct file *file)
294 {
295         struct hpet_dev *devp;
296         struct hpet_timer *timer;
297         int irq = 0;
298
299         devp = file->private_data;
300         timer = devp->hd_timer;
301
302         spin_lock_irq(&hpet_lock);
303
304         writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK),
305                &timer->hpet_config);
306
307         irq = devp->hd_irq;
308         devp->hd_irq = 0;
309
310         devp->hd_ireqfreq = 0;
311
312         if (devp->hd_flags & HPET_PERIODIC
313             && readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) {
314                 unsigned long v;
315
316                 v = readq(&timer->hpet_config);
317                 v ^= Tn_TYPE_CNF_MASK;
318                 writeq(v, &timer->hpet_config);
319         }
320
321         devp->hd_flags &= ~(HPET_OPEN | HPET_IE | HPET_PERIODIC);
322         spin_unlock_irq(&hpet_lock);
323
324         if (irq)
325                 free_irq(irq, devp);
326
327         if (file->f_flags & FASYNC)
328                 hpet_fasync(-1, file, 0);
329
330         file->private_data = 0;
331         return 0;
332 }
333
334 static int hpet_ioctl_common(struct hpet_dev *, int, unsigned long, int);
335
336 static int
337 hpet_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
338            unsigned long arg)
339 {
340         struct hpet_dev *devp;
341
342         devp = file->private_data;
343         return hpet_ioctl_common(devp, cmd, arg, 0);
344 }
345
346 static int hpet_ioctl_ieon(struct hpet_dev *devp)
347 {
348         struct hpet_timer *timer;
349         struct hpet *hpet;
350         struct hpets *hpetp;
351         int irq;
352         unsigned long g, v, t, m;
353         unsigned long flags, isr;
354
355         timer = devp->hd_timer;
356         hpet = devp->hd_hpet;
357         hpetp = devp->hd_hpets;
358
359         v = readq(&timer->hpet_config);
360         spin_lock_irq(&hpet_lock);
361
362         if (devp->hd_flags & HPET_IE) {
363                 spin_unlock_irq(&hpet_lock);
364                 return -EBUSY;
365         }
366
367         devp->hd_flags |= HPET_IE;
368         spin_unlock_irq(&hpet_lock);
369
370         t = readq(&timer->hpet_config);
371         irq = devp->hd_hdwirq;
372
373         if (irq) {
374                 char name[7];
375
376                 sprintf(name, "hpet%d", (int)(devp - hpetp->hp_dev));
377
378                 if (request_irq
379                     (irq, hpet_interrupt, SA_INTERRUPT, name, (void *)devp)) {
380                         printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
381                         irq = 0;
382                 }
383         }
384
385         if (irq == 0) {
386                 spin_lock_irq(&hpet_lock);
387                 devp->hd_flags ^= HPET_IE;
388                 spin_unlock_irq(&hpet_lock);
389                 return -EIO;
390         }
391
392         devp->hd_irq = irq;
393         t = devp->hd_ireqfreq;
394         v = readq(&timer->hpet_config);
395         g = v | Tn_INT_ENB_CNF_MASK;
396
397         if (devp->hd_flags & HPET_PERIODIC) {
398                 write_counter(t, &timer->hpet_compare);
399                 g |= Tn_TYPE_CNF_MASK;
400                 v |= Tn_TYPE_CNF_MASK;
401                 writeq(v, &timer->hpet_config);
402                 v |= Tn_VAL_SET_CNF_MASK;
403                 writeq(v, &timer->hpet_config);
404                 local_irq_save(flags);
405                 m = read_counter(&hpet->hpet_mc);
406                 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
407         } else {
408                 local_irq_save(flags);
409                 m = read_counter(&hpet->hpet_mc);
410                 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
411         }
412
413         isr = (1 << (devp - hpets->hp_dev));
414         writeq(isr, &hpet->hpet_isr);
415         writeq(g, &timer->hpet_config);
416         local_irq_restore(flags);
417
418         return 0;
419 }
420
421 static inline unsigned long hpet_time_div(unsigned long dis)
422 {
423         unsigned long long m = 1000000000000000ULL;
424
425         do_div(m, dis);
426
427         return (unsigned long)m;
428 }
429
430 static int
431 hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
432 {
433         struct hpet_timer *timer;
434         struct hpet *hpet;
435         struct hpets *hpetp;
436         int err;
437         unsigned long v;
438
439         switch (cmd) {
440         case HPET_IE_OFF:
441         case HPET_INFO:
442         case HPET_EPI:
443         case HPET_DPI:
444         case HPET_IRQFREQ:
445                 timer = devp->hd_timer;
446                 hpet = devp->hd_hpet;
447                 hpetp = devp->hd_hpets;
448                 break;
449         case HPET_IE_ON:
450                 return hpet_ioctl_ieon(devp);
451         default:
452                 return -EINVAL;
453         }
454
455         err = 0;
456
457         switch (cmd) {
458         case HPET_IE_OFF:
459                 if ((devp->hd_flags & HPET_IE) == 0)
460                         break;
461                 v = readq(&timer->hpet_config);
462                 v &= ~Tn_INT_ENB_CNF_MASK;
463                 writeq(v, &timer->hpet_config);
464                 if (devp->hd_irq) {
465                         free_irq(devp->hd_irq, devp);
466                         devp->hd_irq = 0;
467                 }
468                 devp->hd_flags ^= HPET_IE;
469                 break;
470         case HPET_INFO:
471                 {
472                         struct hpet_info info;
473
474                         info.hi_ireqfreq = hpet_time_div(hpetp->hp_period *
475                                                          devp->hd_ireqfreq);
476                         info.hi_flags =
477                             readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK;
478                         info.hi_hpet = devp->hd_hpets->hp_which;
479                         info.hi_timer = devp - devp->hd_hpets->hp_dev;
480                         if (copy_to_user((void *)arg, &info, sizeof(info)))
481                                 err = -EFAULT;
482                         break;
483                 }
484         case HPET_EPI:
485                 v = readq(&timer->hpet_config);
486                 if ((v & Tn_PER_INT_CAP_MASK) == 0) {
487                         err = -ENXIO;
488                         break;
489                 }
490                 devp->hd_flags |= HPET_PERIODIC;
491                 break;
492         case HPET_DPI:
493                 v = readq(&timer->hpet_config);
494                 if ((v & Tn_PER_INT_CAP_MASK) == 0) {
495                         err = -ENXIO;
496                         break;
497                 }
498                 if (devp->hd_flags & HPET_PERIODIC &&
499                     readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) {
500                         v = readq(&timer->hpet_config);
501                         v ^= Tn_TYPE_CNF_MASK;
502                         writeq(v, &timer->hpet_config);
503                 }
504                 devp->hd_flags &= ~HPET_PERIODIC;
505                 break;
506         case HPET_IRQFREQ:
507                 if (!kernel && (arg > hpet_max_freq) &&
508                     !capable(CAP_SYS_RESOURCE)) {
509                         err = -EACCES;
510                         break;
511                 }
512
513                 if (arg & (arg - 1)) {
514                         err = -EINVAL;
515                         break;
516                 }
517
518                 devp->hd_ireqfreq = hpet_time_div(hpetp->hp_period * arg);
519         }
520
521         return err;
522 }
523
524 static struct file_operations hpet_fops = {
525         .owner = THIS_MODULE,
526         .llseek = no_llseek,
527         .read = hpet_read,
528         .poll = hpet_poll,
529         .ioctl = hpet_ioctl,
530         .open = hpet_open,
531         .release = hpet_release,
532         .fasync = hpet_fasync,
533         .mmap = hpet_mmap,
534 };
535
536 EXPORT_SYMBOL(hpet_alloc);
537 EXPORT_SYMBOL(hpet_register);
538 EXPORT_SYMBOL(hpet_unregister);
539 EXPORT_SYMBOL(hpet_control);
540
541 int hpet_register(struct hpet_task *tp, int periodic)
542 {
543         unsigned int i;
544         u64 mask;
545         struct hpet_timer *timer;
546         struct hpet_dev *devp;
547         struct hpets *hpetp;
548
549         switch (periodic) {
550         case 1:
551                 mask = Tn_PER_INT_CAP_MASK;
552                 break;
553         case 0:
554                 mask = 0;
555                 break;
556         default:
557                 return -EINVAL;
558         }
559
560         spin_lock_irq(&hpet_task_lock);
561         spin_lock(&hpet_lock);
562
563         for (devp = 0, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
564                 for (timer = hpetp->hp_hpet->hpet_timers, i = 0;
565                      i < hpetp->hp_ntimer; i++, timer++) {
566                         if ((readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK)
567                             != mask)
568                                 continue;
569
570                         devp = &hpetp->hp_dev[i];
571
572                         if (devp->hd_flags & HPET_OPEN || devp->hd_task) {
573                                 devp = 0;
574                                 continue;
575                         }
576
577                         tp->ht_opaque = devp;
578                         devp->hd_task = tp;
579                         break;
580                 }
581
582         spin_unlock(&hpet_lock);
583         spin_unlock_irq(&hpet_task_lock);
584
585         if (tp->ht_opaque)
586                 return 0;
587         else
588                 return -EBUSY;
589 }
590
591 static inline int hpet_tpcheck(struct hpet_task *tp)
592 {
593         struct hpet_dev *devp;
594         struct hpets *hpetp;
595
596         devp = tp->ht_opaque;
597
598         if (!devp)
599                 return -ENXIO;
600
601         for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
602                 if (devp >= hpetp->hp_dev
603                     && devp < (hpetp->hp_dev + hpetp->hp_ntimer)
604                     && devp->hd_hpet == hpetp->hp_hpet)
605                         return 0;
606
607         return -ENXIO;
608 }
609
610 int hpet_unregister(struct hpet_task *tp)
611 {
612         struct hpet_dev *devp;
613         struct hpet_timer *timer;
614         int err;
615
616         if ((err = hpet_tpcheck(tp)))
617                 return err;
618
619         spin_lock_irq(&hpet_task_lock);
620         spin_lock(&hpet_lock);
621
622         devp = tp->ht_opaque;
623         if (devp->hd_task != tp) {
624                 spin_unlock(&hpet_lock);
625                 spin_unlock_irq(&hpet_task_lock);
626                 return -ENXIO;
627         }
628
629         timer = devp->hd_timer;
630         writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK),
631                &timer->hpet_config);
632         devp->hd_flags &= ~(HPET_IE | HPET_PERIODIC);
633         devp->hd_task = 0;
634         spin_unlock(&hpet_lock);
635         spin_unlock_irq(&hpet_task_lock);
636
637         return 0;
638 }
639
640 int hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg)
641 {
642         struct hpet_dev *devp;
643         int err;
644
645         if ((err = hpet_tpcheck(tp)))
646                 return err;
647
648         spin_lock_irq(&hpet_lock);
649         devp = tp->ht_opaque;
650         if (devp->hd_task != tp) {
651                 spin_unlock_irq(&hpet_lock);
652                 return -ENXIO;
653         }
654         spin_unlock_irq(&hpet_lock);
655         return hpet_ioctl_common(devp, cmd, arg, 1);
656 }
657
658 #ifdef  CONFIG_TIME_INTERPOLATION
659
660 static unsigned long hpet_offset, last_wall_hpet;
661 static long hpet_nsecs_per_cycle, hpet_cycles_per_sec;
662
663 static unsigned long hpet_getoffset(void)
664 {
665         return hpet_offset + (read_counter(&hpets->hp_hpet->hpet_mc) -
666                               last_wall_hpet) * hpet_nsecs_per_cycle;
667 }
668
669 static void hpet_update(long delta)
670 {
671         unsigned long mc;
672         unsigned long offset;
673
674         mc = read_counter(&hpets->hp_hpet->hpet_mc);
675         offset = hpet_offset + (mc - last_wall_hpet) * hpet_nsecs_per_cycle;
676
677         if (delta < 0 || (unsigned long)delta < offset)
678                 hpet_offset = offset - delta;
679         else
680                 hpet_offset = 0;
681         last_wall_hpet = mc;
682 }
683
684 static void hpet_reset(void)
685 {
686         hpet_offset = 0;
687         last_wall_hpet = read_counter(&hpets->hp_hpet->hpet_mc);
688 }
689
690 static struct time_interpolator hpet_interpolator = {
691         .get_offset = hpet_getoffset,
692         .update = hpet_update,
693         .reset = hpet_reset
694 };
695
696 #endif
697
698 static ctl_table hpet_table[] = {
699         {
700          .ctl_name = 1,
701          .procname = "max-user-freq",
702          .data = &hpet_max_freq,
703          .maxlen = sizeof(int),
704          .mode = 0644,
705          .proc_handler = &proc_dointvec,
706          },
707         {.ctl_name = 0}
708 };
709
710 static ctl_table hpet_root[] = {
711         {
712          .ctl_name = 1,
713          .procname = "hpet",
714          .maxlen = 0,
715          .mode = 0555,
716          .child = hpet_table,
717          },
718         {.ctl_name = 0}
719 };
720
721 static ctl_table dev_root[] = {
722         {
723          .ctl_name = CTL_DEV,
724          .procname = "dev",
725          .maxlen = 0,
726          .mode = 0555,
727          .child = hpet_root,
728          },
729         {.ctl_name = 0}
730 };
731
732 static struct ctl_table_header *sysctl_header;
733
734 static void *hpet_start(struct seq_file *s, loff_t * pos)
735 {
736         struct hpets *hpetp;
737         loff_t n;
738
739         for (n = *pos, hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
740                 if (!n--)
741                         return hpetp;
742
743         return 0;
744 }
745
746 static void *hpet_next(struct seq_file *s, void *v, loff_t * pos)
747 {
748         struct hpets *hpetp;
749
750         hpetp = v;
751         ++*pos;
752         return hpetp->hp_next;
753 }
754
755 static void hpet_stop(struct seq_file *s, void *v)
756 {
757         return;
758 }
759
760 static int hpet_show(struct seq_file *s, void *v)
761 {
762         struct hpets *hpetp;
763         struct hpet *hpet;
764         u64 cap, vendor, period;
765
766         hpetp = v;
767         hpet = hpetp->hp_hpet;
768
769         cap = readq(&hpet->hpet_cap);
770         period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
771             HPET_COUNTER_CLK_PERIOD_SHIFT;
772         vendor = (cap & HPET_VENDOR_ID_MASK) >> HPET_VENDOR_ID_SHIFT;
773
774         seq_printf(s,
775                    "HPET%d period = %d 10**-15  vendor = 0x%x number timer = %d\n",
776                    hpetp->hp_which, (u32) period, (u32) vendor,
777                    hpetp->hp_ntimer);
778
779         return 0;
780 }
781
782 static struct seq_operations hpet_seq_ops = {
783         .start = hpet_start,
784         .next = hpet_next,
785         .stop = hpet_stop,
786         .show = hpet_show
787 };
788
789 static int hpet_proc_open(struct inode *inode, struct file *file)
790 {
791         return seq_open(file, &hpet_seq_ops);
792 }
793
794 static struct file_operations hpet_proc_fops = {
795         .open = hpet_proc_open,
796         .read = seq_read,
797         .llseek = seq_lseek,
798         .release = seq_release
799 };
800
801 /*
802  * Adjustment for when arming the timer with
803  * initial conditions.  That is, main counter
804  * ticks expired before interrupts are enabled.
805  */
806 #define TICK_CALIBRATE  (1000UL)
807
808 static unsigned long __init hpet_calibrate(struct hpets *hpetp)
809 {
810         struct hpet_timer *timer;
811         unsigned long t, m, count, i, flags, start;
812         struct hpet_dev *devp;
813         int j;
814         struct hpet *hpet;
815
816         for (timer = 0, j = 0, devp = hpetp->hp_dev; j < hpetp->hp_ntimer;
817              j++, devp++)
818                 if ((devp->hd_flags & HPET_OPEN) == 0) {
819                         timer = devp->hd_timer;
820                         break;
821                 }
822
823         if (!timer)
824                 return 0;
825
826         hpet = hpets->hp_hpet;
827         t = read_counter(&timer->hpet_compare);
828
829         i = 0;
830         count = hpet_time_div(hpetp->hp_period * TICK_CALIBRATE);
831
832         local_irq_save(flags);
833
834         start = read_counter(&hpet->hpet_mc);
835
836         do {
837                 m = read_counter(&hpet->hpet_mc);
838                 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
839         } while (i++, (m - start) < count);
840
841         local_irq_restore(flags);
842
843         return (m - start) / i;
844 }
845
846 int __init hpet_alloc(struct hpet_data *hdp)
847 {
848         u64 cap, mcfg;
849         struct hpet_dev *devp;
850         u32 i, ntimer;
851         struct hpets *hpetp;
852         size_t siz;
853         struct hpet *hpet;
854         static struct hpets *last __initdata = (struct hpets *)0;
855
856         /*
857          * hpet_alloc can be called by platform dependent code.
858          * if platform dependent code has allocated the hpet
859          * ACPI also reports hpet, then we catch it here.
860          */
861         for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
862                 if (hpetp->hp_hpet == (struct hpet *)(hdp->hd_address))
863                         return 0;
864
865         siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
866                                       sizeof(struct hpet_dev));
867
868         hpetp = kmalloc(siz, GFP_KERNEL);
869
870         if (!hpetp)
871                 return -ENOMEM;
872
873         memset(hpetp, 0, siz);
874
875         hpetp->hp_which = hpet_nhpet++;
876         hpetp->hp_hpet = (struct hpet *)hdp->hd_address;
877
878         hpetp->hp_ntimer = hdp->hd_nirqs;
879
880         for (i = 0; i < hdp->hd_nirqs; i++)
881                 hpetp->hp_dev[i].hd_hdwirq = hdp->hd_irq[i];
882
883         hpet = hpetp->hp_hpet;
884
885         cap = readq(&hpet->hpet_cap);
886
887         ntimer = ((cap & HPET_NUM_TIM_CAP_MASK) >> HPET_NUM_TIM_CAP_SHIFT) + 1;
888
889         if (hpetp->hp_ntimer != ntimer) {
890                 printk(KERN_WARNING "hpet: number irqs doesn't agree"
891                        " with number of timers\n");
892                 kfree(hpetp);
893                 return -ENODEV;
894         }
895
896         if (last)
897                 last->hp_next = hpetp;
898         else
899                 hpets = hpetp;
900
901         last = hpetp;
902
903         hpetp->hp_period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
904             HPET_COUNTER_CLK_PERIOD_SHIFT;
905
906         mcfg = readq(&hpet->hpet_config);
907         if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) {
908                 write_counter(0L, &hpet->hpet_mc);
909                 mcfg |= HPET_ENABLE_CNF_MASK;
910                 writeq(mcfg, &hpet->hpet_config);
911         }
912
913         for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer;
914              i++, hpet_ntimer++, devp++) {
915                 unsigned long v;
916                 struct hpet_timer *timer;
917
918                 timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
919                 v = readq(&timer->hpet_config);
920
921                 devp->hd_hpets = hpetp;
922                 devp->hd_hpet = hpet;
923                 devp->hd_timer = timer;
924
925                 /*
926                  * If the timer was reserved by platform code,
927                  * then make timer unavailable for opens.
928                  */
929                 if (hdp->hd_state & (1 << i)) {
930                         devp->hd_flags = HPET_OPEN;
931                         continue;
932                 }
933
934                 init_waitqueue_head(&devp->hd_waitqueue);
935         }
936
937         hpetp->hp_delta = hpet_calibrate(hpetp);
938
939         return 0;
940 }
941
942 static acpi_status __init hpet_resources(struct acpi_resource *res, void *data)
943 {
944         struct hpet_data *hdp;
945         acpi_status status;
946         struct acpi_resource_address64 addr;
947         struct hpets *hpetp;
948
949         hdp = data;
950
951         status = acpi_resource_to_address64(res, &addr);
952
953         if (ACPI_SUCCESS(status)) {
954                 unsigned long size;
955
956                 size = addr.max_address_range - addr.min_address_range + 1;
957                 hdp->hd_address =
958                     (unsigned long)ioremap(addr.min_address_range, size);
959
960                 for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
961                         if (hpetp->hp_hpet == (struct hpet *)(hdp->hd_address))
962                                 return -EBUSY;
963         } else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
964                 struct acpi_resource_ext_irq *irqp;
965                 int i;
966
967                 irqp = &res->data.extended_irq;
968
969                 if (irqp->number_of_interrupts > 0) {
970                         hdp->hd_nirqs = irqp->number_of_interrupts;
971
972                         for (i = 0; i < hdp->hd_nirqs; i++)
973 #ifdef  CONFIG_IA64
974                                 hdp->hd_irq[i] =
975                                     acpi_register_gsi(irqp->interrupts[i],
976                                                       irqp->edge_level,
977                                                       irqp->active_high_low);
978 #else
979                                 hdp->hd_irq[i] = irqp->interrupts[i];
980 #endif
981                 }
982         }
983
984         return AE_OK;
985 }
986
987 static int __init hpet_acpi_add(struct acpi_device *device)
988 {
989         acpi_status result;
990         struct hpet_data data;
991
992         memset(&data, 0, sizeof(data));
993
994         result =
995             acpi_walk_resources(device->handle, METHOD_NAME__CRS,
996                                 hpet_resources, &data);
997
998         if (ACPI_FAILURE(result))
999                 return -ENODEV;
1000
1001         if (!data.hd_address || !data.hd_nirqs) {
1002                 printk("%s: no address or irqs in _CRS\n", __FUNCTION__);
1003                 return -ENODEV;
1004         }
1005
1006         return hpet_alloc(&data);
1007 }
1008
1009 static int __init hpet_acpi_remove(struct acpi_device *device, int type)
1010 {
1011         return 0;
1012 }
1013
1014 static struct acpi_driver hpet_acpi_driver __initdata = {
1015         .name = "hpet",
1016         .class = "",
1017         .ids = "PNP0103",
1018         .ops = {
1019                 .add = hpet_acpi_add,
1020                 .remove = hpet_acpi_remove,
1021                 },
1022 };
1023
1024 static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
1025
1026 static int __init hpet_init(void)
1027 {
1028         struct proc_dir_entry *entry;
1029
1030         (void)acpi_bus_register_driver(&hpet_acpi_driver);
1031
1032         if (hpets) {
1033                 if (misc_register(&hpet_misc))
1034                         return -ENODEV;
1035
1036                 entry = create_proc_entry("driver/hpet", 0, 0);
1037
1038                 if (entry)
1039                         entry->proc_fops = &hpet_proc_fops;
1040
1041                 sysctl_header = register_sysctl_table(dev_root, 0);
1042
1043 #ifdef  CONFIG_TIME_INTERPOLATION
1044                 {
1045                         struct hpet *hpet;
1046
1047                         hpet = hpets->hp_hpet;
1048                         hpet_cycles_per_sec = hpet_time_div(hpets->hp_period);
1049                         hpet_interpolator.frequency = hpet_cycles_per_sec;
1050                         hpet_interpolator.drift = hpet_cycles_per_sec *
1051                             HPET_DRIFT / 1000000;
1052                         hpet_nsecs_per_cycle = 1000000000 / hpet_cycles_per_sec;
1053                         register_time_interpolator(&hpet_interpolator);
1054                 }
1055 #endif
1056                 return 0;
1057         } else
1058                 return -ENODEV;
1059 }
1060
1061 static void __exit hpet_exit(void)
1062 {
1063         acpi_bus_unregister_driver(&hpet_acpi_driver);
1064
1065         if (hpets) {
1066                 unregister_sysctl_table(sysctl_header);
1067                 remove_proc_entry("driver/hpet", NULL);
1068         }
1069
1070         return;
1071 }
1072
1073 module_init(hpet_init);
1074 module_exit(hpet_exit);
1075 MODULE_AUTHOR("Bob Picco <Robert.Picco@hp.com>");
1076 MODULE_LICENSE("GPL");