@@ -195,8 +195,20 @@ struct apple_nvme {
195195
196196 int irq ;
197197 spinlock_t lock ;
198+
199+ /*
200+ * Delayed cache flush handling state
201+ */
202+ struct nvme_ns * flush_ns ;
203+ unsigned long flush_interval ;
204+ unsigned long last_flush ;
205+ struct delayed_work flush_dwork ;
198206};
199207
208+ unsigned int flush_interval = 1000 ;
209+ module_param (flush_interval , uint , 0644 );
210+ MODULE_PARM_DESC (flush_interval , "Grace period in msecs between flushes" );
211+
200212static_assert (sizeof (struct nvme_command ) == 64 );
201213static_assert (sizeof (struct apple_nvmmu_tcb ) == 128 );
202214
@@ -730,6 +742,26 @@ static int apple_nvme_remove_sq(struct apple_nvme *anv)
730742 return nvme_submit_sync_cmd (anv -> ctrl .admin_q , & c , NULL , 0 );
731743}
732744
745+ static bool apple_nvme_delayed_flush (struct apple_nvme * anv , struct nvme_ns * ns ,
746+ struct request * req )
747+ {
748+ if (!anv -> flush_interval || req_op (req ) != REQ_OP_FLUSH )
749+ return false;
750+ if (delayed_work_pending (& anv -> flush_dwork ))
751+ return true;
752+ if (time_before (jiffies , anv -> last_flush + anv -> flush_interval )) {
753+ kblockd_mod_delayed_work_on (WORK_CPU_UNBOUND , & anv -> flush_dwork ,
754+ anv -> flush_interval );
755+ if (WARN_ON_ONCE (anv -> flush_ns && anv -> flush_ns != ns ))
756+ goto out ;
757+ anv -> flush_ns = ns ;
758+ return true;
759+ }
760+ out :
761+ anv -> last_flush = jiffies ;
762+ return false;
763+ }
764+
733765static blk_status_t apple_nvme_queue_rq (struct blk_mq_hw_ctx * hctx ,
734766 const struct blk_mq_queue_data * bd )
735767{
@@ -765,6 +797,12 @@ static blk_status_t apple_nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
765797 }
766798
767799 nvme_start_request (req );
800+
801+ if (apple_nvme_delayed_flush (anv , ns , req )) {
802+ blk_mq_complete_request (req );
803+ return BLK_STS_OK ;
804+ }
805+
768806 apple_nvme_submit_cmd (q , cmnd );
769807 return BLK_STS_OK ;
770808
@@ -1012,25 +1050,37 @@ static void apple_nvme_reset_work(struct work_struct *work)
10121050 ret = apple_rtkit_shutdown (anv -> rtk );
10131051 if (ret )
10141052 goto out ;
1053+
1054+ writel (0 , anv -> mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL );
10151055 }
10161056
1017- writel (0 , anv -> mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL );
1057+ /*
1058+ * Only do the soft-reset if the CPU is not running, which means either we
1059+ * or the previous stage shut it down cleanly.
1060+ */
1061+ if (!(readl (anv -> mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL ) &
1062+ APPLE_ANS_COPROC_CPU_CONTROL_RUN )) {
10181063
1019- ret = reset_control_assert (anv -> reset );
1020- if (ret )
1021- goto out ;
1064+ ret = reset_control_assert (anv -> reset );
1065+ if (ret )
1066+ goto out ;
10221067
1023- ret = apple_rtkit_reinit (anv -> rtk );
1024- if (ret )
1025- goto out ;
1068+ ret = apple_rtkit_reinit (anv -> rtk );
1069+ if (ret )
1070+ goto out ;
10261071
1027- ret = reset_control_deassert (anv -> reset );
1028- if (ret )
1029- goto out ;
1072+ ret = reset_control_deassert (anv -> reset );
1073+ if (ret )
1074+ goto out ;
1075+
1076+ writel (APPLE_ANS_COPROC_CPU_CONTROL_RUN ,
1077+ anv -> mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL );
1078+
1079+ ret = apple_rtkit_boot (anv -> rtk );
1080+ } else {
1081+ ret = apple_rtkit_wake (anv -> rtk );
1082+ }
10301083
1031- writel (APPLE_ANS_COPROC_CPU_CONTROL_RUN ,
1032- anv -> mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL );
1033- ret = apple_rtkit_boot (anv -> rtk );
10341084 if (ret ) {
10351085 dev_err (anv -> dev , "ANS did not boot" );
10361086 goto out ;
@@ -1389,6 +1439,28 @@ static void devm_apple_nvme_mempool_destroy(void *data)
13891439 mempool_destroy (data );
13901440}
13911441
1442+ static void apple_nvme_flush_work (struct work_struct * work )
1443+ {
1444+ struct nvme_command c = { };
1445+ struct apple_nvme * anv ;
1446+ struct nvme_ns * ns ;
1447+ int err ;
1448+
1449+ anv = container_of (work , struct apple_nvme , flush_dwork .work );
1450+ ns = anv -> flush_ns ;
1451+ if (WARN_ON_ONCE (!ns ))
1452+ return ;
1453+
1454+ c .common .opcode = nvme_cmd_flush ;
1455+ c .common .nsid = cpu_to_le32 (anv -> flush_ns -> head -> ns_id );
1456+ err = nvme_submit_sync_cmd (ns -> queue , & c , NULL , 0 );
1457+ if (err ) {
1458+ dev_err (anv -> dev , "Deferred flush failed: %d\n" , err );
1459+ } else {
1460+ anv -> last_flush = jiffies ;
1461+ }
1462+ }
1463+
13921464static struct apple_nvme * apple_nvme_alloc (struct platform_device * pdev )
13931465{
13941466 struct device * dev = & pdev -> dev ;
@@ -1544,6 +1616,14 @@ static int apple_nvme_probe(struct platform_device *pdev)
15441616 goto out_uninit_ctrl ;
15451617 }
15461618
1619+ if (flush_interval ) {
1620+ anv -> flush_interval = msecs_to_jiffies (flush_interval );
1621+ anv -> flush_ns = NULL ;
1622+ anv -> last_flush = jiffies - anv -> flush_interval ;
1623+ }
1624+
1625+ INIT_DELAYED_WORK (& anv -> flush_dwork , apple_nvme_flush_work );
1626+
15471627 nvme_reset_ctrl (& anv -> ctrl );
15481628 async_schedule (apple_nvme_async_probe , anv );
15491629
@@ -1568,19 +1648,26 @@ static void apple_nvme_remove(struct platform_device *pdev)
15681648 apple_nvme_disable (anv , true);
15691649 nvme_uninit_ctrl (& anv -> ctrl );
15701650
1571- if (apple_rtkit_is_running (anv -> rtk ))
1651+ if (apple_rtkit_is_running (anv -> rtk )) {
15721652 apple_rtkit_shutdown (anv -> rtk );
15731653
1654+ writel (0 , anv -> mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL );
1655+ }
1656+
15741657 apple_nvme_detach_genpd (anv );
15751658}
15761659
15771660static void apple_nvme_shutdown (struct platform_device * pdev )
15781661{
15791662 struct apple_nvme * anv = platform_get_drvdata (pdev );
15801663
1664+ flush_delayed_work (& anv -> flush_dwork );
15811665 apple_nvme_disable (anv , true);
1582- if (apple_rtkit_is_running (anv -> rtk ))
1666+ if (apple_rtkit_is_running (anv -> rtk )) {
15831667 apple_rtkit_shutdown (anv -> rtk );
1668+
1669+ writel (0 , anv -> mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL );
1670+ }
15841671}
15851672
15861673static int apple_nvme_resume (struct device * dev )
@@ -1597,10 +1684,11 @@ static int apple_nvme_suspend(struct device *dev)
15971684
15981685 apple_nvme_disable (anv , true);
15991686
1600- if (apple_rtkit_is_running (anv -> rtk ))
1687+ if (apple_rtkit_is_running (anv -> rtk )) {
16011688 ret = apple_rtkit_shutdown (anv -> rtk );
16021689
1603- writel (0 , anv -> mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL );
1690+ writel (0 , anv -> mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL );
1691+ }
16041692
16051693 return ret ;
16061694}
0 commit comments