clk: basic clock hardware types

Many platforms support simple gateable clocks, fixed-rate clocks,
adjustable divider clocks and multi-parent multiplexer clocks.

This patch introduces basic clock types for the above-mentioned hardware
which share some common characteristics.

Based on original work by Jeremy Kerr and contribution by Jamie Iles.
Dividers and multiplexor clocks originally contributed by Richard Zhao &
Sascha Hauer.

Signed-off-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Mike Turquette <mturquette@ti.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Rob Herring <rob.herring@calxeda.com>
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: Jamie Iles <jamie@jamieiles.com>
Cc: Richard Zhao <richard.zhao@linaro.org>
Cc: Saravana Kannan <skannan@codeaurora.org>
Cc: Magnus Damm <magnus.damm@gmail.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>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index e2cce6f..5e4312b 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -46,6 +46,130 @@
 #endif
 };
 
+/*
+ * DOC: Basic clock implementations common to many platforms
+ *
+ * Each basic clock hardware type is comprised of a structure describing the
+ * clock hardware, implementations of the relevant callbacks in struct clk_ops,
+ * unique flags for that hardware type, a registration function and an
+ * alternative macro for static initialization
+ */
+
+extern struct clk_ops clk_fixed_rate_ops;
+
+#define DEFINE_CLK_FIXED_RATE(_name, _flags, _rate,		\
+				_fixed_rate_flags)		\
+	static struct clk _name;				\
+	static char *_name##_parent_names[] = {};		\
+	static struct clk_fixed_rate _name##_hw = {		\
+		.hw = {						\
+			.clk = &_name,				\
+		},						\
+		.fixed_rate = _rate,				\
+		.flags = _fixed_rate_flags,			\
+	};							\
+	static struct clk _name = {				\
+		.name = #_name,					\
+		.ops = &clk_fixed_rate_ops,			\
+		.hw = &_name##_hw.hw,				\
+		.parent_names = _name##_parent_names,		\
+		.num_parents =					\
+			ARRAY_SIZE(_name##_parent_names),	\
+		.flags = _flags,				\
+	};
+
+extern struct clk_ops clk_gate_ops;
+
+#define DEFINE_CLK_GATE(_name, _parent_name, _parent_ptr,	\
+				_flags, _reg, _bit_idx,		\
+				_gate_flags, _lock)		\
+	static struct clk _name;				\
+	static char *_name##_parent_names[] = {			\
+		_parent_name,					\
+	};							\
+	static struct clk *_name##_parents[] = {		\
+		_parent_ptr,					\
+	};							\
+	static struct clk_gate _name##_hw = {			\
+		.hw = {						\
+			.clk = &_name,				\
+		},						\
+		.reg = _reg,					\
+		.bit_idx = _bit_idx,				\
+		.flags = _gate_flags,				\
+		.lock = _lock,					\
+	};							\
+	static struct clk _name = {				\
+		.name = #_name,					\
+		.ops = &clk_gate_ops,				\
+		.hw = &_name##_hw.hw,				\
+		.parent_names = _name##_parent_names,		\
+		.num_parents =					\
+			ARRAY_SIZE(_name##_parent_names),	\
+		.parents = _name##_parents,			\
+		.flags = _flags,				\
+	};
+
+extern struct clk_ops clk_divider_ops;
+
+#define DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr,	\
+				_flags, _reg, _shift, _width,	\
+				_divider_flags, _lock)		\
+	static struct clk _name;				\
+	static char *_name##_parent_names[] = {			\
+		_parent_name,					\
+	};							\
+	static struct clk *_name##_parents[] = {		\
+		_parent_ptr,					\
+	};							\
+	static struct clk_divider _name##_hw = {		\
+		.hw = {						\
+			.clk = &_name,				\
+		},						\
+		.reg = _reg,					\
+		.shift = _shift,				\
+		.width = _width,				\
+		.flags = _divider_flags,			\
+		.lock = _lock,					\
+	};							\
+	static struct clk _name = {				\
+		.name = #_name,					\
+		.ops = &clk_divider_ops,			\
+		.hw = &_name##_hw.hw,				\
+		.parent_names = _name##_parent_names,		\
+		.num_parents =					\
+			ARRAY_SIZE(_name##_parent_names),	\
+		.parents = _name##_parents,			\
+		.flags = _flags,				\
+	};
+
+extern struct clk_ops clk_mux_ops;
+
+#define DEFINE_CLK_MUX(_name, _parent_names, _parents, _flags,	\
+				_reg, _shift, _width,		\
+				_mux_flags, _lock)		\
+	static struct clk _name;				\
+	static struct clk_mux _name##_hw = {			\
+		.hw = {						\
+			.clk = &_name,				\
+		},						\
+		.reg = _reg,					\
+		.shift = _shift,				\
+		.width = _width,				\
+		.flags = _mux_flags,				\
+		.lock = _lock,					\
+	};							\
+	static struct clk _name = {				\
+		.name = #_name,					\
+		.ops = &clk_mux_ops,				\
+		.hw = &_name##_hw.hw,				\
+		.parent_names = _parent_names,			\
+		.num_parents =					\
+			ARRAY_SIZE(_parent_names),		\
+		.parents = _parents,				\
+		.flags = _flags,				\
+	};
+
 /**
  * __clk_init - initialize the data structures in a struct clk
  * @dev:	device initializing this clk, placeholder for now