diff options
Diffstat (limited to 'drivers/cxl/core/pmem.c')
-rw-r--r-- | drivers/cxl/core/pmem.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/cxl/core/pmem.c b/drivers/cxl/core/pmem.c index 5032f4c1c69d..36aa5070d902 100644 --- a/drivers/cxl/core/pmem.c +++ b/drivers/cxl/core/pmem.c @@ -49,26 +49,40 @@ struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev) return NULL; return container_of(dev, struct cxl_nvdimm_bridge, dev); } -EXPORT_SYMBOL_GPL(to_cxl_nvdimm_bridge); +EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm_bridge, CXL); -__mock int match_nvdimm_bridge(struct device *dev, const void *data) +bool is_cxl_nvdimm_bridge(struct device *dev) { return dev->type == &cxl_nvdimm_bridge_type; } +EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm_bridge, CXL); -struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_nvdimm *cxl_nvd) +static int match_nvdimm_bridge(struct device *dev, void *data) { + return is_cxl_nvdimm_bridge(dev); +} + +struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct device *start) +{ + struct cxl_port *port = find_cxl_root(start); struct device *dev; - dev = bus_find_device(&cxl_bus_type, NULL, cxl_nvd, match_nvdimm_bridge); + if (!port) + return NULL; + + dev = device_find_child(&port->dev, NULL, match_nvdimm_bridge); + put_device(&port->dev); + if (!dev) return NULL; + return to_cxl_nvdimm_bridge(dev); } -EXPORT_SYMBOL_GPL(cxl_find_nvdimm_bridge); +EXPORT_SYMBOL_NS_GPL(cxl_find_nvdimm_bridge, CXL); -static struct cxl_nvdimm_bridge * -cxl_nvdimm_bridge_alloc(struct cxl_port *port) +static struct lock_class_key cxl_nvdimm_bridge_key; + +static struct cxl_nvdimm_bridge *cxl_nvdimm_bridge_alloc(struct cxl_port *port) { struct cxl_nvdimm_bridge *cxl_nvb; struct device *dev; @@ -87,6 +101,7 @@ cxl_nvdimm_bridge_alloc(struct cxl_port *port) cxl_nvb->port = port; cxl_nvb->state = CXL_NVB_NEW; device_initialize(dev); + lockdep_set_class(&dev->mutex, &cxl_nvdimm_bridge_key); device_set_pm_not_required(dev); dev->parent = &port->dev; dev->bus = &cxl_bus_type; @@ -167,12 +182,13 @@ err: put_device(dev); return ERR_PTR(rc); } -EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm_bridge); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm_bridge, CXL); static void cxl_nvdimm_release(struct device *dev) { struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev); + xa_destroy(&cxl_nvd->pmem_regions); kfree(cxl_nvd); } @@ -191,7 +207,7 @@ bool is_cxl_nvdimm(struct device *dev) { return dev->type == &cxl_nvdimm_type; } -EXPORT_SYMBOL_GPL(is_cxl_nvdimm); +EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm, CXL); struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) { @@ -200,7 +216,9 @@ struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) return NULL; return container_of(dev, struct cxl_nvdimm, dev); } -EXPORT_SYMBOL_GPL(to_cxl_nvdimm); +EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm, CXL); + +static struct lock_class_key cxl_nvdimm_key; static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) { @@ -213,7 +231,9 @@ static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) dev = &cxl_nvd->dev; cxl_nvd->cxlmd = cxlmd; + xa_init(&cxl_nvd->pmem_regions); device_initialize(dev); + lockdep_set_class(&dev->mutex, &cxl_nvdimm_key); device_set_pm_not_required(dev); dev->parent = &cxlmd->dev; dev->bus = &cxl_bus_type; @@ -262,4 +282,4 @@ err: put_device(dev); return rc; } -EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm, CXL); |