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