10318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King/* 26d803ba736abb5e122dede70a4720e4843dd6df4Jean-Christop PLAGNIOL-VILLARD * drivers/clk/clkdev.c 30318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King * 40318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King * Copyright (C) 2008 Russell King. 50318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King * 60318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King * This program is free software; you can redistribute it and/or modify 70318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King * it under the terms of the GNU General Public License version 2 as 80318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King * published by the Free Software Foundation. 90318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King * 100318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King * Helper for the clk API to assist looking up a struct clk. 110318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King */ 120318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#include <linux/module.h> 130318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#include <linux/kernel.h> 140318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#include <linux/device.h> 150318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#include <linux/list.h> 160318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#include <linux/errno.h> 170318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#include <linux/err.h> 180318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#include <linux/string.h> 190318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#include <linux/mutex.h> 20c0c60c4b9ab45bb02b20796401dd6a90770fd0eeHartley Sweeten#include <linux/clk.h> 216d803ba736abb5e122dede70a4720e4843dd6df4Jean-Christop PLAGNIOL-VILLARD#include <linux/clkdev.h> 22766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely#include <linux/of.h> 230318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 243a3d2b0551d79ef476ef57424beeb8f68789fbcdSylwester Nawrocki#include "clk.h" 253a3d2b0551d79ef476ef57424beeb8f68789fbcdSylwester Nawrocki 260318e693d3a56836632bf1a2cfdafb7f34bcc703Russell Kingstatic LIST_HEAD(clocks); 270318e693d3a56836632bf1a2cfdafb7f34bcc703Russell Kingstatic DEFINE_MUTEX(clocks_mutex); 280318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 29137f8a7213d80c1388ca48280c1ef0856b6fec30Rob Herring#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) 307f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki 317f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki/** 327f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki * of_clk_get_by_clkspec() - Lookup a clock form a clock provider 337f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki * @clkspec: pointer to a clock specifier data structure 347f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki * 357f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki * This function looks up a struct clk from the registered list of clock 367f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki * providers, an input is a clock specifier data structure as returned 377f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki * from the of_parse_phandle_with_args() function call. 387f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki */ 397f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrockistruct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec) 407f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki{ 417f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki struct clk *clk; 427f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki 437f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki if (!clkspec) 447f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki return ERR_PTR(-EINVAL); 457f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki 467f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki of_clk_lock(); 477f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki clk = __of_clk_get_from_provider(clkspec); 487f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki 497f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki if (!IS_ERR(clk) && !__clk_get(clk)) 507f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki clk = ERR_PTR(-ENOENT); 517f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki 527f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki of_clk_unlock(); 537f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki return clk; 547f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki} 557f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki 56766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likelystruct clk *of_clk_get(struct device_node *np, int index) 57766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely{ 58766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely struct of_phandle_args clkspec; 59766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely struct clk *clk; 60766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely int rc; 61766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 62766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely if (index < 0) 63766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely return ERR_PTR(-EINVAL); 64766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 65766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index, 66766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely &clkspec); 67766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely if (rc) 68766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely return ERR_PTR(rc); 69766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 707f05e28f9dd3eb7a3f27c6f50b715995dc7a88c5Sylwester Nawrocki clk = of_clk_get_by_clkspec(&clkspec); 71766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely of_node_put(clkspec.np); 72766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely return clk; 73766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely} 74766e6a4ec602d0c107553b91b3434fe9c03474f4Grant LikelyEXPORT_SYMBOL(of_clk_get); 75766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 76766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely/** 77766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node 78766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * @np: pointer to clock consumer node 79766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * @name: name of consumer's clock input, or NULL for the first clock reference 80766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * 81766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * This function parses the clocks and clock-names properties, 82766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * and uses them to look up the struct clk from the registered list of clock 83766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * providers. 84766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely */ 85766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likelystruct clk *of_clk_get_by_name(struct device_node *np, const char *name) 86766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely{ 87766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely struct clk *clk = ERR_PTR(-ENOENT); 88766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 89766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely /* Walk up the tree of devices looking for a clock that matches */ 90766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely while (np) { 91766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely int index = 0; 92766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 93766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely /* 94766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * For named clocks, first look up the name in the 95766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * "clock-names" property. If it cannot be found, then 96766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * index will be an error code, and of_clk_get() will fail. 97766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely */ 98766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely if (name) 99766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely index = of_property_match_string(np, "clock-names", name); 100766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely clk = of_clk_get(np, index); 101766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely if (!IS_ERR(clk)) 102766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely break; 103766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely else if (name && index >= 0) { 104d8e53c3deb46ec5b45bd7f5e1cc8ff8d35ec92baStephen Boyd if (PTR_ERR(clk) != -EPROBE_DEFER) 105d8e53c3deb46ec5b45bd7f5e1cc8ff8d35ec92baStephen Boyd pr_err("ERROR: could not get clock %s:%s(%i)\n", 106d8e53c3deb46ec5b45bd7f5e1cc8ff8d35ec92baStephen Boyd np->full_name, name ? name : "", index); 107766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely return clk; 108766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely } 109766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 110766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely /* 111766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * No matching clock found on this node. If the parent node 112766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * has a "clock-ranges" property, then we can try one of its 113766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely * clocks. 114766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely */ 115766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely np = np->parent; 116766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely if (np && !of_get_property(np, "clock-ranges", NULL)) 117766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely break; 118766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely } 119766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 120766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely return clk; 121766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely} 122766e6a4ec602d0c107553b91b3434fe9c03474f4Grant LikelyEXPORT_SYMBOL(of_clk_get_by_name); 123766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely#endif 124766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 125409dc360b49480b57869ffd457e4b95901b76b75Russell King/* 126409dc360b49480b57869ffd457e4b95901b76b75Russell King * Find the correct struct clk for the device and connection ID. 127409dc360b49480b57869ffd457e4b95901b76b75Russell King * We do slightly fuzzy matching here: 128409dc360b49480b57869ffd457e4b95901b76b75Russell King * An entry with a NULL ID is assumed to be a wildcard. 129409dc360b49480b57869ffd457e4b95901b76b75Russell King * If an entry has a device ID, it must match 130409dc360b49480b57869ffd457e4b95901b76b75Russell King * If an entry has a connection ID, it must match 131409dc360b49480b57869ffd457e4b95901b76b75Russell King * Then we take the most specific entry - with the following 132659431fcafd820cc426afedadcc4548933224985Uwe Kleine-König * order of precedence: dev+con > dev only > con only. 133409dc360b49480b57869ffd457e4b95901b76b75Russell King */ 134e8bf8df9c296b782c32236c6a5893aec301320c7Russell Kingstatic struct clk_lookup *clk_find(const char *dev_id, const char *con_id) 1350318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King{ 136e8bf8df9c296b782c32236c6a5893aec301320c7Russell King struct clk_lookup *p, *cl = NULL; 13767b508715a61962f9b5b3ef3432e045a9cba4f1eViresh Kumar int match, best_found = 0, best_possible = 0; 13867b508715a61962f9b5b3ef3432e045a9cba4f1eViresh Kumar 13967b508715a61962f9b5b3ef3432e045a9cba4f1eViresh Kumar if (dev_id) 14067b508715a61962f9b5b3ef3432e045a9cba4f1eViresh Kumar best_possible += 2; 14167b508715a61962f9b5b3ef3432e045a9cba4f1eViresh Kumar if (con_id) 14267b508715a61962f9b5b3ef3432e045a9cba4f1eViresh Kumar best_possible += 1; 1430318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 1440318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King list_for_each_entry(p, &clocks, node) { 1450318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King match = 0; 146409dc360b49480b57869ffd457e4b95901b76b75Russell King if (p->dev_id) { 147409dc360b49480b57869ffd457e4b95901b76b75Russell King if (!dev_id || strcmp(p->dev_id, dev_id)) 148409dc360b49480b57869ffd457e4b95901b76b75Russell King continue; 149409dc360b49480b57869ffd457e4b95901b76b75Russell King match += 2; 150409dc360b49480b57869ffd457e4b95901b76b75Russell King } 151409dc360b49480b57869ffd457e4b95901b76b75Russell King if (p->con_id) { 152409dc360b49480b57869ffd457e4b95901b76b75Russell King if (!con_id || strcmp(p->con_id, con_id)) 153409dc360b49480b57869ffd457e4b95901b76b75Russell King continue; 154409dc360b49480b57869ffd457e4b95901b76b75Russell King match += 1; 155409dc360b49480b57869ffd457e4b95901b76b75Russell King } 1560318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 15767b508715a61962f9b5b3ef3432e045a9cba4f1eViresh Kumar if (match > best_found) { 158e8bf8df9c296b782c32236c6a5893aec301320c7Russell King cl = p; 15967b508715a61962f9b5b3ef3432e045a9cba4f1eViresh Kumar if (match != best_possible) 16067b508715a61962f9b5b3ef3432e045a9cba4f1eViresh Kumar best_found = match; 161e4bf5becccf4685754c4d8e4485bb2ff7d28147fviresh kumar else 162e4bf5becccf4685754c4d8e4485bb2ff7d28147fviresh kumar break; 1630318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King } 1640318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King } 165e8bf8df9c296b782c32236c6a5893aec301320c7Russell King return cl; 1660318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King} 1670318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 16805fd8e73e1357feaea9c48938d937eae76b4aef4Sascha Hauerstruct clk *clk_get_sys(const char *dev_id, const char *con_id) 1690318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King{ 170e8bf8df9c296b782c32236c6a5893aec301320c7Russell King struct clk_lookup *cl; 1710318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 1720318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King mutex_lock(&clocks_mutex); 173e8bf8df9c296b782c32236c6a5893aec301320c7Russell King cl = clk_find(dev_id, con_id); 174e8bf8df9c296b782c32236c6a5893aec301320c7Russell King if (cl && !__clk_get(cl->clk)) 175e8bf8df9c296b782c32236c6a5893aec301320c7Russell King cl = NULL; 1760318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King mutex_unlock(&clocks_mutex); 1770318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 178e8bf8df9c296b782c32236c6a5893aec301320c7Russell King return cl ? cl->clk : ERR_PTR(-ENOENT); 1790318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King} 18005fd8e73e1357feaea9c48938d937eae76b4aef4Sascha HauerEXPORT_SYMBOL(clk_get_sys); 18105fd8e73e1357feaea9c48938d937eae76b4aef4Sascha Hauer 18205fd8e73e1357feaea9c48938d937eae76b4aef4Sascha Hauerstruct clk *clk_get(struct device *dev, const char *con_id) 18305fd8e73e1357feaea9c48938d937eae76b4aef4Sascha Hauer{ 18405fd8e73e1357feaea9c48938d937eae76b4aef4Sascha Hauer const char *dev_id = dev ? dev_name(dev) : NULL; 185766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely struct clk *clk; 186766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely 187766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely if (dev) { 188766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely clk = of_clk_get_by_name(dev->of_node, con_id); 1893a3d2b0551d79ef476ef57424beeb8f68789fbcdSylwester Nawrocki if (!IS_ERR(clk)) 190766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely return clk; 191a34cd4666f3da84228a82f70c94b8d9b692034eaJean-Francois Moine if (PTR_ERR(clk) == -EPROBE_DEFER) 192a34cd4666f3da84228a82f70c94b8d9b692034eaJean-Francois Moine return clk; 193766e6a4ec602d0c107553b91b3434fe9c03474f4Grant Likely } 19405fd8e73e1357feaea9c48938d937eae76b4aef4Sascha Hauer 19505fd8e73e1357feaea9c48938d937eae76b4aef4Sascha Hauer return clk_get_sys(dev_id, con_id); 19605fd8e73e1357feaea9c48938d937eae76b4aef4Sascha Hauer} 1970318e693d3a56836632bf1a2cfdafb7f34bcc703Russell KingEXPORT_SYMBOL(clk_get); 1980318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 1990318e693d3a56836632bf1a2cfdafb7f34bcc703Russell Kingvoid clk_put(struct clk *clk) 2000318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King{ 2010318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King __clk_put(clk); 2020318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King} 2030318e693d3a56836632bf1a2cfdafb7f34bcc703Russell KingEXPORT_SYMBOL(clk_put); 2040318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 2050318e693d3a56836632bf1a2cfdafb7f34bcc703Russell Kingvoid clkdev_add(struct clk_lookup *cl) 2060318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King{ 2070318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King mutex_lock(&clocks_mutex); 2080318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King list_add_tail(&cl->node, &clocks); 2090318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King mutex_unlock(&clocks_mutex); 2100318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King} 2110318e693d3a56836632bf1a2cfdafb7f34bcc703Russell KingEXPORT_SYMBOL(clkdev_add); 2120318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 2130a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell Kingvoid __init clkdev_add_table(struct clk_lookup *cl, size_t num) 2140a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell King{ 2150a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell King mutex_lock(&clocks_mutex); 2160a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell King while (num--) { 2170a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell King list_add_tail(&cl->node, &clocks); 2180a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell King cl++; 2190a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell King } 2200a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell King mutex_unlock(&clocks_mutex); 2210a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell King} 2220a0300dc8c4b3f3ce5c9ef5a0a4be5442590398fRussell King 2230318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#define MAX_DEV_ID 20 2240318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King#define MAX_CON_ID 16 2250318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 2260318e693d3a56836632bf1a2cfdafb7f34bcc703Russell Kingstruct clk_lookup_alloc { 2270318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King struct clk_lookup cl; 2280318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King char dev_id[MAX_DEV_ID]; 2290318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King char con_id[MAX_CON_ID]; 2300318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King}; 2310318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 232e9d7f4065408e92338a41b809e437c6e043da090Russell Kingstatic struct clk_lookup * __init_refok 233e9d7f4065408e92338a41b809e437c6e043da090Russell Kingvclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, 234e9d7f4065408e92338a41b809e437c6e043da090Russell King va_list ap) 2350318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King{ 2360318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King struct clk_lookup_alloc *cla; 2370318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 2386d803ba736abb5e122dede70a4720e4843dd6df4Jean-Christop PLAGNIOL-VILLARD cla = __clkdev_alloc(sizeof(*cla)); 2390318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King if (!cla) 2400318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King return NULL; 2410318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 2420318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King cla->cl.clk = clk; 2430318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King if (con_id) { 2440318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King strlcpy(cla->con_id, con_id, sizeof(cla->con_id)); 2450318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King cla->cl.con_id = cla->con_id; 2460318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King } 2470318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 2480318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King if (dev_fmt) { 2490318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap); 2500318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King cla->cl.dev_id = cla->dev_id; 2510318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King } 2520318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 2530318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King return &cla->cl; 2540318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King} 255e9d7f4065408e92338a41b809e437c6e043da090Russell King 256e9d7f4065408e92338a41b809e437c6e043da090Russell Kingstruct clk_lookup * __init_refok 257e9d7f4065408e92338a41b809e437c6e043da090Russell Kingclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...) 258e9d7f4065408e92338a41b809e437c6e043da090Russell King{ 259e9d7f4065408e92338a41b809e437c6e043da090Russell King struct clk_lookup *cl; 260e9d7f4065408e92338a41b809e437c6e043da090Russell King va_list ap; 261e9d7f4065408e92338a41b809e437c6e043da090Russell King 262e9d7f4065408e92338a41b809e437c6e043da090Russell King va_start(ap, dev_fmt); 263e9d7f4065408e92338a41b809e437c6e043da090Russell King cl = vclkdev_alloc(clk, con_id, dev_fmt, ap); 264e9d7f4065408e92338a41b809e437c6e043da090Russell King va_end(ap); 265e9d7f4065408e92338a41b809e437c6e043da090Russell King 266e9d7f4065408e92338a41b809e437c6e043da090Russell King return cl; 267e9d7f4065408e92338a41b809e437c6e043da090Russell King} 2680318e693d3a56836632bf1a2cfdafb7f34bcc703Russell KingEXPORT_SYMBOL(clkdev_alloc); 2690318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King 270c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgrenint clk_add_alias(const char *alias, const char *alias_dev_name, char *id, 271c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren struct device *dev) 272c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren{ 273c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren struct clk *r = clk_get(dev, id); 274c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren struct clk_lookup *l; 275c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren 276c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren if (IS_ERR(r)) 277c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren return PTR_ERR(r); 278c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren 279c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren l = clkdev_alloc(r, alias, alias_dev_name); 280c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren clk_put(r); 281c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren if (!l) 282c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren return -ENODEV; 283c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren clkdev_add(l); 284c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren return 0; 285c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren} 286c0683039207226afcffbe0fbf6a1caaee77a37b0Tony LindgrenEXPORT_SYMBOL(clk_add_alias); 287c0683039207226afcffbe0fbf6a1caaee77a37b0Tony Lindgren 2880318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King/* 2890318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King * clkdev_drop - remove a clock dynamically allocated 2900318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King */ 2910318e693d3a56836632bf1a2cfdafb7f34bcc703Russell Kingvoid clkdev_drop(struct clk_lookup *cl) 2920318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King{ 2930318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King mutex_lock(&clocks_mutex); 2940318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King list_del(&cl->node); 2950318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King mutex_unlock(&clocks_mutex); 2960318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King kfree(cl); 2970318e693d3a56836632bf1a2cfdafb7f34bcc703Russell King} 2980318e693d3a56836632bf1a2cfdafb7f34bcc703Russell KingEXPORT_SYMBOL(clkdev_drop); 299e9d7f4065408e92338a41b809e437c6e043da090Russell King 300e9d7f4065408e92338a41b809e437c6e043da090Russell King/** 301e9d7f4065408e92338a41b809e437c6e043da090Russell King * clk_register_clkdev - register one clock lookup for a struct clk 302e9d7f4065408e92338a41b809e437c6e043da090Russell King * @clk: struct clk to associate with all clk_lookups 303e9d7f4065408e92338a41b809e437c6e043da090Russell King * @con_id: connection ID string on device 304e9d7f4065408e92338a41b809e437c6e043da090Russell King * @dev_id: format string describing device name 305e9d7f4065408e92338a41b809e437c6e043da090Russell King * 306e9d7f4065408e92338a41b809e437c6e043da090Russell King * con_id or dev_id may be NULL as a wildcard, just as in the rest of 307e9d7f4065408e92338a41b809e437c6e043da090Russell King * clkdev. 308e9d7f4065408e92338a41b809e437c6e043da090Russell King * 309e9d7f4065408e92338a41b809e437c6e043da090Russell King * To make things easier for mass registration, we detect error clks 310e9d7f4065408e92338a41b809e437c6e043da090Russell King * from a previous clk_register() call, and return the error code for 311e9d7f4065408e92338a41b809e437c6e043da090Russell King * those. This is to permit this function to be called immediately 312e9d7f4065408e92338a41b809e437c6e043da090Russell King * after clk_register(). 313e9d7f4065408e92338a41b809e437c6e043da090Russell King */ 314e9d7f4065408e92338a41b809e437c6e043da090Russell Kingint clk_register_clkdev(struct clk *clk, const char *con_id, 315e9d7f4065408e92338a41b809e437c6e043da090Russell King const char *dev_fmt, ...) 316e9d7f4065408e92338a41b809e437c6e043da090Russell King{ 317e9d7f4065408e92338a41b809e437c6e043da090Russell King struct clk_lookup *cl; 318e9d7f4065408e92338a41b809e437c6e043da090Russell King va_list ap; 319e9d7f4065408e92338a41b809e437c6e043da090Russell King 320e9d7f4065408e92338a41b809e437c6e043da090Russell King if (IS_ERR(clk)) 321e9d7f4065408e92338a41b809e437c6e043da090Russell King return PTR_ERR(clk); 322e9d7f4065408e92338a41b809e437c6e043da090Russell King 323e9d7f4065408e92338a41b809e437c6e043da090Russell King va_start(ap, dev_fmt); 324e9d7f4065408e92338a41b809e437c6e043da090Russell King cl = vclkdev_alloc(clk, con_id, dev_fmt, ap); 325e9d7f4065408e92338a41b809e437c6e043da090Russell King va_end(ap); 326e9d7f4065408e92338a41b809e437c6e043da090Russell King 327e9d7f4065408e92338a41b809e437c6e043da090Russell King if (!cl) 328e9d7f4065408e92338a41b809e437c6e043da090Russell King return -ENOMEM; 329e9d7f4065408e92338a41b809e437c6e043da090Russell King 330e9d7f4065408e92338a41b809e437c6e043da090Russell King clkdev_add(cl); 331e9d7f4065408e92338a41b809e437c6e043da090Russell King 332e9d7f4065408e92338a41b809e437c6e043da090Russell King return 0; 333e9d7f4065408e92338a41b809e437c6e043da090Russell King} 334e9d7f4065408e92338a41b809e437c6e043da090Russell King 335e9d7f4065408e92338a41b809e437c6e043da090Russell King/** 336e9d7f4065408e92338a41b809e437c6e043da090Russell King * clk_register_clkdevs - register a set of clk_lookup for a struct clk 337e9d7f4065408e92338a41b809e437c6e043da090Russell King * @clk: struct clk to associate with all clk_lookups 338e9d7f4065408e92338a41b809e437c6e043da090Russell King * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized 339e9d7f4065408e92338a41b809e437c6e043da090Russell King * @num: number of clk_lookup structures to register 340e9d7f4065408e92338a41b809e437c6e043da090Russell King * 341e9d7f4065408e92338a41b809e437c6e043da090Russell King * To make things easier for mass registration, we detect error clks 342e9d7f4065408e92338a41b809e437c6e043da090Russell King * from a previous clk_register() call, and return the error code for 343e9d7f4065408e92338a41b809e437c6e043da090Russell King * those. This is to permit this function to be called immediately 344e9d7f4065408e92338a41b809e437c6e043da090Russell King * after clk_register(). 345e9d7f4065408e92338a41b809e437c6e043da090Russell King */ 346e9d7f4065408e92338a41b809e437c6e043da090Russell Kingint clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num) 347e9d7f4065408e92338a41b809e437c6e043da090Russell King{ 348e9d7f4065408e92338a41b809e437c6e043da090Russell King unsigned i; 349e9d7f4065408e92338a41b809e437c6e043da090Russell King 350e9d7f4065408e92338a41b809e437c6e043da090Russell King if (IS_ERR(clk)) 351e9d7f4065408e92338a41b809e437c6e043da090Russell King return PTR_ERR(clk); 352e9d7f4065408e92338a41b809e437c6e043da090Russell King 353e9d7f4065408e92338a41b809e437c6e043da090Russell King for (i = 0; i < num; i++, cl++) { 354e9d7f4065408e92338a41b809e437c6e043da090Russell King cl->clk = clk; 355e9d7f4065408e92338a41b809e437c6e043da090Russell King clkdev_add(cl); 356e9d7f4065408e92338a41b809e437c6e043da090Russell King } 357e9d7f4065408e92338a41b809e437c6e043da090Russell King 358e9d7f4065408e92338a41b809e437c6e043da090Russell King return 0; 359e9d7f4065408e92338a41b809e437c6e043da090Russell King} 360e9d7f4065408e92338a41b809e437c6e043da090Russell KingEXPORT_SYMBOL(clk_register_clkdevs); 361