summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/mach/pci.h5
-rw-r--r--arch/arm/kernel/bios32.c45
-rw-r--r--drivers/ata/ahci.c13
-rw-r--r--drivers/ata/pata_jmicron.c12
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/host/Kconfig2
-rw-r--r--drivers/pci/host/pci-host-generic.c52
-rw-r--r--drivers/pci/host/pci-mvebu.c1
-rw-r--r--drivers/pci/host/pci-xgene.c1
-rw-r--r--drivers/pci/host/pcie-designware.c12
-rw-r--r--drivers/pci/host/pcie-xilinx.c11
-rw-r--r--drivers/pci/msi.c17
-rw-r--r--drivers/pci/pci.c2
-rw-r--r--drivers/pci/probe.c75
-rw-r--r--drivers/pci/quirks.c15
-rw-r--r--include/linux/pci.h13
16 files changed, 148 insertions, 129 deletions
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 28b9bb35949e..8857d2869a5f 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -19,9 +19,7 @@ struct pci_bus;
struct device;
struct hw_pci {
-#ifdef CONFIG_PCI_MSI
struct msi_controller *msi_ctrl;
-#endif
struct pci_ops *ops;
int nr_controllers;
void **private_data;
@@ -42,9 +40,6 @@ struct hw_pci {
* Per-controller structure
*/
struct pci_sys_data {
-#ifdef CONFIG_PCI_MSI
- struct msi_controller *msi_ctrl;
-#endif
struct list_head node;
int busnr; /* primary bus number */
u64 mem_offset; /* bus->cpu memory mapping offset */
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index fcbbbb1b9e95..874e1823f803 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -18,15 +18,6 @@
static int debug_pci;
-#ifdef CONFIG_PCI_MSI
-struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
-{
- struct pci_sys_data *sysdata = dev->bus->sysdata;
-
- return sysdata->msi_ctrl;
-}
-#endif
-
/*
* We can't use pci_get_device() here since we are
* called from interrupt context.
@@ -459,12 +450,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
- if (!sys)
- panic("PCI: unable to allocate sys data!");
+ if (WARN(!sys, "PCI: unable to allocate sys data!"))
+ break;
-#ifdef CONFIG_PCI_MSI
- sys->msi_ctrl = hw->msi_ctrl;
-#endif
sys->busnr = busnr;
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
@@ -486,11 +474,14 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
if (hw->scan)
sys->bus = hw->scan(nr, sys);
else
- sys->bus = pci_scan_root_bus(parent, sys->busnr,
- hw->ops, sys, &sys->resources);
+ sys->bus = pci_scan_root_bus_msi(parent,
+ sys->busnr, hw->ops, sys,
+ &sys->resources, hw->msi_ctrl);
- if (!sys->bus)
- panic("PCI: unable to scan bus!");
+ if (WARN(!sys->bus, "PCI: unable to scan bus!")) {
+ kfree(sys);
+ break;
+ }
busnr = sys->bus->busn_res.end + 1;
@@ -521,6 +512,8 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
struct pci_bus *bus = sys->bus;
if (!pci_has_flag(PCI_PROBE_ONLY)) {
+ struct pci_bus *child;
+
/*
* Size the bridge windows.
*/
@@ -530,25 +523,15 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
* Assign resources.
*/
pci_bus_assign_resources(bus);
- }
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
+ }
/*
* Tell drivers about devices found.
*/
pci_bus_add_devices(bus);
}
-
- list_for_each_entry(sys, &head, node) {
- struct pci_bus *bus = sys->bus;
-
- /* Configure PCI Express settings */
- if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
- struct pci_bus *child;
-
- list_for_each_entry(child, &bus->children, node)
- pcie_bus_configure_settings(child);
- }
- }
}
#ifndef CONFIG_PCI_HOST_ITE8152
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 7e62751abfac..a46660204e3a 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -351,6 +351,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* JMicron 362B and 362C have an AHCI function with IDE class code */
{ PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr },
{ PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },
+ /* May need to update quirk_jmicron_async_suspend() for additions */
/* ATI */
{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
@@ -1451,18 +1452,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
else if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
ahci_pci_bar = AHCI_PCI_BAR_CAVIUM;
- /*
- * The JMicron chip 361/363 contains one SATA controller and one
- * PATA controller,for powering on these both controllers, we must
- * follow the sequence one by one, otherwise one of them can not be
- * powered on successfully, so here we disable the async suspend
- * method for these chips.
- */
- if (pdev->vendor == PCI_VENDOR_ID_JMICRON &&
- (pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 ||
- pdev->device == PCI_DEVICE_ID_JMICRON_JMB361))
- device_disable_async_suspend(&pdev->dev);
-
/* acquire resources */
rc = pcim_enable_device(pdev);
if (rc)
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 47e418b8c8ba..4d1a5d2c4287 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -143,18 +143,6 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
};
const struct ata_port_info *ppi[] = { &info, NULL };
- /*
- * The JMicron chip 361/363 contains one SATA controller and one
- * PATA controller,for powering on these both controllers, we must
- * follow the sequence one by one, otherwise one of them can not be
- * powered on successfully, so here we disable the async suspend
- * method for these chips.
- */
- if (pdev->vendor == PCI_VENDOR_ID_JMICRON &&
- (pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 ||
- pdev->device == PCI_DEVICE_ID_JMICRON_JMB361))
- device_disable_async_suspend(&pdev->dev);
-
return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0);
}
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 73e4af400a5a..be3f631c3f75 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o
#
obj-$(CONFIG_ALPHA) += setup-irq.o
obj-$(CONFIG_ARM) += setup-irq.o
+obj-$(CONFIG_ARM64) += setup-irq.o
obj-$(CONFIG_UNICORE32) += setup-irq.o
obj-$(CONFIG_SUPERH) += setup-irq.o
obj-$(CONFIG_MIPS) += setup-irq.o
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index e339a8c42f76..1272b8002884 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -53,7 +53,7 @@ config PCI_RCAR_GEN2_PCIE
config PCI_HOST_GENERIC
bool "Generic PCI host controller"
- depends on ARM && OF
+ depends on (ARM || ARM64) && OF
help
Say Y here if you want to support a simple generic PCI host
controller, such as the one emulated by kvmtool.
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index ba46e581db99..265dd25169bf 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -38,7 +38,16 @@ struct gen_pci_cfg_windows {
const struct gen_pci_cfg_bus_ops *ops;
};
+/*
+ * ARM pcibios functions expect the ARM struct pci_sys_data as the PCI
+ * sysdata. Add pci_sys_data as the first element in struct gen_pci so
+ * that when we use a gen_pci pointer as sysdata, it is also a pointer to
+ * a struct pci_sys_data.
+ */
struct gen_pci {
+#ifdef CONFIG_ARM
+ struct pci_sys_data sys;
+#endif
struct pci_host_bridge host;
struct gen_pci_cfg_windows cfg;
struct list_head resources;
@@ -48,8 +57,7 @@ static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,
unsigned int devfn,
int where)
{
- struct pci_sys_data *sys = bus->sysdata;
- struct gen_pci *pci = sys->private_data;
+ struct gen_pci *pci = bus->sysdata;
resource_size_t idx = bus->number - pci->cfg.bus_range->start;
return pci->cfg.win[idx] + ((devfn << 8) | where);
@@ -64,8 +72,7 @@ static void __iomem *gen_pci_map_cfg_bus_ecam(struct pci_bus *bus,
unsigned int devfn,
int where)
{
- struct pci_sys_data *sys = bus->sysdata;
- struct gen_pci *pci = sys->private_data;
+ struct gen_pci *pci = bus->sysdata;
resource_size_t idx = bus->number - pci->cfg.bus_range->start;
return pci->cfg.win[idx] + ((devfn << 12) | where);
@@ -198,13 +205,6 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
return 0;
}
-static int gen_pci_setup(int nr, struct pci_sys_data *sys)
-{
- struct gen_pci *pci = sys->private_data;
- list_splice_init(&pci->resources, &sys->resources);
- return 1;
-}
-
static int gen_pci_probe(struct platform_device *pdev)
{
int err;
@@ -214,13 +214,7 @@ static int gen_pci_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
- struct hw_pci hw = {
- .nr_controllers = 1,
- .private_data = (void **)&pci,
- .setup = gen_pci_setup,
- .map_irq = of_irq_parse_and_map_pci,
- .ops = &gen_pci_ops,
- };
+ struct pci_bus *bus, *child;
if (!pci)
return -ENOMEM;
@@ -258,7 +252,27 @@ static int gen_pci_probe(struct platform_device *pdev)
return err;
}
- pci_common_init_dev(dev, &hw);
+ /* Do not reassign resources if probe only */
+ if (!pci_has_flag(PCI_PROBE_ONLY))
+ pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
+
+ bus = pci_scan_root_bus(dev, 0, &gen_pci_ops, pci, &pci->resources);
+ if (!bus) {
+ dev_err(dev, "Scanning rootbus failed");
+ return -ENODEV;
+ }
+
+ pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+
+ if (!pci_has_flag(PCI_PROBE_ONLY)) {
+ pci_bus_size_bridges(bus);
+ pci_bus_assign_resources(bus);
+
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
+ }
+
+ pci_bus_add_devices(bus);
return 0;
}
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 70aa09556ec5..67ec5e1c99db 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
return;
pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
+ of_node_put(msi_node);
if (pcie->msi)
pcie->msi->dev = &pcie->pdev->dev;
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index 55fe86548d77..0236ab9d5720 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -522,6 +522,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
if (!bus->msi)
return -ENODEV;
+ of_node_put(msi_node);
bus->msi->dev = &bus->dev;
return 0;
}
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 308957f09873..8d52ce73f842 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -525,7 +525,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
#ifdef CONFIG_PCI_MSI
dw_pcie_msi_chip.dev = pp->dev;
- dw_pci.msi_ctrl = &dw_pcie_msi_chip;
#endif
dw_pci.nr_controllers = 1;
@@ -707,8 +706,15 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
struct pcie_port *pp = sys_to_pcie(sys);
pp->root_bus_nr = sys->busnr;
- bus = pci_scan_root_bus(pp->dev, sys->busnr,
- &dw_pcie_ops, sys, &sys->resources);
+
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ bus = pci_scan_root_bus_msi(pp->dev, sys->busnr, &dw_pcie_ops,
+ sys, &sys->resources,
+ &dw_pcie_msi_chip);
+ else
+ bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
+ sys, &sys->resources);
+
if (!bus)
return NULL;
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index 0e1f480b9db4..1aeaa914bd30 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -648,9 +648,15 @@ static struct pci_bus *xilinx_pcie_scan_bus(int nr, struct pci_sys_data *sys)
struct pci_bus *bus;
port->root_busno = sys->busnr;
- bus = pci_scan_root_bus(port->dev, sys->busnr, &xilinx_pcie_ops,
- sys, &sys->resources);
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ bus = pci_scan_root_bus_msi(port->dev, sys->busnr,
+ &xilinx_pcie_ops, sys,
+ &sys->resources,
+ &xilinx_pcie_msi_chip);
+ else
+ bus = pci_scan_root_bus(port->dev, sys->busnr,
+ &xilinx_pcie_ops, sys, &sys->resources);
return bus;
}
@@ -848,7 +854,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev)
#ifdef CONFIG_PCI_MSI
xilinx_pcie_msi_chip.dev = port->dev;
- hw.msi_ctrl = &xilinx_pcie_msi_chip;
#endif
pci_common_init_dev(dev, &hw);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index bb74238c0cb6..2f9b1c0d1f96 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -77,24 +77,9 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
/* Arch hooks */
-struct msi_controller * __weak pcibios_msi_controller(struct pci_dev *dev)
-{
- return NULL;
-}
-
-static struct msi_controller *pci_msi_controller(struct pci_dev *dev)
-{
- struct msi_controller *msi_ctrl = dev->bus->msi;
-
- if (msi_ctrl)
- return msi_ctrl;
-
- return pcibios_msi_controller(dev);
-}
-
int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
- struct msi_controller *chip = pci_msi_controller(dev);
+ struct msi_controller *chip = dev->bus->msi;
int err;
if (!chip || !chip->setup_irq)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8037c27beb05..cc76238c86fb 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -81,7 +81,7 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE;
unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
-enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT;
/*
* The default CLS is used if arch didn't set CLS explicitly and not
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 51ebb9783f5e..d2e36bbecb42 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1277,6 +1277,44 @@ int pci_setup_device(struct pci_dev *dev)
return 0;
}
+static void pci_configure_mps(struct pci_dev *dev)
+{
+ struct pci_dev *bridge = pci_upstream_bridge(dev);
+ int mps, p_mps, rc;
+
+ if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge))
+ return;
+
+ mps = pcie_get_mps(dev);
+ p_mps = pcie_get_mps(bridge);
+
+ if (mps == p_mps)
+ return;
+
+ if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
+ dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+ mps, pci_name(bridge), p_mps);
+ return;
+ }
+
+ /*
+ * Fancier MPS configuration is done later by
+ * pcie_bus_configure_settings()
+ */
+ if (pcie_bus_config != PCIE_BUS_DEFAULT)
+ return;
+
+ rc = pcie_set_mps(dev, p_mps);
+ if (rc) {
+ dev_warn(&dev->dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+ p_mps);
+ return;
+ }
+
+ dev_info(&dev->dev, "Max Payload Size set to %d (was %d, max %d)\n",
+ p_mps, mps, 128 << dev->pcie_mpss);
+}
+
static struct hpp_type0 pci_default_type0 = {
.revision = 1,
.cache_line_size = 8,
@@ -1398,6 +1436,8 @@ static void pci_configure_device(struct pci_dev *dev)
struct hotplug_params hpp;
int ret;
+ pci_configure_mps(dev);
+
memset(&hpp, 0, sizeof(hpp));
ret = pci_get_hp_params(dev, &hpp);
if (ret)
@@ -1796,22 +1836,6 @@ static void pcie_write_mrrs(struct pci_dev *dev)
dev_err(&dev->dev, "MRRS was unable to be configured with a safe value. If problems are experienced, try running with pci=pcie_bus_safe\n");
}
-static void pcie_bus_detect_mps(struct pci_dev *dev)
-{
- struct pci_dev *bridge = dev->bus->self;
- int mps, p_mps;
-
- if (!bridge)
- return;
-
- mps = pcie_get_mps(dev);
- p_mps = pcie_get_mps(bridge);
-
- if (mps != p_mps)
- dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
- mps, pci_name(bridge), p_mps);
-}
-
static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
{
int mps, orig_mps;
@@ -1819,10 +1843,9 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
if (!pci_is_pcie(dev))
return 0;
- if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
- pcie_bus_detect_mps(dev);
+ if (pcie_bus_config == PCIE_BUS_TUNE_OFF ||
+ pcie_bus_config == PCIE_BUS_DEFAULT)
return 0;
- }
mps = 128 << *(u8 *)data;
orig_mps = pcie_get_mps(dev);
@@ -2101,8 +2124,9 @@ void pci_bus_release_busn_res(struct pci_bus *b)
res, ret ? "can not be" : "is");
}
-struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
- struct pci_ops *ops, void *sysdata, struct list_head *resources)
+struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata,
+ struct list_head *resources, struct msi_controller *msi)
{
struct resource_entry *window;
bool found = false;
@@ -2119,6 +2143,8 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
if (!b)
return NULL;
+ b->msi = msi;
+
if (!found) {
dev_info(&b->dev,
"No busn resource found for root bus, will use [bus %02x-ff]\n",
@@ -2133,6 +2159,13 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
return b;
}
+
+struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+ return pci_scan_root_bus_msi(parent, bus, ops, sysdata, resources,
+ NULL);
+}
EXPORT_SYMBOL(pci_scan_root_bus);
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7741250f1095..de5f610e0810 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1570,6 +1570,18 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB3
#endif
+static void quirk_jmicron_async_suspend(struct pci_dev *dev)
+{
+ if (dev->multifunction) {
+ device_disable_async_suspend(&dev->dev);
+ dev_info(&dev->dev, "async suspend disabled to avoid multi-function power-on ordering issue\n");
+ }
+}
+DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, 8, quirk_jmicron_async_suspend);
+DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_SATA_AHCI, 0, quirk_jmicron_async_suspend);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_JMICRON, 0x2362, quirk_jmicron_async_suspend);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_JMICRON, 0x236f, quirk_jmicron_async_suspend);
+
#ifdef CONFIG_X86_IO_APIC
static void quirk_alder_ioapic(struct pci_dev *pdev)
{
@@ -2879,7 +2891,8 @@ static void quirk_intel_mc_errata(struct pci_dev *dev)
int err;
u16 rcc;
- if (pcie_bus_config == PCIE_BUS_TUNE_OFF)
+ if (pcie_bus_config == PCIE_BUS_TUNE_OFF ||
+ pcie_bus_config == PCIE_BUS_DEFAULT)
return;
/* Intel errata specifies bits to change but does not say what they are.
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5eb2bf9ff456..e393393115c4 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -744,10 +744,11 @@ struct pci_driver {
void pcie_bus_configure_settings(struct pci_bus *bus);
enum pcie_bus_config_types {
- PCIE_BUS_TUNE_OFF,
- PCIE_BUS_SAFE,
- PCIE_BUS_PERFORMANCE,
- PCIE_BUS_PEER2PEER,
+ PCIE_BUS_TUNE_OFF, /* don't touch MPS at all */
+ PCIE_BUS_DEFAULT, /* ensure MPS matches upstream bridge */
+ PCIE_BUS_SAFE, /* use largest MPS boot-time devices support */
+ PCIE_BUS_PERFORMANCE, /* use MPS and MRRS for best performance */
+ PCIE_BUS_PEER2PEER, /* set MPS = 128 for all devices */
};
extern enum pcie_bus_config_types pcie_bus_config;
@@ -793,6 +794,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
void pci_bus_release_busn_res(struct pci_bus *b);
+struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata,
+ struct list_head *resources,
+ struct msi_controller *msi);
struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata,
struct list_head *resources);