Add a new cxl_devdax_region driver that probes CXL regions in device dax mode and creates dax_region devices. This allows explicit binding to the device_dax dax driver instead of the kmem driver.
Exports to_cxl_region() to core.h so it can be used by the driver. Signed-off-by: Gregory Price <[email protected]> --- drivers/cxl/core/core.h | 2 ++ drivers/cxl/core/dax_region.c | 16 ++++++++++++++++ drivers/cxl/core/region.c | 21 +++++++++++++++++---- drivers/cxl/cxl.h | 1 + 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 217dd708a2a6..ea4df8abc2ad 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -46,6 +46,8 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, int devm_cxl_add_dax_region(struct cxl_region *cxlr, enum dax_driver_type); int devm_cxl_add_pmem_region(struct cxl_region *cxlr); +extern struct cxl_driver cxl_devdax_region_driver; + #else static inline u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, u64 dpa) diff --git a/drivers/cxl/core/dax_region.c b/drivers/cxl/core/dax_region.c index 0602db5f7248..391d51e5ec37 100644 --- a/drivers/cxl/core/dax_region.c +++ b/drivers/cxl/core/dax_region.c @@ -111,3 +111,19 @@ int devm_cxl_add_dax_region(struct cxl_region *cxlr, put_device(dev); return rc; } + +static int cxl_devdax_region_driver_probe(struct device *dev) +{ + struct cxl_region *cxlr = to_cxl_region(dev); + + if (cxlr->mode != CXL_PARTMODE_RAM) + return -ENODEV; + + return devm_cxl_add_dax_region(cxlr, DAXDRV_DEVICE_TYPE); +} + +struct cxl_driver cxl_devdax_region_driver = { + .name = "cxl_devdax_region", + .probe = cxl_devdax_region_driver_probe, + .id = CXL_DEVICE_REGION, +}; diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 61ec939c1462..6200ca1cc2dd 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -39,8 +39,6 @@ */ static nodemask_t nodemask_region_seen = NODE_MASK_NONE; -static struct cxl_region *to_cxl_region(struct device *dev); - #define __ACCESS_ATTR_RO(_level, _name) { \ .attr = { .name = __stringify(_name), .mode = 0444 }, \ .show = _name##_access##_level##_show, \ @@ -2430,7 +2428,7 @@ bool is_cxl_region(struct device *dev) } EXPORT_SYMBOL_NS_GPL(is_cxl_region, "CXL"); -static struct cxl_region *to_cxl_region(struct device *dev) +struct cxl_region *to_cxl_region(struct device *dev) { if (dev_WARN_ONCE(dev, dev->type != &cxl_region_type, "not a cxl_region device\n")) @@ -3726,11 +3724,26 @@ static struct cxl_driver cxl_region_driver = { int cxl_region_init(void) { - return cxl_driver_register(&cxl_region_driver); + int rc; + + rc = cxl_driver_register(&cxl_region_driver); + if (rc) + return rc; + + rc = cxl_driver_register(&cxl_devdax_region_driver); + if (rc) + goto err_dax; + + return 0; + +err_dax: + cxl_driver_unregister(&cxl_region_driver); + return rc; } void cxl_region_exit(void) { + cxl_driver_unregister(&cxl_devdax_region_driver); cxl_driver_unregister(&cxl_region_driver); } diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index c06a239c0008..674d5f870c70 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -859,6 +859,7 @@ int cxl_dvsec_rr_decode(struct cxl_dev_state *cxlds, struct cxl_endpoint_dvsec_info *info); bool is_cxl_region(struct device *dev); +struct cxl_region *to_cxl_region(struct device *dev); extern const struct bus_type cxl_bus_type; -- 2.52.0
