diff options
Diffstat (limited to 'drivers/nvdimm/dimm.c')
| -rw-r--r-- | drivers/nvdimm/dimm.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c new file mode 100644 index 000000000000..71d12bb67339 --- /dev/null +++ b/drivers/nvdimm/dimm.c | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /* | ||
| 2 | * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. | ||
| 3 | * | ||
| 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. | ||
| 7 | * | ||
| 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. | ||
| 12 | */ | ||
| 13 | #include <linux/vmalloc.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/sizes.h> | ||
| 17 | #include <linux/ndctl.h> | ||
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/mm.h> | ||
| 20 | #include <linux/nd.h> | ||
| 21 | #include "label.h" | ||
| 22 | #include "nd.h" | ||
| 23 | |||
| 24 | static int nvdimm_probe(struct device *dev) | ||
| 25 | { | ||
| 26 | struct nvdimm_drvdata *ndd; | ||
| 27 | int rc; | ||
| 28 | |||
| 29 | ndd = kzalloc(sizeof(*ndd), GFP_KERNEL); | ||
| 30 | if (!ndd) | ||
| 31 | return -ENOMEM; | ||
| 32 | |||
| 33 | dev_set_drvdata(dev, ndd); | ||
| 34 | ndd->dpa.name = dev_name(dev); | ||
| 35 | ndd->ns_current = -1; | ||
| 36 | ndd->ns_next = -1; | ||
| 37 | ndd->dpa.start = 0; | ||
| 38 | ndd->dpa.end = -1; | ||
| 39 | ndd->dev = dev; | ||
| 40 | get_device(dev); | ||
| 41 | kref_init(&ndd->kref); | ||
| 42 | |||
| 43 | rc = nvdimm_init_nsarea(ndd); | ||
| 44 | if (rc) | ||
| 45 | goto err; | ||
| 46 | |||
| 47 | rc = nvdimm_init_config_data(ndd); | ||
| 48 | if (rc) | ||
| 49 | goto err; | ||
| 50 | |||
| 51 | dev_dbg(dev, "config data size: %d\n", ndd->nsarea.config_size); | ||
| 52 | |||
| 53 | nvdimm_bus_lock(dev); | ||
| 54 | ndd->ns_current = nd_label_validate(ndd); | ||
| 55 | ndd->ns_next = nd_label_next_nsindex(ndd->ns_current); | ||
| 56 | nd_label_copy(ndd, to_next_namespace_index(ndd), | ||
| 57 | to_current_namespace_index(ndd)); | ||
| 58 | rc = nd_label_reserve_dpa(ndd); | ||
| 59 | nvdimm_bus_unlock(dev); | ||
| 60 | |||
| 61 | if (rc) | ||
| 62 | goto err; | ||
| 63 | |||
| 64 | return 0; | ||
| 65 | |||
| 66 | err: | ||
| 67 | put_ndd(ndd); | ||
| 68 | return rc; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int nvdimm_remove(struct device *dev) | ||
| 72 | { | ||
| 73 | struct nvdimm_drvdata *ndd = dev_get_drvdata(dev); | ||
| 74 | |||
| 75 | nvdimm_bus_lock(dev); | ||
| 76 | dev_set_drvdata(dev, NULL); | ||
| 77 | nvdimm_bus_unlock(dev); | ||
| 78 | put_ndd(ndd); | ||
| 79 | |||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | static struct nd_device_driver nvdimm_driver = { | ||
| 84 | .probe = nvdimm_probe, | ||
| 85 | .remove = nvdimm_remove, | ||
| 86 | .drv = { | ||
| 87 | .name = "nvdimm", | ||
| 88 | }, | ||
| 89 | .type = ND_DRIVER_DIMM, | ||
| 90 | }; | ||
| 91 | |||
| 92 | int __init nvdimm_init(void) | ||
| 93 | { | ||
| 94 | return nd_driver_register(&nvdimm_driver); | ||
| 95 | } | ||
| 96 | |||
| 97 | void nvdimm_exit(void) | ||
| 98 | { | ||
| 99 | driver_unregister(&nvdimm_driver.drv); | ||
| 100 | } | ||
| 101 | |||
| 102 | MODULE_ALIAS_ND_DEVICE(ND_DEVICE_DIMM); | ||
