diff options
author | Olof Johansson <olof@lixom.net> | 2016-07-07 01:12:04 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2016-07-07 01:12:04 -0400 |
commit | b85751c761a56232e772f4c2d1aba2cd43d52849 (patch) | |
tree | fdbc7a115b460ddd4410689f0c594c3727bc1137 | |
parent | 564c9741aa508beba23f3b05b7235775a51bae00 (diff) | |
parent | ced42730d19dd140a76f86c3761f646b83a35d09 (diff) |
Merge tag 'renesas-rcar-sysc2-for-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/drivers
Second Round of Renesas ARM Based SoC R-Car SYSC Updates for v4.8
* Prepare for handling SYSC interrupt configuration purely
from DT in the rcar-sysc driver for new SoCs, while preserving
backward compatibility with old DTBs for R-Car H1, H2, and M2-W
* Add R8A7792 support
* tag 'renesas-rcar-sysc2-for-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas:
soc: renesas: rcar-sysc: Improve SYSC interrupt config in legacy wrapper
soc: renesas: rcar-sysc: Move SYSC interrupt config to rcar-sysc driver
soc: renesas: rcar-sysc: Make rcar_sysc_init() init the PM domains
soc: renesas: rcar-sysc: Fix uninitialized error code in rcar_sysc_pd_init()
soc: renesas: rcar-sysc: add R8A7792 support
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | arch/arm/mach-shmobile/pm-r8a7779.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pm-rcar-gen2.c | 6 | ||||
-rw-r--r-- | drivers/soc/renesas/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/renesas/r8a7792-sysc.c | 34 | ||||
-rw-r--r-- | drivers/soc/renesas/rcar-sysc.c | 42 | ||||
-rw-r--r-- | drivers/soc/renesas/rcar-sysc.h | 1 | ||||
-rw-r--r-- | include/linux/soc/renesas/rcar-sysc.h | 2 |
7 files changed, 71 insertions, 21 deletions
diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c index 4174cbcbc467..5c9a93f5e650 100644 --- a/arch/arm/mach-shmobile/pm-r8a7779.c +++ b/arch/arm/mach-shmobile/pm-r8a7779.c | |||
@@ -23,11 +23,7 @@ | |||
23 | 23 | ||
24 | static void __init r8a7779_sysc_init(void) | 24 | static void __init r8a7779_sysc_init(void) |
25 | { | 25 | { |
26 | void __iomem *base = rcar_sysc_init(0xffd85000); | 26 | rcar_sysc_init(0xffd85000, 0x0131000e); |
27 | |||
28 | /* enable all interrupt sources, but do not use interrupt handler */ | ||
29 | iowrite32(0x0131000e, base + SYSCIER); | ||
30 | iowrite32(0, base + SYSCIMR); | ||
31 | } | 27 | } |
32 | 28 | ||
33 | #else /* CONFIG_PM || CONFIG_SMP */ | 29 | #else /* CONFIG_PM || CONFIG_SMP */ |
diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c index 691ac166a277..7768fd1bce65 100644 --- a/arch/arm/mach-shmobile/pm-rcar-gen2.c +++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c | |||
@@ -37,11 +37,7 @@ | |||
37 | 37 | ||
38 | static void __init rcar_gen2_sysc_init(u32 syscier) | 38 | static void __init rcar_gen2_sysc_init(u32 syscier) |
39 | { | 39 | { |
40 | void __iomem *base = rcar_sysc_init(0xe6180000); | 40 | rcar_sysc_init(0xe6180000, syscier); |
41 | |||
42 | /* enable all interrupt sources, but do not use interrupt handler */ | ||
43 | iowrite32(syscier, base + SYSCIER); | ||
44 | iowrite32(0, base + SYSCIMR); | ||
45 | } | 41 | } |
46 | 42 | ||
47 | #else /* CONFIG_SMP */ | 43 | #else /* CONFIG_SMP */ |
diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index cd85cd5e6a01..623039c3514c 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | obj-$(CONFIG_ARCH_R8A7779) += rcar-sysc.o r8a7779-sysc.o | 1 | obj-$(CONFIG_ARCH_R8A7779) += rcar-sysc.o r8a7779-sysc.o |
2 | obj-$(CONFIG_ARCH_R8A7790) += rcar-sysc.o r8a7790-sysc.o | 2 | obj-$(CONFIG_ARCH_R8A7790) += rcar-sysc.o r8a7790-sysc.o |
3 | obj-$(CONFIG_ARCH_R8A7791) += rcar-sysc.o r8a7791-sysc.o | 3 | obj-$(CONFIG_ARCH_R8A7791) += rcar-sysc.o r8a7791-sysc.o |
4 | obj-$(CONFIG_ARCH_R8A7792) += rcar-sysc.o r8a7792-sysc.o | ||
4 | # R-Car M2-N is identical to R-Car M2-W w.r.t. power domains. | 5 | # R-Car M2-N is identical to R-Car M2-W w.r.t. power domains. |
5 | obj-$(CONFIG_ARCH_R8A7793) += rcar-sysc.o r8a7791-sysc.o | 6 | obj-$(CONFIG_ARCH_R8A7793) += rcar-sysc.o r8a7791-sysc.o |
6 | obj-$(CONFIG_ARCH_R8A7794) += rcar-sysc.o r8a7794-sysc.o | 7 | obj-$(CONFIG_ARCH_R8A7794) += rcar-sysc.o r8a7794-sysc.o |
diff --git a/drivers/soc/renesas/r8a7792-sysc.c b/drivers/soc/renesas/r8a7792-sysc.c new file mode 100644 index 000000000000..ca7467d7b7ec --- /dev/null +++ b/drivers/soc/renesas/r8a7792-sysc.c | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Renesas R-Car V2H (R8A7792) System Controller | ||
3 | * | ||
4 | * Copyright (C) 2016 Cogent Embedded Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | */ | ||
10 | |||
11 | #include <linux/bug.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/kernel.h> | ||
14 | |||
15 | #include <dt-bindings/power/r8a7792-sysc.h> | ||
16 | |||
17 | #include "rcar-sysc.h" | ||
18 | |||
19 | static const struct rcar_sysc_area r8a7792_areas[] __initconst = { | ||
20 | { "always-on", 0, 0, R8A7792_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, | ||
21 | { "ca15-scu", 0x180, 0, R8A7792_PD_CA15_SCU, R8A7792_PD_ALWAYS_ON, | ||
22 | PD_SCU }, | ||
23 | { "ca15-cpu0", 0x40, 0, R8A7792_PD_CA15_CPU0, R8A7792_PD_CA15_SCU, | ||
24 | PD_CPU_NOCR }, | ||
25 | { "ca15-cpu1", 0x40, 1, R8A7792_PD_CA15_CPU1, R8A7792_PD_CA15_SCU, | ||
26 | PD_CPU_NOCR }, | ||
27 | { "sgx", 0xc0, 0, R8A7792_PD_SGX, R8A7792_PD_ALWAYS_ON }, | ||
28 | { "imp", 0x140, 0, R8A7792_PD_IMP, R8A7792_PD_ALWAYS_ON }, | ||
29 | }; | ||
30 | |||
31 | const struct rcar_sysc_info r8a7792_sysc_info __initconst = { | ||
32 | .areas = r8a7792_areas, | ||
33 | .num_areas = ARRAY_SIZE(r8a7792_areas), | ||
34 | }; | ||
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index fc997d4d2a4a..65c8e1eb90c0 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c | |||
@@ -164,15 +164,6 @@ static bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch) | |||
164 | return false; | 164 | return false; |
165 | } | 165 | } |
166 | 166 | ||
167 | void __iomem *rcar_sysc_init(phys_addr_t base) | ||
168 | { | ||
169 | rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE); | ||
170 | if (!rcar_sysc_base) | ||
171 | panic("unable to ioremap R-Car SYSC hardware block\n"); | ||
172 | |||
173 | return rcar_sysc_base; | ||
174 | } | ||
175 | |||
176 | struct rcar_sysc_pd { | 167 | struct rcar_sysc_pd { |
177 | struct generic_pm_domain genpd; | 168 | struct generic_pm_domain genpd; |
178 | struct rcar_sysc_ch ch; | 169 | struct rcar_sysc_ch ch; |
@@ -293,6 +284,9 @@ static const struct of_device_id rcar_sysc_matches[] = { | |||
293 | #ifdef CONFIG_ARCH_R8A7791 | 284 | #ifdef CONFIG_ARCH_R8A7791 |
294 | { .compatible = "renesas,r8a7791-sysc", .data = &r8a7791_sysc_info }, | 285 | { .compatible = "renesas,r8a7791-sysc", .data = &r8a7791_sysc_info }, |
295 | #endif | 286 | #endif |
287 | #ifdef CONFIG_ARCH_R8A7792 | ||
288 | { .compatible = "renesas,r8a7792-sysc", .data = &r8a7792_sysc_info }, | ||
289 | #endif | ||
296 | #ifdef CONFIG_ARCH_R8A7793 | 290 | #ifdef CONFIG_ARCH_R8A7793 |
297 | /* R-Car M2-N is identical to R-Car M2-W w.r.t. power domains. */ | 291 | /* R-Car M2-N is identical to R-Car M2-W w.r.t. power domains. */ |
298 | { .compatible = "renesas,r8a7793-sysc", .data = &r8a7791_sysc_info }, | 292 | { .compatible = "renesas,r8a7793-sysc", .data = &r8a7791_sysc_info }, |
@@ -325,6 +319,9 @@ static int __init rcar_sysc_pd_init(void) | |||
325 | unsigned int i; | 319 | unsigned int i; |
326 | int error; | 320 | int error; |
327 | 321 | ||
322 | if (rcar_sysc_base) | ||
323 | return 0; | ||
324 | |||
328 | np = of_find_matching_node_and_match(NULL, rcar_sysc_matches, &match); | 325 | np = of_find_matching_node_and_match(NULL, rcar_sysc_matches, &match); |
329 | if (!np) | 326 | if (!np) |
330 | return -ENODEV; | 327 | return -ENODEV; |
@@ -395,10 +392,35 @@ static int __init rcar_sysc_pd_init(void) | |||
395 | domains->domains[area->isr_bit] = &pd->genpd; | 392 | domains->domains[area->isr_bit] = &pd->genpd; |
396 | } | 393 | } |
397 | 394 | ||
398 | of_genpd_add_provider_onecell(np, &domains->onecell_data); | 395 | error = of_genpd_add_provider_onecell(np, &domains->onecell_data); |
399 | 396 | ||
400 | out_put: | 397 | out_put: |
401 | of_node_put(np); | 398 | of_node_put(np); |
402 | return error; | 399 | return error; |
403 | } | 400 | } |
404 | early_initcall(rcar_sysc_pd_init); | 401 | early_initcall(rcar_sysc_pd_init); |
402 | |||
403 | void __init rcar_sysc_init(phys_addr_t base, u32 syscier) | ||
404 | { | ||
405 | u32 syscimr; | ||
406 | |||
407 | if (!rcar_sysc_pd_init()) | ||
408 | return; | ||
409 | |||
410 | rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE); | ||
411 | |||
412 | /* | ||
413 | * Mask all interrupt sources to prevent the CPU from receiving them. | ||
414 | * Make sure not to clear reserved bits that were set before. | ||
415 | */ | ||
416 | syscimr = ioread32(rcar_sysc_base + SYSCIMR); | ||
417 | syscimr |= syscier; | ||
418 | pr_debug("%s: syscimr = 0x%08x\n", __func__, syscimr); | ||
419 | iowrite32(syscimr, rcar_sysc_base + SYSCIMR); | ||
420 | |||
421 | /* | ||
422 | * SYSC needs all interrupt sources enabled to control power. | ||
423 | */ | ||
424 | pr_debug("%s: syscier = 0x%08x\n", __func__, syscier); | ||
425 | iowrite32(syscier, rcar_sysc_base + SYSCIER); | ||
426 | } | ||
diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h index 4ac3d7bf7f38..77dbe861473f 100644 --- a/drivers/soc/renesas/rcar-sysc.h +++ b/drivers/soc/renesas/rcar-sysc.h | |||
@@ -53,6 +53,7 @@ struct rcar_sysc_info { | |||
53 | extern const struct rcar_sysc_info r8a7779_sysc_info; | 53 | extern const struct rcar_sysc_info r8a7779_sysc_info; |
54 | extern const struct rcar_sysc_info r8a7790_sysc_info; | 54 | extern const struct rcar_sysc_info r8a7790_sysc_info; |
55 | extern const struct rcar_sysc_info r8a7791_sysc_info; | 55 | extern const struct rcar_sysc_info r8a7791_sysc_info; |
56 | extern const struct rcar_sysc_info r8a7792_sysc_info; | ||
56 | extern const struct rcar_sysc_info r8a7794_sysc_info; | 57 | extern const struct rcar_sysc_info r8a7794_sysc_info; |
57 | extern const struct rcar_sysc_info r8a7795_sysc_info; | 58 | extern const struct rcar_sysc_info r8a7795_sysc_info; |
58 | extern const struct rcar_sysc_info r8a7796_sysc_info; | 59 | extern const struct rcar_sysc_info r8a7796_sysc_info; |
diff --git a/include/linux/soc/renesas/rcar-sysc.h b/include/linux/soc/renesas/rcar-sysc.h index 92fc613ab23d..7b8b280c181b 100644 --- a/include/linux/soc/renesas/rcar-sysc.h +++ b/include/linux/soc/renesas/rcar-sysc.h | |||
@@ -11,6 +11,6 @@ struct rcar_sysc_ch { | |||
11 | 11 | ||
12 | int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch); | 12 | int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch); |
13 | int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch); | 13 | int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch); |
14 | void __iomem *rcar_sysc_init(phys_addr_t base); | 14 | void rcar_sysc_init(phys_addr_t base, u32 syscier); |
15 | 15 | ||
16 | #endif /* __LINUX_SOC_RENESAS_RCAR_SYSC_H__ */ | 16 | #endif /* __LINUX_SOC_RENESAS_RCAR_SYSC_H__ */ |