linux/arch/arm/mach-mmp/clock.c
<<
>>
Prefs
   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 "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 void apmu_clk_enable(struct clk *clk)
  38{
  39        __raw_writel(clk->enable_val, clk->clk_rst);
  40}
  41
  42static void apmu_clk_disable(struct clk *clk)
  43{
  44        __raw_writel(0, clk->clk_rst);
  45}
  46
  47struct clkops apmu_clk_ops = {
  48        .enable         = apmu_clk_enable,
  49        .disable        = apmu_clk_disable,
  50};
  51
  52static DEFINE_SPINLOCK(clocks_lock);
  53
  54int clk_enable(struct clk *clk)
  55{
  56        unsigned long flags;
  57
  58        spin_lock_irqsave(&clocks_lock, flags);
  59        if (clk->enabled++ == 0)
  60                clk->ops->enable(clk);
  61        spin_unlock_irqrestore(&clocks_lock, flags);
  62        return 0;
  63}
  64EXPORT_SYMBOL(clk_enable);
  65
  66void clk_disable(struct clk *clk)
  67{
  68        unsigned long flags;
  69
  70        if (!clk)
  71                return;
  72
  73        WARN_ON(clk->enabled == 0);
  74
  75        spin_lock_irqsave(&clocks_lock, flags);
  76        if (--clk->enabled == 0)
  77                clk->ops->disable(clk);
  78        spin_unlock_irqrestore(&clocks_lock, flags);
  79}
  80EXPORT_SYMBOL(clk_disable);
  81
  82unsigned long clk_get_rate(struct clk *clk)
  83{
  84        unsigned long rate;
  85
  86        if (clk->ops->getrate)
  87                rate = clk->ops->getrate(clk);
  88        else
  89                rate = clk->rate;
  90
  91        return rate;
  92}
  93EXPORT_SYMBOL(clk_get_rate);
  94
  95int clk_set_rate(struct clk *clk, unsigned long rate)
  96{
  97        unsigned long flags;
  98        int ret = -EINVAL;
  99
 100        if (clk->ops->setrate) {
 101                spin_lock_irqsave(&clocks_lock, flags);
 102                ret = clk->ops->setrate(clk, rate);
 103                spin_unlock_irqrestore(&clocks_lock, flags);
 104        }
 105
 106        return ret;
 107}
 108EXPORT_SYMBOL(clk_set_rate);
 109