aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/core.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2015-04-25 03:56:17 -0400
committerDan Williams <dan.j.williams@intel.com>2015-06-24 21:24:10 -0400
commite6dfb2de47768efe8cc37c9a1863d2aff81440fb (patch)
treea1ad89328d88a37195f23ca9421071fc29e6722f /drivers/nvdimm/core.c
parent45def22c1fab85764646746ce38d45b2f3281fa5 (diff)
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.c33
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 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include "nd-core.h" 19#include "nd-core.h"
20 20
21static LIST_HEAD(nvdimm_bus_list); 21LIST_HEAD(nvdimm_bus_list);
22static DEFINE_MUTEX(nvdimm_bus_list_mutex); 22DEFINE_MUTEX(nvdimm_bus_list_mutex);
23static DEFINE_IDA(nd_ida); 23static DEFINE_IDA(nd_ida);
24 24
25static void nvdimm_bus_release(struct device *dev) 25static void nvdimm_bus_release(struct device *dev)
@@ -48,6 +48,19 @@ struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus)
48} 48}
49EXPORT_SYMBOL_GPL(to_nd_desc); 49EXPORT_SYMBOL_GPL(to_nd_desc);
50 50
51struct nvdimm_bus *walk_to_nvdimm_bus(struct device *nd_dev)
52{
53 struct device *dev;
54
55 for (dev = nd_dev; dev; dev = dev->parent)
56 if (dev->release == nvdimm_bus_release)
57 break;
58 dev_WARN_ONCE(nd_dev, !dev, "invalid dev, not on nd bus\n");
59 if (dev)
60 return to_nvdimm_bus(dev);
61 return NULL;
62}
63
51static const char *nvdimm_bus_provider(struct nvdimm_bus *nvdimm_bus) 64static const char *nvdimm_bus_provider(struct nvdimm_bus *nvdimm_bus)
52{ 65{
53 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc; 66 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
@@ -121,6 +134,21 @@ struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
121} 134}
122EXPORT_SYMBOL_GPL(nvdimm_bus_register); 135EXPORT_SYMBOL_GPL(nvdimm_bus_register);
123 136
137static int child_unregister(struct device *dev, void *data)
138{
139 /*
140 * the singular ndctl class device per bus needs to be
141 * "device_destroy"ed, so skip it here
142 *
143 * i.e. remove classless children
144 */
145 if (dev->class)
146 /* pass */;
147 else
148 device_unregister(dev);
149 return 0;
150}
151
124void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus) 152void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus)
125{ 153{
126 if (!nvdimm_bus) 154 if (!nvdimm_bus)
@@ -130,6 +158,7 @@ void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus)
130 list_del_init(&nvdimm_bus->list); 158 list_del_init(&nvdimm_bus->list);
131 mutex_unlock(&nvdimm_bus_list_mutex); 159 mutex_unlock(&nvdimm_bus_list_mutex);
132 160
161 device_for_each_child(&nvdimm_bus->dev, NULL, child_unregister);
133 nvdimm_bus_destroy_ndctl(nvdimm_bus); 162 nvdimm_bus_destroy_ndctl(nvdimm_bus);
134 163
135 device_unregister(&nvdimm_bus->dev); 164 device_unregister(&nvdimm_bus->dev);