diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2013-05-22 10:15:13 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-06-17 07:54:35 -0400 |
commit | cf0ce095c932becf48ed794ecdfad925e931dc9c (patch) | |
tree | 107d791b310c669c79d44d084323a9817f521eda | |
parent | be2885a569f43fa6c44e2a5e1795583ae9941c27 (diff) |
ARM: u300: add syscon node
This adds a device tree node for the U300 system controller
and remaps this dynamically instead of using hard-coded
virtual addresses. The board power set-up code is altered
to fetch a reference to the syscon using ampersand <&syscon>
notation. This way of passing a pointer to the syscon will
also be used by the clocks.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | Documentation/devicetree/bindings/arm/ste-u300.txt | 30 | ||||
-rw-r--r-- | arch/arm/boot/dts/ste-u300.dts | 6 | ||||
-rw-r--r-- | arch/arm/mach-u300/core.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-u300/regulator.c | 21 |
4 files changed, 69 insertions, 10 deletions
diff --git a/Documentation/devicetree/bindings/arm/ste-u300.txt b/Documentation/devicetree/bindings/arm/ste-u300.txt index cd9001a667bc..69b5ab0b5f4b 100644 --- a/Documentation/devicetree/bindings/arm/ste-u300.txt +++ b/Documentation/devicetree/bindings/arm/ste-u300.txt | |||
@@ -8,15 +8,39 @@ Required root node property: | |||
8 | 8 | ||
9 | compatible="stericsson,u300"; | 9 | compatible="stericsson,u300"; |
10 | 10 | ||
11 | Required node: syscon | ||
12 | This contains the system controller. | ||
13 | - compatible: must be "stericsson,u300-syscon". | ||
14 | - reg: the base address and size of the system controller. | ||
15 | |||
11 | Boards with the U300 SoC include: | 16 | Boards with the U300 SoC include: |
12 | 17 | ||
13 | S365 "Small Board U365": | 18 | S365 "Small Board U365": |
14 | 19 | ||
15 | Required node: s365 | 20 | Required node: s365 |
21 | This contains the board-specific information. | ||
22 | - compatible: must be "stericsson,s365". | ||
23 | - vana15-supply: the regulator supplying the 1.5V to drive the | ||
24 | board. | ||
25 | - syscon: a pointer to the syscon node so we can acccess the | ||
26 | syscon registers to set the board as self-powered. | ||
16 | 27 | ||
17 | Example: | 28 | Example: |
18 | 29 | ||
19 | s365 { | 30 | / { |
20 | compatible = "stericsson,s365"; | 31 | model = "ST-Ericsson U300"; |
21 | vana15-supply = <&ab3100_ldo_d_reg>; | 32 | compatible = "stericsson,u300"; |
33 | #address-cells = <1>; | ||
34 | #size-cells = <1>; | ||
35 | |||
36 | s365 { | ||
37 | compatible = "stericsson,s365"; | ||
38 | vana15-supply = <&ab3100_ldo_d_reg>; | ||
39 | syscon = <&syscon>; | ||
40 | }; | ||
41 | |||
42 | syscon: syscon@c0011000 { | ||
43 | compatible = "stericsson,u300-syscon"; | ||
44 | reg = <0xc0011000 0x1000>; | ||
45 | }; | ||
22 | }; | 46 | }; |
diff --git a/arch/arm/boot/dts/ste-u300.dts b/arch/arm/boot/dts/ste-u300.dts index b8a8ddb5abff..644befd5ea8f 100644 --- a/arch/arm/boot/dts/ste-u300.dts +++ b/arch/arm/boot/dts/ste-u300.dts | |||
@@ -27,6 +27,12 @@ | |||
27 | s365 { | 27 | s365 { |
28 | compatible = "stericsson,s365"; | 28 | compatible = "stericsson,s365"; |
29 | vana15-supply = <&ab3100_ldo_d_reg>; | 29 | vana15-supply = <&ab3100_ldo_d_reg>; |
30 | syscon = <&syscon>; | ||
31 | }; | ||
32 | |||
33 | syscon: syscon@c0011000 { | ||
34 | compatible = "stericsson,u300-syscon"; | ||
35 | reg = <0xc0011000 0x1000>; | ||
30 | }; | 36 | }; |
31 | 37 | ||
32 | timer: timer@c0014000 { | 38 | timer: timer@c0014000 { |
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 1fdaf81771fa..8cfca45d3650 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/platform_data/clk-u300.h> | 14 | #include <linux/platform_data/clk-u300.h> |
15 | #include <linux/platform_data/pinctrl-coh901.h> | 15 | #include <linux/platform_data/pinctrl-coh901.h> |
16 | #include <linux/irqchip.h> | 16 | #include <linux/irqchip.h> |
17 | #include <linux/of_address.h> | ||
17 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
18 | #include <linux/clocksource.h> | 19 | #include <linux/clocksource.h> |
19 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
@@ -48,6 +49,8 @@ | |||
48 | #define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK (0x01FC) | 49 | #define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK (0x01FC) |
49 | #define U300_SYSCON_BCR_APP_BOOT_SERV_MASK (0x0003) | 50 | #define U300_SYSCON_BCR_APP_BOOT_SERV_MASK (0x0003) |
50 | 51 | ||
52 | static void __iomem *syscon_base; | ||
53 | |||
51 | /* | 54 | /* |
52 | * Static I/O mappings that are needed for booting the U300 platforms. The | 55 | * Static I/O mappings that are needed for booting the U300 platforms. The |
53 | * only things we need are the areas where we find the timer, syscon and | 56 | * only things we need are the areas where we find the timer, syscon and |
@@ -171,7 +174,7 @@ static void __init u300_init_check_chip(void) | |||
171 | const char unknown[] = "UNKNOWN"; | 174 | const char unknown[] = "UNKNOWN"; |
172 | 175 | ||
173 | /* Read out and print chip ID */ | 176 | /* Read out and print chip ID */ |
174 | val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR); | 177 | val = readw(syscon_base + U300_SYSCON_CIDR); |
175 | /* This is in funky bigendian order... */ | 178 | /* This is in funky bigendian order... */ |
176 | val = (val & 0xFFU) << 8 | (val >> 8); | 179 | val = (val & 0xFFU) << 8 | (val >> 8); |
177 | chip = db_chips; | 180 | chip = db_chips; |
@@ -244,10 +247,21 @@ static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = { | |||
244 | 247 | ||
245 | static void __init u300_init_irq_dt(void) | 248 | static void __init u300_init_irq_dt(void) |
246 | { | 249 | { |
250 | struct device_node *syscon; | ||
247 | struct clk *clk; | 251 | struct clk *clk; |
248 | 252 | ||
253 | syscon = of_find_node_by_path("/syscon@c0011000"); | ||
254 | if (!syscon) { | ||
255 | pr_crit("could not find syscon node\n"); | ||
256 | return; | ||
257 | } | ||
258 | syscon_base = of_iomap(syscon, 0); | ||
259 | if (!syscon_base) { | ||
260 | pr_crit("could not remap syscon\n"); | ||
261 | return; | ||
262 | } | ||
249 | /* initialize clocking early, we want to clock the INTCON */ | 263 | /* initialize clocking early, we want to clock the INTCON */ |
250 | u300_clk_init(U300_SYSCON_VBASE); | 264 | u300_clk_init(syscon_base); |
251 | 265 | ||
252 | /* Bootstrap EMIF and SEMI clocks */ | 266 | /* Bootstrap EMIF and SEMI clocks */ |
253 | clk = clk_get_sys("pl172", NULL); | 267 | clk = clk_get_sys("pl172", NULL); |
@@ -280,9 +294,9 @@ static void __init u300_init_machine_dt(void) | |||
280 | u300_auxdata_lookup, NULL); | 294 | u300_auxdata_lookup, NULL); |
281 | 295 | ||
282 | /* Enable SEMI self refresh */ | 296 | /* Enable SEMI self refresh */ |
283 | val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) | | 297 | val = readw(syscon_base + U300_SYSCON_SMCR) | |
284 | U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE; | 298 | U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE; |
285 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR); | 299 | writew(val, syscon_base + U300_SYSCON_SMCR); |
286 | } | 300 | } |
287 | 301 | ||
288 | static const char * u300_board_compat[] = { | 302 | static const char * u300_board_compat[] = { |
diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c index 1cbe88c74367..273fceb83685 100644 --- a/arch/arm/mach-u300/regulator.c +++ b/arch/arm/mach-u300/regulator.c | |||
@@ -16,8 +16,8 @@ | |||
16 | #include <linux/regulator/machine.h> | 16 | #include <linux/regulator/machine.h> |
17 | #include <linux/regulator/consumer.h> | 17 | #include <linux/regulator/consumer.h> |
18 | /* Those are just for writing in syscon */ | 18 | /* Those are just for writing in syscon */ |
19 | #include <linux/of_address.h> | ||
19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
20 | #include "u300-regs.h" | ||
21 | 21 | ||
22 | /* Power Management Control 16bit (R/W) */ | 22 | /* Power Management Control 16bit (R/W) */ |
23 | #define U300_SYSCON_PMCR (0x50) | 23 | #define U300_SYSCON_PMCR (0x50) |
@@ -57,10 +57,25 @@ void u300_pm_poweroff(void) | |||
57 | */ | 57 | */ |
58 | static int __init __u300_init_boardpower(struct platform_device *pdev) | 58 | static int __init __u300_init_boardpower(struct platform_device *pdev) |
59 | { | 59 | { |
60 | struct device_node *np = pdev->dev.of_node; | ||
61 | struct device_node *syscon_np; | ||
62 | static void __iomem *syscon_base; | ||
60 | int err; | 63 | int err; |
61 | u32 val; | 64 | u32 val; |
62 | 65 | ||
63 | pr_info("U300: setting up board power\n"); | 66 | pr_info("U300: setting up board power\n"); |
67 | |||
68 | syscon_np = of_parse_phandle(np, "syscon", 0); | ||
69 | if (!syscon_np) { | ||
70 | pr_crit("U300: no syscon node\n"); | ||
71 | return -ENODEV; | ||
72 | } | ||
73 | syscon_base = of_iomap(syscon_np, 0); | ||
74 | if (!syscon_base) { | ||
75 | pr_crit("U300: could not remap syscon\n"); | ||
76 | return -ENODEV; | ||
77 | } | ||
78 | |||
64 | main_power_15 = regulator_get(&pdev->dev, "vana15"); | 79 | main_power_15 = regulator_get(&pdev->dev, "vana15"); |
65 | 80 | ||
66 | if (IS_ERR(main_power_15)) { | 81 | if (IS_ERR(main_power_15)) { |
@@ -81,9 +96,9 @@ static int __init __u300_init_boardpower(struct platform_device *pdev) | |||
81 | * the rest of the U300 power management is implemented. | 96 | * the rest of the U300 power management is implemented. |
82 | */ | 97 | */ |
83 | pr_info("U300: disable system controller pull-up\n"); | 98 | pr_info("U300: disable system controller pull-up\n"); |
84 | val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR); | 99 | val = readw(syscon_base + U300_SYSCON_PMCR); |
85 | val &= ~U300_SYSCON_PMCR_DCON_ENABLE; | 100 | val &= ~U300_SYSCON_PMCR_DCON_ENABLE; |
86 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR); | 101 | writew(val, syscon_base + U300_SYSCON_PMCR); |
87 | 102 | ||
88 | /* Register globally exported PM poweroff hook */ | 103 | /* Register globally exported PM poweroff hook */ |
89 | pm_power_off = u300_pm_poweroff; | 104 | pm_power_off = u300_pm_poweroff; |