aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/sunxi
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2016-02-16 05:46:07 -0500
committerMaxime Ripard <maxime.ripard@free-electrons.com>2016-02-21 22:44:38 -0500
commitb26803ebfba8d81e2e8fb392c1248df2ebd1ba83 (patch)
tree426d3015823bb16f790aa6e94fc08a0914480de2 /drivers/clk/sunxi
parent72360b91164aa35753942e5310ae1e1d16e28611 (diff)
clk: sunxi: improve divider_clk error handling and reporting
We now report a failing ioremap, failing output names parsing, failures in table registration and in the final step. Also there was a bug where clk_register_divider_table() would return an ERR_PTR value instead of NULL, which we were checking for. We now implement proper rollback in case of an error. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Diffstat (limited to 'drivers/clk/sunxi')
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 775e13776f84..4bd09179a401 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -805,17 +805,47 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
805 void __iomem *reg; 805 void __iomem *reg;
806 806
807 reg = of_iomap(node, 0); 807 reg = of_iomap(node, 0);
808 if (!reg) {
809 pr_err("Could not map registers for mux-clk: %s\n",
810 of_node_full_name(node));
811 return;
812 }
808 813
809 clk_parent = of_clk_get_parent_name(node, 0); 814 clk_parent = of_clk_get_parent_name(node, 0);
810 815
811 of_property_read_string(node, "clock-output-names", &clk_name); 816 if (of_property_read_string(node, "clock-output-names", &clk_name)) {
817 pr_err("%s: could not read clock-output-names from \"%s\"\n",
818 __func__, of_node_full_name(node));
819 goto out_unmap;
820 }
812 821
813 clk = clk_register_divider_table(NULL, clk_name, clk_parent, 0, 822 clk = clk_register_divider_table(NULL, clk_name, clk_parent, 0,
814 reg, data->shift, data->width, 823 reg, data->shift, data->width,
815 data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, 824 data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
816 data->table, &clk_lock); 825 data->table, &clk_lock);
817 if (clk) 826 if (IS_ERR(clk)) {
818 of_clk_add_provider(node, of_clk_src_simple_get, clk); 827 pr_err("%s: failed to register divider clock %s: %ld\n",
828 __func__, clk_name, PTR_ERR(clk));
829 goto out_unmap;
830 }
831
832 if (of_clk_add_provider(node, of_clk_src_simple_get, clk)) {
833 pr_err("%s: failed to add clock provider for %s\n",
834 __func__, clk_name);
835 goto out_unregister;
836 }
837
838 if (clk_register_clkdev(clk, clk_name, NULL)) {
839 of_clk_del_provider(node);
840 goto out_unregister;
841 }
842
843 return;
844out_unregister:
845 clk_unregister_divider(clk);
846
847out_unmap:
848 iounmap(reg);
819} 849}
820 850
821static void __init sun4i_ahb_clk_setup(struct device_node *node) 851static void __init sun4i_ahb_clk_setup(struct device_node *node)