diff options
Diffstat (limited to 'drivers/cxl/port.c')
-rw-r--r-- | drivers/cxl/port.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c index 1049bb5ea496..c23b6164e1c0 100644 --- a/drivers/cxl/port.c +++ b/drivers/cxl/port.c @@ -60,26 +60,38 @@ static int discover_region(struct device *dev, void *root) static int cxl_switch_port_probe(struct cxl_port *port) { struct cxl_hdm *cxlhdm; - int rc; + int rc, nr_dports; - rc = devm_cxl_port_enumerate_dports(port); - if (rc < 0) + nr_dports = devm_cxl_port_enumerate_dports(port); + if (nr_dports < 0) + return nr_dports; + + cxlhdm = devm_cxl_setup_hdm(port, NULL); + rc = devm_cxl_enable_hdm(port, cxlhdm); + if (rc) return rc; - if (rc == 1) - return devm_cxl_add_passthrough_decoder(port); + if (!IS_ERR(cxlhdm)) + return devm_cxl_enumerate_decoders(cxlhdm, NULL); - cxlhdm = devm_cxl_setup_hdm(port, NULL); - if (IS_ERR(cxlhdm)) + if (PTR_ERR(cxlhdm) != -ENODEV) { + dev_err(&port->dev, "Failed to map HDM decoder capability\n"); return PTR_ERR(cxlhdm); + } + + if (nr_dports == 1) { + dev_dbg(&port->dev, "Fallback to passthrough decoder\n"); + return devm_cxl_add_passthrough_decoder(port); + } - return devm_cxl_enumerate_decoders(cxlhdm, NULL); + dev_err(&port->dev, "HDM decoder capability not found\n"); + return -ENXIO; } static int cxl_endpoint_port_probe(struct cxl_port *port) { + struct cxl_endpoint_dvsec_info info = { .port = port }; struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport); - struct cxl_endpoint_dvsec_info info = { 0 }; struct cxl_dev_state *cxlds = cxlmd->cxlds; struct cxl_hdm *cxlhdm; struct cxl_port *root; @@ -105,12 +117,6 @@ static int cxl_endpoint_port_probe(struct cxl_port *port) if (rc) return rc; - rc = cxl_await_media_ready(cxlds); - if (rc) { - dev_err(&port->dev, "Media not active (%d)\n", rc); - return rc; - } - rc = devm_cxl_enumerate_decoders(cxlhdm, &info); if (rc) return rc; @@ -119,7 +125,7 @@ static int cxl_endpoint_port_probe(struct cxl_port *port) * This can't fail in practice as CXL root exit unregisters all * descendant ports and that in turn synchronizes with cxl_port_probe() */ - root = find_cxl_root(&cxlmd->dev); + root = find_cxl_root(port); /* * Now that all endpoint decoders are successfully enumerated, try to |