aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-08-24 09:00:10 -0400
committerSylwester Nawrocki <s.nawrocki@samsung.com>2013-12-04 11:19:52 -0500
commitfcb0ee6a3d331fb23dbb546500021f6e4cac5689 (patch)
treeaeb616745828ea298e1a793cfc819e9b8401bc0d
parentac2df527fb407b61f9c812a99035b62a75a77d6d (diff)
clk: Implement clk_unregister
clk_unregister() is currently not implemented and it is required when a clock provider module needs to be unloaded. Normally the clock supplier module is prevented to be unloaded by taking reference on the module in clk_get(). For cases when the clock supplier module deinitializes despite the consumers of its clocks holding a reference on the module, e.g. when the driver is unbound through "unbind" sysfs attribute, there are empty clock ops added. These ops are assigned temporarily to struct clk and used until all consumers release the clock, to avoid invoking callbacks from the module which just got removed. Signed-off-by: Jiada Wang <jiada_wang@mentor.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--drivers/clk/clk.c121
-rw-r--r--include/linux/clk-private.h2
2 files changed, 120 insertions, 3 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index baa2f66a7d19..da7b33e4c5a2 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -345,6 +345,21 @@ out:
345 return ret; 345 return ret;
346} 346}
347 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
348/** 363/**
349 * clk_debug_reparent - reparent clk node in the debugfs clk tree 364 * clk_debug_reparent - reparent clk node in the debugfs clk tree
350 * @clk: the clk being reparented 365 * @clk: the clk being reparented
@@ -435,6 +450,9 @@ static inline int clk_debug_register(struct clk *clk) { return 0; }
435static 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)
436{ 451{
437} 452}
453static inline void clk_debug_unregister(struct clk *clk)
454{
455}
438#endif 456#endif
439 457
440/* caller must hold prepare_lock */ 458/* caller must hold prepare_lock */
@@ -1778,6 +1796,7 @@ int __clk_init(struct device *dev, struct clk *clk)
1778 1796
1779 clk_debug_register(clk); 1797 clk_debug_register(clk);
1780 1798
1799 kref_init(&clk->ref);
1781out: 1800out:
1782 clk_prepare_unlock(); 1801 clk_prepare_unlock();
1783 1802
@@ -1913,13 +1932,104 @@ fail_out:
1913} 1932}
1914EXPORT_SYMBOL_GPL(clk_register); 1933EXPORT_SYMBOL_GPL(clk_register);
1915 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
1916/** 1988/**
1917 * clk_unregister - unregister a currently registered clock 1989 * clk_unregister - unregister a currently registered clock
1918 * @clk: clock to unregister 1990 * @clk: clock to unregister
1919 *
1920 * Currently unimplemented.
1921 */ 1991 */
1922void 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}
1923EXPORT_SYMBOL_GPL(clk_unregister); 2033EXPORT_SYMBOL_GPL(clk_unregister);
1924 2034
1925static void devm_clk_release(struct device *dev, void *res) 2035static void devm_clk_release(struct device *dev, void *res)
@@ -1987,6 +2097,7 @@ int __clk_get(struct clk *clk)
1987 if (clk && !try_module_get(clk->owner)) 2097 if (clk && !try_module_get(clk->owner))
1988 return 0; 2098 return 0;
1989 2099
2100 kref_get(&clk->ref);
1990 return 1; 2101 return 1;
1991} 2102}
1992 2103
@@ -1995,6 +2106,10 @@ void __clk_put(struct clk *clk)
1995 if (WARN_ON_ONCE(IS_ERR(clk))) 2106 if (WARN_ON_ONCE(IS_ERR(clk)))
1996 return; 2107 return;
1997 2108
2109 clk_prepare_lock();
2110 kref_put(&clk->ref, __clk_release);
2111 clk_prepare_unlock();
2112
1998 if (clk) 2113 if (clk)
1999 module_put(clk->owner); 2114 module_put(clk->owner);
2000} 2115}
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 8cb1865e7d9d..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/*
@@ -50,6 +51,7 @@ struct clk {
50#ifdef CONFIG_COMMON_CLK_DEBUG 51#ifdef CONFIG_COMMON_CLK_DEBUG
51 struct dentry *dentry; 52 struct dentry *dentry;
52#endif 53#endif
54 struct kref ref;
53}; 55};
54 56
55/* 57/*