x86/platform/intel-mid: Implement power off sequence

Tell SCU that we are about powering off the device.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20160907123955.21228-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Andy Shevchenko 2016-09-07 15:39:55 +03:00 committed by Ingo Molnar
parent 3976b0380b
commit bda7b072de
4 changed files with 32 additions and 1 deletions

View File

@ -18,6 +18,8 @@
extern int intel_mid_pci_init(void);
extern int intel_mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state);
extern void intel_mid_pwr_power_off(void);
#define INTEL_MID_PWR_LSS_OFFSET 4
#define INTEL_MID_PWR_LSS_TYPE (1 << 7)

View File

@ -3,6 +3,8 @@
#include <linux/notifier.h>
#define IPCMSG_COLD_OFF 0x80 /* Only for Tangier */
#define IPCMSG_WARM_RESET 0xF0
#define IPCMSG_COLD_RESET 0xF1
#define IPCMSG_SOFT_RESET 0xF2

View File

@ -70,6 +70,11 @@ EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip);
static void intel_mid_power_off(void)
{
/* Shut down South Complex via PWRMU */
intel_mid_pwr_power_off();
/* Only for Tangier, the rest will ignore this command */
intel_scu_ipc_simple_command(IPCMSG_COLD_OFF, 1);
};
static void intel_mid_reboot(void)

View File

@ -48,7 +48,15 @@
#define PM_CMD_CM_IMMEDIATE (1 << 9)
#define PM_CMD_CM_DELAY (2 << 9)
#define PM_CMD_CM_TRIGGER (3 << 9)
#define PM_CMD_D3cold (1 << 21)
/* System states */
#define PM_CMD_SYS_STATE_S5 (5 << 16)
/* Trigger variants */
#define PM_CMD_CFG_TRIGGER_NC (3 << 19)
/* Message to wait for TRIGGER_NC case */
#define TRIGGER_NC_MSG_2 (2 << 22)
/* List of commands */
#define CMD_SET_CFG 0x01
@ -264,6 +272,20 @@ int intel_mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state)
}
EXPORT_SYMBOL_GPL(intel_mid_pci_set_power_state);
void intel_mid_pwr_power_off(void)
{
struct mid_pwr *pwr = midpwr;
u32 cmd = PM_CMD_SYS_STATE_S5 |
PM_CMD_CMD(CMD_SET_CFG) |
PM_CMD_CM_TRIGGER |
PM_CMD_CFG_TRIGGER_NC |
TRIGGER_NC_MSG_2;
/* Send command to SCU */
writel(cmd, pwr->regs + PM_CMD);
mid_pwr_wait(pwr);
}
int intel_mid_pwr_get_lss_id(struct pci_dev *pdev)
{
int vndr;