Commit 8b35a3bb authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pmdomain-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm

Pull pmdomain updates from Ulf Hansson:
 "pmdomain core:
   - Don't clear suspended_count at genpd_prepare()
   - Update the rejected/usage counters at system suspend too

  pmdomain providers:
   - ti-sci: Fix duplicate PD referrals
   - mediatek: Add MT8188 buck isolation setting
   - renesas: Add R-Car M3-W power-off delay quirk
   - renesas: Split R-Car M3-W and M3-W+ sub-drivers

  cpuidle-psci:
   - Update MAINTAINERS to set a git for DT IDLE PM DOMAIN/ARM PSCI PM
     DOMAIN
   - Update init level to core_initcall()
   - Drop superfluous wrappers psci_dt_attach|detach_cpu()"

* tag 'pmdomain-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm:
  pmdomain: ti-sci: Fix duplicate PD referrals
  pmdomain: core: Don't clear suspended_count at genpd_prepare()
  pmdomain: core: Update the rejected/usage counters at system suspend too
  pmdomain: renesas: rcar-sysc: Add R-Car M3-W power-off delay quirk
  pmdomain: renesas: rcar-sysc: Remove rcar_sysc_nullify() helper
  pmdomain: renesas: rcar-sysc: Split R-Car M3-W and M3-W+ sub-drivers
  pmdomain: renesas: rcar-sysc: Absorb rcar_sysc_ch into rcar_sysc_pd
  MAINTAINERS: Add a git for the DT IDLE PM DOMAIN
  MAINTAINERS: Add a git for the ARM PSCI PM DOMAIN
  cpuidle: psci: Update init level to core_initcall()
  cpuidle: psci: Drop superfluous wrappers psci_dt_attach|detach_cpu()
  pmdomain: mediatek: Add MT8188 buck isolation setting
  pmdomain: mediatek: scpsys: drop driver owner assignment
parents 6fd600d7 d88ea303
...@@ -5658,6 +5658,7 @@ M: Ulf Hansson <ulf.hansson@linaro.org> ...@@ -5658,6 +5658,7 @@ M: Ulf Hansson <ulf.hansson@linaro.org>
L: linux-pm@vger.kernel.org L: linux-pm@vger.kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Supported S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git
F: drivers/cpuidle/cpuidle-psci-domain.c F: drivers/cpuidle/cpuidle-psci-domain.c
F: drivers/cpuidle/cpuidle-psci.h F: drivers/cpuidle/cpuidle-psci.h
...@@ -5665,6 +5666,7 @@ CPUIDLE DRIVER - DT IDLE PM DOMAIN ...@@ -5665,6 +5666,7 @@ CPUIDLE DRIVER - DT IDLE PM DOMAIN
M: Ulf Hansson <ulf.hansson@linaro.org> M: Ulf Hansson <ulf.hansson@linaro.org>
L: linux-pm@vger.kernel.org L: linux-pm@vger.kernel.org
S: Supported S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git
F: drivers/cpuidle/dt_idle_genpd.c F: drivers/cpuidle/dt_idle_genpd.c
F: drivers/cpuidle/dt_idle_genpd.h F: drivers/cpuidle/dt_idle_genpd.h
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/string.h> #include <linux/string.h>
#include "cpuidle-psci.h" #include "cpuidle-psci.h"
#include "dt_idle_genpd.h"
struct psci_pd_provider { struct psci_pd_provider {
struct list_head link; struct list_head link;
...@@ -200,4 +201,4 @@ static int __init psci_idle_init_domains(void) ...@@ -200,4 +201,4 @@ static int __init psci_idle_init_domains(void)
{ {
return platform_driver_register(&psci_cpuidle_domain_driver); return platform_driver_register(&psci_cpuidle_domain_driver);
} }
subsys_initcall(psci_idle_init_domains); core_initcall(psci_idle_init_domains);
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "cpuidle-psci.h" #include "cpuidle-psci.h"
#include "dt_idle_states.h" #include "dt_idle_states.h"
#include "dt_idle_genpd.h"
struct psci_cpuidle_data { struct psci_cpuidle_data {
u32 *psci_states; u32 *psci_states;
...@@ -224,7 +225,7 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv, ...@@ -224,7 +225,7 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
if (IS_ENABLED(CONFIG_PREEMPT_RT)) if (IS_ENABLED(CONFIG_PREEMPT_RT))
return 0; return 0;
data->dev = psci_dt_attach_cpu(cpu); data->dev = dt_idle_attach_cpu(cpu, "psci");
if (IS_ERR_OR_NULL(data->dev)) if (IS_ERR_OR_NULL(data->dev))
return PTR_ERR_OR_ZERO(data->dev); return PTR_ERR_OR_ZERO(data->dev);
...@@ -311,7 +312,7 @@ static void psci_cpu_deinit_idle(int cpu) ...@@ -311,7 +312,7 @@ static void psci_cpu_deinit_idle(int cpu)
{ {
struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu); struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu);
psci_dt_detach_cpu(data->dev); dt_idle_detach_cpu(data->dev);
psci_cpuidle_use_cpuhp = false; psci_cpuidle_use_cpuhp = false;
} }
......
...@@ -3,29 +3,9 @@ ...@@ -3,29 +3,9 @@
#ifndef __CPUIDLE_PSCI_H #ifndef __CPUIDLE_PSCI_H
#define __CPUIDLE_PSCI_H #define __CPUIDLE_PSCI_H
struct device;
struct device_node; struct device_node;
void psci_set_domain_state(u32 state); void psci_set_domain_state(u32 state);
int psci_dt_parse_state_node(struct device_node *np, u32 *state); int psci_dt_parse_state_node(struct device_node *np, u32 *state);
#ifdef CONFIG_ARM_PSCI_CPUIDLE_DOMAIN
#include "dt_idle_genpd.h"
static inline struct device *psci_dt_attach_cpu(int cpu)
{
return dt_idle_attach_cpu(cpu, "psci");
}
static inline void psci_dt_detach_cpu(struct device *dev)
{
dt_idle_detach_cpu(dev);
}
#else
static inline struct device *psci_dt_attach_cpu(int cpu) { return NULL; }
static inline void psci_dt_detach_cpu(struct device *dev) { }
#endif
#endif /* __CPUIDLE_PSCI_H */ #endif /* __CPUIDLE_PSCI_H */
...@@ -1178,8 +1178,12 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, ...@@ -1178,8 +1178,12 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
/* Choose the deepest state when suspending */ /* Choose the deepest state when suspending */
genpd->state_idx = genpd->state_count - 1; genpd->state_idx = genpd->state_count - 1;
if (_genpd_power_off(genpd, false)) if (_genpd_power_off(genpd, false)) {
genpd->states[genpd->state_idx].rejected++;
return; return;
} else {
genpd->states[genpd->state_idx].usage++;
}
genpd->status = GENPD_STATE_OFF; genpd->status = GENPD_STATE_OFF;
...@@ -1251,10 +1255,7 @@ static int genpd_prepare(struct device *dev) ...@@ -1251,10 +1255,7 @@ static int genpd_prepare(struct device *dev)
return -EINVAL; return -EINVAL;
genpd_lock(genpd); genpd_lock(genpd);
genpd->prepared_count++;
if (genpd->prepared_count++ == 0)
genpd->suspended_count = 0;
genpd_unlock(genpd); genpd_unlock(genpd);
ret = pm_generic_prepare(dev); ret = pm_generic_prepare(dev);
......
...@@ -175,6 +175,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { ...@@ -175,6 +175,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.ctl_offs = 0x35C, .ctl_offs = 0x35C,
.pwr_sta_offs = 0x16C, .pwr_sta_offs = 0x16C,
.pwr_sta2nd_offs = 0x170, .pwr_sta2nd_offs = 0x170,
.ext_buck_iso_offs = 0x3EC,
.ext_buck_iso_mask = BIT(10),
.bp_cfg = { .bp_cfg = {
BUS_PROT_WR(INFRA, BUS_PROT_WR(INFRA,
MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP1, MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP1,
...@@ -187,7 +189,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { ...@@ -187,7 +189,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
MT8188_TOP_AXI_PROT_EN_2_CLR, MT8188_TOP_AXI_PROT_EN_2_CLR,
MT8188_TOP_AXI_PROT_EN_2_STA), MT8188_TOP_AXI_PROT_EN_2_STA),
}, },
.caps = MTK_SCPD_ALWAYS_ON, .caps = MTK_SCPD_ALWAYS_ON | MTK_SCPD_EXT_BUCK_ISO,
}, },
[MT8188_POWER_DOMAIN_ADSP_INFRA] = { [MT8188_POWER_DOMAIN_ADSP_INFRA] = {
.name = "adsp_infra", .name = "adsp_infra",
...@@ -524,6 +526,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { ...@@ -524,6 +526,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.ctl_offs = 0x3A4, .ctl_offs = 0x3A4,
.pwr_sta_offs = 0x16C, .pwr_sta_offs = 0x16C,
.pwr_sta2nd_offs = 0x170, .pwr_sta2nd_offs = 0x170,
.ext_buck_iso_offs = 0x3EC,
.ext_buck_iso_mask = BIT(12),
.bp_cfg = { .bp_cfg = {
BUS_PROT_WR(INFRA, BUS_PROT_WR(INFRA,
MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP1, MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP1,
...@@ -541,7 +545,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { ...@@ -541,7 +545,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
MT8188_TOP_AXI_PROT_EN_MM_2_CLR, MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA), MT8188_TOP_AXI_PROT_EN_MM_2_STA),
}, },
.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY |
MTK_SCPD_EXT_BUCK_ISO,
}, },
[MT8188_POWER_DOMAIN_IMG_MAIN] = { [MT8188_POWER_DOMAIN_IMG_MAIN] = {
.name = "img_main", .name = "img_main",
...@@ -591,6 +596,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { ...@@ -591,6 +596,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
.ctl_offs = 0x3A0, .ctl_offs = 0x3A0,
.pwr_sta_offs = 0x16C, .pwr_sta_offs = 0x16C,
.pwr_sta2nd_offs = 0x170, .pwr_sta2nd_offs = 0x170,
.ext_buck_iso_offs = 0x3EC,
.ext_buck_iso_mask = BIT(11),
.bp_cfg = { .bp_cfg = {
BUS_PROT_WR(INFRA, BUS_PROT_WR(INFRA,
MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP1, MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP1,
...@@ -618,7 +625,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { ...@@ -618,7 +625,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
MT8188_TOP_AXI_PROT_EN_MM_2_CLR, MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
MT8188_TOP_AXI_PROT_EN_MM_2_STA), MT8188_TOP_AXI_PROT_EN_MM_2_STA),
}, },
.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY |
MTK_SCPD_EXT_BUCK_ISO,
}, },
[MT8188_POWER_DOMAIN_CAM_MAIN] = { [MT8188_POWER_DOMAIN_CAM_MAIN] = {
.name = "cam_main", .name = "cam_main",
......
...@@ -1138,7 +1138,6 @@ static struct platform_driver scpsys_drv = { ...@@ -1138,7 +1138,6 @@ static struct platform_driver scpsys_drv = {
.driver = { .driver = {
.name = "mtk-scpsys", .name = "mtk-scpsys",
.suppress_bind_attrs = true, .suppress_bind_attrs = true,
.owner = THIS_MODULE,
.of_match_table = of_scpsys_match_tbl, .of_match_table = of_scpsys_match_tbl,
}, },
}; };
......
...@@ -14,8 +14,8 @@ obj-$(CONFIG_SYSC_R8A7791) += r8a7791-sysc.o ...@@ -14,8 +14,8 @@ obj-$(CONFIG_SYSC_R8A7791) += r8a7791-sysc.o
obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o
obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o
obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o
obj-$(CONFIG_SYSC_R8A77960) += r8a7796-sysc.o obj-$(CONFIG_SYSC_R8A77960) += r8a77960-sysc.o
obj-$(CONFIG_SYSC_R8A77961) += r8a7796-sysc.o obj-$(CONFIG_SYSC_R8A77961) += r8a77961-sysc.o
obj-$(CONFIG_SYSC_R8A77965) += r8a77965-sysc.o obj-$(CONFIG_SYSC_R8A77965) += r8a77965-sysc.o
obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o
obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o
......
// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car M3-W System Controller
*
* Copyright (C) 2016 Glider bvba
* Copyright (C) 2018-2019 Renesas Electronics Corporation
*/
#include <linux/bits.h>
#include <linux/kernel.h>
#include <dt-bindings/power/r8a7796-sysc.h>
#include "rcar-sysc.h"
static const struct rcar_sysc_area r8a77960_areas[] __initconst = {
{ "always-on", 0, 0, R8A7796_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
{ "ca57-scu", 0x1c0, 0, R8A7796_PD_CA57_SCU, R8A7796_PD_ALWAYS_ON,
PD_SCU },
{ "ca57-cpu0", 0x80, 0, R8A7796_PD_CA57_CPU0, R8A7796_PD_CA57_SCU,
PD_CPU_NOCR },
{ "ca57-cpu1", 0x80, 1, R8A7796_PD_CA57_CPU1, R8A7796_PD_CA57_SCU,
PD_CPU_NOCR },
{ "ca53-scu", 0x140, 0, R8A7796_PD_CA53_SCU, R8A7796_PD_ALWAYS_ON,
PD_SCU },
{ "ca53-cpu0", 0x200, 0, R8A7796_PD_CA53_CPU0, R8A7796_PD_CA53_SCU,
PD_CPU_NOCR },
{ "ca53-cpu1", 0x200, 1, R8A7796_PD_CA53_CPU1, R8A7796_PD_CA53_SCU,
PD_CPU_NOCR },
{ "ca53-cpu2", 0x200, 2, R8A7796_PD_CA53_CPU2, R8A7796_PD_CA53_SCU,
PD_CPU_NOCR },
{ "ca53-cpu3", 0x200, 3, R8A7796_PD_CA53_CPU3, R8A7796_PD_CA53_SCU,
PD_CPU_NOCR },
{ "cr7", 0x240, 0, R8A7796_PD_CR7, R8A7796_PD_ALWAYS_ON },
{ "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON,
PD_OFF_DELAY },
{ "a2vc0", 0x3c0, 0, R8A7796_PD_A2VC0, R8A7796_PD_A3VC },
{ "a2vc1", 0x3c0, 1, R8A7796_PD_A2VC1, R8A7796_PD_A3VC },
{ "3dg-a", 0x100, 0, R8A7796_PD_3DG_A, R8A7796_PD_ALWAYS_ON },
{ "3dg-b", 0x100, 1, R8A7796_PD_3DG_B, R8A7796_PD_3DG_A },
{ "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON,
PD_OFF_DELAY },
};
const struct rcar_sysc_info r8a77960_sysc_info __initconst = {
.areas = r8a77960_areas,
.num_areas = ARRAY_SIZE(r8a77960_areas),
};
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* /*
* Renesas R-Car M3-W/W+ System Controller * Renesas R-Car M3-W+ System Controller
* *
* Copyright (C) 2016 Glider bvba * Copyright (C) 2016 Glider bvba
* Copyright (C) 2018-2019 Renesas Electronics Corporation * Copyright (C) 2018-2019 Renesas Electronics Corporation
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "rcar-sysc.h" #include "rcar-sysc.h"
static struct rcar_sysc_area r8a7796_areas[] __initdata = { static const struct rcar_sysc_area r8a77961_areas[] __initconst = {
{ "always-on", 0, 0, R8A7796_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, { "always-on", 0, 0, R8A7796_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
{ "ca57-scu", 0x1c0, 0, R8A7796_PD_CA57_SCU, R8A7796_PD_ALWAYS_ON, { "ca57-scu", 0x1c0, 0, R8A7796_PD_CA57_SCU, R8A7796_PD_ALWAYS_ON,
PD_SCU }, PD_SCU },
...@@ -33,35 +33,15 @@ static struct rcar_sysc_area r8a7796_areas[] __initdata = { ...@@ -33,35 +33,15 @@ static struct rcar_sysc_area r8a7796_areas[] __initdata = {
PD_CPU_NOCR }, PD_CPU_NOCR },
{ "cr7", 0x240, 0, R8A7796_PD_CR7, R8A7796_PD_ALWAYS_ON }, { "cr7", 0x240, 0, R8A7796_PD_CR7, R8A7796_PD_ALWAYS_ON },
{ "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON }, { "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON },
{ "a2vc0", 0x3c0, 0, R8A7796_PD_A2VC0, R8A7796_PD_A3VC },
{ "a2vc1", 0x3c0, 1, R8A7796_PD_A2VC1, R8A7796_PD_A3VC }, { "a2vc1", 0x3c0, 1, R8A7796_PD_A2VC1, R8A7796_PD_A3VC },
{ "3dg-a", 0x100, 0, R8A7796_PD_3DG_A, R8A7796_PD_ALWAYS_ON }, { "3dg-a", 0x100, 0, R8A7796_PD_3DG_A, R8A7796_PD_ALWAYS_ON },
{ "3dg-b", 0x100, 1, R8A7796_PD_3DG_B, R8A7796_PD_3DG_A }, { "3dg-b", 0x100, 1, R8A7796_PD_3DG_B, R8A7796_PD_3DG_A },
{ "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON }, { "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON },
}; };
#ifdef CONFIG_SYSC_R8A77960
const struct rcar_sysc_info r8a77960_sysc_info __initconst = {
.areas = r8a7796_areas,
.num_areas = ARRAY_SIZE(r8a7796_areas),
};
#endif /* CONFIG_SYSC_R8A77960 */
#ifdef CONFIG_SYSC_R8A77961
static int __init r8a77961_sysc_init(void)
{
rcar_sysc_nullify(r8a7796_areas, ARRAY_SIZE(r8a7796_areas),
R8A7796_PD_A2VC0);
return 0;
}
const struct rcar_sysc_info r8a77961_sysc_info __initconst = { const struct rcar_sysc_info r8a77961_sysc_info __initconst = {
.init = r8a77961_sysc_init, .areas = r8a77961_areas,
.areas = r8a7796_areas, .num_areas = ARRAY_SIZE(r8a77961_areas),
.num_areas = ARRAY_SIZE(r8a7796_areas),
.extmask_offs = 0x2f8, .extmask_offs = 0x2f8,
.extmask_val = BIT(0), .extmask_val = BIT(0),
}; };
#endif /* CONFIG_SYSC_R8A77961 */
...@@ -56,17 +56,20 @@ ...@@ -56,17 +56,20 @@
#define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */ #define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */
struct rcar_sysc_ch { struct rcar_sysc_pd {
struct generic_pm_domain genpd;
u16 chan_offs; u16 chan_offs;
u8 chan_bit; u8 chan_bit;
u8 isr_bit; u8 isr_bit;
unsigned int flags;
char name[];
}; };
static void __iomem *rcar_sysc_base; static void __iomem *rcar_sysc_base;
static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */ static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
static u32 rcar_sysc_extmask_offs, rcar_sysc_extmask_val; static u32 rcar_sysc_extmask_offs, rcar_sysc_extmask_val;
static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on) static int rcar_sysc_pwr_on_off(const struct rcar_sysc_pd *pd, bool on)
{ {
unsigned int sr_bit, reg_offs; unsigned int sr_bit, reg_offs;
u32 val; u32 val;
...@@ -87,17 +90,20 @@ static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on) ...@@ -87,17 +90,20 @@ static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)
if (ret) if (ret)
return -EAGAIN; return -EAGAIN;
/* Power-off delay quirk */
if (!on && (pd->flags & PD_OFF_DELAY))
udelay(1);
/* Submit power shutoff or power resume request */ /* Submit power shutoff or power resume request */
iowrite32(BIT(sysc_ch->chan_bit), iowrite32(BIT(pd->chan_bit), rcar_sysc_base + pd->chan_offs + reg_offs);
rcar_sysc_base + sysc_ch->chan_offs + reg_offs);
return 0; return 0;
} }
static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on) static int rcar_sysc_power(const struct rcar_sysc_pd *pd, bool on)
{ {
unsigned int isr_mask = BIT(sysc_ch->isr_bit); unsigned int isr_mask = BIT(pd->isr_bit);
unsigned int chan_mask = BIT(sysc_ch->chan_bit); unsigned int chan_mask = BIT(pd->chan_bit);
unsigned int status, k; unsigned int status, k;
unsigned long flags; unsigned long flags;
int ret; int ret;
...@@ -125,12 +131,11 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on) ...@@ -125,12 +131,11 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
/* Submit power shutoff or resume request until it was accepted */ /* Submit power shutoff or resume request until it was accepted */
for (k = 0; k < PWRER_RETRIES; k++) { for (k = 0; k < PWRER_RETRIES; k++) {
ret = rcar_sysc_pwr_on_off(sysc_ch, on); ret = rcar_sysc_pwr_on_off(pd, on);
if (ret) if (ret)
goto out; goto out;
status = ioread32(rcar_sysc_base + status = ioread32(rcar_sysc_base + pd->chan_offs + PWRER_OFFS);
sysc_ch->chan_offs + PWRER_OFFS);
if (!(status & chan_mask)) if (!(status & chan_mask))
break; break;
...@@ -158,28 +163,21 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on) ...@@ -158,28 +163,21 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
spin_unlock_irqrestore(&rcar_sysc_lock, flags); spin_unlock_irqrestore(&rcar_sysc_lock, flags);
pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off", pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off",
sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret); pd->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret);
return ret; return ret;
} }
static bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch) static bool rcar_sysc_power_is_off(const struct rcar_sysc_pd *pd)
{ {
unsigned int st; unsigned int st;
st = ioread32(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS); st = ioread32(rcar_sysc_base + pd->chan_offs + PWRSR_OFFS);
if (st & BIT(sysc_ch->chan_bit)) if (st & BIT(pd->chan_bit))
return true; return true;
return false; return false;
} }
struct rcar_sysc_pd {
struct generic_pm_domain genpd;
struct rcar_sysc_ch ch;
unsigned int flags;
char name[];
};
static inline struct rcar_sysc_pd *to_rcar_pd(struct generic_pm_domain *d) static inline struct rcar_sysc_pd *to_rcar_pd(struct generic_pm_domain *d)
{ {
return container_of(d, struct rcar_sysc_pd, genpd); return container_of(d, struct rcar_sysc_pd, genpd);
...@@ -190,7 +188,7 @@ static int rcar_sysc_pd_power_off(struct generic_pm_domain *genpd) ...@@ -190,7 +188,7 @@ static int rcar_sysc_pd_power_off(struct generic_pm_domain *genpd)
struct rcar_sysc_pd *pd = to_rcar_pd(genpd); struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
pr_debug("%s: %s\n", __func__, genpd->name); pr_debug("%s: %s\n", __func__, genpd->name);
return rcar_sysc_power(&pd->ch, false); return rcar_sysc_power(pd, false);
} }
static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd) static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
...@@ -198,7 +196,7 @@ static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd) ...@@ -198,7 +196,7 @@ static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
struct rcar_sysc_pd *pd = to_rcar_pd(genpd); struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
pr_debug("%s: %s\n", __func__, genpd->name); pr_debug("%s: %s\n", __func__, genpd->name);
return rcar_sysc_power(&pd->ch, true); return rcar_sysc_power(pd, true);
} }
static bool has_cpg_mstp; static bool has_cpg_mstp;
...@@ -252,12 +250,12 @@ static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd) ...@@ -252,12 +250,12 @@ static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
goto finalize; goto finalize;
} }
if (!rcar_sysc_power_is_off(&pd->ch)) { if (!rcar_sysc_power_is_off(pd)) {
pr_debug("%s: %s is already powered\n", __func__, genpd->name); pr_debug("%s: %s is already powered\n", __func__, genpd->name);
goto finalize; goto finalize;
} }
rcar_sysc_power(&pd->ch, true); rcar_sysc_power(pd, true);
finalize: finalize:
error = pm_genpd_init(genpd, &simple_qos_governor, false); error = pm_genpd_init(genpd, &simple_qos_governor, false);
...@@ -412,9 +410,9 @@ static int __init rcar_sysc_pd_init(void) ...@@ -412,9 +410,9 @@ static int __init rcar_sysc_pd_init(void)
memcpy(pd->name, area->name, n); memcpy(pd->name, area->name, n);
pd->genpd.name = pd->name; pd->genpd.name = pd->name;
pd->ch.chan_offs = area->chan_offs; pd->chan_offs = area->chan_offs;
pd->ch.chan_bit = area->chan_bit; pd->chan_bit = area->chan_bit;
pd->ch.isr_bit = area->isr_bit; pd->isr_bit = area->isr_bit;
pd->flags = area->flags; pd->flags = area->flags;
error = rcar_sysc_pd_setup(pd); error = rcar_sysc_pd_setup(pd);
...@@ -445,18 +443,6 @@ static int __init rcar_sysc_pd_init(void) ...@@ -445,18 +443,6 @@ static int __init rcar_sysc_pd_init(void)
} }
early_initcall(rcar_sysc_pd_init); 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;
}
}
#ifdef CONFIG_ARCH_R8A7779 #ifdef CONFIG_ARCH_R8A7779
static int rcar_sysc_power_cpu(unsigned int idx, bool on) static int rcar_sysc_power_cpu(unsigned int idx, bool on)
{ {
...@@ -473,10 +459,10 @@ static int rcar_sysc_power_cpu(unsigned int idx, bool on) ...@@ -473,10 +459,10 @@ static int rcar_sysc_power_cpu(unsigned int idx, bool on)
continue; continue;
pd = to_rcar_pd(genpd); pd = to_rcar_pd(genpd);
if (!(pd->flags & PD_CPU) || pd->ch.chan_bit != idx) if (!(pd->flags & PD_CPU) || pd->chan_bit != idx)
continue; continue;
return rcar_sysc_power(&pd->ch, on); return rcar_sysc_power(pd, on);
} }
return -ENOENT; return -ENOENT;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#define PD_CPU BIT(0) /* Area contains main CPU core */ #define PD_CPU BIT(0) /* Area contains main CPU core */
#define PD_SCU BIT(1) /* Area contains SCU and L2 cache */ #define PD_SCU BIT(1) /* Area contains SCU and L2 cache */
#define PD_NO_CR BIT(2) /* Area lacks PWR{ON,OFF}CR registers */ #define PD_NO_CR BIT(2) /* Area lacks PWR{ON,OFF}CR registers */
#define PD_OFF_DELAY BIT(3) /* Area is subject to power-off delay quirk */
#define PD_CPU_CR PD_CPU /* CPU area has CR (R-Car H1) */ #define PD_CPU_CR PD_CPU /* CPU area has CR (R-Car H1) */
#define PD_CPU_NOCR PD_CPU | PD_NO_CR /* CPU area lacks CR (R-Car Gen2/3) */ #define PD_CPU_NOCR PD_CPU | PD_NO_CR /* CPU area lacks CR (R-Car Gen2/3) */
...@@ -71,12 +72,4 @@ extern const struct rcar_sysc_info r8a77980_sysc_info; ...@@ -71,12 +72,4 @@ extern const struct rcar_sysc_info r8a77980_sysc_info;
extern const struct rcar_sysc_info r8a77990_sysc_info; extern const struct rcar_sysc_info r8a77990_sysc_info;
extern const struct rcar_sysc_info r8a77995_sysc_info; extern const struct rcar_sysc_info r8a77995_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__ */ #endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
...@@ -114,6 +114,18 @@ static const struct of_device_id ti_sci_pm_domain_matches[] = { ...@@ -114,6 +114,18 @@ static const struct of_device_id ti_sci_pm_domain_matches[] = {
}; };
MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches); MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches);
static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32 idx)
{
struct ti_sci_pm_domain *pd;
list_for_each_entry(pd, &pd_provider->pd_list, node) {
if (pd->idx == idx)
return true;
}
return false;
}
static int ti_sci_pm_domain_probe(struct platform_device *pdev) static int ti_sci_pm_domain_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -149,8 +161,14 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) ...@@ -149,8 +161,14 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
break; break;
if (args.args_count >= 1 && args.np == dev->of_node) { if (args.args_count >= 1 && args.np == dev->of_node) {
if (args.args[0] > max_id) if (args.args[0] > max_id) {
max_id = args.args[0]; max_id = args.args[0];
} else {
if (ti_sci_pm_idx_exists(pd_provider, args.args[0])) {
index++;
continue;
}
}
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
if (!pd) { if (!pd) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment