linux/arch/m68k/coldfire/clk.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/***************************************************************************/
   3
   4/*
   5 *      clk.c -- general ColdFire CPU kernel clk handling
   6 *
   7 *      Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
   8 */
   9
  10/***************************************************************************/
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/platform_device.h>
  15#include <linux/mutex.h>
  16#include <linux/clk.h>
  17#include <linux/io.h>
  18#include <linux/err.h>
  19#include <asm/coldfire.h>
  20#include <asm/mcfsim.h>
  21#include <asm/mcfclk.h>
  22
  23static DEFINE_SPINLOCK(clk_lock);
  24
  25#ifdef MCFPM_PPMCR0
  26/*
  27 *      For more advanced ColdFire parts that have clocks that can be enabled
  28 *      we supply enable/disable functions. These must properly define their
  29 *      clocks in their platform specific code.
  30 */
  31void __clk_init_enabled(struct clk *clk)
  32{
  33        clk->enabled = 1;
  34        clk->clk_ops->enable(clk);
  35}
  36
  37void __clk_init_disabled(struct clk *clk)
  38{
  39        clk->enabled = 0;
  40        clk->clk_ops->disable(clk);
  41}
  42
  43static void __clk_enable0(struct clk *clk)
  44{
  45        __raw_writeb(clk->slot, MCFPM_PPMCR0);
  46}
  47
  48static void __clk_disable0(struct clk *clk)
  49{
  50        __raw_writeb(clk->slot, MCFPM_PPMSR0);
  51}
  52
  53struct clk_ops clk_ops0 = {
  54        .enable         = __clk_enable0,
  55        .disable        = __clk_disable0,
  56};
  57
  58#ifdef MCFPM_PPMCR1
  59static void __clk_enable1(struct clk *clk)
  60{
  61        __raw_writeb(clk->slot, MCFPM_PPMCR1);
  62}
  63
  64static void __clk_disable1(struct clk *clk)
  65{
  66        __raw_writeb(clk->slot, MCFPM_PPMSR1);
  67}
  68
  69struct clk_ops clk_ops1 = {
  70        .enable         = __clk_enable1,
  71        .disable        = __clk_disable1,
  72};
  73#endif /* MCFPM_PPMCR1 */
  74#endif /* MCFPM_PPMCR0 */
  75
  76int clk_enable(struct clk *clk)
  77{
  78        unsigned long flags;
  79
  80        if (!clk)
  81                return -EINVAL;
  82
  83        spin_lock_irqsave(&clk_lock, flags);
  84        if ((clk->enabled++ == 0) && clk->clk_ops)
  85                clk->clk_ops->enable(clk);
  86        spin_unlock_irqrestore(&clk_lock, flags);
  87
  88        return 0;
  89}
  90EXPORT_SYMBOL(clk_enable);
  91
  92void clk_disable(struct clk *clk)
  93{
  94        unsigned long flags;
  95
  96        if (!clk)
  97                return;
  98
  99        spin_lock_irqsave(&clk_lock, flags);
 100        if ((--clk->enabled == 0) && clk->clk_ops)
 101                clk->clk_ops->disable(clk);
 102        spin_unlock_irqrestore(&clk_lock, flags);
 103}
 104EXPORT_SYMBOL(clk_disable);
 105
 106unsigned long clk_get_rate(struct clk *clk)
 107{
 108        if (!clk)
 109                return 0;
 110
 111        return clk->rate;
 112}
 113EXPORT_SYMBOL(clk_get_rate);
 114
 115/* dummy functions, should not be called */
 116long clk_round_rate(struct clk *clk, unsigned long rate)
 117{
 118        WARN_ON(clk);
 119        return 0;
 120}
 121EXPORT_SYMBOL(clk_round_rate);
 122
 123int clk_set_rate(struct clk *clk, unsigned long rate)
 124{
 125        WARN_ON(clk);
 126        return 0;
 127}
 128EXPORT_SYMBOL(clk_set_rate);
 129
 130int clk_set_parent(struct clk *clk, struct clk *parent)
 131{
 132        WARN_ON(clk);
 133        return 0;
 134}
 135EXPORT_SYMBOL(clk_set_parent);
 136
 137struct clk *clk_get_parent(struct clk *clk)
 138{
 139        WARN_ON(clk);
 140        return NULL;
 141}
 142EXPORT_SYMBOL(clk_get_parent);
 143
 144/***************************************************************************/
 145