aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c6
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c140
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h2
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7724.h1
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7723.c76
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7724.c44
-rw-r--r--drivers/sh/clk/core.c9
-rw-r--r--drivers/sh/clk/cpg.c77
-rw-r--r--drivers/sh/pfc.c273
-rw-r--r--include/linux/sh_clk.h10
-rw-r--r--include/linux/sh_pfc.h22
11 files changed, 442 insertions, 218 deletions
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 995a9c3aec8f..e349c22a0d71 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -411,11 +411,11 @@ static struct clk *fsibckcr_parent[] = {
411}; 411};
412 412
413static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { 413static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
414 [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0, 414 [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
415 hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), 415 hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
416 [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0, 416 [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
417 fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2), 417 fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
418 [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0, 418 [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
419 fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2), 419 fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
420}; 420};
421 421
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 1370a89ca358..34944d01bf1e 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -92,6 +92,24 @@ static struct clk_ops div2_clk_ops = {
92 .recalc = div2_recalc, 92 .recalc = div2_recalc,
93}; 93};
94 94
95static unsigned long div7_recalc(struct clk *clk)
96{
97 return clk->parent->rate / 7;
98}
99
100static struct clk_ops div7_clk_ops = {
101 .recalc = div7_recalc,
102};
103
104static unsigned long div13_recalc(struct clk *clk)
105{
106 return clk->parent->rate / 13;
107}
108
109static struct clk_ops div13_clk_ops = {
110 .recalc = div13_recalc,
111};
112
95/* Divide extal1 by two */ 113/* Divide extal1 by two */
96static struct clk extal1_div2_clk = { 114static struct clk extal1_div2_clk = {
97 .ops = &div2_clk_ops, 115 .ops = &div2_clk_ops,
@@ -174,12 +192,29 @@ static struct clk pll3_clk = {
174 .enable_bit = 3, 192 .enable_bit = 3,
175}; 193};
176 194
177/* Divide PLL1 by two */ 195/* Divide PLL */
178static struct clk pll1_div2_clk = { 196static struct clk pll1_div2_clk = {
179 .ops = &div2_clk_ops, 197 .ops = &div2_clk_ops,
180 .parent = &pll1_clk, 198 .parent = &pll1_clk,
181}; 199};
182 200
201static struct clk pll1_div7_clk = {
202 .ops = &div7_clk_ops,
203 .parent = &pll1_clk,
204};
205
206static struct clk pll1_div13_clk = {
207 .ops = &div13_clk_ops,
208 .parent = &pll1_clk,
209};
210
211/* External input clock */
212struct clk sh73a0_extcki_clk = {
213};
214
215struct clk sh73a0_extalr_clk = {
216};
217
183static struct clk *main_clks[] = { 218static struct clk *main_clks[] = {
184 &r_clk, 219 &r_clk,
185 &sh73a0_extal1_clk, 220 &sh73a0_extal1_clk,
@@ -193,6 +228,10 @@ static struct clk *main_clks[] = {
193 &pll2_clk, 228 &pll2_clk,
194 &pll3_clk, 229 &pll3_clk,
195 &pll1_div2_clk, 230 &pll1_div2_clk,
231 &pll1_div7_clk,
232 &pll1_div13_clk,
233 &sh73a0_extcki_clk,
234 &sh73a0_extalr_clk,
196}; 235};
197 236
198static void div4_kick(struct clk *clk) 237static void div4_kick(struct clk *clk)
@@ -246,27 +285,84 @@ enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
246 DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, 285 DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
247 DIV6_NR }; 286 DIV6_NR };
248 287
288static struct clk *vck_parent[8] = {
289 [0] = &pll1_div2_clk,
290 [1] = &pll2_clk,
291 [2] = &sh73a0_extcki_clk,
292 [3] = &sh73a0_extal2_clk,
293 [4] = &main_div2_clk,
294 [5] = &sh73a0_extalr_clk,
295 [6] = &main_clk,
296};
297
298static struct clk *pll_parent[4] = {
299 [0] = &pll1_div2_clk,
300 [1] = &pll2_clk,
301 [2] = &pll1_div13_clk,
302};
303
304static struct clk *hsi_parent[4] = {
305 [0] = &pll1_div2_clk,
306 [1] = &pll2_clk,
307 [2] = &pll1_div7_clk,
308};
309
310static struct clk *pll_extal2_parent[] = {
311 [0] = &pll1_div2_clk,
312 [1] = &pll2_clk,
313 [2] = &sh73a0_extal2_clk,
314 [3] = &sh73a0_extal2_clk,
315};
316
317static struct clk *dsi_parent[8] = {
318 [0] = &pll1_div2_clk,
319 [1] = &pll2_clk,
320 [2] = &main_clk,
321 [3] = &sh73a0_extal2_clk,
322 [4] = &sh73a0_extcki_clk,
323};
324
249static struct clk div6_clks[DIV6_NR] = { 325static struct clk div6_clks[DIV6_NR] = {
250 [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0), 326 [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
251 [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0), 327 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
252 [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0), 328 [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
253 [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, CLK_ENABLE_ON_INIT), 329 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
254 [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0), 330 [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
255 [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0), 331 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
256 [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0), 332 [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
257 [DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0), 333 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
258 [DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0), 334 [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
259 [DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0), 335 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
260 [DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0), 336 [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
261 [DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0), 337 pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
262 [DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0), 338 [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
263 [DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0), 339 pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
264 [DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0), 340 [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
265 [DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0), 341 pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
266 [DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0), 342 [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
267 [DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0), 343 pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
268 [DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0), 344 [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
269 [DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0), 345 pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
346 [DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
347 pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
348 [DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
349 pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
350 [DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
351 pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
352 [DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
353 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
354 [DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
355 hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
356 [DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
357 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
358 [DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
359 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
360 [DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
361 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
362 [DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
363 dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
364 [DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
365 dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
270}; 366};
271 367
272enum { MSTP001, 368enum { MSTP001,
@@ -403,7 +499,7 @@ void __init sh73a0_clock_init(void)
403 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); 499 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
404 500
405 if (!ret) 501 if (!ret)
406 ret = sh_clk_div6_register(div6_clks, DIV6_NR); 502 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
407 503
408 if (!ret) 504 if (!ret)
409 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); 505 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 3a9250bb6d05..c2ed19b43560 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -46,6 +46,8 @@ extern void sh73a0_clock_init(void);
46extern void sh73a0_pinmux_init(void); 46extern void sh73a0_pinmux_init(void);
47extern struct clk sh73a0_extal1_clk; 47extern struct clk sh73a0_extal1_clk;
48extern struct clk sh73a0_extal2_clk; 48extern struct clk sh73a0_extal2_clk;
49extern struct clk sh73a0_extcki_clk;
50extern struct clk sh73a0_extalr_clk;
49 51
50extern unsigned int sh73a0_get_core_count(void); 52extern unsigned int sh73a0_get_core_count(void);
51extern void sh73a0_secondary_init(unsigned int cpu); 53extern void sh73a0_secondary_init(unsigned int cpu);
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h
index cbc47e6bcab5..36ce466cbf07 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7724.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h
@@ -314,5 +314,6 @@ enum {
314 314
315extern struct clk sh7724_fsimcka_clk; 315extern struct clk sh7724_fsimcka_clk;
316extern struct clk sh7724_fsimckb_clk; 316extern struct clk sh7724_fsimckb_clk;
317extern struct clk sh7724_dv_clki;
317 318
318#endif /* __ASM_SH7724_H__ */ 319#endif /* __ASM_SH7724_H__ */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index 3cc3827380e3..f254166e1f3b 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -233,73 +233,10 @@ static struct clk_lookup lookups[] = {
233 CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]), 233 CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
234 CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]), 234 CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
235 CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]), 235 CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
236 {
237 /* TMU0 */
238 .dev_id = "sh_tmu.0",
239 .con_id = "tmu_fck",
240 .clk = &mstp_clks[HWBLK_TMU0],
241 }, {
242 /* TMU1 */
243 .dev_id = "sh_tmu.1",
244 .con_id = "tmu_fck",
245 .clk = &mstp_clks[HWBLK_TMU0],
246 }, {
247 /* TMU2 */
248 .dev_id = "sh_tmu.2",
249 .con_id = "tmu_fck",
250 .clk = &mstp_clks[HWBLK_TMU0],
251 },
252 CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]), 236 CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
253 CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]), 237 CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]),
254 CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]), 238 CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]),
255 {
256 /* TMU3 */
257 .dev_id = "sh_tmu.3",
258 .con_id = "tmu_fck",
259 .clk = &mstp_clks[HWBLK_TMU1],
260 }, {
261 /* TMU4 */
262 .dev_id = "sh_tmu.4",
263 .con_id = "tmu_fck",
264 .clk = &mstp_clks[HWBLK_TMU1],
265 }, {
266 /* TMU5 */
267 .dev_id = "sh_tmu.5",
268 .con_id = "tmu_fck",
269 .clk = &mstp_clks[HWBLK_TMU1],
270 },
271 CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]), 239 CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
272 {
273 /* SCIF0 */
274 .dev_id = "sh-sci.0",
275 .con_id = "sci_fck",
276 .clk = &mstp_clks[HWBLK_SCIF0],
277 }, {
278 /* SCIF1 */
279 .dev_id = "sh-sci.1",
280 .con_id = "sci_fck",
281 .clk = &mstp_clks[HWBLK_SCIF1],
282 }, {
283 /* SCIF2 */
284 .dev_id = "sh-sci.2",
285 .con_id = "sci_fck",
286 .clk = &mstp_clks[HWBLK_SCIF2],
287 }, {
288 /* SCIF3 */
289 .dev_id = "sh-sci.3",
290 .con_id = "sci_fck",
291 .clk = &mstp_clks[HWBLK_SCIF3],
292 }, {
293 /* SCIF4 */
294 .dev_id = "sh-sci.4",
295 .con_id = "sci_fck",
296 .clk = &mstp_clks[HWBLK_SCIF4],
297 }, {
298 /* SCIF5 */
299 .dev_id = "sh-sci.5",
300 .con_id = "sci_fck",
301 .clk = &mstp_clks[HWBLK_SCIF5],
302 },
303 CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]), 240 CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]),
304 CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]), 241 CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]),
305 CLKDEV_CON_ID("meram0", &mstp_clks[HWBLK_MERAM]), 242 CLKDEV_CON_ID("meram0", &mstp_clks[HWBLK_MERAM]),
@@ -324,6 +261,19 @@ static struct clk_lookup lookups[] = {
324 CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU2H0]), 261 CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU2H0]),
325 CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]), 262 CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
326 CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]), 263 CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]),
264
265 CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[HWBLK_TMU0]),
266 CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[HWBLK_TMU0]),
267 CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU0]),
268 CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[HWBLK_TMU1]),
269 CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[HWBLK_TMU1]),
270 CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[HWBLK_TMU1]),
271 CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
272 CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
273 CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
274 CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
275 CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
276 CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
327}; 277};
328 278
329int __init arch_clk_init(void) 279int __init arch_clk_init(void)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 8668f557e0ac..9ee4b3667ddf 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -111,13 +111,16 @@ static struct clk div3_clk = {
111 .parent = &pll_clk, 111 .parent = &pll_clk,
112}; 112};
113 113
114/* External input clock (pin name: FSIMCKA/FSIMCKB ) */ 114/* External input clock (pin name: FSIMCKA/FSIMCKB/DV_CLKI ) */
115struct clk sh7724_fsimcka_clk = { 115struct clk sh7724_fsimcka_clk = {
116}; 116};
117 117
118struct clk sh7724_fsimckb_clk = { 118struct clk sh7724_fsimckb_clk = {
119}; 119};
120 120
121struct clk sh7724_dv_clki = {
122};
123
121static struct clk *main_clks[] = { 124static struct clk *main_clks[] = {
122 &r_clk, 125 &r_clk,
123 &extal_clk, 126 &extal_clk,
@@ -126,6 +129,7 @@ static struct clk *main_clks[] = {
126 &div3_clk, 129 &div3_clk,
127 &sh7724_fsimcka_clk, 130 &sh7724_fsimcka_clk,
128 &sh7724_fsimckb_clk, 131 &sh7724_fsimckb_clk,
132 &sh7724_dv_clki,
129}; 133};
130 134
131static void div4_kick(struct clk *clk) 135static void div4_kick(struct clk *clk)
@@ -163,17 +167,20 @@ struct clk div4_clks[DIV4_NR] = {
163 [DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT), 167 [DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
164}; 168};
165 169
166enum { DIV6_V, DIV6_I, DIV6_S, DIV6_NR }; 170enum { DIV6_V, DIV6_I, DIV6_S, DIV6_FA, DIV6_FB, DIV6_NR };
167 171
168static struct clk div6_clks[DIV6_NR] = { 172/* Indices are important - they are the actual src selecting values */
169 [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0), 173static struct clk *common_parent[] = {
170 [DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0), 174 [0] = &div3_clk,
171 [DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT), 175 [1] = NULL,
172}; 176};
173 177
174enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR }; 178static struct clk *vclkcr_parent[8] = {
179 [0] = &div3_clk,
180 [2] = &sh7724_dv_clki,
181 [4] = &extal_clk,
182};
175 183
176/* Indices are important - they are the actual src selecting values */
177static struct clk *fclkacr_parent[] = { 184static struct clk *fclkacr_parent[] = {
178 [0] = &div3_clk, 185 [0] = &div3_clk,
179 [1] = NULL, 186 [1] = NULL,
@@ -188,10 +195,16 @@ static struct clk *fclkbcr_parent[] = {
188 [3] = NULL, 195 [3] = NULL,
189}; 196};
190 197
191static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { 198static struct clk div6_clks[DIV6_NR] = {
192 [DIV6_FA] = SH_CLK_DIV6_EXT(&div3_clk, FCLKACR, 0, 199 [DIV6_V] = SH_CLK_DIV6_EXT(VCLKCR, 0,
200 vclkcr_parent, ARRAY_SIZE(vclkcr_parent), 12, 3),
201 [DIV6_I] = SH_CLK_DIV6_EXT(IRDACLKCR, 0,
202 common_parent, ARRAY_SIZE(common_parent), 6, 1),
203 [DIV6_S] = SH_CLK_DIV6_EXT(SPUCLKCR, CLK_ENABLE_ON_INIT,
204 common_parent, ARRAY_SIZE(common_parent), 6, 1),
205 [DIV6_FA] = SH_CLK_DIV6_EXT(FCLKACR, 0,
193 fclkacr_parent, ARRAY_SIZE(fclkacr_parent), 6, 2), 206 fclkacr_parent, ARRAY_SIZE(fclkacr_parent), 6, 2),
194 [DIV6_FB] = SH_CLK_DIV6_EXT(&div3_clk, FCLKBCR, 0, 207 [DIV6_FB] = SH_CLK_DIV6_EXT(FCLKBCR, 0,
195 fclkbcr_parent, ARRAY_SIZE(fclkbcr_parent), 6, 2), 208 fclkbcr_parent, ARRAY_SIZE(fclkbcr_parent), 6, 2),
196}; 209};
197 210
@@ -269,8 +282,8 @@ static struct clk_lookup lookups[] = {
269 282
270 /* DIV6 clocks */ 283 /* DIV6 clocks */
271 CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), 284 CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
272 CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FA]), 285 CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]),
273 CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FB]), 286 CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]),
274 CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]), 287 CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]),
275 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]), 288 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]),
276 289
@@ -356,10 +369,7 @@ int __init arch_clk_init(void)
356 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); 369 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
357 370
358 if (!ret) 371 if (!ret)
359 ret = sh_clk_div6_register(div6_clks, DIV6_NR); 372 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
360
361 if (!ret)
362 ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
363 373
364 if (!ret) 374 if (!ret)
365 ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR); 375 ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c
index db257a35e71a..7715de2629c1 100644
--- a/drivers/sh/clk/core.c
+++ b/drivers/sh/clk/core.c
@@ -355,7 +355,7 @@ static int clk_establish_mapping(struct clk *clk)
355 */ 355 */
356 if (!clk->parent) { 356 if (!clk->parent) {
357 clk->mapping = &dummy_mapping; 357 clk->mapping = &dummy_mapping;
358 return 0; 358 goto out;
359 } 359 }
360 360
361 /* 361 /*
@@ -384,6 +384,9 @@ static int clk_establish_mapping(struct clk *clk)
384 } 384 }
385 385
386 clk->mapping = mapping; 386 clk->mapping = mapping;
387out:
388 clk->mapped_reg = clk->mapping->base;
389 clk->mapped_reg += (phys_addr_t)clk->enable_reg - clk->mapping->phys;
387 return 0; 390 return 0;
388} 391}
389 392
@@ -402,10 +405,12 @@ static void clk_teardown_mapping(struct clk *clk)
402 405
403 /* Nothing to do */ 406 /* Nothing to do */
404 if (mapping == &dummy_mapping) 407 if (mapping == &dummy_mapping)
405 return; 408 goto out;
406 409
407 kref_put(&mapping->ref, clk_destroy_mapping); 410 kref_put(&mapping->ref, clk_destroy_mapping);
408 clk->mapping = NULL; 411 clk->mapping = NULL;
412out:
413 clk->mapped_reg = NULL;
409} 414}
410 415
411int clk_register(struct clk *clk) 416int clk_register(struct clk *clk)
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index 82dd6fb17838..a0d8faa40baa 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -15,15 +15,15 @@
15 15
16static int sh_clk_mstp32_enable(struct clk *clk) 16static int sh_clk_mstp32_enable(struct clk *clk)
17{ 17{
18 __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit), 18 iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
19 clk->enable_reg); 19 clk->mapped_reg);
20 return 0; 20 return 0;
21} 21}
22 22
23static void sh_clk_mstp32_disable(struct clk *clk) 23static void sh_clk_mstp32_disable(struct clk *clk)
24{ 24{
25 __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit), 25 iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
26 clk->enable_reg); 26 clk->mapped_reg);
27} 27}
28 28
29static struct clk_ops sh_clk_mstp32_clk_ops = { 29static struct clk_ops sh_clk_mstp32_clk_ops = {
@@ -72,7 +72,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk)
72 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 72 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
73 table, NULL); 73 table, NULL);
74 74
75 idx = __raw_readl(clk->enable_reg) & 0x003f; 75 idx = ioread32(clk->mapped_reg) & 0x003f;
76 76
77 return clk->freq_table[idx].frequency; 77 return clk->freq_table[idx].frequency;
78} 78}
@@ -98,10 +98,10 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
98 if (ret < 0) 98 if (ret < 0)
99 return ret; 99 return ret;
100 100
101 value = __raw_readl(clk->enable_reg) & 101 value = ioread32(clk->mapped_reg) &
102 ~(((1 << clk->src_width) - 1) << clk->src_shift); 102 ~(((1 << clk->src_width) - 1) << clk->src_shift);
103 103
104 __raw_writel(value | (i << clk->src_shift), clk->enable_reg); 104 iowrite32(value | (i << clk->src_shift), clk->mapped_reg);
105 105
106 /* Rebuild the frequency table */ 106 /* Rebuild the frequency table */
107 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 107 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -119,10 +119,10 @@ static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
119 if (idx < 0) 119 if (idx < 0)
120 return idx; 120 return idx;
121 121
122 value = __raw_readl(clk->enable_reg); 122 value = ioread32(clk->mapped_reg);
123 value &= ~0x3f; 123 value &= ~0x3f;
124 value |= idx; 124 value |= idx;
125 __raw_writel(value, clk->enable_reg); 125 iowrite32(value, clk->mapped_reg);
126 return 0; 126 return 0;
127} 127}
128 128
@@ -133,9 +133,9 @@ static int sh_clk_div6_enable(struct clk *clk)
133 133
134 ret = sh_clk_div6_set_rate(clk, clk->rate); 134 ret = sh_clk_div6_set_rate(clk, clk->rate);
135 if (ret == 0) { 135 if (ret == 0) {
136 value = __raw_readl(clk->enable_reg); 136 value = ioread32(clk->mapped_reg);
137 value &= ~0x100; /* clear stop bit to enable clock */ 137 value &= ~0x100; /* clear stop bit to enable clock */
138 __raw_writel(value, clk->enable_reg); 138 iowrite32(value, clk->mapped_reg);
139 } 139 }
140 return ret; 140 return ret;
141} 141}
@@ -144,10 +144,10 @@ static void sh_clk_div6_disable(struct clk *clk)
144{ 144{
145 unsigned long value; 145 unsigned long value;
146 146
147 value = __raw_readl(clk->enable_reg); 147 value = ioread32(clk->mapped_reg);
148 value |= 0x100; /* stop clock */ 148 value |= 0x100; /* stop clock */
149 value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ 149 value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
150 __raw_writel(value, clk->enable_reg); 150 iowrite32(value, clk->mapped_reg);
151} 151}
152 152
153static struct clk_ops sh_clk_div6_clk_ops = { 153static struct clk_ops sh_clk_div6_clk_ops = {
@@ -167,6 +167,38 @@ static struct clk_ops sh_clk_div6_reparent_clk_ops = {
167 .set_parent = sh_clk_div6_set_parent, 167 .set_parent = sh_clk_div6_set_parent,
168}; 168};
169 169
170static int __init sh_clk_init_parent(struct clk *clk)
171{
172 u32 val;
173
174 if (clk->parent)
175 return 0;
176
177 if (!clk->parent_table || !clk->parent_num)
178 return 0;
179
180 if (!clk->src_width) {
181 pr_err("sh_clk_init_parent: cannot select parent clock\n");
182 return -EINVAL;
183 }
184
185 val = (ioread32(clk->mapped_reg) >> clk->src_shift);
186 val &= (1 << clk->src_width) - 1;
187
188 if (val >= clk->parent_num) {
189 pr_err("sh_clk_init_parent: parent table size failed\n");
190 return -EINVAL;
191 }
192
193 clk->parent = clk->parent_table[val];
194 if (!clk->parent) {
195 pr_err("sh_clk_init_parent: unable to set parent");
196 return -EINVAL;
197 }
198
199 return 0;
200}
201
170static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, 202static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
171 struct clk_ops *ops) 203 struct clk_ops *ops)
172{ 204{
@@ -190,6 +222,9 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
190 clkp->ops = ops; 222 clkp->ops = ops;
191 clkp->freq_table = freq_table + (k * freq_table_size); 223 clkp->freq_table = freq_table + (k * freq_table_size);
192 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; 224 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
225 ret = sh_clk_init_parent(clkp);
226 if (ret < 0)
227 break;
193 228
194 ret = clk_register(clkp); 229 ret = clk_register(clkp);
195 } 230 }
@@ -217,7 +252,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk)
217 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 252 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
218 table, &clk->arch_flags); 253 table, &clk->arch_flags);
219 254
220 idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f; 255 idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f;
221 256
222 return clk->freq_table[idx].frequency; 257 return clk->freq_table[idx].frequency;
223} 258}
@@ -235,15 +270,15 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
235 */ 270 */
236 271
237 if (parent->flags & CLK_ENABLE_ON_INIT) 272 if (parent->flags & CLK_ENABLE_ON_INIT)
238 value = __raw_readl(clk->enable_reg) & ~(1 << 7); 273 value = ioread32(clk->mapped_reg) & ~(1 << 7);
239 else 274 else
240 value = __raw_readl(clk->enable_reg) | (1 << 7); 275 value = ioread32(clk->mapped_reg) | (1 << 7);
241 276
242 ret = clk_reparent(clk, parent); 277 ret = clk_reparent(clk, parent);
243 if (ret < 0) 278 if (ret < 0)
244 return ret; 279 return ret;
245 280
246 __raw_writel(value, clk->enable_reg); 281 iowrite32(value, clk->mapped_reg);
247 282
248 /* Rebiuld the frequency table */ 283 /* Rebiuld the frequency table */
249 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 284 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -260,10 +295,10 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
260 if (idx < 0) 295 if (idx < 0)
261 return idx; 296 return idx;
262 297
263 value = __raw_readl(clk->enable_reg); 298 value = ioread32(clk->mapped_reg);
264 value &= ~(0xf << clk->enable_bit); 299 value &= ~(0xf << clk->enable_bit);
265 value |= (idx << clk->enable_bit); 300 value |= (idx << clk->enable_bit);
266 __raw_writel(value, clk->enable_reg); 301 iowrite32(value, clk->mapped_reg);
267 302
268 if (d4t->kick) 303 if (d4t->kick)
269 d4t->kick(clk); 304 d4t->kick(clk);
@@ -273,13 +308,13 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
273 308
274static int sh_clk_div4_enable(struct clk *clk) 309static int sh_clk_div4_enable(struct clk *clk)
275{ 310{
276 __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg); 311 iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg);
277 return 0; 312 return 0;
278} 313}
279 314
280static void sh_clk_div4_disable(struct clk *clk) 315static void sh_clk_div4_disable(struct clk *clk)
281{ 316{
282 __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg); 317 iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg);
283} 318}
284 319
285static struct clk_ops sh_clk_div4_clk_ops = { 320static struct clk_ops sh_clk_div4_clk_ops = {
diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c
index e67fe170d8d5..522c6c46d1be 100644
--- a/drivers/sh/pfc.c
+++ b/drivers/sh/pfc.c
@@ -19,6 +19,75 @@
19#include <linux/irq.h> 19#include <linux/irq.h>
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <linux/gpio.h> 21#include <linux/gpio.h>
22#include <linux/slab.h>
23#include <linux/ioport.h>
24
25static void pfc_iounmap(struct pinmux_info *pip)
26{
27 int k;
28
29 for (k = 0; k < pip->num_resources; k++)
30 if (pip->window[k].virt)
31 iounmap(pip->window[k].virt);
32
33 kfree(pip->window);
34 pip->window = NULL;
35}
36
37static int pfc_ioremap(struct pinmux_info *pip)
38{
39 struct resource *res;
40 int k;
41
42 if (!pip->num_resources)
43 return 0;
44
45 pip->window = kzalloc(pip->num_resources * sizeof(*pip->window),
46 GFP_NOWAIT);
47 if (!pip->window)
48 goto err1;
49
50 for (k = 0; k < pip->num_resources; k++) {
51 res = pip->resource + k;
52 WARN_ON(resource_type(res) != IORESOURCE_MEM);
53 pip->window[k].phys = res->start;
54 pip->window[k].size = resource_size(res);
55 pip->window[k].virt = ioremap_nocache(res->start,
56 resource_size(res));
57 if (!pip->window[k].virt)
58 goto err2;
59 }
60
61 return 0;
62
63err2:
64 pfc_iounmap(pip);
65err1:
66 return -1;
67}
68
69static void __iomem *pfc_phys_to_virt(struct pinmux_info *pip,
70 unsigned long address)
71{
72 struct pfc_window *window;
73 int k;
74
75 /* scan through physical windows and convert address */
76 for (k = 0; k < pip->num_resources; k++) {
77 window = pip->window + k;
78
79 if (address < window->phys)
80 continue;
81
82 if (address >= (window->phys + window->size))
83 continue;
84
85 return window->virt + (address - window->phys);
86 }
87
88 /* no windows defined, register must be 1:1 mapped virt:phys */
89 return (void __iomem *)address;
90}
22 91
23static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) 92static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
24{ 93{
@@ -31,41 +100,54 @@ static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
31 return 1; 100 return 1;
32} 101}
33 102
34static unsigned long gpio_read_raw_reg(unsigned long reg, 103static unsigned long gpio_read_raw_reg(void __iomem *mapped_reg,
35 unsigned long reg_width) 104 unsigned long reg_width)
36{ 105{
37 switch (reg_width) { 106 switch (reg_width) {
38 case 8: 107 case 8:
39 return __raw_readb(reg); 108 return ioread8(mapped_reg);
40 case 16: 109 case 16:
41 return __raw_readw(reg); 110 return ioread16(mapped_reg);
42 case 32: 111 case 32:
43 return __raw_readl(reg); 112 return ioread32(mapped_reg);
44 } 113 }
45 114
46 BUG(); 115 BUG();
47 return 0; 116 return 0;
48} 117}
49 118
50static void gpio_write_raw_reg(unsigned long reg, 119static void gpio_write_raw_reg(void __iomem *mapped_reg,
51 unsigned long reg_width, 120 unsigned long reg_width,
52 unsigned long data) 121 unsigned long data)
53{ 122{
54 switch (reg_width) { 123 switch (reg_width) {
55 case 8: 124 case 8:
56 __raw_writeb(data, reg); 125 iowrite8(data, mapped_reg);
57 return; 126 return;
58 case 16: 127 case 16:
59 __raw_writew(data, reg); 128 iowrite16(data, mapped_reg);
60 return; 129 return;
61 case 32: 130 case 32:
62 __raw_writel(data, reg); 131 iowrite32(data, mapped_reg);
63 return; 132 return;
64 } 133 }
65 134
66 BUG(); 135 BUG();
67} 136}
68 137
138static int gpio_read_bit(struct pinmux_data_reg *dr,
139 unsigned long in_pos)
140{
141 unsigned long pos;
142
143 pos = dr->reg_width - (in_pos + 1);
144
145 pr_debug("read_bit: addr = %lx, pos = %ld, "
146 "r_width = %ld\n", dr->reg, pos, dr->reg_width);
147
148 return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1;
149}
150
69static void gpio_write_bit(struct pinmux_data_reg *dr, 151static void gpio_write_bit(struct pinmux_data_reg *dr,
70 unsigned long in_pos, unsigned long value) 152 unsigned long in_pos, unsigned long value)
71{ 153{
@@ -82,53 +164,72 @@ static void gpio_write_bit(struct pinmux_data_reg *dr,
82 else 164 else
83 clear_bit(pos, &dr->reg_shadow); 165 clear_bit(pos, &dr->reg_shadow);
84 166
85 gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow); 167 gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
86} 168}
87 169
88static int gpio_read_reg(unsigned long reg, unsigned long reg_width, 170static void config_reg_helper(struct pinmux_info *gpioc,
89 unsigned long field_width, unsigned long in_pos) 171 struct pinmux_cfg_reg *crp,
172 unsigned long in_pos,
173 void __iomem **mapped_regp,
174 unsigned long *maskp,
175 unsigned long *posp)
90{ 176{
91 unsigned long data, mask, pos; 177 int k;
178
179 *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
92 180
93 data = 0; 181 if (crp->field_width) {
94 mask = (1 << field_width) - 1; 182 *maskp = (1 << crp->field_width) - 1;
95 pos = reg_width - ((in_pos + 1) * field_width); 183 *posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
184 } else {
185 *maskp = (1 << crp->var_field_width[in_pos]) - 1;
186 *posp = crp->reg_width;
187 for (k = 0; k <= in_pos; k++)
188 *posp -= crp->var_field_width[k];
189 }
190}
96 191
97 pr_debug("read_reg: addr = %lx, pos = %ld, " 192static int read_config_reg(struct pinmux_info *gpioc,
193 struct pinmux_cfg_reg *crp,
194 unsigned long field)
195{
196 void __iomem *mapped_reg;
197 unsigned long mask, pos;
198
199 config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
200
201 pr_debug("read_reg: addr = %lx, field = %ld, "
98 "r_width = %ld, f_width = %ld\n", 202 "r_width = %ld, f_width = %ld\n",
99 reg, pos, reg_width, field_width); 203 crp->reg, field, crp->reg_width, crp->field_width);
100 204
101 data = gpio_read_raw_reg(reg, reg_width); 205 return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
102 return (data >> pos) & mask;
103} 206}
104 207
105static void gpio_write_reg(unsigned long reg, unsigned long reg_width, 208static void write_config_reg(struct pinmux_info *gpioc,
106 unsigned long field_width, unsigned long in_pos, 209 struct pinmux_cfg_reg *crp,
107 unsigned long value) 210 unsigned long field, unsigned long value)
108{ 211{
109 unsigned long mask, pos; 212 void __iomem *mapped_reg;
213 unsigned long mask, pos, data;
110 214
111 mask = (1 << field_width) - 1; 215 config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
112 pos = reg_width - ((in_pos + 1) * field_width);
113 216
114 pr_debug("write_reg addr = %lx, value = %ld, pos = %ld, " 217 pr_debug("write_reg addr = %lx, value = %ld, field = %ld, "
115 "r_width = %ld, f_width = %ld\n", 218 "r_width = %ld, f_width = %ld\n",
116 reg, value, pos, reg_width, field_width); 219 crp->reg, value, field, crp->reg_width, crp->field_width);
117 220
118 mask = ~(mask << pos); 221 mask = ~(mask << pos);
119 value = value << pos; 222 value = value << pos;
120 223
121 switch (reg_width) { 224 data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
122 case 8: 225 data &= mask;
123 __raw_writeb((__raw_readb(reg) & mask) | value, reg); 226 data |= value;
124 break; 227
125 case 16: 228 if (gpioc->unlock_reg)
126 __raw_writew((__raw_readw(reg) & mask) | value, reg); 229 gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg),
127 break; 230 32, ~data);
128 case 32: 231
129 __raw_writel((__raw_readl(reg) & mask) | value, reg); 232 gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
130 break;
131 }
132} 233}
133 234
134static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio) 235static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
@@ -147,6 +248,8 @@ static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
147 if (!data_reg->reg_width) 248 if (!data_reg->reg_width)
148 break; 249 break;
149 250
251 data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
252
150 for (n = 0; n < data_reg->reg_width; n++) { 253 for (n = 0; n < data_reg->reg_width; n++) {
151 if (data_reg->enum_ids[n] == gpiop->enum_id) { 254 if (data_reg->enum_ids[n] == gpiop->enum_id) {
152 gpiop->flags &= ~PINMUX_FLAG_DREG; 255 gpiop->flags &= ~PINMUX_FLAG_DREG;
@@ -179,7 +282,8 @@ static void setup_data_regs(struct pinmux_info *gpioc)
179 if (!drp->reg_width) 282 if (!drp->reg_width)
180 break; 283 break;
181 284
182 drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width); 285 drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
286 drp->reg_width);
183 k++; 287 k++;
184 } 288 }
185} 289}
@@ -201,12 +305,13 @@ static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
201} 305}
202 306
203static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id, 307static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
204 struct pinmux_cfg_reg **crp, int *indexp, 308 struct pinmux_cfg_reg **crp,
309 int *fieldp, int *valuep,
205 unsigned long **cntp) 310 unsigned long **cntp)
206{ 311{
207 struct pinmux_cfg_reg *config_reg; 312 struct pinmux_cfg_reg *config_reg;
208 unsigned long r_width, f_width; 313 unsigned long r_width, f_width, curr_width, ncomb;
209 int k, n; 314 int k, m, n, pos, bit_pos;
210 315
211 k = 0; 316 k = 0;
212 while (1) { 317 while (1) {
@@ -217,13 +322,27 @@ static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
217 322
218 if (!r_width) 323 if (!r_width)
219 break; 324 break;
220 for (n = 0; n < (r_width / f_width) * (1 << f_width); n++) { 325
221 if (config_reg->enum_ids[n] == enum_id) { 326 pos = 0;
222 *crp = config_reg; 327 m = 0;
223 *indexp = n; 328 for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
224 *cntp = &config_reg->cnt[n / (1 << f_width)]; 329 if (f_width)
225 return 0; 330 curr_width = f_width;
331 else
332 curr_width = config_reg->var_field_width[m];
333
334 ncomb = 1 << curr_width;
335 for (n = 0; n < ncomb; n++) {
336 if (config_reg->enum_ids[pos + n] == enum_id) {
337 *crp = config_reg;
338 *fieldp = m;
339 *valuep = n;
340 *cntp = &config_reg->cnt[m];
341 return 0;
342 }
226 } 343 }
344 pos += ncomb;
345 m++;
227 } 346 }
228 k++; 347 k++;
229 } 348 }
@@ -261,36 +380,6 @@ static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
261 return -1; 380 return -1;
262} 381}
263 382
264static void write_config_reg(struct pinmux_info *gpioc,
265 struct pinmux_cfg_reg *crp,
266 int index)
267{
268 unsigned long ncomb, pos, value;
269
270 ncomb = 1 << crp->field_width;
271 pos = index / ncomb;
272 value = index % ncomb;
273
274 gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
275}
276
277static int check_config_reg(struct pinmux_info *gpioc,
278 struct pinmux_cfg_reg *crp,
279 int index)
280{
281 unsigned long ncomb, pos, value;
282
283 ncomb = 1 << crp->field_width;
284 pos = index / ncomb;
285 value = index % ncomb;
286
287 if (gpio_read_reg(crp->reg, crp->reg_width,
288 crp->field_width, pos) == value)
289 return 0;
290
291 return -1;
292}
293
294enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; 383enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
295 384
296static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, 385static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
@@ -299,7 +388,7 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
299 struct pinmux_cfg_reg *cr = NULL; 388 struct pinmux_cfg_reg *cr = NULL;
300 pinmux_enum_t enum_id; 389 pinmux_enum_t enum_id;
301 struct pinmux_range *range; 390 struct pinmux_range *range;
302 int in_range, pos, index; 391 int in_range, pos, field, value;
303 unsigned long *cntp; 392 unsigned long *cntp;
304 393
305 switch (pinmux_type) { 394 switch (pinmux_type) {
@@ -330,7 +419,8 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
330 419
331 pos = 0; 420 pos = 0;
332 enum_id = 0; 421 enum_id = 0;
333 index = 0; 422 field = 0;
423 value = 0;
334 while (1) { 424 while (1) {
335 pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id); 425 pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
336 if (pos <= 0) 426 if (pos <= 0)
@@ -377,17 +467,19 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
377 if (!in_range) 467 if (!in_range)
378 continue; 468 continue;
379 469
380 if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0) 470 if (get_config_reg(gpioc, enum_id, &cr,
471 &field, &value, &cntp) != 0)
381 goto out_err; 472 goto out_err;
382 473
383 switch (cfg_mode) { 474 switch (cfg_mode) {
384 case GPIO_CFG_DRYRUN: 475 case GPIO_CFG_DRYRUN:
385 if (!*cntp || !check_config_reg(gpioc, cr, index)) 476 if (!*cntp ||
477 (read_config_reg(gpioc, cr, field) != value))
386 continue; 478 continue;
387 break; 479 break;
388 480
389 case GPIO_CFG_REQ: 481 case GPIO_CFG_REQ:
390 write_config_reg(gpioc, cr, index); 482 write_config_reg(gpioc, cr, field, value);
391 *cntp = *cntp + 1; 483 *cntp = *cntp + 1;
392 break; 484 break;
393 485
@@ -564,7 +656,7 @@ static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
564 if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) 656 if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
565 return -EINVAL; 657 return -EINVAL;
566 658
567 return gpio_read_reg(dr->reg, dr->reg_width, 1, bit); 659 return gpio_read_bit(dr, bit);
568} 660}
569 661
570static int sh_gpio_get(struct gpio_chip *chip, unsigned offset) 662static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -606,10 +698,15 @@ static int sh_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
606int register_pinmux(struct pinmux_info *pip) 698int register_pinmux(struct pinmux_info *pip)
607{ 699{
608 struct gpio_chip *chip = &pip->chip; 700 struct gpio_chip *chip = &pip->chip;
701 int ret;
609 702
610 pr_info("%s handling gpio %d -> %d\n", 703 pr_info("%s handling gpio %d -> %d\n",
611 pip->name, pip->first_gpio, pip->last_gpio); 704 pip->name, pip->first_gpio, pip->last_gpio);
612 705
706 ret = pfc_ioremap(pip);
707 if (ret < 0)
708 return ret;
709
613 setup_data_regs(pip); 710 setup_data_regs(pip);
614 711
615 chip->request = sh_gpio_request; 712 chip->request = sh_gpio_request;
@@ -627,12 +724,16 @@ int register_pinmux(struct pinmux_info *pip)
627 chip->base = pip->first_gpio; 724 chip->base = pip->first_gpio;
628 chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1; 725 chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
629 726
630 return gpiochip_add(chip); 727 ret = gpiochip_add(chip);
728 if (ret < 0)
729 pfc_iounmap(pip);
730
731 return ret;
631} 732}
632 733
633int unregister_pinmux(struct pinmux_info *pip) 734int unregister_pinmux(struct pinmux_info *pip)
634{ 735{
635 pr_info("%s deregistering\n", pip->name); 736 pr_info("%s deregistering\n", pip->name);
636 737 pfc_iounmap(pip);
637 return gpiochip_remove(&pip->chip); 738 return gpiochip_remove(&pip->chip);
638} 739}
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
index a20831cf336a..54341d811685 100644
--- a/include/linux/sh_clk.h
+++ b/include/linux/sh_clk.h
@@ -49,6 +49,7 @@ struct clk {
49 49
50 void __iomem *enable_reg; 50 void __iomem *enable_reg;
51 unsigned int enable_bit; 51 unsigned int enable_bit;
52 void __iomem *mapped_reg;
52 53
53 unsigned long arch_flags; 54 unsigned long arch_flags;
54 void *priv; 55 void *priv;
@@ -131,10 +132,9 @@ int sh_clk_div4_enable_register(struct clk *clks, int nr,
131int sh_clk_div4_reparent_register(struct clk *clks, int nr, 132int sh_clk_div4_reparent_register(struct clk *clks, int nr,
132 struct clk_div4_table *table); 133 struct clk_div4_table *table);
133 134
134#define SH_CLK_DIV6_EXT(_parent, _reg, _flags, _parents, \ 135#define SH_CLK_DIV6_EXT(_reg, _flags, _parents, \
135 _num_parents, _src_shift, _src_width) \ 136 _num_parents, _src_shift, _src_width) \
136{ \ 137{ \
137 .parent = _parent, \
138 .enable_reg = (void __iomem *)_reg, \ 138 .enable_reg = (void __iomem *)_reg, \
139 .flags = _flags, \ 139 .flags = _flags, \
140 .parent_table = _parents, \ 140 .parent_table = _parents, \
@@ -144,7 +144,11 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr,
144} 144}
145 145
146#define SH_CLK_DIV6(_parent, _reg, _flags) \ 146#define SH_CLK_DIV6(_parent, _reg, _flags) \
147 SH_CLK_DIV6_EXT(_parent, _reg, _flags, NULL, 0, 0, 0) 147{ \
148 .parent = _parent, \
149 .enable_reg = (void __iomem *)_reg, \
150 .flags = _flags, \
151}
148 152
149int sh_clk_div6_register(struct clk *clks, int nr); 153int sh_clk_div6_register(struct clk *clks, int nr);
150int sh_clk_div6_reparent_register(struct clk *clks, int nr); 154int sh_clk_div6_reparent_register(struct clk *clks, int nr);
diff --git a/include/linux/sh_pfc.h b/include/linux/sh_pfc.h
index 8446789216e5..5c15aed9c4b2 100644
--- a/include/linux/sh_pfc.h
+++ b/include/linux/sh_pfc.h
@@ -45,16 +45,24 @@ struct pinmux_cfg_reg {
45 unsigned long reg, reg_width, field_width; 45 unsigned long reg, reg_width, field_width;
46 unsigned long *cnt; 46 unsigned long *cnt;
47 pinmux_enum_t *enum_ids; 47 pinmux_enum_t *enum_ids;
48 unsigned long *var_field_width;
48}; 49};
49 50
50#define PINMUX_CFG_REG(name, r, r_width, f_width) \ 51#define PINMUX_CFG_REG(name, r, r_width, f_width) \
51 .reg = r, .reg_width = r_width, .field_width = f_width, \ 52 .reg = r, .reg_width = r_width, .field_width = f_width, \
52 .cnt = (unsigned long [r_width / f_width]) {}, \ 53 .cnt = (unsigned long [r_width / f_width]) {}, \
53 .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \ 54 .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)])
55
56#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \
57 .reg = r, .reg_width = r_width, \
58 .cnt = (unsigned long [r_width]) {}, \
59 .var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \
60 .enum_ids = (pinmux_enum_t [])
54 61
55struct pinmux_data_reg { 62struct pinmux_data_reg {
56 unsigned long reg, reg_width, reg_shadow; 63 unsigned long reg, reg_width, reg_shadow;
57 pinmux_enum_t *enum_ids; 64 pinmux_enum_t *enum_ids;
65 void __iomem *mapped_reg;
58}; 66};
59 67
60#define PINMUX_DATA_REG(name, r, r_width) \ 68#define PINMUX_DATA_REG(name, r, r_width) \
@@ -75,6 +83,12 @@ struct pinmux_range {
75 pinmux_enum_t force; 83 pinmux_enum_t force;
76}; 84};
77 85
86struct pfc_window {
87 phys_addr_t phys;
88 void __iomem *virt;
89 unsigned long size;
90};
91
78struct pinmux_info { 92struct pinmux_info {
79 char *name; 93 char *name;
80 pinmux_enum_t reserved_id; 94 pinmux_enum_t reserved_id;
@@ -98,6 +112,12 @@ struct pinmux_info {
98 struct pinmux_irq *gpio_irq; 112 struct pinmux_irq *gpio_irq;
99 unsigned int gpio_irq_size; 113 unsigned int gpio_irq_size;
100 114
115 struct resource *resource;
116 unsigned int num_resources;
117 struct pfc_window *window;
118
119 unsigned long unlock_reg;
120
101 struct gpio_chip chip; 121 struct gpio_chip chip;
102}; 122};
103 123