diff options
Diffstat (limited to 'arch/powerpc/mm/mem.c')
-rw-r--r-- | arch/powerpc/mm/mem.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 9ee536ec0739..3bbba178b464 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -126,14 +126,31 @@ int __weak remove_section_mapping(unsigned long start, unsigned long end) return -ENODEV; } -int arch_add_memory(int nid, u64 start, u64 size, bool for_device) +int arch_add_memory(int nid, u64 start, u64 size, enum memory_type type) { struct pglist_data *pgdata; - struct zone *zone; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; + bool for_device = false; + struct zone *zone; int rc; + /* + * Each memory_type needs special handling, so error out on an + * unsupported type. In particular, MEMORY_DEVICE_UNADDRESSABLE + * is not supported on this architecture. + */ + switch (type) { + case MEMORY_NORMAL: + break; + case MEMORY_DEVICE_PERSISTENT: + for_device = true; + break; + default: + pr_err("hotplug unsupported memory type %d\n", type); + return -EINVAL; + } + resize_hpt_for_hotplug(memblock_phys_mem_size()); pgdata = NODE_DATA(nid); @@ -155,13 +172,27 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device) } #ifdef CONFIG_MEMORY_HOTREMOVE -int arch_remove_memory(u64 start, u64 size) +int arch_remove_memory(u64 start, u64 size, enum memory_type type) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; struct zone *zone; int ret; + /* + * Each memory_type needs special handling, so error out on an + * unsupported type. In particular, MEMORY_DEVICE_UNADDRESSABLE + * is not supported on this architecture. + */ + switch (type) { + case MEMORY_NORMAL: + case MEMORY_DEVICE_PERSISTENT: + break; + default: + pr_err("hotplug unsupported memory type %d\n", type); + return -EINVAL; + } + zone = page_zone(pfn_to_page(start_pfn)); ret = __remove_pages(zone, start_pfn, nr_pages); if (ret) |