1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright(c) 2013-2016 Intel Corporation. All rights reserved.
5 #include <linux/device.h>
6 #include <linux/sizes.h>
7 #include <linux/slab.h>
13 static void nd_dax_release(struct device
*dev
)
15 struct nd_region
*nd_region
= to_nd_region(dev
->parent
);
16 struct nd_dax
*nd_dax
= to_nd_dax(dev
);
17 struct nd_pfn
*nd_pfn
= &nd_dax
->nd_pfn
;
19 dev_dbg(dev
, "trace\n");
20 nd_detach_ndns(dev
, &nd_pfn
->ndns
);
21 ida_simple_remove(&nd_region
->dax_ida
, nd_pfn
->id
);
26 static struct device_type nd_dax_device_type
= {
28 .release
= nd_dax_release
,
31 bool is_nd_dax(struct device
*dev
)
33 return dev
? dev
->type
== &nd_dax_device_type
: false;
35 EXPORT_SYMBOL(is_nd_dax
);
37 struct nd_dax
*to_nd_dax(struct device
*dev
)
39 struct nd_dax
*nd_dax
= container_of(dev
, struct nd_dax
, nd_pfn
.dev
);
41 WARN_ON(!is_nd_dax(dev
));
44 EXPORT_SYMBOL(to_nd_dax
);
46 static const struct attribute_group
*nd_dax_attribute_groups
[] = {
47 &nd_pfn_attribute_group
,
48 &nd_device_attribute_group
,
49 &nd_numa_attribute_group
,
53 static struct nd_dax
*nd_dax_alloc(struct nd_region
*nd_region
)
55 struct nd_pfn
*nd_pfn
;
56 struct nd_dax
*nd_dax
;
59 nd_dax
= kzalloc(sizeof(*nd_dax
), GFP_KERNEL
);
63 nd_pfn
= &nd_dax
->nd_pfn
;
64 nd_pfn
->id
= ida_simple_get(&nd_region
->dax_ida
, 0, 0, GFP_KERNEL
);
71 dev_set_name(dev
, "dax%d.%d", nd_region
->id
, nd_pfn
->id
);
72 dev
->groups
= nd_dax_attribute_groups
;
73 dev
->type
= &nd_dax_device_type
;
74 dev
->parent
= &nd_region
->dev
;
79 struct device
*nd_dax_create(struct nd_region
*nd_region
)
81 struct device
*dev
= NULL
;
82 struct nd_dax
*nd_dax
;
84 if (!is_memory(&nd_region
->dev
))
87 nd_dax
= nd_dax_alloc(nd_region
);
89 dev
= nd_pfn_devinit(&nd_dax
->nd_pfn
, NULL
);
90 __nd_device_register(dev
);
94 int nd_dax_probe(struct device
*dev
, struct nd_namespace_common
*ndns
)
97 struct nd_dax
*nd_dax
;
98 struct device
*dax_dev
;
99 struct nd_pfn
*nd_pfn
;
100 struct nd_pfn_sb
*pfn_sb
;
101 struct nd_region
*nd_region
= to_nd_region(ndns
->dev
.parent
);
106 switch (ndns
->claim_class
) {
107 case NVDIMM_CCLASS_NONE
:
108 case NVDIMM_CCLASS_DAX
:
114 nvdimm_bus_lock(&ndns
->dev
);
115 nd_dax
= nd_dax_alloc(nd_region
);
116 nd_pfn
= &nd_dax
->nd_pfn
;
117 dax_dev
= nd_pfn_devinit(nd_pfn
, ndns
);
118 nvdimm_bus_unlock(&ndns
->dev
);
121 pfn_sb
= devm_kmalloc(dev
, sizeof(*pfn_sb
), GFP_KERNEL
);
122 nd_pfn
->pfn_sb
= pfn_sb
;
123 rc
= nd_pfn_validate(nd_pfn
, DAX_SIG
);
124 dev_dbg(dev
, "dax: %s\n", rc
== 0 ? dev_name(dax_dev
) : "<none>");
126 nd_detach_ndns(dax_dev
, &nd_pfn
->ndns
);
129 __nd_device_register(dax_dev
);
133 EXPORT_SYMBOL(nd_dax_probe
);