}
}
-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;
- int ret;
if (!clk)
- return -EINVAL;
+ return;
spin_lock_irqsave(&clock_lock, flags);
- ret = __clk_enable(clk);
+ __clk_disable(clk);
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;
+ int ret;
if (!clk)
- return;
+ return -EINVAL;
spin_lock_irqsave(&clock_lock, flags);
- __clk_disable(clk);
+ ret = __clk_enable(clk);
spin_unlock_irqrestore(&clock_lock, flags);
+
+ return ret;
}
-EXPORT_SYMBOL_GPL(clk_disable);
+EXPORT_SYMBOL_GPL(clk_enable);
static LIST_HEAD(root_clks);
return 0;
}
-static void sh7722_siu_enable(struct clk *clk)
+static int sh7722_siu_enable(struct clk *clk)
{
- sh7722_siu_start_stop(clk, 1);
+ return sh7722_siu_start_stop(clk, 1);
}
static void sh7722_siu_disable(struct clk *clk)
#endif /* CONFIG_CPU_SUBTYPE_SH7343 */
-static void sh7722_video_enable(struct clk *clk)
+static int sh7722_video_enable(struct clk *clk)
{
unsigned long r;
r = ctrl_inl(VCLKCR);
ctrl_outl( r & ~(1<<8), VCLKCR);
+ return 0;
}
static void sh7722_video_disable(struct clk *clk)
return 0;
}
-static void sh7722_mstpcr_enable(struct clk *clk)
+static int sh7722_mstpcr_enable(struct clk *clk)
{
- sh7722_mstpcr_start_stop(clk, 1);
+ return sh7722_mstpcr_start_stop(clk, 1);
}
static void sh7722_mstpcr_disable(struct clk *clk)