mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 18:41:23 +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 device;
|
||||||
|
|
||||||
struct hw_pci {
|
struct hw_pci {
|
||||||
#ifdef CONFIG_PCI_MSI
|
|
||||||
struct msi_controller *msi_ctrl;
|
struct msi_controller *msi_ctrl;
|
||||||
#endif
|
|
||||||
struct pci_ops *ops;
|
struct pci_ops *ops;
|
||||||
int nr_controllers;
|
int nr_controllers;
|
||||||
void **private_data;
|
void **private_data;
|
||||||
@ -42,9 +40,6 @@ struct hw_pci {
|
|||||||
* Per-controller structure
|
* Per-controller structure
|
||||||
*/
|
*/
|
||||||
struct pci_sys_data {
|
struct pci_sys_data {
|
||||||
#ifdef CONFIG_PCI_MSI
|
|
||||||
struct msi_controller *msi_ctrl;
|
|
||||||
#endif
|
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
int busnr; /* primary bus number */
|
int busnr; /* primary bus number */
|
||||||
u64 mem_offset; /* bus->cpu memory mapping offset */
|
u64 mem_offset; /* bus->cpu memory mapping offset */
|
||||||
|
@ -18,15 +18,6 @@
|
|||||||
|
|
||||||
static int debug_pci;
|
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
|
* We can't use pci_get_device() here since we are
|
||||||
* called from interrupt context.
|
* 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++) {
|
for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
|
||||||
sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
|
sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
|
||||||
if (!sys)
|
if (WARN(!sys, "PCI: unable to allocate sys data!"))
|
||||||
panic("PCI: unable to allocate sys data!");
|
break;
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_MSI
|
|
||||||
sys->msi_ctrl = hw->msi_ctrl;
|
|
||||||
#endif
|
|
||||||
sys->busnr = busnr;
|
sys->busnr = busnr;
|
||||||
sys->swizzle = hw->swizzle;
|
sys->swizzle = hw->swizzle;
|
||||||
sys->map_irq = hw->map_irq;
|
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)
|
if (hw->scan)
|
||||||
sys->bus = hw->scan(nr, sys);
|
sys->bus = hw->scan(nr, sys);
|
||||||
else
|
else
|
||||||
sys->bus = pci_scan_root_bus(parent, sys->busnr,
|
sys->bus = pci_scan_root_bus_msi(parent,
|
||||||
hw->ops, sys, &sys->resources);
|
sys->busnr, hw->ops, sys,
|
||||||
|
&sys->resources, hw->msi_ctrl);
|
||||||
|
|
||||||
if (!sys->bus)
|
if (WARN(!sys->bus, "PCI: unable to scan bus!")) {
|
||||||
panic("PCI: unable to scan bus!");
|
kfree(sys);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
busnr = sys->bus->busn_res.end + 1;
|
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;
|
struct pci_bus *bus = sys->bus;
|
||||||
|
|
||||||
if (!pci_has_flag(PCI_PROBE_ONLY)) {
|
if (!pci_has_flag(PCI_PROBE_ONLY)) {
|
||||||
|
struct pci_bus *child;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Size the bridge windows.
|
* Size the bridge windows.
|
||||||
*/
|
*/
|
||||||
@ -530,24 +523,14 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
|
|||||||
* Assign resources.
|
* Assign resources.
|
||||||
*/
|
*/
|
||||||
pci_bus_assign_resources(bus);
|
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)
|
list_for_each_entry(child, &bus->children, node)
|
||||||
pcie_bus_configure_settings(child);
|
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 */
|
/* JMicron 362B and 362C have an AHCI function with IDE class code */
|
||||||
{ PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr },
|
{ PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr },
|
||||||
{ PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },
|
{ PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },
|
||||||
|
/* May need to update quirk_jmicron_async_suspend() for additions */
|
||||||
|
|
||||||
/* ATI */
|
/* ATI */
|
||||||
{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
|
{ 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)
|
else if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
|
||||||
ahci_pci_bar = AHCI_PCI_BAR_CAVIUM;
|
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 */
|
/* acquire resources */
|
||||||
rc = pcim_enable_device(pdev);
|
rc = pcim_enable_device(pdev);
|
||||||
if (rc)
|
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 };
|
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);
|
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_ALPHA) += setup-irq.o
|
||||||
obj-$(CONFIG_ARM) += setup-irq.o
|
obj-$(CONFIG_ARM) += setup-irq.o
|
||||||
|
obj-$(CONFIG_ARM64) += setup-irq.o
|
||||||
obj-$(CONFIG_UNICORE32) += setup-irq.o
|
obj-$(CONFIG_UNICORE32) += setup-irq.o
|
||||||
obj-$(CONFIG_SUPERH) += setup-irq.o
|
obj-$(CONFIG_SUPERH) += setup-irq.o
|
||||||
obj-$(CONFIG_MIPS) += setup-irq.o
|
obj-$(CONFIG_MIPS) += setup-irq.o
|
||||||
|
@ -53,7 +53,7 @@ config PCI_RCAR_GEN2_PCIE
|
|||||||
|
|
||||||
config PCI_HOST_GENERIC
|
config PCI_HOST_GENERIC
|
||||||
bool "Generic PCI host controller"
|
bool "Generic PCI host controller"
|
||||||
depends on ARM && OF
|
depends on (ARM || ARM64) && OF
|
||||||
help
|
help
|
||||||
Say Y here if you want to support a simple generic PCI host
|
Say Y here if you want to support a simple generic PCI host
|
||||||
controller, such as the one emulated by kvmtool.
|
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;
|
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 {
|
struct gen_pci {
|
||||||
|
#ifdef CONFIG_ARM
|
||||||
|
struct pci_sys_data sys;
|
||||||
|
#endif
|
||||||
struct pci_host_bridge host;
|
struct pci_host_bridge host;
|
||||||
struct gen_pci_cfg_windows cfg;
|
struct gen_pci_cfg_windows cfg;
|
||||||
struct list_head resources;
|
struct list_head resources;
|
||||||
@ -48,8 +57,7 @@ static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,
|
|||||||
unsigned int devfn,
|
unsigned int devfn,
|
||||||
int where)
|
int where)
|
||||||
{
|
{
|
||||||
struct pci_sys_data *sys = bus->sysdata;
|
struct gen_pci *pci = bus->sysdata;
|
||||||
struct gen_pci *pci = sys->private_data;
|
|
||||||
resource_size_t idx = bus->number - pci->cfg.bus_range->start;
|
resource_size_t idx = bus->number - pci->cfg.bus_range->start;
|
||||||
|
|
||||||
return pci->cfg.win[idx] + ((devfn << 8) | where);
|
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,
|
unsigned int devfn,
|
||||||
int where)
|
int where)
|
||||||
{
|
{
|
||||||
struct pci_sys_data *sys = bus->sysdata;
|
struct gen_pci *pci = bus->sysdata;
|
||||||
struct gen_pci *pci = sys->private_data;
|
|
||||||
resource_size_t idx = bus->number - pci->cfg.bus_range->start;
|
resource_size_t idx = bus->number - pci->cfg.bus_range->start;
|
||||||
|
|
||||||
return pci->cfg.win[idx] + ((devfn << 12) | where);
|
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;
|
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)
|
static int gen_pci_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
@ -214,13 +214,7 @@ static int gen_pci_probe(struct platform_device *pdev)
|
|||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct device_node *np = dev->of_node;
|
struct device_node *np = dev->of_node;
|
||||||
struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
|
struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
|
||||||
struct hw_pci hw = {
|
struct pci_bus *bus, *child;
|
||||||
.nr_controllers = 1,
|
|
||||||
.private_data = (void **)&pci,
|
|
||||||
.setup = gen_pci_setup,
|
|
||||||
.map_irq = of_irq_parse_and_map_pci,
|
|
||||||
.ops = &gen_pci_ops,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!pci)
|
if (!pci)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -258,7 +252,27 @@ static int gen_pci_probe(struct platform_device *pdev)
|
|||||||
return err;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
|
pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
|
||||||
|
of_node_put(msi_node);
|
||||||
|
|
||||||
if (pcie->msi)
|
if (pcie->msi)
|
||||||
pcie->msi->dev = &pcie->pdev->dev;
|
pcie->msi->dev = &pcie->pdev->dev;
|
||||||
|
@ -522,6 +522,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
|
|||||||
if (!bus->msi)
|
if (!bus->msi)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
of_node_put(msi_node);
|
||||||
bus->msi->dev = &bus->dev;
|
bus->msi->dev = &bus->dev;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
|
|||||||
|
|
||||||
#ifdef CONFIG_PCI_MSI
|
#ifdef CONFIG_PCI_MSI
|
||||||
dw_pcie_msi_chip.dev = pp->dev;
|
dw_pcie_msi_chip.dev = pp->dev;
|
||||||
dw_pci.msi_ctrl = &dw_pcie_msi_chip;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dw_pci.nr_controllers = 1;
|
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);
|
struct pcie_port *pp = sys_to_pcie(sys);
|
||||||
|
|
||||||
pp->root_bus_nr = sys->busnr;
|
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)
|
if (!bus)
|
||||||
return NULL;
|
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;
|
struct pci_bus *bus;
|
||||||
|
|
||||||
port->root_busno = sys->busnr;
|
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;
|
return bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -848,7 +854,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
#ifdef CONFIG_PCI_MSI
|
#ifdef CONFIG_PCI_MSI
|
||||||
xilinx_pcie_msi_chip.dev = port->dev;
|
xilinx_pcie_msi_chip.dev = port->dev;
|
||||||
hw.msi_ctrl = &xilinx_pcie_msi_chip;
|
|
||||||
#endif
|
#endif
|
||||||
pci_common_init_dev(dev, &hw);
|
pci_common_init_dev(dev, &hw);
|
||||||
|
|
||||||
|
@ -77,24 +77,9 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
|
|||||||
|
|
||||||
/* Arch hooks */
|
/* 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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!chip || !chip->setup_irq)
|
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_io_size = DEFAULT_HOTPLUG_IO_SIZE;
|
||||||
unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_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
|
* 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;
|
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 = {
|
static struct hpp_type0 pci_default_type0 = {
|
||||||
.revision = 1,
|
.revision = 1,
|
||||||
.cache_line_size = 8,
|
.cache_line_size = 8,
|
||||||
@ -1398,6 +1436,8 @@ static void pci_configure_device(struct pci_dev *dev)
|
|||||||
struct hotplug_params hpp;
|
struct hotplug_params hpp;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
pci_configure_mps(dev);
|
||||||
|
|
||||||
memset(&hpp, 0, sizeof(hpp));
|
memset(&hpp, 0, sizeof(hpp));
|
||||||
ret = pci_get_hp_params(dev, &hpp);
|
ret = pci_get_hp_params(dev, &hpp);
|
||||||
if (ret)
|
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");
|
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)
|
static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
||||||
{
|
{
|
||||||
int mps, orig_mps;
|
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))
|
if (!pci_is_pcie(dev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
|
if (pcie_bus_config == PCIE_BUS_TUNE_OFF ||
|
||||||
pcie_bus_detect_mps(dev);
|
pcie_bus_config == PCIE_BUS_DEFAULT)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
mps = 128 << *(u8 *)data;
|
mps = 128 << *(u8 *)data;
|
||||||
orig_mps = pcie_get_mps(dev);
|
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");
|
res, ret ? "can not be" : "is");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
|
struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
|
||||||
struct pci_ops *ops, void *sysdata, struct list_head *resources)
|
struct pci_ops *ops, void *sysdata,
|
||||||
|
struct list_head *resources, struct msi_controller *msi)
|
||||||
{
|
{
|
||||||
struct resource_entry *window;
|
struct resource_entry *window;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -2119,6 +2143,8 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
|
|||||||
if (!b)
|
if (!b)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
b->msi = msi;
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
dev_info(&b->dev,
|
dev_info(&b->dev,
|
||||||
"No busn resource found for root bus, will use [bus %02x-ff]\n",
|
"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;
|
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);
|
EXPORT_SYMBOL(pci_scan_root_bus);
|
||||||
|
|
||||||
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
|
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
|
#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
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
static void quirk_alder_ioapic(struct pci_dev *pdev)
|
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;
|
int err;
|
||||||
u16 rcc;
|
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;
|
return;
|
||||||
|
|
||||||
/* Intel errata specifies bits to change but does not say what they are.
|
/* 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);
|
void pcie_bus_configure_settings(struct pci_bus *bus);
|
||||||
|
|
||||||
enum pcie_bus_config_types {
|
enum pcie_bus_config_types {
|
||||||
PCIE_BUS_TUNE_OFF,
|
PCIE_BUS_TUNE_OFF, /* don't touch MPS at all */
|
||||||
PCIE_BUS_SAFE,
|
PCIE_BUS_DEFAULT, /* ensure MPS matches upstream bridge */
|
||||||
PCIE_BUS_PERFORMANCE,
|
PCIE_BUS_SAFE, /* use largest MPS boot-time devices support */
|
||||||
PCIE_BUS_PEER2PEER,
|
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;
|
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_insert_busn_res(struct pci_bus *b, int bus, int busmax);
|
||||||
int pci_bus_update_busn_res_end(struct pci_bus *b, 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);
|
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_bus *pci_scan_root_bus(struct device *parent, int bus,
|
||||||
struct pci_ops *ops, void *sysdata,
|
struct pci_ops *ops, void *sysdata,
|
||||||
struct list_head *resources);
|
struct list_head *resources);
|
||||||
|
Loading…
Reference in New Issue
Block a user