Commit ccd8ec4a authored by Linus Torvalds's avatar Linus Torvalds

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
......@@ -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
......
/* 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 */
......@@ -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);
}
......@@ -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)
......
......@@ -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
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -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>
......@@ -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;
}
......
......@@ -541,17 +541,17 @@ static int picdev_slave_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
addr, len, val);
}
static int picdev_eclr_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
static int picdev_elcr_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
gpa_t addr, int len, const void *val)
{
return picdev_write(container_of(dev, struct kvm_pic, dev_eclr),
return picdev_write(container_of(dev, struct kvm_pic, dev_elcr),
addr, len, val);
}
static int picdev_eclr_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
static int picdev_elcr_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
gpa_t addr, int len, void *val)
{
return picdev_read(container_of(dev, struct kvm_pic, dev_eclr),
return picdev_read(container_of(dev, struct kvm_pic, dev_elcr),
addr, len, val);
}
......@@ -577,9 +577,9 @@ static const struct kvm_io_device_ops picdev_slave_ops = {
.write = picdev_slave_write,
};
static const struct kvm_io_device_ops picdev_eclr_ops = {
.read = picdev_eclr_read,
.write = picdev_eclr_write,
static const struct kvm_io_device_ops picdev_elcr_ops = {
.read = picdev_elcr_read,
.write = picdev_elcr_write,
};
int kvm_pic_init(struct kvm *kvm)
......@@ -602,7 +602,7 @@ int kvm_pic_init(struct kvm *kvm)
*/
kvm_iodevice_init(&s->dev_master, &picdev_master_ops);
kvm_iodevice_init(&s->dev_slave, &picdev_slave_ops);
kvm_iodevice_init(&s->dev_eclr, &picdev_eclr_ops);
kvm_iodevice_init(&s->dev_elcr, &picdev_elcr_ops);
mutex_lock(&kvm->slots_lock);
ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0x20, 2,
&s->dev_master);
......@@ -613,7 +613,7 @@ int kvm_pic_init(struct kvm *kvm)
if (ret < 0)
goto fail_unreg_2;
ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0x4d0, 2, &s->dev_eclr);
ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0x4d0, 2, &s->dev_elcr);
if (ret < 0)
goto fail_unreg_1;
......@@ -647,7 +647,7 @@ void kvm_pic_destroy(struct kvm *kvm)
mutex_lock(&kvm->slots_lock);
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_master);
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_slave);
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_eclr);
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_elcr);
mutex_unlock(&kvm->slots_lock);
kvm->arch.vpic = NULL;
......
......@@ -55,7 +55,7 @@ struct kvm_pic {
int output; /* intr from master PIC */
struct kvm_io_device dev_master;
struct kvm_io_device dev_slave;
struct kvm_io_device dev_eclr;
struct kvm_io_device dev_elcr;
void (*ack_notifier)(void *opaque, int irq);
unsigned long irq_states[PIC_NUM_PINS];
};
......
......@@ -44,6 +44,7 @@ obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o
lib-y := delay.o misc.o cmdline.o cpu.o
lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o
lib-y += memcpy_$(BITS).o
lib-y += pc-conf-reg.o
lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc.o copy_mc_64.o
lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o
lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
......
// 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. As the space is indirectly addressed
* it may have to be protected with a spinlock, depending on the context.
*/
#include <linux/spinlock.h>
#include <asm/pc-conf-reg.h>
DEFINE_RAW_SPINLOCK(pc_conf_lock);
......@@ -13,9 +13,13 @@
#include <linux/dmi.h>
#include <linux/io.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <asm/io_apic.h>
#include <linux/irq.h>
#include <linux/acpi.h>
#include <asm/i8259.h>
#include <asm/pc-conf-reg.h>
#include <asm/pci_x86.h>
#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
......@@ -47,6 +51,8 @@ struct irq_router {
int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq);
int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq,
int new);
int (*lvl)(struct pci_dev *router, struct pci_dev *dev, int pirq,
int irq);
};
struct irq_router_handler {
......@@ -153,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;
......@@ -169,6 +175,139 @@ void elcr_set_level_irq(unsigned int irq)
}
}
/*
* PIRQ routing for the M1487 ISA Bus Controller (IBC) ASIC used
* with the ALi FinALi 486 chipset. The IBC is not decoded in the
* PCI configuration space, so we identify it by the accompanying
* M1489 Cache-Memory PCI Controller (CMP) ASIC.
*
* There are four 4-bit mappings provided, spread across two PCI
* INTx Routing Table Mapping Registers, available in the port I/O
* space accessible indirectly via the index/data register pair at
* 0x22/0x23, located at indices 0x42 and 0x43 for the INT1/INT2
* and INT3/INT4 lines respectively. The INT1/INT3 and INT2/INT4
* lines are mapped in the low and the high 4-bit nibble of the
* corresponding register as follows:
*
* 0000 : Disabled
* 0001 : IRQ9
* 0010 : IRQ3
* 0011 : IRQ10
* 0100 : IRQ4
* 0101 : IRQ5
* 0110 : IRQ7
* 0111 : IRQ6
* 1000 : Reserved
* 1001 : IRQ11
* 1010 : Reserved
* 1011 : IRQ12
* 1100 : Reserved
* 1101 : IRQ14
* 1110 : Reserved
* 1111 : IRQ15
*
* In addition to the usual ELCR register pair there is a separate
* PCI INTx Sensitivity Register at index 0x44 in the same port I/O
* space, whose bits 3:0 select the trigger mode for INT[4:1] lines
* respectively. Any bit set to 1 causes interrupts coming on the
* corresponding line to be passed to ISA as edge-triggered and
* otherwise they are passed as level-triggered. Manufacturer's
* documentation says this register has to be set consistently with
* the relevant ELCR register.
*
* Accesses to the port I/O space concerned here need to be unlocked
* by writing the value of 0xc5 to the Lock Register at index 0x03
* beforehand. Any other value written to said register prevents
* further accesses from reaching the register file, except for the
* Lock Register being written with 0xc5 again.
*
* References:
*
* "M1489/M1487: 486 PCI Chip Set", Version 1.2, Acer Laboratories
* Inc., July 1997
*/
#define PC_CONF_FINALI_LOCK 0x03u
#define PC_CONF_FINALI_PCI_INTX_RT1 0x42u
#define PC_CONF_FINALI_PCI_INTX_RT2 0x43u
#define PC_CONF_FINALI_PCI_INTX_SENS 0x44u
#define PC_CONF_FINALI_LOCK_KEY 0xc5u
static u8 read_pc_conf_nybble(u8 base, u8 index)
{
u8 reg = base + (index >> 1);
u8 x;
x = pc_conf_get(reg);
return index & 1 ? x >> 4 : x & 0xf;
}
static void write_pc_conf_nybble(u8 base, u8 index, u8 val)
{
u8 reg = base + (index >> 1);
u8 x;
x = pc_conf_get(reg);
x = index & 1 ? (x & 0x0f) | (val << 4) : (x & 0xf0) | val;
pc_conf_set(reg, x);
}
static int pirq_finali_get(struct pci_dev *router, struct pci_dev *dev,
int pirq)
{
static const u8 irqmap[16] = {
0, 9, 3, 10, 4, 5, 7, 6, 0, 11, 0, 12, 0, 14, 0, 15
};
unsigned long flags;
u8 x;
raw_spin_lock_irqsave(&pc_conf_lock, flags);
pc_conf_set(PC_CONF_FINALI_LOCK, PC_CONF_FINALI_LOCK_KEY);
x = irqmap[read_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, pirq - 1)];
pc_conf_set(PC_CONF_FINALI_LOCK, 0);
raw_spin_unlock_irqrestore(&pc_conf_lock, flags);
return x;
}
static int pirq_finali_set(struct pci_dev *router, struct pci_dev *dev,
int pirq, int irq)
{
static const u8 irqmap[16] = {
0, 0, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15
};
u8 val = irqmap[irq];
unsigned long flags;
if (!val)
return 0;
raw_spin_lock_irqsave(&pc_conf_lock, flags);
pc_conf_set(PC_CONF_FINALI_LOCK, PC_CONF_FINALI_LOCK_KEY);
write_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, pirq - 1, val);
pc_conf_set(PC_CONF_FINALI_LOCK, 0);
raw_spin_unlock_irqrestore(&pc_conf_lock, flags);
return 1;
}
static int pirq_finali_lvl(struct pci_dev *router, struct pci_dev *dev,
int pirq, int irq)
{
u8 mask = ~(1u << (pirq - 1));
unsigned long flags;
u8 trig;
elcr_set_level_irq(irq);
raw_spin_lock_irqsave(&pc_conf_lock, flags);
pc_conf_set(PC_CONF_FINALI_LOCK, PC_CONF_FINALI_LOCK_KEY);
trig = pc_conf_get(PC_CONF_FINALI_PCI_INTX_SENS);
trig &= mask;
pc_conf_set(PC_CONF_FINALI_PCI_INTX_SENS, trig);
pc_conf_set(PC_CONF_FINALI_LOCK, 0);
raw_spin_unlock_irqrestore(&pc_conf_lock, flags);
return 1;
}
/*
* Common IRQ routing practice: nibbles in config space,
* offset by some magic constant.
......@@ -219,6 +358,74 @@ static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
return 0;
}
/*
* PIRQ routing for the 82374EB/82374SB EISA System Component (ESC)
* ASIC used with the Intel 82420 and 82430 PCIsets. The ESC is not
* decoded in the PCI configuration space, so we identify it by the
* accompanying 82375EB/82375SB PCI-EISA Bridge (PCEB) ASIC.
*
* There are four PIRQ Route Control registers, available in the
* port I/O space accessible indirectly via the index/data register
* pair at 0x22/0x23, located at indices 0x60/0x61/0x62/0x63 for the
* PIRQ0/1/2/3# lines respectively. The semantics is the same as
* with the PIIX router.
*
* Accesses to the port I/O space concerned here need to be unlocked
* by writing the value of 0x0f to the ESC ID Register at index 0x02
* beforehand. Any other value written to said register prevents
* further accesses from reaching the register file, except for the
* ESC ID Register being written with 0x0f again.
*
* References:
*
* "82374EB/82374SB EISA System Component (ESC)", Intel Corporation,
* Order Number: 290476-004, March 1996
*
* "82375EB/82375SB PCI-EISA Bridge (PCEB)", Intel Corporation, Order
* Number: 290477-004, March 1996
*/
#define PC_CONF_I82374_ESC_ID 0x02u
#define PC_CONF_I82374_PIRQ_ROUTE_CONTROL 0x60u
#define PC_CONF_I82374_ESC_ID_KEY 0x0fu
static int pirq_esc_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
unsigned long flags;
int reg;
u8 x;
reg = pirq;
if (reg >= 1 && reg <= 4)
reg += PC_CONF_I82374_PIRQ_ROUTE_CONTROL - 1;
raw_spin_lock_irqsave(&pc_conf_lock, flags);
pc_conf_set(PC_CONF_I82374_ESC_ID, PC_CONF_I82374_ESC_ID_KEY);
x = pc_conf_get(reg);
pc_conf_set(PC_CONF_I82374_ESC_ID, 0);
raw_spin_unlock_irqrestore(&pc_conf_lock, flags);
return (x < 16) ? x : 0;
}
static int pirq_esc_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
int irq)
{
unsigned long flags;
int reg;
reg = pirq;
if (reg >= 1 && reg <= 4)
reg += PC_CONF_I82374_PIRQ_ROUTE_CONTROL - 1;
raw_spin_lock_irqsave(&pc_conf_lock, flags);
pc_conf_set(PC_CONF_I82374_ESC_ID, PC_CONF_I82374_ESC_ID_KEY);
pc_conf_set(reg, irq);
pc_conf_set(PC_CONF_I82374_ESC_ID, 0);
raw_spin_unlock_irqrestore(&pc_conf_lock, flags);
return 1;
}
/*
* The Intel PIIX4 pirq rules are fairly simple: "pirq" is
* just a pointer to the config space.
......@@ -237,6 +444,50 @@ static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
return 1;
}
/*
* PIRQ routing for the 82426EX ISA Bridge (IB) ASIC used with the
* Intel 82420EX PCIset.
*
* There are only two PIRQ Route Control registers, available in the
* combined 82425EX/82426EX PCI configuration space, at 0x66 and 0x67
* for the PIRQ0# and PIRQ1# lines respectively. The semantics is
* the same as with the PIIX router.
*
* References:
*
* "82420EX PCIset Data Sheet, 82425EX PCI System Controller (PSC)
* and 82426EX ISA Bridge (IB)", Intel Corporation, Order Number:
* 290488-004, December 1995
*/
#define PCI_I82426EX_PIRQ_ROUTE_CONTROL 0x66u
static int pirq_ib_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
int reg;
u8 x;
reg = pirq;
if (reg >= 1 && reg <= 2)
reg += PCI_I82426EX_PIRQ_ROUTE_CONTROL - 1;
pci_read_config_byte(router, reg, &x);
return (x < 16) ? x : 0;
}
static int pirq_ib_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
int irq)
{
int reg;
reg = pirq;
if (reg >= 1 && reg <= 2)
reg += PCI_I82426EX_PIRQ_ROUTE_CONTROL - 1;
pci_write_config_byte(router, reg, irq);
return 1;
}
/*
* The VIA pirq rules are nibble-based, like ALI,
* but without the ugly irq number munging.
......@@ -549,6 +800,11 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
return 0;
switch (device) {
case PCI_DEVICE_ID_INTEL_82375:
r->name = "PCEB/ESC";
r->get = pirq_esc_get;
r->set = pirq_esc_set;
return 1;
case PCI_DEVICE_ID_INTEL_82371FB_0:
case PCI_DEVICE_ID_INTEL_82371SB_0:
case PCI_DEVICE_ID_INTEL_82371AB_0:
......@@ -594,6 +850,11 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
r->get = pirq_piix_get;
r->set = pirq_piix_set;
return 1;
case PCI_DEVICE_ID_INTEL_82425:
r->name = "PSC/IB";
r->get = pirq_ib_get;
r->set = pirq_ib_set;
return 1;
}
if ((device >= PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN &&
......@@ -745,6 +1006,12 @@ static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router,
static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
switch (device) {
case PCI_DEVICE_ID_AL_M1489:
r->name = "FinALi";
r->get = pirq_finali_get;
r->set = pirq_finali_set;
r->lvl = pirq_finali_lvl;
return 1;
case PCI_DEVICE_ID_AL_M1533:
case PCI_DEVICE_ID_AL_M1563:
r->name = "ALI";
......@@ -968,10 +1235,16 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
} else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \
((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask))) {
msg = "found";
if (r->lvl)
r->lvl(pirq_router_dev, dev, pirq, irq);
else
elcr_set_level_irq(irq);
} else if (newirq && r->set &&
(dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
if (r->set(pirq_router_dev, dev, pirq, newirq)) {
if (r->lvl)
r->lvl(pirq_router_dev, dev, pirq, newirq);
else
elcr_set_level_irq(newirq);
msg = "assigned";
irq = newirq;
......
......@@ -1121,6 +1121,7 @@
#define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a
#define PCI_VENDOR_ID_AL 0x10b9
#define PCI_DEVICE_ID_AL_M1489 0x1489
#define PCI_DEVICE_ID_AL_M1533 0x1533
#define PCI_DEVICE_ID_AL_M1535 0x1535
#define PCI_DEVICE_ID_AL_M1541 0x1541
......@@ -2643,6 +2644,7 @@
#define PCI_DEVICE_ID_INTEL_82375 0x0482
#define PCI_DEVICE_ID_INTEL_82424 0x0483
#define PCI_DEVICE_ID_INTEL_82378 0x0484
#define PCI_DEVICE_ID_INTEL_82425 0x0486
#define PCI_DEVICE_ID_INTEL_MRST_SD0 0x0807
#define PCI_DEVICE_ID_INTEL_MRST_SD1 0x0808
#define PCI_DEVICE_ID_INTEL_MFD_SD 0x0820
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment