From: Dyut Kumar Sil Date: Mon, 9 Jan 2012 03:39:05 +0000 (+0530) Subject: [PORT FROM R2] mid_pmu: remove sysfs interface (and create kernel interface) used... X-Git-Tag: 2.1b_release~1615 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=386c68c07230db6b5c6be8dd4d83b6956f58987b;p=kernel%2Fkernel-mfld-blackbay.git [PORT FROM R2] mid_pmu: remove sysfs interface (and create kernel interface) used to stop PM for IFWI update. BZ: 19383 This patch create a kernel interface pmu_set_devices_in_d0i0() to set all the south complex devices in D0i0 state and any further request to set any south complex device in some other low power state will be ignored. And this patch removes sysfs interface to do the same functionality. Change-Id: I04429659ef6932eb91f3c6f80f7c25b69b885fd5 Signed-off-by: Dyut Kumar Sil Signed-off-by: Illyas Mansoor Reviewed-on: http://android.intel.com:8080/31149 Tested-by: Martin, LoicX Reviewed-by: buildbot Tested-by: buildbot --- diff --git a/arch/x86/platform/mfld/pmu.c b/arch/x86/platform/mfld/pmu.c index 46d90a3..c09290c 100755 --- a/arch/x86/platform/mfld/pmu.c +++ b/arch/x86/platform/mfld/pmu.c @@ -567,59 +567,6 @@ static int _pmu_issue_command(struct pmu_ss_states *pm_ssc, int mode, int ioc, static void pmu_read_sss(struct pmu_ss_states *pm_ssc); static int _pmu2_wait_not_busy(void); -/* Experimentally disabling/enabling pmu drivers and setting every - * devices state as D0i0 while disabling pmu_driver */ -static char pmu_driver_state[4] = "on"; -static int set_pmu_driver_status(const char *val, struct kernel_param *kp) -{ - char valcp[4]; - int status; - struct pmu_ss_states cur_pmssc; - - strncpy(valcp, val, sizeof(valcp) - 1); - valcp[3] = '\0'; - - if (strncmp(valcp, "off", 3) == 0) { /* disable pmu driver and - * set all devices to D0i0 - */ - /* set all the lss to D0i0 */ - cur_pmssc.pmu2_states[0] = 0; - cur_pmssc.pmu2_states[1] = 0; - cur_pmssc.pmu2_states[2] = 0; - cur_pmssc.pmu2_states[3] = 0; - - /* Issue pmu command to PMU2 without interrupt to pmu_driver */ - down(&mid_pmu_cxt->scu_ready_sem); - status = _pmu_issue_command(&cur_pmssc, SET_MODE, 1, PMU_NUM_2); - - if (unlikely(status != PMU_SUCCESS)) { - dev_dbg(&mid_pmu_cxt->pmu_dev->dev, - "Failed to Issue a PM command to PMU2\n"); - } - up(&mid_pmu_cxt->scu_ready_sem); - - pmu_initialized = false; /* turn off pmu_initialized */ - strcpy(pmu_driver_state, "off"); - - } else { - /* invalid input: do nothing, keep the old state*/ - } - - return 0; -} - -static int get_pmu_driver_status(char *buffer, struct kernel_param *kp) -{ - strcpy(buffer, pmu_driver_state); - return strlen(pmu_driver_state); -} - - -module_param_call(pmu_driver_state, set_pmu_driver_status, - get_pmu_driver_status, NULL, 0644); -MODULE_PARM_DESC(pmu_driver_state, "setup pmu driver's state [on|off]"); - - /* PCI Device Id structure */ static DEFINE_PCI_DEVICE_TABLE(mid_pm_ids) = { {PCI_VDEVICE(INTEL, MID_PMU_MRST_DRV_DEV_ID), 0}, @@ -690,6 +637,54 @@ ret: } EXPORT_SYMBOL(get_target_platform_state); +/** + * This function set all devices in d0i0 and deactivates pmu driver. + * The function is used before IFWI update as it needs devices to be + * in d0i0 during IFWI update. Reboot is needed to work pmu + * driver properly again. After calling this function and IFWI + * update, system is always rebooted as IFWI update function, + * intel_scu_ipc_medfw_upgrade() is called from mrst_emergency_reboot(). + */ +int pmu_set_devices_in_d0i0(void) +{ + int status; + struct pmu_ss_states cur_pmssc; + + /* Ignore request until we have initialized */ + if (unlikely((!pmu_initialized))) + return 0; + + cur_pmssc.pmu2_states[0] = D0I0_MASK; + cur_pmssc.pmu2_states[1] = D0I0_MASK; + cur_pmssc.pmu2_states[2] = D0I0_MASK; + cur_pmssc.pmu2_states[3] = D0I0_MASK; + + down(&mid_pmu_cxt->scu_ready_sem); + + mid_pmu_cxt->shutdown_started = true; + + /* Issue the pmu command to PMU 2 + * flag is needed to distinguish between + * S0ix vs interactive command in pmu_sc_irq() + */ + status = _pmu_issue_command(&cur_pmssc, SET_MODE, 0, PMU_NUM_2); + + if (unlikely(status != PMU_SUCCESS)) { /* pmu command failed */ + dev_dbg(&mid_pmu_cxt->pmu_dev->dev, + "Failed to Issue a PM command to PMU2\n"); + mid_pmu_cxt->shutdown_started = false; + goto unlock; + } + + if (_pmu2_wait_not_busy()) + BUG(); + +unlock: + up(&mid_pmu_cxt->scu_ready_sem); + return status; +} +EXPORT_SYMBOL(pmu_set_devices_in_d0i0); + static int _pmu_read_status(int pmu_num, int type) { u32 temp; @@ -2755,14 +2750,14 @@ static int mid_suspend(suspend_state_t state) /* This function is here just to have a hook to execute code before * generic x86 shutdown is executed. saved_shutdown contains pointer * to original generic x86 shutdown function - * No need to hold scu_ready_sem, since the IPC will hold the sem now. */ void mfld_shutdown(void) { - down(&mid_pmu_cxt->scu_ready_sem); - if (mid_pmu_cxt) + if (mid_pmu_cxt) { + down(&mid_pmu_cxt->scu_ready_sem); mid_pmu_cxt->shutdown_started = true; - up(&mid_pmu_cxt->scu_ready_sem); + up(&mid_pmu_cxt->scu_ready_sem); + } if (saved_shutdown) saved_shutdown(); diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index 3a4f294..53eaaf9 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c @@ -166,9 +166,12 @@ static void mrst_power_off(void) } -static void mrst_reboot(void) +static void mrst_emergency_reboot(void) { - intel_scu_ipc_medfw_upgrade(); + if (intel_scu_ipc_medfw_upgrade()) { + pr_debug("intel_scu_ipc: IFWI upgrade failed...\n"); + BUG(); + } if (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT) intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 0); else @@ -396,7 +399,7 @@ void __init x86_mrst_early_setup(void) saved_shutdown = machine_ops.shutdown; machine_ops.shutdown = mfld_shutdown; } - machine_ops.emergency_restart = mrst_reboot; + machine_ops.emergency_restart = mrst_emergency_reboot; /* Avoid searching for BIOS MP tables */ x86_init.mpparse.find_smp_config = x86_init_noop; diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 81a15d0..f70ad85 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -31,6 +31,7 @@ #include #include #include +#include /* * IPC register summary @@ -1229,6 +1230,12 @@ int intel_scu_ipc_medfw_upgrade(void) goto unmap_mb; } + /* set all devices in d0i0 before IFWI upgrade */ + if (unlikely(pmu_set_devices_in_d0i0())) { + pr_debug("pmu: failed to set all devices in d0i0...\n"); + BUG(); + } + /* fuph header start */ fuph_start = fw_ud_param->fw_file_data + (fw_ud_param->fsize - 1) - (fw_ud_param->fuph_hdr_len - 1); diff --git a/include/linux/intel_mid_pm.h b/include/linux/intel_mid_pm.h index 3235dd2..58ddc08 100644 --- a/include/linux/intel_mid_pm.h +++ b/include/linux/intel_mid_pm.h @@ -103,6 +103,7 @@ extern int mfld_s0ix_enter(int); extern int get_target_platform_state(void); +extern int pmu_set_devices_in_d0i0(void); extern void pmu_set_s0ix_complete(void); extern bool pmu_is_s0i3_in_progress(void); extern int pmu_nc_set_power_state @@ -142,6 +143,8 @@ static inline int pmu_nc_set_power_state static inline void pmu_set_s0ix_complete(void) { return; } static inline void mfld_power_off(void) { return; } static inline bool pmu_is_s0ix_in_progress(void) { return false; }; +static inline int pmu_set_devices_in_d0i0(void) { return 0; } + #define mfld_shutdown NULL /*returns function not implemented*/