Skip to content

Commit 3f22421

Browse files
marcankeithbusch
authored andcommitted
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>
1 parent eefa72a commit 3f22421

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

drivers/nvme/host/apple.c

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,25 +1011,37 @@ static void apple_nvme_reset_work(struct work_struct *work)
10111011
ret = apple_rtkit_shutdown(anv->rtk);
10121012
if (ret)
10131013
goto out;
1014+
1015+
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
10141016
}
10151017

1016-
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1018+
/*
1019+
* Only do the soft-reset if the CPU is not running, which means either we
1020+
* or the previous stage shut it down cleanly.
1021+
*/
1022+
if (!(readl(anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL) &
1023+
APPLE_ANS_COPROC_CPU_CONTROL_RUN)) {
10171024

1018-
ret = reset_control_assert(anv->reset);
1019-
if (ret)
1020-
goto out;
1025+
ret = reset_control_assert(anv->reset);
1026+
if (ret)
1027+
goto out;
10211028

1022-
ret = apple_rtkit_reinit(anv->rtk);
1023-
if (ret)
1024-
goto out;
1029+
ret = apple_rtkit_reinit(anv->rtk);
1030+
if (ret)
1031+
goto out;
10251032

1026-
ret = reset_control_deassert(anv->reset);
1027-
if (ret)
1028-
goto out;
1033+
ret = reset_control_deassert(anv->reset);
1034+
if (ret)
1035+
goto out;
1036+
1037+
writel(APPLE_ANS_COPROC_CPU_CONTROL_RUN,
1038+
anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1039+
1040+
ret = apple_rtkit_boot(anv->rtk);
1041+
} else {
1042+
ret = apple_rtkit_wake(anv->rtk);
1043+
}
10291044

1030-
writel(APPLE_ANS_COPROC_CPU_CONTROL_RUN,
1031-
anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1032-
ret = apple_rtkit_boot(anv->rtk);
10331045
if (ret) {
10341046
dev_err(anv->dev, "ANS did not boot");
10351047
goto out;
@@ -1565,9 +1577,12 @@ static void apple_nvme_remove(struct platform_device *pdev)
15651577
apple_nvme_disable(anv, true);
15661578
nvme_uninit_ctrl(&anv->ctrl);
15671579

1568-
if (apple_rtkit_is_running(anv->rtk))
1580+
if (apple_rtkit_is_running(anv->rtk)) {
15691581
apple_rtkit_shutdown(anv->rtk);
15701582

1583+
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1584+
}
1585+
15711586
apple_nvme_detach_genpd(anv);
15721587
}
15731588

@@ -1576,8 +1591,11 @@ static void apple_nvme_shutdown(struct platform_device *pdev)
15761591
struct apple_nvme *anv = platform_get_drvdata(pdev);
15771592

15781593
apple_nvme_disable(anv, true);
1579-
if (apple_rtkit_is_running(anv->rtk))
1594+
if (apple_rtkit_is_running(anv->rtk)) {
15801595
apple_rtkit_shutdown(anv->rtk);
1596+
1597+
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1598+
}
15811599
}
15821600

15831601
static int apple_nvme_resume(struct device *dev)
@@ -1594,10 +1612,11 @@ static int apple_nvme_suspend(struct device *dev)
15941612

15951613
apple_nvme_disable(anv, true);
15961614

1597-
if (apple_rtkit_is_running(anv->rtk))
1615+
if (apple_rtkit_is_running(anv->rtk)) {
15981616
ret = apple_rtkit_shutdown(anv->rtk);
15991617

1600-
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1618+
writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
1619+
}
16011620

16021621
return ret;
16031622
}

0 commit comments

Comments
 (0)