root/drivers/clk/uniphier/clk-uniphier-cpugear.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uniphier_clk_cpugear_set_parent
  2. uniphier_clk_cpugear_get_parent
  3. uniphier_clk_register_cpugear

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2016 Socionext Inc.
   4  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
   5  */
   6 
   7 #include <linux/clk-provider.h>
   8 #include <linux/device.h>
   9 #include <linux/regmap.h>
  10 
  11 #include "clk-uniphier.h"
  12 
  13 #define UNIPHIER_CLK_CPUGEAR_STAT       0       /* status */
  14 #define UNIPHIER_CLK_CPUGEAR_SET        4       /* set */
  15 #define UNIPHIER_CLK_CPUGEAR_UPD        8       /* update */
  16 #define   UNIPHIER_CLK_CPUGEAR_UPD_BIT  BIT(0)
  17 
  18 struct uniphier_clk_cpugear {
  19         struct clk_hw hw;
  20         struct regmap *regmap;
  21         unsigned int regbase;
  22         unsigned int mask;
  23 };
  24 
  25 #define to_uniphier_clk_cpugear(_hw) \
  26                         container_of(_hw, struct uniphier_clk_cpugear, hw)
  27 
  28 static int uniphier_clk_cpugear_set_parent(struct clk_hw *hw, u8 index)
  29 {
  30         struct uniphier_clk_cpugear *gear = to_uniphier_clk_cpugear(hw);
  31         int ret;
  32         unsigned int val;
  33 
  34         ret = regmap_write_bits(gear->regmap,
  35                                 gear->regbase + UNIPHIER_CLK_CPUGEAR_SET,
  36                                 gear->mask, index);
  37         if (ret)
  38                 return ret;
  39 
  40         ret = regmap_write_bits(gear->regmap,
  41                                 gear->regbase + UNIPHIER_CLK_CPUGEAR_UPD,
  42                                 UNIPHIER_CLK_CPUGEAR_UPD_BIT,
  43                                 UNIPHIER_CLK_CPUGEAR_UPD_BIT);
  44         if (ret)
  45                 return ret;
  46 
  47         return regmap_read_poll_timeout(gear->regmap,
  48                                 gear->regbase + UNIPHIER_CLK_CPUGEAR_UPD,
  49                                 val, !(val & UNIPHIER_CLK_CPUGEAR_UPD_BIT),
  50                                 0, 1);
  51 }
  52 
  53 static u8 uniphier_clk_cpugear_get_parent(struct clk_hw *hw)
  54 {
  55         struct uniphier_clk_cpugear *gear = to_uniphier_clk_cpugear(hw);
  56         int num_parents = clk_hw_get_num_parents(hw);
  57         int ret;
  58         unsigned int val;
  59 
  60         ret = regmap_read(gear->regmap,
  61                           gear->regbase + UNIPHIER_CLK_CPUGEAR_STAT, &val);
  62         if (ret)
  63                 return ret;
  64 
  65         val &= gear->mask;
  66 
  67         return val < num_parents ? val : -EINVAL;
  68 }
  69 
  70 static const struct clk_ops uniphier_clk_cpugear_ops = {
  71         .determine_rate = __clk_mux_determine_rate,
  72         .set_parent = uniphier_clk_cpugear_set_parent,
  73         .get_parent = uniphier_clk_cpugear_get_parent,
  74 };
  75 
  76 struct clk_hw *uniphier_clk_register_cpugear(struct device *dev,
  77                                          struct regmap *regmap,
  78                                          const char *name,
  79                                 const struct uniphier_clk_cpugear_data *data)
  80 {
  81         struct uniphier_clk_cpugear *gear;
  82         struct clk_init_data init;
  83         int ret;
  84 
  85         gear = devm_kzalloc(dev, sizeof(*gear), GFP_KERNEL);
  86         if (!gear)
  87                 return ERR_PTR(-ENOMEM);
  88 
  89         init.name = name;
  90         init.ops = &uniphier_clk_cpugear_ops;
  91         init.flags = CLK_SET_RATE_PARENT;
  92         init.parent_names = data->parent_names;
  93         init.num_parents = data->num_parents,
  94 
  95         gear->regmap = regmap;
  96         gear->regbase = data->regbase;
  97         gear->mask = data->mask;
  98         gear->hw.init = &init;
  99 
 100         ret = devm_clk_hw_register(dev, &gear->hw);
 101         if (ret)
 102                 return ERR_PTR(ret);
 103 
 104         return &gear->hw;
 105 }

/* [<][>][^][v][top][bottom][index][help] */