| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- // SPDX-License-Identifier: GPL-2.0
- #include <linux/platform_device.h>
- #include <linux/memregion.h>
- #include <linux/module.h>
- #include <linux/dax.h>
- #include <linux/mm.h>
- static bool nohmem;
- module_param_named(disable, nohmem, bool, 0444);
- static bool platform_initialized;
- static DEFINE_MUTEX(hmem_resource_lock);
- static struct resource hmem_active = {
- .name = "HMEM devices",
- .start = 0,
- .end = -1,
- .flags = IORESOURCE_MEM,
- };
- int walk_hmem_resources(struct device *host, walk_hmem_fn fn)
- {
- struct resource *res;
- int rc = 0;
- mutex_lock(&hmem_resource_lock);
- for (res = hmem_active.child; res; res = res->sibling) {
- rc = fn(host, (int) res->desc, res);
- if (rc)
- break;
- }
- mutex_unlock(&hmem_resource_lock);
- return rc;
- }
- EXPORT_SYMBOL_GPL(walk_hmem_resources);
- static void __hmem_register_resource(int target_nid, struct resource *res)
- {
- struct platform_device *pdev;
- struct resource *new;
- int rc;
- new = __request_region(&hmem_active, res->start, resource_size(res), "",
- 0);
- if (!new) {
- pr_debug("hmem range %pr already active\n", res);
- return;
- }
- new->desc = target_nid;
- if (platform_initialized)
- return;
- pdev = platform_device_alloc("hmem_platform", 0);
- if (!pdev) {
- pr_err_once("failed to register device-dax hmem_platform device\n");
- return;
- }
- rc = platform_device_add(pdev);
- if (rc)
- platform_device_put(pdev);
- else
- platform_initialized = true;
- }
- void hmem_register_resource(int target_nid, struct resource *res)
- {
- if (nohmem)
- return;
- mutex_lock(&hmem_resource_lock);
- __hmem_register_resource(target_nid, res);
- mutex_unlock(&hmem_resource_lock);
- }
- static __init int hmem_register_one(struct resource *res, void *data)
- {
- hmem_register_resource(phys_to_target_node(res->start), res);
- return 0;
- }
- static __init int hmem_init(void)
- {
- walk_iomem_res_desc(IORES_DESC_SOFT_RESERVED,
- IORESOURCE_MEM, 0, -1, NULL, hmem_register_one);
- return 0;
- }
- /*
- * As this is a fallback for address ranges unclaimed by the ACPI HMAT
- * parsing it must be at an initcall level greater than hmat_init().
- */
- device_initcall(hmem_init);
|