diff options
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7372.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh73a0.c | 140 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/common.h | 2 | ||||
-rw-r--r-- | arch/sh/include/cpu-sh4/cpu/sh7724.h | 1 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 76 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 44 | ||||
-rw-r--r-- | drivers/sh/clk/core.c | 9 | ||||
-rw-r--r-- | drivers/sh/clk/cpg.c | 77 | ||||
-rw-r--r-- | drivers/sh/pfc.c | 273 | ||||
-rw-r--r-- | include/linux/sh_clk.h | 10 | ||||
-rw-r--r-- | include/linux/sh_pfc.h | 22 |
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 | ||
413 | static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { | 413 | static 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 | ||
95 | static unsigned long div7_recalc(struct clk *clk) | ||
96 | { | ||
97 | return clk->parent->rate / 7; | ||
98 | } | ||
99 | |||
100 | static struct clk_ops div7_clk_ops = { | ||
101 | .recalc = div7_recalc, | ||
102 | }; | ||
103 | |||
104 | static unsigned long div13_recalc(struct clk *clk) | ||
105 | { | ||
106 | return clk->parent->rate / 13; | ||
107 | } | ||
108 | |||
109 | static struct clk_ops div13_clk_ops = { | ||
110 | .recalc = div13_recalc, | ||
111 | }; | ||
112 | |||
95 | /* Divide extal1 by two */ | 113 | /* Divide extal1 by two */ |
96 | static struct clk extal1_div2_clk = { | 114 | static 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 */ |
178 | static struct clk pll1_div2_clk = { | 196 | static 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 | ||
201 | static struct clk pll1_div7_clk = { | ||
202 | .ops = &div7_clk_ops, | ||
203 | .parent = &pll1_clk, | ||
204 | }; | ||
205 | |||
206 | static struct clk pll1_div13_clk = { | ||
207 | .ops = &div13_clk_ops, | ||
208 | .parent = &pll1_clk, | ||
209 | }; | ||
210 | |||
211 | /* External input clock */ | ||
212 | struct clk sh73a0_extcki_clk = { | ||
213 | }; | ||
214 | |||
215 | struct clk sh73a0_extalr_clk = { | ||
216 | }; | ||
217 | |||
183 | static struct clk *main_clks[] = { | 218 | static 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 | ||
198 | static void div4_kick(struct clk *clk) | 237 | static 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 | ||
288 | static 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 | |||
298 | static struct clk *pll_parent[4] = { | ||
299 | [0] = &pll1_div2_clk, | ||
300 | [1] = &pll2_clk, | ||
301 | [2] = &pll1_div13_clk, | ||
302 | }; | ||
303 | |||
304 | static struct clk *hsi_parent[4] = { | ||
305 | [0] = &pll1_div2_clk, | ||
306 | [1] = &pll2_clk, | ||
307 | [2] = &pll1_div7_clk, | ||
308 | }; | ||
309 | |||
310 | static 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 | |||
317 | static 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 | |||
249 | static struct clk div6_clks[DIV6_NR] = { | 325 | static 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 | ||
272 | enum { MSTP001, | 368 | enum { 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); | |||
46 | extern void sh73a0_pinmux_init(void); | 46 | extern void sh73a0_pinmux_init(void); |
47 | extern struct clk sh73a0_extal1_clk; | 47 | extern struct clk sh73a0_extal1_clk; |
48 | extern struct clk sh73a0_extal2_clk; | 48 | extern struct clk sh73a0_extal2_clk; |
49 | extern struct clk sh73a0_extcki_clk; | ||
50 | extern struct clk sh73a0_extalr_clk; | ||
49 | 51 | ||
50 | extern unsigned int sh73a0_get_core_count(void); | 52 | extern unsigned int sh73a0_get_core_count(void); |
51 | extern void sh73a0_secondary_init(unsigned int cpu); | 53 | extern 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 | ||
315 | extern struct clk sh7724_fsimcka_clk; | 315 | extern struct clk sh7724_fsimcka_clk; |
316 | extern struct clk sh7724_fsimckb_clk; | 316 | extern struct clk sh7724_fsimckb_clk; |
317 | extern 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 | ||
329 | int __init arch_clk_init(void) | 279 | int __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 ) */ |
115 | struct clk sh7724_fsimcka_clk = { | 115 | struct clk sh7724_fsimcka_clk = { |
116 | }; | 116 | }; |
117 | 117 | ||
118 | struct clk sh7724_fsimckb_clk = { | 118 | struct clk sh7724_fsimckb_clk = { |
119 | }; | 119 | }; |
120 | 120 | ||
121 | struct clk sh7724_dv_clki = { | ||
122 | }; | ||
123 | |||
121 | static struct clk *main_clks[] = { | 124 | static 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 | ||
131 | static void div4_kick(struct clk *clk) | 135 | static 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 | ||
166 | enum { DIV6_V, DIV6_I, DIV6_S, DIV6_NR }; | 170 | enum { DIV6_V, DIV6_I, DIV6_S, DIV6_FA, DIV6_FB, DIV6_NR }; |
167 | 171 | ||
168 | static 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), | 173 | static 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 | ||
174 | enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR }; | 178 | static 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 */ | ||
177 | static struct clk *fclkacr_parent[] = { | 184 | static 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 | ||
191 | static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { | 198 | static 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; |
387 | out: | ||
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; |
412 | out: | ||
413 | clk->mapped_reg = NULL; | ||
409 | } | 414 | } |
410 | 415 | ||
411 | int clk_register(struct clk *clk) | 416 | int 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 | ||
16 | static int sh_clk_mstp32_enable(struct clk *clk) | 16 | static 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 | ||
23 | static void sh_clk_mstp32_disable(struct clk *clk) | 23 | static 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 | ||
29 | static struct clk_ops sh_clk_mstp32_clk_ops = { | 29 | static 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 | ||
153 | static struct clk_ops sh_clk_div6_clk_ops = { | 153 | static 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 | ||
170 | static 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 | |||
170 | static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, | 202 | static 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 | ||
274 | static int sh_clk_div4_enable(struct clk *clk) | 309 | static 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 | ||
280 | static void sh_clk_div4_disable(struct clk *clk) | 315 | static 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 | ||
285 | static struct clk_ops sh_clk_div4_clk_ops = { | 320 | static 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 | |||
25 | static 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 | |||
37 | static 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 | |||
63 | err2: | ||
64 | pfc_iounmap(pip); | ||
65 | err1: | ||
66 | return -1; | ||
67 | } | ||
68 | |||
69 | static 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 | ||
23 | static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) | 92 | static 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 | ||
34 | static unsigned long gpio_read_raw_reg(unsigned long reg, | 103 | static 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 | ||
50 | static void gpio_write_raw_reg(unsigned long reg, | 119 | static 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 | ||
138 | static 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 | |||
69 | static void gpio_write_bit(struct pinmux_data_reg *dr, | 151 | static 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 | ||
88 | static int gpio_read_reg(unsigned long reg, unsigned long reg_width, | 170 | static 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, " | 192 | static 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 | ||
105 | static void gpio_write_reg(unsigned long reg, unsigned long reg_width, | 208 | static 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 | ||
134 | static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio) | 235 | static 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 | ||
203 | static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id, | 307 | static 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 | ||
264 | static 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 | |||
277 | static 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 | |||
294 | enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; | 383 | enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; |
295 | 384 | ||
296 | static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, | 385 | static 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 | ||
570 | static int sh_gpio_get(struct gpio_chip *chip, unsigned offset) | 662 | static 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) | |||
606 | int register_pinmux(struct pinmux_info *pip) | 698 | int 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 | ||
633 | int unregister_pinmux(struct pinmux_info *pip) | 734 | int 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, | |||
131 | int sh_clk_div4_reparent_register(struct clk *clks, int nr, | 132 | int 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 | ||
149 | int sh_clk_div6_register(struct clk *clks, int nr); | 153 | int sh_clk_div6_register(struct clk *clks, int nr); |
150 | int sh_clk_div6_reparent_register(struct clk *clks, int nr); | 154 | int 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 | ||
55 | struct pinmux_data_reg { | 62 | struct 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 | ||
86 | struct pfc_window { | ||
87 | phys_addr_t phys; | ||
88 | void __iomem *virt; | ||
89 | unsigned long size; | ||
90 | }; | ||
91 | |||
78 | struct pinmux_info { | 92 | struct 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 | ||