mirror of
https://github.com/torvalds/linux.git
synced 2024-12-04 18:13:04 +00:00
Merge branches 'pci/enumeration' and 'pci/misc' into next
* pci/enumeration: PCI: Set MPS to match upstream bridge PCI: Move MPS configuration check to pci_configure_device() PCI: Drop references acquired by of_parse_phandle() PCI/MSI: Remove unused pcibios_msi_controller() hook ARM/PCI: Remove msi_controller from struct pci_sys_data ARM/PCI, designware, xilinx: Use pci_scan_root_bus_msi() PCI: Add pci_scan_root_bus_msi() ARM/PCI: Replace panic with WARN messages on failures PCI: generic: Add arm64 support PCI: Build setup-irq.o for arm64 PCI: generic: Remove dependency on ARM-specific struct hw_pci ARM/PCI: Set MPS before pci_bus_add_devices() * pci/misc: PCI: Disable async suspend/resume for JMicron multi-function SATA/AHCI
This commit is contained in:
commit
9ca678d1df
@ -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 */
|
||||
|
@ -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,24 +523,14 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
|
||||
* Assign resources.
|
||||
*/
|
||||
pci_bus_assign_resources(bus);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
/*
|
||||
* Tell drivers about devices found.
|
||||
*/
|
||||
pci_bus_add_devices(bus);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user