@@ -39,6 +39,13 @@ static LIST_HEAD(clk_notifier_list);
3939
4040/*** private data structures ***/
4141
42+ struct clk_parent_map {
43+ const struct clk_hw * hw ;
44+ struct clk_core * core ;
45+ const char * fw_name ;
46+ const char * name ;
47+ };
48+
4249struct clk_core {
4350 const char * name ;
4451 const struct clk_ops * ops ;
@@ -47,8 +54,7 @@ struct clk_core {
4754 struct device * dev ;
4855 struct device_node * of_node ;
4956 struct clk_core * parent ;
50- const char * * parent_names ;
51- struct clk_core * * parents ;
57+ struct clk_parent_map * parents ;
5258 u8 num_parents ;
5359 u8 new_parent_index ;
5460 unsigned long rate ;
@@ -317,17 +323,92 @@ static struct clk_core *clk_core_lookup(const char *name)
317323 return NULL ;
318324}
319325
326+ /**
327+ * clk_core_get - Find the parent of a clk using a clock specifier in DT
328+ * @core: clk to find parent of
329+ * @name: name to search for in 'clock-names' of device providing clk
330+ *
331+ * This is the preferred method for clk providers to find the parent of a
332+ * clk when that parent is external to the clk controller. The parent_names
333+ * array is indexed and treated as a local name matching a string in the device
334+ * node's 'clock-names' property. This allows clk providers to use their own
335+ * namespace instead of looking for a globally unique parent string.
336+ *
337+ * For example the following DT snippet would allow a clock registered by the
338+ * clock-controller@c001 that has a clk_init_data::parent_data array
339+ * with 'xtal' in the 'name' member to find the clock provided by the
340+ * clock-controller@f00abcd without needing to get the globally unique name of
341+ * the xtal clk.
342+ *
343+ * parent: clock-controller@f00abcd {
344+ * reg = <0xf00abcd 0xabcd>;
345+ * #clock-cells = <0>;
346+ * };
347+ *
348+ * clock-controller@c001 {
349+ * reg = <0xc001 0xf00d>;
350+ * clocks = <&parent>;
351+ * clock-names = "xtal";
352+ * #clock-cells = <1>;
353+ * };
354+ *
355+ * Returns: -ENOENT when the provider can't be found or the clk doesn't
356+ * exist in the provider. -EINVAL when the name can't be found. NULL when the
357+ * provider knows about the clk but it isn't provided on this system.
358+ * A valid clk_core pointer when the clk can be found in the provider.
359+ */
360+ static struct clk_core * clk_core_get (struct clk_core * core , const char * name )
361+ {
362+ struct clk_hw * hw ;
363+ struct device_node * np = core -> of_node ;
364+
365+ if (!np )
366+ return ERR_PTR (- ENOENT );
367+
368+ /* TODO: Support clkdev clk_lookups */
369+ hw = of_clk_get_hw (np , -1 , name );
370+ if (IS_ERR_OR_NULL (hw ))
371+ return ERR_CAST (hw );
372+
373+ return hw -> core ;
374+ }
375+
376+ static void clk_core_fill_parent_index (struct clk_core * core , u8 index )
377+ {
378+ struct clk_parent_map * entry = & core -> parents [index ];
379+ struct clk_core * parent = ERR_PTR (- ENOENT );
380+
381+ if (entry -> hw ) {
382+ parent = entry -> hw -> core ;
383+ /*
384+ * We have a direct reference but it isn't registered yet?
385+ * Orphan it and let clk_reparent() update the orphan status
386+ * when the parent is registered.
387+ */
388+ if (!parent )
389+ parent = ERR_PTR (- EPROBE_DEFER );
390+ } else {
391+ if (entry -> fw_name )
392+ parent = clk_core_get (core , entry -> fw_name );
393+ if (IS_ERR (parent ) && PTR_ERR (parent ) == - ENOENT )
394+ parent = clk_core_lookup (entry -> name );
395+ }
396+
397+ /* Only cache it if it's not an error */
398+ if (!IS_ERR (parent ))
399+ entry -> core = parent ;
400+ }
401+
320402static struct clk_core * clk_core_get_parent_by_index (struct clk_core * core ,
321403 u8 index )
322404{
323- if (!core || index >= core -> num_parents )
405+ if (!core || index >= core -> num_parents || ! core -> parents )
324406 return NULL ;
325407
326- if (!core -> parents [index ])
327- core -> parents [index ] =
328- clk_core_lookup (core -> parent_names [index ]);
408+ if (!core -> parents [index ].core )
409+ clk_core_fill_parent_index (core , index );
329410
330- return core -> parents [index ];
411+ return core -> parents [index ]. core ;
331412}
332413
333414struct clk_hw *
@@ -1520,15 +1601,15 @@ static int clk_fetch_parent_index(struct clk_core *core,
15201601 return - EINVAL ;
15211602
15221603 for (i = 0 ; i < core -> num_parents ; i ++ ) {
1523- if (core -> parents [i ] == parent )
1604+ if (core -> parents [i ]. core == parent )
15241605 return i ;
15251606
1526- if (core -> parents [i ])
1607+ if (core -> parents [i ]. core )
15271608 continue ;
15281609
15291610 /* Fallback to comparing globally unique names */
1530- if (!strcmp (parent -> name , core -> parent_names [i ])) {
1531- core -> parents [i ] = parent ;
1611+ if (!strcmp (parent -> name , core -> parents [i ]. name )) {
1612+ core -> parents [i ]. core = parent ;
15321613 return i ;
15331614 }
15341615 }
@@ -2294,6 +2375,7 @@ void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent)
22942375bool clk_has_parent (struct clk * clk , struct clk * parent )
22952376{
22962377 struct clk_core * core , * parent_core ;
2378+ int i ;
22972379
22982380 /* NULL clocks should be nops, so return success if either is NULL. */
22992381 if (!clk || !parent )
@@ -2306,8 +2388,11 @@ bool clk_has_parent(struct clk *clk, struct clk *parent)
23062388 if (core -> parent == parent_core )
23072389 return true;
23082390
2309- return match_string (core -> parent_names , core -> num_parents ,
2310- parent_core -> name ) >= 0 ;
2391+ for (i = 0 ; i < core -> num_parents ; i ++ )
2392+ if (!strcmp (core -> parents [i ].name , parent_core -> name ))
2393+ return true;
2394+
2395+ return false;
23112396}
23122397EXPORT_SYMBOL_GPL (clk_has_parent );
23132398
@@ -2890,9 +2975,9 @@ static int possible_parents_show(struct seq_file *s, void *data)
28902975 int i ;
28912976
28922977 for (i = 0 ; i < core -> num_parents - 1 ; i ++ )
2893- seq_printf (s , "%s " , core -> parent_names [i ]);
2978+ seq_printf (s , "%s " , core -> parents [i ]. name );
28942979
2895- seq_printf (s , "%s\n" , core -> parent_names [i ]);
2980+ seq_printf (s , "%s\n" , core -> parents [i ]. name );
28962981
28972982 return 0 ;
28982983}
@@ -3026,7 +3111,7 @@ static inline void clk_debug_unregister(struct clk_core *core)
30263111 */
30273112static int __clk_core_init (struct clk_core * core )
30283113{
3029- int i , ret ;
3114+ int ret ;
30303115 struct clk_core * orphan ;
30313116 struct hlist_node * tmp2 ;
30323117 unsigned long rate ;
@@ -3080,12 +3165,6 @@ static int __clk_core_init(struct clk_core *core)
30803165 goto out ;
30813166 }
30823167
3083- /* throw a WARN if any entries in parent_names are NULL */
3084- for (i = 0 ; i < core -> num_parents ; i ++ )
3085- WARN (!core -> parent_names [i ],
3086- "%s: invalid NULL in %s's .parent_names\n" ,
3087- __func__ , core -> name );
3088-
30893168 core -> parent = __clk_init_parent (core );
30903169
30913170 /*
@@ -3314,10 +3393,102 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
33143393 return clk ;
33153394}
33163395
3396+ static int clk_cpy_name (const char * * dst_p , const char * src , bool must_exist )
3397+ {
3398+ const char * dst ;
3399+
3400+ if (!src ) {
3401+ if (must_exist )
3402+ return - EINVAL ;
3403+ return 0 ;
3404+ }
3405+
3406+ * dst_p = dst = kstrdup_const (src , GFP_KERNEL );
3407+ if (!dst )
3408+ return - ENOMEM ;
3409+
3410+ return 0 ;
3411+ }
3412+
3413+ static int clk_core_populate_parent_map (struct clk_core * core )
3414+ {
3415+ const struct clk_init_data * init = core -> hw -> init ;
3416+ u8 num_parents = init -> num_parents ;
3417+ const char * const * parent_names = init -> parent_names ;
3418+ const struct clk_hw * * parent_hws = init -> parent_hws ;
3419+ const struct clk_parent_data * parent_data = init -> parent_data ;
3420+ int i , ret = 0 ;
3421+ struct clk_parent_map * parents , * parent ;
3422+
3423+ if (!num_parents )
3424+ return 0 ;
3425+
3426+ /*
3427+ * Avoid unnecessary string look-ups of clk_core's possible parents by
3428+ * having a cache of names/clk_hw pointers to clk_core pointers.
3429+ */
3430+ parents = kcalloc (num_parents , sizeof (* parents ), GFP_KERNEL );
3431+ core -> parents = parents ;
3432+ if (!parents )
3433+ return - ENOMEM ;
3434+
3435+ /* Copy everything over because it might be __initdata */
3436+ for (i = 0 , parent = parents ; i < num_parents ; i ++ , parent ++ ) {
3437+ if (parent_names ) {
3438+ /* throw a WARN if any entries are NULL */
3439+ WARN (!parent_names [i ],
3440+ "%s: invalid NULL in %s's .parent_names\n" ,
3441+ __func__ , core -> name );
3442+ ret = clk_cpy_name (& parent -> name , parent_names [i ],
3443+ true);
3444+ } else if (parent_data ) {
3445+ parent -> hw = parent_data [i ].hw ;
3446+ ret = clk_cpy_name (& parent -> fw_name ,
3447+ parent_data [i ].fw_name , false);
3448+ if (!ret )
3449+ ret = clk_cpy_name (& parent -> name ,
3450+ parent_data [i ].name ,
3451+ false);
3452+ } else if (parent_hws ) {
3453+ parent -> hw = parent_hws [i ];
3454+ } else {
3455+ ret = - EINVAL ;
3456+ WARN (1 , "Must specify parents if num_parents > 0\n" );
3457+ }
3458+
3459+ if (ret ) {
3460+ do {
3461+ kfree_const (parents [i ].name );
3462+ kfree_const (parents [i ].fw_name );
3463+ } while (-- i >= 0 );
3464+ kfree (parents );
3465+
3466+ return ret ;
3467+ }
3468+ }
3469+
3470+ return 0 ;
3471+ }
3472+
3473+ static void clk_core_free_parent_map (struct clk_core * core )
3474+ {
3475+ int i = core -> num_parents ;
3476+
3477+ if (!core -> num_parents )
3478+ return ;
3479+
3480+ while (-- i >= 0 ) {
3481+ kfree_const (core -> parents [i ].name );
3482+ kfree_const (core -> parents [i ].fw_name );
3483+ }
3484+
3485+ kfree (core -> parents );
3486+ }
3487+
33173488static struct clk *
33183489__clk_register (struct device * dev , struct device_node * np , struct clk_hw * hw )
33193490{
3320- int i , ret ;
3491+ int ret ;
33213492 struct clk_core * core ;
33223493
33233494 core = kzalloc (sizeof (* core ), GFP_KERNEL );
@@ -3351,33 +3522,9 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
33513522 core -> max_rate = ULONG_MAX ;
33523523 hw -> core = core ;
33533524
3354- /* allocate local copy in case parent_names is __initdata */
3355- core -> parent_names = kcalloc (core -> num_parents , sizeof (char * ),
3356- GFP_KERNEL );
3357-
3358- if (!core -> parent_names ) {
3359- ret = - ENOMEM ;
3360- goto fail_parent_names ;
3361- }
3362-
3363-
3364- /* copy each string name in case parent_names is __initdata */
3365- for (i = 0 ; i < core -> num_parents ; i ++ ) {
3366- core -> parent_names [i ] = kstrdup_const (hw -> init -> parent_names [i ],
3367- GFP_KERNEL );
3368- if (!core -> parent_names [i ]) {
3369- ret = - ENOMEM ;
3370- goto fail_parent_names_copy ;
3371- }
3372- }
3373-
3374- /* avoid unnecessary string look-ups of clk_core's possible parents. */
3375- core -> parents = kcalloc (core -> num_parents , sizeof (* core -> parents ),
3376- GFP_KERNEL );
3377- if (!core -> parents ) {
3378- ret = - ENOMEM ;
3525+ ret = clk_core_populate_parent_map (core );
3526+ if (ret )
33793527 goto fail_parents ;
3380- };
33813528
33823529 INIT_HLIST_HEAD (& core -> clks );
33833530
@@ -3388,7 +3535,7 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
33883535 hw -> clk = alloc_clk (core , NULL , NULL );
33893536 if (IS_ERR (hw -> clk )) {
33903537 ret = PTR_ERR (hw -> clk );
3391- goto fail_parents ;
3538+ goto fail_create_clk ;
33923539 }
33933540
33943541 clk_core_link_consumer (hw -> core , hw -> clk );
@@ -3404,13 +3551,9 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
34043551 free_clk (hw -> clk );
34053552 hw -> clk = NULL ;
34063553
3554+ fail_create_clk :
3555+ clk_core_free_parent_map (core );
34073556fail_parents :
3408- kfree (core -> parents );
3409- fail_parent_names_copy :
3410- while (-- i >= 0 )
3411- kfree_const (core -> parent_names [i ]);
3412- kfree (core -> parent_names );
3413- fail_parent_names :
34143557fail_ops :
34153558 kfree_const (core -> name );
34163559fail_name :
@@ -3473,15 +3616,10 @@ EXPORT_SYMBOL_GPL(of_clk_hw_register);
34733616static void __clk_release (struct kref * ref )
34743617{
34753618 struct clk_core * core = container_of (ref , struct clk_core , ref );
3476- int i = core -> num_parents ;
34773619
34783620 lockdep_assert_held (& prepare_lock );
34793621
3480- kfree (core -> parents );
3481- while (-- i >= 0 )
3482- kfree_const (core -> parent_names [i ]);
3483-
3484- kfree (core -> parent_names );
3622+ clk_core_free_parent_map (core );
34853623 kfree_const (core -> name );
34863624 kfree (core );
34873625}
0 commit comments