diff options
author | Jason Cooper <jason@lakedaemon.net> | 2014-07-22 16:46:48 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-07-22 16:46:48 -0400 |
commit | ba3ec5780bba27819bbc4f669e6c77418a00f14b (patch) | |
tree | eebf5055d0fee3360e7930759ab1b3712eea2407 | |
parent | ba364fc752daeded072a5ef31e43b84cb1f9e5fd (diff) | |
parent | ee2d8ea1e9bb27989f4f157520500dd6c4d45347 (diff) |
Merge branch 'mvebu/soc-cpufreq' into mvebu/soc
-rw-r--r-- | Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt | 5 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/platsmp.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/pmsu.c | 162 | ||||
-rw-r--r-- | drivers/clk/mvebu/clk-cpu.c | 80 | ||||
-rw-r--r-- | include/linux/mvebu-pmsu.h | 20 |
5 files changed, 261 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt index feb830130714..99c214660bdc 100644 --- a/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt +++ b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt | |||
@@ -3,14 +3,15 @@ Device Tree Clock bindings for cpu clock of Marvell EBU platforms | |||
3 | Required properties: | 3 | Required properties: |
4 | - compatible : shall be one of the following: | 4 | - compatible : shall be one of the following: |
5 | "marvell,armada-xp-cpu-clock" - cpu clocks for Armada XP | 5 | "marvell,armada-xp-cpu-clock" - cpu clocks for Armada XP |
6 | - reg : Address and length of the clock complex register set | 6 | - reg : Address and length of the clock complex register set, followed |
7 | by address and length of the PMU DFS registers | ||
7 | - #clock-cells : should be set to 1. | 8 | - #clock-cells : should be set to 1. |
8 | - clocks : shall be the input parent clock phandle for the clock. | 9 | - clocks : shall be the input parent clock phandle for the clock. |
9 | 10 | ||
10 | cpuclk: clock-complex@d0018700 { | 11 | cpuclk: clock-complex@d0018700 { |
11 | #clock-cells = <1>; | 12 | #clock-cells = <1>; |
12 | compatible = "marvell,armada-xp-cpu-clock"; | 13 | compatible = "marvell,armada-xp-cpu-clock"; |
13 | reg = <0xd0018700 0xA0>; | 14 | reg = <0xd0018700 0xA0>, <0x1c054 0x10>; |
14 | clocks = <&coreclk 1>; | 15 | clocks = <&coreclk 1>; |
15 | } | 16 | } |
16 | 17 | ||
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index b6fa9f0c98b8..f278acebeaeb 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c | |||
@@ -67,6 +67,7 @@ static void __init set_secondary_cpus_clock(void) | |||
67 | if (!cpu_clk) | 67 | if (!cpu_clk) |
68 | return; | 68 | return; |
69 | clk_set_rate(cpu_clk, rate); | 69 | clk_set_rate(cpu_clk, rate); |
70 | clk_prepare_enable(cpu_clk); | ||
70 | } | 71 | } |
71 | } | 72 | } |
72 | 73 | ||
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c index 9c819d65b337..0ca285fdd569 100644 --- a/arch/arm/mach-mvebu/pmsu.c +++ b/arch/arm/mach-mvebu/pmsu.c | |||
@@ -18,20 +18,26 @@ | |||
18 | 18 | ||
19 | #define pr_fmt(fmt) "mvebu-pmsu: " fmt | 19 | #define pr_fmt(fmt) "mvebu-pmsu: " fmt |
20 | 20 | ||
21 | #include <linux/clk.h> | ||
21 | #include <linux/cpu_pm.h> | 22 | #include <linux/cpu_pm.h> |
23 | #include <linux/delay.h> | ||
22 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
23 | #include <linux/init.h> | 25 | #include <linux/init.h> |
24 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
27 | #include <linux/of_device.h> | ||
25 | #include <linux/io.h> | 28 | #include <linux/io.h> |
26 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/pm_opp.h> | ||
27 | #include <linux/smp.h> | 31 | #include <linux/smp.h> |
28 | #include <linux/resource.h> | 32 | #include <linux/resource.h> |
33 | #include <linux/slab.h> | ||
29 | #include <asm/cacheflush.h> | 34 | #include <asm/cacheflush.h> |
30 | #include <asm/cp15.h> | 35 | #include <asm/cp15.h> |
31 | #include <asm/smp_plat.h> | 36 | #include <asm/smp_plat.h> |
32 | #include <asm/suspend.h> | 37 | #include <asm/suspend.h> |
33 | #include <asm/tlbflush.h> | 38 | #include <asm/tlbflush.h> |
34 | #include "common.h" | 39 | #include "common.h" |
40 | #include "armada-370-xp.h" | ||
35 | 41 | ||
36 | static void __iomem *pmsu_mp_base; | 42 | static void __iomem *pmsu_mp_base; |
37 | 43 | ||
@@ -57,6 +63,10 @@ static void __iomem *pmsu_mp_base; | |||
57 | #define PMSU_STATUS_AND_MASK_IRQ_MASK BIT(24) | 63 | #define PMSU_STATUS_AND_MASK_IRQ_MASK BIT(24) |
58 | #define PMSU_STATUS_AND_MASK_FIQ_MASK BIT(25) | 64 | #define PMSU_STATUS_AND_MASK_FIQ_MASK BIT(25) |
59 | 65 | ||
66 | #define PMSU_EVENT_STATUS_AND_MASK(cpu) ((cpu * 0x100) + 0x120) | ||
67 | #define PMSU_EVENT_STATUS_AND_MASK_DFS_DONE BIT(1) | ||
68 | #define PMSU_EVENT_STATUS_AND_MASK_DFS_DONE_MASK BIT(17) | ||
69 | |||
60 | #define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x124) | 70 | #define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x124) |
61 | 71 | ||
62 | /* PMSU fabric registers */ | 72 | /* PMSU fabric registers */ |
@@ -291,3 +301,155 @@ static int __init armada_370_xp_cpu_pm_init(void) | |||
291 | 301 | ||
292 | arch_initcall(armada_370_xp_cpu_pm_init); | 302 | arch_initcall(armada_370_xp_cpu_pm_init); |
293 | early_initcall(armada_370_xp_pmsu_init); | 303 | early_initcall(armada_370_xp_pmsu_init); |
304 | |||
305 | static void mvebu_pmsu_dfs_request_local(void *data) | ||
306 | { | ||
307 | u32 reg; | ||
308 | u32 cpu = smp_processor_id(); | ||
309 | unsigned long flags; | ||
310 | |||
311 | local_irq_save(flags); | ||
312 | |||
313 | /* Prepare to enter idle */ | ||
314 | reg = readl(pmsu_mp_base + PMSU_STATUS_AND_MASK(cpu)); | ||
315 | reg |= PMSU_STATUS_AND_MASK_CPU_IDLE_WAIT | | ||
316 | PMSU_STATUS_AND_MASK_IRQ_MASK | | ||
317 | PMSU_STATUS_AND_MASK_FIQ_MASK; | ||
318 | writel(reg, pmsu_mp_base + PMSU_STATUS_AND_MASK(cpu)); | ||
319 | |||
320 | /* Request the DFS transition */ | ||
321 | reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(cpu)); | ||
322 | reg |= PMSU_CONTROL_AND_CONFIG_DFS_REQ; | ||
323 | writel(reg, pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(cpu)); | ||
324 | |||
325 | /* The fact of entering idle will trigger the DFS transition */ | ||
326 | wfi(); | ||
327 | |||
328 | /* | ||
329 | * We're back from idle, the DFS transition has completed, | ||
330 | * clear the idle wait indication. | ||
331 | */ | ||
332 | reg = readl(pmsu_mp_base + PMSU_STATUS_AND_MASK(cpu)); | ||
333 | reg &= ~PMSU_STATUS_AND_MASK_CPU_IDLE_WAIT; | ||
334 | writel(reg, pmsu_mp_base + PMSU_STATUS_AND_MASK(cpu)); | ||
335 | |||
336 | local_irq_restore(flags); | ||
337 | } | ||
338 | |||
339 | int mvebu_pmsu_dfs_request(int cpu) | ||
340 | { | ||
341 | unsigned long timeout; | ||
342 | int hwcpu = cpu_logical_map(cpu); | ||
343 | u32 reg; | ||
344 | |||
345 | /* Clear any previous DFS DONE event */ | ||
346 | reg = readl(pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu)); | ||
347 | reg &= ~PMSU_EVENT_STATUS_AND_MASK_DFS_DONE; | ||
348 | writel(reg, pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu)); | ||
349 | |||
350 | /* Mask the DFS done interrupt, since we are going to poll */ | ||
351 | reg = readl(pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu)); | ||
352 | reg |= PMSU_EVENT_STATUS_AND_MASK_DFS_DONE_MASK; | ||
353 | writel(reg, pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu)); | ||
354 | |||
355 | /* Trigger the DFS on the appropriate CPU */ | ||
356 | smp_call_function_single(cpu, mvebu_pmsu_dfs_request_local, | ||
357 | NULL, false); | ||
358 | |||
359 | /* Poll until the DFS done event is generated */ | ||
360 | timeout = jiffies + HZ; | ||
361 | while (time_before(jiffies, timeout)) { | ||
362 | reg = readl(pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu)); | ||
363 | if (reg & PMSU_EVENT_STATUS_AND_MASK_DFS_DONE) | ||
364 | break; | ||
365 | udelay(10); | ||
366 | } | ||
367 | |||
368 | if (time_after(jiffies, timeout)) | ||
369 | return -ETIME; | ||
370 | |||
371 | /* Restore the DFS mask to its original state */ | ||
372 | reg = readl(pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu)); | ||
373 | reg &= ~PMSU_EVENT_STATUS_AND_MASK_DFS_DONE_MASK; | ||
374 | writel(reg, pmsu_mp_base + PMSU_EVENT_STATUS_AND_MASK(hwcpu)); | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int __init armada_xp_pmsu_cpufreq_init(void) | ||
380 | { | ||
381 | struct device_node *np; | ||
382 | struct resource res; | ||
383 | int ret, cpu; | ||
384 | |||
385 | if (!of_machine_is_compatible("marvell,armadaxp")) | ||
386 | return 0; | ||
387 | |||
388 | /* | ||
389 | * In order to have proper cpufreq handling, we need to ensure | ||
390 | * that the Device Tree description of the CPU clock includes | ||
391 | * the definition of the PMU DFS registers. If not, we do not | ||
392 | * register the clock notifier and the cpufreq driver. This | ||
393 | * piece of code is only for compatibility with old Device | ||
394 | * Trees. | ||
395 | */ | ||
396 | np = of_find_compatible_node(NULL, NULL, "marvell,armada-xp-cpu-clock"); | ||
397 | if (!np) | ||
398 | return 0; | ||
399 | |||
400 | ret = of_address_to_resource(np, 1, &res); | ||
401 | if (ret) { | ||
402 | pr_warn(FW_WARN "not enabling cpufreq, deprecated armada-xp-cpu-clock binding\n"); | ||
403 | of_node_put(np); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | of_node_put(np); | ||
408 | |||
409 | /* | ||
410 | * For each CPU, this loop registers the operating points | ||
411 | * supported (which are the nominal CPU frequency and half of | ||
412 | * it), and registers the clock notifier that will take care | ||
413 | * of doing the PMSU part of a frequency transition. | ||
414 | */ | ||
415 | for_each_possible_cpu(cpu) { | ||
416 | struct device *cpu_dev; | ||
417 | struct clk *clk; | ||
418 | int ret; | ||
419 | |||
420 | cpu_dev = get_cpu_device(cpu); | ||
421 | if (!cpu_dev) { | ||
422 | pr_err("Cannot get CPU %d\n", cpu); | ||
423 | continue; | ||
424 | } | ||
425 | |||
426 | clk = clk_get(cpu_dev, 0); | ||
427 | if (!clk) { | ||
428 | pr_err("Cannot get clock for CPU %d\n", cpu); | ||
429 | return -ENODEV; | ||
430 | } | ||
431 | |||
432 | /* | ||
433 | * In case of a failure of dev_pm_opp_add(), we don't | ||
434 | * bother with cleaning up the registered OPP (there's | ||
435 | * no function to do so), and simply cancel the | ||
436 | * registration of the cpufreq device. | ||
437 | */ | ||
438 | ret = dev_pm_opp_add(cpu_dev, clk_get_rate(clk), 0); | ||
439 | if (ret) { | ||
440 | clk_put(clk); | ||
441 | return ret; | ||
442 | } | ||
443 | |||
444 | ret = dev_pm_opp_add(cpu_dev, clk_get_rate(clk) / 2, 0); | ||
445 | if (ret) { | ||
446 | clk_put(clk); | ||
447 | return ret; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | platform_device_register_simple("cpufreq-generic", -1, NULL, 0); | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | device_initcall(armada_xp_pmsu_cpufreq_init); | ||
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index 8ebf757d29e2..3821a88077ea 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c | |||
@@ -16,10 +16,19 @@ | |||
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/mvebu-pmsu.h> | ||
20 | #include <asm/smp_plat.h> | ||
19 | 21 | ||
20 | #define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET 0x0 | 22 | #define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET 0x0 |
21 | #define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET 0xC | 23 | #define SYS_CTRL_CLK_DIVIDER_CTRL_RESET_ALL 0xff |
22 | #define SYS_CTRL_CLK_DIVIDER_MASK 0x3F | 24 | #define SYS_CTRL_CLK_DIVIDER_CTRL_RESET_SHIFT 8 |
25 | #define SYS_CTRL_CLK_DIVIDER_CTRL2_OFFSET 0x8 | ||
26 | #define SYS_CTRL_CLK_DIVIDER_CTRL2_NBCLK_RATIO_SHIFT 16 | ||
27 | #define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET 0xC | ||
28 | #define SYS_CTRL_CLK_DIVIDER_MASK 0x3F | ||
29 | |||
30 | #define PMU_DFS_RATIO_SHIFT 16 | ||
31 | #define PMU_DFS_RATIO_MASK 0x3F | ||
23 | 32 | ||
24 | #define MAX_CPU 4 | 33 | #define MAX_CPU 4 |
25 | struct cpu_clk { | 34 | struct cpu_clk { |
@@ -28,6 +37,7 @@ struct cpu_clk { | |||
28 | const char *clk_name; | 37 | const char *clk_name; |
29 | const char *parent_name; | 38 | const char *parent_name; |
30 | void __iomem *reg_base; | 39 | void __iomem *reg_base; |
40 | void __iomem *pmu_dfs; | ||
31 | }; | 41 | }; |
32 | 42 | ||
33 | static struct clk **clks; | 43 | static struct clk **clks; |
@@ -62,8 +72,9 @@ static long clk_cpu_round_rate(struct clk_hw *hwclk, unsigned long rate, | |||
62 | return *parent_rate / div; | 72 | return *parent_rate / div; |
63 | } | 73 | } |
64 | 74 | ||
65 | static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate, | 75 | static int clk_cpu_off_set_rate(struct clk_hw *hwclk, unsigned long rate, |
66 | unsigned long parent_rate) | 76 | unsigned long parent_rate) |
77 | |||
67 | { | 78 | { |
68 | struct cpu_clk *cpuclk = to_cpu_clk(hwclk); | 79 | struct cpu_clk *cpuclk = to_cpu_clk(hwclk); |
69 | u32 reg, div; | 80 | u32 reg, div; |
@@ -95,6 +106,58 @@ static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate, | |||
95 | return 0; | 106 | return 0; |
96 | } | 107 | } |
97 | 108 | ||
109 | static int clk_cpu_on_set_rate(struct clk_hw *hwclk, unsigned long rate, | ||
110 | unsigned long parent_rate) | ||
111 | { | ||
112 | u32 reg; | ||
113 | unsigned long fabric_div, target_div, cur_rate; | ||
114 | struct cpu_clk *cpuclk = to_cpu_clk(hwclk); | ||
115 | |||
116 | /* | ||
117 | * PMU DFS registers are not mapped, Device Tree does not | ||
118 | * describes them. We cannot change the frequency dynamically. | ||
119 | */ | ||
120 | if (!cpuclk->pmu_dfs) | ||
121 | return -ENODEV; | ||
122 | |||
123 | cur_rate = __clk_get_rate(hwclk->clk); | ||
124 | |||
125 | reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL2_OFFSET); | ||
126 | fabric_div = (reg >> SYS_CTRL_CLK_DIVIDER_CTRL2_NBCLK_RATIO_SHIFT) & | ||
127 | SYS_CTRL_CLK_DIVIDER_MASK; | ||
128 | |||
129 | /* Frequency is going up */ | ||
130 | if (rate == 2 * cur_rate) | ||
131 | target_div = fabric_div / 2; | ||
132 | /* Frequency is going down */ | ||
133 | else | ||
134 | target_div = fabric_div; | ||
135 | |||
136 | if (target_div == 0) | ||
137 | target_div = 1; | ||
138 | |||
139 | reg = readl(cpuclk->pmu_dfs); | ||
140 | reg &= ~(PMU_DFS_RATIO_MASK << PMU_DFS_RATIO_SHIFT); | ||
141 | reg |= (target_div << PMU_DFS_RATIO_SHIFT); | ||
142 | writel(reg, cpuclk->pmu_dfs); | ||
143 | |||
144 | reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET); | ||
145 | reg |= (SYS_CTRL_CLK_DIVIDER_CTRL_RESET_ALL << | ||
146 | SYS_CTRL_CLK_DIVIDER_CTRL_RESET_SHIFT); | ||
147 | writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET); | ||
148 | |||
149 | return mvebu_pmsu_dfs_request(cpuclk->cpu); | ||
150 | } | ||
151 | |||
152 | static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate, | ||
153 | unsigned long parent_rate) | ||
154 | { | ||
155 | if (__clk_is_enabled(hwclk->clk)) | ||
156 | return clk_cpu_on_set_rate(hwclk, rate, parent_rate); | ||
157 | else | ||
158 | return clk_cpu_off_set_rate(hwclk, rate, parent_rate); | ||
159 | } | ||
160 | |||
98 | static const struct clk_ops cpu_ops = { | 161 | static const struct clk_ops cpu_ops = { |
99 | .recalc_rate = clk_cpu_recalc_rate, | 162 | .recalc_rate = clk_cpu_recalc_rate, |
100 | .round_rate = clk_cpu_round_rate, | 163 | .round_rate = clk_cpu_round_rate, |
@@ -105,6 +168,7 @@ static void __init of_cpu_clk_setup(struct device_node *node) | |||
105 | { | 168 | { |
106 | struct cpu_clk *cpuclk; | 169 | struct cpu_clk *cpuclk; |
107 | void __iomem *clock_complex_base = of_iomap(node, 0); | 170 | void __iomem *clock_complex_base = of_iomap(node, 0); |
171 | void __iomem *pmu_dfs_base = of_iomap(node, 1); | ||
108 | int ncpus = 0; | 172 | int ncpus = 0; |
109 | struct device_node *dn; | 173 | struct device_node *dn; |
110 | 174 | ||
@@ -114,6 +178,10 @@ static void __init of_cpu_clk_setup(struct device_node *node) | |||
114 | return; | 178 | return; |
115 | } | 179 | } |
116 | 180 | ||
181 | if (pmu_dfs_base == NULL) | ||
182 | pr_warn("%s: pmu-dfs base register not set, dynamic frequency scaling not available\n", | ||
183 | __func__); | ||
184 | |||
117 | for_each_node_by_type(dn, "cpu") | 185 | for_each_node_by_type(dn, "cpu") |
118 | ncpus++; | 186 | ncpus++; |
119 | 187 | ||
@@ -146,6 +214,8 @@ static void __init of_cpu_clk_setup(struct device_node *node) | |||
146 | cpuclk[cpu].clk_name = clk_name; | 214 | cpuclk[cpu].clk_name = clk_name; |
147 | cpuclk[cpu].cpu = cpu; | 215 | cpuclk[cpu].cpu = cpu; |
148 | cpuclk[cpu].reg_base = clock_complex_base; | 216 | cpuclk[cpu].reg_base = clock_complex_base; |
217 | if (pmu_dfs_base) | ||
218 | cpuclk[cpu].pmu_dfs = pmu_dfs_base + 4 * cpu; | ||
149 | cpuclk[cpu].hw.init = &init; | 219 | cpuclk[cpu].hw.init = &init; |
150 | 220 | ||
151 | init.name = cpuclk[cpu].clk_name; | 221 | init.name = cpuclk[cpu].clk_name; |
diff --git a/include/linux/mvebu-pmsu.h b/include/linux/mvebu-pmsu.h new file mode 100644 index 000000000000..b918d07efe23 --- /dev/null +++ b/include/linux/mvebu-pmsu.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Marvell | ||
3 | * | ||
4 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #ifndef __MVEBU_PMSU_H__ | ||
12 | #define __MVEBU_PMSU_H__ | ||
13 | |||
14 | #ifdef CONFIG_MACH_MVEBU_V7 | ||
15 | int mvebu_pmsu_dfs_request(int cpu); | ||
16 | #else | ||
17 | static inline int mvebu_pmsu_dfs_request(int cpu) { return -ENODEV; } | ||
18 | #endif | ||
19 | |||
20 | #endif /* __MVEBU_PMSU_H__ */ | ||