1/* 2 * linux/arch/arm/mach-mmp/clock.c 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9#include <linux/module.h> 10#include <linux/kernel.h> 11#include <linux/list.h> 12#include <linux/spinlock.h> 13#include <linux/clk.h> 14#include <linux/io.h> 15 16#include <mach/regs-apbc.h> 17#include "clock.h" 18 19static void apbc_clk_enable(struct clk *clk) 20{ 21 uint32_t clk_rst; 22 23 clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel); 24 __raw_writel(clk_rst, clk->clk_rst); 25} 26 27static void apbc_clk_disable(struct clk *clk) 28{ 29 __raw_writel(0, clk->clk_rst); 30} 31 32struct clkops apbc_clk_ops = { 33 .enable = apbc_clk_enable, 34 .disable = apbc_clk_disable, 35}; 36 37static DEFINE_SPINLOCK(clocks_lock); 38 39int clk_enable(struct clk *clk) 40{ 41 unsigned long flags; 42 43 spin_lock_irqsave(&clocks_lock, flags); 44 if (clk->enabled++ == 0) 45 clk->ops->enable(clk); 46 spin_unlock_irqrestore(&clocks_lock, flags); 47 return 0; 48} 49EXPORT_SYMBOL(clk_enable); 50 51void clk_disable(struct clk *clk) 52{ 53 unsigned long flags; 54 55 WARN_ON(clk->enabled == 0); 56 57 spin_lock_irqsave(&clocks_lock, flags); 58 if (--clk->enabled == 0) 59 clk->ops->disable(clk); 60 spin_unlock_irqrestore(&clocks_lock, flags); 61} 62EXPORT_SYMBOL(clk_disable); 63 64unsigned long clk_get_rate(struct clk *clk) 65{ 66 unsigned long rate; 67 68 if (clk->ops->getrate) 69 rate = clk->ops->getrate(clk); 70 else 71 rate = clk->rate; 72 73 return rate; 74} 75EXPORT_SYMBOL(clk_get_rate); 76 77void clks_register(struct clk_lookup *clks, size_t num) 78{ 79 int i; 80 81 for (i = 0; i < num; i++) 82 clkdev_add(&clks[i]); 83} 84