提交 920bc476 编写于 作者: P Patel, Mayurkumar 提交者: Caspar Zhang

PCI/AER: Save AER Capability for suspend/resume

task #29600094

commit af65d1ad416bc6e069ccb9e649faeda224248f96 upstream.
Backport summary: for 4.19 kernel ICX PCIe Gen4 support.

Previously we did not save and restore the AER configuration on
suspend/resume, so the configuration may be lost after resume.

Save the AER configuration during suspend and restore it during resume.

[bhelgaas: commit log]
Link: https://lore.kernel.org/r/92EBB4272BF81E4089A7126EC1E7B28492C3B007@IRSMSX101.ger.corp.intel.comSigned-off-by: NMayurkumar Patel <mayurkumar.patel@intel.com>
Signed-off-by: NKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>

(cherry picked from commit af65d1ad416bc6e069ccb9e649faeda224248f96)
Signed-off-by: NEthan Zhao <haifeng.zhao@intel.com>
Signed-off-by: NArtie Ding <artie.ding@linux.alibaba.com>
Acked-by: NCaspar Zhang <caspar@linux.alibaba.com>
上级 9a20a746
......@@ -355,7 +355,7 @@ static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT;
}
static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev)
bool pcie_cap_has_rtctl(const struct pci_dev *dev)
{
int type = pci_pcie_type(dev);
......
......@@ -1324,6 +1324,7 @@ int pci_save_state(struct pci_dev *dev)
pci_save_ltr_state(dev);
pci_save_dpc_state(dev);
pci_save_aer_state(dev);
return pci_save_vc_state(dev);
}
EXPORT_SYMBOL(pci_save_state);
......@@ -1437,6 +1438,7 @@ void pci_restore_state(struct pci_dev *dev)
pci_restore_dpc_state(dev);
pci_cleanup_aer_error_status_regs(dev);
pci_restore_aer_state(dev);
pci_restore_config_space(dev);
......
......@@ -10,6 +10,7 @@ extern const unsigned char pcie_link_speed[];
extern bool pci_early_dump;
bool pcie_cap_has_lnkctl(const struct pci_dev *dev);
bool pcie_cap_has_rtctl(const struct pci_dev *dev);
/* Functions internal to the PCI core code */
......
......@@ -448,12 +448,70 @@ int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
return 0;
}
void pci_save_aer_state(struct pci_dev *dev)
{
struct pci_cap_saved_state *save_state;
u32 *cap;
int pos;
pos = dev->aer_cap;
if (!pos)
return;
save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_ERR);
if (!save_state)
return;
cap = &save_state->cap.data[0];
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, cap++);
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, cap++);
pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, cap++);
pci_read_config_dword(dev, pos + PCI_ERR_CAP, cap++);
if (pcie_cap_has_rtctl(dev))
pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, cap++);
}
void pci_restore_aer_state(struct pci_dev *dev)
{
struct pci_cap_saved_state *save_state;
u32 *cap;
int pos;
pos = dev->aer_cap;
if (!pos)
return;
save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_ERR);
if (!save_state)
return;
cap = &save_state->cap.data[0];
pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, *cap++);
pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, *cap++);
pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, *cap++);
pci_write_config_dword(dev, pos + PCI_ERR_CAP, *cap++);
if (pcie_cap_has_rtctl(dev))
pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, *cap++);
}
void pci_aer_init(struct pci_dev *dev)
{
int n;
dev->aer_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!dev->aer_cap)
return;
if (dev->aer_cap)
dev->aer_stats = kzalloc(sizeof(struct aer_stats), GFP_KERNEL);
dev->aer_stats = kzalloc(sizeof(struct aer_stats), GFP_KERNEL);
/*
* We save/restore PCI_ERR_UNCOR_MASK, PCI_ERR_UNCOR_SEVER,
* PCI_ERR_COR_MASK, and PCI_ERR_CAP. Root and Root Complex Event
* Collectors also implement PCI_ERR_ROOT_COMMAND (PCIe r5.0, sec
* 7.8.4).
*/
n = pcie_cap_has_rtctl(dev) ? 5 : 4;
pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_ERR, sizeof(u32) * n);
pci_cleanup_aer_error_status_regs(dev);
}
......
......@@ -46,6 +46,8 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev);
int pci_disable_pcie_error_reporting(struct pci_dev *dev);
int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
int pci_cleanup_aer_error_status_regs(struct pci_dev *dev);
void pci_save_aer_state(struct pci_dev *dev);
void pci_restore_aer_state(struct pci_dev *dev);
#else
static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
......@@ -63,6 +65,8 @@ static inline int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
{
return -EINVAL;
}
static inline void pci_save_aer_state(struct pci_dev *dev) {}
static inline void pci_restore_aer_state(struct pci_dev *dev) {}
#endif
void cper_print_aer(struct pci_dev *dev, int aer_severity,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册