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);
}
예제 #2
0
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);
}
예제 #3
0
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;
		}
	}
}
예제 #4
0
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;
}