Currently SOF has disabled CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE option and
use pm_suspend_devices() to suspend and resume IPC device during D3
power flow. The pm_suspend_devices() function skips suspending devices
that are busy. In very rare cases, the IPC device is busy during the
power state transition, which results in the device not being restored
during reboot. This happens when FW sends a message to the HOST and
waits for ACK, and the HOST simultaneously sends a SET_DX message to the
DSP. This suspend/resume logic in IPC driver does not work well when the
system enters the D3 state because it is not a suspend state, but rather
a power-off. IPC does not require suspending, only reinitialization when
exiting D3. We cannot avoid this one missing ACK and it cannot block the
DSP from turning off.
When FW receives a SET_DX message it checks whether it can enter the D3
state and then returns an error (via IPC) or calls the pm_state_force
function. Success response is sent directly from power_down assembly and
not via ipc driver. This is because after receiving the response, the
HOST will turn off the DSP.
In order for the transition to D3 to take place, only the primary core
can be active, all pipes must be stopped (and therefore all modules in
FW). The only active thread at this time is the Idle thread. Driver on
the host will not send another ipc because is still waiting for
response. FW can try to send only two notification:
- FW exception: from this place there is no return to continue the power
transition,
- log buffer status: skipped, they remain in the queue without being
sent.
I'm moving pm_device_busy_clear(dev) from IRQ handler to
intel_adsp_ipc_send_message function so the pending ACK does not block
power transition.
Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>