2019-05-19 13:08:20 +01:00
// SPDX-License-Identifier: GPL-2.0-only
2015-08-19 00:34:34 -04:00
/*
* Copyright ( c ) 2015 , Christoph Hellwig .
* Copyright ( c ) 2015 , Intel Corporation .
*/
# include <linux/platform_device.h>
2015-11-11 16:46:33 -08:00
# include <linux/memory_hotplug.h>
2015-08-19 00:34:34 -04:00
# include <linux/libnvdimm.h>
# include <linux/module.h>
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 ;
}
2015-11-11 16:46:33 -08:00
# ifdef CONFIG_MEMORY_HOTPLUG
static int e820_range_to_nid ( resource_size_t addr )
{
return memory_add_physaddr_to_nid ( addr ) ;
}
# else
static int e820_range_to_nid ( resource_size_t addr )
{
return NUMA_NO_NODE ;
}
# endif
2018-06-02 11:43:39 -07:00
static int e820_register_one ( struct resource * res , void * data )
{
struct nd_region_desc ndr_desc ;
struct nvdimm_bus * nvdimm_bus = data ;
memset ( & ndr_desc , 0 , sizeof ( ndr_desc ) ) ;
ndr_desc . res = res ;
ndr_desc . numa_node = e820_range_to_nid ( res - > start ) ;
2018-11-09 12:43:07 -08:00
ndr_desc . target_node = ndr_desc . numa_node ;
2018-06-02 11:43:39 -07:00
set_bit ( ND_REGION_PAGEMAP , & ndr_desc . flags ) ;
if ( ! nvdimm_pmem_region_create ( nvdimm_bus , & ndr_desc ) )
return - ENXIO ;
return 0 ;
}
2015-08-19 00:34:34 -04:00
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 ;
2018-06-02 11:43:39 -07:00
int rc = - ENXIO ;
2015-08-19 00:34:34 -04:00
nd_desc . provider_name = " e820 " ;
2016-07-21 20:03:19 -07:00
nd_desc . module = THIS_MODULE ;
2015-08-19 00:34:34 -04:00
nvdimm_bus = nvdimm_bus_register ( dev , & nd_desc ) ;
if ( ! nvdimm_bus )
goto err ;
platform_set_drvdata ( pdev , nvdimm_bus ) ;
2018-06-02 11:43:39 -07:00
rc = walk_iomem_res_desc ( IORES_DESC_PERSISTENT_MEMORY_LEGACY ,
IORESOURCE_MEM , 0 , - 1 , nvdimm_bus , e820_register_one ) ;
if ( rc )
goto err ;
2015-08-19 00:34:34 -04:00
return 0 ;
2018-06-02 11:43:39 -07:00
err :
2015-08-19 00:34:34 -04:00
nvdimm_bus_unregister ( nvdimm_bus ) ;
dev_err ( dev , " failed to register legacy persistent memory ranges \n " ) ;
2018-06-02 11:43:39 -07:00
return rc ;
2015-08-19 00:34:34 -04:00
}
static struct platform_driver e820_pmem_driver = {
. probe = e820_pmem_probe ,
. remove = e820_pmem_remove ,
. driver = {
. name = " e820_pmem " ,
} ,
} ;
2016-12-05 09:23:20 +01:00
module_platform_driver ( e820_pmem_driver ) ;
2015-08-19 00:34:34 -04:00
MODULE_ALIAS ( " platform:e820_pmem* " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_AUTHOR ( " Intel Corporation " ) ;