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:
Bjorn Helgaas 2015-08-28 15:53:08 -05:00
commit 9ca678d1df
16 changed files with 149 additions and 130 deletions

View File

@ -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 */

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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.

View File

@ -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);