From c8004a28186110657aa3e75135a6b96ebfa3e8f0 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 24 Jan 2008 22:25:31 -0700 Subject: [POWERPC] Add common clock setting routine mpc52xx_psc_set_clkdiv() PSC drivers should not access the CDM registers directly. Instead provide a common routine for setting the PSC clock parameters with the required locking. Signed-off-by: Grant Likely --- arch/ppc/syslib/mpc52xx_setup.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'arch/ppc/syslib') diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c index ecfa2c0f8ba..9f504fc7693 100644 --- a/arch/ppc/syslib/mpc52xx_setup.c +++ b/arch/ppc/syslib/mpc52xx_setup.c @@ -16,6 +16,7 @@ */ +#include #include #include #include @@ -275,3 +276,38 @@ int mpc52xx_match_psc_function(int psc_idx, const char *func) return 0; } + +int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv) +{ + static spinlock_t lock = SPIN_LOCK_UNLOCKED; + struct mpc52xx_cdm __iomem *cdm; + unsigned long flags; + u16 mclken_div; + u16 __iomem *reg; + u32 mask; + + cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE); + if (!cdm) { + printk(KERN_ERR __FILE__ ": Error mapping CDM\n"); + return -ENODEV; + } + + mclken_div = 0x8000 | (clkdiv & 0x1FF); + switch (psc_id) { + case 1: reg = &cdm->mclken_div_psc1; mask = 0x20; break; + case 2: reg = &cdm->mclken_div_psc2; mask = 0x40; break; + case 3: reg = &cdm->mclken_div_psc3; mask = 0x80; break; + case 6: reg = &cdm->mclken_div_psc6; mask = 0x10; break; + default: + return -ENODEV; + } + + /* Set the rate and enable the clock */ + spin_lock_irqsave(&lock, flags); + out_be16(reg, mclken_div); + out_be32(&cdm->clk_enables, in_be32(&cdm->clk_enables) | mask); + spin_unlock_irqrestore(&lock, flags); + + iounmap(cdm); + return 0; +} -- cgit v1.2.3