apple-nvme: Support coprocessors left idle
iBoot on at least some firmwares/machines leaves ANS2 running, requiring a wake command instead of a CPU boot (and if we reset ANS2 in that state, everything breaks). Only stop the CPU if RTKit was running, and only do the reset dance if the CPU is stopped. Normal shutdown handoff: - RTKit not yet running - CPU detected not running - Reset - CPU powerup - RTKit boot wait ANS2 left running/idle: - RTKit not yet running - CPU detected running - RTKit wake message Sleep/resume cycle: - RTKit shutdown - CPU stopped - (sleep here) - CPU detected not running - Reset - CPU powerup - RTKit boot wait Shutdown or device removal: - RTKit shutdown - CPU stopped Therefore, the CPU running bit serves as a consistent flag of whether the coprocessor is fully stopped or just idle. Signed-off-by: Hector Martin <marcan@marcan.st> Reviewed-by: Neal Gompa <neal@gompa.dev> Reviewed-by: Sven Peter <sven@svenpeter.dev> Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
parent
eefa72a15e
commit
3f22421f6a
1 changed files with 36 additions and 17 deletions
|
@ -1011,25 +1011,37 @@ static void apple_nvme_reset_work(struct work_struct *work)
|
|||
ret = apple_rtkit_shutdown(anv->rtk);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
|
||||
}
|
||||
|
||||
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
|
||||
/*
|
||||
* Only do the soft-reset if the CPU is not running, which means either we
|
||||
* or the previous stage shut it down cleanly.
|
||||
*/
|
||||
if (!(readl(anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL) &
|
||||
APPLE_ANS_COPROC_CPU_CONTROL_RUN)) {
|
||||
|
||||
ret = reset_control_assert(anv->reset);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = reset_control_assert(anv->reset);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = apple_rtkit_reinit(anv->rtk);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = apple_rtkit_reinit(anv->rtk);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = reset_control_deassert(anv->reset);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = reset_control_deassert(anv->reset);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
writel(APPLE_ANS_COPROC_CPU_CONTROL_RUN,
|
||||
anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
|
||||
|
||||
ret = apple_rtkit_boot(anv->rtk);
|
||||
} else {
|
||||
ret = apple_rtkit_wake(anv->rtk);
|
||||
}
|
||||
|
||||
writel(APPLE_ANS_COPROC_CPU_CONTROL_RUN,
|
||||
anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
|
||||
ret = apple_rtkit_boot(anv->rtk);
|
||||
if (ret) {
|
||||
dev_err(anv->dev, "ANS did not boot");
|
||||
goto out;
|
||||
|
@ -1565,9 +1577,12 @@ static void apple_nvme_remove(struct platform_device *pdev)
|
|||
apple_nvme_disable(anv, true);
|
||||
nvme_uninit_ctrl(&anv->ctrl);
|
||||
|
||||
if (apple_rtkit_is_running(anv->rtk))
|
||||
if (apple_rtkit_is_running(anv->rtk)) {
|
||||
apple_rtkit_shutdown(anv->rtk);
|
||||
|
||||
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
|
||||
}
|
||||
|
||||
apple_nvme_detach_genpd(anv);
|
||||
}
|
||||
|
||||
|
@ -1576,8 +1591,11 @@ static void apple_nvme_shutdown(struct platform_device *pdev)
|
|||
struct apple_nvme *anv = platform_get_drvdata(pdev);
|
||||
|
||||
apple_nvme_disable(anv, true);
|
||||
if (apple_rtkit_is_running(anv->rtk))
|
||||
if (apple_rtkit_is_running(anv->rtk)) {
|
||||
apple_rtkit_shutdown(anv->rtk);
|
||||
|
||||
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
|
||||
}
|
||||
}
|
||||
|
||||
static int apple_nvme_resume(struct device *dev)
|
||||
|
@ -1594,10 +1612,11 @@ static int apple_nvme_suspend(struct device *dev)
|
|||
|
||||
apple_nvme_disable(anv, true);
|
||||
|
||||
if (apple_rtkit_is_running(anv->rtk))
|
||||
if (apple_rtkit_is_running(anv->rtk)) {
|
||||
ret = apple_rtkit_shutdown(anv->rtk);
|
||||
|
||||
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
|
||||
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue