Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: add devm_get_clk_from_child() API

Some driver is using this type of DT bindings for clock (more detail,
see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt).

sound_soc {
...
cpu {
clocks = <&xxx>;
...
};
codec {
clocks = <&xxx>;
...
};
};

Current driver in this case uses of_clk_get() for each node, but there
is no devm_of_clk_get() today.
OTOH, the problem of having devm_of_clk_get() is that it encourages the
use of of_clk_get() when clk_get() is more desirable.

Thus, this patch adds new devm_get_clk_from_chile() which explicitly
reads as get a clock from a child node of this device.
By this function, we can also use this type of DT bindings

sound_soc {
clocks = <&xxx>, <&xxx>;
clock-names = "cpu", "codec";
clock-ranges;
...
cpu {
...
};
codec {
...
};
};

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
[sboyd@codeurora.org: Rename subject to clk + add API]
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>

authored by

Kuninori Morimoto and committed by
Stephen Boyd
71a2f115 16cd7764

+46 -4
+21
drivers/clk/clk-devres.c
··· 53 53 WARN_ON(ret); 54 54 } 55 55 EXPORT_SYMBOL(devm_clk_put); 56 + 57 + struct clk *devm_get_clk_from_child(struct device *dev, 58 + struct device_node *np, const char *con_id) 59 + { 60 + struct clk **ptr, *clk; 61 + 62 + ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); 63 + if (!ptr) 64 + return ERR_PTR(-ENOMEM); 65 + 66 + clk = of_clk_get_by_name(np, con_id); 67 + if (!IS_ERR(clk)) { 68 + *ptr = clk; 69 + devres_add(dev, ptr); 70 + } else { 71 + devres_free(ptr); 72 + } 73 + 74 + return clk; 75 + } 76 + EXPORT_SYMBOL(devm_get_clk_from_child);
+25 -4
include/linux/clk.h
··· 17 17 #include <linux/notifier.h> 18 18 19 19 struct device; 20 - 21 20 struct clk; 21 + struct device_node; 22 + struct of_phandle_args; 22 23 23 24 /** 24 25 * DOC: clk notifier callback types ··· 250 249 struct clk *devm_clk_get(struct device *dev, const char *id); 251 250 252 251 /** 252 + * devm_get_clk_from_child - lookup and obtain a managed reference to a 253 + * clock producer from child node. 254 + * @dev: device for clock "consumer" 255 + * @np: pointer to clock consumer node 256 + * @con_id: clock consumer ID 257 + * 258 + * This function parses the clocks, and uses them to look up the 259 + * struct clk from the registered list of clock providers by using 260 + * @np and @con_id 261 + * 262 + * The clock will automatically be freed when the device is unbound 263 + * from the bus. 264 + */ 265 + struct clk *devm_get_clk_from_child(struct device *dev, 266 + struct device_node *np, const char *con_id); 267 + 268 + /** 253 269 * clk_enable - inform the system when the clock source should be running. 254 270 * @clk: clock source 255 271 * ··· 450 432 return NULL; 451 433 } 452 434 435 + static inline struct clk *devm_get_clk_from_child(struct device *dev, 436 + struct device_node *np, const char *con_id) 437 + { 438 + return NULL; 439 + } 440 + 453 441 static inline void clk_put(struct clk *clk) {} 454 442 455 443 static inline void devm_clk_put(struct device *dev, struct clk *clk) {} ··· 524 500 clk_disable(clk); 525 501 clk_unprepare(clk); 526 502 } 527 - 528 - struct device_node; 529 - struct of_phandle_args; 530 503 531 504 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) 532 505 struct clk *of_clk_get(struct device_node *np, int index);