1/* 2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by the 6 * Free Software Foundation; either version 2 of the License, or (at your 7 * option) any later version. 8 * 9 * You should have received a copy of the GNU General Public License along 10 * with this program; if not, write to the Free Software Foundation, Inc., 11 * 675 Mass Ave, Cambridge, MA 02139, USA. 12 * 13 */ 14 15#include <linux/io.h> 16#include <linux/kernel.h> 17#include <linux/pm.h> 18 19#include <asm/reboot.h> 20 21#include <asm/mach-jz4740/base.h> 22#include <asm/mach-jz4740/timer.h> 23 24static void jz4740_halt(void) 25{ 26 while (1) { 27 __asm__(".set push;\n" 28 ".set mips3;\n" 29 "wait;\n" 30 ".set pop;\n" 31 ); 32 } 33} 34 35#define JZ_REG_WDT_DATA 0x00 36#define JZ_REG_WDT_COUNTER_ENABLE 0x04 37#define JZ_REG_WDT_COUNTER 0x08 38#define JZ_REG_WDT_CTRL 0x0c 39 40static void jz4740_restart(char *command) 41{ 42 void __iomem *wdt_base = ioremap(JZ4740_WDT_BASE_ADDR, 0x0f); 43 44 jz4740_timer_enable_watchdog(); 45 46 writeb(0, wdt_base + JZ_REG_WDT_COUNTER_ENABLE); 47 48 writew(0, wdt_base + JZ_REG_WDT_COUNTER); 49 writew(0, wdt_base + JZ_REG_WDT_DATA); 50 writew(BIT(2), wdt_base + JZ_REG_WDT_CTRL); 51 52 writeb(1, wdt_base + JZ_REG_WDT_COUNTER_ENABLE); 53 jz4740_halt(); 54} 55 56#define JZ_REG_RTC_CTRL 0x00 57#define JZ_REG_RTC_HIBERNATE 0x20 58 59#define JZ_RTC_CTRL_WRDY BIT(7) 60 61static void jz4740_power_off(void) 62{ 63 void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x24); 64 uint32_t ctrl; 65 66 do { 67 ctrl = readl(rtc_base + JZ_REG_RTC_CTRL); 68 } while (!(ctrl & JZ_RTC_CTRL_WRDY)); 69 70 writel(1, rtc_base + JZ_REG_RTC_HIBERNATE); 71 jz4740_halt(); 72} 73 74void jz4740_reset_init(void) 75{ 76 _machine_restart = jz4740_restart; 77 _machine_halt = jz4740_halt; 78 pm_power_off = jz4740_power_off; 79} 80