Quark: Set up IRQ routing for PCIe explicitly

IRQAGENT3 is initialized explicitly, but IRQAGENT0 isn't and its value
is based on the value the BIOS or bootloader had set before. Fix this by
explicitly initializing IRQAGENT0, and swizzle the IRQs to reduce
conflicts.

Update the pci_pin2irq function to accommodate for these changes.
Also remove pci_irq2pin function since it is unused.

Change-Id: I7b1dfc7659ab227fe66711a3af5a1f34fd4a7972
Signed-off-by: Ido Yariv <idox.yariv@intel.com>
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Signed-off-by: Ido Yariv <ido@wizery.com>
This commit is contained in:
Ido Yariv 2016-01-28 14:50:59 -05:00 committed by Anas Nashif
parent 6b6ef8bbb7
commit 3db6a541c8
3 changed files with 19 additions and 23 deletions

View file

@ -63,6 +63,10 @@ static int pci_legacy_bridge_irq_config(struct device *unused)
pci_legacy_bridge_configure(&info, 1, PCI_INTB, 17);
pci_legacy_bridge_configure(&info, 1, PCI_INTC, 18);
pci_legacy_bridge_configure(&info, 1, PCI_INTD, 19);
pci_legacy_bridge_configure(&info, 0, PCI_INTA, 17);
pci_legacy_bridge_configure(&info, 0, PCI_INTB, 18);
pci_legacy_bridge_configure(&info, 0, PCI_INTC, 19);
pci_legacy_bridge_configure(&info, 0, PCI_INTD, 16);
}
return 0;
}

View file

@ -95,30 +95,23 @@ extern "C" {
* INTC (pin 3) -> IRQ 18
* INTD (pin 4) -> IRQ 19
*
* In case a mini-PCIe card is used, the IRQs are swizzled:
* INTA (pin 1) -> IRQ 17
* INTB (pin 2) -> IRQ 18
* INTC (pin 3) -> IRQ 19
* INTD (pin 4) -> IRQ 16
*
* @return IRQ number, -1 if the result is incorrect
*
*/
static inline int pci_pin2irq(int pin)
static inline int pci_pin2irq(int bus, int dev, int pin)
{
if (bus < 0 || bus > 1)
return -1;
if ((pin < PCI_INTA) || (pin > PCI_INTD))
return -1;
return NUM_STD_IRQS + pin - 1;
}
/**
*
* @brief Convert IRQ to PCI interrupt pin
*
* @return pin number, -1 if the result is incorrect
*
*/
static inline int pci_irq2pin(int irq)
{
if ((irq < NUM_STD_IRQS) || (irq > NUM_STD_IRQS + PCI_INTD - 1))
return -1;
return irq - NUM_STD_IRQS + 1;
return NUM_STD_IRQS + ((pin - 1 + bus) & 3);
}
#ifdef __cplusplus

View file

@ -314,13 +314,16 @@ static inline int pci_dev_scan(union pci_addr_reg pci_ctrl_addr,
lookup.baridx != lookup.info.bar) {
continue;
} else {
dev_info->bus = lookup.bus;
dev_info->dev = lookup.dev;
dev_info->vendor_id =
pci_dev_header.field.vendor_id;
dev_info->device_id =
pci_dev_header.field.device_id;
dev_info->class_type =
pci_dev_header.field.class;
dev_info->irq = pci_pin2irq(
dev_info->irq = pci_pin2irq(dev_info->bus,
dev_info->dev,
pci_dev_header.field.interrupt_pin);
dev_info->function = lookup.func;
dev_info->bar = lookup.baridx;
@ -395,12 +398,8 @@ int pci_bus_scan(struct pci_dev_info *dev_info)
pci_ctrl_addr.field.bus = lookup.bus;
pci_ctrl_addr.field.device = lookup.dev;
if (pci_dev_scan(pci_ctrl_addr, dev_info)) {
dev_info->bus = lookup.bus;
dev_info->dev = lookup.dev;
if (pci_dev_scan(pci_ctrl_addr, dev_info))
return 1;
}
if (lookup.info.function != PCI_FUNCTION_ANY) {
lookup.func = lookup.info.function;