aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2015-02-06 09:00:32 -0500
committerTero Kristo <t-kristo@ti.com>2015-03-31 14:26:55 -0400
commit80cbb224b789d256ad5cb36b0af3e5c04ed46bca (patch)
tree6ef237dd27648da426c57a25344b597ff3c03e1f /arch
parent219595b6ee139d883b98a9a32efbe2970802200a (diff)
ARM: OMAP2+: clock: add low-level support for regmap
Some of the TI clock providers will be converted to use syscon, thus low-level regmap support is needed for the clock drivers also. This patch adds this support, which can be enabled for individual drivers in later patches. Signed-off-by: Tero Kristo <t-kristo@ti.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/clock.c48
-rw-r--r--arch/arm/mach-omap2/clock.h4
-rw-r--r--arch/arm/mach-omap2/cm_common.c2
-rw-r--r--arch/arm/mach-omap2/control.c2
-rw-r--r--arch/arm/mach-omap2/prm_common.c2
5 files changed, 47 insertions, 11 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 @@
23#include <linux/clk-provider.h> 23#include <linux/clk-provider.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/bitops.h> 25#include <linux/bitops.h>
26#include <linux/regmap.h>
26#include <linux/of_address.h> 27#include <linux/of_address.h>
28#include <linux/bootmem.h>
27#include <asm/cpu.h> 29#include <asm/cpu.h>
28 30
29#include <trace/events/power.h> 31#include <trace/events/power.h>
@@ -73,20 +75,37 @@ struct ti_clk_features ti_clk_features;
73static bool clkdm_control = true; 75static bool clkdm_control = true;
74 76
75static LIST_HEAD(clk_hw_omap_clocks); 77static LIST_HEAD(clk_hw_omap_clocks);
76static void __iomem *clk_memmaps[CLK_MAX_MEMMAPS]; 78
79struct clk_iomap {
80 struct regmap *regmap;
81 void __iomem *mem;
82};
83
84static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
77 85
78static void clk_memmap_writel(u32 val, void __iomem *reg) 86static void clk_memmap_writel(u32 val, void __iomem *reg)
79{ 87{
80 struct clk_omap_reg *r = (struct clk_omap_reg *)&reg; 88 struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
89 struct clk_iomap *io = clk_memmaps[r->index];
81 90
82 writel_relaxed(val, clk_memmaps[r->index] + r->offset); 91 if (io->regmap)
92 regmap_write(io->regmap, r->offset, val);
93 else
94 writel_relaxed(val, io->mem + r->offset);
83} 95}
84 96
85static u32 clk_memmap_readl(void __iomem *reg) 97static u32 clk_memmap_readl(void __iomem *reg)
86{ 98{
99 u32 val;
87 struct clk_omap_reg *r = (struct clk_omap_reg *)&reg; 100 struct clk_omap_reg *r = (struct clk_omap_reg *)&reg;
101 struct clk_iomap *io = clk_memmaps[r->index];
88 102
89 return readl_relaxed(clk_memmaps[r->index] + r->offset); 103 if (io->regmap)
104 regmap_read(io->regmap, r->offset, &val);
105 else
106 val = readl_relaxed(io->mem + r->offset);
107
108 return val;
90} 109}
91 110
92void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg) 111void 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 = {
115 * @match_table: DT device table to match for devices to init 134 * @match_table: DT device table to match for devices to init
116 * @np: device node pointer for the this clock provider 135 * @np: device node pointer for the this clock provider
117 * @index: index for the clock provider 136 * @index: index for the clock provider
118 * @mem: iomem pointer for the clock provider memory area 137 + @syscon: syscon regmap pointer
138 * @mem: iomem pointer for the clock provider memory area, only used if
139 * syscon is not provided
119 * 140 *
120 * Initializes a clock provider module (CM/PRM etc.), registering 141 * Initializes a clock provider module (CM/PRM etc.), registering
121 * the memory mapping at specified index and initializing the 142 * the memory mapping at specified index and initializing the
122 * low level driver infrastructure. Returns 0 in success. 143 * low level driver infrastructure. Returns 0 in success.
123 */ 144 */
124int __init omap2_clk_provider_init(struct device_node *np, int index, 145int __init omap2_clk_provider_init(struct device_node *np, int index,
125 void __iomem *mem) 146 struct regmap *syscon, void __iomem *mem)
126{ 147{
148 struct clk_iomap *io;
149
127 ti_clk_ll_ops = &omap_clk_ll_ops; 150 ti_clk_ll_ops = &omap_clk_ll_ops;
128 151
129 clk_memmaps[index] = mem; 152 io = kzalloc(sizeof(*io), GFP_KERNEL);
153
154 io->regmap = syscon;
155 io->mem = mem;
156
157 clk_memmaps[index] = io;
130 158
131 ti_dt_clk_init_provider(np, index); 159 ti_dt_clk_init_provider(np, index);
132 160
@@ -142,9 +170,15 @@ int __init omap2_clk_provider_init(struct device_node *np, int index,
142 */ 170 */
143void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem) 171void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
144{ 172{
173 struct clk_iomap *io;
174
145 ti_clk_ll_ops = &omap_clk_ll_ops; 175 ti_clk_ll_ops = &omap_clk_ll_ops;
146 176
147 clk_memmaps[index] = mem; 177 io = memblock_virt_alloc(sizeof(*io), 0);
178
179 io->mem = mem;
180
181 clk_memmaps[index] = io;
148} 182}
149 183
150/* 184/*
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index b6433fc284ce..652ed0ab86ec 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -274,8 +274,10 @@ extern const struct clksel_rate div31_1to31_rates[];
274extern int omap2_clkops_enable_clkdm(struct clk_hw *hw); 274extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
275extern void omap2_clkops_disable_clkdm(struct clk_hw *hw); 275extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
276 276
277struct regmap;
278
277int __init omap2_clk_provider_init(struct device_node *np, int index, 279int __init omap2_clk_provider_init(struct device_node *np, int index,
278 void __iomem *mem); 280 struct regmap *syscon, void __iomem *mem);
279void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem); 281void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem);
280 282
281void __init ti_clk_init_features(void); 283void __init ti_clk_init_features(void);
diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c
index ff24fdfb3bb2..23e8bcec34e3 100644
--- a/arch/arm/mach-omap2/cm_common.c
+++ b/arch/arm/mach-omap2/cm_common.c
@@ -361,7 +361,7 @@ int __init omap_cm_init(void)
361 if (data->flags & CM_NO_CLOCKS) 361 if (data->flags & CM_NO_CLOCKS)
362 continue; 362 continue;
363 363
364 ret = omap2_clk_provider_init(np, data->index, data->mem); 364 ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
365 if (ret) 365 if (ret)
366 return ret; 366 return ret;
367 } 367 }
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 21ff32c6001a..4b4094685087 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -676,7 +676,7 @@ int __init omap_control_init(void)
676 for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) { 676 for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
677 data = match->data; 677 data = match->data;
678 678
679 ret = omap2_clk_provider_init(np, data->index, data->mem); 679 ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
680 if (ret) 680 if (ret)
681 return ret; 681 return ret;
682 } 682 }
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 6832a31e9a70..7add7994dbfc 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -798,7 +798,7 @@ int __init omap_prcm_init(void)
798 for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) { 798 for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
799 data = match->data; 799 data = match->data;
800 800
801 ret = omap2_clk_provider_init(np, data->index, data->mem); 801 ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
802 if (ret) 802 if (ret)
803 return ret; 803 return ret;
804 } 804 }