aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Turquette <mturquette@linaro.org>2013-12-04 15:14:59 -0500
committerMike Turquette <mturquette@linaro.org>2013-12-04 15:14:59 -0500
commit9ffe29d780dd5f9c662f2c32f8dc64435da726bf (patch)
treef583f02351c36f50c43b7e4eb2dc7d2bc6ed2dab
parentcdf64eeeb0d762585e2126f3024458d199c2635d (diff)
parentfcb0ee6a3d331fb23dbb546500021f6e4cac5689 (diff)
Merge branch 'clk/clk-unregister' of git://linuxtv.org/snawrocki/samsung into clk-next-unregister
-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 77fcd069c64a..da7b33e4c5a2 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
@@ -343,6 +345,21 @@ out:
343 return ret; 345 return ret;
344} 346}
345 347
348 /**
349 * clk_debug_unregister - remove a clk node from the debugfs clk tree
350 * @clk: the clk being removed from the debugfs clk tree
351 *
352 * Dynamically removes a clk and all it's children clk nodes from the
353 * debugfs clk tree if clk->dentry points to debugfs created by
354 * clk_debug_register in __clk_init.
355 *
356 * Caller must hold prepare_lock.
357 */
358static void clk_debug_unregister(struct clk *clk)
359{
360 debugfs_remove_recursive(clk->dentry);
361}
362
346/** 363/**
347 * clk_debug_reparent - reparent clk node in the debugfs clk tree 364 * clk_debug_reparent - reparent clk node in the debugfs clk tree
348 * @clk: the clk being reparented 365 * @clk: the clk being reparented
@@ -433,6 +450,9 @@ static inline int clk_debug_register(struct clk *clk) { return 0; }
433static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent) 450static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent)
434{ 451{
435} 452}
453static inline void clk_debug_unregister(struct clk *clk)
454{
455}
436#endif 456#endif
437 457
438/* caller must hold prepare_lock */ 458/* caller must hold prepare_lock */
@@ -1776,6 +1796,7 @@ int __clk_init(struct device *dev, struct clk *clk)
1776 1796
1777 clk_debug_register(clk); 1797 clk_debug_register(clk);
1778 1798
1799 kref_init(&clk->ref);
1779out: 1800out:
1780 clk_prepare_unlock(); 1801 clk_prepare_unlock();
1781 1802
@@ -1811,6 +1832,10 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
1811 clk->flags = hw->init->flags; 1832 clk->flags = hw->init->flags;
1812 clk->parent_names = hw->init->parent_names; 1833 clk->parent_names = hw->init->parent_names;
1813 clk->num_parents = hw->init->num_parents; 1834 clk->num_parents = hw->init->num_parents;
1835 if (dev && dev->driver)
1836 clk->owner = dev->driver->owner;
1837 else
1838 clk->owner = NULL;
1814 1839
1815 ret = __clk_init(dev, clk); 1840 ret = __clk_init(dev, clk);
1816 if (ret) 1841 if (ret)
@@ -1831,6 +1856,8 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk)
1831 goto fail_name; 1856 goto fail_name;
1832 } 1857 }
1833 clk->ops = hw->init->ops; 1858 clk->ops = hw->init->ops;
1859 if (dev && dev->driver)
1860 clk->owner = dev->driver->owner;
1834 clk->hw = hw; 1861 clk->hw = hw;
1835 clk->flags = hw->init->flags; 1862 clk->flags = hw->init->flags;
1836 clk->num_parents = hw->init->num_parents; 1863 clk->num_parents = hw->init->num_parents;
@@ -1905,13 +1932,104 @@ fail_out:
1905} 1932}
1906EXPORT_SYMBOL_GPL(clk_register); 1933EXPORT_SYMBOL_GPL(clk_register);
1907 1934
1935/*
1936 * Free memory allocated for a clock.
1937 * Caller must hold prepare_lock.
1938 */
1939static void __clk_release(struct kref *ref)
1940{
1941 struct clk *clk = container_of(ref, struct clk, ref);
1942 int i = clk->num_parents;
1943
1944 kfree(clk->parents);
1945 while (--i >= 0)
1946 kfree(clk->parent_names[i]);
1947
1948 kfree(clk->parent_names);
1949 kfree(clk->name);
1950 kfree(clk);
1951}
1952
1953/*
1954 * Empty clk_ops for unregistered clocks. These are used temporarily
1955 * after clk_unregister() was called on a clock and until last clock
1956 * consumer calls clk_put() and the struct clk object is freed.
1957 */
1958static int clk_nodrv_prepare_enable(struct clk_hw *hw)
1959{
1960 return -ENXIO;
1961}
1962
1963static void clk_nodrv_disable_unprepare(struct clk_hw *hw)
1964{
1965 WARN_ON_ONCE(1);
1966}
1967
1968static int clk_nodrv_set_rate(struct clk_hw *hw, unsigned long rate,
1969 unsigned long parent_rate)
1970{
1971 return -ENXIO;
1972}
1973
1974static int clk_nodrv_set_parent(struct clk_hw *hw, u8 index)
1975{
1976 return -ENXIO;
1977}
1978
1979static const struct clk_ops clk_nodrv_ops = {
1980 .enable = clk_nodrv_prepare_enable,
1981 .disable = clk_nodrv_disable_unprepare,
1982 .prepare = clk_nodrv_prepare_enable,
1983 .unprepare = clk_nodrv_disable_unprepare,
1984 .set_rate = clk_nodrv_set_rate,
1985 .set_parent = clk_nodrv_set_parent,
1986};
1987
1908/** 1988/**
1909 * clk_unregister - unregister a currently registered clock 1989 * clk_unregister - unregister a currently registered clock
1910 * @clk: clock to unregister 1990 * @clk: clock to unregister
1911 *
1912 * Currently unimplemented.
1913 */ 1991 */
1914void clk_unregister(struct clk *clk) {} 1992void clk_unregister(struct clk *clk)
1993{
1994 unsigned long flags;
1995
1996 if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
1997 return;
1998
1999 clk_prepare_lock();
2000
2001 if (clk->ops == &clk_nodrv_ops) {
2002 pr_err("%s: unregistered clock: %s\n", __func__, clk->name);
2003 goto out;
2004 }
2005 /*
2006 * Assign empty clock ops for consumers that might still hold
2007 * a reference to this clock.
2008 */
2009 flags = clk_enable_lock();
2010 clk->ops = &clk_nodrv_ops;
2011 clk_enable_unlock(flags);
2012
2013 if (!hlist_empty(&clk->children)) {
2014 struct clk *child;
2015
2016 /* Reparent all children to the orphan list. */
2017 hlist_for_each_entry(child, &clk->children, child_node)
2018 clk_set_parent(child, NULL);
2019 }
2020
2021 clk_debug_unregister(clk);
2022
2023 hlist_del_init(&clk->child_node);
2024
2025 if (clk->prepare_count)
2026 pr_warn("%s: unregistering prepared clock: %s\n",
2027 __func__, clk->name);
2028
2029 kref_put(&clk->ref, __clk_release);
2030out:
2031 clk_prepare_unlock();
2032}
1915EXPORT_SYMBOL_GPL(clk_unregister); 2033EXPORT_SYMBOL_GPL(clk_unregister);
1916 2034
1917static void devm_clk_release(struct device *dev, void *res) 2035static void devm_clk_release(struct device *dev, void *res)
@@ -1971,6 +2089,31 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
1971} 2089}
1972EXPORT_SYMBOL_GPL(devm_clk_unregister); 2090EXPORT_SYMBOL_GPL(devm_clk_unregister);
1973 2091
2092/*
2093 * clkdev helpers
2094 */
2095int __clk_get(struct clk *clk)
2096{
2097 if (clk && !try_module_get(clk->owner))
2098 return 0;
2099
2100 kref_get(&clk->ref);
2101 return 1;
2102}
2103
2104void __clk_put(struct clk *clk)
2105{
2106 if (WARN_ON_ONCE(IS_ERR(clk)))
2107 return;
2108
2109 clk_prepare_lock();
2110 kref_put(&clk->ref, __clk_release);
2111 clk_prepare_unlock();
2112
2113 if (clk)
2114 module_put(clk->owner);
2115}
2116
1974/*** clk rate change notifiers ***/ 2117/*** clk rate change notifiers ***/
1975 2118
1976/** 2119/**
@@ -2111,7 +2254,18 @@ static const struct of_device_id __clk_of_table_sentinel
2111 __used __section(__clk_of_table_end); 2254 __used __section(__clk_of_table_end);
2112 2255
2113static LIST_HEAD(of_clk_providers); 2256static LIST_HEAD(of_clk_providers);
2114static DEFINE_MUTEX(of_clk_lock); 2257static DEFINE_MUTEX(of_clk_mutex);
2258
2259/* of_clk_provider list locking helpers */
2260void of_clk_lock(void)
2261{
2262 mutex_lock(&of_clk_mutex);
2263}
2264
2265void of_clk_unlock(void)
2266{
2267 mutex_unlock(&of_clk_mutex);
2268}
2115 2269
2116struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, 2270struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
2117 void *data) 2271 void *data)
@@ -2155,9 +2309,9 @@ int of_clk_add_provider(struct device_node *np,
2155 cp->data = data; 2309 cp->data = data;
2156 cp->get = clk_src_get; 2310 cp->get = clk_src_get;
2157 2311
2158 mutex_lock(&of_clk_lock); 2312 mutex_lock(&of_clk_mutex);
2159 list_add(&cp->link, &of_clk_providers); 2313 list_add(&cp->link, &of_clk_providers);
2160 mutex_unlock(&of_clk_lock); 2314 mutex_unlock(&of_clk_mutex);
2161 pr_debug("Added clock from %s\n", np->full_name); 2315 pr_debug("Added clock from %s\n", np->full_name);
2162 2316
2163 return 0; 2317 return 0;
@@ -2172,7 +2326,7 @@ void of_clk_del_provider(struct device_node *np)
2172{ 2326{
2173 struct of_clk_provider *cp; 2327 struct of_clk_provider *cp;
2174 2328
2175 mutex_lock(&of_clk_lock); 2329 mutex_lock(&of_clk_mutex);
2176 list_for_each_entry(cp, &of_clk_providers, link) { 2330 list_for_each_entry(cp, &of_clk_providers, link) {
2177 if (cp->node == np) { 2331 if (cp->node == np) {
2178 list_del(&cp->link); 2332 list_del(&cp->link);
@@ -2181,24 +2335,33 @@ void of_clk_del_provider(struct device_node *np)
2181 break; 2335 break;
2182 } 2336 }
2183 } 2337 }
2184 mutex_unlock(&of_clk_lock); 2338 mutex_unlock(&of_clk_mutex);
2185} 2339}
2186EXPORT_SYMBOL_GPL(of_clk_del_provider); 2340EXPORT_SYMBOL_GPL(of_clk_del_provider);
2187 2341
2188struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) 2342struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
2189{ 2343{
2190 struct of_clk_provider *provider; 2344 struct of_clk_provider *provider;
2191 struct clk *clk = ERR_PTR(-ENOENT); 2345 struct clk *clk = ERR_PTR(-ENOENT);
2192 2346
2193 /* Check if we have such a provider in our array */ 2347 /* Check if we have such a provider in our array */
2194 mutex_lock(&of_clk_lock);
2195 list_for_each_entry(provider, &of_clk_providers, link) { 2348 list_for_each_entry(provider, &of_clk_providers, link) {
2196 if (provider->node == clkspec->np) 2349 if (provider->node == clkspec->np)
2197 clk = provider->get(clkspec, provider->data); 2350 clk = provider->get(clkspec, provider->data);
2198 if (!IS_ERR(clk)) 2351 if (!IS_ERR(clk))
2199 break; 2352 break;
2200 } 2353 }
2201 mutex_unlock(&of_clk_lock); 2354
2355 return clk;
2356}
2357
2358struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
2359{
2360 struct clk *clk;
2361
2362 mutex_lock(&of_clk_mutex);
2363 clk = __of_clk_get_from_provider(clkspec);
2364 mutex_unlock(&of_clk_mutex);
2202 2365
2203 return clk; 2366 return clk;
2204} 2367}
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 8138c94409f3..72c65e05450b 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;
@@ -47,6 +51,7 @@ struct clk {
47#ifdef CONFIG_COMMON_CLK_DEBUG 51#ifdef CONFIG_COMMON_CLK_DEBUG
48 struct dentry *dentry; 52 struct dentry *dentry;
49#endif 53#endif
54 struct kref ref;
50}; 55};
51 56
52/* 57/*
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