118bcaa4eSMauro Carvalho Chehab========================
218bcaa4eSMauro Carvalho ChehabThe Common Clk Framework
318bcaa4eSMauro Carvalho Chehab========================
418bcaa4eSMauro Carvalho Chehab
518bcaa4eSMauro Carvalho Chehab:Author: Mike Turquette <mturquette@ti.com>
618bcaa4eSMauro Carvalho Chehab
718bcaa4eSMauro Carvalho ChehabThis document endeavours to explain the common clk framework details,
818bcaa4eSMauro Carvalho Chehaband how to port a platform over to this framework.  It is not yet a
918bcaa4eSMauro Carvalho Chehabdetailed explanation of the clock api in include/linux/clk.h, but
1018bcaa4eSMauro Carvalho Chehabperhaps someday it will include that information.
1118bcaa4eSMauro Carvalho Chehab
1218bcaa4eSMauro Carvalho ChehabIntroduction and interface split
1318bcaa4eSMauro Carvalho Chehab================================
1418bcaa4eSMauro Carvalho Chehab
1518bcaa4eSMauro Carvalho ChehabThe common clk framework is an interface to control the clock nodes
1618bcaa4eSMauro Carvalho Chehabavailable on various devices today.  This may come in the form of clock
1718bcaa4eSMauro Carvalho Chehabgating, rate adjustment, muxing or other operations.  This framework is
1818bcaa4eSMauro Carvalho Chehabenabled with the CONFIG_COMMON_CLK option.
1918bcaa4eSMauro Carvalho Chehab
2018bcaa4eSMauro Carvalho ChehabThe interface itself is divided into two halves, each shielded from the
2118bcaa4eSMauro Carvalho Chehabdetails of its counterpart.  First is the common definition of struct
2218bcaa4eSMauro Carvalho Chehabclk which unifies the framework-level accounting and infrastructure that
2318bcaa4eSMauro Carvalho Chehabhas traditionally been duplicated across a variety of platforms.  Second
2418bcaa4eSMauro Carvalho Chehabis a common implementation of the clk.h api, defined in
2518bcaa4eSMauro Carvalho Chehabdrivers/clk/clk.c.  Finally there is struct clk_ops, whose operations
2618bcaa4eSMauro Carvalho Chehabare invoked by the clk api implementation.
2718bcaa4eSMauro Carvalho Chehab
2818bcaa4eSMauro Carvalho ChehabThe second half of the interface is comprised of the hardware-specific
2918bcaa4eSMauro Carvalho Chehabcallbacks registered with struct clk_ops and the corresponding
3018bcaa4eSMauro Carvalho Chehabhardware-specific structures needed to model a particular clock.  For
3118bcaa4eSMauro Carvalho Chehabthe remainder of this document any reference to a callback in struct
3218bcaa4eSMauro Carvalho Chehabclk_ops, such as .enable or .set_rate, implies the hardware-specific
3318bcaa4eSMauro Carvalho Chehabimplementation of that code.  Likewise, references to struct clk_foo
3418bcaa4eSMauro Carvalho Chehabserve as a convenient shorthand for the implementation of the
3518bcaa4eSMauro Carvalho Chehabhardware-specific bits for the hypothetical "foo" hardware.
3618bcaa4eSMauro Carvalho Chehab
3718bcaa4eSMauro Carvalho ChehabTying the two halves of this interface together is struct clk_hw, which
3818bcaa4eSMauro Carvalho Chehabis defined in struct clk_foo and pointed to within struct clk_core.  This
3918bcaa4eSMauro Carvalho Chehaballows for easy navigation between the two discrete halves of the common
4018bcaa4eSMauro Carvalho Chehabclock interface.
4118bcaa4eSMauro Carvalho Chehab
4218bcaa4eSMauro Carvalho ChehabCommon data structures and api
4318bcaa4eSMauro Carvalho Chehab==============================
4418bcaa4eSMauro Carvalho Chehab
4518bcaa4eSMauro Carvalho ChehabBelow is the common struct clk_core definition from
4618bcaa4eSMauro Carvalho Chehabdrivers/clk/clk.c, modified for brevity::
4718bcaa4eSMauro Carvalho Chehab
4818bcaa4eSMauro Carvalho Chehab	struct clk_core {
4918bcaa4eSMauro Carvalho Chehab		const char		*name;
5018bcaa4eSMauro Carvalho Chehab		const struct clk_ops	*ops;
5118bcaa4eSMauro Carvalho Chehab		struct clk_hw		*hw;
5218bcaa4eSMauro Carvalho Chehab		struct module		*owner;
5318bcaa4eSMauro Carvalho Chehab		struct clk_core		*parent;
5418bcaa4eSMauro Carvalho Chehab		const char		**parent_names;
5518bcaa4eSMauro Carvalho Chehab		struct clk_core		**parents;
5618bcaa4eSMauro Carvalho Chehab		u8			num_parents;
5718bcaa4eSMauro Carvalho Chehab		u8			new_parent_index;
5818bcaa4eSMauro Carvalho Chehab		...
5918bcaa4eSMauro Carvalho Chehab	};
6018bcaa4eSMauro Carvalho Chehab
6118bcaa4eSMauro Carvalho ChehabThe members above make up the core of the clk tree topology.  The clk
6218bcaa4eSMauro Carvalho Chehabapi itself defines several driver-facing functions which operate on
6318bcaa4eSMauro Carvalho Chehabstruct clk.  That api is documented in include/linux/clk.h.
6418bcaa4eSMauro Carvalho Chehab
6518bcaa4eSMauro Carvalho ChehabPlatforms and devices utilizing the common struct clk_core use the struct
6618bcaa4eSMauro Carvalho Chehabclk_ops pointer in struct clk_core to perform the hardware-specific parts of
6718bcaa4eSMauro Carvalho Chehabthe operations defined in clk-provider.h::
6818bcaa4eSMauro Carvalho Chehab
6918bcaa4eSMauro Carvalho Chehab	struct clk_ops {
7018bcaa4eSMauro Carvalho Chehab		int		(*prepare)(struct clk_hw *hw);
7118bcaa4eSMauro Carvalho Chehab		void		(*unprepare)(struct clk_hw *hw);
7218bcaa4eSMauro Carvalho Chehab		int		(*is_prepared)(struct clk_hw *hw);
7318bcaa4eSMauro Carvalho Chehab		void		(*unprepare_unused)(struct clk_hw *hw);
7418bcaa4eSMauro Carvalho Chehab		int		(*enable)(struct clk_hw *hw);
7518bcaa4eSMauro Carvalho Chehab		void		(*disable)(struct clk_hw *hw);
7618bcaa4eSMauro Carvalho Chehab		int		(*is_enabled)(struct clk_hw *hw);
7718bcaa4eSMauro Carvalho Chehab		void		(*disable_unused)(struct clk_hw *hw);
7818bcaa4eSMauro Carvalho Chehab		unsigned long	(*recalc_rate)(struct clk_hw *hw,
7918bcaa4eSMauro Carvalho Chehab						unsigned long parent_rate);
8018bcaa4eSMauro Carvalho Chehab		long		(*round_rate)(struct clk_hw *hw,
8118bcaa4eSMauro Carvalho Chehab						unsigned long rate,
8218bcaa4eSMauro Carvalho Chehab						unsigned long *parent_rate);
8318bcaa4eSMauro Carvalho Chehab		int		(*determine_rate)(struct clk_hw *hw,
8418bcaa4eSMauro Carvalho Chehab						  struct clk_rate_request *req);
8518bcaa4eSMauro Carvalho Chehab		int		(*set_parent)(struct clk_hw *hw, u8 index);
8618bcaa4eSMauro Carvalho Chehab		u8		(*get_parent)(struct clk_hw *hw);
8718bcaa4eSMauro Carvalho Chehab		int		(*set_rate)(struct clk_hw *hw,
8818bcaa4eSMauro Carvalho Chehab					    unsigned long rate,
8918bcaa4eSMauro Carvalho Chehab					    unsigned long parent_rate);
9018bcaa4eSMauro Carvalho Chehab		int		(*set_rate_and_parent)(struct clk_hw *hw,
9118bcaa4eSMauro Carvalho Chehab					    unsigned long rate,
9218bcaa4eSMauro Carvalho Chehab					    unsigned long parent_rate,
9318bcaa4eSMauro Carvalho Chehab					    u8 index);
9418bcaa4eSMauro Carvalho Chehab		unsigned long	(*recalc_accuracy)(struct clk_hw *hw,
9518bcaa4eSMauro Carvalho Chehab						unsigned long parent_accuracy);
9618bcaa4eSMauro Carvalho Chehab		int		(*get_phase)(struct clk_hw *hw);
9718bcaa4eSMauro Carvalho Chehab		int		(*set_phase)(struct clk_hw *hw, int degrees);
9818bcaa4eSMauro Carvalho Chehab		void		(*init)(struct clk_hw *hw);
996419945eSLinus Torvalds		void		(*debug_init)(struct clk_hw *hw,
10018bcaa4eSMauro Carvalho Chehab					      struct dentry *dentry);
10118bcaa4eSMauro Carvalho Chehab	};
10218bcaa4eSMauro Carvalho Chehab
10318bcaa4eSMauro Carvalho ChehabHardware clk implementations
10418bcaa4eSMauro Carvalho Chehab============================
10518bcaa4eSMauro Carvalho Chehab
10618bcaa4eSMauro Carvalho ChehabThe strength of the common struct clk_core comes from its .ops and .hw pointers
10718bcaa4eSMauro Carvalho Chehabwhich abstract the details of struct clk from the hardware-specific bits, and
10818bcaa4eSMauro Carvalho Chehabvice versa.  To illustrate consider the simple gateable clk implementation in
10918bcaa4eSMauro Carvalho Chehabdrivers/clk/clk-gate.c::
11018bcaa4eSMauro Carvalho Chehab
11118bcaa4eSMauro Carvalho Chehab	struct clk_gate {
11218bcaa4eSMauro Carvalho Chehab		struct clk_hw	hw;
11318bcaa4eSMauro Carvalho Chehab		void __iomem    *reg;
11418bcaa4eSMauro Carvalho Chehab		u8              bit_idx;
11518bcaa4eSMauro Carvalho Chehab		...
11618bcaa4eSMauro Carvalho Chehab	};
11718bcaa4eSMauro Carvalho Chehab
11818bcaa4eSMauro Carvalho Chehabstruct clk_gate contains struct clk_hw hw as well as hardware-specific
11918bcaa4eSMauro Carvalho Chehabknowledge about which register and bit controls this clk's gating.
12018bcaa4eSMauro Carvalho ChehabNothing about clock topology or accounting, such as enable_count or
12118bcaa4eSMauro Carvalho Chehabnotifier_count, is needed here.  That is all handled by the common
12218bcaa4eSMauro Carvalho Chehabframework code and struct clk_core.
12318bcaa4eSMauro Carvalho Chehab
12418bcaa4eSMauro Carvalho ChehabLet's walk through enabling this clk from driver code::
12518bcaa4eSMauro Carvalho Chehab
12618bcaa4eSMauro Carvalho Chehab	struct clk *clk;
12718bcaa4eSMauro Carvalho Chehab	clk = clk_get(NULL, "my_gateable_clk");
12818bcaa4eSMauro Carvalho Chehab
12918bcaa4eSMauro Carvalho Chehab	clk_prepare(clk);
13018bcaa4eSMauro Carvalho Chehab	clk_enable(clk);
13118bcaa4eSMauro Carvalho Chehab
13218bcaa4eSMauro Carvalho ChehabThe call graph for clk_enable is very simple::
13318bcaa4eSMauro Carvalho Chehab
13418bcaa4eSMauro Carvalho Chehab	clk_enable(clk);
13518bcaa4eSMauro Carvalho Chehab		clk->ops->enable(clk->hw);
13618bcaa4eSMauro Carvalho Chehab		[resolves to...]
13718bcaa4eSMauro Carvalho Chehab			clk_gate_enable(hw);
13818bcaa4eSMauro Carvalho Chehab			[resolves struct clk gate with to_clk_gate(hw)]
13918bcaa4eSMauro Carvalho Chehab				clk_gate_set_bit(gate);
14018bcaa4eSMauro Carvalho Chehab
14118bcaa4eSMauro Carvalho ChehabAnd the definition of clk_gate_set_bit::
14218bcaa4eSMauro Carvalho Chehab
14318bcaa4eSMauro Carvalho Chehab	static void clk_gate_set_bit(struct clk_gate *gate)
14418bcaa4eSMauro Carvalho Chehab	{
14518bcaa4eSMauro Carvalho Chehab		u32 reg;
14618bcaa4eSMauro Carvalho Chehab
14718bcaa4eSMauro Carvalho Chehab		reg = __raw_readl(gate->reg);
14818bcaa4eSMauro Carvalho Chehab		reg |= BIT(gate->bit_idx);
14918bcaa4eSMauro Carvalho Chehab		writel(reg, gate->reg);
15018bcaa4eSMauro Carvalho Chehab	}
15118bcaa4eSMauro Carvalho Chehab
15218bcaa4eSMauro Carvalho ChehabNote that to_clk_gate is defined as::
15318bcaa4eSMauro Carvalho Chehab
15418bcaa4eSMauro Carvalho Chehab	#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
15518bcaa4eSMauro Carvalho Chehab
15618bcaa4eSMauro Carvalho ChehabThis pattern of abstraction is used for every clock hardware
15718bcaa4eSMauro Carvalho Chehabrepresentation.
15818bcaa4eSMauro Carvalho Chehab
15918bcaa4eSMauro Carvalho ChehabSupporting your own clk hardware
16018bcaa4eSMauro Carvalho Chehab================================
16118bcaa4eSMauro Carvalho Chehab
16218bcaa4eSMauro Carvalho ChehabWhen implementing support for a new type of clock it is only necessary to
16318bcaa4eSMauro Carvalho Chehabinclude the following header::
16418bcaa4eSMauro Carvalho Chehab
16518bcaa4eSMauro Carvalho Chehab	#include <linux/clk-provider.h>
16618bcaa4eSMauro Carvalho Chehab
16718bcaa4eSMauro Carvalho ChehabTo construct a clk hardware structure for your platform you must define
16818bcaa4eSMauro Carvalho Chehabthe following::
16918bcaa4eSMauro Carvalho Chehab
17018bcaa4eSMauro Carvalho Chehab	struct clk_foo {
17118bcaa4eSMauro Carvalho Chehab		struct clk_hw hw;
17218bcaa4eSMauro Carvalho Chehab		... hardware specific data goes here ...
17318bcaa4eSMauro Carvalho Chehab	};
17418bcaa4eSMauro Carvalho Chehab
17518bcaa4eSMauro Carvalho ChehabTo take advantage of your data you'll need to support valid operations
17618bcaa4eSMauro Carvalho Chehabfor your clk::
17718bcaa4eSMauro Carvalho Chehab
17818bcaa4eSMauro Carvalho Chehab	struct clk_ops clk_foo_ops {
17918bcaa4eSMauro Carvalho Chehab		.enable		= &clk_foo_enable;
18018bcaa4eSMauro Carvalho Chehab		.disable	= &clk_foo_disable;
18118bcaa4eSMauro Carvalho Chehab	};
18218bcaa4eSMauro Carvalho Chehab
18318bcaa4eSMauro Carvalho ChehabImplement the above functions using container_of::
18418bcaa4eSMauro Carvalho Chehab
18518bcaa4eSMauro Carvalho Chehab	#define to_clk_foo(_hw) container_of(_hw, struct clk_foo, hw)
18618bcaa4eSMauro Carvalho Chehab
18718bcaa4eSMauro Carvalho Chehab	int clk_foo_enable(struct clk_hw *hw)
18818bcaa4eSMauro Carvalho Chehab	{
18918bcaa4eSMauro Carvalho Chehab		struct clk_foo *foo;
19018bcaa4eSMauro Carvalho Chehab
19118bcaa4eSMauro Carvalho Chehab		foo = to_clk_foo(hw);
19218bcaa4eSMauro Carvalho Chehab
19318bcaa4eSMauro Carvalho Chehab		... perform magic on foo ...
19418bcaa4eSMauro Carvalho Chehab
19518bcaa4eSMauro Carvalho Chehab		return 0;
19618bcaa4eSMauro Carvalho Chehab	};
19718bcaa4eSMauro Carvalho Chehab
19818bcaa4eSMauro Carvalho ChehabBelow is a matrix detailing which clk_ops are mandatory based upon the
19918bcaa4eSMauro Carvalho Chehabhardware capabilities of that clock.  A cell marked as "y" means
20018bcaa4eSMauro Carvalho Chehabmandatory, a cell marked as "n" implies that either including that
20118bcaa4eSMauro Carvalho Chehabcallback is invalid or otherwise unnecessary.  Empty cells are either
20218bcaa4eSMauro Carvalho Chehaboptional or must be evaluated on a case-by-case basis.
20318bcaa4eSMauro Carvalho Chehab
20418bcaa4eSMauro Carvalho Chehab.. table:: clock hardware characteristics
20518bcaa4eSMauro Carvalho Chehab
20618bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
20718bcaa4eSMauro Carvalho Chehab   |                | gate | change rate | single parent | multiplexer | root |
20818bcaa4eSMauro Carvalho Chehab   +================+======+=============+===============+=============+======+
20918bcaa4eSMauro Carvalho Chehab   |.prepare        |      |             |               |             |      |
21018bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
21118bcaa4eSMauro Carvalho Chehab   |.unprepare      |      |             |               |             |      |
21218bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
21318bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
21418bcaa4eSMauro Carvalho Chehab   |.enable         | y    |             |               |             |      |
21518bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
21618bcaa4eSMauro Carvalho Chehab   |.disable        | y    |             |               |             |      |
21718bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
21818bcaa4eSMauro Carvalho Chehab   |.is_enabled     | y    |             |               |             |      |
21918bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
22018bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
22118bcaa4eSMauro Carvalho Chehab   |.recalc_rate    |      | y           |               |             |      |
22218bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
22318bcaa4eSMauro Carvalho Chehab   |.round_rate     |      | y [1]_      |               |             |      |
22418bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
22518bcaa4eSMauro Carvalho Chehab   |.determine_rate |      | y [1]_      |               |             |      |
22618bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
22718bcaa4eSMauro Carvalho Chehab   |.set_rate       |      | y           |               |             |      |
22818bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
22918bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
23018bcaa4eSMauro Carvalho Chehab   |.set_parent     |      |             | n             | y           | n    |
23118bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
23218bcaa4eSMauro Carvalho Chehab   |.get_parent     |      |             | n             | y           | n    |
23318bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
23418bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
23518bcaa4eSMauro Carvalho Chehab   |.recalc_accuracy|      |             |               |             |      |
23618bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
23718bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
23818bcaa4eSMauro Carvalho Chehab   |.init           |      |             |               |             |      |
23918bcaa4eSMauro Carvalho Chehab   +----------------+------+-------------+---------------+-------------+------+
24018bcaa4eSMauro Carvalho Chehab
24118bcaa4eSMauro Carvalho Chehab.. [1] either one of round_rate or determine_rate is required.
24218bcaa4eSMauro Carvalho Chehab
24318bcaa4eSMauro Carvalho ChehabFinally, register your clock at run-time with a hardware-specific
24418bcaa4eSMauro Carvalho Chehabregistration function.  This function simply populates struct clk_foo's
24518bcaa4eSMauro Carvalho Chehabdata and then passes the common struct clk parameters to the framework
24618bcaa4eSMauro Carvalho Chehabwith a call to::
24718bcaa4eSMauro Carvalho Chehab
24818bcaa4eSMauro Carvalho Chehab	clk_register(...)
24918bcaa4eSMauro Carvalho Chehab
25018bcaa4eSMauro Carvalho ChehabSee the basic clock types in ``drivers/clk/clk-*.c`` for examples.
25118bcaa4eSMauro Carvalho Chehab
25218bcaa4eSMauro Carvalho ChehabDisabling clock gating of unused clocks
25318bcaa4eSMauro Carvalho Chehab=======================================
25418bcaa4eSMauro Carvalho Chehab
25518bcaa4eSMauro Carvalho ChehabSometimes during development it can be useful to be able to bypass the
25618bcaa4eSMauro Carvalho Chehabdefault disabling of unused clocks. For example, if drivers aren't enabling
25718bcaa4eSMauro Carvalho Chehabclocks properly but rely on them being on from the bootloader, bypassing
25818bcaa4eSMauro Carvalho Chehabthe disabling means that the driver will remain functional while the issues
25918bcaa4eSMauro Carvalho Chehabare sorted out.
26018bcaa4eSMauro Carvalho Chehab
26118bcaa4eSMauro Carvalho ChehabTo bypass this disabling, include "clk_ignore_unused" in the bootargs to the
26218bcaa4eSMauro Carvalho Chehabkernel.
26318bcaa4eSMauro Carvalho Chehab
26418bcaa4eSMauro Carvalho ChehabLocking
26518bcaa4eSMauro Carvalho Chehab=======
26618bcaa4eSMauro Carvalho Chehab
26718bcaa4eSMauro Carvalho ChehabThe common clock framework uses two global locks, the prepare lock and the
26818bcaa4eSMauro Carvalho Chehabenable lock.
26918bcaa4eSMauro Carvalho Chehab
27018bcaa4eSMauro Carvalho ChehabThe enable lock is a spinlock and is held across calls to the .enable,
27118bcaa4eSMauro Carvalho Chehab.disable operations. Those operations are thus not allowed to sleep,
27218bcaa4eSMauro Carvalho Chehaband calls to the clk_enable(), clk_disable() API functions are allowed in
27318bcaa4eSMauro Carvalho Chehabatomic context.
27418bcaa4eSMauro Carvalho Chehab
27518bcaa4eSMauro Carvalho ChehabFor clk_is_enabled() API, it is also designed to be allowed to be used in
27618bcaa4eSMauro Carvalho Chehabatomic context. However, it doesn't really make any sense to hold the enable
27718bcaa4eSMauro Carvalho Chehablock in core, unless you want to do something else with the information of
27818bcaa4eSMauro Carvalho Chehabthe enable state with that lock held. Otherwise, seeing if a clk is enabled is
27918bcaa4eSMauro Carvalho Chehaba one-shot read of the enabled state, which could just as easily change after
28018bcaa4eSMauro Carvalho Chehabthe function returns because the lock is released. Thus the user of this API
28118bcaa4eSMauro Carvalho Chehabneeds to handle synchronizing the read of the state with whatever they're
28218bcaa4eSMauro Carvalho Chehabusing it for to make sure that the enable state doesn't change during that
28318bcaa4eSMauro Carvalho Chehabtime.
28418bcaa4eSMauro Carvalho Chehab
28518bcaa4eSMauro Carvalho ChehabThe prepare lock is a mutex and is held across calls to all other operations.
28618bcaa4eSMauro Carvalho ChehabAll those operations are allowed to sleep, and calls to the corresponding API
28718bcaa4eSMauro Carvalho Chehabfunctions are not allowed in atomic context.
28818bcaa4eSMauro Carvalho Chehab
28918bcaa4eSMauro Carvalho ChehabThis effectively divides operations in two groups from a locking perspective.
29018bcaa4eSMauro Carvalho Chehab
29118bcaa4eSMauro Carvalho ChehabDrivers don't need to manually protect resources shared between the operations
29218bcaa4eSMauro Carvalho Chehabof one group, regardless of whether those resources are shared by multiple
29318bcaa4eSMauro Carvalho Chehabclocks or not. However, access to resources that are shared between operations
29418bcaa4eSMauro Carvalho Chehabof the two groups needs to be protected by the drivers. An example of such a
29518bcaa4eSMauro Carvalho Chehabresource would be a register that controls both the clock rate and the clock
29618bcaa4eSMauro Carvalho Chehabenable/disable state.
29718bcaa4eSMauro Carvalho Chehab
29818bcaa4eSMauro Carvalho ChehabThe clock framework is reentrant, in that a driver is allowed to call clock
29918bcaa4eSMauro Carvalho Chehabframework functions from within its implementation of clock operations. This
30018bcaa4eSMauro Carvalho Chehabcan for instance cause a .set_rate operation of one clock being called from
30118bcaa4eSMauro Carvalho Chehabwithin the .set_rate operation of another clock. This case must be considered
30218bcaa4eSMauro Carvalho Chehabin the driver implementations, but the code flow is usually controlled by the
30318bcaa4eSMauro Carvalho Chehabdriver in that case.
30418bcaa4eSMauro Carvalho Chehab
30518bcaa4eSMauro Carvalho ChehabNote that locking must also be considered when code outside of the common
30618bcaa4eSMauro Carvalho Chehabclock framework needs to access resources used by the clock operations. This
30718bcaa4eSMauro Carvalho Chehabis considered out of scope of this document.
308