summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Lucero <alucerop@amd.com>2026-02-28 20:36:03 +0300
committerDave Jiang <dave.jiang@intel.com>2026-03-17 02:32:21 +0300
commit64584273dfb8a1e5fc7d78094ba22a93c204b44e (patch)
tree956c911347aa60bf6dac2b5d4afb1f2e7ec9e2c6
parent29f0724c4592a5ab9076e1ff6e4e39f0de60cc9e (diff)
downloadlinux-64584273dfb8a1e5fc7d78094ba22a93c204b44e.tar.xz
cxl/region: Factor out interleave granularity setup
Region creation based on Type3 devices can be triggered from user space allowing memory combination through interleaving. In preparation for kernel driven region creation, that is Type2 drivers triggering region creation backed with its advertised CXL memory, factor out a common helper from the user-sysfs region setup for interleave granularity. Signed-off-by: Alejandro Lucero <alucerop@amd.com> Reviewed-by: Gregory Price <gourry@gourry.net> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Tested-by: Gregory Price <gourry@gourry.net> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Link: https://patch.msgid.link/20260228173603.1125109-4-alejandro.lucero-palau@amd.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
-rw-r--r--drivers/cxl/core/region.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 55cbad38ec89..3edb5703d6de 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -559,21 +559,14 @@ static ssize_t interleave_granularity_show(struct device *dev,
return sysfs_emit(buf, "%d\n", p->interleave_granularity);
}
-static ssize_t interleave_granularity_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
+static int set_interleave_granularity(struct cxl_region *cxlr, int val)
{
- struct cxl_region *cxlr = to_cxl_region(dev);
struct cxl_root_decoder *cxlrd = cxlr->cxlrd;
struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
struct cxl_region_params *p = &cxlr->params;
- int rc, val;
+ int rc;
u16 ig;
- rc = kstrtoint(buf, 0, &val);
- if (rc)
- return rc;
-
rc = granularity_to_eig(val, &ig);
if (rc)
return rc;
@@ -589,14 +582,33 @@ static ssize_t interleave_granularity_store(struct device *dev,
if (cxld->interleave_ways > 1 && val != cxld->interleave_granularity)
return -EINVAL;
- ACQUIRE(rwsem_write_kill, rwsem)(&cxl_rwsem.region);
- if ((rc = ACQUIRE_ERR(rwsem_write_kill, &rwsem)))
- return rc;
+ lockdep_assert_held_write(&cxl_rwsem.region);
if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE)
return -EBUSY;
p->interleave_granularity = val;
+ return 0;
+}
+
+static ssize_t interleave_granularity_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct cxl_region *cxlr = to_cxl_region(dev);
+ int rc, val;
+
+ rc = kstrtoint(buf, 0, &val);
+ if (rc)
+ return rc;
+
+ ACQUIRE(rwsem_write_kill, rwsem)(&cxl_rwsem.region);
+ if ((rc = ACQUIRE_ERR(rwsem_write_kill, &rwsem)))
+ return rc;
+
+ rc = set_interleave_granularity(cxlr, val);
+ if (rc)
+ return rc;
return len;
}