aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Turquette <mturquette@linaro.org>2013-12-31 14:35:12 -0500
committerMike Turquette <mturquette@linaro.org>2013-12-31 14:35:12 -0500
commitdbdf6ff51e3ce13ade5834b0d7d451522fcdb478 (patch)
treeb5594d70cf4d484101891adbfc01798c14827fa8
parent391e3903e63781debc52a0de73f2e922dcc3f602 (diff)
parent9ffe29d780dd5f9c662f2c32f8dc64435da726bf (diff)
Merge branch 'clk-next-unregister' into clk-next
Conflicts: drivers/clk/clk.c
-rw-r--r--arch/arm/include/asm/clkdev.h2
-rw-r--r--arch/blackfin/include/asm/clkdev.h2
-rw-r--r--arch/mips/include/asm/clkdev.h2
-rw-r--r--arch/sh/include/asm/clkdev.h2
-rw-r--r--drivers/clk/clk.c185
-rw-r--r--drivers/clk/clk.h16
-rw-r--r--drivers/clk/clkdev.c12
-rw-r--r--drivers/media/platform/omap3isp/isp.c22
-rw-r--r--drivers/media/platform/omap3isp/isp.h1
-rw-r--r--include/linux/clk-private.h5
-rw-r--r--include/linux/clkdev.h5
11 files changed, 235 insertions, 19 deletions
diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h
index 80751c15c300..4e8a4b27d7c7 100644
--- a/arch/arm/include/asm/clkdev.h
+++ b/arch/arm/include/asm/clkdev.h
@@ -14,12 +14,14 @@
14 14
15#include <linux/slab.h> 15#include <linux/slab.h>
16 16
17#ifndef CONFIG_COMMON_CLK
17#ifdef CONFIG_HAVE_MACH_CLKDEV 18#ifdef CONFIG_HAVE_MACH_CLKDEV
18#include <mach/clkdev.h> 19#include <mach/clkdev.h>
19#else 20#else
20#define __clk_get(clk) ({ 1; }) 21#define __clk_get(clk) ({ 1; })
21#define __clk_put(clk) do { } while (0) 22#define __clk_put(clk) do { } while (0)
22#endif 23#endif
24#endif
23 25
24static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) 26static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
25{ 27{
diff --git a/arch/blackfin/include/asm/clkdev.h b/arch/blackfin/include/asm/clkdev.h
index 9053beda8c50..7ac2436856a5 100644
--- a/arch/blackfin/include/asm/clkdev.h
+++ b/arch/blackfin/include/asm/clkdev.h
@@ -8,7 +8,9 @@ static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
8 return kzalloc(size, GFP_KERNEL); 8 return kzalloc(size, GFP_KERNEL);
9} 9}
10 10
11#ifndef CONFIG_COMMON_CLK
11#define __clk_put(clk) 12#define __clk_put(clk)
12#define __clk_get(clk) ({ 1; }) 13#define __clk_get(clk) ({ 1; })
14#endif
13 15
14#endif 16#endif
diff --git a/arch/mips/include/asm/clkdev.h b/arch/mips/include/asm/clkdev.h
index 262475414e5f..1b3ad7b09dc1 100644
--- a/arch/mips/include/asm/clkdev.h
+++ b/arch/mips/include/asm/clkdev.h
@@ -14,8 +14,10 @@
14 14
15#include <linux/slab.h> 15#include <linux/slab.h>
16 16
17#ifndef CONFIG_COMMON_CLK
17#define __clk_get(clk) ({ 1; }) 18#define __clk_get(clk) ({ 1; })
18#define __clk_put(clk) do { } while (0) 19#define __clk_put(clk) do { } while (0)
20#endif
19 21
20static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) 22static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
21{ 23{
diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
index 6ba91868201c..c41901465fb0 100644
--- a/arch/sh/include/asm/clkdev.h
+++ b/arch/sh/include/asm/clkdev.h
@@ -25,7 +25,9 @@ static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
25 return kzalloc(size, GFP_KERNEL); 25 return kzalloc(size, GFP_KERNEL);
26} 26}
27 27
28#ifndef CONFIG_COMMON_CLK
28#define __clk_put(clk) 29#define __clk_put(clk)
29#define __clk_get(clk) ({ 1; }) 30#define __clk_get(clk) ({ 1; })
31#endif
30 32
31#endif /* __CLKDEV_H__ */ 33#endif /* __CLKDEV_H__ */
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index b7f6e99e61eb..e3e03270b95e 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -21,6 +21,8 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/sched.h> 22#include <linux/sched.h>
23 23
24#include "clk.h"
25
24static DEFINE_SPINLOCK(enable_lock); 26static DEFINE_SPINLOCK(enable_lock);
25static DEFINE_MUTEX(prepare_lock); 27static DEFINE_MUTEX(prepare_lock);
26 28
@@ -350,6 +352,21 @@ out:
350 return ret; 352 return ret;
351} 353}
352 354
355 /**
356 * clk_debug_unregister - remove a clk node from the debugfs clk tree
357 * @clk: the clk being removed from the debugfs clk tree
358 *
359 * Dynamically removes a clk and all it's children clk nodes from the
360 * debugfs clk tree if clk->dentry points to debugfs created by
361 * clk_debug_register in __clk_init.
362 *
363 * Caller must hold prepare_lock.
364 */
365static void clk_debug_unregister(struct clk *clk)
366{
367 debugfs_remove_recursive(clk->dentry);
368}
369
353/** 370/**
354 * clk_debug_reparent - reparent clk node in the debugfs clk tree 371 * clk_debug_reparent - reparent clk node in the debugfs clk tree
355 * @clk: the clk being reparented 372 * @clk: the clk being reparented
@@ -440,6 +457,9 @@ static inline int clk_debug_register(struct clk *clk) { return 0; }
440static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent) 457static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent)
441{ 458{
442} 459}
460static inline void clk_debug_unregister(struct clk *clk)
461{
462}
443#endif 463#endif
444 464
445/* caller must hold prepare_lock */ 465/* caller must hold prepare_lock */
@@ -1861,6 +1881,7 @@ int __clk_init(struct device *dev, struct clk *clk)
1861 if (clk->ops->init) 1881 if (clk->ops->init)
1862 clk->ops->init(clk->hw); 1882 clk->ops->init(clk->hw);
1863 1883
1884 kref_init(&clk->ref);
1864out: 1885out:
1865 clk_prepare_unlock(); 1886 clk_prepare_unlock();
1866 1887
@@ -1896,6 +1917,10 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
1896 clk->flags = hw->init->flags; 1917 clk->flags = hw->init->flags;
1897 clk->parent_names = hw->init->parent_names; 1918 clk->parent_names = hw->init->parent_names;
1898 clk->num_parents = hw->init->num_parents; 1919 clk->num_parents = hw->init->num_parents;
1920 if (dev && dev->driver)
1921 clk->owner = dev->driver->owner;
1922 else
1923 clk->owner = NULL;
1899 1924
1900 ret = __clk_init(dev, clk); 1925 ret = __clk_init(dev, clk);
1901 if (ret) 1926 if (ret)
@@ -1916,6 +1941,8 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk)
1916 goto fail_name; 1941 goto fail_name;
1917 } 1942 }
1918 clk->ops = hw->init->ops; 1943 clk->ops = hw->init->ops;
1944 if (dev && dev->driver)
1945 clk->owner = dev->driver->owner;
1919 clk->hw = hw; 1946 clk->hw = hw;
1920 clk->flags = hw->init->flags; 1947 clk->flags = hw->init->flags;
1921 clk->num_parents = hw->init->num_parents; 1948 clk->num_parents = hw->init->num_parents;
@@ -1990,13 +2017,104 @@ fail_out:
1990} 2017}
1991EXPORT_SYMBOL_GPL(clk_register); 2018EXPORT_SYMBOL_GPL(clk_register);
1992 2019
2020/*
2021 * Free memory allocated for a clock.
2022 * Caller must hold prepare_lock.
2023 */
2024static void __clk_release(struct kref *ref)
2025{
2026 struct clk *clk = container_of(ref, struct clk, ref);
2027 int i = clk->num_parents;
2028
2029 kfree(clk->parents);
2030 while (--i >= 0)
2031 kfree(clk->parent_names[i]);
2032
2033 kfree(clk->parent_names);
2034 kfree(clk->name);
2035 kfree(clk);
2036}
2037
2038/*
2039 * Empty clk_ops for unregistered clocks. These are used temporarily
2040 * after clk_unregister() was called on a clock and until last clock
2041 * consumer calls clk_put() and the struct clk object is freed.
2042 */
2043static int clk_nodrv_prepare_enable(struct clk_hw *hw)
2044{
2045 return -ENXIO;
2046}
2047
2048static void clk_nodrv_disable_unprepare(struct clk_hw *hw)
2049{
2050 WARN_ON_ONCE(1);
2051}
2052
2053static int clk_nodrv_set_rate(struct clk_hw *hw, unsigned long rate,
2054 unsigned long parent_rate)
2055{
2056 return -ENXIO;
2057}
2058
2059static int clk_nodrv_set_parent(struct clk_hw *hw, u8 index)
2060{
2061 return -ENXIO;
2062}
2063
2064static const struct clk_ops clk_nodrv_ops = {
2065 .enable = clk_nodrv_prepare_enable,
2066 .disable = clk_nodrv_disable_unprepare,
2067 .prepare = clk_nodrv_prepare_enable,
2068 .unprepare = clk_nodrv_disable_unprepare,
2069 .set_rate = clk_nodrv_set_rate,
2070 .set_parent = clk_nodrv_set_parent,
2071};
2072
1993/** 2073/**
1994 * clk_unregister - unregister a currently registered clock 2074 * clk_unregister - unregister a currently registered clock
1995 * @clk: clock to unregister 2075 * @clk: clock to unregister
1996 *
1997 * Currently unimplemented.
1998 */ 2076 */
1999void clk_unregister(struct clk *clk) {} 2077void clk_unregister(struct clk *clk)
2078{
2079 unsigned long flags;
2080
2081 if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
2082 return;
2083
2084 clk_prepare_lock();
2085
2086 if (clk->ops == &clk_nodrv_ops) {
2087 pr_err("%s: unregistered clock: %s\n", __func__, clk->name);
2088 goto out;
2089 }
2090 /*
2091 * Assign empty clock ops for consumers that might still hold
2092 * a reference to this clock.
2093 */
2094 flags = clk_enable_lock();
2095 clk->ops = &clk_nodrv_ops;
2096 clk_enable_unlock(flags);
2097
2098 if (!hlist_empty(&clk->children)) {
2099 struct clk *child;
2100
2101 /* Reparent all children to the orphan list. */
2102 hlist_for_each_entry(child, &clk->children, child_node)
2103 clk_set_parent(child, NULL);
2104 }
2105
2106 clk_debug_unregister(clk);
2107
2108 hlist_del_init(&clk->child_node);
2109
2110 if (clk->prepare_count)
2111 pr_warn("%s: unregistering prepared clock: %s\n",
2112 __func__, clk->name);
2113
2114 kref_put(&clk->ref, __clk_release);
2115out:
2116 clk_prepare_unlock();
2117}
2000EXPORT_SYMBOL_GPL(clk_unregister); 2118EXPORT_SYMBOL_GPL(clk_unregister);
2001 2119
2002static void devm_clk_release(struct device *dev, void *res) 2120static void devm_clk_release(struct device *dev, void *res)
@@ -2056,6 +2174,31 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
2056} 2174}
2057EXPORT_SYMBOL_GPL(devm_clk_unregister); 2175EXPORT_SYMBOL_GPL(devm_clk_unregister);
2058 2176
2177/*
2178 * clkdev helpers
2179 */
2180int __clk_get(struct clk *clk)
2181{
2182 if (clk && !try_module_get(clk->owner))
2183 return 0;
2184
2185 kref_get(&clk->ref);
2186 return 1;
2187}
2188
2189void __clk_put(struct clk *clk)
2190{
2191 if (WARN_ON_ONCE(IS_ERR(clk)))
2192 return;
2193
2194 clk_prepare_lock();
2195 kref_put(&clk->ref, __clk_release);
2196 clk_prepare_unlock();
2197
2198 if (clk)
2199 module_put(clk->owner);
2200}
2201
2059/*** clk rate change notifiers ***/ 2202/*** clk rate change notifiers ***/
2060 2203
2061/** 2204/**
@@ -2196,7 +2339,18 @@ static const struct of_device_id __clk_of_table_sentinel
2196 __used __section(__clk_of_table_end); 2339 __used __section(__clk_of_table_end);
2197 2340
2198static LIST_HEAD(of_clk_providers); 2341static LIST_HEAD(of_clk_providers);
2199static DEFINE_MUTEX(of_clk_lock); 2342static DEFINE_MUTEX(of_clk_mutex);
2343
2344/* of_clk_provider list locking helpers */
2345void of_clk_lock(void)
2346{
2347 mutex_lock(&of_clk_mutex);
2348}
2349
2350void of_clk_unlock(void)
2351{
2352 mutex_unlock(&of_clk_mutex);
2353}
2200 2354
2201struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, 2355struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
2202 void *data) 2356 void *data)
@@ -2240,9 +2394,9 @@ int of_clk_add_provider(struct device_node *np,
2240 cp->data = data; 2394 cp->data = data;
2241 cp->get = clk_src_get; 2395 cp->get = clk_src_get;
2242 2396
2243 mutex_lock(&of_clk_lock); 2397 mutex_lock(&of_clk_mutex);
2244 list_add(&cp->link, &of_clk_providers); 2398 list_add(&cp->link, &of_clk_providers);
2245 mutex_unlock(&of_clk_lock); 2399 mutex_unlock(&of_clk_mutex);
2246 pr_debug("Added clock from %s\n", np->full_name); 2400 pr_debug("Added clock from %s\n", np->full_name);
2247 2401
2248 return 0; 2402 return 0;
@@ -2257,7 +2411,7 @@ void of_clk_del_provider(struct device_node *np)
2257{ 2411{
2258 struct of_clk_provider *cp; 2412 struct of_clk_provider *cp;
2259 2413
2260 mutex_lock(&of_clk_lock); 2414 mutex_lock(&of_clk_mutex);
2261 list_for_each_entry(cp, &of_clk_providers, link) { 2415 list_for_each_entry(cp, &of_clk_providers, link) {
2262 if (cp->node == np) { 2416 if (cp->node == np) {
2263 list_del(&cp->link); 2417 list_del(&cp->link);
@@ -2266,24 +2420,33 @@ void of_clk_del_provider(struct device_node *np)
2266 break; 2420 break;
2267 } 2421 }
2268 } 2422 }
2269 mutex_unlock(&of_clk_lock); 2423 mutex_unlock(&of_clk_mutex);
2270} 2424}
2271EXPORT_SYMBOL_GPL(of_clk_del_provider); 2425EXPORT_SYMBOL_GPL(of_clk_del_provider);
2272 2426
2273struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) 2427struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
2274{ 2428{
2275 struct of_clk_provider *provider; 2429 struct of_clk_provider *provider;
2276 struct clk *clk = ERR_PTR(-ENOENT); 2430 struct clk *clk = ERR_PTR(-ENOENT);
2277 2431
2278 /* Check if we have such a provider in our array */ 2432 /* Check if we have such a provider in our array */
2279 mutex_lock(&of_clk_lock);
2280 list_for_each_entry(provider, &of_clk_providers, link) { 2433 list_for_each_entry(provider, &of_clk_providers, link) {
2281 if (provider->node == clkspec->np) 2434 if (provider->node == clkspec->np)
2282 clk = provider->get(clkspec, provider->data); 2435 clk = provider->get(clkspec, provider->data);
2283 if (!IS_ERR(clk)) 2436 if (!IS_ERR(clk))
2284 break; 2437 break;
2285 } 2438 }
2286 mutex_unlock(&of_clk_lock); 2439
2440 return clk;
2441}
2442
2443struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
2444{
2445 struct clk *clk;
2446
2447 mutex_lock(&of_clk_mutex);
2448 clk = __of_clk_get_from_provider(clkspec);
2449 mutex_unlock(&of_clk_mutex);
2287 2450
2288 return clk; 2451 return clk;
2289} 2452}
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
new file mode 100644
index 000000000000..795cc9f0dac0
--- /dev/null
+++ b/drivers/clk/clk.h
@@ -0,0 +1,16 @@
1/*
2 * linux/drivers/clk/clk.h
3 *
4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
13struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec);
14void of_clk_lock(void);
15void of_clk_unlock(void);
16#endif
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 442a31363873..48f67218247c 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -21,6 +21,8 @@
21#include <linux/clkdev.h> 21#include <linux/clkdev.h>
22#include <linux/of.h> 22#include <linux/of.h>
23 23
24#include "clk.h"
25
24static LIST_HEAD(clocks); 26static LIST_HEAD(clocks);
25static DEFINE_MUTEX(clocks_mutex); 27static DEFINE_MUTEX(clocks_mutex);
26 28
@@ -39,7 +41,13 @@ struct clk *of_clk_get(struct device_node *np, int index)
39 if (rc) 41 if (rc)
40 return ERR_PTR(rc); 42 return ERR_PTR(rc);
41 43
42 clk = of_clk_get_from_provider(&clkspec); 44 of_clk_lock();
45 clk = __of_clk_get_from_provider(&clkspec);
46
47 if (!IS_ERR(clk) && !__clk_get(clk))
48 clk = ERR_PTR(-ENOENT);
49
50 of_clk_unlock();
43 of_node_put(clkspec.np); 51 of_node_put(clkspec.np);
44 return clk; 52 return clk;
45} 53}
@@ -157,7 +165,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
157 165
158 if (dev) { 166 if (dev) {
159 clk = of_clk_get_by_name(dev->of_node, con_id); 167 clk = of_clk_get_by_name(dev->of_node, con_id);
160 if (!IS_ERR(clk) && __clk_get(clk)) 168 if (!IS_ERR(clk))
161 return clk; 169 return clk;
162 } 170 }
163 171
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 1c3608039663..59106623e71e 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -290,9 +290,11 @@ static int isp_xclk_init(struct isp_device *isp)
290 struct clk_init_data init; 290 struct clk_init_data init;
291 unsigned int i; 291 unsigned int i;
292 292
293 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i)
294 isp->xclks[i].clk = ERR_PTR(-EINVAL);
295
293 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) { 296 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {
294 struct isp_xclk *xclk = &isp->xclks[i]; 297 struct isp_xclk *xclk = &isp->xclks[i];
295 struct clk *clk;
296 298
297 xclk->isp = isp; 299 xclk->isp = isp;
298 xclk->id = i == 0 ? ISP_XCLK_A : ISP_XCLK_B; 300 xclk->id = i == 0 ? ISP_XCLK_A : ISP_XCLK_B;
@@ -305,10 +307,15 @@ static int isp_xclk_init(struct isp_device *isp)
305 init.num_parents = 1; 307 init.num_parents = 1;
306 308
307 xclk->hw.init = &init; 309 xclk->hw.init = &init;
308 310 /*
309 clk = devm_clk_register(isp->dev, &xclk->hw); 311 * The first argument is NULL in order to avoid circular
310 if (IS_ERR(clk)) 312 * reference, as this driver takes reference on the
311 return PTR_ERR(clk); 313 * sensor subdevice modules and the sensors would take
314 * reference on this module through clk_get().
315 */
316 xclk->clk = clk_register(NULL, &xclk->hw);
317 if (IS_ERR(xclk->clk))
318 return PTR_ERR(xclk->clk);
312 319
313 if (pdata->xclks[i].con_id == NULL && 320 if (pdata->xclks[i].con_id == NULL &&
314 pdata->xclks[i].dev_id == NULL) 321 pdata->xclks[i].dev_id == NULL)
@@ -320,7 +327,7 @@ static int isp_xclk_init(struct isp_device *isp)
320 327
321 xclk->lookup->con_id = pdata->xclks[i].con_id; 328 xclk->lookup->con_id = pdata->xclks[i].con_id;
322 xclk->lookup->dev_id = pdata->xclks[i].dev_id; 329 xclk->lookup->dev_id = pdata->xclks[i].dev_id;
323 xclk->lookup->clk = clk; 330 xclk->lookup->clk = xclk->clk;
324 331
325 clkdev_add(xclk->lookup); 332 clkdev_add(xclk->lookup);
326 } 333 }
@@ -335,6 +342,9 @@ static void isp_xclk_cleanup(struct isp_device *isp)
335 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) { 342 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {
336 struct isp_xclk *xclk = &isp->xclks[i]; 343 struct isp_xclk *xclk = &isp->xclks[i];
337 344
345 if (!IS_ERR(xclk->clk))
346 clk_unregister(xclk->clk);
347
338 if (xclk->lookup) 348 if (xclk->lookup)
339 clkdev_drop(xclk->lookup); 349 clkdev_drop(xclk->lookup);
340 } 350 }
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index ce65d3ae1aa7..d1e857e41731 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -135,6 +135,7 @@ struct isp_xclk {
135 struct isp_device *isp; 135 struct isp_device *isp;
136 struct clk_hw hw; 136 struct clk_hw hw;
137 struct clk_lookup *lookup; 137 struct clk_lookup *lookup;
138 struct clk *clk;
138 enum isp_xclk_id id; 139 enum isp_xclk_id id;
139 140
140 spinlock_t lock; /* Protects enabled and divider */ 141 spinlock_t lock; /* Protects enabled and divider */
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 5fb086b06c83..efbf70b9fd84 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -12,6 +12,7 @@
12#define __LINUX_CLK_PRIVATE_H 12#define __LINUX_CLK_PRIVATE_H
13 13
14#include <linux/clk-provider.h> 14#include <linux/clk-provider.h>
15#include <linux/kref.h>
15#include <linux/list.h> 16#include <linux/list.h>
16 17
17/* 18/*
@@ -25,10 +26,13 @@
25 26
26#ifdef CONFIG_COMMON_CLK 27#ifdef CONFIG_COMMON_CLK
27 28
29struct module;
30
28struct clk { 31struct clk {
29 const char *name; 32 const char *name;
30 const struct clk_ops *ops; 33 const struct clk_ops *ops;
31 struct clk_hw *hw; 34 struct clk_hw *hw;
35 struct module *owner;
32 struct clk *parent; 36 struct clk *parent;
33 const char **parent_names; 37 const char **parent_names;
34 struct clk **parents; 38 struct clk **parents;
@@ -48,6 +52,7 @@ struct clk {
48#ifdef CONFIG_DEBUG_FS 52#ifdef CONFIG_DEBUG_FS
49 struct dentry *dentry; 53 struct dentry *dentry;
50#endif 54#endif
55 struct kref ref;
51}; 56};
52 57
53/* 58/*
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index a6a6f603103b..94bad77eeb4a 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -43,4 +43,9 @@ int clk_add_alias(const char *, const char *, char *, struct device *);
43int clk_register_clkdev(struct clk *, const char *, const char *, ...); 43int clk_register_clkdev(struct clk *, const char *, const char *, ...);
44int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); 44int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
45 45
46#ifdef CONFIG_COMMON_CLK
47int __clk_get(struct clk *clk);
48void __clk_put(struct clk *clk);
49#endif
50
46#endif 51#endif