root/drivers/clk/zynqmp/clk-gate-zynqmp.c

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

DEFINITIONS

This source file includes following definitions.
  1. zynqmp_clk_gate_enable
  2. zynqmp_clk_gate_disable
  3. zynqmp_clk_gate_is_enabled
  4. zynqmp_clk_register_gate

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Zynq UltraScale+ MPSoC clock controller
   4  *
   5  *  Copyright (C) 2016-2018 Xilinx
   6  *
   7  * Gated clock implementation
   8  */
   9 
  10 #include <linux/clk-provider.h>
  11 #include <linux/slab.h>
  12 #include "clk-zynqmp.h"
  13 
  14 /**
  15  * struct clk_gate - gating clock
  16  * @hw:         handle between common and hardware-specific interfaces
  17  * @flags:      hardware-specific flags
  18  * @clk_id:     Id of clock
  19  */
  20 struct zynqmp_clk_gate {
  21         struct clk_hw hw;
  22         u8 flags;
  23         u32 clk_id;
  24 };
  25 
  26 #define to_zynqmp_clk_gate(_hw) container_of(_hw, struct zynqmp_clk_gate, hw)
  27 
  28 /**
  29  * zynqmp_clk_gate_enable() - Enable clock
  30  * @hw:         handle between common and hardware-specific interfaces
  31  *
  32  * Return: 0 on success else error code
  33  */
  34 static int zynqmp_clk_gate_enable(struct clk_hw *hw)
  35 {
  36         struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
  37         const char *clk_name = clk_hw_get_name(hw);
  38         u32 clk_id = gate->clk_id;
  39         int ret;
  40         const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
  41 
  42         ret = eemi_ops->clock_enable(clk_id);
  43 
  44         if (ret)
  45                 pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
  46                              __func__, clk_name, ret);
  47 
  48         return ret;
  49 }
  50 
  51 /*
  52  * zynqmp_clk_gate_disable() - Disable clock
  53  * @hw:         handle between common and hardware-specific interfaces
  54  */
  55 static void zynqmp_clk_gate_disable(struct clk_hw *hw)
  56 {
  57         struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
  58         const char *clk_name = clk_hw_get_name(hw);
  59         u32 clk_id = gate->clk_id;
  60         int ret;
  61         const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
  62 
  63         ret = eemi_ops->clock_disable(clk_id);
  64 
  65         if (ret)
  66                 pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
  67                              __func__, clk_name, ret);
  68 }
  69 
  70 /**
  71  * zynqmp_clk_gate_is_enable() - Check clock state
  72  * @hw:         handle between common and hardware-specific interfaces
  73  *
  74  * Return: 1 if enabled, 0 if disabled else error code
  75  */
  76 static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)
  77 {
  78         struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
  79         const char *clk_name = clk_hw_get_name(hw);
  80         u32 clk_id = gate->clk_id;
  81         int state, ret;
  82         const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
  83 
  84         ret = eemi_ops->clock_getstate(clk_id, &state);
  85         if (ret) {
  86                 pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
  87                              __func__, clk_name, ret);
  88                 return -EIO;
  89         }
  90 
  91         return state ? 1 : 0;
  92 }
  93 
  94 static const struct clk_ops zynqmp_clk_gate_ops = {
  95         .enable = zynqmp_clk_gate_enable,
  96         .disable = zynqmp_clk_gate_disable,
  97         .is_enabled = zynqmp_clk_gate_is_enabled,
  98 };
  99 
 100 /**
 101  * zynqmp_clk_register_gate() - Register a gate clock with the clock framework
 102  * @name:               Name of this clock
 103  * @clk_id:             Id of this clock
 104  * @parents:            Name of this clock's parents
 105  * @num_parents:        Number of parents
 106  * @nodes:              Clock topology node
 107  *
 108  * Return: clock hardware of the registered clock gate
 109  */
 110 struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id,
 111                                         const char * const *parents,
 112                                         u8 num_parents,
 113                                         const struct clock_topology *nodes)
 114 {
 115         struct zynqmp_clk_gate *gate;
 116         struct clk_hw *hw;
 117         int ret;
 118         struct clk_init_data init;
 119 
 120         /* allocate the gate */
 121         gate = kzalloc(sizeof(*gate), GFP_KERNEL);
 122         if (!gate)
 123                 return ERR_PTR(-ENOMEM);
 124 
 125         init.name = name;
 126         init.ops = &zynqmp_clk_gate_ops;
 127         init.flags = nodes->flag;
 128         init.parent_names = parents;
 129         init.num_parents = 1;
 130 
 131         /* struct clk_gate assignments */
 132         gate->flags = nodes->type_flag;
 133         gate->hw.init = &init;
 134         gate->clk_id = clk_id;
 135 
 136         hw = &gate->hw;
 137         ret = clk_hw_register(NULL, hw);
 138         if (ret) {
 139                 kfree(gate);
 140                 hw = ERR_PTR(ret);
 141         }
 142 
 143         return hw;
 144 }

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