1ebafb63dSStephen Boyd // SPDX-License-Identifier: GPL-2.0
2b2476490SMike Turquette /*
3b2476490SMike Turquette * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
4b2476490SMike Turquette * Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
5b2476490SMike Turquette *
65fb94e9cSMauro Carvalho Chehab * Standard functionality for the common clock API. See Documentation/driver-api/clk.rst
7b2476490SMike Turquette */
8b2476490SMike Turquette
93c373117SStephen Boyd #include <linux/clk.h>
10b09d6d99SMichael Turquette #include <linux/clk-provider.h>
1186be408bSSylwester Nawrocki #include <linux/clk/clk-conf.h>
12b2476490SMike Turquette #include <linux/module.h>
13b2476490SMike Turquette #include <linux/mutex.h>
14b2476490SMike Turquette #include <linux/spinlock.h>
15b2476490SMike Turquette #include <linux/err.h>
16b2476490SMike Turquette #include <linux/list.h>
17b2476490SMike Turquette #include <linux/slab.h>
18766e6a4eSGrant Likely #include <linux/of.h>
1946c8773aSStephen Boyd #include <linux/device.h>
20f2f6c255SPrashant Gaikwad #include <linux/init.h>
219a34b453SMarek Szyprowski #include <linux/pm_runtime.h>
22533ddeb1SMike Turquette #include <linux/sched.h>
23562ef0b0SStephen Boyd #include <linux/clkdev.h>
24b2476490SMike Turquette
25d6782c26SSylwester Nawrocki #include "clk.h"
26d6782c26SSylwester Nawrocki
27b2476490SMike Turquette static DEFINE_SPINLOCK(enable_lock);
28b2476490SMike Turquette static DEFINE_MUTEX(prepare_lock);
29b2476490SMike Turquette
30533ddeb1SMike Turquette static struct task_struct *prepare_owner;
31533ddeb1SMike Turquette static struct task_struct *enable_owner;
32533ddeb1SMike Turquette
33533ddeb1SMike Turquette static int prepare_refcnt;
34533ddeb1SMike Turquette static int enable_refcnt;
35533ddeb1SMike Turquette
36b2476490SMike Turquette static HLIST_HEAD(clk_root_list);
37b2476490SMike Turquette static HLIST_HEAD(clk_orphan_list);
38b2476490SMike Turquette static LIST_HEAD(clk_notifier_list);
39b2476490SMike Turquette
4060ff482cSStephen Boyd /* List of registered clks that use runtime PM */
4160ff482cSStephen Boyd static HLIST_HEAD(clk_rpm_list);
4260ff482cSStephen Boyd static DEFINE_MUTEX(clk_rpm_list_lock);
4360ff482cSStephen Boyd
4475061a6fSStephen Boyd static const struct hlist_head *all_lists[] = {
45bdcf1dc2SStephen Boyd &clk_root_list,
46bdcf1dc2SStephen Boyd &clk_orphan_list,
47bdcf1dc2SStephen Boyd NULL,
48bdcf1dc2SStephen Boyd };
49bdcf1dc2SStephen Boyd
50b09d6d99SMichael Turquette /*** private data structures ***/
51b09d6d99SMichael Turquette
52fc0c209cSStephen Boyd struct clk_parent_map {
53fc0c209cSStephen Boyd const struct clk_hw *hw;
54fc0c209cSStephen Boyd struct clk_core *core;
55fc0c209cSStephen Boyd const char *fw_name;
56fc0c209cSStephen Boyd const char *name;
57601b6e93SStephen Boyd int index;
58fc0c209cSStephen Boyd };
59fc0c209cSStephen Boyd
60b09d6d99SMichael Turquette struct clk_core {
61b09d6d99SMichael Turquette const char *name;
62b09d6d99SMichael Turquette const struct clk_ops *ops;
63b09d6d99SMichael Turquette struct clk_hw *hw;
64b09d6d99SMichael Turquette struct module *owner;
659a34b453SMarek Szyprowski struct device *dev;
6660ff482cSStephen Boyd struct hlist_node rpm_node;
6789a5ddccSStephen Boyd struct device_node *of_node;
68b09d6d99SMichael Turquette struct clk_core *parent;
69fc0c209cSStephen Boyd struct clk_parent_map *parents;
70b09d6d99SMichael Turquette u8 num_parents;
71b09d6d99SMichael Turquette u8 new_parent_index;
72b09d6d99SMichael Turquette unsigned long rate;
731c8e6004STomeu Vizoso unsigned long req_rate;
74b09d6d99SMichael Turquette unsigned long new_rate;
75b09d6d99SMichael Turquette struct clk_core *new_parent;
76b09d6d99SMichael Turquette struct clk_core *new_child;
77b09d6d99SMichael Turquette unsigned long flags;
78e6500344SHeiko Stuebner bool orphan;
7924478839SMiquel Raynal bool rpm_enabled;
80b09d6d99SMichael Turquette unsigned int enable_count;
81b09d6d99SMichael Turquette unsigned int prepare_count;
82e55a839aSJerome Brunet unsigned int protect_count;
839783c0d9SStephen Boyd unsigned long min_rate;
849783c0d9SStephen Boyd unsigned long max_rate;
85b09d6d99SMichael Turquette unsigned long accuracy;
86b09d6d99SMichael Turquette int phase;
879fba738aSJerome Brunet struct clk_duty duty;
88b09d6d99SMichael Turquette struct hlist_head children;
89b09d6d99SMichael Turquette struct hlist_node child_node;
901c8e6004STomeu Vizoso struct hlist_head clks;
91b09d6d99SMichael Turquette unsigned int notifier_count;
92b09d6d99SMichael Turquette #ifdef CONFIG_DEBUG_FS
93b09d6d99SMichael Turquette struct dentry *dentry;
948c9a8a8fSMaxime Coquelin struct hlist_node debug_node;
95b09d6d99SMichael Turquette #endif
96b09d6d99SMichael Turquette struct kref ref;
97b09d6d99SMichael Turquette };
98b09d6d99SMichael Turquette
99dfc202eaSStephen Boyd #define CREATE_TRACE_POINTS
100dfc202eaSStephen Boyd #include <trace/events/clk.h>
101dfc202eaSStephen Boyd
102b09d6d99SMichael Turquette struct clk {
103b09d6d99SMichael Turquette struct clk_core *core;
104efa85048SStephen Boyd struct device *dev;
105b09d6d99SMichael Turquette const char *dev_id;
106b09d6d99SMichael Turquette const char *con_id;
1071c8e6004STomeu Vizoso unsigned long min_rate;
1081c8e6004STomeu Vizoso unsigned long max_rate;
10955e9b8b7SJerome Brunet unsigned int exclusive_count;
11050595f8bSStephen Boyd struct hlist_node clks_node;
111b09d6d99SMichael Turquette };
112b09d6d99SMichael Turquette
1139a34b453SMarek Szyprowski /*** runtime pm ***/
clk_pm_runtime_get(struct clk_core * core)1149a34b453SMarek Szyprowski static int clk_pm_runtime_get(struct clk_core *core)
1159a34b453SMarek Szyprowski {
11624478839SMiquel Raynal if (!core->rpm_enabled)
1179a34b453SMarek Szyprowski return 0;
1189a34b453SMarek Szyprowski
1193196a605SMinghao Chi return pm_runtime_resume_and_get(core->dev);
1209a34b453SMarek Szyprowski }
1219a34b453SMarek Szyprowski
clk_pm_runtime_put(struct clk_core * core)1229a34b453SMarek Szyprowski static void clk_pm_runtime_put(struct clk_core *core)
1239a34b453SMarek Szyprowski {
12424478839SMiquel Raynal if (!core->rpm_enabled)
1259a34b453SMarek Szyprowski return;
1269a34b453SMarek Szyprowski
1279a34b453SMarek Szyprowski pm_runtime_put_sync(core->dev);
1289a34b453SMarek Szyprowski }
1299a34b453SMarek Szyprowski
13060ff482cSStephen Boyd /**
13160ff482cSStephen Boyd * clk_pm_runtime_get_all() - Runtime "get" all clk provider devices
13260ff482cSStephen Boyd *
13360ff482cSStephen Boyd * Call clk_pm_runtime_get() on all runtime PM enabled clks in the clk tree so
13460ff482cSStephen Boyd * that disabling unused clks avoids a deadlock where a device is runtime PM
13560ff482cSStephen Boyd * resuming/suspending and the runtime PM callback is trying to grab the
13660ff482cSStephen Boyd * prepare_lock for something like clk_prepare_enable() while
13760ff482cSStephen Boyd * clk_disable_unused_subtree() holds the prepare_lock and is trying to runtime
13860ff482cSStephen Boyd * PM resume/suspend the device as well.
13960ff482cSStephen Boyd *
14060ff482cSStephen Boyd * Context: Acquires the 'clk_rpm_list_lock' and returns with the lock held on
14160ff482cSStephen Boyd * success. Otherwise the lock is released on failure.
14260ff482cSStephen Boyd *
14360ff482cSStephen Boyd * Return: 0 on success, negative errno otherwise.
14460ff482cSStephen Boyd */
clk_pm_runtime_get_all(void)14560ff482cSStephen Boyd static int clk_pm_runtime_get_all(void)
14660ff482cSStephen Boyd {
14760ff482cSStephen Boyd int ret;
14860ff482cSStephen Boyd struct clk_core *core, *failed;
14960ff482cSStephen Boyd
15060ff482cSStephen Boyd /*
15160ff482cSStephen Boyd * Grab the list lock to prevent any new clks from being registered
15260ff482cSStephen Boyd * or unregistered until clk_pm_runtime_put_all().
15360ff482cSStephen Boyd */
15460ff482cSStephen Boyd mutex_lock(&clk_rpm_list_lock);
15560ff482cSStephen Boyd
15660ff482cSStephen Boyd /*
15760ff482cSStephen Boyd * Runtime PM "get" all the devices that are needed for the clks
15860ff482cSStephen Boyd * currently registered. Do this without holding the prepare_lock, to
15960ff482cSStephen Boyd * avoid the deadlock.
16060ff482cSStephen Boyd */
16160ff482cSStephen Boyd hlist_for_each_entry(core, &clk_rpm_list, rpm_node) {
16260ff482cSStephen Boyd ret = clk_pm_runtime_get(core);
16360ff482cSStephen Boyd if (ret) {
16460ff482cSStephen Boyd failed = core;
16560ff482cSStephen Boyd pr_err("clk: Failed to runtime PM get '%s' for clk '%s'\n",
16660ff482cSStephen Boyd dev_name(failed->dev), failed->name);
16760ff482cSStephen Boyd goto err;
16860ff482cSStephen Boyd }
16960ff482cSStephen Boyd }
17060ff482cSStephen Boyd
17160ff482cSStephen Boyd return 0;
17260ff482cSStephen Boyd
17360ff482cSStephen Boyd err:
17460ff482cSStephen Boyd hlist_for_each_entry(core, &clk_rpm_list, rpm_node) {
17560ff482cSStephen Boyd if (core == failed)
17660ff482cSStephen Boyd break;
17760ff482cSStephen Boyd
17860ff482cSStephen Boyd clk_pm_runtime_put(core);
17960ff482cSStephen Boyd }
18060ff482cSStephen Boyd mutex_unlock(&clk_rpm_list_lock);
18160ff482cSStephen Boyd
18260ff482cSStephen Boyd return ret;
18360ff482cSStephen Boyd }
18460ff482cSStephen Boyd
18560ff482cSStephen Boyd /**
18660ff482cSStephen Boyd * clk_pm_runtime_put_all() - Runtime "put" all clk provider devices
18760ff482cSStephen Boyd *
18860ff482cSStephen Boyd * Put the runtime PM references taken in clk_pm_runtime_get_all() and release
18960ff482cSStephen Boyd * the 'clk_rpm_list_lock'.
19060ff482cSStephen Boyd */
clk_pm_runtime_put_all(void)19160ff482cSStephen Boyd static void clk_pm_runtime_put_all(void)
19260ff482cSStephen Boyd {
19360ff482cSStephen Boyd struct clk_core *core;
19460ff482cSStephen Boyd
19560ff482cSStephen Boyd hlist_for_each_entry(core, &clk_rpm_list, rpm_node)
19660ff482cSStephen Boyd clk_pm_runtime_put(core);
19760ff482cSStephen Boyd mutex_unlock(&clk_rpm_list_lock);
19860ff482cSStephen Boyd }
19960ff482cSStephen Boyd
clk_pm_runtime_init(struct clk_core * core)20060ff482cSStephen Boyd static void clk_pm_runtime_init(struct clk_core *core)
20160ff482cSStephen Boyd {
20260ff482cSStephen Boyd struct device *dev = core->dev;
20360ff482cSStephen Boyd
20460ff482cSStephen Boyd if (dev && pm_runtime_enabled(dev)) {
20560ff482cSStephen Boyd core->rpm_enabled = true;
20660ff482cSStephen Boyd
20760ff482cSStephen Boyd mutex_lock(&clk_rpm_list_lock);
20860ff482cSStephen Boyd hlist_add_head(&core->rpm_node, &clk_rpm_list);
20960ff482cSStephen Boyd mutex_unlock(&clk_rpm_list_lock);
21060ff482cSStephen Boyd }
21160ff482cSStephen Boyd }
21260ff482cSStephen Boyd
213eab89f69SMike Turquette /*** locking ***/
clk_prepare_lock(void)214eab89f69SMike Turquette static void clk_prepare_lock(void)
215eab89f69SMike Turquette {
216533ddeb1SMike Turquette if (!mutex_trylock(&prepare_lock)) {
217533ddeb1SMike Turquette if (prepare_owner == current) {
218533ddeb1SMike Turquette prepare_refcnt++;
219533ddeb1SMike Turquette return;
220533ddeb1SMike Turquette }
221eab89f69SMike Turquette mutex_lock(&prepare_lock);
222eab89f69SMike Turquette }
223533ddeb1SMike Turquette WARN_ON_ONCE(prepare_owner != NULL);
224533ddeb1SMike Turquette WARN_ON_ONCE(prepare_refcnt != 0);
225533ddeb1SMike Turquette prepare_owner = current;
226533ddeb1SMike Turquette prepare_refcnt = 1;
227533ddeb1SMike Turquette }
228eab89f69SMike Turquette
clk_prepare_unlock(void)229eab89f69SMike Turquette static void clk_prepare_unlock(void)
230eab89f69SMike Turquette {
231533ddeb1SMike Turquette WARN_ON_ONCE(prepare_owner != current);
232533ddeb1SMike Turquette WARN_ON_ONCE(prepare_refcnt == 0);
233533ddeb1SMike Turquette
234533ddeb1SMike Turquette if (--prepare_refcnt)
235533ddeb1SMike Turquette return;
236533ddeb1SMike Turquette prepare_owner = NULL;
237eab89f69SMike Turquette mutex_unlock(&prepare_lock);
238eab89f69SMike Turquette }
239eab89f69SMike Turquette
clk_enable_lock(void)240eab89f69SMike Turquette static unsigned long clk_enable_lock(void)
241a57aa185SStephen Boyd __acquires(enable_lock)
242eab89f69SMike Turquette {
243eab89f69SMike Turquette unsigned long flags;
244533ddeb1SMike Turquette
245a12aa8a6SDavid Lechner /*
246a12aa8a6SDavid Lechner * On UP systems, spin_trylock_irqsave() always returns true, even if
247a12aa8a6SDavid Lechner * we already hold the lock. So, in that case, we rely only on
248a12aa8a6SDavid Lechner * reference counting.
249a12aa8a6SDavid Lechner */
250a12aa8a6SDavid Lechner if (!IS_ENABLED(CONFIG_SMP) ||
251a12aa8a6SDavid Lechner !spin_trylock_irqsave(&enable_lock, flags)) {
252533ddeb1SMike Turquette if (enable_owner == current) {
253533ddeb1SMike Turquette enable_refcnt++;
254a57aa185SStephen Boyd __acquire(enable_lock);
255a12aa8a6SDavid Lechner if (!IS_ENABLED(CONFIG_SMP))
256a12aa8a6SDavid Lechner local_save_flags(flags);
257533ddeb1SMike Turquette return flags;
258533ddeb1SMike Turquette }
259eab89f69SMike Turquette spin_lock_irqsave(&enable_lock, flags);
260533ddeb1SMike Turquette }
261533ddeb1SMike Turquette WARN_ON_ONCE(enable_owner != NULL);
262533ddeb1SMike Turquette WARN_ON_ONCE(enable_refcnt != 0);
263533ddeb1SMike Turquette enable_owner = current;
264533ddeb1SMike Turquette enable_refcnt = 1;
265eab89f69SMike Turquette return flags;
266eab89f69SMike Turquette }
267eab89f69SMike Turquette
clk_enable_unlock(unsigned long flags)268eab89f69SMike Turquette static void clk_enable_unlock(unsigned long flags)
269a57aa185SStephen Boyd __releases(enable_lock)
270eab89f69SMike Turquette {
271533ddeb1SMike Turquette WARN_ON_ONCE(enable_owner != current);
272533ddeb1SMike Turquette WARN_ON_ONCE(enable_refcnt == 0);
273533ddeb1SMike Turquette
274a57aa185SStephen Boyd if (--enable_refcnt) {
275a57aa185SStephen Boyd __release(enable_lock);
276533ddeb1SMike Turquette return;
277a57aa185SStephen Boyd }
278533ddeb1SMike Turquette enable_owner = NULL;
279eab89f69SMike Turquette spin_unlock_irqrestore(&enable_lock, flags);
280eab89f69SMike Turquette }
281eab89f69SMike Turquette
clk_core_rate_is_protected(struct clk_core * core)282e55a839aSJerome Brunet static bool clk_core_rate_is_protected(struct clk_core *core)
283e55a839aSJerome Brunet {
284e55a839aSJerome Brunet return core->protect_count;
285e55a839aSJerome Brunet }
286e55a839aSJerome Brunet
clk_core_is_prepared(struct clk_core * core)2874dff95dcSStephen Boyd static bool clk_core_is_prepared(struct clk_core *core)
2881af599dfSPrashant Gaikwad {
2899a34b453SMarek Szyprowski bool ret = false;
2909a34b453SMarek Szyprowski
2914dff95dcSStephen Boyd /*
2924dff95dcSStephen Boyd * .is_prepared is optional for clocks that can prepare
2934dff95dcSStephen Boyd * fall back to software usage counter if it is missing
294b2476490SMike Turquette */
2954dff95dcSStephen Boyd if (!core->ops->is_prepared)
2964dff95dcSStephen Boyd return core->prepare_count;
297b2476490SMike Turquette
2989a34b453SMarek Szyprowski if (!clk_pm_runtime_get(core)) {
2999a34b453SMarek Szyprowski ret = core->ops->is_prepared(core->hw);
3009a34b453SMarek Szyprowski clk_pm_runtime_put(core);
3019a34b453SMarek Szyprowski }
3029a34b453SMarek Szyprowski
3039a34b453SMarek Szyprowski return ret;
304b2476490SMike Turquette }
305b2476490SMike Turquette
clk_core_is_enabled(struct clk_core * core)3064dff95dcSStephen Boyd static bool clk_core_is_enabled(struct clk_core *core)
3074dff95dcSStephen Boyd {
3089a34b453SMarek Szyprowski bool ret = false;
3099a34b453SMarek Szyprowski
3104dff95dcSStephen Boyd /*
3114dff95dcSStephen Boyd * .is_enabled is only mandatory for clocks that gate
3124dff95dcSStephen Boyd * fall back to software usage counter if .is_enabled is missing
313fcb0ee6aSSylwester Nawrocki */
3144dff95dcSStephen Boyd if (!core->ops->is_enabled)
3154dff95dcSStephen Boyd return core->enable_count;
3164dff95dcSStephen Boyd
3179a34b453SMarek Szyprowski /*
3189a34b453SMarek Szyprowski * Check if clock controller's device is runtime active before
3199a34b453SMarek Szyprowski * calling .is_enabled callback. If not, assume that clock is
3209a34b453SMarek Szyprowski * disabled, because we might be called from atomic context, from
3219a34b453SMarek Szyprowski * which pm_runtime_get() is not allowed.
3229a34b453SMarek Szyprowski * This function is called mainly from clk_disable_unused_subtree,
3239a34b453SMarek Szyprowski * which ensures proper runtime pm activation of controller before
3249a34b453SMarek Szyprowski * taking enable spinlock, but the below check is needed if one tries
3259a34b453SMarek Szyprowski * to call it from other places.
3269a34b453SMarek Szyprowski */
32724478839SMiquel Raynal if (core->rpm_enabled) {
3289a34b453SMarek Szyprowski pm_runtime_get_noresume(core->dev);
3299a34b453SMarek Szyprowski if (!pm_runtime_active(core->dev)) {
3309a34b453SMarek Szyprowski ret = false;
3319a34b453SMarek Szyprowski goto done;
3329a34b453SMarek Szyprowski }
3339a34b453SMarek Szyprowski }
3349a34b453SMarek Szyprowski
33579200d58SChen-Yu Tsai /*
33679200d58SChen-Yu Tsai * This could be called with the enable lock held, or from atomic
33779200d58SChen-Yu Tsai * context. If the parent isn't enabled already, we can't do
33879200d58SChen-Yu Tsai * anything here. We can also assume this clock isn't enabled.
33979200d58SChen-Yu Tsai */
34079200d58SChen-Yu Tsai if ((core->flags & CLK_OPS_PARENT_ENABLE) && core->parent)
34179200d58SChen-Yu Tsai if (!clk_core_is_enabled(core->parent)) {
34279200d58SChen-Yu Tsai ret = false;
34379200d58SChen-Yu Tsai goto done;
34479200d58SChen-Yu Tsai }
34579200d58SChen-Yu Tsai
3469a34b453SMarek Szyprowski ret = core->ops->is_enabled(core->hw);
3479a34b453SMarek Szyprowski done:
34824478839SMiquel Raynal if (core->rpm_enabled)
349756efe13SDong Aisheng pm_runtime_put(core->dev);
3509a34b453SMarek Szyprowski
3519a34b453SMarek Szyprowski return ret;
352fcb0ee6aSSylwester Nawrocki }
353fcb0ee6aSSylwester Nawrocki
354b2476490SMike Turquette /*** helper functions ***/
355b2476490SMike Turquette
__clk_get_name(const struct clk * clk)356b76281cbSGeert Uytterhoeven const char *__clk_get_name(const struct clk *clk)
357b2476490SMike Turquette {
358035a61c3STomeu Vizoso return !clk ? NULL : clk->core->name;
359b2476490SMike Turquette }
3604895084cSNiels de Vos EXPORT_SYMBOL_GPL(__clk_get_name);
361b2476490SMike Turquette
clk_hw_get_name(const struct clk_hw * hw)362e7df6f6eSStephen Boyd const char *clk_hw_get_name(const struct clk_hw *hw)
3631a9c069cSStephen Boyd {
3641a9c069cSStephen Boyd return hw->core->name;
3651a9c069cSStephen Boyd }
3661a9c069cSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_name);
3671a9c069cSStephen Boyd
__clk_get_hw(struct clk * clk)36865800b2cSRuss Dill struct clk_hw *__clk_get_hw(struct clk *clk)
369b2476490SMike Turquette {
370035a61c3STomeu Vizoso return !clk ? NULL : clk->core->hw;
371b2476490SMike Turquette }
3720b7f04b8SStephen Boyd EXPORT_SYMBOL_GPL(__clk_get_hw);
373b2476490SMike Turquette
clk_hw_get_num_parents(const struct clk_hw * hw)374e7df6f6eSStephen Boyd unsigned int clk_hw_get_num_parents(const struct clk_hw *hw)
3751a9c069cSStephen Boyd {
3761a9c069cSStephen Boyd return hw->core->num_parents;
3771a9c069cSStephen Boyd }
3781a9c069cSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_num_parents);
3791a9c069cSStephen Boyd
clk_hw_get_parent(const struct clk_hw * hw)380e7df6f6eSStephen Boyd struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw)
3811a9c069cSStephen Boyd {
3821a9c069cSStephen Boyd return hw->core->parent ? hw->core->parent->hw : NULL;
3831a9c069cSStephen Boyd }
3841a9c069cSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_parent);
3851a9c069cSStephen Boyd
__clk_lookup_subtree(const char * name,struct clk_core * core)3864dff95dcSStephen Boyd static struct clk_core *__clk_lookup_subtree(const char *name,
3874dff95dcSStephen Boyd struct clk_core *core)
3884dff95dcSStephen Boyd {
3894dff95dcSStephen Boyd struct clk_core *child;
3904dff95dcSStephen Boyd struct clk_core *ret;
3914dff95dcSStephen Boyd
3924dff95dcSStephen Boyd if (!strcmp(core->name, name))
3934dff95dcSStephen Boyd return core;
3944dff95dcSStephen Boyd
3954dff95dcSStephen Boyd hlist_for_each_entry(child, &core->children, child_node) {
3964dff95dcSStephen Boyd ret = __clk_lookup_subtree(name, child);
3974dff95dcSStephen Boyd if (ret)
3984dff95dcSStephen Boyd return ret;
3994dff95dcSStephen Boyd }
4004dff95dcSStephen Boyd
4014dff95dcSStephen Boyd return NULL;
4024dff95dcSStephen Boyd }
4034dff95dcSStephen Boyd
clk_core_lookup(const char * name)4044dff95dcSStephen Boyd static struct clk_core *clk_core_lookup(const char *name)
4054dff95dcSStephen Boyd {
4064dff95dcSStephen Boyd struct clk_core *root_clk;
4074dff95dcSStephen Boyd struct clk_core *ret;
4084dff95dcSStephen Boyd
4094dff95dcSStephen Boyd if (!name)
4104dff95dcSStephen Boyd return NULL;
4114dff95dcSStephen Boyd
4124dff95dcSStephen Boyd /* search the 'proper' clk tree first */
4134dff95dcSStephen Boyd hlist_for_each_entry(root_clk, &clk_root_list, child_node) {
4144dff95dcSStephen Boyd ret = __clk_lookup_subtree(name, root_clk);
4154dff95dcSStephen Boyd if (ret)
4164dff95dcSStephen Boyd return ret;
4174dff95dcSStephen Boyd }
4184dff95dcSStephen Boyd
4194dff95dcSStephen Boyd /* if not found, then search the orphan tree */
4204dff95dcSStephen Boyd hlist_for_each_entry(root_clk, &clk_orphan_list, child_node) {
4214dff95dcSStephen Boyd ret = __clk_lookup_subtree(name, root_clk);
4224dff95dcSStephen Boyd if (ret)
4234dff95dcSStephen Boyd return ret;
4244dff95dcSStephen Boyd }
4254dff95dcSStephen Boyd
4264dff95dcSStephen Boyd return NULL;
4274dff95dcSStephen Boyd }
4284dff95dcSStephen Boyd
4294f8c6abaSStephen Boyd #ifdef CONFIG_OF
4304f8c6abaSStephen Boyd static int of_parse_clkspec(const struct device_node *np, int index,
4314f8c6abaSStephen Boyd const char *name, struct of_phandle_args *out_args);
4324f8c6abaSStephen Boyd static struct clk_hw *
4334f8c6abaSStephen Boyd of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec);
4344f8c6abaSStephen Boyd #else
of_parse_clkspec(const struct device_node * np,int index,const char * name,struct of_phandle_args * out_args)4354f8c6abaSStephen Boyd static inline int of_parse_clkspec(const struct device_node *np, int index,
4364f8c6abaSStephen Boyd const char *name,
4374f8c6abaSStephen Boyd struct of_phandle_args *out_args)
4384f8c6abaSStephen Boyd {
4394f8c6abaSStephen Boyd return -ENOENT;
4404f8c6abaSStephen Boyd }
4414f8c6abaSStephen Boyd static inline struct clk_hw *
of_clk_get_hw_from_clkspec(struct of_phandle_args * clkspec)4424f8c6abaSStephen Boyd of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
4434f8c6abaSStephen Boyd {
4444f8c6abaSStephen Boyd return ERR_PTR(-ENOENT);
4454f8c6abaSStephen Boyd }
4464f8c6abaSStephen Boyd #endif
4474f8c6abaSStephen Boyd
448fc0c209cSStephen Boyd /**
449dde4eff4SStephen Boyd * clk_core_get - Find the clk_core parent of a clk
450fc0c209cSStephen Boyd * @core: clk to find parent of
4511a079560SStephen Boyd * @p_index: parent index to search for
452fc0c209cSStephen Boyd *
453fc0c209cSStephen Boyd * This is the preferred method for clk providers to find the parent of a
454fc0c209cSStephen Boyd * clk when that parent is external to the clk controller. The parent_names
455fc0c209cSStephen Boyd * array is indexed and treated as a local name matching a string in the device
456dde4eff4SStephen Boyd * node's 'clock-names' property or as the 'con_id' matching the device's
457dde4eff4SStephen Boyd * dev_name() in a clk_lookup. This allows clk providers to use their own
458fc0c209cSStephen Boyd * namespace instead of looking for a globally unique parent string.
459fc0c209cSStephen Boyd *
460fc0c209cSStephen Boyd * For example the following DT snippet would allow a clock registered by the
461fc0c209cSStephen Boyd * clock-controller@c001 that has a clk_init_data::parent_data array
462fc0c209cSStephen Boyd * with 'xtal' in the 'name' member to find the clock provided by the
463fc0c209cSStephen Boyd * clock-controller@f00abcd without needing to get the globally unique name of
464fc0c209cSStephen Boyd * the xtal clk.
465fc0c209cSStephen Boyd *
466fc0c209cSStephen Boyd * parent: clock-controller@f00abcd {
467fc0c209cSStephen Boyd * reg = <0xf00abcd 0xabcd>;
468fc0c209cSStephen Boyd * #clock-cells = <0>;
469fc0c209cSStephen Boyd * };
470fc0c209cSStephen Boyd *
471fc0c209cSStephen Boyd * clock-controller@c001 {
472fc0c209cSStephen Boyd * reg = <0xc001 0xf00d>;
473fc0c209cSStephen Boyd * clocks = <&parent>;
474fc0c209cSStephen Boyd * clock-names = "xtal";
475fc0c209cSStephen Boyd * #clock-cells = <1>;
476fc0c209cSStephen Boyd * };
477fc0c209cSStephen Boyd *
478fc0c209cSStephen Boyd * Returns: -ENOENT when the provider can't be found or the clk doesn't
4794f8c6abaSStephen Boyd * exist in the provider or the name can't be found in the DT node or
4804f8c6abaSStephen Boyd * in a clkdev lookup. NULL when the provider knows about the clk but it
4814f8c6abaSStephen Boyd * isn't provided on this system.
482fc0c209cSStephen Boyd * A valid clk_core pointer when the clk can be found in the provider.
483fc0c209cSStephen Boyd */
clk_core_get(struct clk_core * core,u8 p_index)4841a079560SStephen Boyd static struct clk_core *clk_core_get(struct clk_core *core, u8 p_index)
485fc0c209cSStephen Boyd {
4861a079560SStephen Boyd const char *name = core->parents[p_index].fw_name;
4871a079560SStephen Boyd int index = core->parents[p_index].index;
488dde4eff4SStephen Boyd struct clk_hw *hw = ERR_PTR(-ENOENT);
489dde4eff4SStephen Boyd struct device *dev = core->dev;
490dde4eff4SStephen Boyd const char *dev_id = dev ? dev_name(dev) : NULL;
491fc0c209cSStephen Boyd struct device_node *np = core->of_node;
4924f8c6abaSStephen Boyd struct of_phandle_args clkspec;
493fc0c209cSStephen Boyd
4944f8c6abaSStephen Boyd if (np && (name || index >= 0) &&
4954f8c6abaSStephen Boyd !of_parse_clkspec(np, index, name, &clkspec)) {
4964f8c6abaSStephen Boyd hw = of_clk_get_hw_from_clkspec(&clkspec);
4974f8c6abaSStephen Boyd of_node_put(clkspec.np);
4984f8c6abaSStephen Boyd } else if (name) {
499dde4eff4SStephen Boyd /*
5004f8c6abaSStephen Boyd * If the DT search above couldn't find the provider fallback to
5014f8c6abaSStephen Boyd * looking up via clkdev based clk_lookups.
502dde4eff4SStephen Boyd */
503dde4eff4SStephen Boyd hw = clk_find_hw(dev_id, name);
5044f8c6abaSStephen Boyd }
505dde4eff4SStephen Boyd
506dde4eff4SStephen Boyd if (IS_ERR(hw))
507fc0c209cSStephen Boyd return ERR_CAST(hw);
508fc0c209cSStephen Boyd
509a5d9b1aaSBryan O'Donoghue if (!hw)
510a5d9b1aaSBryan O'Donoghue return NULL;
511a5d9b1aaSBryan O'Donoghue
512fc0c209cSStephen Boyd return hw->core;
513fc0c209cSStephen Boyd }
514fc0c209cSStephen Boyd
clk_core_fill_parent_index(struct clk_core * core,u8 index)515fc0c209cSStephen Boyd static void clk_core_fill_parent_index(struct clk_core *core, u8 index)
516fc0c209cSStephen Boyd {
517fc0c209cSStephen Boyd struct clk_parent_map *entry = &core->parents[index];
5186a178497SLukas Bulwahn struct clk_core *parent;
519fc0c209cSStephen Boyd
520fc0c209cSStephen Boyd if (entry->hw) {
521fc0c209cSStephen Boyd parent = entry->hw->core;
5225c1c42c4SStephen Boyd } else {
5235c1c42c4SStephen Boyd parent = clk_core_get(core, index);
5245c1c42c4SStephen Boyd if (PTR_ERR(parent) == -ENOENT && entry->name)
5255c1c42c4SStephen Boyd parent = clk_core_lookup(entry->name);
5265c1c42c4SStephen Boyd }
5275c1c42c4SStephen Boyd
528fc0c209cSStephen Boyd /*
529fc0c209cSStephen Boyd * We have a direct reference but it isn't registered yet?
530fc0c209cSStephen Boyd * Orphan it and let clk_reparent() update the orphan status
531fc0c209cSStephen Boyd * when the parent is registered.
532fc0c209cSStephen Boyd */
533fc0c209cSStephen Boyd if (!parent)
534fc0c209cSStephen Boyd parent = ERR_PTR(-EPROBE_DEFER);
535fc0c209cSStephen Boyd
536fc0c209cSStephen Boyd /* Only cache it if it's not an error */
537fc0c209cSStephen Boyd if (!IS_ERR(parent))
538fc0c209cSStephen Boyd entry->core = parent;
539fc0c209cSStephen Boyd }
540fc0c209cSStephen Boyd
clk_core_get_parent_by_index(struct clk_core * core,u8 index)541d6968fcaSStephen Boyd static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
542035a61c3STomeu Vizoso u8 index)
5437ef3dcc8SJames Hogan {
544fc0c209cSStephen Boyd if (!core || index >= core->num_parents || !core->parents)
5457ef3dcc8SJames Hogan return NULL;
54688cfbef2SMasahiro Yamada
547fc0c209cSStephen Boyd if (!core->parents[index].core)
548fc0c209cSStephen Boyd clk_core_fill_parent_index(core, index);
54988cfbef2SMasahiro Yamada
550fc0c209cSStephen Boyd return core->parents[index].core;
5517ef3dcc8SJames Hogan }
552035a61c3STomeu Vizoso
553e7df6f6eSStephen Boyd struct clk_hw *
clk_hw_get_parent_by_index(const struct clk_hw * hw,unsigned int index)554e7df6f6eSStephen Boyd clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index)
5551a9c069cSStephen Boyd {
5561a9c069cSStephen Boyd struct clk_core *parent;
5571a9c069cSStephen Boyd
5581a9c069cSStephen Boyd parent = clk_core_get_parent_by_index(hw->core, index);
5591a9c069cSStephen Boyd
5601a9c069cSStephen Boyd return !parent ? NULL : parent->hw;
5611a9c069cSStephen Boyd }
5621a9c069cSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_parent_by_index);
5631a9c069cSStephen Boyd
__clk_get_enable_count(struct clk * clk)56465800b2cSRuss Dill unsigned int __clk_get_enable_count(struct clk *clk)
565b2476490SMike Turquette {
566035a61c3STomeu Vizoso return !clk ? 0 : clk->core->enable_count;
567b2476490SMike Turquette }
568b2476490SMike Turquette
clk_core_get_rate_nolock(struct clk_core * core)569d6968fcaSStephen Boyd static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
570b2476490SMike Turquette {
57173d4f945SStephen Boyd if (!core)
57273d4f945SStephen Boyd return 0;
573b2476490SMike Turquette
57473d4f945SStephen Boyd if (!core->num_parents || core->parent)
57573d4f945SStephen Boyd return core->rate;
576b2476490SMike Turquette
57773d4f945SStephen Boyd /*
57873d4f945SStephen Boyd * Clk must have a parent because num_parents > 0 but the parent isn't
57973d4f945SStephen Boyd * known yet. Best to return 0 as the rate of this clk until we can
58073d4f945SStephen Boyd * properly recalc the rate based on the parent's rate.
58173d4f945SStephen Boyd */
58273d4f945SStephen Boyd return 0;
583b2476490SMike Turquette }
584035a61c3STomeu Vizoso
clk_hw_get_rate(const struct clk_hw * hw)585e7df6f6eSStephen Boyd unsigned long clk_hw_get_rate(const struct clk_hw *hw)
5861a9c069cSStephen Boyd {
5871a9c069cSStephen Boyd return clk_core_get_rate_nolock(hw->core);
5881a9c069cSStephen Boyd }
5891a9c069cSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_rate);
5901a9c069cSStephen Boyd
clk_core_get_accuracy_no_lock(struct clk_core * core)5910daa376dSStephen Boyd static unsigned long clk_core_get_accuracy_no_lock(struct clk_core *core)
5925279fc40SBoris BREZILLON {
593d6968fcaSStephen Boyd if (!core)
5945279fc40SBoris BREZILLON return 0;
5955279fc40SBoris BREZILLON
596d6968fcaSStephen Boyd return core->accuracy;
5975279fc40SBoris BREZILLON }
5985279fc40SBoris BREZILLON
clk_hw_get_flags(const struct clk_hw * hw)599e7df6f6eSStephen Boyd unsigned long clk_hw_get_flags(const struct clk_hw *hw)
6001a9c069cSStephen Boyd {
6011a9c069cSStephen Boyd return hw->core->flags;
6021a9c069cSStephen Boyd }
6031a9c069cSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_flags);
6041a9c069cSStephen Boyd
clk_hw_is_prepared(const struct clk_hw * hw)605e7df6f6eSStephen Boyd bool clk_hw_is_prepared(const struct clk_hw *hw)
6061a9c069cSStephen Boyd {
6071a9c069cSStephen Boyd return clk_core_is_prepared(hw->core);
6081a9c069cSStephen Boyd }
60912aa377bSJerome Brunet EXPORT_SYMBOL_GPL(clk_hw_is_prepared);
6101a9c069cSStephen Boyd
clk_hw_rate_is_protected(const struct clk_hw * hw)611e55a839aSJerome Brunet bool clk_hw_rate_is_protected(const struct clk_hw *hw)
612e55a839aSJerome Brunet {
613e55a839aSJerome Brunet return clk_core_rate_is_protected(hw->core);
614e55a839aSJerome Brunet }
61512aa377bSJerome Brunet EXPORT_SYMBOL_GPL(clk_hw_rate_is_protected);
616e55a839aSJerome Brunet
clk_hw_is_enabled(const struct clk_hw * hw)617be68bf88SJoachim Eastwood bool clk_hw_is_enabled(const struct clk_hw *hw)
618be68bf88SJoachim Eastwood {
619be68bf88SJoachim Eastwood return clk_core_is_enabled(hw->core);
620be68bf88SJoachim Eastwood }
62112aa377bSJerome Brunet EXPORT_SYMBOL_GPL(clk_hw_is_enabled);
622be68bf88SJoachim Eastwood
__clk_is_enabled(struct clk * clk)623035a61c3STomeu Vizoso bool __clk_is_enabled(struct clk *clk)
624035a61c3STomeu Vizoso {
625035a61c3STomeu Vizoso if (!clk)
626035a61c3STomeu Vizoso return false;
627035a61c3STomeu Vizoso
628035a61c3STomeu Vizoso return clk_core_is_enabled(clk->core);
629035a61c3STomeu Vizoso }
6300b7f04b8SStephen Boyd EXPORT_SYMBOL_GPL(__clk_is_enabled);
631b2476490SMike Turquette
mux_is_better_rate(unsigned long rate,unsigned long now,unsigned long best,unsigned long flags)63215a02c1fSStephen Boyd static bool mux_is_better_rate(unsigned long rate, unsigned long now,
63315a02c1fSStephen Boyd unsigned long best, unsigned long flags)
634e366fdd7SJames Hogan {
63515a02c1fSStephen Boyd if (flags & CLK_MUX_ROUND_CLOSEST)
63615a02c1fSStephen Boyd return abs(now - rate) < abs(best - rate);
63715a02c1fSStephen Boyd
63815a02c1fSStephen Boyd return now <= rate && now > best;
63915a02c1fSStephen Boyd }
64015a02c1fSStephen Boyd
641262ca38fSMaxime Ripard static void clk_core_init_rate_req(struct clk_core * const core,
642262ca38fSMaxime Ripard struct clk_rate_request *req,
643262ca38fSMaxime Ripard unsigned long rate);
644262ca38fSMaxime Ripard
645666650b2SMaxime Ripard static int clk_core_round_rate_nolock(struct clk_core *core,
646666650b2SMaxime Ripard struct clk_rate_request *req);
647666650b2SMaxime Ripard
clk_core_has_parent(struct clk_core * core,const struct clk_core * parent)6481234a2c4SMaxime Ripard static bool clk_core_has_parent(struct clk_core *core, const struct clk_core *parent)
6491234a2c4SMaxime Ripard {
6501234a2c4SMaxime Ripard struct clk_core *tmp;
6511234a2c4SMaxime Ripard unsigned int i;
6521234a2c4SMaxime Ripard
6531234a2c4SMaxime Ripard /* Optimize for the case where the parent is already the parent. */
6541234a2c4SMaxime Ripard if (core->parent == parent)
6551234a2c4SMaxime Ripard return true;
6561234a2c4SMaxime Ripard
6571234a2c4SMaxime Ripard for (i = 0; i < core->num_parents; i++) {
6581234a2c4SMaxime Ripard tmp = clk_core_get_parent_by_index(core, i);
6591234a2c4SMaxime Ripard if (!tmp)
6601234a2c4SMaxime Ripard continue;
6611234a2c4SMaxime Ripard
6621234a2c4SMaxime Ripard if (tmp == parent)
6631234a2c4SMaxime Ripard return true;
6641234a2c4SMaxime Ripard }
6651234a2c4SMaxime Ripard
6661234a2c4SMaxime Ripard return false;
6671234a2c4SMaxime Ripard }
6681234a2c4SMaxime Ripard
669262ca38fSMaxime Ripard static void
clk_core_forward_rate_req(struct clk_core * core,const struct clk_rate_request * old_req,struct clk_core * parent,struct clk_rate_request * req,unsigned long parent_rate)670262ca38fSMaxime Ripard clk_core_forward_rate_req(struct clk_core *core,
671262ca38fSMaxime Ripard const struct clk_rate_request *old_req,
672262ca38fSMaxime Ripard struct clk_core *parent,
673262ca38fSMaxime Ripard struct clk_rate_request *req,
674262ca38fSMaxime Ripard unsigned long parent_rate)
675262ca38fSMaxime Ripard {
676262ca38fSMaxime Ripard if (WARN_ON(!clk_core_has_parent(core, parent)))
677262ca38fSMaxime Ripard return;
678262ca38fSMaxime Ripard
679262ca38fSMaxime Ripard clk_core_init_rate_req(parent, req, parent_rate);
680262ca38fSMaxime Ripard
681262ca38fSMaxime Ripard if (req->min_rate < old_req->min_rate)
682262ca38fSMaxime Ripard req->min_rate = old_req->min_rate;
683262ca38fSMaxime Ripard
684262ca38fSMaxime Ripard if (req->max_rate > old_req->max_rate)
685262ca38fSMaxime Ripard req->max_rate = old_req->max_rate;
686262ca38fSMaxime Ripard }
687262ca38fSMaxime Ripard
6881b4e99fdSStephen Boyd static int
clk_core_determine_rate_no_reparent(struct clk_hw * hw,struct clk_rate_request * req)6891b4e99fdSStephen Boyd clk_core_determine_rate_no_reparent(struct clk_hw *hw,
6901b4e99fdSStephen Boyd struct clk_rate_request *req)
691e366fdd7SJames Hogan {
6921b4e99fdSStephen Boyd struct clk_core *core = hw->core;
6931b4e99fdSStephen Boyd struct clk_core *parent = core->parent;
6941b4e99fdSStephen Boyd unsigned long best;
6951b4e99fdSStephen Boyd int ret;
696e366fdd7SJames Hogan
6970817b62cSBoris Brezillon if (core->flags & CLK_SET_RATE_PARENT) {
698262ca38fSMaxime Ripard struct clk_rate_request parent_req;
699262ca38fSMaxime Ripard
700666650b2SMaxime Ripard if (!parent) {
701666650b2SMaxime Ripard req->rate = 0;
702666650b2SMaxime Ripard return 0;
703666650b2SMaxime Ripard }
704666650b2SMaxime Ripard
7051b4e99fdSStephen Boyd clk_core_forward_rate_req(core, req, parent, &parent_req,
7061b4e99fdSStephen Boyd req->rate);
70749e62e0dSMaxime Ripard
70849e62e0dSMaxime Ripard trace_clk_rate_request_start(&parent_req);
70949e62e0dSMaxime Ripard
710666650b2SMaxime Ripard ret = clk_core_round_rate_nolock(parent, &parent_req);
7110817b62cSBoris Brezillon if (ret)
7120817b62cSBoris Brezillon return ret;
7130817b62cSBoris Brezillon
71449e62e0dSMaxime Ripard trace_clk_rate_request_done(&parent_req);
71549e62e0dSMaxime Ripard
7160817b62cSBoris Brezillon best = parent_req.rate;
7170817b62cSBoris Brezillon } else if (parent) {
718035a61c3STomeu Vizoso best = clk_core_get_rate_nolock(parent);
7190817b62cSBoris Brezillon } else {
720035a61c3STomeu Vizoso best = clk_core_get_rate_nolock(core);
7210817b62cSBoris Brezillon }
7220817b62cSBoris Brezillon
723be8fa5fdSMarek Szyprowski req->best_parent_rate = best;
7241b4e99fdSStephen Boyd req->rate = best;
7251b4e99fdSStephen Boyd
7261b4e99fdSStephen Boyd return 0;
727e366fdd7SJames Hogan }
728e366fdd7SJames Hogan
clk_mux_determine_rate_flags(struct clk_hw * hw,struct clk_rate_request * req,unsigned long flags)7291b4e99fdSStephen Boyd int clk_mux_determine_rate_flags(struct clk_hw *hw,
7301b4e99fdSStephen Boyd struct clk_rate_request *req,
7311b4e99fdSStephen Boyd unsigned long flags)
7321b4e99fdSStephen Boyd {
7331b4e99fdSStephen Boyd struct clk_core *core = hw->core, *parent, *best_parent = NULL;
7341b4e99fdSStephen Boyd int i, num_parents, ret;
7351b4e99fdSStephen Boyd unsigned long best = 0;
7361b4e99fdSStephen Boyd
7371b4e99fdSStephen Boyd /* if NO_REPARENT flag set, pass through to current parent */
7381b4e99fdSStephen Boyd if (core->flags & CLK_SET_RATE_NO_REPARENT)
7391b4e99fdSStephen Boyd return clk_core_determine_rate_no_reparent(hw, req);
7401b4e99fdSStephen Boyd
741e366fdd7SJames Hogan /* find the parent that can provide the fastest rate <= rate */
742035a61c3STomeu Vizoso num_parents = core->num_parents;
743e366fdd7SJames Hogan for (i = 0; i < num_parents; i++) {
744262ca38fSMaxime Ripard unsigned long parent_rate;
745262ca38fSMaxime Ripard
746035a61c3STomeu Vizoso parent = clk_core_get_parent_by_index(core, i);
747e366fdd7SJames Hogan if (!parent)
748e366fdd7SJames Hogan continue;
7490817b62cSBoris Brezillon
7500817b62cSBoris Brezillon if (core->flags & CLK_SET_RATE_PARENT) {
751262ca38fSMaxime Ripard struct clk_rate_request parent_req;
752262ca38fSMaxime Ripard
753262ca38fSMaxime Ripard clk_core_forward_rate_req(core, req, parent, &parent_req, req->rate);
75449e62e0dSMaxime Ripard
75549e62e0dSMaxime Ripard trace_clk_rate_request_start(&parent_req);
75649e62e0dSMaxime Ripard
757666650b2SMaxime Ripard ret = clk_core_round_rate_nolock(parent, &parent_req);
7580817b62cSBoris Brezillon if (ret)
7590817b62cSBoris Brezillon continue;
760262ca38fSMaxime Ripard
76149e62e0dSMaxime Ripard trace_clk_rate_request_done(&parent_req);
76249e62e0dSMaxime Ripard
763262ca38fSMaxime Ripard parent_rate = parent_req.rate;
7640817b62cSBoris Brezillon } else {
765262ca38fSMaxime Ripard parent_rate = clk_core_get_rate_nolock(parent);
7660817b62cSBoris Brezillon }
7670817b62cSBoris Brezillon
768262ca38fSMaxime Ripard if (mux_is_better_rate(req->rate, parent_rate,
7690817b62cSBoris Brezillon best, flags)) {
770e366fdd7SJames Hogan best_parent = parent;
771262ca38fSMaxime Ripard best = parent_rate;
772e366fdd7SJames Hogan }
773e366fdd7SJames Hogan }
774e366fdd7SJames Hogan
77557d866e6SBoris Brezillon if (!best_parent)
77657d866e6SBoris Brezillon return -EINVAL;
77757d866e6SBoris Brezillon
7780817b62cSBoris Brezillon req->best_parent_hw = best_parent->hw;
7790817b62cSBoris Brezillon req->best_parent_rate = best;
7800817b62cSBoris Brezillon req->rate = best;
781e366fdd7SJames Hogan
7820817b62cSBoris Brezillon return 0;
783e366fdd7SJames Hogan }
7844ad69b80SJerome Brunet EXPORT_SYMBOL_GPL(clk_mux_determine_rate_flags);
78515a02c1fSStephen Boyd
__clk_lookup(const char * name)786035a61c3STomeu Vizoso struct clk *__clk_lookup(const char *name)
787035a61c3STomeu Vizoso {
788035a61c3STomeu Vizoso struct clk_core *core = clk_core_lookup(name);
789035a61c3STomeu Vizoso
790035a61c3STomeu Vizoso return !core ? NULL : core->hw->clk;
791035a61c3STomeu Vizoso }
792035a61c3STomeu Vizoso
clk_core_get_boundaries(struct clk_core * core,unsigned long * min_rate,unsigned long * max_rate)793d6968fcaSStephen Boyd static void clk_core_get_boundaries(struct clk_core *core,
7941c8e6004STomeu Vizoso unsigned long *min_rate,
7951c8e6004STomeu Vizoso unsigned long *max_rate)
7961c8e6004STomeu Vizoso {
7971c8e6004STomeu Vizoso struct clk *clk_user;
7981c8e6004STomeu Vizoso
7999f776722SLeonard Crestez lockdep_assert_held(&prepare_lock);
8009f776722SLeonard Crestez
8019783c0d9SStephen Boyd *min_rate = core->min_rate;
8029783c0d9SStephen Boyd *max_rate = core->max_rate;
8031c8e6004STomeu Vizoso
804d6968fcaSStephen Boyd hlist_for_each_entry(clk_user, &core->clks, clks_node)
8051c8e6004STomeu Vizoso *min_rate = max(*min_rate, clk_user->min_rate);
8061c8e6004STomeu Vizoso
807d6968fcaSStephen Boyd hlist_for_each_entry(clk_user, &core->clks, clks_node)
8081c8e6004STomeu Vizoso *max_rate = min(*max_rate, clk_user->max_rate);
8091c8e6004STomeu Vizoso }
8101c8e6004STomeu Vizoso
81125399325SMaxime Ripard /*
81225399325SMaxime Ripard * clk_hw_get_rate_range() - returns the clock rate range for a hw clk
81325399325SMaxime Ripard * @hw: the hw clk we want to get the range from
81425399325SMaxime Ripard * @min_rate: pointer to the variable that will hold the minimum
81525399325SMaxime Ripard * @max_rate: pointer to the variable that will hold the maximum
81625399325SMaxime Ripard *
81725399325SMaxime Ripard * Fills the @min_rate and @max_rate variables with the minimum and
81825399325SMaxime Ripard * maximum that clock can reach.
81925399325SMaxime Ripard */
clk_hw_get_rate_range(struct clk_hw * hw,unsigned long * min_rate,unsigned long * max_rate)82025399325SMaxime Ripard void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
82125399325SMaxime Ripard unsigned long *max_rate)
82225399325SMaxime Ripard {
82325399325SMaxime Ripard clk_core_get_boundaries(hw->core, min_rate, max_rate);
82425399325SMaxime Ripard }
82525399325SMaxime Ripard EXPORT_SYMBOL_GPL(clk_hw_get_rate_range);
82625399325SMaxime Ripard
clk_core_check_boundaries(struct clk_core * core,unsigned long min_rate,unsigned long max_rate)82710c46f2eSMaxime Ripard static bool clk_core_check_boundaries(struct clk_core *core,
82810c46f2eSMaxime Ripard unsigned long min_rate,
82910c46f2eSMaxime Ripard unsigned long max_rate)
83010c46f2eSMaxime Ripard {
83110c46f2eSMaxime Ripard struct clk *user;
83210c46f2eSMaxime Ripard
83310c46f2eSMaxime Ripard lockdep_assert_held(&prepare_lock);
83410c46f2eSMaxime Ripard
83510c46f2eSMaxime Ripard if (min_rate > core->max_rate || max_rate < core->min_rate)
83610c46f2eSMaxime Ripard return false;
83710c46f2eSMaxime Ripard
83810c46f2eSMaxime Ripard hlist_for_each_entry(user, &core->clks, clks_node)
83910c46f2eSMaxime Ripard if (min_rate > user->max_rate || max_rate < user->min_rate)
84010c46f2eSMaxime Ripard return false;
84110c46f2eSMaxime Ripard
84210c46f2eSMaxime Ripard return true;
84310c46f2eSMaxime Ripard }
84410c46f2eSMaxime Ripard
clk_hw_set_rate_range(struct clk_hw * hw,unsigned long min_rate,unsigned long max_rate)8459783c0d9SStephen Boyd void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
8469783c0d9SStephen Boyd unsigned long max_rate)
8479783c0d9SStephen Boyd {
8489783c0d9SStephen Boyd hw->core->min_rate = min_rate;
8499783c0d9SStephen Boyd hw->core->max_rate = max_rate;
8509783c0d9SStephen Boyd }
8519783c0d9SStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_set_rate_range);
8529783c0d9SStephen Boyd
85315a02c1fSStephen Boyd /*
854777c1a40SStephen Boyd * __clk_mux_determine_rate - clk_ops::determine_rate implementation for a mux type clk
855777c1a40SStephen Boyd * @hw: mux type clk to determine rate on
856777c1a40SStephen Boyd * @req: rate request, also used to return preferred parent and frequencies
857777c1a40SStephen Boyd *
85815a02c1fSStephen Boyd * Helper for finding best parent to provide a given frequency. This can be used
85915a02c1fSStephen Boyd * directly as a determine_rate callback (e.g. for a mux), or from a more
86015a02c1fSStephen Boyd * complex clock that may combine a mux with other operations.
861777c1a40SStephen Boyd *
862777c1a40SStephen Boyd * Returns: 0 on success, -EERROR value on error
86315a02c1fSStephen Boyd */
__clk_mux_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)8640817b62cSBoris Brezillon int __clk_mux_determine_rate(struct clk_hw *hw,
8650817b62cSBoris Brezillon struct clk_rate_request *req)
86615a02c1fSStephen Boyd {
8670817b62cSBoris Brezillon return clk_mux_determine_rate_flags(hw, req, 0);
86815a02c1fSStephen Boyd }
8690b7f04b8SStephen Boyd EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
870e366fdd7SJames Hogan
__clk_mux_determine_rate_closest(struct clk_hw * hw,struct clk_rate_request * req)8710817b62cSBoris Brezillon int __clk_mux_determine_rate_closest(struct clk_hw *hw,
8720817b62cSBoris Brezillon struct clk_rate_request *req)
87315a02c1fSStephen Boyd {
8740817b62cSBoris Brezillon return clk_mux_determine_rate_flags(hw, req, CLK_MUX_ROUND_CLOSEST);
87515a02c1fSStephen Boyd }
87615a02c1fSStephen Boyd EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
87715a02c1fSStephen Boyd
87833b70fbcSStephen Boyd /*
87933b70fbcSStephen Boyd * clk_hw_determine_rate_no_reparent - clk_ops::determine_rate implementation for a clk that doesn't reparent
88033b70fbcSStephen Boyd * @hw: mux type clk to determine rate on
88133b70fbcSStephen Boyd * @req: rate request, also used to return preferred frequency
88233b70fbcSStephen Boyd *
88333b70fbcSStephen Boyd * Helper for finding best parent rate to provide a given frequency.
88433b70fbcSStephen Boyd * This can be used directly as a determine_rate callback (e.g. for a
88533b70fbcSStephen Boyd * mux), or from a more complex clock that may combine a mux with other
88633b70fbcSStephen Boyd * operations.
88733b70fbcSStephen Boyd *
88833b70fbcSStephen Boyd * Returns: 0 on success, -EERROR value on error
88933b70fbcSStephen Boyd */
clk_hw_determine_rate_no_reparent(struct clk_hw * hw,struct clk_rate_request * req)89033b70fbcSStephen Boyd int clk_hw_determine_rate_no_reparent(struct clk_hw *hw,
89133b70fbcSStephen Boyd struct clk_rate_request *req)
89233b70fbcSStephen Boyd {
89333b70fbcSStephen Boyd return clk_core_determine_rate_no_reparent(hw, req);
89433b70fbcSStephen Boyd }
89533b70fbcSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_determine_rate_no_reparent);
89633b70fbcSStephen Boyd
897b2476490SMike Turquette /*** clk api ***/
898b2476490SMike Turquette
clk_core_rate_unprotect(struct clk_core * core)899e55a839aSJerome Brunet static void clk_core_rate_unprotect(struct clk_core *core)
900e55a839aSJerome Brunet {
901e55a839aSJerome Brunet lockdep_assert_held(&prepare_lock);
902e55a839aSJerome Brunet
903e55a839aSJerome Brunet if (!core)
904e55a839aSJerome Brunet return;
905e55a839aSJerome Brunet
906ab525dccSFabio Estevam if (WARN(core->protect_count == 0,
907ab525dccSFabio Estevam "%s already unprotected\n", core->name))
908e55a839aSJerome Brunet return;
909e55a839aSJerome Brunet
910e55a839aSJerome Brunet if (--core->protect_count > 0)
911e55a839aSJerome Brunet return;
912e55a839aSJerome Brunet
913e55a839aSJerome Brunet clk_core_rate_unprotect(core->parent);
914e55a839aSJerome Brunet }
915e55a839aSJerome Brunet
clk_core_rate_nuke_protect(struct clk_core * core)916e55a839aSJerome Brunet static int clk_core_rate_nuke_protect(struct clk_core *core)
917e55a839aSJerome Brunet {
918e55a839aSJerome Brunet int ret;
919e55a839aSJerome Brunet
920e55a839aSJerome Brunet lockdep_assert_held(&prepare_lock);
921e55a839aSJerome Brunet
922e55a839aSJerome Brunet if (!core)
923e55a839aSJerome Brunet return -EINVAL;
924e55a839aSJerome Brunet
925e55a839aSJerome Brunet if (core->protect_count == 0)
926e55a839aSJerome Brunet return 0;
927e55a839aSJerome Brunet
928e55a839aSJerome Brunet ret = core->protect_count;
929e55a839aSJerome Brunet core->protect_count = 1;
930e55a839aSJerome Brunet clk_core_rate_unprotect(core);
931e55a839aSJerome Brunet
932e55a839aSJerome Brunet return ret;
933e55a839aSJerome Brunet }
934e55a839aSJerome Brunet
93555e9b8b7SJerome Brunet /**
93655e9b8b7SJerome Brunet * clk_rate_exclusive_put - release exclusivity over clock rate control
93755e9b8b7SJerome Brunet * @clk: the clk over which the exclusivity is released
93855e9b8b7SJerome Brunet *
93955e9b8b7SJerome Brunet * clk_rate_exclusive_put() completes a critical section during which a clock
94055e9b8b7SJerome Brunet * consumer cannot tolerate any other consumer making any operation on the
94155e9b8b7SJerome Brunet * clock which could result in a rate change or rate glitch. Exclusive clocks
94255e9b8b7SJerome Brunet * cannot have their rate changed, either directly or indirectly due to changes
94355e9b8b7SJerome Brunet * further up the parent chain of clocks. As a result, clocks up parent chain
94455e9b8b7SJerome Brunet * also get under exclusive control of the calling consumer.
94555e9b8b7SJerome Brunet *
94655e9b8b7SJerome Brunet * If exlusivity is claimed more than once on clock, even by the same consumer,
94755e9b8b7SJerome Brunet * the rate effectively gets locked as exclusivity can't be preempted.
94855e9b8b7SJerome Brunet *
94955e9b8b7SJerome Brunet * Calls to clk_rate_exclusive_put() must be balanced with calls to
95055e9b8b7SJerome Brunet * clk_rate_exclusive_get(). Calls to this function may sleep, and do not return
95155e9b8b7SJerome Brunet * error status.
95255e9b8b7SJerome Brunet */
clk_rate_exclusive_put(struct clk * clk)95355e9b8b7SJerome Brunet void clk_rate_exclusive_put(struct clk *clk)
95455e9b8b7SJerome Brunet {
95555e9b8b7SJerome Brunet if (!clk)
95655e9b8b7SJerome Brunet return;
95755e9b8b7SJerome Brunet
95855e9b8b7SJerome Brunet clk_prepare_lock();
95955e9b8b7SJerome Brunet
96055e9b8b7SJerome Brunet /*
96155e9b8b7SJerome Brunet * if there is something wrong with this consumer protect count, stop
96255e9b8b7SJerome Brunet * here before messing with the provider
96355e9b8b7SJerome Brunet */
96455e9b8b7SJerome Brunet if (WARN_ON(clk->exclusive_count <= 0))
96555e9b8b7SJerome Brunet goto out;
96655e9b8b7SJerome Brunet
96755e9b8b7SJerome Brunet clk_core_rate_unprotect(clk->core);
96855e9b8b7SJerome Brunet clk->exclusive_count--;
96955e9b8b7SJerome Brunet out:
97055e9b8b7SJerome Brunet clk_prepare_unlock();
97155e9b8b7SJerome Brunet }
97255e9b8b7SJerome Brunet EXPORT_SYMBOL_GPL(clk_rate_exclusive_put);
97355e9b8b7SJerome Brunet
clk_core_rate_protect(struct clk_core * core)974e55a839aSJerome Brunet static void clk_core_rate_protect(struct clk_core *core)
975e55a839aSJerome Brunet {
976e55a839aSJerome Brunet lockdep_assert_held(&prepare_lock);
977e55a839aSJerome Brunet
978e55a839aSJerome Brunet if (!core)
979e55a839aSJerome Brunet return;
980e55a839aSJerome Brunet
981e55a839aSJerome Brunet if (core->protect_count == 0)
982e55a839aSJerome Brunet clk_core_rate_protect(core->parent);
983e55a839aSJerome Brunet
984e55a839aSJerome Brunet core->protect_count++;
985e55a839aSJerome Brunet }
986e55a839aSJerome Brunet
clk_core_rate_restore_protect(struct clk_core * core,int count)987e55a839aSJerome Brunet static void clk_core_rate_restore_protect(struct clk_core *core, int count)
988e55a839aSJerome Brunet {
989e55a839aSJerome Brunet lockdep_assert_held(&prepare_lock);
990e55a839aSJerome Brunet
991e55a839aSJerome Brunet if (!core)
992e55a839aSJerome Brunet return;
993e55a839aSJerome Brunet
994e55a839aSJerome Brunet if (count == 0)
995e55a839aSJerome Brunet return;
996e55a839aSJerome Brunet
997e55a839aSJerome Brunet clk_core_rate_protect(core);
998e55a839aSJerome Brunet core->protect_count = count;
999e55a839aSJerome Brunet }
1000e55a839aSJerome Brunet
100155e9b8b7SJerome Brunet /**
100255e9b8b7SJerome Brunet * clk_rate_exclusive_get - get exclusivity over the clk rate control
100355e9b8b7SJerome Brunet * @clk: the clk over which the exclusity of rate control is requested
100455e9b8b7SJerome Brunet *
1005a37a5a9dSAndy Shevchenko * clk_rate_exclusive_get() begins a critical section during which a clock
100655e9b8b7SJerome Brunet * consumer cannot tolerate any other consumer making any operation on the
100755e9b8b7SJerome Brunet * clock which could result in a rate change or rate glitch. Exclusive clocks
100855e9b8b7SJerome Brunet * cannot have their rate changed, either directly or indirectly due to changes
100955e9b8b7SJerome Brunet * further up the parent chain of clocks. As a result, clocks up parent chain
101055e9b8b7SJerome Brunet * also get under exclusive control of the calling consumer.
101155e9b8b7SJerome Brunet *
101255e9b8b7SJerome Brunet * If exlusivity is claimed more than once on clock, even by the same consumer,
101355e9b8b7SJerome Brunet * the rate effectively gets locked as exclusivity can't be preempted.
101455e9b8b7SJerome Brunet *
101555e9b8b7SJerome Brunet * Calls to clk_rate_exclusive_get() should be balanced with calls to
101655e9b8b7SJerome Brunet * clk_rate_exclusive_put(). Calls to this function may sleep.
101755e9b8b7SJerome Brunet * Returns 0 on success, -EERROR otherwise
101855e9b8b7SJerome Brunet */
clk_rate_exclusive_get(struct clk * clk)101955e9b8b7SJerome Brunet int clk_rate_exclusive_get(struct clk *clk)
102055e9b8b7SJerome Brunet {
102155e9b8b7SJerome Brunet if (!clk)
102255e9b8b7SJerome Brunet return 0;
102355e9b8b7SJerome Brunet
102455e9b8b7SJerome Brunet clk_prepare_lock();
102555e9b8b7SJerome Brunet clk_core_rate_protect(clk->core);
102655e9b8b7SJerome Brunet clk->exclusive_count++;
102755e9b8b7SJerome Brunet clk_prepare_unlock();
102855e9b8b7SJerome Brunet
102955e9b8b7SJerome Brunet return 0;
103055e9b8b7SJerome Brunet }
103155e9b8b7SJerome Brunet EXPORT_SYMBOL_GPL(clk_rate_exclusive_get);
103255e9b8b7SJerome Brunet
clk_core_unprepare(struct clk_core * core)1033d6968fcaSStephen Boyd static void clk_core_unprepare(struct clk_core *core)
1034b2476490SMike Turquette {
1035a6334725SStephen Boyd lockdep_assert_held(&prepare_lock);
1036a6334725SStephen Boyd
1037d6968fcaSStephen Boyd if (!core)
1038b2476490SMike Turquette return;
1039b2476490SMike Turquette
1040ab525dccSFabio Estevam if (WARN(core->prepare_count == 0,
1041ab525dccSFabio Estevam "%s already unprepared\n", core->name))
1042b2476490SMike Turquette return;
1043b2476490SMike Turquette
1044ab525dccSFabio Estevam if (WARN(core->prepare_count == 1 && core->flags & CLK_IS_CRITICAL,
1045ab525dccSFabio Estevam "Unpreparing critical %s\n", core->name))
10462e20fbf5SLee Jones return;
10472e20fbf5SLee Jones
10489461f7b3SJerome Brunet if (core->flags & CLK_SET_RATE_GATE)
10499461f7b3SJerome Brunet clk_core_rate_unprotect(core);
10509461f7b3SJerome Brunet
1051d6968fcaSStephen Boyd if (--core->prepare_count > 0)
1052b2476490SMike Turquette return;
1053b2476490SMike Turquette
1054ab525dccSFabio Estevam WARN(core->enable_count > 0, "Unpreparing enabled %s\n", core->name);
1055b2476490SMike Turquette
1056d6968fcaSStephen Boyd trace_clk_unprepare(core);
1057dfc202eaSStephen Boyd
1058d6968fcaSStephen Boyd if (core->ops->unprepare)
1059d6968fcaSStephen Boyd core->ops->unprepare(core->hw);
1060b2476490SMike Turquette
1061d6968fcaSStephen Boyd trace_clk_unprepare_complete(core);
1062d6968fcaSStephen Boyd clk_core_unprepare(core->parent);
10634b592061SChen-Yu Tsai clk_pm_runtime_put(core);
1064b2476490SMike Turquette }
1065b2476490SMike Turquette
clk_core_unprepare_lock(struct clk_core * core)1066a6adc30bSDong Aisheng static void clk_core_unprepare_lock(struct clk_core *core)
1067a6adc30bSDong Aisheng {
1068a6adc30bSDong Aisheng clk_prepare_lock();
1069a6adc30bSDong Aisheng clk_core_unprepare(core);
1070a6adc30bSDong Aisheng clk_prepare_unlock();
1071a6adc30bSDong Aisheng }
1072a6adc30bSDong Aisheng
1073b2476490SMike Turquette /**
1074b2476490SMike Turquette * clk_unprepare - undo preparation of a clock source
107524ee1a08SPeter Meerwald * @clk: the clk being unprepared
1076b2476490SMike Turquette *
1077b2476490SMike Turquette * clk_unprepare may sleep, which differentiates it from clk_disable. In a
1078b2476490SMike Turquette * simple case, clk_unprepare can be used instead of clk_disable to gate a clk
1079b2476490SMike Turquette * if the operation may sleep. One example is a clk which is accessed over
1080b2476490SMike Turquette * I2c. In the complex case a clk gate operation may require a fast and a slow
1081b2476490SMike Turquette * part. It is this reason that clk_unprepare and clk_disable are not mutually
1082b2476490SMike Turquette * exclusive. In fact clk_disable must be called before clk_unprepare.
1083b2476490SMike Turquette */
clk_unprepare(struct clk * clk)1084b2476490SMike Turquette void clk_unprepare(struct clk *clk)
1085b2476490SMike Turquette {
108663589e92SStephen Boyd if (IS_ERR_OR_NULL(clk))
108763589e92SStephen Boyd return;
108863589e92SStephen Boyd
1089a6adc30bSDong Aisheng clk_core_unprepare_lock(clk->core);
1090b2476490SMike Turquette }
1091b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_unprepare);
1092b2476490SMike Turquette
clk_core_prepare(struct clk_core * core)1093d6968fcaSStephen Boyd static int clk_core_prepare(struct clk_core *core)
1094b2476490SMike Turquette {
1095b2476490SMike Turquette int ret = 0;
1096b2476490SMike Turquette
1097a6334725SStephen Boyd lockdep_assert_held(&prepare_lock);
1098a6334725SStephen Boyd
1099d6968fcaSStephen Boyd if (!core)
1100b2476490SMike Turquette return 0;
1101b2476490SMike Turquette
1102d6968fcaSStephen Boyd if (core->prepare_count == 0) {
11039a34b453SMarek Szyprowski ret = clk_pm_runtime_get(core);
1104b2476490SMike Turquette if (ret)
1105b2476490SMike Turquette return ret;
1106b2476490SMike Turquette
11079a34b453SMarek Szyprowski ret = clk_core_prepare(core->parent);
11089a34b453SMarek Szyprowski if (ret)
11099a34b453SMarek Szyprowski goto runtime_put;
11109a34b453SMarek Szyprowski
1111d6968fcaSStephen Boyd trace_clk_prepare(core);
1112dfc202eaSStephen Boyd
1113d6968fcaSStephen Boyd if (core->ops->prepare)
1114d6968fcaSStephen Boyd ret = core->ops->prepare(core->hw);
1115dfc202eaSStephen Boyd
1116d6968fcaSStephen Boyd trace_clk_prepare_complete(core);
1117dfc202eaSStephen Boyd
11189a34b453SMarek Szyprowski if (ret)
11199a34b453SMarek Szyprowski goto unprepare;
1120b2476490SMike Turquette }
1121b2476490SMike Turquette
1122d6968fcaSStephen Boyd core->prepare_count++;
1123b2476490SMike Turquette
11249461f7b3SJerome Brunet /*
11259461f7b3SJerome Brunet * CLK_SET_RATE_GATE is a special case of clock protection
11269461f7b3SJerome Brunet * Instead of a consumer claiming exclusive rate control, it is
11279461f7b3SJerome Brunet * actually the provider which prevents any consumer from making any
11289461f7b3SJerome Brunet * operation which could result in a rate change or rate glitch while
11299461f7b3SJerome Brunet * the clock is prepared.
11309461f7b3SJerome Brunet */
11319461f7b3SJerome Brunet if (core->flags & CLK_SET_RATE_GATE)
11329461f7b3SJerome Brunet clk_core_rate_protect(core);
11339461f7b3SJerome Brunet
1134b2476490SMike Turquette return 0;
11359a34b453SMarek Szyprowski unprepare:
11369a34b453SMarek Szyprowski clk_core_unprepare(core->parent);
11379a34b453SMarek Szyprowski runtime_put:
11389a34b453SMarek Szyprowski clk_pm_runtime_put(core);
11399a34b453SMarek Szyprowski return ret;
1140b2476490SMike Turquette }
1141b2476490SMike Turquette
clk_core_prepare_lock(struct clk_core * core)1142a6adc30bSDong Aisheng static int clk_core_prepare_lock(struct clk_core *core)
1143a6adc30bSDong Aisheng {
1144a6adc30bSDong Aisheng int ret;
1145a6adc30bSDong Aisheng
1146a6adc30bSDong Aisheng clk_prepare_lock();
1147a6adc30bSDong Aisheng ret = clk_core_prepare(core);
1148a6adc30bSDong Aisheng clk_prepare_unlock();
1149a6adc30bSDong Aisheng
1150a6adc30bSDong Aisheng return ret;
1151a6adc30bSDong Aisheng }
1152a6adc30bSDong Aisheng
1153b2476490SMike Turquette /**
1154b2476490SMike Turquette * clk_prepare - prepare a clock source
1155b2476490SMike Turquette * @clk: the clk being prepared
1156b2476490SMike Turquette *
1157b2476490SMike Turquette * clk_prepare may sleep, which differentiates it from clk_enable. In a simple
1158b2476490SMike Turquette * case, clk_prepare can be used instead of clk_enable to ungate a clk if the
1159b2476490SMike Turquette * operation may sleep. One example is a clk which is accessed over I2c. In
1160b2476490SMike Turquette * the complex case a clk ungate operation may require a fast and a slow part.
1161b2476490SMike Turquette * It is this reason that clk_prepare and clk_enable are not mutually
1162b2476490SMike Turquette * exclusive. In fact clk_prepare must be called before clk_enable.
1163b2476490SMike Turquette * Returns 0 on success, -EERROR otherwise.
1164b2476490SMike Turquette */
clk_prepare(struct clk * clk)1165b2476490SMike Turquette int clk_prepare(struct clk *clk)
1166b2476490SMike Turquette {
1167035a61c3STomeu Vizoso if (!clk)
1168035a61c3STomeu Vizoso return 0;
1169035a61c3STomeu Vizoso
1170a6adc30bSDong Aisheng return clk_core_prepare_lock(clk->core);
1171b2476490SMike Turquette }
1172b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_prepare);
1173b2476490SMike Turquette
clk_core_disable(struct clk_core * core)1174d6968fcaSStephen Boyd static void clk_core_disable(struct clk_core *core)
1175b2476490SMike Turquette {
1176a6334725SStephen Boyd lockdep_assert_held(&enable_lock);
1177a6334725SStephen Boyd
1178d6968fcaSStephen Boyd if (!core)
1179b2476490SMike Turquette return;
1180b2476490SMike Turquette
1181ab525dccSFabio Estevam if (WARN(core->enable_count == 0, "%s already disabled\n", core->name))
1182b2476490SMike Turquette return;
1183b2476490SMike Turquette
1184ab525dccSFabio Estevam if (WARN(core->enable_count == 1 && core->flags & CLK_IS_CRITICAL,
1185ab525dccSFabio Estevam "Disabling critical %s\n", core->name))
11862e20fbf5SLee Jones return;
11872e20fbf5SLee Jones
1188d6968fcaSStephen Boyd if (--core->enable_count > 0)
1189b2476490SMike Turquette return;
1190b2476490SMike Turquette
1191ca502fc6SPeter Zijlstra trace_clk_disable(core);
1192dfc202eaSStephen Boyd
1193d6968fcaSStephen Boyd if (core->ops->disable)
1194d6968fcaSStephen Boyd core->ops->disable(core->hw);
1195b2476490SMike Turquette
1196ca502fc6SPeter Zijlstra trace_clk_disable_complete(core);
1197dfc202eaSStephen Boyd
1198d6968fcaSStephen Boyd clk_core_disable(core->parent);
1199035a61c3STomeu Vizoso }
1200035a61c3STomeu Vizoso
clk_core_disable_lock(struct clk_core * core)1201a6adc30bSDong Aisheng static void clk_core_disable_lock(struct clk_core *core)
1202a6adc30bSDong Aisheng {
1203a6adc30bSDong Aisheng unsigned long flags;
1204a6adc30bSDong Aisheng
1205a6adc30bSDong Aisheng flags = clk_enable_lock();
1206a6adc30bSDong Aisheng clk_core_disable(core);
1207a6adc30bSDong Aisheng clk_enable_unlock(flags);
1208a6adc30bSDong Aisheng }
1209a6adc30bSDong Aisheng
1210b2476490SMike Turquette /**
1211b2476490SMike Turquette * clk_disable - gate a clock
1212b2476490SMike Turquette * @clk: the clk being gated
1213b2476490SMike Turquette *
1214b2476490SMike Turquette * clk_disable must not sleep, which differentiates it from clk_unprepare. In
1215b2476490SMike Turquette * a simple case, clk_disable can be used instead of clk_unprepare to gate a
1216b2476490SMike Turquette * clk if the operation is fast and will never sleep. One example is a
1217b2476490SMike Turquette * SoC-internal clk which is controlled via simple register writes. In the
1218b2476490SMike Turquette * complex case a clk gate operation may require a fast and a slow part. It is
1219b2476490SMike Turquette * this reason that clk_unprepare and clk_disable are not mutually exclusive.
1220b2476490SMike Turquette * In fact clk_disable must be called before clk_unprepare.
1221b2476490SMike Turquette */
clk_disable(struct clk * clk)1222b2476490SMike Turquette void clk_disable(struct clk *clk)
1223b2476490SMike Turquette {
122463589e92SStephen Boyd if (IS_ERR_OR_NULL(clk))
122563589e92SStephen Boyd return;
122663589e92SStephen Boyd
1227a6adc30bSDong Aisheng clk_core_disable_lock(clk->core);
1228b2476490SMike Turquette }
1229b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_disable);
1230b2476490SMike Turquette
clk_core_enable(struct clk_core * core)1231d6968fcaSStephen Boyd static int clk_core_enable(struct clk_core *core)
1232b2476490SMike Turquette {
1233b2476490SMike Turquette int ret = 0;
1234b2476490SMike Turquette
1235a6334725SStephen Boyd lockdep_assert_held(&enable_lock);
1236a6334725SStephen Boyd
1237d6968fcaSStephen Boyd if (!core)
1238b2476490SMike Turquette return 0;
1239b2476490SMike Turquette
1240ab525dccSFabio Estevam if (WARN(core->prepare_count == 0,
1241ab525dccSFabio Estevam "Enabling unprepared %s\n", core->name))
1242b2476490SMike Turquette return -ESHUTDOWN;
1243b2476490SMike Turquette
1244d6968fcaSStephen Boyd if (core->enable_count == 0) {
1245d6968fcaSStephen Boyd ret = clk_core_enable(core->parent);
1246b2476490SMike Turquette
1247b2476490SMike Turquette if (ret)
1248b2476490SMike Turquette return ret;
1249b2476490SMike Turquette
1250ca502fc6SPeter Zijlstra trace_clk_enable(core);
1251dfc202eaSStephen Boyd
1252d6968fcaSStephen Boyd if (core->ops->enable)
1253d6968fcaSStephen Boyd ret = core->ops->enable(core->hw);
1254dfc202eaSStephen Boyd
1255ca502fc6SPeter Zijlstra trace_clk_enable_complete(core);
1256dfc202eaSStephen Boyd
1257b2476490SMike Turquette if (ret) {
1258d6968fcaSStephen Boyd clk_core_disable(core->parent);
1259b2476490SMike Turquette return ret;
1260b2476490SMike Turquette }
1261b2476490SMike Turquette }
1262b2476490SMike Turquette
1263d6968fcaSStephen Boyd core->enable_count++;
1264b2476490SMike Turquette return 0;
1265b2476490SMike Turquette }
1266b2476490SMike Turquette
clk_core_enable_lock(struct clk_core * core)1267a6adc30bSDong Aisheng static int clk_core_enable_lock(struct clk_core *core)
1268a6adc30bSDong Aisheng {
1269a6adc30bSDong Aisheng unsigned long flags;
1270a6adc30bSDong Aisheng int ret;
1271a6adc30bSDong Aisheng
1272a6adc30bSDong Aisheng flags = clk_enable_lock();
1273a6adc30bSDong Aisheng ret = clk_core_enable(core);
1274a6adc30bSDong Aisheng clk_enable_unlock(flags);
1275a6adc30bSDong Aisheng
1276a6adc30bSDong Aisheng return ret;
1277a6adc30bSDong Aisheng }
1278a6adc30bSDong Aisheng
127943536548SKeerthy /**
128043536548SKeerthy * clk_gate_restore_context - restore context for poweroff
128143536548SKeerthy * @hw: the clk_hw pointer of clock whose state is to be restored
128243536548SKeerthy *
128343536548SKeerthy * The clock gate restore context function enables or disables
128443536548SKeerthy * the gate clocks based on the enable_count. This is done in cases
128543536548SKeerthy * where the clock context is lost and based on the enable_count
128643536548SKeerthy * the clock either needs to be enabled/disabled. This
128743536548SKeerthy * helps restore the state of gate clocks.
128843536548SKeerthy */
clk_gate_restore_context(struct clk_hw * hw)128943536548SKeerthy void clk_gate_restore_context(struct clk_hw *hw)
129043536548SKeerthy {
12919be76627SStephen Boyd struct clk_core *core = hw->core;
12929be76627SStephen Boyd
12939be76627SStephen Boyd if (core->enable_count)
12949be76627SStephen Boyd core->ops->enable(hw);
129543536548SKeerthy else
12969be76627SStephen Boyd core->ops->disable(hw);
129743536548SKeerthy }
129843536548SKeerthy EXPORT_SYMBOL_GPL(clk_gate_restore_context);
129943536548SKeerthy
clk_core_save_context(struct clk_core * core)13009be76627SStephen Boyd static int clk_core_save_context(struct clk_core *core)
13018b95d1ceSRuss Dill {
13028b95d1ceSRuss Dill struct clk_core *child;
13038b95d1ceSRuss Dill int ret = 0;
13048b95d1ceSRuss Dill
13059be76627SStephen Boyd hlist_for_each_entry(child, &core->children, child_node) {
13069be76627SStephen Boyd ret = clk_core_save_context(child);
13078b95d1ceSRuss Dill if (ret < 0)
13088b95d1ceSRuss Dill return ret;
13098b95d1ceSRuss Dill }
13108b95d1ceSRuss Dill
13119be76627SStephen Boyd if (core->ops && core->ops->save_context)
13129be76627SStephen Boyd ret = core->ops->save_context(core->hw);
13138b95d1ceSRuss Dill
13148b95d1ceSRuss Dill return ret;
13158b95d1ceSRuss Dill }
13168b95d1ceSRuss Dill
clk_core_restore_context(struct clk_core * core)13179be76627SStephen Boyd static void clk_core_restore_context(struct clk_core *core)
13188b95d1ceSRuss Dill {
13198b95d1ceSRuss Dill struct clk_core *child;
13208b95d1ceSRuss Dill
13219be76627SStephen Boyd if (core->ops && core->ops->restore_context)
13229be76627SStephen Boyd core->ops->restore_context(core->hw);
13238b95d1ceSRuss Dill
13249be76627SStephen Boyd hlist_for_each_entry(child, &core->children, child_node)
13259be76627SStephen Boyd clk_core_restore_context(child);
13268b95d1ceSRuss Dill }
13278b95d1ceSRuss Dill
13288b95d1ceSRuss Dill /**
13298b95d1ceSRuss Dill * clk_save_context - save clock context for poweroff
13308b95d1ceSRuss Dill *
13318b95d1ceSRuss Dill * Saves the context of the clock register for powerstates in which the
13328b95d1ceSRuss Dill * contents of the registers will be lost. Occurs deep within the suspend
13338b95d1ceSRuss Dill * code. Returns 0 on success.
13348b95d1ceSRuss Dill */
clk_save_context(void)13358b95d1ceSRuss Dill int clk_save_context(void)
13368b95d1ceSRuss Dill {
13378b95d1ceSRuss Dill struct clk_core *clk;
13388b95d1ceSRuss Dill int ret;
13398b95d1ceSRuss Dill
13408b95d1ceSRuss Dill hlist_for_each_entry(clk, &clk_root_list, child_node) {
13419be76627SStephen Boyd ret = clk_core_save_context(clk);
13428b95d1ceSRuss Dill if (ret < 0)
13438b95d1ceSRuss Dill return ret;
13448b95d1ceSRuss Dill }
13458b95d1ceSRuss Dill
13468b95d1ceSRuss Dill hlist_for_each_entry(clk, &clk_orphan_list, child_node) {
13479be76627SStephen Boyd ret = clk_core_save_context(clk);
13488b95d1ceSRuss Dill if (ret < 0)
13498b95d1ceSRuss Dill return ret;
13508b95d1ceSRuss Dill }
13518b95d1ceSRuss Dill
13528b95d1ceSRuss Dill return 0;
13538b95d1ceSRuss Dill }
13548b95d1ceSRuss Dill EXPORT_SYMBOL_GPL(clk_save_context);
13558b95d1ceSRuss Dill
13568b95d1ceSRuss Dill /**
13578b95d1ceSRuss Dill * clk_restore_context - restore clock context after poweroff
13588b95d1ceSRuss Dill *
13598b95d1ceSRuss Dill * Restore the saved clock context upon resume.
13608b95d1ceSRuss Dill *
13618b95d1ceSRuss Dill */
clk_restore_context(void)13628b95d1ceSRuss Dill void clk_restore_context(void)
13638b95d1ceSRuss Dill {
13649be76627SStephen Boyd struct clk_core *core;
13658b95d1ceSRuss Dill
13669be76627SStephen Boyd hlist_for_each_entry(core, &clk_root_list, child_node)
13679be76627SStephen Boyd clk_core_restore_context(core);
13688b95d1ceSRuss Dill
13699be76627SStephen Boyd hlist_for_each_entry(core, &clk_orphan_list, child_node)
13709be76627SStephen Boyd clk_core_restore_context(core);
13718b95d1ceSRuss Dill }
13728b95d1ceSRuss Dill EXPORT_SYMBOL_GPL(clk_restore_context);
13738b95d1ceSRuss Dill
1374b2476490SMike Turquette /**
1375b2476490SMike Turquette * clk_enable - ungate a clock
1376b2476490SMike Turquette * @clk: the clk being ungated
1377b2476490SMike Turquette *
1378b2476490SMike Turquette * clk_enable must not sleep, which differentiates it from clk_prepare. In a
1379b2476490SMike Turquette * simple case, clk_enable can be used instead of clk_prepare to ungate a clk
1380b2476490SMike Turquette * if the operation will never sleep. One example is a SoC-internal clk which
1381b2476490SMike Turquette * is controlled via simple register writes. In the complex case a clk ungate
1382b2476490SMike Turquette * operation may require a fast and a slow part. It is this reason that
1383b2476490SMike Turquette * clk_enable and clk_prepare are not mutually exclusive. In fact clk_prepare
1384b2476490SMike Turquette * must be called before clk_enable. Returns 0 on success, -EERROR
1385b2476490SMike Turquette * otherwise.
1386b2476490SMike Turquette */
clk_enable(struct clk * clk)1387b2476490SMike Turquette int clk_enable(struct clk *clk)
1388b2476490SMike Turquette {
1389864e160aSDong Aisheng if (!clk)
1390864e160aSDong Aisheng return 0;
1391864e160aSDong Aisheng
1392a6adc30bSDong Aisheng return clk_core_enable_lock(clk->core);
1393a6adc30bSDong Aisheng }
1394a6adc30bSDong Aisheng EXPORT_SYMBOL_GPL(clk_enable);
1395a6adc30bSDong Aisheng
13960bfa0820SNicolas Pitre /**
13970bfa0820SNicolas Pitre * clk_is_enabled_when_prepared - indicate if preparing a clock also enables it.
13980bfa0820SNicolas Pitre * @clk: clock source
13990bfa0820SNicolas Pitre *
14000bfa0820SNicolas Pitre * Returns true if clk_prepare() implicitly enables the clock, effectively
14010bfa0820SNicolas Pitre * making clk_enable()/clk_disable() no-ops, false otherwise.
14020bfa0820SNicolas Pitre *
14030bfa0820SNicolas Pitre * This is of interest mainly to power management code where actually
14040bfa0820SNicolas Pitre * disabling the clock also requires unpreparing it to have any material
14050bfa0820SNicolas Pitre * effect.
14060bfa0820SNicolas Pitre *
14070bfa0820SNicolas Pitre * Regardless of the value returned here, the caller must always invoke
14080bfa0820SNicolas Pitre * clk_enable() or clk_prepare_enable() and counterparts for usage counts
14090bfa0820SNicolas Pitre * to be right.
14100bfa0820SNicolas Pitre */
clk_is_enabled_when_prepared(struct clk * clk)14110bfa0820SNicolas Pitre bool clk_is_enabled_when_prepared(struct clk *clk)
14120bfa0820SNicolas Pitre {
14130bfa0820SNicolas Pitre return clk && !(clk->core->ops->enable && clk->core->ops->disable);
14140bfa0820SNicolas Pitre }
14150bfa0820SNicolas Pitre EXPORT_SYMBOL_GPL(clk_is_enabled_when_prepared);
14160bfa0820SNicolas Pitre
clk_core_prepare_enable(struct clk_core * core)1417a6adc30bSDong Aisheng static int clk_core_prepare_enable(struct clk_core *core)
1418a6adc30bSDong Aisheng {
1419a6adc30bSDong Aisheng int ret;
1420a6adc30bSDong Aisheng
1421a6adc30bSDong Aisheng ret = clk_core_prepare_lock(core);
1422a6adc30bSDong Aisheng if (ret)
1423a6adc30bSDong Aisheng return ret;
1424a6adc30bSDong Aisheng
1425a6adc30bSDong Aisheng ret = clk_core_enable_lock(core);
1426a6adc30bSDong Aisheng if (ret)
1427a6adc30bSDong Aisheng clk_core_unprepare_lock(core);
1428b2476490SMike Turquette
1429b2476490SMike Turquette return ret;
1430b2476490SMike Turquette }
1431a6adc30bSDong Aisheng
clk_core_disable_unprepare(struct clk_core * core)1432a6adc30bSDong Aisheng static void clk_core_disable_unprepare(struct clk_core *core)
1433a6adc30bSDong Aisheng {
1434a6adc30bSDong Aisheng clk_core_disable_lock(core);
1435a6adc30bSDong Aisheng clk_core_unprepare_lock(core);
1436a6adc30bSDong Aisheng }
1437b2476490SMike Turquette
clk_unprepare_unused_subtree(struct clk_core * core)1438564f86d3SRasmus Villemoes static void __init clk_unprepare_unused_subtree(struct clk_core *core)
14397ec986efSDong Aisheng {
14407ec986efSDong Aisheng struct clk_core *child;
14417ec986efSDong Aisheng
14427ec986efSDong Aisheng lockdep_assert_held(&prepare_lock);
14437ec986efSDong Aisheng
14447ec986efSDong Aisheng hlist_for_each_entry(child, &core->children, child_node)
14457ec986efSDong Aisheng clk_unprepare_unused_subtree(child);
14467ec986efSDong Aisheng
14477ec986efSDong Aisheng if (core->prepare_count)
14487ec986efSDong Aisheng return;
14497ec986efSDong Aisheng
14507ec986efSDong Aisheng if (core->flags & CLK_IGNORE_UNUSED)
14517ec986efSDong Aisheng return;
14527ec986efSDong Aisheng
14537ec986efSDong Aisheng if (clk_core_is_prepared(core)) {
14547ec986efSDong Aisheng trace_clk_unprepare(core);
14557ec986efSDong Aisheng if (core->ops->unprepare_unused)
14567ec986efSDong Aisheng core->ops->unprepare_unused(core->hw);
14577ec986efSDong Aisheng else if (core->ops->unprepare)
14587ec986efSDong Aisheng core->ops->unprepare(core->hw);
14597ec986efSDong Aisheng trace_clk_unprepare_complete(core);
14607ec986efSDong Aisheng }
14617ec986efSDong Aisheng }
14627ec986efSDong Aisheng
clk_disable_unused_subtree(struct clk_core * core)1463564f86d3SRasmus Villemoes static void __init clk_disable_unused_subtree(struct clk_core *core)
14647ec986efSDong Aisheng {
14657ec986efSDong Aisheng struct clk_core *child;
14667ec986efSDong Aisheng unsigned long flags;
14677ec986efSDong Aisheng
14687ec986efSDong Aisheng lockdep_assert_held(&prepare_lock);
14697ec986efSDong Aisheng
14707ec986efSDong Aisheng hlist_for_each_entry(child, &core->children, child_node)
14717ec986efSDong Aisheng clk_disable_unused_subtree(child);
14727ec986efSDong Aisheng
1473a4b3518dSDong Aisheng if (core->flags & CLK_OPS_PARENT_ENABLE)
1474a4b3518dSDong Aisheng clk_core_prepare_enable(core->parent);
1475a4b3518dSDong Aisheng
14767ec986efSDong Aisheng flags = clk_enable_lock();
14777ec986efSDong Aisheng
14787ec986efSDong Aisheng if (core->enable_count)
14797ec986efSDong Aisheng goto unlock_out;
14807ec986efSDong Aisheng
14817ec986efSDong Aisheng if (core->flags & CLK_IGNORE_UNUSED)
14827ec986efSDong Aisheng goto unlock_out;
14837ec986efSDong Aisheng
14847ec986efSDong Aisheng /*
14857ec986efSDong Aisheng * some gate clocks have special needs during the disable-unused
14867ec986efSDong Aisheng * sequence. call .disable_unused if available, otherwise fall
14877ec986efSDong Aisheng * back to .disable
14887ec986efSDong Aisheng */
14897ec986efSDong Aisheng if (clk_core_is_enabled(core)) {
14907ec986efSDong Aisheng trace_clk_disable(core);
14917ec986efSDong Aisheng if (core->ops->disable_unused)
14927ec986efSDong Aisheng core->ops->disable_unused(core->hw);
14937ec986efSDong Aisheng else if (core->ops->disable)
14947ec986efSDong Aisheng core->ops->disable(core->hw);
14957ec986efSDong Aisheng trace_clk_disable_complete(core);
14967ec986efSDong Aisheng }
14977ec986efSDong Aisheng
14987ec986efSDong Aisheng unlock_out:
14997ec986efSDong Aisheng clk_enable_unlock(flags);
1500a4b3518dSDong Aisheng if (core->flags & CLK_OPS_PARENT_ENABLE)
1501a4b3518dSDong Aisheng clk_core_disable_unprepare(core->parent);
15027ec986efSDong Aisheng }
15037ec986efSDong Aisheng
1504564f86d3SRasmus Villemoes static bool clk_ignore_unused __initdata;
clk_ignore_unused_setup(char * __unused)15057ec986efSDong Aisheng static int __init clk_ignore_unused_setup(char *__unused)
15067ec986efSDong Aisheng {
15077ec986efSDong Aisheng clk_ignore_unused = true;
15087ec986efSDong Aisheng return 1;
15097ec986efSDong Aisheng }
15107ec986efSDong Aisheng __setup("clk_ignore_unused", clk_ignore_unused_setup);
15117ec986efSDong Aisheng
clk_disable_unused(void)1512564f86d3SRasmus Villemoes static int __init clk_disable_unused(void)
15137ec986efSDong Aisheng {
15147ec986efSDong Aisheng struct clk_core *core;
151560ff482cSStephen Boyd int ret;
15167ec986efSDong Aisheng
15177ec986efSDong Aisheng if (clk_ignore_unused) {
15187ec986efSDong Aisheng pr_warn("clk: Not disabling unused clocks\n");
15197ec986efSDong Aisheng return 0;
15207ec986efSDong Aisheng }
15217ec986efSDong Aisheng
152212ca59b9SKonrad Dybcio pr_info("clk: Disabling unused clocks\n");
152312ca59b9SKonrad Dybcio
152460ff482cSStephen Boyd ret = clk_pm_runtime_get_all();
152560ff482cSStephen Boyd if (ret)
152660ff482cSStephen Boyd return ret;
152760ff482cSStephen Boyd /*
152860ff482cSStephen Boyd * Grab the prepare lock to keep the clk topology stable while iterating
152960ff482cSStephen Boyd * over clks.
153060ff482cSStephen Boyd */
15317ec986efSDong Aisheng clk_prepare_lock();
15327ec986efSDong Aisheng
15337ec986efSDong Aisheng hlist_for_each_entry(core, &clk_root_list, child_node)
15347ec986efSDong Aisheng clk_disable_unused_subtree(core);
15357ec986efSDong Aisheng
15367ec986efSDong Aisheng hlist_for_each_entry(core, &clk_orphan_list, child_node)
15377ec986efSDong Aisheng clk_disable_unused_subtree(core);
15387ec986efSDong Aisheng
15397ec986efSDong Aisheng hlist_for_each_entry(core, &clk_root_list, child_node)
15407ec986efSDong Aisheng clk_unprepare_unused_subtree(core);
15417ec986efSDong Aisheng
15427ec986efSDong Aisheng hlist_for_each_entry(core, &clk_orphan_list, child_node)
15437ec986efSDong Aisheng clk_unprepare_unused_subtree(core);
15447ec986efSDong Aisheng
15457ec986efSDong Aisheng clk_prepare_unlock();
15467ec986efSDong Aisheng
154760ff482cSStephen Boyd clk_pm_runtime_put_all();
154860ff482cSStephen Boyd
15497ec986efSDong Aisheng return 0;
15507ec986efSDong Aisheng }
15517ec986efSDong Aisheng late_initcall_sync(clk_disable_unused);
15527ec986efSDong Aisheng
clk_core_determine_round_nolock(struct clk_core * core,struct clk_rate_request * req)15530f6cc2b8SJerome Brunet static int clk_core_determine_round_nolock(struct clk_core *core,
15540817b62cSBoris Brezillon struct clk_rate_request *req)
1555b2476490SMike Turquette {
15560817b62cSBoris Brezillon long rate;
1557b2476490SMike Turquette
1558496eadf8SKrzysztof Kozlowski lockdep_assert_held(&prepare_lock);
1559496eadf8SKrzysztof Kozlowski
1560d6968fcaSStephen Boyd if (!core)
15612ac6b1f5SStephen Boyd return 0;
1562b2476490SMike Turquette
1563facf949bSMaxime Ripard /*
1564facf949bSMaxime Ripard * Some clock providers hand-craft their clk_rate_requests and
1565facf949bSMaxime Ripard * might not fill min_rate and max_rate.
1566facf949bSMaxime Ripard *
1567facf949bSMaxime Ripard * If it's the case, clamping the rate is equivalent to setting
1568facf949bSMaxime Ripard * the rate to 0 which is bad. Skip the clamping but complain so
1569facf949bSMaxime Ripard * that it gets fixed, hopefully.
1570facf949bSMaxime Ripard */
1571facf949bSMaxime Ripard if (!req->min_rate && !req->max_rate)
1572facf949bSMaxime Ripard pr_warn("%s: %s: clk_rate_request has initialized min or max rate.\n",
1573facf949bSMaxime Ripard __func__, core->name);
1574facf949bSMaxime Ripard else
1575948fb096SMaxime Ripard req->rate = clamp(req->rate, req->min_rate, req->max_rate);
1576948fb096SMaxime Ripard
157755e9b8b7SJerome Brunet /*
1578e27453adSGeert Uytterhoeven * At this point, core protection will be disabled
157955e9b8b7SJerome Brunet * - if the provider is not protected at all
158055e9b8b7SJerome Brunet * - if the calling consumer is the only one which has exclusivity
158155e9b8b7SJerome Brunet * over the provider
158255e9b8b7SJerome Brunet */
1583e55a839aSJerome Brunet if (clk_core_rate_is_protected(core)) {
1584e55a839aSJerome Brunet req->rate = core->rate;
1585e55a839aSJerome Brunet } else if (core->ops->determine_rate) {
15860817b62cSBoris Brezillon return core->ops->determine_rate(core->hw, req);
15870817b62cSBoris Brezillon } else if (core->ops->round_rate) {
15880817b62cSBoris Brezillon rate = core->ops->round_rate(core->hw, req->rate,
15890817b62cSBoris Brezillon &req->best_parent_rate);
15900817b62cSBoris Brezillon if (rate < 0)
15910817b62cSBoris Brezillon return rate;
15920817b62cSBoris Brezillon
15930817b62cSBoris Brezillon req->rate = rate;
15940817b62cSBoris Brezillon } else {
15950f6cc2b8SJerome Brunet return -EINVAL;
15960817b62cSBoris Brezillon }
15970817b62cSBoris Brezillon
15980817b62cSBoris Brezillon return 0;
1599f4d8af2eSShawn Guo }
1600035a61c3STomeu Vizoso
clk_core_init_rate_req(struct clk_core * const core,struct clk_rate_request * req,unsigned long rate)16010f6cc2b8SJerome Brunet static void clk_core_init_rate_req(struct clk_core * const core,
1602718af795SMaxime Ripard struct clk_rate_request *req,
1603718af795SMaxime Ripard unsigned long rate)
16040f6cc2b8SJerome Brunet {
16050f6cc2b8SJerome Brunet struct clk_core *parent;
16060f6cc2b8SJerome Brunet
16072079d029SMaxime Ripard if (WARN_ON(!req))
16080f6cc2b8SJerome Brunet return;
16090f6cc2b8SJerome Brunet
1610b46fd8dbSMaxime Ripard memset(req, 0, sizeof(*req));
1611774560cfSMaxime Ripard req->max_rate = ULONG_MAX;
1612b46fd8dbSMaxime Ripard
16132079d029SMaxime Ripard if (!core)
16142079d029SMaxime Ripard return;
16152079d029SMaxime Ripard
1616ef13f8b6SMaxime Ripard req->core = core;
1617718af795SMaxime Ripard req->rate = rate;
161811c84a38SMaxime Ripard clk_core_get_boundaries(core, &req->min_rate, &req->max_rate);
1619718af795SMaxime Ripard
1620b2476490SMike Turquette parent = core->parent;
1621b2476490SMike Turquette if (parent) {
1622b2476490SMike Turquette req->best_parent_hw = parent->hw;
1623b2476490SMike Turquette req->best_parent_rate = parent->rate;
1624b2476490SMike Turquette } else {
1625b2476490SMike Turquette req->best_parent_hw = NULL;
1626b2476490SMike Turquette req->best_parent_rate = 0;
1627b2476490SMike Turquette }
1628b2476490SMike Turquette }
162981536e07SShawn Guo
1630c35e84b0SMaxime Ripard /**
1631c35e84b0SMaxime Ripard * clk_hw_init_rate_request - Initializes a clk_rate_request
1632c35e84b0SMaxime Ripard * @hw: the clk for which we want to submit a rate request
1633c35e84b0SMaxime Ripard * @req: the clk_rate_request structure we want to initialise
1634c35e84b0SMaxime Ripard * @rate: the rate which is to be requested
1635c35e84b0SMaxime Ripard *
1636c35e84b0SMaxime Ripard * Initializes a clk_rate_request structure to submit to
1637c35e84b0SMaxime Ripard * __clk_determine_rate() or similar functions.
1638c35e84b0SMaxime Ripard */
clk_hw_init_rate_request(const struct clk_hw * hw,struct clk_rate_request * req,unsigned long rate)1639c35e84b0SMaxime Ripard void clk_hw_init_rate_request(const struct clk_hw *hw,
1640c35e84b0SMaxime Ripard struct clk_rate_request *req,
1641c35e84b0SMaxime Ripard unsigned long rate)
1642c35e84b0SMaxime Ripard {
1643c35e84b0SMaxime Ripard if (WARN_ON(!hw || !req))
1644c35e84b0SMaxime Ripard return;
1645c35e84b0SMaxime Ripard
1646c35e84b0SMaxime Ripard clk_core_init_rate_req(hw->core, req, rate);
1647c35e84b0SMaxime Ripard }
1648c35e84b0SMaxime Ripard EXPORT_SYMBOL_GPL(clk_hw_init_rate_request);
1649c35e84b0SMaxime Ripard
1650262ca38fSMaxime Ripard /**
1651262ca38fSMaxime Ripard * clk_hw_forward_rate_request - Forwards a clk_rate_request to a clock's parent
1652262ca38fSMaxime Ripard * @hw: the original clock that got the rate request
1653262ca38fSMaxime Ripard * @old_req: the original clk_rate_request structure we want to forward
1654262ca38fSMaxime Ripard * @parent: the clk we want to forward @old_req to
1655262ca38fSMaxime Ripard * @req: the clk_rate_request structure we want to initialise
1656262ca38fSMaxime Ripard * @parent_rate: The rate which is to be requested to @parent
1657262ca38fSMaxime Ripard *
1658262ca38fSMaxime Ripard * Initializes a clk_rate_request structure to submit to a clock parent
1659262ca38fSMaxime Ripard * in __clk_determine_rate() or similar functions.
1660262ca38fSMaxime Ripard */
clk_hw_forward_rate_request(const struct clk_hw * hw,const struct clk_rate_request * old_req,const struct clk_hw * parent,struct clk_rate_request * req,unsigned long parent_rate)1661262ca38fSMaxime Ripard void clk_hw_forward_rate_request(const struct clk_hw *hw,
1662262ca38fSMaxime Ripard const struct clk_rate_request *old_req,
1663262ca38fSMaxime Ripard const struct clk_hw *parent,
1664262ca38fSMaxime Ripard struct clk_rate_request *req,
1665262ca38fSMaxime Ripard unsigned long parent_rate)
1666262ca38fSMaxime Ripard {
1667262ca38fSMaxime Ripard if (WARN_ON(!hw || !old_req || !parent || !req))
1668262ca38fSMaxime Ripard return;
1669262ca38fSMaxime Ripard
1670262ca38fSMaxime Ripard clk_core_forward_rate_req(hw->core, old_req,
1671262ca38fSMaxime Ripard parent->core, req,
1672262ca38fSMaxime Ripard parent_rate);
1673262ca38fSMaxime Ripard }
1674ed046ac7SMaxime Ripard EXPORT_SYMBOL_GPL(clk_hw_forward_rate_request);
1675262ca38fSMaxime Ripard
clk_core_can_round(struct clk_core * const core)16760f6cc2b8SJerome Brunet static bool clk_core_can_round(struct clk_core * const core)
16770f6cc2b8SJerome Brunet {
1678eef1f1b6SGeert Uytterhoeven return core->ops->determine_rate || core->ops->round_rate;
16790f6cc2b8SJerome Brunet }
16800f6cc2b8SJerome Brunet
clk_core_round_rate_nolock(struct clk_core * core,struct clk_rate_request * req)16810f6cc2b8SJerome Brunet static int clk_core_round_rate_nolock(struct clk_core *core,
16820f6cc2b8SJerome Brunet struct clk_rate_request *req)
16830f6cc2b8SJerome Brunet {
1684262ca38fSMaxime Ripard int ret;
1685262ca38fSMaxime Ripard
16860f6cc2b8SJerome Brunet lockdep_assert_held(&prepare_lock);
16870f6cc2b8SJerome Brunet
168804bf9ab3SJerome Brunet if (!core) {
168904bf9ab3SJerome Brunet req->rate = 0;
16900f6cc2b8SJerome Brunet return 0;
169104bf9ab3SJerome Brunet }
16920f6cc2b8SJerome Brunet
16930f6cc2b8SJerome Brunet if (clk_core_can_round(core))
16940f6cc2b8SJerome Brunet return clk_core_determine_round_nolock(core, req);
1695262ca38fSMaxime Ripard
1696262ca38fSMaxime Ripard if (core->flags & CLK_SET_RATE_PARENT) {
1697262ca38fSMaxime Ripard struct clk_rate_request parent_req;
1698262ca38fSMaxime Ripard
1699262ca38fSMaxime Ripard clk_core_forward_rate_req(core, req, core->parent, &parent_req, req->rate);
170049e62e0dSMaxime Ripard
170149e62e0dSMaxime Ripard trace_clk_rate_request_start(&parent_req);
170249e62e0dSMaxime Ripard
1703262ca38fSMaxime Ripard ret = clk_core_round_rate_nolock(core->parent, &parent_req);
1704262ca38fSMaxime Ripard if (ret)
1705262ca38fSMaxime Ripard return ret;
1706262ca38fSMaxime Ripard
170749e62e0dSMaxime Ripard trace_clk_rate_request_done(&parent_req);
170849e62e0dSMaxime Ripard
1709262ca38fSMaxime Ripard req->best_parent_rate = parent_req.rate;
1710262ca38fSMaxime Ripard req->rate = parent_req.rate;
1711262ca38fSMaxime Ripard
1712262ca38fSMaxime Ripard return 0;
1713262ca38fSMaxime Ripard }
17140f6cc2b8SJerome Brunet
17150f6cc2b8SJerome Brunet req->rate = core->rate;
171681536e07SShawn Guo return 0;
171781536e07SShawn Guo }
1718035a61c3STomeu Vizoso
1719035a61c3STomeu Vizoso /**
17201c8e6004STomeu Vizoso * __clk_determine_rate - get the closest rate actually supported by a clock
17211c8e6004STomeu Vizoso * @hw: determine the rate of this clock
17222d5b520cSPeng Fan * @req: target rate request
17231c8e6004STomeu Vizoso *
17246e5ab41bSStephen Boyd * Useful for clk_ops such as .set_rate and .determine_rate.
17251c8e6004STomeu Vizoso */
__clk_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)17260817b62cSBoris Brezillon int __clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
17271c8e6004STomeu Vizoso {
17280817b62cSBoris Brezillon if (!hw) {
17290817b62cSBoris Brezillon req->rate = 0;
17301c8e6004STomeu Vizoso return 0;
17310817b62cSBoris Brezillon }
17321c8e6004STomeu Vizoso
17330817b62cSBoris Brezillon return clk_core_round_rate_nolock(hw->core, req);
17341c8e6004STomeu Vizoso }
17351c8e6004STomeu Vizoso EXPORT_SYMBOL_GPL(__clk_determine_rate);
17361c8e6004STomeu Vizoso
1737e8c849c2SSarang Mairal /**
1738e8c849c2SSarang Mairal * clk_hw_round_rate() - round the given rate for a hw clk
1739e8c849c2SSarang Mairal * @hw: the hw clk for which we are rounding a rate
1740e8c849c2SSarang Mairal * @rate: the rate which is to be rounded
1741e8c849c2SSarang Mairal *
1742e8c849c2SSarang Mairal * Takes in a rate as input and rounds it to a rate that the clk can actually
1743e8c849c2SSarang Mairal * use.
1744e8c849c2SSarang Mairal *
1745e8c849c2SSarang Mairal * Context: prepare_lock must be held.
1746e8c849c2SSarang Mairal * For clk providers to call from within clk_ops such as .round_rate,
1747e8c849c2SSarang Mairal * .determine_rate.
1748e8c849c2SSarang Mairal *
1749e8c849c2SSarang Mairal * Return: returns rounded rate of hw clk if clk supports round_rate operation
1750e8c849c2SSarang Mairal * else returns the parent rate.
1751e8c849c2SSarang Mairal */
clk_hw_round_rate(struct clk_hw * hw,unsigned long rate)17521a9c069cSStephen Boyd unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate)
17531a9c069cSStephen Boyd {
17541a9c069cSStephen Boyd int ret;
17551a9c069cSStephen Boyd struct clk_rate_request req;
17561a9c069cSStephen Boyd
17578cd9c39dSMaxime Ripard clk_core_init_rate_req(hw->core, &req, rate);
17581a9c069cSStephen Boyd
175949e62e0dSMaxime Ripard trace_clk_rate_request_start(&req);
176049e62e0dSMaxime Ripard
17611a9c069cSStephen Boyd ret = clk_core_round_rate_nolock(hw->core, &req);
17621a9c069cSStephen Boyd if (ret)
17631a9c069cSStephen Boyd return 0;
17641a9c069cSStephen Boyd
176549e62e0dSMaxime Ripard trace_clk_rate_request_done(&req);
176649e62e0dSMaxime Ripard
17671a9c069cSStephen Boyd return req.rate;
17681a9c069cSStephen Boyd }
17691a9c069cSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_round_rate);
17701a9c069cSStephen Boyd
1771b2476490SMike Turquette /**
1772b2476490SMike Turquette * clk_round_rate - round the given rate for a clk
1773b2476490SMike Turquette * @clk: the clk for which we are rounding a rate
1774b2476490SMike Turquette * @rate: the rate which is to be rounded
1775b2476490SMike Turquette *
1776b2476490SMike Turquette * Takes in a rate as input and rounds it to a rate that the clk can actually
1777b2476490SMike Turquette * use which is then returned. If clk doesn't support round_rate operation
1778b2476490SMike Turquette * then the parent rate is returned.
1779b2476490SMike Turquette */
clk_round_rate(struct clk * clk,unsigned long rate)1780b2476490SMike Turquette long clk_round_rate(struct clk *clk, unsigned long rate)
1781b2476490SMike Turquette {
1782fc4a05d4SStephen Boyd struct clk_rate_request req;
1783fc4a05d4SStephen Boyd int ret;
1784b2476490SMike Turquette
1785035a61c3STomeu Vizoso if (!clk)
1786035a61c3STomeu Vizoso return 0;
1787035a61c3STomeu Vizoso
1788eab89f69SMike Turquette clk_prepare_lock();
1789fc4a05d4SStephen Boyd
179055e9b8b7SJerome Brunet if (clk->exclusive_count)
179155e9b8b7SJerome Brunet clk_core_rate_unprotect(clk->core);
179255e9b8b7SJerome Brunet
17938cd9c39dSMaxime Ripard clk_core_init_rate_req(clk->core, &req, rate);
1794fc4a05d4SStephen Boyd
179549e62e0dSMaxime Ripard trace_clk_rate_request_start(&req);
179649e62e0dSMaxime Ripard
1797fc4a05d4SStephen Boyd ret = clk_core_round_rate_nolock(clk->core, &req);
179855e9b8b7SJerome Brunet
179949e62e0dSMaxime Ripard trace_clk_rate_request_done(&req);
180049e62e0dSMaxime Ripard
180155e9b8b7SJerome Brunet if (clk->exclusive_count)
180255e9b8b7SJerome Brunet clk_core_rate_protect(clk->core);
180355e9b8b7SJerome Brunet
1804eab89f69SMike Turquette clk_prepare_unlock();
1805b2476490SMike Turquette
1806fc4a05d4SStephen Boyd if (ret)
1807b2476490SMike Turquette return ret;
1808fc4a05d4SStephen Boyd
1809fc4a05d4SStephen Boyd return req.rate;
1810b2476490SMike Turquette }
1811b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_round_rate);
1812b2476490SMike Turquette
1813b2476490SMike Turquette /**
1814b2476490SMike Turquette * __clk_notify - call clk notifier chain
1815d6968fcaSStephen Boyd * @core: clk that is changing rate
1816b2476490SMike Turquette * @msg: clk notifier type (see include/linux/clk.h)
1817b2476490SMike Turquette * @old_rate: old clk rate
1818b2476490SMike Turquette * @new_rate: new clk rate
1819b2476490SMike Turquette *
1820b2476490SMike Turquette * Triggers a notifier call chain on the clk rate-change notification
1821b2476490SMike Turquette * for 'clk'. Passes a pointer to the struct clk and the previous
1822b2476490SMike Turquette * and current rates to the notifier callback. Intended to be called by
1823b2476490SMike Turquette * internal clock code only. Returns NOTIFY_DONE from the last driver
1824b2476490SMike Turquette * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
1825b2476490SMike Turquette * a driver returns that.
1826b2476490SMike Turquette */
__clk_notify(struct clk_core * core,unsigned long msg,unsigned long old_rate,unsigned long new_rate)1827d6968fcaSStephen Boyd static int __clk_notify(struct clk_core *core, unsigned long msg,
1828b2476490SMike Turquette unsigned long old_rate, unsigned long new_rate)
1829b2476490SMike Turquette {
1830b2476490SMike Turquette struct clk_notifier *cn;
1831b2476490SMike Turquette struct clk_notifier_data cnd;
1832b2476490SMike Turquette int ret = NOTIFY_DONE;
1833b2476490SMike Turquette
1834b2476490SMike Turquette cnd.old_rate = old_rate;
1835b2476490SMike Turquette cnd.new_rate = new_rate;
1836b2476490SMike Turquette
1837b2476490SMike Turquette list_for_each_entry(cn, &clk_notifier_list, node) {
1838d6968fcaSStephen Boyd if (cn->clk->core == core) {
1839035a61c3STomeu Vizoso cnd.clk = cn->clk;
1840b2476490SMike Turquette ret = srcu_notifier_call_chain(&cn->notifier_head, msg,
1841b2476490SMike Turquette &cnd);
184217c34c56SPeter De Schrijver if (ret & NOTIFY_STOP_MASK)
184317c34c56SPeter De Schrijver return ret;
1844b2476490SMike Turquette }
1845b2476490SMike Turquette }
1846b2476490SMike Turquette
1847b2476490SMike Turquette return ret;
1848b2476490SMike Turquette }
1849b2476490SMike Turquette
1850b2476490SMike Turquette /**
18515279fc40SBoris BREZILLON * __clk_recalc_accuracies
1852d6968fcaSStephen Boyd * @core: first clk in the subtree
18535279fc40SBoris BREZILLON *
18545279fc40SBoris BREZILLON * Walks the subtree of clks starting with clk and recalculates accuracies as
18555279fc40SBoris BREZILLON * it goes. Note that if a clk does not implement the .recalc_accuracy
18566e5ab41bSStephen Boyd * callback then it is assumed that the clock will take on the accuracy of its
18575279fc40SBoris BREZILLON * parent.
18585279fc40SBoris BREZILLON */
__clk_recalc_accuracies(struct clk_core * core)1859d6968fcaSStephen Boyd static void __clk_recalc_accuracies(struct clk_core *core)
18605279fc40SBoris BREZILLON {
18615279fc40SBoris BREZILLON unsigned long parent_accuracy = 0;
1862035a61c3STomeu Vizoso struct clk_core *child;
18635279fc40SBoris BREZILLON
1864496eadf8SKrzysztof Kozlowski lockdep_assert_held(&prepare_lock);
1865496eadf8SKrzysztof Kozlowski
1866d6968fcaSStephen Boyd if (core->parent)
1867d6968fcaSStephen Boyd parent_accuracy = core->parent->accuracy;
18685279fc40SBoris BREZILLON
1869d6968fcaSStephen Boyd if (core->ops->recalc_accuracy)
1870d6968fcaSStephen Boyd core->accuracy = core->ops->recalc_accuracy(core->hw,
18715279fc40SBoris BREZILLON parent_accuracy);
18725279fc40SBoris BREZILLON else
1873d6968fcaSStephen Boyd core->accuracy = parent_accuracy;
18745279fc40SBoris BREZILLON
1875d6968fcaSStephen Boyd hlist_for_each_entry(child, &core->children, child_node)
18765279fc40SBoris BREZILLON __clk_recalc_accuracies(child);
18775279fc40SBoris BREZILLON }
18785279fc40SBoris BREZILLON
clk_core_get_accuracy_recalc(struct clk_core * core)18790daa376dSStephen Boyd static long clk_core_get_accuracy_recalc(struct clk_core *core)
18805279fc40SBoris BREZILLON {
1881d6968fcaSStephen Boyd if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE))
1882d6968fcaSStephen Boyd __clk_recalc_accuracies(core);
18835279fc40SBoris BREZILLON
18840daa376dSStephen Boyd return clk_core_get_accuracy_no_lock(core);
18855279fc40SBoris BREZILLON }
1886035a61c3STomeu Vizoso
1887035a61c3STomeu Vizoso /**
1888035a61c3STomeu Vizoso * clk_get_accuracy - return the accuracy of clk
1889035a61c3STomeu Vizoso * @clk: the clk whose accuracy is being returned
1890035a61c3STomeu Vizoso *
1891035a61c3STomeu Vizoso * Simply returns the cached accuracy of the clk, unless
1892035a61c3STomeu Vizoso * CLK_GET_ACCURACY_NOCACHE flag is set, which means a recalc_rate will be
1893035a61c3STomeu Vizoso * issued.
1894035a61c3STomeu Vizoso * If clk is NULL then returns 0.
1895035a61c3STomeu Vizoso */
clk_get_accuracy(struct clk * clk)1896035a61c3STomeu Vizoso long clk_get_accuracy(struct clk *clk)
1897035a61c3STomeu Vizoso {
18980daa376dSStephen Boyd long accuracy;
18990daa376dSStephen Boyd
1900035a61c3STomeu Vizoso if (!clk)
1901035a61c3STomeu Vizoso return 0;
1902035a61c3STomeu Vizoso
19030daa376dSStephen Boyd clk_prepare_lock();
19040daa376dSStephen Boyd accuracy = clk_core_get_accuracy_recalc(clk->core);
19050daa376dSStephen Boyd clk_prepare_unlock();
19060daa376dSStephen Boyd
19070daa376dSStephen Boyd return accuracy;
1908035a61c3STomeu Vizoso }
19095279fc40SBoris BREZILLON EXPORT_SYMBOL_GPL(clk_get_accuracy);
19105279fc40SBoris BREZILLON
clk_recalc(struct clk_core * core,unsigned long parent_rate)1911d6968fcaSStephen Boyd static unsigned long clk_recalc(struct clk_core *core,
1912035a61c3STomeu Vizoso unsigned long parent_rate)
19138f2c2db1SStephen Boyd {
19149a34b453SMarek Szyprowski unsigned long rate = parent_rate;
19159a34b453SMarek Szyprowski
19169a34b453SMarek Szyprowski if (core->ops->recalc_rate && !clk_pm_runtime_get(core)) {
19179a34b453SMarek Szyprowski rate = core->ops->recalc_rate(core->hw, parent_rate);
19189a34b453SMarek Szyprowski clk_pm_runtime_put(core);
19199a34b453SMarek Szyprowski }
19209a34b453SMarek Szyprowski return rate;
19218f2c2db1SStephen Boyd }
19228f2c2db1SStephen Boyd
19235279fc40SBoris BREZILLON /**
1924b2476490SMike Turquette * __clk_recalc_rates
1925d6968fcaSStephen Boyd * @core: first clk in the subtree
1926096f2a0cSMaxime Ripard * @update_req: Whether req_rate should be updated with the new rate
1927b2476490SMike Turquette * @msg: notification type (see include/linux/clk.h)
1928b2476490SMike Turquette *
1929b2476490SMike Turquette * Walks the subtree of clks starting with clk and recalculates rates as it
1930b2476490SMike Turquette * goes. Note that if a clk does not implement the .recalc_rate callback then
193124ee1a08SPeter Meerwald * it is assumed that the clock will take on the rate of its parent.
1932b2476490SMike Turquette *
1933b2476490SMike Turquette * clk_recalc_rates also propagates the POST_RATE_CHANGE notification,
1934b2476490SMike Turquette * if necessary.
1935b2476490SMike Turquette */
__clk_recalc_rates(struct clk_core * core,bool update_req,unsigned long msg)1936096f2a0cSMaxime Ripard static void __clk_recalc_rates(struct clk_core *core, bool update_req,
1937096f2a0cSMaxime Ripard unsigned long msg)
1938b2476490SMike Turquette {
1939b2476490SMike Turquette unsigned long old_rate;
1940b2476490SMike Turquette unsigned long parent_rate = 0;
1941035a61c3STomeu Vizoso struct clk_core *child;
1942b2476490SMike Turquette
1943496eadf8SKrzysztof Kozlowski lockdep_assert_held(&prepare_lock);
1944496eadf8SKrzysztof Kozlowski
1945d6968fcaSStephen Boyd old_rate = core->rate;
1946b2476490SMike Turquette
1947d6968fcaSStephen Boyd if (core->parent)
1948d6968fcaSStephen Boyd parent_rate = core->parent->rate;
1949b2476490SMike Turquette
1950d6968fcaSStephen Boyd core->rate = clk_recalc(core, parent_rate);
1951096f2a0cSMaxime Ripard if (update_req)
1952096f2a0cSMaxime Ripard core->req_rate = core->rate;
1953b2476490SMike Turquette
1954b2476490SMike Turquette /*
1955b2476490SMike Turquette * ignore NOTIFY_STOP and NOTIFY_BAD return values for POST_RATE_CHANGE
1956b2476490SMike Turquette * & ABORT_RATE_CHANGE notifiers
1957b2476490SMike Turquette */
1958d6968fcaSStephen Boyd if (core->notifier_count && msg)
1959d6968fcaSStephen Boyd __clk_notify(core, msg, old_rate, core->rate);
1960b2476490SMike Turquette
1961d6968fcaSStephen Boyd hlist_for_each_entry(child, &core->children, child_node)
1962096f2a0cSMaxime Ripard __clk_recalc_rates(child, update_req, msg);
1963b2476490SMike Turquette }
1964b2476490SMike Turquette
clk_core_get_rate_recalc(struct clk_core * core)19650daa376dSStephen Boyd static unsigned long clk_core_get_rate_recalc(struct clk_core *core)
1966035a61c3STomeu Vizoso {
1967d6968fcaSStephen Boyd if (core && (core->flags & CLK_GET_RATE_NOCACHE))
1968096f2a0cSMaxime Ripard __clk_recalc_rates(core, false, 0);
1969035a61c3STomeu Vizoso
19700daa376dSStephen Boyd return clk_core_get_rate_nolock(core);
1971035a61c3STomeu Vizoso }
1972035a61c3STomeu Vizoso
1973b2476490SMike Turquette /**
1974a093bde2SUlf Hansson * clk_get_rate - return the rate of clk
1975a093bde2SUlf Hansson * @clk: the clk whose rate is being returned
1976a093bde2SUlf Hansson *
1977a093bde2SUlf Hansson * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag
1978bde8870cSMaxime Ripard * is set, which means a recalc_rate will be issued. Can be called regardless of
1979bde8870cSMaxime Ripard * the clock enabledness. If clk is NULL, or if an error occurred, then returns
1980bde8870cSMaxime Ripard * 0.
1981a093bde2SUlf Hansson */
clk_get_rate(struct clk * clk)1982a093bde2SUlf Hansson unsigned long clk_get_rate(struct clk *clk)
1983a093bde2SUlf Hansson {
19840daa376dSStephen Boyd unsigned long rate;
19850daa376dSStephen Boyd
1986035a61c3STomeu Vizoso if (!clk)
1987035a61c3STomeu Vizoso return 0;
1988a093bde2SUlf Hansson
19890daa376dSStephen Boyd clk_prepare_lock();
19900daa376dSStephen Boyd rate = clk_core_get_rate_recalc(clk->core);
19910daa376dSStephen Boyd clk_prepare_unlock();
19920daa376dSStephen Boyd
19930daa376dSStephen Boyd return rate;
1994a093bde2SUlf Hansson }
1995a093bde2SUlf Hansson EXPORT_SYMBOL_GPL(clk_get_rate);
1996a093bde2SUlf Hansson
clk_fetch_parent_index(struct clk_core * core,struct clk_core * parent)1997d6968fcaSStephen Boyd static int clk_fetch_parent_index(struct clk_core *core,
1998035a61c3STomeu Vizoso struct clk_core *parent)
19994935b22cSJames Hogan {
2000f1c8b2edSTomasz Figa int i;
20014935b22cSJames Hogan
2002508f884aSMasahiro Yamada if (!parent)
2003508f884aSMasahiro Yamada return -EINVAL;
2004508f884aSMasahiro Yamada
2005ede77858SDerek Basehore for (i = 0; i < core->num_parents; i++) {
20061a079560SStephen Boyd /* Found it first try! */
2007fc0c209cSStephen Boyd if (core->parents[i].core == parent)
2008f1c8b2edSTomasz Figa return i;
2009da0f0b2cSTomasz Figa
20101a079560SStephen Boyd /* Something else is here, so keep looking */
2011fc0c209cSStephen Boyd if (core->parents[i].core)
2012ede77858SDerek Basehore continue;
2013ede77858SDerek Basehore
20141a079560SStephen Boyd /* Maybe core hasn't been cached but the hw is all we know? */
20151a079560SStephen Boyd if (core->parents[i].hw) {
20161a079560SStephen Boyd if (core->parents[i].hw == parent->hw)
20171a079560SStephen Boyd break;
20181a079560SStephen Boyd
20191a079560SStephen Boyd /* Didn't match, but we're expecting a clk_hw */
20201a079560SStephen Boyd continue;
2021ede77858SDerek Basehore }
2022ede77858SDerek Basehore
20231a079560SStephen Boyd /* Maybe it hasn't been cached (clk_set_parent() path) */
20241a079560SStephen Boyd if (parent == clk_core_get(core, i))
20251a079560SStephen Boyd break;
20261a079560SStephen Boyd
20271a079560SStephen Boyd /* Fallback to comparing globally unique names */
202824876f09SMartin Blumenstingl if (core->parents[i].name &&
202924876f09SMartin Blumenstingl !strcmp(parent->name, core->parents[i].name))
20301a079560SStephen Boyd break;
20311a079560SStephen Boyd }
20321a079560SStephen Boyd
20331a079560SStephen Boyd if (i == core->num_parents)
2034f1c8b2edSTomasz Figa return -EINVAL;
20351a079560SStephen Boyd
20361a079560SStephen Boyd core->parents[i].core = parent;
20371a079560SStephen Boyd return i;
20384935b22cSJames Hogan }
20394935b22cSJames Hogan
2040d9b86cc4SSowjanya Komatineni /**
2041d9b86cc4SSowjanya Komatineni * clk_hw_get_parent_index - return the index of the parent clock
2042d9b86cc4SSowjanya Komatineni * @hw: clk_hw associated with the clk being consumed
2043d9b86cc4SSowjanya Komatineni *
2044d9b86cc4SSowjanya Komatineni * Fetches and returns the index of parent clock. Returns -EINVAL if the given
2045d9b86cc4SSowjanya Komatineni * clock does not have a current parent.
2046d9b86cc4SSowjanya Komatineni */
clk_hw_get_parent_index(struct clk_hw * hw)2047d9b86cc4SSowjanya Komatineni int clk_hw_get_parent_index(struct clk_hw *hw)
2048d9b86cc4SSowjanya Komatineni {
2049d9b86cc4SSowjanya Komatineni struct clk_hw *parent = clk_hw_get_parent(hw);
2050d9b86cc4SSowjanya Komatineni
2051d9b86cc4SSowjanya Komatineni if (WARN_ON(parent == NULL))
2052d9b86cc4SSowjanya Komatineni return -EINVAL;
2053d9b86cc4SSowjanya Komatineni
2054d9b86cc4SSowjanya Komatineni return clk_fetch_parent_index(hw->core, parent->core);
2055d9b86cc4SSowjanya Komatineni }
2056d9b86cc4SSowjanya Komatineni EXPORT_SYMBOL_GPL(clk_hw_get_parent_index);
2057d9b86cc4SSowjanya Komatineni
2058e6500344SHeiko Stuebner /*
2059e6500344SHeiko Stuebner * Update the orphan status of @core and all its children.
2060e6500344SHeiko Stuebner */
clk_core_update_orphan_status(struct clk_core * core,bool is_orphan)2061e6500344SHeiko Stuebner static void clk_core_update_orphan_status(struct clk_core *core, bool is_orphan)
2062e6500344SHeiko Stuebner {
2063e6500344SHeiko Stuebner struct clk_core *child;
2064e6500344SHeiko Stuebner
2065e6500344SHeiko Stuebner core->orphan = is_orphan;
2066e6500344SHeiko Stuebner
2067e6500344SHeiko Stuebner hlist_for_each_entry(child, &core->children, child_node)
2068e6500344SHeiko Stuebner clk_core_update_orphan_status(child, is_orphan);
2069e6500344SHeiko Stuebner }
2070e6500344SHeiko Stuebner
clk_reparent(struct clk_core * core,struct clk_core * new_parent)2071d6968fcaSStephen Boyd static void clk_reparent(struct clk_core *core, struct clk_core *new_parent)
20724935b22cSJames Hogan {
2073e6500344SHeiko Stuebner bool was_orphan = core->orphan;
2074e6500344SHeiko Stuebner
2075d6968fcaSStephen Boyd hlist_del(&core->child_node);
2076903efc55SJames Hogan
2077903efc55SJames Hogan if (new_parent) {
2078e6500344SHeiko Stuebner bool becomes_orphan = new_parent->orphan;
2079e6500344SHeiko Stuebner
208071472c0cSJames Hogan /* avoid duplicate POST_RATE_CHANGE notifications */
2081d6968fcaSStephen Boyd if (new_parent->new_child == core)
208271472c0cSJames Hogan new_parent->new_child = NULL;
208371472c0cSJames Hogan
2084d6968fcaSStephen Boyd hlist_add_head(&core->child_node, &new_parent->children);
2085e6500344SHeiko Stuebner
2086e6500344SHeiko Stuebner if (was_orphan != becomes_orphan)
2087e6500344SHeiko Stuebner clk_core_update_orphan_status(core, becomes_orphan);
2088903efc55SJames Hogan } else {
2089d6968fcaSStephen Boyd hlist_add_head(&core->child_node, &clk_orphan_list);
2090e6500344SHeiko Stuebner if (!was_orphan)
2091e6500344SHeiko Stuebner clk_core_update_orphan_status(core, true);
2092903efc55SJames Hogan }
20934935b22cSJames Hogan
2094d6968fcaSStephen Boyd core->parent = new_parent;
20954935b22cSJames Hogan }
20964935b22cSJames Hogan
__clk_set_parent_before(struct clk_core * core,struct clk_core * parent)2097d6968fcaSStephen Boyd static struct clk_core *__clk_set_parent_before(struct clk_core *core,
2098035a61c3STomeu Vizoso struct clk_core *parent)
20994935b22cSJames Hogan {
21004935b22cSJames Hogan unsigned long flags;
2101d6968fcaSStephen Boyd struct clk_core *old_parent = core->parent;
21024935b22cSJames Hogan
21034935b22cSJames Hogan /*
2104fc8726a2SDong Aisheng * 1. enable parents for CLK_OPS_PARENT_ENABLE clock
2105fc8726a2SDong Aisheng *
2106fc8726a2SDong Aisheng * 2. Migrate prepare state between parents and prevent race with
21074935b22cSJames Hogan * clk_enable().
21084935b22cSJames Hogan *
21094935b22cSJames Hogan * If the clock is not prepared, then a race with
21104935b22cSJames Hogan * clk_enable/disable() is impossible since we already have the
21114935b22cSJames Hogan * prepare lock (future calls to clk_enable() need to be preceded by
21124935b22cSJames Hogan * a clk_prepare()).
21134935b22cSJames Hogan *
21144935b22cSJames Hogan * If the clock is prepared, migrate the prepared state to the new
21154935b22cSJames Hogan * parent and also protect against a race with clk_enable() by
21164935b22cSJames Hogan * forcing the clock and the new parent on. This ensures that all
21174935b22cSJames Hogan * future calls to clk_enable() are practically NOPs with respect to
21184935b22cSJames Hogan * hardware and software states.
21194935b22cSJames Hogan *
21204935b22cSJames Hogan * See also: Comment for clk_set_parent() below.
21214935b22cSJames Hogan */
2122fc8726a2SDong Aisheng
2123fc8726a2SDong Aisheng /* enable old_parent & parent if CLK_OPS_PARENT_ENABLE is set */
2124fc8726a2SDong Aisheng if (core->flags & CLK_OPS_PARENT_ENABLE) {
2125fc8726a2SDong Aisheng clk_core_prepare_enable(old_parent);
2126fc8726a2SDong Aisheng clk_core_prepare_enable(parent);
2127fc8726a2SDong Aisheng }
2128fc8726a2SDong Aisheng
2129fc8726a2SDong Aisheng /* migrate prepare count if > 0 */
2130d6968fcaSStephen Boyd if (core->prepare_count) {
2131fc8726a2SDong Aisheng clk_core_prepare_enable(parent);
2132fc8726a2SDong Aisheng clk_core_enable_lock(core);
21334935b22cSJames Hogan }
21344935b22cSJames Hogan
21354935b22cSJames Hogan /* update the clk tree topology */
21364935b22cSJames Hogan flags = clk_enable_lock();
2137d6968fcaSStephen Boyd clk_reparent(core, parent);
21384935b22cSJames Hogan clk_enable_unlock(flags);
21394935b22cSJames Hogan
21403fa2252bSStephen Boyd return old_parent;
21413fa2252bSStephen Boyd }
21423fa2252bSStephen Boyd
__clk_set_parent_after(struct clk_core * core,struct clk_core * parent,struct clk_core * old_parent)2143035a61c3STomeu Vizoso static void __clk_set_parent_after(struct clk_core *core,
2144035a61c3STomeu Vizoso struct clk_core *parent,
2145035a61c3STomeu Vizoso struct clk_core *old_parent)
21463fa2252bSStephen Boyd {
21473fa2252bSStephen Boyd /*
21483fa2252bSStephen Boyd * Finish the migration of prepare state and undo the changes done
21493fa2252bSStephen Boyd * for preventing a race with clk_enable().
21503fa2252bSStephen Boyd */
2151035a61c3STomeu Vizoso if (core->prepare_count) {
2152fc8726a2SDong Aisheng clk_core_disable_lock(core);
2153fc8726a2SDong Aisheng clk_core_disable_unprepare(old_parent);
2154fc8726a2SDong Aisheng }
2155fc8726a2SDong Aisheng
2156fc8726a2SDong Aisheng /* re-balance ref counting if CLK_OPS_PARENT_ENABLE is set */
2157fc8726a2SDong Aisheng if (core->flags & CLK_OPS_PARENT_ENABLE) {
2158fc8726a2SDong Aisheng clk_core_disable_unprepare(parent);
2159fc8726a2SDong Aisheng clk_core_disable_unprepare(old_parent);
21603fa2252bSStephen Boyd }
21613fa2252bSStephen Boyd }
21623fa2252bSStephen Boyd
__clk_set_parent(struct clk_core * core,struct clk_core * parent,u8 p_index)2163d6968fcaSStephen Boyd static int __clk_set_parent(struct clk_core *core, struct clk_core *parent,
2164035a61c3STomeu Vizoso u8 p_index)
21653fa2252bSStephen Boyd {
21663fa2252bSStephen Boyd unsigned long flags;
21673fa2252bSStephen Boyd int ret = 0;
2168035a61c3STomeu Vizoso struct clk_core *old_parent;
21693fa2252bSStephen Boyd
2170d6968fcaSStephen Boyd old_parent = __clk_set_parent_before(core, parent);
21713fa2252bSStephen Boyd
2172d6968fcaSStephen Boyd trace_clk_set_parent(core, parent);
2173dfc202eaSStephen Boyd
21744935b22cSJames Hogan /* change clock input source */
2175d6968fcaSStephen Boyd if (parent && core->ops->set_parent)
2176d6968fcaSStephen Boyd ret = core->ops->set_parent(core->hw, p_index);
21774935b22cSJames Hogan
2178d6968fcaSStephen Boyd trace_clk_set_parent_complete(core, parent);
2179dfc202eaSStephen Boyd
21804935b22cSJames Hogan if (ret) {
21814935b22cSJames Hogan flags = clk_enable_lock();
2182d6968fcaSStephen Boyd clk_reparent(core, old_parent);
21834935b22cSJames Hogan clk_enable_unlock(flags);
2184cb1b1dd9SMaxime Ripard
2185c660b2ebSDong Aisheng __clk_set_parent_after(core, old_parent, parent);
21864935b22cSJames Hogan
21874935b22cSJames Hogan return ret;
21884935b22cSJames Hogan }
21894935b22cSJames Hogan
2190d6968fcaSStephen Boyd __clk_set_parent_after(core, parent, old_parent);
21914935b22cSJames Hogan
21924935b22cSJames Hogan return 0;
21934935b22cSJames Hogan }
21944935b22cSJames Hogan
2195a093bde2SUlf Hansson /**
2196b2476490SMike Turquette * __clk_speculate_rates
2197d6968fcaSStephen Boyd * @core: first clk in the subtree
2198b2476490SMike Turquette * @parent_rate: the "future" rate of clk's parent
2199b2476490SMike Turquette *
2200b2476490SMike Turquette * Walks the subtree of clks starting with clk, speculating rates as it
2201b2476490SMike Turquette * goes and firing off PRE_RATE_CHANGE notifications as necessary.
2202b2476490SMike Turquette *
2203b2476490SMike Turquette * Unlike clk_recalc_rates, clk_speculate_rates exists only for sending
2204b2476490SMike Turquette * pre-rate change notifications and returns early if no clks in the
2205b2476490SMike Turquette * subtree have subscribed to the notifications. Note that if a clk does not
2206b2476490SMike Turquette * implement the .recalc_rate callback then it is assumed that the clock will
220724ee1a08SPeter Meerwald * take on the rate of its parent.
2208b2476490SMike Turquette */
__clk_speculate_rates(struct clk_core * core,unsigned long parent_rate)2209d6968fcaSStephen Boyd static int __clk_speculate_rates(struct clk_core *core,
2210035a61c3STomeu Vizoso unsigned long parent_rate)
2211b2476490SMike Turquette {
2212035a61c3STomeu Vizoso struct clk_core *child;
2213b2476490SMike Turquette unsigned long new_rate;
2214b2476490SMike Turquette int ret = NOTIFY_DONE;
2215b2476490SMike Turquette
2216496eadf8SKrzysztof Kozlowski lockdep_assert_held(&prepare_lock);
2217496eadf8SKrzysztof Kozlowski
2218d6968fcaSStephen Boyd new_rate = clk_recalc(core, parent_rate);
2219b2476490SMike Turquette
2220fb72a059SSoren Brinkmann /* abort rate change if a driver returns NOTIFY_BAD or NOTIFY_STOP */
2221d6968fcaSStephen Boyd if (core->notifier_count)
2222d6968fcaSStephen Boyd ret = __clk_notify(core, PRE_RATE_CHANGE, core->rate, new_rate);
2223b2476490SMike Turquette
222486bcfa2eSMike Turquette if (ret & NOTIFY_STOP_MASK) {
222586bcfa2eSMike Turquette pr_debug("%s: clk notifier callback for clock %s aborted with error %d\n",
2226d6968fcaSStephen Boyd __func__, core->name, ret);
2227b2476490SMike Turquette goto out;
222886bcfa2eSMike Turquette }
2229b2476490SMike Turquette
2230d6968fcaSStephen Boyd hlist_for_each_entry(child, &core->children, child_node) {
2231b2476490SMike Turquette ret = __clk_speculate_rates(child, new_rate);
2232fb72a059SSoren Brinkmann if (ret & NOTIFY_STOP_MASK)
2233b2476490SMike Turquette break;
2234b2476490SMike Turquette }
2235b2476490SMike Turquette
2236b2476490SMike Turquette out:
2237b2476490SMike Turquette return ret;
2238b2476490SMike Turquette }
2239b2476490SMike Turquette
clk_calc_subtree(struct clk_core * core,unsigned long new_rate,struct clk_core * new_parent,u8 p_index)2240d6968fcaSStephen Boyd static void clk_calc_subtree(struct clk_core *core, unsigned long new_rate,
2241035a61c3STomeu Vizoso struct clk_core *new_parent, u8 p_index)
2242b2476490SMike Turquette {
2243035a61c3STomeu Vizoso struct clk_core *child;
2244b2476490SMike Turquette
2245d6968fcaSStephen Boyd core->new_rate = new_rate;
2246d6968fcaSStephen Boyd core->new_parent = new_parent;
2247d6968fcaSStephen Boyd core->new_parent_index = p_index;
224871472c0cSJames Hogan /* include clk in new parent's PRE_RATE_CHANGE notifications */
2249d6968fcaSStephen Boyd core->new_child = NULL;
2250d6968fcaSStephen Boyd if (new_parent && new_parent != core->parent)
2251d6968fcaSStephen Boyd new_parent->new_child = core;
2252b2476490SMike Turquette
2253d6968fcaSStephen Boyd hlist_for_each_entry(child, &core->children, child_node) {
22548f2c2db1SStephen Boyd child->new_rate = clk_recalc(child, new_rate);
225571472c0cSJames Hogan clk_calc_subtree(child, child->new_rate, NULL, 0);
2256b2476490SMike Turquette }
2257b2476490SMike Turquette }
2258b2476490SMike Turquette
2259b2476490SMike Turquette /*
2260b2476490SMike Turquette * calculate the new rates returning the topmost clock that has to be
2261b2476490SMike Turquette * changed.
2262b2476490SMike Turquette */
clk_calc_new_rates(struct clk_core * core,unsigned long rate)2263d6968fcaSStephen Boyd static struct clk_core *clk_calc_new_rates(struct clk_core *core,
2264035a61c3STomeu Vizoso unsigned long rate)
2265b2476490SMike Turquette {
2266d6968fcaSStephen Boyd struct clk_core *top = core;
2267035a61c3STomeu Vizoso struct clk_core *old_parent, *parent;
226881536e07SShawn Guo unsigned long best_parent_rate = 0;
2269b2476490SMike Turquette unsigned long new_rate;
22701c8e6004STomeu Vizoso unsigned long min_rate;
22711c8e6004STomeu Vizoso unsigned long max_rate;
2272f1c8b2edSTomasz Figa int p_index = 0;
227303bc10abSBoris Brezillon long ret;
2274b2476490SMike Turquette
22757452b219SMike Turquette /* sanity */
2276d6968fcaSStephen Boyd if (IS_ERR_OR_NULL(core))
22777452b219SMike Turquette return NULL;
22787452b219SMike Turquette
227963f5c3b2SMike Turquette /* save parent rate, if it exists */
2280d6968fcaSStephen Boyd parent = old_parent = core->parent;
228171472c0cSJames Hogan if (parent)
228271472c0cSJames Hogan best_parent_rate = parent->rate;
228363f5c3b2SMike Turquette
2284d6968fcaSStephen Boyd clk_core_get_boundaries(core, &min_rate, &max_rate);
22851c8e6004STomeu Vizoso
228671472c0cSJames Hogan /* find the closest rate and parent clk/rate */
22870f6cc2b8SJerome Brunet if (clk_core_can_round(core)) {
22880817b62cSBoris Brezillon struct clk_rate_request req;
22890817b62cSBoris Brezillon
2290718af795SMaxime Ripard clk_core_init_rate_req(core, &req, rate);
22910f6cc2b8SJerome Brunet
229249e62e0dSMaxime Ripard trace_clk_rate_request_start(&req);
229349e62e0dSMaxime Ripard
22940f6cc2b8SJerome Brunet ret = clk_core_determine_round_nolock(core, &req);
229503bc10abSBoris Brezillon if (ret < 0)
229603bc10abSBoris Brezillon return NULL;
229703bc10abSBoris Brezillon
229849e62e0dSMaxime Ripard trace_clk_rate_request_done(&req);
229949e62e0dSMaxime Ripard
23000817b62cSBoris Brezillon best_parent_rate = req.best_parent_rate;
23010817b62cSBoris Brezillon new_rate = req.rate;
23020817b62cSBoris Brezillon parent = req.best_parent_hw ? req.best_parent_hw->core : NULL;
230303bc10abSBoris Brezillon
23041c8e6004STomeu Vizoso if (new_rate < min_rate || new_rate > max_rate)
23051c8e6004STomeu Vizoso return NULL;
2306d6968fcaSStephen Boyd } else if (!parent || !(core->flags & CLK_SET_RATE_PARENT)) {
230771472c0cSJames Hogan /* pass-through clock without adjustable parent */
2308d6968fcaSStephen Boyd core->new_rate = core->rate;
2309b2476490SMike Turquette return NULL;
231071472c0cSJames Hogan } else {
231171472c0cSJames Hogan /* pass-through clock with adjustable parent */
231271472c0cSJames Hogan top = clk_calc_new_rates(parent, rate);
231371472c0cSJames Hogan new_rate = parent->new_rate;
231463f5c3b2SMike Turquette goto out;
23157452b219SMike Turquette }
23167452b219SMike Turquette
231771472c0cSJames Hogan /* some clocks must be gated to change parent */
231871472c0cSJames Hogan if (parent != old_parent &&
2319d6968fcaSStephen Boyd (core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) {
232071472c0cSJames Hogan pr_debug("%s: %s not gated but wants to reparent\n",
2321d6968fcaSStephen Boyd __func__, core->name);
23227452b219SMike Turquette return NULL;
2323b2476490SMike Turquette }
2324b2476490SMike Turquette
232571472c0cSJames Hogan /* try finding the new parent index */
2326d6968fcaSStephen Boyd if (parent && core->num_parents > 1) {
2327d6968fcaSStephen Boyd p_index = clk_fetch_parent_index(core, parent);
2328f1c8b2edSTomasz Figa if (p_index < 0) {
232971472c0cSJames Hogan pr_debug("%s: clk %s can not be parent of clk %s\n",
2330d6968fcaSStephen Boyd __func__, parent->name, core->name);
233171472c0cSJames Hogan return NULL;
233271472c0cSJames Hogan }
2333b2476490SMike Turquette }
2334b2476490SMike Turquette
2335d6968fcaSStephen Boyd if ((core->flags & CLK_SET_RATE_PARENT) && parent &&
233671472c0cSJames Hogan best_parent_rate != parent->rate)
233771472c0cSJames Hogan top = clk_calc_new_rates(parent, best_parent_rate);
2338b2476490SMike Turquette
2339b2476490SMike Turquette out:
2340d6968fcaSStephen Boyd clk_calc_subtree(core, new_rate, parent, p_index);
2341b2476490SMike Turquette
2342b2476490SMike Turquette return top;
2343b2476490SMike Turquette }
2344b2476490SMike Turquette
2345b2476490SMike Turquette /*
2346b2476490SMike Turquette * Notify about rate changes in a subtree. Always walk down the whole tree
2347b2476490SMike Turquette * so that in case of an error we can walk down the whole tree again and
2348b2476490SMike Turquette * abort the change.
2349b2476490SMike Turquette */
clk_propagate_rate_change(struct clk_core * core,unsigned long event)2350d6968fcaSStephen Boyd static struct clk_core *clk_propagate_rate_change(struct clk_core *core,
2351035a61c3STomeu Vizoso unsigned long event)
2352b2476490SMike Turquette {
2353035a61c3STomeu Vizoso struct clk_core *child, *tmp_clk, *fail_clk = NULL;
2354b2476490SMike Turquette int ret = NOTIFY_DONE;
2355b2476490SMike Turquette
2356d6968fcaSStephen Boyd if (core->rate == core->new_rate)
23575fda6858SSachin Kamat return NULL;
2358b2476490SMike Turquette
2359d6968fcaSStephen Boyd if (core->notifier_count) {
2360d6968fcaSStephen Boyd ret = __clk_notify(core, event, core->rate, core->new_rate);
2361fb72a059SSoren Brinkmann if (ret & NOTIFY_STOP_MASK)
2362d6968fcaSStephen Boyd fail_clk = core;
2363b2476490SMike Turquette }
2364b2476490SMike Turquette
2365d6968fcaSStephen Boyd hlist_for_each_entry(child, &core->children, child_node) {
236671472c0cSJames Hogan /* Skip children who will be reparented to another clock */
2367d6968fcaSStephen Boyd if (child->new_parent && child->new_parent != core)
236871472c0cSJames Hogan continue;
236971472c0cSJames Hogan tmp_clk = clk_propagate_rate_change(child, event);
237071472c0cSJames Hogan if (tmp_clk)
237171472c0cSJames Hogan fail_clk = tmp_clk;
237271472c0cSJames Hogan }
237371472c0cSJames Hogan
2374d6968fcaSStephen Boyd /* handle the new child who might not be in core->children yet */
2375d6968fcaSStephen Boyd if (core->new_child) {
2376d6968fcaSStephen Boyd tmp_clk = clk_propagate_rate_change(core->new_child, event);
237771472c0cSJames Hogan if (tmp_clk)
237871472c0cSJames Hogan fail_clk = tmp_clk;
2379b2476490SMike Turquette }
2380b2476490SMike Turquette
2381b2476490SMike Turquette return fail_clk;
2382b2476490SMike Turquette }
2383b2476490SMike Turquette
2384b2476490SMike Turquette /*
2385b2476490SMike Turquette * walk down a subtree and set the new rates notifying the rate
2386b2476490SMike Turquette * change on the way
2387b2476490SMike Turquette */
clk_change_rate(struct clk_core * core)2388d6968fcaSStephen Boyd static void clk_change_rate(struct clk_core *core)
2389b2476490SMike Turquette {
2390035a61c3STomeu Vizoso struct clk_core *child;
2391067bb174STero Kristo struct hlist_node *tmp;
2392b2476490SMike Turquette unsigned long old_rate;
2393bf47b4fdSPawel Moll unsigned long best_parent_rate = 0;
23943fa2252bSStephen Boyd bool skip_set_rate = false;
2395035a61c3STomeu Vizoso struct clk_core *old_parent;
2396fc8726a2SDong Aisheng struct clk_core *parent = NULL;
2397b2476490SMike Turquette
2398d6968fcaSStephen Boyd old_rate = core->rate;
2399b2476490SMike Turquette
2400fc8726a2SDong Aisheng if (core->new_parent) {
2401fc8726a2SDong Aisheng parent = core->new_parent;
2402d6968fcaSStephen Boyd best_parent_rate = core->new_parent->rate;
2403fc8726a2SDong Aisheng } else if (core->parent) {
2404fc8726a2SDong Aisheng parent = core->parent;
2405d6968fcaSStephen Boyd best_parent_rate = core->parent->rate;
2406fc8726a2SDong Aisheng }
2407bf47b4fdSPawel Moll
2408588fb54bSMarek Szyprowski if (clk_pm_runtime_get(core))
2409588fb54bSMarek Szyprowski return;
2410588fb54bSMarek Szyprowski
24112eb8c710SHeiko Stuebner if (core->flags & CLK_SET_RATE_UNGATE) {
24122eb8c710SHeiko Stuebner clk_core_prepare(core);
241335a79631SRasmus Villemoes clk_core_enable_lock(core);
24142eb8c710SHeiko Stuebner }
24152eb8c710SHeiko Stuebner
2416d6968fcaSStephen Boyd if (core->new_parent && core->new_parent != core->parent) {
2417d6968fcaSStephen Boyd old_parent = __clk_set_parent_before(core, core->new_parent);
2418d6968fcaSStephen Boyd trace_clk_set_parent(core, core->new_parent);
24193fa2252bSStephen Boyd
2420d6968fcaSStephen Boyd if (core->ops->set_rate_and_parent) {
24213fa2252bSStephen Boyd skip_set_rate = true;
2422d6968fcaSStephen Boyd core->ops->set_rate_and_parent(core->hw, core->new_rate,
24233fa2252bSStephen Boyd best_parent_rate,
2424d6968fcaSStephen Boyd core->new_parent_index);
2425d6968fcaSStephen Boyd } else if (core->ops->set_parent) {
2426d6968fcaSStephen Boyd core->ops->set_parent(core->hw, core->new_parent_index);
24273fa2252bSStephen Boyd }
24283fa2252bSStephen Boyd
2429d6968fcaSStephen Boyd trace_clk_set_parent_complete(core, core->new_parent);
2430d6968fcaSStephen Boyd __clk_set_parent_after(core, core->new_parent, old_parent);
24313fa2252bSStephen Boyd }
24323fa2252bSStephen Boyd
2433fc8726a2SDong Aisheng if (core->flags & CLK_OPS_PARENT_ENABLE)
2434fc8726a2SDong Aisheng clk_core_prepare_enable(parent);
2435fc8726a2SDong Aisheng
2436d6968fcaSStephen Boyd trace_clk_set_rate(core, core->new_rate);
2437dfc202eaSStephen Boyd
2438d6968fcaSStephen Boyd if (!skip_set_rate && core->ops->set_rate)
2439d6968fcaSStephen Boyd core->ops->set_rate(core->hw, core->new_rate, best_parent_rate);
2440b2476490SMike Turquette
2441d6968fcaSStephen Boyd trace_clk_set_rate_complete(core, core->new_rate);
2442dfc202eaSStephen Boyd
2443d6968fcaSStephen Boyd core->rate = clk_recalc(core, best_parent_rate);
2444b2476490SMike Turquette
24452eb8c710SHeiko Stuebner if (core->flags & CLK_SET_RATE_UNGATE) {
244635a79631SRasmus Villemoes clk_core_disable_lock(core);
24472eb8c710SHeiko Stuebner clk_core_unprepare(core);
24482eb8c710SHeiko Stuebner }
24492eb8c710SHeiko Stuebner
2450fc8726a2SDong Aisheng if (core->flags & CLK_OPS_PARENT_ENABLE)
2451fc8726a2SDong Aisheng clk_core_disable_unprepare(parent);
2452fc8726a2SDong Aisheng
2453d6968fcaSStephen Boyd if (core->notifier_count && old_rate != core->rate)
2454d6968fcaSStephen Boyd __clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
2455b2476490SMike Turquette
245685e88fabSMichael Turquette if (core->flags & CLK_RECALC_NEW_RATES)
245785e88fabSMichael Turquette (void)clk_calc_new_rates(core, core->new_rate);
2458d8d91987SBartlomiej Zolnierkiewicz
2459067bb174STero Kristo /*
2460067bb174STero Kristo * Use safe iteration, as change_rate can actually swap parents
2461067bb174STero Kristo * for certain clock types.
2462067bb174STero Kristo */
2463d6968fcaSStephen Boyd hlist_for_each_entry_safe(child, tmp, &core->children, child_node) {
246471472c0cSJames Hogan /* Skip children who will be reparented to another clock */
2465d6968fcaSStephen Boyd if (child->new_parent && child->new_parent != core)
246671472c0cSJames Hogan continue;
2467b2476490SMike Turquette clk_change_rate(child);
2468b2476490SMike Turquette }
2469b2476490SMike Turquette
2470d6968fcaSStephen Boyd /* handle the new child who might not be in core->children yet */
2471d6968fcaSStephen Boyd if (core->new_child)
2472d6968fcaSStephen Boyd clk_change_rate(core->new_child);
2473588fb54bSMarek Szyprowski
2474588fb54bSMarek Szyprowski clk_pm_runtime_put(core);
247571472c0cSJames Hogan }
247671472c0cSJames Hogan
clk_core_req_round_rate_nolock(struct clk_core * core,unsigned long req_rate)2477ca5e089aSJerome Brunet static unsigned long clk_core_req_round_rate_nolock(struct clk_core *core,
2478ca5e089aSJerome Brunet unsigned long req_rate)
2479ca5e089aSJerome Brunet {
2480e55a839aSJerome Brunet int ret, cnt;
2481ca5e089aSJerome Brunet struct clk_rate_request req;
2482ca5e089aSJerome Brunet
2483ca5e089aSJerome Brunet lockdep_assert_held(&prepare_lock);
2484ca5e089aSJerome Brunet
2485ca5e089aSJerome Brunet if (!core)
2486ca5e089aSJerome Brunet return 0;
2487ca5e089aSJerome Brunet
2488e55a839aSJerome Brunet /* simulate what the rate would be if it could be freely set */
2489e55a839aSJerome Brunet cnt = clk_core_rate_nuke_protect(core);
2490e55a839aSJerome Brunet if (cnt < 0)
2491e55a839aSJerome Brunet return cnt;
2492e55a839aSJerome Brunet
24938cd9c39dSMaxime Ripard clk_core_init_rate_req(core, &req, req_rate);
2494ca5e089aSJerome Brunet
249549e62e0dSMaxime Ripard trace_clk_rate_request_start(&req);
249649e62e0dSMaxime Ripard
2497ca5e089aSJerome Brunet ret = clk_core_round_rate_nolock(core, &req);
2498ca5e089aSJerome Brunet
249949e62e0dSMaxime Ripard trace_clk_rate_request_done(&req);
250049e62e0dSMaxime Ripard
2501e55a839aSJerome Brunet /* restore the protection */
2502e55a839aSJerome Brunet clk_core_rate_restore_protect(core, cnt);
2503e55a839aSJerome Brunet
2504ca5e089aSJerome Brunet return ret ? 0 : req.rate;
2505b2476490SMike Turquette }
2506b2476490SMike Turquette
clk_core_set_rate_nolock(struct clk_core * core,unsigned long req_rate)2507d6968fcaSStephen Boyd static int clk_core_set_rate_nolock(struct clk_core *core,
25081c8e6004STomeu Vizoso unsigned long req_rate)
25091c8e6004STomeu Vizoso {
25101c8e6004STomeu Vizoso struct clk_core *top, *fail_clk;
2511ca5e089aSJerome Brunet unsigned long rate;
251275569a03SClaudiu Beznea int ret;
25131c8e6004STomeu Vizoso
2514d6968fcaSStephen Boyd if (!core)
25151c8e6004STomeu Vizoso return 0;
25161c8e6004STomeu Vizoso
2517ca5e089aSJerome Brunet rate = clk_core_req_round_rate_nolock(core, req_rate);
2518ca5e089aSJerome Brunet
25191c8e6004STomeu Vizoso /* bail early if nothing to do */
2520d6968fcaSStephen Boyd if (rate == clk_core_get_rate_nolock(core))
25211c8e6004STomeu Vizoso return 0;
25221c8e6004STomeu Vizoso
2523e55a839aSJerome Brunet /* fail on a direct rate set of a protected provider */
2524e55a839aSJerome Brunet if (clk_core_rate_is_protected(core))
2525e55a839aSJerome Brunet return -EBUSY;
2526e55a839aSJerome Brunet
25271c8e6004STomeu Vizoso /* calculate new rates and get the topmost changed clock */
2528ca5e089aSJerome Brunet top = clk_calc_new_rates(core, req_rate);
25291c8e6004STomeu Vizoso if (!top)
25301c8e6004STomeu Vizoso return -EINVAL;
25311c8e6004STomeu Vizoso
25329a34b453SMarek Szyprowski ret = clk_pm_runtime_get(core);
25339a34b453SMarek Szyprowski if (ret)
25349a34b453SMarek Szyprowski return ret;
25359a34b453SMarek Szyprowski
25361c8e6004STomeu Vizoso /* notify that we are about to change rates */
25371c8e6004STomeu Vizoso fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
25381c8e6004STomeu Vizoso if (fail_clk) {
25391c8e6004STomeu Vizoso pr_debug("%s: failed to set %s rate\n", __func__,
25401c8e6004STomeu Vizoso fail_clk->name);
25411c8e6004STomeu Vizoso clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
25429a34b453SMarek Szyprowski ret = -EBUSY;
25439a34b453SMarek Szyprowski goto err;
25441c8e6004STomeu Vizoso }
25451c8e6004STomeu Vizoso
25461c8e6004STomeu Vizoso /* change the rates */
25471c8e6004STomeu Vizoso clk_change_rate(top);
25481c8e6004STomeu Vizoso
2549d6968fcaSStephen Boyd core->req_rate = req_rate;
25509a34b453SMarek Szyprowski err:
25519a34b453SMarek Szyprowski clk_pm_runtime_put(core);
25521c8e6004STomeu Vizoso
25539a34b453SMarek Szyprowski return ret;
25541c8e6004STomeu Vizoso }
25551c8e6004STomeu Vizoso
2556b2476490SMike Turquette /**
2557b2476490SMike Turquette * clk_set_rate - specify a new rate for clk
2558b2476490SMike Turquette * @clk: the clk whose rate is being changed
2559b2476490SMike Turquette * @rate: the new rate for clk
2560b2476490SMike Turquette *
25615654dc94SMike Turquette * In the simplest case clk_set_rate will only adjust the rate of clk.
2562b2476490SMike Turquette *
25635654dc94SMike Turquette * Setting the CLK_SET_RATE_PARENT flag allows the rate change operation to
25645654dc94SMike Turquette * propagate up to clk's parent; whether or not this happens depends on the
25655654dc94SMike Turquette * outcome of clk's .round_rate implementation. If *parent_rate is unchanged
25665654dc94SMike Turquette * after calling .round_rate then upstream parent propagation is ignored. If
25675654dc94SMike Turquette * *parent_rate comes back with a new rate for clk's parent then we propagate
256824ee1a08SPeter Meerwald * up to clk's parent and set its rate. Upward propagation will continue
25695654dc94SMike Turquette * until either a clk does not support the CLK_SET_RATE_PARENT flag or
25705654dc94SMike Turquette * .round_rate stops requesting changes to clk's parent_rate.
2571b2476490SMike Turquette *
25725654dc94SMike Turquette * Rate changes are accomplished via tree traversal that also recalculates the
25735654dc94SMike Turquette * rates for the clocks and fires off POST_RATE_CHANGE notifiers.
2574b2476490SMike Turquette *
2575b2476490SMike Turquette * Returns 0 on success, -EERROR otherwise.
2576b2476490SMike Turquette */
clk_set_rate(struct clk * clk,unsigned long rate)2577b2476490SMike Turquette int clk_set_rate(struct clk *clk, unsigned long rate)
2578b2476490SMike Turquette {
25791c8e6004STomeu Vizoso int ret;
2580b2476490SMike Turquette
258189ac8d7aSMike Turquette if (!clk)
258289ac8d7aSMike Turquette return 0;
258389ac8d7aSMike Turquette
2584b2476490SMike Turquette /* prevent racing with updates to the clock topology */
2585eab89f69SMike Turquette clk_prepare_lock();
2586b2476490SMike Turquette
258755e9b8b7SJerome Brunet if (clk->exclusive_count)
258855e9b8b7SJerome Brunet clk_core_rate_unprotect(clk->core);
258955e9b8b7SJerome Brunet
25901c8e6004STomeu Vizoso ret = clk_core_set_rate_nolock(clk->core, rate);
2591b2476490SMike Turquette
259255e9b8b7SJerome Brunet if (clk->exclusive_count)
259355e9b8b7SJerome Brunet clk_core_rate_protect(clk->core);
259455e9b8b7SJerome Brunet
2595eab89f69SMike Turquette clk_prepare_unlock();
2596b2476490SMike Turquette
2597b2476490SMike Turquette return ret;
2598b2476490SMike Turquette }
2599b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_set_rate);
2600b2476490SMike Turquette
2601b2476490SMike Turquette /**
260265e2218dSGeert Uytterhoeven * clk_set_rate_exclusive - specify a new rate and get exclusive control
260355e9b8b7SJerome Brunet * @clk: the clk whose rate is being changed
260455e9b8b7SJerome Brunet * @rate: the new rate for clk
260555e9b8b7SJerome Brunet *
260655e9b8b7SJerome Brunet * This is a combination of clk_set_rate() and clk_rate_exclusive_get()
260755e9b8b7SJerome Brunet * within a critical section
260855e9b8b7SJerome Brunet *
260955e9b8b7SJerome Brunet * This can be used initially to ensure that at least 1 consumer is
261065e2218dSGeert Uytterhoeven * satisfied when several consumers are competing for exclusivity over the
261155e9b8b7SJerome Brunet * same clock provider.
261255e9b8b7SJerome Brunet *
261355e9b8b7SJerome Brunet * The exclusivity is not applied if setting the rate failed.
261455e9b8b7SJerome Brunet *
261555e9b8b7SJerome Brunet * Calls to clk_rate_exclusive_get() should be balanced with calls to
261655e9b8b7SJerome Brunet * clk_rate_exclusive_put().
261755e9b8b7SJerome Brunet *
261855e9b8b7SJerome Brunet * Returns 0 on success, -EERROR otherwise.
261955e9b8b7SJerome Brunet */
clk_set_rate_exclusive(struct clk * clk,unsigned long rate)262055e9b8b7SJerome Brunet int clk_set_rate_exclusive(struct clk *clk, unsigned long rate)
262155e9b8b7SJerome Brunet {
262255e9b8b7SJerome Brunet int ret;
262355e9b8b7SJerome Brunet
262455e9b8b7SJerome Brunet if (!clk)
262555e9b8b7SJerome Brunet return 0;
262655e9b8b7SJerome Brunet
262755e9b8b7SJerome Brunet /* prevent racing with updates to the clock topology */
262855e9b8b7SJerome Brunet clk_prepare_lock();
262955e9b8b7SJerome Brunet
263055e9b8b7SJerome Brunet /*
263155e9b8b7SJerome Brunet * The temporary protection removal is not here, on purpose
263255e9b8b7SJerome Brunet * This function is meant to be used instead of clk_rate_protect,
263355e9b8b7SJerome Brunet * so before the consumer code path protect the clock provider
263455e9b8b7SJerome Brunet */
263555e9b8b7SJerome Brunet
263655e9b8b7SJerome Brunet ret = clk_core_set_rate_nolock(clk->core, rate);
263755e9b8b7SJerome Brunet if (!ret) {
263855e9b8b7SJerome Brunet clk_core_rate_protect(clk->core);
263955e9b8b7SJerome Brunet clk->exclusive_count++;
264055e9b8b7SJerome Brunet }
264155e9b8b7SJerome Brunet
264255e9b8b7SJerome Brunet clk_prepare_unlock();
264355e9b8b7SJerome Brunet
264455e9b8b7SJerome Brunet return ret;
264555e9b8b7SJerome Brunet }
264655e9b8b7SJerome Brunet EXPORT_SYMBOL_GPL(clk_set_rate_exclusive);
264755e9b8b7SJerome Brunet
clk_set_rate_range_nolock(struct clk * clk,unsigned long min,unsigned long max)2648d7738822SMaxime Ripard static int clk_set_rate_range_nolock(struct clk *clk,
2649d7738822SMaxime Ripard unsigned long min,
2650d7738822SMaxime Ripard unsigned long max)
26511c8e6004STomeu Vizoso {
26521c8e6004STomeu Vizoso int ret = 0;
26536562fbcfSJerome Brunet unsigned long old_min, old_max, rate;
26541c8e6004STomeu Vizoso
2655d7738822SMaxime Ripard lockdep_assert_held(&prepare_lock);
2656d7738822SMaxime Ripard
26571c8e6004STomeu Vizoso if (!clk)
26581c8e6004STomeu Vizoso return 0;
26591c8e6004STomeu Vizoso
266003813d9bSMaxime Ripard trace_clk_set_rate_range(clk->core, min, max);
266103813d9bSMaxime Ripard
26621c8e6004STomeu Vizoso if (min > max) {
26631c8e6004STomeu Vizoso pr_err("%s: clk %s dev %s con %s: invalid range [%lu, %lu]\n",
26641c8e6004STomeu Vizoso __func__, clk->core->name, clk->dev_id, clk->con_id,
26651c8e6004STomeu Vizoso min, max);
26661c8e6004STomeu Vizoso return -EINVAL;
26671c8e6004STomeu Vizoso }
26681c8e6004STomeu Vizoso
266955e9b8b7SJerome Brunet if (clk->exclusive_count)
267055e9b8b7SJerome Brunet clk_core_rate_unprotect(clk->core);
267155e9b8b7SJerome Brunet
26726562fbcfSJerome Brunet /* Save the current values in case we need to rollback the change */
26736562fbcfSJerome Brunet old_min = clk->min_rate;
26746562fbcfSJerome Brunet old_max = clk->max_rate;
26751c8e6004STomeu Vizoso clk->min_rate = min;
26761c8e6004STomeu Vizoso clk->max_rate = max;
26776562fbcfSJerome Brunet
267810c46f2eSMaxime Ripard if (!clk_core_check_boundaries(clk->core, min, max)) {
267910c46f2eSMaxime Ripard ret = -EINVAL;
268010c46f2eSMaxime Ripard goto out;
268110c46f2eSMaxime Ripard }
268210c46f2eSMaxime Ripard
26833afb0723SMaxime Ripard rate = clk->core->req_rate;
26843afb0723SMaxime Ripard if (clk->core->flags & CLK_GET_RATE_NOCACHE)
26853afb0723SMaxime Ripard rate = clk_core_get_rate_recalc(clk->core);
26863afb0723SMaxime Ripard
26876562fbcfSJerome Brunet /*
2688c80ac50cSMaxime Ripard * Since the boundaries have been changed, let's give the
2689c80ac50cSMaxime Ripard * opportunity to the provider to adjust the clock rate based on
2690c80ac50cSMaxime Ripard * the new boundaries.
2691c80ac50cSMaxime Ripard *
2692c80ac50cSMaxime Ripard * We also need to handle the case where the clock is currently
2693c80ac50cSMaxime Ripard * outside of the boundaries. Clamping the last requested rate
2694c80ac50cSMaxime Ripard * to the current minimum and maximum will also handle this.
2695c80ac50cSMaxime Ripard *
26966562fbcfSJerome Brunet * FIXME:
2697c80ac50cSMaxime Ripard * There is a catch. It may fail for the usual reason (clock
2698c80ac50cSMaxime Ripard * broken, clock protected, etc) but also because:
26996562fbcfSJerome Brunet * - round_rate() was not favorable and fell on the wrong
27006562fbcfSJerome Brunet * side of the boundary
27016562fbcfSJerome Brunet * - the determine_rate() callback does not really check for
27026562fbcfSJerome Brunet * this corner case when determining the rate
27036562fbcfSJerome Brunet */
27043afb0723SMaxime Ripard rate = clamp(rate, min, max);
27056562fbcfSJerome Brunet ret = clk_core_set_rate_nolock(clk->core, rate);
27066562fbcfSJerome Brunet if (ret) {
27076562fbcfSJerome Brunet /* rollback the changes */
27086562fbcfSJerome Brunet clk->min_rate = old_min;
27096562fbcfSJerome Brunet clk->max_rate = old_max;
27101c8e6004STomeu Vizoso }
27111c8e6004STomeu Vizoso
271210c46f2eSMaxime Ripard out:
271355e9b8b7SJerome Brunet if (clk->exclusive_count)
271455e9b8b7SJerome Brunet clk_core_rate_protect(clk->core);
27151c8e6004STomeu Vizoso
2716d7738822SMaxime Ripard return ret;
2717d7738822SMaxime Ripard }
2718d7738822SMaxime Ripard
2719d7738822SMaxime Ripard /**
2720d7738822SMaxime Ripard * clk_set_rate_range - set a rate range for a clock source
2721d7738822SMaxime Ripard * @clk: clock source
2722d7738822SMaxime Ripard * @min: desired minimum clock rate in Hz, inclusive
2723d7738822SMaxime Ripard * @max: desired maximum clock rate in Hz, inclusive
2724d7738822SMaxime Ripard *
2725d7738822SMaxime Ripard * Return: 0 for success or negative errno on failure.
2726d7738822SMaxime Ripard */
clk_set_rate_range(struct clk * clk,unsigned long min,unsigned long max)2727d7738822SMaxime Ripard int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
2728d7738822SMaxime Ripard {
2729d7738822SMaxime Ripard int ret;
2730d7738822SMaxime Ripard
2731d7738822SMaxime Ripard if (!clk)
2732d7738822SMaxime Ripard return 0;
2733d7738822SMaxime Ripard
2734d7738822SMaxime Ripard clk_prepare_lock();
2735d7738822SMaxime Ripard
2736d7738822SMaxime Ripard ret = clk_set_rate_range_nolock(clk, min, max);
2737d7738822SMaxime Ripard
27381c8e6004STomeu Vizoso clk_prepare_unlock();
27391c8e6004STomeu Vizoso
27401c8e6004STomeu Vizoso return ret;
27411c8e6004STomeu Vizoso }
27421c8e6004STomeu Vizoso EXPORT_SYMBOL_GPL(clk_set_rate_range);
27431c8e6004STomeu Vizoso
27441c8e6004STomeu Vizoso /**
27451c8e6004STomeu Vizoso * clk_set_min_rate - set a minimum clock rate for a clock source
27461c8e6004STomeu Vizoso * @clk: clock source
27471c8e6004STomeu Vizoso * @rate: desired minimum clock rate in Hz, inclusive
27481c8e6004STomeu Vizoso *
27491c8e6004STomeu Vizoso * Returns success (0) or negative errno.
27501c8e6004STomeu Vizoso */
clk_set_min_rate(struct clk * clk,unsigned long rate)27511c8e6004STomeu Vizoso int clk_set_min_rate(struct clk *clk, unsigned long rate)
27521c8e6004STomeu Vizoso {
27531c8e6004STomeu Vizoso if (!clk)
27541c8e6004STomeu Vizoso return 0;
27551c8e6004STomeu Vizoso
275603813d9bSMaxime Ripard trace_clk_set_min_rate(clk->core, rate);
275703813d9bSMaxime Ripard
27581c8e6004STomeu Vizoso return clk_set_rate_range(clk, rate, clk->max_rate);
27591c8e6004STomeu Vizoso }
27601c8e6004STomeu Vizoso EXPORT_SYMBOL_GPL(clk_set_min_rate);
27611c8e6004STomeu Vizoso
27621c8e6004STomeu Vizoso /**
27631c8e6004STomeu Vizoso * clk_set_max_rate - set a maximum clock rate for a clock source
27641c8e6004STomeu Vizoso * @clk: clock source
27651c8e6004STomeu Vizoso * @rate: desired maximum clock rate in Hz, inclusive
27661c8e6004STomeu Vizoso *
27671c8e6004STomeu Vizoso * Returns success (0) or negative errno.
27681c8e6004STomeu Vizoso */
clk_set_max_rate(struct clk * clk,unsigned long rate)27691c8e6004STomeu Vizoso int clk_set_max_rate(struct clk *clk, unsigned long rate)
27701c8e6004STomeu Vizoso {
27711c8e6004STomeu Vizoso if (!clk)
27721c8e6004STomeu Vizoso return 0;
27731c8e6004STomeu Vizoso
277403813d9bSMaxime Ripard trace_clk_set_max_rate(clk->core, rate);
277503813d9bSMaxime Ripard
27761c8e6004STomeu Vizoso return clk_set_rate_range(clk, clk->min_rate, rate);
27771c8e6004STomeu Vizoso }
27781c8e6004STomeu Vizoso EXPORT_SYMBOL_GPL(clk_set_max_rate);
27791c8e6004STomeu Vizoso
27801c8e6004STomeu Vizoso /**
2781b2476490SMike Turquette * clk_get_parent - return the parent of a clk
2782b2476490SMike Turquette * @clk: the clk whose parent gets returned
2783b2476490SMike Turquette *
2784b2476490SMike Turquette * Simply returns clk->parent. Returns NULL if clk is NULL.
2785b2476490SMike Turquette */
clk_get_parent(struct clk * clk)2786b2476490SMike Turquette struct clk *clk_get_parent(struct clk *clk)
2787b2476490SMike Turquette {
2788b2476490SMike Turquette struct clk *parent;
2789b2476490SMike Turquette
2790fc4a05d4SStephen Boyd if (!clk)
2791fc4a05d4SStephen Boyd return NULL;
2792fc4a05d4SStephen Boyd
2793eab89f69SMike Turquette clk_prepare_lock();
2794fc4a05d4SStephen Boyd /* TODO: Create a per-user clk and change callers to call clk_put */
2795fc4a05d4SStephen Boyd parent = !clk->core->parent ? NULL : clk->core->parent->hw->clk;
2796eab89f69SMike Turquette clk_prepare_unlock();
2797b2476490SMike Turquette
2798b2476490SMike Turquette return parent;
2799b2476490SMike Turquette }
2800b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_get_parent);
2801b2476490SMike Turquette
__clk_init_parent(struct clk_core * core)2802d6968fcaSStephen Boyd static struct clk_core *__clk_init_parent(struct clk_core *core)
2803b2476490SMike Turquette {
28045146e0b0SMasahiro Yamada u8 index = 0;
2805b2476490SMike Turquette
28062430a94dSMasahiro Yamada if (core->num_parents > 1 && core->ops->get_parent)
2807d6968fcaSStephen Boyd index = core->ops->get_parent(core->hw);
2808b2476490SMike Turquette
28095146e0b0SMasahiro Yamada return clk_core_get_parent_by_index(core, index);
2810b2476490SMike Turquette }
2811b2476490SMike Turquette
clk_core_reparent(struct clk_core * core,struct clk_core * new_parent)2812d6968fcaSStephen Boyd static void clk_core_reparent(struct clk_core *core,
2813035a61c3STomeu Vizoso struct clk_core *new_parent)
2814b33d212fSUlf Hansson {
2815d6968fcaSStephen Boyd clk_reparent(core, new_parent);
2816d6968fcaSStephen Boyd __clk_recalc_accuracies(core);
2817096f2a0cSMaxime Ripard __clk_recalc_rates(core, true, POST_RATE_CHANGE);
2818b2476490SMike Turquette }
2819b2476490SMike Turquette
clk_hw_reparent(struct clk_hw * hw,struct clk_hw * new_parent)282042c86547STomeu Vizoso void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent)
282142c86547STomeu Vizoso {
282242c86547STomeu Vizoso if (!hw)
282342c86547STomeu Vizoso return;
282442c86547STomeu Vizoso
282542c86547STomeu Vizoso clk_core_reparent(hw->core, !new_parent ? NULL : new_parent->core);
282642c86547STomeu Vizoso }
282742c86547STomeu Vizoso
2828b2476490SMike Turquette /**
28294e88f3deSThierry Reding * clk_has_parent - check if a clock is a possible parent for another
28304e88f3deSThierry Reding * @clk: clock source
28314e88f3deSThierry Reding * @parent: parent clock source
2832b2476490SMike Turquette *
28334e88f3deSThierry Reding * This function can be used in drivers that need to check that a clock can be
28344e88f3deSThierry Reding * the parent of another without actually changing the parent.
2835f8aa0bd5SSaravana Kannan *
28364e88f3deSThierry Reding * Returns true if @parent is a possible parent for @clk, false otherwise.
2837b2476490SMike Turquette */
clk_has_parent(const struct clk * clk,const struct clk * parent)283822fb0e28SMaxime Ripard bool clk_has_parent(const struct clk *clk, const struct clk *parent)
28394e88f3deSThierry Reding {
28404e88f3deSThierry Reding /* NULL clocks should be nops, so return success if either is NULL. */
28414e88f3deSThierry Reding if (!clk || !parent)
28424e88f3deSThierry Reding return true;
28434e88f3deSThierry Reding
28441234a2c4SMaxime Ripard return clk_core_has_parent(clk->core, parent->core);
28454e88f3deSThierry Reding }
28464e88f3deSThierry Reding EXPORT_SYMBOL_GPL(clk_has_parent);
28474e88f3deSThierry Reding
clk_core_set_parent_nolock(struct clk_core * core,struct clk_core * parent)284891baa9ffSJerome Brunet static int clk_core_set_parent_nolock(struct clk_core *core,
284991baa9ffSJerome Brunet struct clk_core *parent)
2850b2476490SMike Turquette {
2851b2476490SMike Turquette int ret = 0;
2852f1c8b2edSTomasz Figa int p_index = 0;
2853031dcc9bSUlf Hansson unsigned long p_rate = 0;
2854b2476490SMike Turquette
285591baa9ffSJerome Brunet lockdep_assert_held(&prepare_lock);
285691baa9ffSJerome Brunet
2857d6968fcaSStephen Boyd if (!core)
285889ac8d7aSMike Turquette return 0;
285989ac8d7aSMike Turquette
2860d6968fcaSStephen Boyd if (core->parent == parent)
286191baa9ffSJerome Brunet return 0;
2862b2476490SMike Turquette
2863ef13e55cSRishi Gupta /* verify ops for multi-parent clks */
286491baa9ffSJerome Brunet if (core->num_parents > 1 && !core->ops->set_parent)
286591baa9ffSJerome Brunet return -EPERM;
2866b61c43c0SStephen Boyd
2867031dcc9bSUlf Hansson /* check that we are allowed to re-parent if the clock is in use */
286891baa9ffSJerome Brunet if ((core->flags & CLK_SET_PARENT_GATE) && core->prepare_count)
286991baa9ffSJerome Brunet return -EBUSY;
2870031dcc9bSUlf Hansson
2871e55a839aSJerome Brunet if (clk_core_rate_is_protected(core))
2872e55a839aSJerome Brunet return -EBUSY;
2873031dcc9bSUlf Hansson
2874031dcc9bSUlf Hansson /* try finding the new parent index */
2875031dcc9bSUlf Hansson if (parent) {
2876d6968fcaSStephen Boyd p_index = clk_fetch_parent_index(core, parent);
2877f1c8b2edSTomasz Figa if (p_index < 0) {
2878031dcc9bSUlf Hansson pr_debug("%s: clk %s can not be parent of clk %s\n",
2879d6968fcaSStephen Boyd __func__, parent->name, core->name);
288091baa9ffSJerome Brunet return p_index;
2881031dcc9bSUlf Hansson }
2882e8f0e68eSMasahiro Yamada p_rate = parent->rate;
2883031dcc9bSUlf Hansson }
2884031dcc9bSUlf Hansson
28859a34b453SMarek Szyprowski ret = clk_pm_runtime_get(core);
28869a34b453SMarek Szyprowski if (ret)
288791baa9ffSJerome Brunet return ret;
28889a34b453SMarek Szyprowski
2889b2476490SMike Turquette /* propagate PRE_RATE_CHANGE notifications */
2890d6968fcaSStephen Boyd ret = __clk_speculate_rates(core, p_rate);
2891b2476490SMike Turquette
2892b2476490SMike Turquette /* abort if a driver objects */
2893fb72a059SSoren Brinkmann if (ret & NOTIFY_STOP_MASK)
28949a34b453SMarek Szyprowski goto runtime_put;
2895b2476490SMike Turquette
2896031dcc9bSUlf Hansson /* do the re-parent */
2897d6968fcaSStephen Boyd ret = __clk_set_parent(core, parent, p_index);
2898b2476490SMike Turquette
28995279fc40SBoris BREZILLON /* propagate rate an accuracy recalculation accordingly */
29005279fc40SBoris BREZILLON if (ret) {
2901096f2a0cSMaxime Ripard __clk_recalc_rates(core, true, ABORT_RATE_CHANGE);
29025279fc40SBoris BREZILLON } else {
2903096f2a0cSMaxime Ripard __clk_recalc_rates(core, true, POST_RATE_CHANGE);
2904d6968fcaSStephen Boyd __clk_recalc_accuracies(core);
29055279fc40SBoris BREZILLON }
2906b2476490SMike Turquette
29079a34b453SMarek Szyprowski runtime_put:
29089a34b453SMarek Szyprowski clk_pm_runtime_put(core);
2909b2476490SMike Turquette
2910b2476490SMike Turquette return ret;
2911b2476490SMike Turquette }
2912035a61c3STomeu Vizoso
clk_hw_set_parent(struct clk_hw * hw,struct clk_hw * parent)29133567894bSNeil Armstrong int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *parent)
29143567894bSNeil Armstrong {
29153567894bSNeil Armstrong return clk_core_set_parent_nolock(hw->core, parent->core);
29163567894bSNeil Armstrong }
29173567894bSNeil Armstrong EXPORT_SYMBOL_GPL(clk_hw_set_parent);
29183567894bSNeil Armstrong
2919035a61c3STomeu Vizoso /**
2920035a61c3STomeu Vizoso * clk_set_parent - switch the parent of a mux clk
2921035a61c3STomeu Vizoso * @clk: the mux clk whose input we are switching
2922035a61c3STomeu Vizoso * @parent: the new input to clk
2923035a61c3STomeu Vizoso *
2924035a61c3STomeu Vizoso * Re-parent clk to use parent as its new input source. If clk is in
2925035a61c3STomeu Vizoso * prepared state, the clk will get enabled for the duration of this call. If
2926035a61c3STomeu Vizoso * that's not acceptable for a specific clk (Eg: the consumer can't handle
2927035a61c3STomeu Vizoso * that, the reparenting is glitchy in hardware, etc), use the
2928035a61c3STomeu Vizoso * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
2929035a61c3STomeu Vizoso *
2930035a61c3STomeu Vizoso * After successfully changing clk's parent clk_set_parent will update the
2931035a61c3STomeu Vizoso * clk topology, sysfs topology and propagate rate recalculation via
2932035a61c3STomeu Vizoso * __clk_recalc_rates.
2933035a61c3STomeu Vizoso *
2934035a61c3STomeu Vizoso * Returns 0 on success, -EERROR otherwise.
2935035a61c3STomeu Vizoso */
clk_set_parent(struct clk * clk,struct clk * parent)2936035a61c3STomeu Vizoso int clk_set_parent(struct clk *clk, struct clk *parent)
2937035a61c3STomeu Vizoso {
293891baa9ffSJerome Brunet int ret;
293991baa9ffSJerome Brunet
2940035a61c3STomeu Vizoso if (!clk)
2941035a61c3STomeu Vizoso return 0;
2942035a61c3STomeu Vizoso
294391baa9ffSJerome Brunet clk_prepare_lock();
294455e9b8b7SJerome Brunet
294555e9b8b7SJerome Brunet if (clk->exclusive_count)
294655e9b8b7SJerome Brunet clk_core_rate_unprotect(clk->core);
294755e9b8b7SJerome Brunet
294891baa9ffSJerome Brunet ret = clk_core_set_parent_nolock(clk->core,
294991baa9ffSJerome Brunet parent ? parent->core : NULL);
295055e9b8b7SJerome Brunet
295155e9b8b7SJerome Brunet if (clk->exclusive_count)
295255e9b8b7SJerome Brunet clk_core_rate_protect(clk->core);
295355e9b8b7SJerome Brunet
295491baa9ffSJerome Brunet clk_prepare_unlock();
295591baa9ffSJerome Brunet
295691baa9ffSJerome Brunet return ret;
2957035a61c3STomeu Vizoso }
2958b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_set_parent);
2959b2476490SMike Turquette
clk_core_set_phase_nolock(struct clk_core * core,int degrees)29609e4d04adSJerome Brunet static int clk_core_set_phase_nolock(struct clk_core *core, int degrees)
29619e4d04adSJerome Brunet {
29629e4d04adSJerome Brunet int ret = -EINVAL;
29639e4d04adSJerome Brunet
29649e4d04adSJerome Brunet lockdep_assert_held(&prepare_lock);
29659e4d04adSJerome Brunet
29669e4d04adSJerome Brunet if (!core)
29679e4d04adSJerome Brunet return 0;
29689e4d04adSJerome Brunet
2969e55a839aSJerome Brunet if (clk_core_rate_is_protected(core))
2970e55a839aSJerome Brunet return -EBUSY;
2971e55a839aSJerome Brunet
29729e4d04adSJerome Brunet trace_clk_set_phase(core, degrees);
29739e4d04adSJerome Brunet
29747f95beeaSShawn Lin if (core->ops->set_phase) {
29759e4d04adSJerome Brunet ret = core->ops->set_phase(core->hw, degrees);
29767f95beeaSShawn Lin if (!ret)
29777f95beeaSShawn Lin core->phase = degrees;
29787f95beeaSShawn Lin }
29799e4d04adSJerome Brunet
29809e4d04adSJerome Brunet trace_clk_set_phase_complete(core, degrees);
29819e4d04adSJerome Brunet
29829e4d04adSJerome Brunet return ret;
29839e4d04adSJerome Brunet }
29849e4d04adSJerome Brunet
2985b2476490SMike Turquette /**
2986e59c5371SMike Turquette * clk_set_phase - adjust the phase shift of a clock signal
2987e59c5371SMike Turquette * @clk: clock signal source
2988e59c5371SMike Turquette * @degrees: number of degrees the signal is shifted
2989e59c5371SMike Turquette *
2990e59c5371SMike Turquette * Shifts the phase of a clock signal by the specified
2991e59c5371SMike Turquette * degrees. Returns 0 on success, -EERROR otherwise.
2992e59c5371SMike Turquette *
2993e59c5371SMike Turquette * This function makes no distinction about the input or reference
2994e59c5371SMike Turquette * signal that we adjust the clock signal phase against. For example
2995e59c5371SMike Turquette * phase locked-loop clock signal generators we may shift phase with
2996e59c5371SMike Turquette * respect to feedback clock signal input, but for other cases the
2997e59c5371SMike Turquette * clock phase may be shifted with respect to some other, unspecified
2998e59c5371SMike Turquette * signal.
2999e59c5371SMike Turquette *
3000e59c5371SMike Turquette * Additionally the concept of phase shift does not propagate through
3001e59c5371SMike Turquette * the clock tree hierarchy, which sets it apart from clock rates and
3002e59c5371SMike Turquette * clock accuracy. A parent clock phase attribute does not have an
3003e59c5371SMike Turquette * impact on the phase attribute of a child clock.
3004e59c5371SMike Turquette */
clk_set_phase(struct clk * clk,int degrees)3005e59c5371SMike Turquette int clk_set_phase(struct clk *clk, int degrees)
3006e59c5371SMike Turquette {
30079e4d04adSJerome Brunet int ret;
3008e59c5371SMike Turquette
3009e59c5371SMike Turquette if (!clk)
301008b95756SStephen Boyd return 0;
3011e59c5371SMike Turquette
3012e59c5371SMike Turquette /* sanity check degrees */
3013e59c5371SMike Turquette degrees %= 360;
3014e59c5371SMike Turquette if (degrees < 0)
3015e59c5371SMike Turquette degrees += 360;
3016e59c5371SMike Turquette
3017e59c5371SMike Turquette clk_prepare_lock();
3018e59c5371SMike Turquette
301955e9b8b7SJerome Brunet if (clk->exclusive_count)
302055e9b8b7SJerome Brunet clk_core_rate_unprotect(clk->core);
3021dfc202eaSStephen Boyd
30229e4d04adSJerome Brunet ret = clk_core_set_phase_nolock(clk->core, degrees);
3023e59c5371SMike Turquette
302455e9b8b7SJerome Brunet if (clk->exclusive_count)
302555e9b8b7SJerome Brunet clk_core_rate_protect(clk->core);
3026e59c5371SMike Turquette
3027e59c5371SMike Turquette clk_prepare_unlock();
3028e59c5371SMike Turquette
3029e59c5371SMike Turquette return ret;
3030e59c5371SMike Turquette }
30319767b04fSMaxime Ripard EXPORT_SYMBOL_GPL(clk_set_phase);
3032e59c5371SMike Turquette
clk_core_get_phase(struct clk_core * core)3033d6968fcaSStephen Boyd static int clk_core_get_phase(struct clk_core *core)
3034e59c5371SMike Turquette {
30351f3e1983SStephen Boyd int ret;
3036e59c5371SMike Turquette
3037f21cf9c7SStephen Boyd lockdep_assert_held(&prepare_lock);
3038f21cf9c7SStephen Boyd if (!core->ops->get_phase)
3039f21cf9c7SStephen Boyd return 0;
3040f21cf9c7SStephen Boyd
30411f9c63e8SShawn Lin /* Always try to update cached phase if possible */
3042f21cf9c7SStephen Boyd ret = core->ops->get_phase(core->hw);
3043f21cf9c7SStephen Boyd if (ret >= 0)
3044f21cf9c7SStephen Boyd core->phase = ret;
3045e59c5371SMike Turquette
3046e59c5371SMike Turquette return ret;
3047e59c5371SMike Turquette }
3048e59c5371SMike Turquette
3049e59c5371SMike Turquette /**
3050035a61c3STomeu Vizoso * clk_get_phase - return the phase shift of a clock signal
3051035a61c3STomeu Vizoso * @clk: clock signal source
3052035a61c3STomeu Vizoso *
3053035a61c3STomeu Vizoso * Returns the phase shift of a clock node in degrees, otherwise returns
3054035a61c3STomeu Vizoso * -EERROR.
3055035a61c3STomeu Vizoso */
clk_get_phase(struct clk * clk)3056035a61c3STomeu Vizoso int clk_get_phase(struct clk *clk)
3057035a61c3STomeu Vizoso {
3058f21cf9c7SStephen Boyd int ret;
3059f21cf9c7SStephen Boyd
3060035a61c3STomeu Vizoso if (!clk)
3061035a61c3STomeu Vizoso return 0;
3062035a61c3STomeu Vizoso
3063f21cf9c7SStephen Boyd clk_prepare_lock();
3064f21cf9c7SStephen Boyd ret = clk_core_get_phase(clk->core);
3065f21cf9c7SStephen Boyd clk_prepare_unlock();
3066f21cf9c7SStephen Boyd
3067f21cf9c7SStephen Boyd return ret;
3068035a61c3STomeu Vizoso }
30694dff95dcSStephen Boyd EXPORT_SYMBOL_GPL(clk_get_phase);
3070b2476490SMike Turquette
clk_core_reset_duty_cycle_nolock(struct clk_core * core)30719fba738aSJerome Brunet static void clk_core_reset_duty_cycle_nolock(struct clk_core *core)
30729fba738aSJerome Brunet {
30739fba738aSJerome Brunet /* Assume a default value of 50% */
30749fba738aSJerome Brunet core->duty.num = 1;
30759fba738aSJerome Brunet core->duty.den = 2;
30769fba738aSJerome Brunet }
30779fba738aSJerome Brunet
30789fba738aSJerome Brunet static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core);
30799fba738aSJerome Brunet
clk_core_update_duty_cycle_nolock(struct clk_core * core)30809fba738aSJerome Brunet static int clk_core_update_duty_cycle_nolock(struct clk_core *core)
30819fba738aSJerome Brunet {
30829fba738aSJerome Brunet struct clk_duty *duty = &core->duty;
30839fba738aSJerome Brunet int ret = 0;
30849fba738aSJerome Brunet
30859fba738aSJerome Brunet if (!core->ops->get_duty_cycle)
30869fba738aSJerome Brunet return clk_core_update_duty_cycle_parent_nolock(core);
30879fba738aSJerome Brunet
30889fba738aSJerome Brunet ret = core->ops->get_duty_cycle(core->hw, duty);
30899fba738aSJerome Brunet if (ret)
30909fba738aSJerome Brunet goto reset;
30919fba738aSJerome Brunet
30929fba738aSJerome Brunet /* Don't trust the clock provider too much */
30939fba738aSJerome Brunet if (duty->den == 0 || duty->num > duty->den) {
30949fba738aSJerome Brunet ret = -EINVAL;
30959fba738aSJerome Brunet goto reset;
30969fba738aSJerome Brunet }
30979fba738aSJerome Brunet
30989fba738aSJerome Brunet return 0;
30999fba738aSJerome Brunet
31009fba738aSJerome Brunet reset:
31019fba738aSJerome Brunet clk_core_reset_duty_cycle_nolock(core);
31029fba738aSJerome Brunet return ret;
31039fba738aSJerome Brunet }
31049fba738aSJerome Brunet
clk_core_update_duty_cycle_parent_nolock(struct clk_core * core)31059fba738aSJerome Brunet static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core)
31069fba738aSJerome Brunet {
31079fba738aSJerome Brunet int ret = 0;
31089fba738aSJerome Brunet
31099fba738aSJerome Brunet if (core->parent &&
31109fba738aSJerome Brunet core->flags & CLK_DUTY_CYCLE_PARENT) {
31119fba738aSJerome Brunet ret = clk_core_update_duty_cycle_nolock(core->parent);
31129fba738aSJerome Brunet memcpy(&core->duty, &core->parent->duty, sizeof(core->duty));
31139fba738aSJerome Brunet } else {
31149fba738aSJerome Brunet clk_core_reset_duty_cycle_nolock(core);
31159fba738aSJerome Brunet }
31169fba738aSJerome Brunet
31179fba738aSJerome Brunet return ret;
31189fba738aSJerome Brunet }
31199fba738aSJerome Brunet
31209fba738aSJerome Brunet static int clk_core_set_duty_cycle_parent_nolock(struct clk_core *core,
31219fba738aSJerome Brunet struct clk_duty *duty);
31229fba738aSJerome Brunet
clk_core_set_duty_cycle_nolock(struct clk_core * core,struct clk_duty * duty)31239fba738aSJerome Brunet static int clk_core_set_duty_cycle_nolock(struct clk_core *core,
31249fba738aSJerome Brunet struct clk_duty *duty)
31259fba738aSJerome Brunet {
31269fba738aSJerome Brunet int ret;
31279fba738aSJerome Brunet
31289fba738aSJerome Brunet lockdep_assert_held(&prepare_lock);
31299fba738aSJerome Brunet
31309fba738aSJerome Brunet if (clk_core_rate_is_protected(core))
31319fba738aSJerome Brunet return -EBUSY;
31329fba738aSJerome Brunet
31339fba738aSJerome Brunet trace_clk_set_duty_cycle(core, duty);
31349fba738aSJerome Brunet
31359fba738aSJerome Brunet if (!core->ops->set_duty_cycle)
31369fba738aSJerome Brunet return clk_core_set_duty_cycle_parent_nolock(core, duty);
31379fba738aSJerome Brunet
31389fba738aSJerome Brunet ret = core->ops->set_duty_cycle(core->hw, duty);
31399fba738aSJerome Brunet if (!ret)
31409fba738aSJerome Brunet memcpy(&core->duty, duty, sizeof(*duty));
31419fba738aSJerome Brunet
31429fba738aSJerome Brunet trace_clk_set_duty_cycle_complete(core, duty);
31439fba738aSJerome Brunet
31449fba738aSJerome Brunet return ret;
31459fba738aSJerome Brunet }
31469fba738aSJerome Brunet
clk_core_set_duty_cycle_parent_nolock(struct clk_core * core,struct clk_duty * duty)31479fba738aSJerome Brunet static int clk_core_set_duty_cycle_parent_nolock(struct clk_core *core,
31489fba738aSJerome Brunet struct clk_duty *duty)
31499fba738aSJerome Brunet {
31509fba738aSJerome Brunet int ret = 0;
31519fba738aSJerome Brunet
31529fba738aSJerome Brunet if (core->parent &&
31539fba738aSJerome Brunet core->flags & (CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)) {
31549fba738aSJerome Brunet ret = clk_core_set_duty_cycle_nolock(core->parent, duty);
31559fba738aSJerome Brunet memcpy(&core->duty, &core->parent->duty, sizeof(core->duty));
31569fba738aSJerome Brunet }
31579fba738aSJerome Brunet
31589fba738aSJerome Brunet return ret;
31599fba738aSJerome Brunet }
31609fba738aSJerome Brunet
31619fba738aSJerome Brunet /**
31629fba738aSJerome Brunet * clk_set_duty_cycle - adjust the duty cycle ratio of a clock signal
31639fba738aSJerome Brunet * @clk: clock signal source
31649fba738aSJerome Brunet * @num: numerator of the duty cycle ratio to be applied
31659fba738aSJerome Brunet * @den: denominator of the duty cycle ratio to be applied
31669fba738aSJerome Brunet *
31679fba738aSJerome Brunet * Apply the duty cycle ratio if the ratio is valid and the clock can
31689fba738aSJerome Brunet * perform this operation
31699fba738aSJerome Brunet *
31709fba738aSJerome Brunet * Returns (0) on success, a negative errno otherwise.
31719fba738aSJerome Brunet */
clk_set_duty_cycle(struct clk * clk,unsigned int num,unsigned int den)31729fba738aSJerome Brunet int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den)
31739fba738aSJerome Brunet {
31749fba738aSJerome Brunet int ret;
31759fba738aSJerome Brunet struct clk_duty duty;
31769fba738aSJerome Brunet
31779fba738aSJerome Brunet if (!clk)
31789fba738aSJerome Brunet return 0;
31799fba738aSJerome Brunet
31809fba738aSJerome Brunet /* sanity check the ratio */
31819fba738aSJerome Brunet if (den == 0 || num > den)
31829fba738aSJerome Brunet return -EINVAL;
31839fba738aSJerome Brunet
31849fba738aSJerome Brunet duty.num = num;
31859fba738aSJerome Brunet duty.den = den;
31869fba738aSJerome Brunet
31879fba738aSJerome Brunet clk_prepare_lock();
31889fba738aSJerome Brunet
31899fba738aSJerome Brunet if (clk->exclusive_count)
31909fba738aSJerome Brunet clk_core_rate_unprotect(clk->core);
31919fba738aSJerome Brunet
31929fba738aSJerome Brunet ret = clk_core_set_duty_cycle_nolock(clk->core, &duty);
31939fba738aSJerome Brunet
31949fba738aSJerome Brunet if (clk->exclusive_count)
31959fba738aSJerome Brunet clk_core_rate_protect(clk->core);
31969fba738aSJerome Brunet
31979fba738aSJerome Brunet clk_prepare_unlock();
31989fba738aSJerome Brunet
31999fba738aSJerome Brunet return ret;
32009fba738aSJerome Brunet }
32019fba738aSJerome Brunet EXPORT_SYMBOL_GPL(clk_set_duty_cycle);
32029fba738aSJerome Brunet
clk_core_get_scaled_duty_cycle(struct clk_core * core,unsigned int scale)32039fba738aSJerome Brunet static int clk_core_get_scaled_duty_cycle(struct clk_core *core,
32049fba738aSJerome Brunet unsigned int scale)
32059fba738aSJerome Brunet {
32069fba738aSJerome Brunet struct clk_duty *duty = &core->duty;
32079fba738aSJerome Brunet int ret;
32089fba738aSJerome Brunet
32099fba738aSJerome Brunet clk_prepare_lock();
32109fba738aSJerome Brunet
32119fba738aSJerome Brunet ret = clk_core_update_duty_cycle_nolock(core);
32129fba738aSJerome Brunet if (!ret)
32139fba738aSJerome Brunet ret = mult_frac(scale, duty->num, duty->den);
32149fba738aSJerome Brunet
32159fba738aSJerome Brunet clk_prepare_unlock();
32169fba738aSJerome Brunet
32179fba738aSJerome Brunet return ret;
32189fba738aSJerome Brunet }
32199fba738aSJerome Brunet
32209fba738aSJerome Brunet /**
32219fba738aSJerome Brunet * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal
32229fba738aSJerome Brunet * @clk: clock signal source
32239fba738aSJerome Brunet * @scale: scaling factor to be applied to represent the ratio as an integer
32249fba738aSJerome Brunet *
32259fba738aSJerome Brunet * Returns the duty cycle ratio of a clock node multiplied by the provided
32269fba738aSJerome Brunet * scaling factor, or negative errno on error.
32279fba738aSJerome Brunet */
clk_get_scaled_duty_cycle(struct clk * clk,unsigned int scale)32289fba738aSJerome Brunet int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale)
32299fba738aSJerome Brunet {
32309fba738aSJerome Brunet if (!clk)
32319fba738aSJerome Brunet return 0;
32329fba738aSJerome Brunet
32339fba738aSJerome Brunet return clk_core_get_scaled_duty_cycle(clk->core, scale);
32349fba738aSJerome Brunet }
32359fba738aSJerome Brunet EXPORT_SYMBOL_GPL(clk_get_scaled_duty_cycle);
32369fba738aSJerome Brunet
3237b2476490SMike Turquette /**
32383d3801efSMichael Turquette * clk_is_match - check if two clk's point to the same hardware clock
32393d3801efSMichael Turquette * @p: clk compared against q
32403d3801efSMichael Turquette * @q: clk compared against p
32413d3801efSMichael Turquette *
32423d3801efSMichael Turquette * Returns true if the two struct clk pointers both point to the same hardware
32433d3801efSMichael Turquette * clock node. Put differently, returns true if struct clk *p and struct clk *q
32443d3801efSMichael Turquette * share the same struct clk_core object.
32453d3801efSMichael Turquette *
32463d3801efSMichael Turquette * Returns false otherwise. Note that two NULL clks are treated as matching.
32473d3801efSMichael Turquette */
clk_is_match(const struct clk * p,const struct clk * q)32483d3801efSMichael Turquette bool clk_is_match(const struct clk *p, const struct clk *q)
32493d3801efSMichael Turquette {
32503d3801efSMichael Turquette /* trivial case: identical struct clk's or both NULL */
32513d3801efSMichael Turquette if (p == q)
32523d3801efSMichael Turquette return true;
32533d3801efSMichael Turquette
32543fe003f9SGeert Uytterhoeven /* true if clk->core pointers match. Avoid dereferencing garbage */
32553d3801efSMichael Turquette if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q))
32563d3801efSMichael Turquette if (p->core == q->core)
32573d3801efSMichael Turquette return true;
32583d3801efSMichael Turquette
32593d3801efSMichael Turquette return false;
32603d3801efSMichael Turquette }
32613d3801efSMichael Turquette EXPORT_SYMBOL_GPL(clk_is_match);
32623d3801efSMichael Turquette
32634dff95dcSStephen Boyd /*** debugfs support ***/
32644dff95dcSStephen Boyd
32654dff95dcSStephen Boyd #ifdef CONFIG_DEBUG_FS
32664dff95dcSStephen Boyd #include <linux/debugfs.h>
32674dff95dcSStephen Boyd
32684dff95dcSStephen Boyd static struct dentry *rootdir;
32694dff95dcSStephen Boyd static int inited = 0;
32704dff95dcSStephen Boyd static DEFINE_MUTEX(clk_debug_lock);
32714dff95dcSStephen Boyd static HLIST_HEAD(clk_debug_list);
32724dff95dcSStephen Boyd
32734dff95dcSStephen Boyd static struct hlist_head *orphan_list[] = {
32744dff95dcSStephen Boyd &clk_orphan_list,
32754dff95dcSStephen Boyd NULL,
32764dff95dcSStephen Boyd };
32774dff95dcSStephen Boyd
clk_summary_show_one(struct seq_file * s,struct clk_core * c,int level)32784dff95dcSStephen Boyd static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
32794dff95dcSStephen Boyd int level)
32804dff95dcSStephen Boyd {
3281f21cf9c7SStephen Boyd int phase;
3282888a44f2SVishal Badole struct clk *clk_user;
3283888a44f2SVishal Badole int multi_node = 0;
3284f21cf9c7SStephen Boyd
3285888a44f2SVishal Badole seq_printf(s, "%*s%-*s %-7d %-8d %-8d %-11lu %-10lu ",
32864dff95dcSStephen Boyd level * 3 + 1, "",
3287888a44f2SVishal Badole 35 - level * 3, c->name,
3288e55a839aSJerome Brunet c->enable_count, c->prepare_count, c->protect_count,
32890daa376dSStephen Boyd clk_core_get_rate_recalc(c),
32900daa376dSStephen Boyd clk_core_get_accuracy_recalc(c));
3291f21cf9c7SStephen Boyd
3292f21cf9c7SStephen Boyd phase = clk_core_get_phase(c);
3293f21cf9c7SStephen Boyd if (phase >= 0)
3294888a44f2SVishal Badole seq_printf(s, "%-5d", phase);
3295f21cf9c7SStephen Boyd else
3296f21cf9c7SStephen Boyd seq_puts(s, "-----");
3297f21cf9c7SStephen Boyd
3298888a44f2SVishal Badole seq_printf(s, " %-6d", clk_core_get_scaled_duty_cycle(c, 100000));
3299bf6d43d7SDmitry Osipenko
3300bf6d43d7SDmitry Osipenko if (c->ops->is_enabled)
3301888a44f2SVishal Badole seq_printf(s, " %5c ", clk_core_is_enabled(c) ? 'Y' : 'N');
3302bf6d43d7SDmitry Osipenko else if (!c->ops->enable)
3303888a44f2SVishal Badole seq_printf(s, " %5c ", 'Y');
3304bf6d43d7SDmitry Osipenko else
3305888a44f2SVishal Badole seq_printf(s, " %5c ", '?');
3306888a44f2SVishal Badole
3307888a44f2SVishal Badole hlist_for_each_entry(clk_user, &c->clks, clks_node) {
3308888a44f2SVishal Badole seq_printf(s, "%*s%-*s %-25s\n",
3309888a44f2SVishal Badole level * 3 + 2 + 105 * multi_node, "",
3310888a44f2SVishal Badole 30,
3311888a44f2SVishal Badole clk_user->dev_id ? clk_user->dev_id : "deviceless",
3312888a44f2SVishal Badole clk_user->con_id ? clk_user->con_id : "no_connection_id");
3313888a44f2SVishal Badole
3314888a44f2SVishal Badole multi_node = 1;
3315888a44f2SVishal Badole }
3316888a44f2SVishal Badole
33174dff95dcSStephen Boyd }
33184dff95dcSStephen Boyd
clk_summary_show_subtree(struct seq_file * s,struct clk_core * c,int level)33194dff95dcSStephen Boyd static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
33204dff95dcSStephen Boyd int level)
33214dff95dcSStephen Boyd {
33224dff95dcSStephen Boyd struct clk_core *child;
33234dff95dcSStephen Boyd
33244dff95dcSStephen Boyd clk_summary_show_one(s, c, level);
33254dff95dcSStephen Boyd
33264dff95dcSStephen Boyd hlist_for_each_entry(child, &c->children, child_node)
33274dff95dcSStephen Boyd clk_summary_show_subtree(s, child, level + 1);
33284dff95dcSStephen Boyd }
33294dff95dcSStephen Boyd
clk_summary_show(struct seq_file * s,void * data)33304dff95dcSStephen Boyd static int clk_summary_show(struct seq_file *s, void *data)
33314dff95dcSStephen Boyd {
33324dff95dcSStephen Boyd struct clk_core *c;
33335b1a1c1aSYu Zhe struct hlist_head **lists = s->private;
33342c077fdfSStephen Boyd int ret;
33354dff95dcSStephen Boyd
3336888a44f2SVishal Badole seq_puts(s, " enable prepare protect duty hardware connection\n");
3337888a44f2SVishal Badole seq_puts(s, " clock count count count rate accuracy phase cycle enable consumer id\n");
3338888a44f2SVishal Badole seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n");
3339888a44f2SVishal Badole
33402c077fdfSStephen Boyd ret = clk_pm_runtime_get_all();
33412c077fdfSStephen Boyd if (ret)
33422c077fdfSStephen Boyd return ret;
33434dff95dcSStephen Boyd
33444dff95dcSStephen Boyd clk_prepare_lock();
33454dff95dcSStephen Boyd
33464dff95dcSStephen Boyd for (; *lists; lists++)
33474dff95dcSStephen Boyd hlist_for_each_entry(c, *lists, child_node)
33484dff95dcSStephen Boyd clk_summary_show_subtree(s, c, 0);
33494dff95dcSStephen Boyd
33504dff95dcSStephen Boyd clk_prepare_unlock();
33512c077fdfSStephen Boyd clk_pm_runtime_put_all();
33524dff95dcSStephen Boyd
33534dff95dcSStephen Boyd return 0;
33544dff95dcSStephen Boyd }
3355fec0ef3fSAndy Shevchenko DEFINE_SHOW_ATTRIBUTE(clk_summary);
33564dff95dcSStephen Boyd
clk_dump_one(struct seq_file * s,struct clk_core * c,int level)33574dff95dcSStephen Boyd static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
33584dff95dcSStephen Boyd {
3359f21cf9c7SStephen Boyd int phase;
33601bd37a46SLeonard Crestez unsigned long min_rate, max_rate;
33611bd37a46SLeonard Crestez
33621bd37a46SLeonard Crestez clk_core_get_boundaries(c, &min_rate, &max_rate);
33634dff95dcSStephen Boyd
33647cb81136SStefan Wahren /* This should be JSON format, i.e. elements separated with a comma */
33654dff95dcSStephen Boyd seq_printf(s, "\"%s\": { ", c->name);
33664dff95dcSStephen Boyd seq_printf(s, "\"enable_count\": %d,", c->enable_count);
33674dff95dcSStephen Boyd seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
3368e55a839aSJerome Brunet seq_printf(s, "\"protect_count\": %d,", c->protect_count);
33690daa376dSStephen Boyd seq_printf(s, "\"rate\": %lu,", clk_core_get_rate_recalc(c));
33701bd37a46SLeonard Crestez seq_printf(s, "\"min_rate\": %lu,", min_rate);
33711bd37a46SLeonard Crestez seq_printf(s, "\"max_rate\": %lu,", max_rate);
33720daa376dSStephen Boyd seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy_recalc(c));
3373f21cf9c7SStephen Boyd phase = clk_core_get_phase(c);
3374f21cf9c7SStephen Boyd if (phase >= 0)
3375f21cf9c7SStephen Boyd seq_printf(s, "\"phase\": %d,", phase);
33769fba738aSJerome Brunet seq_printf(s, "\"duty_cycle\": %u",
33779fba738aSJerome Brunet clk_core_get_scaled_duty_cycle(c, 100000));
33784dff95dcSStephen Boyd }
33794dff95dcSStephen Boyd
clk_dump_subtree(struct seq_file * s,struct clk_core * c,int level)33804dff95dcSStephen Boyd static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
33814dff95dcSStephen Boyd {
33824dff95dcSStephen Boyd struct clk_core *child;
33834dff95dcSStephen Boyd
33844dff95dcSStephen Boyd clk_dump_one(s, c, level);
33854dff95dcSStephen Boyd
33864dff95dcSStephen Boyd hlist_for_each_entry(child, &c->children, child_node) {
33874d327586SMarkus Elfring seq_putc(s, ',');
33884dff95dcSStephen Boyd clk_dump_subtree(s, child, level + 1);
33894dff95dcSStephen Boyd }
33904dff95dcSStephen Boyd
33914d327586SMarkus Elfring seq_putc(s, '}');
33924dff95dcSStephen Boyd }
33934dff95dcSStephen Boyd
clk_dump_show(struct seq_file * s,void * data)3394fec0ef3fSAndy Shevchenko static int clk_dump_show(struct seq_file *s, void *data)
33954dff95dcSStephen Boyd {
33964dff95dcSStephen Boyd struct clk_core *c;
33974dff95dcSStephen Boyd bool first_node = true;
33985b1a1c1aSYu Zhe struct hlist_head **lists = s->private;
33992c077fdfSStephen Boyd int ret;
34002c077fdfSStephen Boyd
34012c077fdfSStephen Boyd ret = clk_pm_runtime_get_all();
34022c077fdfSStephen Boyd if (ret)
34032c077fdfSStephen Boyd return ret;
34044dff95dcSStephen Boyd
34054d327586SMarkus Elfring seq_putc(s, '{');
34062c077fdfSStephen Boyd
34074dff95dcSStephen Boyd clk_prepare_lock();
34084dff95dcSStephen Boyd
34094dff95dcSStephen Boyd for (; *lists; lists++) {
34104dff95dcSStephen Boyd hlist_for_each_entry(c, *lists, child_node) {
34114dff95dcSStephen Boyd if (!first_node)
34124d327586SMarkus Elfring seq_putc(s, ',');
34134dff95dcSStephen Boyd first_node = false;
34144dff95dcSStephen Boyd clk_dump_subtree(s, c, 0);
34154dff95dcSStephen Boyd }
34164dff95dcSStephen Boyd }
34174dff95dcSStephen Boyd
34184dff95dcSStephen Boyd clk_prepare_unlock();
34192c077fdfSStephen Boyd clk_pm_runtime_put_all();
34204dff95dcSStephen Boyd
342170e9f4ddSFelipe Balbi seq_puts(s, "}\n");
34224dff95dcSStephen Boyd return 0;
34234dff95dcSStephen Boyd }
3424fec0ef3fSAndy Shevchenko DEFINE_SHOW_ATTRIBUTE(clk_dump);
34254dff95dcSStephen Boyd
342637215da5SGeert Uytterhoeven #undef CLOCK_ALLOW_WRITE_DEBUGFS
342737215da5SGeert Uytterhoeven #ifdef CLOCK_ALLOW_WRITE_DEBUGFS
342837215da5SGeert Uytterhoeven /*
342937215da5SGeert Uytterhoeven * This can be dangerous, therefore don't provide any real compile time
343037215da5SGeert Uytterhoeven * configuration option for this feature.
343137215da5SGeert Uytterhoeven * People who want to use this will need to modify the source code directly.
343237215da5SGeert Uytterhoeven */
clk_rate_set(void * data,u64 val)343337215da5SGeert Uytterhoeven static int clk_rate_set(void *data, u64 val)
343437215da5SGeert Uytterhoeven {
343537215da5SGeert Uytterhoeven struct clk_core *core = data;
343637215da5SGeert Uytterhoeven int ret;
343737215da5SGeert Uytterhoeven
343837215da5SGeert Uytterhoeven clk_prepare_lock();
343937215da5SGeert Uytterhoeven ret = clk_core_set_rate_nolock(core, val);
344037215da5SGeert Uytterhoeven clk_prepare_unlock();
344137215da5SGeert Uytterhoeven
344237215da5SGeert Uytterhoeven return ret;
344337215da5SGeert Uytterhoeven }
344437215da5SGeert Uytterhoeven
344537215da5SGeert Uytterhoeven #define clk_rate_mode 0644
344603111b10SMike Tipton
clk_prepare_enable_set(void * data,u64 val)344703111b10SMike Tipton static int clk_prepare_enable_set(void *data, u64 val)
344803111b10SMike Tipton {
344903111b10SMike Tipton struct clk_core *core = data;
345003111b10SMike Tipton int ret = 0;
345103111b10SMike Tipton
345203111b10SMike Tipton if (val)
345303111b10SMike Tipton ret = clk_prepare_enable(core->hw->clk);
345403111b10SMike Tipton else
345503111b10SMike Tipton clk_disable_unprepare(core->hw->clk);
345603111b10SMike Tipton
345703111b10SMike Tipton return ret;
345803111b10SMike Tipton }
345903111b10SMike Tipton
clk_prepare_enable_get(void * data,u64 * val)346003111b10SMike Tipton static int clk_prepare_enable_get(void *data, u64 *val)
346103111b10SMike Tipton {
346203111b10SMike Tipton struct clk_core *core = data;
346303111b10SMike Tipton
346403111b10SMike Tipton *val = core->enable_count && core->prepare_count;
346503111b10SMike Tipton return 0;
346603111b10SMike Tipton }
346703111b10SMike Tipton
346803111b10SMike Tipton DEFINE_DEBUGFS_ATTRIBUTE(clk_prepare_enable_fops, clk_prepare_enable_get,
346903111b10SMike Tipton clk_prepare_enable_set, "%llu\n");
347003111b10SMike Tipton
347137215da5SGeert Uytterhoeven #else
347237215da5SGeert Uytterhoeven #define clk_rate_set NULL
347337215da5SGeert Uytterhoeven #define clk_rate_mode 0444
347437215da5SGeert Uytterhoeven #endif
347537215da5SGeert Uytterhoeven
clk_rate_get(void * data,u64 * val)347637215da5SGeert Uytterhoeven static int clk_rate_get(void *data, u64 *val)
347737215da5SGeert Uytterhoeven {
347837215da5SGeert Uytterhoeven struct clk_core *core = data;
347937215da5SGeert Uytterhoeven
3480dd742cacSClaudiu Beznea clk_prepare_lock();
3481dd742cacSClaudiu Beznea *val = clk_core_get_rate_recalc(core);
3482dd742cacSClaudiu Beznea clk_prepare_unlock();
3483dd742cacSClaudiu Beznea
348437215da5SGeert Uytterhoeven return 0;
348537215da5SGeert Uytterhoeven }
348637215da5SGeert Uytterhoeven
348737215da5SGeert Uytterhoeven DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, clk_rate_get, clk_rate_set, "%llu\n");
348837215da5SGeert Uytterhoeven
3489a6059ab9SGeert Uytterhoeven static const struct {
3490a6059ab9SGeert Uytterhoeven unsigned long flag;
3491a6059ab9SGeert Uytterhoeven const char *name;
3492a6059ab9SGeert Uytterhoeven } clk_flags[] = {
349340dd71c7SGeert Uytterhoeven #define ENTRY(f) { f, #f }
3494a6059ab9SGeert Uytterhoeven ENTRY(CLK_SET_RATE_GATE),
3495a6059ab9SGeert Uytterhoeven ENTRY(CLK_SET_PARENT_GATE),
3496a6059ab9SGeert Uytterhoeven ENTRY(CLK_SET_RATE_PARENT),
3497a6059ab9SGeert Uytterhoeven ENTRY(CLK_IGNORE_UNUSED),
3498a6059ab9SGeert Uytterhoeven ENTRY(CLK_GET_RATE_NOCACHE),
3499a6059ab9SGeert Uytterhoeven ENTRY(CLK_SET_RATE_NO_REPARENT),
3500a6059ab9SGeert Uytterhoeven ENTRY(CLK_GET_ACCURACY_NOCACHE),
3501a6059ab9SGeert Uytterhoeven ENTRY(CLK_RECALC_NEW_RATES),
3502a6059ab9SGeert Uytterhoeven ENTRY(CLK_SET_RATE_UNGATE),
3503a6059ab9SGeert Uytterhoeven ENTRY(CLK_IS_CRITICAL),
3504a6059ab9SGeert Uytterhoeven ENTRY(CLK_OPS_PARENT_ENABLE),
35059fba738aSJerome Brunet ENTRY(CLK_DUTY_CYCLE_PARENT),
3506a6059ab9SGeert Uytterhoeven #undef ENTRY
3507a6059ab9SGeert Uytterhoeven };
3508a6059ab9SGeert Uytterhoeven
clk_flags_show(struct seq_file * s,void * data)3509fec0ef3fSAndy Shevchenko static int clk_flags_show(struct seq_file *s, void *data)
3510a6059ab9SGeert Uytterhoeven {
3511a6059ab9SGeert Uytterhoeven struct clk_core *core = s->private;
3512a6059ab9SGeert Uytterhoeven unsigned long flags = core->flags;
3513a6059ab9SGeert Uytterhoeven unsigned int i;
3514a6059ab9SGeert Uytterhoeven
3515a6059ab9SGeert Uytterhoeven for (i = 0; flags && i < ARRAY_SIZE(clk_flags); i++) {
3516a6059ab9SGeert Uytterhoeven if (flags & clk_flags[i].flag) {
3517a6059ab9SGeert Uytterhoeven seq_printf(s, "%s\n", clk_flags[i].name);
3518a6059ab9SGeert Uytterhoeven flags &= ~clk_flags[i].flag;
3519a6059ab9SGeert Uytterhoeven }
3520a6059ab9SGeert Uytterhoeven }
3521a6059ab9SGeert Uytterhoeven if (flags) {
3522a6059ab9SGeert Uytterhoeven /* Unknown flags */
3523a6059ab9SGeert Uytterhoeven seq_printf(s, "0x%lx\n", flags);
3524a6059ab9SGeert Uytterhoeven }
3525a6059ab9SGeert Uytterhoeven
3526a6059ab9SGeert Uytterhoeven return 0;
3527a6059ab9SGeert Uytterhoeven }
3528fec0ef3fSAndy Shevchenko DEFINE_SHOW_ATTRIBUTE(clk_flags);
3529a6059ab9SGeert Uytterhoeven
possible_parent_show(struct seq_file * s,struct clk_core * core,unsigned int i,char terminator)353011f6c230SStephen Boyd static void possible_parent_show(struct seq_file *s, struct clk_core *core,
353111f6c230SStephen Boyd unsigned int i, char terminator)
353292031575SPeter De Schrijver {
35332d156b78SChen-Yu Tsai struct clk_core *parent;
3534ceb87a36SAlessandro Carminati const char *name = NULL;
353592031575SPeter De Schrijver
35362d156b78SChen-Yu Tsai /*
35372d156b78SChen-Yu Tsai * Go through the following options to fetch a parent's name.
35382d156b78SChen-Yu Tsai *
35392d156b78SChen-Yu Tsai * 1. Fetch the registered parent clock and use its name
35402d156b78SChen-Yu Tsai * 2. Use the global (fallback) name if specified
35412d156b78SChen-Yu Tsai * 3. Use the local fw_name if provided
35422d156b78SChen-Yu Tsai * 4. Fetch parent clock's clock-output-name if DT index was set
35432d156b78SChen-Yu Tsai *
35442d156b78SChen-Yu Tsai * This may still fail in some cases, such as when the parent is
35452d156b78SChen-Yu Tsai * specified directly via a struct clk_hw pointer, but it isn't
35462d156b78SChen-Yu Tsai * registered (yet).
35472d156b78SChen-Yu Tsai */
35482d156b78SChen-Yu Tsai parent = clk_core_get_parent_by_index(core, i);
3549ceb87a36SAlessandro Carminati if (parent) {
35501ccc0ddfSMarkus Elfring seq_puts(s, parent->name);
3551ceb87a36SAlessandro Carminati } else if (core->parents[i].name) {
35521ccc0ddfSMarkus Elfring seq_puts(s, core->parents[i].name);
3553ceb87a36SAlessandro Carminati } else if (core->parents[i].fw_name) {
35542d156b78SChen-Yu Tsai seq_printf(s, "<%s>(fw)", core->parents[i].fw_name);
3555ceb87a36SAlessandro Carminati } else {
3556ceb87a36SAlessandro Carminati if (core->parents[i].index >= 0)
3557ceb87a36SAlessandro Carminati name = of_clk_get_parent_name(core->of_node, core->parents[i].index);
3558ceb87a36SAlessandro Carminati if (!name)
3559ceb87a36SAlessandro Carminati name = "(missing)";
3560ceb87a36SAlessandro Carminati
3561ceb87a36SAlessandro Carminati seq_puts(s, name);
3562ceb87a36SAlessandro Carminati }
356311f6c230SStephen Boyd
356411f6c230SStephen Boyd seq_putc(s, terminator);
35652d156b78SChen-Yu Tsai }
356692031575SPeter De Schrijver
possible_parents_show(struct seq_file * s,void * data)356792031575SPeter De Schrijver static int possible_parents_show(struct seq_file *s, void *data)
356892031575SPeter De Schrijver {
356992031575SPeter De Schrijver struct clk_core *core = s->private;
357092031575SPeter De Schrijver int i;
357192031575SPeter De Schrijver
357292031575SPeter De Schrijver for (i = 0; i < core->num_parents - 1; i++)
357311f6c230SStephen Boyd possible_parent_show(s, core, i, ' ');
357492031575SPeter De Schrijver
357511f6c230SStephen Boyd possible_parent_show(s, core, i, '\n');
357692031575SPeter De Schrijver
357792031575SPeter De Schrijver return 0;
357892031575SPeter De Schrijver }
3579fec0ef3fSAndy Shevchenko DEFINE_SHOW_ATTRIBUTE(possible_parents);
358092031575SPeter De Schrijver
current_parent_show(struct seq_file * s,void * data)3581e5e89247SLeonard Crestez static int current_parent_show(struct seq_file *s, void *data)
3582e5e89247SLeonard Crestez {
3583e5e89247SLeonard Crestez struct clk_core *core = s->private;
3584e5e89247SLeonard Crestez
3585e5e89247SLeonard Crestez if (core->parent)
3586e5e89247SLeonard Crestez seq_printf(s, "%s\n", core->parent->name);
3587e5e89247SLeonard Crestez
3588e5e89247SLeonard Crestez return 0;
3589e5e89247SLeonard Crestez }
3590e5e89247SLeonard Crestez DEFINE_SHOW_ATTRIBUTE(current_parent);
3591e5e89247SLeonard Crestez
3592a331659eSSam Protsenko #ifdef CLOCK_ALLOW_WRITE_DEBUGFS
current_parent_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)3593a331659eSSam Protsenko static ssize_t current_parent_write(struct file *file, const char __user *ubuf,
3594a331659eSSam Protsenko size_t count, loff_t *ppos)
3595a331659eSSam Protsenko {
3596a331659eSSam Protsenko struct seq_file *s = file->private_data;
3597a331659eSSam Protsenko struct clk_core *core = s->private;
3598a331659eSSam Protsenko struct clk_core *parent;
3599a331659eSSam Protsenko u8 idx;
3600a331659eSSam Protsenko int err;
3601a331659eSSam Protsenko
3602a331659eSSam Protsenko err = kstrtou8_from_user(ubuf, count, 0, &idx);
3603a331659eSSam Protsenko if (err < 0)
3604a331659eSSam Protsenko return err;
3605a331659eSSam Protsenko
3606a331659eSSam Protsenko parent = clk_core_get_parent_by_index(core, idx);
3607a331659eSSam Protsenko if (!parent)
3608a331659eSSam Protsenko return -ENOENT;
3609a331659eSSam Protsenko
3610a331659eSSam Protsenko clk_prepare_lock();
3611a331659eSSam Protsenko err = clk_core_set_parent_nolock(core, parent);
3612a331659eSSam Protsenko clk_prepare_unlock();
3613a331659eSSam Protsenko if (err)
3614a331659eSSam Protsenko return err;
3615a331659eSSam Protsenko
3616a331659eSSam Protsenko return count;
3617a331659eSSam Protsenko }
3618a331659eSSam Protsenko
3619a331659eSSam Protsenko static const struct file_operations current_parent_rw_fops = {
3620a331659eSSam Protsenko .open = current_parent_open,
3621a331659eSSam Protsenko .write = current_parent_write,
3622a331659eSSam Protsenko .read = seq_read,
3623a331659eSSam Protsenko .llseek = seq_lseek,
3624a331659eSSam Protsenko .release = single_release,
3625a331659eSSam Protsenko };
3626a331659eSSam Protsenko #endif
3627a331659eSSam Protsenko
clk_duty_cycle_show(struct seq_file * s,void * data)36289fba738aSJerome Brunet static int clk_duty_cycle_show(struct seq_file *s, void *data)
36299fba738aSJerome Brunet {
36309fba738aSJerome Brunet struct clk_core *core = s->private;
36319fba738aSJerome Brunet struct clk_duty *duty = &core->duty;
36329fba738aSJerome Brunet
36339fba738aSJerome Brunet seq_printf(s, "%u/%u\n", duty->num, duty->den);
36349fba738aSJerome Brunet
36359fba738aSJerome Brunet return 0;
36369fba738aSJerome Brunet }
36379fba738aSJerome Brunet DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle);
36389fba738aSJerome Brunet
clk_min_rate_show(struct seq_file * s,void * data)36391bd37a46SLeonard Crestez static int clk_min_rate_show(struct seq_file *s, void *data)
36401bd37a46SLeonard Crestez {
36411bd37a46SLeonard Crestez struct clk_core *core = s->private;
36421bd37a46SLeonard Crestez unsigned long min_rate, max_rate;
36431bd37a46SLeonard Crestez
36441bd37a46SLeonard Crestez clk_prepare_lock();
36451bd37a46SLeonard Crestez clk_core_get_boundaries(core, &min_rate, &max_rate);
36461bd37a46SLeonard Crestez clk_prepare_unlock();
36471bd37a46SLeonard Crestez seq_printf(s, "%lu\n", min_rate);
36481bd37a46SLeonard Crestez
36491bd37a46SLeonard Crestez return 0;
36501bd37a46SLeonard Crestez }
36511bd37a46SLeonard Crestez DEFINE_SHOW_ATTRIBUTE(clk_min_rate);
36521bd37a46SLeonard Crestez
clk_max_rate_show(struct seq_file * s,void * data)36531bd37a46SLeonard Crestez static int clk_max_rate_show(struct seq_file *s, void *data)
36541bd37a46SLeonard Crestez {
36551bd37a46SLeonard Crestez struct clk_core *core = s->private;
36561bd37a46SLeonard Crestez unsigned long min_rate, max_rate;
36571bd37a46SLeonard Crestez
36581bd37a46SLeonard Crestez clk_prepare_lock();
36591bd37a46SLeonard Crestez clk_core_get_boundaries(core, &min_rate, &max_rate);
36601bd37a46SLeonard Crestez clk_prepare_unlock();
36611bd37a46SLeonard Crestez seq_printf(s, "%lu\n", max_rate);
36621bd37a46SLeonard Crestez
36631bd37a46SLeonard Crestez return 0;
36641bd37a46SLeonard Crestez }
36651bd37a46SLeonard Crestez DEFINE_SHOW_ATTRIBUTE(clk_max_rate);
36661bd37a46SLeonard Crestez
clk_debug_create_one(struct clk_core * core,struct dentry * pdentry)36678a26bbbbSGreg Kroah-Hartman static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
36684dff95dcSStephen Boyd {
36698a26bbbbSGreg Kroah-Hartman struct dentry *root;
36704dff95dcSStephen Boyd
36718a26bbbbSGreg Kroah-Hartman if (!core || !pdentry)
36728a26bbbbSGreg Kroah-Hartman return;
36734dff95dcSStephen Boyd
36748a26bbbbSGreg Kroah-Hartman root = debugfs_create_dir(core->name, pdentry);
36758a26bbbbSGreg Kroah-Hartman core->dentry = root;
36764dff95dcSStephen Boyd
367737215da5SGeert Uytterhoeven debugfs_create_file("clk_rate", clk_rate_mode, root, core,
367837215da5SGeert Uytterhoeven &clk_rate_fops);
36791bd37a46SLeonard Crestez debugfs_create_file("clk_min_rate", 0444, root, core, &clk_min_rate_fops);
36801bd37a46SLeonard Crestez debugfs_create_file("clk_max_rate", 0444, root, core, &clk_max_rate_fops);
36818a26bbbbSGreg Kroah-Hartman debugfs_create_ulong("clk_accuracy", 0444, root, &core->accuracy);
36828a26bbbbSGreg Kroah-Hartman debugfs_create_u32("clk_phase", 0444, root, &core->phase);
36838a26bbbbSGreg Kroah-Hartman debugfs_create_file("clk_flags", 0444, root, core, &clk_flags_fops);
36848a26bbbbSGreg Kroah-Hartman debugfs_create_u32("clk_prepare_count", 0444, root, &core->prepare_count);
36858a26bbbbSGreg Kroah-Hartman debugfs_create_u32("clk_enable_count", 0444, root, &core->enable_count);
36868a26bbbbSGreg Kroah-Hartman debugfs_create_u32("clk_protect_count", 0444, root, &core->protect_count);
36878a26bbbbSGreg Kroah-Hartman debugfs_create_u32("clk_notifier_count", 0444, root, &core->notifier_count);
36889fba738aSJerome Brunet debugfs_create_file("clk_duty_cycle", 0444, root, core,
36899fba738aSJerome Brunet &clk_duty_cycle_fops);
369003111b10SMike Tipton #ifdef CLOCK_ALLOW_WRITE_DEBUGFS
369103111b10SMike Tipton debugfs_create_file("clk_prepare_enable", 0644, root, core,
369203111b10SMike Tipton &clk_prepare_enable_fops);
36934dff95dcSStephen Boyd
3694a331659eSSam Protsenko if (core->num_parents > 1)
3695a331659eSSam Protsenko debugfs_create_file("clk_parent", 0644, root, core,
3696a331659eSSam Protsenko ¤t_parent_rw_fops);
3697a331659eSSam Protsenko else
3698a331659eSSam Protsenko #endif
3699e5e89247SLeonard Crestez if (core->num_parents > 0)
3700e5e89247SLeonard Crestez debugfs_create_file("clk_parent", 0444, root, core,
3701e5e89247SLeonard Crestez ¤t_parent_fops);
3702e5e89247SLeonard Crestez
37038a26bbbbSGreg Kroah-Hartman if (core->num_parents > 1)
37048a26bbbbSGreg Kroah-Hartman debugfs_create_file("clk_possible_parents", 0444, root, core,
37058a26bbbbSGreg Kroah-Hartman &possible_parents_fops);
37064dff95dcSStephen Boyd
37078a26bbbbSGreg Kroah-Hartman if (core->ops->debug_init)
37088a26bbbbSGreg Kroah-Hartman core->ops->debug_init(core->hw, core->dentry);
37094dff95dcSStephen Boyd }
37104dff95dcSStephen Boyd
37114dff95dcSStephen Boyd /**
37126e5ab41bSStephen Boyd * clk_debug_register - add a clk node to the debugfs clk directory
37136e5ab41bSStephen Boyd * @core: the clk being added to the debugfs clk directory
37144dff95dcSStephen Boyd *
37156e5ab41bSStephen Boyd * Dynamically adds a clk to the debugfs clk directory if debugfs has been
37166e5ab41bSStephen Boyd * initialized. Otherwise it bails out early since the debugfs clk directory
37174dff95dcSStephen Boyd * will be created lazily by clk_debug_init as part of a late_initcall.
37184dff95dcSStephen Boyd */
clk_debug_register(struct clk_core * core)37198a26bbbbSGreg Kroah-Hartman static void clk_debug_register(struct clk_core *core)
37204dff95dcSStephen Boyd {
37214dff95dcSStephen Boyd mutex_lock(&clk_debug_lock);
37224dff95dcSStephen Boyd hlist_add_head(&core->debug_node, &clk_debug_list);
3723db3188faSStephen Boyd if (inited)
37248a26bbbbSGreg Kroah-Hartman clk_debug_create_one(core, rootdir);
37254dff95dcSStephen Boyd mutex_unlock(&clk_debug_lock);
37264dff95dcSStephen Boyd }
37274dff95dcSStephen Boyd
37284dff95dcSStephen Boyd /**
37296e5ab41bSStephen Boyd * clk_debug_unregister - remove a clk node from the debugfs clk directory
37306e5ab41bSStephen Boyd * @core: the clk being removed from the debugfs clk directory
37314dff95dcSStephen Boyd *
37326e5ab41bSStephen Boyd * Dynamically removes a clk and all its child nodes from the
37336e5ab41bSStephen Boyd * debugfs clk directory if clk->dentry points to debugfs created by
3734706d5c73SStephen Boyd * clk_debug_register in __clk_core_init.
37354dff95dcSStephen Boyd */
clk_debug_unregister(struct clk_core * core)37364dff95dcSStephen Boyd static void clk_debug_unregister(struct clk_core *core)
37374dff95dcSStephen Boyd {
37384dff95dcSStephen Boyd mutex_lock(&clk_debug_lock);
37394dff95dcSStephen Boyd hlist_del_init(&core->debug_node);
37404dff95dcSStephen Boyd debugfs_remove_recursive(core->dentry);
37414dff95dcSStephen Boyd core->dentry = NULL;
37424dff95dcSStephen Boyd mutex_unlock(&clk_debug_lock);
37434dff95dcSStephen Boyd }
37444dff95dcSStephen Boyd
37454dff95dcSStephen Boyd /**
37466e5ab41bSStephen Boyd * clk_debug_init - lazily populate the debugfs clk directory
37474dff95dcSStephen Boyd *
37486e5ab41bSStephen Boyd * clks are often initialized very early during boot before memory can be
37496e5ab41bSStephen Boyd * dynamically allocated and well before debugfs is setup. This function
37506e5ab41bSStephen Boyd * populates the debugfs clk directory once at boot-time when we know that
37516e5ab41bSStephen Boyd * debugfs is setup. It should only be called once at boot-time, all other clks
37526e5ab41bSStephen Boyd * added dynamically will be done so with clk_debug_register.
37534dff95dcSStephen Boyd */
clk_debug_init(void)37544dff95dcSStephen Boyd static int __init clk_debug_init(void)
37554dff95dcSStephen Boyd {
37564dff95dcSStephen Boyd struct clk_core *core;
37574dff95dcSStephen Boyd
3758489a7196SStephen Boyd #ifdef CLOCK_ALLOW_WRITE_DEBUGFS
3759489a7196SStephen Boyd pr_warn("\n");
3760489a7196SStephen Boyd pr_warn("********************************************************************\n");
3761489a7196SStephen Boyd pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
3762489a7196SStephen Boyd pr_warn("** **\n");
3763489a7196SStephen Boyd pr_warn("** WRITEABLE clk DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n");
3764489a7196SStephen Boyd pr_warn("** **\n");
3765489a7196SStephen Boyd pr_warn("** This means that this kernel is built to expose clk operations **\n");
3766489a7196SStephen Boyd pr_warn("** such as parent or rate setting, enabling, disabling, etc. **\n");
3767489a7196SStephen Boyd pr_warn("** to userspace, which may compromise security on your system. **\n");
3768489a7196SStephen Boyd pr_warn("** **\n");
3769489a7196SStephen Boyd pr_warn("** If you see this message and you are not debugging the **\n");
3770489a7196SStephen Boyd pr_warn("** kernel, report this immediately to your vendor! **\n");
3771489a7196SStephen Boyd pr_warn("** **\n");
3772489a7196SStephen Boyd pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
3773489a7196SStephen Boyd pr_warn("********************************************************************\n");
3774489a7196SStephen Boyd #endif
3775489a7196SStephen Boyd
37764dff95dcSStephen Boyd rootdir = debugfs_create_dir("clk", NULL);
37774dff95dcSStephen Boyd
37788a26bbbbSGreg Kroah-Hartman debugfs_create_file("clk_summary", 0444, rootdir, &all_lists,
37794dff95dcSStephen Boyd &clk_summary_fops);
37808a26bbbbSGreg Kroah-Hartman debugfs_create_file("clk_dump", 0444, rootdir, &all_lists,
37814dff95dcSStephen Boyd &clk_dump_fops);
37828a26bbbbSGreg Kroah-Hartman debugfs_create_file("clk_orphan_summary", 0444, rootdir, &orphan_list,
37838a26bbbbSGreg Kroah-Hartman &clk_summary_fops);
37848a26bbbbSGreg Kroah-Hartman debugfs_create_file("clk_orphan_dump", 0444, rootdir, &orphan_list,
37858a26bbbbSGreg Kroah-Hartman &clk_dump_fops);
37864dff95dcSStephen Boyd
37874dff95dcSStephen Boyd mutex_lock(&clk_debug_lock);
37884dff95dcSStephen Boyd hlist_for_each_entry(core, &clk_debug_list, debug_node)
37894dff95dcSStephen Boyd clk_debug_create_one(core, rootdir);
37904dff95dcSStephen Boyd
37914dff95dcSStephen Boyd inited = 1;
37924dff95dcSStephen Boyd mutex_unlock(&clk_debug_lock);
37934dff95dcSStephen Boyd
37944dff95dcSStephen Boyd return 0;
37954dff95dcSStephen Boyd }
37964dff95dcSStephen Boyd late_initcall(clk_debug_init);
37974dff95dcSStephen Boyd #else
clk_debug_register(struct clk_core * core)37988a26bbbbSGreg Kroah-Hartman static inline void clk_debug_register(struct clk_core *core) { }
clk_debug_unregister(struct clk_core * core)37994dff95dcSStephen Boyd static inline void clk_debug_unregister(struct clk_core *core)
38004dff95dcSStephen Boyd {
38014dff95dcSStephen Boyd }
38024dff95dcSStephen Boyd #endif
38034dff95dcSStephen Boyd
clk_core_reparent_orphans_nolock(void)380466d95064SJerome Brunet static void clk_core_reparent_orphans_nolock(void)
380566d95064SJerome Brunet {
380666d95064SJerome Brunet struct clk_core *orphan;
380766d95064SJerome Brunet struct hlist_node *tmp2;
380866d95064SJerome Brunet
380966d95064SJerome Brunet /*
381066d95064SJerome Brunet * walk the list of orphan clocks and reparent any that newly finds a
381166d95064SJerome Brunet * parent.
381266d95064SJerome Brunet */
381366d95064SJerome Brunet hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
381466d95064SJerome Brunet struct clk_core *parent = __clk_init_parent(orphan);
381566d95064SJerome Brunet
381666d95064SJerome Brunet /*
381766d95064SJerome Brunet * We need to use __clk_set_parent_before() and _after() to
38183378d0ccSJason Wang * properly migrate any prepare/enable count of the orphan
381966d95064SJerome Brunet * clock. This is important for CLK_IS_CRITICAL clocks, which
382066d95064SJerome Brunet * are enabled during init but might not have a parent yet.
382166d95064SJerome Brunet */
382266d95064SJerome Brunet if (parent) {
382366d95064SJerome Brunet /* update the clk tree topology */
382466d95064SJerome Brunet __clk_set_parent_before(orphan, parent);
382566d95064SJerome Brunet __clk_set_parent_after(orphan, parent, NULL);
382666d95064SJerome Brunet __clk_recalc_accuracies(orphan);
3827096f2a0cSMaxime Ripard __clk_recalc_rates(orphan, true, 0);
38285f7e2af0SMaxime Ripard
38295f7e2af0SMaxime Ripard /*
38305f7e2af0SMaxime Ripard * __clk_init_parent() will set the initial req_rate to
38315f7e2af0SMaxime Ripard * 0 if the clock doesn't have clk_ops::recalc_rate and
38325f7e2af0SMaxime Ripard * is an orphan when it's registered.
38335f7e2af0SMaxime Ripard *
38345f7e2af0SMaxime Ripard * 'req_rate' is used by clk_set_rate_range() and
38355f7e2af0SMaxime Ripard * clk_put() to trigger a clk_set_rate() call whenever
38365f7e2af0SMaxime Ripard * the boundaries are modified. Let's make sure
38375f7e2af0SMaxime Ripard * 'req_rate' is set to something non-zero so that
38385f7e2af0SMaxime Ripard * clk_set_rate_range() doesn't drop the frequency.
38395f7e2af0SMaxime Ripard */
38405f7e2af0SMaxime Ripard orphan->req_rate = orphan->rate;
384166d95064SJerome Brunet }
384266d95064SJerome Brunet }
384366d95064SJerome Brunet }
384466d95064SJerome Brunet
38453d3801efSMichael Turquette /**
3846be45ebf2SMasahiro Yamada * __clk_core_init - initialize the data structures in a struct clk_core
3847d35c80c2SMasahiro Yamada * @core: clk_core being initialized
3848b2476490SMike Turquette *
3849035a61c3STomeu Vizoso * Initializes the lists in struct clk_core, queries the hardware for the
3850b2476490SMike Turquette * parent and rate and sets them both.
3851b2476490SMike Turquette */
__clk_core_init(struct clk_core * core)3852be45ebf2SMasahiro Yamada static int __clk_core_init(struct clk_core *core)
3853b2476490SMike Turquette {
3854fc0c209cSStephen Boyd int ret;
3855768a5d4fSStephen Boyd struct clk_core *parent;
38561c8e6004STomeu Vizoso unsigned long rate;
3857c3944ec8SMaxime Ripard int phase;
3858b2476490SMike Turquette
3859eab89f69SMike Turquette clk_prepare_lock();
3860b2476490SMike Turquette
386154baf56eSMike Tipton /*
386254baf56eSMike Tipton * Set hw->core after grabbing the prepare_lock to synchronize with
386354baf56eSMike Tipton * callers of clk_core_fill_parent_index() where we treat hw->core
386454baf56eSMike Tipton * being NULL as the clk not being registered yet. This is crucial so
386554baf56eSMike Tipton * that clks aren't parented until their parent is fully registered.
386654baf56eSMike Tipton */
386754baf56eSMike Tipton core->hw->core = core;
386854baf56eSMike Tipton
38699a34b453SMarek Szyprowski ret = clk_pm_runtime_get(core);
38709a34b453SMarek Szyprowski if (ret)
38719a34b453SMarek Szyprowski goto unlock;
38729a34b453SMarek Szyprowski
3873b2476490SMike Turquette /* check to see if a clock with this name is already registered */
3874d6968fcaSStephen Boyd if (clk_core_lookup(core->name)) {
3875d1302a36SMike Turquette pr_debug("%s: clk %s already initialized\n",
3876d6968fcaSStephen Boyd __func__, core->name);
3877d1302a36SMike Turquette ret = -EEXIST;
3878b2476490SMike Turquette goto out;
3879d1302a36SMike Turquette }
3880b2476490SMike Turquette
38815fb94e9cSMauro Carvalho Chehab /* check that clk_ops are sane. See Documentation/driver-api/clk.rst */
3882d6968fcaSStephen Boyd if (core->ops->set_rate &&
3883d6968fcaSStephen Boyd !((core->ops->round_rate || core->ops->determine_rate) &&
3884d6968fcaSStephen Boyd core->ops->recalc_rate)) {
3885c44fccb5SMasahiro Yamada pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
3886d6968fcaSStephen Boyd __func__, core->name);
3887d1302a36SMike Turquette ret = -EINVAL;
3888d4d7e3ddSMike Turquette goto out;
3889d4d7e3ddSMike Turquette }
3890d4d7e3ddSMike Turquette
3891d6968fcaSStephen Boyd if (core->ops->set_parent && !core->ops->get_parent) {
3892c44fccb5SMasahiro Yamada pr_err("%s: %s must implement .get_parent & .set_parent\n",
3893d6968fcaSStephen Boyd __func__, core->name);
3894d1302a36SMike Turquette ret = -EINVAL;
3895d4d7e3ddSMike Turquette goto out;
3896d4d7e3ddSMike Turquette }
3897d4d7e3ddSMike Turquette
3898326cc42fSMaxime Ripard if (core->ops->set_parent && !core->ops->determine_rate) {
3899326cc42fSMaxime Ripard pr_err("%s: %s must implement .set_parent & .determine_rate\n",
3900326cc42fSMaxime Ripard __func__, core->name);
3901326cc42fSMaxime Ripard ret = -EINVAL;
3902326cc42fSMaxime Ripard goto out;
3903326cc42fSMaxime Ripard }
3904326cc42fSMaxime Ripard
39053c8e77ddSMasahiro Yamada if (core->num_parents > 1 && !core->ops->get_parent) {
39063c8e77ddSMasahiro Yamada pr_err("%s: %s must implement .get_parent as it has multi parents\n",
39073c8e77ddSMasahiro Yamada __func__, core->name);
39083c8e77ddSMasahiro Yamada ret = -EINVAL;
39093c8e77ddSMasahiro Yamada goto out;
39103c8e77ddSMasahiro Yamada }
39113c8e77ddSMasahiro Yamada
3912d6968fcaSStephen Boyd if (core->ops->set_rate_and_parent &&
3913d6968fcaSStephen Boyd !(core->ops->set_parent && core->ops->set_rate)) {
3914c44fccb5SMasahiro Yamada pr_err("%s: %s must implement .set_parent & .set_rate\n",
3915d6968fcaSStephen Boyd __func__, core->name);
39163fa2252bSStephen Boyd ret = -EINVAL;
39173fa2252bSStephen Boyd goto out;
39183fa2252bSStephen Boyd }
39193fa2252bSStephen Boyd
3920f6fa75caSJerome Brunet /*
3921f6fa75caSJerome Brunet * optional platform-specific magic
3922f6fa75caSJerome Brunet *
3923f6fa75caSJerome Brunet * The .init callback is not used by any of the basic clock types, but
392489d079dcSJerome Brunet * exists for weird hardware that must perform initialization magic for
392589d079dcSJerome Brunet * CCF to get an accurate view of clock for any other callbacks. It may
392689d079dcSJerome Brunet * also be used needs to perform dynamic allocations. Such allocation
392789d079dcSJerome Brunet * must be freed in the terminate() callback.
392889d079dcSJerome Brunet * This callback shall not be used to initialize the parameters state,
392989d079dcSJerome Brunet * such as rate, parent, etc ...
3930f6fa75caSJerome Brunet *
3931f6fa75caSJerome Brunet * If it exist, this callback should called before any other callback of
3932f6fa75caSJerome Brunet * the clock
3933f6fa75caSJerome Brunet */
393489d079dcSJerome Brunet if (core->ops->init) {
393589d079dcSJerome Brunet ret = core->ops->init(core->hw);
393689d079dcSJerome Brunet if (ret)
393789d079dcSJerome Brunet goto out;
393889d079dcSJerome Brunet }
3939f6fa75caSJerome Brunet
3940768a5d4fSStephen Boyd parent = core->parent = __clk_init_parent(core);
3941b2476490SMike Turquette
3942b2476490SMike Turquette /*
3943706d5c73SStephen Boyd * Populate core->parent if parent has already been clk_core_init'd. If
3944706d5c73SStephen Boyd * parent has not yet been clk_core_init'd then place clk in the orphan
394547b0eeb3SStephen Boyd * list. If clk doesn't have any parents then place it in the root
3946b2476490SMike Turquette * clk list.
3947b2476490SMike Turquette *
3948b2476490SMike Turquette * Every time a new clk is clk_init'd then we walk the list of orphan
3949b2476490SMike Turquette * clocks and re-parent any that are children of the clock currently
3950b2476490SMike Turquette * being clk_init'd.
3951b2476490SMike Turquette */
3952768a5d4fSStephen Boyd if (parent) {
3953768a5d4fSStephen Boyd hlist_add_head(&core->child_node, &parent->children);
3954768a5d4fSStephen Boyd core->orphan = parent->orphan;
395547b0eeb3SStephen Boyd } else if (!core->num_parents) {
3956d6968fcaSStephen Boyd hlist_add_head(&core->child_node, &clk_root_list);
3957e6500344SHeiko Stuebner core->orphan = false;
3958e6500344SHeiko Stuebner } else {
3959d6968fcaSStephen Boyd hlist_add_head(&core->child_node, &clk_orphan_list);
3960e6500344SHeiko Stuebner core->orphan = true;
3961e6500344SHeiko Stuebner }
3962b2476490SMike Turquette
3963b2476490SMike Turquette /*
39645279fc40SBoris BREZILLON * Set clk's accuracy. The preferred method is to use
39655279fc40SBoris BREZILLON * .recalc_accuracy. For simple clocks and lazy developers the default
39665279fc40SBoris BREZILLON * fallback is to use the parent's accuracy. If a clock doesn't have a
39675279fc40SBoris BREZILLON * parent (or is orphaned) then accuracy is set to zero (perfect
39685279fc40SBoris BREZILLON * clock).
39695279fc40SBoris BREZILLON */
3970d6968fcaSStephen Boyd if (core->ops->recalc_accuracy)
3971d6968fcaSStephen Boyd core->accuracy = core->ops->recalc_accuracy(core->hw,
39720daa376dSStephen Boyd clk_core_get_accuracy_no_lock(parent));
3973768a5d4fSStephen Boyd else if (parent)
3974768a5d4fSStephen Boyd core->accuracy = parent->accuracy;
39755279fc40SBoris BREZILLON else
3976d6968fcaSStephen Boyd core->accuracy = 0;
39775279fc40SBoris BREZILLON
39785279fc40SBoris BREZILLON /*
3979f21cf9c7SStephen Boyd * Set clk's phase by clk_core_get_phase() caching the phase.
39809824cf73SMaxime Ripard * Since a phase is by definition relative to its parent, just
39819824cf73SMaxime Ripard * query the current clock phase, or just assume it's in phase.
39829824cf73SMaxime Ripard */
3983c3944ec8SMaxime Ripard phase = clk_core_get_phase(core);
3984c3944ec8SMaxime Ripard if (phase < 0) {
3985c3944ec8SMaxime Ripard ret = phase;
398627608786SStephen Boyd pr_warn("%s: Failed to get phase for clk '%s'\n", __func__,
398727608786SStephen Boyd core->name);
398827608786SStephen Boyd goto out;
398927608786SStephen Boyd }
39909824cf73SMaxime Ripard
39919824cf73SMaxime Ripard /*
39929fba738aSJerome Brunet * Set clk's duty cycle.
39939fba738aSJerome Brunet */
39949fba738aSJerome Brunet clk_core_update_duty_cycle_nolock(core);
39959fba738aSJerome Brunet
39969fba738aSJerome Brunet /*
3997b2476490SMike Turquette * Set clk's rate. The preferred method is to use .recalc_rate. For
3998b2476490SMike Turquette * simple clocks and lazy developers the default fallback is to use the
3999b2476490SMike Turquette * parent's rate. If a clock doesn't have a parent (or is orphaned)
4000b2476490SMike Turquette * then rate is set to zero.
4001b2476490SMike Turquette */
4002d6968fcaSStephen Boyd if (core->ops->recalc_rate)
4003d6968fcaSStephen Boyd rate = core->ops->recalc_rate(core->hw,
4004768a5d4fSStephen Boyd clk_core_get_rate_nolock(parent));
4005768a5d4fSStephen Boyd else if (parent)
4006768a5d4fSStephen Boyd rate = parent->rate;
4007b2476490SMike Turquette else
40081c8e6004STomeu Vizoso rate = 0;
4009d6968fcaSStephen Boyd core->rate = core->req_rate = rate;
4010b2476490SMike Turquette
4011b2476490SMike Turquette /*
401299652a46SJerome Brunet * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
401399652a46SJerome Brunet * don't get accidentally disabled when walking the orphan tree and
401499652a46SJerome Brunet * reparenting clocks
401599652a46SJerome Brunet */
401699652a46SJerome Brunet if (core->flags & CLK_IS_CRITICAL) {
401712ead774SGuenter Roeck ret = clk_core_prepare(core);
40182d269992SStephen Boyd if (ret) {
40192d269992SStephen Boyd pr_warn("%s: critical clk '%s' failed to prepare\n",
40202d269992SStephen Boyd __func__, core->name);
402112ead774SGuenter Roeck goto out;
40222d269992SStephen Boyd }
402399652a46SJerome Brunet
402435a79631SRasmus Villemoes ret = clk_core_enable_lock(core);
402512ead774SGuenter Roeck if (ret) {
40262d269992SStephen Boyd pr_warn("%s: critical clk '%s' failed to enable\n",
40272d269992SStephen Boyd __func__, core->name);
402812ead774SGuenter Roeck clk_core_unprepare(core);
402912ead774SGuenter Roeck goto out;
403012ead774SGuenter Roeck }
403199652a46SJerome Brunet }
403299652a46SJerome Brunet
403366d95064SJerome Brunet clk_core_reparent_orphans_nolock();
4034b2476490SMike Turquette out:
40359a34b453SMarek Szyprowski clk_pm_runtime_put(core);
40369a34b453SMarek Szyprowski unlock:
403754baf56eSMike Tipton if (ret) {
4038018d4671SMarc Zyngier hlist_del_init(&core->child_node);
403954baf56eSMike Tipton core->hw->core = NULL;
404054baf56eSMike Tipton }
4041018d4671SMarc Zyngier
4042eab89f69SMike Turquette clk_prepare_unlock();
4043b2476490SMike Turquette
404489f7e9deSStephen Boyd if (!ret)
4045d6968fcaSStephen Boyd clk_debug_register(core);
404689f7e9deSStephen Boyd
4047d1302a36SMike Turquette return ret;
4048b2476490SMike Turquette }
4049b2476490SMike Turquette
40501df4046aSStephen Boyd /**
40511df4046aSStephen Boyd * clk_core_link_consumer - Add a clk consumer to the list of consumers in a clk_core
40521df4046aSStephen Boyd * @core: clk to add consumer to
40531df4046aSStephen Boyd * @clk: consumer to link to a clk
40541df4046aSStephen Boyd */
clk_core_link_consumer(struct clk_core * core,struct clk * clk)40551df4046aSStephen Boyd static void clk_core_link_consumer(struct clk_core *core, struct clk *clk)
40561df4046aSStephen Boyd {
40571df4046aSStephen Boyd clk_prepare_lock();
40581df4046aSStephen Boyd hlist_add_head(&clk->clks_node, &core->clks);
40591df4046aSStephen Boyd clk_prepare_unlock();
40601df4046aSStephen Boyd }
40611df4046aSStephen Boyd
40621df4046aSStephen Boyd /**
40631df4046aSStephen Boyd * clk_core_unlink_consumer - Remove a clk consumer from the list of consumers in a clk_core
40641df4046aSStephen Boyd * @clk: consumer to unlink
40651df4046aSStephen Boyd */
clk_core_unlink_consumer(struct clk * clk)40661df4046aSStephen Boyd static void clk_core_unlink_consumer(struct clk *clk)
40671df4046aSStephen Boyd {
40681df4046aSStephen Boyd lockdep_assert_held(&prepare_lock);
40691df4046aSStephen Boyd hlist_del(&clk->clks_node);
40701df4046aSStephen Boyd }
40711df4046aSStephen Boyd
40721df4046aSStephen Boyd /**
40731df4046aSStephen Boyd * alloc_clk - Allocate a clk consumer, but leave it unlinked to the clk_core
40741df4046aSStephen Boyd * @core: clk to allocate a consumer for
40751df4046aSStephen Boyd * @dev_id: string describing device name
40761df4046aSStephen Boyd * @con_id: connection ID string on device
40771df4046aSStephen Boyd *
40781df4046aSStephen Boyd * Returns: clk consumer left unlinked from the consumer list
40791df4046aSStephen Boyd */
alloc_clk(struct clk_core * core,const char * dev_id,const char * con_id)40801df4046aSStephen Boyd static struct clk *alloc_clk(struct clk_core *core, const char *dev_id,
4081035a61c3STomeu Vizoso const char *con_id)
40820197b3eaSSaravana Kannan {
40830197b3eaSSaravana Kannan struct clk *clk;
40840197b3eaSSaravana Kannan
4085035a61c3STomeu Vizoso clk = kzalloc(sizeof(*clk), GFP_KERNEL);
4086035a61c3STomeu Vizoso if (!clk)
4087035a61c3STomeu Vizoso return ERR_PTR(-ENOMEM);
4088035a61c3STomeu Vizoso
40891df4046aSStephen Boyd clk->core = core;
4090035a61c3STomeu Vizoso clk->dev_id = dev_id;
4091253160a8SLeonard Crestez clk->con_id = kstrdup_const(con_id, GFP_KERNEL);
40921c8e6004STomeu Vizoso clk->max_rate = ULONG_MAX;
40931c8e6004STomeu Vizoso
40940197b3eaSSaravana Kannan return clk;
40950197b3eaSSaravana Kannan }
4096035a61c3STomeu Vizoso
40971df4046aSStephen Boyd /**
40981df4046aSStephen Boyd * free_clk - Free a clk consumer
40991df4046aSStephen Boyd * @clk: clk consumer to free
41001df4046aSStephen Boyd *
41011df4046aSStephen Boyd * Note, this assumes the clk has been unlinked from the clk_core consumer
41021df4046aSStephen Boyd * list.
41031df4046aSStephen Boyd */
free_clk(struct clk * clk)41041df4046aSStephen Boyd static void free_clk(struct clk *clk)
41051c8e6004STomeu Vizoso {
4106253160a8SLeonard Crestez kfree_const(clk->con_id);
41071c8e6004STomeu Vizoso kfree(clk);
41081c8e6004STomeu Vizoso }
41090197b3eaSSaravana Kannan
4110293ba3b4SStephen Boyd /**
41111df4046aSStephen Boyd * clk_hw_create_clk: Allocate and link a clk consumer to a clk_core given
41121df4046aSStephen Boyd * a clk_hw
4113efa85048SStephen Boyd * @dev: clk consumer device
41141df4046aSStephen Boyd * @hw: clk_hw associated with the clk being consumed
41151df4046aSStephen Boyd * @dev_id: string describing device name
41161df4046aSStephen Boyd * @con_id: connection ID string on device
41171df4046aSStephen Boyd *
41181df4046aSStephen Boyd * This is the main function used to create a clk pointer for use by clk
41191df4046aSStephen Boyd * consumers. It connects a consumer to the clk_core and clk_hw structures
41201df4046aSStephen Boyd * used by the framework and clk provider respectively.
41211df4046aSStephen Boyd */
clk_hw_create_clk(struct device * dev,struct clk_hw * hw,const char * dev_id,const char * con_id)4122efa85048SStephen Boyd struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
41231df4046aSStephen Boyd const char *dev_id, const char *con_id)
41241df4046aSStephen Boyd {
41251df4046aSStephen Boyd struct clk *clk;
41261df4046aSStephen Boyd struct clk_core *core;
41271df4046aSStephen Boyd
41281df4046aSStephen Boyd /* This is to allow this function to be chained to others */
41291df4046aSStephen Boyd if (IS_ERR_OR_NULL(hw))
41301df4046aSStephen Boyd return ERR_CAST(hw);
41311df4046aSStephen Boyd
41321df4046aSStephen Boyd core = hw->core;
41331df4046aSStephen Boyd clk = alloc_clk(core, dev_id, con_id);
41341df4046aSStephen Boyd if (IS_ERR(clk))
41351df4046aSStephen Boyd return clk;
4136efa85048SStephen Boyd clk->dev = dev;
41371df4046aSStephen Boyd
41381df4046aSStephen Boyd if (!try_module_get(core->owner)) {
41391df4046aSStephen Boyd free_clk(clk);
41401df4046aSStephen Boyd return ERR_PTR(-ENOENT);
41411df4046aSStephen Boyd }
41421df4046aSStephen Boyd
41431df4046aSStephen Boyd kref_get(&core->ref);
41441df4046aSStephen Boyd clk_core_link_consumer(core, clk);
41451df4046aSStephen Boyd
41461df4046aSStephen Boyd return clk;
41471df4046aSStephen Boyd }
41481df4046aSStephen Boyd
414930d6f8c1SJerome Brunet /**
415030d6f8c1SJerome Brunet * clk_hw_get_clk - get clk consumer given an clk_hw
415130d6f8c1SJerome Brunet * @hw: clk_hw associated with the clk being consumed
415230d6f8c1SJerome Brunet * @con_id: connection ID string on device
415330d6f8c1SJerome Brunet *
415430d6f8c1SJerome Brunet * Returns: new clk consumer
415530d6f8c1SJerome Brunet * This is the function to be used by providers which need
415630d6f8c1SJerome Brunet * to get a consumer clk and act on the clock element
415730d6f8c1SJerome Brunet * Calls to this function must be balanced with calls clk_put()
415830d6f8c1SJerome Brunet */
clk_hw_get_clk(struct clk_hw * hw,const char * con_id)415930d6f8c1SJerome Brunet struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id)
416030d6f8c1SJerome Brunet {
416130d6f8c1SJerome Brunet struct device *dev = hw->core->dev;
41620c1b56dfSMaxime Ripard const char *name = dev ? dev_name(dev) : NULL;
416330d6f8c1SJerome Brunet
41640c1b56dfSMaxime Ripard return clk_hw_create_clk(dev, hw, name, con_id);
416530d6f8c1SJerome Brunet }
416630d6f8c1SJerome Brunet EXPORT_SYMBOL(clk_hw_get_clk);
416730d6f8c1SJerome Brunet
clk_cpy_name(const char ** dst_p,const char * src,bool must_exist)4168fc0c209cSStephen Boyd static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist)
4169b2476490SMike Turquette {
4170fc0c209cSStephen Boyd const char *dst;
4171fc0c209cSStephen Boyd
4172fc0c209cSStephen Boyd if (!src) {
4173fc0c209cSStephen Boyd if (must_exist)
4174fc0c209cSStephen Boyd return -EINVAL;
4175fc0c209cSStephen Boyd return 0;
4176fc0c209cSStephen Boyd }
4177fc0c209cSStephen Boyd
4178fc0c209cSStephen Boyd *dst_p = dst = kstrdup_const(src, GFP_KERNEL);
4179fc0c209cSStephen Boyd if (!dst)
4180fc0c209cSStephen Boyd return -ENOMEM;
4181fc0c209cSStephen Boyd
4182fc0c209cSStephen Boyd return 0;
4183fc0c209cSStephen Boyd }
4184fc0c209cSStephen Boyd
clk_core_populate_parent_map(struct clk_core * core,const struct clk_init_data * init)41850214f33cSStephen Boyd static int clk_core_populate_parent_map(struct clk_core *core,
41860214f33cSStephen Boyd const struct clk_init_data *init)
4187fc0c209cSStephen Boyd {
4188fc0c209cSStephen Boyd u8 num_parents = init->num_parents;
4189fc0c209cSStephen Boyd const char * const *parent_names = init->parent_names;
4190fc0c209cSStephen Boyd const struct clk_hw **parent_hws = init->parent_hws;
4191fc0c209cSStephen Boyd const struct clk_parent_data *parent_data = init->parent_data;
4192fc0c209cSStephen Boyd int i, ret = 0;
4193fc0c209cSStephen Boyd struct clk_parent_map *parents, *parent;
4194fc0c209cSStephen Boyd
4195fc0c209cSStephen Boyd if (!num_parents)
4196fc0c209cSStephen Boyd return 0;
4197fc0c209cSStephen Boyd
4198fc0c209cSStephen Boyd /*
4199fc0c209cSStephen Boyd * Avoid unnecessary string look-ups of clk_core's possible parents by
4200fc0c209cSStephen Boyd * having a cache of names/clk_hw pointers to clk_core pointers.
4201fc0c209cSStephen Boyd */
4202fc0c209cSStephen Boyd parents = kcalloc(num_parents, sizeof(*parents), GFP_KERNEL);
4203fc0c209cSStephen Boyd core->parents = parents;
4204fc0c209cSStephen Boyd if (!parents)
4205fc0c209cSStephen Boyd return -ENOMEM;
4206fc0c209cSStephen Boyd
4207fc0c209cSStephen Boyd /* Copy everything over because it might be __initdata */
4208fc0c209cSStephen Boyd for (i = 0, parent = parents; i < num_parents; i++, parent++) {
4209601b6e93SStephen Boyd parent->index = -1;
4210fc0c209cSStephen Boyd if (parent_names) {
4211fc0c209cSStephen Boyd /* throw a WARN if any entries are NULL */
4212fc0c209cSStephen Boyd WARN(!parent_names[i],
4213fc0c209cSStephen Boyd "%s: invalid NULL in %s's .parent_names\n",
4214fc0c209cSStephen Boyd __func__, core->name);
4215fc0c209cSStephen Boyd ret = clk_cpy_name(&parent->name, parent_names[i],
4216fc0c209cSStephen Boyd true);
4217fc0c209cSStephen Boyd } else if (parent_data) {
4218fc0c209cSStephen Boyd parent->hw = parent_data[i].hw;
4219601b6e93SStephen Boyd parent->index = parent_data[i].index;
4220fc0c209cSStephen Boyd ret = clk_cpy_name(&parent->fw_name,
4221fc0c209cSStephen Boyd parent_data[i].fw_name, false);
4222fc0c209cSStephen Boyd if (!ret)
4223fc0c209cSStephen Boyd ret = clk_cpy_name(&parent->name,
4224fc0c209cSStephen Boyd parent_data[i].name,
4225fc0c209cSStephen Boyd false);
4226fc0c209cSStephen Boyd } else if (parent_hws) {
4227fc0c209cSStephen Boyd parent->hw = parent_hws[i];
4228fc0c209cSStephen Boyd } else {
4229fc0c209cSStephen Boyd ret = -EINVAL;
4230fc0c209cSStephen Boyd WARN(1, "Must specify parents if num_parents > 0\n");
4231fc0c209cSStephen Boyd }
4232fc0c209cSStephen Boyd
4233fc0c209cSStephen Boyd if (ret) {
4234fc0c209cSStephen Boyd do {
4235fc0c209cSStephen Boyd kfree_const(parents[i].name);
4236fc0c209cSStephen Boyd kfree_const(parents[i].fw_name);
4237fc0c209cSStephen Boyd } while (--i >= 0);
4238fc0c209cSStephen Boyd kfree(parents);
4239fc0c209cSStephen Boyd
4240fc0c209cSStephen Boyd return ret;
4241fc0c209cSStephen Boyd }
4242fc0c209cSStephen Boyd }
4243fc0c209cSStephen Boyd
4244fc0c209cSStephen Boyd return 0;
4245fc0c209cSStephen Boyd }
4246fc0c209cSStephen Boyd
clk_core_free_parent_map(struct clk_core * core)4247fc0c209cSStephen Boyd static void clk_core_free_parent_map(struct clk_core *core)
4248fc0c209cSStephen Boyd {
4249fc0c209cSStephen Boyd int i = core->num_parents;
4250fc0c209cSStephen Boyd
4251fc0c209cSStephen Boyd if (!core->num_parents)
4252fc0c209cSStephen Boyd return;
4253fc0c209cSStephen Boyd
4254fc0c209cSStephen Boyd while (--i >= 0) {
4255fc0c209cSStephen Boyd kfree_const(core->parents[i].name);
4256fc0c209cSStephen Boyd kfree_const(core->parents[i].fw_name);
4257fc0c209cSStephen Boyd }
4258fc0c209cSStephen Boyd
4259fc0c209cSStephen Boyd kfree(core->parents);
4260fc0c209cSStephen Boyd }
4261fc0c209cSStephen Boyd
4262731ffd8dSStephen Boyd /* Free memory allocated for a struct clk_core */
__clk_release(struct kref * ref)4263731ffd8dSStephen Boyd static void __clk_release(struct kref *ref)
4264731ffd8dSStephen Boyd {
4265731ffd8dSStephen Boyd struct clk_core *core = container_of(ref, struct clk_core, ref);
4266731ffd8dSStephen Boyd
426760ff482cSStephen Boyd if (core->rpm_enabled) {
426860ff482cSStephen Boyd mutex_lock(&clk_rpm_list_lock);
426960ff482cSStephen Boyd hlist_del(&core->rpm_node);
427060ff482cSStephen Boyd mutex_unlock(&clk_rpm_list_lock);
427160ff482cSStephen Boyd }
427260ff482cSStephen Boyd
4273731ffd8dSStephen Boyd clk_core_free_parent_map(core);
4274731ffd8dSStephen Boyd kfree_const(core->name);
4275731ffd8dSStephen Boyd kfree(core);
4276731ffd8dSStephen Boyd }
4277731ffd8dSStephen Boyd
427889a5ddccSStephen Boyd static struct clk *
__clk_register(struct device * dev,struct device_node * np,struct clk_hw * hw)427989a5ddccSStephen Boyd __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
4280b2476490SMike Turquette {
4281fc0c209cSStephen Boyd int ret;
4282d6968fcaSStephen Boyd struct clk_core *core;
42830214f33cSStephen Boyd const struct clk_init_data *init = hw->init;
42840214f33cSStephen Boyd
42850214f33cSStephen Boyd /*
42860214f33cSStephen Boyd * The init data is not supposed to be used outside of registration path.
42870214f33cSStephen Boyd * Set it to NULL so that provider drivers can't use it either and so that
42880214f33cSStephen Boyd * we catch use of hw->init early on in the core.
42890214f33cSStephen Boyd */
42900214f33cSStephen Boyd hw->init = NULL;
4291293ba3b4SStephen Boyd
4292d6968fcaSStephen Boyd core = kzalloc(sizeof(*core), GFP_KERNEL);
4293d6968fcaSStephen Boyd if (!core) {
4294293ba3b4SStephen Boyd ret = -ENOMEM;
4295293ba3b4SStephen Boyd goto fail_out;
4296293ba3b4SStephen Boyd }
4297b2476490SMike Turquette
4298731ffd8dSStephen Boyd kref_init(&core->ref);
4299731ffd8dSStephen Boyd
43000214f33cSStephen Boyd core->name = kstrdup_const(init->name, GFP_KERNEL);
4301d6968fcaSStephen Boyd if (!core->name) {
43020197b3eaSSaravana Kannan ret = -ENOMEM;
43030197b3eaSSaravana Kannan goto fail_name;
43040197b3eaSSaravana Kannan }
430529fd2a34SJerome Brunet
43060214f33cSStephen Boyd if (WARN_ON(!init->ops)) {
430729fd2a34SJerome Brunet ret = -EINVAL;
430829fd2a34SJerome Brunet goto fail_ops;
430929fd2a34SJerome Brunet }
43100214f33cSStephen Boyd core->ops = init->ops;
431129fd2a34SJerome Brunet
43129a34b453SMarek Szyprowski core->dev = dev;
431360ff482cSStephen Boyd clk_pm_runtime_init(core);
431489a5ddccSStephen Boyd core->of_node = np;
4315ac2df527SSylwester Nawrocki if (dev && dev->driver)
4316d6968fcaSStephen Boyd core->owner = dev->driver->owner;
4317d6968fcaSStephen Boyd core->hw = hw;
43180214f33cSStephen Boyd core->flags = init->flags;
43190214f33cSStephen Boyd core->num_parents = init->num_parents;
43209783c0d9SStephen Boyd core->min_rate = 0;
43219783c0d9SStephen Boyd core->max_rate = ULONG_MAX;
4322b2476490SMike Turquette
43230214f33cSStephen Boyd ret = clk_core_populate_parent_map(core, init);
4324fc0c209cSStephen Boyd if (ret)
4325176d1169SMasahiro Yamada goto fail_parents;
4326176d1169SMasahiro Yamada
4327d6968fcaSStephen Boyd INIT_HLIST_HEAD(&core->clks);
43281c8e6004STomeu Vizoso
43291df4046aSStephen Boyd /*
43301df4046aSStephen Boyd * Don't call clk_hw_create_clk() here because that would pin the
43311df4046aSStephen Boyd * provider module to itself and prevent it from ever being removed.
43321df4046aSStephen Boyd */
43331df4046aSStephen Boyd hw->clk = alloc_clk(core, NULL, NULL);
4334035a61c3STomeu Vizoso if (IS_ERR(hw->clk)) {
4335035a61c3STomeu Vizoso ret = PTR_ERR(hw->clk);
4336fc0c209cSStephen Boyd goto fail_create_clk;
4337035a61c3STomeu Vizoso }
4338d1302a36SMike Turquette
433954baf56eSMike Tipton clk_core_link_consumer(core, hw->clk);
43401df4046aSStephen Boyd
4341be45ebf2SMasahiro Yamada ret = __clk_core_init(core);
4342b2476490SMike Turquette if (!ret)
4343035a61c3STomeu Vizoso return hw->clk;
4344035a61c3STomeu Vizoso
43451df4046aSStephen Boyd clk_prepare_lock();
43461df4046aSStephen Boyd clk_core_unlink_consumer(hw->clk);
43471df4046aSStephen Boyd clk_prepare_unlock();
43481df4046aSStephen Boyd
43491df4046aSStephen Boyd free_clk(hw->clk);
4350035a61c3STomeu Vizoso hw->clk = NULL;
4351d1302a36SMike Turquette
4352fc0c209cSStephen Boyd fail_create_clk:
4353176d1169SMasahiro Yamada fail_parents:
435429fd2a34SJerome Brunet fail_ops:
43550197b3eaSSaravana Kannan fail_name:
4356731ffd8dSStephen Boyd kref_put(&core->ref, __clk_release);
4357d1302a36SMike Turquette fail_out:
4358d1302a36SMike Turquette return ERR_PTR(ret);
4359b2476490SMike Turquette }
4360fceaa7d8SStephen Boyd
4361fceaa7d8SStephen Boyd /**
43629011f926SStephen Boyd * dev_or_parent_of_node() - Get device node of @dev or @dev's parent
43639011f926SStephen Boyd * @dev: Device to get device node of
43649011f926SStephen Boyd *
43659011f926SStephen Boyd * Return: device node pointer of @dev, or the device node pointer of
43669011f926SStephen Boyd * @dev->parent if dev doesn't have a device node, or NULL if neither
43679011f926SStephen Boyd * @dev or @dev->parent have a device node.
43689011f926SStephen Boyd */
dev_or_parent_of_node(struct device * dev)43699011f926SStephen Boyd static struct device_node *dev_or_parent_of_node(struct device *dev)
43709011f926SStephen Boyd {
43719011f926SStephen Boyd struct device_node *np;
43729011f926SStephen Boyd
43739011f926SStephen Boyd if (!dev)
43749011f926SStephen Boyd return NULL;
43759011f926SStephen Boyd
43769011f926SStephen Boyd np = dev_of_node(dev);
43779011f926SStephen Boyd if (!np)
43789011f926SStephen Boyd np = dev_of_node(dev->parent);
43799011f926SStephen Boyd
43809011f926SStephen Boyd return np;
43819011f926SStephen Boyd }
43829011f926SStephen Boyd
43839011f926SStephen Boyd /**
4384fceaa7d8SStephen Boyd * clk_register - allocate a new clock, register it and return an opaque cookie
4385fceaa7d8SStephen Boyd * @dev: device that is registering this clock
4386fceaa7d8SStephen Boyd * @hw: link to hardware-specific clock data
4387fceaa7d8SStephen Boyd *
4388c1157f60SStephen Boyd * clk_register is the *deprecated* interface for populating the clock tree with
4389c1157f60SStephen Boyd * new clock nodes. Use clk_hw_register() instead.
4390c1157f60SStephen Boyd *
4391c1157f60SStephen Boyd * Returns: a pointer to the newly allocated struct clk which
4392fceaa7d8SStephen Boyd * cannot be dereferenced by driver code but may be used in conjunction with the
4393fceaa7d8SStephen Boyd * rest of the clock API. In the event of an error clk_register will return an
4394fceaa7d8SStephen Boyd * error code; drivers must test for an error code after calling clk_register.
4395fceaa7d8SStephen Boyd */
clk_register(struct device * dev,struct clk_hw * hw)4396fceaa7d8SStephen Boyd struct clk *clk_register(struct device *dev, struct clk_hw *hw)
4397fceaa7d8SStephen Boyd {
43989011f926SStephen Boyd return __clk_register(dev, dev_or_parent_of_node(dev), hw);
4399fceaa7d8SStephen Boyd }
4400b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_register);
4401b2476490SMike Turquette
44024143804cSStephen Boyd /**
44034143804cSStephen Boyd * clk_hw_register - register a clk_hw and return an error code
44044143804cSStephen Boyd * @dev: device that is registering this clock
44054143804cSStephen Boyd * @hw: link to hardware-specific clock data
44064143804cSStephen Boyd *
44074143804cSStephen Boyd * clk_hw_register is the primary interface for populating the clock tree with
44084143804cSStephen Boyd * new clock nodes. It returns an integer equal to zero indicating success or
44094143804cSStephen Boyd * less than zero indicating failure. Drivers must test for an error code after
44104143804cSStephen Boyd * calling clk_hw_register().
44114143804cSStephen Boyd */
clk_hw_register(struct device * dev,struct clk_hw * hw)44124143804cSStephen Boyd int clk_hw_register(struct device *dev, struct clk_hw *hw)
44134143804cSStephen Boyd {
44149011f926SStephen Boyd return PTR_ERR_OR_ZERO(__clk_register(dev, dev_or_parent_of_node(dev),
44159011f926SStephen Boyd hw));
44164143804cSStephen Boyd }
44174143804cSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_register);
44184143804cSStephen Boyd
441989a5ddccSStephen Boyd /*
442089a5ddccSStephen Boyd * of_clk_hw_register - register a clk_hw and return an error code
442189a5ddccSStephen Boyd * @node: device_node of device that is registering this clock
442289a5ddccSStephen Boyd * @hw: link to hardware-specific clock data
442389a5ddccSStephen Boyd *
442489a5ddccSStephen Boyd * of_clk_hw_register() is the primary interface for populating the clock tree
442589a5ddccSStephen Boyd * with new clock nodes when a struct device is not available, but a struct
442689a5ddccSStephen Boyd * device_node is. It returns an integer equal to zero indicating success or
442789a5ddccSStephen Boyd * less than zero indicating failure. Drivers must test for an error code after
442889a5ddccSStephen Boyd * calling of_clk_hw_register().
442989a5ddccSStephen Boyd */
of_clk_hw_register(struct device_node * node,struct clk_hw * hw)443089a5ddccSStephen Boyd int of_clk_hw_register(struct device_node *node, struct clk_hw *hw)
443189a5ddccSStephen Boyd {
443289a5ddccSStephen Boyd return PTR_ERR_OR_ZERO(__clk_register(NULL, node, hw));
443389a5ddccSStephen Boyd }
443489a5ddccSStephen Boyd EXPORT_SYMBOL_GPL(of_clk_hw_register);
443589a5ddccSStephen Boyd
4436fcb0ee6aSSylwester Nawrocki /*
4437fcb0ee6aSSylwester Nawrocki * Empty clk_ops for unregistered clocks. These are used temporarily
4438fcb0ee6aSSylwester Nawrocki * after clk_unregister() was called on a clock and until last clock
4439fcb0ee6aSSylwester Nawrocki * consumer calls clk_put() and the struct clk object is freed.
4440fcb0ee6aSSylwester Nawrocki */
clk_nodrv_prepare_enable(struct clk_hw * hw)4441fcb0ee6aSSylwester Nawrocki static int clk_nodrv_prepare_enable(struct clk_hw *hw)
4442fcb0ee6aSSylwester Nawrocki {
4443fcb0ee6aSSylwester Nawrocki return -ENXIO;
4444fcb0ee6aSSylwester Nawrocki }
4445fcb0ee6aSSylwester Nawrocki
clk_nodrv_disable_unprepare(struct clk_hw * hw)4446fcb0ee6aSSylwester Nawrocki static void clk_nodrv_disable_unprepare(struct clk_hw *hw)
4447fcb0ee6aSSylwester Nawrocki {
4448fcb0ee6aSSylwester Nawrocki WARN_ON_ONCE(1);
4449fcb0ee6aSSylwester Nawrocki }
4450fcb0ee6aSSylwester Nawrocki
clk_nodrv_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)4451fcb0ee6aSSylwester Nawrocki static int clk_nodrv_set_rate(struct clk_hw *hw, unsigned long rate,
4452fcb0ee6aSSylwester Nawrocki unsigned long parent_rate)
4453fcb0ee6aSSylwester Nawrocki {
4454fcb0ee6aSSylwester Nawrocki return -ENXIO;
4455fcb0ee6aSSylwester Nawrocki }
4456fcb0ee6aSSylwester Nawrocki
clk_nodrv_set_parent(struct clk_hw * hw,u8 index)4457fcb0ee6aSSylwester Nawrocki static int clk_nodrv_set_parent(struct clk_hw *hw, u8 index)
4458fcb0ee6aSSylwester Nawrocki {
4459fcb0ee6aSSylwester Nawrocki return -ENXIO;
4460fcb0ee6aSSylwester Nawrocki }
4461fcb0ee6aSSylwester Nawrocki
clk_nodrv_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)44629e3943afSMaxime Ripard static int clk_nodrv_determine_rate(struct clk_hw *hw,
44639e3943afSMaxime Ripard struct clk_rate_request *req)
44649e3943afSMaxime Ripard {
44659e3943afSMaxime Ripard return -ENXIO;
44669e3943afSMaxime Ripard }
44679e3943afSMaxime Ripard
4468fcb0ee6aSSylwester Nawrocki static const struct clk_ops clk_nodrv_ops = {
4469fcb0ee6aSSylwester Nawrocki .enable = clk_nodrv_prepare_enable,
4470fcb0ee6aSSylwester Nawrocki .disable = clk_nodrv_disable_unprepare,
4471fcb0ee6aSSylwester Nawrocki .prepare = clk_nodrv_prepare_enable,
4472fcb0ee6aSSylwester Nawrocki .unprepare = clk_nodrv_disable_unprepare,
44739e3943afSMaxime Ripard .determine_rate = clk_nodrv_determine_rate,
4474fcb0ee6aSSylwester Nawrocki .set_rate = clk_nodrv_set_rate,
4475fcb0ee6aSSylwester Nawrocki .set_parent = clk_nodrv_set_parent,
4476fcb0ee6aSSylwester Nawrocki };
4477fcb0ee6aSSylwester Nawrocki
clk_core_evict_parent_cache_subtree(struct clk_core * root,const struct clk_core * target)4478bdcf1dc2SStephen Boyd static void clk_core_evict_parent_cache_subtree(struct clk_core *root,
44798df64183SStephen Boyd const struct clk_core *target)
4480bdcf1dc2SStephen Boyd {
4481bdcf1dc2SStephen Boyd int i;
4482bdcf1dc2SStephen Boyd struct clk_core *child;
4483bdcf1dc2SStephen Boyd
4484bdcf1dc2SStephen Boyd for (i = 0; i < root->num_parents; i++)
4485bdcf1dc2SStephen Boyd if (root->parents[i].core == target)
4486bdcf1dc2SStephen Boyd root->parents[i].core = NULL;
4487bdcf1dc2SStephen Boyd
4488bdcf1dc2SStephen Boyd hlist_for_each_entry(child, &root->children, child_node)
4489bdcf1dc2SStephen Boyd clk_core_evict_parent_cache_subtree(child, target);
4490bdcf1dc2SStephen Boyd }
4491bdcf1dc2SStephen Boyd
4492bdcf1dc2SStephen Boyd /* Remove this clk from all parent caches */
clk_core_evict_parent_cache(struct clk_core * core)4493bdcf1dc2SStephen Boyd static void clk_core_evict_parent_cache(struct clk_core *core)
4494bdcf1dc2SStephen Boyd {
449575061a6fSStephen Boyd const struct hlist_head **lists;
4496bdcf1dc2SStephen Boyd struct clk_core *root;
4497bdcf1dc2SStephen Boyd
4498bdcf1dc2SStephen Boyd lockdep_assert_held(&prepare_lock);
4499bdcf1dc2SStephen Boyd
4500bdcf1dc2SStephen Boyd for (lists = all_lists; *lists; lists++)
4501bdcf1dc2SStephen Boyd hlist_for_each_entry(root, *lists, child_node)
4502bdcf1dc2SStephen Boyd clk_core_evict_parent_cache_subtree(root, core);
4503bdcf1dc2SStephen Boyd
4504bdcf1dc2SStephen Boyd }
4505bdcf1dc2SStephen Boyd
45061df5c939SMark Brown /**
45071df5c939SMark Brown * clk_unregister - unregister a currently registered clock
45081df5c939SMark Brown * @clk: clock to unregister
45091df5c939SMark Brown */
clk_unregister(struct clk * clk)4510fcb0ee6aSSylwester Nawrocki void clk_unregister(struct clk *clk)
4511fcb0ee6aSSylwester Nawrocki {
4512fcb0ee6aSSylwester Nawrocki unsigned long flags;
4513f873744cSJerome Brunet const struct clk_ops *ops;
4514fcb0ee6aSSylwester Nawrocki
4515fcb0ee6aSSylwester Nawrocki if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
4516fcb0ee6aSSylwester Nawrocki return;
4517fcb0ee6aSSylwester Nawrocki
4518035a61c3STomeu Vizoso clk_debug_unregister(clk->core);
45196314b679SStephen Boyd
4520fcb0ee6aSSylwester Nawrocki clk_prepare_lock();
4521fcb0ee6aSSylwester Nawrocki
4522f873744cSJerome Brunet ops = clk->core->ops;
4523f873744cSJerome Brunet if (ops == &clk_nodrv_ops) {
4524035a61c3STomeu Vizoso pr_err("%s: unregistered clock: %s\n", __func__,
4525035a61c3STomeu Vizoso clk->core->name);
4526427ede28SStephen Boyd clk_prepare_unlock();
4527427ede28SStephen Boyd return;
4528fcb0ee6aSSylwester Nawrocki }
4529fcb0ee6aSSylwester Nawrocki /*
4530fcb0ee6aSSylwester Nawrocki * Assign empty clock ops for consumers that might still hold
4531fcb0ee6aSSylwester Nawrocki * a reference to this clock.
4532fcb0ee6aSSylwester Nawrocki */
4533fcb0ee6aSSylwester Nawrocki flags = clk_enable_lock();
4534035a61c3STomeu Vizoso clk->core->ops = &clk_nodrv_ops;
4535fcb0ee6aSSylwester Nawrocki clk_enable_unlock(flags);
4536fcb0ee6aSSylwester Nawrocki
4537f873744cSJerome Brunet if (ops->terminate)
4538f873744cSJerome Brunet ops->terminate(clk->core->hw);
4539f873744cSJerome Brunet
4540035a61c3STomeu Vizoso if (!hlist_empty(&clk->core->children)) {
4541035a61c3STomeu Vizoso struct clk_core *child;
4542874f224cSStephen Boyd struct hlist_node *t;
4543fcb0ee6aSSylwester Nawrocki
4544fcb0ee6aSSylwester Nawrocki /* Reparent all children to the orphan list. */
4545035a61c3STomeu Vizoso hlist_for_each_entry_safe(child, t, &clk->core->children,
4546035a61c3STomeu Vizoso child_node)
454791baa9ffSJerome Brunet clk_core_set_parent_nolock(child, NULL);
4548fcb0ee6aSSylwester Nawrocki }
4549fcb0ee6aSSylwester Nawrocki
4550bdcf1dc2SStephen Boyd clk_core_evict_parent_cache(clk->core);
4551bdcf1dc2SStephen Boyd
4552035a61c3STomeu Vizoso hlist_del_init(&clk->core->child_node);
4553fcb0ee6aSSylwester Nawrocki
4554035a61c3STomeu Vizoso if (clk->core->prepare_count)
4555fcb0ee6aSSylwester Nawrocki pr_warn("%s: unregistering prepared clock: %s\n",
4556035a61c3STomeu Vizoso __func__, clk->core->name);
4557e55a839aSJerome Brunet
4558e55a839aSJerome Brunet if (clk->core->protect_count)
4559e55a839aSJerome Brunet pr_warn("%s: unregistering protected clock: %s\n",
4560e55a839aSJerome Brunet __func__, clk->core->name);
4561427ede28SStephen Boyd clk_prepare_unlock();
4562e55a839aSJerome Brunet
4563035a61c3STomeu Vizoso kref_put(&clk->core->ref, __clk_release);
456482474707SKishon Vijay Abraham I free_clk(clk);
4565fcb0ee6aSSylwester Nawrocki }
45661df5c939SMark Brown EXPORT_SYMBOL_GPL(clk_unregister);
45671df5c939SMark Brown
45684143804cSStephen Boyd /**
45694143804cSStephen Boyd * clk_hw_unregister - unregister a currently registered clk_hw
45704143804cSStephen Boyd * @hw: hardware-specific clock data to unregister
45714143804cSStephen Boyd */
clk_hw_unregister(struct clk_hw * hw)45724143804cSStephen Boyd void clk_hw_unregister(struct clk_hw *hw)
45734143804cSStephen Boyd {
45744143804cSStephen Boyd clk_unregister(hw->clk);
45754143804cSStephen Boyd }
45764143804cSStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_unregister);
45774143804cSStephen Boyd
devm_clk_unregister_cb(struct device * dev,void * res)4578e5a4b9b9SJerome Brunet static void devm_clk_unregister_cb(struct device *dev, void *res)
457946c8773aSStephen Boyd {
4580293ba3b4SStephen Boyd clk_unregister(*(struct clk **)res);
458146c8773aSStephen Boyd }
458246c8773aSStephen Boyd
devm_clk_hw_unregister_cb(struct device * dev,void * res)4583e5a4b9b9SJerome Brunet static void devm_clk_hw_unregister_cb(struct device *dev, void *res)
45844143804cSStephen Boyd {
45854143804cSStephen Boyd clk_hw_unregister(*(struct clk_hw **)res);
45864143804cSStephen Boyd }
45874143804cSStephen Boyd
458846c8773aSStephen Boyd /**
458946c8773aSStephen Boyd * devm_clk_register - resource managed clk_register()
459046c8773aSStephen Boyd * @dev: device that is registering this clock
459146c8773aSStephen Boyd * @hw: link to hardware-specific clock data
459246c8773aSStephen Boyd *
45939fe9b7abSStephen Boyd * Managed clk_register(). This function is *deprecated*, use devm_clk_hw_register() instead.
45949fe9b7abSStephen Boyd *
45959fe9b7abSStephen Boyd * Clocks returned from this function are automatically clk_unregister()ed on
45969fe9b7abSStephen Boyd * driver detach. See clk_register() for more information.
459746c8773aSStephen Boyd */
devm_clk_register(struct device * dev,struct clk_hw * hw)459846c8773aSStephen Boyd struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
459946c8773aSStephen Boyd {
460046c8773aSStephen Boyd struct clk *clk;
4601293ba3b4SStephen Boyd struct clk **clkp;
460246c8773aSStephen Boyd
4603e5a4b9b9SJerome Brunet clkp = devres_alloc(devm_clk_unregister_cb, sizeof(*clkp), GFP_KERNEL);
4604293ba3b4SStephen Boyd if (!clkp)
460546c8773aSStephen Boyd return ERR_PTR(-ENOMEM);
460646c8773aSStephen Boyd
4607293ba3b4SStephen Boyd clk = clk_register(dev, hw);
4608293ba3b4SStephen Boyd if (!IS_ERR(clk)) {
4609293ba3b4SStephen Boyd *clkp = clk;
4610293ba3b4SStephen Boyd devres_add(dev, clkp);
461146c8773aSStephen Boyd } else {
4612293ba3b4SStephen Boyd devres_free(clkp);
461346c8773aSStephen Boyd }
461446c8773aSStephen Boyd
461546c8773aSStephen Boyd return clk;
461646c8773aSStephen Boyd }
461746c8773aSStephen Boyd EXPORT_SYMBOL_GPL(devm_clk_register);
461846c8773aSStephen Boyd
46194143804cSStephen Boyd /**
46204143804cSStephen Boyd * devm_clk_hw_register - resource managed clk_hw_register()
46214143804cSStephen Boyd * @dev: device that is registering this clock
46224143804cSStephen Boyd * @hw: link to hardware-specific clock data
46234143804cSStephen Boyd *
4624c47265adSMasahiro Yamada * Managed clk_hw_register(). Clocks registered by this function are
46254143804cSStephen Boyd * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register()
46264143804cSStephen Boyd * for more information.
46274143804cSStephen Boyd */
devm_clk_hw_register(struct device * dev,struct clk_hw * hw)46284143804cSStephen Boyd int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
46294143804cSStephen Boyd {
46304143804cSStephen Boyd struct clk_hw **hwp;
46314143804cSStephen Boyd int ret;
46324143804cSStephen Boyd
4633e5a4b9b9SJerome Brunet hwp = devres_alloc(devm_clk_hw_unregister_cb, sizeof(*hwp), GFP_KERNEL);
46344143804cSStephen Boyd if (!hwp)
46354143804cSStephen Boyd return -ENOMEM;
46364143804cSStephen Boyd
46374143804cSStephen Boyd ret = clk_hw_register(dev, hw);
46384143804cSStephen Boyd if (!ret) {
46394143804cSStephen Boyd *hwp = hw;
46404143804cSStephen Boyd devres_add(dev, hwp);
46414143804cSStephen Boyd } else {
46424143804cSStephen Boyd devres_free(hwp);
46434143804cSStephen Boyd }
46444143804cSStephen Boyd
46454143804cSStephen Boyd return ret;
46464143804cSStephen Boyd }
46474143804cSStephen Boyd EXPORT_SYMBOL_GPL(devm_clk_hw_register);
46484143804cSStephen Boyd
devm_clk_release(struct device * dev,void * res)464930d6f8c1SJerome Brunet static void devm_clk_release(struct device *dev, void *res)
465030d6f8c1SJerome Brunet {
465130d6f8c1SJerome Brunet clk_put(*(struct clk **)res);
465230d6f8c1SJerome Brunet }
465330d6f8c1SJerome Brunet
465430d6f8c1SJerome Brunet /**
465530d6f8c1SJerome Brunet * devm_clk_hw_get_clk - resource managed clk_hw_get_clk()
465630d6f8c1SJerome Brunet * @dev: device that is registering this clock
465730d6f8c1SJerome Brunet * @hw: clk_hw associated with the clk being consumed
465830d6f8c1SJerome Brunet * @con_id: connection ID string on device
465930d6f8c1SJerome Brunet *
466030d6f8c1SJerome Brunet * Managed clk_hw_get_clk(). Clocks got with this function are
466130d6f8c1SJerome Brunet * automatically clk_put() on driver detach. See clk_put()
466230d6f8c1SJerome Brunet * for more information.
466330d6f8c1SJerome Brunet */
devm_clk_hw_get_clk(struct device * dev,struct clk_hw * hw,const char * con_id)466430d6f8c1SJerome Brunet struct clk *devm_clk_hw_get_clk(struct device *dev, struct clk_hw *hw,
466530d6f8c1SJerome Brunet const char *con_id)
466630d6f8c1SJerome Brunet {
466730d6f8c1SJerome Brunet struct clk *clk;
466830d6f8c1SJerome Brunet struct clk **clkp;
466930d6f8c1SJerome Brunet
467030d6f8c1SJerome Brunet /* This should not happen because it would mean we have drivers
467130d6f8c1SJerome Brunet * passing around clk_hw pointers instead of having the caller use
467230d6f8c1SJerome Brunet * proper clk_get() style APIs
467330d6f8c1SJerome Brunet */
467430d6f8c1SJerome Brunet WARN_ON_ONCE(dev != hw->core->dev);
467530d6f8c1SJerome Brunet
467630d6f8c1SJerome Brunet clkp = devres_alloc(devm_clk_release, sizeof(*clkp), GFP_KERNEL);
467730d6f8c1SJerome Brunet if (!clkp)
467830d6f8c1SJerome Brunet return ERR_PTR(-ENOMEM);
467930d6f8c1SJerome Brunet
468030d6f8c1SJerome Brunet clk = clk_hw_get_clk(hw, con_id);
468130d6f8c1SJerome Brunet if (!IS_ERR(clk)) {
468230d6f8c1SJerome Brunet *clkp = clk;
468330d6f8c1SJerome Brunet devres_add(dev, clkp);
468430d6f8c1SJerome Brunet } else {
468530d6f8c1SJerome Brunet devres_free(clkp);
468630d6f8c1SJerome Brunet }
468730d6f8c1SJerome Brunet
468830d6f8c1SJerome Brunet return clk;
468930d6f8c1SJerome Brunet }
469030d6f8c1SJerome Brunet EXPORT_SYMBOL_GPL(devm_clk_hw_get_clk);
469130d6f8c1SJerome Brunet
4692ac2df527SSylwester Nawrocki /*
4693ac2df527SSylwester Nawrocki * clkdev helpers
4694ac2df527SSylwester Nawrocki */
4695035a61c3STomeu Vizoso
__clk_put(struct clk * clk)4696ac2df527SSylwester Nawrocki void __clk_put(struct clk *clk)
4697ac2df527SSylwester Nawrocki {
469810cdfe54STomeu Vizoso struct module *owner;
469910cdfe54STomeu Vizoso
470000efcb1cSSylwester Nawrocki if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
4701ac2df527SSylwester Nawrocki return;
4702ac2df527SSylwester Nawrocki
4703fcb0ee6aSSylwester Nawrocki clk_prepare_lock();
47041c8e6004STomeu Vizoso
470555e9b8b7SJerome Brunet /*
470655e9b8b7SJerome Brunet * Before calling clk_put, all calls to clk_rate_exclusive_get() from a
470755e9b8b7SJerome Brunet * given user should be balanced with calls to clk_rate_exclusive_put()
470855e9b8b7SJerome Brunet * and by that same consumer
470955e9b8b7SJerome Brunet */
471055e9b8b7SJerome Brunet if (WARN_ON(clk->exclusive_count)) {
471155e9b8b7SJerome Brunet /* We voiced our concern, let's sanitize the situation */
471255e9b8b7SJerome Brunet clk->core->protect_count -= (clk->exclusive_count - 1);
471355e9b8b7SJerome Brunet clk_core_rate_unprotect(clk->core);
471455e9b8b7SJerome Brunet clk->exclusive_count = 0;
471555e9b8b7SJerome Brunet }
471655e9b8b7SJerome Brunet
471750595f8bSStephen Boyd hlist_del(&clk->clks_node);
4718d7738822SMaxime Ripard
4719d7738822SMaxime Ripard /* If we had any boundaries on that clock, let's drop them. */
4720d7738822SMaxime Ripard if (clk->min_rate > 0 || clk->max_rate < ULONG_MAX)
4721d7738822SMaxime Ripard clk_set_rate_range_nolock(clk, 0, ULONG_MAX);
4722ec02ace8STomeu Vizoso
4723fcb0ee6aSSylwester Nawrocki clk_prepare_unlock();
4724fcb0ee6aSSylwester Nawrocki
4725427ede28SStephen Boyd owner = clk->core->owner;
4726427ede28SStephen Boyd kref_put(&clk->core->ref, __clk_release);
472710cdfe54STomeu Vizoso module_put(owner);
47281df4046aSStephen Boyd free_clk(clk);
4729ac2df527SSylwester Nawrocki }
4730ac2df527SSylwester Nawrocki
4731b2476490SMike Turquette /*** clk rate change notifiers ***/
4732b2476490SMike Turquette
4733b2476490SMike Turquette /**
4734b2476490SMike Turquette * clk_notifier_register - add a clk rate change notifier
4735b2476490SMike Turquette * @clk: struct clk * to watch
4736b2476490SMike Turquette * @nb: struct notifier_block * with callback info
4737b2476490SMike Turquette *
4738b2476490SMike Turquette * Request notification when clk's rate changes. This uses an SRCU
4739b2476490SMike Turquette * notifier because we want it to block and notifier unregistrations are
4740b2476490SMike Turquette * uncommon. The callbacks associated with the notifier must not
4741b2476490SMike Turquette * re-enter into the clk framework by calling any top-level clk APIs;
4742b2476490SMike Turquette * this will cause a nested prepare_lock mutex.
4743b2476490SMike Turquette *
4744198bb594SMasahiro Yamada * In all notification cases (pre, post and abort rate change) the original
4745198bb594SMasahiro Yamada * clock rate is passed to the callback via struct clk_notifier_data.old_rate
4746198bb594SMasahiro Yamada * and the new frequency is passed via struct clk_notifier_data.new_rate.
4747b2476490SMike Turquette *
4748b2476490SMike Turquette * clk_notifier_register() must be called from non-atomic context.
4749b2476490SMike Turquette * Returns -EINVAL if called with null arguments, -ENOMEM upon
4750b2476490SMike Turquette * allocation failure; otherwise, passes along the return value of
4751b2476490SMike Turquette * srcu_notifier_chain_register().
4752b2476490SMike Turquette */
clk_notifier_register(struct clk * clk,struct notifier_block * nb)4753b2476490SMike Turquette int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
4754b2476490SMike Turquette {
4755b2476490SMike Turquette struct clk_notifier *cn;
4756b2476490SMike Turquette int ret = -ENOMEM;
4757b2476490SMike Turquette
4758b2476490SMike Turquette if (!clk || !nb)
4759b2476490SMike Turquette return -EINVAL;
4760b2476490SMike Turquette
4761eab89f69SMike Turquette clk_prepare_lock();
4762b2476490SMike Turquette
4763b2476490SMike Turquette /* search the list of notifiers for this clk */
4764b2476490SMike Turquette list_for_each_entry(cn, &clk_notifier_list, node)
4765b2476490SMike Turquette if (cn->clk == clk)
47668d3c0c01SLukasz Bartosik goto found;
4767b2476490SMike Turquette
4768b2476490SMike Turquette /* if clk wasn't in the notifier list, allocate new clk_notifier */
47691808a320SMarkus Elfring cn = kzalloc(sizeof(*cn), GFP_KERNEL);
4770b2476490SMike Turquette if (!cn)
4771b2476490SMike Turquette goto out;
4772b2476490SMike Turquette
4773b2476490SMike Turquette cn->clk = clk;
4774b2476490SMike Turquette srcu_init_notifier_head(&cn->notifier_head);
4775b2476490SMike Turquette
4776b2476490SMike Turquette list_add(&cn->node, &clk_notifier_list);
4777b2476490SMike Turquette
47788d3c0c01SLukasz Bartosik found:
4779b2476490SMike Turquette ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
4780b2476490SMike Turquette
4781035a61c3STomeu Vizoso clk->core->notifier_count++;
4782b2476490SMike Turquette
4783b2476490SMike Turquette out:
4784eab89f69SMike Turquette clk_prepare_unlock();
4785b2476490SMike Turquette
4786b2476490SMike Turquette return ret;
4787b2476490SMike Turquette }
4788b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_notifier_register);
4789b2476490SMike Turquette
4790b2476490SMike Turquette /**
4791b2476490SMike Turquette * clk_notifier_unregister - remove a clk rate change notifier
4792b2476490SMike Turquette * @clk: struct clk *
4793b2476490SMike Turquette * @nb: struct notifier_block * with callback info
4794b2476490SMike Turquette *
4795b2476490SMike Turquette * Request no further notification for changes to 'clk' and frees memory
4796b2476490SMike Turquette * allocated in clk_notifier_register.
4797b2476490SMike Turquette *
4798b2476490SMike Turquette * Returns -EINVAL if called with null arguments; otherwise, passes
4799b2476490SMike Turquette * along the return value of srcu_notifier_chain_unregister().
4800b2476490SMike Turquette */
clk_notifier_unregister(struct clk * clk,struct notifier_block * nb)4801b2476490SMike Turquette int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
4802b2476490SMike Turquette {
480370454655SLukasz Bartosik struct clk_notifier *cn;
480470454655SLukasz Bartosik int ret = -ENOENT;
4805b2476490SMike Turquette
4806b2476490SMike Turquette if (!clk || !nb)
4807b2476490SMike Turquette return -EINVAL;
4808b2476490SMike Turquette
4809eab89f69SMike Turquette clk_prepare_lock();
4810b2476490SMike Turquette
481170454655SLukasz Bartosik list_for_each_entry(cn, &clk_notifier_list, node) {
4812b2476490SMike Turquette if (cn->clk == clk) {
4813b2476490SMike Turquette ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
4814b2476490SMike Turquette
4815035a61c3STomeu Vizoso clk->core->notifier_count--;
4816b2476490SMike Turquette
4817b2476490SMike Turquette /* XXX the notifier code should handle this better */
4818b2476490SMike Turquette if (!cn->notifier_head.head) {
4819b2476490SMike Turquette srcu_cleanup_notifier_head(&cn->notifier_head);
482072b5322fSLai Jiangshan list_del(&cn->node);
4821b2476490SMike Turquette kfree(cn);
4822b2476490SMike Turquette }
482370454655SLukasz Bartosik break;
482470454655SLukasz Bartosik }
4825b2476490SMike Turquette }
4826b2476490SMike Turquette
4827eab89f69SMike Turquette clk_prepare_unlock();
4828b2476490SMike Turquette
4829b2476490SMike Turquette return ret;
4830b2476490SMike Turquette }
4831b2476490SMike Turquette EXPORT_SYMBOL_GPL(clk_notifier_unregister);
4832766e6a4eSGrant Likely
48336d30d50dSJerome Brunet struct clk_notifier_devres {
48346d30d50dSJerome Brunet struct clk *clk;
48356d30d50dSJerome Brunet struct notifier_block *nb;
48366d30d50dSJerome Brunet };
48376d30d50dSJerome Brunet
devm_clk_notifier_release(struct device * dev,void * res)48386d30d50dSJerome Brunet static void devm_clk_notifier_release(struct device *dev, void *res)
48396d30d50dSJerome Brunet {
48406d30d50dSJerome Brunet struct clk_notifier_devres *devres = res;
48416d30d50dSJerome Brunet
48426d30d50dSJerome Brunet clk_notifier_unregister(devres->clk, devres->nb);
48436d30d50dSJerome Brunet }
48446d30d50dSJerome Brunet
devm_clk_notifier_register(struct device * dev,struct clk * clk,struct notifier_block * nb)48456d30d50dSJerome Brunet int devm_clk_notifier_register(struct device *dev, struct clk *clk,
48466d30d50dSJerome Brunet struct notifier_block *nb)
48476d30d50dSJerome Brunet {
48486d30d50dSJerome Brunet struct clk_notifier_devres *devres;
48496d30d50dSJerome Brunet int ret;
48506d30d50dSJerome Brunet
48516d30d50dSJerome Brunet devres = devres_alloc(devm_clk_notifier_release,
48526d30d50dSJerome Brunet sizeof(*devres), GFP_KERNEL);
48536d30d50dSJerome Brunet
48546d30d50dSJerome Brunet if (!devres)
48556d30d50dSJerome Brunet return -ENOMEM;
48566d30d50dSJerome Brunet
48576d30d50dSJerome Brunet ret = clk_notifier_register(clk, nb);
48586d30d50dSJerome Brunet if (!ret) {
48596d30d50dSJerome Brunet devres->clk = clk;
48606d30d50dSJerome Brunet devres->nb = nb;
48617fb933e5SFei Shao devres_add(dev, devres);
48626d30d50dSJerome Brunet } else {
48636d30d50dSJerome Brunet devres_free(devres);
48646d30d50dSJerome Brunet }
48656d30d50dSJerome Brunet
48666d30d50dSJerome Brunet return ret;
48676d30d50dSJerome Brunet }
48686d30d50dSJerome Brunet EXPORT_SYMBOL_GPL(devm_clk_notifier_register);
48696d30d50dSJerome Brunet
4870766e6a4eSGrant Likely #ifdef CONFIG_OF
clk_core_reparent_orphans(void)4871c771256eSOlof Johansson static void clk_core_reparent_orphans(void)
4872c771256eSOlof Johansson {
4873c771256eSOlof Johansson clk_prepare_lock();
4874c771256eSOlof Johansson clk_core_reparent_orphans_nolock();
4875c771256eSOlof Johansson clk_prepare_unlock();
4876c771256eSOlof Johansson }
4877c771256eSOlof Johansson
4878766e6a4eSGrant Likely /**
4879766e6a4eSGrant Likely * struct of_clk_provider - Clock provider registration structure
4880766e6a4eSGrant Likely * @link: Entry in global list of clock providers
4881766e6a4eSGrant Likely * @node: Pointer to device tree node of clock provider
4882766e6a4eSGrant Likely * @get: Get clock callback. Returns NULL or a struct clk for the
4883766e6a4eSGrant Likely * given clock specifier
48846378cfdcSStephen Boyd * @get_hw: Get clk_hw callback. Returns NULL, ERR_PTR or a
48856378cfdcSStephen Boyd * struct clk_hw for the given clock specifier
4886766e6a4eSGrant Likely * @data: context pointer to be passed into @get callback
4887766e6a4eSGrant Likely */
4888766e6a4eSGrant Likely struct of_clk_provider {
4889766e6a4eSGrant Likely struct list_head link;
4890766e6a4eSGrant Likely
4891766e6a4eSGrant Likely struct device_node *node;
4892766e6a4eSGrant Likely struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
48930861e5b8SStephen Boyd struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
4894766e6a4eSGrant Likely void *data;
4895766e6a4eSGrant Likely };
4896766e6a4eSGrant Likely
489730d5a945SStephen Boyd extern struct of_device_id __clk_of_table;
4898f2f6c255SPrashant Gaikwad static const struct of_device_id __clk_of_table_sentinel
489933def849SJoe Perches __used __section("__clk_of_table_end");
4900f2f6c255SPrashant Gaikwad
4901766e6a4eSGrant Likely static LIST_HEAD(of_clk_providers);
4902d6782c26SSylwester Nawrocki static DEFINE_MUTEX(of_clk_mutex);
4903d6782c26SSylwester Nawrocki
of_clk_src_simple_get(struct of_phandle_args * clkspec,void * data)4904766e6a4eSGrant Likely struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
4905766e6a4eSGrant Likely void *data)
4906766e6a4eSGrant Likely {
4907766e6a4eSGrant Likely return data;
4908766e6a4eSGrant Likely }
4909766e6a4eSGrant Likely EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
4910766e6a4eSGrant Likely
of_clk_hw_simple_get(struct of_phandle_args * clkspec,void * data)49110861e5b8SStephen Boyd struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
49120861e5b8SStephen Boyd {
49130861e5b8SStephen Boyd return data;
49140861e5b8SStephen Boyd }
49150861e5b8SStephen Boyd EXPORT_SYMBOL_GPL(of_clk_hw_simple_get);
49160861e5b8SStephen Boyd
of_clk_src_onecell_get(struct of_phandle_args * clkspec,void * data)4917494bfec9SShawn Guo struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
4918494bfec9SShawn Guo {
4919494bfec9SShawn Guo struct clk_onecell_data *clk_data = data;
4920494bfec9SShawn Guo unsigned int idx = clkspec->args[0];
4921494bfec9SShawn Guo
4922494bfec9SShawn Guo if (idx >= clk_data->clk_num) {
49237e96353cSGeert Uytterhoeven pr_err("%s: invalid clock index %u\n", __func__, idx);
4924494bfec9SShawn Guo return ERR_PTR(-EINVAL);
4925494bfec9SShawn Guo }
4926494bfec9SShawn Guo
4927494bfec9SShawn Guo return clk_data->clks[idx];
4928494bfec9SShawn Guo }
4929494bfec9SShawn Guo EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
4930494bfec9SShawn Guo
49310861e5b8SStephen Boyd struct clk_hw *
of_clk_hw_onecell_get(struct of_phandle_args * clkspec,void * data)49320861e5b8SStephen Boyd of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
49330861e5b8SStephen Boyd {
49340861e5b8SStephen Boyd struct clk_hw_onecell_data *hw_data = data;
49350861e5b8SStephen Boyd unsigned int idx = clkspec->args[0];
49360861e5b8SStephen Boyd
49370861e5b8SStephen Boyd if (idx >= hw_data->num) {
49380861e5b8SStephen Boyd pr_err("%s: invalid index %u\n", __func__, idx);
49390861e5b8SStephen Boyd return ERR_PTR(-EINVAL);
49400861e5b8SStephen Boyd }
49410861e5b8SStephen Boyd
49420861e5b8SStephen Boyd return hw_data->hws[idx];
49430861e5b8SStephen Boyd }
49440861e5b8SStephen Boyd EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
49450861e5b8SStephen Boyd
4946766e6a4eSGrant Likely /**
4947766e6a4eSGrant Likely * of_clk_add_provider() - Register a clock provider for a node
4948766e6a4eSGrant Likely * @np: Device node pointer associated with clock provider
4949766e6a4eSGrant Likely * @clk_src_get: callback for decoding clock
4950766e6a4eSGrant Likely * @data: context pointer for @clk_src_get callback.
49519fe9b7abSStephen Boyd *
49529fe9b7abSStephen Boyd * This function is *deprecated*. Use of_clk_add_hw_provider() instead.
4953766e6a4eSGrant Likely */
of_clk_add_provider(struct device_node * np,struct clk * (* clk_src_get)(struct of_phandle_args * clkspec,void * data),void * data)4954766e6a4eSGrant Likely int of_clk_add_provider(struct device_node *np,
4955766e6a4eSGrant Likely struct clk *(*clk_src_get)(struct of_phandle_args *clkspec,
4956766e6a4eSGrant Likely void *data),
4957766e6a4eSGrant Likely void *data)
4958766e6a4eSGrant Likely {
4959766e6a4eSGrant Likely struct of_clk_provider *cp;
496086be408bSSylwester Nawrocki int ret;
4961766e6a4eSGrant Likely
4962bb4031b8STudor Ambarus if (!np)
4963bb4031b8STudor Ambarus return 0;
4964bb4031b8STudor Ambarus
49651808a320SMarkus Elfring cp = kzalloc(sizeof(*cp), GFP_KERNEL);
4966766e6a4eSGrant Likely if (!cp)
4967766e6a4eSGrant Likely return -ENOMEM;
4968766e6a4eSGrant Likely
4969766e6a4eSGrant Likely cp->node = of_node_get(np);
4970766e6a4eSGrant Likely cp->data = data;
4971766e6a4eSGrant Likely cp->get = clk_src_get;
4972766e6a4eSGrant Likely
4973d6782c26SSylwester Nawrocki mutex_lock(&of_clk_mutex);
4974766e6a4eSGrant Likely list_add(&cp->link, &of_clk_providers);
4975d6782c26SSylwester Nawrocki mutex_unlock(&of_clk_mutex);
497616673931SRob Herring pr_debug("Added clock from %pOF\n", np);
4977766e6a4eSGrant Likely
497866d95064SJerome Brunet clk_core_reparent_orphans();
497966d95064SJerome Brunet
498086be408bSSylwester Nawrocki ret = of_clk_set_defaults(np, true);
498186be408bSSylwester Nawrocki if (ret < 0)
498286be408bSSylwester Nawrocki of_clk_del_provider(np);
498386be408bSSylwester Nawrocki
49843c9ea428SSaravana Kannan fwnode_dev_initialized(&np->fwnode, true);
49853c9ea428SSaravana Kannan
498686be408bSSylwester Nawrocki return ret;
4987766e6a4eSGrant Likely }
4988766e6a4eSGrant Likely EXPORT_SYMBOL_GPL(of_clk_add_provider);
4989766e6a4eSGrant Likely
4990766e6a4eSGrant Likely /**
49910861e5b8SStephen Boyd * of_clk_add_hw_provider() - Register a clock provider for a node
49920861e5b8SStephen Boyd * @np: Device node pointer associated with clock provider
49930861e5b8SStephen Boyd * @get: callback for decoding clk_hw
49940861e5b8SStephen Boyd * @data: context pointer for @get callback.
49950861e5b8SStephen Boyd */
of_clk_add_hw_provider(struct device_node * np,struct clk_hw * (* get)(struct of_phandle_args * clkspec,void * data),void * data)49960861e5b8SStephen Boyd int of_clk_add_hw_provider(struct device_node *np,
49970861e5b8SStephen Boyd struct clk_hw *(*get)(struct of_phandle_args *clkspec,
49980861e5b8SStephen Boyd void *data),
49990861e5b8SStephen Boyd void *data)
50000861e5b8SStephen Boyd {
50010861e5b8SStephen Boyd struct of_clk_provider *cp;
50020861e5b8SStephen Boyd int ret;
50030861e5b8SStephen Boyd
5004bb4031b8STudor Ambarus if (!np)
5005bb4031b8STudor Ambarus return 0;
5006bb4031b8STudor Ambarus
50070861e5b8SStephen Boyd cp = kzalloc(sizeof(*cp), GFP_KERNEL);
50080861e5b8SStephen Boyd if (!cp)
50090861e5b8SStephen Boyd return -ENOMEM;
50100861e5b8SStephen Boyd
50110861e5b8SStephen Boyd cp->node = of_node_get(np);
50120861e5b8SStephen Boyd cp->data = data;
50130861e5b8SStephen Boyd cp->get_hw = get;
50140861e5b8SStephen Boyd
50150861e5b8SStephen Boyd mutex_lock(&of_clk_mutex);
50160861e5b8SStephen Boyd list_add(&cp->link, &of_clk_providers);
50170861e5b8SStephen Boyd mutex_unlock(&of_clk_mutex);
501816673931SRob Herring pr_debug("Added clk_hw provider from %pOF\n", np);
50190861e5b8SStephen Boyd
502066d95064SJerome Brunet clk_core_reparent_orphans();
502166d95064SJerome Brunet
50220861e5b8SStephen Boyd ret = of_clk_set_defaults(np, true);
50230861e5b8SStephen Boyd if (ret < 0)
50240861e5b8SStephen Boyd of_clk_del_provider(np);
50250861e5b8SStephen Boyd
50266579c8d9STudor Ambarus fwnode_dev_initialized(&np->fwnode, true);
50276579c8d9STudor Ambarus
50280861e5b8SStephen Boyd return ret;
50290861e5b8SStephen Boyd }
50300861e5b8SStephen Boyd EXPORT_SYMBOL_GPL(of_clk_add_hw_provider);
50310861e5b8SStephen Boyd
devm_of_clk_release_provider(struct device * dev,void * res)5032aa795c41SStephen Boyd static void devm_of_clk_release_provider(struct device *dev, void *res)
5033aa795c41SStephen Boyd {
5034aa795c41SStephen Boyd of_clk_del_provider(*(struct device_node **)res);
5035aa795c41SStephen Boyd }
5036aa795c41SStephen Boyd
503705502bf9SMatti Vaittinen /*
503805502bf9SMatti Vaittinen * We allow a child device to use its parent device as the clock provider node
503905502bf9SMatti Vaittinen * for cases like MFD sub-devices where the child device driver wants to use
504005502bf9SMatti Vaittinen * devm_*() APIs but not list the device in DT as a sub-node.
504105502bf9SMatti Vaittinen */
get_clk_provider_node(struct device * dev)504205502bf9SMatti Vaittinen static struct device_node *get_clk_provider_node(struct device *dev)
504305502bf9SMatti Vaittinen {
504405502bf9SMatti Vaittinen struct device_node *np, *parent_np;
504505502bf9SMatti Vaittinen
504605502bf9SMatti Vaittinen np = dev->of_node;
504705502bf9SMatti Vaittinen parent_np = dev->parent ? dev->parent->of_node : NULL;
504805502bf9SMatti Vaittinen
5049d02fddf2SRob Herring if (!of_property_present(np, "#clock-cells"))
5050d02fddf2SRob Herring if (of_property_present(parent_np, "#clock-cells"))
505105502bf9SMatti Vaittinen np = parent_np;
505205502bf9SMatti Vaittinen
505305502bf9SMatti Vaittinen return np;
505405502bf9SMatti Vaittinen }
505505502bf9SMatti Vaittinen
5056e45838b5SMatti Vaittinen /**
5057e45838b5SMatti Vaittinen * devm_of_clk_add_hw_provider() - Managed clk provider node registration
5058e45838b5SMatti Vaittinen * @dev: Device acting as the clock provider (used for DT node and lifetime)
5059e45838b5SMatti Vaittinen * @get: callback for decoding clk_hw
5060e45838b5SMatti Vaittinen * @data: context pointer for @get callback
5061e45838b5SMatti Vaittinen *
506205502bf9SMatti Vaittinen * Registers clock provider for given device's node. If the device has no DT
506305502bf9SMatti Vaittinen * node or if the device node lacks of clock provider information (#clock-cells)
506405502bf9SMatti Vaittinen * then the parent device's node is scanned for this information. If parent node
506505502bf9SMatti Vaittinen * has the #clock-cells then it is used in registration. Provider is
506605502bf9SMatti Vaittinen * automatically released at device exit.
5067e45838b5SMatti Vaittinen *
5068e45838b5SMatti Vaittinen * Return: 0 on success or an errno on failure.
5069e45838b5SMatti Vaittinen */
devm_of_clk_add_hw_provider(struct device * dev,struct clk_hw * (* get)(struct of_phandle_args * clkspec,void * data),void * data)5070aa795c41SStephen Boyd int devm_of_clk_add_hw_provider(struct device *dev,
5071aa795c41SStephen Boyd struct clk_hw *(*get)(struct of_phandle_args *clkspec,
5072aa795c41SStephen Boyd void *data),
5073aa795c41SStephen Boyd void *data)
5074aa795c41SStephen Boyd {
5075aa795c41SStephen Boyd struct device_node **ptr, *np;
5076aa795c41SStephen Boyd int ret;
5077aa795c41SStephen Boyd
5078aa795c41SStephen Boyd ptr = devres_alloc(devm_of_clk_release_provider, sizeof(*ptr),
5079aa795c41SStephen Boyd GFP_KERNEL);
5080aa795c41SStephen Boyd if (!ptr)
5081aa795c41SStephen Boyd return -ENOMEM;
5082aa795c41SStephen Boyd
508305502bf9SMatti Vaittinen np = get_clk_provider_node(dev);
5084aa795c41SStephen Boyd ret = of_clk_add_hw_provider(np, get, data);
5085aa795c41SStephen Boyd if (!ret) {
5086aa795c41SStephen Boyd *ptr = np;
5087aa795c41SStephen Boyd devres_add(dev, ptr);
5088aa795c41SStephen Boyd } else {
5089aa795c41SStephen Boyd devres_free(ptr);
5090aa795c41SStephen Boyd }
5091aa795c41SStephen Boyd
5092aa795c41SStephen Boyd return ret;
5093aa795c41SStephen Boyd }
5094aa795c41SStephen Boyd EXPORT_SYMBOL_GPL(devm_of_clk_add_hw_provider);
5095aa795c41SStephen Boyd
50960861e5b8SStephen Boyd /**
5097766e6a4eSGrant Likely * of_clk_del_provider() - Remove a previously registered clock provider
5098766e6a4eSGrant Likely * @np: Device node pointer associated with clock provider
5099766e6a4eSGrant Likely */
of_clk_del_provider(struct device_node * np)5100766e6a4eSGrant Likely void of_clk_del_provider(struct device_node *np)
5101766e6a4eSGrant Likely {
5102766e6a4eSGrant Likely struct of_clk_provider *cp;
5103766e6a4eSGrant Likely
5104bb4031b8STudor Ambarus if (!np)
5105bb4031b8STudor Ambarus return;
5106bb4031b8STudor Ambarus
5107d6782c26SSylwester Nawrocki mutex_lock(&of_clk_mutex);
5108766e6a4eSGrant Likely list_for_each_entry(cp, &of_clk_providers, link) {
5109766e6a4eSGrant Likely if (cp->node == np) {
5110766e6a4eSGrant Likely list_del(&cp->link);
51113c9ea428SSaravana Kannan fwnode_dev_initialized(&np->fwnode, false);
5112766e6a4eSGrant Likely of_node_put(cp->node);
5113766e6a4eSGrant Likely kfree(cp);
5114766e6a4eSGrant Likely break;
5115766e6a4eSGrant Likely }
5116766e6a4eSGrant Likely }
5117d6782c26SSylwester Nawrocki mutex_unlock(&of_clk_mutex);
5118766e6a4eSGrant Likely }
5119766e6a4eSGrant Likely EXPORT_SYMBOL_GPL(of_clk_del_provider);
5120766e6a4eSGrant Likely
5121226fd702SStephen Boyd /**
5122226fd702SStephen Boyd * of_parse_clkspec() - Parse a DT clock specifier for a given device node
5123226fd702SStephen Boyd * @np: device node to parse clock specifier from
5124226fd702SStephen Boyd * @index: index of phandle to parse clock out of. If index < 0, @name is used
5125226fd702SStephen Boyd * @name: clock name to find and parse. If name is NULL, the index is used
5126226fd702SStephen Boyd * @out_args: Result of parsing the clock specifier
5127226fd702SStephen Boyd *
5128226fd702SStephen Boyd * Parses a device node's "clocks" and "clock-names" properties to find the
5129226fd702SStephen Boyd * phandle and cells for the index or name that is desired. The resulting clock
5130226fd702SStephen Boyd * specifier is placed into @out_args, or an errno is returned when there's a
5131226fd702SStephen Boyd * parsing error. The @index argument is ignored if @name is non-NULL.
5132226fd702SStephen Boyd *
5133226fd702SStephen Boyd * Example:
5134226fd702SStephen Boyd *
5135226fd702SStephen Boyd * phandle1: clock-controller@1 {
5136226fd702SStephen Boyd * #clock-cells = <2>;
5137226fd702SStephen Boyd * }
5138226fd702SStephen Boyd *
5139226fd702SStephen Boyd * phandle2: clock-controller@2 {
5140226fd702SStephen Boyd * #clock-cells = <1>;
5141226fd702SStephen Boyd * }
5142226fd702SStephen Boyd *
5143226fd702SStephen Boyd * clock-consumer@3 {
5144226fd702SStephen Boyd * clocks = <&phandle1 1 2 &phandle2 3>;
5145226fd702SStephen Boyd * clock-names = "name1", "name2";
5146226fd702SStephen Boyd * }
5147226fd702SStephen Boyd *
5148226fd702SStephen Boyd * To get a device_node for `clock-controller@2' node you may call this
5149226fd702SStephen Boyd * function a few different ways:
5150226fd702SStephen Boyd *
5151226fd702SStephen Boyd * of_parse_clkspec(clock-consumer@3, -1, "name2", &args);
5152226fd702SStephen Boyd * of_parse_clkspec(clock-consumer@3, 1, NULL, &args);
5153226fd702SStephen Boyd * of_parse_clkspec(clock-consumer@3, 1, "name2", &args);
5154226fd702SStephen Boyd *
5155226fd702SStephen Boyd * Return: 0 upon successfully parsing the clock specifier. Otherwise, -ENOENT
5156226fd702SStephen Boyd * if @name is NULL or -EINVAL if @name is non-NULL and it can't be found in
5157226fd702SStephen Boyd * the "clock-names" property of @np.
51585dc7e842SStephen Boyd */
of_parse_clkspec(const struct device_node * np,int index,const char * name,struct of_phandle_args * out_args)5159cf13f289SStephen Boyd static int of_parse_clkspec(const struct device_node *np, int index,
5160cf13f289SStephen Boyd const char *name, struct of_phandle_args *out_args)
51614472287aSStephen Boyd {
51624472287aSStephen Boyd int ret = -ENOENT;
51634472287aSStephen Boyd
51644472287aSStephen Boyd /* Walk up the tree of devices looking for a clock property that matches */
51654472287aSStephen Boyd while (np) {
51664472287aSStephen Boyd /*
51674472287aSStephen Boyd * For named clocks, first look up the name in the
51684472287aSStephen Boyd * "clock-names" property. If it cannot be found, then index
51694472287aSStephen Boyd * will be an error code and of_parse_phandle_with_args() will
51704472287aSStephen Boyd * return -EINVAL.
51714472287aSStephen Boyd */
51724472287aSStephen Boyd if (name)
51734472287aSStephen Boyd index = of_property_match_string(np, "clock-names", name);
51744472287aSStephen Boyd ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells",
51754472287aSStephen Boyd index, out_args);
51764472287aSStephen Boyd if (!ret)
51774472287aSStephen Boyd break;
51784472287aSStephen Boyd if (name && index >= 0)
51794472287aSStephen Boyd break;
51804472287aSStephen Boyd
51814472287aSStephen Boyd /*
51824472287aSStephen Boyd * No matching clock found on this node. If the parent node
51834472287aSStephen Boyd * has a "clock-ranges" property, then we can try one of its
51844472287aSStephen Boyd * clocks.
51854472287aSStephen Boyd */
51864472287aSStephen Boyd np = np->parent;
51874472287aSStephen Boyd if (np && !of_get_property(np, "clock-ranges", NULL))
51884472287aSStephen Boyd break;
51894472287aSStephen Boyd index = 0;
51904472287aSStephen Boyd }
51914472287aSStephen Boyd
51924472287aSStephen Boyd return ret;
51934472287aSStephen Boyd }
51944472287aSStephen Boyd
51950861e5b8SStephen Boyd static struct clk_hw *
__of_clk_get_hw_from_provider(struct of_clk_provider * provider,struct of_phandle_args * clkspec)51960861e5b8SStephen Boyd __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
51970861e5b8SStephen Boyd struct of_phandle_args *clkspec)
51980861e5b8SStephen Boyd {
51990861e5b8SStephen Boyd struct clk *clk;
52000861e5b8SStephen Boyd
520174002fcdSStephen Boyd if (provider->get_hw)
520274002fcdSStephen Boyd return provider->get_hw(clkspec, provider->data);
520374002fcdSStephen Boyd
52040861e5b8SStephen Boyd clk = provider->get(clkspec, provider->data);
520574002fcdSStephen Boyd if (IS_ERR(clk))
520674002fcdSStephen Boyd return ERR_CAST(clk);
520774002fcdSStephen Boyd return __clk_get_hw(clk);
52080861e5b8SStephen Boyd }
52090861e5b8SStephen Boyd
5210cf13f289SStephen Boyd static struct clk_hw *
of_clk_get_hw_from_clkspec(struct of_phandle_args * clkspec)5211cf13f289SStephen Boyd of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
5212766e6a4eSGrant Likely {
5213766e6a4eSGrant Likely struct of_clk_provider *provider;
52141df4046aSStephen Boyd struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
5215766e6a4eSGrant Likely
5216306c342fSStephen Boyd if (!clkspec)
5217306c342fSStephen Boyd return ERR_PTR(-EINVAL);
5218306c342fSStephen Boyd
5219306c342fSStephen Boyd mutex_lock(&of_clk_mutex);
5220766e6a4eSGrant Likely list_for_each_entry(provider, &of_clk_providers, link) {
5221f155d15bSStephen Boyd if (provider->node == clkspec->np) {
52220861e5b8SStephen Boyd hw = __of_clk_get_hw_from_provider(provider, clkspec);
52231df4046aSStephen Boyd if (!IS_ERR(hw))
5224766e6a4eSGrant Likely break;
5225766e6a4eSGrant Likely }
522673e0e496SStephen Boyd }
5227306c342fSStephen Boyd mutex_unlock(&of_clk_mutex);
5228d6782c26SSylwester Nawrocki
52294472287aSStephen Boyd return hw;
5230d6782c26SSylwester Nawrocki }
5231d6782c26SSylwester Nawrocki
5232306c342fSStephen Boyd /**
5233306c342fSStephen Boyd * of_clk_get_from_provider() - Lookup a clock from a clock provider
5234306c342fSStephen Boyd * @clkspec: pointer to a clock specifier data structure
5235306c342fSStephen Boyd *
5236306c342fSStephen Boyd * This function looks up a struct clk from the registered list of clock
5237306c342fSStephen Boyd * providers, an input is a clock specifier data structure as returned
5238306c342fSStephen Boyd * from the of_parse_phandle_with_args() function call.
5239306c342fSStephen Boyd */
of_clk_get_from_provider(struct of_phandle_args * clkspec)5240d6782c26SSylwester Nawrocki struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
5241d6782c26SSylwester Nawrocki {
52424472287aSStephen Boyd struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec);
52434472287aSStephen Boyd
5244efa85048SStephen Boyd return clk_hw_create_clk(NULL, hw, NULL, __func__);
5245766e6a4eSGrant Likely }
5246fb4dd222SAndrew F. Davis EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
5247766e6a4eSGrant Likely
of_clk_get_hw(struct device_node * np,int index,const char * con_id)5248cf13f289SStephen Boyd struct clk_hw *of_clk_get_hw(struct device_node *np, int index,
5249cf13f289SStephen Boyd const char *con_id)
5250cf13f289SStephen Boyd {
5251cf13f289SStephen Boyd int ret;
5252cf13f289SStephen Boyd struct clk_hw *hw;
5253cf13f289SStephen Boyd struct of_phandle_args clkspec;
5254cf13f289SStephen Boyd
5255cf13f289SStephen Boyd ret = of_parse_clkspec(np, index, con_id, &clkspec);
5256cf13f289SStephen Boyd if (ret)
5257cf13f289SStephen Boyd return ERR_PTR(ret);
5258cf13f289SStephen Boyd
5259cf13f289SStephen Boyd hw = of_clk_get_hw_from_clkspec(&clkspec);
5260cf13f289SStephen Boyd of_node_put(clkspec.np);
5261cf13f289SStephen Boyd
5262cf13f289SStephen Boyd return hw;
5263cf13f289SStephen Boyd }
5264cf13f289SStephen Boyd
__of_clk_get(struct device_node * np,int index,const char * dev_id,const char * con_id)5265cf13f289SStephen Boyd static struct clk *__of_clk_get(struct device_node *np,
5266cf13f289SStephen Boyd int index, const char *dev_id,
5267cf13f289SStephen Boyd const char *con_id)
5268cf13f289SStephen Boyd {
5269cf13f289SStephen Boyd struct clk_hw *hw = of_clk_get_hw(np, index, con_id);
5270cf13f289SStephen Boyd
5271cf13f289SStephen Boyd return clk_hw_create_clk(NULL, hw, dev_id, con_id);
5272cf13f289SStephen Boyd }
5273cf13f289SStephen Boyd
of_clk_get(struct device_node * np,int index)5274cf13f289SStephen Boyd struct clk *of_clk_get(struct device_node *np, int index)
5275cf13f289SStephen Boyd {
5276cf13f289SStephen Boyd return __of_clk_get(np, index, np->full_name, NULL);
5277cf13f289SStephen Boyd }
5278cf13f289SStephen Boyd EXPORT_SYMBOL(of_clk_get);
5279cf13f289SStephen Boyd
5280cf13f289SStephen Boyd /**
5281cf13f289SStephen Boyd * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
5282cf13f289SStephen Boyd * @np: pointer to clock consumer node
5283cf13f289SStephen Boyd * @name: name of consumer's clock input, or NULL for the first clock reference
5284cf13f289SStephen Boyd *
5285cf13f289SStephen Boyd * This function parses the clocks and clock-names properties,
5286cf13f289SStephen Boyd * and uses them to look up the struct clk from the registered list of clock
5287cf13f289SStephen Boyd * providers.
5288cf13f289SStephen Boyd */
of_clk_get_by_name(struct device_node * np,const char * name)5289cf13f289SStephen Boyd struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
5290cf13f289SStephen Boyd {
5291cf13f289SStephen Boyd if (!np)
5292cf13f289SStephen Boyd return ERR_PTR(-ENOENT);
5293cf13f289SStephen Boyd
529465cf20adSKuninori Morimoto return __of_clk_get(np, 0, np->full_name, name);
5295cf13f289SStephen Boyd }
5296cf13f289SStephen Boyd EXPORT_SYMBOL(of_clk_get_by_name);
5297cf13f289SStephen Boyd
5298929e7f3bSStephen Boyd /**
5299929e7f3bSStephen Boyd * of_clk_get_parent_count() - Count the number of clocks a device node has
5300929e7f3bSStephen Boyd * @np: device node to count
5301929e7f3bSStephen Boyd *
5302929e7f3bSStephen Boyd * Returns: The number of clocks that are possible parents of this node
5303929e7f3bSStephen Boyd */
of_clk_get_parent_count(const struct device_node * np)53044a4472fdSGeert Uytterhoeven unsigned int of_clk_get_parent_count(const struct device_node *np)
5305f6102742SMike Turquette {
5306929e7f3bSStephen Boyd int count;
5307929e7f3bSStephen Boyd
5308929e7f3bSStephen Boyd count = of_count_phandle_with_args(np, "clocks", "#clock-cells");
5309929e7f3bSStephen Boyd if (count < 0)
5310929e7f3bSStephen Boyd return 0;
5311929e7f3bSStephen Boyd
5312929e7f3bSStephen Boyd return count;
5313f6102742SMike Turquette }
5314f6102742SMike Turquette EXPORT_SYMBOL_GPL(of_clk_get_parent_count);
5315f6102742SMike Turquette
of_clk_get_parent_name(const struct device_node * np,int index)53164a4472fdSGeert Uytterhoeven const char *of_clk_get_parent_name(const struct device_node *np, int index)
5317766e6a4eSGrant Likely {
5318766e6a4eSGrant Likely struct of_phandle_args clkspec;
5319766e6a4eSGrant Likely const char *clk_name;
5320914ef7d1SLuca Ceresoli bool found = false;
53217a0fc1a3SBen Dooks u32 pv;
5322766e6a4eSGrant Likely int rc;
53237a0fc1a3SBen Dooks int count;
53240a4807c2SStephen Boyd struct clk *clk;
5325766e6a4eSGrant Likely
5326766e6a4eSGrant Likely rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
5327766e6a4eSGrant Likely &clkspec);
5328766e6a4eSGrant Likely if (rc)
5329766e6a4eSGrant Likely return NULL;
5330766e6a4eSGrant Likely
53317a0fc1a3SBen Dooks index = clkspec.args_count ? clkspec.args[0] : 0;
53327a0fc1a3SBen Dooks count = 0;
53337a0fc1a3SBen Dooks
53347a0fc1a3SBen Dooks /* if there is an indices property, use it to transfer the index
53357a0fc1a3SBen Dooks * specified into an array offset for the clock-output-names property.
53367a0fc1a3SBen Dooks */
5337914ef7d1SLuca Ceresoli of_property_for_each_u32(clkspec.np, "clock-indices", pv) {
53387a0fc1a3SBen Dooks if (index == pv) {
53397a0fc1a3SBen Dooks index = count;
5340914ef7d1SLuca Ceresoli found = true;
53417a0fc1a3SBen Dooks break;
53427a0fc1a3SBen Dooks }
53437a0fc1a3SBen Dooks count++;
53447a0fc1a3SBen Dooks }
53458da411ccSMasahiro Yamada /* We went off the end of 'clock-indices' without finding it */
5346*1ffbe3a0SJoe Hattori if (of_property_present(clkspec.np, "clock-indices") && !found) {
5347*1ffbe3a0SJoe Hattori of_node_put(clkspec.np);
53488da411ccSMasahiro Yamada return NULL;
5349*1ffbe3a0SJoe Hattori }
53507a0fc1a3SBen Dooks
5351766e6a4eSGrant Likely if (of_property_read_string_index(clkspec.np, "clock-output-names",
53527a0fc1a3SBen Dooks index,
53530a4807c2SStephen Boyd &clk_name) < 0) {
53540a4807c2SStephen Boyd /*
53550a4807c2SStephen Boyd * Best effort to get the name if the clock has been
53560a4807c2SStephen Boyd * registered with the framework. If the clock isn't
53570a4807c2SStephen Boyd * registered, we return the node name as the name of
53580a4807c2SStephen Boyd * the clock as long as #clock-cells = 0.
53590a4807c2SStephen Boyd */
53600a4807c2SStephen Boyd clk = of_clk_get_from_provider(&clkspec);
53610a4807c2SStephen Boyd if (IS_ERR(clk)) {
53620a4807c2SStephen Boyd if (clkspec.args_count == 0)
5363766e6a4eSGrant Likely clk_name = clkspec.np->name;
53640a4807c2SStephen Boyd else
53650a4807c2SStephen Boyd clk_name = NULL;
53660a4807c2SStephen Boyd } else {
53670a4807c2SStephen Boyd clk_name = __clk_get_name(clk);
53680a4807c2SStephen Boyd clk_put(clk);
53690a4807c2SStephen Boyd }
53700a4807c2SStephen Boyd }
53710a4807c2SStephen Boyd
5372766e6a4eSGrant Likely
5373766e6a4eSGrant Likely of_node_put(clkspec.np);
5374766e6a4eSGrant Likely return clk_name;
5375766e6a4eSGrant Likely }
5376766e6a4eSGrant Likely EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
5377766e6a4eSGrant Likely
53782e61dfb3SDinh Nguyen /**
53792e61dfb3SDinh Nguyen * of_clk_parent_fill() - Fill @parents with names of @np's parents and return
53802e61dfb3SDinh Nguyen * number of parents
53812e61dfb3SDinh Nguyen * @np: Device node pointer associated with clock provider
53822e61dfb3SDinh Nguyen * @parents: pointer to char array that hold the parents' names
53832e61dfb3SDinh Nguyen * @size: size of the @parents array
53842e61dfb3SDinh Nguyen *
53852e61dfb3SDinh Nguyen * Return: number of parents for the clock node.
53862e61dfb3SDinh Nguyen */
of_clk_parent_fill(struct device_node * np,const char ** parents,unsigned int size)53872e61dfb3SDinh Nguyen int of_clk_parent_fill(struct device_node *np, const char **parents,
53882e61dfb3SDinh Nguyen unsigned int size)
53892e61dfb3SDinh Nguyen {
53902e61dfb3SDinh Nguyen unsigned int i = 0;
53912e61dfb3SDinh Nguyen
53922e61dfb3SDinh Nguyen while (i < size && (parents[i] = of_clk_get_parent_name(np, i)) != NULL)
53932e61dfb3SDinh Nguyen i++;
53942e61dfb3SDinh Nguyen
53952e61dfb3SDinh Nguyen return i;
53962e61dfb3SDinh Nguyen }
53972e61dfb3SDinh Nguyen EXPORT_SYMBOL_GPL(of_clk_parent_fill);
53982e61dfb3SDinh Nguyen
53991771b10dSGregory CLEMENT struct clock_provider {
5400a5970433SGeert Uytterhoeven void (*clk_init_cb)(struct device_node *);
54011771b10dSGregory CLEMENT struct device_node *np;
54021771b10dSGregory CLEMENT struct list_head node;
54031771b10dSGregory CLEMENT };
54041771b10dSGregory CLEMENT
54051771b10dSGregory CLEMENT /*
54061771b10dSGregory CLEMENT * This function looks for a parent clock. If there is one, then it
54071771b10dSGregory CLEMENT * checks that the provider for this parent clock was initialized, in
54081771b10dSGregory CLEMENT * this case the parent clock will be ready.
54091771b10dSGregory CLEMENT */
parent_ready(struct device_node * np)54101771b10dSGregory CLEMENT static int parent_ready(struct device_node *np)
54111771b10dSGregory CLEMENT {
54121771b10dSGregory CLEMENT int i = 0;
54131771b10dSGregory CLEMENT
54141771b10dSGregory CLEMENT while (true) {
54151771b10dSGregory CLEMENT struct clk *clk = of_clk_get(np, i);
54161771b10dSGregory CLEMENT
54171771b10dSGregory CLEMENT /* this parent is ready we can check the next one */
54181771b10dSGregory CLEMENT if (!IS_ERR(clk)) {
54191771b10dSGregory CLEMENT clk_put(clk);
54201771b10dSGregory CLEMENT i++;
54211771b10dSGregory CLEMENT continue;
54221771b10dSGregory CLEMENT }
54231771b10dSGregory CLEMENT
54241771b10dSGregory CLEMENT /* at least one parent is not ready, we exit now */
54251771b10dSGregory CLEMENT if (PTR_ERR(clk) == -EPROBE_DEFER)
54261771b10dSGregory CLEMENT return 0;
54271771b10dSGregory CLEMENT
54281771b10dSGregory CLEMENT /*
54291771b10dSGregory CLEMENT * Here we make assumption that the device tree is
54301771b10dSGregory CLEMENT * written correctly. So an error means that there is
54311771b10dSGregory CLEMENT * no more parent. As we didn't exit yet, then the
54321771b10dSGregory CLEMENT * previous parent are ready. If there is no clock
54331771b10dSGregory CLEMENT * parent, no need to wait for them, then we can
54341771b10dSGregory CLEMENT * consider their absence as being ready
54351771b10dSGregory CLEMENT */
54361771b10dSGregory CLEMENT return 1;
54371771b10dSGregory CLEMENT }
54381771b10dSGregory CLEMENT }
54391771b10dSGregory CLEMENT
5440766e6a4eSGrant Likely /**
5441d56f8994SLee Jones * of_clk_detect_critical() - set CLK_IS_CRITICAL flag from Device Tree
5442d56f8994SLee Jones * @np: Device node pointer associated with clock provider
5443d56f8994SLee Jones * @index: clock index
5444f7ae7503SGeert Uytterhoeven * @flags: pointer to top-level framework flags
5445d56f8994SLee Jones *
5446d56f8994SLee Jones * Detects if the clock-critical property exists and, if so, sets the
5447d56f8994SLee Jones * corresponding CLK_IS_CRITICAL flag.
5448d56f8994SLee Jones *
5449d56f8994SLee Jones * Do not use this function. It exists only for legacy Device Tree
5450d56f8994SLee Jones * bindings, such as the one-clock-per-node style that are outdated.
5451d56f8994SLee Jones * Those bindings typically put all clock data into .dts and the Linux
5452d56f8994SLee Jones * driver has no clock data, thus making it impossible to set this flag
5453d56f8994SLee Jones * correctly from the driver. Only those drivers may call
5454d56f8994SLee Jones * of_clk_detect_critical from their setup functions.
5455d56f8994SLee Jones *
5456d56f8994SLee Jones * Return: error code or zero on success
5457d56f8994SLee Jones */
of_clk_detect_critical(struct device_node * np,int index,unsigned long * flags)5458be545c79SGeert Uytterhoeven int of_clk_detect_critical(struct device_node *np, int index,
5459be545c79SGeert Uytterhoeven unsigned long *flags)
5460d56f8994SLee Jones {
5461d56f8994SLee Jones uint32_t idx;
5462d56f8994SLee Jones
5463d56f8994SLee Jones if (!np || !flags)
5464d56f8994SLee Jones return -EINVAL;
5465d56f8994SLee Jones
5466914ef7d1SLuca Ceresoli of_property_for_each_u32(np, "clock-critical", idx)
5467d56f8994SLee Jones if (index == idx)
5468d56f8994SLee Jones *flags |= CLK_IS_CRITICAL;
5469d56f8994SLee Jones
5470d56f8994SLee Jones return 0;
5471d56f8994SLee Jones }
5472d56f8994SLee Jones
5473d56f8994SLee Jones /**
5474766e6a4eSGrant Likely * of_clk_init() - Scan and init clock providers from the DT
5475766e6a4eSGrant Likely * @matches: array of compatible values and init functions for providers.
5476766e6a4eSGrant Likely *
54771771b10dSGregory CLEMENT * This function scans the device tree for matching clock providers
5478e5ca8fb4SSylwester Nawrocki * and calls their initialization functions. It also does it by trying
54791771b10dSGregory CLEMENT * to follow the dependencies.
5480766e6a4eSGrant Likely */
of_clk_init(const struct of_device_id * matches)5481766e6a4eSGrant Likely void __init of_clk_init(const struct of_device_id *matches)
5482766e6a4eSGrant Likely {
54837f7ed584SAlex Elder const struct of_device_id *match;
5484766e6a4eSGrant Likely struct device_node *np;
54851771b10dSGregory CLEMENT struct clock_provider *clk_provider, *next;
54861771b10dSGregory CLEMENT bool is_init_done;
54871771b10dSGregory CLEMENT bool force = false;
54882573a02aSStephen Boyd LIST_HEAD(clk_provider_list);
5489766e6a4eSGrant Likely
5490f2f6c255SPrashant Gaikwad if (!matches)
5491819b4861STero Kristo matches = &__clk_of_table;
5492f2f6c255SPrashant Gaikwad
54931771b10dSGregory CLEMENT /* First prepare the list of the clocks providers */
54947f7ed584SAlex Elder for_each_matching_node_and_match(np, matches, &match) {
54952e3b19f1SStephen Boyd struct clock_provider *parent;
54962e3b19f1SStephen Boyd
54973e5dd6f6SGeert Uytterhoeven if (!of_device_is_available(np))
54983e5dd6f6SGeert Uytterhoeven continue;
54993e5dd6f6SGeert Uytterhoeven
55002e3b19f1SStephen Boyd parent = kzalloc(sizeof(*parent), GFP_KERNEL);
55012e3b19f1SStephen Boyd if (!parent) {
55022e3b19f1SStephen Boyd list_for_each_entry_safe(clk_provider, next,
55032e3b19f1SStephen Boyd &clk_provider_list, node) {
55042e3b19f1SStephen Boyd list_del(&clk_provider->node);
55056bc9d9d6SJulia Lawall of_node_put(clk_provider->np);
55062e3b19f1SStephen Boyd kfree(clk_provider);
55072e3b19f1SStephen Boyd }
55086bc9d9d6SJulia Lawall of_node_put(np);
55092e3b19f1SStephen Boyd return;
55102e3b19f1SStephen Boyd }
55111771b10dSGregory CLEMENT
55121771b10dSGregory CLEMENT parent->clk_init_cb = match->data;
55136bc9d9d6SJulia Lawall parent->np = of_node_get(np);
55143f6d439fSSylwester Nawrocki list_add_tail(&parent->node, &clk_provider_list);
55151771b10dSGregory CLEMENT }
55161771b10dSGregory CLEMENT
55171771b10dSGregory CLEMENT while (!list_empty(&clk_provider_list)) {
55181771b10dSGregory CLEMENT is_init_done = false;
55191771b10dSGregory CLEMENT list_for_each_entry_safe(clk_provider, next,
55201771b10dSGregory CLEMENT &clk_provider_list, node) {
55211771b10dSGregory CLEMENT if (force || parent_ready(clk_provider->np)) {
552286be408bSSylwester Nawrocki
5523989eafd0SRicardo Ribalda Delgado /* Don't populate platform devices */
5524989eafd0SRicardo Ribalda Delgado of_node_set_flag(clk_provider->np,
5525989eafd0SRicardo Ribalda Delgado OF_POPULATED);
5526989eafd0SRicardo Ribalda Delgado
55271771b10dSGregory CLEMENT clk_provider->clk_init_cb(clk_provider->np);
552886be408bSSylwester Nawrocki of_clk_set_defaults(clk_provider->np, true);
552986be408bSSylwester Nawrocki
55301771b10dSGregory CLEMENT list_del(&clk_provider->node);
55316bc9d9d6SJulia Lawall of_node_put(clk_provider->np);
55321771b10dSGregory CLEMENT kfree(clk_provider);
55331771b10dSGregory CLEMENT is_init_done = true;
55341771b10dSGregory CLEMENT }
55351771b10dSGregory CLEMENT }
55361771b10dSGregory CLEMENT
55371771b10dSGregory CLEMENT /*
5538e5ca8fb4SSylwester Nawrocki * We didn't manage to initialize any of the
55391771b10dSGregory CLEMENT * remaining providers during the last loop, so now we
55401771b10dSGregory CLEMENT * initialize all the remaining ones unconditionally
55411771b10dSGregory CLEMENT * in case the clock parent was not mandatory
55421771b10dSGregory CLEMENT */
55431771b10dSGregory CLEMENT if (!is_init_done)
55441771b10dSGregory CLEMENT force = true;
5545766e6a4eSGrant Likely }
5546766e6a4eSGrant Likely }
5547766e6a4eSGrant Likely #endif
5548