Message ID | 20180619141700.7842-2-hch@lst.de (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
On Tue, Jun 19, 2018 at 4:16 PM, Christoph Hellwig <hch@lst.de> wrote: > From: "Wesley W. Terpstra" <wesley@sifive.com> > index 340029b2fb38..ea9609fc44fc 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -662,6 +662,7 @@ static inline int pcibios_err_to_errno(int err) > struct pci_ops { > int (*add_bus)(struct pci_bus *bus); > void (*remove_bus)(struct pci_bus *bus); > + void (*add_dev)(struct pci_dev *dev, struct pci_bus *bus); > void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where); > int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); > int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); We are a bit inconsistent about adding callbacks to pci_ops or pci_host_bridge. I would argue this should be part of pci_host_bridge, and the other two should probably be there as well, or possibly moved into a separate 'pci_host_bridge_ops' structure referenced from pci_host_bridge along with the other callbacks there. One of the things we discussed in the past (but never implemented) is that many of the current '__weak' functions in the PCI core can be turned into host_bridge specific operations. Some config space operations by contrast are currently shared across host bridge drivers (see pci_bus_set_ops, or drivers/pci/ecam.c) and probably better left out of the host bridge. Arnd
On Tue, Jun 19, 2018 at 04:31:06PM +0200, Arnd Bergmann wrote: > We are a bit inconsistent about adding callbacks to pci_ops or pci_host_bridge. > I would argue this should be part of pci_host_bridge, and the other two should > probably be there as well, or possibly moved into a separate > 'pci_host_bridge_ops' > structure referenced from pci_host_bridge along with the other callbacks there. How do we find the proper pci_host_bridge from an arbitrary device deep down the hierachy below it?
On Tue, Jun 19, 2018 at 07:32:40PM +0200, Christoph Hellwig wrote: > On Tue, Jun 19, 2018 at 04:31:06PM +0200, Arnd Bergmann wrote: > > We are a bit inconsistent about adding callbacks to pci_ops or pci_host_bridge. > > I would argue this should be part of pci_host_bridge, and the other two should > > probably be there as well, or possibly moved into a separate > > 'pci_host_bridge_ops' > > structure referenced from pci_host_bridge along with the other callbacks there. > > How do we find the proper pci_host_bridge from an arbitrary > device deep down the hierachy below it? pci_get_host_bridge_device() should do the work.
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ac876e32de4b..978e684cba2c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2331,6 +2331,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) /* Set up MSI IRQ domain */ pci_set_msi_domain(dev); + if (bus->ops->add_dev) + bus->ops->add_dev(dev, bus); + /* Notifier could use PCI capabilities */ dev->match_driver = false; ret = device_add(&dev->dev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 340029b2fb38..ea9609fc44fc 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -662,6 +662,7 @@ static inline int pcibios_err_to_errno(int err) struct pci_ops { int (*add_bus)(struct pci_bus *bus); void (*remove_bus)(struct pci_bus *bus); + void (*add_dev)(struct pci_dev *dev, struct pci_bus *bus); void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where); int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);