composite.c (6757B)
1/* 2 * TI composite clock support 3 * 4 * Copyright (C) 2013 Texas Instruments, Inc. 5 * 6 * Tero Kristo <t-kristo@ti.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 13 * kind, whether express or implied; without even the implied warranty 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 */ 17 18#include <linux/clk-provider.h> 19#include <linux/slab.h> 20#include <linux/io.h> 21#include <linux/of.h> 22#include <linux/of_address.h> 23#include <linux/clk/ti.h> 24#include <linux/list.h> 25 26#include "clock.h" 27 28#undef pr_fmt 29#define pr_fmt(fmt) "%s: " fmt, __func__ 30 31static unsigned long ti_composite_recalc_rate(struct clk_hw *hw, 32 unsigned long parent_rate) 33{ 34 return ti_clk_divider_ops.recalc_rate(hw, parent_rate); 35} 36 37static long ti_composite_round_rate(struct clk_hw *hw, unsigned long rate, 38 unsigned long *prate) 39{ 40 return -EINVAL; 41} 42 43static int ti_composite_set_rate(struct clk_hw *hw, unsigned long rate, 44 unsigned long parent_rate) 45{ 46 return -EINVAL; 47} 48 49static const struct clk_ops ti_composite_divider_ops = { 50 .recalc_rate = &ti_composite_recalc_rate, 51 .round_rate = &ti_composite_round_rate, 52 .set_rate = &ti_composite_set_rate, 53}; 54 55static const struct clk_ops ti_composite_gate_ops = { 56 .enable = &omap2_dflt_clk_enable, 57 .disable = &omap2_dflt_clk_disable, 58 .is_enabled = &omap2_dflt_clk_is_enabled, 59}; 60 61struct component_clk { 62 int num_parents; 63 const char **parent_names; 64 struct device_node *node; 65 int type; 66 struct clk_hw *hw; 67 struct list_head link; 68}; 69 70static const char * const component_clk_types[] __initconst = { 71 "gate", "divider", "mux" 72}; 73 74static LIST_HEAD(component_clks); 75 76static struct device_node *_get_component_node(struct device_node *node, int i) 77{ 78 int rc; 79 struct of_phandle_args clkspec; 80 81 rc = of_parse_phandle_with_args(node, "clocks", "#clock-cells", i, 82 &clkspec); 83 if (rc) 84 return NULL; 85 86 return clkspec.np; 87} 88 89static struct component_clk *_lookup_component(struct device_node *node) 90{ 91 struct component_clk *comp; 92 93 list_for_each_entry(comp, &component_clks, link) { 94 if (comp->node == node) 95 return comp; 96 } 97 return NULL; 98} 99 100struct clk_hw_omap_comp { 101 struct clk_hw hw; 102 struct device_node *comp_nodes[CLK_COMPONENT_TYPE_MAX]; 103 struct component_clk *comp_clks[CLK_COMPONENT_TYPE_MAX]; 104}; 105 106static inline struct clk_hw *_get_hw(struct clk_hw_omap_comp *clk, int idx) 107{ 108 if (!clk) 109 return NULL; 110 111 if (!clk->comp_clks[idx]) 112 return NULL; 113 114 return clk->comp_clks[idx]->hw; 115} 116 117#define to_clk_hw_comp(_hw) container_of(_hw, struct clk_hw_omap_comp, hw) 118 119static void __init _register_composite(void *user, 120 struct device_node *node) 121{ 122 struct clk_hw *hw = user; 123 struct clk *clk; 124 struct clk_hw_omap_comp *cclk = to_clk_hw_comp(hw); 125 struct component_clk *comp; 126 int num_parents = 0; 127 const char **parent_names = NULL; 128 const char *name; 129 int i; 130 int ret; 131 132 /* Check for presence of each component clock */ 133 for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) { 134 if (!cclk->comp_nodes[i]) 135 continue; 136 137 comp = _lookup_component(cclk->comp_nodes[i]); 138 if (!comp) { 139 pr_debug("component %s not ready for %pOFn, retry\n", 140 cclk->comp_nodes[i]->name, node); 141 if (!ti_clk_retry_init(node, hw, 142 _register_composite)) 143 return; 144 145 goto cleanup; 146 } 147 if (cclk->comp_clks[comp->type] != NULL) { 148 pr_err("duplicate component types for %pOFn (%s)!\n", 149 node, component_clk_types[comp->type]); 150 goto cleanup; 151 } 152 153 cclk->comp_clks[comp->type] = comp; 154 155 /* Mark this node as found */ 156 cclk->comp_nodes[i] = NULL; 157 } 158 159 /* All components exists, proceed with registration */ 160 for (i = CLK_COMPONENT_TYPE_MAX - 1; i >= 0; i--) { 161 comp = cclk->comp_clks[i]; 162 if (!comp) 163 continue; 164 if (comp->num_parents) { 165 num_parents = comp->num_parents; 166 parent_names = comp->parent_names; 167 break; 168 } 169 } 170 171 if (!num_parents) { 172 pr_err("%s: no parents found for %pOFn!\n", __func__, node); 173 goto cleanup; 174 } 175 176 name = ti_dt_clk_name(node); 177 clk = clk_register_composite(NULL, name, 178 parent_names, num_parents, 179 _get_hw(cclk, CLK_COMPONENT_TYPE_MUX), 180 &ti_clk_mux_ops, 181 _get_hw(cclk, CLK_COMPONENT_TYPE_DIVIDER), 182 &ti_composite_divider_ops, 183 _get_hw(cclk, CLK_COMPONENT_TYPE_GATE), 184 &ti_composite_gate_ops, 0); 185 186 if (!IS_ERR(clk)) { 187 ret = ti_clk_add_alias(NULL, clk, name); 188 if (ret) { 189 clk_unregister(clk); 190 goto cleanup; 191 } 192 of_clk_add_provider(node, of_clk_src_simple_get, clk); 193 } 194 195cleanup: 196 /* Free component clock list entries */ 197 for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) { 198 if (!cclk->comp_clks[i]) 199 continue; 200 list_del(&cclk->comp_clks[i]->link); 201 kfree(cclk->comp_clks[i]->parent_names); 202 kfree(cclk->comp_clks[i]); 203 } 204 205 kfree(cclk); 206} 207 208static void __init of_ti_composite_clk_setup(struct device_node *node) 209{ 210 unsigned int num_clks; 211 int i; 212 struct clk_hw_omap_comp *cclk; 213 214 /* Number of component clocks to be put inside this clock */ 215 num_clks = of_clk_get_parent_count(node); 216 217 if (!num_clks) { 218 pr_err("composite clk %pOFn must have component(s)\n", node); 219 return; 220 } 221 222 cclk = kzalloc(sizeof(*cclk), GFP_KERNEL); 223 if (!cclk) 224 return; 225 226 /* Get device node pointers for each component clock */ 227 for (i = 0; i < num_clks; i++) 228 cclk->comp_nodes[i] = _get_component_node(node, i); 229 230 _register_composite(&cclk->hw, node); 231} 232CLK_OF_DECLARE(ti_composite_clock, "ti,composite-clock", 233 of_ti_composite_clk_setup); 234 235/** 236 * ti_clk_add_component - add a component clock to the pool 237 * @node: device node of the component clock 238 * @hw: hardware clock definition for the component clock 239 * @type: type of the component clock 240 * 241 * Adds a component clock to the list of available components, so that 242 * it can be registered by a composite clock. 243 */ 244int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw, 245 int type) 246{ 247 unsigned int num_parents; 248 const char **parent_names; 249 struct component_clk *clk; 250 251 num_parents = of_clk_get_parent_count(node); 252 253 if (!num_parents) { 254 pr_err("component-clock %pOFn must have parent(s)\n", node); 255 return -EINVAL; 256 } 257 258 parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); 259 if (!parent_names) 260 return -ENOMEM; 261 262 of_clk_parent_fill(node, parent_names, num_parents); 263 264 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 265 if (!clk) { 266 kfree(parent_names); 267 return -ENOMEM; 268 } 269 270 clk->num_parents = num_parents; 271 clk->parent_names = parent_names; 272 clk->hw = hw; 273 clk->node = node; 274 clk->type = type; 275 list_add(&clk->link, &component_clks); 276 277 return 0; 278}