static void __devinit pdev_fixup_irq(struct pci_dev *dev, u8 (*swizzle)(struct pci_dev *, u8 *), int (*map_irq)(const struct pci_dev *, u8, u8)) { u8 pin, slot; int irq = 0; /* If this device is not on the primary bus, we need to figure out which interrupt pin it will come in on. We know which slot it will come in on 'cos that slot is where the bridge is. Each time the interrupt line passes through a PCI-PCI bridge we must apply the swizzle function. */ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); /* Cope with illegal. */ if (pin > 4) pin = 1; if (pin != 0) { /* Follow the chain of bridges, swizzling as we go. */ slot = (*swizzle)(dev, &pin); irq = (*map_irq)(dev, slot, pin); if (irq == -1) irq = 0; } dev->irq = irq; dev_dbg(&dev->dev, "fixup irq: got %d\n", dev->irq); /* Always tell the device, so the driver knows what is the real IRQ to use; the device does not use it. */ pcibios_update_irq(dev, irq); }
static void __init pdev_fixup_irq(struct pci_dev *dev, u8 (*swizzle)(struct pci_dev *, u8 *), int (*map_irq)(struct pci_dev *, u8, u8)) { u8 pin, slot; int irq = 0; pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin > 4) pin = 1; if (pin != 0) { slot = (*swizzle)(dev, &pin); irq = (*map_irq)(dev, slot, pin); if (irq == -1) irq = 0; } dev->irq = irq; dev_dbg(&dev->dev, "fixup irq: got %d\n", dev->irq); pcibios_update_irq(dev, irq); }
void __init pcibios_fixup_irqs(void) { struct pci_dev *dev; int slot_num; #ifdef DEBUG printk("-->pcibios_fixup_irqs\n"); #endif pci_for_each_dev(dev) { slot_num = PCI_SLOT(dev->devfn); #ifdef DEBUG printk("-->pcibios_fixup_irqs, slot=%x\n", slot_num); #endif switch (slot_num) { case PCI_DEVICE_ID_3250: /* BCM3250 */ pcibios_update_irq(dev, BCM_LINUX_3250_IRQ); dev->irq = BCM_LINUX_3250_IRQ; break; case PCI_DEVICE_ID_SATA: /* IDE controller */ pcibios_update_irq(dev, BCM_LINUX_SATA_IRQ); dev->irq = BCM_LINUX_SATA_IRQ; break; case PCI_DEVICE_ID_EXT: /* On-board PCI slot */ pcibios_update_irq(dev, BCM_LINUX_EXT_PCI_IRQ); dev->irq = BCM_LINUX_EXT_PCI_IRQ; break; case PCI_DEVICE_ID_7041: /* do not need to fixup. */ break; case PCI_DEVICE_ID_EXT2: /* On-board 2nd PCI slot */ /* For board with 2 expansion slots, both slots share the same IRQ */ pcibios_update_irq(dev, BCM_LINUX_EXT_PCI_IRQ); dev->irq = BCM_LINUX_EXT_PCI_IRQ; break; default: printk("unknown slot num 0x%x for pcibios_fixup_irqs\n", slot_num); break; } } }
int pcie_wifi_pwrctrl_restore(void) { int ret = 0; ret = regulator_enable(pcie_regulator); if (ret) { printk(KERN_ERR "fail to enable regulator\n"); return ret; } pcie_wifi_poweron(); #if !defined(BSP_CONFIG_V7R2_SFT) pcie_clk_enable(); pcie_phy_ctrl_reset(); pcie_phy_ctrl_undo_reset(); #endif enable_irq(INT_LVL_PCIE0_LINK_DOWN); pcie_hw_preinit(); pcie_ltssm_enable(true); ret = pcie_link_up_confirm(); if(-EIO == ret) { goto out; } pcie_hw_postinit(); pci_rescan_bus(root_bus); pcie_port_dev = pci_get_class((PCI_CLASS_BRIDGE_PCI << 8), NULL); if(!pcie_port_dev) { printk(KERN_ERR "bridge not found,please check.\n"); return -EIO; } pcie_wifi_dev = pci_get_subsys(WIFI_VENDOR_ID,WIFI_DEVICE_ID, WIFI_SS_VENDOR_ID,WIFI_SS_ID,NULL); if(!pcie_wifi_dev) { printk(KERN_ERR "wifi dev not found,please check.\n"); return -EIO; } /*recover interrupt pin&line*/ pci_write_config_byte(pcie_port_dev,PCI_INTERRUPT_PIN,pcie_port_dev_int_pin); pci_write_config_byte(pcie_wifi_dev,PCI_INTERRUPT_PIN,pcie_wifi_dev_int_pin); pcie_port_dev->pin = pcie_port_dev_int_pin; pcie_port_dev->irq = pcie_port_dev_int_irq; pcie_wifi_dev->pin = pcie_wifi_dev_int_pin; pcie_wifi_dev->irq = pcie_wifi_dev_int_irq; pcibios_update_irq(pcie_port_dev,pcie_port_dev_int_irq); pcibios_update_irq(pcie_wifi_dev,pcie_wifi_dev_int_irq); ret = pcie_port_bus_register(); if (ret) { printk(KERN_WARNING "PCIE: bus_register error: %d\n", ret); goto out; } ret = pci_register_driver(&pcie_portdriver); if (ret) { pcie_port_bus_unregister(); } out: return ret; }