at v3.9 6.0 kB view raw
1/* 2 * linux/include/linux/clk-private.h 3 * 4 * Copyright (c) 2010-2011 Jeremy Kerr <jeremy.kerr@canonical.com> 5 * Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11#ifndef __LINUX_CLK_PRIVATE_H 12#define __LINUX_CLK_PRIVATE_H 13 14#include <linux/clk-provider.h> 15#include <linux/list.h> 16 17/* 18 * WARNING: Do not include clk-private.h from any file that implements struct 19 * clk_ops. Doing so is a layering violation! 20 * 21 * This header exists only to allow for statically initialized clock data. Any 22 * static clock data must be defined in a separate file from the logic that 23 * implements the clock operations for that same data. 24 */ 25 26#ifdef CONFIG_COMMON_CLK 27 28struct clk { 29 const char *name; 30 const struct clk_ops *ops; 31 struct clk_hw *hw; 32 struct clk *parent; 33 const char **parent_names; 34 struct clk **parents; 35 u8 num_parents; 36 unsigned long rate; 37 unsigned long new_rate; 38 unsigned long flags; 39 unsigned int enable_count; 40 unsigned int prepare_count; 41 struct hlist_head children; 42 struct hlist_node child_node; 43 unsigned int notifier_count; 44#ifdef CONFIG_COMMON_CLK_DEBUG 45 struct dentry *dentry; 46#endif 47}; 48 49/* 50 * DOC: Basic clock implementations common to many platforms 51 * 52 * Each basic clock hardware type is comprised of a structure describing the 53 * clock hardware, implementations of the relevant callbacks in struct clk_ops, 54 * unique flags for that hardware type, a registration function and an 55 * alternative macro for static initialization 56 */ 57 58#define DEFINE_CLK(_name, _ops, _flags, _parent_names, \ 59 _parents) \ 60 static struct clk _name = { \ 61 .name = #_name, \ 62 .ops = &_ops, \ 63 .hw = &_name##_hw.hw, \ 64 .parent_names = _parent_names, \ 65 .num_parents = ARRAY_SIZE(_parent_names), \ 66 .parents = _parents, \ 67 .flags = _flags | CLK_IS_BASIC, \ 68 } 69 70#define DEFINE_CLK_FIXED_RATE(_name, _flags, _rate, \ 71 _fixed_rate_flags) \ 72 static struct clk _name; \ 73 static const char *_name##_parent_names[] = {}; \ 74 static struct clk_fixed_rate _name##_hw = { \ 75 .hw = { \ 76 .clk = &_name, \ 77 }, \ 78 .fixed_rate = _rate, \ 79 .flags = _fixed_rate_flags, \ 80 }; \ 81 DEFINE_CLK(_name, clk_fixed_rate_ops, _flags, \ 82 _name##_parent_names, NULL); 83 84#define DEFINE_CLK_GATE(_name, _parent_name, _parent_ptr, \ 85 _flags, _reg, _bit_idx, \ 86 _gate_flags, _lock) \ 87 static struct clk _name; \ 88 static const char *_name##_parent_names[] = { \ 89 _parent_name, \ 90 }; \ 91 static struct clk *_name##_parents[] = { \ 92 _parent_ptr, \ 93 }; \ 94 static struct clk_gate _name##_hw = { \ 95 .hw = { \ 96 .clk = &_name, \ 97 }, \ 98 .reg = _reg, \ 99 .bit_idx = _bit_idx, \ 100 .flags = _gate_flags, \ 101 .lock = _lock, \ 102 }; \ 103 DEFINE_CLK(_name, clk_gate_ops, _flags, \ 104 _name##_parent_names, _name##_parents); 105 106#define _DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr, \ 107 _flags, _reg, _shift, _width, \ 108 _divider_flags, _table, _lock) \ 109 static struct clk _name; \ 110 static const char *_name##_parent_names[] = { \ 111 _parent_name, \ 112 }; \ 113 static struct clk *_name##_parents[] = { \ 114 _parent_ptr, \ 115 }; \ 116 static struct clk_divider _name##_hw = { \ 117 .hw = { \ 118 .clk = &_name, \ 119 }, \ 120 .reg = _reg, \ 121 .shift = _shift, \ 122 .width = _width, \ 123 .flags = _divider_flags, \ 124 .table = _table, \ 125 .lock = _lock, \ 126 }; \ 127 DEFINE_CLK(_name, clk_divider_ops, _flags, \ 128 _name##_parent_names, _name##_parents); 129 130#define DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr, \ 131 _flags, _reg, _shift, _width, \ 132 _divider_flags, _lock) \ 133 _DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr, \ 134 _flags, _reg, _shift, _width, \ 135 _divider_flags, NULL, _lock) 136 137#define DEFINE_CLK_DIVIDER_TABLE(_name, _parent_name, \ 138 _parent_ptr, _flags, _reg, \ 139 _shift, _width, _divider_flags, \ 140 _table, _lock) \ 141 _DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr, \ 142 _flags, _reg, _shift, _width, \ 143 _divider_flags, _table, _lock) \ 144 145#define DEFINE_CLK_MUX(_name, _parent_names, _parents, _flags, \ 146 _reg, _shift, _width, \ 147 _mux_flags, _lock) \ 148 static struct clk _name; \ 149 static struct clk_mux _name##_hw = { \ 150 .hw = { \ 151 .clk = &_name, \ 152 }, \ 153 .reg = _reg, \ 154 .shift = _shift, \ 155 .width = _width, \ 156 .flags = _mux_flags, \ 157 .lock = _lock, \ 158 }; \ 159 DEFINE_CLK(_name, clk_mux_ops, _flags, _parent_names, \ 160 _parents); 161 162#define DEFINE_CLK_FIXED_FACTOR(_name, _parent_name, \ 163 _parent_ptr, _flags, \ 164 _mult, _div) \ 165 static struct clk _name; \ 166 static const char *_name##_parent_names[] = { \ 167 _parent_name, \ 168 }; \ 169 static struct clk *_name##_parents[] = { \ 170 _parent_ptr, \ 171 }; \ 172 static struct clk_fixed_factor _name##_hw = { \ 173 .hw = { \ 174 .clk = &_name, \ 175 }, \ 176 .mult = _mult, \ 177 .div = _div, \ 178 }; \ 179 DEFINE_CLK(_name, clk_fixed_factor_ops, _flags, \ 180 _name##_parent_names, _name##_parents); 181 182/** 183 * __clk_init - initialize the data structures in a struct clk 184 * @dev: device initializing this clk, placeholder for now 185 * @clk: clk being initialized 186 * 187 * Initializes the lists in struct clk, queries the hardware for the 188 * parent and rate and sets them both. 189 * 190 * Any struct clk passed into __clk_init must have the following members 191 * populated: 192 * .name 193 * .ops 194 * .hw 195 * .parent_names 196 * .num_parents 197 * .flags 198 * 199 * It is not necessary to call clk_register if __clk_init is used directly with 200 * statically initialized clock data. 201 * 202 * Returns 0 on success, otherwise an error code. 203 */ 204int __clk_init(struct device *dev, struct clk *clk); 205 206struct clk *__clk_register(struct device *dev, struct clk_hw *hw); 207 208#endif /* CONFIG_COMMON_CLK */ 209#endif /* CLK_PRIVATE_H */