summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r--arch/arm/mach-omap2/clock.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 94080fba02f6..a699d7169307 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -23,7 +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>
@@ -73,20 +75,37 @@ struct ti_clk_features ti_clk_features;
static bool clkdm_control = true;
static LIST_HEAD(clk_hw_omap_clocks);
-static 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];
- writel_relaxed(val, clk_memmaps[r->index] + r->offset);
+ 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];
- return readl_relaxed(clk_memmaps[r->index] + r->offset);
+ 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)
@@ -115,18 +134,27 @@ static struct ti_clk_ll_ops omap_clk_ll_ops = {
* @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
- * @mem: iomem pointer for the clock provider memory area
+ + @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,
- void __iomem *mem)
+ struct regmap *syscon, void __iomem *mem)
{
+ struct clk_iomap *io;
+
ti_clk_ll_ops = &omap_clk_ll_ops;
- clk_memmaps[index] = mem;
+ io = kzalloc(sizeof(*io), GFP_KERNEL);
+
+ io->regmap = syscon;
+ io->mem = mem;
+
+ clk_memmaps[index] = io;
ti_dt_clk_init_provider(np, index);
@@ -142,9 +170,15 @@ int __init omap2_clk_provider_init(struct device_node *np, int index,
*/
void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
{
+ struct clk_iomap *io;
+
ti_clk_ll_ops = &omap_clk_ll_ops;
- clk_memmaps[index] = mem;
+ io = memblock_virt_alloc(sizeof(*io), 0);
+
+ io->mem = mem;
+
+ clk_memmaps[index] = io;
}
/*