Commit | Line | Data |
---|---|---|
02c981c0 BD |
1 | /* |
2 | * reset controller for CSR SiRFprimaII | |
3 | * | |
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | |
5 | * | |
6 | * Licensed under GPLv2 or later. | |
7 | */ | |
8 | ||
9 | #include <linux/kernel.h> | |
10 | #include <linux/mutex.h> | |
11 | #include <linux/io.h> | |
12 | #include <linux/delay.h> | |
13 | #include <linux/device.h> | |
14 | #include <linux/of.h> | |
15 | #include <linux/of_address.h> | |
7b6d864b | 16 | #include <linux/reboot.h> |
02c981c0 BD |
17 | |
18 | void __iomem *sirfsoc_rstc_base; | |
19 | static DEFINE_MUTEX(rstc_lock); | |
20 | ||
21 | static struct of_device_id rstc_ids[] = { | |
22 | { .compatible = "sirf,prima2-rstc" }, | |
0ecb40ca | 23 | { .compatible = "sirf,marco-rstc" }, |
6a53747b | 24 | {}, |
02c981c0 BD |
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); | |
7e5955db HZ |
32 | if (!np) { |
33 | pr_err("unable to find compatible sirf rstc node in dtb\n"); | |
34 | return -ENOENT; | |
35 | } | |
02c981c0 BD |
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 | { | |
0ecb40ca | 49 | u32 reset_bit; |
02c981c0 | 50 | |
0ecb40ca BS |
51 | if (of_property_read_u32(dev->of_node, "reset-bit", &reset_bit)) |
52 | return -EINVAL; | |
02c981c0 BD |
53 | |
54 | mutex_lock(&rstc_lock); | |
55 | ||
0ecb40ca BS |
56 | if (of_device_is_compatible(dev->of_node, "sirf,prima2-rstc")) { |
57 | /* | |
58 | * Writing 1 to this bit resets corresponding block. Writing 0 to this | |
59 | * bit de-asserts reset signal of the corresponding block. | |
60 | * datasheet doesn't require explicit delay between the set and clear | |
61 | * of reset bit. it could be shorter if tests pass. | |
62 | */ | |
63 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit, | |
64 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | |
65 | msleep(10); | |
66 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit, | |
67 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | |
68 | } else { | |
69 | /* | |
70 | * For MARCO and POLO | |
71 | * Writing 1 to SET register resets corresponding block. Writing 1 to CLEAR | |
72 | * register de-asserts reset signal of the corresponding block. | |
73 | * datasheet doesn't require explicit delay between the set and clear | |
74 | * of reset bit. it could be shorter if tests pass. | |
75 | */ | |
76 | writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8); | |
77 | msleep(10); | |
78 | writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4); | |
79 | } | |
02c981c0 BD |
80 | |
81 | mutex_unlock(&rstc_lock); | |
82 | ||
83 | return 0; | |
84 | } | |
125c4033 RK |
85 | |
86 | #define SIRFSOC_SYS_RST_BIT BIT(31) | |
87 | ||
7b6d864b | 88 | void sirfsoc_restart(enum reboot_mode mode, const char *cmd) |
125c4033 RK |
89 | { |
90 | writel(SIRFSOC_SYS_RST_BIT, sirfsoc_rstc_base); | |
91 | } |