[Meego-kernel] [PATCH 2/2] xf86/mrst.c: implement power_off and reboot for Medfield

Hong Liu hong.liu at intel.com
Thu Dec 2 01:12:38 PST 2010


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 <hong.liu at intel.com>
---
 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



More information about the MeeGo-kernel mailing list