linux/drivers/clk/tegra/clk-audio-sync.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms and conditions of the GNU General Public License,
   6 * version 2, as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope it will be useful, but WITHOUT
   9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  11 * more details.
  12 *
  13 * You should have received a copy of the GNU General Public License
  14 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  15 */
  16
  17#include <linux/clk-provider.h>
  18#include <linux/slab.h>
  19#include <linux/err.h>
  20
  21#include "clk.h"
  22
  23static unsigned long clk_sync_source_recalc_rate(struct clk_hw *hw,
  24                                                 unsigned long parent_rate)
  25{
  26        struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
  27
  28        return sync->rate;
  29}
  30
  31static long clk_sync_source_round_rate(struct clk_hw *hw, unsigned long rate,
  32                                       unsigned long *prate)
  33{
  34        struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
  35
  36        if (rate > sync->max_rate)
  37                return -EINVAL;
  38        else
  39                return rate;
  40}
  41
  42static int clk_sync_source_set_rate(struct clk_hw *hw, unsigned long rate,
  43                                    unsigned long parent_rate)
  44{
  45        struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
  46
  47        sync->rate = rate;
  48        return 0;
  49}
  50
  51const struct clk_ops tegra_clk_sync_source_ops = {
  52        .round_rate = clk_sync_source_round_rate,
  53        .set_rate = clk_sync_source_set_rate,
  54        .recalc_rate = clk_sync_source_recalc_rate,
  55};
  56
  57struct clk *tegra_clk_register_sync_source(const char *name,
  58                unsigned long rate, unsigned long max_rate)
  59{
  60        struct tegra_clk_sync_source *sync;
  61        struct clk_init_data init;
  62        struct clk *clk;
  63
  64        sync = kzalloc(sizeof(*sync), GFP_KERNEL);
  65        if (!sync) {
  66                pr_err("%s: could not allocate sync source clk\n", __func__);
  67                return ERR_PTR(-ENOMEM);
  68        }
  69
  70        sync->rate = rate;
  71        sync->max_rate = max_rate;
  72
  73        init.ops = &tegra_clk_sync_source_ops;
  74        init.name = name;
  75        init.flags = CLK_IS_ROOT;
  76        init.parent_names = NULL;
  77        init.num_parents = 0;
  78
  79        /* Data in .init is copied by clk_register(), so stack variable OK */
  80        sync->hw.init = &init;
  81
  82        clk = clk_register(NULL, &sync->hw);
  83        if (IS_ERR(clk))
  84                kfree(sync);
  85
  86        return clk;
  87}
  88