Use IPC driver to do the real work. For power_off, we need to detect the charger connection status. If it is connected, we need to boot into a special mode (active dead) to do the battery charging.
Signed-off-by: Hong Liu <[email protected]> --- arch/x86/kernel/mrst.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 62 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/mrst.c b/arch/x86/kernel/mrst.c index 7b1ad26..4dee8ca 100644 --- a/arch/x86/kernel/mrst.c +++ b/arch/x86/kernel/mrst.c @@ -371,14 +371,74 @@ static int mrst_i8042_detect(void) return 0; } +#define IPCMSG_COLD_RESET 0xF1 +#define IPCMSG_COLD_BOOT 0xF3 + +#define MSIC_RTC_CONFIG2 0x156 + #define MSIC_ACTIVE_DEAD (0x2 << 2) + #define MSIC_ACTIVE_DEAD_MASK (0x3 << 2) +#define MSIC_CHIP_CTRL 0x100 + #define MSIC_CHIP_COLD_OFF (1 << 3) + +#define MSIC_POWER_SRC_STAT 0x192 + #define MSIC_POWER_BATT (1 << 0) + #define MSIC_POWER_USB (1 << 1) +#define MSIC_USB_CHARGER_STAT 0x193 + #define MSIC_USB_CHARGER_MASK (BIT(6) | BIT(2)) + #define MSIC_USB_CDP BIT(6) + #define MSIC_USB_DCP BIT(2) + #define MSIC_USB_SDP 0 + +static bool check_charger_conn(void) +{ + int ret; + u8 data; + + ret = intel_scu_ipc_ioread8(MSIC_POWER_SRC_STAT, &data); + if (ret) + return false; + + if (!((data & MSIC_POWER_BATT) && (data & MSIC_POWER_USB))) + return false; + + ret = intel_scu_ipc_ioread8(MSIC_USB_CHARGER_STAT, &data); + if (ret) + return false; + + data &= MSIC_USB_CHARGER_MASK; + if (data != MSIC_USB_CDP && data != MSIC_USB_DCP && + data != MSIC_USB_SDP) + return false; + + return true; + +} + static void mrst_power_off(void) { - intel_scu_ipc_simple_command(0xf1, 1); + if (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT) + intel_scu_ipc_simple_command(0xf1, 1); + else { + bool charger_conn = check_charger_conn(); + + if (charger_conn) { + /* enter into active dead mode to do battery charging */ + intel_scu_ipc_update_register(MSIC_RTC_CONFIG2, + MSIC_ACTIVE_DEAD, MSIC_ACTIVE_DEAD_MASK); + intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 0); + } else { + intel_scu_ipc_update_register(MSIC_CHIP_CTRL, + MSIC_CHIP_COLD_OFF, MSIC_CHIP_COLD_OFF); + } + } } static void mrst_reboot(void) { - intel_scu_ipc_simple_command(0xf1, 0); + if (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT) + intel_scu_ipc_simple_command(0xf1, 0); + else + intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0); } /* -- 1.7.3.2 _______________________________________________ MeeGo-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
