@@ -90,11 +90,11 @@ pvr_power_request_pwr_off(struct pvr_device *pvr_dev)
9090}
9191
9292static int
93- pvr_power_fw_disable (struct pvr_device * pvr_dev , bool hard_reset )
93+ pvr_power_fw_disable (struct pvr_device * pvr_dev , bool hard_reset , bool rpm_suspend )
9494{
95- if (!hard_reset ) {
96- int err ;
95+ int err ;
9796
97+ if (!hard_reset ) {
9898 cancel_delayed_work_sync (& pvr_dev -> watchdog .work );
9999
100100 err = pvr_power_request_idle (pvr_dev );
@@ -106,29 +106,47 @@ pvr_power_fw_disable(struct pvr_device *pvr_dev, bool hard_reset)
106106 return err ;
107107 }
108108
109- return pvr_fw_stop (pvr_dev );
109+ if (rpm_suspend ) {
110+ /* This also waits for late processing of GPU or firmware IRQs in other cores */
111+ disable_irq (pvr_dev -> irq );
112+ }
113+
114+ err = pvr_fw_stop (pvr_dev );
115+ if (err && rpm_suspend )
116+ enable_irq (pvr_dev -> irq );
117+
118+ return err ;
110119}
111120
112121static int
113- pvr_power_fw_enable (struct pvr_device * pvr_dev )
122+ pvr_power_fw_enable (struct pvr_device * pvr_dev , bool rpm_resume )
114123{
115124 int err ;
116125
126+ if (rpm_resume )
127+ enable_irq (pvr_dev -> irq );
128+
117129 err = pvr_fw_start (pvr_dev );
118130 if (err )
119- return err ;
131+ goto out ;
120132
121133 err = pvr_wait_for_fw_boot (pvr_dev );
122134 if (err ) {
123135 drm_err (from_pvr_device (pvr_dev ), "Firmware failed to boot\n" );
124136 pvr_fw_stop (pvr_dev );
125- return err ;
137+ goto out ;
126138 }
127139
128140 queue_delayed_work (pvr_dev -> sched_wq , & pvr_dev -> watchdog .work ,
129141 msecs_to_jiffies (WATCHDOG_TIME_MS ));
130142
131143 return 0 ;
144+
145+ out :
146+ if (rpm_resume )
147+ disable_irq (pvr_dev -> irq );
148+
149+ return err ;
132150}
133151
134152bool
@@ -361,7 +379,7 @@ pvr_power_device_suspend(struct device *dev)
361379 return - EIO ;
362380
363381 if (pvr_dev -> fw_dev .booted ) {
364- err = pvr_power_fw_disable (pvr_dev , false);
382+ err = pvr_power_fw_disable (pvr_dev , false, true );
365383 if (err )
366384 goto err_drm_dev_exit ;
367385 }
@@ -391,7 +409,7 @@ pvr_power_device_resume(struct device *dev)
391409 goto err_drm_dev_exit ;
392410
393411 if (pvr_dev -> fw_dev .booted ) {
394- err = pvr_power_fw_enable (pvr_dev );
412+ err = pvr_power_fw_enable (pvr_dev , true );
395413 if (err )
396414 goto err_power_off ;
397415 }
@@ -510,15 +528,24 @@ pvr_power_reset(struct pvr_device *pvr_dev, bool hard_reset)
510528 }
511529
512530 /* Disable IRQs for the duration of the reset. */
513- disable_irq (pvr_dev -> irq );
531+ if (hard_reset ) {
532+ disable_irq (pvr_dev -> irq );
533+ } else {
534+ /*
535+ * Soft reset is triggered as a response to a FW command to the Host and is
536+ * processed from the threaded IRQ handler. This code cannot (nor needs to)
537+ * wait for any IRQ processing to complete.
538+ */
539+ disable_irq_nosync (pvr_dev -> irq );
540+ }
514541
515542 do {
516543 if (hard_reset ) {
517544 pvr_queue_device_pre_reset (pvr_dev );
518545 queues_disabled = true;
519546 }
520547
521- err = pvr_power_fw_disable (pvr_dev , hard_reset );
548+ err = pvr_power_fw_disable (pvr_dev , hard_reset , false );
522549 if (!err ) {
523550 if (hard_reset ) {
524551 pvr_dev -> fw_dev .booted = false;
@@ -541,7 +568,7 @@ pvr_power_reset(struct pvr_device *pvr_dev, bool hard_reset)
541568
542569 pvr_fw_irq_clear (pvr_dev );
543570
544- err = pvr_power_fw_enable (pvr_dev );
571+ err = pvr_power_fw_enable (pvr_dev , false );
545572 }
546573
547574 if (err && hard_reset )
0 commit comments