1 // SPDX-License-Identifier: GPL-2.0
3 * Purpose: PCI Express Port Bus Driver
5 * Copyright (C) 2004 Intel
9 #include <linux/bitfield.h>
10 #include <linux/dmi.h>
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/pci.h>
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/string.h>
19 #include <linux/slab.h>
20 #include <linux/aer.h>
26 * The PCIe Capability Interrupt Message Number (PCIe r3.1, sec 7.8.2) must
27 * be one of the first 32 MSI-X entries. Per PCI r3.0, sec 6.8.3.1, MSI
28 * supports a maximum of 32 vectors per function.
30 #define PCIE_PORT_MAX_MSI_ENTRIES 32
32 #define get_descriptor_id(type, service) (((type - 4) << 8) | service)
34 struct portdrv_service_data {
35 struct pcie_port_service_driver *drv;
41 * release_pcie_device - free PCI Express port service device structure
42 * @dev: Port service device to release
44 * Invoked automatically when device is being removed in response to
45 * device_unregister(dev). Release all resources being claimed.
47 static void release_pcie_device(struct device *dev)
49 kfree(to_pcie_device(dev));
53 * Fill in *pme, *aer, *dpc with the relevant Interrupt Message Numbers if
54 * services are enabled in "mask". Return the number of MSI/MSI-X vectors
55 * required to accommodate the largest Message Number.
57 static int pcie_message_numbers(struct pci_dev *dev, int mask,
58 u32 *pme, u32 *aer, u32 *dpc)
64 * The Interrupt Message Number indicates which vector is used, i.e.,
65 * the MSI-X table entry or the MSI offset between the base Message
66 * Data and the generated interrupt message. See PCIe r3.1, sec
67 * 7.8.2, 7.10.10, 7.31.2.
70 if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP |
71 PCIE_PORT_SERVICE_BWCTRL)) {
72 pcie_capability_read_word(dev, PCI_EXP_FLAGS, ®16);
73 *pme = FIELD_GET(PCI_EXP_FLAGS_IRQ, reg16);
78 if (mask & PCIE_PORT_SERVICE_AER) {
83 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS,
85 *aer = FIELD_GET(PCI_ERR_ROOT_AER_IRQ, reg32);
86 nvec = max(nvec, *aer + 1);
91 if (mask & PCIE_PORT_SERVICE_DPC) {
92 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC);
94 pci_read_config_word(dev, pos + PCI_EXP_DPC_CAP,
96 *dpc = FIELD_GET(PCI_EXP_DPC_IRQ, reg16);
97 nvec = max(nvec, *dpc + 1);
105 * pcie_port_enable_irq_vec - try to set up MSI-X or MSI as interrupt mode
107 * @dev: PCI Express port to handle
108 * @irqs: Array of interrupt vectors to populate
109 * @mask: Bitmask of port capabilities returned by get_port_device_capability()
111 * Return value: 0 on success, error code on failure
113 static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask)
115 int nr_entries, nvec, pcie_irq;
116 u32 pme = 0, aer = 0, dpc = 0;
118 /* Allocate the maximum possible number of MSI/MSI-X vectors */
119 nr_entries = pci_alloc_irq_vectors(dev, 1, PCIE_PORT_MAX_MSI_ENTRIES,
120 PCI_IRQ_MSIX | PCI_IRQ_MSI);
124 /* See how many and which Interrupt Message Numbers we actually use */
125 nvec = pcie_message_numbers(dev, mask, &pme, &aer, &dpc);
126 if (nvec > nr_entries) {
127 pci_free_irq_vectors(dev);
132 * If we allocated more than we need, free them and reallocate fewer.
134 * Reallocating may change the specific vectors we get, so
135 * pci_irq_vector() must be done *after* the reallocation.
137 * If we're using MSI, hardware is *allowed* to change the Interrupt
138 * Message Numbers when we free and reallocate the vectors, but we
139 * assume it won't because we allocate enough vectors for the
140 * biggest Message Number we found.
142 if (nvec != nr_entries) {
143 pci_free_irq_vectors(dev);
145 nr_entries = pci_alloc_irq_vectors(dev, nvec, nvec,
146 PCI_IRQ_MSIX | PCI_IRQ_MSI);
151 /* PME, hotplug and bandwidth notification share an MSI/MSI-X vector */
152 if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP |
153 PCIE_PORT_SERVICE_BWCTRL)) {
154 pcie_irq = pci_irq_vector(dev, pme);
155 irqs[PCIE_PORT_SERVICE_PME_SHIFT] = pcie_irq;
156 irqs[PCIE_PORT_SERVICE_HP_SHIFT] = pcie_irq;
157 irqs[PCIE_PORT_SERVICE_BWCTRL_SHIFT] = pcie_irq;
160 if (mask & PCIE_PORT_SERVICE_AER)
161 irqs[PCIE_PORT_SERVICE_AER_SHIFT] = pci_irq_vector(dev, aer);
163 if (mask & PCIE_PORT_SERVICE_DPC)
164 irqs[PCIE_PORT_SERVICE_DPC_SHIFT] = pci_irq_vector(dev, dpc);
170 * pcie_init_service_irqs - initialize irqs for PCI Express port services
171 * @dev: PCI Express port to handle
172 * @irqs: Array of irqs to populate
173 * @mask: Bitmask of port capabilities returned by get_port_device_capability()
175 * Return value: Interrupt mode associated with the port
177 static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
181 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
185 * If we support PME but can't use MSI/MSI-X for it, we have to
186 * fall back to INTx or other interrupts, e.g., a system shared
189 if ((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi())
192 /* Try to use MSI-X or MSI if supported */
193 if (pcie_port_enable_irq_vec(dev, irqs, mask) == 0)
197 /* fall back to INTX IRQ */
198 ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_INTX);
202 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
203 irqs[i] = pci_irq_vector(dev, 0);
209 * get_port_device_capability - discover capabilities of a PCI Express port
210 * @dev: PCI Express port to examine
212 * The capabilities are read from the port's PCI Express configuration registers
213 * as described in PCI Express Base Specification 1.0a sections 7.8.2, 7.8.9 and
216 * Return value: Bitmask of discovered port capabilities
218 static int get_port_device_capability(struct pci_dev *dev)
220 struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
223 if (dev->is_hotplug_bridge &&
224 (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
225 pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) &&
226 (pcie_ports_native || host->native_pcie_hotplug)) {
227 services |= PCIE_PORT_SERVICE_HP;
230 * Disable hot-plug interrupts in case they have been enabled
231 * by the BIOS and the hot-plug service driver is not loaded.
233 pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,
234 PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
237 #ifdef CONFIG_PCIEAER
238 if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
239 pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
240 dev->aer_cap && pci_aer_available() &&
241 (pcie_ports_native || host->native_aer))
242 services |= PCIE_PORT_SERVICE_AER;
245 /* Root Ports and Root Complex Event Collectors may generate PMEs */
246 if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
247 pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&
248 (pcie_ports_native || host->native_pme)) {
249 services |= PCIE_PORT_SERVICE_PME;
252 * Disable PME interrupt on this port in case it's been enabled
253 * by the BIOS (the PME service driver will enable it when
256 pcie_pme_interrupt_enable(dev, false);
260 * With dpc-native, allow Linux to use DPC even if it doesn't have
261 * permission to use AER.
263 if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC) &&
264 pci_aer_available() &&
265 (pcie_ports_dpc_native || (services & PCIE_PORT_SERVICE_AER)))
266 services |= PCIE_PORT_SERVICE_DPC;
268 /* Enable bandwidth control if more than one speed is supported. */
269 if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||
270 pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
273 pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &linkcap);
274 if (linkcap & PCI_EXP_LNKCAP_LBNC &&
275 hweight8(dev->supported_speeds) > 1)
276 services |= PCIE_PORT_SERVICE_BWCTRL;
283 * pcie_device_init - allocate and initialize PCI Express port service device
284 * @pdev: PCI Express port to associate the service device with
285 * @service: Type of service to associate with the service device
286 * @irq: Interrupt vector to associate with the service device
288 static int pcie_device_init(struct pci_dev *pdev, int service, int irq)
291 struct pcie_device *pcie;
292 struct device *device;
294 pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);
299 pcie->service = service;
301 /* Initialize generic device interface */
302 device = &pcie->device;
303 device->bus = &pcie_port_bus_type;
304 device->release = release_pcie_device; /* callback to free pcie dev */
305 dev_set_name(device, "%s:pcie%03x",
307 get_descriptor_id(pci_pcie_type(pdev), service));
308 device->parent = &pdev->dev;
309 device_enable_async_suspend(device);
311 retval = device_register(device);
317 pm_runtime_no_callbacks(device);
323 * pcie_port_device_register - register PCI Express port
324 * @dev: PCI Express port to register
326 * Allocate the port extension structure and register services associated with
329 static int pcie_port_device_register(struct pci_dev *dev)
331 int status, capabilities, i, nr_service;
332 int irqs[PCIE_PORT_DEVICE_MAXSERVICES];
334 /* Enable PCI Express port device */
335 status = pci_enable_device(dev);
339 /* Get and check PCI Express port services */
340 capabilities = get_port_device_capability(dev);
346 * Initialize service irqs. Don't use service devices that
347 * require interrupts if there is no way to generate them.
348 * However, some drivers may have a polling mode (e.g. pciehp_poll_mode)
349 * that can be used in the absence of irqs. Allow them to determine
350 * if that is to be used.
352 status = pcie_init_service_irqs(dev, irqs, capabilities);
354 capabilities &= PCIE_PORT_SERVICE_HP;
359 /* Allocate child services if any */
362 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
363 int service = 1 << i;
364 if (!(capabilities & service))
366 if (!pcie_device_init(dev, service, irqs[i]))
370 goto error_cleanup_irqs;
375 pci_free_irq_vectors(dev);
377 pci_disable_device(dev);
381 typedef int (*pcie_callback_t)(struct pcie_device *);
383 static int pcie_port_device_iter(struct device *dev, void *data)
385 struct pcie_port_service_driver *service_driver;
386 size_t offset = *(size_t *)data;
389 if ((dev->bus == &pcie_port_bus_type) && dev->driver) {
390 service_driver = to_service_driver(dev->driver);
391 cb = *(pcie_callback_t *)((void *)service_driver + offset);
393 return cb(to_pcie_device(dev));
400 * pcie_port_device_suspend - suspend port services associated with a PCIe port
401 * @dev: PCI Express port to handle
403 static int pcie_port_device_suspend(struct device *dev)
405 size_t off = offsetof(struct pcie_port_service_driver, suspend);
406 return device_for_each_child(dev, &off, pcie_port_device_iter);
409 static int pcie_port_device_resume_noirq(struct device *dev)
411 size_t off = offsetof(struct pcie_port_service_driver, resume_noirq);
412 return device_for_each_child(dev, &off, pcie_port_device_iter);
416 * pcie_port_device_resume - resume port services associated with a PCIe port
417 * @dev: PCI Express port to handle
419 static int pcie_port_device_resume(struct device *dev)
421 size_t off = offsetof(struct pcie_port_service_driver, resume);
422 return device_for_each_child(dev, &off, pcie_port_device_iter);
426 * pcie_port_device_runtime_suspend - runtime suspend port services
427 * @dev: PCI Express port to handle
429 static int pcie_port_device_runtime_suspend(struct device *dev)
431 size_t off = offsetof(struct pcie_port_service_driver, runtime_suspend);
432 return device_for_each_child(dev, &off, pcie_port_device_iter);
436 * pcie_port_device_runtime_resume - runtime resume port services
437 * @dev: PCI Express port to handle
439 static int pcie_port_device_runtime_resume(struct device *dev)
441 size_t off = offsetof(struct pcie_port_service_driver, runtime_resume);
442 return device_for_each_child(dev, &off, pcie_port_device_iter);
446 static int remove_iter(struct device *dev, void *data)
448 if (dev->bus == &pcie_port_bus_type)
449 device_unregister(dev);
453 static int find_service_iter(struct device *device, void *data)
455 struct pcie_port_service_driver *service_driver;
456 struct portdrv_service_data *pdrvs;
459 pdrvs = (struct portdrv_service_data *) data;
460 service = pdrvs->service;
462 if (device->bus == &pcie_port_bus_type && device->driver) {
463 service_driver = to_service_driver(device->driver);
464 if (service_driver->service == service) {
465 pdrvs->drv = service_driver;
475 * pcie_port_find_device - find the struct device
476 * @dev: PCI Express port the service is associated with
477 * @service: For the service to find
479 * Find the struct device associated with given service on a pci_dev
481 struct device *pcie_port_find_device(struct pci_dev *dev,
484 struct device *device;
485 struct portdrv_service_data pdrvs;
488 pdrvs.service = service;
489 device_for_each_child(&dev->dev, &pdrvs, find_service_iter);
494 EXPORT_SYMBOL_GPL(pcie_port_find_device);
497 * pcie_port_device_remove - unregister PCI Express port service devices
498 * @dev: PCI Express port the service devices to unregister are associated with
500 * Remove PCI Express port service devices associated with given port and
501 * disable MSI-X or MSI for the port.
503 static void pcie_port_device_remove(struct pci_dev *dev)
505 device_for_each_child(&dev->dev, NULL, remove_iter);
506 pci_free_irq_vectors(dev);
510 * pcie_port_probe_service - probe driver for given PCI Express port service
511 * @dev: PCI Express port service device to probe against
513 * If PCI Express port service driver is registered with
514 * pcie_port_service_register(), this function will be called by the driver core
515 * whenever match is found between the driver and a port service device.
517 static int pcie_port_probe_service(struct device *dev)
519 struct pcie_device *pciedev;
520 struct pcie_port_service_driver *driver;
523 if (!dev || !dev->driver)
526 driver = to_service_driver(dev->driver);
527 if (!driver || !driver->probe)
530 pciedev = to_pcie_device(dev);
531 status = driver->probe(pciedev);
540 * pcie_port_remove_service - detach driver from given PCI Express port service
541 * @dev: PCI Express port service device to handle
543 * If PCI Express port service driver is registered with
544 * pcie_port_service_register(), this function will be called by the driver core
545 * when device_unregister() is called for the port service device associated
548 static int pcie_port_remove_service(struct device *dev)
550 struct pcie_device *pciedev;
551 struct pcie_port_service_driver *driver;
553 if (!dev || !dev->driver)
556 pciedev = to_pcie_device(dev);
557 driver = to_service_driver(dev->driver);
558 if (driver && driver->remove) {
559 driver->remove(pciedev);
566 * pcie_port_shutdown_service - shut down given PCI Express port service
567 * @dev: PCI Express port service device to handle
569 * If PCI Express port service driver is registered with
570 * pcie_port_service_register(), this function will be called by the driver core
571 * when device_shutdown() is called for the port service device associated
574 static void pcie_port_shutdown_service(struct device *dev) {}
577 * pcie_port_service_register - register PCI Express port service driver
578 * @new: PCI Express port service driver to register
580 int pcie_port_service_register(struct pcie_port_service_driver *new)
582 if (pcie_ports_disabled)
585 new->driver.name = new->name;
586 new->driver.bus = &pcie_port_bus_type;
587 new->driver.probe = pcie_port_probe_service;
588 new->driver.remove = pcie_port_remove_service;
589 new->driver.shutdown = pcie_port_shutdown_service;
591 return driver_register(&new->driver);
595 * pcie_port_service_unregister - unregister PCI Express port service driver
596 * @drv: PCI Express port service driver to unregister
598 void pcie_port_service_unregister(struct pcie_port_service_driver *drv)
600 driver_unregister(&drv->driver);
603 /* If this switch is set, PCIe port native services should not be enabled. */
604 bool pcie_ports_disabled;
607 * If the user specified "pcie_ports=native", use the PCIe services regardless
608 * of whether the platform has given us permission. On ACPI systems, this
609 * means we ignore _OSC.
611 bool pcie_ports_native;
614 * If the user specified "pcie_ports=dpc-native", use the Linux DPC PCIe
615 * service even if the platform hasn't given us permission.
617 bool pcie_ports_dpc_native;
619 static int __init pcie_port_setup(char *str)
621 if (!strncmp(str, "compat", 6))
622 pcie_ports_disabled = true;
623 else if (!strncmp(str, "native", 6))
624 pcie_ports_native = true;
625 else if (!strncmp(str, "dpc-native", 10))
626 pcie_ports_dpc_native = true;
630 __setup("pcie_ports=", pcie_port_setup);
635 static int pcie_port_runtime_suspend(struct device *dev)
637 if (!to_pci_dev(dev)->bridge_d3)
640 return pcie_port_device_runtime_suspend(dev);
643 static int pcie_port_runtime_idle(struct device *dev)
646 * Assume the PCI core has set bridge_d3 whenever it thinks the port
647 * should be good to go to D3. Everything else, including moving
648 * the port to D3, is handled by the PCI core.
650 return to_pci_dev(dev)->bridge_d3 ? 0 : -EBUSY;
653 static const struct dev_pm_ops pcie_portdrv_pm_ops = {
654 .suspend = pcie_port_device_suspend,
655 .resume_noirq = pcie_port_device_resume_noirq,
656 .resume = pcie_port_device_resume,
657 .freeze = pcie_port_device_suspend,
658 .thaw = pcie_port_device_resume,
659 .poweroff = pcie_port_device_suspend,
660 .restore_noirq = pcie_port_device_resume_noirq,
661 .restore = pcie_port_device_resume,
662 .runtime_suspend = pcie_port_runtime_suspend,
663 .runtime_resume = pcie_port_device_runtime_resume,
664 .runtime_idle = pcie_port_runtime_idle,
667 #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops)
671 #define PCIE_PORTDRV_PM_OPS NULL
675 * pcie_portdrv_probe - Probe PCI-Express port devices
676 * @dev: PCI-Express port device being probed
678 * If detected invokes the pcie_port_device_register() method for
682 static int pcie_portdrv_probe(struct pci_dev *dev,
683 const struct pci_device_id *id)
685 int type = pci_pcie_type(dev);
688 if (!pci_is_pcie(dev) ||
689 ((type != PCI_EXP_TYPE_ROOT_PORT) &&
690 (type != PCI_EXP_TYPE_UPSTREAM) &&
691 (type != PCI_EXP_TYPE_DOWNSTREAM) &&
692 (type != PCI_EXP_TYPE_RC_EC)))
695 if (type == PCI_EXP_TYPE_RC_EC)
698 status = pcie_port_device_register(dev);
704 dev_pm_set_driver_flags(&dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE |
705 DPM_FLAG_SMART_SUSPEND);
707 if (pci_bridge_d3_possible(dev)) {
709 * Keep the port resumed 100ms to make sure things like
710 * config space accesses from userspace (lspci) will not
711 * cause the port to repeatedly suspend and resume.
713 pm_runtime_set_autosuspend_delay(&dev->dev, 100);
714 pm_runtime_use_autosuspend(&dev->dev);
715 pm_runtime_mark_last_busy(&dev->dev);
716 pm_runtime_put_autosuspend(&dev->dev);
717 pm_runtime_allow(&dev->dev);
723 static void pcie_portdrv_remove(struct pci_dev *dev)
725 if (pci_bridge_d3_possible(dev)) {
726 pm_runtime_forbid(&dev->dev);
727 pm_runtime_get_noresume(&dev->dev);
728 pm_runtime_dont_use_autosuspend(&dev->dev);
731 pcie_port_device_remove(dev);
733 pci_disable_device(dev);
736 static void pcie_portdrv_shutdown(struct pci_dev *dev)
738 if (pci_bridge_d3_possible(dev)) {
739 pm_runtime_forbid(&dev->dev);
740 pm_runtime_get_noresume(&dev->dev);
741 pm_runtime_dont_use_autosuspend(&dev->dev);
744 pcie_port_device_remove(dev);
747 static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
748 pci_channel_state_t error)
750 if (error == pci_channel_io_frozen)
751 return PCI_ERS_RESULT_NEED_RESET;
752 return PCI_ERS_RESULT_CAN_RECOVER;
755 static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)
757 size_t off = offsetof(struct pcie_port_service_driver, slot_reset);
758 device_for_each_child(&dev->dev, &off, pcie_port_device_iter);
760 pci_restore_state(dev);
762 return PCI_ERS_RESULT_RECOVERED;
765 static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev)
767 return PCI_ERS_RESULT_RECOVERED;
771 * LINUX Device Driver Model
773 static const struct pci_device_id port_pci_ids[] = {
774 /* handle any PCI-Express port */
775 { PCI_DEVICE_CLASS(PCI_CLASS_BRIDGE_PCI_NORMAL, ~0) },
776 /* subtractive decode PCI-to-PCI bridge, class type is 060401h */
777 { PCI_DEVICE_CLASS(PCI_CLASS_BRIDGE_PCI_SUBTRACTIVE, ~0) },
778 /* handle any Root Complex Event Collector */
779 { PCI_DEVICE_CLASS(((PCI_CLASS_SYSTEM_RCEC << 8) | 0x00), ~0) },
783 static const struct pci_error_handlers pcie_portdrv_err_handler = {
784 .error_detected = pcie_portdrv_error_detected,
785 .slot_reset = pcie_portdrv_slot_reset,
786 .mmio_enabled = pcie_portdrv_mmio_enabled,
789 static struct pci_driver pcie_portdriver = {
791 .id_table = port_pci_ids,
793 .probe = pcie_portdrv_probe,
794 .remove = pcie_portdrv_remove,
795 .shutdown = pcie_portdrv_shutdown,
797 .err_handler = &pcie_portdrv_err_handler,
799 .driver_managed_dma = true,
801 .driver.pm = PCIE_PORTDRV_PM_OPS,
804 static int __init dmi_pcie_pme_disable_msi(const struct dmi_system_id *d)
806 pr_notice("%s detected: will not use MSI for PCIe PME signaling\n",
808 pcie_pme_disable_msi();
812 static const struct dmi_system_id pcie_portdrv_dmi_table[] __initconst = {
814 * Boxes that should not use MSI for PCIe PME signaling.
817 .callback = dmi_pcie_pme_disable_msi,
818 .ident = "MSI Wind U-100",
820 DMI_MATCH(DMI_SYS_VENDOR,
821 "MICRO-STAR INTERNATIONAL CO., LTD"),
822 DMI_MATCH(DMI_PRODUCT_NAME, "U-100"),
828 static void __init pcie_init_services(void)
837 static int __init pcie_portdrv_init(void)
839 if (pcie_ports_disabled)
842 pcie_init_services();
843 dmi_check_system(pcie_portdrv_dmi_table);
845 return pci_register_driver(&pcie_portdriver);
847 device_initcall(pcie_portdrv_init);