Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sparc64: add MDESC node name property to VIO device metadata

Add the MDESC node name of MDESC client to VIO device metadata. It is
later used to uniquely identify a node in the MDESC. VIO & MDESC APIs
are updated to handle this node name.

Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Liam Merwick <liam.merwick@oracle.com>
Reviewed-by: Shannon Nelson <shannon.nelson@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jag Raman and committed by
David S. Miller
06f3c3ac 0ab2fcd6

+65 -48
+4 -3
arch/sparc/include/asm/mdesc.h
··· 63 63 void mdesc_update(void); 64 64 65 65 struct mdesc_notifier_client { 66 - void (*add)(struct mdesc_handle *handle, u64 node); 67 - void (*remove)(struct mdesc_handle *handle, u64 node); 68 - 66 + void (*add)(struct mdesc_handle *handle, u64 node, 67 + const char *node_name); 68 + void (*remove)(struct mdesc_handle *handle, u64 node, 69 + const char *node_name); 69 70 const char *node_name; 70 71 struct mdesc_notifier_client *next; 71 72 };
+2
arch/sparc/include/asm/vio.h
··· 316 316 } 317 317 318 318 #define VIO_MAX_TYPE_LEN 32 319 + #define VIO_MAX_NAME_LEN 32 319 320 #define VIO_MAX_COMPAT_LEN 64 320 321 321 322 struct vio_dev { 322 323 u64 mp; 323 324 struct device_node *dp; 324 325 326 + char node_name[VIO_MAX_NAME_LEN]; 325 327 char type[VIO_MAX_TYPE_LEN]; 326 328 char compat[VIO_MAX_COMPAT_LEN]; 327 329 int compat_len;
+44 -38
arch/sparc/kernel/mdesc.c
··· 291 291 client_list = client; 292 292 293 293 mdesc_for_each_node_by_name(cur_mdesc, node, client->node_name) 294 - client->add(cur_mdesc, node); 294 + client->add(cur_mdesc, node, client->node_name); 295 295 296 296 mutex_unlock(&mdesc_mutex); 297 297 } ··· 399 399 static void invoke_on_missing(const char *name, 400 400 struct mdesc_handle *a, 401 401 struct mdesc_handle *b, 402 - void (*func)(struct mdesc_handle *, u64)) 402 + void (*func)(struct mdesc_handle *, u64, 403 + const char *node_name)) 403 404 { 404 - u64 node; 405 + mdesc_node_info_get_f get_info_func; 406 + mdesc_node_info_rel_f rel_info_func; 407 + mdesc_node_match_f node_match_func; 408 + union md_node_info a_node_info; 409 + union md_node_info b_node_info; 410 + bool found; 411 + u64 a_node; 412 + u64 b_node; 413 + int rv; 405 414 406 - mdesc_for_each_node_by_name(a, node, name) { 407 - int found = 0, is_vdc_port = 0; 408 - const char *name_prop; 409 - const u64 *id; 410 - u64 fnode; 415 + /* 416 + * Find the get_info, rel_info and node_match ops for the given 417 + * node name 418 + */ 419 + mdesc_get_node_ops(name, &get_info_func, &rel_info_func, 420 + &node_match_func); 411 421 412 - name_prop = mdesc_get_property(a, node, "name", NULL); 413 - if (name_prop && !strcmp(name_prop, "vdc-port")) { 414 - is_vdc_port = 1; 415 - id = parent_cfg_handle(a, node); 416 - } else 417 - id = mdesc_get_property(a, node, "id", NULL); 422 + /* If we didn't find a match, the node type is not supported */ 423 + if (!get_info_func || !rel_info_func || !node_match_func) { 424 + pr_err("MD: %s node type is not supported\n", name); 425 + return; 426 + } 418 427 419 - if (!id) { 420 - printk(KERN_ERR "MD: Cannot find ID for %s node.\n", 421 - (name_prop ? name_prop : name)); 428 + mdesc_for_each_node_by_name(a, a_node, name) { 429 + found = false; 430 + 431 + rv = get_info_func(a, a_node, &a_node_info); 432 + if (rv != 0) { 433 + pr_err("MD: Cannot find 1 or more required match properties for %s node.\n", 434 + name); 422 435 continue; 423 436 } 424 437 425 - mdesc_for_each_node_by_name(b, fnode, name) { 426 - const u64 *fid; 438 + /* Check each node in B for node matching a_node */ 439 + mdesc_for_each_node_by_name(b, b_node, name) { 440 + rv = get_info_func(b, b_node, &b_node_info); 441 + if (rv != 0) 442 + continue; 427 443 428 - if (is_vdc_port) { 429 - name_prop = mdesc_get_property(b, fnode, 430 - "name", NULL); 431 - if (!name_prop || 432 - strcmp(name_prop, "vdc-port")) 433 - continue; 434 - fid = parent_cfg_handle(b, fnode); 435 - if (!fid) { 436 - printk(KERN_ERR "MD: Cannot find ID " 437 - "for vdc-port node.\n"); 438 - continue; 439 - } 440 - } else 441 - fid = mdesc_get_property(b, fnode, 442 - "id", NULL); 443 - 444 - if (*id == *fid) { 445 - found = 1; 444 + if (node_match_func(&a_node_info, &b_node_info)) { 445 + found = true; 446 + rel_info_func(&b_node_info); 446 447 break; 447 448 } 449 + 450 + rel_info_func(&b_node_info); 448 451 } 452 + 453 + rel_info_func(&a_node_info); 454 + 449 455 if (!found) 450 - func(a, node); 456 + func(a, a_node, name); 451 457 } 452 458 } 453 459
+15 -7
arch/sparc/kernel/vio.c
··· 219 219 EXPORT_SYMBOL(vio_set_intr); 220 220 221 221 static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, 222 + const char *node_name, 222 223 struct device *parent) 223 224 { 224 225 const char *type, *compat, *bus_id_name; ··· 237 236 tlen = strlen(type) + 1; 238 237 } 239 238 } 240 - if (tlen > VIO_MAX_TYPE_LEN) { 239 + if (tlen > VIO_MAX_TYPE_LEN || strlen(type) >= VIO_MAX_TYPE_LEN) { 241 240 printk(KERN_ERR "VIO: Type string [%s] is too long.\n", 242 241 type); 243 242 return NULL; ··· 336 335 337 336 printk(KERN_INFO "VIO: Adding device %s\n", dev_name(&vdev->dev)); 338 337 338 + /* node_name is NULL for the parent/channel-devices node */ 339 + if (node_name != NULL) 340 + (void) snprintf(vdev->node_name, VIO_MAX_NAME_LEN, "%s", 341 + node_name); 342 + 339 343 err = device_register(&vdev->dev); 340 344 if (err) { 341 345 printk(KERN_ERR "VIO: Could not register device %s, err=%d\n", ··· 355 349 return vdev; 356 350 } 357 351 358 - static void vio_add(struct mdesc_handle *hp, u64 node) 352 + static void vio_add(struct mdesc_handle *hp, u64 node, 353 + const char *node_name) 359 354 { 360 - (void) vio_create_one(hp, node, &root_vdev->dev); 355 + (void) vio_create_one(hp, node, node_name, &root_vdev->dev); 361 356 } 362 357 363 358 struct vio_md_node_query { ··· 382 375 return 1; 383 376 } 384 377 385 - static void vio_remove(struct mdesc_handle *hp, u64 node) 378 + static void vio_remove(struct mdesc_handle *hp, u64 node, const char *node_name) 386 379 { 387 380 const char *type; 388 381 const u64 *id, *cfg_handle; ··· 453 446 * under "openboot" that we should not mess with as aparently that is 454 447 * reserved exclusively for OBP use. 455 448 */ 456 - static void vio_add_ds(struct mdesc_handle *hp, u64 node) 449 + static void vio_add_ds(struct mdesc_handle *hp, u64 node, 450 + const char *node_name) 457 451 { 458 452 int found; 459 453 u64 a; ··· 471 463 } 472 464 473 465 if (found) 474 - (void) vio_create_one(hp, node, &root_vdev->dev); 466 + (void) vio_create_one(hp, node, node_name, &root_vdev->dev); 475 467 } 476 468 477 469 static struct mdesc_notifier_client vio_ds_notifier = { ··· 538 530 539 531 cdev_cfg_handle = *cfg_handle; 540 532 541 - root_vdev = vio_create_one(hp, root, NULL); 533 + root_vdev = vio_create_one(hp, root, NULL, NULL); 542 534 err = -ENODEV; 543 535 if (!root_vdev) { 544 536 printk(KERN_ERR "VIO: Could not create root device.\n");