|
@@ -93,57 +93,78 @@ void propagate_rate(struct clk *tclk)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static int __clk_enable(struct clk *clk)
|
|
|
|
|
|
+static void __clk_disable(struct clk *clk)
|
|
{
|
|
{
|
|
- if (clk->usecount++ == 0) {
|
|
|
|
- if (clk->parent)
|
|
|
|
- __clk_enable(clk->parent);
|
|
|
|
-
|
|
|
|
- if (clk->ops && clk->ops->enable)
|
|
|
|
- clk->ops->enable(clk);
|
|
|
|
|
|
+ if (clk->usecount == 0) {
|
|
|
|
+ printk(KERN_ERR "Trying disable clock %s with 0 usecount\n",
|
|
|
|
+ clk->name);
|
|
|
|
+ WARN_ON(1);
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ if (!(--clk->usecount)) {
|
|
|
|
+ if (likely(clk->ops && clk->ops->disable))
|
|
|
|
+ clk->ops->disable(clk);
|
|
|
|
+ if (likely(clk->parent))
|
|
|
|
+ __clk_disable(clk->parent);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-int clk_enable(struct clk *clk)
|
|
|
|
|
|
+void clk_disable(struct clk *clk)
|
|
{
|
|
{
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
- int ret;
|
|
|
|
|
|
|
|
if (!clk)
|
|
if (!clk)
|
|
- return -EINVAL;
|
|
|
|
|
|
+ return;
|
|
|
|
|
|
spin_lock_irqsave(&clock_lock, flags);
|
|
spin_lock_irqsave(&clock_lock, flags);
|
|
- ret = __clk_enable(clk);
|
|
|
|
|
|
+ __clk_disable(clk);
|
|
spin_unlock_irqrestore(&clock_lock, flags);
|
|
spin_unlock_irqrestore(&clock_lock, flags);
|
|
-
|
|
|
|
- return ret;
|
|
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL_GPL(clk_enable);
|
|
|
|
|
|
+EXPORT_SYMBOL_GPL(clk_disable);
|
|
|
|
|
|
-static void __clk_disable(struct clk *clk)
|
|
|
|
|
|
+static int __clk_enable(struct clk *clk)
|
|
{
|
|
{
|
|
- if (clk->usecount > 0 && !(--clk->usecount)) {
|
|
|
|
- if (likely(clk->ops && clk->ops->disable))
|
|
|
|
- clk->ops->disable(clk);
|
|
|
|
- if (likely(clk->parent))
|
|
|
|
- __clk_disable(clk->parent);
|
|
|
|
|
|
+ int ret = 0;
|
|
|
|
+
|
|
|
|
+ if (clk->usecount++ == 0) {
|
|
|
|
+ if (clk->parent) {
|
|
|
|
+ ret = __clk_enable(clk->parent);
|
|
|
|
+ if (unlikely(ret))
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (clk->ops && clk->ops->enable) {
|
|
|
|
+ ret = clk->ops->enable(clk);
|
|
|
|
+ if (ret) {
|
|
|
|
+ if (clk->parent)
|
|
|
|
+ __clk_disable(clk->parent);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+err:
|
|
|
|
+ clk->usecount--;
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-void clk_disable(struct clk *clk)
|
|
|
|
|
|
+int clk_enable(struct clk *clk)
|
|
{
|
|
{
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
+ int ret;
|
|
|
|
|
|
if (!clk)
|
|
if (!clk)
|
|
- return;
|
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
spin_lock_irqsave(&clock_lock, flags);
|
|
spin_lock_irqsave(&clock_lock, flags);
|
|
- __clk_disable(clk);
|
|
|
|
|
|
+ ret = __clk_enable(clk);
|
|
spin_unlock_irqrestore(&clock_lock, flags);
|
|
spin_unlock_irqrestore(&clock_lock, flags);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL_GPL(clk_disable);
|
|
|
|
|
|
+EXPORT_SYMBOL_GPL(clk_enable);
|
|
|
|
|
|
static LIST_HEAD(root_clks);
|
|
static LIST_HEAD(root_clks);
|
|
|
|
|