mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
x86/PCI: Add support for the SiS85C497 PIRQ router
The SiS 85C496/497 486 Green PC VESA/ISA/PCI Chipset has support for PCI steering and the ELCR register implemented. These features are handled by the SiS85C497 AT Bus Controller & Megacell (ATM) ISA bridge, however the device is wired as a peer bridge directly to the host bus and has its PCI configuration registers decoded at addresses 0x80-0xff by the accompanying SiS85C496 PCI & CPU Memory Controller (PCM) host bridge[1]. Therefore we need to match on the host bridge's vendor and device ID. Like with the SiS85C503 PIRQ router handle link value ranges of 1-4 and 0xc0-0xc3, corresponding respectively to PIRQ line numbers counted from 1 and link register PCI configuration space addresses. References: [1] "486 Green PC VESA/ISA/PCI Chipset, SiS 85C496/497", Rev 3.0, Silicon Integrated Systems Corp., July 1995, Part IV, Section 3. "PCI Configuration Space Registers (00h ~ FFh)", p. 114 Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Nikolai Zhubr <zhubr.2@gmail.com> Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203301610490.22465@angie.orcam.me.uk
This commit is contained in:
parent
5a0e5fa957
commit
fe62bc2362
@ -580,6 +580,81 @@ static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PIRQ routing for the SiS85C497 AT Bus Controller & Megacell (ATM)
|
||||
* ISA bridge used with the SiS 85C496/497 486 Green PC VESA/ISA/PCI
|
||||
* Chipset.
|
||||
*
|
||||
* There are four PCI INTx#-to-IRQ Link registers provided in the
|
||||
* SiS85C497 part of the peculiar combined 85C496/497 configuration
|
||||
* space decoded by the SiS85C496 PCI & CPU Memory Controller (PCM)
|
||||
* host bridge, at 0xc0/0xc1/0xc2/0xc3 respectively for the PCI INT
|
||||
* A/B/C/D lines. Bit 7 enables the respective link if set and bits
|
||||
* 3:0 select the 8259A IRQ line as follows:
|
||||
*
|
||||
* 0000 : Reserved
|
||||
* 0001 : Reserved
|
||||
* 0010 : Reserved
|
||||
* 0011 : IRQ3
|
||||
* 0100 : IRQ4
|
||||
* 0101 : IRQ5
|
||||
* 0110 : IRQ6
|
||||
* 0111 : IRQ7
|
||||
* 1000 : Reserved
|
||||
* 1001 : IRQ9
|
||||
* 1010 : IRQ10
|
||||
* 1011 : IRQ11
|
||||
* 1100 : IRQ12
|
||||
* 1101 : Reserved
|
||||
* 1110 : IRQ14
|
||||
* 1111 : IRQ15
|
||||
*
|
||||
* We avoid using a reserved value for disabled links, hence the
|
||||
* choice of IRQ15 for that case.
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* "486 Green PC VESA/ISA/PCI Chipset, SiS 85C496/497", Rev 3.0,
|
||||
* Silicon Integrated Systems Corp., July 1995
|
||||
*/
|
||||
|
||||
#define PCI_SIS497_INTA_TO_IRQ_LINK 0xc0u
|
||||
|
||||
#define PIRQ_SIS497_IRQ_MASK 0x0fu
|
||||
#define PIRQ_SIS497_IRQ_ENABLE 0x80u
|
||||
|
||||
static int pirq_sis497_get(struct pci_dev *router, struct pci_dev *dev,
|
||||
int pirq)
|
||||
{
|
||||
int reg;
|
||||
u8 x;
|
||||
|
||||
reg = pirq;
|
||||
if (reg >= 1 && reg <= 4)
|
||||
reg += PCI_SIS497_INTA_TO_IRQ_LINK - 1;
|
||||
|
||||
pci_read_config_byte(router, reg, &x);
|
||||
return (x & PIRQ_SIS497_IRQ_ENABLE) ? (x & PIRQ_SIS497_IRQ_MASK) : 0;
|
||||
}
|
||||
|
||||
static int pirq_sis497_set(struct pci_dev *router, struct pci_dev *dev,
|
||||
int pirq, int irq)
|
||||
{
|
||||
int reg;
|
||||
u8 x;
|
||||
|
||||
reg = pirq;
|
||||
if (reg >= 1 && reg <= 4)
|
||||
reg += PCI_SIS497_INTA_TO_IRQ_LINK - 1;
|
||||
|
||||
pci_read_config_byte(router, reg, &x);
|
||||
x &= ~(PIRQ_SIS497_IRQ_MASK | PIRQ_SIS497_IRQ_ENABLE);
|
||||
x |= irq ? (PIRQ_SIS497_IRQ_ENABLE | irq) : PIRQ_SIS497_IRQ_MASK;
|
||||
pci_write_config_byte(router, reg, x);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* PIRQ routing for SiS 85C503 router used in several SiS chipsets.
|
||||
* We have to deal with the following issues here:
|
||||
@ -962,6 +1037,11 @@ static __init int serverworks_router_probe(struct irq_router *r,
|
||||
static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
|
||||
{
|
||||
switch (device) {
|
||||
case PCI_DEVICE_ID_SI_496:
|
||||
r->name = "SiS85C497";
|
||||
r->get = pirq_sis497_get;
|
||||
r->set = pirq_sis497_set;
|
||||
return 1;
|
||||
case PCI_DEVICE_ID_SI_503:
|
||||
r->name = "SiS85C503";
|
||||
r->get = pirq_sis503_get;
|
||||
|
Loading…
Reference in New Issue
Block a user