1/* 2 * arch/blackfin/kernel/reboot.c - handle shutdown/reboot 3 * 4 * Copyright 2004-2007 Analog Devices Inc. 5 * 6 * Licensed under the GPL-2 or later. 7 */ 8 9#include <linux/interrupt.h> 10#include <asm/bfin-global.h> 11#include <asm/reboot.h> 12#include <asm/bfrom.h> 13 14/* A system soft reset makes external memory unusable so force 15 * this function into L1. We use the compiler ssync here rather 16 * than SSYNC() because it's safe (no interrupts and such) and 17 * we save some L1. We do not need to force sanity in the SYSCR 18 * register as the BMODE selection bit is cleared by the soft 19 * reset while the Core B bit (on dual core parts) is cleared by 20 * the core reset. 21 */ 22__attribute__ ((__l1_text__, __noreturn__)) 23static void bfin_reset(void) 24{ 25#ifndef CONFIG_BF60x 26 if (!ANOMALY_05000353 && !ANOMALY_05000386) 27 bfrom_SoftReset((void *)(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 20)); 28 29 /* Wait for completion of "system" events such as cache line 30 * line fills so that we avoid infinite stalls later on as 31 * much as possible. This code is in L1, so it won't trigger 32 * any such event after this point in time. 33 */ 34 __builtin_bfin_ssync(); 35 36 /* Initiate System software reset. */ 37 bfin_write_SWRST(0x7); 38 39 /* Due to the way reset is handled in the hardware, we need 40 * to delay for 10 SCLKS. The only reliable way to do this is 41 * to calculate the CCLK/SCLK ratio and multiply 10. For now, 42 * we'll assume worse case which is a 1:15 ratio. 43 */ 44 asm( 45 "LSETUP (1f, 1f) LC0 = %0\n" 46 "1: nop;" 47 : 48 : "a" (15 * 10) 49 : "LC0", "LB0", "LT0" 50 ); 51 52 /* Clear System software reset */ 53 bfin_write_SWRST(0); 54 55 /* The BF526 ROM will crash during reset */ 56#if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) 57 /* Seems to be fixed with newer parts though ... */ 58 if (__SILICON_REVISION__ < 1 && bfin_revid() < 1) 59 bfin_read_SWRST(); 60#endif 61 /* Wait for the SWRST write to complete. Cannot rely on SSYNC 62 * though as the System state is all reset now. 63 */ 64 asm( 65 "LSETUP (1f, 1f) LC1 = %0\n" 66 "1: nop;" 67 : 68 : "a" (15 * 1) 69 : "LC1", "LB1", "LT1" 70 ); 71 72 while (1) 73 /* Issue core reset */ 74 asm("raise 1"); 75#else 76 while (1) 77 bfin_write_RCU0_CTL(0x1); 78#endif 79} 80 81__attribute__((weak)) 82void native_machine_restart(char *cmd) 83{ 84} 85 86void machine_restart(char *cmd) 87{ 88 native_machine_restart(cmd); 89 if (smp_processor_id()) 90 smp_call_function((void *)bfin_reset, 0, 1); 91 else 92 bfin_reset(); 93} 94 95__attribute__((weak)) 96void native_machine_halt(void) 97{ 98 idle_with_irq_disabled(); 99} 100 101void machine_halt(void) 102{ 103 native_machine_halt(); 104} 105 106__attribute__((weak)) 107void native_machine_power_off(void) 108{ 109 idle_with_irq_disabled(); 110} 111 112void machine_power_off(void) 113{ 114 native_machine_power_off(); 115} 116