Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
7b5bb891 YS |
2 | /* |
3 | * H8/300 divide clock driver | |
4 | * | |
5 | * Copyright 2015 Yoshinori Sato <ysato@users.sourceforge.jp> | |
6 | */ | |
7 | ||
7b5bb891 YS |
8 | #include <linux/clk-provider.h> |
9 | #include <linux/err.h> | |
10 | #include <linux/of.h> | |
11 | #include <linux/of_address.h> | |
12 | ||
13 | static DEFINE_SPINLOCK(clklock); | |
14 | ||
15 | static void __init h8300_div_clk_setup(struct device_node *node) | |
16 | { | |
ebf3f9a9 | 17 | unsigned int num_parents; |
8b2bdc76 | 18 | struct clk_hw *hw; |
7b5bb891 YS |
19 | const char *clk_name = node->name; |
20 | const char *parent_name; | |
21 | void __iomem *divcr = NULL; | |
22 | int width; | |
aca25180 | 23 | int offset; |
7b5bb891 YS |
24 | |
25 | num_parents = of_clk_get_parent_count(node); | |
ebf3f9a9 | 26 | if (!num_parents) { |
7b5bb891 YS |
27 | pr_err("%s: no parent found", clk_name); |
28 | return; | |
29 | } | |
30 | ||
31 | divcr = of_iomap(node, 0); | |
32 | if (divcr == NULL) { | |
33 | pr_err("%s: failed to map divide register", clk_name); | |
34 | goto error; | |
35 | } | |
aca25180 YS |
36 | offset = (unsigned long)divcr & 3; |
37 | offset = (3 - offset) * 8; | |
d3622b58 | 38 | divcr = (void __iomem *)((unsigned long)divcr & ~3); |
7b5bb891 YS |
39 | |
40 | parent_name = of_clk_get_parent_name(node, 0); | |
41 | of_property_read_u32(node, "renesas,width", &width); | |
8b2bdc76 | 42 | hw = clk_hw_register_divider(NULL, clk_name, parent_name, |
aca25180 | 43 | CLK_SET_RATE_GATE, divcr, offset, width, |
7b5bb891 | 44 | CLK_DIVIDER_POWER_OF_TWO, &clklock); |
8b2bdc76 SB |
45 | if (!IS_ERR(hw)) { |
46 | of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); | |
7b5bb891 YS |
47 | return; |
48 | } | |
49 | pr_err("%s: failed to register %s div clock (%ld)\n", | |
8b2bdc76 | 50 | __func__, clk_name, PTR_ERR(hw)); |
7b5bb891 YS |
51 | error: |
52 | if (divcr) | |
53 | iounmap(divcr); | |
54 | } | |
55 | ||
56 | CLK_OF_DECLARE(h8300_div_clk, "renesas,h8300-div-clock", h8300_div_clk_setup); |