Lines 412-424
void pci_dpc_init(struct pci_dev *pdev)
Link Here
|
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 |
#define FLAG(x, y) (((x) & (y)) ? '+' : '-') |
446 |
#define FLAG(x, y) (((x) & (y)) ? '+' : '-') |
416 |
static int dpc_probe(struct pcie_device *dev) |
447 |
static int dpc_probe(struct pcie_device *dev) |
417 |
{ |
448 |
{ |
418 |
struct pci_dev *pdev = dev->port; |
449 |
struct pci_dev *pdev = dev->port; |
419 |
struct device *device = &dev->device; |
450 |
struct device *device = &dev->device; |
420 |
int status; |
451 |
int status; |
421 |
u16 ctl, cap; |
452 |
u16 cap; |
422 |
|
453 |
|
423 |
if (!pcie_aer_is_native(pdev) && !pcie_ports_dpc_native) |
454 |
if (!pcie_aer_is_native(pdev) && !pcie_ports_dpc_native) |
424 |
return -ENOTSUPP; |
455 |
return -ENOTSUPP; |
Lines 433-443
static int dpc_probe(struct pcie_device *dev)
Link Here
|
433 |
} |
464 |
} |
434 |
|
465 |
|
435 |
pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CAP, &cap); |
466 |
pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CAP, &cap); |
436 |
|
467 |
dpc_enable(dev); |
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); |
441 |
|
468 |
|
442 |
pci_info(pdev, "enabled with IRQ %d\n", dev->irq); |
469 |
pci_info(pdev, "enabled with IRQ %d\n", dev->irq); |
443 |
pci_info(pdev, "error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n", |
470 |
pci_info(pdev, "error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n", |
Lines 450-463
static int dpc_probe(struct pcie_device *dev)
Link Here
|
450 |
return status; |
477 |
return status; |
451 |
} |
478 |
} |
452 |
|
479 |
|
|
|
480 |
static int dpc_suspend(struct pcie_device *dev) |
481 |
{ |
482 |
dpc_disable(dev); |
483 |
return 0; |
484 |
} |
485 |
|
486 |
static int dpc_resume(struct pcie_device *dev) |
487 |
{ |
488 |
dpc_enable(dev); |
489 |
return 0; |
490 |
} |
491 |
|
453 |
static void dpc_remove(struct pcie_device *dev) |
492 |
static void dpc_remove(struct pcie_device *dev) |
454 |
{ |
493 |
{ |
455 |
struct pci_dev *pdev = dev->port; |
494 |
dpc_disable(dev); |
456 |
u16 ctl; |
|
|
457 |
|
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); |
461 |
} |
495 |
} |
462 |
|
496 |
|
463 |
static struct pcie_port_service_driver dpcdriver = { |
497 |
static struct pcie_port_service_driver dpcdriver = { |
Lines 465-470
static struct pcie_port_service_driver dpcdriver = {
Link Here
|
465 |
.port_type = PCIE_ANY_PORT, |
499 |
.port_type = PCIE_ANY_PORT, |
466 |
.service = PCIE_PORT_SERVICE_DPC, |
500 |
.service = PCIE_PORT_SERVICE_DPC, |
467 |
.probe = dpc_probe, |
501 |
.probe = dpc_probe, |
|
|
502 |
.suspend = dpc_suspend, |
503 |
.resume = dpc_resume, |
468 |
.remove = dpc_remove, |
504 |
.remove = dpc_remove, |
469 |
}; |
505 |
}; |
470 |
|
506 |
|