1 /* 2 * Copyright (C) 2004, 2013 Intel Corporation 3 * Author: Naveen B S <naveen.b.s@intel.com> 4 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> 5 * 6 * All rights reserved. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or (at 11 * your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 16 * NON INFRINGEMENT. See the GNU General Public License for more 17 * details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * 23 * 24 * ACPI based HotPlug driver that supports Memory Hotplug 25 * This driver fields notifications from firmware for memory add 26 * and remove operations and alerts the VM of the affected memory 27 * ranges. 28 */ 29 30 #include <linux/acpi.h> 31 #include <linux/memory.h> 32 #include <linux/memory_hotplug.h> 33 34 #include "internal.h" 35 36 #define ACPI_MEMORY_DEVICE_CLASS "memory" 37 #define ACPI_MEMORY_DEVICE_HID "PNP0C80" 38 #define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" 39 40 #define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT 41 42 #undef PREFIX 43 #define PREFIX "ACPI:memory_hp:" 44 45 ACPI_MODULE_NAME("acpi_memhotplug"); 46 47 static const struct acpi_device_id memory_device_ids[] = { 48 {ACPI_MEMORY_DEVICE_HID, 0}, 49 {"", 0}, 50 }; 51 52 #ifdef CONFIG_ACPI_HOTPLUG_MEMORY 53 54 /* Memory Device States */ 55 #define MEMORY_INVALID_STATE 0 56 #define MEMORY_POWER_ON_STATE 1 57 #define MEMORY_POWER_OFF_STATE 2 58 59 static int acpi_memory_device_add(struct acpi_device *device, 60 const struct acpi_device_id *not_used); 61 static void acpi_memory_device_remove(struct acpi_device *device); 62 63 static struct acpi_scan_handler memory_device_handler = { 64 .ids = memory_device_ids, 65 .attach = acpi_memory_device_add, 66 .detach = acpi_memory_device_remove, 67 .hotplug = { 68 .enabled = true, 69 }, 70 }; 71 72 struct acpi_memory_info { 73 struct list_head list; 74 u64 start_addr; /* Memory Range start physical addr */ 75 u64 length; /* Memory Range length */ 76 unsigned short caching; /* memory cache attribute */ 77 unsigned short write_protect; /* memory read/write attribute */ 78 unsigned int enabled:1; 79 }; 80 81 struct acpi_memory_device { 82 struct acpi_device * device; 83 unsigned int state; /* State of the memory device */ 84 struct list_head res_list; 85 }; 86 87 static acpi_status 88 acpi_memory_get_resource(struct acpi_resource *resource, void *context) 89 { 90 struct acpi_memory_device *mem_device = context; 91 struct acpi_resource_address64 address64; 92 struct acpi_memory_info *info, *new; 93 acpi_status status; 94 95 status = acpi_resource_to_address64(resource, &address64); 96 if (ACPI_FAILURE(status) || 97 (address64.resource_type != ACPI_MEMORY_RANGE)) 98 return AE_OK; 99 100 list_for_each_entry(info, &mem_device->res_list, list) { 101 /* Can we combine the resource range information? */ 102 if ((info->caching == address64.info.mem.caching) && 103 (info->write_protect == address64.info.mem.write_protect) && 104 (info->start_addr + info->length == address64.address.minimum)) { 105 info->length += address64.address.address_length; 106 return AE_OK; 107 } 108 } 109 110 new = kzalloc(sizeof(struct acpi_memory_info), GFP_KERNEL); 111 if (!new) 112 return AE_ERROR; 113 114 INIT_LIST_HEAD(&new->list); 115 new->caching = address64.info.mem.caching; 116 new->write_protect = address64.info.mem.write_protect; 117 new->start_addr = address64.address.minimum; 118 new->length = address64.address.address_length; 119 list_add_tail(&new->list, &mem_device->res_list); 120 121 return AE_OK; 122 } 123 124 static void 125 acpi_memory_free_device_resources(struct acpi_memory_device *mem_device) 126 { 127 struct acpi_memory_info *info, *n; 128 129 list_for_each_entry_safe(info, n, &mem_device->res_list, list) 130 kfree(info); 131 INIT_LIST_HEAD(&mem_device->res_list); 132 } 133 134 static int 135 acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) 136 { 137 acpi_status status; 138 139 if (!list_empty(&mem_device->res_list)) 140 return 0; 141 142 status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, 143 acpi_memory_get_resource, mem_device); 144 if (ACPI_FAILURE(status)) { 145 acpi_memory_free_device_resources(mem_device); 146 return -EINVAL; 147 } 148 149 return 0; 150 } 151 152 static int acpi_memory_check_device(struct acpi_memory_device *mem_device) 153 { 154 unsigned long long current_status; 155 156 /* Get device present/absent information from the _STA */ 157 if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, 158 METHOD_NAME__STA, NULL, 159 ¤t_status))) 160 return -ENODEV; 161 /* 162 * Check for device status. Device should be 163 * present/enabled/functioning. 164 */ 165 if (!((current_status & ACPI_STA_DEVICE_PRESENT) 166 && (current_status & ACPI_STA_DEVICE_ENABLED) 167 && (current_status & ACPI_STA_DEVICE_FUNCTIONING))) 168 return -ENODEV; 169 170 return 0; 171 } 172 173 static unsigned long acpi_meminfo_start_pfn(struct acpi_memory_info *info) 174 { 175 return PFN_DOWN(info->start_addr); 176 } 177 178 static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info) 179 { 180 return PFN_UP(info->start_addr + info->length-1); 181 } 182 183 static int acpi_bind_memblk(struct memory_block *mem, void *arg) 184 { 185 return acpi_bind_one(&mem->dev, arg); 186 } 187 188 static int acpi_bind_memory_blocks(struct acpi_memory_info *info, 189 struct acpi_device *adev) 190 { 191 return walk_memory_range(acpi_meminfo_start_pfn(info), 192 acpi_meminfo_end_pfn(info), adev, 193 acpi_bind_memblk); 194 } 195 196 static int acpi_unbind_memblk(struct memory_block *mem, void *arg) 197 { 198 acpi_unbind_one(&mem->dev); 199 return 0; 200 } 201 202 static void acpi_unbind_memory_blocks(struct acpi_memory_info *info) 203 { 204 walk_memory_range(acpi_meminfo_start_pfn(info), 205 acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk); 206 } 207 208 static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) 209 { 210 acpi_handle handle = mem_device->device->handle; 211 int result, num_enabled = 0; 212 struct acpi_memory_info *info; 213 int node; 214 215 node = acpi_get_node(handle); 216 /* 217 * Tell the VM there is more memory here... 218 * Note: Assume that this function returns zero on success 219 * We don't have memory-hot-add rollback function,now. 220 * (i.e. memory-hot-remove function) 221 */ 222 list_for_each_entry(info, &mem_device->res_list, list) { 223 if (info->enabled) { /* just sanity check...*/ 224 num_enabled++; 225 continue; 226 } 227 /* 228 * If the memory block size is zero, please ignore it. 229 * Don't try to do the following memory hotplug flowchart. 230 */ 231 if (!info->length) 232 continue; 233 if (node < 0) 234 node = memory_add_physaddr_to_nid(info->start_addr); 235 236 result = add_memory(node, info->start_addr, info->length); 237 238 /* 239 * If the memory block has been used by the kernel, add_memory() 240 * returns -EEXIST. If add_memory() returns the other error, it 241 * means that this memory block is not used by the kernel. 242 */ 243 if (result && result != -EEXIST) 244 continue; 245 246 result = acpi_bind_memory_blocks(info, mem_device->device); 247 if (result) { 248 acpi_unbind_memory_blocks(info); 249 return -ENODEV; 250 } 251 252 info->enabled = 1; 253 254 /* 255 * Add num_enable even if add_memory() returns -EEXIST, so the 256 * device is bound to this driver. 257 */ 258 num_enabled++; 259 } 260 if (!num_enabled) { 261 dev_err(&mem_device->device->dev, "add_memory failed\n"); 262 mem_device->state = MEMORY_INVALID_STATE; 263 return -EINVAL; 264 } 265 /* 266 * Sometimes the memory device will contain several memory blocks. 267 * When one memory block is hot-added to the system memory, it will 268 * be regarded as a success. 269 * Otherwise if the last memory block can't be hot-added to the system 270 * memory, it will be failure and the memory device can't be bound with 271 * driver. 272 */ 273 return 0; 274 } 275 276 static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device) 277 { 278 acpi_handle handle = mem_device->device->handle; 279 struct acpi_memory_info *info, *n; 280 int nid = acpi_get_node(handle); 281 282 list_for_each_entry_safe(info, n, &mem_device->res_list, list) { 283 if (!info->enabled) 284 continue; 285 286 if (nid == NUMA_NO_NODE) 287 nid = memory_add_physaddr_to_nid(info->start_addr); 288 289 acpi_unbind_memory_blocks(info); 290 remove_memory(nid, info->start_addr, info->length); 291 list_del(&info->list); 292 kfree(info); 293 } 294 } 295 296 static void acpi_memory_device_free(struct acpi_memory_device *mem_device) 297 { 298 if (!mem_device) 299 return; 300 301 acpi_memory_free_device_resources(mem_device); 302 mem_device->device->driver_data = NULL; 303 kfree(mem_device); 304 } 305 306 static int acpi_memory_device_add(struct acpi_device *device, 307 const struct acpi_device_id *not_used) 308 { 309 struct acpi_memory_device *mem_device; 310 int result; 311 312 if (!device) 313 return -EINVAL; 314 315 mem_device = kzalloc(sizeof(struct acpi_memory_device), GFP_KERNEL); 316 if (!mem_device) 317 return -ENOMEM; 318 319 INIT_LIST_HEAD(&mem_device->res_list); 320 mem_device->device = device; 321 sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); 322 sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); 323 device->driver_data = mem_device; 324 325 /* Get the range from the _CRS */ 326 result = acpi_memory_get_device_resources(mem_device); 327 if (result) { 328 device->driver_data = NULL; 329 kfree(mem_device); 330 return result; 331 } 332 333 /* Set the device state */ 334 mem_device->state = MEMORY_POWER_ON_STATE; 335 336 result = acpi_memory_check_device(mem_device); 337 if (result) { 338 acpi_memory_device_free(mem_device); 339 return 0; 340 } 341 342 result = acpi_memory_enable_device(mem_device); 343 if (result) { 344 dev_err(&device->dev, "acpi_memory_enable_device() error\n"); 345 acpi_memory_device_free(mem_device); 346 return result; 347 } 348 349 dev_dbg(&device->dev, "Memory device configured by ACPI\n"); 350 return 1; 351 } 352 353 static void acpi_memory_device_remove(struct acpi_device *device) 354 { 355 struct acpi_memory_device *mem_device; 356 357 if (!device || !acpi_driver_data(device)) 358 return; 359 360 mem_device = acpi_driver_data(device); 361 acpi_memory_remove_memory(mem_device); 362 acpi_memory_device_free(mem_device); 363 } 364 365 static bool __initdata acpi_no_memhotplug; 366 367 void __init acpi_memory_hotplug_init(void) 368 { 369 if (acpi_no_memhotplug) { 370 memory_device_handler.attach = NULL; 371 acpi_scan_add_handler(&memory_device_handler); 372 return; 373 } 374 acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory"); 375 } 376 377 static int __init disable_acpi_memory_hotplug(char *str) 378 { 379 acpi_no_memhotplug = true; 380 return 1; 381 } 382 __setup("acpi_no_memhotplug", disable_acpi_memory_hotplug); 383 384 #else 385 386 static struct acpi_scan_handler memory_device_handler = { 387 .ids = memory_device_ids, 388 }; 389 390 void __init acpi_memory_hotplug_init(void) 391 { 392 acpi_scan_add_handler(&memory_device_handler); 393 } 394 395 #endif /* CONFIG_ACPI_HOTPLUG_MEMORY */ 396