2 * Copyright 2016 Maxime Ripard
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <linux/clk-provider.h>
18 #include <linux/iopoll.h>
19 #include <linux/slab.h>
21 #include "ccu_common.h"
22 #include "ccu_reset.h"
24 static DEFINE_SPINLOCK(ccu_lock
);
26 void ccu_helper_wait_for_lock(struct ccu_common
*common
, u32 lock
)
33 WARN_ON(readl_relaxed_poll_timeout(common
->base
+ common
->reg
, reg
,
34 reg
& lock
, 100, 70000));
37 int sunxi_ccu_probe(struct device_node
*node
, void __iomem
*reg
,
38 const struct sunxi_ccu_desc
*desc
)
40 struct ccu_reset
*reset
;
43 for (i
= 0; i
< desc
->num_ccu_clks
; i
++) {
44 struct ccu_common
*cclk
= desc
->ccu_clks
[i
];
50 cclk
->lock
= &ccu_lock
;
53 for (i
= 0; i
< desc
->hw_clks
->num
; i
++) {
54 struct clk_hw
*hw
= desc
->hw_clks
->hws
[i
];
59 ret
= clk_hw_register(NULL
, hw
);
61 pr_err("Couldn't register clock %s\n",
67 ret
= of_clk_add_hw_provider(node
, of_clk_hw_onecell_get
,
72 reset
= kzalloc(sizeof(*reset
), GFP_KERNEL
);
73 reset
->rcdev
.of_node
= node
;
74 reset
->rcdev
.ops
= &ccu_reset_ops
;
75 reset
->rcdev
.owner
= THIS_MODULE
;
76 reset
->rcdev
.nr_resets
= desc
->num_resets
;
78 reset
->lock
= &ccu_lock
;
79 reset
->reset_map
= desc
->resets
;
81 ret
= reset_controller_register(&reset
->rcdev
);
83 goto err_of_clk_unreg
;