Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'renesas-sysc-for-v4.12' of https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/drivers

Renesas ARM Based SoC Sysc Updates for v4.12

* Add support for R-Car H3 ES2.0

* tag 'renesas-sysc-for-v4.12' of https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas:
soc: renesas: rcar-sysc: Add support for R-Car H3 ES2.0
soc: renesas: rcar-sysc: Add support for fixing up power area tables
soc: renesas: Register SoC device early
base: soc: Allow early registration of a single SoC device
base: soc: Let soc_device_match() return no match when called too early

Signed-off-by: Olof Johansson <olof@lixom.net>

+104 -33
+44 -28
drivers/base/soc.c
··· 109 109 kfree(soc_dev); 110 110 } 111 111 112 + static struct soc_device_attribute *early_soc_dev_attr; 113 + 112 114 struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr) 113 115 { 114 116 struct soc_device *soc_dev; 115 117 int ret; 116 118 117 119 if (!soc_bus_type.p) { 118 - ret = bus_register(&soc_bus_type); 119 - if (ret) 120 - goto out1; 120 + if (early_soc_dev_attr) 121 + return ERR_PTR(-EBUSY); 122 + early_soc_dev_attr = soc_dev_attr; 123 + return NULL; 121 124 } 122 125 123 126 soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL); ··· 162 159 ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); 163 160 164 161 device_unregister(&soc_dev->dev); 162 + early_soc_dev_attr = NULL; 165 163 } 166 164 167 165 static int __init soc_bus_register(void) 168 166 { 169 - if (soc_bus_type.p) 170 - return 0; 167 + int ret; 171 168 172 - return bus_register(&soc_bus_type); 169 + ret = bus_register(&soc_bus_type); 170 + if (ret) 171 + return ret; 172 + 173 + if (early_soc_dev_attr) 174 + return PTR_ERR(soc_device_register(early_soc_dev_attr)); 175 + 176 + return 0; 173 177 } 174 178 core_initcall(soc_bus_register); 179 + 180 + static int soc_device_match_attr(const struct soc_device_attribute *attr, 181 + const struct soc_device_attribute *match) 182 + { 183 + if (match->machine && 184 + (!attr->machine || !glob_match(match->machine, attr->machine))) 185 + return 0; 186 + 187 + if (match->family && 188 + (!attr->family || !glob_match(match->family, attr->family))) 189 + return 0; 190 + 191 + if (match->revision && 192 + (!attr->revision || !glob_match(match->revision, attr->revision))) 193 + return 0; 194 + 195 + if (match->soc_id && 196 + (!attr->soc_id || !glob_match(match->soc_id, attr->soc_id))) 197 + return 0; 198 + 199 + return 1; 200 + } 175 201 176 202 static int soc_device_match_one(struct device *dev, void *arg) 177 203 { 178 204 struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); 179 - const struct soc_device_attribute *match = arg; 180 205 181 - if (match->machine && 182 - (!soc_dev->attr->machine || 183 - !glob_match(match->machine, soc_dev->attr->machine))) 184 - return 0; 185 - 186 - if (match->family && 187 - (!soc_dev->attr->family || 188 - !glob_match(match->family, soc_dev->attr->family))) 189 - return 0; 190 - 191 - if (match->revision && 192 - (!soc_dev->attr->revision || 193 - !glob_match(match->revision, soc_dev->attr->revision))) 194 - return 0; 195 - 196 - if (match->soc_id && 197 - (!soc_dev->attr->soc_id || 198 - !glob_match(match->soc_id, soc_dev->attr->soc_id))) 199 - return 0; 200 - 201 - return 1; 206 + return soc_device_match_attr(soc_dev->attr, arg); 202 207 } 203 208 204 209 /* ··· 241 230 break; 242 231 ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, 243 232 soc_device_match_one); 233 + if (ret < 0 && early_soc_dev_attr) 234 + ret = soc_device_match_attr(early_soc_dev_attr, 235 + matches); 236 + if (ret < 0) 237 + return NULL; 244 238 if (!ret) 245 239 matches++; 246 240 else
+24 -2
drivers/soc/renesas/r8a7795-sysc.c
··· 1 1 /* 2 2 * Renesas R-Car H3 System Controller 3 3 * 4 - * Copyright (C) 2016 Glider bvba 4 + * Copyright (C) 2016-2017 Glider bvba 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify 7 7 * it under the terms of the GNU General Public License as published by ··· 10 10 11 11 #include <linux/bug.h> 12 12 #include <linux/kernel.h> 13 + #include <linux/sys_soc.h> 13 14 14 15 #include <dt-bindings/power/r8a7795-sysc.h> 15 16 16 17 #include "rcar-sysc.h" 17 18 18 - static const struct rcar_sysc_area r8a7795_areas[] __initconst = { 19 + static struct rcar_sysc_area r8a7795_areas[] __initdata = { 19 20 { "always-on", 0, 0, R8A7795_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, 20 21 { "ca57-scu", 0x1c0, 0, R8A7795_PD_CA57_SCU, R8A7795_PD_ALWAYS_ON, 21 22 PD_SCU }, ··· 41 40 { "a3vp", 0x340, 0, R8A7795_PD_A3VP, R8A7795_PD_ALWAYS_ON }, 42 41 { "cr7", 0x240, 0, R8A7795_PD_CR7, R8A7795_PD_ALWAYS_ON }, 43 42 { "a3vc", 0x380, 0, R8A7795_PD_A3VC, R8A7795_PD_ALWAYS_ON }, 43 + /* A2VC0 exists on ES1.x only */ 44 44 { "a2vc0", 0x3c0, 0, R8A7795_PD_A2VC0, R8A7795_PD_A3VC }, 45 45 { "a2vc1", 0x3c0, 1, R8A7795_PD_A2VC1, R8A7795_PD_A3VC }, 46 46 { "3dg-a", 0x100, 0, R8A7795_PD_3DG_A, R8A7795_PD_ALWAYS_ON }, ··· 52 50 { "a3ir", 0x180, 0, R8A7795_PD_A3IR, R8A7795_PD_ALWAYS_ON }, 53 51 }; 54 52 53 + 54 + /* 55 + * Fixups for R-Car H3 revisions after ES1.x 56 + */ 57 + 58 + static const struct soc_device_attribute r8a7795es1[] __initconst = { 59 + { .soc_id = "r8a7795", .revision = "ES1.*" }, 60 + { /* sentinel */ } 61 + }; 62 + 63 + static int __init r8a7795_sysc_init(void) 64 + { 65 + if (!soc_device_match(r8a7795es1)) 66 + rcar_sysc_nullify(r8a7795_areas, ARRAY_SIZE(r8a7795_areas), 67 + R8A7795_PD_A2VC0); 68 + 69 + return 0; 70 + } 71 + 55 72 const struct rcar_sysc_info r8a7795_sysc_info __initconst = { 73 + .init = r8a7795_sysc_init, 56 74 .areas = r8a7795_areas, 57 75 .num_areas = ARRAY_SIZE(r8a7795_areas), 58 76 };
+24 -1
drivers/soc/renesas/rcar-sysc.c
··· 2 2 * R-Car SYSC Power management support 3 3 * 4 4 * Copyright (C) 2014 Magnus Damm 5 - * Copyright (C) 2015-2016 Glider bvba 5 + * Copyright (C) 2015-2017 Glider bvba 6 6 * 7 7 * This file is subject to the terms and conditions of the GNU General Public 8 8 * License. See the file "COPYING" in the main directory of this archive ··· 334 334 335 335 info = match->data; 336 336 337 + if (info->init) { 338 + error = info->init(); 339 + if (error) 340 + return error; 341 + } 342 + 337 343 has_cpg_mstp = of_find_compatible_node(NULL, NULL, 338 344 "renesas,cpg-mstp-clocks"); 339 345 ··· 383 377 const struct rcar_sysc_area *area = &info->areas[i]; 384 378 struct rcar_sysc_pd *pd; 385 379 380 + if (!area->name) { 381 + /* Skip NULLified area */ 382 + continue; 383 + } 384 + 386 385 pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL); 387 386 if (!pd) { 388 387 error = -ENOMEM; ··· 416 405 return error; 417 406 } 418 407 early_initcall(rcar_sysc_pd_init); 408 + 409 + void __init rcar_sysc_nullify(struct rcar_sysc_area *areas, 410 + unsigned int num_areas, u8 id) 411 + { 412 + unsigned int i; 413 + 414 + for (i = 0; i < num_areas; i++) 415 + if (areas[i].isr_bit == id) { 416 + areas[i].name = NULL; 417 + return; 418 + } 419 + } 419 420 420 421 void __init rcar_sysc_init(phys_addr_t base, u32 syscier) 421 422 {
+10
drivers/soc/renesas/rcar-sysc.h
··· 46 46 */ 47 47 48 48 struct rcar_sysc_info { 49 + int (*init)(void); /* Optional */ 49 50 const struct rcar_sysc_area *areas; 50 51 unsigned int num_areas; 51 52 }; ··· 60 59 extern const struct rcar_sysc_info r8a7794_sysc_info; 61 60 extern const struct rcar_sysc_info r8a7795_sysc_info; 62 61 extern const struct rcar_sysc_info r8a7796_sysc_info; 62 + 63 + 64 + /* 65 + * Helpers for fixing up power area tables depending on SoC revision 66 + */ 67 + 68 + extern void rcar_sysc_nullify(struct rcar_sysc_area *areas, 69 + unsigned int num_areas, u8 id); 70 + 63 71 #endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
+1 -1
drivers/soc/renesas/renesas-soc.c
··· 270 270 271 271 return 0; 272 272 } 273 - core_initcall(renesas_soc_init); 273 + early_initcall(renesas_soc_init);
+1 -1
include/dt-bindings/power/r8a7795-sysc.h
··· 33 33 #define R8A7795_PD_CA53_SCU 21 34 34 #define R8A7795_PD_3DG_E 22 35 35 #define R8A7795_PD_A3IR 24 36 - #define R8A7795_PD_A2VC0 25 36 + #define R8A7795_PD_A2VC0 25 /* ES1.x only */ 37 37 #define R8A7795_PD_A2VC1 26 38 38 39 39 /* Always-on power area */