Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[deliverable/linux.git] / arch / arm / mach-omap2 / clock.c
index 6124db5c37aebf5d3092b66c355c326bdf6815f9..a699d716930746d4f37bd603be865b248d5986bc 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <linux/of_address.h>
+#include <linux/bootmem.h>
 #include <asm/cpu.h>
 
 #include <trace/events/power.h>
@@ -72,30 +75,110 @@ struct ti_clk_features ti_clk_features;
 static bool clkdm_control = true;
 
 static LIST_HEAD(clk_hw_omap_clocks);
-void __iomem *clk_memmaps[CLK_MAX_MEMMAPS];
+
+struct clk_iomap {
+       struct regmap *regmap;
+       void __iomem *mem;
+};
+
+static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
+
+static void clk_memmap_writel(u32 val, void __iomem *reg)
+{
+       struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
+       struct clk_iomap *io = clk_memmaps[r->index];
+
+       if (io->regmap)
+               regmap_write(io->regmap, r->offset, val);
+       else
+               writel_relaxed(val, io->mem + r->offset);
+}
+
+static u32 clk_memmap_readl(void __iomem *reg)
+{
+       u32 val;
+       struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
+       struct clk_iomap *io = clk_memmaps[r->index];
+
+       if (io->regmap)
+               regmap_read(io->regmap, r->offset, &val);
+       else
+               val = readl_relaxed(io->mem + r->offset);
+
+       return val;
+}
 
 void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg)
 {
-       if (clk->flags & MEMMAP_ADDRESSING) {
-               struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
-               writel_relaxed(val, clk_memmaps[r->index] + r->offset);
-       } else {
+       if (WARN_ON_ONCE(!(clk->flags & MEMMAP_ADDRESSING)))
                writel_relaxed(val, reg);
-       }
+       else
+               clk_memmap_writel(val, reg);
 }
 
 u32 omap2_clk_readl(struct clk_hw_omap *clk, void __iomem *reg)
 {
-       u32 val;
+       if (WARN_ON_ONCE(!(clk->flags & MEMMAP_ADDRESSING)))
+               return readl_relaxed(reg);
+       else
+               return clk_memmap_readl(reg);
+}
 
-       if (clk->flags & MEMMAP_ADDRESSING) {
-               struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
-               val = readl_relaxed(clk_memmaps[r->index] + r->offset);
-       } else {
-               val = readl_relaxed(reg);
-       }
+static struct ti_clk_ll_ops omap_clk_ll_ops = {
+       .clk_readl = clk_memmap_readl,
+       .clk_writel = clk_memmap_writel,
+};
 
-       return val;
+/**
+ * omap2_clk_provider_init - initialize a clock provider
+ * @match_table: DT device table to match for devices to init
+ * @np: device node pointer for the this clock provider
+ * @index: index for the clock provider
+ + @syscon: syscon regmap pointer
+ * @mem: iomem pointer for the clock provider memory area, only used if
+ *      syscon is not provided
+ *
+ * Initializes a clock provider module (CM/PRM etc.), registering
+ * the memory mapping at specified index and initializing the
+ * low level driver infrastructure. Returns 0 in success.
+ */
+int __init omap2_clk_provider_init(struct device_node *np, int index,
+                                  struct regmap *syscon, void __iomem *mem)
+{
+       struct clk_iomap *io;
+
+       ti_clk_ll_ops = &omap_clk_ll_ops;
+
+       io = kzalloc(sizeof(*io), GFP_KERNEL);
+
+       io->regmap = syscon;
+       io->mem = mem;
+
+       clk_memmaps[index] = io;
+
+       ti_dt_clk_init_provider(np, index);
+
+       return 0;
+}
+
+/**
+ * omap2_clk_legacy_provider_init - initialize a legacy clock provider
+ * @index: index for the clock provider
+ * @mem: iomem pointer for the clock provider memory area
+ *
+ * Initializes a legacy clock provider memory mapping.
+ */
+void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
+{
+       struct clk_iomap *io;
+
+       ti_clk_ll_ops = &omap_clk_ll_ops;
+
+       io = memblock_virt_alloc(sizeof(*io), 0);
+
+       io->mem = mem;
+
+       clk_memmaps[index] = io;
 }
 
 /*
This page took 0.025078 seconds and 5 git commands to generate.