1 /* 2 * Copyright (C) 2004 Intel Corporation <naveen.b.s@intel.com> 3 * 4 * All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or (at 9 * your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 14 * NON INFRINGEMENT. See the GNU General Public License for more 15 * details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * 21 * 22 * ACPI based HotPlug driver that supports Memory Hotplug 23 * This driver fields notifications from firmware for memory add 24 * and remove operations and alerts the VM of the affected memory 25 * ranges. 26 */ 27 28 #include <linux/kernel.h> 29 #include <linux/module.h> 30 #include <linux/init.h> 31 #include <linux/types.h> 32 #include <linux/memory_hotplug.h> 33 #include <linux/slab.h> 34 #include <linux/acpi.h> 35 #include <acpi/acpi_drivers.h> 36 37 #define ACPI_MEMORY_DEVICE_CLASS "memory" 38 #define ACPI_MEMORY_DEVICE_HID "PNP0C80" 39 #define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" 40 41 #define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT 42 43 #undef PREFIX 44 #define PREFIX "ACPI:memory_hp:" 45 46 ACPI_MODULE_NAME("acpi_memhotplug"); 47 MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>"); 48 MODULE_DESCRIPTION("Hotplug Mem Driver"); 49 MODULE_LICENSE("GPL"); 50 51 /* Memory Device States */ 52 #define MEMORY_INVALID_STATE 0 53 #define MEMORY_POWER_ON_STATE 1 54 #define MEMORY_POWER_OFF_STATE 2 55 56 static int acpi_memory_device_add(struct acpi_device *device); 57 static int acpi_memory_device_remove(struct acpi_device *device, int type); 58 59 static const struct acpi_device_id memory_device_ids[] = { 60 {ACPI_MEMORY_DEVICE_HID, 0}, 61 {"", 0}, 62 }; 63 MODULE_DEVICE_TABLE(acpi, memory_device_ids); 64 65 static struct acpi_driver acpi_memory_device_driver = { 66 .name = "acpi_memhotplug", 67 .class = ACPI_MEMORY_DEVICE_CLASS, 68 .ids = memory_device_ids, 69 .ops = { 70 .add = acpi_memory_device_add, 71 .remove = acpi_memory_device_remove, 72 }, 73 }; 74 75 struct acpi_memory_info { 76 struct list_head list; 77 u64 start_addr; /* Memory Range start physical addr */ 78 u64 length; /* Memory Range length */ 79 unsigned short caching; /* memory cache attribute */ 80 unsigned short write_protect; /* memory read/write attribute */ 81 unsigned int enabled:1; 82 unsigned int failed:1; 83 }; 84 85 struct acpi_memory_device { 86 struct acpi_device * device; 87 unsigned int state; /* State of the memory device */ 88 struct list_head res_list; 89 }; 90 91 static acpi_status 92 acpi_memory_get_resource(struct acpi_resource *resource, void *context) 93 { 94 struct acpi_memory_device *mem_device = context; 95 struct acpi_resource_address64 address64; 96 struct acpi_memory_info *info, *new; 97 acpi_status status; 98 99 status = acpi_resource_to_address64(resource, &address64); 100 if (ACPI_FAILURE(status) || 101 (address64.resource_type != ACPI_MEMORY_RANGE)) 102 return AE_OK; 103 104 list_for_each_entry(info, &mem_device->res_list, list) { 105 /* Can we combine the resource range information? */ 106 if ((info->caching == address64.info.mem.caching) && 107 (info->write_protect == address64.info.mem.write_protect) && 108 (info->start_addr + info->length == address64.minimum)) { 109 info->length += address64.address_length; 110 return AE_OK; 111 } 112 } 113 114 new = kzalloc(sizeof(struct acpi_memory_info), GFP_KERNEL); 115 if (!new) 116 return AE_ERROR; 117 118 INIT_LIST_HEAD(&new->list); 119 new->caching = address64.info.mem.caching; 120 new->write_protect = address64.info.mem.write_protect; 121 new->start_addr = address64.minimum; 122 new->length = address64.address_length; 123 list_add_tail(&new->list, &mem_device->res_list); 124 125 return AE_OK; 126 } 127 128 static void 129 acpi_memory_free_device_resources(struct acpi_memory_device *mem_device) 130 { 131 struct acpi_memory_info *info, *n; 132 133 list_for_each_entry_safe(info, n, &mem_device->res_list, list) 134 kfree(info); 135 INIT_LIST_HEAD(&mem_device->res_list); 136 } 137 138 static int 139 acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) 140 { 141 acpi_status status; 142 143 if (!list_empty(&mem_device->res_list)) 144 return 0; 145 146 status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, 147 acpi_memory_get_resource, mem_device); 148 if (ACPI_FAILURE(status)) { 149 acpi_memory_free_device_resources(mem_device); 150 return -EINVAL; 151 } 152 153 return 0; 154 } 155 156 static int 157 acpi_memory_get_device(acpi_handle handle, 158 struct acpi_memory_device **mem_device) 159 { 160 acpi_status status; 161 acpi_handle phandle; 162 struct acpi_device *device = NULL; 163 struct acpi_device *pdevice = NULL; 164 int result; 165 166 167 if (!acpi_bus_get_device(handle, &device) && device) 168 goto end; 169 170 status = acpi_get_parent(handle, &phandle); 171 if (ACPI_FAILURE(status)) { 172 ACPI_EXCEPTION((AE_INFO, status, "Cannot find acpi parent")); 173 return -EINVAL; 174 } 175 176 /* Get the parent device */ 177 result = acpi_bus_get_device(phandle, &pdevice); 178 if (result) { 179 acpi_handle_warn(phandle, "Cannot get acpi bus device\n"); 180 return -EINVAL; 181 } 182 183 /* 184 * Now add the notified device. This creates the acpi_device 185 * and invokes .add function 186 */ 187 result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); 188 if (result) { 189 acpi_handle_warn(handle, "Cannot add acpi bus\n"); 190 return -EINVAL; 191 } 192 193 end: 194 *mem_device = acpi_driver_data(device); 195 if (!(*mem_device)) { 196 dev_err(&device->dev, "driver data not found\n"); 197 return -ENODEV; 198 } 199 200 return 0; 201 } 202 203 static int acpi_memory_check_device(struct acpi_memory_device *mem_device) 204 { 205 unsigned long long current_status; 206 207 /* Get device present/absent information from the _STA */ 208 if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA", 209 NULL, ¤t_status))) 210 return -ENODEV; 211 /* 212 * Check for device status. Device should be 213 * present/enabled/functioning. 214 */ 215 if (!((current_status & ACPI_STA_DEVICE_PRESENT) 216 && (current_status & ACPI_STA_DEVICE_ENABLED) 217 && (current_status & ACPI_STA_DEVICE_FUNCTIONING))) 218 return -ENODEV; 219 220 return 0; 221 } 222 223 static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) 224 { 225 int result, num_enabled = 0; 226 struct acpi_memory_info *info; 227 int node; 228 229 node = acpi_get_node(mem_device->device->handle); 230 /* 231 * Tell the VM there is more memory here... 232 * Note: Assume that this function returns zero on success 233 * We don't have memory-hot-add rollback function,now. 234 * (i.e. memory-hot-remove function) 235 */ 236 list_for_each_entry(info, &mem_device->res_list, list) { 237 if (info->enabled) { /* just sanity check...*/ 238 num_enabled++; 239 continue; 240 } 241 /* 242 * If the memory block size is zero, please ignore it. 243 * Don't try to do the following memory hotplug flowchart. 244 */ 245 if (!info->length) 246 continue; 247 if (node < 0) 248 node = memory_add_physaddr_to_nid(info->start_addr); 249 250 result = add_memory(node, info->start_addr, info->length); 251 252 /* 253 * If the memory block has been used by the kernel, add_memory() 254 * returns -EEXIST. If add_memory() returns the other error, it 255 * means that this memory block is not used by the kernel. 256 */ 257 if (result && result != -EEXIST) { 258 info->failed = 1; 259 continue; 260 } 261 262 if (!result) 263 info->enabled = 1; 264 /* 265 * Add num_enable even if add_memory() returns -EEXIST, so the 266 * device is bound to this driver. 267 */ 268 num_enabled++; 269 } 270 if (!num_enabled) { 271 dev_err(&mem_device->device->dev, "add_memory failed\n"); 272 mem_device->state = MEMORY_INVALID_STATE; 273 return -EINVAL; 274 } 275 /* 276 * Sometimes the memory device will contain several memory blocks. 277 * When one memory block is hot-added to the system memory, it will 278 * be regarded as a success. 279 * Otherwise if the last memory block can't be hot-added to the system 280 * memory, it will be failure and the memory device can't be bound with 281 * driver. 282 */ 283 return 0; 284 } 285 286 static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) 287 { 288 int result = 0; 289 struct acpi_memory_info *info, *n; 290 291 list_for_each_entry_safe(info, n, &mem_device->res_list, list) { 292 if (info->failed) 293 /* The kernel does not use this memory block */ 294 continue; 295 296 if (!info->enabled) 297 /* 298 * The kernel uses this memory block, but it may be not 299 * managed by us. 300 */ 301 return -EBUSY; 302 303 result = remove_memory(info->start_addr, info->length); 304 if (result) 305 return result; 306 307 list_del(&info->list); 308 kfree(info); 309 } 310 311 return result; 312 } 313 314 static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) 315 { 316 struct acpi_memory_device *mem_device; 317 struct acpi_device *device; 318 struct acpi_eject_event *ej_event = NULL; 319 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ 320 321 switch (event) { 322 case ACPI_NOTIFY_BUS_CHECK: 323 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 324 "\nReceived BUS CHECK notification for device\n")); 325 /* Fall Through */ 326 case ACPI_NOTIFY_DEVICE_CHECK: 327 if (event == ACPI_NOTIFY_DEVICE_CHECK) 328 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 329 "\nReceived DEVICE CHECK notification for device\n")); 330 if (acpi_memory_get_device(handle, &mem_device)) { 331 acpi_handle_err(handle, "Cannot find driver data\n"); 332 break; 333 } 334 335 ost_code = ACPI_OST_SC_SUCCESS; 336 break; 337 338 case ACPI_NOTIFY_EJECT_REQUEST: 339 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 340 "\nReceived EJECT REQUEST notification for device\n")); 341 342 if (acpi_bus_get_device(handle, &device)) { 343 acpi_handle_err(handle, "Device doesn't exist\n"); 344 break; 345 } 346 mem_device = acpi_driver_data(device); 347 if (!mem_device) { 348 acpi_handle_err(handle, "Driver Data is NULL\n"); 349 break; 350 } 351 352 ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); 353 if (!ej_event) { 354 pr_err(PREFIX "No memory, dropping EJECT\n"); 355 break; 356 } 357 358 ej_event->handle = handle; 359 ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; 360 acpi_os_hotplug_execute(acpi_bus_hot_remove_device, 361 (void *)ej_event); 362 363 /* eject is performed asynchronously */ 364 return; 365 default: 366 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 367 "Unsupported event [0x%x]\n", event)); 368 369 /* non-hotplug event; possibly handled by other handler */ 370 return; 371 } 372 373 /* Inform firmware that the hotplug operation has completed */ 374 (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); 375 return; 376 } 377 378 static void acpi_memory_device_free(struct acpi_memory_device *mem_device) 379 { 380 if (!mem_device) 381 return; 382 383 acpi_memory_free_device_resources(mem_device); 384 kfree(mem_device); 385 } 386 387 static int acpi_memory_device_add(struct acpi_device *device) 388 { 389 int result; 390 struct acpi_memory_device *mem_device = NULL; 391 392 393 if (!device) 394 return -EINVAL; 395 396 mem_device = kzalloc(sizeof(struct acpi_memory_device), GFP_KERNEL); 397 if (!mem_device) 398 return -ENOMEM; 399 400 INIT_LIST_HEAD(&mem_device->res_list); 401 mem_device->device = device; 402 sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); 403 sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); 404 device->driver_data = mem_device; 405 406 /* Get the range from the _CRS */ 407 result = acpi_memory_get_device_resources(mem_device); 408 if (result) { 409 kfree(mem_device); 410 return result; 411 } 412 413 /* Set the device state */ 414 mem_device->state = MEMORY_POWER_ON_STATE; 415 416 pr_debug("%s\n", acpi_device_name(device)); 417 418 if (!acpi_memory_check_device(mem_device)) { 419 /* call add_memory func */ 420 result = acpi_memory_enable_device(mem_device); 421 if (result) { 422 dev_err(&device->dev, 423 "Error in acpi_memory_enable_device\n"); 424 acpi_memory_device_free(mem_device); 425 } 426 } 427 return result; 428 } 429 430 static int acpi_memory_device_remove(struct acpi_device *device, int type) 431 { 432 struct acpi_memory_device *mem_device = NULL; 433 int result; 434 435 if (!device || !acpi_driver_data(device)) 436 return -EINVAL; 437 438 mem_device = acpi_driver_data(device); 439 440 result = acpi_memory_remove_memory(mem_device); 441 if (result) 442 return result; 443 444 acpi_memory_device_free(mem_device); 445 446 return 0; 447 } 448 449 /* 450 * Helper function to check for memory device 451 */ 452 static acpi_status is_memory_device(acpi_handle handle) 453 { 454 char *hardware_id; 455 acpi_status status; 456 struct acpi_device_info *info; 457 458 status = acpi_get_object_info(handle, &info); 459 if (ACPI_FAILURE(status)) 460 return status; 461 462 if (!(info->valid & ACPI_VALID_HID)) { 463 kfree(info); 464 return AE_ERROR; 465 } 466 467 hardware_id = info->hardware_id.string; 468 if ((hardware_id == NULL) || 469 (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) 470 status = AE_ERROR; 471 472 kfree(info); 473 return status; 474 } 475 476 static acpi_status 477 acpi_memory_register_notify_handler(acpi_handle handle, 478 u32 level, void *ctxt, void **retv) 479 { 480 acpi_status status; 481 482 483 status = is_memory_device(handle); 484 if (ACPI_FAILURE(status)) 485 return AE_OK; /* continue */ 486 487 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 488 acpi_memory_device_notify, NULL); 489 /* continue */ 490 return AE_OK; 491 } 492 493 static acpi_status 494 acpi_memory_deregister_notify_handler(acpi_handle handle, 495 u32 level, void *ctxt, void **retv) 496 { 497 acpi_status status; 498 499 500 status = is_memory_device(handle); 501 if (ACPI_FAILURE(status)) 502 return AE_OK; /* continue */ 503 504 status = acpi_remove_notify_handler(handle, 505 ACPI_SYSTEM_NOTIFY, 506 acpi_memory_device_notify); 507 508 return AE_OK; /* continue */ 509 } 510 511 static int __init acpi_memory_device_init(void) 512 { 513 int result; 514 acpi_status status; 515 516 517 result = acpi_bus_register_driver(&acpi_memory_device_driver); 518 519 if (result < 0) 520 return -ENODEV; 521 522 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 523 ACPI_UINT32_MAX, 524 acpi_memory_register_notify_handler, NULL, 525 NULL, NULL); 526 527 if (ACPI_FAILURE(status)) { 528 ACPI_EXCEPTION((AE_INFO, status, "walk_namespace failed")); 529 acpi_bus_unregister_driver(&acpi_memory_device_driver); 530 return -ENODEV; 531 } 532 533 return 0; 534 } 535 536 static void __exit acpi_memory_device_exit(void) 537 { 538 acpi_status status; 539 540 541 /* 542 * Adding this to un-install notification handlers for all the device 543 * handles. 544 */ 545 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 546 ACPI_UINT32_MAX, 547 acpi_memory_deregister_notify_handler, NULL, 548 NULL, NULL); 549 550 if (ACPI_FAILURE(status)) 551 ACPI_EXCEPTION((AE_INFO, status, "walk_namespace failed")); 552 553 acpi_bus_unregister_driver(&acpi_memory_device_driver); 554 555 return; 556 } 557 558 module_init(acpi_memory_device_init); 559 module_exit(acpi_memory_device_exit); 560