int clk_set_parent(struct clk *clk, struct clk *parent) { unsigned long flags; struct clk *old_parent; if (!clk || !parent) return -EINVAL; if (!clk_is_primary(parent) || !clk_is_bypassable(clk)) return -EINVAL; /* if more than one user, parent is not allowed */ if (clk->use_cnt > 1) return -EBUSY; if (clk->parent == parent) return 0; spin_lock_irqsave(&clk_lock, flags); old_parent = clk->parent; clk->parent = parent; if (clk_is_using_xtal(parent)) clk->mode |= CLK_MODE_XTAL; else clk->mode &= (~CLK_MODE_XTAL); /* if clock is active */ if (clk->use_cnt != 0) { clk->use_cnt--; /* enable clock with the new parent */ __clk_enable(clk); /* disable the old parent */ __clk_disable(old_parent); } spin_unlock_irqrestore(&clk_lock, flags); return 0; }
int clk_set_parent(struct clk *clk, struct clk *parent) { unsigned long flags; struct clk *old_parent; if (!clk || !parent) return -EINVAL; if (!clk_is_primary(parent) || !clk_is_bypassable(clk)) return -EINVAL; if (clk->use_cnt > 1) return -EBUSY; if (clk->parent == parent) return 0; spin_lock_irqsave(&clk_lock, flags); old_parent = clk->parent; clk->parent = parent; if (clk_is_using_xtal(parent)) clk->mode |= CLK_MODE_XTAL; else clk->mode &= (~CLK_MODE_XTAL); if (clk->use_cnt != 0) { clk->use_cnt--; __clk_enable(clk); __clk_disable(old_parent); } spin_unlock_irqrestore(&clk_lock, flags); return 0; }