162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * RCPM(Run Control/Power Management) support 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2012-2015 Freescale Semiconductor Inc. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Author: Chenhui Zhao <chenhui.zhao@freescale.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#define pr_fmt(fmt) "%s: " fmt, __func__ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/types.h> 1362306a36Sopenharmony_ci#include <linux/errno.h> 1462306a36Sopenharmony_ci#include <linux/of_address.h> 1562306a36Sopenharmony_ci#include <linux/export.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <asm/io.h> 1862306a36Sopenharmony_ci#include <linux/fsl/guts.h> 1962306a36Sopenharmony_ci#include <asm/cputhreads.h> 2062306a36Sopenharmony_ci#include <asm/fsl_pm.h> 2162306a36Sopenharmony_ci#include <asm/smp.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistatic struct ccsr_rcpm_v1 __iomem *rcpm_v1_regs; 2462306a36Sopenharmony_cistatic struct ccsr_rcpm_v2 __iomem *rcpm_v2_regs; 2562306a36Sopenharmony_cistatic unsigned int fsl_supported_pm_modes; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic void rcpm_v1_irq_mask(int cpu) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci int hw_cpu = get_hard_smp_processor_id(cpu); 3062306a36Sopenharmony_ci unsigned int mask = 1 << hw_cpu; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci setbits32(&rcpm_v1_regs->cpmimr, mask); 3362306a36Sopenharmony_ci setbits32(&rcpm_v1_regs->cpmcimr, mask); 3462306a36Sopenharmony_ci setbits32(&rcpm_v1_regs->cpmmcmr, mask); 3562306a36Sopenharmony_ci setbits32(&rcpm_v1_regs->cpmnmimr, mask); 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic void rcpm_v2_irq_mask(int cpu) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci int hw_cpu = get_hard_smp_processor_id(cpu); 4162306a36Sopenharmony_ci unsigned int mask = 1 << hw_cpu; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->tpmimr0, mask); 4462306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->tpmcimr0, mask); 4562306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->tpmmcmr0, mask); 4662306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->tpmnmimr0, mask); 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic void rcpm_v1_irq_unmask(int cpu) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci int hw_cpu = get_hard_smp_processor_id(cpu); 5262306a36Sopenharmony_ci unsigned int mask = 1 << hw_cpu; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci clrbits32(&rcpm_v1_regs->cpmimr, mask); 5562306a36Sopenharmony_ci clrbits32(&rcpm_v1_regs->cpmcimr, mask); 5662306a36Sopenharmony_ci clrbits32(&rcpm_v1_regs->cpmmcmr, mask); 5762306a36Sopenharmony_ci clrbits32(&rcpm_v1_regs->cpmnmimr, mask); 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic void rcpm_v2_irq_unmask(int cpu) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci int hw_cpu = get_hard_smp_processor_id(cpu); 6362306a36Sopenharmony_ci unsigned int mask = 1 << hw_cpu; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci clrbits32(&rcpm_v2_regs->tpmimr0, mask); 6662306a36Sopenharmony_ci clrbits32(&rcpm_v2_regs->tpmcimr0, mask); 6762306a36Sopenharmony_ci clrbits32(&rcpm_v2_regs->tpmmcmr0, mask); 6862306a36Sopenharmony_ci clrbits32(&rcpm_v2_regs->tpmnmimr0, mask); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistatic void rcpm_v1_set_ip_power(bool enable, u32 mask) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci if (enable) 7462306a36Sopenharmony_ci setbits32(&rcpm_v1_regs->ippdexpcr, mask); 7562306a36Sopenharmony_ci else 7662306a36Sopenharmony_ci clrbits32(&rcpm_v1_regs->ippdexpcr, mask); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic void rcpm_v2_set_ip_power(bool enable, u32 mask) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci if (enable) 8262306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->ippdexpcr[0], mask); 8362306a36Sopenharmony_ci else 8462306a36Sopenharmony_ci clrbits32(&rcpm_v2_regs->ippdexpcr[0], mask); 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic void rcpm_v1_cpu_enter_state(int cpu, int state) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci int hw_cpu = get_hard_smp_processor_id(cpu); 9062306a36Sopenharmony_ci unsigned int mask = 1 << hw_cpu; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci switch (state) { 9362306a36Sopenharmony_ci case E500_PM_PH10: 9462306a36Sopenharmony_ci setbits32(&rcpm_v1_regs->cdozcr, mask); 9562306a36Sopenharmony_ci break; 9662306a36Sopenharmony_ci case E500_PM_PH15: 9762306a36Sopenharmony_ci setbits32(&rcpm_v1_regs->cnapcr, mask); 9862306a36Sopenharmony_ci break; 9962306a36Sopenharmony_ci default: 10062306a36Sopenharmony_ci pr_warn("Unknown cpu PM state (%d)\n", state); 10162306a36Sopenharmony_ci break; 10262306a36Sopenharmony_ci } 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic void rcpm_v2_cpu_enter_state(int cpu, int state) 10662306a36Sopenharmony_ci{ 10762306a36Sopenharmony_ci int hw_cpu = get_hard_smp_processor_id(cpu); 10862306a36Sopenharmony_ci u32 mask = 1 << cpu_core_index_of_thread(cpu); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci switch (state) { 11162306a36Sopenharmony_ci case E500_PM_PH10: 11262306a36Sopenharmony_ci /* one bit corresponds to one thread for PH10 of 6500 */ 11362306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu); 11462306a36Sopenharmony_ci break; 11562306a36Sopenharmony_ci case E500_PM_PH15: 11662306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->pcph15setr, mask); 11762306a36Sopenharmony_ci break; 11862306a36Sopenharmony_ci case E500_PM_PH20: 11962306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->pcph20setr, mask); 12062306a36Sopenharmony_ci break; 12162306a36Sopenharmony_ci case E500_PM_PH30: 12262306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->pcph30setr, mask); 12362306a36Sopenharmony_ci break; 12462306a36Sopenharmony_ci default: 12562306a36Sopenharmony_ci pr_warn("Unknown cpu PM state (%d)\n", state); 12662306a36Sopenharmony_ci } 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic void rcpm_v1_cpu_die(int cpu) 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci rcpm_v1_cpu_enter_state(cpu, E500_PM_PH15); 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci#ifdef CONFIG_PPC64 13562306a36Sopenharmony_cistatic void qoriq_disable_thread(int cpu) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci int thread = cpu_thread_in_core(cpu); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci book3e_stop_thread(thread); 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ci#endif 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_cistatic void rcpm_v2_cpu_die(int cpu) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci#ifdef CONFIG_PPC64 14662306a36Sopenharmony_ci int primary; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci if (threads_per_core == 2) { 14962306a36Sopenharmony_ci primary = cpu_first_thread_sibling(cpu); 15062306a36Sopenharmony_ci if (cpu_is_offline(primary) && cpu_is_offline(primary + 1)) { 15162306a36Sopenharmony_ci /* if both threads are offline, put the cpu in PH20 */ 15262306a36Sopenharmony_ci rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20); 15362306a36Sopenharmony_ci } else { 15462306a36Sopenharmony_ci /* if only one thread is offline, disable the thread */ 15562306a36Sopenharmony_ci qoriq_disable_thread(cpu); 15662306a36Sopenharmony_ci } 15762306a36Sopenharmony_ci } 15862306a36Sopenharmony_ci#endif 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci if (threads_per_core == 1) 16162306a36Sopenharmony_ci rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20); 16262306a36Sopenharmony_ci} 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cistatic void rcpm_v1_cpu_exit_state(int cpu, int state) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci int hw_cpu = get_hard_smp_processor_id(cpu); 16762306a36Sopenharmony_ci unsigned int mask = 1 << hw_cpu; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci switch (state) { 17062306a36Sopenharmony_ci case E500_PM_PH10: 17162306a36Sopenharmony_ci clrbits32(&rcpm_v1_regs->cdozcr, mask); 17262306a36Sopenharmony_ci break; 17362306a36Sopenharmony_ci case E500_PM_PH15: 17462306a36Sopenharmony_ci clrbits32(&rcpm_v1_regs->cnapcr, mask); 17562306a36Sopenharmony_ci break; 17662306a36Sopenharmony_ci default: 17762306a36Sopenharmony_ci pr_warn("Unknown cpu PM state (%d)\n", state); 17862306a36Sopenharmony_ci break; 17962306a36Sopenharmony_ci } 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic void rcpm_v1_cpu_up_prepare(int cpu) 18362306a36Sopenharmony_ci{ 18462306a36Sopenharmony_ci rcpm_v1_cpu_exit_state(cpu, E500_PM_PH15); 18562306a36Sopenharmony_ci rcpm_v1_irq_unmask(cpu); 18662306a36Sopenharmony_ci} 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_cistatic void rcpm_v2_cpu_exit_state(int cpu, int state) 18962306a36Sopenharmony_ci{ 19062306a36Sopenharmony_ci int hw_cpu = get_hard_smp_processor_id(cpu); 19162306a36Sopenharmony_ci u32 mask = 1 << cpu_core_index_of_thread(cpu); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci switch (state) { 19462306a36Sopenharmony_ci case E500_PM_PH10: 19562306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu); 19662306a36Sopenharmony_ci break; 19762306a36Sopenharmony_ci case E500_PM_PH15: 19862306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->pcph15clrr, mask); 19962306a36Sopenharmony_ci break; 20062306a36Sopenharmony_ci case E500_PM_PH20: 20162306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->pcph20clrr, mask); 20262306a36Sopenharmony_ci break; 20362306a36Sopenharmony_ci case E500_PM_PH30: 20462306a36Sopenharmony_ci setbits32(&rcpm_v2_regs->pcph30clrr, mask); 20562306a36Sopenharmony_ci break; 20662306a36Sopenharmony_ci default: 20762306a36Sopenharmony_ci pr_warn("Unknown cpu PM state (%d)\n", state); 20862306a36Sopenharmony_ci } 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_cistatic void rcpm_v2_cpu_up_prepare(int cpu) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci rcpm_v2_cpu_exit_state(cpu, E500_PM_PH20); 21462306a36Sopenharmony_ci rcpm_v2_irq_unmask(cpu); 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_cistatic int rcpm_v1_plat_enter_state(int state) 21862306a36Sopenharmony_ci{ 21962306a36Sopenharmony_ci u32 *pmcsr_reg = &rcpm_v1_regs->powmgtcsr; 22062306a36Sopenharmony_ci int ret = 0; 22162306a36Sopenharmony_ci int result; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci switch (state) { 22462306a36Sopenharmony_ci case PLAT_PM_SLEEP: 22562306a36Sopenharmony_ci setbits32(pmcsr_reg, RCPM_POWMGTCSR_SLP); 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci /* Upon resume, wait for RCPM_POWMGTCSR_SLP bit to be clear. */ 22862306a36Sopenharmony_ci result = spin_event_timeout( 22962306a36Sopenharmony_ci !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_SLP), 10000, 10); 23062306a36Sopenharmony_ci if (!result) { 23162306a36Sopenharmony_ci pr_err("timeout waiting for SLP bit to be cleared\n"); 23262306a36Sopenharmony_ci ret = -ETIMEDOUT; 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci break; 23562306a36Sopenharmony_ci default: 23662306a36Sopenharmony_ci pr_warn("Unknown platform PM state (%d)", state); 23762306a36Sopenharmony_ci ret = -EINVAL; 23862306a36Sopenharmony_ci } 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci return ret; 24162306a36Sopenharmony_ci} 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_cistatic int rcpm_v2_plat_enter_state(int state) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci u32 *pmcsr_reg = &rcpm_v2_regs->powmgtcsr; 24662306a36Sopenharmony_ci int ret = 0; 24762306a36Sopenharmony_ci int result; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci switch (state) { 25062306a36Sopenharmony_ci case PLAT_PM_LPM20: 25162306a36Sopenharmony_ci /* clear previous LPM20 status */ 25262306a36Sopenharmony_ci setbits32(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST); 25362306a36Sopenharmony_ci /* enter LPM20 status */ 25462306a36Sopenharmony_ci setbits32(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ); 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci /* At this point, the device is in LPM20 status. */ 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci /* resume ... */ 25962306a36Sopenharmony_ci result = spin_event_timeout( 26062306a36Sopenharmony_ci !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_LPM20_ST), 10000, 10); 26162306a36Sopenharmony_ci if (!result) { 26262306a36Sopenharmony_ci pr_err("timeout waiting for LPM20 bit to be cleared\n"); 26362306a36Sopenharmony_ci ret = -ETIMEDOUT; 26462306a36Sopenharmony_ci } 26562306a36Sopenharmony_ci break; 26662306a36Sopenharmony_ci default: 26762306a36Sopenharmony_ci pr_warn("Unknown platform PM state (%d)\n", state); 26862306a36Sopenharmony_ci ret = -EINVAL; 26962306a36Sopenharmony_ci } 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci return ret; 27262306a36Sopenharmony_ci} 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_cistatic int rcpm_v1_plat_enter_sleep(void) 27562306a36Sopenharmony_ci{ 27662306a36Sopenharmony_ci return rcpm_v1_plat_enter_state(PLAT_PM_SLEEP); 27762306a36Sopenharmony_ci} 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cistatic int rcpm_v2_plat_enter_sleep(void) 28062306a36Sopenharmony_ci{ 28162306a36Sopenharmony_ci return rcpm_v2_plat_enter_state(PLAT_PM_LPM20); 28262306a36Sopenharmony_ci} 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_cistatic void rcpm_common_freeze_time_base(u32 *tben_reg, int freeze) 28562306a36Sopenharmony_ci{ 28662306a36Sopenharmony_ci static u32 mask; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci if (freeze) { 28962306a36Sopenharmony_ci mask = in_be32(tben_reg); 29062306a36Sopenharmony_ci clrbits32(tben_reg, mask); 29162306a36Sopenharmony_ci } else { 29262306a36Sopenharmony_ci setbits32(tben_reg, mask); 29362306a36Sopenharmony_ci } 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci /* read back to push the previous write */ 29662306a36Sopenharmony_ci in_be32(tben_reg); 29762306a36Sopenharmony_ci} 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_cistatic void rcpm_v1_freeze_time_base(bool freeze) 30062306a36Sopenharmony_ci{ 30162306a36Sopenharmony_ci rcpm_common_freeze_time_base(&rcpm_v1_regs->ctbenr, freeze); 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_cistatic void rcpm_v2_freeze_time_base(bool freeze) 30562306a36Sopenharmony_ci{ 30662306a36Sopenharmony_ci rcpm_common_freeze_time_base(&rcpm_v2_regs->pctbenr, freeze); 30762306a36Sopenharmony_ci} 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_cistatic unsigned int rcpm_get_pm_modes(void) 31062306a36Sopenharmony_ci{ 31162306a36Sopenharmony_ci return fsl_supported_pm_modes; 31262306a36Sopenharmony_ci} 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_cistatic const struct fsl_pm_ops qoriq_rcpm_v1_ops = { 31562306a36Sopenharmony_ci .irq_mask = rcpm_v1_irq_mask, 31662306a36Sopenharmony_ci .irq_unmask = rcpm_v1_irq_unmask, 31762306a36Sopenharmony_ci .cpu_enter_state = rcpm_v1_cpu_enter_state, 31862306a36Sopenharmony_ci .cpu_exit_state = rcpm_v1_cpu_exit_state, 31962306a36Sopenharmony_ci .cpu_up_prepare = rcpm_v1_cpu_up_prepare, 32062306a36Sopenharmony_ci .cpu_die = rcpm_v1_cpu_die, 32162306a36Sopenharmony_ci .plat_enter_sleep = rcpm_v1_plat_enter_sleep, 32262306a36Sopenharmony_ci .set_ip_power = rcpm_v1_set_ip_power, 32362306a36Sopenharmony_ci .freeze_time_base = rcpm_v1_freeze_time_base, 32462306a36Sopenharmony_ci .get_pm_modes = rcpm_get_pm_modes, 32562306a36Sopenharmony_ci}; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic const struct fsl_pm_ops qoriq_rcpm_v2_ops = { 32862306a36Sopenharmony_ci .irq_mask = rcpm_v2_irq_mask, 32962306a36Sopenharmony_ci .irq_unmask = rcpm_v2_irq_unmask, 33062306a36Sopenharmony_ci .cpu_enter_state = rcpm_v2_cpu_enter_state, 33162306a36Sopenharmony_ci .cpu_exit_state = rcpm_v2_cpu_exit_state, 33262306a36Sopenharmony_ci .cpu_up_prepare = rcpm_v2_cpu_up_prepare, 33362306a36Sopenharmony_ci .cpu_die = rcpm_v2_cpu_die, 33462306a36Sopenharmony_ci .plat_enter_sleep = rcpm_v2_plat_enter_sleep, 33562306a36Sopenharmony_ci .set_ip_power = rcpm_v2_set_ip_power, 33662306a36Sopenharmony_ci .freeze_time_base = rcpm_v2_freeze_time_base, 33762306a36Sopenharmony_ci .get_pm_modes = rcpm_get_pm_modes, 33862306a36Sopenharmony_ci}; 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_cistatic const struct of_device_id rcpm_matches[] = { 34162306a36Sopenharmony_ci { 34262306a36Sopenharmony_ci .compatible = "fsl,qoriq-rcpm-1.0", 34362306a36Sopenharmony_ci .data = &qoriq_rcpm_v1_ops, 34462306a36Sopenharmony_ci }, 34562306a36Sopenharmony_ci { 34662306a36Sopenharmony_ci .compatible = "fsl,qoriq-rcpm-2.0", 34762306a36Sopenharmony_ci .data = &qoriq_rcpm_v2_ops, 34862306a36Sopenharmony_ci }, 34962306a36Sopenharmony_ci { 35062306a36Sopenharmony_ci .compatible = "fsl,qoriq-rcpm-2.1", 35162306a36Sopenharmony_ci .data = &qoriq_rcpm_v2_ops, 35262306a36Sopenharmony_ci }, 35362306a36Sopenharmony_ci {}, 35462306a36Sopenharmony_ci}; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ciint __init fsl_rcpm_init(void) 35762306a36Sopenharmony_ci{ 35862306a36Sopenharmony_ci struct device_node *np; 35962306a36Sopenharmony_ci const struct of_device_id *match; 36062306a36Sopenharmony_ci void __iomem *base; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci np = of_find_matching_node_and_match(NULL, rcpm_matches, &match); 36362306a36Sopenharmony_ci if (!np) 36462306a36Sopenharmony_ci return 0; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci base = of_iomap(np, 0); 36762306a36Sopenharmony_ci of_node_put(np); 36862306a36Sopenharmony_ci if (!base) { 36962306a36Sopenharmony_ci pr_err("of_iomap() error.\n"); 37062306a36Sopenharmony_ci return -ENOMEM; 37162306a36Sopenharmony_ci } 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci rcpm_v1_regs = base; 37462306a36Sopenharmony_ci rcpm_v2_regs = base; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci /* support sleep by default */ 37762306a36Sopenharmony_ci fsl_supported_pm_modes = FSL_PM_SLEEP; 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci qoriq_pm_ops = match->data; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci return 0; 38262306a36Sopenharmony_ci} 383