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