Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * drivers/clk/clkdev.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2008 Russell King.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Helper for the clk API to assist looking up a struct clk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static LIST_HEAD(clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static DEFINE_MUTEX(clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * Find the correct struct clk for the device and connection ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * We do slightly fuzzy matching here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *  An entry with a NULL ID is assumed to be a wildcard.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *  If an entry has a device ID, it must match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *  If an entry has a connection ID, it must match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * Then we take the most specific entry - with the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * order of precedence: dev+con > dev only > con only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	struct clk_lookup *p, *cl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	int match, best_found = 0, best_possible = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	if (dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		best_possible += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	if (con_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		best_possible += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	lockdep_assert_held(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	list_for_each_entry(p, &clocks, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		match = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		if (p->dev_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			if (!dev_id || strcmp(p->dev_id, dev_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			match += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		if (p->con_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			if (!con_id || strcmp(p->con_id, con_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			match += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		if (match > best_found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			cl = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 			if (match != best_possible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 				best_found = match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	return cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct clk_hw *hw = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	mutex_lock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	cl = clk_find(dev_id, con_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	if (cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		hw = cl->clk_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	mutex_unlock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static struct clk *__clk_get_sys(struct device *dev, const char *dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				 const char *con_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	struct clk_hw *hw = clk_find_hw(dev_id, con_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return clk_hw_create_clk(dev, hw, dev_id, con_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) struct clk *clk_get_sys(const char *dev_id, const char *con_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	return __clk_get_sys(NULL, dev_id, con_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) EXPORT_SYMBOL(clk_get_sys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct clk *clk_get(struct device *dev, const char *con_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	const char *dev_id = dev ? dev_name(dev) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (dev && dev->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		hw = of_clk_get_hw(dev->of_node, 0, con_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			return clk_hw_create_clk(dev, hw, dev_id, con_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	return __clk_get_sys(dev, dev_id, con_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) EXPORT_SYMBOL(clk_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void clk_put(struct clk *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	__clk_put(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) EXPORT_SYMBOL(clk_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static void __clkdev_add(struct clk_lookup *cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	mutex_lock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	list_add_tail(&cl->node, &clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	mutex_unlock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) void clkdev_add(struct clk_lookup *cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	if (!cl->clk_hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		cl->clk_hw = __clk_get_hw(cl->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	__clkdev_add(cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) EXPORT_SYMBOL(clkdev_add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) void clkdev_add_table(struct clk_lookup *cl, size_t num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	mutex_lock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	while (num--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		cl->clk_hw = __clk_get_hw(cl->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		list_add_tail(&cl->node, &clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		cl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	mutex_unlock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define MAX_DEV_ID	20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define MAX_CON_ID	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct clk_lookup_alloc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct clk_lookup cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	char	dev_id[MAX_DEV_ID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	char	con_id[MAX_CON_ID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static struct clk_lookup * __ref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) vclkdev_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	va_list ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	struct clk_lookup_alloc *cla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	cla = kzalloc(sizeof(*cla), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (!cla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	cla->cl.clk_hw = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	if (con_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		cla->cl.con_id = cla->con_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (dev_fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		cla->cl.dev_id = cla->dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	return &cla->cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static struct clk_lookup *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) vclkdev_create(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	va_list ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	if (cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		__clkdev_add(cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	return cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct clk_lookup * __ref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	va_start(ap, dev_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	cl = vclkdev_alloc(__clk_get_hw(clk), con_id, dev_fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	return cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) EXPORT_SYMBOL(clkdev_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct clk_lookup *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	va_start(ap, dev_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	return cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) EXPORT_SYMBOL(clkdev_hw_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  * clkdev_create - allocate and add a clkdev lookup structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * @clk: struct clk to associate with all clk_lookups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  * @con_id: connection ID string on device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  * @dev_fmt: format string describing device name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * Returns a clk_lookup structure, which can be later unregistered and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  * freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	const char *dev_fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	va_start(ap, dev_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	cl = vclkdev_create(__clk_get_hw(clk), con_id, dev_fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	return cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) EXPORT_SYMBOL_GPL(clkdev_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  * clkdev_hw_create - allocate and add a clkdev lookup structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  * @hw: struct clk_hw to associate with all clk_lookups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * @con_id: connection ID string on device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  * @dev_fmt: format string describing device name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  * Returns a clk_lookup structure, which can be later unregistered and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  * freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	const char *dev_fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	va_start(ap, dev_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	cl = vclkdev_create(hw, con_id, dev_fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	return cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) EXPORT_SYMBOL_GPL(clkdev_hw_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int clk_add_alias(const char *alias, const char *alias_dev_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	const char *con_id, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	struct clk *r = clk_get(dev, con_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	struct clk_lookup *l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	if (IS_ERR(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		return PTR_ERR(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	l = clkdev_create(r, alias, alias_dev_name ? "%s" : NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			  alias_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	clk_put(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	return l ? 0 : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) EXPORT_SYMBOL(clk_add_alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  * clkdev_drop - remove a clock dynamically allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) void clkdev_drop(struct clk_lookup *cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	mutex_lock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	list_del(&cl->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	mutex_unlock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	kfree(cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) EXPORT_SYMBOL(clkdev_drop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 						const char *con_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 						const char *dev_id, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	va_start(ap, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	cl = vclkdev_create(hw, con_id, dev_id, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	return cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static int do_clk_register_clkdev(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	struct clk_lookup **cl, const char *con_id, const char *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	 * Since dev_id can be NULL, and NULL is handled specially, we must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	 * pass it as either a NULL format string, or with "%s".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		*cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		*cl = __clk_register_clkdev(hw, con_id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	return *cl ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  * clk_register_clkdev - register one clock lookup for a struct clk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)  * @clk: struct clk to associate with all clk_lookups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)  * @con_id: connection ID string on device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)  * @dev_id: string describing device name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)  * con_id or dev_id may be NULL as a wildcard, just as in the rest of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)  * clkdev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)  * To make things easier for mass registration, we detect error clks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  * from a previous clk_register() call, and return the error code for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  * those.  This is to permit this function to be called immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  * after clk_register().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) int clk_register_clkdev(struct clk *clk, const char *con_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	const char *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	return do_clk_register_clkdev(__clk_get_hw(clk), &cl, con_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 					      dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) EXPORT_SYMBOL(clk_register_clkdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * clk_hw_register_clkdev - register one clock lookup for a struct clk_hw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  * @hw: struct clk_hw to associate with all clk_lookups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  * @con_id: connection ID string on device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  * @dev_id: format string describing device name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  * con_id or dev_id may be NULL as a wildcard, just as in the rest of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  * clkdev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)  * To make things easier for mass registration, we detect error clk_hws
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)  * from a previous clk_hw_register_*() call, and return the error code for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)  * those.  This is to permit this function to be called immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)  * after clk_hw_register_*().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	const char *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	return do_clk_register_clkdev(hw, &cl, con_id, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) EXPORT_SYMBOL(clk_hw_register_clkdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static void devm_clkdev_release(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	clkdev_drop(*(struct clk_lookup **)res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static int devm_clk_match_clkdev(struct device *dev, void *res, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	struct clk_lookup **l = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	return *l == data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)  * devm_clk_release_clkdev - Resource managed clkdev lookup release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  * @dev: device this lookup is bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  * @con_id: connection ID string on device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  * @dev_id: format string describing device name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  * Drop the clkdev lookup created with devm_clk_hw_register_clkdev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * Normally this function will not need to be called and the resource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  * management code will ensure that the resource is freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) void devm_clk_release_clkdev(struct device *dev, const char *con_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			     const char *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	struct clk_lookup *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	mutex_lock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	cl = clk_find(dev_id, con_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	mutex_unlock(&clocks_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	WARN_ON(!cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	rval = devres_release(dev, devm_clkdev_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			      devm_clk_match_clkdev, cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	WARN_ON(rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) EXPORT_SYMBOL(devm_clk_release_clkdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  * devm_clk_hw_register_clkdev - managed clk lookup registration for clk_hw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  * @dev: device this lookup is bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)  * @hw: struct clk_hw to associate with all clk_lookups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)  * @con_id: connection ID string on device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)  * @dev_id: format string describing device name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  * con_id or dev_id may be NULL as a wildcard, just as in the rest of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  * clkdev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  * To make things easier for mass registration, we detect error clk_hws
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  * from a previous clk_hw_register_*() call, and return the error code for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)  * those.  This is to permit this function to be called immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)  * after clk_hw_register_*().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 				const char *con_id, const char *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	int rval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	struct clk_lookup **cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	cl = devres_alloc(devm_clkdev_release, sizeof(*cl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	if (cl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		rval = do_clk_register_clkdev(hw, cl, con_id, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		if (!rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			devres_add(dev, cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			devres_free(cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) EXPORT_SYMBOL(devm_clk_hw_register_clkdev);