aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/syslib/mpc52xx_setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc/syslib/mpc52xx_setup.c')
-rw-r--r--arch/ppc/syslib/mpc52xx_setup.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index ecfa2c0f8ba3..9f504fc7693e 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18 18
19#include <linux/spinlock.h>
19#include <asm/io.h> 20#include <asm/io.h>
20#include <asm/time.h> 21#include <asm/time.h>
21#include <asm/mpc52xx.h> 22#include <asm/mpc52xx.h>
@@ -275,3 +276,38 @@ int mpc52xx_match_psc_function(int psc_idx, const char *func)
275 276
276 return 0; 277 return 0;
277} 278}
279
280int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
281{
282 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
283 struct mpc52xx_cdm __iomem *cdm;
284 unsigned long flags;
285 u16 mclken_div;
286 u16 __iomem *reg;
287 u32 mask;
288
289 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
290 if (!cdm) {
291 printk(KERN_ERR __FILE__ ": Error mapping CDM\n");
292 return -ENODEV;
293 }
294
295 mclken_div = 0x8000 | (clkdiv & 0x1FF);
296 switch (psc_id) {
297 case 1: reg = &cdm->mclken_div_psc1; mask = 0x20; break;
298 case 2: reg = &cdm->mclken_div_psc2; mask = 0x40; break;
299 case 3: reg = &cdm->mclken_div_psc3; mask = 0x80; break;
300 case 6: reg = &cdm->mclken_div_psc6; mask = 0x10; break;
301 default:
302 return -ENODEV;
303 }
304
305 /* Set the rate and enable the clock */
306 spin_lock_irqsave(&lock, flags);
307 out_be16(reg, mclken_div);
308 out_be32(&cdm->clk_enables, in_be32(&cdm->clk_enables) | mask);
309 spin_unlock_irqrestore(&lock, flags);
310
311 iounmap(cdm);
312 return 0;
313}