]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
soc: renesas: rcar-sysc: Add support for fixing up power area tables
authorGeert Uytterhoeven <geert+renesas@glider.be>
Fri, 31 Mar 2017 09:01:55 +0000 (11:01 +0200)
committerSimon Horman <horms+renesas@verge.net.au>
Fri, 7 Apr 2017 17:53:40 +0000 (13:53 -0400)
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 <geert+renesas@glider.be>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
drivers/soc/renesas/rcar-sysc.c
drivers/soc/renesas/rcar-sysc.h

index 225c35c79d9abad07308d2226f99448ba0d93531..528a13742aeb98d8035c7a998e5e2a037ccffe2c 100644 (file)
@@ -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;
index f6e842e2976ebe326ca2439dfb58a4b14f6464bc..07edb049a401196c7a6cd8903d37d310a96d09c0 100644 (file)
@@ -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__ */