diff options
author | Olof Johansson <olof@lixom.net> | 2014-07-08 01:27:00 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2014-07-08 01:27:00 -0400 |
commit | b3c20e983269667ecce75fa7f4b0353917a8d0d1 (patch) | |
tree | ffae8b70f4c1b66791d7b805c427388f28aabfc2 /arch/arm/mach-mvebu | |
parent | 98abaf1370c932db38a23b270f86689b66b34cdf (diff) | |
parent | e65714740d65237c40878b63acad6bf921481974 (diff) |
Merge tag 'mvebu-soc-3.17' of git://git.infradead.org/linux-mvebu into next/soc
Merge "mvebu SoC changes for v3.17" from Jason Cooper:
- kirkwood
* add setup file for netxbig LEDs (non-trivial DT binding doesn't exist yet)
- mvebu
* staticize where needed
* add CPU hotplug for Armada XP
* add public datasheet for Armada 370
* don't apply thermal quirk by default
* get SoC ID from the system controller when possible
* tag 'mvebu-soc-3.17' of git://git.infradead.org/linux-mvebu:
ARM: mvebu: Staticize mvebu_cpu_reset_init
ARM: mvebu: Staticize armada_370_xp_cpu_pm_init
ARM: mvebu: Staticize armada_375_smp_cpu1_enable_wa
ARM: mvebu: Use system controller to get the soc id when possible
ARM: mvebu: Use the a standard errno in mvebu_get_soc_id
ARM: mvebu: Don't apply the thermal quirk if the SoC revision is unknown
Documentation: arm: add URLs to public datasheets for the Marvell Armada 370 SoC
ARM: mvebu: implement CPU hotplug support for Armada XP
ARM: mvebu: export PMSU idle enter/exit functions
ARM: mvebu: slightly refactor/rename PMSU idle related functions
ARM: mvebu: remove stub implementation of CPU hotplug on Armada 375/38x
ARM: Kirkwood: Add setup file for netxbig LEDs
ARM: mvebu: mark armada_370_xp_pmsu_idle_prepare() as static
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-mvebu')
-rw-r--r-- | arch/arm/mach-mvebu/Kconfig | 7 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/armada-370-xp.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/board-v7.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/board.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/common.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/cpu-reset.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/hotplug.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/kirkwood.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/mvebu-soc-id.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/netxbig.c | 191 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/platsmp-a9.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/platsmp.c | 48 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/pmsu.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/system-controller.c | 19 |
15 files changed, 316 insertions, 54 deletions
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index b9bc599a5fd0..955d4a3afabd 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig | |||
@@ -96,4 +96,11 @@ config MACH_KIRKWOOD | |||
96 | Say 'Y' here if you want your kernel to support boards based | 96 | Say 'Y' here if you want your kernel to support boards based |
97 | on the Marvell Kirkwood device tree. | 97 | on the Marvell Kirkwood device tree. |
98 | 98 | ||
99 | config MACH_NETXBIG | ||
100 | bool "LaCie 2Big and 5Big Network v2" | ||
101 | depends on MACH_KIRKWOOD | ||
102 | help | ||
103 | Say 'Y' here if you want your kernel to support the | ||
104 | LaCie 2Big and 5Big Network v2 | ||
105 | |||
99 | endif | 106 | endif |
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 2ecb828e4a8b..90bcd5327312 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile | |||
@@ -9,8 +9,8 @@ obj-y += system-controller.o mvebu-soc-id.o | |||
9 | ifeq ($(CONFIG_MACH_MVEBU_V7),y) | 9 | ifeq ($(CONFIG_MACH_MVEBU_V7),y) |
10 | obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o | 10 | obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o |
11 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o | 11 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o |
12 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | ||
13 | endif | 12 | endif |
14 | 13 | ||
15 | obj-$(CONFIG_MACH_DOVE) += dove.o | 14 | obj-$(CONFIG_MACH_DOVE) += dove.o |
16 | obj-$(CONFIG_MACH_KIRKWOOD) += kirkwood.o kirkwood-pm.o | 15 | obj-$(CONFIG_MACH_KIRKWOOD) += kirkwood.o kirkwood-pm.o |
16 | obj-$(CONFIG_MACH_NETXBIG) += netxbig.o | ||
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h index c3465f5b1250..52c1603a4f92 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.h +++ b/arch/arm/mach-mvebu/armada-370-xp.h | |||
@@ -24,4 +24,7 @@ void armada_xp_secondary_startup(void); | |||
24 | extern struct smp_operations armada_xp_smp_ops; | 24 | extern struct smp_operations armada_xp_smp_ops; |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | int armada_370_xp_pmsu_idle_enter(unsigned long deepidle); | ||
28 | void armada_370_xp_pmsu_idle_exit(void); | ||
29 | |||
27 | #endif /* __MACH_ARMADA_370_XP_H */ | 30 | #endif /* __MACH_ARMADA_370_XP_H */ |
diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c index 8bb742fdf5ca..a04675e2ec99 100644 --- a/arch/arm/mach-mvebu/board-v7.c +++ b/arch/arm/mach-mvebu/board-v7.c | |||
@@ -118,8 +118,16 @@ static void __init thermal_quirk(void) | |||
118 | { | 118 | { |
119 | struct device_node *np; | 119 | struct device_node *np; |
120 | u32 dev, rev; | 120 | u32 dev, rev; |
121 | int res; | ||
121 | 122 | ||
122 | if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV) | 123 | /* |
124 | * The early SoC Z1 revision needs a quirk to be applied in order | ||
125 | * for the thermal controller to work properly. This quirk breaks | ||
126 | * the thermal support if applied on a SoC that doesn't need it, | ||
127 | * so we enforce the SoC revision to be known. | ||
128 | */ | ||
129 | res = mvebu_get_soc_id(&dev, &rev); | ||
130 | if (res < 0 || (res == 0 && rev > ARMADA_375_Z1_REV)) | ||
123 | return; | 131 | return; |
124 | 132 | ||
125 | for_each_compatible_node(np, NULL, "marvell,armada375-thermal") { | 133 | for_each_compatible_node(np, NULL, "marvell,armada375-thermal") { |
@@ -153,7 +161,8 @@ static void __init thermal_quirk(void) | |||
153 | 161 | ||
154 | /* | 162 | /* |
155 | * The thermal controller needs some quirk too, so let's change | 163 | * The thermal controller needs some quirk too, so let's change |
156 | * the compatible string to reflect this. | 164 | * the compatible string to reflect this and allow the driver |
165 | * the take the necessary action. | ||
157 | */ | 166 | */ |
158 | prop = kzalloc(sizeof(*prop), GFP_KERNEL); | 167 | prop = kzalloc(sizeof(*prop), GFP_KERNEL); |
159 | prop->name = kstrdup("compatible", GFP_KERNEL); | 168 | prop->name = kstrdup("compatible", GFP_KERNEL); |
diff --git a/arch/arm/mach-mvebu/board.h b/arch/arm/mach-mvebu/board.h index 9c7bb4386f8b..98e32cc2ef3d 100644 --- a/arch/arm/mach-mvebu/board.h +++ b/arch/arm/mach-mvebu/board.h | |||
@@ -13,4 +13,9 @@ | |||
13 | #ifndef __ARCH_MVEBU_BOARD_H | 13 | #ifndef __ARCH_MVEBU_BOARD_H |
14 | #define __ARCH_MVEBU_BOARD_H | 14 | #define __ARCH_MVEBU_BOARD_H |
15 | 15 | ||
16 | #ifdef CONFIG_MACH_NETXBIG | ||
17 | void netxbig_init(void); | ||
18 | #else | ||
19 | static inline void netxbig_init(void) {}; | ||
20 | #endif | ||
16 | #endif | 21 | #endif |
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h index b67fb7a10d8b..a97778e28bf6 100644 --- a/arch/arm/mach-mvebu/common.h +++ b/arch/arm/mach-mvebu/common.h | |||
@@ -21,7 +21,6 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd); | |||
21 | int mvebu_cpu_reset_deassert(int cpu); | 21 | int mvebu_cpu_reset_deassert(int cpu); |
22 | void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr); | 22 | void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr); |
23 | void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr); | 23 | void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr); |
24 | 24 | int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev); | |
25 | void armada_xp_cpu_die(unsigned int cpu); | ||
26 | 25 | ||
27 | #endif | 26 | #endif |
diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c index 4a8f9eebebea..60fb53787004 100644 --- a/arch/arm/mach-mvebu/cpu-reset.c +++ b/arch/arm/mach-mvebu/cpu-reset.c | |||
@@ -67,7 +67,7 @@ static int mvebu_cpu_reset_map(struct device_node *np, int res_idx) | |||
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | int __init mvebu_cpu_reset_init(void) | 70 | static int __init mvebu_cpu_reset_init(void) |
71 | { | 71 | { |
72 | struct device_node *np; | 72 | struct device_node *np; |
73 | int res_idx; | 73 | int res_idx; |
diff --git a/arch/arm/mach-mvebu/hotplug.c b/arch/arm/mach-mvebu/hotplug.c deleted file mode 100644 index d95e91047168..000000000000 --- a/arch/arm/mach-mvebu/hotplug.c +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | /* | ||
2 | * Symmetric Multi Processing (SMP) support for Armada XP | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * | ||
10 | * This file is licensed under the terms of the GNU General Public | ||
11 | * License version 2. This program is licensed "as is" without any | ||
12 | * warranty of any kind, whether express or implied. | ||
13 | */ | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/smp.h> | ||
17 | #include <asm/proc-fns.h> | ||
18 | #include "common.h" | ||
19 | |||
20 | /* | ||
21 | * platform-specific code to shutdown a CPU | ||
22 | * | ||
23 | * Called with IRQs disabled | ||
24 | */ | ||
25 | void __ref armada_xp_cpu_die(unsigned int cpu) | ||
26 | { | ||
27 | cpu_do_idle(); | ||
28 | |||
29 | /* We should never return from idle */ | ||
30 | panic("mvebu: cpu %d unexpectedly exit from shutdown\n", cpu); | ||
31 | } | ||
diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c index 46f105913c84..6b5310828eb2 100644 --- a/arch/arm/mach-mvebu/kirkwood.c +++ b/arch/arm/mach-mvebu/kirkwood.c | |||
@@ -180,6 +180,9 @@ static void __init kirkwood_dt_init(void) | |||
180 | kirkwood_pm_init(); | 180 | kirkwood_pm_init(); |
181 | kirkwood_dt_eth_fixup(); | 181 | kirkwood_dt_eth_fixup(); |
182 | 182 | ||
183 | if (of_machine_is_compatible("lacie,netxbig")) | ||
184 | netxbig_init(); | ||
185 | |||
183 | of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL); | 186 | of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL); |
184 | } | 187 | } |
185 | 188 | ||
diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.c b/arch/arm/mach-mvebu/mvebu-soc-id.c index d0f35b4d4a23..a99434bcee84 100644 --- a/arch/arm/mach-mvebu/mvebu-soc-id.c +++ b/arch/arm/mach-mvebu/mvebu-soc-id.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/of_address.h> | 25 | #include <linux/of_address.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/sys_soc.h> | 27 | #include <linux/sys_soc.h> |
28 | #include "common.h" | ||
28 | #include "mvebu-soc-id.h" | 29 | #include "mvebu-soc-id.h" |
29 | 30 | ||
30 | #define PCIE_DEV_ID_OFF 0x0 | 31 | #define PCIE_DEV_ID_OFF 0x0 |
@@ -51,10 +52,10 @@ int mvebu_get_soc_id(u32 *dev, u32 *rev) | |||
51 | *rev = soc_rev; | 52 | *rev = soc_rev; |
52 | return 0; | 53 | return 0; |
53 | } else | 54 | } else |
54 | return -1; | 55 | return -ENODEV; |
55 | } | 56 | } |
56 | 57 | ||
57 | static int __init mvebu_soc_id_init(void) | 58 | static int __init get_soc_id_by_pci(void) |
58 | { | 59 | { |
59 | struct device_node *np; | 60 | struct device_node *np; |
60 | int ret = 0; | 61 | int ret = 0; |
@@ -129,6 +130,22 @@ clk_err: | |||
129 | 130 | ||
130 | return ret; | 131 | return ret; |
131 | } | 132 | } |
133 | |||
134 | static int __init mvebu_soc_id_init(void) | ||
135 | { | ||
136 | |||
137 | /* | ||
138 | * First try to get the ID and the revision by the system | ||
139 | * register and use PCI registers only if it is not possible | ||
140 | */ | ||
141 | if (!mvebu_system_controller_get_soc_id(&soc_dev_id, &soc_rev)) { | ||
142 | is_id_valid = true; | ||
143 | pr_info("MVEBU SoC ID=0x%X, Rev=0x%X\n", soc_dev_id, soc_rev); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | return get_soc_id_by_pci(); | ||
148 | } | ||
132 | early_initcall(mvebu_soc_id_init); | 149 | early_initcall(mvebu_soc_id_init); |
133 | 150 | ||
134 | static int __init mvebu_soc_device(void) | 151 | static int __init mvebu_soc_device(void) |
diff --git a/arch/arm/mach-mvebu/netxbig.c b/arch/arm/mach-mvebu/netxbig.c new file mode 100644 index 000000000000..94b11b6585a4 --- /dev/null +++ b/arch/arm/mach-mvebu/netxbig.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-mvbu/board-netxbig.c | ||
3 | * | ||
4 | * LaCie 2Big and 5Big Network v2 board setup | ||
5 | * | ||
6 | * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/platform_data/leds-kirkwood-netxbig.h> | ||
23 | #include "common.h" | ||
24 | |||
25 | /***************************************************************************** | ||
26 | * GPIO extension LEDs | ||
27 | ****************************************************************************/ | ||
28 | |||
29 | /* | ||
30 | * The LEDs are controlled by a CPLD and can be configured through a GPIO | ||
31 | * extension bus: | ||
32 | * | ||
33 | * - address register : bit [0-2] -> GPIO [47-49] | ||
34 | * - data register : bit [0-2] -> GPIO [44-46] | ||
35 | * - enable register : GPIO 29 | ||
36 | */ | ||
37 | |||
38 | static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 }; | ||
39 | static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 }; | ||
40 | |||
41 | static struct netxbig_gpio_ext netxbig_v2_gpio_ext = { | ||
42 | .addr = netxbig_v2_gpio_ext_addr, | ||
43 | .num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr), | ||
44 | .data = netxbig_v2_gpio_ext_data, | ||
45 | .num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data), | ||
46 | .enable = 29, | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * Address register selection: | ||
51 | * | ||
52 | * addr | register | ||
53 | * ---------------------------- | ||
54 | * 0 | front LED | ||
55 | * 1 | front LED brightness | ||
56 | * 2 | SATA LED brightness | ||
57 | * 3 | SATA0 LED | ||
58 | * 4 | SATA1 LED | ||
59 | * 5 | SATA2 LED | ||
60 | * 6 | SATA3 LED | ||
61 | * 7 | SATA4 LED | ||
62 | * | ||
63 | * Data register configuration: | ||
64 | * | ||
65 | * data | LED brightness | ||
66 | * ------------------------------------------------- | ||
67 | * 0 | min (off) | ||
68 | * - | - | ||
69 | * 7 | max | ||
70 | * | ||
71 | * data | front LED mode | ||
72 | * ------------------------------------------------- | ||
73 | * 0 | fix off | ||
74 | * 1 | fix blue on | ||
75 | * 2 | fix red on | ||
76 | * 3 | blink blue on=1 sec and blue off=1 sec | ||
77 | * 4 | blink red on=1 sec and red off=1 sec | ||
78 | * 5 | blink blue on=2.5 sec and red on=0.5 sec | ||
79 | * 6 | blink blue on=1 sec and red on=1 sec | ||
80 | * 7 | blink blue on=0.5 sec and blue off=2.5 sec | ||
81 | * | ||
82 | * data | SATA LED mode | ||
83 | * ------------------------------------------------- | ||
84 | * 0 | fix off | ||
85 | * 1 | SATA activity blink | ||
86 | * 2 | fix red on | ||
87 | * 3 | blink blue on=1 sec and blue off=1 sec | ||
88 | * 4 | blink red on=1 sec and red off=1 sec | ||
89 | * 5 | blink blue on=2.5 sec and red on=0.5 sec | ||
90 | * 6 | blink blue on=1 sec and red on=1 sec | ||
91 | * 7 | fix blue on | ||
92 | */ | ||
93 | |||
94 | static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = { | ||
95 | [NETXBIG_LED_OFF] = 0, | ||
96 | [NETXBIG_LED_ON] = 2, | ||
97 | [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE, | ||
98 | [NETXBIG_LED_TIMER1] = 4, | ||
99 | [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE, | ||
100 | }; | ||
101 | |||
102 | static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = { | ||
103 | [NETXBIG_LED_OFF] = 0, | ||
104 | [NETXBIG_LED_ON] = 1, | ||
105 | [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE, | ||
106 | [NETXBIG_LED_TIMER1] = 3, | ||
107 | [NETXBIG_LED_TIMER2] = 7, | ||
108 | }; | ||
109 | |||
110 | static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = { | ||
111 | [NETXBIG_LED_OFF] = 0, | ||
112 | [NETXBIG_LED_ON] = 7, | ||
113 | [NETXBIG_LED_SATA] = 1, | ||
114 | [NETXBIG_LED_TIMER1] = 3, | ||
115 | [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE, | ||
116 | }; | ||
117 | |||
118 | static struct netxbig_led_timer netxbig_v2_led_timer[] = { | ||
119 | [0] = { | ||
120 | .delay_on = 500, | ||
121 | .delay_off = 500, | ||
122 | .mode = NETXBIG_LED_TIMER1, | ||
123 | }, | ||
124 | [1] = { | ||
125 | .delay_on = 500, | ||
126 | .delay_off = 1000, | ||
127 | .mode = NETXBIG_LED_TIMER2, | ||
128 | }, | ||
129 | }; | ||
130 | |||
131 | #define NETXBIG_LED(_name, maddr, mval, baddr) \ | ||
132 | { .name = _name, \ | ||
133 | .mode_addr = maddr, \ | ||
134 | .mode_val = mval, \ | ||
135 | .bright_addr = baddr } | ||
136 | |||
137 | static struct netxbig_led net2big_v2_leds_ctrl[] = { | ||
138 | NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1), | ||
139 | NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1), | ||
140 | NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2), | ||
141 | NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2), | ||
142 | NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2), | ||
143 | NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2), | ||
144 | }; | ||
145 | |||
146 | static struct netxbig_led_platform_data net2big_v2_leds_data = { | ||
147 | .gpio_ext = &netxbig_v2_gpio_ext, | ||
148 | .timer = netxbig_v2_led_timer, | ||
149 | .num_timer = ARRAY_SIZE(netxbig_v2_led_timer), | ||
150 | .leds = net2big_v2_leds_ctrl, | ||
151 | .num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl), | ||
152 | }; | ||
153 | |||
154 | static struct netxbig_led net5big_v2_leds_ctrl[] = { | ||
155 | NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1), | ||
156 | NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1), | ||
157 | NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2), | ||
158 | NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2), | ||
159 | NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2), | ||
160 | NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2), | ||
161 | NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2), | ||
162 | NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2), | ||
163 | NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2), | ||
164 | NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2), | ||
165 | NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2), | ||
166 | NETXBIG_LED("net5big-v2:red:sata4", 7, netxbig_v2_red_mled, 2), | ||
167 | }; | ||
168 | |||
169 | static struct netxbig_led_platform_data net5big_v2_leds_data = { | ||
170 | .gpio_ext = &netxbig_v2_gpio_ext, | ||
171 | .timer = netxbig_v2_led_timer, | ||
172 | .num_timer = ARRAY_SIZE(netxbig_v2_led_timer), | ||
173 | .leds = net5big_v2_leds_ctrl, | ||
174 | .num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl), | ||
175 | }; | ||
176 | |||
177 | static struct platform_device netxbig_v2_leds = { | ||
178 | .name = "leds-netxbig", | ||
179 | .id = -1, | ||
180 | .dev = { | ||
181 | .platform_data = &net2big_v2_leds_data, | ||
182 | }, | ||
183 | }; | ||
184 | |||
185 | void __init netxbig_init(void) | ||
186 | { | ||
187 | |||
188 | if (of_machine_is_compatible("lacie,net5big_v2")) | ||
189 | netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data; | ||
190 | platform_device_register(&netxbig_v2_leds); | ||
191 | } | ||
diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c index 96c2c59e34b6..43aaf3fa75ee 100644 --- a/arch/arm/mach-mvebu/platsmp-a9.c +++ b/arch/arm/mach-mvebu/platsmp-a9.c | |||
@@ -33,7 +33,7 @@ | |||
33 | extern unsigned char armada_375_smp_cpu1_enable_code_end; | 33 | extern unsigned char armada_375_smp_cpu1_enable_code_end; |
34 | extern unsigned char armada_375_smp_cpu1_enable_code_start; | 34 | extern unsigned char armada_375_smp_cpu1_enable_code_start; |
35 | 35 | ||
36 | void armada_375_smp_cpu1_enable_wa(void) | 36 | static void armada_375_smp_cpu1_enable_wa(void) |
37 | { | 37 | { |
38 | void __iomem *sram_virt_base; | 38 | void __iomem *sram_virt_base; |
39 | 39 | ||
@@ -91,9 +91,6 @@ static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu, | |||
91 | 91 | ||
92 | static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = { | 92 | static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = { |
93 | .smp_boot_secondary = mvebu_cortex_a9_boot_secondary, | 93 | .smp_boot_secondary = mvebu_cortex_a9_boot_secondary, |
94 | #ifdef CONFIG_HOTPLUG_CPU | ||
95 | .cpu_die = armada_xp_cpu_die, | ||
96 | #endif | ||
97 | }; | 94 | }; |
98 | 95 | ||
99 | CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp", | 96 | CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp", |
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index 88b976b31719..b6fa9f0c98b8 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c | |||
@@ -78,6 +78,17 @@ static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
78 | 78 | ||
79 | hw_cpu = cpu_logical_map(cpu); | 79 | hw_cpu = cpu_logical_map(cpu); |
80 | mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup); | 80 | mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup); |
81 | |||
82 | /* | ||
83 | * This is needed to wake up CPUs in the offline state after | ||
84 | * using CPU hotplug. | ||
85 | */ | ||
86 | arch_send_wakeup_ipi_mask(cpumask_of(cpu)); | ||
87 | |||
88 | /* | ||
89 | * This is needed to take secondary CPUs out of reset on the | ||
90 | * initial boot. | ||
91 | */ | ||
81 | ret = mvebu_cpu_reset_deassert(hw_cpu); | 92 | ret = mvebu_cpu_reset_deassert(hw_cpu); |
82 | if (ret) { | 93 | if (ret) { |
83 | pr_warn("unable to boot CPU: %d\n", ret); | 94 | pr_warn("unable to boot CPU: %d\n", ret); |
@@ -87,6 +98,19 @@ static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
87 | return 0; | 98 | return 0; |
88 | } | 99 | } |
89 | 100 | ||
101 | /* | ||
102 | * When a CPU is brought back online, either through CPU hotplug, or | ||
103 | * because of the boot of a kexec'ed kernel, the PMSU configuration | ||
104 | * for this CPU might be in the deep idle state, preventing this CPU | ||
105 | * from receiving interrupts. Here, we therefore take out the current | ||
106 | * CPU from this state, which was entered by armada_xp_cpu_die() | ||
107 | * below. | ||
108 | */ | ||
109 | static void armada_xp_secondary_init(unsigned int cpu) | ||
110 | { | ||
111 | armada_370_xp_pmsu_idle_exit(); | ||
112 | } | ||
113 | |||
90 | static void __init armada_xp_smp_init_cpus(void) | 114 | static void __init armada_xp_smp_init_cpus(void) |
91 | { | 115 | { |
92 | unsigned int ncores = num_possible_cpus(); | 116 | unsigned int ncores = num_possible_cpus(); |
@@ -122,12 +146,36 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) | |||
122 | panic("The address for the BootROM is incorrect"); | 146 | panic("The address for the BootROM is incorrect"); |
123 | } | 147 | } |
124 | 148 | ||
149 | #ifdef CONFIG_HOTPLUG_CPU | ||
150 | static void armada_xp_cpu_die(unsigned int cpu) | ||
151 | { | ||
152 | /* | ||
153 | * CPU hotplug is implemented by putting offline CPUs into the | ||
154 | * deep idle sleep state. | ||
155 | */ | ||
156 | armada_370_xp_pmsu_idle_enter(true); | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * We need a dummy function, so that platform_can_cpu_hotplug() knows | ||
161 | * we support CPU hotplug. However, the function does not need to do | ||
162 | * anything, because CPUs going offline can enter the deep idle state | ||
163 | * by themselves, without any help from a still alive CPU. | ||
164 | */ | ||
165 | static int armada_xp_cpu_kill(unsigned int cpu) | ||
166 | { | ||
167 | return 1; | ||
168 | } | ||
169 | #endif | ||
170 | |||
125 | struct smp_operations armada_xp_smp_ops __initdata = { | 171 | struct smp_operations armada_xp_smp_ops __initdata = { |
126 | .smp_init_cpus = armada_xp_smp_init_cpus, | 172 | .smp_init_cpus = armada_xp_smp_init_cpus, |
127 | .smp_prepare_cpus = armada_xp_smp_prepare_cpus, | 173 | .smp_prepare_cpus = armada_xp_smp_prepare_cpus, |
128 | .smp_boot_secondary = armada_xp_boot_secondary, | 174 | .smp_boot_secondary = armada_xp_boot_secondary, |
175 | .smp_secondary_init = armada_xp_secondary_init, | ||
129 | #ifdef CONFIG_HOTPLUG_CPU | 176 | #ifdef CONFIG_HOTPLUG_CPU |
130 | .cpu_die = armada_xp_cpu_die, | 177 | .cpu_die = armada_xp_cpu_die, |
178 | .cpu_kill = armada_xp_cpu_kill, | ||
131 | #endif | 179 | #endif |
132 | }; | 180 | }; |
133 | 181 | ||
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c index 53a55c8520bf..9c819d65b337 100644 --- a/arch/arm/mach-mvebu/pmsu.c +++ b/arch/arm/mach-mvebu/pmsu.c | |||
@@ -148,13 +148,13 @@ static void armada_370_xp_cpu_resume(void) | |||
148 | } | 148 | } |
149 | 149 | ||
150 | /* No locking is needed because we only access per-CPU registers */ | 150 | /* No locking is needed because we only access per-CPU registers */ |
151 | void armada_370_xp_pmsu_idle_prepare(bool deepidle) | 151 | int armada_370_xp_pmsu_idle_enter(unsigned long deepidle) |
152 | { | 152 | { |
153 | unsigned int hw_cpu = cpu_logical_map(smp_processor_id()); | 153 | unsigned int hw_cpu = cpu_logical_map(smp_processor_id()); |
154 | u32 reg; | 154 | u32 reg; |
155 | 155 | ||
156 | if (pmsu_mp_base == NULL) | 156 | if (pmsu_mp_base == NULL) |
157 | return; | 157 | return -EINVAL; |
158 | 158 | ||
159 | /* | 159 | /* |
160 | * Adjust the PMSU configuration to wait for WFI signal, enable | 160 | * Adjust the PMSU configuration to wait for WFI signal, enable |
@@ -183,11 +183,6 @@ void armada_370_xp_pmsu_idle_prepare(bool deepidle) | |||
183 | reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu)); | 183 | reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu)); |
184 | reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP; | 184 | reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP; |
185 | writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu)); | 185 | writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu)); |
186 | } | ||
187 | |||
188 | static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle) | ||
189 | { | ||
190 | armada_370_xp_pmsu_idle_prepare(deepidle); | ||
191 | 186 | ||
192 | v7_exit_coherency_flush(all); | 187 | v7_exit_coherency_flush(all); |
193 | 188 | ||
@@ -220,11 +215,11 @@ static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle) | |||
220 | 215 | ||
221 | static int armada_370_xp_cpu_suspend(unsigned long deepidle) | 216 | static int armada_370_xp_cpu_suspend(unsigned long deepidle) |
222 | { | 217 | { |
223 | return cpu_suspend(deepidle, do_armada_370_xp_cpu_suspend); | 218 | return cpu_suspend(deepidle, armada_370_xp_pmsu_idle_enter); |
224 | } | 219 | } |
225 | 220 | ||
226 | /* No locking is needed because we only access per-CPU registers */ | 221 | /* No locking is needed because we only access per-CPU registers */ |
227 | static noinline void armada_370_xp_pmsu_idle_restore(void) | 222 | void armada_370_xp_pmsu_idle_exit(void) |
228 | { | 223 | { |
229 | unsigned int hw_cpu = cpu_logical_map(smp_processor_id()); | 224 | unsigned int hw_cpu = cpu_logical_map(smp_processor_id()); |
230 | u32 reg; | 225 | u32 reg; |
@@ -253,7 +248,7 @@ static int armada_370_xp_cpu_pm_notify(struct notifier_block *self, | |||
253 | unsigned int hw_cpu = cpu_logical_map(smp_processor_id()); | 248 | unsigned int hw_cpu = cpu_logical_map(smp_processor_id()); |
254 | mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume); | 249 | mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume); |
255 | } else if (action == CPU_PM_EXIT) { | 250 | } else if (action == CPU_PM_EXIT) { |
256 | armada_370_xp_pmsu_idle_restore(); | 251 | armada_370_xp_pmsu_idle_exit(); |
257 | } | 252 | } |
258 | 253 | ||
259 | return NOTIFY_OK; | 254 | return NOTIFY_OK; |
@@ -263,7 +258,7 @@ static struct notifier_block armada_370_xp_cpu_pm_notifier = { | |||
263 | .notifier_call = armada_370_xp_cpu_pm_notify, | 258 | .notifier_call = armada_370_xp_cpu_pm_notify, |
264 | }; | 259 | }; |
265 | 260 | ||
266 | int __init armada_370_xp_cpu_pm_init(void) | 261 | static int __init armada_370_xp_cpu_pm_init(void) |
267 | { | 262 | { |
268 | struct device_node *np; | 263 | struct device_node *np; |
269 | 264 | ||
diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c index 0c5524ac75b7..b2b4e3d6558c 100644 --- a/arch/arm/mach-mvebu/system-controller.c +++ b/arch/arm/mach-mvebu/system-controller.c | |||
@@ -39,6 +39,9 @@ struct mvebu_system_controller { | |||
39 | u32 system_soft_reset; | 39 | u32 system_soft_reset; |
40 | 40 | ||
41 | u32 resume_boot_addr; | 41 | u32 resume_boot_addr; |
42 | |||
43 | u32 dev_id; | ||
44 | u32 rev_id; | ||
42 | }; | 45 | }; |
43 | static struct mvebu_system_controller *mvebu_sc; | 46 | static struct mvebu_system_controller *mvebu_sc; |
44 | 47 | ||
@@ -47,6 +50,8 @@ static const struct mvebu_system_controller armada_370_xp_system_controller = { | |||
47 | .system_soft_reset_offset = 0x64, | 50 | .system_soft_reset_offset = 0x64, |
48 | .rstoutn_mask_reset_out_en = 0x1, | 51 | .rstoutn_mask_reset_out_en = 0x1, |
49 | .system_soft_reset = 0x1, | 52 | .system_soft_reset = 0x1, |
53 | .dev_id = 0x38, | ||
54 | .rev_id = 0x3c, | ||
50 | }; | 55 | }; |
51 | 56 | ||
52 | static const struct mvebu_system_controller armada_375_system_controller = { | 57 | static const struct mvebu_system_controller armada_375_system_controller = { |
@@ -55,6 +60,8 @@ static const struct mvebu_system_controller armada_375_system_controller = { | |||
55 | .rstoutn_mask_reset_out_en = 0x1, | 60 | .rstoutn_mask_reset_out_en = 0x1, |
56 | .system_soft_reset = 0x1, | 61 | .system_soft_reset = 0x1, |
57 | .resume_boot_addr = 0xd4, | 62 | .resume_boot_addr = 0xd4, |
63 | .dev_id = 0x38, | ||
64 | .rev_id = 0x3c, | ||
58 | }; | 65 | }; |
59 | 66 | ||
60 | static const struct mvebu_system_controller orion_system_controller = { | 67 | static const struct mvebu_system_controller orion_system_controller = { |
@@ -101,6 +108,18 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd) | |||
101 | ; | 108 | ; |
102 | } | 109 | } |
103 | 110 | ||
111 | int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev) | ||
112 | { | ||
113 | if (of_machine_is_compatible("marvell,armada380") && | ||
114 | system_controller_base) { | ||
115 | *dev = readl(system_controller_base + mvebu_sc->dev_id) >> 16; | ||
116 | *rev = (readl(system_controller_base + mvebu_sc->rev_id) >> 8) | ||
117 | & 0xF; | ||
118 | return 0; | ||
119 | } else | ||
120 | return -ENODEV; | ||
121 | } | ||
122 | |||
104 | #ifdef CONFIG_SMP | 123 | #ifdef CONFIG_SMP |
105 | void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr) | 124 | void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr) |
106 | { | 125 | { |