Skip to content

Commit

Permalink
Merge tag 'pci-v4.3-fixes-1' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/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"
  • Loading branch information
torvalds committed Sep 25, 2015
2 parents b6d980f + de24c18 commit 966966a
Show file tree
Hide file tree
Showing 17 changed files with 80 additions and 43 deletions.
3 changes: 2 additions & 1 deletion Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ OHCI and EHCI controllers.

Required properties:
- 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
the operational registers for the OHCI/EHCI controllers and the
second is for the bridge configuration and control registers.
Expand Down
7 changes: 6 additions & 1 deletion arch/alpha/kernel/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,12 @@ pci_restore_srm_config(void)

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) {
pdev_save_srm_config(dev);
Expand Down
2 changes: 2 additions & 0 deletions arch/frv/mb93090-mb00/pci-vdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ void pcibios_fixup_bus(struct pci_bus *bus)
printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
#endif

pci_read_bridge_bases(bus);

if (bus->number == 0) {
struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) {
Expand Down
5 changes: 3 additions & 2 deletions arch/ia64/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,9 +533,10 @@ void pcibios_fixup_bus(struct pci_bus *b)
{
struct pci_dev *dev;

if (b->self)
if (b->self) {
pci_read_bridge_bases(b);
pcibios_fixup_bridge_resources(b->self);

}
list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev);
platform_pci_fixup_bus(b);
Expand Down
9 changes: 8 additions & 1 deletion arch/microblaze/pci/pci-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,14 @@ void pcibios_setup_bus_devices(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);

/* Now fixup devices on that bus */
Expand Down
6 changes: 6 additions & 0 deletions arch/mips/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,12 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)

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);
Expand Down
1 change: 1 addition & 0 deletions arch/mn10300/unit-asb2305/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ void pcibios_fixup_bus(struct pci_bus *bus)
struct pci_dev *dev;

if (bus->self) {
pci_read_bridge_bases(bus);
pcibios_fixup_bridge_resources(bus->self);
}

Expand Down
8 changes: 7 additions & 1 deletion arch/powerpc/kernel/pci-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,13 @@ void pcibios_set_master(struct pci_dev *dev)

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);

/* Now fixup devices on that bus */
Expand Down
1 change: 1 addition & 0 deletions arch/x86/pci/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ void pcibios_fixup_bus(struct pci_bus *b)
{
struct pci_dev *dev;

pci_read_bridge_bases(b);
list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev);
}
Expand Down
4 changes: 4 additions & 0 deletions arch/xtensa/kernel/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ subsys_initcall(pcibios_init);

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)
Expand Down
3 changes: 3 additions & 0 deletions drivers/parisc/dino.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,9 @@ dino_fixup_bus(struct pci_bus *bus)
} else if (bus->parent) {
int i;

pci_read_bridge_bases(bus);


for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
if((bus->self->resource[i].flags &
(IORESOURCE_IO | IORESOURCE_MEM)) == 0)
Expand Down
1 change: 1 addition & 0 deletions drivers/parisc/lba_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,7 @@ lba_fixup_bus(struct pci_bus *bus)
if (bus->parent) {
int i;
/* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++)
pci_claim_bridge_resource(bus->self, i);
} else {
Expand Down
27 changes: 4 additions & 23 deletions drivers/pci/access.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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;

if (!tdev)
Expand All @@ -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,
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;

if (!tdev)
Expand All @@ -473,22 +475,6 @@ static const struct pci_vpd_ops pci_vpd_f0_ops = {
.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)
{
struct pci_vpd_pci22 *vpd;
Expand All @@ -497,12 +483,7 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
if (!cap)
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);
if (!vpd)
return -ENOMEM;
Expand Down
2 changes: 2 additions & 0 deletions drivers/pci/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx)

res->start = start;
res->end = end;
res->flags &= ~IORESOURCE_UNSET;
orig_res.flags &= ~IORESOURCE_UNSET;
dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n",
&orig_res, res);

Expand Down
1 change: 1 addition & 0 deletions drivers/pci/host/pci-rcar-gen2.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ static int rcar_pci_probe(struct platform_device *pdev)
static struct of_device_id rcar_pci_of_match[] = {
{ .compatible = "renesas,pci-r8a7790", },
{ .compatible = "renesas,pci-r8a7791", },
{ .compatible = "renesas,pci-r8a7794", },
{ },
};

Expand Down
23 changes: 11 additions & 12 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
struct irq_domain *d;
struct pci_bus *b;

/*
* Either bus is the root, and we must obtain it from the
* firmware, or we inherit it from the bridge device.
* The bus can be a root bus, a subordinate bus, or a virtual bus
* 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))
d = pci_host_bridge_msi_domain(bus);
else
d = dev_get_msi_domain(&bus->self->dev);
for (b = bus, d = NULL; !d && !pci_is_root_bus(b); b = b->parent) {
if (b->self)
d = dev_get_msi_domain(&b->self->dev);
}

if (!d)
d = pci_host_bridge_msi_domain(b);

dev_set_msi_domain(&bus->dev, d);
}
Expand Down Expand Up @@ -855,9 +860,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
child->bridge_ctl = bctl;
}

/* Read and initialize bridge resources */
pci_read_bridge_bases(child);

cmax = pci_scan_child_bus(child);
if (cmax > subordinate)
dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n",
Expand Down Expand Up @@ -918,9 +920,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)

if (!is_cardbus) {
child->bridge_ctl = bctl;

/* Read and initialize bridge resources */
pci_read_bridge_bases(child);
max = pci_scan_child_bus(child);
} else {
/*
Expand Down
20 changes: 18 additions & 2 deletions drivers/pci/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -1907,11 +1907,27 @@ static void quirk_netmos(struct pci_dev *dev)
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
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)
{
if (!dev->multifunction || !PCI_FUNC(dev->devfn))
struct pci_dev *f0;

if (!PCI_FUNC(dev->devfn))
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,
PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link);
Expand Down

0 comments on commit 966966a

Please sign in to comment.