// SPDX-License-Identifier: GPL-2.0-only
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/export.h>
#include <linux/delay.h>
#include <linux/hpet.h>
#include <linux/cpu.h>
#include <linux/irq.h>
#include <asm/irq_remapping.h>
#include <asm/hpet.h>
#include <asm/time.h>
#include <asm/mwait.h>
#undef pr_fmt
#define pr_fmt(fmt) "hpet: " fmt
enum hpet_mode {
HPET_MODE_UNUSED,
HPET_MODE_LEGACY,
HPET_MODE_CLOCKEVT,
HPET_MODE_DEVICE,
};
struct hpet_channel {
struct clock_event_device evt;
unsigned int num;
unsigned int cpu;
unsigned int irq;
unsigned int in_use;
enum hpet_mode mode;
unsigned int boot_cfg;
char name[10];
};
struct hpet_base {
unsigned int nr_channels;
unsigned int nr_clockevents;
unsigned int boot_cfg;
struct hpet_channel *channels;
};
#define HPET_MASK CLOCKSOURCE_MASK(32)
#define HPET_MIN_CYCLES 128
#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
/*
* HPET address is set in acpi/boot.c, when an ACPI entry exists
*/
unsigned long hpet_address;
u8 hpet_blockid; /* OS timer block num */
bool hpet_msi_disable;
#ifdef CONFIG_GENERIC_MSI_IRQ
static DEFINE_PER_CPU(struct hpet_channel *, cpu_hpet_channel);
static struct irq_domain *hpet_domain;
#endif
static void __iomem *hpet_virt_address;
static struct hpet_base hpet_base;
static bool hpet_legacy_int_enabled;
static unsigned long hpet_freq;
bool boot_hpet_disable;
bool hpet_force_user;
static bool hpet_verbose;
static inline
struct hpet_channel *clockevent_to_channel(<