From: 黄涛 <huangtao@rock-chips.com>
Date: Thu, 9 Feb 2012 02:15:42 +0000 (+0800)
Subject: rk30: clock: add i2c clock for fpga
X-Git-Tag: firefly_0821_release~9595^2~160
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bc590baf89a63d7d07467bb474bacffb4e44a958;p=firefly-linux-kernel-4.4.55.git

rk30: clock: add i2c clock for fpga
---

diff --git a/arch/arm/mach-rk30/clock.c b/arch/arm/mach-rk30/clock.c
index 6510885f295d..18a1966a61a6 100644
--- a/arch/arm/mach-rk30/clock.c
+++ b/arch/arm/mach-rk30/clock.c
@@ -1,8 +1,78 @@
 #include <linux/clk.h>
+#include <linux/clkdev.h>
 #include <linux/err.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 
+#include <mach/board.h>
+
+/* Clock flags */
+/* bit 0 is free */
+#define RATE_FIXED		(1 << 1)	/* Fixed clock rate */
+#define CONFIG_PARTICIPANT	(1 << 10)	/* Fundamental clock */
+#define IS_PD			(1 << 2)	/* Power Domain */
+
+#define MHZ			(1000*1000)
+#define KHZ			1000
+
+struct clk {
+	struct list_head	node;
+	const char		*name;
+	struct clk		*parent;
+	struct list_head	children;
+	struct list_head	sibling;	/* node for children */
+	unsigned long		rate;
+	u32			flags;
+	int			(*mode)(struct clk *clk, int on);
+	unsigned long		(*recalc)(struct clk *);	/* if null, follow parent */
+	int			(*set_rate)(struct clk *, unsigned long);
+	long			(*round_rate)(struct clk *, unsigned long);
+	struct clk*		(*get_parent)(struct clk *);	/* get clk's parent from the hardware. default is clksel_get_parent if parents present */
+	int			(*set_parent)(struct clk *, struct clk *);	/* default is clksel_set_parent if parents present */
+	s16			usecount;
+	u16			notifier_count;
+	u8			gate_idx;
+	u8			pll_idx;
+	u8			clksel_con;
+	u8			clksel_mask;
+	u8			clksel_shift;
+	u8			clksel_maxdiv;
+	u8			clksel_parent_mask;
+	u8			clksel_parent_shift;
+	struct clk		**parents;
+};
+
+static struct clk xin24m = {
+	.name		= "xin24m",
+	.rate		= 24 * MHZ,
+	.flags		= RATE_FIXED,
+};
+
+#define CLK(dev, con, ck) \
+	{ \
+		.dev_id = dev, \
+		.con_id = con, \
+		.clk = ck, \
+	}
+
+static struct clk_lookup clks[] = {
+	CLK("rk30_i2c.0", "i2c", &xin24m),
+	CLK("rk30_i2c.1", "i2c", &xin24m),
+	CLK("rk30_i2c.2", "i2c", &xin24m),
+	CLK("rk30_i2c.3", "i2c", &xin24m),
+	CLK("rk30_i2c.4", "i2c", &xin24m),
+};
+
+void __init rk30_clock_init(void)
+{
+	struct clk_lookup *lk;
+
+	for (lk = clks; lk < clks + ARRAY_SIZE(clks); lk++) {
+		clkdev_add(lk);
+	}
+}
+
 int clk_enable(struct clk *clk)
 {
 	int ret = 0;
diff --git a/arch/arm/mach-rk30/common.c b/arch/arm/mach-rk30/common.c
index 0fe7be5a7be0..40ae1613fb6b 100755
--- a/arch/arm/mach-rk30/common.c
+++ b/arch/arm/mach-rk30/common.c
@@ -22,6 +22,7 @@ void __init rk30_map_io(void)
 {
         rk30_map_common_io();
 	rk29_setup_early_printk();
+	rk30_clock_init();
 	rk30_iomux_init();
 }