linux/arch/x86/kernel/i8259.c

// SPDX-License-Identifier: GPL-2.0
#include <linux/linkage.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/timex.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/syscore_ops.h>
#include <linux/bitops.h>
#include <linux/acpi.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/pgtable.h>

#include <linux/atomic.h>
#include <asm/timer.h>
#include <asm/hw_irq.h>
#include <asm/desc.h>
#include <asm/apic.h>
#include <asm/i8259.h>

/*
 * This is the 'legacy' 8259A Programmable Interrupt Controller,
 * present in the majority of PC/AT boxes.
 * plus some generic x86 specific things if generic specifics makes
 * any sense at all.
 */
static void init_8259A(int auto_eoi);

static bool pcat_compat __ro_after_init;
static int i8259A_auto_eoi;
DEFINE_RAW_SPINLOCK();

/*
 * 8259A PIC functions to handle ISA devices:
 */

/*
 * This contains the irq mask for both 8259A irq controllers,
 */
unsigned int cached_irq_mask =;

/*
 * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
 * boards the timer interrupt is not really connected to any IO-APIC pin,
 * it's fed to the master 8259A's IR0 line only.
 *
 * Any '1' bit in this mask means the IRQ is routed through the IO-APIC.
 * this 'mixed mode' IRQ handling costs nothing because it's only used
 * at IRQ setup time.
 */
unsigned long io_apic_irqs;

static void mask_8259A_irq(unsigned int irq)
{}

static void disable_8259A_irq(struct irq_data *data)
{}

static void unmask_8259A_irq(unsigned int irq)
{}

static void enable_8259A_irq(struct irq_data *data)
{}

static int i8259A_irq_pending(unsigned int irq)
{}

static void make_8259A_irq(unsigned int irq)
{}

/*
 * This function assumes to be called rarely. Switching between
 * 8259A registers is slow.
 * This has to be protected by the irq controller spinlock
 * before being called.
 */
static inline int i8259A_irq_real(unsigned int irq)
{}

/*
 * Careful! The 8259A is a fragile beast, it pretty
 * much _has_ to be done exactly like this (mask it
 * first, _then_ send the EOI, and the order of EOI
 * to the two 8259s is important!
 */
static void mask_and_ack_8259A(struct irq_data *data)
{}

struct irq_chip i8259A_chip =;

static char irq_trigger[2];
/* ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ */
static void restore_ELCR(char *trigger)
{}

static void save_ELCR(char *trigger)
{}

static void i8259A_resume(void)
{}

static int i8259A_suspend(void)
{}

static void i8259A_shutdown(void)
{}

static struct syscore_ops i8259_syscore_ops =;

static void mask_8259A(void)
{}

static void unmask_8259A(void)
{}

static int probe_8259A(void)
{}

static void init_8259A(int auto_eoi)
{}

/*
 * make i8259 a driver so that we can select pic functions at run time. the goal
 * is to make x86 binary compatible among pc compatible and non-pc compatible
 * platforms, such as x86 MID.
 */

static void legacy_pic_noop(void) { };
static void legacy_pic_uint_noop(unsigned int unused) { };
static void legacy_pic_int_noop(int unused) { };
static int legacy_pic_irq_pending_noop(unsigned int irq)
{}
static int legacy_pic_probe(void)
{}

struct legacy_pic null_legacy_pic =;

static struct legacy_pic default_legacy_pic =;

struct legacy_pic *legacy_pic =;
EXPORT_SYMBOL();

static int __init i8259A_init_ops(void)
{}
device_initcall(i8259A_init_ops);

void __init legacy_pic_pcat_compat(void)
{}