+Ricardo On Thu, 2024-10-10 at 17:36 -0700, David E. Box wrote: > On some platforms, aggressive C1 auto-demotion may lead to failure to > enter > the deepest C-state during suspend-to-idle, causing high power > consumption. > To prevent this, disable C1 auto-demotion during suspend and re- > enable on > resume. > > Signed-off-by: David E. Box <david.e.box@xxxxxxxxxxxxxxx> > --- > [...] > void cnl_suspend(struct pmc_dev *pmcdev) > { > + if (!pm_suspend_via_firmware()) { > + preempt_disable(); > + disable_c1_auto_demote(NULL); > + smp_call_function(disable_c1_auto_demote, NULL, 0); > + preempt_enable(); > + } > As suggested by Ricardo using the following will work avoiding separate local CPU call. Preemption will be disabled, no need separate call. Also cpu_online_mask can't be changed during these callbacks. if (!pm_suspend_via_firmware()) on_each_cpu(disable_c1_auto_demote, NULL, true); I think you need wait=true. I have seen on some occasions you will miss msr write as we called mwait before before async calls finished. Thanks, Srinivas > + > /* > * Due to a hardware limitation, the GBE LTR blocks PC10 > * when a cable is attached. To unblock PC10 during suspend, > @@ -218,6 +264,13 @@ void cnl_suspend(struct pmc_dev *pmcdev) > > int cnl_resume(struct pmc_dev *pmcdev) > { > + if (!pm_suspend_via_firmware()) { > + preempt_disable(); > + restore_c1_auto_demote(NULL); > + smp_call_function(restore_c1_auto_demote, NULL, 0); > + preempt_enable(); > + } > + > pmc_core_send_ltr_ignore(pmcdev, 3, 0); > > return pmc_core_resume_common(pmcdev);