summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/controller/cadence/pcie-cadence-plat.c5
-rw-r--r--drivers/pci/controller/dwc/pci-exynos.c4
-rw-r--r--drivers/pci/controller/dwc/pci-keystone.c8
-rw-r--r--drivers/pci/controller/dwc/pci-layerscape.c2
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-host.c3
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.h1
-rw-r--r--drivers/pci/controller/dwc/pcie-kirin.c4
-rw-r--r--drivers/pci/controller/dwc/pcie-qcom.c28
-rw-r--r--drivers/pci/controller/mobiveil/pcie-mobiveil-host.c2
-rw-r--r--drivers/pci/controller/pci-hyperv.c2
-rw-r--r--drivers/pci/controller/pcie-iproc.c2
-rw-r--r--drivers/pci/controller/pcie-rcar-ep.c2
-rw-r--r--drivers/pci/controller/pcie-rcar-host.c2
-rw-r--r--drivers/pci/controller/vmd.c5
-rw-r--r--drivers/pci/endpoint/pci-epc-core.c12
-rw-r--r--drivers/pci/hotplug/Kconfig12
-rw-r--r--drivers/pci/hotplug/Makefile1
-rw-r--r--drivers/pci/hotplug/acpiphp_ampere_altra.c127
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c3
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c6
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c22
-rw-r--r--drivers/pci/hotplug/ibmphp.h5
-rw-r--r--drivers/pci/hotplug/ibmphp_pci.c2
-rw-r--r--drivers/pci/p2pdma.c3
-rw-r--r--drivers/pci/pci-acpi.c15
-rw-r--r--drivers/pci/pci-sysfs.c12
-rw-r--r--drivers/pci/pci.c2
-rw-r--r--drivers/pci/pcie/aer.c45
-rw-r--r--drivers/pci/pcie/aspm.c76
-rw-r--r--drivers/pci/quirks.c53
-rw-r--r--drivers/pci/search.c31
-rw-r--r--drivers/pci/vgaarb.c14
32 files changed, 379 insertions, 132 deletions
diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index 371ffc1f00f8..0456845dabb9 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
@@ -17,12 +17,9 @@
/**
* struct cdns_plat_pcie - private data for this PCIe platform driver
* @pcie: Cadence PCIe controller
- * @is_rc: Set to 1 indicates the PCIe controller mode is Root Complex,
- * if 0 it is in Endpoint mode.
*/
struct cdns_plat_pcie {
struct cdns_pcie *pcie;
- bool is_rc;
};
struct cdns_plat_pcie_of_data {
@@ -76,7 +73,6 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
rc->pcie.dev = dev;
rc->pcie.ops = &cdns_plat_ops;
cdns_plat_pcie->pcie = &rc->pcie;
- cdns_plat_pcie->is_rc = is_rc;
ret = cdns_pcie_init_phy(dev, cdns_plat_pcie->pcie);
if (ret) {
@@ -104,7 +100,6 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
ep->pcie.dev = dev;
ep->pcie.ops = &cdns_plat_ops;
cdns_plat_pcie->pcie = &ep->pcie;
- cdns_plat_pcie->is_rc = is_rc;
ret = cdns_pcie_init_phy(dev, cdns_plat_pcie->pcie);
if (ret) {
diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index 6319082301d6..c6bede346932 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -375,7 +375,7 @@ fail_probe:
return ret;
}
-static int __exit exynos_pcie_remove(struct platform_device *pdev)
+static int exynos_pcie_remove(struct platform_device *pdev)
{
struct exynos_pcie *ep = platform_get_drvdata(pdev);
@@ -431,7 +431,7 @@ static const struct of_device_id exynos_pcie_of_match[] = {
static struct platform_driver exynos_pcie_driver = {
.probe = exynos_pcie_probe,
- .remove = __exit_p(exynos_pcie_remove),
+ .remove = exynos_pcie_remove,
.driver = {
.name = "exynos-pcie",
.of_match_table = exynos_pcie_of_match,
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index 49aea6ce3e87..0def919f89fa 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -1100,7 +1100,7 @@ static const struct of_device_id ks_pcie_of_match[] = {
{ },
};
-static int __init ks_pcie_probe(struct platform_device *pdev)
+static int ks_pcie_probe(struct platform_device *pdev)
{
const struct dw_pcie_host_ops *host_ops;
const struct dw_pcie_ep_ops *ep_ops;
@@ -1302,7 +1302,7 @@ err_link:
return ret;
}
-static int __exit ks_pcie_remove(struct platform_device *pdev)
+static int ks_pcie_remove(struct platform_device *pdev)
{
struct keystone_pcie *ks_pcie = platform_get_drvdata(pdev);
struct device_link **link = ks_pcie->link;
@@ -1318,9 +1318,9 @@ static int __exit ks_pcie_remove(struct platform_device *pdev)
return 0;
}
-static struct platform_driver ks_pcie_driver __refdata = {
+static struct platform_driver ks_pcie_driver = {
.probe = ks_pcie_probe,
- .remove = __exit_p(ks_pcie_remove),
+ .remove = ks_pcie_remove,
.driver = {
.name = "keystone-pcie",
.of_match_table = ks_pcie_of_match,
diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
index b931d597656f..37956e09c65b 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -58,7 +58,7 @@ static bool ls_pcie_is_bridge(struct ls_pcie *pcie)
u32 header_type;
header_type = ioread8(pci->dbi_base + PCI_HEADER_TYPE);
- header_type &= 0x7f;
+ header_type &= PCI_HEADER_TYPE_MASK;
return header_type == PCI_HEADER_TYPE_BRIDGE;
}
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index a7170fd0e847..7991f0e179b2 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -502,6 +502,9 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
if (ret)
goto err_stop_link;
+ if (pp->ops->host_post_init)
+ pp->ops->host_post_init(pp);
+
return 0;
err_stop_link:
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index ef0b2efa9f93..efb4d4754fc8 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -301,6 +301,7 @@ enum dw_pcie_ltssm {
struct dw_pcie_host_ops {
int (*host_init)(struct dw_pcie_rp *pp);
void (*host_deinit)(struct dw_pcie_rp *pp);
+ void (*host_post_init)(struct dw_pcie_rp *pp);
int (*msi_host_init)(struct dw_pcie_rp *pp);
void (*pme_turn_off)(struct dw_pcie_rp *pp);
};
diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
index d93bc2906950..2ee146767971 100644
--- a/drivers/pci/controller/dwc/pcie-kirin.c
+++ b/drivers/pci/controller/dwc/pcie-kirin.c
@@ -741,7 +741,7 @@ err:
return ret;
}
-static int __exit kirin_pcie_remove(struct platform_device *pdev)
+static int kirin_pcie_remove(struct platform_device *pdev)
{
struct kirin_pcie *kirin_pcie = platform_get_drvdata(pdev);
@@ -818,7 +818,7 @@ static int kirin_pcie_probe(struct platform_device *pdev)
static struct platform_driver kirin_pcie_driver = {
.probe = kirin_pcie_probe,
- .remove = __exit_p(kirin_pcie_remove),
+ .remove = kirin_pcie_remove,
.driver = {
.name = "kirin-pcie",
.of_match_table = kirin_pcie_match,
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index e2f29404c84e..a0252c9b2d71 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -219,6 +219,7 @@ struct qcom_pcie_ops {
int (*get_resources)(struct qcom_pcie *pcie);
int (*init)(struct qcom_pcie *pcie);
int (*post_init)(struct qcom_pcie *pcie);
+ void (*host_post_init)(struct qcom_pcie *pcie);
void (*deinit)(struct qcom_pcie *pcie);
void (*ltssm_enable)(struct qcom_pcie *pcie);
int (*config_sid)(struct qcom_pcie *pcie);
@@ -964,6 +965,22 @@ static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie)
return 0;
}
+static int qcom_pcie_enable_aspm(struct pci_dev *pdev, void *userdata)
+{
+ /* Downstream devices need to be in D0 state before enabling PCI PM substates */
+ pci_set_power_state(pdev, PCI_D0);
+ pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL);
+
+ return 0;
+}
+
+static void qcom_pcie_host_post_init_2_7_0(struct qcom_pcie *pcie)
+{
+ struct dw_pcie_rp *pp = &pcie->pci->pp;
+
+ pci_walk_bus(pp->bridge->bus, qcom_pcie_enable_aspm, NULL);
+}
+
static void qcom_pcie_deinit_2_7_0(struct qcom_pcie *pcie)
{
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
@@ -1216,9 +1233,19 @@ static void qcom_pcie_host_deinit(struct dw_pcie_rp *pp)
pcie->cfg->ops->deinit(pcie);
}
+static void qcom_pcie_host_post_init(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct qcom_pcie *pcie = to_qcom_pcie(pci);
+
+ if (pcie->cfg->ops->host_post_init)
+ pcie->cfg->ops->host_post_init(pcie);
+}
+
static const struct dw_pcie_host_ops qcom_pcie_dw_ops = {
.host_init = qcom_pcie_host_init,
.host_deinit = qcom_pcie_host_deinit,
+ .host_post_init = qcom_pcie_host_post_init,
};
/* Qcom IP rev.: 2.1.0 Synopsys IP rev.: 4.01a */
@@ -1280,6 +1307,7 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
.get_resources = qcom_pcie_get_resources_2_7_0,
.init = qcom_pcie_init_2_7_0,
.post_init = qcom_pcie_post_init_2_7_0,
+ .host_post_init = qcom_pcie_host_post_init_2_7_0,
.deinit = qcom_pcie_deinit_2_7_0,
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
.config_sid = qcom_pcie_config_sid_1_9_0,
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index 45b97a4b14db..32951f7d6d6d 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -539,7 +539,7 @@ static bool mobiveil_pcie_is_bridge(struct mobiveil_pcie *pcie)
u32 header_type;
header_type = mobiveil_csr_readb(pcie, PCI_HEADER_TYPE);
- header_type &= 0x7f;
+ header_type &= PCI_HEADER_TYPE_MASK;
return header_type == PCI_HEADER_TYPE_BRIDGE;
}
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index bed3cefdaf19..30c7dfeccb16 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -545,7 +545,7 @@ struct hv_pcidev_description {
struct hv_dr_state {
struct list_head list_entry;
u32 device_count;
- struct hv_pcidev_description func[];
+ struct hv_pcidev_description func[] __counted_by(device_count);
};
struct hv_pci_dev {
diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
index bd1c98b68851..97f739a2c9f8 100644
--- a/drivers/pci/controller/pcie-iproc.c
+++ b/drivers/pci/controller/pcie-iproc.c
@@ -783,7 +783,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie)
/* make sure we are not in EP mode */
iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, &hdr_type);
- if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) {
+ if ((hdr_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE) {
dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type);
return -EFAULT;
}
diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
index f9682df1da61..7034c0ff23d0 100644
--- a/drivers/pci/controller/pcie-rcar-ep.c
+++ b/drivers/pci/controller/pcie-rcar-ep.c
@@ -43,7 +43,7 @@ static void rcar_pcie_ep_hw_init(struct rcar_pcie *pcie)
rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ENDPOINT << 4);
- rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
+ rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), PCI_HEADER_TYPE_MASK,
PCI_HEADER_TYPE_NORMAL);
/* Write out the physical slot number = 0 */
diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
index 88975e40ee2f..bf7cc0b6a695 100644
--- a/drivers/pci/controller/pcie-rcar-host.c
+++ b/drivers/pci/controller/pcie-rcar-host.c
@@ -460,7 +460,7 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
- rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
+ rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), PCI_HEADER_TYPE_MASK,
PCI_HEADER_TYPE_BRIDGE);
/* Enable data link layer active state reporting */
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index ad56df98b8e6..566721c41f3e 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -525,10 +525,9 @@ static void vmd_domain_reset(struct vmd_dev *vmd)
base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus,
PCI_DEVFN(dev, 0), 0);
- hdr_type = readb(base + PCI_HEADER_TYPE) &
- PCI_HEADER_TYPE_MASK;
+ hdr_type = readb(base + PCI_HEADER_TYPE);
- functions = (hdr_type & 0x80) ? 8 : 1;
+ functions = (hdr_type & PCI_HEADER_TYPE_MFD) ? 8 : 1;
for (fn = 0; fn < functions; fn++) {
base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus,
PCI_DEVFN(dev, fn), 0);
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 5a4a8b0be626..fe421d46a8a4 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -38,7 +38,7 @@ static int devm_pci_epc_match(struct device *dev, void *res, void *match_data)
*/
void pci_epc_put(struct pci_epc *epc)
{
- if (!epc || IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc))
return;
module_put(epc->ops->owner);
@@ -660,7 +660,7 @@ void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
struct list_head *list;
u32 func_no = 0;
- if (!epc || IS_ERR(epc) || !epf)
+ if (IS_ERR_OR_NULL(epc) || !epf)
return;
if (type == PRIMARY_INTERFACE) {
@@ -691,7 +691,7 @@ void pci_epc_linkup(struct pci_epc *epc)
{
struct pci_epf *epf;
- if (!epc || IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc))
return;
mutex_lock(&epc->list_lock);
@@ -717,7 +717,7 @@ void pci_epc_linkdown(struct pci_epc *epc)
{
struct pci_epf *epf;
- if (!epc || IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc))
return;
mutex_lock(&epc->list_lock);
@@ -743,7 +743,7 @@ void pci_epc_init_notify(struct pci_epc *epc)
{
struct pci_epf *epf;
- if (!epc || IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc))
return;
mutex_lock(&epc->list_lock);
@@ -769,7 +769,7 @@ void pci_epc_bme_notify(struct pci_epc *epc)
{
struct pci_epf *epf;
- if (!epc || IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc))
return;
mutex_lock(&epc->list_lock);
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 48113b210cf9..1472aef0fb81 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -61,6 +61,18 @@ config HOTPLUG_PCI_ACPI
When in doubt, say N.
+config HOTPLUG_PCI_ACPI_AMPERE_ALTRA
+ tristate "ACPI PCI Hotplug driver Ampere Altra extensions"
+ depends on HOTPLUG_PCI_ACPI
+ depends on HAVE_ARM_SMCCC_DISCOVERY
+ help
+ Say Y here if you have an Ampere Altra system.
+
+ To compile this driver as a module, choose M here: the
+ module will be called acpiphp_ampere_altra.
+
+ When in doubt, say N.
+
config HOTPLUG_PCI_ACPI_IBM
tristate "ACPI PCI Hotplug driver IBM extensions"
depends on HOTPLUG_PCI_ACPI
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 5196983220df..240c99517d5e 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_HOTPLUG_PCI_S390) += s390_pci_hpc.o
# acpiphp_ibm extends acpiphp, so should be linked afterwards.
+obj-$(CONFIG_HOTPLUG_PCI_ACPI_AMPERE_ALTRA) += acpiphp_ampere_altra.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
pci_hotplug-objs := pci_hotplug_core.o
diff --git a/drivers/pci/hotplug/acpiphp_ampere_altra.c b/drivers/pci/hotplug/acpiphp_ampere_altra.c
new file mode 100644
index 000000000000..3fddd04851b6
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_ampere_altra.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACPI PCI Hot Plug Extension for Ampere Altra. Allows control of
+ * attention LEDs via requests to system firmware.
+ *
+ * Copyright (C) 2023 Ampere Computing LLC
+ */
+
+#define pr_fmt(fmt) "acpiphp_ampere_altra: " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/pci_hotplug.h>
+#include <linux/platform_device.h>
+
+#include "acpiphp.h"
+
+#define HANDLE_OPEN 0xb0200000
+#define HANDLE_CLOSE 0xb0300000
+#define REQUEST 0xf0700000
+#define LED_CMD 0x00000004
+#define LED_ATTENTION 0x00000002
+#define LED_SET_ON 0x00000001
+#define LED_SET_OFF 0x00000002
+#define LED_SET_BLINK 0x00000003
+
+static u32 led_service_id[4];
+
+static int led_status(u8 status)
+{
+ switch (status) {
+ case 1: return LED_SET_ON;
+ case 2: return LED_SET_BLINK;
+ default: return LED_SET_OFF;
+ }
+}
+
+static int set_attention_status(struct hotplug_slot *slot, u8 status)
+{
+ struct arm_smccc_res res;
+ struct pci_bus *bus;
+ struct pci_dev *root_port;
+ unsigned long flags;
+ u32 handle;
+ int ret = 0;
+
+ bus = slot->pci_slot->bus;
+ root_port = pcie_find_root_port(bus->self);
+ if (!root_port)
+ return -ENODEV;
+
+ local_irq_save(flags);
+ arm_smccc_smc(HANDLE_OPEN, led_service_id[0], led_service_id[1],
+ led_service_id[2], led_service_id[3], 0, 0, 0, &res);
+ if (res.a0) {
+ ret = -ENODEV;
+ goto out;
+ }
+ handle = res.a1 & 0xffff0000;
+
+ arm_smccc_smc(REQUEST, LED_CMD, led_status(status), LED_ATTENTION,
+ (PCI_SLOT(root_port->devfn) << 4) | (pci_domain_nr(bus) & 0xf),
+ 0, 0, handle, &res);
+ if (res.a0)
+ ret = -ENODEV;
+
+ arm_smccc_smc(HANDLE_CLOSE, handle, 0, 0, 0, 0, 0, 0, &res);
+
+ out:
+ local_irq_restore(flags);
+ return ret;
+}
+
+static int get_attention_status(struct hotplug_slot *slot, u8 *status)
+{
+ return -EINVAL;
+}
+
+static struct acpiphp_attention_info ampere_altra_attn = {
+ .set_attn = set_attention_status,
+ .get_attn = get_attention_status,
+ .owner = THIS_MODULE,
+};
+
+static int altra_led_probe(struct platform_device *pdev)
+{
+ struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev);
+ int ret;
+
+ ret = fwnode_property_read_u32_array(fwnode, "uuid", led_service_id, 4);
+ if (ret) {
+ dev_err(&pdev->dev, "can't find uuid\n");
+ return ret;
+ }
+
+ ret = acpiphp_register_attention(&ampere_altra_attn);
+ if (ret) {
+ dev_err(&pdev->dev, "can't register driver\n");
+ return ret;
+ }
+ return 0;
+}
+
+static void altra_led_remove(struct platform_device *pdev)
+{
+ acpiphp_unregister_attention(&ampere_altra_attn);
+}
+
+static const struct acpi_device_id altra_led_ids[] = {
+ { "AMPC0008", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, altra_led_ids);
+
+static struct platform_driver altra_led_driver = {
+ .driver = {
+ .name = "ampere-altra-leds",
+ .acpi_match_table = altra_led_ids,
+ },
+ .probe = altra_led_probe,
+ .remove_new = altra_led_remove,
+};
+module_platform_driver(altra_led_driver);
+
+MODULE_AUTHOR("D Scott Phillips <scott@os.amperecomputing.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index c02257f4b61c..9dad14e80bcf 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -78,8 +78,7 @@ int acpiphp_register_attention(struct acpiphp_attention_info *info)
{
int retval = -EINVAL;
- if (info && info->owner && info->set_attn &&
- info->get_attn && !attention_info) {
+ if (info && info->set_attn && info->get_attn && !attention_info) {
retval = 0;
attention_info = info;
}
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index e429ecddc8fe..c01968ef0bd7 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -2059,7 +2059,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
return rc;
/* If it's a bridge, check the VGA Enable bit */
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
if (rc)
return rc;
@@ -2342,7 +2342,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
if (rc)
return rc;
- if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ if ((temp_byte & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
/* set Primary bus */
dbg("set Primary bus = %d\n", func->bus);
rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
@@ -2739,7 +2739,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
* PCI_BRIDGE_CTL_SERR |
* PCI_BRIDGE_CTL_NO_ISA */
rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
- } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
+ } else if ((temp_byte & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
/* Standard device */
rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 3b248426a9f4..e9f1fb333a71 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -363,7 +363,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
return rc;
/* If multi-function device, set max_functions to 8 */
- if (header_type & 0x80)
+ if (header_type & PCI_HEADER_TYPE_MFD)
max_functions = 8;
else
max_functions = 1;
@@ -372,7 +372,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
do {
DevError = 0;
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
/* Recurse the subordinate bus
* get the subordinate bus number
*/
@@ -487,13 +487,13 @@ int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot)
pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
- if (header_type & 0x80) /* Multi-function device */
+ if (header_type & PCI_HEADER_TYPE_MFD)
max_functions = 8;
else
max_functions = 1;
while (function < max_functions) {
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
/* Recurse the subordinate bus */
pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
@@ -571,7 +571,7 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)
/* Check for Bridge */
pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus;
@@ -625,7 +625,7 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)
} /* End of base register loop */
- } else if ((header_type & 0x7F) == 0x00) {
+ } else if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
/* Figure out IO and memory base lengths */
for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF;
@@ -723,7 +723,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func)
/* Check for Bridge */
pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
/* Clear Bridge Control Register */
command = 0x00;
pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
@@ -858,7 +858,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func)
}
} /* End of base register loop */
/* Standard header */
- } else if ((header_type & 0x7F) == 0x00) {
+ } else if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
/* Figure out IO and memory base lengths */
for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
@@ -975,7 +975,7 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func)
pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
/* If this is a bridge device, restore subordinate devices */
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus;
@@ -1067,7 +1067,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
/* Check for Bridge */
pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+ if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
/* In order to continue checking, we must program the
* bus registers in the bridge to respond to accesses
* for its subordinate bus(es)
@@ -1090,7 +1090,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
}
/* Check to see if it is a standard config header */
- else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
+ else if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
/* Check subsystem vendor and ID */
pci_bus_read_config_dword(pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
index 41eafe511210..c248a09be7b5 100644
--- a/drivers/pci/hotplug/ibmphp.h
+++ b/drivers/pci/hotplug/ibmphp.h
@@ -17,6 +17,7 @@
*/
#include <linux/pci_hotplug.h>
+#include <linux/pci_regs.h>
extern int ibmphp_debug;
@@ -286,8 +287,8 @@ int ibmphp_register_pci(void);
/* pci specific defines */
#define PCI_VENDOR_ID_NOTVALID 0xFFFF
-#define PCI_HEADER_TYPE_MULTIDEVICE 0x80
-#define PCI_HEADER_TYPE_MULTIBRIDGE 0x81
+#define PCI_HEADER_TYPE_MULTIDEVICE (PCI_HEADER_TYPE_MFD|PCI_HEADER_TYPE_NORMAL)
+#define PCI_HEADER_TYPE_MULTIBRIDGE (PCI_HEADER_TYPE_MFD|PCI_HEADER_TYPE_BRIDGE)
#define LATENCY 0x64
#define CACHE 64
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
index 50038e5f9ca4..eeb412cbd9fe 100644
--- a/drivers/pci/hotplug/ibmphp_pci.c
+++ b/drivers/pci/hotplug/ibmphp_pci.c
@@ -1087,7 +1087,7 @@ static struct res_needed *scan_behind_bridge(struct pci_func *func, u8 busno)
pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
debug("hdr_type behind the bridge is %x\n", hdr_type);
- if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
+ if ((hdr_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
err("embedded bridges not supported for hot-plugging.\n");
amount->not_correct = 1;
return amount;
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index fa7370f9561a..0c361561b855 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -28,9 +28,9 @@ struct pci_p2pdma {
};
struct pci_p2pdma_pagemap {
- struct dev_pagemap pgmap;
struct pci_dev *provider;
u64 bus_offset;
+ struct dev_pagemap pgmap;
};
static struct pci_p2pdma_pagemap *to_p2p_pgmap(struct dev_pagemap *pgmap)
@@ -837,7 +837,6 @@ void *pci_alloc_p2pmem(struct pci_dev *pdev, size_t size)
if (unlikely(!percpu_ref_tryget_live_rcu(ref))) {
gen_pool_free(p2pdma->pool, (unsigned long) ret, size);
ret = NULL;
- goto out;
}
out:
rcu_read_unlock();
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index a05350a4e49c..004575091596 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -911,7 +911,7 @@ pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
{
int acpi_state, d_max;
- if (pdev->no_d3cold)
+ if (pdev->no_d3cold || !pdev->d3cold_allowed)
d_max = ACPI_STATE_D3_HOT;
else
d_max = ACPI_STATE_D3_COLD;
@@ -1215,12 +1215,12 @@ void acpi_pci_add_bus(struct pci_bus *bus)
if (!pci_is_root_bus(bus))
return;
- obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 3,
- DSM_PCI_POWER_ON_RESET_DELAY, NULL);
+ obj = acpi_evaluate_dsm_typed(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 3,
+ DSM_PCI_POWER_ON_RESET_DELAY, NULL, ACPI_TYPE_INTEGER);
if (!obj)
return;
- if (obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 1) {
+ if (obj->integer.value == 1) {
bridge = pci_find_host_bridge(bus);
bridge->ignore_reset_delay = 1;
}
@@ -1376,12 +1376,13 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev,
if (bridge->ignore_reset_delay)
pdev->d3cold_delay = 0;
- obj = acpi_evaluate_dsm(handle, &pci_acpi_dsm_guid, 3,
- DSM_PCI_DEVICE_READINESS_DURATIONS, NULL);
+ obj = acpi_evaluate_dsm_typed(handle, &pci_acpi_dsm_guid, 3,
+ DSM_PCI_DEVICE_READINESS_DURATIONS, NULL,
+ ACPI_TYPE_PACKAGE);
if (!obj)
return;
- if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 5) {
+ if (obj->package.count == 5) {
elements = obj->package.elements;
if (elements[0].type == ACPI_TYPE_INTEGER) {
value = (int)elements[0].integer.value / 1000;
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index d9eede2dbc0e..7f3ea6b33e08 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -530,10 +530,7 @@ static ssize_t d3cold_allowed_store(struct device *dev,
return -EINVAL;
pdev->d3cold_allowed = !!val;
- if (pdev->d3cold_allowed)
- pci_d3cold_enable(pdev);
- else
- pci_d3cold_disable(pdev);
+ pci_bridge_d3_update(pdev);
pm_runtime_resume(dev);
@@ -1551,11 +1548,10 @@ static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
struct device *dev = kobj_to_dev(kobj);
struct pci_dev *pdev = to_pci_dev(dev);
- if (a == &dev_attr_boot_vga.attr)
- if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
- return 0;
+ if (a == &dev_attr_boot_vga.attr && pci_is_vga(pdev))
+ return a->mode;
- return a->mode;
+ return 0;
}
static struct attribute *pci_dev_hp_attrs[] = {
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 59c01d68c6d5..33946ff5c6bd 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -534,7 +534,7 @@ u8 pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
- pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f);
+ pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & PCI_HEADER_TYPE_MASK);
if (pos)
pos = __pci_find_next_cap(bus, devfn, pos, cap);
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index e85ff946e8c8..5706019ea908 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1213,6 +1213,28 @@ static irqreturn_t aer_irq(int irq, void *context)
return IRQ_WAKE_THREAD;
}
+static void aer_enable_irq(struct pci_dev *pdev)
+{
+ int aer = pdev->aer_cap;
+ u32 reg32;
+
+ /* Enable Root Port's interrupt in response to error messages */
+ pci_read_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, &reg32);
+ reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
+ pci_write_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, reg32);
+}
+
+static void aer_disable_irq(struct pci_dev *pdev)
+{
+ int aer = pdev->aer_cap;
+ u32 reg32;
+
+ /* Disable Root's interrupt in response to error messages */
+ pci_read_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, &reg32);
+ reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
+ pci_write_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, reg32);
+}
+
/**
* aer_enable_rootport - enable Root Port's interrupts when receiving messages
* @rpc: pointer to a Root Port data structure
@@ -1242,10 +1264,7 @@ static void aer_enable_rootport(struct aer_rpc *rpc)
pci_read_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS, &reg32);
pci_write_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS, reg32);
- /* Enable Root Port's interrupt in response to error messages */
- pci_read_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, &reg32);
- reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
- pci_write_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, reg32);
+ aer_enable_irq(pdev);
}
/**
@@ -1260,10 +1279,7 @@ static void aer_disable_rootport(struct aer_rpc *rpc)
int aer = pdev->aer_cap;
u32 reg32;
- /* Disable Root's interrupt in response to error messages */
- pci_read_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, &reg32);
- reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
- pci_write_config_dword(pdev, aer + PCI_ERR_ROOT_COMMAND, reg32);
+ aer_disable_irq(pdev);
/* Clear Root's error status reg */
pci_read_config_dword(pdev, aer + PCI_ERR_ROOT_STATUS, &reg32);
@@ -1358,12 +1374,8 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
*/
aer = root ? root->aer_cap : 0;
- if ((host->native_aer || pcie_ports_native) && aer) {
- /* Disable Root's interrupt in response to error messages */
- pci_read_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, &reg32);
- reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
- pci_write_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, reg32);
- }
+ if ((host->native_aer || pcie_ports_native) && aer)
+ aer_disable_irq(root);
if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) {
rc = pcie_reset_flr(dev, PCI_RESET_DO_RESET);
@@ -1382,10 +1394,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
pci_read_config_dword(root, aer + PCI_ERR_ROOT_STATUS, &reg32);
pci_write_config_dword(root, aer + PCI_ERR_ROOT_STATUS, reg32);
- /* Enable Root Port's interrupt in response to error messages */
- pci_read_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, &reg32);
- reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
- pci_write_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, reg32);
+ aer_enable_irq(root);
}
return rc ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 1bf630059264..99656d669f00 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -7,7 +7,9 @@
* Copyright (C) Shaohua Li (shaohua.li@intel.com)
*/
+#include <linux/bitfield.h>
#include <linux/kernel.h>
+#include <linux/limits.h>
#include <linux/math.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -16,9 +18,10 @@
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/init.h>
+#include <linux/printk.h>
#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/delay.h>
+#include <linux/time.h>
+
#include "../pci.h"
#ifdef MODULE_PARAM_PREFIX
@@ -267,10 +270,10 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
/* Convert L0s latency encoding to ns */
static u32 calc_l0s_latency(u32 lnkcap)
{
- u32 encoding = (lnkcap & PCI_EXP_LNKCAP_L0SEL) >> 12;
+ u32 encoding = FIELD_GET(PCI_EXP_LNKCAP_L0SEL, lnkcap);
if (encoding == 0x7)
- return (5 * 1000); /* > 4us */
+ return 5 * NSEC_PER_USEC; /* > 4us */
return (64 << encoding);
}
@@ -278,26 +281,26 @@ static u32 calc_l0s_latency(u32 lnkcap)
static u32 calc_l0s_acceptable(u32 encoding)
{
if (encoding == 0x7)
- return -1U;
+ return U32_MAX;
return (64 << encoding);
}
/* Convert L1 latency encoding to ns */
static u32 calc_l1_latency(u32 lnkcap)
{
- u32 encoding = (lnkcap & PCI_EXP_LNKCAP_L1EL) >> 15;
+ u32 encoding = FIELD_GET(PCI_EXP_LNKCAP_L1EL, lnkcap);
if (encoding == 0x7)
- return (65 * 1000); /* > 64us */
- return (1000 << encoding);
+ return 65 * NSEC_PER_USEC; /* > 64us */
+ return NSEC_PER_USEC << encoding;
}
/* Convert L1 acceptable latency encoding to ns */
static u32 calc_l1_acceptable(u32 encoding)
{
if (encoding == 0x7)
- return -1U;
- return (1000 << encoding);
+ return U32_MAX;
+ return NSEC_PER_USEC << encoding;
}
/* Convert L1SS T_pwr encoding to usec */
@@ -325,33 +328,33 @@ static u32 calc_l12_pwron(struct pci_dev *pdev, u32 scale, u32 val)
*/
static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value)
{
- u64 threshold_ns = (u64) threshold_us * 1000;
+ u64 threshold_ns = (u64)threshold_us * NSEC_PER_USEC;
/*
* LTR_L1.2_THRESHOLD_Value ("value") is a 10-bit field with max
* value of 0x3ff.
*/
- if (threshold_ns <= 0x3ff * 1) {
+ if (threshold_ns <= 1 * FIELD_MAX(PCI_L1SS_CTL1_LTR_L12_TH_VALUE)) {
*scale = 0; /* Value times 1ns */
*value = threshold_ns;
- } else if (threshold_ns <= 0x3ff * 32) {
+ } else if (threshold_ns <= 32 * FIELD_MAX(PCI_L1SS_CTL1_LTR_L12_TH_VALUE)) {
*scale = 1; /* Value times 32ns */
*value = roundup(threshold_ns, 32) / 32;
- } else if (threshold_ns <= 0x3ff * 1024) {
+ } else if (threshold_ns <= 1024 * FIELD_MAX(PCI_L1SS_CTL1_LTR_L12_TH_VALUE)) {
*scale = 2; /* Value times 1024ns */
*value = roundup(threshold_ns, 1024) / 1024;
- } else if (threshold_ns <= 0x3ff * 32768) {
+ } else if (threshold_ns <= 32768 * FIELD_MAX(PCI_L1SS_CTL1_LTR_L12_TH_VALUE)) {
*scale = 3; /* Value times 32768ns */
*value = roundup(threshold_ns, 32768) / 32768;
- } else if (threshold_ns <= 0x3ff * 1048576) {
+ } else if (threshold_ns <= 1048576 * FIELD_MAX(PCI_L1SS_CTL1_LTR_L12_TH_VALUE)) {
*scale = 4; /* Value times 1048576ns */
*value = roundup(threshold_ns, 1048576) / 1048576;
- } else if (threshold_ns <= 0x3ff * (u64) 33554432) {
+ } else if (threshold_ns <= (u64)33554432 * FIELD_MAX(PCI_L1SS_CTL1_LTR_L12_TH_VALUE)) {
*scale = 5; /* Value times 33554432ns */
*value = roundup(threshold_ns, 33554432) / 33554432;
} else {
*scale = 5;
- *value = 0x3ff; /* Max representable value */
+ *value = FIELD_MAX(PCI_L1SS_CTL1_LTR_L12_TH_VALUE);
}
}
@@ -371,11 +374,11 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
link = endpoint->bus->self->link_state;
/* Calculate endpoint L0s acceptable latency */
- encoding = (endpoint->devcap & PCI_EXP_DEVCAP_L0S) >> 6;
+ encoding = FIELD_GET(PCI_EXP_DEVCAP_L0S, endpoint->devcap);
acceptable_l0s = calc_l0s_acceptable(encoding);
/* Calculate endpoint L1 acceptable latency */
- encoding = (endpoint->devcap & PCI_EXP_DEVCAP_L1) >> 9;
+ encoding = FIELD_GET(PCI_EXP_DEVCAP_L1, endpoint->devcap);
acceptable_l1 = calc_l1_acceptable(encoding);
while (link) {
@@ -417,7 +420,7 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
if ((link->aspm_capable & ASPM_STATE_L1) &&
(latency + l1_switch_latency > acceptable_l1))
link->aspm_capable &= ~ASPM_STATE_L1;
- l1_switch_latency += 1000;
+ l1_switch_latency += NSEC_PER_USEC;
link = link->parent;
}
@@ -446,22 +449,24 @@ static void aspm_calc_l12_info(struct pcie_link_state *link,
u32 pl1_2_enables, cl1_2_enables;
/* Choose the greater of the two Port Common_Mode_Restore_Times */
- val1 = (parent_l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
- val2 = (child_l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
+ val1 = FIELD_GET(PCI_L1SS_CAP_CM_RESTORE_TIME, parent_l1ss_cap);
+ val2 = FIELD_GET(PCI_L1SS_CAP_CM_RESTORE_TIME, child_l1ss_cap);
t_common_mode = max(val1, val2);
/* Choose the greater of the two Port T_POWER_ON times */
- val1 = (parent_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
- scale1 = (parent_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
- val2 = (child_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
- scale2 = (child_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
+ val1 = FIELD_GET(PCI_L1SS_CAP_P_PWR_ON_VALUE, parent_l1ss_cap);
+ scale1 = FIELD_GET(PCI_L1SS_CAP_P_PWR_ON_SCALE, parent_l1ss_cap);
+ val2 = FIELD_GET(PCI_L1SS_CAP_P_PWR_ON_VALUE, child_l1ss_cap);
+ scale2 = FIELD_GET(PCI_L1SS_CAP_P_PWR_ON_SCALE, child_l1ss_cap);
if (calc_l12_pwron(parent, scale1, val1) >
calc_l12_pwron(child, scale2, val2)) {
- ctl2 |= scale1 | (val1 << 3);
+ ctl2 |= FIELD_PREP(PCI_L1SS_CTL2_T_PWR_ON_SCALE, scale1) |
+ FIELD_PREP(PCI_L1SS_CTL2_T_PWR_ON_VALUE, val1);
t_power_on = calc_l12_pwron(parent, scale1, val1);
} else {
- ctl2 |= scale2 | (val2 << 3);
+ ctl2 |= FIELD_PREP(PCI_L1SS_CTL2_T_PWR_ON_SCALE, scale2) |
+ FIELD_PREP(PCI_L1SS_CTL2_T_PWR_ON_VALUE, val2);
t_power_on = calc_l12_pwron(child, scale2, val2);
}
@@ -477,7 +482,9 @@ static void aspm_calc_l12_info(struct pcie_link_state *link,
*/
l1_2_threshold = 2 + 4 + t_common_mode + t_power_on;
encode_l12_threshold(l1_2_threshold, &scale, &value);
- ctl1 |= t_common_mode << 8 | scale << 29 | value << 16;
+ ctl1 |= FIELD_PREP(PCI_L1SS_CTL1_CM_RESTORE_TIME, t_common_mode) |
+ FIELD_PREP(PCI_L1SS_CTL1_LTR_L12_TH_VALUE, value) |
+ FIELD_PREP(PCI_L1SS_CTL1_LTR_L12_TH_SCALE, scale);
/* Some broken devices only support dword access to L1 SS */
pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, &pctl1);
@@ -1059,7 +1066,8 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
if (state & PCIE_LINK_STATE_L0S)
link->aspm_disable |= ASPM_STATE_L0S;
if (state & PCIE_LINK_STATE_L1)
- link->aspm_disable |= ASPM_STATE_L1;
+ /* L1 PM substates require L1 */
+ link->aspm_disable |= ASPM_STATE_L1 | ASPM_STATE_L1SS;
if (state & PCIE_LINK_STATE_L1_1)
link->aspm_disable |= ASPM_STATE_L1_1;
if (state & PCIE_LINK_STATE_L1_2)
@@ -1247,6 +1255,8 @@ static ssize_t aspm_attr_store_common(struct device *dev,
link->aspm_disable &= ~ASPM_STATE_L1;
} else {
link->aspm_disable |= state;
+ if (state & ASPM_STATE_L1)
+ link->aspm_disable |= ASPM_STATE_L1SS;
}
pcie_config_aspm_link(link, policy_to_aspm_state(link));
@@ -1361,10 +1371,10 @@ static int __init pcie_aspm_disable(char *str)
aspm_policy = POLICY_DEFAULT;
aspm_disabled = 1;
aspm_support_enabled = false;
- printk(KERN_INFO "PCIe ASPM is disabled\n");
+ pr_info("PCIe ASPM is disabled\n");
} else if (!strcmp(str, "force")) {
aspm_force = 1;
- printk(KERN_INFO "PCIe ASPM is forcibly enabled\n");
+ pr_info("PCIe ASPM is forcibly enabled\n");
}
return 1;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index eeec1d6f9023..32b6b5052f2e 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1844,8 +1844,8 @@ static void quirk_jmicron_ata(struct pci_dev *pdev)
/* Update pdev accordingly */
pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr);
- pdev->hdr_type = hdr & 0x7f;
- pdev->multifunction = !!(hdr & 0x80);
+ pdev->hdr_type = hdr & PCI_HEADER_TYPE_MASK;
+ pdev->multifunction = FIELD_GET(PCI_HEADER_TYPE_MFD, hdr);
pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class);
pdev->class = class >> 8;
@@ -5507,6 +5507,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0420, quirk_no_ext_tags);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags);
#ifdef CONFIG_PCI_ATS
+static void quirk_no_ats(struct pci_dev *pdev)
+{
+ pci_info(pdev, "disabling ATS\n");
+ pdev->ats_cap = 0;
+}
+
/*
* Some devices require additional driver setup to enable ATS. Don't use
* ATS for those devices as ATS will be enabled before the driver has had a
@@ -5520,14 +5526,10 @@ static void quirk_amd_harvest_no_ats(struct pci_dev *pdev)
(pdev->subsystem_device == 0xce19 ||
pdev->subsystem_device == 0xcc10 ||
pdev->subsystem_device == 0xcc08))
- goto no_ats;
- else
- return;
+ quirk_no_ats(pdev);
+ } else {
+ quirk_no_ats(pdev);
}
-
-no_ats:
- pci_info(pdev, "disabling ATS\n");
- pdev->ats_cap = 0;
}
/* AMD Stoney platform GPU */
@@ -5550,6 +5552,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_ats);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_ats);
/* AMD Raven platform iGPU */
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats);
+
+/*
+ * Intel IPU E2000 revisions before C0 implement incorrect endianness
+ * in ATS Invalidate Request message body. Disable ATS for those devices.
+ */
+static void quirk_intel_e2000_no_ats(struct pci_dev *pdev)
+{
+ if (pdev->revision < 0x20)
+ quirk_no_ats(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1451, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1452, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1453, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1454, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1455, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats);
#endif /* CONFIG_PCI_ATS */
/* Freescale PCIe doesn't support MSI in RC mode */
@@ -5666,7 +5687,7 @@ static void quirk_nvidia_hda(struct pci_dev *gpu)
/* The GPU becomes a multi-function device when the HDA is enabled */
pci_read_config_byte(gpu, PCI_HEADER_TYPE, &hdr_type);
- gpu->multifunction = !!(hdr_type & 0x80);
+ gpu->multifunction = FIELD_GET(PCI_HEADER_TYPE_MFD, hdr_type);
}
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_BASE_CLASS_DISPLAY, 16, quirk_nvidia_hda);
@@ -6188,3 +6209,15 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5020, of_pci_make_dev_node);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5021, of_pci_make_dev_node);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT, 0x0005, of_pci_make_dev_node);
+
+/*
+ * Devices known to require a longer delay before first config space access
+ * after reset recovery or resume from D3cold:
+ *
+ * VideoPropulsion (aka Genroco) Torrent QN16e MPEG QAM Modulator
+ */
+static void pci_fixup_d3cold_delay_1sec(struct pci_dev *pdev)
+{
+ pdev->d3cold_delay = 1000;
+}
+DECLARE_PCI_FIXUP_FINAL(0x5555, 0x0004, pci_fixup_d3cold_delay_1sec);
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index b4c138a6ec02..53840634fbfc 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -364,6 +364,37 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
EXPORT_SYMBOL(pci_get_class);
/**
+ * pci_get_base_class - searching for a PCI device by matching against the base class code only
+ * @class: search for a PCI device with this base class code
+ * @from: Previous PCI device found in search, or %NULL for new search.
+ *
+ * Iterates through the list of known PCI devices. If a PCI device is found
+ * with a matching base class code, the reference count to the device is
+ * incremented. See pci_match_one_device() to figure out how does this works.
+ * A new search is initiated by passing %NULL as the @from argument.
+ * Otherwise if @from is not %NULL, searches continue from next device on the
+ * global list. The reference count for @from is always decremented if it is
+ * not %NULL.
+ *
+ * Returns:
+ * A pointer to a matched PCI device, %NULL Otherwise.
+ */
+struct pci_dev *pci_get_base_class(unsigned int class, struct pci_dev *from)
+{
+ struct pci_device_id id = {
+ .vendor = PCI_ANY_ID,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class_mask = 0xFF0000,
+ .class = class << 16,
+ };
+
+ return pci_get_dev_by_id(&id, from);
+}
+EXPORT_SYMBOL(pci_get_base_class);
+
+/**
* pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
* @ids: A pointer to a null terminated list of struct pci_device_id structures
* that describe the type of PCI device the caller is trying to find.
diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 5e6b1eb54c64..feca96fc4255 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -764,10 +764,6 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
struct pci_dev *bridge;
u16 cmd;
- /* Only deal with VGA class devices */
- if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
- return false;
-
/* Allocate structure */
vgadev = kzalloc(sizeof(struct vga_device), GFP_KERNEL);
if (vgadev == NULL) {
@@ -1503,6 +1499,10 @@ static int pci_notify(struct notifier_block *nb, unsigned long action,
vgaarb_dbg(dev, "%s\n", __func__);
+ /* Only deal with VGA class devices */
+ if (!pci_is_vga(pdev))
+ return 0;
+
/*
* For now, we're only interested in devices added and removed.
* I didn't test this thing here, so someone needs to double check
@@ -1550,8 +1550,10 @@ static int __init vga_arb_device_init(void)
pdev = NULL;
while ((pdev =
pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
- PCI_ANY_ID, pdev)) != NULL)
- vga_arbiter_add_pci_device(pdev);
+ PCI_ANY_ID, pdev)) != NULL) {
+ if (pci_is_vga(pdev))
+ vga_arbiter_add_pci_device(pdev);
+ }
pr_info("loaded\n");
return rc;