mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
cxl/pmem: Add support for multiple nvdimm-bridge objects
In preparation for a mocked unit test environment for CXL objects, allow for multiple unique nvdimm-bridge objects. For now, just allow multiple bridges to be registered. Later, when there are multiple present, further updates are needed to cxl_find_nvdimm_bridge() to identify which bridge is associated with which CXL hierarchy for nvdimm registration. Note that this does change the kernel device-name for the bridge object. User space should not have any attachment to the device name at this point as it is still early days in the CXL driver development. Acked-by: Ben Widawsky <ben.widawsky@intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Link: https://lore.kernel.org/r/163164647007.2831228.2150246954620721526.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
60b8f17215
commit
2e52b6256b
@ -2,6 +2,7 @@
|
||||
/* Copyright(c) 2020 Intel Corporation. */
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/idr.h>
|
||||
#include <cxlmem.h>
|
||||
#include <cxl.h>
|
||||
#include "core.h"
|
||||
@ -20,10 +21,13 @@
|
||||
* operations, for example, namespace label access commands.
|
||||
*/
|
||||
|
||||
static DEFINE_IDA(cxl_nvdimm_bridge_ida);
|
||||
|
||||
static void cxl_nvdimm_bridge_release(struct device *dev)
|
||||
{
|
||||
struct cxl_nvdimm_bridge *cxl_nvb = to_cxl_nvdimm_bridge(dev);
|
||||
|
||||
ida_free(&cxl_nvdimm_bridge_ida, cxl_nvb->id);
|
||||
kfree(cxl_nvb);
|
||||
}
|
||||
|
||||
@ -47,16 +51,38 @@ struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(to_cxl_nvdimm_bridge);
|
||||
|
||||
static int match_nvdimm_bridge(struct device *dev, const void *data)
|
||||
{
|
||||
return dev->type == &cxl_nvdimm_bridge_type;
|
||||
}
|
||||
|
||||
struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(void)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = bus_find_device(&cxl_bus_type, NULL, NULL, match_nvdimm_bridge);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
return to_cxl_nvdimm_bridge(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxl_find_nvdimm_bridge);
|
||||
|
||||
static struct cxl_nvdimm_bridge *
|
||||
cxl_nvdimm_bridge_alloc(struct cxl_port *port)
|
||||
{
|
||||
struct cxl_nvdimm_bridge *cxl_nvb;
|
||||
struct device *dev;
|
||||
int rc;
|
||||
|
||||
cxl_nvb = kzalloc(sizeof(*cxl_nvb), GFP_KERNEL);
|
||||
if (!cxl_nvb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
rc = ida_alloc(&cxl_nvdimm_bridge_ida, GFP_KERNEL);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
cxl_nvb->id = rc;
|
||||
|
||||
dev = &cxl_nvb->dev;
|
||||
cxl_nvb->port = port;
|
||||
cxl_nvb->state = CXL_NVB_NEW;
|
||||
@ -67,6 +93,10 @@ cxl_nvdimm_bridge_alloc(struct cxl_port *port)
|
||||
dev->type = &cxl_nvdimm_bridge_type;
|
||||
|
||||
return cxl_nvb;
|
||||
|
||||
err:
|
||||
kfree(cxl_nvb);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
static void unregister_nvb(void *_cxl_nvb)
|
||||
@ -119,7 +149,7 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host,
|
||||
return cxl_nvb;
|
||||
|
||||
dev = &cxl_nvb->dev;
|
||||
rc = dev_set_name(dev, "nvdimm-bridge");
|
||||
rc = dev_set_name(dev, "nvdimm-bridge%d", cxl_nvb->id);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
|
@ -211,6 +211,7 @@ enum cxl_nvdimm_brige_state {
|
||||
};
|
||||
|
||||
struct cxl_nvdimm_bridge {
|
||||
int id;
|
||||
struct device dev;
|
||||
struct cxl_port *port;
|
||||
struct nvdimm_bus *nvdimm_bus;
|
||||
@ -323,4 +324,5 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host,
|
||||
struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev);
|
||||
bool is_cxl_nvdimm(struct device *dev);
|
||||
int devm_cxl_add_nvdimm(struct device *host, struct cxl_memdev *cxlmd);
|
||||
struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(void);
|
||||
#endif /* __CXL_H__ */
|
||||
|
@ -29,21 +29,6 @@ static void unregister_nvdimm(void *nvdimm)
|
||||
nvdimm_delete(nvdimm);
|
||||
}
|
||||
|
||||
static int match_nvdimm_bridge(struct device *dev, const void *data)
|
||||
{
|
||||
return strcmp(dev_name(dev), "nvdimm-bridge") == 0;
|
||||
}
|
||||
|
||||
static struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(void)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = bus_find_device(&cxl_bus_type, NULL, NULL, match_nvdimm_bridge);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
return to_cxl_nvdimm_bridge(dev);
|
||||
}
|
||||
|
||||
static int cxl_nvdimm_probe(struct device *dev)
|
||||
{
|
||||
struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev);
|
||||
|
Loading…
Reference in New Issue
Block a user