@@ -115,41 +115,57 @@ static int ivpu_resume(struct ivpu_device *vdev)
115115 return ret ;
116116}
117117
118- static void ivpu_pm_recovery_work (struct work_struct * work )
118+ static void ivpu_pm_reset_begin (struct ivpu_device * vdev )
119119{
120- struct ivpu_pm_info * pm = container_of (work , struct ivpu_pm_info , recovery_work );
121- struct ivpu_device * vdev = pm -> vdev ;
122- char * evt [2 ] = {"IVPU_PM_EVENT=IVPU_RECOVER" , NULL };
123- int ret ;
124-
125- ivpu_err (vdev , "Recovering the NPU (reset #%d)\n" , atomic_read (& vdev -> pm -> reset_counter ));
126-
127- ret = pm_runtime_resume_and_get (vdev -> drm .dev );
128- if (ret )
129- ivpu_err (vdev , "Failed to resume NPU: %d\n" , ret );
130-
131- ivpu_jsm_state_dump (vdev );
132- ivpu_dev_coredump (vdev );
120+ pm_runtime_disable (vdev -> drm .dev );
133121
134122 atomic_inc (& vdev -> pm -> reset_counter );
135123 atomic_set (& vdev -> pm -> reset_pending , 1 );
136124 down_write (& vdev -> pm -> reset_lock );
125+ }
126+
127+ static void ivpu_pm_reset_complete (struct ivpu_device * vdev )
128+ {
129+ int ret ;
137130
138- ivpu_suspend (vdev );
139131 ivpu_pm_prepare_cold_boot (vdev );
140132 ivpu_jobs_abort_all (vdev );
141133 ivpu_ms_cleanup_all (vdev );
142134
143135 ret = ivpu_resume (vdev );
144- if (ret )
136+ if (ret ) {
145137 ivpu_err (vdev , "Failed to resume NPU: %d\n" , ret );
138+ pm_runtime_set_suspended (vdev -> drm .dev );
139+ } else {
140+ pm_runtime_set_active (vdev -> drm .dev );
141+ }
146142
147143 up_write (& vdev -> pm -> reset_lock );
148144 atomic_set (& vdev -> pm -> reset_pending , 0 );
149145
150- kobject_uevent_env (& vdev -> drm .dev -> kobj , KOBJ_CHANGE , evt );
151146 pm_runtime_mark_last_busy (vdev -> drm .dev );
152- pm_runtime_put_autosuspend (vdev -> drm .dev );
147+ pm_runtime_enable (vdev -> drm .dev );
148+ }
149+
150+ static void ivpu_pm_recovery_work (struct work_struct * work )
151+ {
152+ struct ivpu_pm_info * pm = container_of (work , struct ivpu_pm_info , recovery_work );
153+ struct ivpu_device * vdev = pm -> vdev ;
154+ char * evt [2 ] = {"IVPU_PM_EVENT=IVPU_RECOVER" , NULL };
155+
156+ ivpu_err (vdev , "Recovering the NPU (reset #%d)\n" , atomic_read (& vdev -> pm -> reset_counter ));
157+
158+ ivpu_pm_reset_begin (vdev );
159+
160+ if (!pm_runtime_status_suspended (vdev -> drm .dev )) {
161+ ivpu_jsm_state_dump (vdev );
162+ ivpu_dev_coredump (vdev );
163+ ivpu_suspend (vdev );
164+ }
165+
166+ ivpu_pm_reset_complete (vdev );
167+
168+ kobject_uevent_env (& vdev -> drm .dev -> kobj , KOBJ_CHANGE , evt );
153169}
154170
155171void ivpu_pm_trigger_recovery (struct ivpu_device * vdev , const char * reason )
@@ -309,7 +325,10 @@ int ivpu_rpm_get(struct ivpu_device *vdev)
309325 int ret ;
310326
311327 ret = pm_runtime_resume_and_get (vdev -> drm .dev );
312- drm_WARN_ON (& vdev -> drm , ret < 0 );
328+ if (ret < 0 ) {
329+ ivpu_err (vdev , "Failed to resume NPU: %d\n" , ret );
330+ pm_runtime_set_suspended (vdev -> drm .dev );
331+ }
313332
314333 return ret ;
315334}
@@ -325,35 +344,26 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev)
325344 struct ivpu_device * vdev = pci_get_drvdata (pdev );
326345
327346 ivpu_dbg (vdev , PM , "Pre-reset..\n" );
328- atomic_inc (& vdev -> pm -> reset_counter );
329- atomic_set (& vdev -> pm -> reset_pending , 1 );
330347
331- pm_runtime_get_sync (vdev -> drm .dev );
332- down_write (& vdev -> pm -> reset_lock );
333- ivpu_prepare_for_reset (vdev );
334- ivpu_hw_reset (vdev );
335- ivpu_pm_prepare_cold_boot (vdev );
336- ivpu_jobs_abort_all (vdev );
337- ivpu_ms_cleanup_all (vdev );
348+ ivpu_pm_reset_begin (vdev );
349+
350+ if (!pm_runtime_status_suspended (vdev -> drm .dev )) {
351+ ivpu_prepare_for_reset (vdev );
352+ ivpu_hw_reset (vdev );
353+ }
338354
339355 ivpu_dbg (vdev , PM , "Pre-reset done.\n" );
340356}
341357
342358void ivpu_pm_reset_done_cb (struct pci_dev * pdev )
343359{
344360 struct ivpu_device * vdev = pci_get_drvdata (pdev );
345- int ret ;
346361
347362 ivpu_dbg (vdev , PM , "Post-reset..\n" );
348- ret = ivpu_resume (vdev );
349- if (ret )
350- ivpu_err (vdev , "Failed to set RESUME state: %d\n" , ret );
351- up_write (& vdev -> pm -> reset_lock );
352- atomic_set (& vdev -> pm -> reset_pending , 0 );
353- ivpu_dbg (vdev , PM , "Post-reset done.\n" );
354363
355- pm_runtime_mark_last_busy (vdev -> drm .dev );
356- pm_runtime_put_autosuspend (vdev -> drm .dev );
364+ ivpu_pm_reset_complete (vdev );
365+
366+ ivpu_dbg (vdev , PM , "Post-reset done.\n" );
357367}
358368
359369void ivpu_pm_init (struct ivpu_device * vdev )
0 commit comments