diff options
author | Dan Williams <dan.j.williams@intel.com> | 2015-04-25 03:56:17 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2015-06-24 21:24:10 -0400 |
commit | e6dfb2de47768efe8cc37c9a1863d2aff81440fb (patch) | |
tree | a1ad89328d88a37195f23ca9421071fc29e6722f /drivers/nvdimm/core.c | |
parent | 45def22c1fab85764646746ce38d45b2f3281fa5 (diff) | |
download | linux-e6dfb2de47768efe8cc37c9a1863d2aff81440fb.tar.bz2 |
libnvdimm, nfit: dimm/memory-devices
Enable nvdimm devices to be registered on a nvdimm_bus. The kernel
assigned device id for nvdimm devicesis dynamic. If userspace needs a
more static identifier it should consult a provider-specific attribute.
In the case where NFIT is the provider, the 'nmemX/nfit/handle' or
'nmemX/nfit/serial' attributes may be used for this purpose.
Cc: Neil Brown <neilb@suse.de>
Cc: <linux-acpi@vger.kernel.org>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Robert Moore <robert.moore@intel.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Toshi Kani <toshi.kani@hp.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/core.c')
-rw-r--r-- | drivers/nvdimm/core.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index fa7ab5ad0318..ef957eb37c90 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -18,8 +18,8 @@ #include <linux/slab.h> #include "nd-core.h" -static LIST_HEAD(nvdimm_bus_list); -static DEFINE_MUTEX(nvdimm_bus_list_mutex); +LIST_HEAD(nvdimm_bus_list); +DEFINE_MUTEX(nvdimm_bus_list_mutex); static DEFINE_IDA(nd_ida); static void nvdimm_bus_release(struct device *dev) @@ -48,6 +48,19 @@ struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus) } EXPORT_SYMBOL_GPL(to_nd_desc); +struct nvdimm_bus *walk_to_nvdimm_bus(struct device *nd_dev) +{ + struct device *dev; + + for (dev = nd_dev; dev; dev = dev->parent) + if (dev->release == nvdimm_bus_release) + break; + dev_WARN_ONCE(nd_dev, !dev, "invalid dev, not on nd bus\n"); + if (dev) + return to_nvdimm_bus(dev); + return NULL; +} + static const char *nvdimm_bus_provider(struct nvdimm_bus *nvdimm_bus) { struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc; @@ -121,6 +134,21 @@ struct nvdimm_bus *nvdimm_bus_register(struct device *parent, } EXPORT_SYMBOL_GPL(nvdimm_bus_register); +static int child_unregister(struct device *dev, void *data) +{ + /* + * the singular ndctl class device per bus needs to be + * "device_destroy"ed, so skip it here + * + * i.e. remove classless children + */ + if (dev->class) + /* pass */; + else + device_unregister(dev); + return 0; +} + void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus) { if (!nvdimm_bus) @@ -130,6 +158,7 @@ void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus) list_del_init(&nvdimm_bus->list); mutex_unlock(&nvdimm_bus_list_mutex); + device_for_each_child(&nvdimm_bus->dev, NULL, child_unregister); nvdimm_bus_destroy_ndctl(nvdimm_bus); device_unregister(&nvdimm_bus->dev); |