Lines Matching +full:poll +full:- +full:period

1 // SPDX-License-Identifier: GPL-2.0-only
7 * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
19 #include <linux/io-64-nonatomic-lo-hi.h>
20 #include <linux/poll.h>
52 /* WARNING -- don't get confused. These macros are never used
110 isr = 1 << (devp - devp->hd_hpets->hp_dev); in hpet_interrupt()
112 if ((devp->hd_flags & HPET_SHARED_IRQ) && in hpet_interrupt()
113 !(isr & readl(&devp->hd_hpet->hpet_isr))) in hpet_interrupt()
117 devp->hd_irqdata++; in hpet_interrupt()
120 * For non-periodic timers, increment the accumulator. in hpet_interrupt()
121 * This has the effect of treating non-periodic like periodic. in hpet_interrupt()
123 if ((devp->hd_flags & (HPET_IE | HPET_PERIODIC)) == HPET_IE) { in hpet_interrupt()
125 struct hpet __iomem *hpet = devp->hd_hpet; in hpet_interrupt()
126 struct hpets *hpetp = devp->hd_hpets; in hpet_interrupt()
128 t = devp->hd_ireqfreq; in hpet_interrupt()
129 read_counter(&devp->hd_timer->hpet_compare); in hpet_interrupt()
130 mc = read_counter(&hpet->hpet_mc); in hpet_interrupt()
144 * k may then be computed as (mc - base + delta) / t . in hpet_interrupt()
147 k = (mc - base + hpetp->hp_delta) / t; in hpet_interrupt()
149 &devp->hd_timer->hpet_compare); in hpet_interrupt()
152 if (devp->hd_flags & HPET_SHARED_IRQ) in hpet_interrupt()
153 writel(isr, &devp->hd_hpet->hpet_isr); in hpet_interrupt()
156 wake_up_interruptible(&devp->hd_waitqueue); in hpet_interrupt()
158 kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN); in hpet_interrupt()
171 if (devp->hd_hdwirq) { in hpet_timer_set_irq()
176 timer = devp->hd_timer; in hpet_timer_set_irq()
179 v = readl(&timer->hpet_config); in hpet_timer_set_irq()
182 writel(v, &timer->hpet_config); in hpet_timer_set_irq()
186 v = (readq(&timer->hpet_config) & Tn_INT_ROUTE_CAP_MASK) >> in hpet_timer_set_irq()
190 * In PIC mode, skip IRQ0-4, IRQ6-9, IRQ12-15 which is always used by in hpet_timer_set_irq()
214 v = readl(&timer->hpet_config); in hpet_timer_set_irq()
216 writel(v, &timer->hpet_config); in hpet_timer_set_irq()
217 devp->hd_hdwirq = gsi; in hpet_timer_set_irq()
229 if (file->f_mode & FMODE_WRITE) in hpet_open()
230 return -EINVAL; in hpet_open()
235 for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) in hpet_open()
236 for (i = 0; i < hpetp->hp_ntimer; i++) in hpet_open()
237 if (hpetp->hp_dev[i].hd_flags & HPET_OPEN) { in hpet_open()
240 devp = &hpetp->hp_dev[i]; in hpet_open()
247 return -EBUSY; in hpet_open()
250 file->private_data = devp; in hpet_open()
251 devp->hd_irqdata = 0; in hpet_open()
252 devp->hd_flags |= HPET_OPEN; in hpet_open()
269 devp = file->private_data; in hpet_read()
270 if (!devp->hd_ireqfreq) in hpet_read()
271 return -EIO; in hpet_read()
275 return -EINVAL; in hpet_read()
278 return -EINVAL; in hpet_read()
281 add_wait_queue(&devp->hd_waitqueue, &wait); in hpet_read()
287 data = devp->hd_irqdata; in hpet_read()
288 devp->hd_irqdata = 0; in hpet_read()
293 } else if (file->f_flags & O_NONBLOCK) { in hpet_read()
294 retval = -EAGAIN; in hpet_read()
297 retval = -ERESTARTSYS; in hpet_read()
315 remove_wait_queue(&devp->hd_waitqueue, &wait); in hpet_read()
325 devp = file->private_data; in hpet_poll()
327 if (!devp->hd_ireqfreq) in hpet_poll()
330 poll_wait(file, &devp->hd_waitqueue, wait); in hpet_poll()
333 v = devp->hd_irqdata; in hpet_poll()
363 return -EACCES; in hpet_mmap()
365 devp = file->private_data; in hpet_mmap()
366 addr = devp->hd_hpets->hp_hpet_phys; in hpet_mmap()
368 if (addr & (PAGE_SIZE - 1)) in hpet_mmap()
369 return -ENOSYS; in hpet_mmap()
371 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); in hpet_mmap()
377 return -ENOSYS; in hpet_mmap()
385 devp = file->private_data; in hpet_fasync()
387 if (fasync_helper(fd, file, on, &devp->hd_async_queue) >= 0) in hpet_fasync()
390 return -EIO; in hpet_fasync()
399 devp = file->private_data; in hpet_release()
400 timer = devp->hd_timer; in hpet_release()
404 writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK), in hpet_release()
405 &timer->hpet_config); in hpet_release()
407 irq = devp->hd_irq; in hpet_release()
408 devp->hd_irq = 0; in hpet_release()
410 devp->hd_ireqfreq = 0; in hpet_release()
412 if (devp->hd_flags & HPET_PERIODIC in hpet_release()
413 && readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) { in hpet_release()
416 v = readq(&timer->hpet_config); in hpet_release()
418 writeq(v, &timer->hpet_config); in hpet_release()
421 devp->hd_flags &= ~(HPET_OPEN | HPET_IE | HPET_PERIODIC); in hpet_release()
427 file->private_data = NULL; in hpet_release()
440 timer = devp->hd_timer; in hpet_ioctl_ieon()
441 hpet = devp->hd_hpet; in hpet_ioctl_ieon()
442 hpetp = devp->hd_hpets; in hpet_ioctl_ieon()
444 if (!devp->hd_ireqfreq) in hpet_ioctl_ieon()
445 return -EIO; in hpet_ioctl_ieon()
449 if (devp->hd_flags & HPET_IE) { in hpet_ioctl_ieon()
451 return -EBUSY; in hpet_ioctl_ieon()
454 devp->hd_flags |= HPET_IE; in hpet_ioctl_ieon()
456 if (readl(&timer->hpet_config) & Tn_INT_TYPE_CNF_MASK) in hpet_ioctl_ieon()
457 devp->hd_flags |= HPET_SHARED_IRQ; in hpet_ioctl_ieon()
460 irq = devp->hd_hdwirq; in hpet_ioctl_ieon()
465 if (devp->hd_flags & HPET_SHARED_IRQ) { in hpet_ioctl_ieon()
471 writel(readl(&timer->hpet_config) & ~Tn_TYPE_CNF_MASK, in hpet_ioctl_ieon()
472 &timer->hpet_config); in hpet_ioctl_ieon()
473 write_counter(read_counter(&hpet->hpet_mc), in hpet_ioctl_ieon()
474 &timer->hpet_compare); in hpet_ioctl_ieon()
475 /* ... and clear any left-over status. */ in hpet_ioctl_ieon()
476 isr = 1 << (devp - devp->hd_hpets->hp_dev); in hpet_ioctl_ieon()
477 writel(isr, &hpet->hpet_isr); in hpet_ioctl_ieon()
480 sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); in hpet_ioctl_ieon()
481 irq_flags = devp->hd_flags & HPET_SHARED_IRQ ? IRQF_SHARED : 0; in hpet_ioctl_ieon()
483 devp->hd_name, (void *)devp)) { in hpet_ioctl_ieon()
491 devp->hd_flags ^= HPET_IE; in hpet_ioctl_ieon()
493 return -EIO; in hpet_ioctl_ieon()
496 devp->hd_irq = irq; in hpet_ioctl_ieon()
497 t = devp->hd_ireqfreq; in hpet_ioctl_ieon()
498 v = readq(&timer->hpet_config); in hpet_ioctl_ieon()
500 /* 64-bit comparators are not yet supported through the ioctls, in hpet_ioctl_ieon()
501 * so force this into 32-bit mode if it supports both modes in hpet_ioctl_ieon()
505 if (devp->hd_flags & HPET_PERIODIC) { in hpet_ioctl_ieon()
508 writeq(v, &timer->hpet_config); in hpet_ioctl_ieon()
513 * register supported by periodic-capable comparators. in hpet_ioctl_ieon()
518 m = read_counter(&hpet->hpet_mc); in hpet_ioctl_ieon()
519 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); in hpet_ioctl_ieon()
521 * Then we modify the comparator, indicating the period in hpet_ioctl_ieon()
524 write_counter(t, &timer->hpet_compare); in hpet_ioctl_ieon()
527 m = read_counter(&hpet->hpet_mc); in hpet_ioctl_ieon()
528 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); in hpet_ioctl_ieon()
531 if (devp->hd_flags & HPET_SHARED_IRQ) { in hpet_ioctl_ieon()
532 isr = 1 << (devp - devp->hd_hpets->hp_dev); in hpet_ioctl_ieon()
533 writel(isr, &hpet->hpet_isr); in hpet_ioctl_ieon()
535 writeq(g, &timer->hpet_config); in hpet_ioctl_ieon()
547 m = hpets->hp_tick_freq + (dis >> 1); in hpet_time_div()
566 timer = devp->hd_timer; in hpet_ioctl_common()
567 hpetp = devp->hd_hpets; in hpet_ioctl_common()
572 return -EINVAL; in hpet_ioctl_common()
579 if ((devp->hd_flags & HPET_IE) == 0) in hpet_ioctl_common()
581 v = readq(&timer->hpet_config); in hpet_ioctl_common()
583 writeq(v, &timer->hpet_config); in hpet_ioctl_common()
584 if (devp->hd_irq) { in hpet_ioctl_common()
585 free_irq(devp->hd_irq, devp); in hpet_ioctl_common()
586 devp->hd_irq = 0; in hpet_ioctl_common()
588 devp->hd_flags ^= HPET_IE; in hpet_ioctl_common()
593 if (devp->hd_ireqfreq) in hpet_ioctl_common()
594 info->hi_ireqfreq = in hpet_ioctl_common()
595 hpet_time_div(hpetp, devp->hd_ireqfreq); in hpet_ioctl_common()
596 info->hi_flags = in hpet_ioctl_common()
597 readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK; in hpet_ioctl_common()
598 info->hi_hpet = hpetp->hp_which; in hpet_ioctl_common()
599 info->hi_timer = devp - hpetp->hp_dev; in hpet_ioctl_common()
603 v = readq(&timer->hpet_config); in hpet_ioctl_common()
605 err = -ENXIO; in hpet_ioctl_common()
608 devp->hd_flags |= HPET_PERIODIC; in hpet_ioctl_common()
611 v = readq(&timer->hpet_config); in hpet_ioctl_common()
613 err = -ENXIO; in hpet_ioctl_common()
616 if (devp->hd_flags & HPET_PERIODIC && in hpet_ioctl_common()
617 readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) { in hpet_ioctl_common()
618 v = readq(&timer->hpet_config); in hpet_ioctl_common()
620 writeq(v, &timer->hpet_config); in hpet_ioctl_common()
622 devp->hd_flags &= ~HPET_PERIODIC; in hpet_ioctl_common()
627 err = -EACCES; in hpet_ioctl_common()
632 err = -EINVAL; in hpet_ioctl_common()
636 devp->hd_ireqfreq = hpet_time_div(hpetp, arg); in hpet_ioctl_common()
649 err = hpet_ioctl_common(file->private_data, cmd, arg, &info); in hpet_ioctl()
654 err = -EFAULT; in hpet_ioctl()
667 /* 32-bit types would lead to different command codes which should be
668 * translated into 64-bit ones before passed to hpet_ioctl_common
686 err = hpet_ioctl_common(file->private_data, cmd, arg, &info); in hpet_compat_ioctl()
691 if (put_user(info.hi_ireqfreq, &u->hi_ireqfreq) || in hpet_compat_ioctl()
692 put_user(info.hi_flags, &u->hi_flags) || in hpet_compat_ioctl()
693 put_user(info.hi_hpet, &u->hi_hpet) || in hpet_compat_ioctl()
694 put_user(info.hi_timer, &u->hi_timer)) in hpet_compat_ioctl()
695 err = -EFAULT; in hpet_compat_ioctl()
705 .poll = hpet_poll,
720 for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) in hpet_is_known()
721 if (hpetp->hp_hpet_phys == hdp->hd_phys_address) in hpet_is_known()
729 .procname = "max-user-freq",
754 for (j = 0, devp = hpetp->hp_dev; j < hpetp->hp_ntimer; j++, devp++) in __hpet_calibrate()
755 if ((devp->hd_flags & HPET_OPEN) == 0) { in __hpet_calibrate()
756 timer = devp->hd_timer; in __hpet_calibrate()
763 hpet = hpetp->hp_hpet; in __hpet_calibrate()
764 t = read_counter(&timer->hpet_compare); in __hpet_calibrate()
771 start = read_counter(&hpet->hpet_mc); in __hpet_calibrate()
774 m = read_counter(&hpet->hpet_mc); in __hpet_calibrate()
775 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); in __hpet_calibrate()
776 } while (i++, (m - start) < count); in __hpet_calibrate()
780 return (m - start) / i; in __hpet_calibrate()
811 u32 period; in hpet_alloc() local
826 hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs), in hpet_alloc()
830 return -ENOMEM; in hpet_alloc()
832 hpetp->hp_which = hpet_nhpet++; in hpet_alloc()
833 hpetp->hp_hpet = hdp->hd_address; in hpet_alloc()
834 hpetp->hp_hpet_phys = hdp->hd_phys_address; in hpet_alloc()
836 hpetp->hp_ntimer = hdp->hd_nirqs; in hpet_alloc()
838 for (i = 0; i < hdp->hd_nirqs; i++) in hpet_alloc()
839 hpetp->hp_dev[i].hd_hdwirq = hdp->hd_irq[i]; in hpet_alloc()
841 hpet = hpetp->hp_hpet; in hpet_alloc()
843 cap = readq(&hpet->hpet_cap); in hpet_alloc()
847 if (hpetp->hp_ntimer != ntimer) { in hpet_alloc()
851 return -ENODEV; in hpet_alloc()
855 last->hp_next = hpetp; in hpet_alloc()
861 period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >> in hpet_alloc()
862 HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */ in hpet_alloc()
864 temp += period >> 1; /* round */ in hpet_alloc()
865 do_div(temp, period); in hpet_alloc()
866 hpetp->hp_tick_freq = temp; /* ticks per second */ in hpet_alloc()
869 hpetp->hp_which, hdp->hd_phys_address, in hpet_alloc()
870 hpetp->hp_ntimer > 1 ? "s" : ""); in hpet_alloc()
871 for (i = 0; i < hpetp->hp_ntimer; i++) in hpet_alloc()
872 printk(KERN_CONT "%s %u", i > 0 ? "," : "", hdp->hd_irq[i]); in hpet_alloc()
875 temp = hpetp->hp_tick_freq; in hpet_alloc()
878 "hpet%u: %u comparators, %d-bit %u.%06u MHz counter\n", in hpet_alloc()
879 hpetp->hp_which, hpetp->hp_ntimer, in hpet_alloc()
883 mcfg = readq(&hpet->hpet_config); in hpet_alloc()
885 write_counter(0L, &hpet->hpet_mc); in hpet_alloc()
887 writeq(mcfg, &hpet->hpet_config); in hpet_alloc()
890 for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; i++, devp++) { in hpet_alloc()
893 timer = &hpet->hpet_timers[devp - hpetp->hp_dev]; in hpet_alloc()
895 devp->hd_hpets = hpetp; in hpet_alloc()
896 devp->hd_hpet = hpet; in hpet_alloc()
897 devp->hd_timer = timer; in hpet_alloc()
903 if (hdp->hd_state & (1 << i)) { in hpet_alloc()
904 devp->hd_flags = HPET_OPEN; in hpet_alloc()
908 init_waitqueue_head(&devp->hd_waitqueue); in hpet_alloc()
911 hpetp->hp_delta = hpet_calibrate(hpetp); in hpet_alloc()
927 hdp->hd_phys_address = addr.address.minimum; in hpet_resources()
928 hdp->hd_address = ioremap(addr.address.minimum, addr.address.address_length); in hpet_resources()
929 if (!hdp->hd_address) in hpet_resources()
933 iounmap(hdp->hd_address); in hpet_resources()
936 } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) { in hpet_resources()
939 fixmem32 = &res->data.fixed_memory32; in hpet_resources()
941 hdp->hd_phys_address = fixmem32->address; in hpet_resources()
942 hdp->hd_address = ioremap(fixmem32->address, in hpet_resources()
944 if (!hdp->hd_address) in hpet_resources()
948 iounmap(hdp->hd_address); in hpet_resources()
951 } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { in hpet_resources()
955 irqp = &res->data.extended_irq; in hpet_resources()
957 for (i = 0; i < irqp->interrupt_count; i++) { in hpet_resources()
958 if (hdp->hd_nirqs >= HPET_MAX_TIMERS) in hpet_resources()
961 irq = acpi_register_gsi(NULL, irqp->interrupts[i], in hpet_resources()
962 irqp->triggering, in hpet_resources()
963 irqp->polarity); in hpet_resources()
967 hdp->hd_irq[hdp->hd_nirqs] = irq; in hpet_resources()
968 hdp->hd_nirqs++; in hpet_resources()
983 acpi_walk_resources(device->handle, METHOD_NAME__CRS, in hpet_acpi_add()
987 return -ENODEV; in hpet_acpi_add()
993 return -ENODEV; in hpet_acpi_add()
1020 return -ENODEV; in hpet_init()