Commit 966966a6 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pci-v4.3-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull PCI fixes from Bjorn Helgaas:
 "These are fixes for things we merged for v4.3 (VPD, MSI, and bridge
  window management), and a new Renesas R8A7794 SoC device ID.

  Details:

  Resource management:
   - Revert pci_read_bridge_bases() unification (Bjorn Helgaas)
   - Clear IORESOURCE_UNSET when clipping a bridge window (Bjorn
     Helgaas)

  MSI:
   - Fix MSI IRQ domains for VFs on virtual buses (Alex Williamson)

  Renesas R-Car host bridge driver:
   - Add R8A7794 support (Sergei Shtylyov)

  Miscellaneous:
   - Fix devfn for VPD access through function 0 (Alex Williamson)
   - Use function 0 VPD only for identical functions (Alex Williamson)"

* tag 'pci-v4.3-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
  PCI: rcar: Add R8A7794 support
  PCI: Use function 0 VPD for identical functions, regular VPD for others
  PCI: Fix devfn for VPD access through function 0
  PCI/MSI: Fix MSI IRQ domains for VFs on virtual buses
  PCI: Clear IORESOURCE_UNSET when clipping a bridge window
  PCI: Revert "PCI: Call pci_read_bridge_bases() from core instead of arch code"
parents b6d980f4 de24c18c
...@@ -7,7 +7,8 @@ OHCI and EHCI controllers. ...@@ -7,7 +7,8 @@ OHCI and EHCI controllers.
Required properties: Required properties:
- compatible: "renesas,pci-r8a7790" for the R8A7790 SoC; - compatible: "renesas,pci-r8a7790" for the R8A7790 SoC;
"renesas,pci-r8a7791" for the R8A7791 SoC. "renesas,pci-r8a7791" for the R8A7791 SoC;
"renesas,pci-r8a7794" for the R8A7794 SoC.
- reg: A list of physical regions to access the device: the first is - reg: A list of physical regions to access the device: the first is
the operational registers for the OHCI/EHCI controllers and the the operational registers for the OHCI/EHCI controllers and the
second is for the bridge configuration and control registers. second is for the bridge configuration and control registers.
......
...@@ -242,7 +242,12 @@ pci_restore_srm_config(void) ...@@ -242,7 +242,12 @@ pci_restore_srm_config(void)
void pcibios_fixup_bus(struct pci_bus *bus) void pcibios_fixup_bus(struct pci_bus *bus)
{ {
struct pci_dev *dev; struct pci_dev *dev = bus->self;
if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pci_read_bridge_bases(bus);
}
list_for_each_entry(dev, &bus->devices, bus_list) { list_for_each_entry(dev, &bus->devices, bus_list) {
pdev_save_srm_config(dev); pdev_save_srm_config(dev);
......
...@@ -294,6 +294,8 @@ void pcibios_fixup_bus(struct pci_bus *bus) ...@@ -294,6 +294,8 @@ void pcibios_fixup_bus(struct pci_bus *bus)
printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number); printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
#endif #endif
pci_read_bridge_bases(bus);
if (bus->number == 0) { if (bus->number == 0) {
struct pci_dev *dev; struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) { list_for_each_entry(dev, &bus->devices, bus_list) {
......
...@@ -533,9 +533,10 @@ void pcibios_fixup_bus(struct pci_bus *b) ...@@ -533,9 +533,10 @@ void pcibios_fixup_bus(struct pci_bus *b)
{ {
struct pci_dev *dev; struct pci_dev *dev;
if (b->self) if (b->self) {
pci_read_bridge_bases(b);
pcibios_fixup_bridge_resources(b->self); pcibios_fixup_bridge_resources(b->self);
}
list_for_each_entry(dev, &b->devices, bus_list) list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev); pcibios_fixup_device_resources(dev);
platform_pci_fixup_bus(b); platform_pci_fixup_bus(b);
......
...@@ -863,7 +863,14 @@ void pcibios_setup_bus_devices(struct pci_bus *bus) ...@@ -863,7 +863,14 @@ void pcibios_setup_bus_devices(struct pci_bus *bus)
void pcibios_fixup_bus(struct pci_bus *bus) void pcibios_fixup_bus(struct pci_bus *bus)
{ {
/* Fixup the bus */ /* When called from the generic PCI probe, read PCI<->PCI bridge
* bases. This is -not- called when generating the PCI tree from
* the OF device-tree.
*/
if (bus->self != NULL)
pci_read_bridge_bases(bus);
/* Now fixup the bus bus */
pcibios_setup_bus_self(bus); pcibios_setup_bus_self(bus);
/* Now fixup devices on that bus */ /* Now fixup devices on that bus */
......
...@@ -311,6 +311,12 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) ...@@ -311,6 +311,12 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
void pcibios_fixup_bus(struct pci_bus *bus) void pcibios_fixup_bus(struct pci_bus *bus)
{ {
struct pci_dev *dev = bus->self;
if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pci_read_bridge_bases(bus);
}
} }
EXPORT_SYMBOL(PCIBIOS_MIN_IO); EXPORT_SYMBOL(PCIBIOS_MIN_IO);
......
...@@ -324,6 +324,7 @@ void pcibios_fixup_bus(struct pci_bus *bus) ...@@ -324,6 +324,7 @@ void pcibios_fixup_bus(struct pci_bus *bus)
struct pci_dev *dev; struct pci_dev *dev;
if (bus->self) { if (bus->self) {
pci_read_bridge_bases(bus);
pcibios_fixup_bridge_resources(bus->self); pcibios_fixup_bridge_resources(bus->self);
} }
......
...@@ -1032,7 +1032,13 @@ void pcibios_set_master(struct pci_dev *dev) ...@@ -1032,7 +1032,13 @@ void pcibios_set_master(struct pci_dev *dev)
void pcibios_fixup_bus(struct pci_bus *bus) void pcibios_fixup_bus(struct pci_bus *bus)
{ {
/* Fixup the bus */ /* When called from the generic PCI probe, read PCI<->PCI bridge
* bases. This is -not- called when generating the PCI tree from
* the OF device-tree.
*/
pci_read_bridge_bases(bus);
/* Now fixup the bus bus */
pcibios_setup_bus_self(bus); pcibios_setup_bus_self(bus);
/* Now fixup devices on that bus */ /* Now fixup devices on that bus */
......
...@@ -166,6 +166,7 @@ void pcibios_fixup_bus(struct pci_bus *b) ...@@ -166,6 +166,7 @@ void pcibios_fixup_bus(struct pci_bus *b)
{ {
struct pci_dev *dev; struct pci_dev *dev;
pci_read_bridge_bases(b);
list_for_each_entry(dev, &b->devices, bus_list) list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev); pcibios_fixup_device_resources(dev);
} }
......
...@@ -210,6 +210,10 @@ subsys_initcall(pcibios_init); ...@@ -210,6 +210,10 @@ subsys_initcall(pcibios_init);
void pcibios_fixup_bus(struct pci_bus *bus) void pcibios_fixup_bus(struct pci_bus *bus)
{ {
if (bus->parent) {
/* This is a subordinate bridge */
pci_read_bridge_bases(bus);
}
} }
void pcibios_set_master(struct pci_dev *dev) void pcibios_set_master(struct pci_dev *dev)
......
...@@ -560,6 +560,9 @@ dino_fixup_bus(struct pci_bus *bus) ...@@ -560,6 +560,9 @@ dino_fixup_bus(struct pci_bus *bus)
} else if (bus->parent) { } else if (bus->parent) {
int i; int i;
pci_read_bridge_bases(bus);
for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
if((bus->self->resource[i].flags & if((bus->self->resource[i].flags &
(IORESOURCE_IO | IORESOURCE_MEM)) == 0) (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
......
...@@ -693,6 +693,7 @@ lba_fixup_bus(struct pci_bus *bus) ...@@ -693,6 +693,7 @@ lba_fixup_bus(struct pci_bus *bus)
if (bus->parent) { if (bus->parent) {
int i; int i;
/* PCI-PCI Bridge */ /* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++)
pci_claim_bridge_resource(bus->self, i); pci_claim_bridge_resource(bus->self, i);
} else { } else {
......
...@@ -442,7 +442,8 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = { ...@@ -442,7 +442,8 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = {
static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
void *arg) void *arg)
{ {
struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); struct pci_dev *tdev = pci_get_slot(dev->bus,
PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
ssize_t ret; ssize_t ret;
if (!tdev) if (!tdev)
...@@ -456,7 +457,8 @@ static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, ...@@ -456,7 +457,8 @@ static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
const void *arg) const void *arg)
{ {
struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); struct pci_dev *tdev = pci_get_slot(dev->bus,
PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
ssize_t ret; ssize_t ret;
if (!tdev) if (!tdev)
...@@ -473,22 +475,6 @@ static const struct pci_vpd_ops pci_vpd_f0_ops = { ...@@ -473,22 +475,6 @@ static const struct pci_vpd_ops pci_vpd_f0_ops = {
.release = pci_vpd_pci22_release, .release = pci_vpd_pci22_release,
}; };
static int pci_vpd_f0_dev_check(struct pci_dev *dev)
{
struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn));
int ret = 0;
if (!tdev)
return -ENODEV;
if (!tdev->vpd || !tdev->multifunction ||
dev->class != tdev->class || dev->vendor != tdev->vendor ||
dev->device != tdev->device)
ret = -ENODEV;
pci_dev_put(tdev);
return ret;
}
int pci_vpd_pci22_init(struct pci_dev *dev) int pci_vpd_pci22_init(struct pci_dev *dev)
{ {
struct pci_vpd_pci22 *vpd; struct pci_vpd_pci22 *vpd;
...@@ -497,12 +483,7 @@ int pci_vpd_pci22_init(struct pci_dev *dev) ...@@ -497,12 +483,7 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
cap = pci_find_capability(dev, PCI_CAP_ID_VPD); cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
if (!cap) if (!cap)
return -ENODEV; return -ENODEV;
if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) {
int ret = pci_vpd_f0_dev_check(dev);
if (ret)
return ret;
}
vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);
if (!vpd) if (!vpd)
return -ENOMEM; return -ENOMEM;
......
...@@ -256,6 +256,8 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx) ...@@ -256,6 +256,8 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx)
res->start = start; res->start = start;
res->end = end; res->end = end;
res->flags &= ~IORESOURCE_UNSET;
orig_res.flags &= ~IORESOURCE_UNSET;
dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n", dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n",
&orig_res, res); &orig_res, res);
......
...@@ -362,6 +362,7 @@ static int rcar_pci_probe(struct platform_device *pdev) ...@@ -362,6 +362,7 @@ static int rcar_pci_probe(struct platform_device *pdev)
static struct of_device_id rcar_pci_of_match[] = { static struct of_device_id rcar_pci_of_match[] = {
{ .compatible = "renesas,pci-r8a7790", }, { .compatible = "renesas,pci-r8a7790", },
{ .compatible = "renesas,pci-r8a7791", }, { .compatible = "renesas,pci-r8a7791", },
{ .compatible = "renesas,pci-r8a7794", },
{ }, { },
}; };
......
...@@ -676,15 +676,20 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) ...@@ -676,15 +676,20 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
static void pci_set_bus_msi_domain(struct pci_bus *bus) static void pci_set_bus_msi_domain(struct pci_bus *bus)
{ {
struct irq_domain *d; struct irq_domain *d;
struct pci_bus *b;
/* /*
* Either bus is the root, and we must obtain it from the * The bus can be a root bus, a subordinate bus, or a virtual bus
* firmware, or we inherit it from the bridge device. * created by an SR-IOV device. Walk up to the first bridge device
* found or derive the domain from the host bridge.
*/ */
if (pci_is_root_bus(bus)) for (b = bus, d = NULL; !d && !pci_is_root_bus(b); b = b->parent) {
d = pci_host_bridge_msi_domain(bus); if (b->self)
else d = dev_get_msi_domain(&b->self->dev);
d = dev_get_msi_domain(&bus->self->dev); }
if (!d)
d = pci_host_bridge_msi_domain(b);
dev_set_msi_domain(&bus->dev, d); dev_set_msi_domain(&bus->dev, d);
} }
...@@ -855,9 +860,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) ...@@ -855,9 +860,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
child->bridge_ctl = bctl; child->bridge_ctl = bctl;
} }
/* Read and initialize bridge resources */
pci_read_bridge_bases(child);
cmax = pci_scan_child_bus(child); cmax = pci_scan_child_bus(child);
if (cmax > subordinate) if (cmax > subordinate)
dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n", dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n",
...@@ -918,9 +920,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) ...@@ -918,9 +920,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
if (!is_cardbus) { if (!is_cardbus) {
child->bridge_ctl = bctl; child->bridge_ctl = bctl;
/* Read and initialize bridge resources */
pci_read_bridge_bases(child);
max = pci_scan_child_bus(child); max = pci_scan_child_bus(child);
} else { } else {
/* /*
......
...@@ -1907,11 +1907,27 @@ static void quirk_netmos(struct pci_dev *dev) ...@@ -1907,11 +1907,27 @@ static void quirk_netmos(struct pci_dev *dev)
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos);
/*
* Quirk non-zero PCI functions to route VPD access through function 0 for
* devices that share VPD resources between functions. The functions are
* expected to be identical devices.
*/
static void quirk_f0_vpd_link(struct pci_dev *dev) static void quirk_f0_vpd_link(struct pci_dev *dev)
{ {
if (!dev->multifunction || !PCI_FUNC(dev->devfn)) struct pci_dev *f0;
if (!PCI_FUNC(dev->devfn))
return; return;
dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
f0 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
if (!f0)
return;
if (f0->vpd && dev->class == f0->class &&
dev->vendor == f0->vendor && dev->device == f0->device)
dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
pci_dev_put(f0);
} }
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment