@@ -383,15 +383,43 @@ static void process_evl_entries(struct idxd_device *idxd)
383383 mutex_unlock (& evl -> lock );
384384}
385385
386+ static irqreturn_t idxd_halt (struct idxd_device * idxd )
387+ {
388+ union gensts_reg gensts ;
389+
390+ gensts .bits = ioread32 (idxd -> reg_base + IDXD_GENSTATS_OFFSET );
391+ if (gensts .state == IDXD_DEVICE_STATE_HALT ) {
392+ idxd -> state = IDXD_DEV_HALTED ;
393+ if (gensts .reset_type == IDXD_DEVICE_RESET_SOFTWARE ) {
394+ /*
395+ * If we need a software reset, we will throw the work
396+ * on a system workqueue in order to allow interrupts
397+ * for the device command completions.
398+ */
399+ INIT_WORK (& idxd -> work , idxd_device_reinit );
400+ queue_work (idxd -> wq , & idxd -> work );
401+ } else {
402+ idxd -> state = IDXD_DEV_HALTED ;
403+ idxd_wqs_quiesce (idxd );
404+ idxd_wqs_unmap_portal (idxd );
405+ idxd_device_clear_state (idxd );
406+ dev_err (& idxd -> pdev -> dev ,
407+ "idxd halted, need %s.\n" ,
408+ gensts .reset_type == IDXD_DEVICE_RESET_FLR ?
409+ "FLR" : "system reset" );
410+ }
411+ }
412+
413+ return IRQ_HANDLED ;
414+ }
415+
386416irqreturn_t idxd_misc_thread (int vec , void * data )
387417{
388418 struct idxd_irq_entry * irq_entry = data ;
389419 struct idxd_device * idxd = ie_to_idxd (irq_entry );
390420 struct device * dev = & idxd -> pdev -> dev ;
391- union gensts_reg gensts ;
392421 u32 val = 0 ;
393422 int i ;
394- bool err = false;
395423 u32 cause ;
396424
397425 cause = ioread32 (idxd -> reg_base + IDXD_INTCAUSE_OFFSET );
@@ -401,7 +429,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
401429 iowrite32 (cause , idxd -> reg_base + IDXD_INTCAUSE_OFFSET );
402430
403431 if (cause & IDXD_INTC_HALT_STATE )
404- goto halt ;
432+ return idxd_halt ( idxd ) ;
405433
406434 if (cause & IDXD_INTC_ERR ) {
407435 spin_lock (& idxd -> dev_lock );
@@ -435,7 +463,6 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
435463 for (i = 0 ; i < 4 ; i ++ )
436464 dev_warn_ratelimited (dev , "err[%d]: %#16.16llx\n" ,
437465 i , idxd -> sw_err .bits [i ]);
438- err = true;
439466 }
440467
441468 if (cause & IDXD_INTC_INT_HANDLE_REVOKED ) {
@@ -480,34 +507,6 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
480507 dev_warn_once (dev , "Unexpected interrupt cause bits set: %#x\n" ,
481508 val );
482509
483- if (!err )
484- goto out ;
485-
486- halt :
487- gensts .bits = ioread32 (idxd -> reg_base + IDXD_GENSTATS_OFFSET );
488- if (gensts .state == IDXD_DEVICE_STATE_HALT ) {
489- idxd -> state = IDXD_DEV_HALTED ;
490- if (gensts .reset_type == IDXD_DEVICE_RESET_SOFTWARE ) {
491- /*
492- * If we need a software reset, we will throw the work
493- * on a system workqueue in order to allow interrupts
494- * for the device command completions.
495- */
496- INIT_WORK (& idxd -> work , idxd_device_reinit );
497- queue_work (idxd -> wq , & idxd -> work );
498- } else {
499- idxd -> state = IDXD_DEV_HALTED ;
500- idxd_wqs_quiesce (idxd );
501- idxd_wqs_unmap_portal (idxd );
502- idxd_device_clear_state (idxd );
503- dev_err (& idxd -> pdev -> dev ,
504- "idxd halted, need %s.\n" ,
505- gensts .reset_type == IDXD_DEVICE_RESET_FLR ?
506- "FLR" : "system reset" );
507- }
508- }
509-
510- out :
511510 return IRQ_HANDLED ;
512511}
513512
0 commit comments