1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform. 4 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com> 5 * 6 * All rights reserved. 7 * 8 * Send feedback to <lxie@us.ibm.com> 9 * 10 */ 11 #include <linux/kernel.h> 12 #include <linux/module.h> 13 #include <linux/moduleparam.h> 14 #include <linux/of.h> 15 #include <linux/pci.h> 16 #include <linux/pci_hotplug.h> 17 #include <linux/smp.h> 18 #include <linux/init.h> 19 #include <linux/vmalloc.h> 20 #include <asm/firmware.h> 21 #include <asm/eeh.h> /* for eeh_add_device() */ 22 #include <asm/rtas.h> /* rtas_call */ 23 #include <asm/pci-bridge.h> /* for pci_controller */ 24 #include <asm/prom.h> 25 #include "../pci.h" /* for pci_add_new_bus */ 26 /* and pci_do_scan_bus */ 27 #include "rpaphp.h" 28 29 bool rpaphp_debug; 30 LIST_HEAD(rpaphp_slot_head); 31 EXPORT_SYMBOL_GPL(rpaphp_slot_head); 32 33 #define DRIVER_VERSION "0.1" 34 #define DRIVER_AUTHOR "Linda Xie <lxie@us.ibm.com>" 35 #define DRIVER_DESC "RPA HOT Plug PCI Controller Driver" 36 37 #define MAX_LOC_CODE 128 38 39 MODULE_AUTHOR(DRIVER_AUTHOR); 40 MODULE_DESCRIPTION(DRIVER_DESC); 41 MODULE_LICENSE("GPL"); 42 43 module_param_named(debug, rpaphp_debug, bool, 0644); 44 45 /** 46 * set_attention_status - set attention LED 47 * @hotplug_slot: target &hotplug_slot 48 * @value: LED control value 49 * 50 * echo 0 > attention -- set LED OFF 51 * echo 1 > attention -- set LED ON 52 * echo 2 > attention -- set LED ID(identify, light is blinking) 53 */ 54 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) 55 { 56 int rc; 57 struct slot *slot = to_slot(hotplug_slot); 58 59 switch (value) { 60 case 0: 61 case 1: 62 case 2: 63 break; 64 default: 65 value = 1; 66 break; 67 } 68 69 rc = rtas_set_indicator(DR_INDICATOR, slot->index, value); 70 if (!rc) 71 slot->attention_status = value; 72 73 return rc; 74 } 75 76 /** 77 * get_power_status - get power status of a slot 78 * @hotplug_slot: slot to get status 79 * @value: pointer to store status 80 */ 81 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 82 { 83 int retval, level; 84 struct slot *slot = to_slot(hotplug_slot); 85 86 retval = rtas_get_power_level(slot->power_domain, &level); 87 if (!retval) 88 *value = level; 89 return retval; 90 } 91 92 /** 93 * get_attention_status - get attention LED status 94 * @hotplug_slot: slot to get status 95 * @value: pointer to store status 96 */ 97 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) 98 { 99 struct slot *slot = to_slot(hotplug_slot); 100 *value = slot->attention_status; 101 return 0; 102 } 103 104 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 105 { 106 struct slot *slot = to_slot(hotplug_slot); 107 int rc, state; 108 109 rc = rpaphp_get_sensor_state(slot, &state); 110 111 *value = NOT_VALID; 112 if (rc) 113 return rc; 114 115 if (state == EMPTY) 116 *value = EMPTY; 117 else if (state == PRESENT) 118 *value = slot->state; 119 120 return 0; 121 } 122 123 static enum pci_bus_speed get_max_bus_speed(struct slot *slot) 124 { 125 enum pci_bus_speed speed; 126 switch (slot->type) { 127 case 1: 128 case 2: 129 case 3: 130 case 4: 131 case 5: 132 case 6: 133 speed = PCI_SPEED_33MHz; /* speed for case 1-6 */ 134 break; 135 case 7: 136 case 8: 137 speed = PCI_SPEED_66MHz; 138 break; 139 case 11: 140 case 14: 141 speed = PCI_SPEED_66MHz_PCIX; 142 break; 143 case 12: 144 case 15: 145 speed = PCI_SPEED_100MHz_PCIX; 146 break; 147 case 13: 148 case 16: 149 speed = PCI_SPEED_133MHz_PCIX; 150 break; 151 default: 152 speed = PCI_SPEED_UNKNOWN; 153 break; 154 } 155 156 return speed; 157 } 158 159 static int get_children_props(struct device_node *dn, const __be32 **drc_indexes, 160 const __be32 **drc_names, const __be32 **drc_types, 161 const __be32 **drc_power_domains) 162 { 163 const __be32 *indexes, *names, *types, *domains; 164 165 indexes = of_get_property(dn, "ibm,drc-indexes", NULL); 166 names = of_get_property(dn, "ibm,drc-names", NULL); 167 types = of_get_property(dn, "ibm,drc-types", NULL); 168 domains = of_get_property(dn, "ibm,drc-power-domains", NULL); 169 170 if (!indexes || !names || !types || !domains) { 171 /* Slot does not have dynamically-removable children */ 172 return -EINVAL; 173 } 174 if (drc_indexes) 175 *drc_indexes = indexes; 176 if (drc_names) 177 /* &drc_names[1] contains NULL terminated slot names */ 178 *drc_names = names; 179 if (drc_types) 180 /* &drc_types[1] contains NULL terminated slot types */ 181 *drc_types = types; 182 if (drc_power_domains) 183 *drc_power_domains = domains; 184 185 return 0; 186 } 187 188 189 /* Verify the existence of 'drc_name' and/or 'drc_type' within the 190 * current node. First obtain its my-drc-index property. Next, 191 * obtain the DRC info from its parent. Use the my-drc-index for 192 * correlation, and obtain/validate the requested properties. 193 */ 194 195 static int rpaphp_check_drc_props_v1(struct device_node *dn, char *drc_name, 196 char *drc_type, unsigned int my_index) 197 { 198 char *name_tmp, *type_tmp; 199 const __be32 *indexes, *names; 200 const __be32 *types, *domains; 201 int i, rc; 202 203 rc = get_children_props(dn->parent, &indexes, &names, &types, &domains); 204 if (rc < 0) { 205 return -EINVAL; 206 } 207 208 name_tmp = (char *) &names[1]; 209 type_tmp = (char *) &types[1]; 210 211 /* Iterate through parent properties, looking for my-drc-index */ 212 for (i = 0; i < be32_to_cpu(indexes[0]); i++) { 213 if (be32_to_cpu(indexes[i + 1]) == my_index) 214 break; 215 216 name_tmp += (strlen(name_tmp) + 1); 217 type_tmp += (strlen(type_tmp) + 1); 218 } 219 220 if (((drc_name == NULL) || (drc_name && !strcmp(drc_name, name_tmp))) && 221 ((drc_type == NULL) || (drc_type && !strcmp(drc_type, type_tmp)))) 222 return 0; 223 224 return -EINVAL; 225 } 226 227 static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name, 228 char *drc_type, unsigned int my_index) 229 { 230 struct property *info; 231 unsigned int entries; 232 struct of_drc_info drc; 233 const __be32 *value; 234 char cell_drc_name[MAX_DRC_NAME_LEN]; 235 int j; 236 237 info = of_find_property(dn->parent, "ibm,drc-info", NULL); 238 if (info == NULL) 239 return -EINVAL; 240 241 value = of_prop_next_u32(info, NULL, &entries); 242 if (!value) 243 return -EINVAL; 244 else 245 value++; 246 247 for (j = 0; j < entries; j++) { 248 of_read_drc_info_cell(&info, &value, &drc); 249 250 /* Should now know end of current entry */ 251 252 /* Found it */ 253 if (my_index >= drc.drc_index_start && my_index <= drc.last_drc_index) { 254 int index = my_index - drc.drc_index_start; 255 sprintf(cell_drc_name, "%s%d", drc.drc_name_prefix, 256 drc.drc_name_suffix_start + index); 257 break; 258 } 259 } 260 261 if (((drc_name == NULL) || 262 (drc_name && !strcmp(drc_name, cell_drc_name))) && 263 ((drc_type == NULL) || 264 (drc_type && !strcmp(drc_type, drc.drc_type)))) 265 return 0; 266 267 return -EINVAL; 268 } 269 270 int rpaphp_check_drc_props(struct device_node *dn, char *drc_name, 271 char *drc_type) 272 { 273 const __be32 *my_index; 274 275 my_index = of_get_property(dn, "ibm,my-drc-index", NULL); 276 if (!my_index) { 277 /* Node isn't DLPAR/hotplug capable */ 278 return -EINVAL; 279 } 280 281 if (of_property_present(dn->parent, "ibm,drc-info")) 282 return rpaphp_check_drc_props_v2(dn, drc_name, drc_type, 283 be32_to_cpu(*my_index)); 284 else 285 return rpaphp_check_drc_props_v1(dn, drc_name, drc_type, 286 be32_to_cpu(*my_index)); 287 } 288 EXPORT_SYMBOL_GPL(rpaphp_check_drc_props); 289 290 291 static int is_php_type(char *drc_type) 292 { 293 char *endptr; 294 295 /* PCI Hotplug nodes have an integer for drc_type */ 296 simple_strtoul(drc_type, &endptr, 10); 297 if (endptr == drc_type) 298 return 0; 299 300 return 1; 301 } 302 303 /** 304 * is_php_dn() - return 1 if this is a hotpluggable pci slot, else 0 305 * @dn: target &device_node 306 * @indexes: passed to get_children_props() 307 * @names: passed to get_children_props() 308 * @types: returned from get_children_props() 309 * @power_domains: 310 * 311 * This routine will return true only if the device node is 312 * a hotpluggable slot. This routine will return false 313 * for built-in pci slots (even when the built-in slots are 314 * dlparable.) 315 */ 316 static int is_php_dn(struct device_node *dn, const __be32 **indexes, 317 const __be32 **names, const __be32 **types, 318 const __be32 **power_domains) 319 { 320 const __be32 *drc_types; 321 int rc; 322 323 rc = get_children_props(dn, indexes, names, &drc_types, power_domains); 324 if (rc < 0) 325 return 0; 326 327 if (!is_php_type((char *) &drc_types[1])) 328 return 0; 329 330 *types = drc_types; 331 return 1; 332 } 333 334 static int rpaphp_drc_info_add_slot(struct device_node *dn) 335 { 336 struct slot *slot; 337 struct property *info; 338 struct of_drc_info drc; 339 char drc_name[MAX_DRC_NAME_LEN]; 340 const __be32 *cur; 341 u32 count; 342 int retval = 0; 343 344 info = of_find_property(dn, "ibm,drc-info", NULL); 345 if (!info) 346 return 0; 347 348 cur = of_prop_next_u32(info, NULL, &count); 349 if (cur) 350 cur++; 351 else 352 return 0; 353 354 of_read_drc_info_cell(&info, &cur, &drc); 355 if (!is_php_type(drc.drc_type)) 356 return 0; 357 358 sprintf(drc_name, "%s%d", drc.drc_name_prefix, drc.drc_name_suffix_start); 359 360 slot = alloc_slot_struct(dn, drc.drc_index_start, drc_name, drc.drc_power_domain); 361 if (!slot) 362 return -ENOMEM; 363 364 slot->type = simple_strtoul(drc.drc_type, NULL, 10); 365 retval = rpaphp_enable_slot(slot); 366 if (!retval) 367 retval = rpaphp_register_slot(slot); 368 369 if (retval) 370 dealloc_slot_struct(slot); 371 372 return retval; 373 } 374 375 static int rpaphp_drc_add_slot(struct device_node *dn) 376 { 377 struct slot *slot; 378 int retval = 0; 379 int i; 380 const __be32 *indexes, *names, *types, *power_domains; 381 char *name, *type; 382 383 /* If this is not a hotplug slot, return without doing anything. */ 384 if (!is_php_dn(dn, &indexes, &names, &types, &power_domains)) 385 return 0; 386 387 dbg("Entry %s: dn=%pOF\n", __func__, dn); 388 389 /* register PCI devices */ 390 name = (char *) &names[1]; 391 type = (char *) &types[1]; 392 for (i = 0; i < be32_to_cpu(indexes[0]); i++) { 393 int index; 394 395 index = be32_to_cpu(indexes[i + 1]); 396 slot = alloc_slot_struct(dn, index, name, 397 be32_to_cpu(power_domains[i + 1])); 398 if (!slot) 399 return -ENOMEM; 400 401 slot->type = simple_strtoul(type, NULL, 10); 402 403 dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", 404 index, name, type); 405 406 retval = rpaphp_enable_slot(slot); 407 if (!retval) 408 retval = rpaphp_register_slot(slot); 409 410 if (retval) 411 dealloc_slot_struct(slot); 412 413 name += strlen(name) + 1; 414 type += strlen(type) + 1; 415 } 416 dbg("%s - Exit: rc[%d]\n", __func__, retval); 417 418 /* XXX FIXME: reports a failure only if last entry in loop failed */ 419 return retval; 420 } 421 422 /** 423 * rpaphp_add_slot -- declare a hotplug slot to the hotplug subsystem. 424 * @dn: device node of slot 425 * 426 * This subroutine will register a hotpluggable slot with the 427 * PCI hotplug infrastructure. This routine is typically called 428 * during boot time, if the hotplug slots are present at boot time, 429 * or is called later, by the dlpar add code, if the slot is 430 * being dynamically added during runtime. 431 * 432 * If the device node points at an embedded (built-in) slot, this 433 * routine will just return without doing anything, since embedded 434 * slots cannot be hotplugged. 435 * 436 * To remove a slot, it suffices to call rpaphp_deregister_slot(). 437 */ 438 int rpaphp_add_slot(struct device_node *dn) 439 { 440 if (!of_node_name_eq(dn, "pci")) 441 return 0; 442 443 if (of_property_present(dn, "ibm,drc-info")) 444 return rpaphp_drc_info_add_slot(dn); 445 else 446 return rpaphp_drc_add_slot(dn); 447 } 448 EXPORT_SYMBOL_GPL(rpaphp_add_slot); 449 450 static void __exit cleanup_slots(void) 451 { 452 struct slot *slot, *next; 453 454 /* 455 * Unregister all of our slots with the pci_hotplug subsystem, 456 * and free up all memory that we had allocated. 457 */ 458 459 list_for_each_entry_safe(slot, next, &rpaphp_slot_head, 460 rpaphp_slot_list) { 461 list_del(&slot->rpaphp_slot_list); 462 pci_hp_deregister(&slot->hotplug_slot); 463 dealloc_slot_struct(slot); 464 } 465 } 466 467 static int __init rpaphp_init(void) 468 { 469 struct device_node *dn; 470 471 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 472 473 for_each_node_by_name(dn, "pci") 474 rpaphp_add_slot(dn); 475 476 return 0; 477 } 478 479 static void __exit rpaphp_exit(void) 480 { 481 cleanup_slots(); 482 } 483 484 static int enable_slot(struct hotplug_slot *hotplug_slot) 485 { 486 struct slot *slot = to_slot(hotplug_slot); 487 int state; 488 int retval; 489 490 if (slot->state == CONFIGURED) 491 return 0; 492 493 retval = rpaphp_get_sensor_state(slot, &state); 494 if (retval) 495 return retval; 496 497 if (state == PRESENT) { 498 pseries_eeh_init_edev_recursive(PCI_DN(slot->dn)); 499 500 pci_lock_rescan_remove(); 501 pci_hp_add_devices(slot->bus); 502 pci_unlock_rescan_remove(); 503 slot->state = CONFIGURED; 504 } else if (state == EMPTY) { 505 slot->state = EMPTY; 506 } else { 507 err("%s: slot[%s] is in invalid state\n", __func__, slot->name); 508 slot->state = NOT_VALID; 509 return -EINVAL; 510 } 511 512 slot->bus->max_bus_speed = get_max_bus_speed(slot); 513 return 0; 514 } 515 516 static int disable_slot(struct hotplug_slot *hotplug_slot) 517 { 518 struct slot *slot = to_slot(hotplug_slot); 519 if (slot->state == NOT_CONFIGURED) 520 return -EINVAL; 521 522 pci_lock_rescan_remove(); 523 pci_hp_remove_devices(slot->bus); 524 pci_unlock_rescan_remove(); 525 vm_unmap_aliases(); 526 527 slot->state = NOT_CONFIGURED; 528 return 0; 529 } 530 531 const struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { 532 .enable_slot = enable_slot, 533 .disable_slot = disable_slot, 534 .set_attention_status = set_attention_status, 535 .get_power_status = get_power_status, 536 .get_attention_status = get_attention_status, 537 .get_adapter_status = get_adapter_status, 538 }; 539 540 module_init(rpaphp_init); 541 module_exit(rpaphp_exit); 542