Merge tag 'v4.4-rc7'
[firefly-linux-kernel-4.4.55.git] / Documentation / clk.txt
index 1c8406a2bae6aac7b01c302dc3e1095cbe6c2df5..5c4bc4d01d0c32939af28b3c0044f1700231d4a1 100644 (file)
@@ -32,7 +32,7 @@ hardware-specific bits for the hypothetical "foo" hardware.
 
 Tying the two halves of this interface together is struct clk_hw, which
 is defined in struct clk_foo and pointed to within struct clk.  This
 
 Tying the two halves of this interface together is struct clk_hw, which
 is defined in struct clk_foo and pointed to within struct clk.  This
-allows easy for navigation between the two discrete halves of the common
+allows for easy navigation between the two discrete halves of the common
 clock interface.
 
        Part 2 - common data structures and api
 clock interface.
 
        Part 2 - common data structures and api
@@ -68,16 +68,25 @@ the operations defined in clk.h:
                int             (*is_enabled)(struct clk_hw *hw);
                unsigned long   (*recalc_rate)(struct clk_hw *hw,
                                                unsigned long parent_rate);
                int             (*is_enabled)(struct clk_hw *hw);
                unsigned long   (*recalc_rate)(struct clk_hw *hw,
                                                unsigned long parent_rate);
-               long            (*round_rate)(struct clk_hw *hw, unsigned long,
-                                               unsigned long *);
-               long            (*determine_rate)(struct clk_hw *hw,
+               long            (*round_rate)(struct clk_hw *hw,
                                                unsigned long rate,
                                                unsigned long rate,
-                                               unsigned long *best_parent_rate,
-                                               struct clk **best_parent_clk);
+                                               unsigned long *parent_rate);
+               int             (*determine_rate)(struct clk_hw *hw,
+                                                 struct clk_rate_request *req);
                int             (*set_parent)(struct clk_hw *hw, u8 index);
                u8              (*get_parent)(struct clk_hw *hw);
                int             (*set_parent)(struct clk_hw *hw, u8 index);
                u8              (*get_parent)(struct clk_hw *hw);
-               int             (*set_rate)(struct clk_hw *hw, unsigned long);
+               int             (*set_rate)(struct clk_hw *hw,
+                                           unsigned long rate,
+                                           unsigned long parent_rate);
+               int             (*set_rate_and_parent)(struct clk_hw *hw,
+                                           unsigned long rate,
+                                           unsigned long parent_rate,
+                                           u8 index);
+               unsigned long   (*recalc_accuracy)(struct clk_hw *hw,
+                                               unsigned long parent_accuracy);
                void            (*init)(struct clk_hw *hw);
                void            (*init)(struct clk_hw *hw);
+               int             (*debug_init)(struct clk_hw *hw,
+                                             struct dentry *dentry);
        };
 
        Part 3 - hardware clk implementations
        };
 
        Part 3 - hardware clk implementations
@@ -202,6 +211,8 @@ optional or must be evaluated on a case-by-case basis.
 .set_parent     |      |             | n             | y           | n    |
 .get_parent     |      |             | n             | y           | n    |
                 |      |             |               |             |      |
 .set_parent     |      |             | n             | y           | n    |
 .get_parent     |      |             | n             | y           | n    |
                 |      |             |               |             |      |
+.recalc_accuracy|      |             |               |             |      |
+                |      |             |               |             |      |
 .init           |      |             |               |             |      |
                 -----------------------------------------------------------
 [1] either one of round_rate or determine_rate is required.
 .init           |      |             |               |             |      |
                 -----------------------------------------------------------
 [1] either one of round_rate or determine_rate is required.
@@ -215,30 +226,7 @@ clk_register(...)
 
 See the basic clock types in drivers/clk/clk-*.c for examples.
 
 
 See the basic clock types in drivers/clk/clk-*.c for examples.
 
-       Part 5 - static initialization of clock data
-
-For platforms with many clocks (often numbering into the hundreds) it
-may be desirable to statically initialize some clock data.  This
-presents a problem since the definition of struct clk should be hidden
-from everyone except for the clock core in drivers/clk/clk.c.
-
-To get around this problem struct clk's definition is exposed in
-include/linux/clk-private.h along with some macros for more easily
-initializing instances of the basic clock types.  These clocks must
-still be initialized with the common clock framework via a call to
-__clk_init.
-
-clk-private.h must NEVER be included by code which implements struct
-clk_ops callbacks, nor must it be included by any logic which pokes
-around inside of struct clk at run-time.  To do so is a layering
-violation.
-
-To better enforce this policy, always follow this simple rule: any
-statically initialized clock data MUST be defined in a separate file
-from the logic that implements its ops.  Basically separate the logic
-from the data and all is well.
-
-       Part 6 - Disabling clock gating of unused clocks
+       Part 5 - Disabling clock gating of unused clocks
 
 Sometimes during development it can be useful to be able to bypass the
 default disabling of unused clocks. For example, if drivers aren't enabling
 
 Sometimes during development it can be useful to be able to bypass the
 default disabling of unused clocks. For example, if drivers aren't enabling
@@ -248,3 +236,37 @@ are sorted out.
 
 To bypass this disabling, include "clk_ignore_unused" in the bootargs to the
 kernel.
 
 To bypass this disabling, include "clk_ignore_unused" in the bootargs to the
 kernel.
+
+       Part 6 - Locking
+
+The common clock framework uses two global locks, the prepare lock and the
+enable lock.
+
+The enable lock is a spinlock and is held across calls to the .enable,
+.disable and .is_enabled operations. Those operations are thus not allowed to
+sleep, and calls to the clk_enable(), clk_disable() and clk_is_enabled() API
+functions are allowed in atomic context.
+
+The prepare lock is a mutex and is held across calls to all other operations.
+All those operations are allowed to sleep, and calls to the corresponding API
+functions are not allowed in atomic context.
+
+This effectively divides operations in two groups from a locking perspective.
+
+Drivers don't need to manually protect resources shared between the operations
+of one group, regardless of whether those resources are shared by multiple
+clocks or not. However, access to resources that are shared between operations
+of the two groups needs to be protected by the drivers. An example of such a
+resource would be a register that controls both the clock rate and the clock
+enable/disable state.
+
+The clock framework is reentrant, in that a driver is allowed to call clock
+framework functions from within its implementation of clock operations. This
+can for instance cause a .set_rate operation of one clock being called from
+within the .set_rate operation of another clock. This case must be considered
+in the driver implementations, but the code flow is usually controlled by the
+driver in that case.
+
+Note that locking must also be considered when code outside of the common
+clock framework needs to access resources used by the clock operations. This
+is considered out of scope of this document.