@@ -939,8 +939,9 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
return ERR_PTR(-ENOMEM);
if (rcrb != CXL_RESOURCE_NONE) {
- component_reg_phys = cxl_rcrb_to_component(dport_dev,
- rcrb, CXL_RCRB_DOWNSTREAM);
+ component_reg_phys =
+ cxl_probe_rcrb(dport_dev, rcrb, &dport->rcrb,
+ CXL_RCRB_DOWNSTREAM);
if (component_reg_phys == CXL_RESOURCE_NONE) {
dev_warn(dport_dev, "Invalid Component Registers in RCRB");
return ERR_PTR(-ENXIO);
@@ -957,7 +958,6 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
dport->port_id = port_id;
dport->component_reg_phys = component_reg_phys;
dport->port = port;
- dport->rcrb = rcrb;
cond_cxl_root_lock(port);
rc = add_dport(port, dport);
@@ -332,9 +332,8 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
}
EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL);
-resource_size_t cxl_rcrb_to_component(struct device *dev,
- resource_size_t rcrb,
- enum cxl_rcrb which)
+resource_size_t cxl_probe_rcrb(struct device *dev, resource_size_t rcrb,
+ struct cxl_rcrb_info *ri, enum cxl_rcrb which)
{
resource_size_t component_reg_phys;
void __iomem *addr;
@@ -344,6 +343,8 @@ resource_size_t cxl_rcrb_to_component(struct device *dev,
if (which == CXL_RCRB_UPSTREAM)
rcrb += SZ_4K;
+ else if (ri)
+ ri->base = rcrb;
/*
* RCRB's BAR[0..1] point to component block containing CXL
@@ -364,6 +365,7 @@ resource_size_t cxl_rcrb_to_component(struct device *dev,
cmd = readw(addr + PCI_COMMAND);
bar0 = readl(addr + PCI_BASE_ADDRESS_0);
bar1 = readl(addr + PCI_BASE_ADDRESS_1);
+
iounmap(addr);
release_mem_region(rcrb, SZ_4K);
@@ -395,4 +397,4 @@ resource_size_t cxl_rcrb_to_component(struct device *dev,
return component_reg_phys;
}
-EXPORT_SYMBOL_NS_GPL(cxl_rcrb_to_component, CXL);
+EXPORT_SYMBOL_NS_GPL(cxl_probe_rcrb, CXL);
@@ -267,9 +267,9 @@ enum cxl_rcrb {
CXL_RCRB_DOWNSTREAM,
CXL_RCRB_UPSTREAM,
};
-resource_size_t cxl_rcrb_to_component(struct device *dev,
- resource_size_t rcrb,
- enum cxl_rcrb which);
+struct cxl_rcrb_info;
+resource_size_t cxl_probe_rcrb(struct device *dev, resource_size_t rcrb,
+ struct cxl_rcrb_info *ri, enum cxl_rcrb which);
#define CXL_RESOURCE_NONE ((resource_size_t) -1)
#define CXL_TARGET_STRLEN 20
@@ -587,22 +587,27 @@ cxl_find_dport_by_dev(struct cxl_port *port, const struct device *dport_dev)
return xa_load(&port->dports, (unsigned long)dport_dev);
}
+struct cxl_rcrb_info {
+ resource_size_t base;
+ u16 aer_cap;
+};
+
/**
* struct cxl_dport - CXL downstream port
* @dport: PCI bridge or firmware device representing the downstream link
+ * @port: reference to cxl_port that contains this downstream port
* @port_id: unique hardware identifier for dport in decoder target list
* @component_reg_phys: downstream port component registers
- * @rcrb: base address for the Root Complex Register Block
* @rch: Indicate whether this dport was enumerated in RCH or VH mode
- * @port: reference to cxl_port that contains this downstream port
+ * @rcrb: Data about the Root Complex Register Block layout
*/
struct cxl_dport {
struct device *dport;
+ struct cxl_port *port;
int port_id;
resource_size_t component_reg_phys;
- resource_size_t rcrb;
bool rch;
- struct cxl_port *port;
+ struct cxl_rcrb_info rcrb;
};
/**
@@ -72,8 +72,9 @@ static int devm_cxl_add_endpoint(struct device *host, struct cxl_memdev *cxlmd,
* typical register locator mechanism.
*/
if (parent_dport->rch && cxlds->component_reg_phys == CXL_RESOURCE_NONE)
- component_reg_phys = cxl_rcrb_to_component(
- &cxlmd->dev, parent_dport->rcrb, CXL_RCRB_UPSTREAM);
+ component_reg_phys =
+ cxl_probe_rcrb(&cxlmd->dev, parent_dport->rcrb.base,
+ NULL, CXL_RCRB_UPSTREAM);
else
component_reg_phys = cxlds->component_reg_phys;
endpoint = devm_cxl_add_port(host, &cxlmd->dev, component_reg_phys,
@@ -12,7 +12,7 @@ ldflags-y += --wrap=devm_cxl_enumerate_decoders
ldflags-y += --wrap=cxl_await_media_ready
ldflags-y += --wrap=cxl_hdm_decode_init
ldflags-y += --wrap=cxl_dvsec_rr_decode
-ldflags-y += --wrap=cxl_rcrb_to_component
+ldflags-y += --wrap=cxl_probe_rcrb
DRIVERS := ../../../drivers
CXL_SRC := $(DRIVERS)/cxl
@@ -971,12 +971,14 @@ static int mock_cxl_port_enumerate_dports(struct cxl_port *port)
return 0;
}
-resource_size_t mock_cxl_rcrb_to_component(struct device *dev,
- resource_size_t rcrb,
- enum cxl_rcrb which)
+resource_size_t mock_cxl_probe_rcrb(struct device *dev, resource_size_t rcrb,
+ struct cxl_rcrb_info *ri, enum cxl_rcrb which)
{
dev_dbg(dev, "rcrb: %pa which: %d\n", &rcrb, which);
+ if (which == CXL_RCRB_DOWNSTREAM)
+ ri->base = rcrb;
+
return (resource_size_t) which + 1;
}
@@ -988,7 +990,7 @@ static struct cxl_mock_ops cxl_mock_ops = {
.is_mock_dev = is_mock_dev,
.acpi_table_parse_cedt = mock_acpi_table_parse_cedt,
.acpi_evaluate_integer = mock_acpi_evaluate_integer,
- .cxl_rcrb_to_component = mock_cxl_rcrb_to_component,
+ .cxl_probe_rcrb = mock_cxl_probe_rcrb,
.acpi_pci_find_root = mock_acpi_pci_find_root,
.devm_cxl_port_enumerate_dports = mock_cxl_port_enumerate_dports,
.devm_cxl_setup_hdm = mock_cxl_setup_hdm,
@@ -259,9 +259,9 @@ int __wrap_cxl_dvsec_rr_decode(struct device *dev, int dvsec,
}
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dvsec_rr_decode, CXL);
-resource_size_t __wrap_cxl_rcrb_to_component(struct device *dev,
- resource_size_t rcrb,
- enum cxl_rcrb which)
+resource_size_t __wrap_cxl_probe_rcrb(struct device *dev, resource_size_t rcrb,
+ struct cxl_rcrb_info *ri,
+ enum cxl_rcrb which)
{
int index;
resource_size_t component_reg_phys;
@@ -269,14 +269,14 @@ resource_size_t __wrap_cxl_rcrb_to_component(struct device *dev,
if (ops && ops->is_mock_port(dev))
component_reg_phys =
- ops->cxl_rcrb_to_component(dev, rcrb, which);
+ ops->cxl_probe_rcrb(dev, rcrb, ri, which);
else
- component_reg_phys = cxl_rcrb_to_component(dev, rcrb, which);
+ component_reg_phys = cxl_probe_rcrb(dev, rcrb, ri, which);
put_cxl_mock_ops(index);
return component_reg_phys;
}
-EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcrb_to_component, CXL);
+EXPORT_SYMBOL_NS_GPL(__wrap_cxl_probe_rcrb, CXL);
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(ACPI);
@@ -15,9 +15,10 @@ struct cxl_mock_ops {
acpi_string pathname,
struct acpi_object_list *arguments,
unsigned long long *data);
- resource_size_t (*cxl_rcrb_to_component)(struct device *dev,
- resource_size_t rcrb,
- enum cxl_rcrb which);
+ resource_size_t (*cxl_probe_rcrb)(struct device *dev,
+ resource_size_t rcrb,
+ struct cxl_rcrb_info *ri,
+ enum cxl_rcrb which);
struct acpi_pci_root *(*acpi_pci_find_root)(acpi_handle handle);
bool (*is_mock_bus)(struct pci_bus *bus);
bool (*is_mock_port)(struct device *dev);