Path: blob/master/arch/powerpc/platforms/pasemi/idle.c
10819 views
/*1* Copyright (C) 2006-2007 PA Semi, Inc2*3* Maintained by: Olof Johansson <[email protected]>4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License version 2 as7* published by the Free Software Foundation.8*9* This program is distributed in the hope that it will be useful,10* but WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12* GNU General Public License for more details.13*14* You should have received a copy of the GNU General Public License15* along with this program; if not, write to the Free Software16* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA17*18*/1920#undef DEBUG2122#include <linux/kernel.h>23#include <linux/string.h>24#include <linux/irq.h>2526#include <asm/machdep.h>27#include <asm/reg.h>28#include <asm/smp.h>2930#include "pasemi.h"3132struct sleep_mode {33char *name;34void (*entry)(void);35};3637static struct sleep_mode modes[] = {38{ .name = "spin", .entry = &idle_spin },39{ .name = "doze", .entry = &idle_doze },40};4142static int current_mode = 0;4344static int pasemi_system_reset_exception(struct pt_regs *regs)45{46/* If we were woken up from power savings, we need to return47* to the calling function, since nip is not saved across48* all modes.49*/5051if (regs->msr & SRR1_WAKEMASK)52regs->nip = regs->link;5354switch (regs->msr & SRR1_WAKEMASK) {55case SRR1_WAKEEE:56do_IRQ(regs);57break;58case SRR1_WAKEDEC:59timer_interrupt(regs);60break;61default:62/* do system reset */63return 0;64}6566/* Set higher astate since we come out of power savings at 0 */67restore_astate(hard_smp_processor_id());6869/* everything handled */70regs->msr |= MSR_RI;71return 1;72}7374static int __init pasemi_idle_init(void)75{76#ifndef CONFIG_PPC_PASEMI_CPUFREQ77printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n");78current_mode = 0;79#endif8081ppc_md.system_reset_exception = pasemi_system_reset_exception;82ppc_md.power_save = modes[current_mode].entry;83printk(KERN_INFO "Using PA6T idle loop (%s)\n", modes[current_mode].name);8485return 0;86}87machine_late_initcall(pasemi, pasemi_idle_init);8889static int __init idle_param(char *p)90{91int i;92for (i = 0; i < ARRAY_SIZE(modes); i++) {93if (!strcmp(modes[i].name, p)) {94current_mode = i;95break;96}97}98return 0;99}100101early_param("idle", idle_param);102103104