2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-22 20:23:57 +08:00
linux-next/include/linux/hpet.h
David Brownell 64a76f667d hpet: /dev/hpet - fixes and cleanup
Minor /dev/hpet updates and bugfixes:

  * Remove dead code, mostly remnants of an incomplete/unusable
    kernel interface ... noted when addressing "sparse" warnings:
      + hpet_unregister() and a routine it calls
      + hpet_task and all references, including hpet_task_lock
      + hpet_data.hd_flags (and HPET_DATA_PLATFORM)

  * Correct and improve boot message:
      + displays *counter* (shared between comparators) bit width,
        not *timer* bit widths (which are often mixed)
      + relabel "timers" as "comparators"; this is less confusing,
        they are not independent like normal timers are (sigh)
      + display MHz not Hz; it's never less than 10 MHz.

  * Tighten and correct the userspace interface code
      + don't accidentally program comparators in 64-bit mode using
        32-bit values ... always force comparators into 32-bit mode
      + provide the correct bit definition flagging comparators with
        periodic capability ... the ABI is unchanged

  * Update Documentation/hpet.txt
      + be more correct and current
      + expand description a bit
      + don't mention that now-gone kernel interface

Plus, add a FIXME comment for something that could cause big trouble
on systems with more capable HPETs than at least Intel seems to ship.

It seems that few folk use this userspace interface; it's not very
usable given the general lack of HPET IRQ routing.  I'm told that
the only real point of it any more is to mmap for fast timestamps;
IMO that's handled better through the gettimeofday() vsyscall.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2008-07-31 18:45:41 +02:00

130 lines
3.1 KiB
C

#ifndef __HPET__
#define __HPET__ 1
#include <linux/compiler.h>
#ifdef __KERNEL__
/*
* Offsets into HPET Registers
*/
struct hpet {
u64 hpet_cap; /* capabilities */
u64 res0; /* reserved */
u64 hpet_config; /* configuration */
u64 res1; /* reserved */
u64 hpet_isr; /* interrupt status reg */
u64 res2[25]; /* reserved */
union { /* main counter */
u64 _hpet_mc64;
u32 _hpet_mc32;
unsigned long _hpet_mc;
} _u0;
u64 res3; /* reserved */
struct hpet_timer {
u64 hpet_config; /* configuration/cap */
union { /* timer compare register */
u64 _hpet_hc64;
u32 _hpet_hc32;
unsigned long _hpet_compare;
} _u1;
u64 hpet_fsb[2]; /* FSB route */
} hpet_timers[1];
};
#define hpet_mc _u0._hpet_mc
#define hpet_compare _u1._hpet_compare
#define HPET_MAX_TIMERS (32)
#define HPET_MAX_IRQ (32)
/*
* HPET general capabilities register
*/
#define HPET_COUNTER_CLK_PERIOD_MASK (0xffffffff00000000ULL)
#define HPET_COUNTER_CLK_PERIOD_SHIFT (32UL)
#define HPET_VENDOR_ID_MASK (0x00000000ffff0000ULL)
#define HPET_VENDOR_ID_SHIFT (16ULL)
#define HPET_LEG_RT_CAP_MASK (0x8000)
#define HPET_COUNTER_SIZE_MASK (0x2000)
#define HPET_NUM_TIM_CAP_MASK (0x1f00)
#define HPET_NUM_TIM_CAP_SHIFT (8ULL)
/*
* HPET general configuration register
*/
#define HPET_LEG_RT_CNF_MASK (2UL)
#define HPET_ENABLE_CNF_MASK (1UL)
/*
* Timer configuration register
*/
#define Tn_INT_ROUTE_CAP_MASK (0xffffffff00000000ULL)
#define Tn_INT_ROUTE_CAP_SHIFT (32UL)
#define Tn_FSB_INT_DELCAP_MASK (0x8000UL)
#define Tn_FSB_INT_DELCAP_SHIFT (15)
#define Tn_FSB_EN_CNF_MASK (0x4000UL)
#define Tn_FSB_EN_CNF_SHIFT (14)
#define Tn_INT_ROUTE_CNF_MASK (0x3e00UL)
#define Tn_INT_ROUTE_CNF_SHIFT (9)
#define Tn_32MODE_CNF_MASK (0x0100UL)
#define Tn_VAL_SET_CNF_MASK (0x0040UL)
#define Tn_SIZE_CAP_MASK (0x0020UL)
#define Tn_PER_INT_CAP_MASK (0x0010UL)
#define Tn_TYPE_CNF_MASK (0x0008UL)
#define Tn_INT_ENB_CNF_MASK (0x0004UL)
#define Tn_INT_TYPE_CNF_MASK (0x0002UL)
/*
* Timer FSB Interrupt Route Register
*/
#define Tn_FSB_INT_ADDR_MASK (0xffffffff00000000ULL)
#define Tn_FSB_INT_ADDR_SHIFT (32UL)
#define Tn_FSB_INT_VAL_MASK (0x00000000ffffffffULL)
/*
* exported interfaces
*/
struct hpet_data {
unsigned long hd_phys_address;
void __iomem *hd_address;
unsigned short hd_nirqs;
unsigned int hd_state; /* timer allocated */
unsigned int hd_irq[HPET_MAX_TIMERS];
};
static inline void hpet_reserve_timer(struct hpet_data *hd, int timer)
{
hd->hd_state |= (1 << timer);
return;
}
int hpet_alloc(struct hpet_data *);
#endif /* __KERNEL__ */
struct hpet_info {
unsigned long hi_ireqfreq; /* Hz */
unsigned long hi_flags; /* information */
unsigned short hi_hpet;
unsigned short hi_timer;
};
#define HPET_INFO_PERIODIC 0x0010 /* periodic-capable comparator */
#define HPET_IE_ON _IO('h', 0x01) /* interrupt on */
#define HPET_IE_OFF _IO('h', 0x02) /* interrupt off */
#define HPET_INFO _IOR('h', 0x03, struct hpet_info)
#define HPET_EPI _IO('h', 0x04) /* enable periodic */
#define HPET_DPI _IO('h', 0x05) /* disable periodic */
#define HPET_IRQFREQ _IOW('h', 0x6, unsigned long) /* IRQFREQ usec */
#endif /* !__HPET__ */