From b1d134ba9de2b7a136406530e34fc8b110ba6efd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 31 Mar 2017 11:01:54 +0200 Subject: soc: renesas: Register SoC device early The r8a7795 SYSC driver manages PM Domains, and thus is initialized from an early_initcall(). However, this means the driver cannot check the SoC revision, as the SoC device hasn't been registered yet. Change renesas_soc_init() from a core_initcall() to an early_initcall() to fix this (renesas-soc.o is listed before rcar-sysc.o in the Makefile). Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- drivers/soc/renesas/renesas-soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index 330960312296..51ed33f3426d 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c @@ -254,4 +254,4 @@ static int __init renesas_soc_init(void) return 0; } -core_initcall(renesas_soc_init); +early_initcall(renesas_soc_init); -- cgit v1.2.3 From afa6f53df6052968ce3934ad324777c0057e31d1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 31 Mar 2017 11:01:55 +0200 Subject: soc: renesas: rcar-sysc: Add support for fixing up power area tables The same SoC may have different power areas, depending on SoC revision. One option is to use different sets of power area tables for each SoC revision. However, if the differences are small, it is much more space-efficient to have a single set of tables, and fix those up at runtime instead. Hence provide a helper to NULLify power areas that do not exist on some revisions (NULLified power areas are skipped during the registration phase), and support for an optional initialization callback to e.g. fix up power area tables. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- drivers/soc/renesas/rcar-sysc.c | 25 ++++++++++++++++++++++++- drivers/soc/renesas/rcar-sysc.h | 10 ++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index 225c35c79d9a..528a13742aeb 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -2,7 +2,7 @@ * R-Car SYSC Power management support * * Copyright (C) 2014 Magnus Damm - * Copyright (C) 2015-2016 Glider bvba + * Copyright (C) 2015-2017 Glider bvba * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -334,6 +334,12 @@ static int __init rcar_sysc_pd_init(void) info = match->data; + if (info->init) { + error = info->init(); + if (error) + return error; + } + has_cpg_mstp = of_find_compatible_node(NULL, NULL, "renesas,cpg-mstp-clocks"); @@ -377,6 +383,11 @@ static int __init rcar_sysc_pd_init(void) const struct rcar_sysc_area *area = &info->areas[i]; struct rcar_sysc_pd *pd; + if (!area->name) { + /* Skip NULLified area */ + continue; + } + pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL); if (!pd) { error = -ENOMEM; @@ -406,6 +417,18 @@ out_put: } early_initcall(rcar_sysc_pd_init); +void __init rcar_sysc_nullify(struct rcar_sysc_area *areas, + unsigned int num_areas, u8 id) +{ + unsigned int i; + + for (i = 0; i < num_areas; i++) + if (areas[i].isr_bit == id) { + areas[i].name = NULL; + return; + } +} + void __init rcar_sysc_init(phys_addr_t base, u32 syscier) { u32 syscimr; diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h index f6e842e2976e..07edb049a401 100644 --- a/drivers/soc/renesas/rcar-sysc.h +++ b/drivers/soc/renesas/rcar-sysc.h @@ -46,6 +46,7 @@ struct rcar_sysc_area { */ struct rcar_sysc_info { + int (*init)(void); /* Optional */ const struct rcar_sysc_area *areas; unsigned int num_areas; }; @@ -59,4 +60,13 @@ extern const struct rcar_sysc_info r8a7792_sysc_info; extern const struct rcar_sysc_info r8a7794_sysc_info; extern const struct rcar_sysc_info r8a7795_sysc_info; extern const struct rcar_sysc_info r8a7796_sysc_info; + + + /* + * Helpers for fixing up power area tables depending on SoC revision + */ + +extern void rcar_sysc_nullify(struct rcar_sysc_area *areas, + unsigned int num_areas, u8 id); + #endif /* __SOC_RENESAS_RCAR_SYSC_H__ */ -- cgit v1.2.3 From fcb87087261e1be51b4c03677f39246bdc312b1c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 31 Mar 2017 11:01:56 +0200 Subject: soc: renesas: rcar-sysc: Add support for R-Car H3 ES2.0 Power area A2VC0 was removed in revision ES2.0, cfr. R-Car Gen3 Hardware User's Manual rev. 0.53E. Hence remove it from the power area table when not running on ES1.x. This is in line with the goal to: 1. Support both the ES1.x and ES2.0 SoC revisions in a single binary for now, 2. Make it clear which code supports ES1.x, so it can easily be identified and removed later, when production SoCs are deemed ubiquitous. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- drivers/soc/renesas/r8a7795-sysc.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/renesas/r8a7795-sysc.c b/drivers/soc/renesas/r8a7795-sysc.c index 5e7537c96f7b..7412666187b3 100644 --- a/drivers/soc/renesas/r8a7795-sysc.c +++ b/drivers/soc/renesas/r8a7795-sysc.c @@ -1,7 +1,7 @@ /* * Renesas R-Car H3 System Controller * - * Copyright (C) 2016 Glider bvba + * Copyright (C) 2016-2017 Glider bvba * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -10,12 +10,13 @@ #include #include +#include #include #include "rcar-sysc.h" -static const struct rcar_sysc_area r8a7795_areas[] __initconst = { +static struct rcar_sysc_area r8a7795_areas[] __initdata = { { "always-on", 0, 0, R8A7795_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, { "ca57-scu", 0x1c0, 0, R8A7795_PD_CA57_SCU, R8A7795_PD_ALWAYS_ON, PD_SCU }, @@ -40,6 +41,7 @@ static const struct rcar_sysc_area r8a7795_areas[] __initconst = { { "a3vp", 0x340, 0, R8A7795_PD_A3VP, R8A7795_PD_ALWAYS_ON }, { "cr7", 0x240, 0, R8A7795_PD_CR7, R8A7795_PD_ALWAYS_ON }, { "a3vc", 0x380, 0, R8A7795_PD_A3VC, R8A7795_PD_ALWAYS_ON }, + /* A2VC0 exists on ES1.x only */ { "a2vc0", 0x3c0, 0, R8A7795_PD_A2VC0, R8A7795_PD_A3VC }, { "a2vc1", 0x3c0, 1, R8A7795_PD_A2VC1, R8A7795_PD_A3VC }, { "3dg-a", 0x100, 0, R8A7795_PD_3DG_A, R8A7795_PD_ALWAYS_ON }, @@ -50,7 +52,27 @@ static const struct rcar_sysc_area r8a7795_areas[] __initconst = { { "a3ir", 0x180, 0, R8A7795_PD_A3IR, R8A7795_PD_ALWAYS_ON }, }; + + /* + * Fixups for R-Car H3 revisions after ES1.x + */ + +static const struct soc_device_attribute r8a7795es1[] __initconst = { + { .soc_id = "r8a7795", .revision = "ES1.*" }, + { /* sentinel */ } +}; + +static int __init r8a7795_sysc_init(void) +{ + if (!soc_device_match(r8a7795es1)) + rcar_sysc_nullify(r8a7795_areas, ARRAY_SIZE(r8a7795_areas), + R8A7795_PD_A2VC0); + + return 0; +} + const struct rcar_sysc_info r8a7795_sysc_info __initconst = { + .init = r8a7795_sysc_init, .areas = r8a7795_areas, .num_areas = ARRAY_SIZE(r8a7795_areas), }; -- cgit v1.2.3