* [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c
@ 2019-08-27 9:49 Krzysztof Wilczynski
2019-08-27 9:49 ` [PATCH 1/3] PCI/ACPI: Rename ACPI Hot Plug structs for Type 0, 1 and 2 from _HPP to _HPX Krzysztof Wilczynski
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Krzysztof Wilczynski @ 2019-08-27 9:49 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Rafael J. Wysocki, Len Brown, linux-pci, linux-acpi, linux-kernel
This series of patches moves the ACPI-specific code currently included
as part of the drivers/pci/probe.c. First, the ACPI Hot Plug structs
for Type 0, 1 and 2, and any relevant variable names, structs, function
names, etc., will have their names changed to reflect that these are
related to _HPX rather than _HPP. Second, all of the ACPI-specific
code will be moved to drivers/pci/pci-acpi.c for better organisation
and to keep ACPI-related code base together. Third, remove the
now obsolete struct hotplug_program_ops from drivers/pci/pci-acpi.c.
Patches should be preferably merged in order as they build upon
one-another.
Related:
https://lore.kernel.org/lkml/20190419220220.GI173520@google.com
https://lore.kernel.org/lkml/20190307213834.5914-3-mr.nuke.me@gmail.com
https://lore.kernel.org/lkml/20190307213834.5914-2-mr.nuke.me@gmail.com
Krzysztof Wilczynski (3):
PCI/ACPI: Rename ACPI Hot Plug structs for Type 0, 1 and 2 from _HPP
to _HPX
PCI/ACPI: Move ACPI-specific Hot Plug programming functions to
pci-acpi.c
PCI/ACPI: Remove unnecessary struct hotplug_program_ops from
pci-acpi.c
drivers/pci/pci-acpi.c | 410 +++++++++++++++++++++++++++++++++---
drivers/pci/pci.h | 9 +
drivers/pci/probe.c | 278 +-----------------------
include/linux/pci_hotplug.h | 100 ---------
4 files changed, 389 insertions(+), 408 deletions(-)
--
2.22.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] PCI/ACPI: Rename ACPI Hot Plug structs for Type 0, 1 and 2 from _HPP to _HPX
2019-08-27 9:49 [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c Krzysztof Wilczynski
@ 2019-08-27 9:49 ` Krzysztof Wilczynski
2019-08-27 9:49 ` [PATCH 2/3] PCI/ACPI: Move ACPI-specific Hot Plug programming functions to pci-acpi.c Krzysztof Wilczynski
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Krzysztof Wilczynski @ 2019-08-27 9:49 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Rafael J. Wysocki, Len Brown, linux-pci, linux-acpi, linux-kernel
The name of the following structs suggests that these are related to the
_HPP record type, whereas these are related to _HPX, not _HPP, that is
the structs hpp_type0, hpp_type1 and hpp_type2.
The struct hpp_type0 denotes an _HPX Type 0 setting record that supersedes
the _HPP setting record type, and has been used interchangeably for _HPP
as per the ACPI specification (see version 6.3, section 6.2.9.1) which
states that it should be applied to PCI, PCI-X and PCI Express devices,
with settings being ignored if they are not applicable. There aren't any
Type 1 and Type 2 setting record types in _HPP, therefore structs hpp_type1
and hpp_type2 are renamed to reflect their relation to _HPX rather than
_HPP.
Any relevant variable names, structs and function names, etc., have been
updated to reflect the name change of the A CPI Hot Plug structs.
Signed-off-by: Krzysztof Wilczynski <kw@linux.com>
---
drivers/pci/pci-acpi.c | 28 +++++++--------
drivers/pci/probe.c | 72 ++++++++++++++++++-------------------
include/linux/pci_hotplug.h | 30 ++++++++--------
3 files changed, 64 insertions(+), 66 deletions(-)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 45049f558860..02addc47edae 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -119,7 +119,7 @@ phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
}
static acpi_status decode_type0_hpx_record(union acpi_object *record,
- struct hpp_type0 *hpx0)
+ struct hpx_type0 *hpx0)
{
int i;
union acpi_object *fields = record->package.elements;
@@ -147,7 +147,7 @@ static acpi_status decode_type0_hpx_record(union acpi_object *record,
}
static acpi_status decode_type1_hpx_record(union acpi_object *record,
- struct hpp_type1 *hpx1)
+ struct hpx_type1 *hpx1)
{
int i;
union acpi_object *fields = record->package.elements;
@@ -174,7 +174,7 @@ static acpi_status decode_type1_hpx_record(union acpi_object *record,
}
static acpi_status decode_type2_hpx_record(union acpi_object *record,
- struct hpp_type2 *hpx2)
+ struct hpx_type2 *hpx2)
{
int i;
union acpi_object *fields = record->package.elements;
@@ -277,9 +277,9 @@ static acpi_status acpi_run_hpx(struct pci_dev *dev, acpi_handle handle,
acpi_status status;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
union acpi_object *package, *record, *fields;
- struct hpp_type0 hpx0;
- struct hpp_type1 hpx1;
- struct hpp_type2 hpx2;
+ struct hpx_type0 hpx0;
+ struct hpx_type1 hpx1;
+ struct hpx_type2 hpx2;
u32 type;
int i;
@@ -353,10 +353,10 @@ static acpi_status acpi_run_hpp(struct pci_dev *dev, acpi_handle handle,
acpi_status status;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *package, *fields;
- struct hpp_type0 hpp0;
+ struct hpx_type0 hpx0;
int i;
- memset(&hpp0, 0, sizeof(hpp0));
+ memset(&hpx0, 0, sizeof(hpx0));
status = acpi_evaluate_object(handle, "_HPP", NULL, &buffer);
if (ACPI_FAILURE(status))
@@ -377,13 +377,13 @@ static acpi_status acpi_run_hpp(struct pci_dev *dev, acpi_handle handle,
}
}
- hpp0.revision = 1;
- hpp0.cache_line_size = fields[0].integer.value;
- hpp0.latency_timer = fields[1].integer.value;
- hpp0.enable_serr = fields[2].integer.value;
- hpp0.enable_perr = fields[3].integer.value;
+ hpx0.revision = 1;
+ hpx0.cache_line_size = fields[0].integer.value;
+ hpx0.latency_timer = fields[1].integer.value;
+ hpx0.enable_serr = fields[2].integer.value;
+ hpx0.enable_perr = fields[3].integer.value;
- hp_ops->program_type0(dev, &hpp0);
+ hp_ops->program_type0(dev, &hpx0);
exit:
kfree(buffer.pointer);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dbeeb385fb9f..33dae8f5e73e 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1915,7 +1915,7 @@ static void pci_configure_mps(struct pci_dev *dev)
p_mps, mps, mpss);
}
-static struct hpp_type0 pci_default_type0 = {
+static struct hpx_type0 pci_default_type0 = {
.revision = 1,
.cache_line_size = 8,
.latency_timer = 0x40,
@@ -1923,44 +1923,44 @@ static struct hpp_type0 pci_default_type0 = {
.enable_perr = 0,
};
-static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
+static void program_hpx_type0(struct pci_dev *dev, struct hpx_type0 *hpx)
{
u16 pci_cmd, pci_bctl;
- if (!hpp)
- hpp = &pci_default_type0;
+ if (!hpx)
+ hpx = &pci_default_type0;
- if (hpp->revision > 1) {
+ if (hpx->revision > 1) {
pci_warn(dev, "PCI settings rev %d not supported; using defaults\n",
- hpp->revision);
- hpp = &pci_default_type0;
+ hpx->revision);
+ hpx = &pci_default_type0;
}
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpx->cache_line_size);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpx->latency_timer);
pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
- if (hpp->enable_serr)
+ if (hpx->enable_serr)
pci_cmd |= PCI_COMMAND_SERR;
- if (hpp->enable_perr)
+ if (hpx->enable_perr)
pci_cmd |= PCI_COMMAND_PARITY;
pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
/* Program bridge control value */
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
- hpp->latency_timer);
+ hpx->latency_timer);
pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
- if (hpp->enable_perr)
+ if (hpx->enable_perr)
pci_bctl |= PCI_BRIDGE_CTL_PARITY;
pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
}
}
-static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
+static void program_hpx_type1(struct pci_dev *dev, struct hpx_type1 *hpx)
{
int pos;
- if (!hpp)
+ if (!hpx)
return;
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
@@ -1985,20 +1985,20 @@ static bool pcie_root_rcb_set(struct pci_dev *dev)
return false;
}
-static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
+static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
{
int pos;
u32 reg32;
- if (!hpp)
+ if (!hpx)
return;
if (!pci_is_pcie(dev))
return;
- if (hpp->revision > 1) {
+ if (hpx->revision > 1) {
pci_warn(dev, "PCIe settings rev %d not supported\n",
- hpp->revision);
+ hpx->revision);
return;
}
@@ -2007,14 +2007,14 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
* those to make sure they're consistent with the rest of the
* platform.
*/
- hpp->pci_exp_devctl_and |= PCI_EXP_DEVCTL_PAYLOAD |
+ hpx->pci_exp_devctl_and |= PCI_EXP_DEVCTL_PAYLOAD |
PCI_EXP_DEVCTL_READRQ;
- hpp->pci_exp_devctl_or &= ~(PCI_EXP_DEVCTL_PAYLOAD |
+ hpx->pci_exp_devctl_or &= ~(PCI_EXP_DEVCTL_PAYLOAD |
PCI_EXP_DEVCTL_READRQ);
/* Initialize Device Control Register */
pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
- ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or);
+ ~hpx->pci_exp_devctl_and, hpx->pci_exp_devctl_or);
/* Initialize Link Control Register */
if (pcie_cap_has_lnkctl(dev)) {
@@ -2023,13 +2023,13 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
* If the Root Port supports Read Completion Boundary of
* 128, set RCB to 128. Otherwise, clear it.
*/
- hpp->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
- hpp->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
+ hpx->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
+ hpx->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
if (pcie_root_rcb_set(dev))
- hpp->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
+ hpx->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
- ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
+ ~hpx->pci_exp_lnkctl_and, hpx->pci_exp_lnkctl_or);
}
/* Find Advanced Error Reporting Enhanced Capability */
@@ -2039,22 +2039,22 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
/* Initialize Uncorrectable Error Mask Register */
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, ®32);
- reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
+ reg32 = (reg32 & hpx->unc_err_mask_and) | hpx->unc_err_mask_or;
pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
/* Initialize Uncorrectable Error Severity Register */
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, ®32);
- reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
+ reg32 = (reg32 & hpx->unc_err_sever_and) | hpx->unc_err_sever_or;
pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
/* Initialize Correctable Error Mask Register */
pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®32);
- reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
+ reg32 = (reg32 & hpx->cor_err_mask_and) | hpx->cor_err_mask_or;
pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
/* Initialize Advanced Error Capabilities and Control Register */
pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32);
- reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
+ reg32 = (reg32 & hpx->adv_err_cap_and) | hpx->adv_err_cap_or;
/* Don't enable ECRC generation or checking if unsupported */
if (!(reg32 & PCI_ERR_CAP_ECRC_GENC))
@@ -2173,15 +2173,15 @@ static void program_hpx_type3_register(struct pci_dev *dev,
pos, orig_value, write_reg);
}
-static void program_hpx_type3(struct pci_dev *dev, struct hpx_type3 *hpx3)
+static void program_hpx_type3(struct pci_dev *dev, struct hpx_type3 *hpx)
{
- if (!hpx3)
+ if (!hpx)
return;
if (!pci_is_pcie(dev))
return;
- program_hpx_type3_register(dev, hpx3);
+ program_hpx_type3_register(dev, hpx);
}
int pci_configure_extended_tags(struct pci_dev *dev, void *ign)
@@ -2365,9 +2365,9 @@ static void pci_configure_serr(struct pci_dev *dev)
static void pci_configure_device(struct pci_dev *dev)
{
static const struct hotplug_program_ops hp_ops = {
- .program_type0 = program_hpp_type0,
- .program_type1 = program_hpp_type1,
- .program_type2 = program_hpp_type2,
+ .program_type0 = program_hpx_type0,
+ .program_type1 = program_hpx_type1,
+ .program_type2 = program_hpx_type2,
.program_type3 = program_hpx_type3,
};
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
index f694eb2ca978..18fc6c7c3249 100644
--- a/include/linux/pci_hotplug.h
+++ b/include/linux/pci_hotplug.h
@@ -86,25 +86,25 @@ void pci_hp_deregister(struct hotplug_slot *slot);
#define pci_hp_initialize(slot, bus, nr, name) \
__pci_hp_initialize(slot, bus, nr, name, THIS_MODULE, KBUILD_MODNAME)
-/* PCI Setting Record (Type 0) */
-struct hpp_type0 {
- u32 revision;
- u8 cache_line_size;
- u8 latency_timer;
+/* _HPX PCI Setting Record (Type 0) */
+struct hpx_type0 {
+ u32 revision; /* Not present in _HPP */
+ u8 cache_line_size; /* Not applicable to PCI Express */
+ u8 latency_timer; /* Not applicable to PCI Express */
u8 enable_serr;
u8 enable_perr;
};
-/* PCI-X Setting Record (Type 1) */
-struct hpp_type1 {
+/* _HPX PCI-X Setting Record (Type 1) */
+struct hpx_type1 {
u32 revision;
u8 max_mem_read;
u8 avg_max_split;
u16 tot_max_split;
};
-/* PCI Express Setting Record (Type 2) */
-struct hpp_type2 {
+/* _HPX PCI Express Setting Record (Type 2) */
+struct hpx_type2 {
u32 revision;
u32 unc_err_mask_and;
u32 unc_err_mask_or;
@@ -124,9 +124,7 @@ struct hpp_type2 {
u32 sec_unc_err_mask_or;
};
-/*
- * _HPX PCI Express Setting Record (Type 3)
- */
+/* _HPX PCI Express Setting Record (Type 3) */
struct hpx_type3 {
u16 device_type;
u16 function_type;
@@ -145,10 +143,10 @@ struct hpx_type3 {
};
struct hotplug_program_ops {
- void (*program_type0)(struct pci_dev *dev, struct hpp_type0 *hpp);
- void (*program_type1)(struct pci_dev *dev, struct hpp_type1 *hpp);
- void (*program_type2)(struct pci_dev *dev, struct hpp_type2 *hpp);
- void (*program_type3)(struct pci_dev *dev, struct hpx_type3 *hpp);
+ void (*program_type0)(struct pci_dev *dev, struct hpx_type0 *hpx);
+ void (*program_type1)(struct pci_dev *dev, struct hpx_type1 *hpx);
+ void (*program_type2)(struct pci_dev *dev, struct hpx_type2 *hpx);
+ void (*program_type3)(struct pci_dev *dev, struct hpx_type3 *hpx);
};
enum hpx_type3_dev_type {
--
2.22.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] PCI/ACPI: Move ACPI-specific Hot Plug programming functions to pci-acpi.c
2019-08-27 9:49 [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c Krzysztof Wilczynski
2019-08-27 9:49 ` [PATCH 1/3] PCI/ACPI: Rename ACPI Hot Plug structs for Type 0, 1 and 2 from _HPP to _HPX Krzysztof Wilczynski
@ 2019-08-27 9:49 ` Krzysztof Wilczynski
2019-08-27 9:49 ` [PATCH 3/3] PCI/ACPI: Remove unnecessary struct hotplug_program_ops from pci-acpi.c Krzysztof Wilczynski
2019-08-28 20:33 ` [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c Bjorn Helgaas
3 siblings, 0 replies; 5+ messages in thread
From: Krzysztof Wilczynski @ 2019-08-27 9:49 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Rafael J. Wysocki, Len Brown, linux-pci, linux-acpi, linux-kernel
Move functions program_hpx_type0(), program_hpx_type1(), etc.,
from drivers/pci/probe.c to drivers/pci/pci-acpi.c, and enums
hpx_type3_dev_type, hpx_type3_fn_type and hpx_type3_cfg_loc to
drivers/pci/pci-acpi.c as these functions and enums are
ACPI-specific.
Then move structs hpx_type0, hpx_type1, hpx_type2 and hpx_type3 to
drivers/pci/pci.h as these are shared between drivers/pci/pci-acpi.c
and drivers/pci/probe.c.
Signed-off-by: Krzysztof Wilczynski <kw@linux.com>
---
drivers/pci/pci-acpi.c | 296 ++++++++++++++++++++++++++++++++++++
drivers/pci/pci.h | 79 ++++++++++
drivers/pci/probe.c | 269 --------------------------------
include/linux/pci_hotplug.h | 100 ------------
4 files changed, 375 insertions(+), 369 deletions(-)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 02addc47edae..0bfabb3f9931 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -118,6 +118,47 @@ phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
return (phys_addr_t)mcfg_addr;
}
+static struct hpx_type0 pci_default_type0 = {
+ .revision = 1,
+ .cache_line_size = 8,
+ .latency_timer = 0x40,
+ .enable_serr = 0,
+ .enable_perr = 0,
+};
+
+void program_hpx_type0(struct pci_dev *dev, struct hpx_type0 *hpx)
+{
+ u16 pci_cmd, pci_bctl;
+
+ if (!hpx)
+ hpx = &pci_default_type0;
+
+ if (hpx->revision > 1) {
+ pci_warn(dev, "PCI settings rev %d not supported; using defaults\n",
+ hpx->revision);
+ hpx = &pci_default_type0;
+ }
+
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpx->cache_line_size);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpx->latency_timer);
+ pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+ if (hpx->enable_serr)
+ pci_cmd |= PCI_COMMAND_SERR;
+ if (hpx->enable_perr)
+ pci_cmd |= PCI_COMMAND_PARITY;
+ pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+
+ /* Program bridge control value */
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
+ hpx->latency_timer);
+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
+ if (hpx->enable_perr)
+ pci_bctl |= PCI_BRIDGE_CTL_PARITY;
+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
+ }
+}
+
static acpi_status decode_type0_hpx_record(union acpi_object *record,
struct hpx_type0 *hpx0)
{
@@ -146,6 +187,20 @@ static acpi_status decode_type0_hpx_record(union acpi_object *record,
return AE_OK;
}
+void program_hpx_type1(struct pci_dev *dev, struct hpx_type1 *hpx)
+{
+ int pos;
+
+ if (!hpx)
+ return;
+
+ pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+ if (!pos)
+ return;
+
+ pci_warn(dev, "PCI-X settings not supported\n");
+}
+
static acpi_status decode_type1_hpx_record(union acpi_object *record,
struct hpx_type1 *hpx1)
{
@@ -173,6 +228,107 @@ static acpi_status decode_type1_hpx_record(union acpi_object *record,
return AE_OK;
}
+static bool pcie_root_rcb_set(struct pci_dev *dev)
+{
+ struct pci_dev *rp = pcie_find_root_port(dev);
+ u16 lnkctl;
+
+ if (!rp)
+ return false;
+
+ pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &lnkctl);
+ if (lnkctl & PCI_EXP_LNKCTL_RCB)
+ return true;
+
+ return false;
+}
+
+void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
+{
+ int pos;
+ u32 reg32;
+
+ if (!hpx)
+ return;
+
+ if (!pci_is_pcie(dev))
+ return;
+
+ if (hpx->revision > 1) {
+ pci_warn(dev, "PCIe settings rev %d not supported\n",
+ hpx->revision);
+ return;
+ }
+
+ /*
+ * Don't allow _HPX to change MPS or MRRS settings. We manage
+ * those to make sure they're consistent with the rest of the
+ * platform.
+ */
+ hpx->pci_exp_devctl_and |= PCI_EXP_DEVCTL_PAYLOAD |
+ PCI_EXP_DEVCTL_READRQ;
+ hpx->pci_exp_devctl_or &= ~(PCI_EXP_DEVCTL_PAYLOAD |
+ PCI_EXP_DEVCTL_READRQ);
+
+ /* Initialize Device Control Register */
+ pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
+ ~hpx->pci_exp_devctl_and, hpx->pci_exp_devctl_or);
+
+ /* Initialize Link Control Register */
+ if (pcie_cap_has_lnkctl(dev)) {
+
+ /*
+ * If the Root Port supports Read Completion Boundary of
+ * 128, set RCB to 128. Otherwise, clear it.
+ */
+ hpx->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
+ hpx->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
+ if (pcie_root_rcb_set(dev))
+ hpx->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
+
+ pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
+ ~hpx->pci_exp_lnkctl_and, hpx->pci_exp_lnkctl_or);
+ }
+
+ /* Find Advanced Error Reporting Enhanced Capability */
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ if (!pos)
+ return;
+
+ /* Initialize Uncorrectable Error Mask Register */
+ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, ®32);
+ reg32 = (reg32 & hpx->unc_err_mask_and) | hpx->unc_err_mask_or;
+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
+
+ /* Initialize Uncorrectable Error Severity Register */
+ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, ®32);
+ reg32 = (reg32 & hpx->unc_err_sever_and) | hpx->unc_err_sever_or;
+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
+
+ /* Initialize Correctable Error Mask Register */
+ pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®32);
+ reg32 = (reg32 & hpx->cor_err_mask_and) | hpx->cor_err_mask_or;
+ pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
+
+ /* Initialize Advanced Error Capabilities and Control Register */
+ pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32);
+ reg32 = (reg32 & hpx->adv_err_cap_and) | hpx->adv_err_cap_or;
+
+ /* Don't enable ECRC generation or checking if unsupported */
+ if (!(reg32 & PCI_ERR_CAP_ECRC_GENC))
+ reg32 &= ~PCI_ERR_CAP_ECRC_GENE;
+ if (!(reg32 & PCI_ERR_CAP_ECRC_CHKC))
+ reg32 &= ~PCI_ERR_CAP_ECRC_CHKE;
+ pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
+
+ /*
+ * FIXME: The following two registers are not supported yet.
+ *
+ * o Secondary Uncorrectable Error Severity Register
+ * o Secondary Uncorrectable Error Mask Register
+ */
+}
+
static acpi_status decode_type2_hpx_record(union acpi_object *record,
struct hpx_type2 *hpx2)
{
@@ -213,6 +369,146 @@ static acpi_status decode_type2_hpx_record(union acpi_object *record,
return AE_OK;
}
+enum hpx_type3_dev_type {
+ HPX_TYPE_ENDPOINT = BIT(0),
+ HPX_TYPE_LEG_END = BIT(1),
+ HPX_TYPE_RC_END = BIT(2),
+ HPX_TYPE_RC_EC = BIT(3),
+ HPX_TYPE_ROOT_PORT = BIT(4),
+ HPX_TYPE_UPSTREAM = BIT(5),
+ HPX_TYPE_DOWNSTREAM = BIT(6),
+ HPX_TYPE_PCI_BRIDGE = BIT(7),
+ HPX_TYPE_PCIE_BRIDGE = BIT(8),
+};
+
+static u16 hpx3_device_type(struct pci_dev *dev)
+{
+ u16 pcie_type = pci_pcie_type(dev);
+ const int pcie_to_hpx3_type[] = {
+ [PCI_EXP_TYPE_ENDPOINT] = HPX_TYPE_ENDPOINT,
+ [PCI_EXP_TYPE_LEG_END] = HPX_TYPE_LEG_END,
+ [PCI_EXP_TYPE_RC_END] = HPX_TYPE_RC_END,
+ [PCI_EXP_TYPE_RC_EC] = HPX_TYPE_RC_EC,
+ [PCI_EXP_TYPE_ROOT_PORT] = HPX_TYPE_ROOT_PORT,
+ [PCI_EXP_TYPE_UPSTREAM] = HPX_TYPE_UPSTREAM,
+ [PCI_EXP_TYPE_DOWNSTREAM] = HPX_TYPE_DOWNSTREAM,
+ [PCI_EXP_TYPE_PCI_BRIDGE] = HPX_TYPE_PCI_BRIDGE,
+ [PCI_EXP_TYPE_PCIE_BRIDGE] = HPX_TYPE_PCIE_BRIDGE,
+ };
+
+ if (pcie_type >= ARRAY_SIZE(pcie_to_hpx3_type))
+ return 0;
+
+ return pcie_to_hpx3_type[pcie_type];
+}
+
+enum hpx_type3_fn_type {
+ HPX_FN_NORMAL = BIT(0),
+ HPX_FN_SRIOV_PHYS = BIT(1),
+ HPX_FN_SRIOV_VIRT = BIT(2),
+};
+
+static u8 hpx3_function_type(struct pci_dev *dev)
+{
+ if (dev->is_virtfn)
+ return HPX_FN_SRIOV_VIRT;
+ else if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV) > 0)
+ return HPX_FN_SRIOV_PHYS;
+ else
+ return HPX_FN_NORMAL;
+}
+
+static bool hpx3_cap_ver_matches(u8 pcie_cap_id, u8 hpx3_cap_id)
+{
+ u8 cap_ver = hpx3_cap_id & 0xf;
+
+ if ((hpx3_cap_id & BIT(4)) && cap_ver >= pcie_cap_id)
+ return true;
+ else if (cap_ver == pcie_cap_id)
+ return true;
+
+ return false;
+}
+
+enum hpx_type3_cfg_loc {
+ HPX_CFG_PCICFG = 0,
+ HPX_CFG_PCIE_CAP = 1,
+ HPX_CFG_PCIE_CAP_EXT = 2,
+ HPX_CFG_VEND_CAP = 3,
+ HPX_CFG_DVSEC = 4,
+ HPX_CFG_MAX,
+};
+
+static void program_hpx_type3_register(struct pci_dev *dev,
+ const struct hpx_type3 *reg)
+{
+ u32 match_reg, write_reg, header, orig_value;
+ u16 pos;
+
+ if (!(hpx3_device_type(dev) & reg->device_type))
+ return;
+
+ if (!(hpx3_function_type(dev) & reg->function_type))
+ return;
+
+ switch (reg->config_space_location) {
+ case HPX_CFG_PCICFG:
+ pos = 0;
+ break;
+ case HPX_CFG_PCIE_CAP:
+ pos = pci_find_capability(dev, reg->pci_exp_cap_id);
+ if (pos == 0)
+ return;
+
+ break;
+ case HPX_CFG_PCIE_CAP_EXT:
+ pos = pci_find_ext_capability(dev, reg->pci_exp_cap_id);
+ if (pos == 0)
+ return;
+
+ pci_read_config_dword(dev, pos, &header);
+ if (!hpx3_cap_ver_matches(PCI_EXT_CAP_VER(header),
+ reg->pci_exp_cap_ver))
+ return;
+
+ break;
+ case HPX_CFG_VEND_CAP: /* Fall through */
+ case HPX_CFG_DVSEC: /* Fall through */
+ default:
+ pci_warn(dev, "Encountered _HPX type 3 with unsupported config space location");
+ return;
+ }
+
+ pci_read_config_dword(dev, pos + reg->match_offset, &match_reg);
+
+ if ((match_reg & reg->match_mask_and) != reg->match_value)
+ return;
+
+ pci_read_config_dword(dev, pos + reg->reg_offset, &write_reg);
+ orig_value = write_reg;
+ write_reg &= reg->reg_mask_and;
+ write_reg |= reg->reg_mask_or;
+
+ if (orig_value == write_reg)
+ return;
+
+ pci_write_config_dword(dev, pos + reg->reg_offset, write_reg);
+
+ pci_dbg(dev, "Applied _HPX3 at [0x%x]: 0x%08x -> 0x%08x",
+ pos, orig_value, write_reg);
+}
+
+void program_hpx_type3(struct pci_dev *dev, struct hpx_type3 *hpx)
+{
+ if (!hpx)
+ return;
+
+ if (!pci_is_pcie(dev))
+ return;
+
+ program_hpx_type3_register(dev, hpx);
+}
+
static void parse_hpx3_register(struct hpx_type3 *hpx3_reg,
union acpi_object *reg_fields)
{
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -649,4 +649,83 @@ static inline void pci_aer_clear_fatal_status(struct pci_dev *dev) { }
static inline void pci_aer_clear_device_status(struct pci_dev *dev) { }
#endif
+/* _HPX PCI Setting Record (Type 0) */
+struct hpx_type0 {
+ u32 revision; /* Not present in _HPP */
+ u8 cache_line_size; /* Not applicable to PCI Express */
+ u8 latency_timer; /* Not applicable to PCI Express */
+ u8 enable_serr;
+ u8 enable_perr;
+};
+
+/* _HPX PCI-X Setting Record (Type 1) */
+struct hpx_type1 {
+ u32 revision;
+ u8 max_mem_read;
+ u8 avg_max_split;
+ u16 tot_max_split;
+};
+
+/* _HPX PCI Express Setting Record (Type 2) */
+struct hpx_type2 {
+ u32 revision;
+ u32 unc_err_mask_and;
+ u32 unc_err_mask_or;
+ u32 unc_err_sever_and;
+ u32 unc_err_sever_or;
+ u32 cor_err_mask_and;
+ u32 cor_err_mask_or;
+ u32 adv_err_cap_and;
+ u32 adv_err_cap_or;
+ u16 pci_exp_devctl_and;
+ u16 pci_exp_devctl_or;
+ u16 pci_exp_lnkctl_and;
+ u16 pci_exp_lnkctl_or;
+ u32 sec_unc_err_sever_and;
+ u32 sec_unc_err_sever_or;
+ u32 sec_unc_err_mask_and;
+ u32 sec_unc_err_mask_or;
+};
+
+/* _HPX PCI Express Setting Record (Type 3) */
+struct hpx_type3 {
+ u16 device_type;
+ u16 function_type;
+ u16 config_space_location;
+ u16 pci_exp_cap_id;
+ u16 pci_exp_cap_ver;
+ u16 pci_exp_vendor_id;
+ u16 dvsec_id;
+ u16 dvsec_rev;
+ u16 match_offset;
+ u32 match_mask_and;
+ u32 match_value;
+ u16 reg_offset;
+ u32 reg_mask_and;
+ u32 reg_mask_or;
+};
+
+void program_hpx_type0(struct pci_dev *dev, struct hpx_type0 *hpx);
+void program_hpx_type1(struct pci_dev *dev, struct hpx_type1 *hpx);
+void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx);
+void program_hpx_type3(struct pci_dev *dev, struct hpx_type3 *hpx);
+
+struct hotplug_program_ops {
+ void (*program_type0)(struct pci_dev *dev, struct hpx_type0 *hpx);
+ void (*program_type1)(struct pci_dev *dev, struct hpx_type1 *hpx);
+ void (*program_type2)(struct pci_dev *dev, struct hpx_type2 *hpx);
+ void (*program_type3)(struct pci_dev *dev, struct hpx_type3 *hpx);
+};
+
+#ifdef CONFIG_ACPI
+int pci_acpi_program_hp_params(struct pci_dev *dev,
+ const struct hotplug_program_ops *hp_ops);
+#else
+static inline int pci_acpi_program_hp_params(struct pci_dev *dev,
+ const struct hotplug_program_ops *hp_ops)
+{
+ return -ENODEV;
+}
+#endif
+
#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1915,275 +1915,6 @@ static void pci_configure_mps(struct pci_dev *dev)
p_mps, mps, mpss);
}
-static struct hpx_type0 pci_default_type0 = {
- .revision = 1,
- .cache_line_size = 8,
- .latency_timer = 0x40,
- .enable_serr = 0,
- .enable_perr = 0,
-};
-
-static void program_hpx_type0(struct pci_dev *dev, struct hpx_type0 *hpx)
-{
- u16 pci_cmd, pci_bctl;
-
- if (!hpx)
- hpx = &pci_default_type0;
-
- if (hpx->revision > 1) {
- pci_warn(dev, "PCI settings rev %d not supported; using defaults\n",
- hpx->revision);
- hpx = &pci_default_type0;
- }
-
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpx->cache_line_size);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpx->latency_timer);
- pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
- if (hpx->enable_serr)
- pci_cmd |= PCI_COMMAND_SERR;
- if (hpx->enable_perr)
- pci_cmd |= PCI_COMMAND_PARITY;
- pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
-
- /* Program bridge control value */
- if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
- pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
- hpx->latency_timer);
- pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
- if (hpx->enable_perr)
- pci_bctl |= PCI_BRIDGE_CTL_PARITY;
- pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
- }
-}
-
-static void program_hpx_type1(struct pci_dev *dev, struct hpx_type1 *hpx)
-{
- int pos;
-
- if (!hpx)
- return;
-
- pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
- if (!pos)
- return;
-
- pci_warn(dev, "PCI-X settings not supported\n");
-}
-
-static bool pcie_root_rcb_set(struct pci_dev *dev)
-{
- struct pci_dev *rp = pcie_find_root_port(dev);
- u16 lnkctl;
-
- if (!rp)
- return false;
-
- pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &lnkctl);
- if (lnkctl & PCI_EXP_LNKCTL_RCB)
- return true;
-
- return false;
-}
-
-static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
-{
- int pos;
- u32 reg32;
-
- if (!hpx)
- return;
-
- if (!pci_is_pcie(dev))
- return;
-
- if (hpx->revision > 1) {
- pci_warn(dev, "PCIe settings rev %d not supported\n",
- hpx->revision);
- return;
- }
-
- /*
- * Don't allow _HPX to change MPS or MRRS settings. We manage
- * those to make sure they're consistent with the rest of the
- * platform.
- */
- hpx->pci_exp_devctl_and |= PCI_EXP_DEVCTL_PAYLOAD |
- PCI_EXP_DEVCTL_READRQ;
- hpx->pci_exp_devctl_or &= ~(PCI_EXP_DEVCTL_PAYLOAD |
- PCI_EXP_DEVCTL_READRQ);
-
- /* Initialize Device Control Register */
- pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
- ~hpx->pci_exp_devctl_and, hpx->pci_exp_devctl_or);
-
- /* Initialize Link Control Register */
- if (pcie_cap_has_lnkctl(dev)) {
-
- /*
- * If the Root Port supports Read Completion Boundary of
- * 128, set RCB to 128. Otherwise, clear it.
- */
- hpx->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
- hpx->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
- if (pcie_root_rcb_set(dev))
- hpx->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
-
- pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
- ~hpx->pci_exp_lnkctl_and, hpx->pci_exp_lnkctl_or);
- }
-
- /* Find Advanced Error Reporting Enhanced Capability */
- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
- if (!pos)
- return;
-
- /* Initialize Uncorrectable Error Mask Register */
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, ®32);
- reg32 = (reg32 & hpx->unc_err_mask_and) | hpx->unc_err_mask_or;
- pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
-
- /* Initialize Uncorrectable Error Severity Register */
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, ®32);
- reg32 = (reg32 & hpx->unc_err_sever_and) | hpx->unc_err_sever_or;
- pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
-
- /* Initialize Correctable Error Mask Register */
- pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®32);
- reg32 = (reg32 & hpx->cor_err_mask_and) | hpx->cor_err_mask_or;
- pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
-
- /* Initialize Advanced Error Capabilities and Control Register */
- pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32);
- reg32 = (reg32 & hpx->adv_err_cap_and) | hpx->adv_err_cap_or;
-
- /* Don't enable ECRC generation or checking if unsupported */
- if (!(reg32 & PCI_ERR_CAP_ECRC_GENC))
- reg32 &= ~PCI_ERR_CAP_ECRC_GENE;
- if (!(reg32 & PCI_ERR_CAP_ECRC_CHKC))
- reg32 &= ~PCI_ERR_CAP_ECRC_CHKE;
- pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
-
- /*
- * FIXME: The following two registers are not supported yet.
- *
- * o Secondary Uncorrectable Error Severity Register
- * o Secondary Uncorrectable Error Mask Register
- */
-}
-
-static u16 hpx3_device_type(struct pci_dev *dev)
-{
- u16 pcie_type = pci_pcie_type(dev);
- const int pcie_to_hpx3_type[] = {
- [PCI_EXP_TYPE_ENDPOINT] = HPX_TYPE_ENDPOINT,
- [PCI_EXP_TYPE_LEG_END] = HPX_TYPE_LEG_END,
- [PCI_EXP_TYPE_RC_END] = HPX_TYPE_RC_END,
- [PCI_EXP_TYPE_RC_EC] = HPX_TYPE_RC_EC,
- [PCI_EXP_TYPE_ROOT_PORT] = HPX_TYPE_ROOT_PORT,
- [PCI_EXP_TYPE_UPSTREAM] = HPX_TYPE_UPSTREAM,
- [PCI_EXP_TYPE_DOWNSTREAM] = HPX_TYPE_DOWNSTREAM,
- [PCI_EXP_TYPE_PCI_BRIDGE] = HPX_TYPE_PCI_BRIDGE,
- [PCI_EXP_TYPE_PCIE_BRIDGE] = HPX_TYPE_PCIE_BRIDGE,
- };
-
- if (pcie_type >= ARRAY_SIZE(pcie_to_hpx3_type))
- return 0;
-
- return pcie_to_hpx3_type[pcie_type];
-}
-
-static u8 hpx3_function_type(struct pci_dev *dev)
-{
- if (dev->is_virtfn)
- return HPX_FN_SRIOV_VIRT;
- else if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV) > 0)
- return HPX_FN_SRIOV_PHYS;
- else
- return HPX_FN_NORMAL;
-}
-
-static bool hpx3_cap_ver_matches(u8 pcie_cap_id, u8 hpx3_cap_id)
-{
- u8 cap_ver = hpx3_cap_id & 0xf;
-
- if ((hpx3_cap_id & BIT(4)) && cap_ver >= pcie_cap_id)
- return true;
- else if (cap_ver == pcie_cap_id)
- return true;
-
- return false;
-}
-
-static void program_hpx_type3_register(struct pci_dev *dev,
- const struct hpx_type3 *reg)
-{
- u32 match_reg, write_reg, header, orig_value;
- u16 pos;
-
- if (!(hpx3_device_type(dev) & reg->device_type))
- return;
-
- if (!(hpx3_function_type(dev) & reg->function_type))
- return;
-
- switch (reg->config_space_location) {
- case HPX_CFG_PCICFG:
- pos = 0;
- break;
- case HPX_CFG_PCIE_CAP:
- pos = pci_find_capability(dev, reg->pci_exp_cap_id);
- if (pos == 0)
- return;
-
- break;
- case HPX_CFG_PCIE_CAP_EXT:
- pos = pci_find_ext_capability(dev, reg->pci_exp_cap_id);
- if (pos == 0)
- return;
-
- pci_read_config_dword(dev, pos, &header);
- if (!hpx3_cap_ver_matches(PCI_EXT_CAP_VER(header),
- reg->pci_exp_cap_ver))
- return;
-
- break;
- case HPX_CFG_VEND_CAP: /* Fall through */
- case HPX_CFG_DVSEC: /* Fall through */
- default:
- pci_warn(dev, "Encountered _HPX type 3 with unsupported config space location");
- return;
- }
-
- pci_read_config_dword(dev, pos + reg->match_offset, &match_reg);
-
- if ((match_reg & reg->match_mask_and) != reg->match_value)
- return;
-
- pci_read_config_dword(dev, pos + reg->reg_offset, &write_reg);
- orig_value = write_reg;
- write_reg &= reg->reg_mask_and;
- write_reg |= reg->reg_mask_or;
-
- if (orig_value == write_reg)
- return;
-
- pci_write_config_dword(dev, pos + reg->reg_offset, write_reg);
-
- pci_dbg(dev, "Applied _HPX3 at [0x%x]: 0x%08x -> 0x%08x",
- pos, orig_value, write_reg);
-}
-
-static void program_hpx_type3(struct pci_dev *dev, struct hpx_type3 *hpx)
-{
- if (!hpx)
- return;
-
- if (!pci_is_pcie(dev))
- return;
-
- program_hpx_type3_register(dev, hpx);
-}
-
int pci_configure_extended_tags(struct pci_dev *dev, void *ign)
{
struct pci_host_bridge *host;
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
--- a/include/linux/pci_hotplug.h
+++ b/include/linux/pci_hotplug.h
@@ -86,112 +86,14 @@ void pci_hp_deregister(struct hotplug_slot *slot);
#define pci_hp_initialize(slot, bus, nr, name) \
__pci_hp_initialize(slot, bus, nr, name, THIS_MODULE, KBUILD_MODNAME)
-/* _HPX PCI Setting Record (Type 0) */
-struct hpx_type0 {
- u32 revision; /* Not present in _HPP */
- u8 cache_line_size; /* Not applicable to PCI Express */
- u8 latency_timer; /* Not applicable to PCI Express */
- u8 enable_serr;
- u8 enable_perr;
-};
-
-/* _HPX PCI-X Setting Record (Type 1) */
-struct hpx_type1 {
- u32 revision;
- u8 max_mem_read;
- u8 avg_max_split;
- u16 tot_max_split;
-};
-
-/* _HPX PCI Express Setting Record (Type 2) */
-struct hpx_type2 {
- u32 revision;
- u32 unc_err_mask_and;
- u32 unc_err_mask_or;
- u32 unc_err_sever_and;
- u32 unc_err_sever_or;
- u32 cor_err_mask_and;
- u32 cor_err_mask_or;
- u32 adv_err_cap_and;
- u32 adv_err_cap_or;
- u16 pci_exp_devctl_and;
- u16 pci_exp_devctl_or;
- u16 pci_exp_lnkctl_and;
- u16 pci_exp_lnkctl_or;
- u32 sec_unc_err_sever_and;
- u32 sec_unc_err_sever_or;
- u32 sec_unc_err_mask_and;
- u32 sec_unc_err_mask_or;
-};
-
-/* _HPX PCI Express Setting Record (Type 3) */
-struct hpx_type3 {
- u16 device_type;
- u16 function_type;
- u16 config_space_location;
- u16 pci_exp_cap_id;
- u16 pci_exp_cap_ver;
- u16 pci_exp_vendor_id;
- u16 dvsec_id;
- u16 dvsec_rev;
- u16 match_offset;
- u32 match_mask_and;
- u32 match_value;
- u16 reg_offset;
- u32 reg_mask_and;
- u32 reg_mask_or;
-};
-
-struct hotplug_program_ops {
- void (*program_type0)(struct pci_dev *dev, struct hpx_type0 *hpx);
- void (*program_type1)(struct pci_dev *dev, struct hpx_type1 *hpx);
- void (*program_type2)(struct pci_dev *dev, struct hpx_type2 *hpx);
- void (*program_type3)(struct pci_dev *dev, struct hpx_type3 *hpx);
-};
-
-enum hpx_type3_dev_type {
- HPX_TYPE_ENDPOINT = BIT(0),
- HPX_TYPE_LEG_END = BIT(1),
- HPX_TYPE_RC_END = BIT(2),
- HPX_TYPE_RC_EC = BIT(3),
- HPX_TYPE_ROOT_PORT = BIT(4),
- HPX_TYPE_UPSTREAM = BIT(5),
- HPX_TYPE_DOWNSTREAM = BIT(6),
- HPX_TYPE_PCI_BRIDGE = BIT(7),
- HPX_TYPE_PCIE_BRIDGE = BIT(8),
-};
-
-enum hpx_type3_fn_type {
- HPX_FN_NORMAL = BIT(0),
- HPX_FN_SRIOV_PHYS = BIT(1),
- HPX_FN_SRIOV_VIRT = BIT(2),
-};
-
-enum hpx_type3_cfg_loc {
- HPX_CFG_PCICFG = 0,
- HPX_CFG_PCIE_CAP = 1,
- HPX_CFG_PCIE_CAP_EXT = 2,
- HPX_CFG_VEND_CAP = 3,
- HPX_CFG_DVSEC = 4,
- HPX_CFG_MAX,
-};
-
#ifdef CONFIG_ACPI
#include <linux/acpi.h>
-int pci_acpi_program_hp_params(struct pci_dev *dev,
- const struct hotplug_program_ops *hp_ops);
bool pciehp_is_native(struct pci_dev *bridge);
int acpi_get_hp_hw_control_from_firmware(struct pci_dev *bridge);
bool shpchp_is_native(struct pci_dev *bridge);
int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle);
int acpi_pci_detect_ejectable(acpi_handle handle);
#else
-static inline int pci_acpi_program_hp_params(struct pci_dev *dev,
- const struct hotplug_program_ops *hp_ops)
-{
- return -ENODEV;
-}
-
static inline int acpi_get_hp_hw_control_from_firmware(struct pci_dev *bridge)
{
return 0;
--
2.22.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] PCI/ACPI: Remove unnecessary struct hotplug_program_ops from pci-acpi.c
2019-08-27 9:49 [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c Krzysztof Wilczynski
2019-08-27 9:49 ` [PATCH 1/3] PCI/ACPI: Rename ACPI Hot Plug structs for Type 0, 1 and 2 from _HPP to _HPX Krzysztof Wilczynski
2019-08-27 9:49 ` [PATCH 2/3] PCI/ACPI: Move ACPI-specific Hot Plug programming functions to pci-acpi.c Krzysztof Wilczynski
@ 2019-08-27 9:49 ` Krzysztof Wilczynski
2019-08-28 20:33 ` [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c Bjorn Helgaas
3 siblings, 0 replies; 5+ messages in thread
From: Krzysztof Wilczynski @ 2019-08-27 9:49 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Rafael J. Wysocki, Len Brown, linux-pci, linux-acpi, linux-kernel
Move the ACPI-specific structs hpx_type0, hpx_type1, hpx_type2 and
hpx_type3 to drivers/pci/pci-acpi.c as they are not used anywhere
else. Then remove the struct hotplug_program_ops that has been
shared between drivers/pci/probe.c and drivers/pci/pci-acpi.c
from drivers/pci/pci.h as it is no longer needed.
The struct hotplug_program_ops was introduced in the commit 87fcf12e846a
("PCI/ACPI: Remove the need for 'struct hotplug_params'") and replaced
previously used struct hotplug_params enabling the support for the _HPX
Type 3 Setting Record that has been added in the commit f873c51a155a
("PCI/ACPI: Implement _HPX Type 3 Setting Record").
The new struct allowed for the static functions such program_hpx_type0(),
program_hpx_type1(), etc., from the drivers/pci/probe.c to be called from
the function pci_acpi_program_hp_params() in the drivers/pci/pci-acpi.c.
Currently, a programming of _HPX Type 0 would be as follows:
drivers/pci/probe.c:
program_hpx_type0()
...
pci_configure_device()
hp_ops = {
.program_type0 = program_hpx_type0,
...
}
pci_acpi_program_hp_params(&hp_ops)
drivers/pci/pci-acpi.c:
pci_acpi_program_hp_params(&hp_ops)
acpi_run_hpx(hp_ops)
decode_type0_hpx_record()
hp_ops->program_type0 # program_hpx_type0() called via hp_ops
After the ACPI-specific functions, structs, enums, etc., have been
moved to drivers/pci/pci-acpi.c there will be no need to keep using
the struct hotplug_program_ops as all of the _HPX Type 0, 1, 2 and 3
would be directly accessible.
Signed-off-by: Krzysztof Wilczynski <kw@linux.com>
---
drivers/pci/pci-acpi.c | 96 ++++++++++++++++++++++++++++++++----------
drivers/pci/pci.h | 74 +-------------------------------
drivers/pci/probe.c | 9 +---
3 files changed, 77 insertions(+), 102 deletions(-)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 0bfabb3f9931..c476b9ed009e 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -118,6 +118,15 @@ phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
return (phys_addr_t)mcfg_addr;
}
+/* _HPX PCI Setting Record (Type 0) */
+struct hpx_type0 {
+ u32 revision; /* Not present in _HPP */
+ u8 cache_line_size; /* Not applicable to PCI Express */
+ u8 latency_timer; /* Not applicable to PCI Express */
+ u8 enable_serr;
+ u8 enable_perr;
+};
+
static struct hpx_type0 pci_default_type0 = {
.revision = 1,
.cache_line_size = 8,
@@ -126,7 +135,7 @@ static struct hpx_type0 pci_default_type0 = {
.enable_perr = 0,
};
-void program_hpx_type0(struct pci_dev *dev, struct hpx_type0 *hpx)
+static void program_hpx_type0(struct pci_dev *dev, struct hpx_type0 *hpx)
{
u16 pci_cmd, pci_bctl;
@@ -187,7 +196,15 @@ static acpi_status decode_type0_hpx_record(union acpi_object *record,
return AE_OK;
}
-void program_hpx_type1(struct pci_dev *dev, struct hpx_type1 *hpx)
+/* _HPX PCI-X Setting Record (Type 1) */
+struct hpx_type1 {
+ u32 revision;
+ u8 max_mem_read;
+ u8 avg_max_split;
+ u16 tot_max_split;
+};
+
+static void program_hpx_type1(struct pci_dev *dev, struct hpx_type1 *hpx)
{
int pos;
@@ -243,7 +260,28 @@ static bool pcie_root_rcb_set(struct pci_dev *dev)
return false;
}
-void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
+/* _HPX PCI Express Setting Record (Type 2) */
+struct hpx_type2 {
+ u32 revision;
+ u32 unc_err_mask_and;
+ u32 unc_err_mask_or;
+ u32 unc_err_sever_and;
+ u32 unc_err_sever_or;
+ u32 cor_err_mask_and;
+ u32 cor_err_mask_or;
+ u32 adv_err_cap_and;
+ u32 adv_err_cap_or;
+ u16 pci_exp_devctl_and;
+ u16 pci_exp_devctl_or;
+ u16 pci_exp_lnkctl_and;
+ u16 pci_exp_lnkctl_or;
+ u32 sec_unc_err_sever_and;
+ u32 sec_unc_err_sever_or;
+ u32 sec_unc_err_mask_and;
+ u32 sec_unc_err_mask_or;
+};
+
+static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
{
int pos;
u32 reg32;
@@ -369,6 +407,24 @@ static acpi_status decode_type2_hpx_record(union acpi_object *record,
return AE_OK;
}
+/* _HPX PCI Express Setting Record (Type 3) */
+struct hpx_type3 {
+ u16 device_type;
+ u16 function_type;
+ u16 config_space_location;
+ u16 pci_exp_cap_id;
+ u16 pci_exp_cap_ver;
+ u16 pci_exp_vendor_id;
+ u16 dvsec_id;
+ u16 dvsec_rev;
+ u16 match_offset;
+ u32 match_mask_and;
+ u32 match_value;
+ u16 reg_offset;
+ u32 reg_mask_and;
+ u32 reg_mask_or;
+};
+
enum hpx_type3_dev_type {
HPX_TYPE_ENDPOINT = BIT(0),
HPX_TYPE_LEG_END = BIT(1),
@@ -498,7 +554,7 @@ static void program_hpx_type3_register(struct pci_dev *dev,
pos, orig_value, write_reg);
}
-void program_hpx_type3(struct pci_dev *dev, struct hpx_type3 *hpx)
+static void program_hpx_type3(struct pci_dev *dev, struct hpx_type3 *hpx)
{
if (!hpx)
return;
@@ -529,8 +585,7 @@ static void parse_hpx3_register(struct hpx_type3 *hpx3_reg,
}
static acpi_status program_type3_hpx_record(struct pci_dev *dev,
- union acpi_object *record,
- const struct hotplug_program_ops *hp_ops)
+ union acpi_object *record)
{
union acpi_object *fields = record->package.elements;
u32 desc_count, expected_length, revision;
@@ -554,7 +609,7 @@ static acpi_status program_type3_hpx_record(struct pci_dev *dev,
for (i = 0; i < desc_count; i++) {
reg_fields = fields + 3 + i * 14;
parse_hpx3_register(&hpx3, reg_fields);
- hp_ops->program_type3(dev, &hpx3);
+ program_hpx_type3(dev, &hpx3);
}
break;
@@ -567,8 +622,7 @@ static acpi_status program_type3_hpx_record(struct pci_dev *dev,
return AE_OK;
}
-static acpi_status acpi_run_hpx(struct pci_dev *dev, acpi_handle handle,
- const struct hotplug_program_ops *hp_ops)
+static acpi_status acpi_run_hpx(struct pci_dev *dev, acpi_handle handle)
{
acpi_status status;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
@@ -610,24 +664,24 @@ static acpi_status acpi_run_hpx(struct pci_dev *dev, acpi_handle handle,
status = decode_type0_hpx_record(record, &hpx0);
if (ACPI_FAILURE(status))
goto exit;
- hp_ops->program_type0(dev, &hpx0);
+ program_hpx_type0(dev, &hpx0);
break;
case 1:
memset(&hpx1, 0, sizeof(hpx1));
status = decode_type1_hpx_record(record, &hpx1);
if (ACPI_FAILURE(status))
goto exit;
- hp_ops->program_type1(dev, &hpx1);
+ program_hpx_type1(dev, &hpx1);
break;
case 2:
memset(&hpx2, 0, sizeof(hpx2));
status = decode_type2_hpx_record(record, &hpx2);
if (ACPI_FAILURE(status))
goto exit;
- hp_ops->program_type2(dev, &hpx2);
+ program_hpx_type2(dev, &hpx2);
break;
case 3:
- status = program_type3_hpx_record(dev, record, hp_ops);
+ status = program_type3_hpx_record(dev, record);
if (ACPI_FAILURE(status))
goto exit;
break;
@@ -643,8 +697,7 @@ static acpi_status acpi_run_hpx(struct pci_dev *dev, acpi_handle handle,
return status;
}
-static acpi_status acpi_run_hpp(struct pci_dev *dev, acpi_handle handle,
- const struct hotplug_program_ops *hp_ops)
+static acpi_status acpi_run_hpp(struct pci_dev *dev, acpi_handle handle)
{
acpi_status status;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -679,20 +732,18 @@ static acpi_status acpi_run_hpp(struct pci_dev *dev, acpi_handle handle,
hpx0.enable_serr = fields[2].integer.value;
hpx0.enable_perr = fields[3].integer.value;
- hp_ops->program_type0(dev, &hpx0);
+ program_hpx_type0(dev, &hpx0);
exit:
kfree(buffer.pointer);
return status;
}
-/* pci_get_hp_params
+/* pci_acpi_program_hp_params
*
* @dev - the pci_dev for which we want parameters
- * @hpp - allocated by the caller
*/
-int pci_acpi_program_hp_params(struct pci_dev *dev,
- const struct hotplug_program_ops *hp_ops)
+int pci_acpi_program_hp_params(struct pci_dev *dev)
{
acpi_status status;
acpi_handle handle, phandle;
@@ -715,10 +766,10 @@ int pci_acpi_program_hp_params(struct pci_dev *dev,
* this pci dev.
*/
while (handle) {
- status = acpi_run_hpx(dev, handle, hp_ops);
+ status = acpi_run_hpx(dev, handle);
if (ACPI_SUCCESS(status))
return 0;
- status = acpi_run_hpp(dev, handle, hp_ops);
+ status = acpi_run_hpp(dev, handle);
if (ACPI_SUCCESS(status))
return 0;
if (acpi_is_root_bridge(handle))
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -649,80 +649,10 @@ static inline void pci_aer_clear_fatal_status(struct pci_dev *dev) { }
static inline void pci_aer_clear_device_status(struct pci_dev *dev) { }
#endif
-/* _HPX PCI Setting Record (Type 0) */
-struct hpx_type0 {
- u32 revision; /* Not present in _HPP */
- u8 cache_line_size; /* Not applicable to PCI Express */
- u8 latency_timer; /* Not applicable to PCI Express */
- u8 enable_serr;
- u8 enable_perr;
-};
-
-/* _HPX PCI-X Setting Record (Type 1) */
-struct hpx_type1 {
- u32 revision;
- u8 max_mem_read;
- u8 avg_max_split;
- u16 tot_max_split;
-};
-
-/* _HPX PCI Express Setting Record (Type 2) */
-struct hpx_type2 {
- u32 revision;
- u32 unc_err_mask_and;
- u32 unc_err_mask_or;
- u32 unc_err_sever_and;
- u32 unc_err_sever_or;
- u32 cor_err_mask_and;
- u32 cor_err_mask_or;
- u32 adv_err_cap_and;
- u32 adv_err_cap_or;
- u16 pci_exp_devctl_and;
- u16 pci_exp_devctl_or;
- u16 pci_exp_lnkctl_and;
- u16 pci_exp_lnkctl_or;
- u32 sec_unc_err_sever_and;
- u32 sec_unc_err_sever_or;
- u32 sec_unc_err_mask_and;
- u32 sec_unc_err_mask_or;
-};
-
-/* _HPX PCI Express Setting Record (Type 3) */
-struct hpx_type3 {
- u16 device_type;
- u16 function_type;
- u16 config_space_location;
- u16 pci_exp_cap_id;
- u16 pci_exp_cap_ver;
- u16 pci_exp_vendor_id;
- u16 dvsec_id;
- u16 dvsec_rev;
- u16 match_offset;
- u32 match_mask_and;
- u32 match_value;
- u16 reg_offset;
- u32 reg_mask_and;
- u32 reg_mask_or;
-};
-
-void program_hpx_type0(struct pci_dev *dev, struct hpx_type0 *hpx);
-void program_hpx_type1(struct pci_dev *dev, struct hpx_type1 *hpx);
-void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx);
-void program_hpx_type3(struct pci_dev *dev, struct hpx_type3 *hpx);
-
-struct hotplug_program_ops {
- void (*program_type0)(struct pci_dev *dev, struct hpx_type0 *hpx);
- void (*program_type1)(struct pci_dev *dev, struct hpx_type1 *hpx);
- void (*program_type2)(struct pci_dev *dev, struct hpx_type2 *hpx);
- void (*program_type3)(struct pci_dev *dev, struct hpx_type3 *hpx);
-};
-
#ifdef CONFIG_ACPI
-int pci_acpi_program_hp_params(struct pci_dev *dev,
- const struct hotplug_program_ops *hp_ops);
+int pci_acpi_program_hp_params(struct pci_dev *dev);
#else
-static inline int pci_acpi_program_hp_params(struct pci_dev *dev,
- const struct hotplug_program_ops *hp_ops)
+static inline int pci_acpi_program_hp_params(struct pci_dev *dev)
{
return -ENODEV;
}
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2095,13 +2095,6 @@ static void pci_configure_serr(struct pci_dev *dev)
static void pci_configure_device(struct pci_dev *dev)
{
- static const struct hotplug_program_ops hp_ops = {
- .program_type0 = program_hpx_type0,
- .program_type1 = program_hpx_type1,
- .program_type2 = program_hpx_type2,
- .program_type3 = program_hpx_type3,
- };
-
pci_configure_mps(dev);
pci_configure_extended_tags(dev, NULL);
pci_configure_relaxed_ordering(dev);
@@ -2109,7 +2102,7 @@ static void pci_configure_device(struct pci_dev *dev)
pci_configure_eetlp_prefix(dev);
pci_configure_serr(dev);
- pci_acpi_program_hp_params(dev, &hp_ops);
+ pci_acpi_program_hp_params(dev);
}
static void pci_release_capabilities(struct pci_dev *dev)
--
2.22.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c
2019-08-27 9:49 [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c Krzysztof Wilczynski
` (2 preceding siblings ...)
2019-08-27 9:49 ` [PATCH 3/3] PCI/ACPI: Remove unnecessary struct hotplug_program_ops from pci-acpi.c Krzysztof Wilczynski
@ 2019-08-28 20:33 ` Bjorn Helgaas
3 siblings, 0 replies; 5+ messages in thread
From: Bjorn Helgaas @ 2019-08-28 20:33 UTC (permalink / raw)
To: Krzysztof Wilczynski
Cc: Rafael J. Wysocki, Len Brown, linux-pci, linux-acpi, linux-kernel
On Tue, Aug 27, 2019 at 11:49:48AM +0200, Krzysztof Wilczynski wrote:
> This series of patches moves the ACPI-specific code currently included
> as part of the drivers/pci/probe.c. First, the ACPI Hot Plug structs
> for Type 0, 1 and 2, and any relevant variable names, structs, function
> names, etc., will have their names changed to reflect that these are
> related to _HPX rather than _HPP. Second, all of the ACPI-specific
> code will be moved to drivers/pci/pci-acpi.c for better organisation
> and to keep ACPI-related code base together. Third, remove the
> now obsolete struct hotplug_program_ops from drivers/pci/pci-acpi.c.
>
> Patches should be preferably merged in order as they build upon
> one-another.
This is always the case; it's one of the main reasons for grouping
patches into a series.
> Related:
> https://lore.kernel.org/lkml/20190419220220.GI173520@google.com
> https://lore.kernel.org/lkml/20190307213834.5914-3-mr.nuke.me@gmail.com
> https://lore.kernel.org/lkml/20190307213834.5914-2-mr.nuke.me@gmail.com
>
> Krzysztof Wilczynski (3):
> PCI/ACPI: Rename ACPI Hot Plug structs for Type 0, 1 and 2 from _HPP
> to _HPX
> PCI/ACPI: Move ACPI-specific Hot Plug programming functions to
> pci-acpi.c
> PCI/ACPI: Remove unnecessary struct hotplug_program_ops from
> pci-acpi.c
>
> drivers/pci/pci-acpi.c | 410 +++++++++++++++++++++++++++++++++---
> drivers/pci/pci.h | 9 +
> drivers/pci/probe.c | 278 +-----------------------
> include/linux/pci_hotplug.h | 100 ---------
> 4 files changed, 389 insertions(+), 408 deletions(-)
I applied these to pci/enumeration for v5.4, thanks!
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-08-28 20:34 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-27 9:49 [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c Krzysztof Wilczynski
2019-08-27 9:49 ` [PATCH 1/3] PCI/ACPI: Rename ACPI Hot Plug structs for Type 0, 1 and 2 from _HPP to _HPX Krzysztof Wilczynski
2019-08-27 9:49 ` [PATCH 2/3] PCI/ACPI: Move ACPI-specific Hot Plug programming functions to pci-acpi.c Krzysztof Wilczynski
2019-08-27 9:49 ` [PATCH 3/3] PCI/ACPI: Remove unnecessary struct hotplug_program_ops from pci-acpi.c Krzysztof Wilczynski
2019-08-28 20:33 ` [PATCH 0/3] PCI/ACPI: Rename _HPP to _HPX and move of ACPI-specific code from probe.c Bjorn Helgaas
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.