diff options
author | Tero Kristo <t-kristo@ti.com> | 2015-02-06 09:00:32 -0500 |
---|---|---|
committer | Tero Kristo <t-kristo@ti.com> | 2015-03-31 14:26:55 -0400 |
commit | 80cbb224b789d256ad5cb36b0af3e5c04ed46bca (patch) | |
tree | 6ef237dd27648da426c57a25344b597ff3c03e1f /arch/arm/mach-omap2/clock.c | |
parent | 219595b6ee139d883b98a9a32efbe2970802200a (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/arm/mach-omap2/clock.c')
-rw-r--r-- | arch/arm/mach-omap2/clock.c | 48 |
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 @@ | |||
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; | |||
73 | static bool clkdm_control = true; | 75 | static bool clkdm_control = true; |
74 | 76 | ||
75 | static LIST_HEAD(clk_hw_omap_clocks); | 77 | static LIST_HEAD(clk_hw_omap_clocks); |
76 | static void __iomem *clk_memmaps[CLK_MAX_MEMMAPS]; | 78 | |
79 | struct clk_iomap { | ||
80 | struct regmap *regmap; | ||
81 | void __iomem *mem; | ||
82 | }; | ||
83 | |||
84 | static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS]; | ||
77 | 85 | ||
78 | static void clk_memmap_writel(u32 val, void __iomem *reg) | 86 | static void clk_memmap_writel(u32 val, void __iomem *reg) |
79 | { | 87 | { |
80 | struct clk_omap_reg *r = (struct clk_omap_reg *)® | 88 | struct clk_omap_reg *r = (struct clk_omap_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 | ||
85 | static u32 clk_memmap_readl(void __iomem *reg) | 97 | static u32 clk_memmap_readl(void __iomem *reg) |
86 | { | 98 | { |
99 | u32 val; | ||
87 | struct clk_omap_reg *r = (struct clk_omap_reg *)® | 100 | struct clk_omap_reg *r = (struct clk_omap_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 | ||
92 | void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg) | 111 | 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 = { | |||
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 | */ |
124 | int __init omap2_clk_provider_init(struct device_node *np, int index, | 145 | int __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 | */ |
143 | void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem) | 171 | void __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 | /* |