aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorAaro Koskinen <aaro.koskinen@iki.fi>2014-06-27 17:59:50 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-08-01 18:06:42 -0400
commitf64988f13e82dd1797e59b26c8728d26c332aa43 (patch)
tree603c37b05a1a830847ebb927a126fd43f69e535e /drivers/watchdog
parent0953609f294bfdffb5144789904f4c11a5dafb38 (diff)
MIPS: OCTEON: watchdog: don't jump to bootloader without entry address
If CONFIG_HOTPLUG_CPU is set, the driver thinks bootloader entry address is configured and we should jump there. However, this is not necessarily true if the kernel is booted on a system with older/incompatible bootloader. Add dynamic checks for the bootloader entry address. Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi> Cc: linux-watchdog@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: David Daney <ddaney.cavm@gmail.com> Cc: linux-watchdog@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7201/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/octeon-wdt-main.c62
1 files changed, 34 insertions, 28 deletions
diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c
index 4baf2d788920..8453531545df 100644
--- a/drivers/watchdog/octeon-wdt-main.c
+++ b/drivers/watchdog/octeon-wdt-main.c
@@ -145,35 +145,39 @@ static void __init octeon_wdt_build_stage1(void)
145 145
146 uasm_i_mfc0(&p, K0, C0_STATUS); 146 uasm_i_mfc0(&p, K0, C0_STATUS);
147#ifdef CONFIG_HOTPLUG_CPU 147#ifdef CONFIG_HOTPLUG_CPU
148 uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), label_enter_bootloader); 148 if (octeon_bootloader_entry_addr)
149 uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI),
150 label_enter_bootloader);
149#endif 151#endif
150 /* Force 64-bit addressing enabled */ 152 /* Force 64-bit addressing enabled */
151 uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX); 153 uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX);
152 uasm_i_mtc0(&p, K0, C0_STATUS); 154 uasm_i_mtc0(&p, K0, C0_STATUS);
153 155
154#ifdef CONFIG_HOTPLUG_CPU 156#ifdef CONFIG_HOTPLUG_CPU
155 uasm_i_mfc0(&p, K0, C0_EBASE); 157 if (octeon_bootloader_entry_addr) {
156 /* Coreid number in K0 */ 158 uasm_i_mfc0(&p, K0, C0_EBASE);
157 uasm_i_andi(&p, K0, K0, 0xf); 159 /* Coreid number in K0 */
158 /* 8 * coreid in bits 16-31 */ 160 uasm_i_andi(&p, K0, K0, 0xf);
159 uasm_i_dsll_safe(&p, K0, K0, 3 + 16); 161 /* 8 * coreid in bits 16-31 */
160 uasm_i_ori(&p, K0, K0, 0x8001); 162 uasm_i_dsll_safe(&p, K0, K0, 3 + 16);
161 uasm_i_dsll_safe(&p, K0, K0, 16); 163 uasm_i_ori(&p, K0, K0, 0x8001);
162 uasm_i_ori(&p, K0, K0, 0x0700); 164 uasm_i_dsll_safe(&p, K0, K0, 16);
163 uasm_i_drotr_safe(&p, K0, K0, 32); 165 uasm_i_ori(&p, K0, K0, 0x0700);
164 /* 166 uasm_i_drotr_safe(&p, K0, K0, 32);
165 * Should result in: 0x8001,0700,0000,8*coreid which is 167 /*
166 * CVMX_CIU_WDOGX(coreid) - 0x0500 168 * Should result in: 0x8001,0700,0000,8*coreid which is
167 * 169 * CVMX_CIU_WDOGX(coreid) - 0x0500
168 * Now ld K0, CVMX_CIU_WDOGX(coreid) 170 *
169 */ 171 * Now ld K0, CVMX_CIU_WDOGX(coreid)
170 uasm_i_ld(&p, K0, 0x500, K0); 172 */
171 /* 173 uasm_i_ld(&p, K0, 0x500, K0);
172 * If bit one set handle the NMI as a watchdog event. 174 /*
173 * otherwise transfer control to bootloader. 175 * If bit one set handle the NMI as a watchdog event.
174 */ 176 * otherwise transfer control to bootloader.
175 uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader); 177 */
176 uasm_i_nop(&p); 178 uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader);
179 uasm_i_nop(&p);
180 }
177#endif 181#endif
178 182
179 /* Clear Dcache so cvmseg works right. */ 183 /* Clear Dcache so cvmseg works right. */
@@ -194,11 +198,13 @@ static void __init octeon_wdt_build_stage1(void)
194 uasm_i_dmfc0(&p, K0, C0_DESAVE); 198 uasm_i_dmfc0(&p, K0, C0_DESAVE);
195 199
196#ifdef CONFIG_HOTPLUG_CPU 200#ifdef CONFIG_HOTPLUG_CPU
197 uasm_build_label(&l, p, label_enter_bootloader); 201 if (octeon_bootloader_entry_addr) {
198 /* Jump to the bootloader and restore K0 */ 202 uasm_build_label(&l, p, label_enter_bootloader);
199 UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr); 203 /* Jump to the bootloader and restore K0 */
200 uasm_i_jr(&p, K0); 204 UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr);
201 uasm_i_dmfc0(&p, K0, C0_DESAVE); 205 uasm_i_jr(&p, K0);
206 uasm_i_dmfc0(&p, K0, C0_DESAVE);
207 }
202#endif 208#endif
203 uasm_resolve_relocs(relocs, labels); 209 uasm_resolve_relocs(relocs, labels);
204 210