linux/arch/arm/mach-tegra/hotplug.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-realview/hotplug.c
   3 *
   4 *  Copyright (C) 2002 ARM Ltd.
   5 *  All Rights Reserved
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11#include <linux/kernel.h>
  12#include <linux/errno.h>
  13#include <linux/smp.h>
  14
  15#include <asm/cacheflush.h>
  16
  17static inline void cpu_enter_lowpower(void)
  18{
  19        unsigned int v;
  20
  21        flush_cache_all();
  22        asm volatile(
  23        "       mcr     p15, 0, %1, c7, c5, 0\n"
  24        "       mcr     p15, 0, %1, c7, c10, 4\n"
  25        /*
  26         * Turn off coherency
  27         */
  28        "       mrc     p15, 0, %0, c1, c0, 1\n"
  29        "       bic     %0, %0, #0x20\n"
  30        "       mcr     p15, 0, %0, c1, c0, 1\n"
  31        "       mrc     p15, 0, %0, c1, c0, 0\n"
  32        "       bic     %0, %0, %2\n"
  33        "       mcr     p15, 0, %0, c1, c0, 0\n"
  34          : "=&r" (v)
  35          : "r" (0), "Ir" (CR_C)
  36          : "cc");
  37}
  38
  39static inline void cpu_leave_lowpower(void)
  40{
  41        unsigned int v;
  42
  43        asm volatile(
  44        "mrc    p15, 0, %0, c1, c0, 0\n"
  45        "       orr     %0, %0, %1\n"
  46        "       mcr     p15, 0, %0, c1, c0, 0\n"
  47        "       mrc     p15, 0, %0, c1, c0, 1\n"
  48        "       orr     %0, %0, #0x20\n"
  49        "       mcr     p15, 0, %0, c1, c0, 1\n"
  50          : "=&r" (v)
  51          : "Ir" (CR_C)
  52          : "cc");
  53}
  54
  55static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
  56{
  57        /*
  58         * there is no power-control hardware on this platform, so all
  59         * we can do is put the core into WFI; this is safe as the calling
  60         * code will have already disabled interrupts
  61         */
  62        for (;;) {
  63                /*
  64                 * here's the WFI
  65                 */
  66                asm(".word      0xe320f003\n"
  67                    :
  68                    :
  69                    : "memory", "cc");
  70
  71                /*if (pen_release == cpu) {*/
  72                        /*
  73                         * OK, proper wakeup, we're done
  74                         */
  75                        break;
  76                /*}*/
  77
  78                /*
  79                 * Getting here, means that we have come out of WFI without
  80                 * having been woken up - this shouldn't happen
  81                 *
  82                 * Just note it happening - when we're woken, we can report
  83                 * its occurrence.
  84                 */
  85                (*spurious)++;
  86        }
  87}
  88
  89int platform_cpu_kill(unsigned int cpu)
  90{
  91        return 1;
  92}
  93
  94/*
  95 * platform-specific code to shutdown a CPU
  96 *
  97 * Called with IRQs disabled
  98 */
  99void platform_cpu_die(unsigned int cpu)
 100{
 101        int spurious = 0;
 102
 103        /*
 104         * we're ready for shutdown now, so do it
 105         */
 106        cpu_enter_lowpower();
 107        platform_do_lowpower(cpu, &spurious);
 108
 109        /*
 110         * bring this CPU back into the world of cache
 111         * coherency, and then restore interrupts
 112         */
 113        cpu_leave_lowpower();
 114
 115        if (spurious)
 116                pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
 117}
 118
 119int platform_cpu_disable(unsigned int cpu)
 120{
 121        /*
 122         * we don't allow CPU 0 to be shutdown (it is still too special
 123         * e.g. clock tick interrupts)
 124         */
 125        return cpu == 0 ? -EPERM : 0;
 126}
 127