linux/arch/arm/mach-mmp/clock.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  linux/arch/arm/mach-mmp/clock.c
   4 */
   5
   6#include <linux/module.h>
   7#include <linux/kernel.h>
   8#include <linux/list.h>
   9#include <linux/spinlock.h>
  10#include <linux/clk.h>
  11#include <linux/io.h>
  12
  13#include "regs-apbc.h"
  14#include "clock.h"
  15
  16static void apbc_clk_enable(struct clk *clk)
  17{
  18        uint32_t clk_rst;
  19
  20        clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel);
  21        __raw_writel(clk_rst, clk->clk_rst);
  22}
  23
  24static void apbc_clk_disable(struct clk *clk)
  25{
  26        __raw_writel(0, clk->clk_rst);
  27}
  28
  29struct clkops apbc_clk_ops = {
  30        .enable         = apbc_clk_enable,
  31        .disable        = apbc_clk_disable,
  32};
  33
  34static void apmu_clk_enable(struct clk *clk)
  35{
  36        __raw_writel(clk->enable_val, clk->clk_rst);
  37}
  38
  39static void apmu_clk_disable(struct clk *clk)
  40{
  41        __raw_writel(0, clk->clk_rst);
  42}
  43
  44struct clkops apmu_clk_ops = {
  45        .enable         = apmu_clk_enable,
  46        .disable        = apmu_clk_disable,
  47};
  48
  49static DEFINE_SPINLOCK(clocks_lock);
  50
  51int clk_enable(struct clk *clk)
  52{
  53        unsigned long flags;
  54
  55        spin_lock_irqsave(&clocks_lock, flags);
  56        if (clk->enabled++ == 0)
  57                clk->ops->enable(clk);
  58        spin_unlock_irqrestore(&clocks_lock, flags);
  59        return 0;
  60}
  61EXPORT_SYMBOL(clk_enable);
  62
  63void clk_disable(struct clk *clk)
  64{
  65        unsigned long flags;
  66
  67        if (!clk)
  68                return;
  69
  70        WARN_ON(clk->enabled == 0);
  71
  72        spin_lock_irqsave(&clocks_lock, flags);
  73        if (--clk->enabled == 0)
  74                clk->ops->disable(clk);
  75        spin_unlock_irqrestore(&clocks_lock, flags);
  76}
  77EXPORT_SYMBOL(clk_disable);
  78
  79unsigned long clk_get_rate(struct clk *clk)
  80{
  81        unsigned long rate;
  82
  83        if (clk->ops->getrate)
  84                rate = clk->ops->getrate(clk);
  85        else
  86                rate = clk->rate;
  87
  88        return rate;
  89}
  90EXPORT_SYMBOL(clk_get_rate);
  91
  92int clk_set_rate(struct clk *clk, unsigned long rate)
  93{
  94        unsigned long flags;
  95        int ret = -EINVAL;
  96
  97        if (clk->ops->setrate) {
  98                spin_lock_irqsave(&clocks_lock, flags);
  99                ret = clk->ops->setrate(clk, rate);
 100                spin_unlock_irqrestore(&clocks_lock, flags);
 101        }
 102
 103        return ret;
 104}
 105EXPORT_SYMBOL(clk_set_rate);
 106