Merge branches 'common/pfc' and 'common/clkfwk' into rmobile/marzen
authorPaul Mundt <lethal@linux-sh.org>
Mon, 9 Jan 2012 01:03:09 +0000 (10:03 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Mon, 9 Jan 2012 01:03:09 +0000 (10:03 +0900)
Conflicts:
arch/arm/mach-shmobile/clock-sh73a0.c

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-shmobile/clock-sh73a0.c
arch/arm/mach-shmobile/include/mach/common.h
arch/sh/include/cpu-sh4/cpu/sh7724.h
arch/sh/kernel/cpu/sh4a/clock-sh7723.c
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
drivers/sh/clk/core.c
drivers/sh/clk/cpg.c
drivers/sh/pfc.c
include/linux/sh_clk.h
include/linux/sh_pfc.h

index 995a9c3aec8fbe60da9c78f3dba9835d20db9003..e349c22a0d71c93c54e49466549814795c80b77b 100644 (file)
@@ -411,11 +411,11 @@ static struct clk *fsibckcr_parent[] = {
 };
 
 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
-       [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
+       [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
                                      hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
-       [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
+       [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
                                      fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
-       [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
+       [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
                                      fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
 };
 
index 1370a89ca358ba548c80ae5ed3ec29b52156b501..34944d01bf1ed99db00a49f4b9845271ddce3a3e 100644 (file)
@@ -92,6 +92,24 @@ static struct clk_ops div2_clk_ops = {
        .recalc         = div2_recalc,
 };
 
+static unsigned long div7_recalc(struct clk *clk)
+{
+       return clk->parent->rate / 7;
+}
+
+static struct clk_ops div7_clk_ops = {
+       .recalc         = div7_recalc,
+};
+
+static unsigned long div13_recalc(struct clk *clk)
+{
+       return clk->parent->rate / 13;
+}
+
+static struct clk_ops div13_clk_ops = {
+       .recalc         = div13_recalc,
+};
+
 /* Divide extal1 by two */
 static struct clk extal1_div2_clk = {
        .ops            = &div2_clk_ops,
@@ -174,12 +192,29 @@ static struct clk pll3_clk = {
        .enable_bit     = 3,
 };
 
-/* Divide PLL1 by two */
+/* Divide PLL */
 static struct clk pll1_div2_clk = {
        .ops            = &div2_clk_ops,
        .parent         = &pll1_clk,
 };
 
+static struct clk pll1_div7_clk = {
+       .ops            = &div7_clk_ops,
+       .parent         = &pll1_clk,
+};
+
+static struct clk pll1_div13_clk = {
+       .ops            = &div13_clk_ops,
+       .parent         = &pll1_clk,
+};
+
+/* External input clock */
+struct clk sh73a0_extcki_clk = {
+};
+
+struct clk sh73a0_extalr_clk = {
+};
+
 static struct clk *main_clks[] = {
        &r_clk,
        &sh73a0_extal1_clk,
@@ -193,6 +228,10 @@ static struct clk *main_clks[] = {
        &pll2_clk,
        &pll3_clk,
        &pll1_div2_clk,
+       &pll1_div7_clk,
+       &pll1_div13_clk,
+       &sh73a0_extcki_clk,
+       &sh73a0_extalr_clk,
 };
 
 static void div4_kick(struct clk *clk)
@@ -246,27 +285,84 @@ enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
        DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
        DIV6_NR };
 
+static struct clk *vck_parent[8] = {
+       [0] = &pll1_div2_clk,
+       [1] = &pll2_clk,
+       [2] = &sh73a0_extcki_clk,
+       [3] = &sh73a0_extal2_clk,
+       [4] = &main_div2_clk,
+       [5] = &sh73a0_extalr_clk,
+       [6] = &main_clk,
+};
+
+static struct clk *pll_parent[4] = {
+       [0] = &pll1_div2_clk,
+       [1] = &pll2_clk,
+       [2] = &pll1_div13_clk,
+};
+
+static struct clk *hsi_parent[4] = {
+       [0] = &pll1_div2_clk,
+       [1] = &pll2_clk,
+       [2] = &pll1_div7_clk,
+};
+
+static struct clk *pll_extal2_parent[] = {
+       [0] = &pll1_div2_clk,
+       [1] = &pll2_clk,
+       [2] = &sh73a0_extal2_clk,
+       [3] = &sh73a0_extal2_clk,
+};
+
+static struct clk *dsi_parent[8] = {
+       [0] = &pll1_div2_clk,
+       [1] = &pll2_clk,
+       [2] = &main_clk,
+       [3] = &sh73a0_extal2_clk,
+       [4] = &sh73a0_extcki_clk,
+};
+
 static struct clk div6_clks[DIV6_NR] = {
-       [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
-       [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
-       [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
-       [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, CLK_ENABLE_ON_INIT),
-       [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
-       [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
-       [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
-       [DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
-       [DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0),
-       [DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0),
-       [DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0),
-       [DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0),
-       [DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0),
-       [DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0),
-       [DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0),
-       [DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0),
-       [DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0),
-       [DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0),
-       [DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0),
-       [DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
+       [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
+                       vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+       [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
+                       vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+       [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
+                       vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+       [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
+                       pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+       [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+       [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+       [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+       [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+       [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
+       [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
+       [DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
+                       pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+       [DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
+                       pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+       [DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
+                       pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+       [DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+       [DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
+                       hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
+       [DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+       [DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+       [DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
+                       pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+       [DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
+                       dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
+       [DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
+                       dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
 };
 
 enum { MSTP001,
@@ -403,7 +499,7 @@ void __init sh73a0_clock_init(void)
                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
        if (!ret)
-               ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+               ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
 
        if (!ret)
                ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
index 3a9250bb6d05186828f3b58733d265b1a05108f4..c2ed19b4356094caea7fb9c8f4f79403d58b320a 100644 (file)
@@ -46,6 +46,8 @@ extern void sh73a0_clock_init(void);
 extern void sh73a0_pinmux_init(void);
 extern struct clk sh73a0_extal1_clk;
 extern struct clk sh73a0_extal2_clk;
+extern struct clk sh73a0_extcki_clk;
+extern struct clk sh73a0_extalr_clk;
 
 extern unsigned int sh73a0_get_core_count(void);
 extern void sh73a0_secondary_init(unsigned int cpu);
index cbc47e6bcab5474b4c675af5600da0c66da1883e..36ce466cbf071b49cd02695bc702938394387447 100644 (file)
@@ -314,5 +314,6 @@ enum {
 
 extern struct clk sh7724_fsimcka_clk;
 extern struct clk sh7724_fsimckb_clk;
+extern struct clk sh7724_dv_clki;
 
 #endif /* __ASM_SH7724_H__ */
index 3cc3827380e3251c1d053c1a8ea8431d49a831b3..f254166e1f3b414ddfddd873015493487395337d 100644 (file)
@@ -233,73 +233,10 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
        CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
        CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
-       {
-               /* TMU0 */
-               .dev_id         = "sh_tmu.0",
-               .con_id         = "tmu_fck",
-               .clk            = &mstp_clks[HWBLK_TMU0],
-       }, {
-               /* TMU1 */
-               .dev_id         = "sh_tmu.1",
-               .con_id         = "tmu_fck",
-               .clk            = &mstp_clks[HWBLK_TMU0],
-       }, {
-               /* TMU2 */
-               .dev_id         = "sh_tmu.2",
-               .con_id         = "tmu_fck",
-               .clk            = &mstp_clks[HWBLK_TMU0],
-       },
        CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
        CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]),
        CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]),
-       {
-               /* TMU3 */
-               .dev_id         = "sh_tmu.3",
-               .con_id         = "tmu_fck",
-               .clk            = &mstp_clks[HWBLK_TMU1],
-       }, {
-               /* TMU4 */
-               .dev_id         = "sh_tmu.4",
-               .con_id         = "tmu_fck",
-               .clk            = &mstp_clks[HWBLK_TMU1],
-       }, {
-               /* TMU5 */
-               .dev_id         = "sh_tmu.5",
-               .con_id         = "tmu_fck",
-               .clk            = &mstp_clks[HWBLK_TMU1],
-       },
        CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
-       {
-               /* SCIF0 */
-               .dev_id         = "sh-sci.0",
-               .con_id         = "sci_fck",
-               .clk            = &mstp_clks[HWBLK_SCIF0],
-       }, {
-               /* SCIF1 */
-               .dev_id         = "sh-sci.1",
-               .con_id         = "sci_fck",
-               .clk            = &mstp_clks[HWBLK_SCIF1],
-       }, {
-               /* SCIF2 */
-               .dev_id         = "sh-sci.2",
-               .con_id         = "sci_fck",
-               .clk            = &mstp_clks[HWBLK_SCIF2],
-       }, {
-               /* SCIF3 */
-               .dev_id         = "sh-sci.3",
-               .con_id         = "sci_fck",
-               .clk            = &mstp_clks[HWBLK_SCIF3],
-       }, {
-               /* SCIF4 */
-               .dev_id         = "sh-sci.4",
-               .con_id         = "sci_fck",
-               .clk            = &mstp_clks[HWBLK_SCIF4],
-       }, {
-               /* SCIF5 */
-               .dev_id         = "sh-sci.5",
-               .con_id         = "sci_fck",
-               .clk            = &mstp_clks[HWBLK_SCIF5],
-       },
        CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]),
        CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]),
        CLKDEV_CON_ID("meram0", &mstp_clks[HWBLK_MERAM]),
@@ -324,6 +261,19 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU2H0]),
        CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
        CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]),
+
+       CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[HWBLK_TMU0]),
+       CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[HWBLK_TMU0]),
+       CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU0]),
+       CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[HWBLK_TMU1]),
+       CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[HWBLK_TMU1]),
+       CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[HWBLK_TMU1]),
+       CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
+       CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
+       CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
+       CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
+       CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
+       CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
 };
 
 int __init arch_clk_init(void)
index 8668f557e0aca654d72a049eeb3b0016202be3bf..9ee4b3667ddfe9218b657d5f94fc9a01ca04925b 100644 (file)
@@ -111,13 +111,16 @@ static struct clk div3_clk = {
        .parent         = &pll_clk,
 };
 
-/* External input clock (pin name: FSIMCKA/FSIMCKB ) */
+/* External input clock (pin name: FSIMCKA/FSIMCKB/DV_CLKI ) */
 struct clk sh7724_fsimcka_clk = {
 };
 
 struct clk sh7724_fsimckb_clk = {
 };
 
+struct clk sh7724_dv_clki = {
+};
+
 static struct clk *main_clks[] = {
        &r_clk,
        &extal_clk,
@@ -126,6 +129,7 @@ static struct clk *main_clks[] = {
        &div3_clk,
        &sh7724_fsimcka_clk,
        &sh7724_fsimckb_clk,
+       &sh7724_dv_clki,
 };
 
 static void div4_kick(struct clk *clk)
@@ -163,17 +167,20 @@ struct clk div4_clks[DIV4_NR] = {
        [DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
 };
 
-enum { DIV6_V, DIV6_I, DIV6_S, DIV6_NR };
+enum { DIV6_V, DIV6_I, DIV6_S, DIV6_FA, DIV6_FB, DIV6_NR };
 
-static struct clk div6_clks[DIV6_NR] = {
-       [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
-       [DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0),
-       [DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
+/* Indices are important - they are the actual src selecting values */
+static struct clk *common_parent[] = {
+       [0] = &div3_clk,
+       [1] = NULL,
 };
 
-enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR };
+static struct clk *vclkcr_parent[8] = {
+       [0] = &div3_clk,
+       [2] = &sh7724_dv_clki,
+       [4] = &extal_clk,
+};
 
-/* Indices are important - they are the actual src selecting values */
 static struct clk *fclkacr_parent[] = {
        [0] = &div3_clk,
        [1] = NULL,
@@ -188,10 +195,16 @@ static struct clk *fclkbcr_parent[] = {
        [3] = NULL,
 };
 
-static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
-       [DIV6_FA] = SH_CLK_DIV6_EXT(&div3_clk, FCLKACR, 0,
+static struct clk div6_clks[DIV6_NR] = {
+       [DIV6_V] = SH_CLK_DIV6_EXT(VCLKCR, 0,
+                       vclkcr_parent, ARRAY_SIZE(vclkcr_parent), 12, 3),
+       [DIV6_I] = SH_CLK_DIV6_EXT(IRDACLKCR, 0,
+                       common_parent, ARRAY_SIZE(common_parent), 6, 1),
+       [DIV6_S] = SH_CLK_DIV6_EXT(SPUCLKCR, CLK_ENABLE_ON_INIT,
+                       common_parent, ARRAY_SIZE(common_parent), 6, 1),
+       [DIV6_FA] = SH_CLK_DIV6_EXT(FCLKACR, 0,
                                      fclkacr_parent, ARRAY_SIZE(fclkacr_parent), 6, 2),
-       [DIV6_FB] = SH_CLK_DIV6_EXT(&div3_clk, FCLKBCR, 0,
+       [DIV6_FB] = SH_CLK_DIV6_EXT(FCLKBCR, 0,
                                      fclkbcr_parent, ARRAY_SIZE(fclkbcr_parent), 6, 2),
 };
 
@@ -269,8 +282,8 @@ static struct clk_lookup lookups[] = {
 
        /* DIV6 clocks */
        CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
-       CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FA]),
-       CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FB]),
+       CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]),
+       CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]),
        CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]),
        CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]),
 
@@ -356,10 +369,7 @@ int __init arch_clk_init(void)
                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
        if (!ret)
-               ret = sh_clk_div6_register(div6_clks, DIV6_NR);
-
-       if (!ret)
-               ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
+               ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
 
        if (!ret)
                ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
index db257a35e71a545aa724b97d40dbdd6dbf1fe7f2..7715de2629c104de4e98a87836ea2ef308a743c4 100644 (file)
@@ -355,7 +355,7 @@ static int clk_establish_mapping(struct clk *clk)
                 */
                if (!clk->parent) {
                        clk->mapping = &dummy_mapping;
-                       return 0;
+                       goto out;
                }
 
                /*
@@ -384,6 +384,9 @@ static int clk_establish_mapping(struct clk *clk)
        }
 
        clk->mapping = mapping;
+out:
+       clk->mapped_reg = clk->mapping->base;
+       clk->mapped_reg += (phys_addr_t)clk->enable_reg - clk->mapping->phys;
        return 0;
 }
 
@@ -402,10 +405,12 @@ static void clk_teardown_mapping(struct clk *clk)
 
        /* Nothing to do */
        if (mapping == &dummy_mapping)
-               return;
+               goto out;
 
        kref_put(&mapping->ref, clk_destroy_mapping);
        clk->mapping = NULL;
+out:
+       clk->mapped_reg = NULL;
 }
 
 int clk_register(struct clk *clk)
index 82dd6fb178386a31ef29ee4adc1dcd96ccf221c5..a0d8faa40baa87abb07793046c028bddf2c5570a 100644 (file)
 
 static int sh_clk_mstp32_enable(struct clk *clk)
 {
-       __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit),
-                    clk->enable_reg);
+       iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
+                 clk->mapped_reg);
        return 0;
 }
 
 static void sh_clk_mstp32_disable(struct clk *clk)
 {
-       __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit),
-                    clk->enable_reg);
+       iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
+                 clk->mapped_reg);
 }
 
 static struct clk_ops sh_clk_mstp32_clk_ops = {
@@ -72,7 +72,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk)
        clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
                             table, NULL);
 
-       idx = __raw_readl(clk->enable_reg) & 0x003f;
+       idx = ioread32(clk->mapped_reg) & 0x003f;
 
        return clk->freq_table[idx].frequency;
 }
@@ -98,10 +98,10 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
        if (ret < 0)
                return ret;
 
-       value = __raw_readl(clk->enable_reg) &
+       value = ioread32(clk->mapped_reg) &
                ~(((1 << clk->src_width) - 1) << clk->src_shift);
 
-       __raw_writel(value | (i << clk->src_shift), clk->enable_reg);
+       iowrite32(value | (i << clk->src_shift), clk->mapped_reg);
 
        /* Rebuild the frequency table */
        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)
        if (idx < 0)
                return idx;
 
-       value = __raw_readl(clk->enable_reg);
+       value = ioread32(clk->mapped_reg);
        value &= ~0x3f;
        value |= idx;
-       __raw_writel(value, clk->enable_reg);
+       iowrite32(value, clk->mapped_reg);
        return 0;
 }
 
@@ -133,9 +133,9 @@ static int sh_clk_div6_enable(struct clk *clk)
 
        ret = sh_clk_div6_set_rate(clk, clk->rate);
        if (ret == 0) {
-               value = __raw_readl(clk->enable_reg);
+               value = ioread32(clk->mapped_reg);
                value &= ~0x100; /* clear stop bit to enable clock */
-               __raw_writel(value, clk->enable_reg);
+               iowrite32(value, clk->mapped_reg);
        }
        return ret;
 }
@@ -144,10 +144,10 @@ static void sh_clk_div6_disable(struct clk *clk)
 {
        unsigned long value;
 
-       value = __raw_readl(clk->enable_reg);
+       value = ioread32(clk->mapped_reg);
        value |= 0x100; /* stop clock */
        value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
-       __raw_writel(value, clk->enable_reg);
+       iowrite32(value, clk->mapped_reg);
 }
 
 static struct clk_ops sh_clk_div6_clk_ops = {
@@ -167,6 +167,38 @@ static struct clk_ops sh_clk_div6_reparent_clk_ops = {
        .set_parent     = sh_clk_div6_set_parent,
 };
 
+static int __init sh_clk_init_parent(struct clk *clk)
+{
+       u32 val;
+
+       if (clk->parent)
+               return 0;
+
+       if (!clk->parent_table || !clk->parent_num)
+               return 0;
+
+       if (!clk->src_width) {
+               pr_err("sh_clk_init_parent: cannot select parent clock\n");
+               return -EINVAL;
+       }
+
+       val  = (ioread32(clk->mapped_reg) >> clk->src_shift);
+       val &= (1 << clk->src_width) - 1;
+
+       if (val >= clk->parent_num) {
+               pr_err("sh_clk_init_parent: parent table size failed\n");
+               return -EINVAL;
+       }
+
+       clk->parent = clk->parent_table[val];
+       if (!clk->parent) {
+               pr_err("sh_clk_init_parent: unable to set parent");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
                                           struct clk_ops *ops)
 {
@@ -190,6 +222,9 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
                clkp->ops = ops;
                clkp->freq_table = freq_table + (k * freq_table_size);
                clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
+               ret = sh_clk_init_parent(clkp);
+               if (ret < 0)
+                       break;
 
                ret = clk_register(clkp);
        }
@@ -217,7 +252,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk)
        clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
                             table, &clk->arch_flags);
 
-       idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f;
+       idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f;
 
        return clk->freq_table[idx].frequency;
 }
@@ -235,15 +270,15 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
         */
 
        if (parent->flags & CLK_ENABLE_ON_INIT)
-               value = __raw_readl(clk->enable_reg) & ~(1 << 7);
+               value = ioread32(clk->mapped_reg) & ~(1 << 7);
        else
-               value = __raw_readl(clk->enable_reg) | (1 << 7);
+               value = ioread32(clk->mapped_reg) | (1 << 7);
 
        ret = clk_reparent(clk, parent);
        if (ret < 0)
                return ret;
 
-       __raw_writel(value, clk->enable_reg);
+       iowrite32(value, clk->mapped_reg);
 
        /* Rebiuld the frequency table */
        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)
        if (idx < 0)
                return idx;
 
-       value = __raw_readl(clk->enable_reg);
+       value = ioread32(clk->mapped_reg);
        value &= ~(0xf << clk->enable_bit);
        value |= (idx << clk->enable_bit);
-       __raw_writel(value, clk->enable_reg);
+       iowrite32(value, clk->mapped_reg);
 
        if (d4t->kick)
                d4t->kick(clk);
@@ -273,13 +308,13 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
 
 static int sh_clk_div4_enable(struct clk *clk)
 {
-       __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
+       iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg);
        return 0;
 }
 
 static void sh_clk_div4_disable(struct clk *clk)
 {
-       __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
+       iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg);
 }
 
 static struct clk_ops sh_clk_div4_clk_ops = {
index e67fe170d8d5e8bef9c7683f6490bf1a7be9dbc6..522c6c46d1be83a5f95527d509cf12142a52e523 100644 (file)
 #include <linux/irq.h>
 #include <linux/bitops.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+
+static void pfc_iounmap(struct pinmux_info *pip)
+{
+       int k;
+
+       for (k = 0; k < pip->num_resources; k++)
+               if (pip->window[k].virt)
+                       iounmap(pip->window[k].virt);
+
+       kfree(pip->window);
+       pip->window = NULL;
+}
+
+static int pfc_ioremap(struct pinmux_info *pip)
+{
+       struct resource *res;
+       int k;
+
+       if (!pip->num_resources)
+               return 0;
+
+       pip->window = kzalloc(pip->num_resources * sizeof(*pip->window),
+                             GFP_NOWAIT);
+       if (!pip->window)
+               goto err1;
+
+       for (k = 0; k < pip->num_resources; k++) {
+               res = pip->resource + k;
+               WARN_ON(resource_type(res) != IORESOURCE_MEM);
+               pip->window[k].phys = res->start;
+               pip->window[k].size = resource_size(res);
+               pip->window[k].virt = ioremap_nocache(res->start,
+                                                        resource_size(res));
+               if (!pip->window[k].virt)
+                       goto err2;
+       }
+
+       return 0;
+
+err2:
+       pfc_iounmap(pip);
+err1:
+       return -1;
+}
+
+static void __iomem *pfc_phys_to_virt(struct pinmux_info *pip,
+                                     unsigned long address)
+{
+       struct pfc_window *window;
+       int k;
+
+       /* scan through physical windows and convert address */
+       for (k = 0; k < pip->num_resources; k++) {
+               window = pip->window + k;
+
+               if (address < window->phys)
+                       continue;
+
+               if (address >= (window->phys + window->size))
+                       continue;
+
+               return window->virt + (address - window->phys);
+       }
+
+       /* no windows defined, register must be 1:1 mapped virt:phys */
+       return (void __iomem *)address;
+}
 
 static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
 {
@@ -31,41 +100,54 @@ static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
        return 1;
 }
 
-static unsigned long gpio_read_raw_reg(unsigned long reg,
+static unsigned long gpio_read_raw_reg(void __iomem *mapped_reg,
                                       unsigned long reg_width)
 {
        switch (reg_width) {
        case 8:
-               return __raw_readb(reg);
+               return ioread8(mapped_reg);
        case 16:
-               return __raw_readw(reg);
+               return ioread16(mapped_reg);
        case 32:
-               return __raw_readl(reg);
+               return ioread32(mapped_reg);
        }
 
        BUG();
        return 0;
 }
 
-static void gpio_write_raw_reg(unsigned long reg,
+static void gpio_write_raw_reg(void __iomem *mapped_reg,
                               unsigned long reg_width,
                               unsigned long data)
 {
        switch (reg_width) {
        case 8:
-               __raw_writeb(data, reg);
+               iowrite8(data, mapped_reg);
                return;
        case 16:
-               __raw_writew(data, reg);
+               iowrite16(data, mapped_reg);
                return;
        case 32:
-               __raw_writel(data, reg);
+               iowrite32(data, mapped_reg);
                return;
        }
 
        BUG();
 }
 
+static int gpio_read_bit(struct pinmux_data_reg *dr,
+                        unsigned long in_pos)
+{
+       unsigned long pos;
+
+       pos = dr->reg_width - (in_pos + 1);
+
+       pr_debug("read_bit: addr = %lx, pos = %ld, "
+                "r_width = %ld\n", dr->reg, pos, dr->reg_width);
+
+       return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1;
+}
+
 static void gpio_write_bit(struct pinmux_data_reg *dr,
                           unsigned long in_pos, unsigned long value)
 {
@@ -82,53 +164,72 @@ static void gpio_write_bit(struct pinmux_data_reg *dr,
        else
                clear_bit(pos, &dr->reg_shadow);
 
-       gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow);
+       gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
 }
 
-static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
-                        unsigned long field_width, unsigned long in_pos)
+static void config_reg_helper(struct pinmux_info *gpioc,
+                             struct pinmux_cfg_reg *crp,
+                             unsigned long in_pos,
+                             void __iomem **mapped_regp,
+                             unsigned long *maskp,
+                             unsigned long *posp)
 {
-       unsigned long data, mask, pos;
+       int k;
+
+       *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
 
-       data = 0;
-       mask = (1 << field_width) - 1;
-       pos = reg_width - ((in_pos + 1) * field_width);
+       if (crp->field_width) {
+               *maskp = (1 << crp->field_width) - 1;
+               *posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
+       } else {
+               *maskp = (1 << crp->var_field_width[in_pos]) - 1;
+               *posp = crp->reg_width;
+               for (k = 0; k <= in_pos; k++)
+                       *posp -= crp->var_field_width[k];
+       }
+}
 
-       pr_debug("read_reg: addr = %lx, pos = %ld, "
+static int read_config_reg(struct pinmux_info *gpioc,
+                          struct pinmux_cfg_reg *crp,
+                          unsigned long field)
+{
+       void __iomem *mapped_reg;
+       unsigned long mask, pos;
+
+       config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
+
+       pr_debug("read_reg: addr = %lx, field = %ld, "
                 "r_width = %ld, f_width = %ld\n",
-                reg, pos, reg_width, field_width);
+                crp->reg, field, crp->reg_width, crp->field_width);
 
-       data = gpio_read_raw_reg(reg, reg_width);
-       return (data >> pos) & mask;
+       return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
 }
 
-static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
-                          unsigned long field_width, unsigned long in_pos,
-                          unsigned long value)
+static void write_config_reg(struct pinmux_info *gpioc,
+                            struct pinmux_cfg_reg *crp,
+                            unsigned long field, unsigned long value)
 {
-       unsigned long mask, pos;
+       void __iomem *mapped_reg;
+       unsigned long mask, pos, data;
 
-       mask = (1 << field_width) - 1;
-       pos = reg_width - ((in_pos + 1) * field_width);
+       config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
 
-       pr_debug("write_reg addr = %lx, value = %ld, pos = %ld, "
+       pr_debug("write_reg addr = %lx, value = %ld, field = %ld, "
                 "r_width = %ld, f_width = %ld\n",
-                reg, value, pos, reg_width, field_width);
+                crp->reg, value, field, crp->reg_width, crp->field_width);
 
        mask = ~(mask << pos);
        value = value << pos;
 
-       switch (reg_width) {
-       case 8:
-               __raw_writeb((__raw_readb(reg) & mask) | value, reg);
-               break;
-       case 16:
-               __raw_writew((__raw_readw(reg) & mask) | value, reg);
-               break;
-       case 32:
-               __raw_writel((__raw_readl(reg) & mask) | value, reg);
-               break;
-       }
+       data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
+       data &= mask;
+       data |= value;
+
+       if (gpioc->unlock_reg)
+               gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg),
+                                  32, ~data);
+
+       gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
 }
 
 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)
                if (!data_reg->reg_width)
                        break;
 
+               data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
+
                for (n = 0; n < data_reg->reg_width; n++) {
                        if (data_reg->enum_ids[n] == gpiop->enum_id) {
                                gpiop->flags &= ~PINMUX_FLAG_DREG;
@@ -179,7 +282,8 @@ static void setup_data_regs(struct pinmux_info *gpioc)
                if (!drp->reg_width)
                        break;
 
-               drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width);
+               drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
+                                                   drp->reg_width);
                k++;
        }
 }
@@ -201,12 +305,13 @@ static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
 }
 
 static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
-                         struct pinmux_cfg_reg **crp, int *indexp,
+                         struct pinmux_cfg_reg **crp,
+                         int *fieldp, int *valuep,
                          unsigned long **cntp)
 {
        struct pinmux_cfg_reg *config_reg;
-       unsigned long r_width, f_width;
-       int k, n;
+       unsigned long r_width, f_width, curr_width, ncomb;
+       int k, m, n, pos, bit_pos;
 
        k = 0;
        while (1) {
@@ -217,13 +322,27 @@ static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
 
                if (!r_width)
                        break;
-               for (n = 0; n < (r_width / f_width) * (1 << f_width); n++) {
-                       if (config_reg->enum_ids[n] == enum_id) {
-                               *crp = config_reg;
-                               *indexp = n;
-                               *cntp = &config_reg->cnt[n / (1 << f_width)];
-                               return 0;
+
+               pos = 0;
+               m = 0;
+               for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
+                       if (f_width)
+                               curr_width = f_width;
+                       else
+                               curr_width = config_reg->var_field_width[m];
+
+                       ncomb = 1 << curr_width;
+                       for (n = 0; n < ncomb; n++) {
+                               if (config_reg->enum_ids[pos + n] == enum_id) {
+                                       *crp = config_reg;
+                                       *fieldp = m;
+                                       *valuep = n;
+                                       *cntp = &config_reg->cnt[m];
+                                       return 0;
+                               }
                        }
+                       pos += ncomb;
+                       m++;
                }
                k++;
        }
@@ -261,36 +380,6 @@ static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
        return -1;
 }
 
-static void write_config_reg(struct pinmux_info *gpioc,
-                            struct pinmux_cfg_reg *crp,
-                            int index)
-{
-       unsigned long ncomb, pos, value;
-
-       ncomb = 1 << crp->field_width;
-       pos = index / ncomb;
-       value = index % ncomb;
-
-       gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
-}
-
-static int check_config_reg(struct pinmux_info *gpioc,
-                           struct pinmux_cfg_reg *crp,
-                           int index)
-{
-       unsigned long ncomb, pos, value;
-
-       ncomb = 1 << crp->field_width;
-       pos = index / ncomb;
-       value = index % ncomb;
-
-       if (gpio_read_reg(crp->reg, crp->reg_width,
-                         crp->field_width, pos) == value)
-               return 0;
-
-       return -1;
-}
-
 enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
 
 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,
        struct pinmux_cfg_reg *cr = NULL;
        pinmux_enum_t enum_id;
        struct pinmux_range *range;
-       int in_range, pos, index;
+       int in_range, pos, field, value;
        unsigned long *cntp;
 
        switch (pinmux_type) {
@@ -330,7 +419,8 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
 
        pos = 0;
        enum_id = 0;
-       index = 0;
+       field = 0;
+       value = 0;
        while (1) {
                pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
                if (pos <= 0)
@@ -377,17 +467,19 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
                if (!in_range)
                        continue;
 
-               if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
+               if (get_config_reg(gpioc, enum_id, &cr,
+                                  &field, &value, &cntp) != 0)
                        goto out_err;
 
                switch (cfg_mode) {
                case GPIO_CFG_DRYRUN:
-                       if (!*cntp || !check_config_reg(gpioc, cr, index))
+                       if (!*cntp ||
+                           (read_config_reg(gpioc, cr, field) != value))
                                continue;
                        break;
 
                case GPIO_CFG_REQ:
-                       write_config_reg(gpioc, cr, index);
+                       write_config_reg(gpioc, cr, field, value);
                        *cntp = *cntp + 1;
                        break;
 
@@ -564,7 +656,7 @@ static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
        if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
                return -EINVAL;
 
-       return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
+       return gpio_read_bit(dr, bit);
 }
 
 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)
 int register_pinmux(struct pinmux_info *pip)
 {
        struct gpio_chip *chip = &pip->chip;
+       int ret;
 
        pr_info("%s handling gpio %d -> %d\n",
                pip->name, pip->first_gpio, pip->last_gpio);
 
+       ret = pfc_ioremap(pip);
+       if (ret < 0)
+               return ret;
+
        setup_data_regs(pip);
 
        chip->request = sh_gpio_request;
@@ -627,12 +724,16 @@ int register_pinmux(struct pinmux_info *pip)
        chip->base = pip->first_gpio;
        chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
 
-       return gpiochip_add(chip);
+       ret = gpiochip_add(chip);
+       if (ret < 0)
+               pfc_iounmap(pip);
+
+       return ret;
 }
 
 int unregister_pinmux(struct pinmux_info *pip)
 {
        pr_info("%s deregistering\n", pip->name);
-
+       pfc_iounmap(pip);
        return gpiochip_remove(&pip->chip);
 }
index a20831cf336a5ef5f6cc427b6b131766a34ca761..54341d811685a2088897491c2255ba605b71ab43 100644 (file)
@@ -49,6 +49,7 @@ struct clk {
 
        void __iomem            *enable_reg;
        unsigned int            enable_bit;
+       void __iomem            *mapped_reg;
 
        unsigned long           arch_flags;
        void                    *priv;
@@ -131,10 +132,9 @@ int sh_clk_div4_enable_register(struct clk *clks, int nr,
 int sh_clk_div4_reparent_register(struct clk *clks, int nr,
                         struct clk_div4_table *table);
 
-#define SH_CLK_DIV6_EXT(_parent, _reg, _flags, _parents,       \
+#define SH_CLK_DIV6_EXT(_reg, _flags, _parents,                        \
                        _num_parents, _src_shift, _src_width)   \
 {                                                              \
-       .parent = _parent,                                      \
        .enable_reg = (void __iomem *)_reg,                     \
        .flags = _flags,                                        \
        .parent_table = _parents,                               \
@@ -144,7 +144,11 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr,
 }
 
 #define SH_CLK_DIV6(_parent, _reg, _flags)                     \
-       SH_CLK_DIV6_EXT(_parent, _reg, _flags, NULL, 0, 0, 0)
+{                                                              \
+       .parent         = _parent,                              \
+       .enable_reg     = (void __iomem *)_reg,                 \
+       .flags          = _flags,                               \
+}
 
 int sh_clk_div6_register(struct clk *clks, int nr);
 int sh_clk_div6_reparent_register(struct clk *clks, int nr);
index 8446789216e568008fb71e9c85189758bf0197a4..5c15aed9c4b2430adebf1b5ca0b9325bcbd22acd 100644 (file)
@@ -45,16 +45,24 @@ struct pinmux_cfg_reg {
        unsigned long reg, reg_width, field_width;
        unsigned long *cnt;
        pinmux_enum_t *enum_ids;
+       unsigned long *var_field_width;
 };
 
 #define PINMUX_CFG_REG(name, r, r_width, f_width) \
        .reg = r, .reg_width = r_width, .field_width = f_width,         \
        .cnt = (unsigned long [r_width / f_width]) {}, \
-       .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
+       .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)])
+
+#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \
+       .reg = r, .reg_width = r_width, \
+       .cnt = (unsigned long [r_width]) {}, \
+       .var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \
+       .enum_ids = (pinmux_enum_t [])
 
 struct pinmux_data_reg {
        unsigned long reg, reg_width, reg_shadow;
        pinmux_enum_t *enum_ids;
+       void __iomem *mapped_reg;
 };
 
 #define PINMUX_DATA_REG(name, r, r_width) \
@@ -75,6 +83,12 @@ struct pinmux_range {
        pinmux_enum_t force;
 };
 
+struct pfc_window {
+       phys_addr_t phys;
+       void __iomem *virt;
+       unsigned long size;
+};
+
 struct pinmux_info {
        char *name;
        pinmux_enum_t reserved_id;
@@ -98,6 +112,12 @@ struct pinmux_info {
        struct pinmux_irq *gpio_irq;
        unsigned int gpio_irq_size;
 
+       struct resource *resource;
+       unsigned int num_resources;
+       struct pfc_window *window;
+
+       unsigned long unlock_reg;
+
        struct gpio_chip chip;
 };