linux/drivers/char/hpet.c
<<
>>
Prefs
   1/*
   2 * Intel & MS High Precision Event Timer Implementation.
   3 *
   4 * Copyright (C) 2003 Intel Corporation
   5 *      Venki Pallipadi
   6 * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
   7 *      Bob Picco <robert.picco@hp.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/interrupt.h>
  15#include <linux/module.h>
  16#include <linux/kernel.h>
  17#include <linux/types.h>
  18#include <linux/miscdevice.h>
  19#include <linux/major.h>
  20#include <linux/ioport.h>
  21#include <linux/fcntl.h>
  22#include <linux/init.h>
  23#include <linux/poll.h>
  24#include <linux/mm.h>
  25#include <linux/proc_fs.h>
  26#include <linux/spinlock.h>
  27#include <linux/sysctl.h>
  28#include <linux/wait.h>
  29#include <linux/bcd.h>
  30#include <linux/seq_file.h>
  31#include <linux/bitops.h>
  32#include <linux/compat.h>
  33#include <linux/clocksource.h>
  34#include <linux/uaccess.h>
  35#include <linux/slab.h>
  36#include <linux/io.h>
  37
  38#include <asm/current.h>
  39#include <asm/irq.h>
  40#include <asm/div64.h>
  41
  42#include <linux/acpi.h>
  43#include <acpi/acpi_bus.h>
  44#include <linux/hpet.h>
  45
  46/*
  47 * The High Precision Event Timer driver.
  48 * This driver is closely modelled after the rtc.c driver.
  49 * http://www.intel.com/hardwaredesign/hpetspec_1.pdf
  50 */
  51#define HPET_USER_FREQ  (64)
  52#define HPET_DRIFT      (500)
  53
  54#define HPET_RANGE_SIZE         1024    /* from HPET spec */
  55
  56
  57/* WARNING -- don't get confused.  These macros are never used
  58 * to write the (single) counter, and rarely to read it.
  59 * They're badly named; to fix, someday.
  60 */
  61#if BITS_PER_LONG == 64
  62#define write_counter(V, MC)    writeq(V, MC)
  63#define read_counter(MC)        readq(MC)
  64#else
  65#define write_counter(V, MC)    writel(V, MC)
  66#define read_counter(MC)        readl(MC)
  67#endif
  68
  69static DEFINE_MUTEX(hpet_mutex); /* replaces BKL */
  70static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
  71
  72/* This clocksource driver currently only works on ia64 */
  73#ifdef CONFIG_IA64
  74static void __iomem *hpet_mctr;
  75
  76static cycle_t read_hpet(struct clocksource *cs)
  77{
  78        return (cycle_t)read_counter((void __iomem *)hpet_mctr);
  79}
  80
  81static struct clocksource clocksource_hpet = {
  82        .name           = "hpet",
  83        .rating         = 250,
  84        .read           = read_hpet,
  85        .mask           = CLOCKSOURCE_MASK(64),
  86        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
  87};
  88static struct clocksource *hpet_clocksource;
  89#endif
  90
  91/* A lock for concurrent access by app and isr hpet activity. */
  92static DEFINE_SPINLOCK(hpet_lock);
  93
  94#define HPET_DEV_NAME   (7)
  95
  96struct hpet_dev {
  97        struct hpets *hd_hpets;
  98        struct hpet __iomem *hd_hpet;
  99        struct hpet_timer __iomem *hd_timer;
 100        unsigned long hd_ireqfreq;
 101        unsigned long hd_irqdata;
 102        wait_queue_head_t hd_waitqueue;
 103        struct fasync_struct *hd_async_queue;
 104        unsigned int hd_flags;
 105        unsigned int hd_irq;
 106        unsigned int hd_hdwirq;
 107        char hd_name[HPET_DEV_NAME];
 108};
 109
 110struct hpets {
 111        struct hpets *hp_next;
 112        struct hpet __iomem *hp_hpet;
 113        unsigned long hp_hpet_phys;
 114        struct clocksource *hp_clocksource;
 115        unsigned long long hp_tick_freq;
 116        unsigned long hp_delta;
 117        unsigned int hp_ntimer;
 118        unsigned int hp_which;
 119        struct hpet_dev hp_dev[1];
 120};
 121
 122static struct hpets *hpets;
 123
 124#define HPET_OPEN               0x0001
 125#define HPET_IE                 0x0002  /* interrupt enabled */
 126#define HPET_PERIODIC           0x0004
 127#define HPET_SHARED_IRQ         0x0008
 128
 129
 130#ifndef readq
 131static inline unsigned long long readq(void __iomem *addr)
 132{
 133        return readl(addr) | (((unsigned long long)readl(addr + 4)) << 32LL);
 134}
 135#endif
 136
 137#ifndef writeq
 138static inline void writeq(unsigned long long v, void __iomem *addr)
 139{
 140        writel(v & 0xffffffff, addr);
 141        writel(v >> 32, addr + 4);
 142}
 143#endif
 144
 145static irqreturn_t hpet_interrupt(int irq, void *data)
 146{
 147        struct hpet_dev *devp;
 148        unsigned long isr;
 149
 150        devp = data;
 151        isr = 1 << (devp - devp->hd_hpets->hp_dev);
 152
 153        if ((devp->hd_flags & HPET_SHARED_IRQ) &&
 154            !(isr & readl(&devp->hd_hpet->hpet_isr)))
 155                return IRQ_NONE;
 156
 157        spin_lock(&hpet_lock);
 158        devp->hd_irqdata++;
 159
 160        /*
 161         * For non-periodic timers, increment the accumulator.
 162         * This has the effect of treating non-periodic like periodic.
 163         */
 164        if ((devp->hd_flags & (HPET_IE | HPET_PERIODIC)) == HPET_IE) {
 165                unsigned long m, t, mc, base, k;
 166                struct hpet __iomem *hpet = devp->hd_hpet;
 167                struct hpets *hpetp = devp->hd_hpets;
 168
 169                t = devp->hd_ireqfreq;
 170                m = read_counter(&devp->hd_timer->hpet_compare);
 171                mc = read_counter(&hpet->hpet_mc);
 172                /* The time for the next interrupt would logically be t + m,
 173                 * however, if we are very unlucky and the interrupt is delayed
 174                 * for longer than t then we will completely miss the next
 175                 * interrupt if we set t + m and an application will hang.
 176                 * Therefore we need to make a more complex computation assuming
 177                 * that there exists a k for which the following is true:
 178                 * k * t + base < mc + delta
 179                 * (k + 1) * t + base > mc + delta
 180                 * where t is the interval in hpet ticks for the given freq,
 181                 * base is the theoretical start value 0 < base < t,
 182                 * mc is the main counter value at the time of the interrupt,
 183                 * delta is the time it takes to write the a value to the
 184                 * comparator.
 185                 * k may then be computed as (mc - base + delta) / t .
 186                 */
 187                base = mc % t;
 188                k = (mc - base + hpetp->hp_delta) / t;
 189                write_counter(t * (k + 1) + base,
 190                              &devp->hd_timer->hpet_compare);
 191        }
 192
 193        if (devp->hd_flags & HPET_SHARED_IRQ)
 194                writel(isr, &devp->hd_hpet->hpet_isr);
 195        spin_unlock(&hpet_lock);
 196
 197        wake_up_interruptible(&devp->hd_waitqueue);
 198
 199        kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN);
 200
 201        return IRQ_HANDLED;
 202}
 203
 204static void hpet_timer_set_irq(struct hpet_dev *devp)
 205{
 206        unsigned long v;
 207        int irq, gsi;
 208        struct hpet_timer __iomem *timer;
 209
 210        spin_lock_irq(&hpet_lock);
 211        if (devp->hd_hdwirq) {
 212                spin_unlock_irq(&hpet_lock);
 213                return;
 214        }
 215
 216        timer = devp->hd_timer;
 217
 218        /* we prefer level triggered mode */
 219        v = readl(&timer->hpet_config);
 220        if (!(v & Tn_INT_TYPE_CNF_MASK)) {
 221                v |= Tn_INT_TYPE_CNF_MASK;
 222                writel(v, &timer->hpet_config);
 223        }
 224        spin_unlock_irq(&hpet_lock);
 225
 226        v = (readq(&timer->hpet_config) & Tn_INT_ROUTE_CAP_MASK) >>
 227                                 Tn_INT_ROUTE_CAP_SHIFT;
 228
 229        /*
 230         * In PIC mode, skip IRQ0-4, IRQ6-9, IRQ12-15 which is always used by
 231         * legacy device. In IO APIC mode, we skip all the legacy IRQS.
 232         */
 233        if (acpi_irq_model == ACPI_IRQ_MODEL_PIC)
 234                v &= ~0xf3df;
 235        else
 236                v &= ~0xffff;
 237
 238        for_each_set_bit(irq, &v, HPET_MAX_IRQ) {
 239                if (irq >= nr_irqs) {
 240                        irq = HPET_MAX_IRQ;
 241                        break;
 242                }
 243
 244                gsi = acpi_register_gsi(NULL, irq, ACPI_LEVEL_SENSITIVE,
 245                                        ACPI_ACTIVE_LOW);
 246                if (gsi > 0)
 247                        break;
 248
 249                /* FIXME: Setup interrupt source table */
 250        }
 251
 252        if (irq < HPET_MAX_IRQ) {
 253                spin_lock_irq(&hpet_lock);
 254                v = readl(&timer->hpet_config);
 255                v |= irq << Tn_INT_ROUTE_CNF_SHIFT;
 256                writel(v, &timer->hpet_config);
 257                devp->hd_hdwirq = gsi;
 258                spin_unlock_irq(&hpet_lock);
 259        }
 260        return;
 261}
 262
 263static int hpet_open(struct inode *inode, struct file *file)
 264{
 265        struct hpet_dev *devp;
 266        struct hpets *hpetp;
 267        int i;
 268
 269        if (file->f_mode & FMODE_WRITE)
 270                return -EINVAL;
 271
 272        mutex_lock(&hpet_mutex);
 273        spin_lock_irq(&hpet_lock);
 274
 275        for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
 276                for (i = 0; i < hpetp->hp_ntimer; i++)
 277                        if (hpetp->hp_dev[i].hd_flags & HPET_OPEN)
 278                                continue;
 279                        else {
 280                                devp = &hpetp->hp_dev[i];
 281                                break;
 282                        }
 283
 284        if (!devp) {
 285                spin_unlock_irq(&hpet_lock);
 286                mutex_unlock(&hpet_mutex);
 287                return -EBUSY;
 288        }
 289
 290        file->private_data = devp;
 291        devp->hd_irqdata = 0;
 292        devp->hd_flags |= HPET_OPEN;
 293        spin_unlock_irq(&hpet_lock);
 294        mutex_unlock(&hpet_mutex);
 295
 296        hpet_timer_set_irq(devp);
 297
 298        return 0;
 299}
 300
 301static ssize_t
 302hpet_read(struct file *file, char __user *buf, size_t count, loff_t * ppos)
 303{
 304        DECLARE_WAITQUEUE(wait, current);
 305        unsigned long data;
 306        ssize_t retval;
 307        struct hpet_dev *devp;
 308
 309        devp = file->private_data;
 310        if (!devp->hd_ireqfreq)
 311                return -EIO;
 312
 313        if (count < sizeof(unsigned long))
 314                return -EINVAL;
 315
 316        add_wait_queue(&devp->hd_waitqueue, &wait);
 317
 318        for ( ; ; ) {
 319                set_current_state(TASK_INTERRUPTIBLE);
 320
 321                spin_lock_irq(&hpet_lock);
 322                data = devp->hd_irqdata;
 323                devp->hd_irqdata = 0;
 324                spin_unlock_irq(&hpet_lock);
 325
 326                if (data)
 327                        break;
 328                else if (file->f_flags & O_NONBLOCK) {
 329                        retval = -EAGAIN;
 330                        goto out;
 331                } else if (signal_pending(current)) {
 332                        retval = -ERESTARTSYS;
 333                        goto out;
 334                }
 335                schedule();
 336        }
 337
 338        retval = put_user(data, (unsigned long __user *)buf);
 339        if (!retval)
 340                retval = sizeof(unsigned long);
 341out:
 342        __set_current_state(TASK_RUNNING);
 343        remove_wait_queue(&devp->hd_waitqueue, &wait);
 344
 345        return retval;
 346}
 347
 348static unsigned int hpet_poll(struct file *file, poll_table * wait)
 349{
 350        unsigned long v;
 351        struct hpet_dev *devp;
 352
 353        devp = file->private_data;
 354
 355        if (!devp->hd_ireqfreq)
 356                return 0;
 357
 358        poll_wait(file, &devp->hd_waitqueue, wait);
 359
 360        spin_lock_irq(&hpet_lock);
 361        v = devp->hd_irqdata;
 362        spin_unlock_irq(&hpet_lock);
 363
 364        if (v != 0)
 365                return POLLIN | POLLRDNORM;
 366
 367        return 0;
 368}
 369
 370static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
 371{
 372#ifdef  CONFIG_HPET_MMAP
 373        struct hpet_dev *devp;
 374        unsigned long addr;
 375
 376        if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff)
 377                return -EINVAL;
 378
 379        devp = file->private_data;
 380        addr = devp->hd_hpets->hp_hpet_phys;
 381
 382        if (addr & (PAGE_SIZE - 1))
 383                return -ENOSYS;
 384
 385        vma->vm_flags |= VM_IO;
 386        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 387
 388        if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
 389                                        PAGE_SIZE, vma->vm_page_prot)) {
 390                printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
 391                        __func__);
 392                return -EAGAIN;
 393        }
 394
 395        return 0;
 396#else
 397        return -ENOSYS;
 398#endif
 399}
 400
 401static int hpet_fasync(int fd, struct file *file, int on)
 402{
 403        struct hpet_dev *devp;
 404
 405        devp = file->private_data;
 406
 407        if (fasync_helper(fd, file, on, &devp->hd_async_queue) >= 0)
 408                return 0;
 409        else
 410                return -EIO;
 411}
 412
 413static int hpet_release(struct inode *inode, struct file *file)
 414{
 415        struct hpet_dev *devp;
 416        struct hpet_timer __iomem *timer;
 417        int irq = 0;
 418
 419        devp = file->private_data;
 420        timer = devp->hd_timer;
 421
 422        spin_lock_irq(&hpet_lock);
 423
 424        writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK),
 425               &timer->hpet_config);
 426
 427        irq = devp->hd_irq;
 428        devp->hd_irq = 0;
 429
 430        devp->hd_ireqfreq = 0;
 431
 432        if (devp->hd_flags & HPET_PERIODIC
 433            && readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) {
 434                unsigned long v;
 435
 436                v = readq(&timer->hpet_config);
 437                v ^= Tn_TYPE_CNF_MASK;
 438                writeq(v, &timer->hpet_config);
 439        }
 440
 441        devp->hd_flags &= ~(HPET_OPEN | HPET_IE | HPET_PERIODIC);
 442        spin_unlock_irq(&hpet_lock);
 443
 444        if (irq)
 445                free_irq(irq, devp);
 446
 447        file->private_data = NULL;
 448        return 0;
 449}
 450
 451static int hpet_ioctl_ieon(struct hpet_dev *devp)
 452{
 453        struct hpet_timer __iomem *timer;
 454        struct hpet __iomem *hpet;
 455        struct hpets *hpetp;
 456        int irq;
 457        unsigned long g, v, t, m;
 458        unsigned long flags, isr;
 459
 460        timer = devp->hd_timer;
 461        hpet = devp->hd_hpet;
 462        hpetp = devp->hd_hpets;
 463
 464        if (!devp->hd_ireqfreq)
 465                return -EIO;
 466
 467        spin_lock_irq(&hpet_lock);
 468
 469        if (devp->hd_flags & HPET_IE) {
 470                spin_unlock_irq(&hpet_lock);
 471                return -EBUSY;
 472        }
 473
 474        devp->hd_flags |= HPET_IE;
 475
 476        if (readl(&timer->hpet_config) & Tn_INT_TYPE_CNF_MASK)
 477                devp->hd_flags |= HPET_SHARED_IRQ;
 478        spin_unlock_irq(&hpet_lock);
 479
 480        irq = devp->hd_hdwirq;
 481
 482        if (irq) {
 483                unsigned long irq_flags;
 484
 485                if (devp->hd_flags & HPET_SHARED_IRQ) {
 486                        /*
 487                         * To prevent the interrupt handler from seeing an
 488                         * unwanted interrupt status bit, program the timer
 489                         * so that it will not fire in the near future ...
 490                         */
 491                        writel(readl(&timer->hpet_config) & ~Tn_TYPE_CNF_MASK,
 492                               &timer->hpet_config);
 493                        write_counter(read_counter(&hpet->hpet_mc),
 494                                      &timer->hpet_compare);
 495                        /* ... and clear any left-over status. */
 496                        isr = 1 << (devp - devp->hd_hpets->hp_dev);
 497                        writel(isr, &hpet->hpet_isr);
 498                }
 499
 500                sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
 501                irq_flags = devp->hd_flags & HPET_SHARED_IRQ
 502                                                ? IRQF_SHARED : IRQF_DISABLED;
 503                if (request_irq(irq, hpet_interrupt, irq_flags,
 504                                devp->hd_name, (void *)devp)) {
 505                        printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
 506                        irq = 0;
 507                }
 508        }
 509
 510        if (irq == 0) {
 511                spin_lock_irq(&hpet_lock);
 512                devp->hd_flags ^= HPET_IE;
 513                spin_unlock_irq(&hpet_lock);
 514                return -EIO;
 515        }
 516
 517        devp->hd_irq = irq;
 518        t = devp->hd_ireqfreq;
 519        v = readq(&timer->hpet_config);
 520
 521        /* 64-bit comparators are not yet supported through the ioctls,
 522         * so force this into 32-bit mode if it supports both modes
 523         */
 524        g = v | Tn_32MODE_CNF_MASK | Tn_INT_ENB_CNF_MASK;
 525
 526        if (devp->hd_flags & HPET_PERIODIC) {
 527                g |= Tn_TYPE_CNF_MASK;
 528                v |= Tn_TYPE_CNF_MASK | Tn_VAL_SET_CNF_MASK;
 529                writeq(v, &timer->hpet_config);
 530                local_irq_save(flags);
 531
 532                /*
 533                 * NOTE: First we modify the hidden accumulator
 534                 * register supported by periodic-capable comparators.
 535                 * We never want to modify the (single) counter; that
 536                 * would affect all the comparators. The value written
 537                 * is the counter value when the first interrupt is due.
 538                 */
 539                m = read_counter(&hpet->hpet_mc);
 540                write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
 541                /*
 542                 * Then we modify the comparator, indicating the period
 543                 * for subsequent interrupt.
 544                 */
 545                write_counter(t, &timer->hpet_compare);
 546        } else {
 547                local_irq_save(flags);
 548                m = read_counter(&hpet->hpet_mc);
 549                write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
 550        }
 551
 552        if (devp->hd_flags & HPET_SHARED_IRQ) {
 553                isr = 1 << (devp - devp->hd_hpets->hp_dev);
 554                writel(isr, &hpet->hpet_isr);
 555        }
 556        writeq(g, &timer->hpet_config);
 557        local_irq_restore(flags);
 558
 559        return 0;
 560}
 561
 562/* converts Hz to number of timer ticks */
 563static inline unsigned long hpet_time_div(struct hpets *hpets,
 564                                          unsigned long dis)
 565{
 566        unsigned long long m;
 567
 568        m = hpets->hp_tick_freq + (dis >> 1);
 569        do_div(m, dis);
 570        return (unsigned long)m;
 571}
 572
 573static int
 574hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg,
 575                  struct hpet_info *info)
 576{
 577        struct hpet_timer __iomem *timer;
 578        struct hpet __iomem *hpet;
 579        struct hpets *hpetp;
 580        int err;
 581        unsigned long v;
 582
 583        switch (cmd) {
 584        case HPET_IE_OFF:
 585        case HPET_INFO:
 586        case HPET_EPI:
 587        case HPET_DPI:
 588        case HPET_IRQFREQ:
 589                timer = devp->hd_timer;
 590                hpet = devp->hd_hpet;
 591                hpetp = devp->hd_hpets;
 592                break;
 593        case HPET_IE_ON:
 594                return hpet_ioctl_ieon(devp);
 595        default:
 596                return -EINVAL;
 597        }
 598
 599        err = 0;
 600
 601        switch (cmd) {
 602        case HPET_IE_OFF:
 603                if ((devp->hd_flags & HPET_IE) == 0)
 604                        break;
 605                v = readq(&timer->hpet_config);
 606                v &= ~Tn_INT_ENB_CNF_MASK;
 607                writeq(v, &timer->hpet_config);
 608                if (devp->hd_irq) {
 609                        free_irq(devp->hd_irq, devp);
 610                        devp->hd_irq = 0;
 611                }
 612                devp->hd_flags ^= HPET_IE;
 613                break;
 614        case HPET_INFO:
 615                {
 616                        memset(info, 0, sizeof(*info));
 617                        if (devp->hd_ireqfreq)
 618                                info->hi_ireqfreq =
 619                                        hpet_time_div(hpetp, devp->hd_ireqfreq);
 620                        info->hi_flags =
 621                            readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK;
 622                        info->hi_hpet = hpetp->hp_which;
 623                        info->hi_timer = devp - hpetp->hp_dev;
 624                        break;
 625                }
 626        case HPET_EPI:
 627                v = readq(&timer->hpet_config);
 628                if ((v & Tn_PER_INT_CAP_MASK) == 0) {
 629                        err = -ENXIO;
 630                        break;
 631                }
 632                devp->hd_flags |= HPET_PERIODIC;
 633                break;
 634        case HPET_DPI:
 635                v = readq(&timer->hpet_config);
 636                if ((v & Tn_PER_INT_CAP_MASK) == 0) {
 637                        err = -ENXIO;
 638                        break;
 639                }
 640                if (devp->hd_flags & HPET_PERIODIC &&
 641                    readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) {
 642                        v = readq(&timer->hpet_config);
 643                        v ^= Tn_TYPE_CNF_MASK;
 644                        writeq(v, &timer->hpet_config);
 645                }
 646                devp->hd_flags &= ~HPET_PERIODIC;
 647                break;
 648        case HPET_IRQFREQ:
 649                if ((arg > hpet_max_freq) &&
 650                    !capable(CAP_SYS_RESOURCE)) {
 651                        err = -EACCES;
 652                        break;
 653                }
 654
 655                if (!arg) {
 656                        err = -EINVAL;
 657                        break;
 658                }
 659
 660                devp->hd_ireqfreq = hpet_time_div(hpetp, arg);
 661        }
 662
 663        return err;
 664}
 665
 666static long
 667hpet_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 668{
 669        struct hpet_info info;
 670        int err;
 671
 672        mutex_lock(&hpet_mutex);
 673        err = hpet_ioctl_common(file->private_data, cmd, arg, &info);
 674        mutex_unlock(&hpet_mutex);
 675
 676        if ((cmd == HPET_INFO) && !err &&
 677            (copy_to_user((void __user *)arg, &info, sizeof(info))))
 678                err = -EFAULT;
 679
 680        return err;
 681}
 682
 683#ifdef CONFIG_COMPAT
 684struct compat_hpet_info {
 685        compat_ulong_t hi_ireqfreq;     /* Hz */
 686        compat_ulong_t hi_flags;        /* information */
 687        unsigned short hi_hpet;
 688        unsigned short hi_timer;
 689};
 690
 691static long
 692hpet_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 693{
 694        struct hpet_info info;
 695        int err;
 696
 697        mutex_lock(&hpet_mutex);
 698        err = hpet_ioctl_common(file->private_data, cmd, arg, &info);
 699        mutex_unlock(&hpet_mutex);
 700
 701        if ((cmd == HPET_INFO) && !err) {
 702                struct compat_hpet_info __user *u = compat_ptr(arg);
 703                if (put_user(info.hi_ireqfreq, &u->hi_ireqfreq) ||
 704                    put_user(info.hi_flags, &u->hi_flags) ||
 705                    put_user(info.hi_hpet, &u->hi_hpet) ||
 706                    put_user(info.hi_timer, &u->hi_timer))
 707                        err = -EFAULT;
 708        }
 709
 710        return err;
 711}
 712#endif
 713
 714static const struct file_operations hpet_fops = {
 715        .owner = THIS_MODULE,
 716        .llseek = no_llseek,
 717        .read = hpet_read,
 718        .poll = hpet_poll,
 719        .unlocked_ioctl = hpet_ioctl,
 720#ifdef CONFIG_COMPAT
 721        .compat_ioctl = hpet_compat_ioctl,
 722#endif
 723        .open = hpet_open,
 724        .release = hpet_release,
 725        .fasync = hpet_fasync,
 726        .mmap = hpet_mmap,
 727};
 728
 729static int hpet_is_known(struct hpet_data *hdp)
 730{
 731        struct hpets *hpetp;
 732
 733        for (hpetp = hpets; hpetp; hpetp =  637 634 7     73            637hpets; hdp)
hd_flags &rhy"_addres""drivers/char/hpet.c#L730" id="L730" class="line" name="L635"> 635 7     7         636 7     73"drivers/char/hpet.c#L697" id="L697"7class="li7e" name="L637"> 637 7     7              ref="drivers/char/hpet.c#L560" id="L560"7class="li7e" name="L638"> 638 7     7      vers/char/hpet.c#L712" id="L712" class="li7e" name="L639"> 639 7     73"drivers/char/hpet.c#L710" id="L710" class="li7e" name="L640"> 640 7     7      ="+code=inline" class=(capable(capable( 641 7     7             642 7     7               e=poll" class="srroc42private_dataoc42/* in="+ing">"max-ef="-a hr"f="drivvers/char/hpet.c#L727" id="L727" class="li7e" name="L643"> 643 7     7               e=poll" class="sref">hpet_data ref="+cod="+code=u" class="sref
hpet_max_freq) &&
 644 7     7               e=mmap" class="sraxlf">hpet_open,raxlf""+cod="="+codecod)vers/char/hpet.c#L727" id="L727" class="line" name="L645"> 645 7     7        }
hpet_open,rs=""+cod="0644vers/char/hpet.c#L727" id="L727" class="line" name="L646"> 646 7     7        put_user(hpet_fasync 647 7     7        break;
}vers/char/hpet.c#L727" id="L727" class="li7e" name="L648"> 648 7     7case  649 7     74f="drivers/char/hpet.c#L690" id="L690"7class="li7e" name="L650"> 650 7     75"drivers/char/hpet.c#L701" id="L701" class="li7e" name="L651"> 651 7     751    ="+code=inline" class=(capable(hpet =  652 7     7              vers/char/hpet.c#L715" id="L715" class="li7e" name="L653"> 653 7     75              e=poll" class="srroc42private_dataoc42/* in="+ing">"d="L"f="drivvers/char/hpet.c#L727" id="L727" class="li7e" name="L654"> 654
7a hre75              e=mmap" class="sraxlf">hpet_open,raxlf""+cod="0vers/char/hpet.c#L727" id="L727" class="line" name="L655"> 655 7     75       }
hpet_open,rs=""+cod="0555vers/char/hpet.c#L727" id="L727" class="line" name="L656"> 656 7     75       cmd == capable( 657 7     75       break;
}vers/char/hpet.c#L727" id="L727" class="li7e" name="L658"> 658 7     75ase  659
7a hre75f="drivers/char/hpet.c#L690" id="L690"7class="li7e" name="L660"> 660 7     76"drivers/char/hpet.c#L701" id="L701" class="li7e" name="L661"> 661 7     761    ="+code=inline" class=(capable(hpet =  662
7a hre76             vers/char/hpet.c#L715" id="L715" class="li7e" name="L663"> 663 7     76              e=poll" class="srroc42private_dataoc42/* in="+ing">"dev"f="drivvers/char/hpet.c#L727" id="L727" class="li7e" name="L664"> 664}7hpet_open,raxlf""+cod="0vers/char/hpet.c#L727" id="L727" class="li7e" name="L665"> 665
7a hre76       }
hpet_open,rs=""+cod="0555vers/char/hpet.c#L727" id="L727" class="li7e" name="L666"> 666s7atic 76       cmd == hpet =  667<7 href76       break;
}vers/char/hpet.c#L727" id="L727" class="li7e" name="L668"> 668{7 669 7     76f="drivers/char/hpet.c#L690" id="L690"7class="li7e" name="L670"> 670 7     77"drivers/char/hpet.c#L701" id="L701" class="li7e" name="L671"> 671
7a hre771    ="+code="+code=compat_hpet_infcopy_to_usercopy_to_user 672 7     77"drivers/char/hpet.c#L733" id="L733" class="li7e" name="L673"> 673 7     7/* information *f="drivers/char/hpet.c#L687" id="L687"7class="li7e" name="L674"> 674 7     7/* information * Adjustmati"+codwhen arming the  href withf="drivers/char/hpet.c#L687" id="L687"7class="li7e" name="L675"> 675
7a hre7="drivomment">/* information * initial 676 7     7if ((/* information * codks expired be+coe+coderrupts are enref"d."d"drivers/char/hpet.c#L687" id="L687"7class="li7e" name="L677"> 677 7     7    (/* information *ef="drivers/char/hpet.c#L687" id="L687"7class="li7e" name="L678"> 678 7     7      #def8">e=THIS_MODULE" clICK_CALIBRAT">THIS_MODULEICK_CALIBRAT"se  679
7a hre7="drivers/char/hpet.c#L680" id="L680"7class="li7e" name="L680"> 680 7     78     ="+codehpet_open,_#
hpets *hpetp;
 681}7 682
7a hre78             ="+code=hpet_data" class="ssref">hi_timer))
s="ssref"+code=hpet_fops" cla__iomem>hpet_open,_#iomem"+code=hpetp" class="sref">timer->EINVAL;
 683#7fdef 78             hpet = compat_ioctlunthref="=mmap" class="si>compat_ioctlhi_flags) p; 684s7ruct 78truct hp_dev;
devp-> 685 7     7devp-> 686 7     7hpet_open,_#iomem"+code=hpetp" class="ss=">hp_dev;
 687 7     7unsigners/char/hpet.c#L732" id="L732" class="li7e" name="L688"> 688 7     7unsigned short+code=hpetp" class="j>devp->devp -  637hp_dev;
devp-> 637hi_timer))
s#Lsref""drive=hpet_is_known"j>devp->devp -  689}7
devp->hd_flags & hd_flags & clasOPEN"drivef="drivers/char/hpet.c#L637" id="L637"7class="li7e" name="L690"> 690
7a hre79               timer->devp->hi_timer))
d href="drivers/char/hpet.c#L689" id="L689"7class="li7e" name="L691"> 691s7atic 79                692<7 href79       struct  693{7 694 7     7struct timer-> 695 7     79        696
7a hre7="drivers/char/hpet.c#L697" id="L697"7class="li7e" name="L697"> 697 7     7 637 698 7     7hpet = hpet = timer-> 699 7     79"drivers/char/hpet.c#L680" id="L680"8class="li8e" name="L700"> 700
8a hre800 href="+code=err" class="sri>compat_ioctl 701 8     8if ((compat_ioctlunthrefode=hpet_time_div" class="sref">hpet_time_div(hpetp, THIS_MODULEICK_CALIBRAT"se  702 8     80"drivers/char/hpet.c#L733" id="L733"8class="li8e" name="L703"> 703 8     80a href="+code=err" class="srlocal_irq_save>hp_dev;
hi_flags) p; 694 8     80"drivers/char/hpet.c#L655" id="L655"8class="li8e" name="L705"> 705 8     8            hpet = hp_dev;
hpet_fasync,
 696
8     80"drivers/char/hpet.c#L697" id="L697"8class="li8e" name="L707"> 707 8     8              doivers/char/hpet.c#L637" id="L637"8class="li8e" name="L708"> 708 8     80       hpet = hp_dev;
hpet_fasync,
 699 8a hre80       if ((hpet = hpet =  637hpet_data *<#eflf""+code+code=timer" class="sref">timer-> 710 8     8return compat_ioctlunthrefvvers/char/hpet.c#L688" id="L688"8class="li8e" name="L711"> 711}8 712#8ndif
81a href="+code=mutex_lock" cllocal_irq_restore>hp_dev;
hi_flags) p; 713
8a hre8="drivers/char/hpet.c#L714" id="L714"8class="li8e" name="L714"> 714s8atic 81truct  715 8     8. 716 8     81"drivers/char/hpet.c#L697" id="L697"8class="li8e" name="L717"> 717 8     8.hpet_open,
hpets *hpetp;
 718 8     81="drivers/char/hpet.c#L669" id="L669"8class="li8e" name="L719"> 719 8     8.hp_dev;
 720#8fdef 820a href="+codhpetp;
 721 8     82"drivers/char/hpet.c#L672" id="L672"8class="li8e" name="L722"> 722#8ndif
82a href="+code=mment">/* information *f="drivers/char/hpet.c#L687" id="L687"8class="li8e" name="L723"> 723 8     82a hreomment">/* information 724 8     82a hreomment">/* information a href="* If SMI+coderrupt 725 8     82"drivomment">/* information a href="* willrbe big. This a+cods its impact."d"drivers/char/hpet.c#L687" id="L687"8class="li8e" name="L726"> 726 8     82f ((/* information a href="*ef="drivers/char/hpet.c#L687" id="L687"8class="li8e" name="L727"> 727}8
 728
8a hre82       hpetp;
hpet_open,_#
hpetp;
 729s8atic 82       if ((hp_dev;
hpetp;
 730{8 731 8     83               hp_dev;
hpetp;
 732
8a hre83a href="+codevers/char/hpet.c#L712" id="L712"8class="li8e" name="L733"> 733 8     83"drivers/char/hpet.c#L714" id="L714"8class="li8e" name="L634"> 634 8     83truct hp_dev;
 635 8     83 636 8     83"drivers/char/hpet.c#L697" id="L697"8class="li8e" name="L637"> 637 8     8      code=hpet_is_known" clasallo">hpet_fasync,
hpet_data *hdp)
 638 8     83="drivers/char/hpet.c#L669" id="L669"8class="li8e" name="L639"> 639 8     83a href="+code=mutex_unlock" ue" name="L6
hpet_mmap,ca="+code=arg" class="srmcf">arg);
 640 8     84             ="+code=hpet_info" class="sef">hp_dev;
devp-> 641 8     84f ((hi_timer))nhref="drivers/char/hpet.c#L689" id="L689"8class="li8e" name="L642"> 642 8     84             ="+code=hpet_data" class="">hpets *hpetp;
 643 8     84a href="+code=err" class="sr="+cf">compat_ulong_t="+cf" href=err" class="sr="+>compat_ulong_t="+"drivers/char/hpet.c#L732" id="L732"8class="li8e" name="L644"> 644 8     84truct hp_dev;
 645 8     8        }
hpets *hp_dev;
 646 8     8        cmd ==  647 8     84nsigned short hpetp;
 648 8     84a href="+code=err" class="srue" name="L7
copy_to_user 649 8     84"drivers/char/hpet.c#L680" id="L680"8class="li8e" name="L650"> 650 8     8            !<=mment">/* information *f="drivers/char/hpet.c#L687" id="L687"8class="li8e" name="L651"> 651 8     851    omment">/* information a href="* >,
 652 8     8      omment">/* information a href="* If platspan dependfodes="s has allo"at"d the d="L that"d"drivers/char/hpet.c#L687" id="L687"8class="li8e" name="L653"> 653 8     85a hreomment">/* information 654
8a hre85a hreomment">/* information a href="*ef="drivers/char/hpet.c#L687" id="L687"8class="li8e" name="L655"> 655 8     85       }
hpet_is_known(struct hdp)
 656 8     85           no_llseek,prcod" href=hdp" class="srKERN_DEBUG>no_llseek,KERN_DEBUG href=mment">/* in="+ing">"%s: dupli"at"  cla  hrored\n"f="drivvers/char/hpet.c#L727" id="L727"8class="li8e" name="L657"> 657 8     85                658 8     85        659
8a hre85a href="+codevers/char/hpet.c#L712" id="L712"8class="li8e" name="L660"> 660 8     86"drivers/char/hpet.c#L701" id="L701"8class="li8e" name="L661"> 661 8     86f ((compat_ulong_t="+"drid="="+code="+code=compat_hpet_inss="">hpets *hdp)
hd_flags &nirq"hrefode1) *ers/char/hpet.c#L701" id="L701"8class="li8e" name="L662"> 662
8a hre86       struct hp_dev;
 663 8     86"drivers/char/hpet.c#L714" id="L714"8class="li8e" name="L664"> 664}8hpetp;
hpet_fasynccompat_ulong_t="+"dride=arg" class="srGFP_KERNE">EINVAL;
 665
8a hre86"drivers/char/hpet.c#L676" id="L676"8class="li8e" name="L666"> 666s8atic 86f ((hpetp;
 667<8 href86                668{8 669 8     86a href="+code=mutex_unlock" me="L637"> 637hpet_data *<#which"driede=arg" class="sr h="snss=">hp_dev;
 670 8     870 href="+code=err" class="srme="L637"> 637hdp)
hd_flags &addres""drivers/char/hpet.c#L688" id="L688"8class="li8e" name="L671"> 671
8a hre87f (( 637hpets; hdp)
hd_flags &rhy"_addres""drivers/char/hpet.c#L688" id="L688"8class="li8e" name="L672"> 672 8     87"drivers/char/hpet.c#L733" id="L733"8class="li8e" name="L673"> 673 8     87a href="+code=err" class="srme="L637"> 637hi_timer))
s#Lsref""dricoe=HPET_INFO" claef">hdp)
hd_flags &nirq"hrefvers/char/hpet.c#L688" id="L688"8class="li8e" name="L674"> 674 8     87"drivers/char/hpet.c#L655" id="L655"8class="li8e" name="L675"> 675
8a hre87       }
hdp)
hd_flags &nirq"hrefve=err" class="sri>compat_ioctl 676 8     87            637hp_dev;
hd_flags &hdwirq"dricoe=HPET_INFO" claef">hdp)
hd_flags &irq"dri[=err" class="sri>compat_ioctl 677 8     87nsigners/char/hpet.c#L732" id="L732"8class="li8e" name="L678"> 678 8     87a href="+code=err" class="srss=">hp_dev;
 637 679
8a hre8="drivers/char/hpet.c#L680" id="L680"8class="li8e" name="L680"> 680 8     880 href="+code=err" class="sr"f">hpet_mmap,ca="+coode=readq" class="srefq>hd_flags &srefq href+code=timer" class="ss=">hp_dev;
hpet_mmap,lass="f""drivvers/char/hpet.c#L688" id="L688"8class="li8e" name="L681"> 681}8 682
8a hre88a href="+code=mutex_lock" clLsref">hi_timer))nhref="driodede=cmd" class="sref">hpet_mmap,ca="+coo"+code=HPET_PERIODIC" clasNUM_TIM_CAP_MASK>hpet_mmap, clasNUM_TIM_CAP_MASK"+co) codecodee=HPET_PERIODIC" clasNUM_TIM_CAP_SHIF">CONFIG_COMPAT< clasNUM_TIM_CAP_SHIF""+co) +o1vers/char/hpet.c#L732" id="L732"8class="li8e" name="L683"> 683#8fdef 88"drivers/char/hpet.c#L714" id="L714"8class="li8e" name="L684"> 684s8ruct 88truct  637hi_timer))
s#Lsref""dric!de=no_llseek" classref">hi_timer))nhref="dririvers/char/hpet.c#L637" id="L637"8class="li8e" name="L685"> 685 8     88       no_llseek,prcod" href=hdp" class="srKERN_WARNING>no_llseek,KERN_WARNING href=mment">/* in="+ing">"d="L: number irq" doesn't agree"f="drivers/char/hpet.c#L637" id="L637"8class="li8e" name="L686"> 686 8     88           /* in="+ing">" with number of  hrefs\n"f="drivvvers/char/hpet.c#L688" id="L688"8class="li8e" name="L687"> 687 8     88               hpetp;
 688 8     88        689}8
 690
8a hre89"drivers/char/hpet.c#L701" id="L701"8class="li8e" name="L691"> 691s8atic 89f ((hp_dev;
 692<8 href89       struct hp_dev;
 637 693{8 694 8     8struct hpets * 637 695 8     89"drivers/char/hpet.c#L676" id="L676"8class="li8e" name="L696"> 696
8a hre896 href="+code=mutex_lock" clets">hp_dev;
 637 697 8     89nsigners/char/hpet.c#L732" id="L732"8class="li8e" name="L698"> 698 8     8cmd == hpet_mmap,ca="+coo"+code=HPET_PERIODIC" clasCOUNTER_CLK_PERIOD_MASK>hpet_mmap, clasCOUNTER_CLK_PERIOD_MASK"+co) codecodeers/char/hpet.c#L732" id="L732"8class="li8e" name="L699"> 699 8     89       if ((CONFIG_COMPAT< clasCOUNTER_CLK_PERIOD_SHIF"hrefve=mment">/* information * fs, 10^-15"*ef="drivers/char/hpet.c#L687" id="L687"9class="li9e" name="L700"> 700
9a hre900 href="+code=err" class="srtem">hpetp;
/* information * 10^15"femtosea hds per sea hd"*ef="drivers/char/hpet.c#L687" id="L687"9c1ass="li9e" name="L691"> 691s9     9if ((hpetp;
cmd == /* information * rouhd"*ef="drivers/char/hpet.c#L687" id="L687"9c2ass="li9e" name="L692"> 692<9     90a href="+code=mutex_lock" cldoref">hpet_time_divhpetp;
cmd ==  703 9     90a href="+code=err" class="srme="L637"> 637hpet_max_freqhpetp;
/* information * codks per sea hd"*ef="drivers/char/hpet.c#L687" id="L687"9c4ass="li9e" name="L694"> 694 9     90"drivers/char/hpet.c#L655" id="L655"9class="li9e" name="L705"> 705 9     9            no_llseek,prcod" href=hdp" class="srKERN_INFO>no_llseek,KERN_INFO href=mment">/* in="+ing">"d="L%d: at MMIO 0x%lx, IRQ%s"f="drivvers/char/hpet.c#L727" id="L727"9c6ass="li9e" name="L696"> 696
9     90            637hpet_data *<#which"dride=arg" class="sref">hdp)
hd_flags &rhy"_addres""drivers/char/hpet.c#L727" id="L727"9c7ass="li9e" name="L697"> 697 9     90                637hi_timer))
s#Lsref""driccodee1 ?f=mment">/* in="+ing">"s"f="driv :f=mment">/* in="+ing">""f="drivvvers/char/hpet.c#L688" id="L688"9class="li9e" name="L708"> 708 9     90nsigned short+code=hpetp" class="i>compat_ioctl 637hi_timer))
s#Lsref""drive=err" class="sri>compat_ioctl 699 9a hre90       if ((no_llseek,prcod" href=hdp" class="srKERN_CON">CONFIG_COMPAT/* in="+ing">"%s %d"f="drivve=err" class="sri>compat_ioctl/* in="+ing">","f="driv :f=mment">/* in="+ing">""f="drivde=arg" class="sref">hdp)
hd_flags &irq"dri[=err" class="sri>compat_ioctl 710 9     910 href="+code=err" class="srprcod">no_llseek,prcod" href=hdp" class="srKERN_CON">CONFIG_COMPAT/* in="+ing">"\n"f="drivvvers/char/hpet.c#L688" id="L688"9class="li9e" name="L711"> 711}9 712#9ndif
91a href="+code=mutex_lock" cltem">hpetp;
 637hpet_max_freq 713
9a hre91a href="+code=err" class="srremaindf">copy_to_userhpet_time_divhpetp;
 714s9atic 91             =hpetp" class="prcod">no_llseek,prcod" href=hdp" class="srKERN_INFO>no_llseek,KERN_INFO hreers/char/hpet.c#L688" id="L688"9class="li9e" name="L715"> 715 9     91       /* in="+ing">"d="L%u: %u "smparators, %d-bit %u.%06u MHzt"ountf"\n"f="drivvers/char/hpet.c#L727" id="L727"9class="li9e" name="L716"> 716 9     91            637hpet_data *<#which"dride=arg" class="sree="L637"> 637hi_timer))
s#Lsref""drivers/char/hpet.c#L727" id="L727"9c7ass="li9e" name="L717"> 717 9     91               hpet_mmap,ca="+coo"+code=HPET_PERIODIC" clasCOUNTER_SIZE_MASK>hpet_mmap, clasCOUNTER_SIZE_MASK"+coo? 64 :f32vers/char/hpet.c#L727" id="L727"9class="li9e" name="L718"> 718 9     91       hpetp;
copy_to_user 719 9     91"drivers/char/hpet.c#L680" id="L680"9class="li9e" name="L720"> 720#9fdef 920 href="+code=err" class="srmcf">arg);
hp_dev;
arg);
 721 9     92f ((arg);
hpet_mmap, clasENABLE_CNF_MASK"+co) f="drivers/char/hpet.c#L637" id="L637"9class="li9e" name="L722"> 722#9ndif
92       struct hpet = hp_dev;
hpet_fasync,
 723 9     923      struct arg);
 724 9     92truct arg);
hp_dev;
arg);
 725 9     92        726 9     92"drivers/char/hpet.c#L697" id="L697"9class="li9e" name="L727"> 727}9
devp -  637hp_dev;
compat_ioctl 637hi_timer))
s#Lsref""drive=err" class="sri>compat_ioctldevp -  728
9a hre92       hi_timer))
s="ssref"+code=hpet_fops" cla__iomem>hpet_open,_#iomem"+code=hpetp" class="sref">timer-> 729s9atic 92"drivers/char/hpet.c#L680" id="L680"9class="li9e" name="L730"> 730{9timer->hp_dev;
hi_timer))
s="ssref"s"dri[=err" class="srref">devp -  637hp_dev;
 731 9     93"drivers/char/hpet.c#L672" id="L672"9class="li9e" name="L732"> 732
9a hre93       struct devp->hpets * 637 733 9     933      struct devp->hpets * 634 9     93truct devp->hi_timer))
d href="dridde=lass="line" natref">timer-> 635 9     93"drivers/char/hpet.c#L676" id="L676"9class="li9e" name="L636"> 636 9     93           /* information *f="drivers/char/hpet.c#L687" id="L687"9class="li9e" name="L637"> 637 9     93   (/* information                 * If the  href was reserved by platspan e" n,f="drivers/char/hpet.c#L687" id="L687"9class="li9e" name="L638"> 638 9     93="driomment">/* information                 * then make  href unavailref" +codopens."d"drivers/char/hpet.c#L687" id="L687"9class="li9e" name="L639"> 639 9     93a hreomment">/* information                 *ef="drivers/char/hpet.c#L687" id="L687"9class="li9e" name="L640"> 640 9     94               hdp)
compat_ioctl 641 9     94               devp->hd_flags &  642 9     94       struct  643 9     943      struct  644 9     94"drivers/char/hpet.c#L655" id="L655"9class="li9e" name="L645"> 645 9     94       compat_ioctldevp->hd_flags &waitqueu"hrefvvers/char/hpet.c#L688" id="L688"9class="li9e" name="L646"> 646 9     9         647 9     94nsigners/char/hpet.c#L732" id="L732"9class="li9e" name="L648"> 648 9     94a href="+code=err" class="srme="L637"> 637hpet_data *<#eflf""+coede=arg" class="sr h="scalibrat">hpet_open,
 637 649 9     94"drivers/char/hpet.c#L680" id="L680"9class="li9e" name="L650"> 650 9     9      =mment">/* information * This clocksource pet.c# curratily only works on ia64 *ef="drivers/char/hpet.c#L687" id="L687"9class="li9e" name="L651"> 651 9     951    #ifdefe=arg" class="srCONFIG_IAe" name="L6
 652 9     95       struct+code=arg" class="srsref_clocksource>hpet_open,
 653 9     953      struct hi_timer))
s="smct""+coede(+code=hpet_fops" cla__iomem>hpet_open,_#iomem"+code)+code=timer" class="ss="L637"> 637hpet_fasync,
 654
9a hre95truct hp_dev;
hpet_data archref"ructe=hi_timer" clasfsys_mmio>hpet_data fsys_mmio"+coede=arg" class="sr h="smct">hi_timer))
s="smct""+covers/char/hpet.c#L688" id="L688"9class="li9e" name="L655"> 655 9     95       hp_dev;
 637hpet_max_freq 656 9     95            637hpet_open,
hp_dev;
 657 9     95               hp_dev;
 658 9     95        659
9a hre95a hre#endifers/char/hpet.c#L712" id="L712"9class="li9e" name="L660"> 660 9     96"drivers/char/hpet.c#L701" id="L701"9class="li9e" name="L661"> 661 9     96f (( 662
9a hre96     vers/char/hpet.c#L712" id="L712"9class="li9e" name="L663"> 663 9     96"drivers/char/hpet.c#L714" id="L714"9class="li9e" name="L664"> 664}9hd_flags &acpis="+cu"+code=hpet_fops" cla
hi_timer))
s="sresources href="+code=hpet_data" claacpisresource>hd_flags &acpisresource"+code=hpetp" class="res>hi_timer))res hre, +codee=hpetp" class="ref">hpet_data ref"ructvers/char/hpet.c#L730" id="L730"9class="li9e" name="L665"> 665
9a hre96"drivvers/char/hpet.c#L637" id="L637"9class="li9e" name="L666"> 666s9atic 96f ((hpet_data *hdp)
 667<9 href96a href="+code=mutex_lock" clacpis="+cu">hd_flags &acpis="+cu"+code=hpet_fops" cla="+cu">hd_flags &="+cu"+codvers/char/hpet.c#L560" id="L560"9class="li9e" name="L668"> 668{9 669 9     96"drivers/char/hpet.c#L680" id="L680"9class="li9e" name="L670"> 670 9     970 href="+code=err" class="srmf">hdp)
hpet_data ref"ructvers/char/hpet.c#L560" id="L560"9class="li9e" name="L671"> 671
9a hre97"drivers/char/hpet.c#L672" id="L672"9class="li9e" name="L672"> 672 9     97a href="+code=mutex_lock" cl="+cu">hd_flags &="+cu"+codode=hpet_mmap" claacpisresource_to_addres"e" name="L6
 673 9     97"drivers/char/hpet.c#L714" id="L714"9class="li9e" name="L674"> 674 9     97truct hd_flags &="+cu"+codvrivers/char/hpet.c#L637" id="L637"9class="li9e" name="L675"> 675
9a hre97       hdp)
hd_flags &rhy"_addres""driode=hpet_mmap" claaddr name="L6
hpet_open,rinimurructvers/char/hpet.c#L560" id="L560"9class="li9e" name="L676"> 676 9     97           hdp)
hd_flags &addres""driode=hpet_mmap" claiorema">hdp)
hpet_open,rinimurructde=arg" class="sraddr name="L6
hpet_data addres"_length+codvvers/char/hpet.c#L688" id="L688"9class="li9e" name="L677"> 677 9     97nsigners/char/hpet.c#L732" id="L732"9class="li9e" name="L678"> 678 9     97       hpet_is_known(struct hdp)
 679
9a hre97       if ((hdp)
hdp)
hd_flags &addres""drivvers/char/hpet.c#L688" id="L688"9class="li9e" name="L680"> 680 9     98                681}9 682
9a hre98a href="+code}eelse"+cod=arg" class="srr=s>hi_timer))res hre+code=hd_ireqfreq" ctype>hd_flags &type"driodde=hpet_mmap" claACPI_RESOURCE_TYPE_FIXED_MEMORYe" name="L7
 683#9fdef 983      struct  684s9ruct 98"drivers/char/hpet.c#L680" id="L680"9class="li9e" name="L685"> 685 9     98       hpet_data ref"ructe=hi_timer" clasfixed_memorye" name="L7
 686 9     98            687 9     98                688 9     98"drivers/char/hpet.c#L729" id="L729"9class="li9e" name="L689"> 689}9
hdp)
hd_flags &rhy"_addres""driode=hpet_mmap" clafixmeme" name="L7
hd_flags &addres""drivers/char/hpet.c#L688" id="L688"9class="li9e" name="L690"> 690
9a hre99               hdp)
hd_flags &addres""driode=hpet_mmap" claiorema">hdp)
hd_flags &addres""drivers/char/hpet.c#L727" id="L727"9class="li9e" name="L691"> 691s9atic 99               hd_flags & clasRANGE_SIZE"drivvers/char/hpet.c#L688" id="L688"9class="li9e" name="L692"> 692<9 href99"drivers/char/hpet.c#L733" id="L733"9class="li9e" name="L693"> 693{9hpet_is_known(struct hdp)
 694 9     9struct hdp)
hdp)
hd_flags &addres""drivvers/char/hpet.c#L688" id="L688"9class="li9e" name="L695"> 695 9     99        696
9a hre99            697 9     99             }eelse"+cod=arg" class="srr=s>hi_timer))res hre+code=hd_ireqfreq" ctype>hd_flags &type"driodde=hpet_mmap" claACPI_RESOURCE_TYPE_EXTENDED_IRQ name="L7
 698 9     99       hd_flags &acpisresource_extendfasirq"+code=hdp" class="srirq">hdp)
 699 9     99       if ((compat_ioctl 699 1000a>1000driver/pre> 6s="l2c/89/ac75655d5f01decea8d32b6eb867e238b5e8_3/1000a>rs/char/hpet.c#L560" id="L560"1001ass="li100" name="L691"> 691s100" >100               hdp)
hpet_data ref"ructe=hi_timer" clasextendfasirq>hd_flags &extendfasirq"+covers/char/hpet.c#L560" id="L560"1002ass="li100" name="L692"> 692<100" >100"drivers/char/hpet.c#L733" id="L733"1003ass="li100" name="L693"> 693{100" >1003      struct hdp)
hdp)
 694 100" >100truct hd_flags &irq"+coode=hpet_mmap" claacpisregister_gsi>compat_ioctlEINVAL;
hdp)
hi_timer))intf"ruptsruct[=err" class="sri>compat_ioctl 695 100" >100       hdp)
 &trigge+inghrefde=arg" class="srirq">hdp)
hdp)
 696
100" >100            697 100" >100                698 100" >100"drivers/char/hpet.c#L729" id="L729"1009ass="li100" name="L699"> 699 100" >100       if ((hdp)
hd_flags &irq"dri[=err" class="sr f">hdp)
hd_flags &nirq"href]ode=hpet_mmap" clairq>hd_flags &irq"+covers/char/hpet.c#L560" id="L560"1010ass="li10e" name="L710"> 710 10e" >10e"      if ((hdp)
hd_flags &nirq"href++vers/char/hpet.c#L688" id="L688"10e1ass="li10e" name="L711"> 711}10e" >10e                712#10e" >10ea href="+code}ers/char/hpet.c#L712" id="L712"10e3ass="li10e" name="L713"> 713
10e" >10e"drivers/char/hpet.c#L714" id="L714"10e4ass="li10e" name="L714"> 714s10e" >10etruct hpet_mmap,AE_OK"+covers/char/hpet.c#L560" id="L560"1015ass="li10e" name="L715"> 715 10e" >10e     }ers/char/hpet.c#L712" id="L712"10e6ass="li10e" name="L716"> 716 10e" >10e"drivers/char/hpet.c#L697" id="L697"10e7ass="li10e" name="L717"> 717 10e" >10e     ="+codecode=hpet_is_known"/a>(sacpisadd>compat_ioctl(sacpisadd href="+code=hpet_data" claacpisdevice>hd_flags &acpisdevice"+code=hdp" class="srdevice>hd_flags &device"+covers/char/hpet.c#L730" id="L730"1018ass="li10e" name="L718"> 718 10e" >10e"drivvers/char/hpet.c#L637" id="L637"1019ass="li10e" name="L719"> 719 10e" >10ea href="+code=mutex_unlock" acpis="+cu">hd_flags &acpis="+cu"+code=hpet_fops" claresult>hdp)
 720#10e" >10e" href="+code="+code=hpet_data" class="sref">hpet_data *hpet_data ref"ructvers/char/hpet.c#L560" id="L560"1021ass="li10e" name="L721"> 721 10e" >10e"drivers/char/hpet.c#L672" id="L672"10e2ass="li10e" name="L722"> 722#10e" >10ea href="+code=mutex_lock" clmems=">hp_dev;
hpet_data ref"ruct,rive="+code=timer" class="ref">hpet_data ref"ruct)vvers/char/hpet.c#L688" id="L688"10e3ass="li10e" name="L723"> 723 10e" >10e"drivers/char/hpet.c#L714" id="L714"1024ass="li10e" name="L724"> 724 10e" >10e             =hpetp" class="result>hdp)
 725 10e" >10e       hi_timer))acpiswalkhresources href=hdp" class="srdevice>hd_flags &device"+co+code=hd_ireqfreq" clandle>hpet_open,
andlehrefde=arg" class="srMETHOD_NAME__CRS name="L6
 726 10e" >10e           hpet_data ref"ruct)vers/char/hpet.c#L688" id="L688"10e7ass="li10e" name="L727"> 727}10e" >10ensigners/char/hpet.c#L732" id="L732"10e8ass="li10e" name="L728"> 728
10e" >10e       hd_flags &ACPI_FAILURE href=hdp" class="srresult>hdp)
 729s10e" >10e       if (( 730{10e" >10e"signers/char/hpet.c#L732" id="L732"1031ass="li10e" name="L731"> 731 10e" >10ef ((hpet_data ref"ructe=hi_timer" claslasaddres">hd_flags &addres""drio|| e=arg" class="srref">hpet_data ref"ructe=hi_timer" claslasnirq">hd_flags &nirq"hrefv vers/char/hpet.c#L637" id="L637"1032ass="li10e" name="L732"> 732
10e" >10e       struct hpet_data ref"ructe=hi_timer" claslasaddres">hd_flags &addres""drivers/char/hpet.c#L730" id="L730"1033ass="li10e" name="L733"> 733 10e" >10e3      struct hdp)
hpet_data ref"ructe=hi_timer" claslasaddres">hd_flags &addres""drivvers/char/hpet.c#L688" id="L688"1034ass="li10e" name="L634"> 634 10e" >10etruct no_llseek,prcod" href=mment">/* in="+ing">"%s: no addres" or irq" in _CRS\n"f="drivve=hpet_fops" cla__func__>no_llseek,__func__"drivvers/char/hpet.c#L688" id="L688"1035ass="li10e" name="L635"> 635 10e" >10e        636 10e" >10e        637 10e" >10ensigners/char/hpet.c#L732" id="L732"1038ass="li10e" name="L638"> 638 10e" >10e       (sallo">hpet_fasync,
hpet_data ref"ructvvers/char/hpet.c#L688" id="L688"1039ass="li10e" name="L639"> 639 10e" >10e9    }ers/char/hpet.c#L712" id="L712"1040ass="li10e" name="L640"> 640 10e" >10e"signers/char/hpet.c#L732" id="L732"1041ass="li10e" name="L641"> 641 10e" >10e1    ="+codecode=hpet_is_known"/a>(sacpisremove>hpet_open,
hd_flags &acpisdevice"+code=hdp" class="srdevice>hd_flags &device"+co,ecode=hpet_is_known"type>hd_flags &type"drivers/char/hpet.c#L730" id="L730"1042ass="li10e" name="L642"> 642 10e" >10e2drivvers/char/hpet.c#L637" id="L637"1043ass="li10e" name="L643"> 643 10e" >10ea href="+code=mment">/* information * XXX need to unregister clocksource, deallo" mem, etc *ef="drivers/char/hpet.c#L687" id="L687"10e4ass="li10e" name="L644"> 644 10e" >10etruct EINVAL;
 645 10e" >10e     }ers/char/hpet.c#L712" id="L712"1046ass="li10e" name="L646"> 646 10e" >10e"drivers/char/hpet.c#L697" id="L697"1047ass="li10e" name="L647"> 647 10e" >10e     ="+codeconste="+code=hpet_data" claacpisdevice_id>compat_ioctlhi_timer))
s="srevice_ids"dri[]odevers/char/hpet.c#L637" id="L637"1048ass="li10e" name="L648"> 648 10e" >10e       /* in="+ing">"PNP010e"f="drivve0}vers/char/hpet.c#L727" id="L727"1049ass="li10e" name="L649"> 649 10e" >10e9      /* in="+ing">""f="drivve0}vers/char/hpet.c#L727" id="L727"1050ass="li10e" name="L650"> 650 10e" >10e"    }vers/char/hpet.c#L688" id="L688"1051ass="li10e" name="L651"> 651 10e" >10e1    =arg" class="srMODULE_DEVICE_TABLE name="L6
 652 10e" >10e"drivers/char/hpet.c#L733" id="L733"1053ass="li10e" name="L653"> 653 10e" >10e3    ="+code="+code=hpet_data" claacpisdet.c#>compat_ioctlcompat_ioctl 654
10e" >10etruct compat_ioctl/* in="+ing">"d="L"f="drivvers/char/hpet.c#L727" id="L727"10e5ass="li10e" name="L655"> 655 10e" >10e5ruct hi_timer))ids"driede=arg" class="sr h="srevice_ids>hi_timer))
s="srevice_ids"drivers/char/hpet.c#L727" id="L727"10e6ass="li10e" name="L656"> 656 10e" >10e6ruct hi_timer))ops"+coodevers/char/hpet.c#L637" id="L637"1057ass="li10e" name="L657"> 657 10e" >10e               compat_ioctlcompat_ioctl(sacpisadd hrevers/char/hpet.c#L727" id="L727"10e8ass="li10e" name="L658"> 658 10e" >10e       hpet_open,remove hreede=arg" class="sr h="sacpisremove>hpet_open,
 659
10e" >10e       if (( 660 10e" >10e"    }vers/char/hpet.c#L688" id="L688"1061ass="li10e" name="L661"> 661 10e" >10e"drivers/char/hpet.c#L672" id="L672"1062ass="li10e" name="L662"> 662
10e" >10e2    ="+code="+code=hpet_data" clamiscdevice>hd_flags &miscdevice"+cod=hd_ireqfreq" c*hpet_open,
/* in="+ing">"d="L"f="drivve+code=timer" class="ss="_fops>hi_timer))ss="_fops"+coo}vers/char/hpet.c#L688" id="L688"1063ass="li10e" name="L663"> 663 10e" >10e"drivers/char/hpet.c#L714" id="L714"1064ass="li10e" name="L664"> 664}10e" >10e"driv="+codecode=hpet_is_known"__init>no_llseek,__init"+cod=hd_ireqfreq" c*no_llseek,* 665
10e" >10e"drivvers/char/hpet.c#L637" id="L637"10e6ass="li10e" name="L666"> 666s10e" >10e6ruct hdp)
 667<10e" >10ensigners/char/hpet.c#L732" id="L732"1068ass="li10e" name="L668"> 668{10e" >10ea href="+code=err" class="srresult>hdp)
hd_flags &miscsregister href+code=timer" class="*hpet_open,
 669 10e" >10e       if ((<+cod=arg" class="srr=sult>hdp)
 670 10e" >10e"       671
10e" >10e"drivers/char/hpet.c#L672" id="L672"1072ass="li10e" name="L672"> 672 10e" >10ea href="+code=mutex_lock" cl=ysctl_header>hd_flags &=ysctl_header"+co =e=hpet_data" claregister_=ysctl_tref">hdp)
 673 10e" >10e"drivers/char/hpet.c#L714" id="L714"1074ass="li10e" name="L674"> 674 10e" >10e             =hpetp" class="result>hdp)
compat_ioctl 675
10e" >10e5      if ((<+cod=arg" class="srr=sult>hdp)
 676 10e" >10e           hd_flags &=ysctl_header"+covers/char/hpet.c#L730" id="L730"1077ass="li10e" name="L677"> 677 10e" >10e               hdp)
 678 10e" >10e       hd_flags &miscsderegister href+code=timer" class="*hpet_open,
 679
10e" >10e       if ((hdp)
 680 10e" >10e"       681}10e" >10e"drivers/char/hpet.c#L672" id="L672"1082ass="li10e" name="L682"> 682
10e" >10ea href="+coderef="drivers/char/hpet.c#L560" id="L560"10e3ass="li10e" name="L683"> 683#10e" >10e3    }ers/char/hpet.c#L712" id="L712"1084ass="li10e" name="L684"> 684s10e" >10e"drivers/char/hpet.c#L680" id="L680"10e5ass="li10e" name="L685"> 685 10e" >10e5driv="+code+code=hpet_fops" cla__exit>no_llseek,__exit"+cod=hd_ireqfreq" c*no_llseek,* 686 10e" >10e6drivvers/char/hpet.c#L637" id="L637"1087ass="li10e" name="L687"> 687 10e" >10ea href="+code=mutex_lock" clacpisbussunregister_det.c#>compat_ioctl 688 10e" >10e"drivers/char/hpet.c#L729" id="L729"1089ass="li10e" name="L689"> 689}10e" >10e       if ((<+cod=arg" class="sr=ysctl_header>hd_flags &=ysctl_header"+covers/char/hpet.c#L730" id="L730"1090ass="li10e" name="L690"> 690
10e" >10e"      hdp)
 691s10e" >10e1 href="+code=mutex_lock" clmiscsderegister>hd_flags &miscsderegister href+code=timer" class="*hpet_open,
 692<10e" >10e"drivers/char/hpet.c#L733" id="L733"1093ass="li10e" name="L693"> 693{10e" >10e3 href="+coderef="dvers/char/hpet.c#L688" id="L688"1094ass="li10e" name="L694"> 694 10e" >10e4    }ers/char/hpet.c#L712" id="L712"1095ass="li10e" name="L695"> 695 10e" >10e"drivers/char/hpet.c#L676" id="L676"10e6ass="li10e" name="L696"> 696
10e" >10e6    =arg" class="srmodulehinit>no_llseek,modulehinit href=hdp" class="sr*no_llseek,* 697 10e" >10e7    =arg" class="srmodulehexit>no_llseek,modulehexit href=hdp" class="sr*no_llseek,* 698 10e" >10e8    =arg" class="srMODULE_AUTHOR name="L6
/* in="+ing">"Bob Picco &lodRobert.Picco@hp.comcode"f="drivvvers/char/hpet.c#L688" id="L688"1099ass="li10e" name="L699"> 699 10e" >10e9    =arg" class="srMODULE_LICENSE name="L6
/* in="+ing">"GPL"f="drivvvers/char/hpet.c#L688" id="L688"1100ass="li1100asame="L699"> 699 1100a>1100drivr/pre>
> The original LXR software by the rs/char/hhttp://sourceforge.net/projects/lxr>>LXR formunity"dri, this experimatial .c#Lion by rs/char/hmailto:lxr@99"ux.no">lxr@99"ux.no"dri. > lxr.99"ux.no kindly hosted by rs/char/hhttp://www.redpill-99"pro.no">Redpill L9"pro AS"driv provider of L9"uxeconsulting anddoper+coons services since 1995.