Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
54ef3fe6
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
54ef3fe6
编写于
7月 24, 2014
作者:
J
Jason Cooper
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'mvebu/soc-cpuidle' into mvebu/soc
Conflicts: arch/arm/mach-mvebu/pmsu.c
上级
b03e119f
e53b1fd4
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
559 addition
and
129 deletion
+559
-129
Documentation/devicetree/bindings/arm/armada-38x.txt
Documentation/devicetree/bindings/arm/armada-38x.txt
+12
-2
arch/arm/boot/dts/armada-380.dtsi
arch/arm/boot/dts/armada-380.dtsi
+1
-1
arch/arm/boot/dts/armada-385-db.dts
arch/arm/boot/dts/armada-385-db.dts
+1
-1
arch/arm/boot/dts/armada-385-rd.dts
arch/arm/boot/dts/armada-385-rd.dts
+1
-1
arch/arm/boot/dts/armada-385.dtsi
arch/arm/boot/dts/armada-385.dtsi
+1
-1
arch/arm/boot/dts/armada-38x.dtsi
arch/arm/boot/dts/armada-38x.dtsi
+1
-1
arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
+2
-2
arch/arm/mach-mvebu/Kconfig
arch/arm/mach-mvebu/Kconfig
+2
-0
arch/arm/mach-mvebu/Makefile
arch/arm/mach-mvebu/Makefile
+1
-1
arch/arm/mach-mvebu/armada-370-xp.h
arch/arm/mach-mvebu/armada-370-xp.h
+0
-1
arch/arm/mach-mvebu/board-v7.c
arch/arm/mach-mvebu/board-v7.c
+26
-12
arch/arm/mach-mvebu/coherency.c
arch/arm/mach-mvebu/coherency.c
+5
-1
arch/arm/mach-mvebu/common.h
arch/arm/mach-mvebu/common.h
+2
-0
arch/arm/mach-mvebu/headsmp-a9.S
arch/arm/mach-mvebu/headsmp-a9.S
+3
-11
arch/arm/mach-mvebu/platsmp-a9.c
arch/arm/mach-mvebu/platsmp-a9.c
+3
-39
arch/arm/mach-mvebu/platsmp.c
arch/arm/mach-mvebu/platsmp.c
+1
-1
arch/arm/mach-mvebu/pmsu.c
arch/arm/mach-mvebu/pmsu.c
+243
-47
arch/arm/mach-mvebu/pmsu.h
arch/arm/mach-mvebu/pmsu.h
+5
-0
arch/arm/mach-mvebu/pmsu_ll.S
arch/arm/mach-mvebu/pmsu_ll.S
+61
-0
arch/arm/mach-mvebu/system-controller.c
arch/arm/mach-mvebu/system-controller.c
+31
-0
drivers/cpuidle/Kconfig.arm
drivers/cpuidle/Kconfig.arm
+6
-6
drivers/cpuidle/Makefile
drivers/cpuidle/Makefile
+1
-1
drivers/cpuidle/cpuidle-mvebu-v7.c
drivers/cpuidle/cpuidle-mvebu-v7.c
+150
-0
未找到文件。
Documentation/devicetree/bindings/arm/armada-38x.txt
浏览文件 @
54ef3fe6
...
...
@@ -6,5 +6,15 @@ following property:
Required root node property:
- compatible: must contain either "marvell,armada380" or
"marvell,armada385" depending on the variant of the SoC being used.
- compatible: must contain "marvell,armada380"
In addition, boards using the Marvell Armada 385 SoC shall have the
following property before the previous one:
Required root node property:
compatible: must contain "marvell,armada385"
Example:
compatible = "marvell,a385-rd", "marvell,armada385", "marvell,armada380";
arch/arm/boot/dts/armada-380.dtsi
浏览文件 @
54ef3fe6
...
...
@@ -16,7 +16,7 @@
/
{
model
=
"Marvell Armada 380 family SoC"
;
compatible
=
"marvell,armada380"
,
"marvell,armada38x"
;
compatible
=
"marvell,armada380"
;
cpus
{
#
address
-
cells
=
<
1
>;
...
...
arch/arm/boot/dts/armada-385-db.dts
浏览文件 @
54ef3fe6
...
...
@@ -16,7 +16,7 @@
/
{
model
=
"Marvell Armada 385 Development Board"
;
compatible
=
"marvell,a385-db"
,
"marvell,armada385"
,
"marvell,armada38
x
"
;
compatible
=
"marvell,a385-db"
,
"marvell,armada385"
,
"marvell,armada38
0
"
;
chosen
{
bootargs
=
"console=ttyS0,115200 earlyprintk"
;
...
...
arch/arm/boot/dts/armada-385-rd.dts
浏览文件 @
54ef3fe6
...
...
@@ -17,7 +17,7 @@
/
{
model
=
"Marvell Armada 385 Reference Design"
;
compatible
=
"marvell,a385-rd"
,
"marvell,armada385"
,
"marvell,armada38
x
"
;
compatible
=
"marvell,a385-rd"
,
"marvell,armada385"
,
"marvell,armada38
0
"
;
chosen
{
bootargs
=
"console=ttyS0,115200 earlyprintk"
;
...
...
arch/arm/boot/dts/armada-385.dtsi
浏览文件 @
54ef3fe6
...
...
@@ -16,7 +16,7 @@
/
{
model
=
"Marvell Armada 385 family SoC"
;
compatible
=
"marvell,armada385"
,
"marvell,armada38
x
"
;
compatible
=
"marvell,armada385"
,
"marvell,armada38
0
"
;
cpus
{
#
address
-
cells
=
<
1
>;
...
...
arch/arm/boot/dts/armada-38x.dtsi
浏览文件 @
54ef3fe6
...
...
@@ -20,7 +20,7 @@
/
{
model
=
"Marvell Armada 38x family SoC"
;
compatible
=
"marvell,armada38
x
"
;
compatible
=
"marvell,armada38
0
"
;
aliases
{
gpio0
=
&
gpio0
;
...
...
arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
浏览文件 @
54ef3fe6
...
...
@@ -105,7 +105,6 @@
compatible
=
"ethernet-phy-id0141.0cb0"
,
"ethernet-phy-ieee802.3-c22"
;
reg
=
<
0
>;
phy
-
connection
-
type
=
"rgmii-id"
;
};
ethphy1
:
ethernet
-
phy
@
1
{
...
...
@@ -113,7 +112,6 @@
compatible
=
"ethernet-phy-id0141.0cb0"
,
"ethernet-phy-ieee802.3-c22"
;
reg
=
<
1
>;
phy
-
connection
-
type
=
"rgmii-id"
;
};
};
...
...
@@ -121,6 +119,7 @@
status
=
"okay"
;
ethernet0
-
port
@
0
{
phy
-
handle
=
<&
ethphy0
>;
phy
-
connection
-
type
=
"rgmii-id"
;
};
};
...
...
@@ -128,5 +127,6 @@
status
=
"okay"
;
ethernet1
-
port
@
0
{
phy
-
handle
=
<&
ethphy1
>;
phy
-
connection
-
type
=
"rgmii-id"
;
};
};
arch/arm/mach-mvebu/Kconfig
浏览文件 @
54ef3fe6
...
...
@@ -10,6 +10,7 @@ config ARCH_MVEBU
select ZONE_DMA if ARM_LPAE
select ARCH_REQUIRE_GPIOLIB
select PCI_QUIRKS if PCI
select OF_ADDRESS_PCI
if ARCH_MVEBU
...
...
@@ -19,6 +20,7 @@ config MACH_MVEBU_V7
bool
select ARMADA_370_XP_TIMER
select CACHE_L2X0
select ARM_CPU_SUSPEND
config MACH_ARMADA_370
bool "Marvell Armada 370 boards" if ARCH_MULTI_V7
...
...
arch/arm/mach-mvebu/Makefile
浏览文件 @
54ef3fe6
...
...
@@ -7,7 +7,7 @@ CFLAGS_pmsu.o := -march=armv7-a
obj-y
+=
system-controller.o mvebu-soc-id.o
ifeq
($(CONFIG_MACH_MVEBU_V7),y)
obj-y
+=
cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o
obj-y
+=
cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o
pmsu_ll.o
obj-$(CONFIG_SMP)
+=
platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
endif
...
...
arch/arm/mach-mvebu/armada-370-xp.h
浏览文件 @
54ef3fe6
...
...
@@ -25,6 +25,5 @@ extern struct smp_operations armada_xp_smp_ops;
#endif
int
armada_370_xp_pmsu_idle_enter
(
unsigned
long
deepidle
);
void
armada_370_xp_pmsu_idle_exit
(
void
);
#endif
/* __MACH_ARMADA_370_XP_H */
arch/arm/mach-mvebu/board-v7.c
浏览文件 @
54ef3fe6
...
...
@@ -23,6 +23,7 @@
#include <linux/mbus.h>
#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/irqchip.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
...
...
@@ -33,14 +34,14 @@
#include "coherency.h"
#include "mvebu-soc-id.h"
static
void
__iomem
*
scu_base
;
/*
* Enables the SCU when available. Obviously, this is only useful on
* Cortex-A based SOCs, not on PJ4B based ones.
*/
static
void
__init
mvebu_scu_enable
(
void
)
{
void
__iomem
*
scu_base
;
struct
device_node
*
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"arm,cortex-a9-scu"
);
if
(
np
)
{
...
...
@@ -50,6 +51,11 @@ static void __init mvebu_scu_enable(void)
}
}
void
__iomem
*
mvebu_get_scu_base
(
void
)
{
return
scu_base
;
}
/*
* Early versions of Armada 375 SoC have a bug where the BootROM
* leaves an external data abort pending. The kernel is hit by this
...
...
@@ -71,17 +77,23 @@ static int armada_375_external_abort_wa(unsigned long addr, unsigned int fsr,
return
1
;
}
static
void
__init
mvebu_
timer_and_clk_init
(
void
)
static
void
__init
mvebu_
init_irq
(
void
)
{
of_clk_init
(
NULL
);
clocksource_of_init
();
irqchip_init
();
mvebu_scu_enable
();
coherency_init
();
BUG_ON
(
mvebu_mbus_dt_init
(
coherency_available
()));
}
if
(
of_machine_is_compatible
(
"marvell,armada375"
))
hook_fault_code
(
16
+
6
,
armada_375_external_abort_wa
,
SIGBUS
,
0
,
"imprecise external abort"
);
static
void
__init
external_abort_quirk
(
void
)
{
u32
dev
,
rev
;
if
(
mvebu_get_soc_id
(
&
dev
,
&
rev
)
==
0
&&
rev
>
ARMADA_375_Z1_REV
)
return
;
hook_fault_code
(
16
+
6
,
armada_375_external_abort_wa
,
SIGBUS
,
0
,
"imprecise external abort"
);
}
static
void
__init
i2c_quirk
(
void
)
...
...
@@ -178,8 +190,10 @@ static void __init mvebu_dt_init(void)
{
if
(
of_machine_is_compatible
(
"plathome,openblocks-ax3-4"
))
i2c_quirk
();
if
(
of_machine_is_compatible
(
"marvell,a375-db"
))
if
(
of_machine_is_compatible
(
"marvell,a375-db"
))
{
external_abort_quirk
();
thermal_quirk
();
}
of_platform_populate
(
NULL
,
of_default_bus_match_table
,
NULL
,
NULL
);
}
...
...
@@ -194,7 +208,7 @@ DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
.
l2c_aux_mask
=
~
0
,
.
smp
=
smp_ops
(
armada_xp_smp_ops
),
.
init_machine
=
mvebu_dt_init
,
.
init_
time
=
mvebu_timer_and_clk_init
,
.
init_
irq
=
mvebu_init_irq
,
.
restart
=
mvebu_restart
,
.
dt_compat
=
armada_370_xp_dt_compat
,
MACHINE_END
...
...
@@ -207,7 +221,7 @@ static const char * const armada_375_dt_compat[] = {
DT_MACHINE_START
(
ARMADA_375_DT
,
"Marvell Armada 375 (Device Tree)"
)
.
l2c_aux_val
=
0
,
.
l2c_aux_mask
=
~
0
,
.
init_
time
=
mvebu_timer_and_clk_init
,
.
init_
irq
=
mvebu_init_irq
,
.
init_machine
=
mvebu_dt_init
,
.
restart
=
mvebu_restart
,
.
dt_compat
=
armada_375_dt_compat
,
...
...
@@ -222,7 +236,7 @@ static const char * const armada_38x_dt_compat[] = {
DT_MACHINE_START
(
ARMADA_38X_DT
,
"Marvell Armada 380/385 (Device Tree)"
)
.
l2c_aux_val
=
0
,
.
l2c_aux_mask
=
~
0
,
.
init_
time
=
mvebu_timer_and_clk_init
,
.
init_
irq
=
mvebu_init_irq
,
.
restart
=
mvebu_restart
,
.
dt_compat
=
armada_38x_dt_compat
,
MACHINE_END
arch/arm/mach-mvebu/coherency.c
浏览文件 @
54ef3fe6
...
...
@@ -292,6 +292,10 @@ static struct notifier_block mvebu_hwcc_nb = {
.
notifier_call
=
mvebu_hwcc_notifier
,
};
static
struct
notifier_block
mvebu_hwcc_pci_nb
=
{
.
notifier_call
=
mvebu_hwcc_notifier
,
};
static
void
__init
armada_370_coherency_init
(
struct
device_node
*
np
)
{
struct
resource
res
;
...
...
@@ -427,7 +431,7 @@ static int __init coherency_pci_init(void)
{
if
(
coherency_available
())
bus_register_notifier
(
&
pci_bus_type
,
&
mvebu_hwcc_nb
);
&
mvebu_hwcc_
pci_
nb
);
return
0
;
}
...
...
arch/arm/mach-mvebu/common.h
浏览文件 @
54ef3fe6
...
...
@@ -23,4 +23,6 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
void
mvebu_system_controller_set_cpu_boot_addr
(
void
*
boot_addr
);
int
mvebu_system_controller_get_soc_id
(
u32
*
dev
,
u32
*
rev
);
void
__iomem
*
mvebu_get_scu_base
(
void
);
#endif
arch/arm/mach-mvebu/headsmp-a9.S
浏览文件 @
54ef3fe6
...
...
@@ -15,20 +15,12 @@
#include <linux/linkage.h>
#include <linux/init.h>
__CPUINIT
#define CPU_RESUME_ADDR_REG 0xf10182d4
.
global
armada_375_smp_cpu1_enable_code_start
.
global
armada_375_smp_cpu1_enable_code_end
#include <asm/assembler.h>
armada_375_smp_cpu1_enable_code_start
:
ldr
r0
,
[
pc
,
#
4
]
ldr
r1
,
[
r0
]
mov
pc
,
r1
.
word
CPU_RESUME_ADDR_REG
armada_375_smp_cpu1_enable_code_end
:
__CPUINIT
ENTRY
(
mvebu_cortex_a9_secondary_startup
)
ARM_BE8
(
setend
be
)
bl
v7_invalidate_l1
b
secondary_startup
ENDPROC
(
mvebu_cortex_a9_secondary_startup
)
arch/arm/mach-mvebu/platsmp-a9.c
浏览文件 @
54ef3fe6
...
...
@@ -20,33 +20,8 @@
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
#include "common.h"
#include "mvebu-soc-id.h"
#include "pmsu.h"
#define CRYPT0_ENG_ID 41
#define CRYPT0_ENG_ATTR 0x1
#define SRAM_PHYS_BASE 0xFFFF0000
#define BOOTROM_BASE 0xFFF00000
#define BOOTROM_SIZE 0x100000
extern
unsigned
char
armada_375_smp_cpu1_enable_code_end
;
extern
unsigned
char
armada_375_smp_cpu1_enable_code_start
;
static
void
armada_375_smp_cpu1_enable_wa
(
void
)
{
void
__iomem
*
sram_virt_base
;
mvebu_mbus_del_window
(
BOOTROM_BASE
,
BOOTROM_SIZE
);
mvebu_mbus_add_window_by_id
(
CRYPT0_ENG_ID
,
CRYPT0_ENG_ATTR
,
SRAM_PHYS_BASE
,
SZ_64K
);
sram_virt_base
=
ioremap
(
SRAM_PHYS_BASE
,
SZ_64K
);
memcpy
(
sram_virt_base
,
&
armada_375_smp_cpu1_enable_code_start
,
&
armada_375_smp_cpu1_enable_code_end
-
&
armada_375_smp_cpu1_enable_code_start
);
}
extern
void
mvebu_cortex_a9_secondary_startup
(
void
);
static
int
__cpuinit
mvebu_cortex_a9_boot_secondary
(
unsigned
int
cpu
,
...
...
@@ -63,21 +38,10 @@ static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu,
* address.
*/
hw_cpu
=
cpu_logical_map
(
cpu
);
if
(
of_machine_is_compatible
(
"marvell,armada375"
))
{
u32
dev
,
rev
;
if
(
mvebu_get_soc_id
(
&
dev
,
&
rev
)
==
0
&&
rev
==
ARMADA_375_Z1_REV
)
armada_375_smp_cpu1_enable_wa
();
if
(
of_machine_is_compatible
(
"marvell,armada375"
))
mvebu_system_controller_set_cpu_boot_addr
(
mvebu_cortex_a9_secondary_startup
);
}
else
{
mvebu_pmsu_set_cpu_boot_addr
(
hw_cpu
,
mvebu_cortex_a9_secondary_startup
);
}
else
mvebu_pmsu_set_cpu_boot_addr
(
hw_cpu
,
mvebu_cortex_a9_secondary_startup
);
smp_wmb
();
ret
=
mvebu_cpu_reset_deassert
(
hw_cpu
);
if
(
ret
)
{
...
...
arch/arm/mach-mvebu/platsmp.c
浏览文件 @
54ef3fe6
...
...
@@ -109,7 +109,7 @@ static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
*/
static
void
armada_xp_secondary_init
(
unsigned
int
cpu
)
{
armada_370_xp
_pmsu_idle_exit
();
mvebu_v7
_pmsu_idle_exit
();
}
static
void
__init
armada_xp_smp_init_cpus
(
void
)
...
...
arch/arm/mach-mvebu/pmsu.c
浏览文件 @
54ef3fe6
...
...
@@ -21,25 +21,26 @@
#include <linux/clk.h>
#include <linux/cpu_pm.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mbus.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/smp.h>
#include <linux/resource.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <asm/cacheflush.h>
#include <asm/cp15.h>
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
#include <asm/suspend.h>
#include <asm/tlbflush.h>
#include "common.h"
#include "armada-370-xp.h"
static
void
__iomem
*
pmsu_mp_base
;
#define PMSU_BASE_OFFSET 0x100
#define PMSU_REG_SIZE 0x1000
...
...
@@ -73,12 +74,35 @@ static void __iomem *pmsu_mp_base;
#define L2C_NFABRIC_PM_CTL 0x4
#define L2C_NFABRIC_PM_CTL_PWR_DOWN BIT(20)
/* PMSU delay registers */
#define PMSU_POWERDOWN_DELAY 0xF04
#define PMSU_POWERDOWN_DELAY_PMU BIT(1)
#define PMSU_POWERDOWN_DELAY_MASK 0xFFFE
#define PMSU_DFLT_ARMADA38X_DELAY 0x64
/* CA9 MPcore SoC Control registers */
#define MPCORE_RESET_CTL 0x64
#define MPCORE_RESET_CTL_L2 BIT(0)
#define MPCORE_RESET_CTL_DEBUG BIT(16)
#define SRAM_PHYS_BASE 0xFFFF0000
#define BOOTROM_BASE 0xFFF00000
#define BOOTROM_SIZE 0x100000
#define ARMADA_370_CRYPT0_ENG_TARGET 0x9
#define ARMADA_370_CRYPT0_ENG_ATTR 0x1
extern
void
ll_disable_coherency
(
void
);
extern
void
ll_enable_coherency
(
void
);
static
struct
platform_device
armada_xp_cpuidle_device
=
{
.
name
=
"cpuidle-armada-370-xp"
,
};
extern
void
armada_370_xp_cpu_resume
(
void
);
extern
void
armada_38x_cpu_resume
(
void
);
static
phys_addr_t
pmsu_mp_phys_base
;
static
void
__iomem
*
pmsu_mp_base
;
static
void
*
mvebu_cpu_resume
;
static
struct
of_device_id
of_pmsu_table
[]
=
{
{
.
compatible
=
"marvell,armada-370-pmsu"
,
},
...
...
@@ -93,7 +117,49 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
PMSU_BOOT_ADDR_REDIRECT_OFFSET
(
hw_cpu
));
}
static
int
__init
armada_370_xp_pmsu_init
(
void
)
extern
unsigned
char
mvebu_boot_wa_start
;
extern
unsigned
char
mvebu_boot_wa_end
;
/*
* This function sets up the boot address workaround needed for SMP
* boot on Armada 375 Z1 and cpuidle on Armada 370. It unmaps the
* BootROM Mbus window, and instead remaps a crypto SRAM into which a
* custom piece of code is copied to replace the problematic BootROM.
*/
int
mvebu_setup_boot_addr_wa
(
unsigned
int
crypto_eng_target
,
unsigned
int
crypto_eng_attribute
,
phys_addr_t
resume_addr_reg
)
{
void
__iomem
*
sram_virt_base
;
u32
code_len
=
&
mvebu_boot_wa_end
-
&
mvebu_boot_wa_start
;
mvebu_mbus_del_window
(
BOOTROM_BASE
,
BOOTROM_SIZE
);
mvebu_mbus_add_window_by_id
(
crypto_eng_target
,
crypto_eng_attribute
,
SRAM_PHYS_BASE
,
SZ_64K
);
sram_virt_base
=
ioremap
(
SRAM_PHYS_BASE
,
SZ_64K
);
if
(
!
sram_virt_base
)
{
pr_err
(
"Unable to map SRAM to setup the boot address WA
\n
"
);
return
-
ENOMEM
;
}
memcpy
(
sram_virt_base
,
&
mvebu_boot_wa_start
,
code_len
);
/*
* The last word of the code copied in SRAM must contain the
* physical base address of the PMSU register. We
* intentionally store this address in the native endianness
* of the system.
*/
__raw_writel
((
unsigned
long
)
resume_addr_reg
,
sram_virt_base
+
code_len
-
4
);
iounmap
(
sram_virt_base
);
return
0
;
}
static
int
__init
mvebu_v7_pmsu_init
(
void
)
{
struct
device_node
*
np
;
struct
resource
res
;
...
...
@@ -124,6 +190,8 @@ static int __init armada_370_xp_pmsu_init(void)
goto
out
;
}
pmsu_mp_phys_base
=
res
.
start
;
pmsu_mp_base
=
ioremap
(
res
.
start
,
resource_size
(
&
res
));
if
(
!
pmsu_mp_base
)
{
pr_err
(
"unable to map registers
\n
"
);
...
...
@@ -137,7 +205,7 @@ static int __init armada_370_xp_pmsu_init(void)
return
ret
;
}
static
void
armada_370_xp
_pmsu_enable_l2_powerdown_onidle
(
void
)
static
void
mvebu_v7
_pmsu_enable_l2_powerdown_onidle
(
void
)
{
u32
reg
;
...
...
@@ -150,15 +218,14 @@ static void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void)
writel
(
reg
,
pmsu_mp_base
+
L2C_NFABRIC_PM_CTL
);
}
static
void
armada_370_xp_cpu_resume
(
void
)
{
asm
volatile
(
"bl ll_add_cpu_to_smp_group
\n\t
"
"bl ll_enable_coherency
\n\t
"
"b cpu_resume
\n\t
"
);
}
enum
pmsu_idle_prepare_flags
{
PMSU_PREPARE_NORMAL
=
0
,
PMSU_PREPARE_DEEP_IDLE
=
BIT
(
0
),
PMSU_PREPARE_SNOOP_DISABLE
=
BIT
(
1
),
};
/* No locking is needed because we only access per-CPU registers */
int
armada_370_xp_pmsu_idle_enter
(
unsigned
long
deepidle
)
static
int
mvebu_v7_pmsu_idle_prepare
(
unsigned
long
flags
)
{
unsigned
int
hw_cpu
=
cpu_logical_map
(
smp_processor_id
());
u32
reg
;
...
...
@@ -182,17 +249,34 @@ int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
reg
=
readl
(
pmsu_mp_base
+
PMSU_CONTROL_AND_CONFIG
(
hw_cpu
));
/* ask HW to power down the L2 Cache if needed */
if
(
deepidle
)
if
(
flags
&
PMSU_PREPARE_DEEP_IDLE
)
reg
|=
PMSU_CONTROL_AND_CONFIG_L2_PWDDN
;
/* request power down */
reg
|=
PMSU_CONTROL_AND_CONFIG_PWDDN_REQ
;
writel
(
reg
,
pmsu_mp_base
+
PMSU_CONTROL_AND_CONFIG
(
hw_cpu
));
/* Disable snoop disable by HW - SW is taking care of it */
reg
=
readl
(
pmsu_mp_base
+
PMSU_CPU_POWER_DOWN_CONTROL
(
hw_cpu
));
reg
|=
PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP
;
writel
(
reg
,
pmsu_mp_base
+
PMSU_CPU_POWER_DOWN_CONTROL
(
hw_cpu
));
if
(
flags
&
PMSU_PREPARE_SNOOP_DISABLE
)
{
/* Disable snoop disable by HW - SW is taking care of it */
reg
=
readl
(
pmsu_mp_base
+
PMSU_CPU_POWER_DOWN_CONTROL
(
hw_cpu
));
reg
|=
PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP
;
writel
(
reg
,
pmsu_mp_base
+
PMSU_CPU_POWER_DOWN_CONTROL
(
hw_cpu
));
}
return
0
;
}
int
armada_370_xp_pmsu_idle_enter
(
unsigned
long
deepidle
)
{
unsigned
long
flags
=
PMSU_PREPARE_SNOOP_DISABLE
;
int
ret
;
if
(
deepidle
)
flags
|=
PMSU_PREPARE_DEEP_IDLE
;
ret
=
mvebu_v7_pmsu_idle_prepare
(
flags
);
if
(
ret
)
return
ret
;
v7_exit_coherency_flush
(
all
);
...
...
@@ -211,14 +295,14 @@ int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
/* Test the CR_C bit and set it if it was cleared */
asm
volatile
(
"mrc p15, 0,
%
0, c1, c0, 0
\n\t
"
"tst
%
0, #(1 << 2)
\n\t
"
"orreq
%0, %
0, #(1 << 2)
\n\t
"
"mcreq p15, 0,
%
0, c1, c0, 0
\n\t
"
"mrc p15, 0,
r
0, c1, c0, 0
\n\t
"
"tst
r
0, #(1 << 2)
\n\t
"
"orreq
r0, r
0, #(1 << 2)
\n\t
"
"mcreq p15, 0,
r
0, c1, c0, 0
\n\t
"
"isb "
:
:
"r"
(
0
)
);
:
:
:
"r0"
);
pr_
warn
(
"Failed to suspend the system
\n
"
);
pr_
debug
(
"Failed to suspend the system
\n
"
);
return
0
;
}
...
...
@@ -228,15 +312,40 @@ static int armada_370_xp_cpu_suspend(unsigned long deepidle)
return
cpu_suspend
(
deepidle
,
armada_370_xp_pmsu_idle_enter
);
}
static
int
armada_38x_do_cpu_suspend
(
unsigned
long
deepidle
)
{
unsigned
long
flags
=
0
;
if
(
deepidle
)
flags
|=
PMSU_PREPARE_DEEP_IDLE
;
mvebu_v7_pmsu_idle_prepare
(
flags
);
/*
* Already flushed cache, but do it again as the outer cache
* functions dirty the cache with spinlocks
*/
v7_exit_coherency_flush
(
louis
);
scu_power_mode
(
mvebu_get_scu_base
(),
SCU_PM_POWEROFF
);
cpu_do_idle
();
return
1
;
}
static
int
armada_38x_cpu_suspend
(
unsigned
long
deepidle
)
{
return
cpu_suspend
(
false
,
armada_38x_do_cpu_suspend
);
}
/* No locking is needed because we only access per-CPU registers */
void
armada_370_xp
_pmsu_idle_exit
(
void
)
void
mvebu_v7
_pmsu_idle_exit
(
void
)
{
unsigned
int
hw_cpu
=
cpu_logical_map
(
smp_processor_id
());
u32
reg
;
if
(
pmsu_mp_base
==
NULL
)
return
;
/* cancel ask HW to power down the L2 Cache if possible */
reg
=
readl
(
pmsu_mp_base
+
PMSU_CONTROL_AND_CONFIG
(
hw_cpu
));
reg
&=
~
PMSU_CONTROL_AND_CONFIG_L2_PWDDN
;
...
...
@@ -251,56 +360,143 @@ void armada_370_xp_pmsu_idle_exit(void)
writel
(
reg
,
pmsu_mp_base
+
PMSU_STATUS_AND_MASK
(
hw_cpu
));
}
static
int
armada_370_xp
_cpu_pm_notify
(
struct
notifier_block
*
self
,
static
int
mvebu_v7
_cpu_pm_notify
(
struct
notifier_block
*
self
,
unsigned
long
action
,
void
*
hcpu
)
{
if
(
action
==
CPU_PM_ENTER
)
{
unsigned
int
hw_cpu
=
cpu_logical_map
(
smp_processor_id
());
mvebu_pmsu_set_cpu_boot_addr
(
hw_cpu
,
armada_370_xp
_cpu_resume
);
mvebu_pmsu_set_cpu_boot_addr
(
hw_cpu
,
mvebu
_cpu_resume
);
}
else
if
(
action
==
CPU_PM_EXIT
)
{
armada_370_xp
_pmsu_idle_exit
();
mvebu_v7
_pmsu_idle_exit
();
}
return
NOTIFY_OK
;
}
static
struct
notifier_block
armada_370_xp
_cpu_pm_notifier
=
{
.
notifier_call
=
armada_370_xp
_cpu_pm_notify
,
static
struct
notifier_block
mvebu_v7
_cpu_pm_notifier
=
{
.
notifier_call
=
mvebu_v7
_cpu_pm_notify
,
};
static
int
__init
armada_370_xp_cpu_pm_init
(
void
)
static
struct
platform_device
mvebu_v7_cpuidle_device
;
static
__init
int
armada_370_cpuidle_init
(
void
)
{
struct
device_node
*
np
;
phys_addr_t
redirect_reg
;
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"marvell,coherency-fabric"
);
if
(
!
np
)
return
-
ENODEV
;
of_node_put
(
np
);
/*
* Check that all the requirements are available to enable
* cpuidle. So far, it is only supported on Armada XP, cpuidle
* needs the coherency fabric and the PMSU enabled
* On Armada 370, there is "a slow exit process from the deep
* idle state due to heavy L1/L2 cache cleanup operations
* performed by the BootROM software". To avoid this, we
* replace the restart code of the bootrom by a a simple jump
* to the boot address. Then the code located at this boot
* address will take care of the initialization.
*/
redirect_reg
=
pmsu_mp_phys_base
+
PMSU_BOOT_ADDR_REDIRECT_OFFSET
(
0
);
mvebu_setup_boot_addr_wa
(
ARMADA_370_CRYPT0_ENG_TARGET
,
ARMADA_370_CRYPT0_ENG_ATTR
,
redirect_reg
);
if
(
!
of_machine_is_compatible
(
"marvell,armadaxp"
))
return
0
;
mvebu_cpu_resume
=
armada_370_xp_cpu_resume
;
mvebu_v7_cpuidle_device
.
dev
.
platform_data
=
armada_370_xp_cpu_suspend
;
mvebu_v7_cpuidle_device
.
name
=
"cpuidle-armada-370"
;
return
0
;
}
static
__init
int
armada_38x_cpuidle_init
(
void
)
{
struct
device_node
*
np
;
void
__iomem
*
mpsoc_base
;
u32
reg
;
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"marvell,armada-380-coherency-fabric"
);
if
(
!
np
)
return
-
ENODEV
;
of_node_put
(
np
);
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"marvell,armada-380-mpcore-soc-ctrl"
);
if
(
!
np
)
return
-
ENODEV
;
mpsoc_base
=
of_iomap
(
np
,
0
);
BUG_ON
(
!
mpsoc_base
);
of_node_put
(
np
);
/* Set up reset mask when powering down the cpus */
reg
=
readl
(
mpsoc_base
+
MPCORE_RESET_CTL
);
reg
|=
MPCORE_RESET_CTL_L2
;
reg
|=
MPCORE_RESET_CTL_DEBUG
;
writel
(
reg
,
mpsoc_base
+
MPCORE_RESET_CTL
);
iounmap
(
mpsoc_base
);
/* Set up delay */
reg
=
readl
(
pmsu_mp_base
+
PMSU_POWERDOWN_DELAY
);
reg
&=
~
PMSU_POWERDOWN_DELAY_MASK
;
reg
|=
PMSU_DFLT_ARMADA38X_DELAY
;
reg
|=
PMSU_POWERDOWN_DELAY_PMU
;
writel
(
reg
,
pmsu_mp_base
+
PMSU_POWERDOWN_DELAY
);
mvebu_cpu_resume
=
armada_38x_cpu_resume
;
mvebu_v7_cpuidle_device
.
dev
.
platform_data
=
armada_38x_cpu_suspend
;
mvebu_v7_cpuidle_device
.
name
=
"cpuidle-armada-38x"
;
return
0
;
}
static
__init
int
armada_xp_cpuidle_init
(
void
)
{
struct
device_node
*
np
;
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"marvell,coherency-fabric"
);
if
(
!
np
)
return
0
;
return
-
ENODEV
;
of_node_put
(
np
);
mvebu_cpu_resume
=
armada_370_xp_cpu_resume
;
mvebu_v7_cpuidle_device
.
dev
.
platform_data
=
armada_370_xp_cpu_suspend
;
mvebu_v7_cpuidle_device
.
name
=
"cpuidle-armada-xp"
;
return
0
;
}
static
int
__init
mvebu_v7_cpu_pm_init
(
void
)
{
struct
device_node
*
np
;
int
ret
;
np
=
of_find_matching_node
(
NULL
,
of_pmsu_table
);
if
(
!
np
)
return
0
;
of_node_put
(
np
);
armada_370_xp_pmsu_enable_l2_powerdown_onidle
();
armada_xp_cpuidle_device
.
dev
.
platform_data
=
armada_370_xp_cpu_suspend
;
platform_device_register
(
&
armada_xp_cpuidle_device
);
cpu_pm_register_notifier
(
&
armada_370_xp_cpu_pm_notifier
);
if
(
of_machine_is_compatible
(
"marvell,armadaxp"
))
ret
=
armada_xp_cpuidle_init
();
else
if
(
of_machine_is_compatible
(
"marvell,armada370"
))
ret
=
armada_370_cpuidle_init
();
else
if
(
of_machine_is_compatible
(
"marvell,armada380"
))
ret
=
armada_38x_cpuidle_init
();
else
return
0
;
if
(
ret
)
return
ret
;
mvebu_v7_pmsu_enable_l2_powerdown_onidle
();
platform_device_register
(
&
mvebu_v7_cpuidle_device
);
cpu_pm_register_notifier
(
&
mvebu_v7_cpu_pm_notifier
);
return
0
;
}
arch_initcall
(
armada_370_xp
_cpu_pm_init
);
early_initcall
(
armada_370_xp
_pmsu_init
);
arch_initcall
(
mvebu_v7
_cpu_pm_init
);
early_initcall
(
mvebu_v7
_pmsu_init
);
static
void
mvebu_pmsu_dfs_request_local
(
void
*
data
)
{
...
...
arch/arm/mach-mvebu/pmsu.h
浏览文件 @
54ef3fe6
...
...
@@ -12,5 +12,10 @@
#define __MACH_MVEBU_PMSU_H
int
armada_xp_boot_cpu
(
unsigned
int
cpu_id
,
void
*
phys_addr
);
int
mvebu_setup_boot_addr_wa
(
unsigned
int
crypto_eng_target
,
unsigned
int
crypto_eng_attribute
,
phys_addr_t
resume_addr_reg
);
void
mvebu_v7_pmsu_idle_exit
(
void
);
#endif
/* __MACH_370_XP_PMSU_H */
arch/arm/mach-mvebu/pmsu_ll.S
0 → 100644
浏览文件 @
54ef3fe6
/*
*
Copyright
(
C
)
2014
Marvell
*
*
Thomas
Petazzoni
<
thomas
.
petazzoni
@
free
-
electrons
.
com
>
*
Gregory
Clement
<
gregory
.
clement
@
free
-
electrons
.
com
>
*
*
This
file
is
licensed
under
the
terms
of
the
GNU
General
Public
*
License
version
2
.
This
program
is
licensed
"as is"
without
any
*
warranty
of
any
kind
,
whether
express
or
implied
.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
/*
*
This
is
the
entry
point
through
which
CPUs
exiting
cpuidle
deep
*
idle
state
are
going
.
*/
ENTRY
(
armada_370_xp_cpu_resume
)
ARM_BE8
(
setend
be
)
@
go
BE8
if
entered
LE
bl
ll_add_cpu_to_smp_group
bl
ll_enable_coherency
b
cpu_resume
ENDPROC
(
armada_370_xp_cpu_resume
)
ENTRY
(
armada_38x_cpu_resume
)
/
*
do
we
need
it
for
Armada
38
x
*/
ARM_BE8
(
setend
be
)
@
go
BE8
if
entered
LE
bl
v7_invalidate_l1
mrc
p15
,
4
,
r1
,
c15
,
c0
@
get
SCU
base
address
orr
r1
,
r1
,
#
0x8
@
SCU
CPU
Power
Status
Register
mrc
15
,
0
,
r0
,
cr0
,
cr0
,
5
@
get
the
CPU
ID
and
r0
,
r0
,
#
15
add
r1
,
r1
,
r0
mov
r0
,
#
0x0
strb
r0
,
[
r1
]
@
switch
SCU
power
state
to
Normal
mode
b
cpu_resume
ENDPROC
(
armada_38x_cpu_resume
)
.
global
mvebu_boot_wa_start
.
global
mvebu_boot_wa_end
/*
The
following
code
will
be
executed
from
SRAM
*/
ENTRY
(
mvebu_boot_wa_start
)
mvebu_boot_wa_start
:
ARM_BE8
(
setend
be
)
adr
r0
,
1
f
ldr
r0
,
[
r0
]
@
load
the
address
of
the
@
resume
register
ldr
r0
,
[
r0
]
@
load
the
value
in
the
@
resume
register
ARM_BE8
(
rev
r0
,
r0
)
@
the
value
is
stored
LE
mov
pc
,
r0
@
jump
to
this
value
/*
*
the
last
word
of
this
piece
of
code
will
be
filled
by
the
physical
*
address
of
the
boot
address
register
just
after
being
copied
in
SRAM
*/
1
:
.
long
.
mvebu_boot_wa_end
:
ENDPROC
(
mvebu_boot_wa_end
)
arch/arm/mach-mvebu/system-controller.c
浏览文件 @
54ef3fe6
...
...
@@ -28,8 +28,14 @@
#include <linux/io.h>
#include <linux/reboot.h>
#include "common.h"
#include "mvebu-soc-id.h"
#include "pmsu.h"
#define ARMADA_375_CRYPT0_ENG_TARGET 41
#define ARMADA_375_CRYPT0_ENG_ATTR 1
static
void
__iomem
*
system_controller_base
;
static
phys_addr_t
system_controller_phys_base
;
struct
mvebu_system_controller
{
u32
rstoutn_mask_offset
;
...
...
@@ -121,10 +127,32 @@ int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev)
}
#ifdef CONFIG_SMP
void
mvebu_armada375_smp_wa_init
(
void
)
{
u32
dev
,
rev
;
phys_addr_t
resume_addr_reg
;
if
(
mvebu_get_soc_id
(
&
dev
,
&
rev
)
!=
0
)
return
;
if
(
rev
!=
ARMADA_375_Z1_REV
)
return
;
resume_addr_reg
=
system_controller_phys_base
+
mvebu_sc
->
resume_boot_addr
;
mvebu_setup_boot_addr_wa
(
ARMADA_375_CRYPT0_ENG_TARGET
,
ARMADA_375_CRYPT0_ENG_ATTR
,
resume_addr_reg
);
}
void
mvebu_system_controller_set_cpu_boot_addr
(
void
*
boot_addr
)
{
BUG_ON
(
system_controller_base
==
NULL
);
BUG_ON
(
mvebu_sc
->
resume_boot_addr
==
0
);
if
(
of_machine_is_compatible
(
"marvell,armada375"
))
mvebu_armada375_smp_wa_init
();
writel
(
virt_to_phys
(
boot_addr
),
system_controller_base
+
mvebu_sc
->
resume_boot_addr
);
}
...
...
@@ -138,7 +166,10 @@ static int __init mvebu_system_controller_init(void)
np
=
of_find_matching_node_and_match
(
NULL
,
of_system_controller_table
,
&
match
);
if
(
np
)
{
struct
resource
res
;
system_controller_base
=
of_iomap
(
np
,
0
);
of_address_to_resource
(
np
,
0
,
&
res
);
system_controller_phys_base
=
res
.
start
;
mvebu_sc
=
(
struct
mvebu_system_controller
*
)
match
->
data
;
of_node_put
(
np
);
}
...
...
drivers/cpuidle/Kconfig.arm
浏览文件 @
54ef3fe6
#
# ARM CPU Idle drivers
#
config ARM_ARMADA_370_XP_CPUIDLE
bool "CPU Idle Driver for Armada 370/XP family processors"
depends on ARCH_MVEBU
help
Select this to enable cpuidle on Armada 370/XP processors.
config ARM_BIG_LITTLE_CPUIDLE
bool "Support for ARM big.LITTLE processors"
depends on ARCH_VEXPRESS_TC2_PM
...
...
@@ -61,3 +55,9 @@ config ARM_EXYNOS_CPUIDLE
depends on ARCH_EXYNOS
help
Select this to enable cpuidle for Exynos processors
config ARM_MVEBU_V7_CPUIDLE
bool "CPU Idle Driver for mvebu v7 family processors"
depends on ARCH_MVEBU
help
Select this to enable cpuidle on Armada 370, 38x and XP processors.
drivers/cpuidle/Makefile
浏览文件 @
54ef3fe6
...
...
@@ -7,7 +7,7 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
##################################################################################
# ARM SoC drivers
obj-$(CONFIG_ARM_
ARMADA_370_XP_CPUIDLE)
+=
cpuidle-armada-370-xp
.o
obj-$(CONFIG_ARM_
MVEBU_V7_CPUIDLE)
+=
cpuidle-mvebu-v7
.o
obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE)
+=
cpuidle-big_little.o
obj-$(CONFIG_ARM_CLPS711X_CPUIDLE)
+=
cpuidle-clps711x.o
obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE)
+=
cpuidle-calxeda.o
...
...
drivers/cpuidle/cpuidle-
armada-370-xp
.c
→
drivers/cpuidle/cpuidle-
mvebu-v7
.c
浏览文件 @
54ef3fe6
/*
* Marvell Armada 370
and Armada
XP SoC cpuidle driver
* Marvell Armada 370
, 38x and
XP SoC cpuidle driver
*
* Copyright (C) 2014 Marvell
*
...
...
@@ -21,12 +21,11 @@
#include <linux/platform_device.h>
#include <asm/cpuidle.h>
#define ARMADA_370_XP_MAX_STATES 3
#define ARMADA_370_XP_FLAG_DEEP_IDLE 0x10000
#define MVEBU_V7_FLAG_DEEP_IDLE 0x10000
static
int
(
*
armada_370_xp
_cpu_suspend
)(
int
);
static
int
(
*
mvebu_v7
_cpu_suspend
)(
int
);
static
int
armada_370_xp
_enter_idle
(
struct
cpuidle_device
*
dev
,
static
int
mvebu_v7
_enter_idle
(
struct
cpuidle_device
*
dev
,
struct
cpuidle_driver
*
drv
,
int
index
)
{
...
...
@@ -34,10 +33,10 @@ static int armada_370_xp_enter_idle(struct cpuidle_device *dev,
bool
deepidle
=
false
;
cpu_pm_enter
();
if
(
drv
->
states
[
index
].
flags
&
ARMADA_370_XP
_FLAG_DEEP_IDLE
)
if
(
drv
->
states
[
index
].
flags
&
MVEBU_V7
_FLAG_DEEP_IDLE
)
deepidle
=
true
;
ret
=
armada_370_xp
_cpu_suspend
(
deepidle
);
ret
=
mvebu_v7
_cpu_suspend
(
deepidle
);
if
(
ret
)
return
ret
;
...
...
@@ -46,11 +45,11 @@ static int armada_370_xp_enter_idle(struct cpuidle_device *dev,
return
index
;
}
static
struct
cpuidle_driver
armada
_370_
xp_idle_driver
=
{
.
name
=
"armada_
370_
xp_idle"
,
static
struct
cpuidle_driver
armadaxp_idle_driver
=
{
.
name
=
"armada_xp_idle"
,
.
states
[
0
]
=
ARM_CPUIDLE_WFI_STATE
,
.
states
[
1
]
=
{
.
enter
=
armada_370_xp
_enter_idle
,
.
enter
=
mvebu_v7
_enter_idle
,
.
exit_latency
=
10
,
.
power_usage
=
50
,
.
target_residency
=
100
,
...
...
@@ -59,35 +58,93 @@ static struct cpuidle_driver armada_370_xp_idle_driver = {
.
desc
=
"CPU power down"
,
},
.
states
[
2
]
=
{
.
enter
=
armada_370_xp
_enter_idle
,
.
enter
=
mvebu_v7
_enter_idle
,
.
exit_latency
=
100
,
.
power_usage
=
5
,
.
target_residency
=
1000
,
.
flags
=
CPUIDLE_FLAG_TIME_VALID
|
ARMADA_370_XP
_FLAG_DEEP_IDLE
,
MVEBU_V7
_FLAG_DEEP_IDLE
,
.
name
=
"MV CPU DEEP IDLE"
,
.
desc
=
"CPU and L2 Fabric power down"
,
},
.
state_count
=
ARMADA_370_XP_MAX_STATES
,
.
state_count
=
3
,
};
static
int
armada_370_xp_cpuidle_probe
(
struct
platform_device
*
pdev
)
static
struct
cpuidle_driver
armada370_idle_driver
=
{
.
name
=
"armada_370_idle"
,
.
states
[
0
]
=
ARM_CPUIDLE_WFI_STATE
,
.
states
[
1
]
=
{
.
enter
=
mvebu_v7_enter_idle
,
.
exit_latency
=
100
,
.
power_usage
=
5
,
.
target_residency
=
1000
,
.
flags
=
(
CPUIDLE_FLAG_TIME_VALID
|
MVEBU_V7_FLAG_DEEP_IDLE
),
.
name
=
"Deep Idle"
,
.
desc
=
"CPU and L2 Fabric power down"
,
},
.
state_count
=
2
,
};
static
struct
cpuidle_driver
armada38x_idle_driver
=
{
.
name
=
"armada_38x_idle"
,
.
states
[
0
]
=
ARM_CPUIDLE_WFI_STATE
,
.
states
[
1
]
=
{
.
enter
=
mvebu_v7_enter_idle
,
.
exit_latency
=
10
,
.
power_usage
=
5
,
.
target_residency
=
100
,
.
flags
=
CPUIDLE_FLAG_TIME_VALID
,
.
name
=
"Idle"
,
.
desc
=
"CPU and SCU power down"
,
},
.
state_count
=
2
,
};
static
int
mvebu_v7_cpuidle_probe
(
struct
platform_device
*
pdev
)
{
mvebu_v7_cpu_suspend
=
pdev
->
dev
.
platform_data
;
armada_370_xp_cpu_suspend
=
(
void
*
)(
pdev
->
dev
.
platform_data
);
return
cpuidle_register
(
&
armada_370_xp_idle_driver
,
NULL
);
if
(
!
strcmp
(
pdev
->
dev
.
driver
->
name
,
"cpuidle-armada-xp"
))
return
cpuidle_register
(
&
armadaxp_idle_driver
,
NULL
);
else
if
(
!
strcmp
(
pdev
->
dev
.
driver
->
name
,
"cpuidle-armada-370"
))
return
cpuidle_register
(
&
armada370_idle_driver
,
NULL
);
else
if
(
!
strcmp
(
pdev
->
dev
.
driver
->
name
,
"cpuidle-armada-38x"
))
return
cpuidle_register
(
&
armada38x_idle_driver
,
NULL
);
else
return
-
EINVAL
;
}
static
struct
platform_driver
armada_370_xp_cpuidle_plat_driver
=
{
static
struct
platform_driver
armadaxp_cpuidle_plat_driver
=
{
.
driver
=
{
.
name
=
"cpuidle-armada-xp"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
mvebu_v7_cpuidle_probe
,
};
module_platform_driver
(
armadaxp_cpuidle_plat_driver
);
static
struct
platform_driver
armada370_cpuidle_plat_driver
=
{
.
driver
=
{
.
name
=
"cpuidle-armada-370"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
mvebu_v7_cpuidle_probe
,
};
module_platform_driver
(
armada370_cpuidle_plat_driver
);
static
struct
platform_driver
armada38x_cpuidle_plat_driver
=
{
.
driver
=
{
.
name
=
"cpuidle-armada-3
70-xp
"
,
.
name
=
"cpuidle-armada-3
8x
"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
armada_370_xp
_cpuidle_probe
,
.
probe
=
mvebu_v7
_cpuidle_probe
,
};
module_platform_driver
(
armada
_370_xp
_cpuidle_plat_driver
);
module_platform_driver
(
armada
38x
_cpuidle_plat_driver
);
MODULE_AUTHOR
(
"Gregory CLEMENT <gregory.clement@free-electrons.com>"
);
MODULE_DESCRIPTION
(
"
Armada 370/XP cpu
idle driver"
);
MODULE_DESCRIPTION
(
"
Marvell EBU v7 cpu
idle driver"
);
MODULE_LICENSE
(
"GPL"
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录