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 struct nd_dax
*to_nd_dax(struct device
*dev
)
28 struct nd_dax
*nd_dax
= container_of(dev
, struct nd_dax
, nd_pfn
.dev
);
30 WARN_ON(!is_nd_dax(dev
));
33 EXPORT_SYMBOL(to_nd_dax
);
35 static const struct device_type nd_dax_device_type
= {
37 .release
= nd_dax_release
,
38 .groups
= nd_pfn_attribute_groups
,
41 bool is_nd_dax(struct device
*dev
)
43 return dev
? dev
->type
== &nd_dax_device_type
: false;
45 EXPORT_SYMBOL(is_nd_dax
);
47 static struct nd_dax
*nd_dax_alloc(struct nd_region
*nd_region
)
49 struct nd_pfn
*nd_pfn
;
50 struct nd_dax
*nd_dax
;
53 nd_dax
= kzalloc(sizeof(*nd_dax
), GFP_KERNEL
);
57 nd_pfn
= &nd_dax
->nd_pfn
;
58 nd_pfn
->id
= ida_simple_get(&nd_region
->dax_ida
, 0, 0, GFP_KERNEL
);
65 dev_set_name(dev
, "dax%d.%d", nd_region
->id
, nd_pfn
->id
);
66 dev
->type
= &nd_dax_device_type
;
67 dev
->parent
= &nd_region
->dev
;
72 struct device
*nd_dax_create(struct nd_region
*nd_region
)
74 struct device
*dev
= NULL
;
75 struct nd_dax
*nd_dax
;
77 if (!is_memory(&nd_region
->dev
))
80 nd_dax
= nd_dax_alloc(nd_region
);
82 dev
= nd_pfn_devinit(&nd_dax
->nd_pfn
, NULL
);
83 __nd_device_register(dev
);
87 int nd_dax_probe(struct device
*dev
, struct nd_namespace_common
*ndns
)
90 struct nd_dax
*nd_dax
;
91 struct device
*dax_dev
;
92 struct nd_pfn
*nd_pfn
;
93 struct nd_pfn_sb
*pfn_sb
;
94 struct nd_region
*nd_region
= to_nd_region(ndns
->dev
.parent
);
99 switch (ndns
->claim_class
) {
100 case NVDIMM_CCLASS_NONE
:
101 case NVDIMM_CCLASS_DAX
:
107 nvdimm_bus_lock(&ndns
->dev
);
108 nd_dax
= nd_dax_alloc(nd_region
);
109 nd_pfn
= &nd_dax
->nd_pfn
;
110 dax_dev
= nd_pfn_devinit(nd_pfn
, ndns
);
111 nvdimm_bus_unlock(&ndns
->dev
);
114 pfn_sb
= devm_kmalloc(dev
, sizeof(*pfn_sb
), GFP_KERNEL
);
115 nd_pfn
->pfn_sb
= pfn_sb
;
116 rc
= nd_pfn_validate(nd_pfn
, DAX_SIG
);
117 dev_dbg(dev
, "dax: %s\n", rc
== 0 ? dev_name(dax_dev
) : "<none>");
119 nd_detach_ndns(dax_dev
, &nd_pfn
->ndns
);
122 __nd_device_register(dax_dev
);
126 EXPORT_SYMBOL(nd_dax_probe
);