pmu.c 2.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3
/*
 *  pmu.c, Power Management Unit routines for NEC VR4100 series.
 *
4
 *  Copyright (C) 2003-2005  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
L
Linus Torvalds 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
20
#include <linux/errno.h>
L
Linus Torvalds 已提交
21
#include <linux/init.h>
22
#include <linux/ioport.h>
L
Linus Torvalds 已提交
23
#include <linux/kernel.h>
24
#include <linux/pm.h>
L
Linus Torvalds 已提交
25 26 27 28 29 30 31 32
#include <linux/smp.h>
#include <linux/types.h>

#include <asm/cpu.h>
#include <asm/io.h>
#include <asm/reboot.h>
#include <asm/system.h>

33 34 35 36 37 38 39
#define PMU_TYPE1_BASE	0x0b0000a0UL
#define PMU_TYPE1_SIZE	0x0eUL

#define PMU_TYPE2_BASE	0x0f0000c0UL
#define PMU_TYPE2_SIZE	0x10UL

#define PMUCNT2REG	0x06
L
Linus Torvalds 已提交
40 41
 #define SOFTRST	0x0010

42 43 44 45 46
static void __iomem *pmu_base;

#define pmu_read(offset)		readw(pmu_base + (offset))
#define pmu_write(offset, value)	writew((value), pmu_base + (offset))

L
Linus Torvalds 已提交
47 48
static inline void software_reset(void)
{
49
	uint16_t pmucnt2;
L
Linus Torvalds 已提交
50 51 52 53 54

	switch (current_cpu_data.cputype) {
	case CPU_VR4122:
	case CPU_VR4131:
	case CPU_VR4133:
55 56 57
		pmucnt2 = pmu_read(PMUCNT2REG);
		pmucnt2 |= SOFTRST;
		pmu_write(PMUCNT2REG, pmucnt2);
L
Linus Torvalds 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
		break;
	default:
		break;
	}
}

static void vr41xx_restart(char *command)
{
	local_irq_disable();
	software_reset();
	printk(KERN_NOTICE "\nYou can reset your system\n");
	while (1) ;
}

static void vr41xx_halt(void)
{
	local_irq_disable();
	printk(KERN_NOTICE "\nYou can turn off the power supply\n");
	while (1) ;
}

static void vr41xx_power_off(void)
{
	local_irq_disable();
	printk(KERN_NOTICE "\nYou can turn off the power supply\n");
	while (1) ;
}

static int __init vr41xx_pmu_init(void)
{
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
	unsigned long start, size;

	switch (current_cpu_data.cputype) {
	case CPU_VR4111:
	case CPU_VR4121:
		start = PMU_TYPE1_BASE;
		size = PMU_TYPE1_SIZE;
		break;
	case CPU_VR4122:
	case CPU_VR4131:
	case CPU_VR4133:
		start = PMU_TYPE2_BASE;
		size = PMU_TYPE2_SIZE;
		break;
	default:
		printk("Unexpected CPU of NEC VR4100 series\n");
		return -ENODEV;
	}

	if (request_mem_region(start, size, "PMU") == NULL)
		return -EBUSY;

	pmu_base = ioremap(start, size);
	if (pmu_base == NULL) {
		release_mem_region(start, size);
		return -EBUSY;
	}

L
Linus Torvalds 已提交
116 117
	_machine_restart = vr41xx_restart;
	_machine_halt = vr41xx_halt;
118
	pm_power_off = vr41xx_power_off;
L
Linus Torvalds 已提交
119 120 121 122

	return 0;
}

123
core_initcall(vr41xx_pmu_init);