OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | From 5f0bb9d0bc545ef53a83f7bd176fdc0736eed8e5 Mon Sep 17 00:00:00 2001 |
2 | From: Jens Kuske <jenskuske@gmail.com> |
||
3 | Date: Tue, 27 Oct 2015 17:50:24 +0100 |
||
4 | Subject: [PATCH] reset: sunxi: Add Allwinner H3 bus resets |
||
5 | |||
6 | The H3 bus resets have some holes between the registers, so we add |
||
7 | an of_xlate() function to skip them according to the datasheet. |
||
8 | |||
9 | Signed-off-by: Jens Kuske <jenskuske@gmail.com> |
||
10 | --- |
||
11 | .../bindings/reset/allwinner,sunxi-clock-reset.txt | 1 + |
||
12 | drivers/reset/reset-sunxi.c | 30 +++++++++++++++++++--- |
||
13 | 2 files changed, 28 insertions(+), 3 deletions(-) |
||
14 | |||
15 | --- a/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt |
||
16 | +++ b/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt |
||
17 | @@ -8,6 +8,7 @@ Required properties: |
||
18 | - compatible: Should be one of the following: |
||
19 | "allwinner,sun6i-a31-ahb1-reset" |
||
20 | "allwinner,sun6i-a31-clock-reset" |
||
21 | + "allwinner,sun8i-h3-bus-reset" |
||
22 | - reg: should be register base and length as documented in the |
||
23 | datasheet |
||
24 | - #reset-cells: 1, see below |
||
25 | --- a/drivers/reset/reset-sunxi.c |
||
26 | +++ b/drivers/reset/reset-sunxi.c |
||
27 | @@ -75,7 +75,9 @@ static const struct reset_control_ops su |
||
28 | .deassert = sunxi_reset_deassert, |
||
29 | }; |
||
30 | |||
31 | -static int sunxi_reset_init(struct device_node *np) |
||
32 | +static int sunxi_reset_init(struct device_node *np, |
||
33 | + int (*of_xlate)(struct reset_controller_dev *rcdev, |
||
34 | + const struct of_phandle_args *reset_spec)) |
||
35 | { |
||
36 | struct sunxi_reset_data *data; |
||
37 | struct resource res; |
||
38 | @@ -108,6 +110,7 @@ static int sunxi_reset_init(struct devic |
||
39 | data->rcdev.nr_resets = size * 32; |
||
40 | data->rcdev.ops = &sunxi_reset_ops; |
||
41 | data->rcdev.of_node = np; |
||
42 | + data->rcdev.of_xlate = of_xlate; |
||
43 | |||
44 | return reset_controller_register(&data->rcdev); |
||
45 | |||
46 | @@ -116,6 +119,21 @@ err_alloc: |
||
47 | return ret; |
||
48 | }; |
||
49 | |||
50 | +static int sun8i_h3_bus_reset_xlate(struct reset_controller_dev *rcdev, |
||
51 | + const struct of_phandle_args *reset_spec) |
||
52 | +{ |
||
53 | + unsigned int index = reset_spec->args[0]; |
||
54 | + |
||
55 | + if (index < 96) |
||
56 | + return index; |
||
57 | + else if (index < 128) |
||
58 | + return index + 32; |
||
59 | + else if (index < 160) |
||
60 | + return index + 64; |
||
61 | + else |
||
62 | + return -EINVAL; |
||
63 | +} |
||
64 | + |
||
65 | /* |
||
66 | * These are the reset controller we need to initialize early on in |
||
67 | * our system, before we can even think of using a regular device |
||
68 | @@ -123,15 +141,21 @@ err_alloc: |
||
69 | */ |
||
70 | static const struct of_device_id sunxi_early_reset_dt_ids[] __initconst = { |
||
71 | { .compatible = "allwinner,sun6i-a31-ahb1-reset", }, |
||
72 | + { .compatible = "allwinner,sun8i-h3-bus-reset", .data = sun8i_h3_bus_reset_xlate, }, |
||
73 | { /* sentinel */ }, |
||
74 | }; |
||
75 | |||
76 | void __init sun6i_reset_init(void) |
||
77 | { |
||
78 | struct device_node *np; |
||
79 | - |
||
80 | - for_each_matching_node(np, sunxi_early_reset_dt_ids) |
||
81 | - sunxi_reset_init(np); |
||
82 | + const struct of_device_id *match; |
||
83 | + int (*of_xlate)(struct reset_controller_dev *rcdev, |
||
84 | + const struct of_phandle_args *reset_spec); |
||
85 | + |
||
86 | + for_each_matching_node_and_match(np, sunxi_early_reset_dt_ids, &match) { |
||
87 | + of_xlate = match->data; |
||
88 | + sunxi_reset_init(np, of_xlate); |
||
89 | + } |
||
90 | } |
||
91 | |||
92 | /* |