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 <geert+renesas@glider.be> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
This commit is contained in:
Родитель
b1d134ba9d
Коммит
afa6f53df6
|
@ -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;
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче