Skip to content

Commit 9936328

Browse files
committed
Merge tag 'pci-v5.1-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI fixes from Bjorn Helgaas: "PCI fixes: - Clear level-triggered interrupts for the bandwidth notification supported added for v5.1 (Alexandru Gagniuc) - Clear bandwidth notification interrupts before enabling them (Lukas Wunner) - Report post-enumeration bandwidth changes only once for multi-function devices (Lukas Wunner)" * tag 'pci-v5.1-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: PCI/LINK: Deduplicate bandwidth reports for multi-function devices PCI/LINK: Clear bandwidth notification interrupt before enabling it PCI/LINK: Supply IRQ handler so level-triggered IRQs are acked
2 parents 8c7ae38 + 0fa635a commit 9936328

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

drivers/pci/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev);
273273
u32 pcie_bandwidth_capable(struct pci_dev *dev, enum pci_bus_speed *speed,
274274
enum pcie_link_width *width);
275275
void __pcie_print_link_status(struct pci_dev *dev, bool verbose);
276+
void pcie_report_downtraining(struct pci_dev *dev);
276277

277278
/* Single Root I/O Virtualization */
278279
struct pci_sriov {

drivers/pci/pcie/bw_notification.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ static void pcie_enable_link_bandwidth_notification(struct pci_dev *dev)
3030
{
3131
u16 lnk_ctl;
3232

33+
pcie_capability_write_word(dev, PCI_EXP_LNKSTA, PCI_EXP_LNKSTA_LBMS);
34+
3335
pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &lnk_ctl);
3436
lnk_ctl |= PCI_EXP_LNKCTL_LBMIE;
3537
pcie_capability_write_word(dev, PCI_EXP_LNKCTL, lnk_ctl);
@@ -44,11 +46,10 @@ static void pcie_disable_link_bandwidth_notification(struct pci_dev *dev)
4446
pcie_capability_write_word(dev, PCI_EXP_LNKCTL, lnk_ctl);
4547
}
4648

47-
static irqreturn_t pcie_bw_notification_handler(int irq, void *context)
49+
static irqreturn_t pcie_bw_notification_irq(int irq, void *context)
4850
{
4951
struct pcie_device *srv = context;
5052
struct pci_dev *port = srv->port;
51-
struct pci_dev *dev;
5253
u16 link_status, events;
5354
int ret;
5455

@@ -58,17 +59,26 @@ static irqreturn_t pcie_bw_notification_handler(int irq, void *context)
5859
if (ret != PCIBIOS_SUCCESSFUL || !events)
5960
return IRQ_NONE;
6061

62+
pcie_capability_write_word(port, PCI_EXP_LNKSTA, events);
63+
pcie_update_link_speed(port->subordinate, link_status);
64+
return IRQ_WAKE_THREAD;
65+
}
66+
67+
static irqreturn_t pcie_bw_notification_handler(int irq, void *context)
68+
{
69+
struct pcie_device *srv = context;
70+
struct pci_dev *port = srv->port;
71+
struct pci_dev *dev;
72+
6173
/*
6274
* Print status from downstream devices, not this root port or
6375
* downstream switch port.
6476
*/
6577
down_read(&pci_bus_sem);
6678
list_for_each_entry(dev, &port->subordinate->devices, bus_list)
67-
__pcie_print_link_status(dev, false);
79+
pcie_report_downtraining(dev);
6880
up_read(&pci_bus_sem);
6981

70-
pcie_update_link_speed(port->subordinate, link_status);
71-
pcie_capability_write_word(port, PCI_EXP_LNKSTA, events);
7282
return IRQ_HANDLED;
7383
}
7484

@@ -80,7 +90,8 @@ static int pcie_bandwidth_notification_probe(struct pcie_device *srv)
8090
if (!pcie_link_bandwidth_notification_supported(srv->port))
8191
return -ENODEV;
8292

83-
ret = request_threaded_irq(srv->irq, NULL, pcie_bw_notification_handler,
93+
ret = request_threaded_irq(srv->irq, pcie_bw_notification_irq,
94+
pcie_bw_notification_handler,
8495
IRQF_SHARED, "PCIe BW notif", srv);
8596
if (ret)
8697
return ret;

drivers/pci/probe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2388,7 +2388,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
23882388
return dev;
23892389
}
23902390

2391-
static void pcie_report_downtraining(struct pci_dev *dev)
2391+
void pcie_report_downtraining(struct pci_dev *dev)
23922392
{
23932393
if (!pci_is_pcie(dev))
23942394
return;

0 commit comments

Comments
 (0)