summary refs log tree commit diff
path: root/drivers/nvdimm/region_devs.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2018-12-27 19:54:10 -0800
committerDan Williams <dan.j.williams@intel.com>2018-12-27 19:54:10 -0800
commit4b5f747e82b12b6d8ab815fc259827a615c7f2c3 (patch)
treeec5eb3857bbb776ac521f555978fcb78cc6bd2a8 /drivers/nvdimm/region_devs.c
parent37379cfc661e51607733f266d9f407b4f8aee16b (diff)
parent3d9cbe37c16ffd19eeab6b49a0311bbb999627d8 (diff)
downloadlinux-4b5f747e82b12b6d8ab815fc259827a615c7f2c3.tar.gz
Merge miscellaneous libnvdimm updates for 4.21
* Use common helpers, bitmap_zalloc() and kstrndup(), to replace open
  coded versions.
* Clarify the comments around hotplug vs initial init case for the nfit
  driver.
* Cleanup the libnvdimm init path.
Diffstat (limited to 'drivers/nvdimm/region_devs.c')
-rw-r--r--drivers/nvdimm/region_devs.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index b4d8e4ed3020..e2818f94f292 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -1189,6 +1189,47 @@ int nvdimm_has_cache(struct nd_region *nd_region)
 }
 EXPORT_SYMBOL_GPL(nvdimm_has_cache);
 
+struct conflict_context {
+	struct nd_region *nd_region;
+	resource_size_t start, size;
+};
+
+static int region_conflict(struct device *dev, void *data)
+{
+	struct nd_region *nd_region;
+	struct conflict_context *ctx = data;
+	resource_size_t res_end, region_end, region_start;
+
+	if (!is_memory(dev))
+		return 0;
+
+	nd_region = to_nd_region(dev);
+	if (nd_region == ctx->nd_region)
+		return 0;
+
+	res_end = ctx->start + ctx->size;
+	region_start = nd_region->ndr_start;
+	region_end = region_start + nd_region->ndr_size;
+	if (ctx->start >= region_start && ctx->start < region_end)
+		return -EBUSY;
+	if (res_end > region_start && res_end <= region_end)
+		return -EBUSY;
+	return 0;
+}
+
+int nd_region_conflict(struct nd_region *nd_region, resource_size_t start,
+		resource_size_t size)
+{
+	struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
+	struct conflict_context ctx = {
+		.nd_region = nd_region,
+		.start = start,
+		.size = size,
+	};
+
+	return device_for_each_child(&nvdimm_bus->dev, &ctx, region_conflict);
+}
+
 void __exit nd_region_devs_exit(void)
 {
 	ida_destroy(&region_ida);