Skip to content

Commit

Permalink
x86: Avoid magic number with ELCR register accesses
Browse files Browse the repository at this point in the history
Define PIC_ELCR1 and PIC_ELCR2 macros for accesses to the ELCR registers 
implemented by many chipsets in their embedded 8259A PIC cores, avoiding 
magic numbers that are difficult to handle, and complementing the macros 
we already have for registers originally defined with discrete 8259A PIC 
implementations.  No functional change.

Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/alpine.DEB.2.21.2107200237300.9461@angie.orcam.me.uk
  • Loading branch information
Maciej W. Rozycki authored and Thomas Gleixner committed Aug 10, 2021
1 parent 0e8c6f5 commit d253166
Show file tree
Hide file tree
Showing 7 changed files with 15 additions and 11 deletions.
2 changes: 2 additions & 0 deletions arch/x86/include/asm/i8259.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ extern unsigned int cached_irq_mask;
#define PIC_MASTER_OCW3 PIC_MASTER_ISR
#define PIC_SLAVE_CMD 0xa0
#define PIC_SLAVE_IMR 0xa1
#define PIC_ELCR1 0x4d0
#define PIC_ELCR2 0x4d1

/* i8259A PIC related value */
#define PIC_CASCADE_IR 2
Expand Down
6 changes: 3 additions & 3 deletions arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
unsigned int old, new;

/* Real old ELCR mask */
old = inb(0x4d0) | (inb(0x4d1) << 8);
old = inb(PIC_ELCR1) | (inb(PIC_ELCR2) << 8);

/*
* If we use ACPI to set PCI IRQs, then we should clear ELCR
Expand All @@ -596,8 +596,8 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
return;

pr_warn("setting ELCR to %04x (from %04x)\n", new, old);
outb(new, 0x4d0);
outb(new >> 8, 0x4d1);
outb(new, PIC_ELCR1);
outb(new >> 8, PIC_ELCR2);
}

int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/apic/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ static bool irq_active_low(int idx)
static bool EISA_ELCR(unsigned int irq)
{
if (irq < nr_legacy_irqs()) {
unsigned int port = 0x4d0 + (irq >> 3);
unsigned int port = PIC_ELCR1 + (irq >> 3);
return (inb(port) >> (irq & 7)) & 1;
}
apic_printk(APIC_VERBOSE, KERN_INFO
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/apic/vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,7 @@ static void __init print_PIC(void)

pr_debug("... PIC ISR: %04x\n", v);

v = inb(0x4d1) << 8 | inb(0x4d0);
v = inb(PIC_ELCR2) << 8 | inb(PIC_ELCR1);
pr_debug("... PIC ELCR: %04x\n", v);
}

Expand Down
8 changes: 4 additions & 4 deletions arch/x86/kernel/i8259.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,15 @@ static char irq_trigger[2];
*/
static void restore_ELCR(char *trigger)
{
outb(trigger[0], 0x4d0);
outb(trigger[1], 0x4d1);
outb(trigger[0], PIC_ELCR1);
outb(trigger[1], PIC_ELCR2);
}

static void save_ELCR(char *trigger)
{
/* IRQ 0,1,2,8,13 are marked as reserved */
trigger[0] = inb(0x4d0) & 0xF8;
trigger[1] = inb(0x4d1) & 0xDE;
trigger[0] = inb(PIC_ELCR1) & 0xF8;
trigger[1] = inb(PIC_ELCR2) & 0xDE;
}

static void i8259A_resume(void)
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/kernel/mpparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/smp.h>
#include <linux/pci.h>

#include <asm/i8259.h>
#include <asm/io_apic.h>
#include <asm/acpi.h>
#include <asm/irqdomain.h>
Expand Down Expand Up @@ -251,7 +252,7 @@ static int __init ELCR_trigger(unsigned int irq)
{
unsigned int port;

port = 0x4d0 + (irq >> 3);
port = PIC_ELCR1 + (irq >> 3);
return (inb(port) >> (irq & 7)) & 1;
}

Expand Down
3 changes: 2 additions & 1 deletion arch/x86/pci/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/irq.h>
#include <linux/acpi.h>

#include <asm/i8259.h>
#include <asm/pc-conf-reg.h>
#include <asm/pci_x86.h>

Expand Down Expand Up @@ -158,7 +159,7 @@ static void __init pirq_peer_trick(void)
void elcr_set_level_irq(unsigned int irq)
{
unsigned char mask = 1 << (irq & 7);
unsigned int port = 0x4d0 + (irq >> 3);
unsigned int port = PIC_ELCR1 + (irq >> 3);
unsigned char val;
static u16 elcr_irq_mask;

Expand Down

0 comments on commit d253166

Please sign in to comment.