12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2d17799f9Schenhui zhao /*
3d17799f9Schenhui zhao * RCPM(Run Control/Power Management) support
4d17799f9Schenhui zhao *
5d17799f9Schenhui zhao * Copyright 2012-2015 Freescale Semiconductor Inc.
6d17799f9Schenhui zhao *
7d17799f9Schenhui zhao * Author: Chenhui Zhao <chenhui.zhao@freescale.com>
8d17799f9Schenhui zhao */
9d17799f9Schenhui zhao
10d17799f9Schenhui zhao #define pr_fmt(fmt) "%s: " fmt, __func__
11d17799f9Schenhui zhao
12d17799f9Schenhui zhao #include <linux/types.h>
13d17799f9Schenhui zhao #include <linux/errno.h>
14d17799f9Schenhui zhao #include <linux/of_address.h>
15d17799f9Schenhui zhao #include <linux/export.h>
16d17799f9Schenhui zhao
17d17799f9Schenhui zhao #include <asm/io.h>
18d17799f9Schenhui zhao #include <linux/fsl/guts.h>
19d17799f9Schenhui zhao #include <asm/cputhreads.h>
20d17799f9Schenhui zhao #include <asm/fsl_pm.h>
21b081251eSMichael Ellerman #include <asm/smp.h>
22d17799f9Schenhui zhao
23d17799f9Schenhui zhao static struct ccsr_rcpm_v1 __iomem *rcpm_v1_regs;
24d17799f9Schenhui zhao static struct ccsr_rcpm_v2 __iomem *rcpm_v2_regs;
25d17799f9Schenhui zhao static unsigned int fsl_supported_pm_modes;
26d17799f9Schenhui zhao
rcpm_v1_irq_mask(int cpu)27d17799f9Schenhui zhao static void rcpm_v1_irq_mask(int cpu)
28d17799f9Schenhui zhao {
29d17799f9Schenhui zhao int hw_cpu = get_hard_smp_processor_id(cpu);
30d17799f9Schenhui zhao unsigned int mask = 1 << hw_cpu;
31d17799f9Schenhui zhao
32d17799f9Schenhui zhao setbits32(&rcpm_v1_regs->cpmimr, mask);
33d17799f9Schenhui zhao setbits32(&rcpm_v1_regs->cpmcimr, mask);
34d17799f9Schenhui zhao setbits32(&rcpm_v1_regs->cpmmcmr, mask);
35d17799f9Schenhui zhao setbits32(&rcpm_v1_regs->cpmnmimr, mask);
36d17799f9Schenhui zhao }
37d17799f9Schenhui zhao
rcpm_v2_irq_mask(int cpu)38d17799f9Schenhui zhao static void rcpm_v2_irq_mask(int cpu)
39d17799f9Schenhui zhao {
40d17799f9Schenhui zhao int hw_cpu = get_hard_smp_processor_id(cpu);
41d17799f9Schenhui zhao unsigned int mask = 1 << hw_cpu;
42d17799f9Schenhui zhao
43d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->tpmimr0, mask);
44d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->tpmcimr0, mask);
45d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->tpmmcmr0, mask);
46d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->tpmnmimr0, mask);
47d17799f9Schenhui zhao }
48d17799f9Schenhui zhao
rcpm_v1_irq_unmask(int cpu)49d17799f9Schenhui zhao static void rcpm_v1_irq_unmask(int cpu)
50d17799f9Schenhui zhao {
51d17799f9Schenhui zhao int hw_cpu = get_hard_smp_processor_id(cpu);
52d17799f9Schenhui zhao unsigned int mask = 1 << hw_cpu;
53d17799f9Schenhui zhao
54d17799f9Schenhui zhao clrbits32(&rcpm_v1_regs->cpmimr, mask);
55d17799f9Schenhui zhao clrbits32(&rcpm_v1_regs->cpmcimr, mask);
56d17799f9Schenhui zhao clrbits32(&rcpm_v1_regs->cpmmcmr, mask);
57d17799f9Schenhui zhao clrbits32(&rcpm_v1_regs->cpmnmimr, mask);
58d17799f9Schenhui zhao }
59d17799f9Schenhui zhao
rcpm_v2_irq_unmask(int cpu)60d17799f9Schenhui zhao static void rcpm_v2_irq_unmask(int cpu)
61d17799f9Schenhui zhao {
62d17799f9Schenhui zhao int hw_cpu = get_hard_smp_processor_id(cpu);
63d17799f9Schenhui zhao unsigned int mask = 1 << hw_cpu;
64d17799f9Schenhui zhao
65d17799f9Schenhui zhao clrbits32(&rcpm_v2_regs->tpmimr0, mask);
66d17799f9Schenhui zhao clrbits32(&rcpm_v2_regs->tpmcimr0, mask);
67d17799f9Schenhui zhao clrbits32(&rcpm_v2_regs->tpmmcmr0, mask);
68d17799f9Schenhui zhao clrbits32(&rcpm_v2_regs->tpmnmimr0, mask);
69d17799f9Schenhui zhao }
70d17799f9Schenhui zhao
rcpm_v1_set_ip_power(bool enable,u32 mask)71d17799f9Schenhui zhao static void rcpm_v1_set_ip_power(bool enable, u32 mask)
72d17799f9Schenhui zhao {
73d17799f9Schenhui zhao if (enable)
74d17799f9Schenhui zhao setbits32(&rcpm_v1_regs->ippdexpcr, mask);
75d17799f9Schenhui zhao else
76d17799f9Schenhui zhao clrbits32(&rcpm_v1_regs->ippdexpcr, mask);
77d17799f9Schenhui zhao }
78d17799f9Schenhui zhao
rcpm_v2_set_ip_power(bool enable,u32 mask)79d17799f9Schenhui zhao static void rcpm_v2_set_ip_power(bool enable, u32 mask)
80d17799f9Schenhui zhao {
81d17799f9Schenhui zhao if (enable)
82d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
83d17799f9Schenhui zhao else
84d17799f9Schenhui zhao clrbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
85d17799f9Schenhui zhao }
86d17799f9Schenhui zhao
rcpm_v1_cpu_enter_state(int cpu,int state)87d17799f9Schenhui zhao static void rcpm_v1_cpu_enter_state(int cpu, int state)
88d17799f9Schenhui zhao {
89d17799f9Schenhui zhao int hw_cpu = get_hard_smp_processor_id(cpu);
90d17799f9Schenhui zhao unsigned int mask = 1 << hw_cpu;
91d17799f9Schenhui zhao
92d17799f9Schenhui zhao switch (state) {
93d17799f9Schenhui zhao case E500_PM_PH10:
94d17799f9Schenhui zhao setbits32(&rcpm_v1_regs->cdozcr, mask);
95d17799f9Schenhui zhao break;
96d17799f9Schenhui zhao case E500_PM_PH15:
97d17799f9Schenhui zhao setbits32(&rcpm_v1_regs->cnapcr, mask);
98d17799f9Schenhui zhao break;
99d17799f9Schenhui zhao default:
100d17799f9Schenhui zhao pr_warn("Unknown cpu PM state (%d)\n", state);
101d17799f9Schenhui zhao break;
102d17799f9Schenhui zhao }
103d17799f9Schenhui zhao }
104d17799f9Schenhui zhao
rcpm_v2_cpu_enter_state(int cpu,int state)105d17799f9Schenhui zhao static void rcpm_v2_cpu_enter_state(int cpu, int state)
106d17799f9Schenhui zhao {
107d17799f9Schenhui zhao int hw_cpu = get_hard_smp_processor_id(cpu);
108d17799f9Schenhui zhao u32 mask = 1 << cpu_core_index_of_thread(cpu);
109d17799f9Schenhui zhao
110d17799f9Schenhui zhao switch (state) {
111d17799f9Schenhui zhao case E500_PM_PH10:
112d17799f9Schenhui zhao /* one bit corresponds to one thread for PH10 of 6500 */
113d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu);
114d17799f9Schenhui zhao break;
115d17799f9Schenhui zhao case E500_PM_PH15:
116d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->pcph15setr, mask);
117d17799f9Schenhui zhao break;
118d17799f9Schenhui zhao case E500_PM_PH20:
119d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->pcph20setr, mask);
120d17799f9Schenhui zhao break;
121d17799f9Schenhui zhao case E500_PM_PH30:
122d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->pcph30setr, mask);
123d17799f9Schenhui zhao break;
124d17799f9Schenhui zhao default:
125d17799f9Schenhui zhao pr_warn("Unknown cpu PM state (%d)\n", state);
126d17799f9Schenhui zhao }
127d17799f9Schenhui zhao }
128d17799f9Schenhui zhao
rcpm_v1_cpu_die(int cpu)129d17799f9Schenhui zhao static void rcpm_v1_cpu_die(int cpu)
130d17799f9Schenhui zhao {
131d17799f9Schenhui zhao rcpm_v1_cpu_enter_state(cpu, E500_PM_PH15);
132d17799f9Schenhui zhao }
133d17799f9Schenhui zhao
134d17799f9Schenhui zhao #ifdef CONFIG_PPC64
qoriq_disable_thread(int cpu)135d17799f9Schenhui zhao static void qoriq_disable_thread(int cpu)
136d17799f9Schenhui zhao {
137d17799f9Schenhui zhao int thread = cpu_thread_in_core(cpu);
138d17799f9Schenhui zhao
139d17799f9Schenhui zhao book3e_stop_thread(thread);
140d17799f9Schenhui zhao }
141d17799f9Schenhui zhao #endif
142d17799f9Schenhui zhao
rcpm_v2_cpu_die(int cpu)143d17799f9Schenhui zhao static void rcpm_v2_cpu_die(int cpu)
144d17799f9Schenhui zhao {
145d17799f9Schenhui zhao #ifdef CONFIG_PPC64
146d17799f9Schenhui zhao int primary;
147d17799f9Schenhui zhao
148d17799f9Schenhui zhao if (threads_per_core == 2) {
149d17799f9Schenhui zhao primary = cpu_first_thread_sibling(cpu);
150d17799f9Schenhui zhao if (cpu_is_offline(primary) && cpu_is_offline(primary + 1)) {
151d17799f9Schenhui zhao /* if both threads are offline, put the cpu in PH20 */
152d17799f9Schenhui zhao rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20);
153d17799f9Schenhui zhao } else {
154d17799f9Schenhui zhao /* if only one thread is offline, disable the thread */
155d17799f9Schenhui zhao qoriq_disable_thread(cpu);
156d17799f9Schenhui zhao }
157d17799f9Schenhui zhao }
158d17799f9Schenhui zhao #endif
159d17799f9Schenhui zhao
160d17799f9Schenhui zhao if (threads_per_core == 1)
161d17799f9Schenhui zhao rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20);
162d17799f9Schenhui zhao }
163d17799f9Schenhui zhao
rcpm_v1_cpu_exit_state(int cpu,int state)164d17799f9Schenhui zhao static void rcpm_v1_cpu_exit_state(int cpu, int state)
165d17799f9Schenhui zhao {
166d17799f9Schenhui zhao int hw_cpu = get_hard_smp_processor_id(cpu);
167d17799f9Schenhui zhao unsigned int mask = 1 << hw_cpu;
168d17799f9Schenhui zhao
169d17799f9Schenhui zhao switch (state) {
170d17799f9Schenhui zhao case E500_PM_PH10:
171d17799f9Schenhui zhao clrbits32(&rcpm_v1_regs->cdozcr, mask);
172d17799f9Schenhui zhao break;
173d17799f9Schenhui zhao case E500_PM_PH15:
174d17799f9Schenhui zhao clrbits32(&rcpm_v1_regs->cnapcr, mask);
175d17799f9Schenhui zhao break;
176d17799f9Schenhui zhao default:
177d17799f9Schenhui zhao pr_warn("Unknown cpu PM state (%d)\n", state);
178d17799f9Schenhui zhao break;
179d17799f9Schenhui zhao }
180d17799f9Schenhui zhao }
181d17799f9Schenhui zhao
rcpm_v1_cpu_up_prepare(int cpu)182d17799f9Schenhui zhao static void rcpm_v1_cpu_up_prepare(int cpu)
183d17799f9Schenhui zhao {
184d17799f9Schenhui zhao rcpm_v1_cpu_exit_state(cpu, E500_PM_PH15);
185d17799f9Schenhui zhao rcpm_v1_irq_unmask(cpu);
186d17799f9Schenhui zhao }
187d17799f9Schenhui zhao
rcpm_v2_cpu_exit_state(int cpu,int state)188d17799f9Schenhui zhao static void rcpm_v2_cpu_exit_state(int cpu, int state)
189d17799f9Schenhui zhao {
190d17799f9Schenhui zhao int hw_cpu = get_hard_smp_processor_id(cpu);
191d17799f9Schenhui zhao u32 mask = 1 << cpu_core_index_of_thread(cpu);
192d17799f9Schenhui zhao
193d17799f9Schenhui zhao switch (state) {
194d17799f9Schenhui zhao case E500_PM_PH10:
195d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu);
196d17799f9Schenhui zhao break;
197d17799f9Schenhui zhao case E500_PM_PH15:
198d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->pcph15clrr, mask);
199d17799f9Schenhui zhao break;
200d17799f9Schenhui zhao case E500_PM_PH20:
201d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->pcph20clrr, mask);
202d17799f9Schenhui zhao break;
203d17799f9Schenhui zhao case E500_PM_PH30:
204d17799f9Schenhui zhao setbits32(&rcpm_v2_regs->pcph30clrr, mask);
205d17799f9Schenhui zhao break;
206d17799f9Schenhui zhao default:
207d17799f9Schenhui zhao pr_warn("Unknown cpu PM state (%d)\n", state);
208d17799f9Schenhui zhao }
209d17799f9Schenhui zhao }
210d17799f9Schenhui zhao
rcpm_v2_cpu_up_prepare(int cpu)211d17799f9Schenhui zhao static void rcpm_v2_cpu_up_prepare(int cpu)
212d17799f9Schenhui zhao {
213d17799f9Schenhui zhao rcpm_v2_cpu_exit_state(cpu, E500_PM_PH20);
214d17799f9Schenhui zhao rcpm_v2_irq_unmask(cpu);
215d17799f9Schenhui zhao }
216d17799f9Schenhui zhao
rcpm_v1_plat_enter_state(int state)217d17799f9Schenhui zhao static int rcpm_v1_plat_enter_state(int state)
218d17799f9Schenhui zhao {
219d17799f9Schenhui zhao u32 *pmcsr_reg = &rcpm_v1_regs->powmgtcsr;
220d17799f9Schenhui zhao int ret = 0;
221d17799f9Schenhui zhao int result;
222d17799f9Schenhui zhao
223d17799f9Schenhui zhao switch (state) {
224d17799f9Schenhui zhao case PLAT_PM_SLEEP:
225d17799f9Schenhui zhao setbits32(pmcsr_reg, RCPM_POWMGTCSR_SLP);
226d17799f9Schenhui zhao
227d17799f9Schenhui zhao /* Upon resume, wait for RCPM_POWMGTCSR_SLP bit to be clear. */
228d17799f9Schenhui zhao result = spin_event_timeout(
229d17799f9Schenhui zhao !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_SLP), 10000, 10);
230d17799f9Schenhui zhao if (!result) {
231d17799f9Schenhui zhao pr_err("timeout waiting for SLP bit to be cleared\n");
232d17799f9Schenhui zhao ret = -ETIMEDOUT;
233d17799f9Schenhui zhao }
234d17799f9Schenhui zhao break;
235d17799f9Schenhui zhao default:
236d17799f9Schenhui zhao pr_warn("Unknown platform PM state (%d)", state);
237d17799f9Schenhui zhao ret = -EINVAL;
238d17799f9Schenhui zhao }
239d17799f9Schenhui zhao
240d17799f9Schenhui zhao return ret;
241d17799f9Schenhui zhao }
242d17799f9Schenhui zhao
rcpm_v2_plat_enter_state(int state)243d17799f9Schenhui zhao static int rcpm_v2_plat_enter_state(int state)
244d17799f9Schenhui zhao {
245d17799f9Schenhui zhao u32 *pmcsr_reg = &rcpm_v2_regs->powmgtcsr;
246d17799f9Schenhui zhao int ret = 0;
247d17799f9Schenhui zhao int result;
248d17799f9Schenhui zhao
249d17799f9Schenhui zhao switch (state) {
250d17799f9Schenhui zhao case PLAT_PM_LPM20:
251d17799f9Schenhui zhao /* clear previous LPM20 status */
252d17799f9Schenhui zhao setbits32(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST);
253d17799f9Schenhui zhao /* enter LPM20 status */
254d17799f9Schenhui zhao setbits32(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ);
255d17799f9Schenhui zhao
256d17799f9Schenhui zhao /* At this point, the device is in LPM20 status. */
257d17799f9Schenhui zhao
258d17799f9Schenhui zhao /* resume ... */
259d17799f9Schenhui zhao result = spin_event_timeout(
260d17799f9Schenhui zhao !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_LPM20_ST), 10000, 10);
261d17799f9Schenhui zhao if (!result) {
262d17799f9Schenhui zhao pr_err("timeout waiting for LPM20 bit to be cleared\n");
263d17799f9Schenhui zhao ret = -ETIMEDOUT;
264d17799f9Schenhui zhao }
265d17799f9Schenhui zhao break;
266d17799f9Schenhui zhao default:
267d17799f9Schenhui zhao pr_warn("Unknown platform PM state (%d)\n", state);
268d17799f9Schenhui zhao ret = -EINVAL;
269d17799f9Schenhui zhao }
270d17799f9Schenhui zhao
271d17799f9Schenhui zhao return ret;
272d17799f9Schenhui zhao }
273d17799f9Schenhui zhao
rcpm_v1_plat_enter_sleep(void)274d17799f9Schenhui zhao static int rcpm_v1_plat_enter_sleep(void)
275d17799f9Schenhui zhao {
276d17799f9Schenhui zhao return rcpm_v1_plat_enter_state(PLAT_PM_SLEEP);
277d17799f9Schenhui zhao }
278d17799f9Schenhui zhao
rcpm_v2_plat_enter_sleep(void)279d17799f9Schenhui zhao static int rcpm_v2_plat_enter_sleep(void)
280d17799f9Schenhui zhao {
281d17799f9Schenhui zhao return rcpm_v2_plat_enter_state(PLAT_PM_LPM20);
282d17799f9Schenhui zhao }
283d17799f9Schenhui zhao
rcpm_common_freeze_time_base(u32 * tben_reg,int freeze)284d17799f9Schenhui zhao static void rcpm_common_freeze_time_base(u32 *tben_reg, int freeze)
285d17799f9Schenhui zhao {
286d17799f9Schenhui zhao static u32 mask;
287d17799f9Schenhui zhao
288d17799f9Schenhui zhao if (freeze) {
289d17799f9Schenhui zhao mask = in_be32(tben_reg);
290d17799f9Schenhui zhao clrbits32(tben_reg, mask);
291d17799f9Schenhui zhao } else {
292d17799f9Schenhui zhao setbits32(tben_reg, mask);
293d17799f9Schenhui zhao }
294d17799f9Schenhui zhao
295d17799f9Schenhui zhao /* read back to push the previous write */
296d17799f9Schenhui zhao in_be32(tben_reg);
297d17799f9Schenhui zhao }
298d17799f9Schenhui zhao
rcpm_v1_freeze_time_base(bool freeze)299d17799f9Schenhui zhao static void rcpm_v1_freeze_time_base(bool freeze)
300d17799f9Schenhui zhao {
301d17799f9Schenhui zhao rcpm_common_freeze_time_base(&rcpm_v1_regs->ctbenr, freeze);
302d17799f9Schenhui zhao }
303d17799f9Schenhui zhao
rcpm_v2_freeze_time_base(bool freeze)304d17799f9Schenhui zhao static void rcpm_v2_freeze_time_base(bool freeze)
305d17799f9Schenhui zhao {
306d17799f9Schenhui zhao rcpm_common_freeze_time_base(&rcpm_v2_regs->pctbenr, freeze);
307d17799f9Schenhui zhao }
308d17799f9Schenhui zhao
rcpm_get_pm_modes(void)309d17799f9Schenhui zhao static unsigned int rcpm_get_pm_modes(void)
310d17799f9Schenhui zhao {
311d17799f9Schenhui zhao return fsl_supported_pm_modes;
312d17799f9Schenhui zhao }
313d17799f9Schenhui zhao
314d17799f9Schenhui zhao static const struct fsl_pm_ops qoriq_rcpm_v1_ops = {
315d17799f9Schenhui zhao .irq_mask = rcpm_v1_irq_mask,
316d17799f9Schenhui zhao .irq_unmask = rcpm_v1_irq_unmask,
317d17799f9Schenhui zhao .cpu_enter_state = rcpm_v1_cpu_enter_state,
318d17799f9Schenhui zhao .cpu_exit_state = rcpm_v1_cpu_exit_state,
319d17799f9Schenhui zhao .cpu_up_prepare = rcpm_v1_cpu_up_prepare,
320d17799f9Schenhui zhao .cpu_die = rcpm_v1_cpu_die,
321d17799f9Schenhui zhao .plat_enter_sleep = rcpm_v1_plat_enter_sleep,
322d17799f9Schenhui zhao .set_ip_power = rcpm_v1_set_ip_power,
323d17799f9Schenhui zhao .freeze_time_base = rcpm_v1_freeze_time_base,
324d17799f9Schenhui zhao .get_pm_modes = rcpm_get_pm_modes,
325d17799f9Schenhui zhao };
326d17799f9Schenhui zhao
327d17799f9Schenhui zhao static const struct fsl_pm_ops qoriq_rcpm_v2_ops = {
328d17799f9Schenhui zhao .irq_mask = rcpm_v2_irq_mask,
329d17799f9Schenhui zhao .irq_unmask = rcpm_v2_irq_unmask,
330d17799f9Schenhui zhao .cpu_enter_state = rcpm_v2_cpu_enter_state,
331d17799f9Schenhui zhao .cpu_exit_state = rcpm_v2_cpu_exit_state,
332d17799f9Schenhui zhao .cpu_up_prepare = rcpm_v2_cpu_up_prepare,
333d17799f9Schenhui zhao .cpu_die = rcpm_v2_cpu_die,
334d17799f9Schenhui zhao .plat_enter_sleep = rcpm_v2_plat_enter_sleep,
335d17799f9Schenhui zhao .set_ip_power = rcpm_v2_set_ip_power,
336d17799f9Schenhui zhao .freeze_time_base = rcpm_v2_freeze_time_base,
337d17799f9Schenhui zhao .get_pm_modes = rcpm_get_pm_modes,
338d17799f9Schenhui zhao };
339d17799f9Schenhui zhao
340d17799f9Schenhui zhao static const struct of_device_id rcpm_matches[] = {
341d17799f9Schenhui zhao {
342d17799f9Schenhui zhao .compatible = "fsl,qoriq-rcpm-1.0",
343d17799f9Schenhui zhao .data = &qoriq_rcpm_v1_ops,
344d17799f9Schenhui zhao },
345d17799f9Schenhui zhao {
346d17799f9Schenhui zhao .compatible = "fsl,qoriq-rcpm-2.0",
347d17799f9Schenhui zhao .data = &qoriq_rcpm_v2_ops,
348d17799f9Schenhui zhao },
349d17799f9Schenhui zhao {
350d17799f9Schenhui zhao .compatible = "fsl,qoriq-rcpm-2.1",
351d17799f9Schenhui zhao .data = &qoriq_rcpm_v2_ops,
352d17799f9Schenhui zhao },
353d17799f9Schenhui zhao {},
354d17799f9Schenhui zhao };
355d17799f9Schenhui zhao
fsl_rcpm_init(void)356d17799f9Schenhui zhao int __init fsl_rcpm_init(void)
357d17799f9Schenhui zhao {
358d17799f9Schenhui zhao struct device_node *np;
359d17799f9Schenhui zhao const struct of_device_id *match;
360d17799f9Schenhui zhao void __iomem *base;
361d17799f9Schenhui zhao
362d17799f9Schenhui zhao np = of_find_matching_node_and_match(NULL, rcpm_matches, &match);
363d17799f9Schenhui zhao if (!np)
364d17799f9Schenhui zhao return 0;
365d17799f9Schenhui zhao
366d17799f9Schenhui zhao base = of_iomap(np, 0);
367d17799f9Schenhui zhao of_node_put(np);
368d17799f9Schenhui zhao if (!base) {
369d17799f9Schenhui zhao pr_err("of_iomap() error.\n");
370d17799f9Schenhui zhao return -ENOMEM;
371d17799f9Schenhui zhao }
372d17799f9Schenhui zhao
373d17799f9Schenhui zhao rcpm_v1_regs = base;
374d17799f9Schenhui zhao rcpm_v2_regs = base;
375d17799f9Schenhui zhao
376d17799f9Schenhui zhao /* support sleep by default */
377d17799f9Schenhui zhao fsl_supported_pm_modes = FSL_PM_SLEEP;
378d17799f9Schenhui zhao
379d17799f9Schenhui zhao qoriq_pm_ops = match->data;
380d17799f9Schenhui zhao
381d17799f9Schenhui zhao return 0;
382d17799f9Schenhui zhao }
383