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 /* Memory Device States */ 48 #define MEMORY_INVALID_STATE 0 49 #define MEMORY_POWER_ON_STATE 1 50 #define MEMORY_POWER_OFF_STATE 2 51 52 static int acpi_memory_device_add(struct acpi_device *device, 53 const struct acpi_device_id *not_used); 54 static void acpi_memory_device_remove(struct acpi_device *device); 55 56 static const struct acpi_device_id memory_device_ids[] = { 57 {ACPI_MEMORY_DEVICE_HID, 0}, 58 {"", 0}, 59 }; 60 61 static struct acpi_scan_handler memory_device_handler = { 62 .ids = memory_device_ids, 63 .attach = acpi_memory_device_add, 64 .detach = acpi_memory_device_remove, 65 .hotplug = { 66 .enabled = true, 67 }, 68 }; 69 70 struct acpi_memory_info { 71 struct list_head list; 72 u64 start_addr; /* Memory Range start physical addr */ 73 u64 length; /* Memory Range length */ 74 unsigned short caching; /* memory cache attribute */ 75 unsigned short write_protect; /* memory read/write attribute */ 76 unsigned int enabled:1; 77 }; 78 79 struct acpi_memory_device { 80 struct acpi_device * device; 81 unsigned int state; /* State of the memory device */ 82 struct list_head res_list; 83 }; 84 85 static acpi_status 86 acpi_memory_get_resource(struct acpi_resource *resource, void *context) 87 { 88 struct acpi_memory_device *mem_device = context; 89 struct acpi_resource_address64 address64; 90 struct acpi_memory_info *info, *new; 91 acpi_status status; 92 93 status = acpi_resource_to_address64(resource, &address64); 94 if (ACPI_FAILURE(status) || 95 (address64.resource_type != ACPI_MEMORY_RANGE)) 96 return AE_OK; 97 98 list_for_each_entry(info, &mem_device->res_list, list) { 99 /* Can we combine the resource range information? */ 100 if ((info->caching == address64.info.mem.caching) && 101 (info->write_protect == address64.info.mem.write_protect) && 102 (info->start_addr + info->length == address64.minimum)) { 103 info->length += address64.address_length; 104 return AE_OK; 105 } 106 } 107 108 new = kzalloc(sizeof(struct acpi_memory_info), GFP_KERNEL); 109 if (!new) 110 return AE_ERROR; 111 112 INIT_LIST_HEAD(&new->list); 113 new->caching = address64.info.mem.caching; 114 new->write_protect = address64.info.mem.write_protect; 115 new->start_addr = address64.minimum; 116 new->length = address64.address_length; 117 list_add_tail(&new->list, &mem_device->res_list); 118 119 return AE_OK; 120 } 121 122 static void 123 acpi_memory_free_device_resources(struct acpi_memory_device *mem_device) 124 { 125 struct acpi_memory_info *info, *n; 126 127 list_for_each_entry_safe(info, n, &mem_device->res_list, list) 128 kfree(info); 129 INIT_LIST_HEAD(&mem_device->res_list); 130 } 131 132 static int 133 acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) 134 { 135 acpi_status status; 136 137 if (!list_empty(&mem_device->res_list)) 138 return 0; 139 140 status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, 141 acpi_memory_get_resource, mem_device); 142 if (ACPI_FAILURE(status)) { 143 acpi_memory_free_device_resources(mem_device); 144 return -EINVAL; 145 } 146 147 return 0; 148 } 149 150 static int acpi_memory_check_device(struct acpi_memory_device *mem_device) 151 { 152 unsigned long long current_status; 153 154 /* Get device present/absent information from the _STA */ 155 if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, 156 METHOD_NAME__STA, NULL, 157 ¤t_status))) 158 return -ENODEV; 159 /* 160 * Check for device status. Device should be 161 * present/enabled/functioning. 162 */ 163 if (!((current_status & ACPI_STA_DEVICE_PRESENT) 164 && (current_status & ACPI_STA_DEVICE_ENABLED) 165 && (current_status & ACPI_STA_DEVICE_FUNCTIONING))) 166 return -ENODEV; 167 168 return 0; 169 } 170 171 static unsigned long acpi_meminfo_start_pfn(struct acpi_memory_info *info) 172 { 173 return PFN_DOWN(info->start_addr); 174 } 175 176 static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info) 177 { 178 return PFN_UP(info->start_addr + info->length-1); 179 } 180 181 static int acpi_bind_memblk(struct memory_block *mem, void *arg) 182 { 183 return acpi_bind_one(&mem->dev, (acpi_handle)arg); 184 } 185 186 static int acpi_bind_memory_blocks(struct acpi_memory_info *info, 187 acpi_handle handle) 188 { 189 return walk_memory_range(acpi_meminfo_start_pfn(info), 190 acpi_meminfo_end_pfn(info), (void *)handle, 191 acpi_bind_memblk); 192 } 193 194 static int acpi_unbind_memblk(struct memory_block *mem, void *arg) 195 { 196 acpi_unbind_one(&mem->dev); 197 return 0; 198 } 199 200 static void acpi_unbind_memory_blocks(struct acpi_memory_info *info, 201 acpi_handle handle) 202 { 203 walk_memory_range(acpi_meminfo_start_pfn(info), 204 acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk); 205 } 206 207 static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) 208 { 209 acpi_handle handle = mem_device->device->handle; 210 int result, num_enabled = 0; 211 struct acpi_memory_info *info; 212 int node; 213 214 node = acpi_get_node(handle); 215 /* 216 * Tell the VM there is more memory here... 217 * Note: Assume that this function returns zero on success 218 * We don't have memory-hot-add rollback function,now. 219 * (i.e. memory-hot-remove function) 220 */ 221 list_for_each_entry(info, &mem_device->res_list, list) { 222 if (info->enabled) { /* just sanity check...*/ 223 num_enabled++; 224 continue; 225 } 226 /* 227 * If the memory block size is zero, please ignore it. 228 * Don't try to do the following memory hotplug flowchart. 229 */ 230 if (!info->length) 231 continue; 232 if (node < 0) 233 node = memory_add_physaddr_to_nid(info->start_addr); 234 235 result = add_memory(node, info->start_addr, info->length); 236 237 /* 238 * If the memory block has been used by the kernel, add_memory() 239 * returns -EEXIST. If add_memory() returns the other error, it 240 * means that this memory block is not used by the kernel. 241 */ 242 if (result && result != -EEXIST) 243 continue; 244 245 result = acpi_bind_memory_blocks(info, handle); 246 if (result) { 247 acpi_unbind_memory_blocks(info, handle); 248 return -ENODEV; 249 } 250 251 info->enabled = 1; 252 253 /* 254 * Add num_enable even if add_memory() returns -EEXIST, so the 255 * device is bound to this driver. 256 */ 257 num_enabled++; 258 } 259 if (!num_enabled) { 260 dev_err(&mem_device->device->dev, "add_memory failed\n"); 261 mem_device->state = MEMORY_INVALID_STATE; 262 return -EINVAL; 263 } 264 /* 265 * Sometimes the memory device will contain several memory blocks. 266 * When one memory block is hot-added to the system memory, it will 267 * be regarded as a success. 268 * Otherwise if the last memory block can't be hot-added to the system 269 * memory, it will be failure and the memory device can't be bound with 270 * driver. 271 */ 272 return 0; 273 } 274 275 static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device) 276 { 277 acpi_handle handle = mem_device->device->handle; 278 struct acpi_memory_info *info, *n; 279 int nid = acpi_get_node(handle); 280 281 list_for_each_entry_safe(info, n, &mem_device->res_list, list) { 282 if (!info->enabled) 283 continue; 284 285 if (nid == NUMA_NO_NODE) 286 nid = memory_add_physaddr_to_nid(info->start_addr); 287 288 acpi_unbind_memory_blocks(info, handle); 289 remove_memory(nid, info->start_addr, info->length); 290 list_del(&info->list); 291 kfree(info); 292 } 293 } 294 295 static void acpi_memory_device_free(struct acpi_memory_device *mem_device) 296 { 297 if (!mem_device) 298 return; 299 300 acpi_memory_free_device_resources(mem_device); 301 mem_device->device->driver_data = NULL; 302 kfree(mem_device); 303 } 304 305 static int acpi_memory_device_add(struct acpi_device *device, 306 const struct acpi_device_id *not_used) 307 { 308 struct acpi_memory_device *mem_device; 309 int result; 310 311 if (!device) 312 return -EINVAL; 313 314 mem_device = kzalloc(sizeof(struct acpi_memory_device), GFP_KERNEL); 315 if (!mem_device) 316 return -ENOMEM; 317 318 INIT_LIST_HEAD(&mem_device->res_list); 319 mem_device->device = device; 320 sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); 321 sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); 322 device->driver_data = mem_device; 323 324 /* Get the range from the _CRS */ 325 result = acpi_memory_get_device_resources(mem_device); 326 if (result) { 327 device->driver_data = NULL; 328 kfree(mem_device); 329 return result; 330 } 331 332 /* Set the device state */ 333 mem_device->state = MEMORY_POWER_ON_STATE; 334 335 result = acpi_memory_check_device(mem_device); 336 if (result) { 337 acpi_memory_device_free(mem_device); 338 return 0; 339 } 340 341 result = acpi_memory_enable_device(mem_device); 342 if (result) { 343 dev_err(&device->dev, "acpi_memory_enable_device() error\n"); 344 acpi_memory_device_free(mem_device); 345 return result; 346 } 347 348 dev_dbg(&device->dev, "Memory device configured by ACPI\n"); 349 return 1; 350 } 351 352 static void acpi_memory_device_remove(struct acpi_device *device) 353 { 354 struct acpi_memory_device *mem_device; 355 356 if (!device || !acpi_driver_data(device)) 357 return; 358 359 mem_device = acpi_driver_data(device); 360 acpi_memory_remove_memory(mem_device); 361 acpi_memory_device_free(mem_device); 362 } 363 364 void __init acpi_memory_hotplug_init(void) 365 { 366 acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory"); 367 } 368