Skip to content

Commit ccd8ec4

Browse files
committed
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
2 parents 0a096f2 + 34739a2 commit ccd8ec4

File tree

15 files changed

+359
-37
lines changed

15 files changed

+359
-37
lines changed

arch/x86/include/asm/i8259.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ extern unsigned int cached_irq_mask;
1919
#define PIC_MASTER_OCW3 PIC_MASTER_ISR
2020
#define PIC_SLAVE_CMD 0xa0
2121
#define PIC_SLAVE_IMR 0xa1
22+
#define PIC_ELCR1 0x4d0
23+
#define PIC_ELCR2 0x4d1
2224

2325
/* i8259A PIC related value */
2426
#define PIC_CASCADE_IR 2

arch/x86/include/asm/pc-conf-reg.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Support for the configuration register space at port I/O locations
4+
* 0x22 and 0x23 variously used by PC architectures, e.g. the MP Spec,
5+
* Cyrix CPUs, numerous chipsets.
6+
*/
7+
#ifndef _ASM_X86_PC_CONF_REG_H
8+
#define _ASM_X86_PC_CONF_REG_H
9+
10+
#include <linux/io.h>
11+
#include <linux/spinlock.h>
12+
#include <linux/types.h>
13+
14+
#define PC_CONF_INDEX 0x22
15+
#define PC_CONF_DATA 0x23
16+
17+
#define PC_CONF_MPS_IMCR 0x70
18+
19+
extern raw_spinlock_t pc_conf_lock;
20+
21+
static inline u8 pc_conf_get(u8 reg)
22+
{
23+
outb(reg, PC_CONF_INDEX);
24+
return inb(PC_CONF_DATA);
25+
}
26+
27+
static inline void pc_conf_set(u8 reg, u8 data)
28+
{
29+
outb(reg, PC_CONF_INDEX);
30+
outb(data, PC_CONF_DATA);
31+
}
32+
33+
#endif /* _ASM_X86_PC_CONF_REG_H */

arch/x86/include/asm/processor-cyrix.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
* Access order is always 0x22 (=offset), 0x23 (=value)
66
*/
77

8+
#include <asm/pc-conf-reg.h>
9+
810
static inline u8 getCx86(u8 reg)
911
{
10-
outb(reg, 0x22);
11-
return inb(0x23);
12+
return pc_conf_get(reg);
1213
}
1314

1415
static inline void setCx86(u8 reg, u8 data)
1516
{
16-
outb(reg, 0x22);
17-
outb(data, 0x23);
17+
pc_conf_set(reg, data);
1818
}

arch/x86/kernel/acpi/boot.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -558,10 +558,10 @@ acpi_parse_nmi_src(union acpi_subtable_headers * header, const unsigned long end
558558
* If a PIC-mode SCI is not recognized or gives spurious IRQ7's
559559
* it may require Edge Trigger -- use "acpi_sci=edge"
560560
*
561-
* Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
561+
* Port 0x4d0-4d1 are ELCR1 and ELCR2, the Edge/Level Control Registers
562562
* for the 8259 PIC. bit[n] = 1 means irq[n] is Level, otherwise Edge.
563-
* ECLR1 is IRQs 0-7 (IRQ 0, 1, 2 must be 0)
564-
* ECLR2 is IRQs 8-15 (IRQ 8, 13 must be 0)
563+
* ELCR1 is IRQs 0-7 (IRQ 0, 1, 2 must be 0)
564+
* ELCR2 is IRQs 8-15 (IRQ 8, 13 must be 0)
565565
*/
566566

567567
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)
570570
unsigned int old, new;
571571

572572
/* Real old ELCR mask */
573-
old = inb(0x4d0) | (inb(0x4d1) << 8);
573+
old = inb(PIC_ELCR1) | (inb(PIC_ELCR2) << 8);
574574

575575
/*
576576
* 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)
596596
return;
597597

598598
pr_warn("setting ELCR to %04x (from %04x)\n", new, old);
599-
outb(new, 0x4d0);
600-
outb(new >> 8, 0x4d1);
599+
outb(new, PIC_ELCR1);
600+
outb(new >> 8, PIC_ELCR2);
601601
}
602602

603603
int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)

arch/x86/kernel/apic/apic.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include <asm/trace/irq_vectors.h>
4040
#include <asm/irq_remapping.h>
41+
#include <asm/pc-conf-reg.h>
4142
#include <asm/perf_event.h>
4243
#include <asm/x86_init.h>
4344
#include <linux/atomic.h>
@@ -132,18 +133,14 @@ static int enabled_via_apicbase __ro_after_init;
132133
*/
133134
static inline void imcr_pic_to_apic(void)
134135
{
135-
/* select IMCR register */
136-
outb(0x70, 0x22);
137136
/* NMI and 8259 INTR go through APIC */
138-
outb(0x01, 0x23);
137+
pc_conf_set(PC_CONF_MPS_IMCR, 0x01);
139138
}
140139

141140
static inline void imcr_apic_to_pic(void)
142141
{
143-
/* select IMCR register */
144-
outb(0x70, 0x22);
145142
/* NMI and 8259 INTR go directly to BSP */
146-
outb(0x00, 0x23);
143+
pc_conf_set(PC_CONF_MPS_IMCR, 0x00);
147144
}
148145
#endif
149146

arch/x86/kernel/apic/io_apic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ static bool irq_active_low(int idx)
764764
static bool EISA_ELCR(unsigned int irq)
765765
{
766766
if (irq < nr_legacy_irqs()) {
767-
unsigned int port = 0x4d0 + (irq >> 3);
767+
unsigned int port = PIC_ELCR1 + (irq >> 3);
768768
return (inb(port) >> (irq & 7)) & 1;
769769
}
770770
apic_printk(APIC_VERBOSE, KERN_INFO

arch/x86/kernel/apic/vector.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ static void __init print_PIC(void)
12991299

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

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

arch/x86/kernel/i8259.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,15 +235,15 @@ static char irq_trigger[2];
235235
*/
236236
static void restore_ELCR(char *trigger)
237237
{
238-
outb(trigger[0], 0x4d0);
239-
outb(trigger[1], 0x4d1);
238+
outb(trigger[0], PIC_ELCR1);
239+
outb(trigger[1], PIC_ELCR2);
240240
}
241241

242242
static void save_ELCR(char *trigger)
243243
{
244244
/* IRQ 0,1,2,8,13 are marked as reserved */
245-
trigger[0] = inb(0x4d0) & 0xF8;
246-
trigger[1] = inb(0x4d1) & 0xDE;
245+
trigger[0] = inb(PIC_ELCR1) & 0xF8;
246+
trigger[1] = inb(PIC_ELCR2) & 0xDE;
247247
}
248248

249249
static void i8259A_resume(void)

arch/x86/kernel/mpparse.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/smp.h>
2020
#include <linux/pci.h>
2121

22+
#include <asm/i8259.h>
2223
#include <asm/io_apic.h>
2324
#include <asm/acpi.h>
2425
#include <asm/irqdomain.h>
@@ -251,7 +252,7 @@ static int __init ELCR_trigger(unsigned int irq)
251252
{
252253
unsigned int port;
253254

254-
port = 0x4d0 + (irq >> 3);
255+
port = PIC_ELCR1 + (irq >> 3);
255256
return (inb(port) >> (irq & 7)) & 1;
256257
}
257258

arch/x86/kvm/i8259.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -541,17 +541,17 @@ static int picdev_slave_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
541541
addr, len, val);
542542
}
543543

544-
static int picdev_eclr_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
544+
static int picdev_elcr_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
545545
gpa_t addr, int len, const void *val)
546546
{
547-
return picdev_write(container_of(dev, struct kvm_pic, dev_eclr),
547+
return picdev_write(container_of(dev, struct kvm_pic, dev_elcr),
548548
addr, len, val);
549549
}
550550

551-
static int picdev_eclr_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
551+
static int picdev_elcr_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
552552
gpa_t addr, int len, void *val)
553553
{
554-
return picdev_read(container_of(dev, struct kvm_pic, dev_eclr),
554+
return picdev_read(container_of(dev, struct kvm_pic, dev_elcr),
555555
addr, len, val);
556556
}
557557

@@ -577,9 +577,9 @@ static const struct kvm_io_device_ops picdev_slave_ops = {
577577
.write = picdev_slave_write,
578578
};
579579

580-
static const struct kvm_io_device_ops picdev_eclr_ops = {
581-
.read = picdev_eclr_read,
582-
.write = picdev_eclr_write,
580+
static const struct kvm_io_device_ops picdev_elcr_ops = {
581+
.read = picdev_elcr_read,
582+
.write = picdev_elcr_write,
583583
};
584584

585585
int kvm_pic_init(struct kvm *kvm)
@@ -602,7 +602,7 @@ int kvm_pic_init(struct kvm *kvm)
602602
*/
603603
kvm_iodevice_init(&s->dev_master, &picdev_master_ops);
604604
kvm_iodevice_init(&s->dev_slave, &picdev_slave_ops);
605-
kvm_iodevice_init(&s->dev_eclr, &picdev_eclr_ops);
605+
kvm_iodevice_init(&s->dev_elcr, &picdev_elcr_ops);
606606
mutex_lock(&kvm->slots_lock);
607607
ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0x20, 2,
608608
&s->dev_master);
@@ -613,7 +613,7 @@ int kvm_pic_init(struct kvm *kvm)
613613
if (ret < 0)
614614
goto fail_unreg_2;
615615

616-
ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0x4d0, 2, &s->dev_eclr);
616+
ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0x4d0, 2, &s->dev_elcr);
617617
if (ret < 0)
618618
goto fail_unreg_1;
619619

@@ -647,7 +647,7 @@ void kvm_pic_destroy(struct kvm *kvm)
647647
mutex_lock(&kvm->slots_lock);
648648
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_master);
649649
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_slave);
650-
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_eclr);
650+
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_elcr);
651651
mutex_unlock(&kvm->slots_lock);
652652

653653
kvm->arch.vpic = NULL;

0 commit comments

Comments
 (0)