mirror of https://gitee.com/openkylin/linux.git
Renesas ARM Based SoC Sysc Updates for v4.12
* Add support for R-Car H3 ES2.0 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJY59ObAAoJENfPZGlqN0++mmAP/iLPRVjE0DoqVVQbNeIq4pOI 0HaIU2MZH6cPN2868CBp+8/UsPQXUBtpBRdRsc7+B2gSQteFhEZ8b+tTJ007BohM YO4XSSfwEUedKoPB5N88hleGrXjvUbNBECOeD5XSOX3X9qQLDUkzpgDgfL0WPl6D gU3G7IitR2KnBTz5n8XbrdTVccZbafXutj3Sp8pTxd4Yc8ajL8MkxbwTjlGratfw sOUW1zxIv7c9eanfbYZQ3ZGNm++2w/WnqhPBTYfxcBVK95dslWjkxf7HawujeaP7 CihAakoH9QoYsrnyEMbMn4xpCJEYB8U5zaIzyOFHhGCtF5AXUrKFcn1DMpU7sORJ mu4UDUHIugGsu/RdOcOdB/dZ5GcfFtVehDLKtAGdoAwyc6eY9URAwOlOV9abOCtf qWSGHv0dKCVg5fLcuCzXMYd7DxXN1X4A0wj94S6XF5S1/wcWJaOU2uJKPSguoUzW vQt4jIM7TUUK6YAVj0xec40lXf0AuJ4FcXI/9TEnYnmqzOEwZzKzrlMv3xnqp08k jQarhWJLvN23lDAtGOorLJKOZyveXy0E3I9IJT8PgZpGmOlijSRBzhXsN1NeGsYo 663+3feI4Qe5vtu8Obv/vA0BcYHiA+AcEBwWYFAZOGGSM2IucORxX9UAu8XBmtRB FnS/AB2yrsoL9VjKgeYt =m+ef -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
32d8b52b90
|
@ -109,15 +109,18 @@ static void soc_release(struct device *dev)
|
|||
kfree(soc_dev);
|
||||
}
|
||||
|
||||
static struct soc_device_attribute *early_soc_dev_attr;
|
||||
|
||||
struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr)
|
||||
{
|
||||
struct soc_device *soc_dev;
|
||||
int ret;
|
||||
|
||||
if (!soc_bus_type.p) {
|
||||
ret = bus_register(&soc_bus_type);
|
||||
if (ret)
|
||||
goto out1;
|
||||
if (early_soc_dev_attr)
|
||||
return ERR_PTR(-EBUSY);
|
||||
early_soc_dev_attr = soc_dev_attr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL);
|
||||
|
@ -159,43 +162,51 @@ void soc_device_unregister(struct soc_device *soc_dev)
|
|||
ida_simple_remove(&soc_ida, soc_dev->soc_dev_num);
|
||||
|
||||
device_unregister(&soc_dev->dev);
|
||||
early_soc_dev_attr = NULL;
|
||||
}
|
||||
|
||||
static int __init soc_bus_register(void)
|
||||
{
|
||||
if (soc_bus_type.p)
|
||||
return 0;
|
||||
int ret;
|
||||
|
||||
return bus_register(&soc_bus_type);
|
||||
ret = bus_register(&soc_bus_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (early_soc_dev_attr)
|
||||
return PTR_ERR(soc_device_register(early_soc_dev_attr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(soc_bus_register);
|
||||
|
||||
static int soc_device_match_attr(const struct soc_device_attribute *attr,
|
||||
const struct soc_device_attribute *match)
|
||||
{
|
||||
if (match->machine &&
|
||||
(!attr->machine || !glob_match(match->machine, attr->machine)))
|
||||
return 0;
|
||||
|
||||
if (match->family &&
|
||||
(!attr->family || !glob_match(match->family, attr->family)))
|
||||
return 0;
|
||||
|
||||
if (match->revision &&
|
||||
(!attr->revision || !glob_match(match->revision, attr->revision)))
|
||||
return 0;
|
||||
|
||||
if (match->soc_id &&
|
||||
(!attr->soc_id || !glob_match(match->soc_id, attr->soc_id)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int soc_device_match_one(struct device *dev, void *arg)
|
||||
{
|
||||
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
|
||||
const struct soc_device_attribute *match = arg;
|
||||
|
||||
if (match->machine &&
|
||||
(!soc_dev->attr->machine ||
|
||||
!glob_match(match->machine, soc_dev->attr->machine)))
|
||||
return 0;
|
||||
|
||||
if (match->family &&
|
||||
(!soc_dev->attr->family ||
|
||||
!glob_match(match->family, soc_dev->attr->family)))
|
||||
return 0;
|
||||
|
||||
if (match->revision &&
|
||||
(!soc_dev->attr->revision ||
|
||||
!glob_match(match->revision, soc_dev->attr->revision)))
|
||||
return 0;
|
||||
|
||||
if (match->soc_id &&
|
||||
(!soc_dev->attr->soc_id ||
|
||||
!glob_match(match->soc_id, soc_dev->attr->soc_id)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return soc_device_match_attr(soc_dev->attr, arg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -230,6 +241,11 @@ const struct soc_device_attribute *soc_device_match(
|
|||
break;
|
||||
ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches,
|
||||
soc_device_match_one);
|
||||
if (ret < 0 && early_soc_dev_attr)
|
||||
ret = soc_device_match_attr(early_soc_dev_attr,
|
||||
matches);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
if (!ret)
|
||||
matches++;
|
||||
else
|
||||
|
|
|
@ -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 <linux/bug.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sys_soc.h>
|
||||
|
||||
#include <dt-bindings/power/r8a7795-sysc.h>
|
||||
|
||||
#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),
|
||||
};
|
||||
|
|
|
@ -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 @@ static int __init rcar_sysc_pd_init(void)
|
|||
}
|
||||
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__ */
|
||||
|
|
|
@ -270,4 +270,4 @@ static int __init renesas_soc_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(renesas_soc_init);
|
||||
early_initcall(renesas_soc_init);
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#define R8A7795_PD_CA53_SCU 21
|
||||
#define R8A7795_PD_3DG_E 22
|
||||
#define R8A7795_PD_A3IR 24
|
||||
#define R8A7795_PD_A2VC0 25
|
||||
#define R8A7795_PD_A2VC0 25 /* ES1.x only */
|
||||
#define R8A7795_PD_A2VC1 26
|
||||
|
||||
/* Always-on power area */
|
||||
|
|
Loading…
Reference in New Issue