Merge branch 'pci/enumeration'
- Enable Configuration RRS SV early instead of during child bus scanning (Bjorn Helgaas) - Cache offset of Resizable BAR capability to avoid redundant searches for it (Bjorn Helgaas) - Fix reference leaks in pci_register_host_bridge() and pci_alloc_child_bus() (Ma Ke) - Drop put_device() in pci_register_host_bridge() left over from converting device_register() to device_add() (Dan Carpenter) * pci/enumeration: PCI: Remove stray put_device() in pci_register_host_bridge() PCI: Fix reference leak in pci_alloc_child_bus() PCI: Fix reference leak in pci_register_host_bridge() PCI: Cache offset of Resizable BAR capability PCI: Enable Configuration RRS SV early
This commit is contained in:
commit
e9e224dadd
@ -1879,7 +1879,7 @@ static void pci_restore_rebar_state(struct pci_dev *pdev)
|
||||
unsigned int pos, nbars, i;
|
||||
u32 ctrl;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
|
||||
pos = pdev->rebar_cap;
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
@ -3726,6 +3726,11 @@ void pci_acs_init(struct pci_dev *dev)
|
||||
pci_enable_acs(dev);
|
||||
}
|
||||
|
||||
void pci_rebar_init(struct pci_dev *pdev)
|
||||
{
|
||||
pdev->rebar_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_rebar_find_pos - find position of resize ctrl reg for BAR
|
||||
* @pdev: PCI device
|
||||
@ -3740,7 +3745,7 @@ static int pci_rebar_find_pos(struct pci_dev *pdev, int bar)
|
||||
unsigned int pos, nbars, i;
|
||||
u32 ctrl;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
|
||||
pos = pdev->rebar_cap;
|
||||
if (!pos)
|
||||
return -ENOTSUPP;
|
||||
|
||||
|
||||
@ -826,6 +826,7 @@ static inline int acpi_get_rc_resources(struct device *dev, const char *hid,
|
||||
}
|
||||
#endif
|
||||
|
||||
void pci_rebar_init(struct pci_dev *pdev);
|
||||
int pci_rebar_get_current_size(struct pci_dev *pdev, int bar);
|
||||
int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size);
|
||||
static inline u64 pci_rebar_size_to_bytes(int size)
|
||||
|
||||
@ -954,6 +954,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
||||
resource_size_t offset, next_offset;
|
||||
LIST_HEAD(resources);
|
||||
struct resource *res, *next_res;
|
||||
bool bus_registered = false;
|
||||
char addr[64], *fmt;
|
||||
const char *name;
|
||||
int err;
|
||||
@ -996,10 +997,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
||||
/* Temporarily move resources off the list */
|
||||
list_splice_init(&bridge->windows, &resources);
|
||||
err = device_add(&bridge->dev);
|
||||
if (err) {
|
||||
put_device(&bridge->dev);
|
||||
if (err)
|
||||
goto free;
|
||||
}
|
||||
|
||||
bus->bridge = get_device(&bridge->dev);
|
||||
device_enable_async_suspend(bus->bridge);
|
||||
pci_set_bus_of_node(bus);
|
||||
@ -1018,6 +1018,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
||||
name = dev_name(&bus->dev);
|
||||
|
||||
err = device_register(&bus->dev);
|
||||
bus_registered = true;
|
||||
if (err)
|
||||
goto unregister;
|
||||
|
||||
@ -1104,12 +1105,15 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
||||
unregister:
|
||||
put_device(&bridge->dev);
|
||||
device_del(&bridge->dev);
|
||||
|
||||
free:
|
||||
#ifdef CONFIG_PCI_DOMAINS_GENERIC
|
||||
pci_bus_release_domain_nr(parent, bus->domain_nr);
|
||||
#endif
|
||||
kfree(bus);
|
||||
if (bus_registered)
|
||||
put_device(&bus->dev);
|
||||
else
|
||||
kfree(bus);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1218,7 +1222,10 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
|
||||
add_dev:
|
||||
pci_set_bus_msi_domain(child);
|
||||
ret = device_register(&child->dev);
|
||||
WARN_ON(ret < 0);
|
||||
if (WARN_ON(ret < 0)) {
|
||||
put_device(&child->dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcibios_add_bus(child);
|
||||
|
||||
@ -1374,8 +1381,6 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
|
||||
pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
|
||||
bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
|
||||
|
||||
pci_enable_rrs_sv(dev);
|
||||
|
||||
if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
|
||||
!is_cardbus && !broken) {
|
||||
unsigned int cmax, buses;
|
||||
@ -1616,6 +1621,11 @@ void set_pcie_port_type(struct pci_dev *pdev)
|
||||
pdev->pcie_cap = pos;
|
||||
pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16);
|
||||
pdev->pcie_flags_reg = reg16;
|
||||
|
||||
type = pci_pcie_type(pdev);
|
||||
if (type == PCI_EXP_TYPE_ROOT_PORT)
|
||||
pci_enable_rrs_sv(pdev);
|
||||
|
||||
pci_read_config_dword(pdev, pos + PCI_EXP_DEVCAP, &pdev->devcap);
|
||||
pdev->pcie_mpss = FIELD_GET(PCI_EXP_DEVCAP_PAYLOAD, pdev->devcap);
|
||||
|
||||
@ -1632,7 +1642,6 @@ void set_pcie_port_type(struct pci_dev *pdev)
|
||||
* correctly so detect impossible configurations here and correct
|
||||
* the port type accordingly.
|
||||
*/
|
||||
type = pci_pcie_type(pdev);
|
||||
if (type == PCI_EXP_TYPE_DOWNSTREAM) {
|
||||
/*
|
||||
* If pdev claims to be downstream port but the parent
|
||||
@ -2565,6 +2574,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
|
||||
pci_rcec_init(dev); /* Root Complex Event Collector */
|
||||
pci_doe_init(dev); /* Data Object Exchange */
|
||||
pci_tph_init(dev); /* TLP Processing Hints */
|
||||
pci_rebar_init(dev); /* Resizable BAR */
|
||||
|
||||
pcie_report_downtraining(dev);
|
||||
pci_init_reset_methods(dev);
|
||||
|
||||
@ -353,6 +353,7 @@ struct pci_dev {
|
||||
struct pci_dev *rcec; /* Associated RCEC device */
|
||||
#endif
|
||||
u32 devcap; /* PCIe Device Capabilities */
|
||||
u16 rebar_cap; /* Resizable BAR capability offset */
|
||||
u8 pcie_cap; /* PCIe capability offset */
|
||||
u8 msi_cap; /* MSI capability offset */
|
||||
u8 msix_cap; /* MSI-X capability offset */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user