rk30: clock: add i2c clock for fpga
author黄涛 <huangtao@rock-chips.com>
Thu, 9 Feb 2012 02:15:42 +0000 (10:15 +0800)
committer黄涛 <huangtao@rock-chips.com>
Thu, 9 Feb 2012 02:15:42 +0000 (10:15 +0800)
arch/arm/mach-rk30/clock.c
arch/arm/mach-rk30/common.c

index 6510885f295d1937678b9cfaae8fb2d302d917ba..18a1966a61a6fe18838676cc32cda44c2282d972 100644 (file)
@@ -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;
index 0fe7be5a7be0650812af536f4036363a7b255b60..40ae1613fb6bb13b868476ce9b894e8d1aef78e1 100755 (executable)
@@ -22,6 +22,7 @@ void __init rk30_map_io(void)
 {
         rk30_map_common_io();
        rk29_setup_early_printk();
+       rk30_clock_init();
        rk30_iomux_init();
 }