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
  76struct clk *clk_get(struct device *dev, const char *id)
  77{
  78        const char *clk_name = dev ? dev_name(dev) : id ? id : NULL;
  79        struct clk *clk;
  80        unsigned i;
  81
  82        for (i = 0; (clk = mcf_clks[i]) != NULL; ++i)
  83                if (!strcmp(clk->name, clk_name))
  84                        return clk;
  85        pr_warn("clk_get: didn't find clock %s\n", clk_name);
  86        return ERR_PTR(-ENOENT);
  87}
  88EXPORT_SYMBOL(clk_get);
  89
  90int clk_enable(struct clk *clk)
  91{
  92        unsigned long flags;
  93        spin_lock_irqsave(&clk_lock, flags);
  94        if ((clk->enabled++ == 0) && clk->clk_ops)
  95                clk->clk_ops->enable(clk);
  96        spin_unlock_irqrestore(&clk_lock, flags);
  97
  98        return 0;
  99}
 100EXPORT_SYMBOL(clk_enable);
 101
 102void clk_disable(struct clk *clk)
 103{
 104        unsigned long flags;
 105
 106        if (!clk)
 107                return;
 108
 109        spin_lock_irqsave(&clk_lock, flags);
 110        if ((--clk->enabled == 0) && clk->clk_ops)
 111                clk->clk_ops->disable(clk);
 112        spin_unlock_irqrestore(&clk_lock, flags);
 113}
 114EXPORT_SYMBOL(clk_disable);
 115
 116void clk_put(struct clk *clk)
 117{
 118        if (clk->enabled != 0)
 119                pr_warn("clk_put %s still enabled\n", clk->name);
 120}
 121EXPORT_SYMBOL(clk_put);
 122
 123unsigned long clk_get_rate(struct clk *clk)
 124{
 125        if (!clk)
 126                return 0;
 127
 128        return clk->rate;
 129}
 130EXPORT_SYMBOL(clk_get_rate);
 131
 132/* dummy functions, should not be called */
 133long clk_round_rate(struct clk *clk, unsigned long rate)
 134{
 135        WARN_ON(clk);
 136        return 0;
 137}
 138EXPORT_SYMBOL(clk_round_rate);
 139
 140int clk_set_rate(struct clk *clk, unsigned long rate)
 141{
 142        WARN_ON(clk);
 143        return 0;
 144}
 145EXPORT_SYMBOL(clk_set_rate);
 146
 147int clk_set_parent(struct clk *clk, struct clk *parent)
 148{
 149        WARN_ON(clk);
 150        return 0;
 151}
 152EXPORT_SYMBOL(clk_set_parent);
 153
 154struct clk *clk_get_parent(struct clk *clk)
 155{
 156        WARN_ON(clk);
 157        return NULL;
 158}
 159EXPORT_SYMBOL(clk_get_parent);
 160
 161/***************************************************************************/
 162