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

Reply via email to