Skip to content

Commit 2639296

Browse files
committed
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 <[email protected]>
1 parent 7ce2916 commit 2639296

1 file changed

Lines changed: 36 additions & 17 deletions

File tree

drivers/nvme/host/apple.c

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,25 +1048,37 @@ static void apple_nvme_reset_work(struct work_struct *work)
10481048
ret = apple_rtkit_shutdown(anv->rtk);
10491049
if (ret)
10501050
goto out;
1051+
1052+
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
10511053
}
10521054

1053-
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1055+
/*
1056+
* Only do the soft-reset if the CPU is not running, which means either we
1057+
* or the previous stage shut it down cleanly.
1058+
*/
1059+
if (!(readl(anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL) &
1060+
APPLE_ANS_COPROC_CPU_CONTROL_RUN)) {
10541061

1055-
ret = reset_control_assert(anv->reset);
1056-
if (ret)
1057-
goto out;
1062+
ret = reset_control_assert(anv->reset);
1063+
if (ret)
1064+
goto out;
10581065

1059-
ret = apple_rtkit_reinit(anv->rtk);
1060-
if (ret)
1061-
goto out;
1066+
ret = apple_rtkit_reinit(anv->rtk);
1067+
if (ret)
1068+
goto out;
10621069

1063-
ret = reset_control_deassert(anv->reset);
1064-
if (ret)
1065-
goto out;
1070+
ret = reset_control_deassert(anv->reset);
1071+
if (ret)
1072+
goto out;
1073+
1074+
writel(APPLE_ANS_COPROC_CPU_CONTROL_RUN,
1075+
anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1076+
1077+
ret = apple_rtkit_boot(anv->rtk);
1078+
} else {
1079+
ret = apple_rtkit_wake(anv->rtk);
1080+
}
10661081

1067-
writel(APPLE_ANS_COPROC_CPU_CONTROL_RUN,
1068-
anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1069-
ret = apple_rtkit_boot(anv->rtk);
10701082
if (ret) {
10711083
dev_err(anv->dev, "ANS did not boot");
10721084
goto out;
@@ -1611,9 +1623,12 @@ static int apple_nvme_remove(struct platform_device *pdev)
16111623
apple_nvme_disable(anv, true);
16121624
nvme_uninit_ctrl(&anv->ctrl);
16131625

1614-
if (apple_rtkit_is_running(anv->rtk))
1626+
if (apple_rtkit_is_running(anv->rtk)) {
16151627
apple_rtkit_shutdown(anv->rtk);
16161628

1629+
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1630+
}
1631+
16171632
apple_nvme_detach_genpd(anv);
16181633

16191634
return 0;
@@ -1625,8 +1640,11 @@ static void apple_nvme_shutdown(struct platform_device *pdev)
16251640

16261641
flush_delayed_work(&anv->flush_dwork);
16271642
apple_nvme_disable(anv, true);
1628-
if (apple_rtkit_is_running(anv->rtk))
1643+
if (apple_rtkit_is_running(anv->rtk)) {
16291644
apple_rtkit_shutdown(anv->rtk);
1645+
1646+
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1647+
}
16301648
}
16311649

16321650
static int apple_nvme_resume(struct device *dev)
@@ -1643,10 +1661,11 @@ static int apple_nvme_suspend(struct device *dev)
16431661

16441662
apple_nvme_disable(anv, true);
16451663

1646-
if (apple_rtkit_is_running(anv->rtk))
1664+
if (apple_rtkit_is_running(anv->rtk)) {
16471665
ret = apple_rtkit_shutdown(anv->rtk);
16481666

1649-
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1667+
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1668+
}
16501669

16511670
return ret;
16521671
}

0 commit comments

Comments
 (0)