Merge branches 'rmobile/mmcif', 'rmobile/ag5' and 'rmobile/mackerel' into rmobile...
authorPaul Mundt <lethal@linux-sh.org>
Wed, 5 Jan 2011 08:25:29 +0000 (17:25 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 5 Jan 2011 08:25:29 +0000 (17:25 +0900)
Conflicts:
arch/arm/mach-shmobile/Kconfig

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
1  2  3  4 
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/clock-sh73a0.c

@@@@@ -17,16 -21,11 -17,16 -17,9 +17,16 @@@@@ config ARCH_SH737
    config ARCH_SH7372
        bool "SH-Mobile AP4 (SH7372)"
        select CPU_V7
 -      select HAVE_CLK
 -      select COMMON_CLKDEV
        select SH_CLK_CPG
 -      select GENERIC_CLOCKEVENTS
 +      select ARCH_WANT_OPTIONAL_GPIOLIB
 +  
 + +config ARCH_SH73A0
 + +    bool "SH-Mobile AG5 (R8A73A00)"
 + +    select CPU_V7
 + +    select SH_CLK_CPG
 + +    select ARCH_WANT_OPTIONAL_GPIOLIB
 + +    select ARM_GIC
   +
    comment "SH-Mobile Board Type"
    
    config MACH_G3EVM
@@@@@ -58,15 -57,6 -58,11 -51,11 +58,15 @@@@@ config AP4EVB_WVG
    
    endchoice
    
 + +config MACH_AG5EVM
 + +    bool "AG5EVM board"
 + +    depends on ARCH_SH73A0
 +++
 ++ config MACH_MACKEREL
 ++     bool "mackerel board"
 ++     depends on ARCH_SH7372
 +      select ARCH_REQUIRE_GPIOLIB
 +  
    comment "SH-Mobile System Configuration"
    
    menu "Memory configuration"
    config MEMORY_START
        hex "Physical memory start address"
        default "0x50000000" if MACH_G3EVM
 ---    default "0x40000000" if MACH_G4EVM
 --     default "0x40000000" if MACH_AP4EVB
  -     default "0x40000000" if MACH_AG5EVM
   -    default "0x40000000" if MACH_AP4EVB || MACH_MACKEREL
 +++    default "0x40000000" if MACH_G4EVM || MACH_AP4EVB || MACH_AG5EVM || \
 +++                            MACH_MACKEREL
        default "0x00000000"
        ---help---
          Tweak this only when porting to a new machine which does not
@@@@@ -86,8 -76,7 -83,8 -75,7 +86,8 @@@@@ config MEMORY_SIZ
        hex "Physical memory size"
        default "0x08000000" if MACH_G3EVM
        default "0x08000000" if MACH_G4EVM
---     default "0x10000000" if MACH_AP4EVB
 + +    default "0x20000000" if MACH_AG5EVM
+++     default "0x10000000" if MACH_AP4EVB || MACH_MACKEREL
        default "0x04000000"
        help
          This sets the default memory size assumed by your kernel. It can
@@@@@ -577,74 -577,8 -567,8 -567,8 +577,74 @@@@@ static struct platform_device *qhd_devi
    
    /* FSI */
    #define IRQ_FSI             evt2irq(0x1840)
  --static int fsi_set_rate(int is_porta, int rate)
 +++static int __fsi_set_rate(struct clk *clk, long rate, int enable)
 +++{
 +++    int ret = 0;
 +  
 -  static int fsi_set_rate(int is_porta, int rate)
 +++    if (rate <= 0)
 +++            return ret;
 +++
 +++    if (enable) {
 +++            ret = clk_set_rate(clk, rate);
 +++            if (0 == ret)
 +++                    ret = clk_enable(clk);
 +++    } else {
 +++            clk_disable(clk);
 +++    }
 +++
 +++    return ret;
 +++}
 +++
 +++static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
 +++{
 +++    return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
 +++}
  ++
 +++static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
 +++{
 +++    struct clk *fsia_ick;
 +++    struct clk *fsiack;
 +++    int ret = -EIO;
 +++
 +++    fsia_ick = clk_get(dev, "icka");
 +++    if (IS_ERR(fsia_ick))
 +++            return PTR_ERR(fsia_ick);
 +++
 +++    /*
 +++     * FSIACK is connected to AK4642,
 +++     * and use external clock pin from it.
 +++     * it is parent of fsia_ick now.
 +++     */
 +++    fsiack = clk_get_parent(fsia_ick);
 +++    if (!fsiack)
 +++            goto fsia_ick_out;
 +++
 +++    /*
 +++     * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
 +++     *
 +++     ** FIXME **
 +++     * Because the freq_table of external clk (fsiack) are all 0,
 +++     * the return value of clk_round_rate became 0.
 +++     * So, it use __fsi_set_rate here.
 +++     */
 +++    ret = __fsi_set_rate(fsiack, rate, enable);
 +++    if (ret < 0)
 +++            goto fsiack_out;
 +++
 +++    ret = __fsi_set_round_rate(fsia_ick, rate, enable);
 +++    if ((ret < 0) && enable)
 +++            __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
 +++
 +++fsiack_out:
 +++    clk_put(fsiack);
 +++
 +++fsia_ick_out:
 +++    clk_put(fsia_ick);
 +++
 +++    return 0;
 +++}
 +++
 +++static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
    {
        struct clk *fsib_clk;
        struct clk *fdiv_clk = &sh7372_fsidivb_clk;
index 4195818,0000000,152c970,0000000..c196a28
mode 100644,000000,100644,000000..100644
--- /dev/null
--- /dev/null
@@@@@ -1,356 -1,0 -1,350 -1,0 +1,356 @@@@@
-                         24, 0, 36, 48 };
 + +/*
 + + * sh73a0 clock framework support
 + + *
 + + * Copyright (C) 2010 Magnus Damm
 + + *
 + + * This program is free software; you can redistribute it and/or modify
 + + * it under the terms of the GNU General Public License as published by
 + + * the Free Software Foundation; either version 2 of the License
 + + *
 + + * This program is distributed in the hope that it will be useful,
 + + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + + * GNU General Public License for more details.
 + + *
 + + * You should have received a copy of the GNU General Public License
 + + * along with this program; if not, write to the Free Software
 + + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + + */
 + +#include <linux/init.h>
 + +#include <linux/kernel.h>
 + +#include <linux/io.h>
 + +#include <linux/sh_clk.h>
 + +#include <mach/common.h>
 + +#include <asm/clkdev.h>
 + +
 + +#define FRQCRA              0xe6150000
 + +#define FRQCRB              0xe6150004
 + +#define FRQCRD              0xe61500e4
 + +#define VCLKCR1             0xe6150008
 + +#define VCLKCR2             0xe615000C
 + +#define VCLKCR3             0xe615001C
 + +#define ZBCKCR              0xe6150010
 + +#define FLCKCR              0xe6150014
 + +#define SD0CKCR             0xe6150074
 + +#define SD1CKCR             0xe6150078
 + +#define SD2CKCR             0xe615007C
 + +#define FSIACKCR    0xe6150018
 + +#define FSIBCKCR    0xe6150090
 + +#define SUBCKCR             0xe6150080
 + +#define SPUACKCR    0xe6150084
 + +#define SPUVCKCR    0xe6150094
 + +#define MSUCKCR             0xe6150088
 + +#define HSICKCR             0xe615008C
 + +#define MFCK1CR             0xe6150098
 + +#define MFCK2CR             0xe615009C
 + +#define DSITCKCR    0xe6150060
 + +#define DSI0PCKCR   0xe6150064
 + +#define DSI1PCKCR   0xe6150068
 + +#define DSI0PHYCR   0xe615006C
 + +#define DSI1PHYCR   0xe6150070
 + +#define PLLECR              0xe61500d0
 + +#define PLL0CR              0xe61500d8
 + +#define PLL1CR              0xe6150028
 + +#define PLL2CR              0xe615002c
 + +#define PLL3CR              0xe61500dc
 + +#define SMSTPCR0    0xe6150130
 + +#define SMSTPCR1    0xe6150134
 + +#define SMSTPCR2    0xe6150138
 + +#define SMSTPCR3    0xe615013c
 + +#define SMSTPCR4    0xe6150140
 + +#define SMSTPCR5    0xe6150144
 + +#define CKSCR               0xe61500c0
 + +
 + +/* Fixed 32 KHz root clock from EXTALR pin */
 + +static struct clk r_clk = {
 + +    .rate           = 32768,
 + +};
 + +
 + +/*
 + + * 26MHz default rate for the EXTAL1 root input clock.
 + + * If needed, reset this with clk_set_rate() from the platform code.
 + + */
 + +struct clk sh73a0_extal1_clk = {
 + +    .rate           = 26000000,
 + +};
 + +
 + +/*
 + + * 48MHz default rate for the EXTAL2 root input clock.
 + + * If needed, reset this with clk_set_rate() from the platform code.
 + + */
 + +struct clk sh73a0_extal2_clk = {
 + +    .rate           = 48000000,
 + +};
 + +
 + +/* A fixed divide-by-2 block */
 + +static unsigned long div2_recalc(struct clk *clk)
 + +{
 + +    return clk->parent->rate / 2;
 + +}
 + +
 + +static struct clk_ops div2_clk_ops = {
 + +    .recalc         = div2_recalc,
 + +};
 + +
 + +/* Divide extal1 by two */
 + +static struct clk extal1_div2_clk = {
 + +    .ops            = &div2_clk_ops,
 + +    .parent         = &sh73a0_extal1_clk,
 + +};
 + +
 + +/* Divide extal2 by two */
 + +static struct clk extal2_div2_clk = {
 + +    .ops            = &div2_clk_ops,
 + +    .parent         = &sh73a0_extal2_clk,
 + +};
 + +
 + +static struct clk_ops main_clk_ops = {
 + +    .recalc         = followparent_recalc,
 + +};
 + +
 + +/* Main clock */
 + +static struct clk main_clk = {
 + +    .ops            = &main_clk_ops,
 + +};
 + +
 + +/* PLL0, PLL1, PLL2, PLL3 */
 + +static unsigned long pll_recalc(struct clk *clk)
 + +{
 + +    unsigned long mult = 1;
 + +
 + +    if (__raw_readl(PLLECR) & (1 << clk->enable_bit))
 + +            mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
 + +
 + +    return clk->parent->rate * mult;
 + +}
 + +
 + +static struct clk_ops pll_clk_ops = {
 + +    .recalc         = pll_recalc,
 + +};
 + +
 + +static struct clk pll0_clk = {
 + +    .ops            = &pll_clk_ops,
 + +    .flags          = CLK_ENABLE_ON_INIT,
 + +    .parent         = &main_clk,
 + +    .enable_reg     = (void __iomem *)PLL0CR,
 + +    .enable_bit     = 0,
 + +};
 + +
 + +static struct clk pll1_clk = {
 + +    .ops            = &pll_clk_ops,
 + +    .flags          = CLK_ENABLE_ON_INIT,
 + +    .parent         = &main_clk,
 + +    .enable_reg     = (void __iomem *)PLL1CR,
 + +    .enable_bit     = 1,
 + +};
 + +
 + +static struct clk pll2_clk = {
 + +    .ops            = &pll_clk_ops,
 + +    .flags          = CLK_ENABLE_ON_INIT,
 + +    .parent         = &main_clk,
 + +    .enable_reg     = (void __iomem *)PLL2CR,
 + +    .enable_bit     = 2,
 + +};
 + +
 + +static struct clk pll3_clk = {
 + +    .ops            = &pll_clk_ops,
 + +    .flags          = CLK_ENABLE_ON_INIT,
 + +    .parent         = &main_clk,
 + +    .enable_reg     = (void __iomem *)PLL3CR,
 + +    .enable_bit     = 3,
 + +};
 + +
 + +/* Divide PLL1 by two */
 + +static struct clk pll1_div2_clk = {
 + +    .ops            = &div2_clk_ops,
 + +    .parent         = &pll1_clk,
 + +};
 + +
 + +static struct clk *main_clks[] = {
 + +    &r_clk,
 + +    &sh73a0_extal1_clk,
 + +    &sh73a0_extal2_clk,
 + +    &extal1_div2_clk,
 + +    &extal2_div2_clk,
 + +    &main_clk,
 + +    &pll0_clk,
 + +    &pll1_clk,
 + +    &pll2_clk,
 + +    &pll3_clk,
 + +    &pll1_div2_clk,
 + +};
 + +
 + +static void div4_kick(struct clk *clk)
 + +{
 + +    unsigned long value;
 + +
 + +    /* set KICK bit in FRQCRB to update hardware setting */
 + +    value = __raw_readl(FRQCRB);
 + +    value |= (1 << 31);
 + +    __raw_writel(value, FRQCRB);
 + +}
 + +
 + +static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
  -     MSTP116,
++ +                      24, 0, 36, 48, 7 };
 + +
 + +static struct clk_div_mult_table div4_div_mult_table = {
 + +    .divisors = divisors,
 + +    .nr_divisors = ARRAY_SIZE(divisors),
 + +};
 + +
 + +static struct clk_div4_table div4_table = {
 + +    .div_mult_table = &div4_div_mult_table,
 + +    .kick = div4_kick,
 + +};
 + +
 + +enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
 + +    DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR };
 + +
 + +#define DIV4(_reg, _bit, _mask, _flags) \
 + +    SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
 + +
 + +static struct clk div4_clks[DIV4_NR] = {
 + +    [DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
 + +    [DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
 + +    [DIV4_M3] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
 + +    [DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
 + +    [DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
 + +    [DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
 + +    [DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0),
 + +    [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0),
 + +    [DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0),
 + +    [DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0),
 + +    [DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0),
 + +};
 + +
 + +enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
 + +    DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
 + +    DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
 + +    DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
 + +    DIV6_HSI,  DIV6_MFG1, DIV6_MFG2,
 + +    DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
 + +    DIV6_NR };
 + +
 + +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, 0),
 + +    [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),
 + +};
 + +
 + +enum { MSTP001,
  -     MSTP331, MSTP329, MSTP323,
 +++    MSTP125, MSTP116,
 + +    MSTP219,
 + +    MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
  -     CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC0 */
 +++    MSTP331, MSTP329, MSTP323, MSTP312,
 + +    MSTP411, MSTP410, MSTP403,
 + +    MSTP_NR };
 + +
 + +#define MSTP(_parent, _reg, _bit, _flags) \
 + +    SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
 + +
 + +static struct clk mstp_clks[MSTP_NR] = {
 + +    [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
 +++    [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
 + +    [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
 + +    [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
 + +    [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
 + +    [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
 + +    [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
 + +    [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
 + +    [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
 + +    [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
 + +    [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
 + +    [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
 + +    [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
 + +    [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
 +++    [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
 + +    [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
 + +    [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
 +++    [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
 + +};
 + +
 + +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
 + +#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
 + +
 + +static struct clk_lookup lookups[] = {
 + +    /* main clocks */
 + +    CLKDEV_CON_ID("r_clk", &r_clk),
 + +
 + +    /* MSTP32 clocks */
 + +    CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
 +++    CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
 +++    CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
 + +    CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
 + +    CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
 + +    CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
 + +    CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
 + +    CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
 + +    CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
 + +    CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
 + +    CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
 + +    CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
 + +    CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
 + +    CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
 + +    CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
 +++    CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
 + +    CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
 + +    CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
 +++    CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
 + +};
 + +
 + +void __init sh73a0_clock_init(void)
 + +{
 + +    int k, ret = 0;
 + +
 + +    /* detect main clock parent */
 + +    switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
 + +    case 0:
 + +            main_clk.parent = &sh73a0_extal1_clk;
 + +            break;
 + +    case 1:
 + +            main_clk.parent = &extal1_div2_clk;
 + +            break;
 + +    case 2:
 + +            main_clk.parent = &sh73a0_extal2_clk;
 + +            break;
 + +    case 3:
 + +            main_clk.parent = &extal2_div2_clk;
 + +            break;
 + +    }
 + +
 + +    for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 + +            ret = clk_register(main_clks[k]);
 + +
 + +    if (!ret)
 + +            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_mstp32_register(mstp_clks, MSTP_NR);
 + +
 + +    clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 + +
 + +    if (!ret)
 + +            clk_init();
 + +    else
 + +            panic("failed to setup sh73a0 clocks\n");
 + +}