Commit ccd8ec4a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'x86-irq-2021-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 PIRQ updates from Thomas Gleixner:
 "A set of updates to support port 0x22/0x23 based PCI configuration
  space which can be found on various ALi chipsets and is also available
  on older Intel systems which expose a PIRQ router.

  While the Intel support is more or less nostalgia, the ALi chips are
  still in use on popular embedded boards used for routers"

* tag 'x86-irq-2021-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86: Fix typo s/ECLR/ELCR/ for the PIC register
  x86: Avoid magic number with ELCR register accesses
  x86/PCI: Add support for the Intel 82426EX PIRQ router
  x86/PCI: Add support for the Intel 82374EB/82374SB (ESC) PIRQ router
  x86/PCI: Add support for the ALi M1487 (IBC) PIRQ router
  x86: Add support for 0x22/0x23 port I/O configuration space
parents 0a096f24 34739a28
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
+33 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Support for the configuration register space at port I/O locations
 * 0x22 and 0x23 variously used by PC architectures, e.g. the MP Spec,
 * Cyrix CPUs, numerous chipsets.
 */
#ifndef _ASM_X86_PC_CONF_REG_H
#define _ASM_X86_PC_CONF_REG_H

#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/types.h>

#define PC_CONF_INDEX		0x22
#define PC_CONF_DATA		0x23

#define PC_CONF_MPS_IMCR	0x70

extern raw_spinlock_t pc_conf_lock;

static inline u8 pc_conf_get(u8 reg)
{
	outb(reg, PC_CONF_INDEX);
	return inb(PC_CONF_DATA);
}

static inline void pc_conf_set(u8 reg, u8 data)
{
	outb(reg, PC_CONF_INDEX);
	outb(data, PC_CONF_DATA);
}

#endif /* _ASM_X86_PC_CONF_REG_H */
+4 −4
Original line number Diff line number Diff line
@@ -5,14 +5,14 @@
 * Access order is always 0x22 (=offset), 0x23 (=value)
 */

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

static inline u8 getCx86(u8 reg)
{
	outb(reg, 0x22);
	return inb(0x23);
	return pc_conf_get(reg);
}

static inline void setCx86(u8 reg, u8 data)
{
	outb(reg, 0x22);
	outb(data, 0x23);
	pc_conf_set(reg, data);
}
+6 −6
Original line number Diff line number Diff line
@@ -558,10 +558,10 @@ acpi_parse_nmi_src(union acpi_subtable_headers * header, const unsigned long end
 * If a PIC-mode SCI is not recognized or gives spurious IRQ7's
 * it may require Edge Trigger -- use "acpi_sci=edge"
 *
 * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
 * Port 0x4d0-4d1 are ELCR1 and ELCR2, the Edge/Level Control Registers
 * for the 8259 PIC.  bit[n] = 1 means irq[n] is Level, otherwise Edge.
 * ECLR1 is IRQs 0-7 (IRQ 0, 1, 2 must be 0)
 * ECLR2 is IRQs 8-15 (IRQ 8, 13 must be 0)
 * ELCR1 is IRQs 0-7 (IRQ 0, 1, 2 must be 0)
 * ELCR2 is IRQs 8-15 (IRQ 8, 13 must be 0)
 */

void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
@@ -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
@@ -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)
+3 −6
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@

#include <asm/trace/irq_vectors.h>
#include <asm/irq_remapping.h>
#include <asm/pc-conf-reg.h>
#include <asm/perf_event.h>
#include <asm/x86_init.h>
#include <linux/atomic.h>
@@ -132,18 +133,14 @@ static int enabled_via_apicbase __ro_after_init;
 */
static inline void imcr_pic_to_apic(void)
{
	/* select IMCR register */
	outb(0x70, 0x22);
	/* NMI and 8259 INTR go through APIC */
	outb(0x01, 0x23);
	pc_conf_set(PC_CONF_MPS_IMCR, 0x01);
}

static inline void imcr_apic_to_pic(void)
{
	/* select IMCR register */
	outb(0x70, 0x22);
	/* NMI and 8259 INTR go directly to BSP */
	outb(0x00, 0x23);
	pc_conf_set(PC_CONF_MPS_IMCR, 0x00);
}
#endif

Loading