linux/arch/blackfin/kernel/reboot.c
<<
>>
Prefs
   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