aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/PCI/pcieaer-howto.txt26
-rw-r--r--arch/x86/include/asm/pci.h14
-rw-r--r--arch/x86/pci/common.c7
-rw-r--r--arch/x86/pci/vmd.c1
-rw-r--r--drivers/acpi/apei/ghes.c2
-rw-r--r--drivers/pci/host/pci-aardvark.c8
-rw-r--r--drivers/pci/host/pci-dra7xx.c31
-rw-r--r--drivers/pci/host/pci-exynos.c7
-rw-r--r--drivers/pci/host/pci-host-common.c15
-rw-r--r--drivers/pci/host/pci-imx6.c9
-rw-r--r--drivers/pci/host/pci-tegra.c7
-rw-r--r--drivers/pci/host/pci-versatile.c8
-rw-r--r--drivers/pci/host/pcie-altera-msi.c10
-rw-r--r--drivers/pci/host/pcie-altera.c12
-rw-r--r--drivers/pci/host/pcie-designware.c26
-rw-r--r--drivers/pci/host/pcie-qcom.c28
-rw-r--r--drivers/pci/host/pcie-rcar.c9
-rw-r--r--drivers/pci/host/pcie-spear13xx.c11
-rw-r--r--drivers/pci/host/pcie-xilinx-nwl.c53
-rw-r--r--drivers/pci/host/pcie-xilinx.c53
-rw-r--r--drivers/pci/hotplug/cpci_hotplug.h2
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c10
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c18
-rw-r--r--drivers/pci/hotplug/pciehp.h3
-rw-r--r--drivers/pci/hotplug/pciehp_core.c23
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c84
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c121
-rw-r--r--drivers/pci/pci-driver.c2
-rw-r--r--drivers/pci/pci.h6
-rw-r--r--drivers/pci/pcie/Kconfig11
-rw-r--r--drivers/pci/pcie/Makefile1
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c36
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h9
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c61
-rw-r--r--drivers/pci/pcie/aer/aerdrv_errprint.c6
-rw-r--r--drivers/pci/pcie/pcie-dpc.c18
-rw-r--r--drivers/pci/pcie/pme.c16
-rw-r--r--drivers/pci/pcie/portdrv_pci.c17
-rw-r--r--drivers/pci/pcie/ptm.c142
-rw-r--r--drivers/pci/probe.c6
-rw-r--r--drivers/pci/quirks.c17
-rw-r--r--include/linux/aer.h2
-rw-r--r--include/linux/pci.h26
-rw-r--r--include/uapi/linux/pci_regs.h12
44 files changed, 483 insertions, 503 deletions
diff --git a/Documentation/PCI/pcieaer-howto.txt b/Documentation/PCI/pcieaer-howto.txt
index b4987c0bcb20..ea8cafba255c 100644
--- a/Documentation/PCI/pcieaer-howto.txt
+++ b/Documentation/PCI/pcieaer-howto.txt
@@ -49,25 +49,17 @@ depends on CONFIG_PCIEPORTBUS, so pls. set CONFIG_PCIEPORTBUS=y and
49CONFIG_PCIEAER = y. 49CONFIG_PCIEAER = y.
50 50
512.2 Load PCI Express AER Root Driver 512.2 Load PCI Express AER Root Driver
52There is a case where a system has AER support in BIOS. Enabling the AER 52
53Root driver and having AER support in BIOS may result unpredictable 53Some systems have AER support in firmware. Enabling Linux AER support at
54behavior. To avoid this conflict, a successful load of the AER Root driver 54the same time the firmware handles AER may result in unpredictable
55requires ACPI _OSC support in the BIOS to allow the AER Root driver to 55behavior. Therefore, Linux does not handle AER events unless the firmware
56request for native control of AER. See the PCI FW 3.0 Specification for 56grants AER control to the OS via the ACPI _OSC method. See the PCI FW 3.0
57details regarding OSC usage. Currently, lots of firmwares don't provide 57Specification for details regarding _OSC usage.
58_OSC support while they use PCI Express. To support such firmwares,
59forceload, a parameter of type bool, could enable AER to continue to
60be initiated although firmwares have no _OSC support. To enable the
61walkaround, pls. add aerdriver.forceload=y to kernel boot parameter line
62when booting kernel. Note that forceload=n by default.
63
64nosourceid, another parameter of type bool, can be used when broken
65hardware (mostly chipsets) has root ports that cannot obtain the reporting
66source ID. nosourceid=n by default.
67 58
682.3 AER error output 592.3 AER error output
69When a PCI-E AER error is captured, an error message will be outputted to 60
70console. If it's a correctable error, it is outputted as a warning. 61When a PCIe AER error is captured, an error message will be output to
62console. If it's a correctable error, it is output as a warning.
71Otherwise, it is printed as an error. So users could choose different 63Otherwise, it is printed as an error. So users could choose different
72log level to filter out correctable error messages. 64log level to filter out correctable error messages.
73 65
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 9ab7507ca1c2..1411dbed5e5e 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -23,6 +23,9 @@ struct pci_sysdata {
23#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN 23#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
24 void *fwnode; /* IRQ domain for MSI assignment */ 24 void *fwnode; /* IRQ domain for MSI assignment */
25#endif 25#endif
26#if IS_ENABLED(CONFIG_VMD)
27 bool vmd_domain; /* True if in Intel VMD domain */
28#endif
26}; 29};
27 30
28extern int pci_routeirq; 31extern int pci_routeirq;
@@ -56,6 +59,17 @@ static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
56#define pci_root_bus_fwnode _pci_root_bus_fwnode 59#define pci_root_bus_fwnode _pci_root_bus_fwnode
57#endif 60#endif
58 61
62static inline bool is_vmd(struct pci_bus *bus)
63{
64#if IS_ENABLED(CONFIG_VMD)
65 struct pci_sysdata *sd = bus->sysdata;
66
67 return sd->vmd_domain;
68#else
69 return false;
70#endif
71}
72
59/* Can be used to override the logic in pci_scan_bus for skipping 73/* Can be used to override the logic in pci_scan_bus for skipping
60 already-configured bus numbers - to be used for buggy BIOSes 74 already-configured bus numbers - to be used for buggy BIOSes
61 or architectures with incomplete PCI setup by the loader */ 75 or architectures with incomplete PCI setup by the loader */
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 7b6a9d14c8c0..a4fdfa7dcc1b 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -677,6 +677,12 @@ static void set_dma_domain_ops(struct pci_dev *pdev)
677static void set_dma_domain_ops(struct pci_dev *pdev) {} 677static void set_dma_domain_ops(struct pci_dev *pdev) {}
678#endif 678#endif
679 679
680static void set_dev_domain_options(struct pci_dev *pdev)
681{
682 if (is_vmd(pdev->bus))
683 pdev->hotplug_user_indicators = 1;
684}
685
680int pcibios_add_device(struct pci_dev *dev) 686int pcibios_add_device(struct pci_dev *dev)
681{ 687{
682 struct setup_data *data; 688 struct setup_data *data;
@@ -707,6 +713,7 @@ int pcibios_add_device(struct pci_dev *dev)
707 iounmap(data); 713 iounmap(data);
708 } 714 }
709 set_dma_domain_ops(dev); 715 set_dma_domain_ops(dev);
716 set_dev_domain_options(dev);
710 return 0; 717 return 0;
711} 718}
712 719
diff --git a/arch/x86/pci/vmd.c b/arch/x86/pci/vmd.c
index b814ca675131..a021b7b0eb69 100644
--- a/arch/x86/pci/vmd.c
+++ b/arch/x86/pci/vmd.c
@@ -596,6 +596,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd)
596 .parent = res, 596 .parent = res,
597 }; 597 };
598 598
599 sd->vmd_domain = true;
599 sd->domain = vmd_find_free_domain(); 600 sd->domain = vmd_find_free_domain();
600 if (sd->domain < 0) 601 if (sd->domain < 0)
601 return sd->domain; 602 return sd->domain;
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 60746ef904e4..f0a029e68d3e 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -457,7 +457,7 @@ static void ghes_do_proc(struct ghes *ghes,
457 457
458 devfn = PCI_DEVFN(pcie_err->device_id.device, 458 devfn = PCI_DEVFN(pcie_err->device_id.device,
459 pcie_err->device_id.function); 459 pcie_err->device_id.function);
460 aer_severity = cper_severity_to_aer(sev); 460 aer_severity = cper_severity_to_aer(gdata->error_severity);
461 461
462 /* 462 /*
463 * If firmware reset the component to contain 463 * If firmware reset the component to contain
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
index ef9893fa3176..4f5e567fd7e0 100644
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -848,7 +848,7 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
848 int err, res_valid = 0; 848 int err, res_valid = 0;
849 struct device *dev = &pcie->pdev->dev; 849 struct device *dev = &pcie->pdev->dev;
850 struct device_node *np = dev->of_node; 850 struct device_node *np = dev->of_node;
851 struct resource_entry *win; 851 struct resource_entry *win, *tmp;
852 resource_size_t iobase; 852 resource_size_t iobase;
853 853
854 INIT_LIST_HEAD(&pcie->resources); 854 INIT_LIST_HEAD(&pcie->resources);
@@ -862,7 +862,7 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
862 if (err) 862 if (err)
863 goto out_release_res; 863 goto out_release_res;
864 864
865 resource_list_for_each_entry(win, &pcie->resources) { 865 resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
866 struct resource *res = win->res; 866 struct resource *res = win->res;
867 867
868 switch (resource_type(res)) { 868 switch (resource_type(res)) {
@@ -874,9 +874,11 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
874 lower_32_bits(res->start), 874 lower_32_bits(res->start),
875 OB_PCIE_IO); 875 OB_PCIE_IO);
876 err = pci_remap_iospace(res, iobase); 876 err = pci_remap_iospace(res, iobase);
877 if (err) 877 if (err) {
878 dev_warn(dev, "error %d: failed to map resource %pR\n", 878 dev_warn(dev, "error %d: failed to map resource %pR\n",
879 err, res); 879 err, res);
880 resource_list_destroy_entry(win);
881 }
880 break; 882 break;
881 case IORESOURCE_MEM: 883 case IORESOURCE_MEM:
882 advk_pcie_set_ob_win(pcie, 0, 884 advk_pcie_set_ob_win(pcie, 0,
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 81b3949a26db..19223ed2e619 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -15,7 +15,7 @@
15#include <linux/irq.h> 15#include <linux/irq.h>
16#include <linux/irqdomain.h> 16#include <linux/irqdomain.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/init.h>
19#include <linux/of_gpio.h> 19#include <linux/of_gpio.h>
20#include <linux/pci.h> 20#include <linux/pci.h>
21#include <linux/phy/phy.h> 21#include <linux/phy/phy.h>
@@ -443,25 +443,6 @@ err_phy:
443 return ret; 443 return ret;
444} 444}
445 445
446static int __exit dra7xx_pcie_remove(struct platform_device *pdev)
447{
448 struct dra7xx_pcie *dra7xx = platform_get_drvdata(pdev);
449 struct pcie_port *pp = &dra7xx->pp;
450 struct device *dev = &pdev->dev;
451 int count = dra7xx->phy_count;
452
453 if (pp->irq_domain)
454 irq_domain_remove(pp->irq_domain);
455 pm_runtime_put(dev);
456 pm_runtime_disable(dev);
457 while (count--) {
458 phy_power_off(dra7xx->phy[count]);
459 phy_exit(dra7xx->phy[count]);
460 }
461
462 return 0;
463}
464
465#ifdef CONFIG_PM_SLEEP 446#ifdef CONFIG_PM_SLEEP
466static int dra7xx_pcie_suspend(struct device *dev) 447static int dra7xx_pcie_suspend(struct device *dev)
467{ 448{
@@ -545,19 +526,13 @@ static const struct of_device_id of_dra7xx_pcie_match[] = {
545 { .compatible = "ti,dra7-pcie", }, 526 { .compatible = "ti,dra7-pcie", },
546 {}, 527 {},
547}; 528};
548MODULE_DEVICE_TABLE(of, of_dra7xx_pcie_match);
549 529
550static struct platform_driver dra7xx_pcie_driver = { 530static struct platform_driver dra7xx_pcie_driver = {
551 .remove = __exit_p(dra7xx_pcie_remove),
552 .driver = { 531 .driver = {
553 .name = "dra7-pcie", 532 .name = "dra7-pcie",
554 .of_match_table = of_dra7xx_pcie_match, 533 .of_match_table = of_dra7xx_pcie_match,
534 .suppress_bind_attrs = true,
555 .pm = &dra7xx_pcie_pm_ops, 535 .pm = &dra7xx_pcie_pm_ops,
556 }, 536 },
557}; 537};
558 538builtin_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe);
559module_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe);
560
561MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
562MODULE_DESCRIPTION("TI PCIe controller driver");
563MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index 219976103efc..c3ae9c7a6e33 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -16,7 +16,7 @@
16#include <linux/gpio.h> 16#include <linux/gpio.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/module.h> 19#include <linux/init.h>
20#include <linux/of_gpio.h> 20#include <linux/of_gpio.h>
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
@@ -624,7 +624,6 @@ static const struct of_device_id exynos_pcie_of_match[] = {
624 { .compatible = "samsung,exynos5440-pcie", }, 624 { .compatible = "samsung,exynos5440-pcie", },
625 {}, 625 {},
626}; 626};
627MODULE_DEVICE_TABLE(of, exynos_pcie_of_match);
628 627
629static struct platform_driver exynos_pcie_driver = { 628static struct platform_driver exynos_pcie_driver = {
630 .remove = __exit_p(exynos_pcie_remove), 629 .remove = __exit_p(exynos_pcie_remove),
@@ -641,7 +640,3 @@ static int __init exynos_pcie_init(void)
641 return platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe); 640 return platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe);
642} 641}
643subsys_initcall(exynos_pcie_init); 642subsys_initcall(exynos_pcie_init);
644
645MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
646MODULE_DESCRIPTION("Samsung PCIe host controller driver");
647MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c
index 9d9d34e959b6..e3c48b5deb93 100644
--- a/drivers/pci/host/pci-host-common.c
+++ b/drivers/pci/host/pci-host-common.c
@@ -1,4 +1,6 @@
1/* 1/*
2 * Generic PCI host driver common code
3 *
2 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
@@ -17,7 +19,6 @@
17 */ 19 */
18 20
19#include <linux/kernel.h> 21#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/of_address.h> 22#include <linux/of_address.h>
22#include <linux/of_pci.h> 23#include <linux/of_pci.h>
23#include <linux/pci-ecam.h> 24#include <linux/pci-ecam.h>
@@ -29,7 +30,7 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev,
29 int err, res_valid = 0; 30 int err, res_valid = 0;
30 struct device_node *np = dev->of_node; 31 struct device_node *np = dev->of_node;
31 resource_size_t iobase; 32 resource_size_t iobase;
32 struct resource_entry *win; 33 struct resource_entry *win, *tmp;
33 34
34 err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase); 35 err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
35 if (err) 36 if (err)
@@ -39,15 +40,17 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev,
39 if (err) 40 if (err)
40 return err; 41 return err;
41 42
42 resource_list_for_each_entry(win, resources) { 43 resource_list_for_each_entry_safe(win, tmp, resources) {
43 struct resource *res = win->res; 44 struct resource *res = win->res;
44 45
45 switch (resource_type(res)) { 46 switch (resource_type(res)) {
46 case IORESOURCE_IO: 47 case IORESOURCE_IO:
47 err = pci_remap_iospace(res, iobase); 48 err = pci_remap_iospace(res, iobase);
48 if (err) 49 if (err) {
49 dev_warn(dev, "error %d: failed to map resource %pR\n", 50 dev_warn(dev, "error %d: failed to map resource %pR\n",
50 err, res); 51 err, res);
52 resource_list_destroy_entry(win);
53 }
51 break; 54 break;
52 case IORESOURCE_MEM: 55 case IORESOURCE_MEM:
53 res_valid |= !(res->flags & IORESOURCE_PREFETCH); 56 res_valid |= !(res->flags & IORESOURCE_PREFETCH);
@@ -162,7 +165,3 @@ int pci_host_common_probe(struct platform_device *pdev,
162 pci_bus_add_devices(bus); 165 pci_bus_add_devices(bus);
163 return 0; 166 return 0;
164} 167}
165
166MODULE_DESCRIPTION("Generic PCI host driver common code");
167MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
168MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index b741a36a67f3..ead4a5c3480b 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -739,7 +739,6 @@ static const struct of_device_id imx6_pcie_of_match[] = {
739 { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, }, 739 { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, },
740 {}, 740 {},
741}; 741};
742MODULE_DEVICE_TABLE(of, imx6_pcie_of_match);
743 742
744static struct platform_driver imx6_pcie_driver = { 743static struct platform_driver imx6_pcie_driver = {
745 .driver = { 744 .driver = {
@@ -749,14 +748,8 @@ static struct platform_driver imx6_pcie_driver = {
749 .shutdown = imx6_pcie_shutdown, 748 .shutdown = imx6_pcie_shutdown,
750}; 749};
751 750
752/* Freescale PCIe driver does not allow module unload */
753
754static int __init imx6_pcie_init(void) 751static int __init imx6_pcie_init(void)
755{ 752{
756 return platform_driver_probe(&imx6_pcie_driver, imx6_pcie_probe); 753 return platform_driver_probe(&imx6_pcie_driver, imx6_pcie_probe);
757} 754}
758module_init(imx6_pcie_init); 755device_initcall(imx6_pcie_init);
759
760MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>");
761MODULE_DESCRIPTION("Freescale i.MX6 PCIe host controller driver");
762MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 6de0757b11e4..8c2590db609b 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -621,7 +621,11 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
621 if (err < 0) 621 if (err < 0)
622 return err; 622 return err;
623 623
624 pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset); 624 err = pci_remap_iospace(&pcie->pio, pcie->io.start);
625 if (!err)
626 pci_add_resource_offset(&sys->resources, &pcie->pio,
627 sys->io_offset);
628
625 pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); 629 pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
626 pci_add_resource_offset(&sys->resources, &pcie->prefetch, 630 pci_add_resource_offset(&sys->resources, &pcie->prefetch,
627 sys->mem_offset); 631 sys->mem_offset);
@@ -631,7 +635,6 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
631 if (err < 0) 635 if (err < 0)
632 return err; 636 return err;
633 637
634 pci_remap_iospace(&pcie->pio, pcie->io.start);
635 return 1; 638 return 1;
636} 639}
637 640
diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c
index f234405770ab..b7dc07002f13 100644
--- a/drivers/pci/host/pci-versatile.c
+++ b/drivers/pci/host/pci-versatile.c
@@ -74,7 +74,7 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev,
74 int err, mem = 1, res_valid = 0; 74 int err, mem = 1, res_valid = 0;
75 struct device_node *np = dev->of_node; 75 struct device_node *np = dev->of_node;
76 resource_size_t iobase; 76 resource_size_t iobase;
77 struct resource_entry *win; 77 struct resource_entry *win, *tmp;
78 78
79 err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase); 79 err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase);
80 if (err) 80 if (err)
@@ -84,15 +84,17 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev,
84 if (err) 84 if (err)
85 goto out_release_res; 85 goto out_release_res;
86 86
87 resource_list_for_each_entry(win, res) { 87 resource_list_for_each_entry_safe(win, tmp, res) {
88 struct resource *res = win->res; 88 struct resource *res = win->res;
89 89
90 switch (resource_type(res)) { 90 switch (resource_type(res)) {
91 case IORESOURCE_IO: 91 case IORESOURCE_IO:
92 err = pci_remap_iospace(res, iobase); 92 err = pci_remap_iospace(res, iobase);
93 if (err) 93 if (err) {
94 dev_warn(dev, "error %d: failed to map resource %pR\n", 94 dev_warn(dev, "error %d: failed to map resource %pR\n",
95 err, res); 95 err, res);
96 resource_list_destroy_entry(win);
97 }
96 break; 98 break;
97 case IORESOURCE_MEM: 99 case IORESOURCE_MEM:
98 res_valid |= !(res->flags & IORESOURCE_PREFETCH); 100 res_valid |= !(res->flags & IORESOURCE_PREFETCH);
diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c
index 99177f4ccde2..369e033449c6 100644
--- a/drivers/pci/host/pcie-altera-msi.c
+++ b/drivers/pci/host/pcie-altera-msi.c
@@ -1,4 +1,8 @@
1/* 1/*
2 * Altera PCIe MSI support
3 *
4 * Author: Ley Foon Tan <lftan@altera.com>
5 *
2 * Copyright Altera Corporation (C) 2013-2015. All rights reserved 6 * Copyright Altera Corporation (C) 2013-2015. All rights reserved
3 * 7 *
4 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
@@ -16,7 +20,7 @@
16 20
17#include <linux/interrupt.h> 21#include <linux/interrupt.h>
18#include <linux/irqchip/chained_irq.h> 22#include <linux/irqchip/chained_irq.h>
19#include <linux/module.h> 23#include <linux/init.h>
20#include <linux/msi.h> 24#include <linux/msi.h>
21#include <linux/of_address.h> 25#include <linux/of_address.h>
22#include <linux/of_irq.h> 26#include <linux/of_irq.h>
@@ -308,7 +312,3 @@ static int __init altera_msi_init(void)
308 return platform_driver_register(&altera_msi_driver); 312 return platform_driver_register(&altera_msi_driver);
309} 313}
310subsys_initcall(altera_msi_init); 314subsys_initcall(altera_msi_init);
311
312MODULE_AUTHOR("Ley Foon Tan <lftan@altera.com>");
313MODULE_DESCRIPTION("Altera PCIe MSI support");
314MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index 2b7837650db8..48f2736a10cd 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -1,6 +1,9 @@
1/* 1/*
2 * Copyright Altera Corporation (C) 2013-2015. All rights reserved 2 * Copyright Altera Corporation (C) 2013-2015. All rights reserved
3 * 3 *
4 * Author: Ley Foon Tan <lftan@altera.com>
5 * Description: Altera PCIe host controller driver
6 *
4 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 8 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation. 9 * version 2, as published by the Free Software Foundation.
@@ -17,7 +20,7 @@
17#include <linux/delay.h> 20#include <linux/delay.h>
18#include <linux/interrupt.h> 21#include <linux/interrupt.h>
19#include <linux/irqchip/chained_irq.h> 22#include <linux/irqchip/chained_irq.h>
20#include <linux/module.h> 23#include <linux/init.h>
21#include <linux/of_address.h> 24#include <linux/of_address.h>
22#include <linux/of_irq.h> 25#include <linux/of_irq.h>
23#include <linux/of_pci.h> 26#include <linux/of_pci.h>
@@ -568,7 +571,6 @@ static const struct of_device_id altera_pcie_of_match[] = {
568 { .compatible = "altr,pcie-root-port-1.0", }, 571 { .compatible = "altr,pcie-root-port-1.0", },
569 {}, 572 {},
570}; 573};
571MODULE_DEVICE_TABLE(of, altera_pcie_of_match);
572 574
573static struct platform_driver altera_pcie_driver = { 575static struct platform_driver altera_pcie_driver = {
574 .probe = altera_pcie_probe, 576 .probe = altera_pcie_probe,
@@ -583,8 +585,4 @@ static int altera_pcie_init(void)
583{ 585{
584 return platform_driver_register(&altera_pcie_driver); 586 return platform_driver_register(&altera_pcie_driver);
585} 587}
586module_init(altera_pcie_init); 588device_initcall(altera_pcie_init);
587
588MODULE_AUTHOR("Ley Foon Tan <lftan@altera.com>");
589MODULE_DESCRIPTION("Altera PCIe host controller driver");
590MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 12afce19890b..ee64f9755ea6 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -14,7 +14,6 @@
14#include <linux/irq.h> 14#include <linux/irq.h>
15#include <linux/irqdomain.h> 15#include <linux/irqdomain.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/msi.h> 17#include <linux/msi.h>
19#include <linux/of_address.h> 18#include <linux/of_address.h>
20#include <linux/of_pci.h> 19#include <linux/of_pci.h>
@@ -436,7 +435,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
436 struct resource *cfg_res; 435 struct resource *cfg_res;
437 int i, ret; 436 int i, ret;
438 LIST_HEAD(res); 437 LIST_HEAD(res);
439 struct resource_entry *win; 438 struct resource_entry *win, *tmp;
440 439
441 cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); 440 cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
442 if (cfg_res) { 441 if (cfg_res) {
@@ -457,17 +456,20 @@ int dw_pcie_host_init(struct pcie_port *pp)
457 goto error; 456 goto error;
458 457
459 /* Get the I/O and memory ranges from DT */ 458 /* Get the I/O and memory ranges from DT */
460 resource_list_for_each_entry(win, &res) { 459 resource_list_for_each_entry_safe(win, tmp, &res) {
461 switch (resource_type(win->res)) { 460 switch (resource_type(win->res)) {
462 case IORESOURCE_IO: 461 case IORESOURCE_IO:
463 pp->io = win->res; 462 ret = pci_remap_iospace(win->res, pp->io_base);
464 pp->io->name = "I/O"; 463 if (ret) {
465 pp->io_size = resource_size(pp->io);
466 pp->io_bus_addr = pp->io->start - win->offset;
467 ret = pci_remap_iospace(pp->io, pp->io_base);
468 if (ret)
469 dev_warn(pp->dev, "error %d: failed to map resource %pR\n", 464 dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
470 ret, pp->io); 465 ret, win->res);
466 resource_list_destroy_entry(win);
467 } else {
468 pp->io = win->res;
469 pp->io->name = "I/O";
470 pp->io_size = resource_size(pp->io);
471 pp->io_bus_addr = pp->io->start - win->offset;
472 }
471 break; 473 break;
472 case IORESOURCE_MEM: 474 case IORESOURCE_MEM:
473 pp->mem = win->res; 475 pp->mem = win->res;
@@ -802,7 +804,3 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
802 val |= PORT_LOGIC_SPEED_CHANGE; 804 val |= PORT_LOGIC_SPEED_CHANGE;
803 dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); 805 dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
804} 806}
805
806MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
807MODULE_DESCRIPTION("Designware PCIe host controller driver");
808MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c
index f2f90c50f75d..5ec2d440a6b7 100644
--- a/drivers/pci/host/pcie-qcom.c
+++ b/drivers/pci/host/pcie-qcom.c
@@ -1,7 +1,11 @@
1/* 1/*
2 * Qualcomm PCIe root complex driver
3 *
2 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
3 * Copyright 2015 Linaro Limited. 5 * Copyright 2015 Linaro Limited.
4 * 6 *
7 * Author: Stanimir Varbanov <svarbanov@mm-sol.com>
8 *
5 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and 10 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation. 11 * only version 2 as published by the Free Software Foundation.
@@ -19,7 +23,7 @@
19#include <linux/io.h> 23#include <linux/io.h>
20#include <linux/iopoll.h> 24#include <linux/iopoll.h>
21#include <linux/kernel.h> 25#include <linux/kernel.h>
22#include <linux/module.h> 26#include <linux/init.h>
23#include <linux/of_device.h> 27#include <linux/of_device.h>
24#include <linux/of_gpio.h> 28#include <linux/of_gpio.h>
25#include <linux/pci.h> 29#include <linux/pci.h>
@@ -570,37 +574,19 @@ static int qcom_pcie_probe(struct platform_device *pdev)
570 return 0; 574 return 0;
571} 575}
572 576
573static int qcom_pcie_remove(struct platform_device *pdev)
574{
575 struct qcom_pcie *pcie = platform_get_drvdata(pdev);
576
577 qcom_ep_reset_assert(pcie);
578 phy_power_off(pcie->phy);
579 phy_exit(pcie->phy);
580 pcie->ops->deinit(pcie);
581
582 return 0;
583}
584
585static const struct of_device_id qcom_pcie_match[] = { 577static const struct of_device_id qcom_pcie_match[] = {
586 { .compatible = "qcom,pcie-ipq8064", .data = &ops_v0 }, 578 { .compatible = "qcom,pcie-ipq8064", .data = &ops_v0 },
587 { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 }, 579 { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 },
588 { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 }, 580 { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 },
589 { } 581 { }
590}; 582};
591MODULE_DEVICE_TABLE(of, qcom_pcie_match);
592 583
593static struct platform_driver qcom_pcie_driver = { 584static struct platform_driver qcom_pcie_driver = {
594 .probe = qcom_pcie_probe, 585 .probe = qcom_pcie_probe,
595 .remove = qcom_pcie_remove,
596 .driver = { 586 .driver = {
597 .name = "qcom-pcie", 587 .name = "qcom-pcie",
588 .suppress_bind_attrs = true,
598 .of_match_table = qcom_pcie_match, 589 .of_match_table = qcom_pcie_match,
599 }, 590 },
600}; 591};
601 592builtin_platform_driver(qcom_pcie_driver);
602module_platform_driver(qcom_pcie_driver);
603
604MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>");
605MODULE_DESCRIPTION("Qualcomm PCIe root complex driver");
606MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 65db7a221509..5f7fcc971cae 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -945,7 +945,7 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci)
945 struct device *dev = pci->dev; 945 struct device *dev = pci->dev;
946 struct device_node *np = dev->of_node; 946 struct device_node *np = dev->of_node;
947 resource_size_t iobase; 947 resource_size_t iobase;
948 struct resource_entry *win; 948 struct resource_entry *win, *tmp;
949 949
950 err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, &iobase); 950 err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, &iobase);
951 if (err) 951 if (err)
@@ -955,14 +955,17 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci)
955 if (err) 955 if (err)
956 goto out_release_res; 956 goto out_release_res;
957 957
958 resource_list_for_each_entry(win, &pci->resources) { 958 resource_list_for_each_entry_safe(win, tmp, &pci->resources) {
959 struct resource *res = win->res; 959 struct resource *res = win->res;
960 960
961 if (resource_type(res) == IORESOURCE_IO) { 961 if (resource_type(res) == IORESOURCE_IO) {
962 err = pci_remap_iospace(res, iobase); 962 err = pci_remap_iospace(res, iobase);
963 if (err) 963 if (err) {
964 dev_warn(dev, "error %d: failed to map resource %pR\n", 964 dev_warn(dev, "error %d: failed to map resource %pR\n",
965 err, res); 965 err, res);
966
967 resource_list_destroy_entry(win);
968 }
966 } 969 }
967 } 970 }
968 971
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index a4060b85ab23..09aed85f275a 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -15,7 +15,7 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/init.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/pci.h> 20#include <linux/pci.h>
21#include <linux/phy/phy.h> 21#include <linux/phy/phy.h>
@@ -355,7 +355,6 @@ static const struct of_device_id spear13xx_pcie_of_match[] = {
355 { .compatible = "st,spear1340-pcie", }, 355 { .compatible = "st,spear1340-pcie", },
356 {}, 356 {},
357}; 357};
358MODULE_DEVICE_TABLE(of, spear13xx_pcie_of_match);
359 358
360static struct platform_driver spear13xx_pcie_driver = { 359static struct platform_driver spear13xx_pcie_driver = {
361 .probe = spear13xx_pcie_probe, 360 .probe = spear13xx_pcie_probe,
@@ -365,14 +364,8 @@ static struct platform_driver spear13xx_pcie_driver = {
365 }, 364 },
366}; 365};
367 366
368/* SPEAr13xx PCIe driver does not allow module unload */
369
370static int __init spear13xx_pcie_init(void) 367static int __init spear13xx_pcie_init(void)
371{ 368{
372 return platform_driver_register(&spear13xx_pcie_driver); 369 return platform_driver_register(&spear13xx_pcie_driver);
373} 370}
374module_init(spear13xx_pcie_init); 371device_initcall(spear13xx_pcie_init);
375
376MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver");
377MODULE_AUTHOR("Pratyush Anand <pratyush.anand@gmail.com>");
378MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pcie-xilinx-nwl.c b/drivers/pci/host/pcie-xilinx-nwl.c
index 0b597d9190b4..df7fb8b69658 100644
--- a/drivers/pci/host/pcie-xilinx-nwl.c
+++ b/drivers/pci/host/pcie-xilinx-nwl.c
@@ -15,7 +15,7 @@
15#include <linux/irq.h> 15#include <linux/irq.h>
16#include <linux/irqdomain.h> 16#include <linux/irqdomain.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/init.h>
19#include <linux/msi.h> 19#include <linux/msi.h>
20#include <linux/of_address.h> 20#include <linux/of_address.h>
21#include <linux/of_pci.h> 21#include <linux/of_pci.h>
@@ -459,40 +459,6 @@ static const struct irq_domain_ops dev_msi_domain_ops = {
459 .free = nwl_irq_domain_free, 459 .free = nwl_irq_domain_free,
460}; 460};
461 461
462static void nwl_msi_free_irq_domain(struct nwl_pcie *pcie)
463{
464 struct nwl_msi *msi = &pcie->msi;
465
466 if (msi->irq_msi0)
467 irq_set_chained_handler_and_data(msi->irq_msi0, NULL, NULL);
468 if (msi->irq_msi1)
469 irq_set_chained_handler_and_data(msi->irq_msi1, NULL, NULL);
470
471 if (msi->msi_domain)
472 irq_domain_remove(msi->msi_domain);
473 if (msi->dev_domain)
474 irq_domain_remove(msi->dev_domain);
475
476 kfree(msi->bitmap);
477 msi->bitmap = NULL;
478}
479
480static void nwl_pcie_free_irq_domain(struct nwl_pcie *pcie)
481{
482 int i;
483 u32 irq;
484
485 for (i = 0; i < INTX_NUM; i++) {
486 irq = irq_find_mapping(pcie->legacy_irq_domain, i + 1);
487 if (irq > 0)
488 irq_dispose_mapping(irq);
489 }
490 if (pcie->legacy_irq_domain)
491 irq_domain_remove(pcie->legacy_irq_domain);
492
493 nwl_msi_free_irq_domain(pcie);
494}
495
496static int nwl_pcie_init_msi_irq_domain(struct nwl_pcie *pcie) 462static int nwl_pcie_init_msi_irq_domain(struct nwl_pcie *pcie)
497{ 463{
498#ifdef CONFIG_PCI_MSI 464#ifdef CONFIG_PCI_MSI
@@ -867,25 +833,12 @@ error:
867 return err; 833 return err;
868} 834}
869 835
870static int nwl_pcie_remove(struct platform_device *pdev)
871{
872 struct nwl_pcie *pcie = platform_get_drvdata(pdev);
873
874 nwl_pcie_free_irq_domain(pcie);
875 platform_set_drvdata(pdev, NULL);
876 return 0;
877}
878
879static struct platform_driver nwl_pcie_driver = { 836static struct platform_driver nwl_pcie_driver = {
880 .driver = { 837 .driver = {
881 .name = "nwl-pcie", 838 .name = "nwl-pcie",
839 .suppress_bind_attrs = true,
882 .of_match_table = nwl_pcie_of_match, 840 .of_match_table = nwl_pcie_of_match,
883 }, 841 },
884 .probe = nwl_pcie_probe, 842 .probe = nwl_pcie_probe,
885 .remove = nwl_pcie_remove,
886}; 843};
887module_platform_driver(nwl_pcie_driver); 844builtin_platform_driver(nwl_pcie_driver);
888
889MODULE_AUTHOR("Xilinx, Inc");
890MODULE_DESCRIPTION("NWL PCIe driver");
891MODULE_LICENSE("GPL");
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index a30e01639557..7b7dbd22bccc 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -18,7 +18,7 @@
18#include <linux/irq.h> 18#include <linux/irq.h>
19#include <linux/irqdomain.h> 19#include <linux/irqdomain.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/module.h> 21#include <linux/init.h>
22#include <linux/msi.h> 22#include <linux/msi.h>
23#include <linux/of_address.h> 23#include <linux/of_address.h>
24#include <linux/of_pci.h> 24#include <linux/of_pci.h>
@@ -506,35 +506,6 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
506} 506}
507 507
508/** 508/**
509 * xilinx_pcie_free_irq_domain - Free IRQ domain
510 * @port: PCIe port information
511 */
512static void xilinx_pcie_free_irq_domain(struct xilinx_pcie_port *port)
513{
514 int i;
515 u32 irq, num_irqs;
516
517 /* Free IRQ Domain */
518 if (IS_ENABLED(CONFIG_PCI_MSI)) {
519
520 free_pages(port->msi_pages, 0);
521
522 num_irqs = XILINX_NUM_MSI_IRQS;
523 } else {
524 /* INTx */
525 num_irqs = 4;
526 }
527
528 for (i = 0; i < num_irqs; i++) {
529 irq = irq_find_mapping(port->irq_domain, i);
530 if (irq > 0)
531 irq_dispose_mapping(irq);
532 }
533
534 irq_domain_remove(port->irq_domain);
535}
536
537/**
538 * xilinx_pcie_init_irq_domain - Initialize IRQ domain 509 * xilinx_pcie_init_irq_domain - Initialize IRQ domain
539 * @port: PCIe port information 510 * @port: PCIe port information
540 * 511 *
@@ -724,21 +695,6 @@ error:
724 return err; 695 return err;
725} 696}
726 697
727/**
728 * xilinx_pcie_remove - Remove function
729 * @pdev: Platform device pointer
730 *
731 * Return: '0' always
732 */
733static int xilinx_pcie_remove(struct platform_device *pdev)
734{
735 struct xilinx_pcie_port *port = platform_get_drvdata(pdev);
736
737 xilinx_pcie_free_irq_domain(port);
738
739 return 0;
740}
741
742static struct of_device_id xilinx_pcie_of_match[] = { 698static struct of_device_id xilinx_pcie_of_match[] = {
743 { .compatible = "xlnx,axi-pcie-host-1.00.a", }, 699 { .compatible = "xlnx,axi-pcie-host-1.00.a", },
744 {} 700 {}
@@ -751,10 +707,5 @@ static struct platform_driver xilinx_pcie_driver = {
751 .suppress_bind_attrs = true, 707 .suppress_bind_attrs = true,
752 }, 708 },
753 .probe = xilinx_pcie_probe, 709 .probe = xilinx_pcie_probe,
754 .remove = xilinx_pcie_remove,
755}; 710};
756module_platform_driver(xilinx_pcie_driver); 711builtin_platform_driver(xilinx_pcie_driver);
757
758MODULE_AUTHOR("Xilinx Inc");
759MODULE_DESCRIPTION("Xilinx AXI PCIe driver");
760MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
index 555bcde3b196..60e66e027ebc 100644
--- a/drivers/pci/hotplug/cpci_hotplug.h
+++ b/drivers/pci/hotplug/cpci_hotplug.h
@@ -101,10 +101,8 @@ int cpci_unconfigure_slot(struct slot *slot);
101 101
102#ifdef CONFIG_HOTPLUG_PCI_CPCI 102#ifdef CONFIG_HOTPLUG_PCI_CPCI
103int cpci_hotplug_init(int debug); 103int cpci_hotplug_init(int debug);
104void cpci_hotplug_exit(void);
105#else 104#else
106static inline int cpci_hotplug_init(int debug) { return 0; } 105static inline int cpci_hotplug_init(int debug) { return 0; }
107static inline void cpci_hotplug_exit(void) { }
108#endif 106#endif
109 107
110#endif /* _CPCI_HOTPLUG_H */ 108#endif /* _CPCI_HOTPLUG_H */
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index 7d3866c47312..7ec8a8f72c69 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -719,13 +719,3 @@ cpci_hotplug_init(int debug)
719 cpci_debug = debug; 719 cpci_debug = debug;
720 return 0; 720 return 0;
721} 721}
722
723void __exit
724cpci_hotplug_exit(void)
725{
726 /*
727 * Clean everything up.
728 */
729 cpci_hp_stop();
730 cpci_hp_unregister_controller(controller);
731}
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 9acd1997c6fe..fea0b8b33589 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -25,7 +25,7 @@
25 * 25 *
26 */ 26 */
27 27
28#include <linux/module.h> 28#include <linux/module.h> /* try_module_get & module_put */
29#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/types.h> 31#include <linux/types.h>
@@ -537,17 +537,11 @@ static int __init pci_hotplug_init(void)
537 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 537 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
538 return result; 538 return result;
539} 539}
540device_initcall(pci_hotplug_init);
540 541
541static void __exit pci_hotplug_exit(void) 542/*
542{ 543 * not really modular, but the easiest way to keep compat with existing
543 cpci_hotplug_exit(); 544 * bootargs behaviour is to continue using module_param here.
544} 545 */
545
546module_init(pci_hotplug_init);
547module_exit(pci_hotplug_exit);
548
549MODULE_AUTHOR(DRIVER_AUTHOR);
550MODULE_DESCRIPTION(DRIVER_DESC);
551MODULE_LICENSE("GPL");
552module_param(debug, bool, 0644); 546module_param(debug, bool, 0644);
553MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); 547MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index e764918641ae..37d70b5ad22f 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -152,6 +152,9 @@ bool pciehp_check_link_active(struct controller *ctrl);
152void pciehp_release_ctrl(struct controller *ctrl); 152void pciehp_release_ctrl(struct controller *ctrl);
153int pciehp_reset_slot(struct slot *slot, int probe); 153int pciehp_reset_slot(struct slot *slot, int probe);
154 154
155int pciehp_set_raw_indicator_status(struct hotplug_slot *h_slot, u8 status);
156int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status);
157
155static inline const char *slot_name(struct slot *slot) 158static inline const char *slot_name(struct slot *slot)
156{ 159{
157 return hotplug_slot_name(slot->hotplug_slot); 160 return hotplug_slot_name(slot->hotplug_slot);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index ac531e674a05..7d32fa33dcef 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -27,7 +27,6 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/module.h>
31#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
@@ -47,10 +46,10 @@ static bool pciehp_force;
47#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" 46#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
48#define DRIVER_DESC "PCI Express Hot Plug Controller Driver" 47#define DRIVER_DESC "PCI Express Hot Plug Controller Driver"
49 48
50MODULE_AUTHOR(DRIVER_AUTHOR); 49/*
51MODULE_DESCRIPTION(DRIVER_DESC); 50 * not really modular, but the easiest way to keep compat with existing
52MODULE_LICENSE("GPL"); 51 * bootargs behaviour is to continue using module_param here.
53 52 */
54module_param(pciehp_debug, bool, 0644); 53module_param(pciehp_debug, bool, 0644);
55module_param(pciehp_poll_mode, bool, 0644); 54module_param(pciehp_poll_mode, bool, 0644);
56module_param(pciehp_poll_time, int, 0644); 55module_param(pciehp_poll_time, int, 0644);
@@ -114,6 +113,9 @@ static int init_slot(struct controller *ctrl)
114 if (ATTN_LED(ctrl)) { 113 if (ATTN_LED(ctrl)) {
115 ops->get_attention_status = get_attention_status; 114 ops->get_attention_status = get_attention_status;
116 ops->set_attention_status = set_attention_status; 115 ops->set_attention_status = set_attention_status;
116 } else if (ctrl->pcie->port->hotplug_user_indicators) {
117 ops->get_attention_status = pciehp_get_raw_indicator_status;
118 ops->set_attention_status = pciehp_set_raw_indicator_status;
117 } 119 }
118 120
119 /* register this slot with the hotplug pci core */ 121 /* register this slot with the hotplug pci core */
@@ -337,13 +339,4 @@ static int __init pcied_init(void)
337 339
338 return retval; 340 return retval;
339} 341}
340 342device_initcall(pcied_init);
341static void __exit pcied_cleanup(void)
342{
343 dbg("unload_pciehpd()\n");
344 pcie_port_service_unregister(&hpdriver_portdrv);
345 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
346}
347
348module_init(pcied_init);
349module_exit(pcied_cleanup);
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 880978b6d534..efe69e879455 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -106,7 +106,7 @@ static int board_added(struct slot *p_slot)
106 106
107 /* Check for a power fault */ 107 /* Check for a power fault */
108 if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { 108 if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
109 ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); 109 ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(p_slot));
110 retval = -EIO; 110 retval = -EIO;
111 goto err_exit; 111 goto err_exit;
112 } 112 }
@@ -120,6 +120,7 @@ static int board_added(struct slot *p_slot)
120 } 120 }
121 121
122 pciehp_green_led_on(p_slot); 122 pciehp_green_led_on(p_slot);
123 pciehp_set_attention_status(p_slot, 0);
123 return 0; 124 return 0;
124 125
125err_exit: 126err_exit:
@@ -253,11 +254,11 @@ static void handle_button_press_event(struct slot *p_slot)
253 pciehp_get_power_status(p_slot, &getstatus); 254 pciehp_get_power_status(p_slot, &getstatus);
254 if (getstatus) { 255 if (getstatus) {
255 p_slot->state = BLINKINGOFF_STATE; 256 p_slot->state = BLINKINGOFF_STATE;
256 ctrl_info(ctrl, "PCI slot #%s - powering off due to button press\n", 257 ctrl_info(ctrl, "Slot(%s): Powering off due to button press\n",
257 slot_name(p_slot)); 258 slot_name(p_slot));
258 } else { 259 } else {
259 p_slot->state = BLINKINGON_STATE; 260 p_slot->state = BLINKINGON_STATE;
260 ctrl_info(ctrl, "PCI slot #%s - powering on due to button press\n", 261 ctrl_info(ctrl, "Slot(%s) Powering on due to button press\n",
261 slot_name(p_slot)); 262 slot_name(p_slot));
262 } 263 }
263 /* blink green LED and turn off amber */ 264 /* blink green LED and turn off amber */
@@ -272,14 +273,14 @@ static void handle_button_press_event(struct slot *p_slot)
272 * press the attention again before the 5 sec. limit 273 * press the attention again before the 5 sec. limit
273 * expires to cancel hot-add or hot-remove 274 * expires to cancel hot-add or hot-remove
274 */ 275 */
275 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot)); 276 ctrl_info(ctrl, "Slot(%s): Button cancel\n", slot_name(p_slot));
276 cancel_delayed_work(&p_slot->work); 277 cancel_delayed_work(&p_slot->work);
277 if (p_slot->state == BLINKINGOFF_STATE) 278 if (p_slot->state == BLINKINGOFF_STATE)
278 pciehp_green_led_on(p_slot); 279 pciehp_green_led_on(p_slot);
279 else 280 else
280 pciehp_green_led_off(p_slot); 281 pciehp_green_led_off(p_slot);
281 pciehp_set_attention_status(p_slot, 0); 282 pciehp_set_attention_status(p_slot, 0);
282 ctrl_info(ctrl, "PCI slot #%s - action canceled due to button press\n", 283 ctrl_info(ctrl, "Slot(%s): Action canceled due to button press\n",
283 slot_name(p_slot)); 284 slot_name(p_slot));
284 p_slot->state = STATIC_STATE; 285 p_slot->state = STATIC_STATE;
285 break; 286 break;
@@ -290,10 +291,12 @@ static void handle_button_press_event(struct slot *p_slot)
290 * this means that the previous attention button action 291 * this means that the previous attention button action
291 * to hot-add or hot-remove is undergoing 292 * to hot-add or hot-remove is undergoing
292 */ 293 */
293 ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot)); 294 ctrl_info(ctrl, "Slot(%s): Button ignored\n",
295 slot_name(p_slot));
294 break; 296 break;
295 default: 297 default:
296 ctrl_warn(ctrl, "ignoring invalid state %#x\n", p_slot->state); 298 ctrl_err(ctrl, "Slot(%s): Ignoring invalid state %#x\n",
299 slot_name(p_slot), p_slot->state);
297 break; 300 break;
298 } 301 }
299} 302}
@@ -301,20 +304,6 @@ static void handle_button_press_event(struct slot *p_slot)
301/* 304/*
302 * Note: This function must be called with slot->lock held 305 * Note: This function must be called with slot->lock held
303 */ 306 */
304static void handle_surprise_event(struct slot *p_slot)
305{
306 u8 getstatus;
307
308 pciehp_get_adapter_status(p_slot, &getstatus);
309 if (!getstatus)
310 pciehp_queue_power_work(p_slot, DISABLE_REQ);
311 else
312 pciehp_queue_power_work(p_slot, ENABLE_REQ);
313}
314
315/*
316 * Note: This function must be called with slot->lock held
317 */
318static void handle_link_event(struct slot *p_slot, u32 event) 307static void handle_link_event(struct slot *p_slot, u32 event)
319{ 308{
320 struct controller *ctrl = p_slot->ctrl; 309 struct controller *ctrl = p_slot->ctrl;
@@ -330,31 +319,27 @@ static void handle_link_event(struct slot *p_slot, u32 event)
330 break; 319 break;
331 case POWERON_STATE: 320 case POWERON_STATE:
332 if (event == INT_LINK_UP) { 321 if (event == INT_LINK_UP) {
333 ctrl_info(ctrl, 322 ctrl_info(ctrl, "Slot(%s): Link Up event ignored; already powering on\n",
334 "Link Up event ignored on slot(%s): already powering on\n",
335 slot_name(p_slot)); 323 slot_name(p_slot));
336 } else { 324 } else {
337 ctrl_info(ctrl, 325 ctrl_info(ctrl, "Slot(%s): Link Down event queued; currently getting powered on\n",
338 "Link Down event queued on slot(%s): currently getting powered on\n",
339 slot_name(p_slot)); 326 slot_name(p_slot));
340 pciehp_queue_power_work(p_slot, DISABLE_REQ); 327 pciehp_queue_power_work(p_slot, DISABLE_REQ);
341 } 328 }
342 break; 329 break;
343 case POWEROFF_STATE: 330 case POWEROFF_STATE:
344 if (event == INT_LINK_UP) { 331 if (event == INT_LINK_UP) {
345 ctrl_info(ctrl, 332 ctrl_info(ctrl, "Slot(%s): Link Up event queued; currently getting powered off\n",
346 "Link Up event queued on slot(%s): currently getting powered off\n",
347 slot_name(p_slot)); 333 slot_name(p_slot));
348 pciehp_queue_power_work(p_slot, ENABLE_REQ); 334 pciehp_queue_power_work(p_slot, ENABLE_REQ);
349 } else { 335 } else {
350 ctrl_info(ctrl, 336 ctrl_info(ctrl, "Slot(%s): Link Down event ignored; already powering off\n",
351 "Link Down event ignored on slot(%s): already powering off\n",
352 slot_name(p_slot)); 337 slot_name(p_slot));
353 } 338 }
354 break; 339 break;
355 default: 340 default:
356 ctrl_err(ctrl, "ignoring invalid state %#x on slot(%s)\n", 341 ctrl_err(ctrl, "Slot(%s): Ignoring invalid state %#x\n",
357 p_slot->state, slot_name(p_slot)); 342 slot_name(p_slot), p_slot->state);
358 break; 343 break;
359 } 344 }
360} 345}
@@ -377,14 +362,14 @@ static void interrupt_event_handler(struct work_struct *work)
377 pciehp_green_led_off(p_slot); 362 pciehp_green_led_off(p_slot);
378 break; 363 break;
379 case INT_PRESENCE_ON: 364 case INT_PRESENCE_ON:
380 handle_surprise_event(p_slot); 365 pciehp_queue_power_work(p_slot, ENABLE_REQ);
381 break; 366 break;
382 case INT_PRESENCE_OFF: 367 case INT_PRESENCE_OFF:
383 /* 368 /*
384 * Regardless of surprise capability, we need to 369 * Regardless of surprise capability, we need to
385 * definitely remove a card that has been pulled out! 370 * definitely remove a card that has been pulled out!
386 */ 371 */
387 handle_surprise_event(p_slot); 372 pciehp_queue_power_work(p_slot, DISABLE_REQ);
388 break; 373 break;
389 case INT_LINK_UP: 374 case INT_LINK_UP:
390 case INT_LINK_DOWN: 375 case INT_LINK_DOWN:
@@ -404,18 +389,17 @@ static void interrupt_event_handler(struct work_struct *work)
404int pciehp_enable_slot(struct slot *p_slot) 389int pciehp_enable_slot(struct slot *p_slot)
405{ 390{
406 u8 getstatus = 0; 391 u8 getstatus = 0;
407 int rc;
408 struct controller *ctrl = p_slot->ctrl; 392 struct controller *ctrl = p_slot->ctrl;
409 393
410 pciehp_get_adapter_status(p_slot, &getstatus); 394 pciehp_get_adapter_status(p_slot, &getstatus);
411 if (!getstatus) { 395 if (!getstatus) {
412 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot)); 396 ctrl_info(ctrl, "Slot(%s): No adapter\n", slot_name(p_slot));
413 return -ENODEV; 397 return -ENODEV;
414 } 398 }
415 if (MRL_SENS(p_slot->ctrl)) { 399 if (MRL_SENS(p_slot->ctrl)) {
416 pciehp_get_latch_status(p_slot, &getstatus); 400 pciehp_get_latch_status(p_slot, &getstatus);
417 if (getstatus) { 401 if (getstatus) {
418 ctrl_info(ctrl, "Latch open on slot(%s)\n", 402 ctrl_info(ctrl, "Slot(%s): Latch open\n",
419 slot_name(p_slot)); 403 slot_name(p_slot));
420 return -ENODEV; 404 return -ENODEV;
421 } 405 }
@@ -424,19 +408,13 @@ int pciehp_enable_slot(struct slot *p_slot)
424 if (POWER_CTRL(p_slot->ctrl)) { 408 if (POWER_CTRL(p_slot->ctrl)) {
425 pciehp_get_power_status(p_slot, &getstatus); 409 pciehp_get_power_status(p_slot, &getstatus);
426 if (getstatus) { 410 if (getstatus) {
427 ctrl_info(ctrl, "Already enabled on slot(%s)\n", 411 ctrl_info(ctrl, "Slot(%s): Already enabled\n",
428 slot_name(p_slot)); 412 slot_name(p_slot));
429 return -EINVAL; 413 return -EINVAL;
430 } 414 }
431 } 415 }
432 416
433 pciehp_get_latch_status(p_slot, &getstatus); 417 return board_added(p_slot);
434
435 rc = board_added(p_slot);
436 if (rc)
437 pciehp_get_latch_status(p_slot, &getstatus);
438
439 return rc;
440} 418}
441 419
442/* 420/*
@@ -453,7 +431,7 @@ int pciehp_disable_slot(struct slot *p_slot)
453 if (POWER_CTRL(p_slot->ctrl)) { 431 if (POWER_CTRL(p_slot->ctrl)) {
454 pciehp_get_power_status(p_slot, &getstatus); 432 pciehp_get_power_status(p_slot, &getstatus);
455 if (!getstatus) { 433 if (!getstatus) {
456 ctrl_info(ctrl, "Already disabled on slot(%s)\n", 434 ctrl_info(ctrl, "Slot(%s): Already disabled\n",
457 slot_name(p_slot)); 435 slot_name(p_slot));
458 return -EINVAL; 436 return -EINVAL;
459 } 437 }
@@ -481,17 +459,17 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
481 p_slot->state = STATIC_STATE; 459 p_slot->state = STATIC_STATE;
482 break; 460 break;
483 case POWERON_STATE: 461 case POWERON_STATE:
484 ctrl_info(ctrl, "Slot %s is already in powering on state\n", 462 ctrl_info(ctrl, "Slot(%s): Already in powering on state\n",
485 slot_name(p_slot)); 463 slot_name(p_slot));
486 break; 464 break;
487 case BLINKINGOFF_STATE: 465 case BLINKINGOFF_STATE:
488 case POWEROFF_STATE: 466 case POWEROFF_STATE:
489 ctrl_info(ctrl, "Already enabled on slot %s\n", 467 ctrl_info(ctrl, "Slot(%s): Already enabled\n",
490 slot_name(p_slot)); 468 slot_name(p_slot));
491 break; 469 break;
492 default: 470 default:
493 ctrl_err(ctrl, "invalid state %#x on slot %s\n", 471 ctrl_err(ctrl, "Slot(%s): Invalid state %#x\n",
494 p_slot->state, slot_name(p_slot)); 472 slot_name(p_slot), p_slot->state);
495 break; 473 break;
496 } 474 }
497 mutex_unlock(&p_slot->lock); 475 mutex_unlock(&p_slot->lock);
@@ -518,17 +496,17 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot)
518 p_slot->state = STATIC_STATE; 496 p_slot->state = STATIC_STATE;
519 break; 497 break;
520 case POWEROFF_STATE: 498 case POWEROFF_STATE:
521 ctrl_info(ctrl, "Slot %s is already in powering off state\n", 499 ctrl_info(ctrl, "Slot(%s): Already in powering off state\n",
522 slot_name(p_slot)); 500 slot_name(p_slot));
523 break; 501 break;
524 case BLINKINGON_STATE: 502 case BLINKINGON_STATE:
525 case POWERON_STATE: 503 case POWERON_STATE:
526 ctrl_info(ctrl, "Already disabled on slot %s\n", 504 ctrl_info(ctrl, "Slot(%s): Already disabled\n",
527 slot_name(p_slot)); 505 slot_name(p_slot));
528 break; 506 break;
529 default: 507 default:
530 ctrl_err(ctrl, "invalid state %#x on slot %s\n", 508 ctrl_err(ctrl, "Slot(%s): Invalid state %#x\n",
531 p_slot->state, slot_name(p_slot)); 509 slot_name(p_slot), p_slot->state);
532 break; 510 break;
533 } 511 }
534 mutex_unlock(&p_slot->lock); 512 mutex_unlock(&p_slot->lock);
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 08e84d61874e..b57fc6d6e28a 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -355,6 +355,18 @@ static int pciehp_link_enable(struct controller *ctrl)
355 return __pciehp_link_set(ctrl, true); 355 return __pciehp_link_set(ctrl, true);
356} 356}
357 357
358int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot,
359 u8 *status)
360{
361 struct slot *slot = hotplug_slot->private;
362 struct pci_dev *pdev = ctrl_dev(slot->ctrl);
363 u16 slot_ctrl;
364
365 pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
366 *status = (slot_ctrl & (PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC)) >> 6;
367 return 0;
368}
369
358void pciehp_get_attention_status(struct slot *slot, u8 *status) 370void pciehp_get_attention_status(struct slot *slot, u8 *status)
359{ 371{
360 struct controller *ctrl = slot->ctrl; 372 struct controller *ctrl = slot->ctrl;
@@ -431,6 +443,17 @@ int pciehp_query_power_fault(struct slot *slot)
431 return !!(slot_status & PCI_EXP_SLTSTA_PFD); 443 return !!(slot_status & PCI_EXP_SLTSTA_PFD);
432} 444}
433 445
446int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot,
447 u8 status)
448{
449 struct slot *slot = hotplug_slot->private;
450 struct controller *ctrl = slot->ctrl;
451
452 pcie_write_cmd_nowait(ctrl, status << 6,
453 PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC);
454 return 0;
455}
456
434void pciehp_set_attention_status(struct slot *slot, u8 value) 457void pciehp_set_attention_status(struct slot *slot, u8 value)
435{ 458{
436 struct controller *ctrl = slot->ctrl; 459 struct controller *ctrl = slot->ctrl;
@@ -535,14 +558,14 @@ void pciehp_power_off_slot(struct slot *slot)
535 PCI_EXP_SLTCTL_PWR_OFF); 558 PCI_EXP_SLTCTL_PWR_OFF);
536} 559}
537 560
538static irqreturn_t pcie_isr(int irq, void *dev_id) 561static irqreturn_t pciehp_isr(int irq, void *dev_id)
539{ 562{
540 struct controller *ctrl = (struct controller *)dev_id; 563 struct controller *ctrl = (struct controller *)dev_id;
541 struct pci_dev *pdev = ctrl_dev(ctrl); 564 struct pci_dev *pdev = ctrl_dev(ctrl);
542 struct pci_bus *subordinate = pdev->subordinate; 565 struct pci_bus *subordinate = pdev->subordinate;
543 struct pci_dev *dev; 566 struct pci_dev *dev;
544 struct slot *slot = ctrl->slot; 567 struct slot *slot = ctrl->slot;
545 u16 detected, intr_loc; 568 u16 status, events;
546 u8 present; 569 u8 present;
547 bool link; 570 bool link;
548 571
@@ -550,36 +573,31 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
550 if (pdev->current_state == PCI_D3cold) 573 if (pdev->current_state == PCI_D3cold)
551 return IRQ_NONE; 574 return IRQ_NONE;
552 575
576 pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status);
577 if (status == (u16) ~0) {
578 ctrl_info(ctrl, "%s: no response from device\n", __func__);
579 return IRQ_NONE;
580 }
581
553 /* 582 /*
554 * In order to guarantee that all interrupt events are 583 * Slot Status contains plain status bits as well as event
555 * serviced, we need to re-inspect Slot Status register after 584 * notification bits; right now we only want the event bits.
556 * clearing what is presumed to be the last pending interrupt.
557 */ 585 */
558 intr_loc = 0; 586 events = status & (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
559 do { 587 PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC |
560 pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &detected); 588 PCI_EXP_SLTSTA_DLLSC);
561 if (detected == (u16) ~0) { 589 if (!events)
562 ctrl_info(ctrl, "%s: no response from device\n", 590 return IRQ_NONE;
563 __func__);
564 return IRQ_HANDLED;
565 }
566 591
567 detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | 592 /* Capture link status before clearing interrupts */
568 PCI_EXP_SLTSTA_PDC | 593 if (events & PCI_EXP_SLTSTA_DLLSC)
569 PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC); 594 link = pciehp_check_link_active(ctrl);
570 detected &= ~intr_loc;
571 intr_loc |= detected;
572 if (!intr_loc)
573 return IRQ_NONE;
574 if (detected)
575 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
576 intr_loc);
577 } while (detected);
578 595
579 ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", intr_loc); 596 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events);
597 ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", events);
580 598
581 /* Check Command Complete Interrupt Pending */ 599 /* Check Command Complete Interrupt Pending */
582 if (intr_loc & PCI_EXP_SLTSTA_CC) { 600 if (events & PCI_EXP_SLTSTA_CC) {
583 ctrl->cmd_busy = 0; 601 ctrl->cmd_busy = 0;
584 smp_mb(); 602 smp_mb();
585 wake_up(&ctrl->queue); 603 wake_up(&ctrl->queue);
@@ -589,42 +607,38 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
589 list_for_each_entry(dev, &subordinate->devices, bus_list) { 607 list_for_each_entry(dev, &subordinate->devices, bus_list) {
590 if (dev->ignore_hotplug) { 608 if (dev->ignore_hotplug) {
591 ctrl_dbg(ctrl, "ignoring hotplug event %#06x (%s requested no hotplug)\n", 609 ctrl_dbg(ctrl, "ignoring hotplug event %#06x (%s requested no hotplug)\n",
592 intr_loc, pci_name(dev)); 610 events, pci_name(dev));
593 return IRQ_HANDLED; 611 return IRQ_HANDLED;
594 } 612 }
595 } 613 }
596 } 614 }
597 615
598 if (!(intr_loc & ~PCI_EXP_SLTSTA_CC))
599 return IRQ_HANDLED;
600
601 /* Check Attention Button Pressed */ 616 /* Check Attention Button Pressed */
602 if (intr_loc & PCI_EXP_SLTSTA_ABP) { 617 if (events & PCI_EXP_SLTSTA_ABP) {
603 ctrl_info(ctrl, "Button pressed on Slot(%s)\n", 618 ctrl_info(ctrl, "Slot(%s): Attention button pressed\n",
604 slot_name(slot)); 619 slot_name(slot));
605 pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS); 620 pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS);
606 } 621 }
607 622
608 /* Check Presence Detect Changed */ 623 /* Check Presence Detect Changed */
609 if (intr_loc & PCI_EXP_SLTSTA_PDC) { 624 if (events & PCI_EXP_SLTSTA_PDC) {
610 pciehp_get_adapter_status(slot, &present); 625 present = !!(status & PCI_EXP_SLTSTA_PDS);
611 ctrl_info(ctrl, "Card %spresent on Slot(%s)\n", 626 ctrl_info(ctrl, "Slot(%s): Card %spresent\n", slot_name(slot),
612 present ? "" : "not ", slot_name(slot)); 627 present ? "" : "not ");
613 pciehp_queue_interrupt_event(slot, present ? INT_PRESENCE_ON : 628 pciehp_queue_interrupt_event(slot, present ? INT_PRESENCE_ON :
614 INT_PRESENCE_OFF); 629 INT_PRESENCE_OFF);
615 } 630 }
616 631
617 /* Check Power Fault Detected */ 632 /* Check Power Fault Detected */
618 if ((intr_loc & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) { 633 if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
619 ctrl->power_fault_detected = 1; 634 ctrl->power_fault_detected = 1;
620 ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(slot)); 635 ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(slot));
621 pciehp_queue_interrupt_event(slot, INT_POWER_FAULT); 636 pciehp_queue_interrupt_event(slot, INT_POWER_FAULT);
622 } 637 }
623 638
624 if (intr_loc & PCI_EXP_SLTSTA_DLLSC) { 639 if (events & PCI_EXP_SLTSTA_DLLSC) {
625 link = pciehp_check_link_active(ctrl); 640 ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot),
626 ctrl_info(ctrl, "slot(%s): Link %s event\n", 641 link ? "Up" : "Down");
627 slot_name(slot), link ? "Up" : "Down");
628 pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP : 642 pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP :
629 INT_LINK_DOWN); 643 INT_LINK_DOWN);
630 } 644 }
@@ -632,6 +646,25 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
632 return IRQ_HANDLED; 646 return IRQ_HANDLED;
633} 647}
634 648
649static irqreturn_t pcie_isr(int irq, void *dev_id)
650{
651 irqreturn_t rc, handled = IRQ_NONE;
652
653 /*
654 * To guarantee that all interrupt events are serviced, we need to
655 * re-inspect Slot Status register after clearing what is presumed
656 * to be the last pending interrupt.
657 */
658 do {
659 rc = pciehp_isr(irq, dev_id);
660 if (rc == IRQ_HANDLED)
661 handled = IRQ_HANDLED;
662 } while (rc == IRQ_HANDLED);
663
664 /* Return IRQ_HANDLED if we handled one or more events */
665 return handled;
666}
667
635void pcie_enable_notification(struct controller *ctrl) 668void pcie_enable_notification(struct controller *ctrl)
636{ 669{
637 u16 cmd, mask; 670 u16 cmd, mask;
@@ -804,6 +837,10 @@ struct controller *pcie_init(struct pcie_device *dev)
804 } 837 }
805 ctrl->pcie = dev; 838 ctrl->pcie = dev;
806 pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap); 839 pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
840
841 if (pdev->hotplug_user_indicators)
842 slot_cap &= ~(PCI_EXP_SLTCAP_AIP | PCI_EXP_SLTCAP_PIP);
843
807 ctrl->slot_cap = slot_cap; 844 ctrl->slot_cap = slot_cap;
808 mutex_init(&ctrl->ctrl_lock); 845 mutex_init(&ctrl->ctrl_lock);
809 init_waitqueue_head(&ctrl->queue); 846 init_waitqueue_head(&ctrl->queue);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e39a67c8ef39..edd78e04b693 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -466,7 +466,6 @@ static void pci_device_shutdown(struct device *dev)
466 pci_msi_shutdown(pci_dev); 466 pci_msi_shutdown(pci_dev);
467 pci_msix_shutdown(pci_dev); 467 pci_msix_shutdown(pci_dev);
468 468
469#ifdef CONFIG_KEXEC_CORE
470 /* 469 /*
471 * If this is a kexec reboot, turn off Bus Master bit on the 470 * If this is a kexec reboot, turn off Bus Master bit on the
472 * device to tell it to not continue to do DMA. Don't touch 471 * device to tell it to not continue to do DMA. Don't touch
@@ -476,7 +475,6 @@ static void pci_device_shutdown(struct device *dev)
476 */ 475 */
477 if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot)) 476 if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot))
478 pci_clear_master(pci_dev); 477 pci_clear_master(pci_dev);
479#endif
480} 478}
481 479
482#ifdef CONFIG_PM 480#ifdef CONFIG_PM
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 9730c474b016..194521bfb1a3 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -332,6 +332,12 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
332 332
333void pci_enable_acs(struct pci_dev *dev); 333void pci_enable_acs(struct pci_dev *dev);
334 334
335#ifdef CONFIG_PCIE_PTM
336void pci_ptm_init(struct pci_dev *dev);
337#else
338static inline void pci_ptm_init(struct pci_dev *dev) { }
339#endif
340
335struct pci_dev_reset_methods { 341struct pci_dev_reset_methods {
336 u16 vendor; 342 u16 vendor;
337 u16 device; 343 u16 device;
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index 7fcea75afa4c..7ce77635e5ad 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -92,3 +92,14 @@ config PCIE_DPC
92 will be handled by the DPC driver. If your system doesn't 92 will be handled by the DPC driver. If your system doesn't
93 have this capability or you do not want to use this feature, 93 have this capability or you do not want to use this feature,
94 it is safe to answer N. 94 it is safe to answer N.
95
96config PCIE_PTM
97 bool "PCIe Precision Time Measurement support"
98 default n
99 depends on PCIEPORTBUS
100 help
101 This enables PCI Express Precision Time Measurement (PTM)
102 support.
103
104 This is only useful if you have devices that support PTM, but it
105 is safe to enable even if you don't.
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index b24525b3dec1..36e35ea8fde7 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_PCIEAER) += aer/
16obj-$(CONFIG_PCIE_PME) += pme.o 16obj-$(CONFIG_PCIE_PME) += pme.o
17 17
18obj-$(CONFIG_PCIE_DPC) += pcie-dpc.o 18obj-$(CONFIG_PCIE_DPC) += pcie-dpc.o
19obj-$(CONFIG_PCIE_PTM) += ptm.o
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 48d21e0edd56..139150b2bdfd 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -15,7 +15,6 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/module.h>
19#include <linux/pci.h> 18#include <linux/pci.h>
20#include <linux/pci-acpi.h> 19#include <linux/pci-acpi.h>
21#include <linux/sched.h> 20#include <linux/sched.h>
@@ -37,9 +36,6 @@
37#define DRIVER_VERSION "v1.0" 36#define DRIVER_VERSION "v1.0"
38#define DRIVER_AUTHOR "tom.l.nguyen@intel.com" 37#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
39#define DRIVER_DESC "Root Port Advanced Error Reporting Driver" 38#define DRIVER_DESC "Root Port Advanced Error Reporting Driver"
40MODULE_AUTHOR(DRIVER_AUTHOR);
41MODULE_DESCRIPTION(DRIVER_DESC);
42MODULE_LICENSE("GPL");
43 39
44static int aer_probe(struct pcie_device *dev); 40static int aer_probe(struct pcie_device *dev);
45static void aer_remove(struct pcie_device *dev); 41static void aer_remove(struct pcie_device *dev);
@@ -70,7 +66,7 @@ static int pcie_aer_disable;
70 66
71void pci_no_aer(void) 67void pci_no_aer(void)
72{ 68{
73 pcie_aer_disable = 1; /* has priority over 'forceload' */ 69 pcie_aer_disable = 1;
74} 70}
75 71
76bool pci_aer_available(void) 72bool pci_aer_available(void)
@@ -134,7 +130,7 @@ static void aer_enable_rootport(struct aer_rpc *rpc)
134 pcie_capability_clear_word(pdev, PCI_EXP_RTCTL, 130 pcie_capability_clear_word(pdev, PCI_EXP_RTCTL,
135 SYSTEM_ERROR_INTR_ON_MESG_MASK); 131 SYSTEM_ERROR_INTR_ON_MESG_MASK);
136 132
137 aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 133 aer_pos = pdev->aer_cap;
138 /* Clear error status */ 134 /* Clear error status */
139 pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32); 135 pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
140 pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); 136 pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
@@ -173,7 +169,7 @@ static void aer_disable_rootport(struct aer_rpc *rpc)
173 */ 169 */
174 set_downstream_devices_error_reporting(pdev, false); 170 set_downstream_devices_error_reporting(pdev, false);
175 171
176 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 172 pos = pdev->aer_cap;
177 /* Disable Root's interrupt in response to error messages */ 173 /* Disable Root's interrupt in response to error messages */
178 pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, &reg32); 174 pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
179 reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK; 175 reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
@@ -200,7 +196,7 @@ irqreturn_t aer_irq(int irq, void *context)
200 unsigned long flags; 196 unsigned long flags;
201 int pos; 197 int pos;
202 198
203 pos = pci_find_ext_capability(pdev->port, PCI_EXT_CAP_ID_ERR); 199 pos = pdev->port->aer_cap;
204 /* 200 /*
205 * Must lock access to Root Error Status Reg, Root Error ID Reg, 201 * Must lock access to Root Error Status Reg, Root Error ID Reg,
206 * and Root error producer/consumer index 202 * and Root error producer/consumer index
@@ -294,7 +290,6 @@ static void aer_remove(struct pcie_device *dev)
294/** 290/**
295 * aer_probe - initialize resources 291 * aer_probe - initialize resources
296 * @dev: pointer to the pcie_dev data structure 292 * @dev: pointer to the pcie_dev data structure
297 * @id: pointer to the service id data structure
298 * 293 *
299 * Invoked when PCI Express bus loads AER service driver. 294 * Invoked when PCI Express bus loads AER service driver.
300 */ 295 */
@@ -304,11 +299,6 @@ static int aer_probe(struct pcie_device *dev)
304 struct aer_rpc *rpc; 299 struct aer_rpc *rpc;
305 struct device *device = &dev->device; 300 struct device *device = &dev->device;
306 301
307 /* Init */
308 status = aer_init(dev);
309 if (status)
310 return status;
311
312 /* Alloc rpc data structure */ 302 /* Alloc rpc data structure */
313 rpc = aer_alloc_rpc(dev); 303 rpc = aer_alloc_rpc(dev);
314 if (!rpc) { 304 if (!rpc) {
@@ -343,7 +333,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
343 u32 reg32; 333 u32 reg32;
344 int pos; 334 int pos;
345 335
346 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 336 pos = dev->aer_cap;
347 337
348 /* Disable Root's interrupt in response to error messages */ 338 /* Disable Root's interrupt in response to error messages */
349 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32); 339 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
@@ -396,7 +386,7 @@ static void aer_error_resume(struct pci_dev *dev)
396 pcie_capability_write_word(dev, PCI_EXP_DEVSTA, reg16); 386 pcie_capability_write_word(dev, PCI_EXP_DEVSTA, reg16);
397 387
398 /* Clean AER Root Error Status */ 388 /* Clean AER Root Error Status */
399 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 389 pos = dev->aer_cap;
400 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); 390 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
401 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); 391 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
402 if (dev->error_state == pci_channel_io_normal) 392 if (dev->error_state == pci_channel_io_normal)
@@ -417,16 +407,4 @@ static int __init aer_service_init(void)
417 return -ENXIO; 407 return -ENXIO;
418 return pcie_port_service_register(&aerdriver); 408 return pcie_port_service_register(&aerdriver);
419} 409}
420 410device_initcall(aer_service_init);
421/**
422 * aer_service_exit - unregister AER root service driver
423 *
424 * Invoked when AER root service driver is unloaded.
425 */
426static void __exit aer_service_exit(void)
427{
428 pcie_port_service_unregister(&aerdriver);
429}
430
431module_init(aer_service_init);
432module_exit(aer_service_exit);
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 945c939a86c5..d51e4a57b190 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -60,6 +60,7 @@ struct aer_rpc {
60 struct pcie_device *rpd; /* Root Port device */ 60 struct pcie_device *rpd; /* Root Port device */
61 struct work_struct dpc_handler; 61 struct work_struct dpc_handler;
62 struct aer_err_source e_sources[AER_ERROR_SOURCES_MAX]; 62 struct aer_err_source e_sources[AER_ERROR_SOURCES_MAX];
63 struct aer_err_info e_info;
63 unsigned short prod_idx; /* Error Producer Index */ 64 unsigned short prod_idx; /* Error Producer Index */
64 unsigned short cons_idx; /* Error Consumer Index */ 65 unsigned short cons_idx; /* Error Consumer Index */
65 int isr; 66 int isr;
@@ -105,7 +106,6 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
105} 106}
106 107
107extern struct bus_type pcie_port_bus_type; 108extern struct bus_type pcie_port_bus_type;
108int aer_init(struct pcie_device *dev);
109void aer_isr(struct work_struct *work); 109void aer_isr(struct work_struct *work);
110void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); 110void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
111void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); 111void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info);
@@ -121,11 +121,4 @@ static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
121 return 0; 121 return 0;
122} 122}
123#endif 123#endif
124
125static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev,
126 int enable)
127{
128 pci_dev->__aer_firmware_first = !!enable;
129 pci_dev->__aer_firmware_first_valid = 1;
130}
131#endif /* _AERDRV_H_ */ 124#endif /* _AERDRV_H_ */
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 521e39c1b66d..b1303b32053f 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -27,11 +27,6 @@
27#include <linux/kfifo.h> 27#include <linux/kfifo.h>
28#include "aerdrv.h" 28#include "aerdrv.h"
29 29
30static bool forceload;
31static bool nosourceid;
32module_param(forceload, bool, 0);
33module_param(nosourceid, bool, 0);
34
35#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \ 30#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
36 PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE) 31 PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
37 32
@@ -40,7 +35,7 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev)
40 if (pcie_aer_get_firmware_first(dev)) 35 if (pcie_aer_get_firmware_first(dev))
41 return -EIO; 36 return -EIO;
42 37
43 if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) 38 if (!dev->aer_cap)
44 return -EIO; 39 return -EIO;
45 40
46 return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS); 41 return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
@@ -62,7 +57,7 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
62 int pos; 57 int pos;
63 u32 status; 58 u32 status;
64 59
65 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 60 pos = dev->aer_cap;
66 if (!pos) 61 if (!pos)
67 return -EIO; 62 return -EIO;
68 63
@@ -83,7 +78,7 @@ int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
83 if (!pci_is_pcie(dev)) 78 if (!pci_is_pcie(dev))
84 return -ENODEV; 79 return -ENODEV;
85 80
86 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 81 pos = dev->aer_cap;
87 if (!pos) 82 if (!pos)
88 return -EIO; 83 return -EIO;
89 84
@@ -102,6 +97,12 @@ int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
102 return 0; 97 return 0;
103} 98}
104 99
100int pci_aer_init(struct pci_dev *dev)
101{
102 dev->aer_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
103 return pci_cleanup_aer_error_status_regs(dev);
104}
105
105/** 106/**
106 * add_error_device - list device to be handled 107 * add_error_device - list device to be handled
107 * @e_info: pointer to error info 108 * @e_info: pointer to error info
@@ -132,7 +133,8 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
132 * When bus id is equal to 0, it might be a bad id 133 * When bus id is equal to 0, it might be a bad id
133 * reported by root port. 134 * reported by root port.
134 */ 135 */
135 if (!nosourceid && (PCI_BUS_NUM(e_info->id) != 0)) { 136 if ((PCI_BUS_NUM(e_info->id) != 0) &&
137 !(dev->bus->bus_flags & PCI_BUS_FLAGS_NO_AERSID)) {
136 /* Device ID match? */ 138 /* Device ID match? */
137 if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) 139 if (e_info->id == ((dev->bus->number << 8) | dev->devfn))
138 return true; 140 return true;
@@ -144,10 +146,10 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
144 146
145 /* 147 /*
146 * When either 148 * When either
147 * 1) nosourceid==y; 149 * 1) bus id is equal to 0. Some ports might lose the bus
148 * 2) bus id is equal to 0. Some ports might lose the bus
149 * id of error source id; 150 * id of error source id;
150 * 3) There are multiple errors and prior id comparing fails; 151 * 2) bus flag PCI_BUS_FLAGS_NO_AERSID is set
152 * 3) There are multiple errors and prior ID comparing fails;
151 * We check AER status registers to find possible reporter. 153 * We check AER status registers to find possible reporter.
152 */ 154 */
153 if (atomic_read(&dev->enable_cnt) == 0) 155 if (atomic_read(&dev->enable_cnt) == 0)
@@ -158,7 +160,7 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
158 if (!(reg16 & PCI_EXP_AER_FLAGS)) 160 if (!(reg16 & PCI_EXP_AER_FLAGS))
159 return false; 161 return false;
160 162
161 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 163 pos = dev->aer_cap;
162 if (!pos) 164 if (!pos)
163 return false; 165 return false;
164 166
@@ -555,7 +557,7 @@ static void handle_error_source(struct pcie_device *aerdev,
555 * Correctable error does not need software intervention. 557 * Correctable error does not need software intervention.
556 * No need to go through error recovery process. 558 * No need to go through error recovery process.
557 */ 559 */
558 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 560 pos = dev->aer_cap;
559 if (pos) 561 if (pos)
560 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, 562 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
561 info->status); 563 info->status);
@@ -647,7 +649,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
647 info->status = 0; 649 info->status = 0;
648 info->tlp_header_valid = 0; 650 info->tlp_header_valid = 0;
649 651
650 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 652 pos = dev->aer_cap;
651 653
652 /* The device might not support AER */ 654 /* The device might not support AER */
653 if (!pos) 655 if (!pos)
@@ -715,15 +717,8 @@ static inline void aer_process_err_devices(struct pcie_device *p_device,
715static void aer_isr_one_error(struct pcie_device *p_device, 717static void aer_isr_one_error(struct pcie_device *p_device,
716 struct aer_err_source *e_src) 718 struct aer_err_source *e_src)
717{ 719{
718 struct aer_err_info *e_info; 720 struct aer_rpc *rpc = get_service_data(p_device);
719 721 struct aer_err_info *e_info = &rpc->e_info;
720 /* struct aer_err_info might be big, so we allocate it with slab */
721 e_info = kmalloc(sizeof(struct aer_err_info), GFP_KERNEL);
722 if (!e_info) {
723 dev_printk(KERN_DEBUG, &p_device->port->dev,
724 "Can't allocate mem when processing AER errors\n");
725 return;
726 }
727 722
728 /* 723 /*
729 * There is a possibility that both correctable error and 724 * There is a possibility that both correctable error and
@@ -762,8 +757,6 @@ static void aer_isr_one_error(struct pcie_device *p_device,
762 if (find_source_device(p_device->port, e_info)) 757 if (find_source_device(p_device->port, e_info))
763 aer_process_err_devices(p_device, e_info); 758 aer_process_err_devices(p_device, e_info);
764 } 759 }
765
766 kfree(e_info);
767} 760}
768 761
769/** 762/**
@@ -812,19 +805,3 @@ void aer_isr(struct work_struct *work)
812 aer_isr_one_error(p_device, &e_src); 805 aer_isr_one_error(p_device, &e_src);
813 mutex_unlock(&rpc->rpc_mutex); 806 mutex_unlock(&rpc->rpc_mutex);
814} 807}
815
816/**
817 * aer_init - provide AER initialization
818 * @dev: pointer to AER pcie device
819 *
820 * Invoked when AER service driver is loaded.
821 */
822int aer_init(struct pcie_device *dev)
823{
824 if (forceload) {
825 dev_printk(KERN_DEBUG, &dev->device,
826 "aerdrv forceload requested.\n");
827 pcie_aer_force_firmware_first(dev->port, 0);
828 }
829 return 0;
830}
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 167fe411ce2e..54c4b691e51f 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -219,15 +219,13 @@ int cper_severity_to_aer(int cper_severity)
219} 219}
220EXPORT_SYMBOL_GPL(cper_severity_to_aer); 220EXPORT_SYMBOL_GPL(cper_severity_to_aer);
221 221
222void cper_print_aer(struct pci_dev *dev, int cper_severity, 222void cper_print_aer(struct pci_dev *dev, int aer_severity,
223 struct aer_capability_regs *aer) 223 struct aer_capability_regs *aer)
224{ 224{
225 int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0; 225 int layer, agent, status_strs_size, tlp_header_valid = 0;
226 u32 status, mask; 226 u32 status, mask;
227 const char **status_strs; 227 const char **status_strs;
228 228
229 aer_severity = cper_severity_to_aer(cper_severity);
230
231 if (aer_severity == AER_CORRECTABLE) { 229 if (aer_severity == AER_CORRECTABLE) {
232 status = aer->cor_status; 230 status = aer->cor_status;
233 mask = aer->cor_mask; 231 mask = aer->cor_mask;
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c
index 250f87861786..9811b14d9ad8 100644
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -1,5 +1,7 @@
1/* 1/*
2 * PCI Express Downstream Port Containment services driver 2 * PCI Express Downstream Port Containment services driver
3 * Author: Keith Busch <keith.busch@intel.com>
4 *
3 * Copyright (C) 2016 Intel Corp. 5 * Copyright (C) 2016 Intel Corp.
4 * 6 *
5 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
@@ -9,7 +11,7 @@
9 11
10#include <linux/delay.h> 12#include <linux/delay.h>
11#include <linux/interrupt.h> 13#include <linux/interrupt.h>
12#include <linux/module.h> 14#include <linux/init.h>
13#include <linux/pci.h> 15#include <linux/pci.h>
14#include <linux/pcieport_if.h> 16#include <linux/pcieport_if.h>
15 17
@@ -143,16 +145,4 @@ static int __init dpc_service_init(void)
143{ 145{
144 return pcie_port_service_register(&dpcdriver); 146 return pcie_port_service_register(&dpcdriver);
145} 147}
146 148device_initcall(dpc_service_init);
147static void __exit dpc_service_exit(void)
148{
149 pcie_port_service_unregister(&dpcdriver);
150}
151
152MODULE_DESCRIPTION("PCI Express Downstream Port Containment driver");
153MODULE_AUTHOR("Keith Busch <keith.busch@intel.com>");
154MODULE_LICENSE("GPL");
155MODULE_VERSION("0.1");
156
157module_init(dpc_service_init);
158module_exit(dpc_service_exit);
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 1ae4c73e7a3c..884bad5320f8 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -10,7 +10,6 @@
10 * for more details. 10 * for more details.
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/pci.h> 13#include <linux/pci.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/errno.h> 15#include <linux/errno.h>
@@ -449,17 +448,6 @@ static int pcie_pme_resume(struct pcie_device *srv)
449 return 0; 448 return 0;
450} 449}
451 450
452/**
453 * pcie_pme_remove - Prepare PCIe PME service device for removal.
454 * @srv - PCIe service device to remove.
455 */
456static void pcie_pme_remove(struct pcie_device *srv)
457{
458 pcie_pme_suspend(srv);
459 free_irq(srv->irq, srv);
460 kfree(get_service_data(srv));
461}
462
463static struct pcie_port_service_driver pcie_pme_driver = { 451static struct pcie_port_service_driver pcie_pme_driver = {
464 .name = "pcie_pme", 452 .name = "pcie_pme",
465 .port_type = PCI_EXP_TYPE_ROOT_PORT, 453 .port_type = PCI_EXP_TYPE_ROOT_PORT,
@@ -468,7 +456,6 @@ static struct pcie_port_service_driver pcie_pme_driver = {
468 .probe = pcie_pme_probe, 456 .probe = pcie_pme_probe,
469 .suspend = pcie_pme_suspend, 457 .suspend = pcie_pme_suspend,
470 .resume = pcie_pme_resume, 458 .resume = pcie_pme_resume,
471 .remove = pcie_pme_remove,
472}; 459};
473 460
474/** 461/**
@@ -478,5 +465,4 @@ static int __init pcie_pme_service_init(void)
478{ 465{
479 return pcie_port_service_register(&pcie_pme_driver); 466 return pcie_port_service_register(&pcie_pme_driver);
480} 467}
481 468device_initcall(pcie_pme_service_init);
482module_init(pcie_pme_service_init);
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 70d7ad8c6d17..79327cc14e7d 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -1,12 +1,13 @@
1/* 1/*
2 * File: portdrv_pci.c 2 * File: portdrv_pci.c
3 * Purpose: PCI Express Port Bus Driver 3 * Purpose: PCI Express Port Bus Driver
4 * Author: Tom Nguyen <tom.l.nguyen@intel.com>
5 * Version: v1.0
4 * 6 *
5 * Copyright (C) 2004 Intel 7 * Copyright (C) 2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) 8 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */ 9 */
8 10
9#include <linux/module.h>
10#include <linux/pci.h> 11#include <linux/pci.h>
11#include <linux/kernel.h> 12#include <linux/kernel.h>
12#include <linux/errno.h> 13#include <linux/errno.h>
@@ -21,16 +22,6 @@
21#include "portdrv.h" 22#include "portdrv.h"
22#include "aer/aerdrv.h" 23#include "aer/aerdrv.h"
23 24
24/*
25 * Version Information
26 */
27#define DRIVER_VERSION "v1.0"
28#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
29#define DRIVER_DESC "PCIe Port Bus Driver"
30MODULE_AUTHOR(DRIVER_AUTHOR);
31MODULE_DESCRIPTION(DRIVER_DESC);
32MODULE_LICENSE("GPL");
33
34/* If this switch is set, PCIe port native services should not be enabled. */ 25/* If this switch is set, PCIe port native services should not be enabled. */
35bool pcie_ports_disabled; 26bool pcie_ports_disabled;
36 27
@@ -341,7 +332,6 @@ static const struct pci_device_id port_pci_ids[] = { {
341 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0), 332 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
342 }, { /* end: all zeroes */ } 333 }, { /* end: all zeroes */ }
343}; 334};
344MODULE_DEVICE_TABLE(pci, port_pci_ids);
345 335
346static const struct pci_error_handlers pcie_portdrv_err_handler = { 336static const struct pci_error_handlers pcie_portdrv_err_handler = {
347 .error_detected = pcie_portdrv_error_detected, 337 .error_detected = pcie_portdrv_error_detected,
@@ -406,5 +396,4 @@ static int __init pcie_portdrv_init(void)
406 out: 396 out:
407 return retval; 397 return retval;
408} 398}
409 399device_initcall(pcie_portdrv_init);
410module_init(pcie_portdrv_init);
diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c
new file mode 100644
index 000000000000..bab8ac63c4f3
--- /dev/null
+++ b/drivers/pci/pcie/ptm.c
@@ -0,0 +1,142 @@
1/*
2 * PCI Express Precision Time Measurement
3 * Copyright (c) 2016, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/pci.h>
18#include "../pci.h"
19
20static void pci_ptm_info(struct pci_dev *dev)
21{
22 char clock_desc[8];
23
24 switch (dev->ptm_granularity) {
25 case 0:
26 snprintf(clock_desc, sizeof(clock_desc), "unknown");
27 break;
28 case 255:
29 snprintf(clock_desc, sizeof(clock_desc), ">254ns");
30 break;
31 default:
32 snprintf(clock_desc, sizeof(clock_desc), "%udns",
33 dev->ptm_granularity);
34 break;
35 }
36 dev_info(&dev->dev, "PTM enabled%s, %s granularity\n",
37 dev->ptm_root ? " (root)" : "", clock_desc);
38}
39
40void pci_ptm_init(struct pci_dev *dev)
41{
42 int pos;
43 u32 cap, ctrl;
44 u8 local_clock;
45 struct pci_dev *ups;
46
47 if (!pci_is_pcie(dev))
48 return;
49
50 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM);
51 if (!pos)
52 return;
53
54 /*
55 * Enable PTM only on interior devices (root ports, switch ports,
56 * etc.) on the assumption that it causes no link traffic until an
57 * endpoint enables it.
58 */
59 if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ENDPOINT ||
60 pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END))
61 return;
62
63 pci_read_config_dword(dev, pos + PCI_PTM_CAP, &cap);
64 local_clock = (cap & PCI_PTM_GRANULARITY_MASK) >> 8;
65
66 /*
67 * There's no point in enabling PTM unless it's enabled in the
68 * upstream device or this device can be a PTM Root itself. Per
69 * the spec recommendation (PCIe r3.1, sec 7.32.3), select the
70 * furthest upstream Time Source as the PTM Root.
71 */
72 ups = pci_upstream_bridge(dev);
73 if (ups && ups->ptm_enabled) {
74 ctrl = PCI_PTM_CTRL_ENABLE;
75 if (ups->ptm_granularity == 0)
76 dev->ptm_granularity = 0;
77 else if (ups->ptm_granularity > local_clock)
78 dev->ptm_granularity = ups->ptm_granularity;
79 } else {
80 if (cap & PCI_PTM_CAP_ROOT) {
81 ctrl = PCI_PTM_CTRL_ENABLE | PCI_PTM_CTRL_ROOT;
82 dev->ptm_root = 1;
83 dev->ptm_granularity = local_clock;
84 } else
85 return;
86 }
87
88 ctrl |= dev->ptm_granularity << 8;
89 pci_write_config_dword(dev, pos + PCI_PTM_CTRL, ctrl);
90 dev->ptm_enabled = 1;
91
92 pci_ptm_info(dev);
93}
94
95int pci_enable_ptm(struct pci_dev *dev, u8 *granularity)
96{
97 int pos;
98 u32 cap, ctrl;
99 struct pci_dev *ups;
100
101 if (!pci_is_pcie(dev))
102 return -EINVAL;
103
104 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM);
105 if (!pos)
106 return -EINVAL;
107
108 pci_read_config_dword(dev, pos + PCI_PTM_CAP, &cap);
109 if (!(cap & PCI_PTM_CAP_REQ))
110 return -EINVAL;
111
112 /*
113 * For a PCIe Endpoint, PTM is only useful if the endpoint can
114 * issue PTM requests to upstream devices that have PTM enabled.
115 *
116 * For Root Complex Integrated Endpoints, there is no upstream
117 * device, so there must be some implementation-specific way to
118 * associate the endpoint with a time source.
119 */
120 if (pci_pcie_type(dev) == PCI_EXP_TYPE_ENDPOINT) {
121 ups = pci_upstream_bridge(dev);
122 if (!ups || !ups->ptm_enabled)
123 return -EINVAL;
124
125 dev->ptm_granularity = ups->ptm_granularity;
126 } else if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) {
127 dev->ptm_granularity = 0;
128 } else
129 return -EINVAL;
130
131 ctrl = PCI_PTM_CTRL_ENABLE;
132 ctrl |= dev->ptm_granularity << 8;
133 pci_write_config_dword(dev, pos + PCI_PTM_CTRL, ctrl);
134 dev->ptm_enabled = 1;
135
136 pci_ptm_info(dev);
137
138 if (granularity)
139 *granularity = dev->ptm_granularity;
140 return 0;
141}
142EXPORT_SYMBOL(pci_enable_ptm);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 93f280df3428..ab002671fa60 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1666,7 +1666,11 @@ static void pci_init_capabilities(struct pci_dev *dev)
1666 /* Enable ACS P2P upstream forwarding */ 1666 /* Enable ACS P2P upstream forwarding */
1667 pci_enable_acs(dev); 1667 pci_enable_acs(dev);
1668 1668
1669 pci_cleanup_aer_error_status_regs(dev); 1669 /* Precision Time Measurement */
1670 pci_ptm_init(dev);
1671
1672 /* Advanced Error Reporting */
1673 pci_aer_init(dev);
1670} 1674}
1671 1675
1672/* 1676/*
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 37ff0158e45f..6297942649bf 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4428,3 +4428,20 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)
4428 } 4428 }
4429} 4429}
4430DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap); 4430DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap);
4431
4432/*
4433 * VMD-enabled root ports will change the source ID for all messages
4434 * to the VMD device. Rather than doing device matching with the source
4435 * ID, the AER driver should traverse the child device tree, reading
4436 * AER registers to find the faulting device.
4437 */
4438static void quirk_no_aersid(struct pci_dev *pdev)
4439{
4440 /* VMD Domain */
4441 if (pdev->bus->sysdata && pci_domain_nr(pdev->bus) >= 0x10000)
4442 pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID;
4443}
4444DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid);
4445DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid);
4446DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid);
4447DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid);
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 164049357e5c..04602cbe85dc 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -63,7 +63,7 @@ static inline int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
63} 63}
64#endif 64#endif
65 65
66void cper_print_aer(struct pci_dev *dev, int cper_severity, 66void cper_print_aer(struct pci_dev *dev, int aer_severity,
67 struct aer_capability_regs *aer); 67 struct aer_capability_regs *aer);
68int cper_severity_to_aer(int cper_severity); 68int cper_severity_to_aer(int cper_severity);
69void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, 69void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2599a980340f..b0e4ed19b315 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -187,8 +187,9 @@ enum pci_irq_reroute_variant {
187 187
188typedef unsigned short __bitwise pci_bus_flags_t; 188typedef unsigned short __bitwise pci_bus_flags_t;
189enum pci_bus_flags { 189enum pci_bus_flags {
190 PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, 190 PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
191 PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2, 191 PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
192 PCI_BUS_FLAGS_NO_AERSID = (__force pci_bus_flags_t) 4,
192}; 193};
193 194
194/* These values come from the PCI Express Spec */ 195/* These values come from the PCI Express Spec */
@@ -268,6 +269,9 @@ struct pci_dev {
268 unsigned int class; /* 3 bytes: (base,sub,prog-if) */ 269 unsigned int class; /* 3 bytes: (base,sub,prog-if) */
269 u8 revision; /* PCI revision, low byte of class word */ 270 u8 revision; /* PCI revision, low byte of class word */
270 u8 hdr_type; /* PCI header type (`multi' flag masked out) */ 271 u8 hdr_type; /* PCI header type (`multi' flag masked out) */
272#ifdef CONFIG_PCIEAER
273 u16 aer_cap; /* AER capability offset */
274#endif
271 u8 pcie_cap; /* PCIe capability offset */ 275 u8 pcie_cap; /* PCIe capability offset */
272 u8 msi_cap; /* MSI capability offset */ 276 u8 msi_cap; /* MSI capability offset */
273 u8 msix_cap; /* MSI-X capability offset */ 277 u8 msix_cap; /* MSI-X capability offset */
@@ -308,6 +312,9 @@ struct pci_dev {
308 powered on/off by the 312 powered on/off by the
309 corresponding bridge */ 313 corresponding bridge */
310 unsigned int ignore_hotplug:1; /* Ignore hotplug events */ 314 unsigned int ignore_hotplug:1; /* Ignore hotplug events */
315 unsigned int hotplug_user_indicators:1; /* SlotCtl indicators
316 controlled exclusively by
317 user sysfs */
311 unsigned int d3_delay; /* D3->D0 transition time in ms */ 318 unsigned int d3_delay; /* D3->D0 transition time in ms */
312 unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */ 319 unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */
313 320
@@ -367,6 +374,12 @@ struct pci_dev {
367 int rom_attr_enabled; /* has display of the rom attribute been enabled? */ 374 int rom_attr_enabled; /* has display of the rom attribute been enabled? */
368 struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ 375 struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
369 struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */ 376 struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
377
378#ifdef CONFIG_PCIE_PTM
379 unsigned int ptm_root:1;
380 unsigned int ptm_enabled:1;
381 u8 ptm_granularity;
382#endif
370#ifdef CONFIG_PCI_MSI 383#ifdef CONFIG_PCI_MSI
371 const struct attribute_group **msi_irq_groups; 384 const struct attribute_group **msi_irq_groups;
372#endif 385#endif
@@ -1368,9 +1381,11 @@ static inline bool pcie_aspm_support_enabled(void) { return false; }
1368#ifdef CONFIG_PCIEAER 1381#ifdef CONFIG_PCIEAER
1369void pci_no_aer(void); 1382void pci_no_aer(void);
1370bool pci_aer_available(void); 1383bool pci_aer_available(void);
1384int pci_aer_init(struct pci_dev *dev);
1371#else 1385#else
1372static inline void pci_no_aer(void) { } 1386static inline void pci_no_aer(void) { }
1373static inline bool pci_aer_available(void) { return false; } 1387static inline bool pci_aer_available(void) { return false; }
1388static inline int pci_aer_init(struct pci_dev *d) { return -ENODEV; }
1374#endif 1389#endif
1375 1390
1376#ifdef CONFIG_PCIE_ECRC 1391#ifdef CONFIG_PCIE_ECRC
@@ -1402,6 +1417,13 @@ static inline void pci_disable_ats(struct pci_dev *d) { }
1402static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; } 1417static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; }
1403#endif 1418#endif
1404 1419
1420#ifdef CONFIG_PCIE_PTM
1421int pci_enable_ptm(struct pci_dev *dev, u8 *granularity);
1422#else
1423static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity)
1424{ return -EINVAL; }
1425#endif
1426
1405void pci_cfg_access_lock(struct pci_dev *dev); 1427void pci_cfg_access_lock(struct pci_dev *dev);
1406bool pci_cfg_access_trylock(struct pci_dev *dev); 1428bool pci_cfg_access_trylock(struct pci_dev *dev);
1407void pci_cfg_access_unlock(struct pci_dev *dev); 1429void pci_cfg_access_unlock(struct pci_dev *dev);
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index 404095124ae2..d812172d1d7b 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -671,7 +671,8 @@
671#define PCI_EXT_CAP_ID_PMUX 0x1A /* Protocol Multiplexing */ 671#define PCI_EXT_CAP_ID_PMUX 0x1A /* Protocol Multiplexing */
672#define PCI_EXT_CAP_ID_PASID 0x1B /* Process Address Space ID */ 672#define PCI_EXT_CAP_ID_PASID 0x1B /* Process Address Space ID */
673#define PCI_EXT_CAP_ID_DPC 0x1D /* Downstream Port Containment */ 673#define PCI_EXT_CAP_ID_DPC 0x1D /* Downstream Port Containment */
674#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DPC 674#define PCI_EXT_CAP_ID_PTM 0x1F /* Precision Time Measurement */
675#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PTM
675 676
676#define PCI_EXT_CAP_DSN_SIZEOF 12 677#define PCI_EXT_CAP_DSN_SIZEOF 12
677#define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 678#define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40
@@ -964,4 +965,13 @@
964 965
965#define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */ 966#define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */
966 967
968/* Precision Time Measurement */
969#define PCI_PTM_CAP 0x04 /* PTM Capability */
970#define PCI_PTM_CAP_REQ 0x00000001 /* Requester capable */
971#define PCI_PTM_CAP_ROOT 0x00000004 /* Root capable */
972#define PCI_PTM_GRANULARITY_MASK 0x0000FF00 /* Clock granularity */
973#define PCI_PTM_CTRL 0x08 /* PTM Control */
974#define PCI_PTM_CTRL_ENABLE 0x00000001 /* PTM enable */
975#define PCI_PTM_CTRL_ROOT 0x00000002 /* Root select */
976
967#endif /* LINUX_PCI_REGS_H */ 977#endif /* LINUX_PCI_REGS_H */