diff options
author | Barry Song <Baohua.Song@csr.com> | 2014-01-09 22:15:42 -0500 |
---|---|---|
committer | Barry Song <Baohua.Song@csr.com> | 2014-03-04 21:33:47 -0500 |
commit | e7eda91f6323bd7dc85598c639f5e4709efc2309 (patch) | |
tree | b94fb7cc2b2e64e66184e813d54acbaea16a53f5 | |
parent | 951ec0909c2ef3b617fe4b03045f396528c8a55f (diff) |
ARM: prima2: move to generic reset controller driver framework
this moves to generic IP module reset framework, and make other drivers
use common device_reset() API.
Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Bin Shi <Bin.Shi@csr.com>
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
-rw-r--r-- | Documentation/devicetree/bindings/reset/sirf,rstc.txt | 42 | ||||
-rw-r--r-- | arch/arm/boot/dts/atlas6.dtsi | 3 | ||||
-rw-r--r-- | arch/arm/boot/dts/marco.dtsi | 3 | ||||
-rw-r--r-- | arch/arm/boot/dts/prima2.dtsi | 3 | ||||
-rw-r--r-- | arch/arm/mach-prima2/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-prima2/rstc.c | 93 |
6 files changed, 108 insertions, 37 deletions
diff --git a/Documentation/devicetree/bindings/reset/sirf,rstc.txt b/Documentation/devicetree/bindings/reset/sirf,rstc.txt new file mode 100644 index 000000000000..0505de742d30 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/sirf,rstc.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | CSR SiRFSoC Reset Controller | ||
2 | ====================================== | ||
3 | |||
4 | Please also refer to reset.txt in this directory for common reset | ||
5 | controller binding usage. | ||
6 | |||
7 | Required properties: | ||
8 | - compatible: Should be "sirf,prima2-rstc" or "sirf,marco-rstc" | ||
9 | - reg: should be register base and length as documented in the | ||
10 | datasheet | ||
11 | - #reset-cells: 1, see below | ||
12 | |||
13 | example: | ||
14 | |||
15 | rstc: reset-controller@88010000 { | ||
16 | compatible = "sirf,prima2-rstc"; | ||
17 | reg = <0x88010000 0x1000>; | ||
18 | #reset-cells = <1>; | ||
19 | }; | ||
20 | |||
21 | Specifying reset lines connected to IP modules | ||
22 | ============================================== | ||
23 | |||
24 | The reset controller(rstc) manages various reset sources. This module provides | ||
25 | reset signals for most blocks in system. Those device nodes should specify the | ||
26 | reset line on the rstc in their resets property, containing a phandle to the | ||
27 | rstc device node and a RESET_INDEX specifying which module to reset, as described | ||
28 | in reset.txt. | ||
29 | |||
30 | For SiRFSoC, RESET_INDEX is just reset_bit defined in SW_RST0 and SW_RST1 registers. | ||
31 | For modules whose rest_bit is in SW_RST0, its RESET_INDEX is 0~31. For modules whose | ||
32 | rest_bit is in SW_RST1, its RESET_INDEX is 32~63. | ||
33 | |||
34 | example: | ||
35 | |||
36 | vpp@90020000 { | ||
37 | compatible = "sirf,prima2-vpp"; | ||
38 | reg = <0x90020000 0x10000>; | ||
39 | interrupts = <31>; | ||
40 | clocks = <&clks 35>; | ||
41 | resets = <&rstc 6>; | ||
42 | }; | ||
diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi index f8674bcc4489..f7f9cafb42f5 100644 --- a/arch/arm/boot/dts/atlas6.dtsi +++ b/arch/arm/boot/dts/atlas6.dtsi | |||
@@ -65,9 +65,10 @@ | |||
65 | #clock-cells = <1>; | 65 | #clock-cells = <1>; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | reset-controller@88010000 { | 68 | rstc: reset-controller@88010000 { |
69 | compatible = "sirf,prima2-rstc"; | 69 | compatible = "sirf,prima2-rstc"; |
70 | reg = <0x88010000 0x1000>; | 70 | reg = <0x88010000 0x1000>; |
71 | #reset-cells = <1>; | ||
71 | }; | 72 | }; |
72 | 73 | ||
73 | rsc-controller@88020000 { | 74 | rsc-controller@88020000 { |
diff --git a/arch/arm/boot/dts/marco.dtsi b/arch/arm/boot/dts/marco.dtsi index 1579c3491ccd..0c9647d28765 100644 --- a/arch/arm/boot/dts/marco.dtsi +++ b/arch/arm/boot/dts/marco.dtsi | |||
@@ -58,9 +58,10 @@ | |||
58 | #size-cells = <1>; | 58 | #size-cells = <1>; |
59 | ranges = <0xc2000000 0xc2000000 0x1000000>; | 59 | ranges = <0xc2000000 0xc2000000 0x1000000>; |
60 | 60 | ||
61 | reset-controller@c2000000 { | 61 | rstc: reset-controller@c2000000 { |
62 | compatible = "sirf,marco-rstc"; | 62 | compatible = "sirf,marco-rstc"; |
63 | reg = <0xc2000000 0x10000>; | 63 | reg = <0xc2000000 0x10000>; |
64 | #reset-cells = <1>; | ||
64 | }; | 65 | }; |
65 | }; | 66 | }; |
66 | 67 | ||
diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi index 0e219932d7cc..0ca0d7fd7a6e 100644 --- a/arch/arm/boot/dts/prima2.dtsi +++ b/arch/arm/boot/dts/prima2.dtsi | |||
@@ -76,9 +76,10 @@ | |||
76 | #clock-cells = <1>; | 76 | #clock-cells = <1>; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | reset-controller@88010000 { | 79 | rstc: reset-controller@88010000 { |
80 | compatible = "sirf,prima2-rstc"; | 80 | compatible = "sirf,prima2-rstc"; |
81 | reg = <0x88010000 0x1000>; | 81 | reg = <0x88010000 0x1000>; |
82 | #reset-cells = <1>; | ||
82 | }; | 83 | }; |
83 | 84 | ||
84 | rsc-controller@88020000 { | 85 | rsc-controller@88020000 { |
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig index 6988b117fc17..f37a1de1a114 100644 --- a/arch/arm/mach-prima2/Kconfig +++ b/arch/arm/mach-prima2/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config ARCH_SIRF | 1 | config ARCH_SIRF |
2 | bool "CSR SiRF" if ARCH_MULTI_V7 | 2 | bool "CSR SiRF" if ARCH_MULTI_V7 |
3 | select ARCH_HAS_RESET_CONTROLLER | ||
3 | select ARCH_REQUIRE_GPIOLIB | 4 | select ARCH_REQUIRE_GPIOLIB |
4 | select GENERIC_CLOCKEVENTS | 5 | select GENERIC_CLOCKEVENTS |
5 | select GENERIC_IRQ_CHIP | 6 | select GENERIC_IRQ_CHIP |
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c index ccb53391147a..a59976743332 100644 --- a/arch/arm/mach-prima2/rstc.c +++ b/arch/arm/mach-prima2/rstc.c | |||
@@ -13,57 +13,36 @@ | |||
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
16 | #include <linux/platform_device.h> | ||
16 | #include <linux/reboot.h> | 17 | #include <linux/reboot.h> |
18 | #include <linux/reset-controller.h> | ||
19 | |||
20 | #define SIRFSOC_RSTBIT_NUM 64 | ||
17 | 21 | ||
18 | void __iomem *sirfsoc_rstc_base; | 22 | void __iomem *sirfsoc_rstc_base; |
19 | static DEFINE_MUTEX(rstc_lock); | 23 | static DEFINE_MUTEX(rstc_lock); |
20 | 24 | ||
21 | static struct of_device_id rstc_ids[] = { | 25 | static int sirfsoc_reset_module(struct reset_controller_dev *rcdev, |
22 | { .compatible = "sirf,prima2-rstc" }, | 26 | unsigned long sw_reset_idx) |
23 | { .compatible = "sirf,marco-rstc" }, | ||
24 | {}, | ||
25 | }; | ||
26 | |||
27 | static int __init sirfsoc_of_rstc_init(void) | ||
28 | { | ||
29 | struct device_node *np; | ||
30 | |||
31 | np = of_find_matching_node(NULL, rstc_ids); | ||
32 | if (!np) { | ||
33 | pr_err("unable to find compatible sirf rstc node in dtb\n"); | ||
34 | return -ENOENT; | ||
35 | } | ||
36 | |||
37 | sirfsoc_rstc_base = of_iomap(np, 0); | ||
38 | if (!sirfsoc_rstc_base) | ||
39 | panic("unable to map rstc cpu registers\n"); | ||
40 | |||
41 | of_node_put(np); | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | early_initcall(sirfsoc_of_rstc_init); | ||
46 | |||
47 | int sirfsoc_reset_device(struct device *dev) | ||
48 | { | 27 | { |
49 | u32 reset_bit; | 28 | u32 reset_bit = sw_reset_idx; |
50 | 29 | ||
51 | if (of_property_read_u32(dev->of_node, "reset-bit", &reset_bit)) | 30 | if (reset_bit >= SIRFSOC_RSTBIT_NUM) |
52 | return -EINVAL; | 31 | return -EINVAL; |
53 | 32 | ||
54 | mutex_lock(&rstc_lock); | 33 | mutex_lock(&rstc_lock); |
55 | 34 | ||
56 | if (of_device_is_compatible(dev->of_node, "sirf,prima2-rstc")) { | 35 | if (of_device_is_compatible(rcdev->of_node, "sirf,prima2-rstc")) { |
57 | /* | 36 | /* |
58 | * Writing 1 to this bit resets corresponding block. Writing 0 to this | 37 | * Writing 1 to this bit resets corresponding block. Writing 0 to this |
59 | * bit de-asserts reset signal of the corresponding block. | 38 | * bit de-asserts reset signal of the corresponding block. |
60 | * datasheet doesn't require explicit delay between the set and clear | 39 | * datasheet doesn't require explicit delay between the set and clear |
61 | * of reset bit. it could be shorter if tests pass. | 40 | * of reset bit. it could be shorter if tests pass. |
62 | */ | 41 | */ |
63 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit, | 42 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | (1 << reset_bit), |
64 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | 43 | sirfsoc_rstc_base + (reset_bit / 32) * 4); |
65 | msleep(10); | 44 | msleep(10); |
66 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit, | 45 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~(1 << reset_bit), |
67 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | 46 | sirfsoc_rstc_base + (reset_bit / 32) * 4); |
68 | } else { | 47 | } else { |
69 | /* | 48 | /* |
@@ -73,9 +52,9 @@ int sirfsoc_reset_device(struct device *dev) | |||
73 | * datasheet doesn't require explicit delay between the set and clear | 52 | * datasheet doesn't require explicit delay between the set and clear |
74 | * of reset bit. it could be shorter if tests pass. | 53 | * of reset bit. it could be shorter if tests pass. |
75 | */ | 54 | */ |
76 | writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8); | 55 | writel(1 << reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8); |
77 | msleep(10); | 56 | msleep(10); |
78 | writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4); | 57 | writel(1 << reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4); |
79 | } | 58 | } |
80 | 59 | ||
81 | mutex_unlock(&rstc_lock); | 60 | mutex_unlock(&rstc_lock); |
@@ -83,6 +62,52 @@ int sirfsoc_reset_device(struct device *dev) | |||
83 | return 0; | 62 | return 0; |
84 | } | 63 | } |
85 | 64 | ||
65 | static struct reset_control_ops sirfsoc_rstc_ops = { | ||
66 | .reset = sirfsoc_reset_module, | ||
67 | }; | ||
68 | |||
69 | static struct reset_controller_dev sirfsoc_reset_controller = { | ||
70 | .ops = &sirfsoc_rstc_ops, | ||
71 | .nr_resets = SIRFSOC_RSTBIT_NUM, | ||
72 | }; | ||
73 | |||
74 | static int sirfsoc_rstc_probe(struct platform_device *pdev) | ||
75 | { | ||
76 | struct device_node *np = pdev->dev.of_node; | ||
77 | sirfsoc_rstc_base = of_iomap(np, 0); | ||
78 | if (!sirfsoc_rstc_base) { | ||
79 | dev_err(&pdev->dev, "unable to map rstc cpu registers\n"); | ||
80 | return -ENOMEM; | ||
81 | } | ||
82 | |||
83 | sirfsoc_reset_controller.of_node = np; | ||
84 | |||
85 | reset_controller_register(&sirfsoc_reset_controller); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static const struct of_device_id rstc_ids[] = { | ||
91 | { .compatible = "sirf,prima2-rstc" }, | ||
92 | { .compatible = "sirf,marco-rstc" }, | ||
93 | {}, | ||
94 | }; | ||
95 | |||
96 | static struct platform_driver sirfsoc_rstc_driver = { | ||
97 | .probe = sirfsoc_rstc_probe, | ||
98 | .driver = { | ||
99 | .name = "sirfsoc_rstc", | ||
100 | .owner = THIS_MODULE, | ||
101 | .of_match_table = rstc_ids, | ||
102 | }, | ||
103 | }; | ||
104 | |||
105 | static int __init sirfsoc_rstc_init(void) | ||
106 | { | ||
107 | return platform_driver_register(&sirfsoc_rstc_driver); | ||
108 | } | ||
109 | subsys_initcall(sirfsoc_rstc_init); | ||
110 | |||
86 | #define SIRFSOC_SYS_RST_BIT BIT(31) | 111 | #define SIRFSOC_SYS_RST_BIT BIT(31) |
87 | 112 | ||
88 | void sirfsoc_restart(enum reboot_mode mode, const char *cmd) | 113 | void sirfsoc_restart(enum reboot_mode mode, const char *cmd) |