-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libnvdimm, e820: make CONFIG_X86_PMEM_LEGACY a tristate option
We currently register a platform device for e820 type-12 memory and register a nvdimm bus beneath it. Registering the platform device triggers the device-core machinery to probe for a driver, but that search currently comes up empty. Building the nvdimm-bus registration into the e820_pmem platform device registration in this way forces libnvdimm to be built-in. Instead, convert the built-in portion of CONFIG_X86_PMEM_LEGACY to simply register a platform device and move the rest of the logic to the driver for e820_pmem, for the following reasons: 1/ Letting e820_pmem support be a module allows building and testing libnvdimm.ko changes without rebooting 2/ All the normal policy around modules can be applied to e820_pmem (unbind to disable and/or blacklisting the module from loading by default) 3/ Moving the driver to a generic location and converting it to scan "iomem_resource" rather than "e820.map" means any other architecture can take advantage of this simple nvdimm resource discovery mechanism by registering a resource named "Persistent Memory (legacy)" Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
- Loading branch information
Dan Williams
committed
Aug 19, 2015
1 parent
6ec6895
commit 7a67832
Showing
7 changed files
with
108 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* Copyright (c) 2015, Christoph Hellwig. | ||
* Copyright (c) 2015, Intel Corporation. | ||
*/ | ||
#include <linux/platform_device.h> | ||
#include <linux/libnvdimm.h> | ||
#include <linux/module.h> | ||
|
||
static const struct attribute_group *e820_pmem_attribute_groups[] = { | ||
&nvdimm_bus_attribute_group, | ||
NULL, | ||
}; | ||
|
||
static const struct attribute_group *e820_pmem_region_attribute_groups[] = { | ||
&nd_region_attribute_group, | ||
&nd_device_attribute_group, | ||
NULL, | ||
}; | ||
|
||
static int e820_pmem_remove(struct platform_device *pdev) | ||
{ | ||
struct nvdimm_bus *nvdimm_bus = platform_get_drvdata(pdev); | ||
|
||
nvdimm_bus_unregister(nvdimm_bus); | ||
return 0; | ||
} | ||
|
||
static int e820_pmem_probe(struct platform_device *pdev) | ||
{ | ||
static struct nvdimm_bus_descriptor nd_desc; | ||
struct device *dev = &pdev->dev; | ||
struct nvdimm_bus *nvdimm_bus; | ||
struct resource *p; | ||
|
||
nd_desc.attr_groups = e820_pmem_attribute_groups; | ||
nd_desc.provider_name = "e820"; | ||
nvdimm_bus = nvdimm_bus_register(dev, &nd_desc); | ||
if (!nvdimm_bus) | ||
goto err; | ||
platform_set_drvdata(pdev, nvdimm_bus); | ||
|
||
for (p = iomem_resource.child; p ; p = p->sibling) { | ||
struct nd_region_desc ndr_desc; | ||
|
||
if (strncmp(p->name, "Persistent Memory (legacy)", 26) != 0) | ||
continue; | ||
|
||
memset(&ndr_desc, 0, sizeof(ndr_desc)); | ||
ndr_desc.res = p; | ||
ndr_desc.attr_groups = e820_pmem_region_attribute_groups; | ||
ndr_desc.numa_node = NUMA_NO_NODE; | ||
if (!nvdimm_pmem_region_create(nvdimm_bus, &ndr_desc)) | ||
goto err; | ||
} | ||
|
||
return 0; | ||
|
||
err: | ||
nvdimm_bus_unregister(nvdimm_bus); | ||
dev_err(dev, "failed to register legacy persistent memory ranges\n"); | ||
return -ENXIO; | ||
} | ||
|
||
static struct platform_driver e820_pmem_driver = { | ||
.probe = e820_pmem_probe, | ||
.remove = e820_pmem_remove, | ||
.driver = { | ||
.name = "e820_pmem", | ||
}, | ||
}; | ||
|
||
static __init int e820_pmem_init(void) | ||
{ | ||
return platform_driver_register(&e820_pmem_driver); | ||
} | ||
|
||
static __exit void e820_pmem_exit(void) | ||
{ | ||
platform_driver_unregister(&e820_pmem_driver); | ||
} | ||
|
||
MODULE_ALIAS("platform:e820_pmem*"); | ||
MODULE_LICENSE("GPL v2"); | ||
MODULE_AUTHOR("Intel Corporation"); | ||
module_init(e820_pmem_init); | ||
module_exit(e820_pmem_exit); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters