diff --git a/arch/x86/soc/quark_x1000/soc.c b/arch/x86/soc/quark_x1000/soc.c index 22c9eb4b033..f7f05ba0c3c 100644 --- a/arch/x86/soc/quark_x1000/soc.c +++ b/arch/x86/soc/quark_x1000/soc.c @@ -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; } diff --git a/arch/x86/soc/quark_x1000/soc.h b/arch/x86/soc/quark_x1000/soc.h index ce00c922fba..0141c4222fa 100644 --- a/arch/x86/soc/quark_x1000/soc.h +++ b/arch/x86/soc/quark_x1000/soc.h @@ -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 diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d9ef75dc775..5e06be6572d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -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;