aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/cxl/core/pci.c36
-rw-r--r--drivers/cxl/cxl.h10
2 files changed, 46 insertions, 0 deletions
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index d101fdafb07c..3b4bb8d05035 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -5,6 +5,7 @@
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/pci-doe.h>
+#include <linux/aer.h>
#include <cxlpci.h>
#include <cxlmem.h>
#include <cxl.h>
@@ -730,6 +731,38 @@ static bool cxl_handle_endpoint_ras(struct cxl_dev_state *cxlds)
#ifdef CONFIG_PCIEAER_CXL
+static void cxl_dport_map_rch_aer(struct cxl_dport *dport)
+{
+ struct cxl_rcrb_info *ri = &dport->rcrb;
+ void __iomem *dport_aer = NULL;
+ resource_size_t aer_phys;
+ struct device *host;
+
+ if (dport->rch && ri->aer_cap) {
+ host = dport->reg_map.host;
+ aer_phys = ri->aer_cap + ri->base;
+ dport_aer = devm_cxl_iomap_block(host, aer_phys,
+ sizeof(struct aer_capability_regs));
+ }
+
+ dport->regs.dport_aer = dport_aer;
+}
+
+static void cxl_dport_map_regs(struct cxl_dport *dport)
+{
+ struct cxl_register_map *map = &dport->reg_map;
+ struct device *dev = dport->dport_dev;
+
+ if (!map->component_map.ras.valid)
+ dev_dbg(dev, "RAS registers not found\n");
+ else if (cxl_map_component_regs(map, &dport->regs.component,
+ BIT(CXL_CM_CAP_CAP_ID_RAS)))
+ dev_dbg(dev, "Failed to map RAS capability.\n");
+
+ if (dport->rch)
+ cxl_dport_map_rch_aer(dport);
+}
+
void cxl_setup_parent_dport(struct device *host, struct cxl_dport *dport)
{
struct device *dport_dev = dport->dport_dev;
@@ -738,6 +771,9 @@ void cxl_setup_parent_dport(struct device *host, struct cxl_dport *dport)
host_bridge = to_pci_host_bridge(dport_dev);
if (host_bridge->native_cxl_error)
dport->rcrb.aer_cap = cxl_rcrb_to_aer(dport_dev, dport->rcrb.base);
+
+ dport->reg_map.host = host;
+ cxl_dport_map_regs(dport);
}
EXPORT_SYMBOL_NS_GPL(cxl_setup_parent_dport, CXL);
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index cdb2ade6ba29..3b09286d9d52 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -221,6 +221,14 @@ struct cxl_regs {
struct_group_tagged(cxl_pmu_regs, pmu_regs,
void __iomem *pmu;
);
+
+ /*
+ * RCH downstream port specific RAS register
+ * @aer: CXL 3.0 8.2.1.1 RCH Downstream Port RCRB
+ */
+ struct_group_tagged(cxl_rch_regs, rch_regs,
+ void __iomem *dport_aer;
+ );
};
struct cxl_reg_map {
@@ -623,6 +631,7 @@ struct cxl_rcrb_info {
* @rcrb: Data about the Root Complex Register Block layout
* @rch: Indicate whether this dport was enumerated in RCH or VH mode
* @port: reference to cxl_port that contains this downstream port
+ * @regs: Dport parsed register blocks
*/
struct cxl_dport {
struct device *dport_dev;
@@ -631,6 +640,7 @@ struct cxl_dport {
struct cxl_rcrb_info rcrb;
bool rch;
struct cxl_port *port;
+ struct cxl_regs regs;
};
/**