2009-01-20 09:15:18 +03:00
/*
* linux / arch / arm / mach - mmp / clock . c
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/list.h>
# include <linux/spinlock.h>
# include <linux/clk.h>
# include <linux/io.h>
2014-04-15 22:38:32 +04:00
# include "regs-apbc.h"
2009-01-20 09:15:18 +03:00
# include "clock.h"
static void apbc_clk_enable ( struct clk * clk )
{
uint32_t clk_rst ;
clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL ( clk - > fnclksel ) ;
__raw_writel ( clk_rst , clk - > clk_rst ) ;
}
static void apbc_clk_disable ( struct clk * clk )
{
__raw_writel ( 0 , clk - > clk_rst ) ;
}
struct clkops apbc_clk_ops = {
. enable = apbc_clk_enable ,
. disable = apbc_clk_disable ,
} ;
2009-09-10 10:01:22 +04:00
static void apmu_clk_enable ( struct clk * clk )
{
__raw_writel ( clk - > enable_val , clk - > clk_rst ) ;
}
static void apmu_clk_disable ( struct clk * clk )
{
__raw_writel ( 0 , clk - > clk_rst ) ;
}
struct clkops apmu_clk_ops = {
. enable = apmu_clk_enable ,
. disable = apmu_clk_disable ,
} ;
2009-01-20 09:15:18 +03:00
static DEFINE_SPINLOCK ( clocks_lock ) ;
int clk_enable ( struct clk * clk )
{
unsigned long flags ;
spin_lock_irqsave ( & clocks_lock , flags ) ;
if ( clk - > enabled + + = = 0 )
clk - > ops - > enable ( clk ) ;
spin_unlock_irqrestore ( & clocks_lock , flags ) ;
return 0 ;
}
EXPORT_SYMBOL ( clk_enable ) ;
void clk_disable ( struct clk * clk )
{
unsigned long flags ;
2017-03-28 12:17:02 +03:00
if ( ! clk )
return ;
2009-01-20 09:15:18 +03:00
WARN_ON ( clk - > enabled = = 0 ) ;
spin_lock_irqsave ( & clocks_lock , flags ) ;
if ( - - clk - > enabled = = 0 )
clk - > ops - > disable ( clk ) ;
spin_unlock_irqrestore ( & clocks_lock , flags ) ;
}
EXPORT_SYMBOL ( clk_disable ) ;
unsigned long clk_get_rate ( struct clk * clk )
{
unsigned long rate ;
if ( clk - > ops - > getrate )
rate = clk - > ops - > getrate ( clk ) ;
else
rate = clk - > rate ;
return rate ;
}
EXPORT_SYMBOL ( clk_get_rate ) ;
2011-04-08 16:15:38 +04:00
int clk_set_rate ( struct clk * clk , unsigned long rate )
{
unsigned long flags ;
int ret = - EINVAL ;
if ( clk - > ops - > setrate ) {
spin_lock_irqsave ( & clocks_lock , flags ) ;
ret = clk - > ops - > setrate ( clk , rate ) ;
spin_unlock_irqrestore ( & clocks_lock , flags ) ;
}
return ret ;
}
EXPORT_SYMBOL ( clk_set_rate ) ;