@@ -543,7 +543,8 @@ static int clk_disable_unused(void)
}
late_initcall_sync(clk_disable_unused);
-struct clk *__clk_create_clk(struct clk_core *clk_core)
+struct clk *__clk_create_clk(struct clk_core *clk_core, const char *dev,
+ const char *con)
{
struct clk *clk;
@@ -556,6 +557,8 @@ struct clk *__clk_create_clk(struct clk_core *clk_core)
return ERR_PTR(-ENOMEM);
clk->core = clk_core;
+ clk->dev_id = dev;
+ clk->con_id = con;
return clk;
}
@@ -980,10 +983,25 @@ EXPORT_SYMBOL_GPL(clk_provider_disable);
*/
void clk_disable(struct clk *clk_user)
{
+ struct clk_core *clk;
+ unsigned long flags;
+
if (IS_ERR_OR_NULL(clk_user))
return;
- clk_provider_disable(clk_to_clk_core(clk_user));
+ clk = clk_to_clk_core(clk_user);
+
+ flags = clk_enable_lock();
+ if (!WARN(clk_user->enable_count == 0,
+ "incorrect disable clk dev %s con %s last disabler %pF\n",
+ clk_user->dev_id, clk_user->con_id, clk_user->last_disable)) {
+
+ clk_user->last_disable = __builtin_return_address(0);
+ clk_user->enable_count--;
+
+ __clk_disable(clk);
+ }
+ clk_enable_unlock(flags);
}
EXPORT_SYMBOL_GPL(clk_disable);
@@ -1044,10 +1062,22 @@ EXPORT_SYMBOL_GPL(clk_provider_enable);
*/
int clk_enable(struct clk *clk_user)
{
+ struct clk_core *clk;
+ unsigned long flags;
+ int ret;
+
if (!clk_user)
return 0;
- return clk_provider_enable(clk_to_clk_core(clk_user));
+ clk = clk_to_clk_core(clk_user);
+
+ flags = clk_enable_lock();
+ ret = __clk_enable(clk);
+ if (!ret)
+ clk_user->enable_count++;
+ clk_enable_unlock(flags);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(clk_enable);
@@ -1745,7 +1775,7 @@ struct clk *clk_get_parent(struct clk *clk_user)
if (IS_ERR(parent))
return (void *)parent;
- parent_user = __clk_create_clk(parent);
+ parent_user = __clk_create_clk(parent, clk_user->dev_id, clk_user->con_id);
if (IS_ERR(parent_user))
__clk_put(parent);
@@ -19,5 +19,6 @@ void of_clk_unlock(void);
#endif
#if defined(CONFIG_COMMON_CLK)
-struct clk *__clk_create_clk(struct clk_core *clk_core);
+struct clk *__clk_create_clk(struct clk_core *clk_core, const char *dev,
+ const char *con);
#endif
@@ -36,7 +36,7 @@ static DEFINE_MUTEX(clocks_mutex);
typedef struct clk_core clkdev_ret_t;
#else
typedef struct clk clkdev_ret_t;
-#define __clk_create_clk(clk) clk
+#define __clk_create_clk(clk, dev_id, con_id) clk
#define clk_to_clk_core(clk) clk
#endif
@@ -96,7 +96,7 @@ struct clk *of_clk_get(struct device_node *np, int index)
if (IS_ERR(clk))
return (void *)clk;
- clk_user = __clk_create_clk(clk);
+ clk_user = __clk_create_clk(clk, np->full_name, NULL);
if (IS_ERR(clk_user))
__clk_put(clk);
@@ -160,7 +160,7 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
if (IS_ERR(clk))
return (void *)clk;
- clk_user = __clk_create_clk(clk);
+ clk_user = __clk_create_clk(clk, np->full_name, NULL);
if (IS_ERR(clk_user))
__clk_put(clk);
@@ -238,7 +238,7 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id)
if (IS_ERR(clk))
return (void *)clk;
- clk_user = __clk_create_clk(clk);
+ clk_user = __clk_create_clk(clk, dev_id, con_id);
if (IS_ERR(clk_user))
__clk_put(clk);
@@ -265,6 +265,7 @@ EXPORT_SYMBOL(clk_provider_get);
struct clk *clk_get(struct device *dev, const char *con_id)
{
+ const char *dev_id = dev ? dev_name(dev) : NULL;
clkdev_ret_t *clk;
struct clk *clk_user;
@@ -272,7 +273,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
if (IS_ERR(clk))
return (void *)clk;
- clk_user = __clk_create_clk(clk);
+ clk_user = __clk_create_clk(clk, dev_id, con_id);
if (IS_ERR(clk_user))
__clk_put(clk);
@@ -57,6 +57,11 @@ struct clk_core {
struct clk {
struct clk_core *core;
+ const char *dev_id;
+ const char *con_id;
+
+ unsigned int enable_count;
+ void *last_disable;
};
/*