aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-u300
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2013-05-22 10:15:13 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-06-17 07:54:35 -0400
commitcf0ce095c932becf48ed794ecdfad925e931dc9c (patch)
tree107d791b310c669c79d44d084323a9817f521eda /arch/arm/mach-u300
parentbe2885a569f43fa6c44e2a5e1795583ae9941c27 (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>
Diffstat (limited to 'arch/arm/mach-u300')
-rw-r--r--arch/arm/mach-u300/core.c22
-rw-r--r--arch/arm/mach-u300/regulator.c21
2 files changed, 36 insertions, 7 deletions
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
52static 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
245static void __init u300_init_irq_dt(void) 248static 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
288static const char * u300_board_compat[] = { 302static 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 */
58static int __init __u300_init_boardpower(struct platform_device *pdev) 58static 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;