summaryrefslogtreecommitdiff
path: root/drivers/cxl/pmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cxl/pmem.c')
-rw-r--r--drivers/cxl/pmem.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
index 9652c3ee41e7..5629289939af 100644
--- a/drivers/cxl/pmem.c
+++ b/drivers/cxl/pmem.c
@@ -16,6 +16,13 @@
*/
static struct workqueue_struct *cxl_pmem_wq;
+static __read_mostly DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX);
+
+static void clear_exclusive(void *cxlm)
+{
+ clear_exclusive_cxl_commands(cxlm, exclusive_cmds);
+}
+
static void unregister_nvdimm(void *nvdimm)
{
nvdimm_delete(nvdimm);
@@ -39,25 +46,37 @@ static struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(void)
static int cxl_nvdimm_probe(struct device *dev)
{
struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev);
+ struct cxl_memdev *cxlmd = cxl_nvd->cxlmd;
+ struct cxl_mem *cxlm = cxlmd->cxlm;
struct cxl_nvdimm_bridge *cxl_nvb;
unsigned long flags = 0;
struct nvdimm *nvdimm;
- int rc = -ENXIO;
+ int rc;
cxl_nvb = cxl_find_nvdimm_bridge();
if (!cxl_nvb)
return -ENXIO;
device_lock(&cxl_nvb->dev);
- if (!cxl_nvb->nvdimm_bus)
+ if (!cxl_nvb->nvdimm_bus) {
+ rc = -ENXIO;
+ goto out;
+ }
+
+ set_exclusive_cxl_commands(cxlm, exclusive_cmds);
+ rc = devm_add_action_or_reset(dev, clear_exclusive, cxlm);
+ if (rc)
goto out;
set_bit(NDD_LABELING, &flags);
nvdimm = nvdimm_create(cxl_nvb->nvdimm_bus, cxl_nvd, NULL, flags, 0, 0,
NULL);
- if (!nvdimm)
+ if (!nvdimm) {
+ rc = -ENOMEM;
goto out;
+ }
+ dev_set_drvdata(dev, nvdimm);
rc = devm_add_action_or_reset(dev, unregister_nvdimm, nvdimm);
out:
device_unlock(&cxl_nvb->dev);
@@ -194,6 +213,10 @@ static __init int cxl_pmem_init(void)
{
int rc;
+ set_bit(CXL_MEM_COMMAND_ID_SET_PARTITION_INFO, exclusive_cmds);
+ set_bit(CXL_MEM_COMMAND_ID_SET_SHUTDOWN_STATE, exclusive_cmds);
+ set_bit(CXL_MEM_COMMAND_ID_SET_LSA, exclusive_cmds);
+
cxl_pmem_wq = alloc_ordered_workqueue("cxl_pmem", 0);
if (!cxl_pmem_wq)
return -ENXIO;