2 * Copyright(c) 2013-2016 Intel Corporation. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 #include <linux/device.h>
14 #include <linux/sizes.h>
15 #include <linux/slab.h>
21 static void nd_dax_release(struct device
*dev
)
23 struct nd_region
*nd_region
= to_nd_region(dev
->parent
);
24 struct nd_dax
*nd_dax
= to_nd_dax(dev
);
25 struct nd_pfn
*nd_pfn
= &nd_dax
->nd_pfn
;
27 dev_dbg(dev
, "%s\n", __func__
);
28 nd_detach_ndns(dev
, &nd_pfn
->ndns
);
29 ida_simple_remove(&nd_region
->dax_ida
, nd_pfn
->id
);
34 static struct device_type nd_dax_device_type
= {
36 .release
= nd_dax_release
,
39 bool is_nd_dax(struct device
*dev
)
41 return dev
? dev
->type
== &nd_dax_device_type
: false;
43 EXPORT_SYMBOL(is_nd_dax
);
45 struct nd_dax
*to_nd_dax(struct device
*dev
)
47 struct nd_dax
*nd_dax
= container_of(dev
, struct nd_dax
, nd_pfn
.dev
);
49 WARN_ON(!is_nd_dax(dev
));
52 EXPORT_SYMBOL(to_nd_dax
);
54 static const struct attribute_group
*nd_dax_attribute_groups
[] = {
55 &nd_pfn_attribute_group
,
56 &nd_device_attribute_group
,
57 &nd_numa_attribute_group
,
61 static struct nd_dax
*nd_dax_alloc(struct nd_region
*nd_region
)
63 struct nd_pfn
*nd_pfn
;
64 struct nd_dax
*nd_dax
;
67 nd_dax
= kzalloc(sizeof(*nd_dax
), GFP_KERNEL
);
71 nd_pfn
= &nd_dax
->nd_pfn
;
72 nd_pfn
->id
= ida_simple_get(&nd_region
->dax_ida
, 0, 0, GFP_KERNEL
);
79 dev_set_name(dev
, "dax%d.%d", nd_region
->id
, nd_pfn
->id
);
80 dev
->groups
= nd_dax_attribute_groups
;
81 dev
->type
= &nd_dax_device_type
;
82 dev
->parent
= &nd_region
->dev
;
87 struct device
*nd_dax_create(struct nd_region
*nd_region
)
89 struct device
*dev
= NULL
;
90 struct nd_dax
*nd_dax
;
92 if (!is_memory(&nd_region
->dev
))
95 nd_dax
= nd_dax_alloc(nd_region
);
97 dev
= nd_pfn_devinit(&nd_dax
->nd_pfn
, NULL
);
98 __nd_device_register(dev
);
102 int nd_dax_probe(struct device
*dev
, struct nd_namespace_common
*ndns
)
105 struct nd_dax
*nd_dax
;
106 struct device
*dax_dev
;
107 struct nd_pfn
*nd_pfn
;
108 struct nd_pfn_sb
*pfn_sb
;
109 struct nd_region
*nd_region
= to_nd_region(ndns
->dev
.parent
);
114 switch (ndns
->claim_class
) {
115 case NVDIMM_CCLASS_NONE
:
116 case NVDIMM_CCLASS_DAX
:
122 nvdimm_bus_lock(&ndns
->dev
);
123 nd_dax
= nd_dax_alloc(nd_region
);
124 nd_pfn
= &nd_dax
->nd_pfn
;
125 dax_dev
= nd_pfn_devinit(nd_pfn
, ndns
);
126 nvdimm_bus_unlock(&ndns
->dev
);
129 pfn_sb
= devm_kzalloc(dev
, sizeof(*pfn_sb
), GFP_KERNEL
);
130 nd_pfn
->pfn_sb
= pfn_sb
;
131 rc
= nd_pfn_validate(nd_pfn
, DAX_SIG
);
132 dev_dbg(dev
, "%s: dax: %s\n", __func__
,
133 rc
== 0 ? dev_name(dax_dev
) : "<none>");
135 nd_detach_ndns(dax_dev
, &nd_pfn
->ndns
);
138 __nd_device_register(dax_dev
);
142 EXPORT_SYMBOL(nd_dax_probe
);