diff options
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r-- | drivers/clk/clk.c | 131 |
1 files changed, 49 insertions, 82 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 0f686a9dac3e..ea67ac81c6f9 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -1125,8 +1125,10 @@ static int clk_core_round_rate_nolock(struct clk_core *core, | |||
1125 | { | 1125 | { |
1126 | lockdep_assert_held(&prepare_lock); | 1126 | lockdep_assert_held(&prepare_lock); |
1127 | 1127 | ||
1128 | if (!core) | 1128 | if (!core) { |
1129 | req->rate = 0; | ||
1129 | return 0; | 1130 | return 0; |
1131 | } | ||
1130 | 1132 | ||
1131 | clk_core_init_rate_req(core, req); | 1133 | clk_core_init_rate_req(core, req); |
1132 | 1134 | ||
@@ -2309,8 +2311,11 @@ static int clk_core_set_phase_nolock(struct clk_core *core, int degrees) | |||
2309 | 2311 | ||
2310 | trace_clk_set_phase(core, degrees); | 2312 | trace_clk_set_phase(core, degrees); |
2311 | 2313 | ||
2312 | if (core->ops->set_phase) | 2314 | if (core->ops->set_phase) { |
2313 | ret = core->ops->set_phase(core->hw, degrees); | 2315 | ret = core->ops->set_phase(core->hw, degrees); |
2316 | if (!ret) | ||
2317 | core->phase = degrees; | ||
2318 | } | ||
2314 | 2319 | ||
2315 | trace_clk_set_phase_complete(core, degrees); | 2320 | trace_clk_set_phase_complete(core, degrees); |
2316 | 2321 | ||
@@ -2370,6 +2375,9 @@ static int clk_core_get_phase(struct clk_core *core) | |||
2370 | int ret; | 2375 | int ret; |
2371 | 2376 | ||
2372 | clk_prepare_lock(); | 2377 | clk_prepare_lock(); |
2378 | /* Always try to update cached phase if possible */ | ||
2379 | if (core->ops->get_phase) | ||
2380 | core->phase = core->ops->get_phase(core->hw); | ||
2373 | ret = core->phase; | 2381 | ret = core->phase; |
2374 | clk_prepare_unlock(); | 2382 | clk_prepare_unlock(); |
2375 | 2383 | ||
@@ -2486,19 +2494,7 @@ static int clk_summary_show(struct seq_file *s, void *data) | |||
2486 | 2494 | ||
2487 | return 0; | 2495 | return 0; |
2488 | } | 2496 | } |
2489 | 2497 | DEFINE_SHOW_ATTRIBUTE(clk_summary); | |
2490 | |||
2491 | static int clk_summary_open(struct inode *inode, struct file *file) | ||
2492 | { | ||
2493 | return single_open(file, clk_summary_show, inode->i_private); | ||
2494 | } | ||
2495 | |||
2496 | static const struct file_operations clk_summary_fops = { | ||
2497 | .open = clk_summary_open, | ||
2498 | .read = seq_read, | ||
2499 | .llseek = seq_lseek, | ||
2500 | .release = single_release, | ||
2501 | }; | ||
2502 | 2498 | ||
2503 | static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) | 2499 | static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) |
2504 | { | 2500 | { |
@@ -2532,7 +2528,7 @@ static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level) | |||
2532 | seq_putc(s, '}'); | 2528 | seq_putc(s, '}'); |
2533 | } | 2529 | } |
2534 | 2530 | ||
2535 | static int clk_dump(struct seq_file *s, void *data) | 2531 | static int clk_dump_show(struct seq_file *s, void *data) |
2536 | { | 2532 | { |
2537 | struct clk_core *c; | 2533 | struct clk_core *c; |
2538 | bool first_node = true; | 2534 | bool first_node = true; |
@@ -2555,19 +2551,7 @@ static int clk_dump(struct seq_file *s, void *data) | |||
2555 | seq_puts(s, "}\n"); | 2551 | seq_puts(s, "}\n"); |
2556 | return 0; | 2552 | return 0; |
2557 | } | 2553 | } |
2558 | 2554 | DEFINE_SHOW_ATTRIBUTE(clk_dump); | |
2559 | |||
2560 | static int clk_dump_open(struct inode *inode, struct file *file) | ||
2561 | { | ||
2562 | return single_open(file, clk_dump, inode->i_private); | ||
2563 | } | ||
2564 | |||
2565 | static const struct file_operations clk_dump_fops = { | ||
2566 | .open = clk_dump_open, | ||
2567 | .read = seq_read, | ||
2568 | .llseek = seq_lseek, | ||
2569 | .release = single_release, | ||
2570 | }; | ||
2571 | 2555 | ||
2572 | static const struct { | 2556 | static const struct { |
2573 | unsigned long flag; | 2557 | unsigned long flag; |
@@ -2589,7 +2573,7 @@ static const struct { | |||
2589 | #undef ENTRY | 2573 | #undef ENTRY |
2590 | }; | 2574 | }; |
2591 | 2575 | ||
2592 | static int clk_flags_dump(struct seq_file *s, void *data) | 2576 | static int clk_flags_show(struct seq_file *s, void *data) |
2593 | { | 2577 | { |
2594 | struct clk_core *core = s->private; | 2578 | struct clk_core *core = s->private; |
2595 | unsigned long flags = core->flags; | 2579 | unsigned long flags = core->flags; |
@@ -2608,20 +2592,9 @@ static int clk_flags_dump(struct seq_file *s, void *data) | |||
2608 | 2592 | ||
2609 | return 0; | 2593 | return 0; |
2610 | } | 2594 | } |
2595 | DEFINE_SHOW_ATTRIBUTE(clk_flags); | ||
2611 | 2596 | ||
2612 | static int clk_flags_open(struct inode *inode, struct file *file) | 2597 | static int possible_parents_show(struct seq_file *s, void *data) |
2613 | { | ||
2614 | return single_open(file, clk_flags_dump, inode->i_private); | ||
2615 | } | ||
2616 | |||
2617 | static const struct file_operations clk_flags_fops = { | ||
2618 | .open = clk_flags_open, | ||
2619 | .read = seq_read, | ||
2620 | .llseek = seq_lseek, | ||
2621 | .release = single_release, | ||
2622 | }; | ||
2623 | |||
2624 | static int possible_parents_dump(struct seq_file *s, void *data) | ||
2625 | { | 2598 | { |
2626 | struct clk_core *core = s->private; | 2599 | struct clk_core *core = s->private; |
2627 | int i; | 2600 | int i; |
@@ -2633,18 +2606,7 @@ static int possible_parents_dump(struct seq_file *s, void *data) | |||
2633 | 2606 | ||
2634 | return 0; | 2607 | return 0; |
2635 | } | 2608 | } |
2636 | 2609 | DEFINE_SHOW_ATTRIBUTE(possible_parents); | |
2637 | static int possible_parents_open(struct inode *inode, struct file *file) | ||
2638 | { | ||
2639 | return single_open(file, possible_parents_dump, inode->i_private); | ||
2640 | } | ||
2641 | |||
2642 | static const struct file_operations possible_parents_fops = { | ||
2643 | .open = possible_parents_open, | ||
2644 | .read = seq_read, | ||
2645 | .llseek = seq_lseek, | ||
2646 | .release = single_release, | ||
2647 | }; | ||
2648 | 2610 | ||
2649 | static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) | 2611 | static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) |
2650 | { | 2612 | { |
@@ -2928,6 +2890,17 @@ static int __clk_core_init(struct clk_core *core) | |||
2928 | } | 2890 | } |
2929 | 2891 | ||
2930 | /* | 2892 | /* |
2893 | * optional platform-specific magic | ||
2894 | * | ||
2895 | * The .init callback is not used by any of the basic clock types, but | ||
2896 | * exists for weird hardware that must perform initialization magic. | ||
2897 | * Please consider other ways of solving initialization problems before | ||
2898 | * using this callback, as its use is discouraged. | ||
2899 | */ | ||
2900 | if (core->ops->init) | ||
2901 | core->ops->init(core->hw); | ||
2902 | |||
2903 | /* | ||
2931 | * Set clk's accuracy. The preferred method is to use | 2904 | * Set clk's accuracy. The preferred method is to use |
2932 | * .recalc_accuracy. For simple clocks and lazy developers the default | 2905 | * .recalc_accuracy. For simple clocks and lazy developers the default |
2933 | * fallback is to use the parent's accuracy. If a clock doesn't have a | 2906 | * fallback is to use the parent's accuracy. If a clock doesn't have a |
@@ -2968,48 +2941,42 @@ static int __clk_core_init(struct clk_core *core) | |||
2968 | core->rate = core->req_rate = rate; | 2941 | core->rate = core->req_rate = rate; |
2969 | 2942 | ||
2970 | /* | 2943 | /* |
2944 | * Enable CLK_IS_CRITICAL clocks so newly added critical clocks | ||
2945 | * don't get accidentally disabled when walking the orphan tree and | ||
2946 | * reparenting clocks | ||
2947 | */ | ||
2948 | if (core->flags & CLK_IS_CRITICAL) { | ||
2949 | unsigned long flags; | ||
2950 | |||
2951 | clk_core_prepare(core); | ||
2952 | |||
2953 | flags = clk_enable_lock(); | ||
2954 | clk_core_enable(core); | ||
2955 | clk_enable_unlock(flags); | ||
2956 | } | ||
2957 | |||
2958 | /* | ||
2971 | * walk the list of orphan clocks and reparent any that newly finds a | 2959 | * walk the list of orphan clocks and reparent any that newly finds a |
2972 | * parent. | 2960 | * parent. |
2973 | */ | 2961 | */ |
2974 | hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { | 2962 | hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { |
2975 | struct clk_core *parent = __clk_init_parent(orphan); | 2963 | struct clk_core *parent = __clk_init_parent(orphan); |
2976 | unsigned long flags; | ||
2977 | 2964 | ||
2978 | /* | 2965 | /* |
2979 | * we could call __clk_set_parent, but that would result in a | 2966 | * We need to use __clk_set_parent_before() and _after() to |
2980 | * redundant call to the .set_rate op, if it exists | 2967 | * to properly migrate any prepare/enable count of the orphan |
2968 | * clock. This is important for CLK_IS_CRITICAL clocks, which | ||
2969 | * are enabled during init but might not have a parent yet. | ||
2981 | */ | 2970 | */ |
2982 | if (parent) { | 2971 | if (parent) { |
2983 | /* update the clk tree topology */ | 2972 | /* update the clk tree topology */ |
2984 | flags = clk_enable_lock(); | 2973 | __clk_set_parent_before(orphan, parent); |
2985 | clk_reparent(orphan, parent); | 2974 | __clk_set_parent_after(orphan, parent, NULL); |
2986 | clk_enable_unlock(flags); | ||
2987 | __clk_recalc_accuracies(orphan); | 2975 | __clk_recalc_accuracies(orphan); |
2988 | __clk_recalc_rates(orphan, 0); | 2976 | __clk_recalc_rates(orphan, 0); |
2989 | } | 2977 | } |
2990 | } | 2978 | } |
2991 | 2979 | ||
2992 | /* | ||
2993 | * optional platform-specific magic | ||
2994 | * | ||
2995 | * The .init callback is not used by any of the basic clock types, but | ||
2996 | * exists for weird hardware that must perform initialization magic. | ||
2997 | * Please consider other ways of solving initialization problems before | ||
2998 | * using this callback, as its use is discouraged. | ||
2999 | */ | ||
3000 | if (core->ops->init) | ||
3001 | core->ops->init(core->hw); | ||
3002 | |||
3003 | if (core->flags & CLK_IS_CRITICAL) { | ||
3004 | unsigned long flags; | ||
3005 | |||
3006 | clk_core_prepare(core); | ||
3007 | |||
3008 | flags = clk_enable_lock(); | ||
3009 | clk_core_enable(core); | ||
3010 | clk_enable_unlock(flags); | ||
3011 | } | ||
3012 | |||
3013 | kref_init(&core->ref); | 2980 | kref_init(&core->ref); |
3014 | out: | 2981 | out: |
3015 | clk_pm_runtime_put(core); | 2982 | clk_pm_runtime_put(core); |