From 4588e5e2a5f14bc63702ff19dfef8693568aa198 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 7 Apr 2011 12:18:26 +0800 Subject: [PATCH] rk29sdk: better support power on/off --- arch/arm/mach-rk29/Makefile | 4 +- arch/arm/mach-rk29/board-rk29-ddr3sdk.c | 13 +---- arch/arm/mach-rk29/board-rk29sdk-power.c | 67 ++++++++++++++++++++++++ arch/arm/mach-rk29/board-rk29sdk.c | 13 +---- arch/arm/mach-rk29/include/mach/board.h | 1 + 5 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 arch/arm/mach-rk29/board-rk29sdk-power.c diff --git a/arch/arm/mach-rk29/Makefile b/arch/arm/mach-rk29/Makefile index 398be7942d47..e514af5e2323 100644 --- a/arch/arm/mach-rk29/Makefile +++ b/arch/arm/mach-rk29/Makefile @@ -8,8 +8,8 @@ obj-$(CONFIG_USB_GADGET) += usb_detect.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_RK29_VPU) += vpu.o vpu_mem.o -obj-$(CONFIG_MACH_RK29SDK) += board-rk29sdk.o board-rk29sdk-key.o board-rk29sdk-rfkill.o -obj-$(CONFIG_MACH_RK29SDK_DDR3) += board-rk29-ddr3sdk.o board-rk29sdk-key.o board-rk29sdk-rfkill.o +obj-$(CONFIG_MACH_RK29SDK) += board-rk29sdk.o board-rk29sdk-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o +obj-$(CONFIG_MACH_RK29SDK_DDR3) += board-rk29-ddr3sdk.o board-rk29sdk-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o obj-$(CONFIG_MACH_RK29WINACCORD) += board-rk29-winaccord.o board-rk29sdk-key.o obj-$(CONFIG_MACH_RK29_AIGO) += board-rk29-aigo.o board-rk29aigo-key.o board-rk29sdk-rfkill.o obj-$(CONFIG_MACH_RK29_MALATA) += board-malata.o board-rk29malata-key.o board-rk29sdk-rfkill.o diff --git a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c index e22a6befc51a..72a5f4b868ea 100755 --- a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c +++ b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c @@ -1874,22 +1874,11 @@ static void __init machine_rk29_init_irq(void) rk29_gpio_init(); } -#define POWER_ON_PIN RK29_PIN4_PA4 -static void rk29_pm_power_off(void) -{ - printk(KERN_ERR "rk29_pm_power_off start...\n"); - gpio_direction_output(POWER_ON_PIN, GPIO_LOW); - while (1); -} - static void __init machine_rk29_board_init(void) { rk29_board_iomux_init(); - gpio_request(POWER_ON_PIN,"poweronpin"); - gpio_set_value(POWER_ON_PIN, GPIO_HIGH); - gpio_direction_output(POWER_ON_PIN, GPIO_HIGH); - pm_power_off = rk29_pm_power_off; + board_power_init(); platform_add_devices(devices, ARRAY_SIZE(devices)); #ifdef CONFIG_I2C0_RK29 diff --git a/arch/arm/mach-rk29/board-rk29sdk-power.c b/arch/arm/mach-rk29/board-rk29sdk-power.c new file mode 100644 index 000000000000..e63b0d99d73c --- /dev/null +++ b/arch/arm/mach-rk29/board-rk29sdk-power.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include + +#include +#include +#include + +#define POWER_ON_PIN RK29_PIN4_PA4 +#define PLAY_ON_PIN RK29_PIN6_PA7 + +static void rk29_pm_power_off(void) +{ + int count = 0; + + local_irq_disable(); + local_fiq_disable(); + + printk(KERN_ERR "rk29_pm_power_off start...\n"); + + /* arm enter slow mode */ + cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CPU_MODE_MASK) | CRU_CPU_MODE_SLOW, CRU_MODE_CON); + LOOP(LOOPS_PER_USEC); + + while (1) { + /* shut down the power by GPIO. */ + if (gpio_get_value(POWER_ON_PIN) == GPIO_HIGH) { + printk("POWER_ON_PIN is high\n"); + gpio_set_value(POWER_ON_PIN, GPIO_LOW); + } + + LOOP(5 * LOOPS_PER_MSEC); + + /* only normal power off can restart system safely */ + if (system_state != SYSTEM_POWER_OFF) + continue; + + if (gpio_get_value(PLAY_ON_PIN) != GPIO_HIGH) { + if (!count) + printk("PLAY_ON_PIN is low\n"); + if (50 == count) /* break if keep low about 250ms */ + break; + count++; + } else { + count = 0; + } + } + + printk("system reboot\n"); + gpio_set_value(POWER_ON_PIN, GPIO_HIGH); + system_state = SYSTEM_RESTART; + arm_pm_restart(0, NULL); + + while (1); +} + +int __init board_power_init(void) +{ + gpio_request(POWER_ON_PIN, "poweronpin"); + gpio_set_value(POWER_ON_PIN, GPIO_HIGH); + gpio_direction_output(POWER_ON_PIN, GPIO_HIGH); + pm_power_off = rk29_pm_power_off; + + return 0; +} + diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 2bbcaf239fc3..ba2f881dab3f 100755 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -1896,22 +1896,11 @@ static void __init machine_rk29_init_irq(void) rk29_gpio_init(); } -#define POWER_ON_PIN RK29_PIN4_PA4 -static void rk29_pm_power_off(void) -{ - printk(KERN_ERR "rk29_pm_power_off start...\n"); - gpio_direction_output(POWER_ON_PIN, GPIO_LOW); - while (1); -} - static void __init machine_rk29_board_init(void) { rk29_board_iomux_init(); - gpio_request(POWER_ON_PIN,"poweronpin"); - gpio_set_value(POWER_ON_PIN, GPIO_HIGH); - gpio_direction_output(POWER_ON_PIN, GPIO_HIGH); - pm_power_off = rk29_pm_power_off; + board_power_init(); platform_add_devices(devices, ARRAY_SIZE(devices)); #ifdef CONFIG_I2C0_RK29 diff --git a/arch/arm/mach-rk29/include/mach/board.h b/arch/arm/mach-rk29/include/mach/board.h index 8a111c602baa..e16ef7a2bd02 100755 --- a/arch/arm/mach-rk29/include/mach/board.h +++ b/arch/arm/mach-rk29/include/mach/board.h @@ -234,6 +234,7 @@ struct tca6424_platform_data { void __init rk29_setup_early_printk(void); void __init rk29_map_common_io(void); void __init rk29_clock_init(void); +void __init board_power_init(void); #define BOOT_MODE_NORMAL 0 #define BOOT_MODE_FACTORY2 1 -- 2.34.1