Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * legacy.c - traditional, old school PCI bus probing
0004  */
0005 #include <linux/init.h>
0006 #include <linux/export.h>
0007 #include <linux/pci.h>
0008 #include <asm/jailhouse_para.h>
0009 #include <asm/pci_x86.h>
0010 
0011 /*
0012  * Discover remaining PCI buses in case there are peer host bridges.
0013  * We use the number of last PCI bus provided by the PCI BIOS.
0014  */
0015 static void pcibios_fixup_peer_bridges(void)
0016 {
0017     int n;
0018 
0019     if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff)
0020         return;
0021     DBG("PCI: Peer bridge fixup\n");
0022 
0023     for (n=0; n <= pcibios_last_bus; n++)
0024         pcibios_scan_specific_bus(n);
0025 }
0026 
0027 int __init pci_legacy_init(void)
0028 {
0029     if (!raw_pci_ops)
0030         return 1;
0031 
0032     pr_info("PCI: Probing PCI hardware\n");
0033     pcibios_scan_root(0);
0034     return 0;
0035 }
0036 
0037 void pcibios_scan_specific_bus(int busn)
0038 {
0039     int stride = jailhouse_paravirt() ? 1 : 8;
0040     int devfn;
0041     u32 l;
0042 
0043     if (pci_find_bus(0, busn))
0044         return;
0045 
0046     for (devfn = 0; devfn < 256; devfn += stride) {
0047         if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) &&
0048             l != 0x0000 && l != 0xffff) {
0049             DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l);
0050             pr_info("PCI: Discovered peer bus %02x\n", busn);
0051             pcibios_scan_root(busn);
0052             return;
0053         }
0054     }
0055 }
0056 EXPORT_SYMBOL_GPL(pcibios_scan_specific_bus);
0057 
0058 static int __init pci_subsys_init(void)
0059 {
0060     /*
0061      * The init function returns an non zero value when
0062      * pci_legacy_init should be invoked.
0063      */
0064     if (x86_init.pci.init()) {
0065         if (pci_legacy_init()) {
0066             pr_info("PCI: System does not support PCI\n");
0067             return -ENODEV;
0068         }
0069     }
0070 
0071     pcibios_fixup_peer_bridges();
0072     x86_init.pci.init_irq();
0073     pcibios_init();
0074 
0075     return 0;
0076 }
0077 subsys_initcall(pci_subsys_init);