@@ -383,15 +383,43 @@ static void process_evl_entries(struct idxd_device *idxd)
383
383
mutex_unlock (& evl -> lock );
384
384
}
385
385
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
+
386
416
irqreturn_t idxd_misc_thread (int vec , void * data )
387
417
{
388
418
struct idxd_irq_entry * irq_entry = data ;
389
419
struct idxd_device * idxd = ie_to_idxd (irq_entry );
390
420
struct device * dev = & idxd -> pdev -> dev ;
391
- union gensts_reg gensts ;
392
421
u32 val = 0 ;
393
422
int i ;
394
- bool err = false;
395
423
u32 cause ;
396
424
397
425
cause = ioread32 (idxd -> reg_base + IDXD_INTCAUSE_OFFSET );
@@ -401,7 +429,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
401
429
iowrite32 (cause , idxd -> reg_base + IDXD_INTCAUSE_OFFSET );
402
430
403
431
if (cause & IDXD_INTC_HALT_STATE )
404
- goto halt ;
432
+ return idxd_halt ( idxd ) ;
405
433
406
434
if (cause & IDXD_INTC_ERR ) {
407
435
spin_lock (& idxd -> dev_lock );
@@ -435,7 +463,6 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
435
463
for (i = 0 ; i < 4 ; i ++ )
436
464
dev_warn_ratelimited (dev , "err[%d]: %#16.16llx\n" ,
437
465
i , idxd -> sw_err .bits [i ]);
438
- err = true;
439
466
}
440
467
441
468
if (cause & IDXD_INTC_INT_HANDLE_REVOKED ) {
@@ -480,34 +507,6 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
480
507
dev_warn_once (dev , "Unexpected interrupt cause bits set: %#x\n" ,
481
508
val );
482
509
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 :
511
510
return IRQ_HANDLED ;
512
511
}
513
512
0 commit comments