View | Details | Raw Unified | Return to bug 216295
Collapse All | Expand All

(-)a/drivers/pci/pcie/aer.c (+18 lines)
Lines 1497-1502 static int aer_probe(struct pcie_device *dev) Link Here
1497
	return 0;
1497
	return 0;
1498
}
1498
}
1499
1499
1500
static int aer_suspend(struct pcie_device *dev)
1501
{
1502
	struct aer_rpc *rpc = get_service_data(dev);
1503
1504
	aer_disable_rootport(rpc);
1505
	return 0;
1506
}
1507
1508
static int aer_resume(struct pcie_device *dev)
1509
{
1510
	struct aer_rpc *rpc = get_service_data(dev);
1511
1512
	aer_enable_rootport(rpc);
1513
	return 0;
1514
}
1515
1500
/**
1516
/**
1501
 * aer_root_reset - reset Root Port hierarchy, RCEC, or RCiEP
1517
 * aer_root_reset - reset Root Port hierarchy, RCEC, or RCiEP
1502
 * @dev: pointer to Root Port, RCEC, or RCiEP
1518
 * @dev: pointer to Root Port, RCEC, or RCiEP
Lines 1561-1566 static struct pcie_port_service_driver aerdriver = { Link Here
1561
	.service	= PCIE_PORT_SERVICE_AER,
1577
	.service	= PCIE_PORT_SERVICE_AER,
1562
1578
1563
	.probe		= aer_probe,
1579
	.probe		= aer_probe,
1580
	.suspend	= aer_suspend,
1581
	.resume		= aer_resume,
1564
	.remove		= aer_remove,
1582
	.remove		= aer_remove,
1565
};
1583
};
1566
1584
1567
   PCI/DPC: Disable DPC service on suspend
1585
   PCI/DPC: Disable DPC service on suspend
1568
   
1586
   
1569
   If the link is powered off during suspend, electrical noise may cause
1587
   If the link is powered off during suspend, electrical noise may cause
1570
   errors that trigger DPC.  If the DPC interrupt is enabled and shares an IRQ
1588
   errors that trigger DPC.  If the DPC interrupt is enabled and shares an IRQ
1571
   with PME, that causes a spurious wakeup during suspend.
1589
   with PME, that causes a spurious wakeup during suspend.
1572
   
1590
   
1573
   Disable DPC triggering and the DPC interrupt during suspend to prevent
1591
   Disable DPC triggering and the DPC interrupt during suspend to prevent
1574
   this.  Clear DPC interrupt status before re-enabling DPC interrupts during
1592
   this.  Clear DPC interrupt status before re-enabling DPC interrupts during
1575
   resume so we don't get an interrupt for errors that occurred during the
1593
   resume so we don't get an interrupt for errors that occurred during the
1576
   suspend/resume process.
1594
   suspend/resume process.
1577
   
1595
   
1578
   Link: https://bugzilla.kernel.org/show_bug.cgi?id=209149
1596
   Link: https://bugzilla.kernel.org/show_bug.cgi?id=209149
1579
   Link: https://bugzilla.kernel.org/show_bug.cgi?id=216295
1597
   Link: https://bugzilla.kernel.org/show_bug.cgi?id=216295
1580
   Link: https://bugzilla.kernel.org/show_bug.cgi?id=218090
1598
   Link: https://bugzilla.kernel.org/show_bug.cgi?id=218090
1581
   Link: https://lore.kernel.org/r/20240416043225.1462548-3-kai.heng.feng@canonical.com
1599
   Link: https://lore.kernel.org/r/20240416043225.1462548-3-kai.heng.feng@canonical.com
1582
   Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
1600
   Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
1583
   [bhelgaas: clear status on resume, add comments, commit log]
1601
   [bhelgaas: clear status on resume, add comments, commit log]
1584
   Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
1602
   Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
(-)a/drivers/pci/pcie/dpc.c (-12 / +48 lines)
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

Return to bug 216295