18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * TI Fixed Factor Clock 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2013 Texas Instruments, Inc. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Tero Kristo <t-kristo@ti.com> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 98c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License version 2 as 108c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * This program is distributed "as is" WITHOUT ANY WARRANTY of any 138c2ecf20Sopenharmony_ci * kind, whether express or implied; without even the implied warranty 148c2ecf20Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 158c2ecf20Sopenharmony_ci * GNU General Public License for more details. 168c2ecf20Sopenharmony_ci */ 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 198c2ecf20Sopenharmony_ci#include <linux/slab.h> 208c2ecf20Sopenharmony_ci#include <linux/err.h> 218c2ecf20Sopenharmony_ci#include <linux/of.h> 228c2ecf20Sopenharmony_ci#include <linux/of_address.h> 238c2ecf20Sopenharmony_ci#include <linux/clk/ti.h> 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#include "clock.h" 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#undef pr_fmt 288c2ecf20Sopenharmony_ci#define pr_fmt(fmt) "%s: " fmt, __func__ 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/** 318c2ecf20Sopenharmony_ci * of_ti_fixed_factor_clk_setup - Setup function for TI fixed factor clock 328c2ecf20Sopenharmony_ci * @node: device node for this clock 338c2ecf20Sopenharmony_ci * 348c2ecf20Sopenharmony_ci * Sets up a simple fixed factor clock based on device tree info. 358c2ecf20Sopenharmony_ci */ 368c2ecf20Sopenharmony_cistatic void __init of_ti_fixed_factor_clk_setup(struct device_node *node) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci struct clk *clk; 398c2ecf20Sopenharmony_ci const char *clk_name = ti_dt_clk_name(node); 408c2ecf20Sopenharmony_ci const char *parent_name; 418c2ecf20Sopenharmony_ci u32 div, mult; 428c2ecf20Sopenharmony_ci u32 flags = 0; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci if (of_property_read_u32(node, "ti,clock-div", &div)) { 458c2ecf20Sopenharmony_ci pr_err("%pOFn must have a clock-div property\n", node); 468c2ecf20Sopenharmony_ci return; 478c2ecf20Sopenharmony_ci } 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci if (of_property_read_u32(node, "ti,clock-mult", &mult)) { 508c2ecf20Sopenharmony_ci pr_err("%pOFn must have a clock-mult property\n", node); 518c2ecf20Sopenharmony_ci return; 528c2ecf20Sopenharmony_ci } 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci if (of_property_read_bool(node, "ti,set-rate-parent")) 558c2ecf20Sopenharmony_ci flags |= CLK_SET_RATE_PARENT; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci parent_name = of_clk_get_parent_name(node, 0); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, 608c2ecf20Sopenharmony_ci mult, div); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci if (!IS_ERR(clk)) { 638c2ecf20Sopenharmony_ci of_clk_add_provider(node, of_clk_src_simple_get, clk); 648c2ecf20Sopenharmony_ci of_ti_clk_autoidle_setup(node); 658c2ecf20Sopenharmony_ci ti_clk_add_alias(clk, clk_name); 668c2ecf20Sopenharmony_ci } 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ciCLK_OF_DECLARE(ti_fixed_factor_clk, "ti,fixed-factor-clock", 698c2ecf20Sopenharmony_ci of_ti_fixed_factor_clk_setup); 70