linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mike Turquette <mturquette@linaro.org>
To: Russell King <linux@arm.linux.org.uk>
Cc: linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linaro-dev@lists.linaro.org, patches@linaro.org,
	Mike Turquette <mturquette@linaro.org>,
	Mike Turquette <mturquette@ti.com>,
	Jeremy Kerr <jeremy.kerr@canonical.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Arnd Bergman <arnd.bergmann@linaro.org>,
	Paul Walmsley <paul@pwsan.com>,
	Shawn Guo <shawn.guo@freescale.com>,
	Sascha Hauer <s.hauer@pengutronix.de>,
	Richard Zhao <richard.zhao@linaro.org>,
	Saravana Kannan <skannan@codeaurora.org>,
	Magnus Damm <magnus.damm@gmail.com>,
	Rob Herring <rob.herring@calxeda.com>,
	Mark Brown <broonie@opensource.wolfsonmicro.com>,
	Linus Walleij <linus.walleij@stericsson.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Amit Kucheria <amit.kucheria@linaro.org>,
	Deepak Saxena <dsaxena@linaro.org>,
	Grant Likely <grant.likely@secretlab.ca>
Subject: [PATCH v7 1/3] Documentation: common clk API
Date: Thu, 15 Mar 2012 23:11:18 -0700	[thread overview]
Message-ID: <1331878280-2758-2-git-send-email-mturquette@linaro.org> (raw)
In-Reply-To: <1331878280-2758-1-git-send-email-mturquette@linaro.org>

Provide documentation for the common clk structures and APIs.  This code
can be found in drivers/clk/ and include/linux/clk*.h.

Signed-off-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Mike Turquette <mturquette@ti.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Jeremy Kerr <jeremy.kerr@canonical.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Arnd Bergman <arnd.bergmann@linaro.org>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Shawn Guo <shawn.guo@freescale.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Richard Zhao <richard.zhao@linaro.org>
Cc: Saravana Kannan <skannan@codeaurora.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: Amit Kucheria <amit.kucheria@linaro.org>
Cc: Deepak Saxena <dsaxena@linaro.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
No changes since v6

Changes since v5:
 * __clk_init must be called for statically initialized clocks
 * added "clk_ops matrix" to better clarify which ops are mandatory

 Documentation/clk.txt |  233 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 233 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/clk.txt

diff --git a/Documentation/clk.txt b/Documentation/clk.txt
new file mode 100644
index 0000000..1943fae
--- /dev/null
+++ b/Documentation/clk.txt
@@ -0,0 +1,233 @@
+		The Common Clk Framework
+		Mike Turquette <mturquette@ti.com>
+
+This document endeavours to explain the common clk framework details,
+and how to port a platform over to this framework.  It is not yet a
+detailed explanation of the clock api in include/linux/clk.h, but
+perhaps someday it will include that information.
+
+	Part 1 - introduction and interface split
+
+The common clk framework is an interface to control the clock nodes
+available on various devices today.  This may come in the form of clock
+gating, rate adjustment, muxing or other operations.  This framework is
+enabled with the CONFIG_COMMON_CLK option.
+
+The interface itself is divided into two halves, each shielded from the
+details of its counterpart.  First is the common definition of struct
+clk which unifies the framework-level accounting and infrastructure that
+has traditionally been duplicated across a variety of platforms.  Second
+is a common implementation of the clk.h api, defined in
+drivers/clk/clk.c.  Finally there is struct clk_ops, whose operations
+are invoked by the clk api implementation.
+
+The second half of the interface is comprised of the hardware-specific
+callbacks registered with struct clk_ops and the corresponding
+hardware-specific structures needed to model a particular clock.  For
+the remainder of this document any reference to a callback in struct
+clk_ops, such as .enable or .set_rate, implies the hardware-specific
+implementation of that code.  Likewise, references to struct clk_foo
+serve as a convenient shorthand for the implementation of the
+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
+allows easy for navigation between the two discrete halves of the common
+clock interface.
+
+	Part 2 - common data structures and api
+
+Below is the common struct clk definition from
+include/linux/clk-private.h, modified for brevity:
+
+	struct clk {
+		const char		*name;
+		const struct clk_ops	*ops;
+		struct clk_hw		*hw;
+		char			**parent_names;
+		struct clk		**parents;
+		struct clk		*parent;
+		struct hlist_head	children;
+		struct hlist_node	child_node;
+		...
+	};
+
+The members above make up the core of the clk tree topology.  The clk
+api itself defines several driver-facing functions which operate on
+struct clk.  That api is documented in include/linux/clk.h.
+
+Platforms and devices utilizing the common struct clk use the struct
+clk_ops pointer in struct clk to perform the hardware-specific parts of
+the operations defined in clk.h:
+
+	struct clk_ops {
+		int		(*prepare)(struct clk_hw *hw);
+		void		(*unprepare)(struct clk_hw *hw);
+		int		(*enable)(struct clk_hw *hw);
+		void		(*disable)(struct clk_hw *hw);
+		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 *);
+		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);
+		void		(*init)(struct clk_hw *hw);
+	};
+
+	Part 3 - hardware clk implementations
+
+The strength of the common struct clk comes from its .ops and .hw pointers
+which abstract the details of struct clk from the hardware-specific bits, and
+vice versa.  To illustrate consider the simple gateable clk implementation in
+drivers/clk/clk-gate.c:
+
+struct clk_gate {
+	struct clk_hw	hw;
+	void __iomem    *reg;
+	u8              bit_idx;
+	...
+};
+
+struct clk_gate contains struct clk_hw hw as well as hardware-specific
+knowledge about which register and bit controls this clk's gating.
+Nothing about clock topology or accounting, such as enable_count or
+notifier_count, is needed here.  That is all handled by the common
+framework code and struct clk.
+
+Let's walk through enabling this clk from driver code:
+
+	struct clk *clk;
+	clk = clk_get(NULL, "my_gateable_clk");
+
+	clk_prepare(clk);
+	clk_enable(clk);
+
+The call graph for clk_enable is very simple:
+
+clk_enable(clk);
+	clk->ops->enable(clk->hw);
+	[resolves to...]
+		clk_gate_enable(hw);
+		[resolves struct clk gate with to_clk_gate(hw)]
+			clk_gate_set_bit(gate);
+
+And the definition of clk_gate_set_bit:
+
+static void clk_gate_set_bit(struct clk_gate *gate)
+{
+	u32 reg;
+
+	reg = __raw_readl(gate->reg);
+	reg |= BIT(gate->bit_idx);
+	writel(reg, gate->reg);
+}
+
+Note that to_clk_gate is defined as:
+
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, clk)
+
+This pattern of abstraction is used for every clock hardware
+representation.
+
+	Part 4 - supporting your own clk hardware
+
+When implementing support for a new type of clock it only necessary to
+include the following header:
+
+#include <linux/clk-provider.h>
+
+include/linux/clk.h is included within that header and clk-private.h
+must never be included from the code which implements the operations for
+a clock.  More on that below in Part 5.
+
+To construct a clk hardware structure for your platform you must define
+the following:
+
+struct clk_foo {
+	struct clk_hw hw;
+	... hardware specific data goes here ...
+};
+
+To take advantage of your data you'll need to support valid operations
+for your clk:
+
+struct clk_ops clk_foo_ops {
+	.enable		= &clk_foo_enable;
+	.disable	= &clk_foo_disable;
+};
+
+Implement the above functions using container_of:
+
+#define to_clk_foo(_hw) container_of(_hw, struct clk_foo, hw)
+
+int clk_foo_enable(struct clk_hw *hw)
+{
+	struct clk_foo *foo;
+
+	foo = to_clk_foo(hw);
+
+	... perform magic on foo ...
+
+	return 0;
+};
+
+Below is a matrix detailing which clk_ops are mandatory based upon the
+hardware capbilities of that clock.  A cell marked as "y" means
+mandatory, a cell marked as "n" implies that either including that
+callback is invalid or otherwise uneccesary.  Empty cells are either
+optional or must be evaluated on a case-by-case basis.
+
+                           clock hardware characteristics
+	     -----------------------------------------------------------
+             | gate | change rate | single parent | multiplexer | root |
+             |------|-------------|---------------|-------------|------|
+.prepare     |      |             |               |             |      |
+.unprepare   |      |             |               |             |      |
+             |      |             |               |             |      |
+.enable      | y    |             |               |             |      |
+.disable     | y    |             |               |             |      |
+.is_enabled  | y    |             |               |             |      |
+             |      |             |               |             |      |
+.recalc_rate |      | y           |               |             |      |
+.round_rate  |      | y           |               |             |      |
+.set_rate    |      | y           |               |             |      |
+             |      |             |               |             |      |
+.set_parent  |      |             | n             | y           | n    |
+.get_parent  |      |             | n             | y           | n    |
+             |      |             |               |             |      |
+.init        |      |             |               |             |      |
+	     -----------------------------------------------------------
+
+Finally, register your clock at run-time with a hardware-specific
+registration function.  This function simply populates struct clk_foo's
+data and then passes the common struct clk parameters to the framework
+with a call to:
+
+clk_register(...)
+
+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.
-- 
1.7.5.4


  reply	other threads:[~2012-03-16  6:11 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-16  6:11 [PATCH v7 0/3] common clk framework Mike Turquette
2012-03-16  6:11 ` Mike Turquette [this message]
2012-03-16  8:25   ` [PATCH v7 1/3] Documentation: common clk API Linus Walleij
2012-03-16 10:29     ` Thomas Gleixner
2012-03-16 11:14       ` Amit Kucheria
2012-03-16 12:18         ` Arnd Bergmann
2012-03-16 20:57           ` Arnd Bergmann
2012-03-16 21:40             ` Turquette, Mike
2012-03-16 21:50             ` Nicolas Pitre
2012-03-16 22:21             ` Paul Walmsley
2012-03-16 22:33               ` Turquette, Mike
2012-03-17  9:05                 ` Arnd Bergmann
2012-03-17 18:02                   ` Turquette, Mike
2012-03-17 18:33                     ` Arnd Bergmann
2012-03-17 20:29                     ` Sascha Hauer
2012-03-17 21:13                       ` Arnd Bergmann
2012-03-20 23:40                   ` Paul Walmsley
2012-03-21  8:59                     ` Arnd Bergmann
2012-03-16 23:47               ` Sascha Hauer
2012-03-17  0:54                 ` Rob Herring
2012-03-17  3:38                   ` Saravana Kannan
2012-03-20 23:31                 ` Paul Walmsley
2012-03-21  3:15                   ` Nicolas Pitre
2012-03-21  3:26                     ` Saravana Kannan
2012-03-21  7:44                       ` Paul Walmsley
2012-03-21  9:10                         ` Sascha Hauer
2012-03-21 18:38                         ` Saravana Kannan
2012-03-21 19:07                           ` Mark Brown
2012-03-21 19:33                             ` Tony Lindgren
2012-03-21 19:41                               ` Saravana Kannan
2012-03-21 19:56                                 ` Mark Brown
2012-03-21 20:04                                   ` Saravana Kannan
2012-03-21 20:10                                     ` Mark Brown
2012-03-22  0:42                                 ` Russell King - ARM Linux
2012-03-21  7:30                     ` Paul Walmsley
2012-03-21 13:23                       ` Nicolas Pitre
2012-03-16  6:11 ` [PATCH v7 2/3] clk: introduce the common clock framework Mike Turquette
2012-03-17  3:28   ` Saravana Kannan
2012-03-19 18:56     ` Turquette, Mike
2012-03-19 19:13       ` Saravana Kannan
2012-03-19 19:33         ` Turquette, Mike
2012-03-19 19:49           ` Saravana Kannan
2012-03-20  3:38           ` [PATCH 1/2] clk: Fix error handling in fixed clock hardware type register fn Saravana Kannan
2012-03-20  3:38             ` [PATCH 2/2] clk: Move init fields from clk to clk_hw Saravana Kannan
2012-03-20  7:20               ` Shawn Guo
2012-03-20  7:54                 ` Saravana Kannan
2012-03-20  8:13                   ` Shawn Guo
2012-03-20  9:40                   ` Sascha Hauer
2012-03-20 10:17                     ` Saravana Kannan
2012-03-20 18:14                       ` Sascha Hauer
2012-03-20 20:14                         ` Saravana Kannan
2012-03-20 22:40                           ` Sascha Hauer
2012-03-22  3:23                             ` Shawn Guo
2012-03-20 14:18                     ` Shawn Guo
2012-03-20 18:10                       ` Sascha Hauer
2012-03-20 20:06                         ` Saravana Kannan
2012-03-20 23:12                           ` Sascha Hauer
2012-03-21  1:47                             ` Turquette, Mike
2012-03-21  3:01                               ` Saravana Kannan
2012-03-27  4:35                                 ` Saravana Kannan
2012-03-27 18:49                                   ` Turquette, Mike
2012-03-27 22:27                                     ` Saravana Kannan
2012-04-06  1:30                                     ` Saravana Kannan
2012-04-11 17:59                                       ` Turquette, Mike
2012-04-11 19:57                                         ` Saravana Kannan
2012-04-11 20:17                                           ` Turquette, Mike
2012-04-11 20:21                                             ` Saravana Kannan
2012-03-20 23:47                         ` Paul Walmsley
2012-03-21  9:16                           ` Sascha Hauer
2012-03-20  7:19             ` [PATCH 1/2] clk: Fix error handling in fixed clock hardware type register fn Sascha Hauer
2012-03-20  7:46               ` Saravana Kannan
2012-03-21  0:13                 ` Turquette, Mike
2012-03-21  2:32                   ` Saravana Kannan
2012-03-21  5:45                     ` Turquette, Mike
2012-03-21  6:33                       ` Saravana Kannan
2012-03-21  9:07                       ` Russell King - ARM Linux
2012-03-21 19:56                         ` Turquette, Mike
2012-03-18 13:46   ` [PATCH v7 2/3] clk: introduce the common clock framework Shawn Guo
2012-03-19 18:58     ` Turquette, Mike
2012-03-18 14:07   ` Shawn Guo
2012-03-19 19:00     ` Turquette, Mike
2012-03-19 11:22   ` Rajendra Nayak
2012-03-19 11:28     ` Sascha Hauer
2012-03-19 19:09       ` Turquette, Mike
2012-03-19 19:53     ` Turquette, Mike
2012-03-20 14:02   ` Shawn Guo
2012-03-20 17:46     ` Saravana Kannan
2012-03-20 23:53       ` Turquette, Mike
2012-03-21  3:10         ` Saravana Kannan
2012-03-23 21:33           ` Saravana Kannan
2012-03-23 21:39             ` Turquette, Mike
2012-03-23 21:51               ` Saravana Kannan
2012-03-23 22:12               ` Saravana Kannan
2012-03-23 22:32                 ` Turquette, Mike
2012-03-23 23:04                   ` Saravana Kannan
2012-03-23 23:28                     ` Turquette, Mike
2012-03-28  3:06                       ` Saravana Kannan
2012-03-28 17:08                         ` Turquette, Mike
2012-03-28 22:25                           ` Saravana Kannan
2012-03-28 23:49                             ` Turquette, Mike
2012-03-20 23:46     ` Turquette, Mike
2012-03-21  5:46       ` Shawn Guo
2012-03-16  6:11 ` [PATCH v7 3/3] clk: basic clock hardware types Mike Turquette
2012-03-16 12:25   ` Richard Zhao
2012-03-16 16:51     ` Turquette, Mike
2012-03-16 10:57 ` [PATCH v7 0/3] common clk framework Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1331878280-2758-2-git-send-email-mturquette@linaro.org \
    --to=mturquette@linaro.org \
    --cc=amit.kucheria@linaro.org \
    --cc=arnd.bergmann@linaro.org \
    --cc=broonie@opensource.wolfsonmicro.com \
    --cc=dsaxena@linaro.org \
    --cc=grant.likely@secretlab.ca \
    --cc=jeremy.kerr@canonical.com \
    --cc=linaro-dev@lists.linaro.org \
    --cc=linus.walleij@stericsson.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=magnus.damm@gmail.com \
    --cc=mturquette@ti.com \
    --cc=patches@linaro.org \
    --cc=paul@pwsan.com \
    --cc=richard.zhao@linaro.org \
    --cc=rob.herring@calxeda.com \
    --cc=s.hauer@pengutronix.de \
    --cc=sboyd@codeaurora.org \
    --cc=shawn.guo@freescale.com \
    --cc=skannan@codeaurora.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).