1/* 2 * pmu.c, Power Management Unit routines for NEC VR4100 series. 3 * 4 * Copyright (C) 2003-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20#include <linux/errno.h> 21#include <linux/init.h> 22#include <linux/ioport.h> 23#include <linux/kernel.h> 24#include <linux/pm.h> 25#include <linux/smp.h> 26#include <linux/types.h> 27 28#include <asm/cpu.h> 29#include <asm/io.h> 30#include <asm/reboot.h> 31#include <asm/system.h> 32 33#define PMU_TYPE1_BASE 0x0b0000a0UL 34#define PMU_TYPE1_SIZE 0x0eUL 35 36#define PMU_TYPE2_BASE 0x0f0000c0UL 37#define PMU_TYPE2_SIZE 0x10UL 38 39#define PMUCNT2REG 0x06 40 #define SOFTRST 0x0010 41 42static void __iomem *pmu_base; 43 44#define pmu_read(offset) readw(pmu_base + (offset)) 45#define pmu_write(offset, value) writew((value), pmu_base + (offset)) 46 47static inline void software_reset(void) 48{ 49 uint16_t pmucnt2; 50 51 switch (current_cpu_data.cputype) { 52 case CPU_VR4122: 53 case CPU_VR4131: 54 case CPU_VR4133: 55 pmucnt2 = pmu_read(PMUCNT2REG); 56 pmucnt2 |= SOFTRST; 57 pmu_write(PMUCNT2REG, pmucnt2); 58 break; 59 default: 60 break; 61 } 62} 63 64static void vr41xx_restart(char *command) 65{ 66 local_irq_disable(); 67 software_reset(); 68 printk(KERN_NOTICE "\nYou can reset your system\n"); 69 while (1) ; 70} 71 72static void vr41xx_halt(void) 73{ 74 local_irq_disable(); 75 printk(KERN_NOTICE "\nYou can turn off the power supply\n"); 76 while (1) ; 77} 78 79static void vr41xx_power_off(void) 80{ 81 local_irq_disable(); 82 printk(KERN_NOTICE "\nYou can turn off the power supply\n"); 83 while (1) ; 84} 85 86static int __init vr41xx_pmu_init(void) 87{ 88 unsigned long start, size; 89 90 switch (current_cpu_data.cputype) { 91 case CPU_VR4111: 92 case CPU_VR4121: 93 start = PMU_TYPE1_BASE; 94 size = PMU_TYPE1_SIZE; 95 break; 96 case CPU_VR4122: 97 case CPU_VR4131: 98 case CPU_VR4133: 99 start = PMU_TYPE2_BASE; 100 size = PMU_TYPE2_SIZE; 101 break; 102 default: 103 printk("Unexpected CPU of NEC VR4100 series\n"); 104 return -ENODEV; 105 } 106 107 if (request_mem_region(start, size, "PMU") == NULL) 108 return -EBUSY; 109 110 pmu_base = ioremap(start, size); 111 if (pmu_base == NULL) { 112 release_mem_region(start, size); 113 return -EBUSY; 114 } 115 116 _machine_restart = vr41xx_restart; 117 _machine_halt = vr41xx_halt; 118 pm_power_off = vr41xx_power_off; 119 120 return 0; 121} 122 123core_initcall(vr41xx_pmu_init); 124