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:
Maciej W. Rozycki 2022-03-31 08:10:46 +01:00 committed by Thomas Gleixner
parent 5a0e5fa957
commit fe62bc2362

View File

@ -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;