aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/sunxi-ng/ccu_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/sunxi-ng/ccu_common.c')
-rw-r--r--drivers/clk/sunxi-ng/ccu_common.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c
index 51d4bac97ab3..8a47bafd7890 100644
--- a/drivers/clk/sunxi-ng/ccu_common.c
+++ b/drivers/clk/sunxi-ng/ccu_common.c
@@ -25,13 +25,18 @@ static DEFINE_SPINLOCK(ccu_lock);
void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
{
+ void __iomem *addr;
u32 reg;
if (!lock)
return;
- WARN_ON(readl_relaxed_poll_timeout(common->base + common->reg, reg,
- reg & lock, 100, 70000));
+ if (common->features & CCU_FEATURE_LOCK_REG)
+ addr = common->base + common->lock_reg;
+ else
+ addr = common->base + common->reg;
+
+ WARN_ON(readl_relaxed_poll_timeout(addr, reg, reg & lock, 100, 70000));
}
int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
@@ -70,6 +75,11 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
goto err_clk_unreg;
reset = kzalloc(sizeof(*reset), GFP_KERNEL);
+ if (!reset) {
+ ret = -ENOMEM;
+ goto err_alloc_reset;
+ }
+
reset->rcdev.of_node = node;
reset->rcdev.ops = &ccu_reset_ops;
reset->rcdev.owner = THIS_MODULE;
@@ -85,6 +95,16 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
return 0;
err_of_clk_unreg:
+ kfree(reset);
+err_alloc_reset:
+ of_clk_del_provider(node);
err_clk_unreg:
+ while (--i >= 0) {
+ struct clk_hw *hw = desc->hw_clks->hws[i];
+
+ if (!hw)
+ continue;
+ clk_hw_unregister(hw);
+ }
return ret;
}