@@ -351,9 +351,9 @@ static struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec)
351
351
}
352
352
353
353
/**
354
- * of_icc_get () - get a path handle from a DT node based on name
354
+ * of_icc_get_by_index () - get a path handle from a DT node based on index
355
355
* @dev: device pointer for the consumer device
356
- * @name : interconnect path name
356
+ * @idx : interconnect path index
357
357
*
358
358
* This function will search for a path between two endpoints and return an
359
359
* icc_path handle on success. Use icc_put() to release constraints when they
@@ -365,13 +365,12 @@ static struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec)
365
365
* Return: icc_path pointer on success or ERR_PTR() on error. NULL is returned
366
366
* when the API is disabled or the "interconnects" DT property is missing.
367
367
*/
368
- struct icc_path * of_icc_get (struct device * dev , const char * name )
368
+ struct icc_path * of_icc_get_by_index (struct device * dev , int idx )
369
369
{
370
- struct icc_path * path = ERR_PTR ( - EPROBE_DEFER ) ;
370
+ struct icc_path * path ;
371
371
struct icc_node * src_node , * dst_node ;
372
- struct device_node * np = NULL ;
372
+ struct device_node * np ;
373
373
struct of_phandle_args src_args , dst_args ;
374
- int idx = 0 ;
375
374
int ret ;
376
375
377
376
if (!dev || !dev -> of_node )
@@ -391,12 +390,6 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
391
390
* lets support only global ids and extend this in the future if needed
392
391
* without breaking DT compatibility.
393
392
*/
394
- if (name ) {
395
- idx = of_property_match_string (np , "interconnect-names" , name );
396
- if (idx < 0 )
397
- return ERR_PTR (idx );
398
- }
399
-
400
393
ret = of_parse_phandle_with_args (np , "interconnects" ,
401
394
"#interconnect-cells" , idx * 2 ,
402
395
& src_args );
@@ -439,19 +432,62 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
439
432
return path ;
440
433
}
441
434
442
- if (name )
443
- path -> name = kstrdup_const (name , GFP_KERNEL );
444
- else
445
- path -> name = kasprintf (GFP_KERNEL , "%s-%s" ,
446
- src_node -> name , dst_node -> name );
447
-
435
+ path -> name = kasprintf (GFP_KERNEL , "%s-%s" ,
436
+ src_node -> name , dst_node -> name );
448
437
if (!path -> name ) {
449
438
kfree (path );
450
439
return ERR_PTR (- ENOMEM );
451
440
}
452
441
453
442
return path ;
454
443
}
444
+ EXPORT_SYMBOL_GPL (of_icc_get_by_index );
445
+
446
+ /**
447
+ * of_icc_get() - get a path handle from a DT node based on name
448
+ * @dev: device pointer for the consumer device
449
+ * @name: interconnect path name
450
+ *
451
+ * This function will search for a path between two endpoints and return an
452
+ * icc_path handle on success. Use icc_put() to release constraints when they
453
+ * are not needed anymore.
454
+ * If the interconnect API is disabled, NULL is returned and the consumer
455
+ * drivers will still build. Drivers are free to handle this specifically,
456
+ * but they don't have to.
457
+ *
458
+ * Return: icc_path pointer on success or ERR_PTR() on error. NULL is returned
459
+ * when the API is disabled or the "interconnects" DT property is missing.
460
+ */
461
+ struct icc_path * of_icc_get (struct device * dev , const char * name )
462
+ {
463
+ struct device_node * np ;
464
+ int idx = 0 ;
465
+
466
+ if (!dev || !dev -> of_node )
467
+ return ERR_PTR (- ENODEV );
468
+
469
+ np = dev -> of_node ;
470
+
471
+ /*
472
+ * When the consumer DT node do not have "interconnects" property
473
+ * return a NULL path to skip setting constraints.
474
+ */
475
+ if (!of_find_property (np , "interconnects" , NULL ))
476
+ return NULL ;
477
+
478
+ /*
479
+ * We use a combination of phandle and specifier for endpoint. For now
480
+ * lets support only global ids and extend this in the future if needed
481
+ * without breaking DT compatibility.
482
+ */
483
+ if (name ) {
484
+ idx = of_property_match_string (np , "interconnect-names" , name );
485
+ if (idx < 0 )
486
+ return ERR_PTR (idx );
487
+ }
488
+
489
+ return of_icc_get_by_index (dev , idx );
490
+ }
455
491
EXPORT_SYMBOL_GPL (of_icc_get );
456
492
457
493
/**
@@ -478,6 +514,24 @@ void icc_set_tag(struct icc_path *path, u32 tag)
478
514
}
479
515
EXPORT_SYMBOL_GPL (icc_set_tag );
480
516
517
+ /**
518
+ * icc_get_name() - Get name of the icc path
519
+ * @path: reference to the path returned by icc_get()
520
+ *
521
+ * This function is used by an interconnect consumer to get the name of the icc
522
+ * path.
523
+ *
524
+ * Returns a valid pointer on success, or NULL otherwise.
525
+ */
526
+ const char * icc_get_name (struct icc_path * path )
527
+ {
528
+ if (!path )
529
+ return NULL ;
530
+
531
+ return path -> name ;
532
+ }
533
+ EXPORT_SYMBOL_GPL (icc_get_name );
534
+
481
535
/**
482
536
* icc_set_bw() - set bandwidth constraints on an interconnect path
483
537
* @path: reference to the path returned by icc_get()
@@ -908,12 +962,7 @@ static int __init icc_init(void)
908
962
return 0 ;
909
963
}
910
964
911
- static void __exit icc_exit (void )
912
- {
913
- debugfs_remove_recursive (icc_debugfs_dir );
914
- }
915
- module_init (icc_init );
916
- module_exit (icc_exit );
965
+ device_initcall (icc_init );
917
966
918
967
MODULE_AUTHOR (
"Georgi Djakov <[email protected] >" );
919
968
MODULE_DESCRIPTION ("Interconnect Driver Core" );
0 commit comments