root/drivers/nvdimm/e820.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. e820_pmem_remove
  2. e820_range_to_nid
  3. e820_range_to_nid
  4. e820_register_one
  5. e820_pmem_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2015, Christoph Hellwig.
   4  * Copyright (c) 2015, Intel Corporation.
   5  */
   6 #include <linux/platform_device.h>
   7 #include <linux/memory_hotplug.h>
   8 #include <linux/libnvdimm.h>
   9 #include <linux/module.h>
  10 
  11 static const struct attribute_group *e820_pmem_attribute_groups[] = {
  12         &nvdimm_bus_attribute_group,
  13         NULL,
  14 };
  15 
  16 static const struct attribute_group *e820_pmem_region_attribute_groups[] = {
  17         &nd_region_attribute_group,
  18         &nd_device_attribute_group,
  19         NULL,
  20 };
  21 
  22 static int e820_pmem_remove(struct platform_device *pdev)
  23 {
  24         struct nvdimm_bus *nvdimm_bus = platform_get_drvdata(pdev);
  25 
  26         nvdimm_bus_unregister(nvdimm_bus);
  27         return 0;
  28 }
  29 
  30 #ifdef CONFIG_MEMORY_HOTPLUG
  31 static int e820_range_to_nid(resource_size_t addr)
  32 {
  33         return memory_add_physaddr_to_nid(addr);
  34 }
  35 #else
  36 static int e820_range_to_nid(resource_size_t addr)
  37 {
  38         return NUMA_NO_NODE;
  39 }
  40 #endif
  41 
  42 static int e820_register_one(struct resource *res, void *data)
  43 {
  44         struct nd_region_desc ndr_desc;
  45         struct nvdimm_bus *nvdimm_bus = data;
  46 
  47         memset(&ndr_desc, 0, sizeof(ndr_desc));
  48         ndr_desc.res = res;
  49         ndr_desc.attr_groups = e820_pmem_region_attribute_groups;
  50         ndr_desc.numa_node = e820_range_to_nid(res->start);
  51         ndr_desc.target_node = ndr_desc.numa_node;
  52         set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags);
  53         if (!nvdimm_pmem_region_create(nvdimm_bus, &ndr_desc))
  54                 return -ENXIO;
  55         return 0;
  56 }
  57 
  58 static int e820_pmem_probe(struct platform_device *pdev)
  59 {
  60         static struct nvdimm_bus_descriptor nd_desc;
  61         struct device *dev = &pdev->dev;
  62         struct nvdimm_bus *nvdimm_bus;
  63         int rc = -ENXIO;
  64 
  65         nd_desc.attr_groups = e820_pmem_attribute_groups;
  66         nd_desc.provider_name = "e820";
  67         nd_desc.module = THIS_MODULE;
  68         nvdimm_bus = nvdimm_bus_register(dev, &nd_desc);
  69         if (!nvdimm_bus)
  70                 goto err;
  71         platform_set_drvdata(pdev, nvdimm_bus);
  72 
  73         rc = walk_iomem_res_desc(IORES_DESC_PERSISTENT_MEMORY_LEGACY,
  74                         IORESOURCE_MEM, 0, -1, nvdimm_bus, e820_register_one);
  75         if (rc)
  76                 goto err;
  77         return 0;
  78 err:
  79         nvdimm_bus_unregister(nvdimm_bus);
  80         dev_err(dev, "failed to register legacy persistent memory ranges\n");
  81         return rc;
  82 }
  83 
  84 static struct platform_driver e820_pmem_driver = {
  85         .probe = e820_pmem_probe,
  86         .remove = e820_pmem_remove,
  87         .driver = {
  88                 .name = "e820_pmem",
  89         },
  90 };
  91 
  92 module_platform_driver(e820_pmem_driver);
  93 
  94 MODULE_ALIAS("platform:e820_pmem*");
  95 MODULE_LICENSE("GPL v2");
  96 MODULE_AUTHOR("Intel Corporation");

/* [<][>][^][v][top][bottom][index][help] */