@@ -412,13 +412,44 @@ void pci_dpc_init(struct pci_dev *pdev)
412
412
}
413
413
}
414
414
415
+ static void dpc_enable (struct pcie_device * dev )
416
+ {
417
+ struct pci_dev * pdev = dev -> port ;
418
+ int dpc = pdev -> dpc_cap ;
419
+ u16 ctl ;
420
+
421
+ /*
422
+ * Clear DPC Interrupt Status so we don't get an interrupt for an
423
+ * old event when setting DPC Interrupt Enable.
424
+ */
425
+ pci_write_config_word (pdev , dpc + PCI_EXP_DPC_STATUS ,
426
+ PCI_EXP_DPC_STATUS_INTERRUPT );
427
+
428
+ pci_read_config_word (pdev , dpc + PCI_EXP_DPC_CTL , & ctl );
429
+ ctl &= ~PCI_EXP_DPC_CTL_EN_MASK ;
430
+ ctl |= PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN ;
431
+ pci_write_config_word (pdev , dpc + PCI_EXP_DPC_CTL , ctl );
432
+ }
433
+
434
+ static void dpc_disable (struct pcie_device * dev )
435
+ {
436
+ struct pci_dev * pdev = dev -> port ;
437
+ int dpc = pdev -> dpc_cap ;
438
+ u16 ctl ;
439
+
440
+ /* Disable DPC triggering and DPC interrupts */
441
+ pci_read_config_word (pdev , dpc + PCI_EXP_DPC_CTL , & ctl );
442
+ ctl &= ~(PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN );
443
+ pci_write_config_word (pdev , dpc + PCI_EXP_DPC_CTL , ctl );
444
+ }
445
+
415
446
#define FLAG (x , y ) (((x) & (y)) ? '+' : '-')
416
447
static int dpc_probe (struct pcie_device * dev )
417
448
{
418
449
struct pci_dev * pdev = dev -> port ;
419
450
struct device * device = & dev -> device ;
420
451
int status ;
421
- u16 ctl , cap ;
452
+ u16 cap ;
422
453
423
454
if (!pcie_aer_is_native (pdev ) && !pcie_ports_dpc_native )
424
455
return - ENOTSUPP ;
@@ -433,11 +464,7 @@ static int dpc_probe(struct pcie_device *dev)
433
464
}
434
465
435
466
pci_read_config_word (pdev , pdev -> dpc_cap + PCI_EXP_DPC_CAP , & cap );
436
-
437
- pci_read_config_word (pdev , pdev -> dpc_cap + PCI_EXP_DPC_CTL , & ctl );
438
- ctl &= ~PCI_EXP_DPC_CTL_EN_MASK ;
439
- ctl |= PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN ;
440
- pci_write_config_word (pdev , pdev -> dpc_cap + PCI_EXP_DPC_CTL , ctl );
467
+ dpc_enable (dev );
441
468
442
469
pci_info (pdev , "enabled with IRQ %d\n" , dev -> irq );
443
470
pci_info (pdev , "error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n" ,
@@ -450,21 +477,30 @@ static int dpc_probe(struct pcie_device *dev)
450
477
return status ;
451
478
}
452
479
453
- static void dpc_remove (struct pcie_device * dev )
480
+ static int dpc_suspend (struct pcie_device * dev )
454
481
{
455
- struct pci_dev * pdev = dev -> port ;
456
- u16 ctl ;
482
+ dpc_disable (dev );
483
+ return 0 ;
484
+ }
457
485
458
- pci_read_config_word (pdev , pdev -> dpc_cap + PCI_EXP_DPC_CTL , & ctl );
459
- ctl &= ~(PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN );
460
- pci_write_config_word (pdev , pdev -> dpc_cap + PCI_EXP_DPC_CTL , ctl );
486
+ static int dpc_resume (struct pcie_device * dev )
487
+ {
488
+ dpc_enable (dev );
489
+ return 0 ;
490
+ }
491
+
492
+ static void dpc_remove (struct pcie_device * dev )
493
+ {
494
+ dpc_disable (dev );
461
495
}
462
496
463
497
static struct pcie_port_service_driver dpcdriver = {
464
498
.name = "dpc" ,
465
499
.port_type = PCIE_ANY_PORT ,
466
500
.service = PCIE_PORT_SERVICE_DPC ,
467
501
.probe = dpc_probe ,
502
+ .suspend = dpc_suspend ,
503
+ .resume = dpc_resume ,
468
504
.remove = dpc_remove ,
469
505
};
470
506
0 commit comments