[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