Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci: (80 commits) x86/PCI: Expand the x86_msi_ops to have a restore MSIs. PCI: Increase resource array mask bit size in pcim_iomap_regions() PCI: DEVICE_COUNT_RESOURCE should be equal to PCI_NUM_RESOURCES PCI: pci_ids: add device ids for STA2X11 device (aka ConneXT) PNP: work around Dell 1536/1546 BIOS MMCONFIG bug that breaks USB x86/PCI: amd: factor out MMCONFIG discovery PCI: Enable ATS at the device state restore PCI: msi: fix imbalanced refcount of msi irq sysfs objects PCI: kconfig: English typo in pci/pcie/Kconfig PCI/PM/Runtime: make PCI traces quieter PCI: remove pci_create_bus() xtensa/PCI: convert to pci_scan_root_bus() for correct root bus resources x86/PCI: convert to pci_create_root_bus() and pci_scan_root_bus() x86/PCI: use pci_scan_bus() instead of pci_scan_bus_parented() x86/PCI: read Broadcom CNB20LE host bridge info before PCI scan sparc32, leon/PCI: convert to pci_scan_root_bus() for correct root bus resources sparc/PCI: convert to pci_create_root_bus() sh/PCI: convert to pci_scan_root_bus() for correct root bus resources powerpc/PCI: convert to pci_create_root_bus() powerpc/PCI: split PHB part out of pcibios_map_io_space() ... Fix up conflicts in drivers/pci/msi.c and include/linux/pci_regs.h due to the same patches being applied in other branches.
This commit is contained in:
Коммит
7b67e75147
|
@ -544,3 +544,15 @@ When: 3.5
|
|||
Why: The iwlagn module has been renamed iwlwifi. The alias will be around
|
||||
for backward compatibility for several cycles and then dropped.
|
||||
Who: Don Fry <donald.h.fry@intel.com>
|
||||
|
||||
----------------------------
|
||||
|
||||
What: pci_scan_bus_parented()
|
||||
When: 3.5
|
||||
Why: The pci_scan_bus_parented() interface creates a new root bus. The
|
||||
bus is created with default resources (ioport_resource and
|
||||
iomem_resource) that are always wrong, so we rely on arch code to
|
||||
correct them later. Callers of pci_scan_bus_parented() should
|
||||
convert to using pci_scan_root_bus() so they can supply a list of
|
||||
bus resources when the bus is created.
|
||||
Who: Bjorn Helgaas <bhelgaas@google.com>
|
||||
|
|
|
@ -281,27 +281,9 @@ pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
|
|||
void __devinit
|
||||
pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
/* Propagate hose info into the subordinate devices. */
|
||||
|
||||
struct pci_controller *hose = bus->sysdata;
|
||||
struct pci_dev *dev = bus->self;
|
||||
|
||||
if (!dev) {
|
||||
/* Root bus. */
|
||||
u32 pci_mem_end;
|
||||
u32 sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0;
|
||||
unsigned long end;
|
||||
|
||||
bus->resource[0] = hose->io_space;
|
||||
bus->resource[1] = hose->mem_space;
|
||||
|
||||
/* Adjust hose mem_space limit to prevent PCI allocations
|
||||
in the iommu windows. */
|
||||
pci_mem_end = min((u32)__direct_map_base, sg_base) - 1;
|
||||
end = hose->mem_space->start + pci_mem_end;
|
||||
if (hose->mem_space->end > end)
|
||||
hose->mem_space->end = end;
|
||||
} else if (pci_probe_only &&
|
||||
if (pci_probe_only && dev &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
pci_read_bridge_bases(bus);
|
||||
pcibios_fixup_device_resources(dev, bus);
|
||||
|
@ -414,13 +396,31 @@ void __init
|
|||
common_init_pci(void)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
struct list_head resources;
|
||||
struct pci_bus *bus;
|
||||
int next_busno;
|
||||
int need_domain_info = 0;
|
||||
u32 pci_mem_end;
|
||||
u32 sg_base;
|
||||
unsigned long end;
|
||||
|
||||
/* Scan all of the recorded PCI controllers. */
|
||||
for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
|
||||
bus = pci_scan_bus(next_busno, alpha_mv.pci_ops, hose);
|
||||
sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0;
|
||||
|
||||
/* Adjust hose mem_space limit to prevent PCI allocations
|
||||
in the iommu windows. */
|
||||
pci_mem_end = min((u32)__direct_map_base, sg_base) - 1;
|
||||
end = hose->mem_space->start + pci_mem_end;
|
||||
if (hose->mem_space->end > end)
|
||||
hose->mem_space->end = end;
|
||||
|
||||
INIT_LIST_HEAD(&resources);
|
||||
pci_add_resource(&resources, hose->io_space);
|
||||
pci_add_resource(&resources, hose->mem_space);
|
||||
|
||||
bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops,
|
||||
hose, &resources);
|
||||
hose->bus = bus;
|
||||
hose->need_domain_info = need_domain_info;
|
||||
next_busno = bus->subordinate + 1;
|
||||
|
|
|
@ -299,8 +299,8 @@ int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
goto err1;
|
||||
}
|
||||
|
||||
sys->resource[0] = &it8152_io;
|
||||
sys->resource[1] = &it8152_mem;
|
||||
pci_add_resource(&sys->resources, &it8152_io);
|
||||
pci_add_resource(&sys->resources, &it8152_mem);
|
||||
|
||||
if (platform_notify || platform_notify_remove) {
|
||||
printk(KERN_ERR "PCI: Can't use platform_notify\n");
|
||||
|
@ -327,6 +327,9 @@ err0:
|
|||
*/
|
||||
unsigned int pcibios_max_latency = 255;
|
||||
|
||||
/* ITE bridge requires setting latency timer to avoid early bus access
|
||||
termination by PCI bus master devices
|
||||
*/
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
u8 lat;
|
||||
|
@ -352,7 +355,7 @@ void pcibios_set_master(struct pci_dev *dev)
|
|||
|
||||
struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(nr, &it8152_ops, sys);
|
||||
return pci_scan_root_bus(NULL, nr, &it8152_ops, sys, &sys->resources);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dma_set_coherent_mask);
|
||||
|
|
|
@ -86,7 +86,8 @@ int __init via82c505_setup(int nr, struct pci_sys_data *sys)
|
|||
struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata)
|
||||
{
|
||||
if (nr == 0)
|
||||
return pci_scan_bus(0, &via82c505_ops, sysdata);
|
||||
return pci_scan_root_bus(NULL, 0, &via82c505_ops, sysdata,
|
||||
&sysdata->resources);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ struct pci_sys_data {
|
|||
u64 mem_offset; /* bus->cpu memory mapping offset */
|
||||
unsigned long io_offset; /* bus->cpu IO mapping offset */
|
||||
struct pci_bus *bus; /* PCI bus */
|
||||
struct resource *resource[3]; /* Primary PCI bus resources */
|
||||
struct list_head resources; /* root bus resources (apertures) */
|
||||
/* Bridge swizzling */
|
||||
u8 (*swizzle)(struct pci_dev *, u8 *);
|
||||
/* IRQ mapping */
|
||||
|
|
|
@ -31,18 +31,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
|
|||
}
|
||||
#endif /* CONFIG_PCI_DOMAINS */
|
||||
|
||||
#ifdef CONFIG_PCI_HOST_ITE8152
|
||||
/* ITE bridge requires setting latency timer to avoid early bus access
|
||||
termination by PIC bus mater devices
|
||||
*/
|
||||
extern void pcibios_set_master(struct pci_dev *dev);
|
||||
#else
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
|
|
|
@ -316,21 +316,6 @@ pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void __devinit
|
||||
pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
|
||||
{
|
||||
struct pci_dev *dev = bus->self;
|
||||
int i;
|
||||
|
||||
if (!dev) {
|
||||
/*
|
||||
* Assign root bus resources.
|
||||
*/
|
||||
for (i = 0; i < 3; i++)
|
||||
bus->resource[i] = root->resource[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pcibios_fixup_bus - Called after each bus is probed,
|
||||
* but before its children are examined.
|
||||
|
@ -341,8 +326,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
|
|||
struct pci_dev *dev;
|
||||
u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK;
|
||||
|
||||
pbus_assign_bus_resources(bus, root);
|
||||
|
||||
/*
|
||||
* Walk the devices on this bus, working out what we can
|
||||
* and can't support.
|
||||
|
@ -508,12 +491,18 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
|
|||
sys->busnr = busnr;
|
||||
sys->swizzle = hw->swizzle;
|
||||
sys->map_irq = hw->map_irq;
|
||||
sys->resource[0] = &ioport_resource;
|
||||
sys->resource[1] = &iomem_resource;
|
||||
INIT_LIST_HEAD(&sys->resources);
|
||||
|
||||
ret = hw->setup(nr, sys);
|
||||
|
||||
if (ret > 0) {
|
||||
if (list_empty(&sys->resources)) {
|
||||
pci_add_resource(&sys->resources,
|
||||
&ioport_resource);
|
||||
pci_add_resource(&sys->resources,
|
||||
&iomem_resource);
|
||||
}
|
||||
|
||||
sys->bus = hw->scan(nr, sys);
|
||||
|
||||
if (!sys->bus)
|
||||
|
@ -571,6 +560,13 @@ void __init pci_common_init(struct hw_pci *hw)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PCI_HOST_ITE8152
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
#endif
|
||||
|
||||
char * __init pcibios_setup(char *str)
|
||||
{
|
||||
if (!strcmp(str, "debug")) {
|
||||
|
|
|
@ -151,13 +151,12 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
struct cns3xxx_pcie *cnspci = sysdata_to_cnspci(sys);
|
||||
struct resource *res_io = &cnspci->res_io;
|
||||
struct resource *res_mem = &cnspci->res_mem;
|
||||
struct resource **sysres = sys->resource;
|
||||
|
||||
BUG_ON(request_resource(&iomem_resource, res_io) ||
|
||||
request_resource(&iomem_resource, res_mem));
|
||||
|
||||
sysres[0] = res_io;
|
||||
sysres[1] = res_mem;
|
||||
pci_add_resource(&sys->resources, res_io);
|
||||
pci_add_resource(&sys->resources, res_mem);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -169,7 +168,8 @@ static struct pci_ops cns3xxx_pcie_ops = {
|
|||
|
||||
static struct pci_bus *cns3xxx_pci_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(sys->busnr, &cns3xxx_pcie_ops, sys);
|
||||
return pci_scan_root_bus(NULL, sys->busnr, &cns3xxx_pcie_ops, sys,
|
||||
&sys->resources);
|
||||
}
|
||||
|
||||
static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
|
|
|
@ -69,7 +69,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
|
|||
pp->res[0].flags = IORESOURCE_IO;
|
||||
if (request_resource(&ioport_resource, &pp->res[0]))
|
||||
panic("Request PCIe IO resource failed\n");
|
||||
sys->resource[0] = &pp->res[0];
|
||||
pci_add_resource(&sys->resources, &pp->res[0]);
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM
|
||||
|
@ -88,9 +88,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
|
|||
pp->res[1].flags = IORESOURCE_MEM;
|
||||
if (request_resource(&iomem_resource, &pp->res[1]))
|
||||
panic("Request PCIe Memory resource failed\n");
|
||||
sys->resource[1] = &pp->res[1];
|
||||
|
||||
sys->resource[2] = NULL;
|
||||
pci_add_resource(&sys->resources, &pp->res[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -184,7 +182,8 @@ dove_pcie_scan_bus(int nr, struct pci_sys_data *sys)
|
|||
struct pci_bus *bus;
|
||||
|
||||
if (nr < num_pcie_ports) {
|
||||
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
|
||||
bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
|
||||
&sys->resources);
|
||||
} else {
|
||||
bus = NULL;
|
||||
BUG();
|
||||
|
|
|
@ -275,9 +275,9 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys)
|
|||
allocate_resource(&iomem_resource, &res[0], 0x40000000,
|
||||
0x80000000, 0xffffffff, 0x40000000, NULL, NULL);
|
||||
|
||||
sys->resource[0] = &ioport_resource;
|
||||
sys->resource[1] = &res[0];
|
||||
sys->resource[2] = &res[1];
|
||||
pci_add_resource(&sys->resources, &ioport_resource);
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
sys->mem_offset = DC21285_PCI_MEM;
|
||||
|
||||
return 1;
|
||||
|
@ -285,7 +285,7 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys)
|
|||
|
||||
struct pci_bus * __init dc21285_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(0, &dc21285_ops, sys);
|
||||
return pci_scan_root_bus(NULL, 0, &dc21285_ops, sys, &sys->resources);
|
||||
}
|
||||
|
||||
#define dc21285_request_irq(_a, _b, _c, _d, _e) \
|
||||
|
|
|
@ -359,7 +359,7 @@ static struct resource pre_mem = {
|
|||
.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
|
||||
};
|
||||
|
||||
static int __init pci_v3_setup_resources(struct resource **resource)
|
||||
static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
|
||||
{
|
||||
if (request_resource(&iomem_resource, &non_mem)) {
|
||||
printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
|
||||
|
@ -374,13 +374,13 @@ static int __init pci_v3_setup_resources(struct resource **resource)
|
|||
}
|
||||
|
||||
/*
|
||||
* bus->resource[0] is the IO resource for this bus
|
||||
* bus->resource[1] is the mem resource for this bus
|
||||
* bus->resource[2] is the prefetch mem resource for this bus
|
||||
* the IO resource for this bus
|
||||
* the mem resource for this bus
|
||||
* the prefetch mem resource for this bus
|
||||
*/
|
||||
resource[0] = &ioport_resource;
|
||||
resource[1] = &non_mem;
|
||||
resource[2] = &pre_mem;
|
||||
pci_add_resource(&sys->resources, &ioport_resource);
|
||||
pci_add_resource(&sys->resources, &non_mem);
|
||||
pci_add_resource(&sys->resources, &pre_mem);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -481,7 +481,7 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
|
|||
|
||||
if (nr == 0) {
|
||||
sys->mem_offset = PHYS_PCI_MEM_BASE;
|
||||
ret = pci_v3_setup_resources(sys->resource);
|
||||
ret = pci_v3_setup_resources(sys);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -489,7 +489,8 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
|
|||
|
||||
struct pci_bus * __init pci_v3_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(sys->busnr, &pci_v3_ops, sys);
|
||||
return pci_scan_root_bus(NULL, sys->busnr, &pci_v3_ops, sys,
|
||||
&sys->resources);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -537,14 +537,14 @@ struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *sys)
|
|||
while(time_before(jiffies, atux_trhfa_timeout))
|
||||
udelay(100);
|
||||
|
||||
bus = pci_bus_atux = pci_scan_bus(sys->busnr,
|
||||
&iop13xx_atux_ops,
|
||||
sys);
|
||||
bus = pci_bus_atux = pci_scan_root_bus(NULL, sys->busnr,
|
||||
&iop13xx_atux_ops,
|
||||
sys, &sys->resources);
|
||||
break;
|
||||
case IOP13XX_INIT_ATU_ATUE:
|
||||
bus = pci_bus_atue = pci_scan_bus(sys->busnr,
|
||||
&iop13xx_atue_ops,
|
||||
sys);
|
||||
bus = pci_bus_atue = pci_scan_root_bus(NULL, sys->busnr,
|
||||
&iop13xx_atue_ops,
|
||||
sys, &sys->resources);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1084,9 +1084,8 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
request_resource(&ioport_resource, &res[0]);
|
||||
request_resource(&iomem_resource, &res[1]);
|
||||
|
||||
sys->resource[0] = &res[0];
|
||||
sys->resource[1] = &res[1];
|
||||
sys->resource[2] = NULL;
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -145,7 +145,8 @@ static struct pci_ops enp2611_pci_ops = {
|
|||
static struct pci_bus * __init enp2611_pci_scan_bus(int nr,
|
||||
struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(sys->busnr, &enp2611_pci_ops, sys);
|
||||
return pci_scan_root_bus(NULL, sys->busnr, &enp2611_pci_ops, sys,
|
||||
&sys->resources);
|
||||
}
|
||||
|
||||
static int __init enp2611_pci_map_irq(const struct pci_dev *dev, u8 slot,
|
||||
|
|
|
@ -132,7 +132,8 @@ static struct pci_ops ixp2000_pci_ops = {
|
|||
|
||||
struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
|
||||
{
|
||||
return pci_scan_bus(sysdata->busnr, &ixp2000_pci_ops, sysdata);
|
||||
return pci_scan_root_bus(NULL, sysdata->busnr, &ixp2000_pci_ops,
|
||||
sysdata, &sysdata->resources);
|
||||
}
|
||||
|
||||
|
||||
|
@ -242,9 +243,8 @@ int ixp2000_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
if (nr >= 1)
|
||||
return 0;
|
||||
|
||||
sys->resource[0] = &ixp2000_pci_io_space;
|
||||
sys->resource[1] = &ixp2000_pci_mem_space;
|
||||
sys->resource[2] = NULL;
|
||||
pci_add_resource(&sys->resources, &ixp2000_pci_io_space);
|
||||
pci_add_resource(&sys->resources, &ixp2000_pci_mem_space);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -143,7 +143,8 @@ struct pci_ops ixp23xx_pci_ops = {
|
|||
|
||||
struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
|
||||
{
|
||||
return pci_scan_bus(sysdata->busnr, &ixp23xx_pci_ops, sysdata);
|
||||
return pci_scan_root_bus(NULL, sysdata->busnr, &ixp23xx_pci_ops,
|
||||
sysdata, &sysdata->resources);
|
||||
}
|
||||
|
||||
int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
||||
|
@ -280,9 +281,8 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
if (nr >= 1)
|
||||
return 0;
|
||||
|
||||
sys->resource[0] = &ixp23xx_pci_io_space;
|
||||
sys->resource[1] = &ixp23xx_pci_mem_space;
|
||||
sys->resource[2] = NULL;
|
||||
pci_add_resource(&sys->resources, &ixp23xx_pci_io_space);
|
||||
pci_add_resource(&sys->resources, &ixp23xx_pci_mem_space);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -472,9 +472,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
|
|||
request_resource(&ioport_resource, &res[0]);
|
||||
request_resource(&iomem_resource, &res[1]);
|
||||
|
||||
sys->resource[0] = &res[0];
|
||||
sys->resource[1] = &res[1];
|
||||
sys->resource[2] = NULL;
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
|
||||
platform_notify = ixp4xx_pci_platform_notify;
|
||||
platform_notify_remove = ixp4xx_pci_platform_notify_remove;
|
||||
|
@ -484,7 +483,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
|
|||
|
||||
struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
|
||||
return pci_scan_root_bus(NULL, sys->busnr, &ixp4xx_ops, sys,
|
||||
&sys->resources);
|
||||
}
|
||||
|
||||
int dma_set_coherent_mask(struct device *dev, u64 mask)
|
||||
|
|
|
@ -198,9 +198,8 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
|
|||
if (request_resource(&iomem_resource, &pp->res[1]))
|
||||
panic("Request PCIe%d Memory resource failed\n", index);
|
||||
|
||||
sys->resource[0] = &pp->res[0];
|
||||
sys->resource[1] = &pp->res[1];
|
||||
sys->resource[2] = NULL;
|
||||
pci_add_resource(&sys->resources, &pp->res[0]);
|
||||
pci_add_resource(&sys->resources, &pp->res[1]);
|
||||
sys->io_offset = 0;
|
||||
|
||||
/*
|
||||
|
@ -236,7 +235,8 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
|
|||
struct pci_bus *bus;
|
||||
|
||||
if (nr < num_pcie_ports) {
|
||||
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
|
||||
bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
|
||||
&sys->resources);
|
||||
} else {
|
||||
bus = NULL;
|
||||
BUG();
|
||||
|
|
|
@ -143,7 +143,8 @@ static struct pci_ops ks8695_pci_ops = {
|
|||
|
||||
static struct pci_bus* __init ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(sys->busnr, &ks8695_pci_ops, sys);
|
||||
return pci_scan_root_bus(NULL, sys->busnr, &ks8695_pci_ops, sys,
|
||||
&sys->resources);
|
||||
}
|
||||
|
||||
static struct resource pci_mem = {
|
||||
|
@ -168,9 +169,8 @@ static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
request_resource(&iomem_resource, &pci_mem);
|
||||
request_resource(&ioport_resource, &pci_io);
|
||||
|
||||
sys->resource[0] = &pci_io;
|
||||
sys->resource[1] = &pci_mem;
|
||||
sys->resource[2] = NULL;
|
||||
pci_add_resource(&sys->resources, &pci_io);
|
||||
pci_add_resource(&sys->resources, &pci_mem);
|
||||
|
||||
/* Assign and enable processor bridge */
|
||||
ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA);
|
||||
|
|
|
@ -155,9 +155,8 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
|
|||
orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
|
||||
orion_pcie_setup(pp->base);
|
||||
|
||||
sys->resource[0] = &pp->res[0];
|
||||
sys->resource[1] = &pp->res[1];
|
||||
sys->resource[2] = NULL;
|
||||
pci_add_resource(&sys->resources, &pp->res[0]);
|
||||
pci_add_resource(&sys->resources, &pp->res[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -251,7 +250,8 @@ mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys)
|
|||
struct pci_bus *bus;
|
||||
|
||||
if (nr < num_pcie_ports) {
|
||||
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
|
||||
bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
|
||||
&sys->resources);
|
||||
} else {
|
||||
bus = NULL;
|
||||
BUG();
|
||||
|
|
|
@ -177,7 +177,7 @@ static int __init pcie_setup(struct pci_sys_data *sys)
|
|||
res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1;
|
||||
if (request_resource(&ioport_resource, &res[0]))
|
||||
panic("Request PCIe IO resource failed\n");
|
||||
sys->resource[0] = &res[0];
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM
|
||||
|
@ -188,9 +188,8 @@ static int __init pcie_setup(struct pci_sys_data *sys)
|
|||
res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1;
|
||||
if (request_resource(&iomem_resource, &res[1]))
|
||||
panic("Request PCIe Memory resource failed\n");
|
||||
sys->resource[1] = &res[1];
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
|
||||
sys->resource[2] = NULL;
|
||||
sys->io_offset = 0;
|
||||
|
||||
return 1;
|
||||
|
@ -506,7 +505,7 @@ static int __init pci_setup(struct pci_sys_data *sys)
|
|||
res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1;
|
||||
if (request_resource(&ioport_resource, &res[0]))
|
||||
panic("Request PCI IO resource failed\n");
|
||||
sys->resource[0] = &res[0];
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM
|
||||
|
@ -517,9 +516,8 @@ static int __init pci_setup(struct pci_sys_data *sys)
|
|||
res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1;
|
||||
if (request_resource(&iomem_resource, &res[1]))
|
||||
panic("Request PCI Memory resource failed\n");
|
||||
sys->resource[1] = &res[1];
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
|
||||
sys->resource[2] = NULL;
|
||||
sys->io_offset = 0;
|
||||
|
||||
return 1;
|
||||
|
@ -580,9 +578,11 @@ struct pci_bus __init *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys
|
|||
struct pci_bus *bus;
|
||||
|
||||
if (nr == 0) {
|
||||
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
|
||||
bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
|
||||
&sys->resources);
|
||||
} else if (nr == 1 && !orion5x_pci_disabled) {
|
||||
bus = pci_scan_bus(sys->busnr, &pci_ops, sys);
|
||||
bus = pci_scan_root_bus(NULL, sys->busnr, &pci_ops, sys,
|
||||
&sys->resources);
|
||||
} else {
|
||||
bus = NULL;
|
||||
BUG();
|
||||
|
|
|
@ -131,7 +131,8 @@ static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot,
|
|||
|
||||
struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(sys->busnr, &pci_nano_ops, sys);
|
||||
return pci_scan_root_bus(NULL, sys->busnr, &pci_nano_ops, sys,
|
||||
&sys->resources);
|
||||
}
|
||||
|
||||
static struct resource pci_io_ports = {
|
||||
|
@ -226,7 +227,7 @@ static struct resource pci_prefetchable_memory = {
|
|||
.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
|
||||
};
|
||||
|
||||
static int __init pci_nanoengine_setup_resources(struct resource **resource)
|
||||
static int __init pci_nanoengine_setup_resources(struct pci_sys_data *sys)
|
||||
{
|
||||
if (request_resource(&ioport_resource, &pci_io_ports)) {
|
||||
printk(KERN_ERR "PCI: unable to allocate io port region\n");
|
||||
|
@ -243,9 +244,9 @@ static int __init pci_nanoengine_setup_resources(struct resource **resource)
|
|||
printk(KERN_ERR "PCI: unable to allocate prefetchable\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
resource[0] = &pci_io_ports;
|
||||
resource[1] = &pci_non_prefetchable_memory;
|
||||
resource[2] = &pci_prefetchable_memory;
|
||||
pci_add_resource(&sys->resources, &pci_io_ports);
|
||||
pci_add_resource(&sys->resources, &pci_non_prefetchable_memory);
|
||||
pci_add_resource(&sys->resources, &pci_prefetchable_memory);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -260,7 +261,7 @@ int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys)
|
|||
if (nr == 0) {
|
||||
sys->mem_offset = NANO_PCI_MEM_RW_PHYS;
|
||||
sys->io_offset = 0x400;
|
||||
ret = pci_nanoengine_setup_resources(sys->resource);
|
||||
ret = pci_nanoengine_setup_resources(sys);
|
||||
/* Enable alternate memory bus master mode, see
|
||||
* "Intel StrongARM SA1110 Developer's Manual",
|
||||
* section 10.8, "Alternate Memory Bus Master Mode". */
|
||||
|
|
|
@ -408,7 +408,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
|
|||
pp->res[0].flags = IORESOURCE_IO;
|
||||
if (request_resource(&ioport_resource, &pp->res[0]))
|
||||
panic("Request PCIe IO resource failed\n");
|
||||
sys->resource[0] = &pp->res[0];
|
||||
pci_add_resource(&sys->resources, &pp->res[0]);
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM
|
||||
|
@ -427,7 +427,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
|
|||
pp->res[1].flags = IORESOURCE_MEM;
|
||||
if (request_resource(&iomem_resource, &pp->res[1]))
|
||||
panic("Request PCIe Memory resource failed\n");
|
||||
sys->resource[1] = &pp->res[1];
|
||||
pci_add_resource(&sys->resources, &pp->res[1]);
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM | IORESOURCE_PREFETCH
|
||||
|
@ -446,7 +446,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
|
|||
pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
|
||||
if (request_resource(&iomem_resource, &pp->res[2]))
|
||||
panic("Request PCIe Prefetch Memory resource failed\n");
|
||||
sys->resource[2] = &pp->res[2];
|
||||
pci_add_resource(&sys->resources, &pp->res[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -467,7 +467,8 @@ static struct pci_bus __init *tegra_pcie_scan_bus(int nr,
|
|||
pp = tegra_pcie.port + nr;
|
||||
pp->root_bus_nr = sys->busnr;
|
||||
|
||||
return pci_scan_bus(sys->busnr, &tegra_pcie_ops, sys);
|
||||
return pci_scan_root_bus(NULL, sys->busnr, &tegra_pcie_ops, sys,
|
||||
&sys->resources);
|
||||
}
|
||||
|
||||
static struct hw_pci tegra_pcie_hw __initdata = {
|
||||
|
|
|
@ -191,7 +191,7 @@ static struct resource pre_mem = {
|
|||
.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
|
||||
};
|
||||
|
||||
static int __init pci_versatile_setup_resources(struct resource **resource)
|
||||
static int __init pci_versatile_setup_resources(struct list_head *resources)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -215,13 +215,13 @@ static int __init pci_versatile_setup_resources(struct resource **resource)
|
|||
}
|
||||
|
||||
/*
|
||||
* bus->resource[0] is the IO resource for this bus
|
||||
* bus->resource[1] is the mem resource for this bus
|
||||
* bus->resource[2] is the prefetch mem resource for this bus
|
||||
* the IO resource for this bus
|
||||
* the mem resource for this bus
|
||||
* the prefetch mem resource for this bus
|
||||
*/
|
||||
resource[0] = &io_mem;
|
||||
resource[1] = &non_mem;
|
||||
resource[2] = &pre_mem;
|
||||
pci_add_resource(resources, &io_mem);
|
||||
pci_add_resource(resources, &non_mem);
|
||||
pci_add_resource(resources, &pre_mem);
|
||||
|
||||
goto out;
|
||||
|
||||
|
@ -250,7 +250,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
|
|||
|
||||
if (nr == 0) {
|
||||
sys->mem_offset = 0;
|
||||
ret = pci_versatile_setup_resources(sys->resource);
|
||||
ret = pci_versatile_setup_resources(&sys->resources);
|
||||
if (ret < 0) {
|
||||
printk("pci_versatile_setup: resources... oops?\n");
|
||||
goto out;
|
||||
|
@ -306,7 +306,8 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
|
|||
|
||||
struct pci_bus * __init pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
|
||||
return pci_scan_root_bus(NULL, sys->busnr, &pci_versatile_ops, sys,
|
||||
&sys->resources);
|
||||
}
|
||||
|
||||
void __init pci_versatile_preinit(void)
|
||||
|
|
|
@ -215,16 +215,16 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0;
|
||||
sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR;
|
||||
|
||||
sys->resource[0] = &res[0];
|
||||
sys->resource[1] = &res[1];
|
||||
sys->resource[2] = NULL;
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
return pci_scan_bus(sys->busnr, &iop3xx_ops, sys);
|
||||
return pci_scan_root_bus(NULL, sys->busnr, &iop3xx_ops, sys,
|
||||
&sys->resources);
|
||||
}
|
||||
|
||||
void __init iop3xx_atu_setup(void)
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
#define PCIBIOS_MIN_IO 0x00001000
|
||||
#define PCIBIOS_MIN_MEM 0x10000000
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
static inline void pcibios_penalize_isa_irq(int irq)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
|
|
|
@ -194,23 +194,3 @@ void __init pcibios_resource_survey(void)
|
|||
pcibios_allocate_resources(1);
|
||||
pcibios_assign_resources();
|
||||
}
|
||||
|
||||
/*
|
||||
* If we set up a device for bus mastering, we need to check the latency
|
||||
* timer as certain crappy BIOSes forget to set it properly.
|
||||
*/
|
||||
unsigned int pcibios_max_latency = 255;
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
u8 lat;
|
||||
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
|
||||
if (lat < 16)
|
||||
lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
|
||||
else if (lat > pcibios_max_latency)
|
||||
lat = pcibios_max_latency;
|
||||
else
|
||||
return;
|
||||
printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@ extern unsigned int __nongpreldata pci_probe;
|
|||
|
||||
/* pci-frv.c */
|
||||
|
||||
extern unsigned int pcibios_max_latency;
|
||||
|
||||
void pcibios_resource_survey(void);
|
||||
|
||||
/* pci-vdk.c */
|
||||
|
|
|
@ -327,11 +327,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
|
|||
printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
|
||||
#endif
|
||||
|
||||
if (bus->number == 0) {
|
||||
bus->resource[0] = &pci_ioport_resource;
|
||||
bus->resource[1] = &pci_iomem_resource;
|
||||
}
|
||||
|
||||
pci_read_bridge_bases(bus);
|
||||
|
||||
if (bus->number == 0) {
|
||||
|
@ -357,6 +352,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
|
|||
int __init pcibios_init(void)
|
||||
{
|
||||
struct pci_ops *dir = NULL;
|
||||
LIST_HEAD(resources);
|
||||
|
||||
if (!mb93090_mb00_detected)
|
||||
return -ENXIO;
|
||||
|
@ -420,7 +416,10 @@ int __init pcibios_init(void)
|
|||
}
|
||||
|
||||
printk("PCI: Probing PCI hardware\n");
|
||||
pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
|
||||
pci_add_resource(&resources, &pci_ioport_resource);
|
||||
pci_add_resource(&resources, &pci_iomem_resource);
|
||||
pci_root_bus = pci_scan_root_bus(NULL, 0, pci_root_ops, NULL,
|
||||
&resources);
|
||||
|
||||
pcibios_irq_init();
|
||||
pcibios_fixup_peer_bridges();
|
||||
|
|
|
@ -9,11 +9,6 @@
|
|||
|
||||
#define pcibios_assign_all_busses() 0
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
|
|
|
@ -42,12 +42,6 @@ struct pci_dev;
|
|||
extern unsigned long ia64_max_iommu_merge_mask;
|
||||
#define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL)
|
||||
|
||||
static inline void
|
||||
pcibios_set_master (struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void
|
||||
pcibios_penalize_isa_irq (int irq, int active)
|
||||
{
|
||||
|
|
|
@ -134,6 +134,7 @@ alloc_pci_controller (int seg)
|
|||
struct pci_root_info {
|
||||
struct acpi_device *bridge;
|
||||
struct pci_controller *controller;
|
||||
struct list_head resources;
|
||||
char *name;
|
||||
};
|
||||
|
||||
|
@ -315,26 +316,15 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
|||
&window->resource);
|
||||
}
|
||||
|
||||
/* HP's firmware has a hack to work around a Windows bug.
|
||||
* Ignore these tiny memory ranges */
|
||||
if (!((window->resource.flags & IORESOURCE_MEM) &&
|
||||
(window->resource.end - window->resource.start < 16)))
|
||||
pci_add_resource(&info->resources, &window->resource);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static void __devinit
|
||||
pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
|
||||
{
|
||||
int i;
|
||||
|
||||
pci_bus_remove_resources(bus);
|
||||
for (i = 0; i < ctrl->windows; i++) {
|
||||
struct resource *res = &ctrl->window[i].resource;
|
||||
/* HP's firmware has a hack to work around a Windows bug.
|
||||
* Ignore these tiny memory ranges */
|
||||
if ((res->flags & IORESOURCE_MEM) &&
|
||||
(res->end - res->start < 16))
|
||||
continue;
|
||||
pci_bus_add_resource(bus, res, 0);
|
||||
}
|
||||
}
|
||||
|
||||
struct pci_bus * __devinit
|
||||
pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
{
|
||||
|
@ -343,6 +333,7 @@ pci_acpi_scan_root(struct acpi_pci_root *root)
|
|||
int bus = root->secondary.start;
|
||||
struct pci_controller *controller;
|
||||
unsigned int windows = 0;
|
||||
struct pci_root_info info;
|
||||
struct pci_bus *pbus;
|
||||
char *name;
|
||||
int pxm;
|
||||
|
@ -359,11 +350,10 @@ pci_acpi_scan_root(struct acpi_pci_root *root)
|
|||
controller->node = pxm_to_node(pxm);
|
||||
#endif
|
||||
|
||||
INIT_LIST_HEAD(&info.resources);
|
||||
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
|
||||
&windows);
|
||||
if (windows) {
|
||||
struct pci_root_info info;
|
||||
|
||||
controller->window =
|
||||
kmalloc_node(sizeof(*controller->window) * windows,
|
||||
GFP_KERNEL, controller->node);
|
||||
|
@ -387,8 +377,14 @@ pci_acpi_scan_root(struct acpi_pci_root *root)
|
|||
* should handle the case here, but it appears that IA64 hasn't
|
||||
* such quirk. So we just ignore the case now.
|
||||
*/
|
||||
pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
|
||||
pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
|
||||
&info.resources);
|
||||
if (!pbus) {
|
||||
pci_free_resource_list(&info.resources);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pbus->subordinate = pci_scan_child_bus(pbus);
|
||||
return pbus;
|
||||
|
||||
out3:
|
||||
|
@ -504,14 +500,15 @@ pcibios_fixup_bus (struct pci_bus *b)
|
|||
if (b->self) {
|
||||
pci_read_bridge_bases(b);
|
||||
pcibios_fixup_bridge_resources(b->self);
|
||||
} else {
|
||||
pcibios_setup_root_windows(b, b->sysdata);
|
||||
}
|
||||
list_for_each_entry(dev, &b->devices, bus_list)
|
||||
pcibios_fixup_device_resources(dev);
|
||||
platform_pci_fixup_bus(b);
|
||||
}
|
||||
|
||||
return;
|
||||
void pcibios_set_master (struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
void __devinit
|
||||
|
|
|
@ -140,7 +140,6 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
|||
/* Allocate & free a PCI host bridge structure */
|
||||
extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
|
||||
extern void pcibios_free_controller(struct pci_controller *phb);
|
||||
extern void pcibios_setup_phb_resources(struct pci_controller *hose);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_MICROBLAZE_PCI_BRIDGE_H */
|
||||
|
|
|
@ -42,11 +42,6 @@ struct pci_dev;
|
|||
*/
|
||||
#define pcibios_assign_all_busses() 0
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
|
|
|
@ -190,6 +190,11 @@ int pcibios_add_platform_entries(struct pci_dev *pdev)
|
|||
return device_create_file(&pdev->dev, &dev_attr_devspec);
|
||||
}
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
char __devinit *pcibios_setup(char *str)
|
||||
{
|
||||
return str;
|
||||
|
@ -1019,7 +1024,6 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
|
|||
struct pci_dev *dev = bus->self;
|
||||
|
||||
pci_bus_for_each_resource(bus, res, i) {
|
||||
res = bus->resource[i];
|
||||
if (!res)
|
||||
continue;
|
||||
if (!res->flags)
|
||||
|
@ -1219,7 +1223,6 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
|
|||
pci_domain_nr(bus), bus->number);
|
||||
|
||||
pci_bus_for_each_resource(bus, res, i) {
|
||||
res = bus->resource[i];
|
||||
if (!res || !res->flags
|
||||
|| res->start > res->end || res->parent)
|
||||
continue;
|
||||
|
@ -1510,14 +1513,18 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
|
||||
static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources)
|
||||
{
|
||||
struct pci_bus *bus = hose->bus;
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
/* Hookup PHB IO resource */
|
||||
bus->resource[0] = res = &hose->io_resource;
|
||||
res = &hose->io_resource;
|
||||
|
||||
/* Fixup IO space offset */
|
||||
io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
|
||||
res->start = (res->start + io_offset) & 0xffffffffu;
|
||||
res->end = (res->end + io_offset) & 0xffffffffu;
|
||||
|
||||
if (!res->flags) {
|
||||
printk(KERN_WARNING "PCI: I/O resource not set for host"
|
||||
|
@ -1528,6 +1535,7 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
|
|||
res->end = res->start + IO_SPACE_LIMIT;
|
||||
res->flags = IORESOURCE_IO;
|
||||
}
|
||||
pci_add_resource(resources, res);
|
||||
|
||||
pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n",
|
||||
(unsigned long long)res->start,
|
||||
|
@ -1550,7 +1558,7 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
|
|||
res->flags = IORESOURCE_MEM;
|
||||
|
||||
}
|
||||
bus->resource[i+1] = res;
|
||||
pci_add_resource(resources, res);
|
||||
|
||||
pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n",
|
||||
i, (unsigned long long)res->start,
|
||||
|
@ -1573,34 +1581,27 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
|
|||
|
||||
static void __devinit pcibios_scan_phb(struct pci_controller *hose)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *bus;
|
||||
struct device_node *node = hose->dn;
|
||||
unsigned long io_offset;
|
||||
struct resource *res = &hose->io_resource;
|
||||
|
||||
pr_debug("PCI: Scanning PHB %s\n",
|
||||
node ? node->full_name : "<NO NAME>");
|
||||
|
||||
/* Create an empty bus for the toplevel */
|
||||
bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
|
||||
pcibios_setup_phb_resources(hose, &resources);
|
||||
|
||||
bus = pci_scan_root_bus(hose->parent, hose->first_busno,
|
||||
hose->ops, hose, &resources);
|
||||
if (bus == NULL) {
|
||||
printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
|
||||
hose->global_number);
|
||||
pci_free_resource_list(&resources);
|
||||
return;
|
||||
}
|
||||
bus->secondary = hose->first_busno;
|
||||
hose->bus = bus;
|
||||
|
||||
/* Fixup IO space offset */
|
||||
io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
|
||||
res->start = (res->start + io_offset) & 0xffffffffu;
|
||||
res->end = (res->end + io_offset) & 0xffffffffu;
|
||||
|
||||
/* Wire up PHB bus resources */
|
||||
pcibios_setup_phb_resources(hose);
|
||||
|
||||
/* Scan children */
|
||||
hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
|
||||
hose->last_busno = bus->subordinate;
|
||||
}
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
|
@ -1614,8 +1615,6 @@ static int __init pcibios_init(void)
|
|||
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
|
||||
hose->last_busno = 0xff;
|
||||
pcibios_scan_phb(hose);
|
||||
printk(KERN_INFO "calling pci_bus_add_devices()\n");
|
||||
pci_bus_add_devices(hose->bus);
|
||||
if (next_busno <= hose->last_busno)
|
||||
next_busno = hose->last_busno + 1;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
|
|||
{
|
||||
static int next_busno;
|
||||
static int need_domain_info;
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *bus;
|
||||
|
||||
if (!hose->iommu)
|
||||
|
@ -89,7 +90,13 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
|
|||
if (hose->get_busno && pci_probe_only)
|
||||
next_busno = (*hose->get_busno)();
|
||||
|
||||
bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
|
||||
pci_add_resource(&resources, hose->mem_resource);
|
||||
pci_add_resource(&resources, hose->io_resource);
|
||||
bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
|
||||
&resources);
|
||||
if (!bus)
|
||||
pci_free_resource_list(&resources);
|
||||
|
||||
hose->bus = bus;
|
||||
|
||||
need_domain_info = need_domain_info || hose->index;
|
||||
|
@ -205,27 +212,6 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we set up a device for bus mastering, we need to check the latency
|
||||
* timer as certain crappy BIOSes forget to set it properly.
|
||||
*/
|
||||
static unsigned int pcibios_max_latency = 255;
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
u8 lat;
|
||||
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
|
||||
if (lat < 16)
|
||||
lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
|
||||
else if (lat > pcibios_max_latency)
|
||||
lat = pcibios_max_latency;
|
||||
else
|
||||
return;
|
||||
printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n",
|
||||
pci_name(dev), lat);
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
|
||||
}
|
||||
|
||||
unsigned int pcibios_assign_all_busses(void)
|
||||
{
|
||||
return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
|
||||
|
@ -266,15 +252,11 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
|||
{
|
||||
/* Propagate hose info into the subordinate devices. */
|
||||
|
||||
struct pci_controller *hose = bus->sysdata;
|
||||
struct list_head *ln;
|
||||
struct pci_dev *dev = bus->self;
|
||||
|
||||
if (!dev) {
|
||||
bus->resource[0] = hose->io_resource;
|
||||
bus->resource[1] = hose->mem_resource;
|
||||
} else if (pci_probe_only &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
if (pci_probe_only && dev &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
pci_read_bridge_bases(bus);
|
||||
pcibios_fixup_device_resources(dev, bus);
|
||||
}
|
||||
|
|
|
@ -213,28 +213,6 @@ void __init pcibios_resource_survey(void)
|
|||
pcibios_allocate_resources(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we set up a device for bus mastering, we need to check the latency
|
||||
* timer as certain crappy BIOSes forget to set it properly.
|
||||
*/
|
||||
unsigned int pcibios_max_latency = 255;
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
u8 lat;
|
||||
|
||||
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
|
||||
|
||||
if (lat < 16)
|
||||
lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
|
||||
else if (lat > pcibios_max_latency)
|
||||
lat = pcibios_max_latency;
|
||||
else
|
||||
return;
|
||||
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
|
||||
}
|
||||
|
||||
int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
enum pci_mmap_state mmap_state, int write_combine)
|
||||
{
|
||||
|
|
|
@ -31,8 +31,6 @@ extern unsigned int pci_probe;
|
|||
|
||||
/* pci-asb2305.c */
|
||||
|
||||
extern unsigned int pcibios_max_latency;
|
||||
|
||||
extern void pcibios_resource_survey(void);
|
||||
|
||||
/* pci.c */
|
||||
|
|
|
@ -380,11 +380,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
|||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
if (bus->number == 0) {
|
||||
bus->resource[0] = &pci_ioport_resource;
|
||||
bus->resource[1] = &pci_iomem_resource;
|
||||
}
|
||||
|
||||
if (bus->self) {
|
||||
pci_read_bridge_bases(bus);
|
||||
pcibios_fixup_device_resources(bus->self);
|
||||
|
@ -402,6 +397,8 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
|||
*/
|
||||
static int __init pcibios_init(void)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
|
||||
ioport_resource.start = 0xA0000000;
|
||||
ioport_resource.end = 0xDFFFFFFF;
|
||||
iomem_resource.start = 0xA0000000;
|
||||
|
@ -423,7 +420,10 @@ static int __init pcibios_init(void)
|
|||
printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n",
|
||||
MEM_PAGING_REG);
|
||||
|
||||
pci_root_bus = pci_scan_bus(0, &pci_direct_ampci, NULL);
|
||||
pci_add_resource(&resources, &pci_ioport_resource);
|
||||
pci_add_resource(&resources, &pci_iomem_resource);
|
||||
pci_root_bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL,
|
||||
&resources);
|
||||
|
||||
pcibios_irq_init();
|
||||
pcibios_fixup_irqs();
|
||||
|
|
|
@ -226,7 +226,6 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
|||
/* Allocate & free a PCI host bridge structure */
|
||||
extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
|
||||
extern void pcibios_free_controller(struct pci_controller *phb);
|
||||
extern void pcibios_setup_phb_resources(struct pci_controller *hose);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern int pcibios_vaddr_is_ioport(void __iomem *address);
|
||||
|
|
|
@ -46,11 +46,6 @@ struct pci_dev;
|
|||
#define pcibios_assign_all_busses() \
|
||||
(pci_has_flag(PCI_REASSIGN_ALL_BUS))
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
|
|
|
@ -1131,6 +1131,11 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
|
|||
}
|
||||
}
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
/* When called from the generic PCI probe, read PCI<->PCI bridge
|
||||
|
@ -1560,14 +1565,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
|
||||
static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources)
|
||||
{
|
||||
struct pci_bus *bus = hose->bus;
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
/* Hookup PHB IO resource */
|
||||
bus->resource[0] = res = &hose->io_resource;
|
||||
res = &hose->io_resource;
|
||||
|
||||
if (!res->flags) {
|
||||
printk(KERN_WARNING "PCI: I/O resource not set for host"
|
||||
|
@ -1585,6 +1589,7 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
|
|||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end,
|
||||
(unsigned long)res->flags);
|
||||
pci_add_resource(resources, res);
|
||||
|
||||
/* Hookup PHB Memory resources */
|
||||
for (i = 0; i < 3; ++i) {
|
||||
|
@ -1602,12 +1607,12 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
|
|||
res->flags = IORESOURCE_MEM;
|
||||
#endif /* CONFIG_PPC32 */
|
||||
}
|
||||
bus->resource[i+1] = res;
|
||||
|
||||
pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i,
|
||||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end,
|
||||
(unsigned long)res->flags);
|
||||
pci_add_resource(resources, res);
|
||||
}
|
||||
|
||||
pr_debug("PCI: PHB MEM offset = %016llx\n",
|
||||
|
@ -1701,6 +1706,7 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
|
|||
*/
|
||||
void __devinit pcibios_scan_phb(struct pci_controller *hose)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *bus;
|
||||
struct device_node *node = hose->dn;
|
||||
int mode;
|
||||
|
@ -1708,21 +1714,23 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
|
|||
pr_debug("PCI: Scanning PHB %s\n",
|
||||
node ? node->full_name : "<NO NAME>");
|
||||
|
||||
/* Create an empty bus for the toplevel */
|
||||
bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
|
||||
if (bus == NULL) {
|
||||
pr_err("Failed to create bus for PCI domain %04x\n",
|
||||
hose->global_number);
|
||||
return;
|
||||
}
|
||||
bus->secondary = hose->first_busno;
|
||||
hose->bus = bus;
|
||||
|
||||
/* Get some IO space for the new PHB */
|
||||
pcibios_setup_phb_io_space(hose);
|
||||
|
||||
/* Wire up PHB bus resources */
|
||||
pcibios_setup_phb_resources(hose);
|
||||
pcibios_setup_phb_resources(hose, &resources);
|
||||
|
||||
/* Create an empty bus for the toplevel */
|
||||
bus = pci_create_root_bus(hose->parent, hose->first_busno,
|
||||
hose->ops, hose, &resources);
|
||||
if (bus == NULL) {
|
||||
pr_err("Failed to create bus for PCI domain %04x\n",
|
||||
hose->global_number);
|
||||
pci_free_resource_list(&resources);
|
||||
return;
|
||||
}
|
||||
bus->secondary = hose->first_busno;
|
||||
hose->bus = bus;
|
||||
|
||||
/* Get probe mode and perform scan */
|
||||
mode = PCI_PROBE_NORMAL;
|
||||
|
|
|
@ -131,30 +131,13 @@ EXPORT_SYMBOL_GPL(pcibios_unmap_io_space);
|
|||
|
||||
#endif /* CONFIG_HOTPLUG */
|
||||
|
||||
int __devinit pcibios_map_io_space(struct pci_bus *bus)
|
||||
static int __devinit pcibios_map_phb_io_space(struct pci_controller *hose)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
unsigned long phys_page;
|
||||
unsigned long size_page;
|
||||
unsigned long io_virt_offset;
|
||||
struct pci_controller *hose;
|
||||
|
||||
WARN_ON(bus == NULL);
|
||||
|
||||
/* If this not a PHB, nothing to do, page tables still exist and
|
||||
* thus HPTEs will be faulted in when needed
|
||||
*/
|
||||
if (bus->self) {
|
||||
pr_debug("IO mapping for PCI-PCI bridge %s\n",
|
||||
pci_name(bus->self));
|
||||
pr_debug(" virt=0x%016llx...0x%016llx\n",
|
||||
bus->resource[0]->start + _IO_BASE,
|
||||
bus->resource[0]->end + _IO_BASE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the host bridge */
|
||||
hose = pci_bus_to_host(bus);
|
||||
phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
|
||||
size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE);
|
||||
|
||||
|
@ -198,11 +181,30 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __devinit pcibios_map_io_space(struct pci_bus *bus)
|
||||
{
|
||||
WARN_ON(bus == NULL);
|
||||
|
||||
/* If this not a PHB, nothing to do, page tables still exist and
|
||||
* thus HPTEs will be faulted in when needed
|
||||
*/
|
||||
if (bus->self) {
|
||||
pr_debug("IO mapping for PCI-PCI bridge %s\n",
|
||||
pci_name(bus->self));
|
||||
pr_debug(" virt=0x%016llx...0x%016llx\n",
|
||||
bus->resource[0]->start + _IO_BASE,
|
||||
bus->resource[0]->end + _IO_BASE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pcibios_map_phb_io_space(pci_bus_to_host(bus));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcibios_map_io_space);
|
||||
|
||||
void __devinit pcibios_setup_phb_io_space(struct pci_controller *hose)
|
||||
{
|
||||
pcibios_map_io_space(hose->bus);
|
||||
pcibios_map_phb_io_space(hose);
|
||||
}
|
||||
|
||||
#define IOBASE_BRIDGE_NUMBER 0
|
||||
|
|
|
@ -36,9 +36,15 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
|
|||
{
|
||||
static int next_busno;
|
||||
static int need_domain_info;
|
||||
LIST_HEAD(resources);
|
||||
int i;
|
||||
struct pci_bus *bus;
|
||||
|
||||
bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
|
||||
for (i = 0; i < hose->nr_resources; i++)
|
||||
pci_add_resource(&resources, hose->resources + i);
|
||||
|
||||
bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
|
||||
&resources);
|
||||
hose->bus = bus;
|
||||
|
||||
need_domain_info = need_domain_info || hose->index;
|
||||
|
@ -55,6 +61,8 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
|
|||
pci_bus_size_bridges(bus);
|
||||
pci_bus_assign_resources(bus);
|
||||
pci_enable_bridges(bus);
|
||||
} else {
|
||||
pci_free_resource_list(&resources);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,16 +170,8 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev,
|
|||
*/
|
||||
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev = bus->self;
|
||||
struct pci_dev *dev;
|
||||
struct list_head *ln;
|
||||
struct pci_channel *hose = bus->sysdata;
|
||||
|
||||
if (!dev) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hose->nr_resources; i++)
|
||||
bus->resource[i] = hose->resources + i;
|
||||
}
|
||||
|
||||
for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
|
||||
dev = pci_dev_b(ln);
|
||||
|
@ -243,27 +243,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we set up a device for bus mastering, we need to check and set
|
||||
* the latency timer as it may not be properly set.
|
||||
*/
|
||||
static unsigned int pcibios_max_latency = 255;
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
u8 lat;
|
||||
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
|
||||
if (lat < 16)
|
||||
lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
|
||||
else if (lat > pcibios_max_latency)
|
||||
lat = pcibios_max_latency;
|
||||
else
|
||||
return;
|
||||
printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n",
|
||||
pci_name(dev), lat);
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
|
||||
}
|
||||
|
||||
void __init pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
|
||||
#define PCI_IRQ_NONE 0xffffffff
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
|
||||
#define PCI_IRQ_NONE 0xffffffff
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
|
|
|
@ -19,22 +19,22 @@
|
|||
*/
|
||||
void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *root_bus;
|
||||
|
||||
root_bus = pci_scan_bus_parented(&ofdev->dev, 0, info->ops, info);
|
||||
pci_add_resource(&resources, &info->io_space);
|
||||
pci_add_resource(&resources, &info->mem_space);
|
||||
|
||||
root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info,
|
||||
&resources);
|
||||
if (root_bus) {
|
||||
root_bus->resource[0] = &info->io_space;
|
||||
root_bus->resource[1] = &info->mem_space;
|
||||
root_bus->resource[2] = NULL;
|
||||
|
||||
/* Init all PCI devices into PCI tree */
|
||||
pci_bus_add_devices(root_bus);
|
||||
|
||||
/* Setup IRQs of all devices using custom routines */
|
||||
pci_fixup_irqs(pci_common_swizzle, info->map_irq);
|
||||
|
||||
/* Assign devices with resources */
|
||||
pci_assign_unassigned_resources();
|
||||
} else {
|
||||
pci_free_resource_list(&resources);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,15 +83,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
|
|||
int i, has_io, has_mem;
|
||||
u16 cmd;
|
||||
|
||||
/* Generic PCI bus probing sets these to point at
|
||||
* &io{port,mem}_resouce which is wrong for us.
|
||||
*/
|
||||
if (pbus->self == NULL) {
|
||||
pbus->resource[0] = &info->io_space;
|
||||
pbus->resource[1] = &info->mem_space;
|
||||
pbus->resource[2] = NULL;
|
||||
}
|
||||
|
||||
list_for_each_entry(dev, &pbus->devices, bus_list) {
|
||||
/*
|
||||
* We can not rely on that the bootloader has enabled I/O
|
||||
|
|
|
@ -685,23 +685,25 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus)
|
|||
struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
|
||||
struct device *parent)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
struct device_node *node = pbm->op->dev.of_node;
|
||||
struct pci_bus *bus;
|
||||
|
||||
printk("PCI: Scanning PBM %s\n", node->full_name);
|
||||
|
||||
bus = pci_create_bus(parent, pbm->pci_first_busno, pbm->pci_ops, pbm);
|
||||
pci_add_resource(&resources, &pbm->io_space);
|
||||
pci_add_resource(&resources, &pbm->mem_space);
|
||||
bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
|
||||
pbm, &resources);
|
||||
if (!bus) {
|
||||
printk(KERN_ERR "Failed to create bus for %s\n",
|
||||
node->full_name);
|
||||
pci_free_resource_list(&resources);
|
||||
return NULL;
|
||||
}
|
||||
bus->secondary = pbm->pci_first_busno;
|
||||
bus->subordinate = pbm->pci_last_busno;
|
||||
|
||||
bus->resource[0] = &pbm->io_space;
|
||||
bus->resource[1] = &pbm->mem_space;
|
||||
|
||||
pci_of_scan_bus(pbm, node, bus);
|
||||
pci_bus_add_devices(bus);
|
||||
pci_bus_register_of_sysfs(bus);
|
||||
|
@ -711,13 +713,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
|
|||
|
||||
void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
|
||||
{
|
||||
struct pci_pbm_info *pbm = pbus->sysdata;
|
||||
|
||||
/* Generic PCI bus probing sets these to point at
|
||||
* &io{port,mem}_resouce which is wrong for us.
|
||||
*/
|
||||
pbus->resource[0] = &pbm->io_space;
|
||||
pbus->resource[1] = &pbm->mem_space;
|
||||
}
|
||||
|
||||
void pcibios_update_irq(struct pci_dev *pdev, int irq)
|
||||
|
@ -1083,6 +1078,11 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar,
|
|||
*end = rp->end - offset;
|
||||
}
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
{
|
||||
pci_dfl_cache_line_size = 64 >> 2;
|
||||
|
|
|
@ -76,13 +76,6 @@ static inline int pcibios_assign_all_busses(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* No special bus mastering setup handling.
|
||||
*/
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
}
|
||||
|
||||
#define PCIBIOS_MIN_MEM 0
|
||||
#define PCIBIOS_MIN_IO 0
|
||||
|
||||
|
|
|
@ -395,6 +395,11 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
|||
/* Nothing needs to be done. */
|
||||
}
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling. */
|
||||
}
|
||||
|
||||
/*
|
||||
* This can be called from the generic PCI layer, but doesn't need to
|
||||
* do anything.
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
#include <asm-generic/pci.h>
|
||||
#include <mach/hardware.h> /* for PCIBIOS_MIN_* */
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
|
|
|
@ -309,6 +309,11 @@ char * __devinit pcibios_setup(char *str)
|
|||
return str;
|
||||
}
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
/*
|
||||
* From arch/i386/kernel/pci-i386.c:
|
||||
*
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _ASM_X86_AMD_NB_H
|
||||
#define _ASM_X86_AMD_NB_H
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
struct amd_nb_bus_dev_range {
|
||||
|
@ -13,6 +14,7 @@ extern const struct pci_device_id amd_nb_misc_ids[];
|
|||
extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[];
|
||||
|
||||
extern bool early_is_amd_nb(u32 value);
|
||||
extern struct resource *amd_get_mmconfig_range(struct resource *res);
|
||||
extern int amd_cache_northbridges(void);
|
||||
extern void amd_flush_garts(void);
|
||||
extern int amd_numa_init(void);
|
||||
|
|
|
@ -112,19 +112,28 @@ static inline void x86_teardown_msi_irq(unsigned int irq)
|
|||
{
|
||||
x86_msi.teardown_msi_irq(irq);
|
||||
}
|
||||
static inline void x86_restore_msi_irqs(struct pci_dev *dev, int irq)
|
||||
{
|
||||
x86_msi.restore_msi_irqs(dev, irq);
|
||||
}
|
||||
#define arch_setup_msi_irqs x86_setup_msi_irqs
|
||||
#define arch_teardown_msi_irqs x86_teardown_msi_irqs
|
||||
#define arch_teardown_msi_irq x86_teardown_msi_irq
|
||||
#define arch_restore_msi_irqs x86_restore_msi_irqs
|
||||
/* implemented in arch/x86/kernel/apic/io_apic. */
|
||||
int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
|
||||
void native_teardown_msi_irq(unsigned int irq);
|
||||
void native_restore_msi_irqs(struct pci_dev *dev, int irq);
|
||||
/* default to the implementation in drivers/lib/msi.c */
|
||||
#define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
|
||||
#define HAVE_DEFAULT_MSI_RESTORE_IRQS
|
||||
void default_teardown_msi_irqs(struct pci_dev *dev);
|
||||
void default_restore_msi_irqs(struct pci_dev *dev, int irq);
|
||||
#else
|
||||
#define native_setup_msi_irqs NULL
|
||||
#define native_teardown_msi_irq NULL
|
||||
#define default_teardown_msi_irqs NULL
|
||||
#define default_restore_msi_irqs NULL
|
||||
#endif
|
||||
|
||||
#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
|
||||
|
|
|
@ -44,8 +44,6 @@ enum pci_bf_sort_state {
|
|||
|
||||
/* pci-i386.c */
|
||||
|
||||
extern unsigned int pcibios_max_latency;
|
||||
|
||||
void pcibios_resource_survey(void);
|
||||
void pcibios_set_cache_line_size(void);
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ static inline void arch_fix_phys_package_id(int num, u32 slot)
|
|||
}
|
||||
|
||||
struct pci_bus;
|
||||
void x86_pci_root_bus_res_quirks(struct pci_bus *b);
|
||||
void x86_pci_root_bus_resources(int bus, struct list_head *resources);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define mc_capable() ((boot_cpu_data.x86_max_cores > 1) && \
|
||||
|
|
|
@ -179,6 +179,7 @@ struct x86_msi_ops {
|
|||
int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
|
||||
void (*teardown_msi_irq)(unsigned int irq);
|
||||
void (*teardown_msi_irqs)(struct pci_dev *dev);
|
||||
void (*restore_msi_irqs)(struct pci_dev *dev, int irq);
|
||||
};
|
||||
|
||||
extern struct x86_init_ops x86_init;
|
||||
|
|
|
@ -119,6 +119,37 @@ bool __init early_is_amd_nb(u32 device)
|
|||
return false;
|
||||
}
|
||||
|
||||
struct resource *amd_get_mmconfig_range(struct resource *res)
|
||||
{
|
||||
u32 address;
|
||||
u64 base, msr;
|
||||
unsigned segn_busn_bits;
|
||||
|
||||
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
|
||||
return NULL;
|
||||
|
||||
/* assume all cpus from fam10h have mmconfig */
|
||||
if (boot_cpu_data.x86 < 0x10)
|
||||
return NULL;
|
||||
|
||||
address = MSR_FAM10H_MMIO_CONF_BASE;
|
||||
rdmsrl(address, msr);
|
||||
|
||||
/* mmconfig is not enabled */
|
||||
if (!(msr & FAM10H_MMIO_CONF_ENABLE))
|
||||
return NULL;
|
||||
|
||||
base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
|
||||
|
||||
segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
|
||||
FAM10H_MMIO_CONF_BUSRANGE_MASK;
|
||||
|
||||
res->flags = IORESOURCE_MEM;
|
||||
res->start = base;
|
||||
res->end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
int amd_get_subcaches(int cpu)
|
||||
{
|
||||
struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
|
||||
|
|
|
@ -115,4 +115,5 @@ struct x86_msi_ops x86_msi = {
|
|||
.setup_msi_irqs = native_setup_msi_irqs,
|
||||
.teardown_msi_irq = native_teardown_msi_irq,
|
||||
.teardown_msi_irqs = default_teardown_msi_irqs,
|
||||
.restore_msi_irqs = default_restore_msi_irqs,
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ struct pci_root_info {
|
|||
char *name;
|
||||
unsigned int res_num;
|
||||
struct resource *res;
|
||||
struct pci_bus *bus;
|
||||
struct list_head *resources;
|
||||
int busnum;
|
||||
};
|
||||
|
||||
|
@ -24,6 +24,12 @@ static int __init set_use_crs(const struct dmi_system_id *id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init set_nouse_crs(const struct dmi_system_id *id)
|
||||
{
|
||||
pci_use_crs = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id pci_use_crs_table[] __initconst = {
|
||||
/* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
|
||||
{
|
||||
|
@ -54,6 +60,29 @@ static const struct dmi_system_id pci_use_crs_table[] __initconst = {
|
|||
DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
|
||||
},
|
||||
},
|
||||
|
||||
/* Now for the blacklist.. */
|
||||
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=769657 */
|
||||
{
|
||||
.callback = set_nouse_crs,
|
||||
.ident = "Dell Studio 1557",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "A09"),
|
||||
},
|
||||
},
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=769657 */
|
||||
{
|
||||
.callback = set_nouse_crs,
|
||||
.ident = "Thinkpad SL510",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "2847DFG"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -149,7 +178,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
|
|||
struct acpi_resource_address64 addr;
|
||||
acpi_status status;
|
||||
unsigned long flags;
|
||||
u64 start, end;
|
||||
u64 start, orig_end, end;
|
||||
|
||||
status = resource_to_addr(acpi_res, &addr);
|
||||
if (!ACPI_SUCCESS(status))
|
||||
|
@ -165,7 +194,21 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
|
|||
return AE_OK;
|
||||
|
||||
start = addr.minimum + addr.translation_offset;
|
||||
end = addr.maximum + addr.translation_offset;
|
||||
orig_end = end = addr.maximum + addr.translation_offset;
|
||||
|
||||
/* Exclude non-addressable range or non-addressable portion of range */
|
||||
end = min(end, (u64)iomem_resource.end);
|
||||
if (end <= start) {
|
||||
dev_info(&info->bridge->dev,
|
||||
"host bridge window [%#llx-%#llx] "
|
||||
"(ignored, not CPU addressable)\n", start, orig_end);
|
||||
return AE_OK;
|
||||
} else if (orig_end != end) {
|
||||
dev_info(&info->bridge->dev,
|
||||
"host bridge window [%#llx-%#llx] "
|
||||
"([%#llx-%#llx] ignored, not CPU addressable)\n",
|
||||
start, orig_end, end + 1, orig_end);
|
||||
}
|
||||
|
||||
res = &info->res[info->res_num];
|
||||
res->name = info->name;
|
||||
|
@ -261,23 +304,20 @@ static void add_resources(struct pci_root_info *info)
|
|||
"ignoring host bridge window %pR (conflicts with %s %pR)\n",
|
||||
res, conflict->name, conflict);
|
||||
else
|
||||
pci_bus_add_resource(info->bus, res, 0);
|
||||
pci_add_resource(info->resources, res);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_current_resources(struct acpi_device *device, int busnum,
|
||||
int domain, struct pci_bus *bus)
|
||||
int domain, struct list_head *resources)
|
||||
{
|
||||
struct pci_root_info info;
|
||||
size_t size;
|
||||
|
||||
if (pci_use_crs)
|
||||
pci_bus_remove_resources(bus);
|
||||
|
||||
info.bridge = device;
|
||||
info.bus = bus;
|
||||
info.res_num = 0;
|
||||
info.resources = resources;
|
||||
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
|
||||
&info);
|
||||
if (!info.res_num)
|
||||
|
@ -286,7 +326,7 @@ get_current_resources(struct acpi_device *device, int busnum,
|
|||
size = sizeof(*info.res) * info.res_num;
|
||||
info.res = kmalloc(size, GFP_KERNEL);
|
||||
if (!info.res)
|
||||
goto res_alloc_fail;
|
||||
return;
|
||||
|
||||
info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum);
|
||||
if (!info.name)
|
||||
|
@ -301,8 +341,6 @@ get_current_resources(struct acpi_device *device, int busnum,
|
|||
|
||||
name_alloc_fail:
|
||||
kfree(info.res);
|
||||
res_alloc_fail:
|
||||
return;
|
||||
}
|
||||
|
||||
struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
|
@ -310,6 +348,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
|
|||
struct acpi_device *device = root->device;
|
||||
int domain = root->segment;
|
||||
int busnum = root->secondary.start;
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *bus;
|
||||
struct pci_sysdata *sd;
|
||||
int node;
|
||||
|
@ -364,11 +403,15 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
|
|||
memcpy(bus->sysdata, sd, sizeof(*sd));
|
||||
kfree(sd);
|
||||
} else {
|
||||
bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd);
|
||||
if (bus) {
|
||||
get_current_resources(device, busnum, domain, bus);
|
||||
get_current_resources(device, busnum, domain, &resources);
|
||||
if (list_empty(&resources))
|
||||
x86_pci_root_bus_resources(busnum, &resources);
|
||||
bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd,
|
||||
&resources);
|
||||
if (bus)
|
||||
bus->subordinate = pci_scan_child_bus(bus);
|
||||
}
|
||||
else
|
||||
pci_free_resource_list(&resources);
|
||||
}
|
||||
|
||||
/* After the PCI-E bus has been walked and all devices discovered,
|
||||
|
|
|
@ -30,34 +30,6 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
|
|||
{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 },
|
||||
};
|
||||
|
||||
static u64 __initdata fam10h_mmconf_start;
|
||||
static u64 __initdata fam10h_mmconf_end;
|
||||
static void __init get_pci_mmcfg_amd_fam10h_range(void)
|
||||
{
|
||||
u32 address;
|
||||
u64 base, msr;
|
||||
unsigned segn_busn_bits;
|
||||
|
||||
/* assume all cpus from fam10h have mmconf */
|
||||
if (boot_cpu_data.x86 < 0x10)
|
||||
return;
|
||||
|
||||
address = MSR_FAM10H_MMIO_CONF_BASE;
|
||||
rdmsrl(address, msr);
|
||||
|
||||
/* mmconfig is not enable */
|
||||
if (!(msr & FAM10H_MMIO_CONF_ENABLE))
|
||||
return;
|
||||
|
||||
base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
|
||||
|
||||
segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
|
||||
FAM10H_MMIO_CONF_BUSRANGE_MASK;
|
||||
|
||||
fam10h_mmconf_start = base;
|
||||
fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
|
||||
}
|
||||
|
||||
#define RANGE_NUM 16
|
||||
|
||||
/**
|
||||
|
@ -85,6 +57,9 @@ static int __init early_fill_mp_bus_info(void)
|
|||
u64 val;
|
||||
u32 address;
|
||||
bool found;
|
||||
struct resource fam10h_mmconf_res, *fam10h_mmconf;
|
||||
u64 fam10h_mmconf_start;
|
||||
u64 fam10h_mmconf_end;
|
||||
|
||||
if (!early_pci_allowed())
|
||||
return -1;
|
||||
|
@ -211,12 +186,17 @@ static int __init early_fill_mp_bus_info(void)
|
|||
subtract_range(range, RANGE_NUM, 0, end);
|
||||
|
||||
/* get mmconfig */
|
||||
get_pci_mmcfg_amd_fam10h_range();
|
||||
fam10h_mmconf = amd_get_mmconfig_range(&fam10h_mmconf_res);
|
||||
/* need to take out mmconf range */
|
||||
if (fam10h_mmconf_end) {
|
||||
printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
|
||||
if (fam10h_mmconf) {
|
||||
printk(KERN_DEBUG "Fam 10h mmconf %pR\n", fam10h_mmconf);
|
||||
fam10h_mmconf_start = fam10h_mmconf->start;
|
||||
fam10h_mmconf_end = fam10h_mmconf->end;
|
||||
subtract_range(range, RANGE_NUM, fam10h_mmconf_start,
|
||||
fam10h_mmconf_end + 1);
|
||||
} else {
|
||||
fam10h_mmconf_start = 0;
|
||||
fam10h_mmconf_end = 0;
|
||||
}
|
||||
|
||||
/* mmio resource */
|
||||
|
@ -403,7 +383,6 @@ static void __init pci_enable_pci_io_ecs(void)
|
|||
++n;
|
||||
}
|
||||
}
|
||||
pr_info("Extended Config Space enabled on %u nodes\n", n);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/pci_x86.h>
|
||||
#include <asm/pci-direct.h>
|
||||
|
||||
#include "bus_numa.h"
|
||||
|
||||
static void __devinit cnb20le_res(struct pci_dev *dev)
|
||||
static void __init cnb20le_res(u8 bus, u8 slot, u8 func)
|
||||
{
|
||||
struct pci_root_info *info;
|
||||
struct resource res;
|
||||
|
@ -26,21 +27,12 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|||
u8 fbus, lbus;
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/*
|
||||
* We should get host bridge information from ACPI unless the BIOS
|
||||
* doesn't support it.
|
||||
*/
|
||||
if (acpi_os_get_root_pointer())
|
||||
return;
|
||||
#endif
|
||||
|
||||
info = &pci_root_info[pci_root_num];
|
||||
pci_root_num++;
|
||||
|
||||
/* read the PCI bus numbers */
|
||||
pci_read_config_byte(dev, 0x44, &fbus);
|
||||
pci_read_config_byte(dev, 0x45, &lbus);
|
||||
fbus = read_pci_config_byte(bus, slot, func, 0x44);
|
||||
lbus = read_pci_config_byte(bus, slot, func, 0x45);
|
||||
info->bus_min = fbus;
|
||||
info->bus_max = lbus;
|
||||
|
||||
|
@ -59,8 +51,8 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|||
}
|
||||
|
||||
/* read the non-prefetchable memory window */
|
||||
pci_read_config_word(dev, 0xc0, &word1);
|
||||
pci_read_config_word(dev, 0xc2, &word2);
|
||||
word1 = read_pci_config_16(bus, slot, func, 0xc0);
|
||||
word2 = read_pci_config_16(bus, slot, func, 0xc2);
|
||||
if (word1 != word2) {
|
||||
res.start = (word1 << 16) | 0x0000;
|
||||
res.end = (word2 << 16) | 0xffff;
|
||||
|
@ -69,8 +61,8 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|||
}
|
||||
|
||||
/* read the prefetchable memory window */
|
||||
pci_read_config_word(dev, 0xc4, &word1);
|
||||
pci_read_config_word(dev, 0xc6, &word2);
|
||||
word1 = read_pci_config_16(bus, slot, func, 0xc4);
|
||||
word2 = read_pci_config_16(bus, slot, func, 0xc6);
|
||||
if (word1 != word2) {
|
||||
res.start = (word1 << 16) | 0x0000;
|
||||
res.end = (word2 << 16) | 0xffff;
|
||||
|
@ -79,8 +71,8 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|||
}
|
||||
|
||||
/* read the IO port window */
|
||||
pci_read_config_word(dev, 0xd0, &word1);
|
||||
pci_read_config_word(dev, 0xd2, &word2);
|
||||
word1 = read_pci_config_16(bus, slot, func, 0xd0);
|
||||
word2 = read_pci_config_16(bus, slot, func, 0xd2);
|
||||
if (word1 != word2) {
|
||||
res.start = word1;
|
||||
res.end = word2;
|
||||
|
@ -92,13 +84,37 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|||
res.start = fbus;
|
||||
res.end = lbus;
|
||||
res.flags = IORESOURCE_BUS;
|
||||
dev_info(&dev->dev, "CNB20LE PCI Host Bridge (domain %04x %pR)\n",
|
||||
pci_domain_nr(dev->bus), &res);
|
||||
printk(KERN_INFO "CNB20LE PCI Host Bridge (domain 0000 %pR)\n", &res);
|
||||
|
||||
for (i = 0; i < info->res_num; i++)
|
||||
dev_info(&dev->dev, "host bridge window %pR\n", &info->res[i]);
|
||||
printk(KERN_INFO "host bridge window %pR\n", &info->res[i]);
|
||||
}
|
||||
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
|
||||
cnb20le_res);
|
||||
static int __init broadcom_postcore_init(void)
|
||||
{
|
||||
u8 bus = 0, slot = 0;
|
||||
u32 id;
|
||||
u16 vendor, device;
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/*
|
||||
* We should get host bridge information from ACPI unless the BIOS
|
||||
* doesn't support it.
|
||||
*/
|
||||
if (acpi_os_get_root_pointer())
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
|
||||
vendor = id & 0xffff;
|
||||
device = (id >> 16) & 0xffff;
|
||||
|
||||
if (vendor == PCI_VENDOR_ID_SERVERWORKS &&
|
||||
device == PCI_DEVICE_ID_SERVERWORKS_LE) {
|
||||
cnb20le_res(bus, slot, 0);
|
||||
cnb20le_res(bus, slot, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
postcore_initcall(broadcom_postcore_init);
|
||||
|
|
|
@ -7,45 +7,50 @@
|
|||
int pci_root_num;
|
||||
struct pci_root_info pci_root_info[PCI_ROOT_NR];
|
||||
|
||||
void x86_pci_root_bus_res_quirks(struct pci_bus *b)
|
||||
void x86_pci_root_bus_resources(int bus, struct list_head *resources)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
struct pci_root_info *info;
|
||||
|
||||
/* don't go for it if _CRS is used already */
|
||||
if (b->resource[0] != &ioport_resource ||
|
||||
b->resource[1] != &iomem_resource)
|
||||
return;
|
||||
|
||||
if (!pci_root_num)
|
||||
return;
|
||||
goto default_resources;
|
||||
|
||||
for (i = 0; i < pci_root_num; i++) {
|
||||
if (pci_root_info[i].bus_min == b->number)
|
||||
if (pci_root_info[i].bus_min == bus)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == pci_root_num)
|
||||
return;
|
||||
goto default_resources;
|
||||
|
||||
printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
|
||||
b->number);
|
||||
printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n",
|
||||
bus);
|
||||
|
||||
pci_bus_remove_resources(b);
|
||||
info = &pci_root_info[i];
|
||||
for (j = 0; j < info->res_num; j++) {
|
||||
struct resource *res;
|
||||
struct resource *root;
|
||||
|
||||
res = &info->res[j];
|
||||
pci_bus_add_resource(b, res, 0);
|
||||
pci_add_resource(resources, res);
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
root = &ioport_resource;
|
||||
else
|
||||
root = &iomem_resource;
|
||||
insert_resource(root, res);
|
||||
}
|
||||
return;
|
||||
|
||||
default_resources:
|
||||
/*
|
||||
* We don't have any host bridge aperture information from the
|
||||
* "native host bridge drivers," e.g., amd_bus or broadcom_bus,
|
||||
* so fall back to the defaults historically used by pci_create_bus().
|
||||
*/
|
||||
printk(KERN_DEBUG "PCI: root bus %02x: using default resources\n", bus);
|
||||
pci_add_resource(resources, &ioport_resource);
|
||||
pci_add_resource(resources, &iomem_resource);
|
||||
}
|
||||
|
||||
void __devinit update_res(struct pci_root_info *info, resource_size_t start,
|
||||
|
|
|
@ -164,9 +164,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *b)
|
|||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
/* root bus? */
|
||||
if (!b->parent)
|
||||
x86_pci_root_bus_res_quirks(b);
|
||||
pci_read_bridge_bases(b);
|
||||
list_for_each_entry(dev, &b->devices, bus_list)
|
||||
pcibios_fixup_device_resources(dev);
|
||||
|
@ -433,6 +430,7 @@ void __init dmi_check_pciprobe(void)
|
|||
|
||||
struct pci_bus * __devinit pcibios_scan_root(int busnum)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *bus = NULL;
|
||||
struct pci_sysdata *sd;
|
||||
|
||||
|
@ -456,9 +454,12 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
|
|||
sd->node = get_mp_bus_to_node(busnum);
|
||||
|
||||
printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
|
||||
bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
|
||||
if (!bus)
|
||||
x86_pci_root_bus_resources(busnum, &resources);
|
||||
bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
|
||||
if (!bus) {
|
||||
pci_free_resource_list(&resources);
|
||||
kfree(sd);
|
||||
}
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
@ -639,6 +640,7 @@ int pci_ext_cfg_avail(struct pci_dev *dev)
|
|||
|
||||
struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *bus = NULL;
|
||||
struct pci_sysdata *sd;
|
||||
|
||||
|
@ -653,9 +655,12 @@ struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops,
|
|||
return NULL;
|
||||
}
|
||||
sd->node = node;
|
||||
bus = pci_scan_bus(busno, ops, sd);
|
||||
if (!bus)
|
||||
x86_pci_root_bus_resources(busno, &resources);
|
||||
bus = pci_scan_root_bus(NULL, busno, ops, sd, &resources);
|
||||
if (!bus) {
|
||||
pci_free_resource_list(&resources);
|
||||
kfree(sd);
|
||||
}
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
|
|
@ -254,26 +254,6 @@ void __init pcibios_resource_survey(void)
|
|||
*/
|
||||
fs_initcall(pcibios_assign_resources);
|
||||
|
||||
/*
|
||||
* If we set up a device for bus mastering, we need to check the latency
|
||||
* timer as certain crappy BIOSes forget to set it properly.
|
||||
*/
|
||||
unsigned int pcibios_max_latency = 255;
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
u8 lat;
|
||||
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
|
||||
if (lat < 16)
|
||||
lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
|
||||
else if (lat > pcibios_max_latency)
|
||||
lat = pcibios_max_latency;
|
||||
else
|
||||
return;
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat);
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct pci_mmap_ops = {
|
||||
.access = generic_access_phys,
|
||||
};
|
||||
|
|
|
@ -31,9 +31,6 @@ int __init pci_legacy_init(void)
|
|||
|
||||
printk("PCI: Probing PCI hardware\n");
|
||||
pci_root_bus = pcibios_scan_root(0);
|
||||
if (pci_root_bus)
|
||||
pci_bus_add_devices(pci_root_bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -153,8 +153,6 @@ int __init pci_numaq_init(void)
|
|||
raw_pci_ops = &pci_direct_conf1_mq;
|
||||
|
||||
pci_root_bus = pcibios_scan_root(0);
|
||||
if (pci_root_bus)
|
||||
pci_bus_add_devices(pci_root_bus);
|
||||
if (num_online_nodes() > 1)
|
||||
for_each_online_node(quad) {
|
||||
if (quad == 0)
|
||||
|
|
|
@ -22,11 +22,6 @@
|
|||
|
||||
extern struct pci_controller* pcibios_alloc_controller(void);
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
|
|
|
@ -134,9 +134,46 @@ struct pci_controller * __init pcibios_alloc_controller(void)
|
|||
return pci_ctrl;
|
||||
}
|
||||
|
||||
static void __init pci_controller_apertures(struct pci_controller *pci_ctrl,
|
||||
struct list_head *resources)
|
||||
{
|
||||
struct resource *res;
|
||||
unsigned long io_offset;
|
||||
int i;
|
||||
|
||||
io_offset = (unsigned long)pci_ctrl->io_space.base;
|
||||
res = &pci_ctrl->io_resource;
|
||||
if (!res->flags) {
|
||||
if (io_offset)
|
||||
printk (KERN_ERR "I/O resource not set for host"
|
||||
" bridge %d\n", pci_ctrl->index);
|
||||
res->start = 0;
|
||||
res->end = IO_SPACE_LIMIT;
|
||||
res->flags = IORESOURCE_IO;
|
||||
}
|
||||
res->start += io_offset;
|
||||
res->end += io_offset;
|
||||
pci_add_resource(resources, res);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
res = &pci_ctrl->mem_resources[i];
|
||||
if (!res->flags) {
|
||||
if (i > 0)
|
||||
continue;
|
||||
printk(KERN_ERR "Memory resource not set for "
|
||||
"host bridge %d\n", pci_ctrl->index);
|
||||
res->start = 0;
|
||||
res->end = ~0U;
|
||||
res->flags = IORESOURCE_MEM;
|
||||
}
|
||||
pci_add_resource(resources, res);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
{
|
||||
struct pci_controller *pci_ctrl;
|
||||
struct list_head resources;
|
||||
struct pci_bus *bus;
|
||||
int next_busno = 0, i;
|
||||
|
||||
|
@ -145,19 +182,10 @@ static int __init pcibios_init(void)
|
|||
/* Scan all of the recorded PCI controllers. */
|
||||
for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) {
|
||||
pci_ctrl->last_busno = 0xff;
|
||||
bus = pci_scan_bus(pci_ctrl->first_busno, pci_ctrl->ops,
|
||||
pci_ctrl);
|
||||
if (pci_ctrl->io_resource.flags) {
|
||||
unsigned long offs;
|
||||
|
||||
offs = (unsigned long)pci_ctrl->io_space.base;
|
||||
pci_ctrl->io_resource.start += offs;
|
||||
pci_ctrl->io_resource.end += offs;
|
||||
bus->resource[0] = &pci_ctrl->io_resource;
|
||||
}
|
||||
for (i = 0; i < 3; ++i)
|
||||
if (pci_ctrl->mem_resources[i].flags)
|
||||
bus->resource[i+1] =&pci_ctrl->mem_resources[i];
|
||||
INIT_LIST_HEAD(&resources);
|
||||
pci_controller_apertures(pci_ctrl, &resources);
|
||||
bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno,
|
||||
pci_ctrl->ops, pci_ctrl, &resources);
|
||||
pci_ctrl->bus = bus;
|
||||
pci_ctrl->last_busno = bus->subordinate;
|
||||
if (next_busno <= pci_ctrl->last_busno)
|
||||
|
@ -178,36 +206,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
|
|||
int i;
|
||||
|
||||
io_offset = (unsigned long)pci_ctrl->io_space.base;
|
||||
if (bus->parent == NULL) {
|
||||
/* this is a host bridge - fill in its resources */
|
||||
pci_ctrl->bus = bus;
|
||||
|
||||
bus->resource[0] = res = &pci_ctrl->io_resource;
|
||||
if (!res->flags) {
|
||||
if (io_offset)
|
||||
printk (KERN_ERR "I/O resource not set for host"
|
||||
" bridge %d\n", pci_ctrl->index);
|
||||
res->start = 0;
|
||||
res->end = IO_SPACE_LIMIT;
|
||||
res->flags = IORESOURCE_IO;
|
||||
}
|
||||
res->start += io_offset;
|
||||
res->end += io_offset;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
res = &pci_ctrl->mem_resources[i];
|
||||
if (!res->flags) {
|
||||
if (i > 0)
|
||||
continue;
|
||||
printk(KERN_ERR "Memory resource not set for "
|
||||
"host bridge %d\n", pci_ctrl->index);
|
||||
res->start = 0;
|
||||
res->end = ~0U;
|
||||
res->flags = IORESOURCE_MEM;
|
||||
}
|
||||
bus->resource[i+1] = res;
|
||||
}
|
||||
} else {
|
||||
if (bus->parent) {
|
||||
/* This is a subordinate bridge */
|
||||
pci_read_bridge_bases(bus);
|
||||
|
||||
|
@ -227,6 +226,11 @@ char __init *pcibios_setup(char *str)
|
|||
return str;
|
||||
}
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
/* the next one is stolen from the alpha port... */
|
||||
|
||||
void __init
|
||||
|
|
|
@ -487,10 +487,10 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
|
|||
else
|
||||
link_desc[0] = '\0';
|
||||
|
||||
dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
|
||||
pin_name(pin), link_desc, gsi,
|
||||
(triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
|
||||
(polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
|
||||
dev_dbg(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
|
||||
pin_name(pin), link_desc, gsi,
|
||||
(triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
|
||||
(polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -524,6 +524,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
|
|||
* (e.g. PCI_UNDEFINED_IRQ).
|
||||
*/
|
||||
|
||||
dev_info(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
|
||||
dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
|
||||
acpi_unregister_gsi(gsi);
|
||||
}
|
||||
|
|
|
@ -562,19 +562,6 @@ dino_fixup_bus(struct pci_bus *bus)
|
|||
/* Firmware doesn't set up card-mode dino, so we have to */
|
||||
if (is_card_dino(&dino_dev->hba.dev->id)) {
|
||||
dino_card_setup(bus, dino_dev->hba.base_addr);
|
||||
} else if(bus->parent == NULL) {
|
||||
/* must have a dino above it, reparent the resources
|
||||
* into the dino window */
|
||||
int i;
|
||||
struct resource *res = &dino_dev->hba.lmmio_space;
|
||||
|
||||
bus->resource[0] = &(dino_dev->hba.io_space);
|
||||
for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) {
|
||||
if(res[i].flags == 0)
|
||||
break;
|
||||
bus->resource[i+1] = &res[i];
|
||||
}
|
||||
|
||||
} else if (bus->parent) {
|
||||
int i;
|
||||
|
||||
|
@ -927,6 +914,7 @@ static int __init dino_probe(struct parisc_device *dev)
|
|||
const char *version = "unknown";
|
||||
char *name;
|
||||
int is_cujo = 0;
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *bus;
|
||||
unsigned long hpa = dev->hpa.start;
|
||||
|
||||
|
@ -1003,26 +991,37 @@ static int __init dino_probe(struct parisc_device *dev)
|
|||
|
||||
dev->dev.platform_data = dino_dev;
|
||||
|
||||
pci_add_resource(&resources, &dino_dev->hba.io_space);
|
||||
if (dino_dev->hba.lmmio_space.flags)
|
||||
pci_add_resource(&resources, &dino_dev->hba.lmmio_space);
|
||||
if (dino_dev->hba.elmmio_space.flags)
|
||||
pci_add_resource(&resources, &dino_dev->hba.elmmio_space);
|
||||
if (dino_dev->hba.gmmio_space.flags)
|
||||
pci_add_resource(&resources, &dino_dev->hba.gmmio_space);
|
||||
|
||||
/*
|
||||
** It's not used to avoid chicken/egg problems
|
||||
** with configuration accessor functions.
|
||||
*/
|
||||
dino_dev->hba.hba_bus = bus = pci_scan_bus_parented(&dev->dev,
|
||||
dino_current_bus, &dino_cfg_ops, NULL);
|
||||
|
||||
if(bus) {
|
||||
/* This code *depends* on scanning being single threaded
|
||||
* if it isn't, this global bus number count will fail
|
||||
*/
|
||||
dino_current_bus = bus->subordinate + 1;
|
||||
pci_bus_assign_resources(bus);
|
||||
pci_bus_add_devices(bus);
|
||||
} else {
|
||||
dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev,
|
||||
dino_current_bus, &dino_cfg_ops, NULL, &resources);
|
||||
if (!bus) {
|
||||
printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n",
|
||||
dev_name(&dev->dev), dino_current_bus);
|
||||
pci_free_resource_list(&resources);
|
||||
/* increment the bus number in case of duplicates */
|
||||
dino_current_bus++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bus->subordinate = pci_scan_child_bus(bus);
|
||||
|
||||
/* This code *depends* on scanning being single threaded
|
||||
* if it isn't, this global bus number count will fail
|
||||
*/
|
||||
dino_current_bus = bus->subordinate + 1;
|
||||
pci_bus_assign_resources(bus);
|
||||
pci_bus_add_devices(bus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -653,7 +653,7 @@ lba_fixup_bus(struct pci_bus *bus)
|
|||
}
|
||||
} else {
|
||||
/* Host-PCI Bridge */
|
||||
int err, i;
|
||||
int err;
|
||||
|
||||
DBG("lba_fixup_bus() %s [%lx/%lx]/%lx\n",
|
||||
ldev->hba.io_space.name,
|
||||
|
@ -669,9 +669,6 @@ lba_fixup_bus(struct pci_bus *bus)
|
|||
lba_dump_res(&ioport_resource, 2);
|
||||
BUG();
|
||||
}
|
||||
/* advertize Host bridge resources to PCI bus */
|
||||
bus->resource[0] = &(ldev->hba.io_space);
|
||||
i = 1;
|
||||
|
||||
if (ldev->hba.elmmio_space.start) {
|
||||
err = request_resource(&iomem_resource,
|
||||
|
@ -685,35 +682,17 @@ lba_fixup_bus(struct pci_bus *bus)
|
|||
|
||||
/* lba_dump_res(&iomem_resource, 2); */
|
||||
/* BUG(); */
|
||||
} else
|
||||
bus->resource[i++] = &(ldev->hba.elmmio_space);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Overlaps with elmmio can (and should) fail here.
|
||||
* We will prune (or ignore) the distributed range.
|
||||
*
|
||||
* FIXME: SBA code should register all elmmio ranges first.
|
||||
* that would take care of elmmio ranges routed
|
||||
* to a different rope (already discovered) from
|
||||
* getting registered *after* LBA code has already
|
||||
* registered it's distributed lmmio range.
|
||||
*/
|
||||
if (truncate_pat_collision(&iomem_resource,
|
||||
&(ldev->hba.lmmio_space))) {
|
||||
|
||||
printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
|
||||
(long)ldev->hba.lmmio_space.start,
|
||||
(long)ldev->hba.lmmio_space.end);
|
||||
} else {
|
||||
if (ldev->hba.lmmio_space.flags) {
|
||||
err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR "FAILED: lba_fixup_bus() request for "
|
||||
"lmmio_space [%lx/%lx]\n",
|
||||
(long)ldev->hba.lmmio_space.start,
|
||||
(long)ldev->hba.lmmio_space.end);
|
||||
} else
|
||||
bus->resource[i++] = &(ldev->hba.lmmio_space);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
@ -728,7 +707,6 @@ lba_fixup_bus(struct pci_bus *bus)
|
|||
lba_dump_res(&iomem_resource, 2);
|
||||
BUG();
|
||||
}
|
||||
bus->resource[i++] = &(ldev->hba.gmmio_space);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1404,6 +1382,7 @@ static int __init
|
|||
lba_driver_probe(struct parisc_device *dev)
|
||||
{
|
||||
struct lba_device *lba_dev;
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *lba_bus;
|
||||
struct pci_ops *cfg_ops;
|
||||
u32 func_class;
|
||||
|
@ -1518,10 +1497,41 @@ lba_driver_probe(struct parisc_device *dev)
|
|||
if (lba_dev->hba.bus_num.start < lba_next_bus)
|
||||
lba_dev->hba.bus_num.start = lba_next_bus;
|
||||
|
||||
/* Overlaps with elmmio can (and should) fail here.
|
||||
* We will prune (or ignore) the distributed range.
|
||||
*
|
||||
* FIXME: SBA code should register all elmmio ranges first.
|
||||
* that would take care of elmmio ranges routed
|
||||
* to a different rope (already discovered) from
|
||||
* getting registered *after* LBA code has already
|
||||
* registered it's distributed lmmio range.
|
||||
*/
|
||||
if (truncate_pat_collision(&iomem_resource,
|
||||
&(lba_dev->hba.lmmio_space))) {
|
||||
printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
|
||||
(long)lba_dev->hba.lmmio_space.start,
|
||||
(long)lba_dev->hba.lmmio_space.end);
|
||||
lba_dev->hba.lmmio_space.flags = 0;
|
||||
}
|
||||
|
||||
pci_add_resource(&resources, &lba_dev->hba.io_space);
|
||||
if (lba_dev->hba.elmmio_space.start)
|
||||
pci_add_resource(&resources, &lba_dev->hba.elmmio_space);
|
||||
if (lba_dev->hba.lmmio_space.flags)
|
||||
pci_add_resource(&resources, &lba_dev->hba.lmmio_space);
|
||||
if (lba_dev->hba.gmmio_space.flags)
|
||||
pci_add_resource(&resources, &lba_dev->hba.gmmio_space);
|
||||
|
||||
dev->dev.platform_data = lba_dev;
|
||||
lba_bus = lba_dev->hba.hba_bus =
|
||||
pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
|
||||
cfg_ops, NULL);
|
||||
pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start,
|
||||
cfg_ops, NULL, &resources);
|
||||
if (!lba_bus) {
|
||||
pci_free_resource_list(&resources);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lba_bus->subordinate = pci_scan_child_bus(lba_bus);
|
||||
|
||||
/* This is in lieu of calling pci_assign_unassigned_resources() */
|
||||
if (is_pdc_pat()) {
|
||||
|
@ -1551,10 +1561,8 @@ lba_driver_probe(struct parisc_device *dev)
|
|||
lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
|
||||
}
|
||||
|
||||
if (lba_bus) {
|
||||
lba_next_bus = lba_bus->subordinate + 1;
|
||||
pci_bus_add_devices(lba_bus);
|
||||
}
|
||||
lba_next_bus = lba_bus->subordinate + 1;
|
||||
pci_bus_add_devices(lba_bus);
|
||||
|
||||
/* Whew! Finally done! Tell services we got this one covered. */
|
||||
return 0;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* configuration space.
|
||||
*/
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(pci_lock);
|
||||
DEFINE_RAW_SPINLOCK(pci_lock);
|
||||
|
||||
/*
|
||||
* Wrappers for all PCI configuration access functions. They just check
|
||||
|
@ -127,20 +127,20 @@ EXPORT_SYMBOL(pci_write_vpd);
|
|||
* We have a bit per device to indicate it's blocked and a global wait queue
|
||||
* for callers to sleep on until devices are unblocked.
|
||||
*/
|
||||
static DECLARE_WAIT_QUEUE_HEAD(pci_ucfg_wait);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(pci_cfg_wait);
|
||||
|
||||
static noinline void pci_wait_ucfg(struct pci_dev *dev)
|
||||
static noinline void pci_wait_cfg(struct pci_dev *dev)
|
||||
{
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
|
||||
__add_wait_queue(&pci_ucfg_wait, &wait);
|
||||
__add_wait_queue(&pci_cfg_wait, &wait);
|
||||
do {
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
raw_spin_unlock_irq(&pci_lock);
|
||||
schedule();
|
||||
raw_spin_lock_irq(&pci_lock);
|
||||
} while (dev->block_ucfg_access);
|
||||
__remove_wait_queue(&pci_ucfg_wait, &wait);
|
||||
} while (dev->block_cfg_access);
|
||||
__remove_wait_queue(&pci_cfg_wait, &wait);
|
||||
}
|
||||
|
||||
/* Returns 0 on success, negative values indicate error. */
|
||||
|
@ -153,7 +153,8 @@ int pci_user_read_config_##size \
|
|||
if (PCI_##size##_BAD) \
|
||||
return -EINVAL; \
|
||||
raw_spin_lock_irq(&pci_lock); \
|
||||
if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \
|
||||
if (unlikely(dev->block_cfg_access)) \
|
||||
pci_wait_cfg(dev); \
|
||||
ret = dev->bus->ops->read(dev->bus, dev->devfn, \
|
||||
pos, sizeof(type), &data); \
|
||||
raw_spin_unlock_irq(&pci_lock); \
|
||||
|
@ -172,7 +173,8 @@ int pci_user_write_config_##size \
|
|||
if (PCI_##size##_BAD) \
|
||||
return -EINVAL; \
|
||||
raw_spin_lock_irq(&pci_lock); \
|
||||
if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \
|
||||
if (unlikely(dev->block_cfg_access)) \
|
||||
pci_wait_cfg(dev); \
|
||||
ret = dev->bus->ops->write(dev->bus, dev->devfn, \
|
||||
pos, sizeof(type), val); \
|
||||
raw_spin_unlock_irq(&pci_lock); \
|
||||
|
@ -401,36 +403,56 @@ int pci_vpd_truncate(struct pci_dev *dev, size_t size)
|
|||
EXPORT_SYMBOL(pci_vpd_truncate);
|
||||
|
||||
/**
|
||||
* pci_block_user_cfg_access - Block userspace PCI config reads/writes
|
||||
* pci_cfg_access_lock - Lock PCI config reads/writes
|
||||
* @dev: pci device struct
|
||||
*
|
||||
* When user access is blocked, any reads or writes to config space will
|
||||
* sleep until access is unblocked again. We don't allow nesting of
|
||||
* block/unblock calls.
|
||||
* When access is locked, any userspace reads or writes to config
|
||||
* space and concurrent lock requests will sleep until access is
|
||||
* allowed via pci_cfg_access_unlocked again.
|
||||
*/
|
||||
void pci_block_user_cfg_access(struct pci_dev *dev)
|
||||
void pci_cfg_access_lock(struct pci_dev *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
int was_blocked;
|
||||
might_sleep();
|
||||
|
||||
raw_spin_lock_irqsave(&pci_lock, flags);
|
||||
was_blocked = dev->block_ucfg_access;
|
||||
dev->block_ucfg_access = 1;
|
||||
raw_spin_unlock_irqrestore(&pci_lock, flags);
|
||||
|
||||
/* If we BUG() inside the pci_lock, we're guaranteed to hose
|
||||
* the machine */
|
||||
BUG_ON(was_blocked);
|
||||
raw_spin_lock_irq(&pci_lock);
|
||||
if (dev->block_cfg_access)
|
||||
pci_wait_cfg(dev);
|
||||
dev->block_cfg_access = 1;
|
||||
raw_spin_unlock_irq(&pci_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_block_user_cfg_access);
|
||||
EXPORT_SYMBOL_GPL(pci_cfg_access_lock);
|
||||
|
||||
/**
|
||||
* pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
|
||||
* pci_cfg_access_trylock - try to lock PCI config reads/writes
|
||||
* @dev: pci device struct
|
||||
*
|
||||
* This function allows userspace PCI config accesses to resume.
|
||||
* Same as pci_cfg_access_lock, but will return 0 if access is
|
||||
* already locked, 1 otherwise. This function can be used from
|
||||
* atomic contexts.
|
||||
*/
|
||||
void pci_unblock_user_cfg_access(struct pci_dev *dev)
|
||||
bool pci_cfg_access_trylock(struct pci_dev *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
bool locked = true;
|
||||
|
||||
raw_spin_lock_irqsave(&pci_lock, flags);
|
||||
if (dev->block_cfg_access)
|
||||
locked = false;
|
||||
else
|
||||
dev->block_cfg_access = 1;
|
||||
raw_spin_unlock_irqrestore(&pci_lock, flags);
|
||||
|
||||
return locked;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_cfg_access_trylock);
|
||||
|
||||
/**
|
||||
* pci_cfg_access_unlock - Unlock PCI config reads/writes
|
||||
* @dev: pci device struct
|
||||
*
|
||||
* This function allows PCI config accesses to resume.
|
||||
*/
|
||||
void pci_cfg_access_unlock(struct pci_dev *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -438,10 +460,10 @@ void pci_unblock_user_cfg_access(struct pci_dev *dev)
|
|||
|
||||
/* This indicates a problem in the caller, but we don't need
|
||||
* to kill them, unlike a double-block above. */
|
||||
WARN_ON(!dev->block_ucfg_access);
|
||||
WARN_ON(!dev->block_cfg_access);
|
||||
|
||||
dev->block_ucfg_access = 0;
|
||||
wake_up_all(&pci_ucfg_wait);
|
||||
dev->block_cfg_access = 0;
|
||||
wake_up_all(&pci_cfg_wait);
|
||||
raw_spin_unlock_irqrestore(&pci_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);
|
||||
EXPORT_SYMBOL_GPL(pci_cfg_access_unlock);
|
||||
|
|
|
@ -128,6 +128,23 @@ void pci_disable_ats(struct pci_dev *dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pci_disable_ats);
|
||||
|
||||
void pci_restore_ats_state(struct pci_dev *dev)
|
||||
{
|
||||
u16 ctrl;
|
||||
|
||||
if (!pci_ats_enabled(dev))
|
||||
return;
|
||||
if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS))
|
||||
BUG();
|
||||
|
||||
ctrl = PCI_ATS_CTRL_ENABLE;
|
||||
if (!dev->is_virtfn)
|
||||
ctrl |= PCI_ATS_CTRL_STU(dev->ats->stu - PCI_ATS_MIN_STU);
|
||||
|
||||
pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_restore_ats_state);
|
||||
|
||||
/**
|
||||
* pci_ats_queue_depth - query the ATS Invalidate Queue Depth
|
||||
* @dev: the PCI device
|
||||
|
|
|
@ -18,6 +18,32 @@
|
|||
|
||||
#include "pci.h"
|
||||
|
||||
void pci_add_resource(struct list_head *resources, struct resource *res)
|
||||
{
|
||||
struct pci_bus_resource *bus_res;
|
||||
|
||||
bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL);
|
||||
if (!bus_res) {
|
||||
printk(KERN_ERR "PCI: can't add bus resource %pR\n", res);
|
||||
return;
|
||||
}
|
||||
|
||||
bus_res->res = res;
|
||||
list_add_tail(&bus_res->list, resources);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_add_resource);
|
||||
|
||||
void pci_free_resource_list(struct list_head *resources)
|
||||
{
|
||||
struct pci_bus_resource *bus_res, *tmp;
|
||||
|
||||
list_for_each_entry_safe(bus_res, tmp, resources, list) {
|
||||
list_del(&bus_res->list);
|
||||
kfree(bus_res);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(pci_free_resource_list);
|
||||
|
||||
void pci_bus_add_resource(struct pci_bus *bus, struct resource *res,
|
||||
unsigned int flags)
|
||||
{
|
||||
|
@ -52,16 +78,12 @@ EXPORT_SYMBOL_GPL(pci_bus_resource_n);
|
|||
|
||||
void pci_bus_remove_resources(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_bus_resource *bus_res, *tmp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
|
||||
bus->resource[i] = NULL;
|
||||
|
||||
list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) {
|
||||
list_del(&bus_res->list);
|
||||
kfree(bus_res);
|
||||
}
|
||||
pci_free_resource_list(&bus->resources);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -347,11 +347,13 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
|
|||
return rc;
|
||||
}
|
||||
|
||||
pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
|
||||
|
||||
iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
|
||||
pci_block_user_cfg_access(dev);
|
||||
pci_cfg_access_lock(dev);
|
||||
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
|
||||
msleep(100);
|
||||
pci_unblock_user_cfg_access(dev);
|
||||
pci_cfg_access_unlock(dev);
|
||||
|
||||
iov->initial = initial;
|
||||
if (nr_virtfn < initial)
|
||||
|
@ -379,10 +381,10 @@ failed:
|
|||
virtfn_remove(dev, j, 0);
|
||||
|
||||
iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
|
||||
pci_block_user_cfg_access(dev);
|
||||
pci_cfg_access_lock(dev);
|
||||
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
|
||||
ssleep(1);
|
||||
pci_unblock_user_cfg_access(dev);
|
||||
pci_cfg_access_unlock(dev);
|
||||
|
||||
if (iov->link != dev->devfn)
|
||||
sysfs_remove_link(&dev->dev.kobj, "dep_link");
|
||||
|
@ -405,10 +407,10 @@ static void sriov_disable(struct pci_dev *dev)
|
|||
virtfn_remove(dev, i, 0);
|
||||
|
||||
iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
|
||||
pci_block_user_cfg_access(dev);
|
||||
pci_cfg_access_lock(dev);
|
||||
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
|
||||
ssleep(1);
|
||||
pci_unblock_user_cfg_access(dev);
|
||||
pci_cfg_access_unlock(dev);
|
||||
|
||||
if (iov->link != dev->devfn)
|
||||
sysfs_remove_link(&dev->dev.kobj, "dep_link");
|
||||
|
@ -452,7 +454,6 @@ static int sriov_init(struct pci_dev *dev, int pos)
|
|||
|
||||
found:
|
||||
pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, ctrl);
|
||||
pci_write_config_word(dev, pos + PCI_SRIOV_NUM_VF, total);
|
||||
pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
|
||||
pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);
|
||||
if (!offset || (total > 1 && !stride))
|
||||
|
@ -465,7 +466,6 @@ found:
|
|||
return -EIO;
|
||||
|
||||
pgsz &= ~(pgsz - 1);
|
||||
pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz);
|
||||
|
||||
nres = 0;
|
||||
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
|
||||
|
|
|
@ -86,6 +86,31 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef arch_restore_msi_irqs
|
||||
# define arch_restore_msi_irqs default_restore_msi_irqs
|
||||
# define HAVE_DEFAULT_MSI_RESTORE_IRQS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DEFAULT_MSI_RESTORE_IRQS
|
||||
void default_restore_msi_irqs(struct pci_dev *dev, int irq)
|
||||
{
|
||||
struct msi_desc *entry;
|
||||
|
||||
entry = NULL;
|
||||
if (dev->msix_enabled) {
|
||||
list_for_each_entry(entry, &dev->msi_list, list) {
|
||||
if (irq == entry->irq)
|
||||
break;
|
||||
}
|
||||
} else if (dev->msi_enabled) {
|
||||
entry = irq_get_msi_desc(irq);
|
||||
}
|
||||
|
||||
if (entry)
|
||||
write_msi_msg(irq, &entry->msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void msi_set_enable(struct pci_dev *dev, int pos, int enable)
|
||||
{
|
||||
u16 control;
|
||||
|
@ -323,8 +348,18 @@ static void free_msi_irqs(struct pci_dev *dev)
|
|||
if (list_is_last(&entry->list, &dev->msi_list))
|
||||
iounmap(entry->mask_base);
|
||||
}
|
||||
kobject_del(&entry->kobj);
|
||||
kobject_put(&entry->kobj);
|
||||
|
||||
/*
|
||||
* Its possible that we get into this path
|
||||
* When populate_msi_sysfs fails, which means the entries
|
||||
* were not registered with sysfs. In that case don't
|
||||
* unregister them.
|
||||
*/
|
||||
if (entry->kobj.parent) {
|
||||
kobject_del(&entry->kobj);
|
||||
kobject_put(&entry->kobj);
|
||||
}
|
||||
|
||||
list_del(&entry->list);
|
||||
kfree(entry);
|
||||
}
|
||||
|
@ -362,7 +397,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
|
|||
|
||||
pci_intx_for_msi(dev, 0);
|
||||
msi_set_enable(dev, pos, 0);
|
||||
write_msi_msg(dev->irq, &entry->msg);
|
||||
arch_restore_msi_irqs(dev, dev->irq);
|
||||
|
||||
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
|
||||
msi_mask_irq(entry, msi_capable_mask(control), entry->masked);
|
||||
|
@ -390,7 +425,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
|
|||
pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
|
||||
|
||||
list_for_each_entry(entry, &dev->msi_list, list) {
|
||||
write_msi_msg(entry->irq, &entry->msg);
|
||||
arch_restore_msi_irqs(dev, entry->irq);
|
||||
msix_mask_irq(entry, entry->masked);
|
||||
}
|
||||
|
||||
|
|
|
@ -604,7 +604,8 @@ static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
|
|||
* supported as well. Drivers are supposed to support either the
|
||||
* former, or the latter, but not both at the same time.
|
||||
*/
|
||||
WARN_ON(ret && drv->driver.pm);
|
||||
WARN(ret && drv->driver.pm, "driver %s device %04x:%04x\n",
|
||||
drv->name, pci_dev->vendor, pci_dev->device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,12 @@ enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
|
|||
u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2;
|
||||
u8 pci_cache_line_size;
|
||||
|
||||
/*
|
||||
* If we set up a device for bus mastering, we need to check the latency
|
||||
* timer as certain BIOSes forget to set it properly.
|
||||
*/
|
||||
unsigned int pcibios_max_latency = 255;
|
||||
|
||||
/**
|
||||
* pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
|
||||
* @bus: pointer to PCI bus structure to search
|
||||
|
@ -959,6 +965,7 @@ void pci_restore_state(struct pci_dev *dev)
|
|||
|
||||
/* PCI Express register must be restored first */
|
||||
pci_restore_pcie_state(dev);
|
||||
pci_restore_ats_state(dev);
|
||||
|
||||
/*
|
||||
* The Base Address register should be programmed before the command
|
||||
|
@ -967,7 +974,7 @@ void pci_restore_state(struct pci_dev *dev)
|
|||
for (i = 15; i >= 0; i--) {
|
||||
pci_read_config_dword(dev, i * 4, &val);
|
||||
if (val != dev->saved_config_space[i]) {
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "restoring config "
|
||||
dev_dbg(&dev->dev, "restoring config "
|
||||
"space at offset %#x (was %#x, writing %#x)\n",
|
||||
i, val, (int)dev->saved_config_space[i]);
|
||||
pci_write_config_dword(dev,i * 4,
|
||||
|
@ -1536,8 +1543,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
|
|||
}
|
||||
|
||||
out:
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "PME# %s\n",
|
||||
enable ? "enabled" : "disabled");
|
||||
dev_dbg(&dev->dev, "PME# %s\n", enable ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2595,6 +2601,33 @@ static void __pci_set_master(struct pci_dev *dev, bool enable)
|
|||
dev->is_busmaster = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* pcibios_set_master - enable PCI bus-mastering for device dev
|
||||
* @dev: the PCI device to enable
|
||||
*
|
||||
* Enables PCI bus-mastering for the device. This is the default
|
||||
* implementation. Architecture specific implementations can override
|
||||
* this if necessary.
|
||||
*/
|
||||
void __weak pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
u8 lat;
|
||||
|
||||
/* The latency timer doesn't apply to PCIe (either Type 0 or Type 1) */
|
||||
if (pci_is_pcie(dev))
|
||||
return;
|
||||
|
||||
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
|
||||
if (lat < 16)
|
||||
lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
|
||||
else if (lat > pcibios_max_latency)
|
||||
lat = pcibios_max_latency;
|
||||
else
|
||||
return;
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat);
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_set_master - enables bus-mastering for device dev
|
||||
* @dev: the PCI device to enable
|
||||
|
@ -2767,6 +2800,116 @@ pci_intx(struct pci_dev *pdev, int enable)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_intx_mask_supported - probe for INTx masking support
|
||||
* @pdev: the PCI device to operate on
|
||||
*
|
||||
* Check if the device dev support INTx masking via the config space
|
||||
* command word.
|
||||
*/
|
||||
bool pci_intx_mask_supported(struct pci_dev *dev)
|
||||
{
|
||||
bool mask_supported = false;
|
||||
u16 orig, new;
|
||||
|
||||
pci_cfg_access_lock(dev);
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &orig);
|
||||
pci_write_config_word(dev, PCI_COMMAND,
|
||||
orig ^ PCI_COMMAND_INTX_DISABLE);
|
||||
pci_read_config_word(dev, PCI_COMMAND, &new);
|
||||
|
||||
/*
|
||||
* There's no way to protect against hardware bugs or detect them
|
||||
* reliably, but as long as we know what the value should be, let's
|
||||
* go ahead and check it.
|
||||
*/
|
||||
if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
|
||||
dev_err(&dev->dev, "Command register changed from "
|
||||
"0x%x to 0x%x: driver or hardware bug?\n", orig, new);
|
||||
} else if ((new ^ orig) & PCI_COMMAND_INTX_DISABLE) {
|
||||
mask_supported = true;
|
||||
pci_write_config_word(dev, PCI_COMMAND, orig);
|
||||
}
|
||||
|
||||
pci_cfg_access_unlock(dev);
|
||||
return mask_supported;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_intx_mask_supported);
|
||||
|
||||
static bool pci_check_and_set_intx_mask(struct pci_dev *dev, bool mask)
|
||||
{
|
||||
struct pci_bus *bus = dev->bus;
|
||||
bool mask_updated = true;
|
||||
u32 cmd_status_dword;
|
||||
u16 origcmd, newcmd;
|
||||
unsigned long flags;
|
||||
bool irq_pending;
|
||||
|
||||
/*
|
||||
* We do a single dword read to retrieve both command and status.
|
||||
* Document assumptions that make this possible.
|
||||
*/
|
||||
BUILD_BUG_ON(PCI_COMMAND % 4);
|
||||
BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
|
||||
|
||||
raw_spin_lock_irqsave(&pci_lock, flags);
|
||||
|
||||
bus->ops->read(bus, dev->devfn, PCI_COMMAND, 4, &cmd_status_dword);
|
||||
|
||||
irq_pending = (cmd_status_dword >> 16) & PCI_STATUS_INTERRUPT;
|
||||
|
||||
/*
|
||||
* Check interrupt status register to see whether our device
|
||||
* triggered the interrupt (when masking) or the next IRQ is
|
||||
* already pending (when unmasking).
|
||||
*/
|
||||
if (mask != irq_pending) {
|
||||
mask_updated = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
origcmd = cmd_status_dword;
|
||||
newcmd = origcmd & ~PCI_COMMAND_INTX_DISABLE;
|
||||
if (mask)
|
||||
newcmd |= PCI_COMMAND_INTX_DISABLE;
|
||||
if (newcmd != origcmd)
|
||||
bus->ops->write(bus, dev->devfn, PCI_COMMAND, 2, newcmd);
|
||||
|
||||
done:
|
||||
raw_spin_unlock_irqrestore(&pci_lock, flags);
|
||||
|
||||
return mask_updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_check_and_mask_intx - mask INTx on pending interrupt
|
||||
* @pdev: the PCI device to operate on
|
||||
*
|
||||
* Check if the device dev has its INTx line asserted, mask it and
|
||||
* return true in that case. False is returned if not interrupt was
|
||||
* pending.
|
||||
*/
|
||||
bool pci_check_and_mask_intx(struct pci_dev *dev)
|
||||
{
|
||||
return pci_check_and_set_intx_mask(dev, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_check_and_mask_intx);
|
||||
|
||||
/**
|
||||
* pci_check_and_mask_intx - unmask INTx of no interrupt is pending
|
||||
* @pdev: the PCI device to operate on
|
||||
*
|
||||
* Check if the device dev has its INTx line asserted, unmask it if not
|
||||
* and return true. False is returned and the mask remains active if
|
||||
* there was still an interrupt pending.
|
||||
*/
|
||||
bool pci_check_and_unmask_intx(struct pci_dev *dev)
|
||||
{
|
||||
return pci_check_and_set_intx_mask(dev, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_check_and_unmask_intx);
|
||||
|
||||
/**
|
||||
* pci_msi_off - disables any msi or msix capabilities
|
||||
* @dev: the PCI device to operate on
|
||||
|
@ -2965,7 +3108,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
|
|||
might_sleep();
|
||||
|
||||
if (!probe) {
|
||||
pci_block_user_cfg_access(dev);
|
||||
pci_cfg_access_lock(dev);
|
||||
/* block PM suspend, driver probe, etc. */
|
||||
device_lock(&dev->dev);
|
||||
}
|
||||
|
@ -2990,7 +3133,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
|
|||
done:
|
||||
if (!probe) {
|
||||
device_unlock(&dev->dev);
|
||||
pci_unblock_user_cfg_access(dev);
|
||||
pci_cfg_access_unlock(dev);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -136,6 +136,8 @@ static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }
|
|||
/* Lock for read/write access to pci device and bus lists */
|
||||
extern struct rw_semaphore pci_bus_sem;
|
||||
|
||||
extern raw_spinlock_t pci_lock;
|
||||
|
||||
extern unsigned int pci_pm_d3_delay;
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
|
@ -249,6 +251,14 @@ struct pci_sriov {
|
|||
u8 __iomem *mstate; /* VF Migration State Array */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI_ATS
|
||||
extern void pci_restore_ats_state(struct pci_dev *dev);
|
||||
#else
|
||||
static inline void pci_restore_ats_state(struct pci_dev *dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_PCI_ATS */
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
extern int pci_iov_init(struct pci_dev *dev);
|
||||
extern void pci_iov_release(struct pci_dev *dev);
|
||||
|
|
|
@ -39,7 +39,7 @@ config PCIEASPM
|
|||
Power Management) and Clock Power Management. ASPM supports
|
||||
state L0/L0s/L1.
|
||||
|
||||
ASPM is initially set up the the firmware. With this option enabled,
|
||||
ASPM is initially set up by the firmware. With this option enabled,
|
||||
Linux can modify this state in order to disable ASPM on known-bad
|
||||
hardware or configurations and enable it when known-safe.
|
||||
|
||||
|
|
|
@ -1522,19 +1522,21 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
|
|||
return max;
|
||||
}
|
||||
|
||||
struct pci_bus * pci_create_bus(struct device *parent,
|
||||
int bus, struct pci_ops *ops, void *sysdata)
|
||||
struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata, struct list_head *resources)
|
||||
{
|
||||
int error;
|
||||
int error, i;
|
||||
struct pci_bus *b, *b2;
|
||||
struct device *dev;
|
||||
struct pci_bus_resource *bus_res, *n;
|
||||
struct resource *res;
|
||||
|
||||
b = pci_alloc_bus();
|
||||
if (!b)
|
||||
return NULL;
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev){
|
||||
if (!dev) {
|
||||
kfree(b);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1577,8 +1579,20 @@ struct pci_bus * pci_create_bus(struct device *parent,
|
|||
pci_create_legacy_files(b);
|
||||
|
||||
b->number = b->secondary = bus;
|
||||
b->resource[0] = &ioport_resource;
|
||||
b->resource[1] = &iomem_resource;
|
||||
|
||||
/* Add initial resources to the bus */
|
||||
list_for_each_entry_safe(bus_res, n, resources, list)
|
||||
list_move_tail(&bus_res->list, &b->resources);
|
||||
|
||||
if (parent)
|
||||
dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
|
||||
else
|
||||
printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev));
|
||||
|
||||
pci_bus_for_each_resource(b, res, i) {
|
||||
if (res)
|
||||
dev_info(&b->dev, "root bus resource %pR\n", res);
|
||||
}
|
||||
|
||||
return b;
|
||||
|
||||
|
@ -1594,18 +1608,58 @@ err_out:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
|
||||
int bus, struct pci_ops *ops, void *sysdata)
|
||||
struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata, struct list_head *resources)
|
||||
{
|
||||
struct pci_bus *b;
|
||||
|
||||
b = pci_create_bus(parent, bus, ops, sysdata);
|
||||
b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
|
||||
if (!b)
|
||||
return NULL;
|
||||
|
||||
b->subordinate = pci_scan_child_bus(b);
|
||||
pci_bus_add_devices(b);
|
||||
return b;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_scan_root_bus);
|
||||
|
||||
/* Deprecated; use pci_scan_root_bus() instead */
|
||||
struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
|
||||
int bus, struct pci_ops *ops, void *sysdata)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *b;
|
||||
|
||||
pci_add_resource(&resources, &ioport_resource);
|
||||
pci_add_resource(&resources, &iomem_resource);
|
||||
b = pci_create_root_bus(parent, bus, ops, sysdata, &resources);
|
||||
if (b)
|
||||
b->subordinate = pci_scan_child_bus(b);
|
||||
else
|
||||
pci_free_resource_list(&resources);
|
||||
return b;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_scan_bus_parented);
|
||||
|
||||
struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
|
||||
void *sysdata)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *b;
|
||||
|
||||
pci_add_resource(&resources, &ioport_resource);
|
||||
pci_add_resource(&resources, &iomem_resource);
|
||||
b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
|
||||
if (b) {
|
||||
b->subordinate = pci_scan_child_bus(b);
|
||||
pci_bus_add_devices(b);
|
||||
} else {
|
||||
pci_free_resource_list(&resources);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_scan_bus);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
/**
|
||||
* pci_rescan_bus - scan a PCI bus for devices.
|
||||
|
|
|
@ -89,9 +89,8 @@ EXPORT_SYMBOL(pci_remove_bus);
|
|||
* device lists, remove the /proc entry, and notify userspace
|
||||
* (/sbin/hotplug).
|
||||
*/
|
||||
void pci_remove_bus_device(struct pci_dev *dev)
|
||||
static void __pci_remove_bus_device(struct pci_dev *dev)
|
||||
{
|
||||
pci_stop_bus_device(dev);
|
||||
if (dev->subordinate) {
|
||||
struct pci_bus *b = dev->subordinate;
|
||||
|
||||
|
@ -102,6 +101,11 @@ void pci_remove_bus_device(struct pci_dev *dev)
|
|||
|
||||
pci_destroy_dev(dev);
|
||||
}
|
||||
void pci_remove_bus_device(struct pci_dev *dev)
|
||||
{
|
||||
pci_stop_bus_device(dev);
|
||||
__pci_remove_bus_device(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_remove_behind_bridge - remove all devices behind a PCI bridge
|
||||
|
@ -117,7 +121,7 @@ void pci_remove_behind_bridge(struct pci_dev *dev)
|
|||
|
||||
if (dev->subordinate)
|
||||
list_for_each_safe(l, n, &dev->subordinate->devices)
|
||||
pci_remove_bus_device(pci_dev_b(l));
|
||||
__pci_remove_bus_device(pci_dev_b(l));
|
||||
}
|
||||
|
||||
static void pci_stop_bus_devices(struct pci_bus *bus)
|
||||
|
|
|
@ -85,9 +85,9 @@ void pci_update_resource(struct pci_dev *dev, int resno)
|
|||
}
|
||||
}
|
||||
res->flags &= ~IORESOURCE_UNSET;
|
||||
dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n",
|
||||
resno, res, (unsigned long long)region.start,
|
||||
(unsigned long long)region.end);
|
||||
dev_dbg(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n",
|
||||
resno, res, (unsigned long long)region.start,
|
||||
(unsigned long long)region.end);
|
||||
}
|
||||
|
||||
int pci_claim_resource(struct pci_dev *dev, int resource)
|
||||
|
|
|
@ -295,6 +295,45 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AMD_NB
|
||||
|
||||
#include <asm/amd_nb.h>
|
||||
|
||||
static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
|
||||
{
|
||||
resource_size_t start, end;
|
||||
struct pnp_resource *pnp_res;
|
||||
struct resource *res;
|
||||
struct resource mmconfig_res, *mmconfig;
|
||||
|
||||
mmconfig = amd_get_mmconfig_range(&mmconfig_res);
|
||||
if (!mmconfig)
|
||||
return;
|
||||
|
||||
list_for_each_entry(pnp_res, &dev->resources, list) {
|
||||
res = &pnp_res->res;
|
||||
if (res->end < mmconfig->start || res->start > mmconfig->end ||
|
||||
(res->start == mmconfig->start && res->end == mmconfig->end))
|
||||
continue;
|
||||
|
||||
dev_info(&dev->dev, FW_BUG
|
||||
"%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
|
||||
res, mmconfig);
|
||||
if (mmconfig->start < res->start) {
|
||||
start = mmconfig->start;
|
||||
end = res->start - 1;
|
||||
pnp_add_mem_resource(dev, start, end, 0);
|
||||
}
|
||||
if (mmconfig->end > res->end) {
|
||||
start = res->end + 1;
|
||||
end = mmconfig->end;
|
||||
pnp_add_mem_resource(dev, start, end, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PnP Quirks
|
||||
* Cards or devices that need some tweaking due to incomplete resource info
|
||||
|
@ -322,6 +361,9 @@ static struct pnp_fixup pnp_fixups[] = {
|
|||
/* PnP resources that might overlap PCI BARs */
|
||||
{"PNP0c01", quirk_system_pci_resources},
|
||||
{"PNP0c02", quirk_system_pci_resources},
|
||||
#ifdef CONFIG_AMD_NB
|
||||
{"PNP0c01", quirk_amd_mmconfig_area},
|
||||
#endif
|
||||
{""}
|
||||
};
|
||||
|
||||
|
|
|
@ -7638,8 +7638,12 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
|
|||
**/
|
||||
static int ipr_reset_bist_done(struct ipr_cmnd *ipr_cmd)
|
||||
{
|
||||
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
|
||||
|
||||
ENTER;
|
||||
pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
|
||||
if (ioa_cfg->cfg_locked)
|
||||
pci_cfg_access_unlock(ioa_cfg->pdev);
|
||||
ioa_cfg->cfg_locked = 0;
|
||||
ipr_cmd->job_step = ipr_reset_restore_cfg_space;
|
||||
LEAVE;
|
||||
return IPR_RC_JOB_CONTINUE;
|
||||
|
@ -7660,8 +7664,6 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
|
|||
int rc = PCIBIOS_SUCCESSFUL;
|
||||
|
||||
ENTER;
|
||||
pci_block_user_cfg_access(ioa_cfg->pdev);
|
||||
|
||||
if (ioa_cfg->ipr_chip->bist_method == IPR_MMIO)
|
||||
writel(IPR_UPROCI_SIS64_START_BIST,
|
||||
ioa_cfg->regs.set_uproc_interrupt_reg32);
|
||||
|
@ -7673,7 +7675,9 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
|
|||
ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT);
|
||||
rc = IPR_RC_JOB_RETURN;
|
||||
} else {
|
||||
pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
|
||||
if (ioa_cfg->cfg_locked)
|
||||
pci_cfg_access_unlock(ipr_cmd->ioa_cfg->pdev);
|
||||
ioa_cfg->cfg_locked = 0;
|
||||
ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
|
||||
rc = IPR_RC_JOB_CONTINUE;
|
||||
}
|
||||
|
@ -7716,7 +7720,6 @@ static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd)
|
|||
struct pci_dev *pdev = ioa_cfg->pdev;
|
||||
|
||||
ENTER;
|
||||
pci_block_user_cfg_access(pdev);
|
||||
pci_set_pcie_reset_state(pdev, pcie_warm_reset);
|
||||
ipr_cmd->job_step = ipr_reset_slot_reset_done;
|
||||
ipr_reset_start_timer(ipr_cmd, IPR_PCI_RESET_TIMEOUT);
|
||||
|
@ -7724,6 +7727,56 @@ static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd)
|
|||
return IPR_RC_JOB_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_reset_block_config_access_wait - Wait for permission to block config access
|
||||
* @ipr_cmd: ipr command struct
|
||||
*
|
||||
* Description: This attempts to block config access to the IOA.
|
||||
*
|
||||
* Return value:
|
||||
* IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
|
||||
**/
|
||||
static int ipr_reset_block_config_access_wait(struct ipr_cmnd *ipr_cmd)
|
||||
{
|
||||
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
|
||||
int rc = IPR_RC_JOB_CONTINUE;
|
||||
|
||||
if (pci_cfg_access_trylock(ioa_cfg->pdev)) {
|
||||
ioa_cfg->cfg_locked = 1;
|
||||
ipr_cmd->job_step = ioa_cfg->reset;
|
||||
} else {
|
||||
if (ipr_cmd->u.time_left) {
|
||||
rc = IPR_RC_JOB_RETURN;
|
||||
ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
|
||||
ipr_reset_start_timer(ipr_cmd,
|
||||
IPR_CHECK_FOR_RESET_TIMEOUT);
|
||||
} else {
|
||||
ipr_cmd->job_step = ioa_cfg->reset;
|
||||
dev_err(&ioa_cfg->pdev->dev,
|
||||
"Timed out waiting to lock config access. Resetting anyway.\n");
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_reset_block_config_access - Block config access to the IOA
|
||||
* @ipr_cmd: ipr command struct
|
||||
*
|
||||
* Description: This attempts to block config access to the IOA
|
||||
*
|
||||
* Return value:
|
||||
* IPR_RC_JOB_CONTINUE
|
||||
**/
|
||||
static int ipr_reset_block_config_access(struct ipr_cmnd *ipr_cmd)
|
||||
{
|
||||
ipr_cmd->ioa_cfg->cfg_locked = 0;
|
||||
ipr_cmd->job_step = ipr_reset_block_config_access_wait;
|
||||
ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT;
|
||||
return IPR_RC_JOB_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_reset_allowed - Query whether or not IOA can be reset
|
||||
* @ioa_cfg: ioa config struct
|
||||
|
@ -7763,7 +7816,7 @@ static int ipr_reset_wait_to_start_bist(struct ipr_cmnd *ipr_cmd)
|
|||
ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
|
||||
ipr_reset_start_timer(ipr_cmd, IPR_CHECK_FOR_RESET_TIMEOUT);
|
||||
} else {
|
||||
ipr_cmd->job_step = ioa_cfg->reset;
|
||||
ipr_cmd->job_step = ipr_reset_block_config_access;
|
||||
rc = IPR_RC_JOB_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -7796,7 +7849,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd)
|
|||
writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32);
|
||||
ipr_cmd->job_step = ipr_reset_wait_to_start_bist;
|
||||
} else {
|
||||
ipr_cmd->job_step = ioa_cfg->reset;
|
||||
ipr_cmd->job_step = ipr_reset_block_config_access;
|
||||
}
|
||||
|
||||
ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT;
|
||||
|
|
|
@ -1387,6 +1387,7 @@ struct ipr_ioa_cfg {
|
|||
u8 msi_received:1;
|
||||
u8 sis64:1;
|
||||
u8 dump_timeout:1;
|
||||
u8 cfg_locked:1;
|
||||
|
||||
u8 revid;
|
||||
|
||||
|
|
|
@ -45,77 +45,12 @@ to_uio_pci_generic_dev(struct uio_info *info)
|
|||
static irqreturn_t irqhandler(int irq, struct uio_info *info)
|
||||
{
|
||||
struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
|
||||
struct pci_dev *pdev = gdev->pdev;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
u32 cmd_status_dword;
|
||||
u16 origcmd, newcmd, status;
|
||||
|
||||
/* We do a single dword read to retrieve both command and status.
|
||||
* Document assumptions that make this possible. */
|
||||
BUILD_BUG_ON(PCI_COMMAND % 4);
|
||||
BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
|
||||
|
||||
pci_block_user_cfg_access(pdev);
|
||||
|
||||
/* Read both command and status registers in a single 32-bit operation.
|
||||
* Note: we could cache the value for command and move the status read
|
||||
* out of the lock if there was a way to get notified of user changes
|
||||
* to command register through sysfs. Should be good for shared irqs. */
|
||||
pci_read_config_dword(pdev, PCI_COMMAND, &cmd_status_dword);
|
||||
origcmd = cmd_status_dword;
|
||||
status = cmd_status_dword >> 16;
|
||||
|
||||
/* Check interrupt status register to see whether our device
|
||||
* triggered the interrupt. */
|
||||
if (!(status & PCI_STATUS_INTERRUPT))
|
||||
goto done;
|
||||
|
||||
/* We triggered the interrupt, disable it. */
|
||||
newcmd = origcmd | PCI_COMMAND_INTX_DISABLE;
|
||||
if (newcmd != origcmd)
|
||||
pci_write_config_word(pdev, PCI_COMMAND, newcmd);
|
||||
if (!pci_check_and_mask_intx(gdev->pdev))
|
||||
return IRQ_NONE;
|
||||
|
||||
/* UIO core will signal the user process. */
|
||||
ret = IRQ_HANDLED;
|
||||
done:
|
||||
|
||||
pci_unblock_user_cfg_access(pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Verify that the device supports Interrupt Disable bit in command register,
|
||||
* per PCI 2.3, by flipping this bit and reading it back: this bit was readonly
|
||||
* in PCI 2.2. */
|
||||
static int __devinit verify_pci_2_3(struct pci_dev *pdev)
|
||||
{
|
||||
u16 orig, new;
|
||||
int err = 0;
|
||||
|
||||
pci_block_user_cfg_access(pdev);
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &orig);
|
||||
pci_write_config_word(pdev, PCI_COMMAND,
|
||||
orig ^ PCI_COMMAND_INTX_DISABLE);
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &new);
|
||||
/* There's no way to protect against
|
||||
* hardware bugs or detect them reliably, but as long as we know
|
||||
* what the value should be, let's go ahead and check it. */
|
||||
if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
|
||||
err = -EBUSY;
|
||||
dev_err(&pdev->dev, "Command changed from 0x%x to 0x%x: "
|
||||
"driver or HW bug?\n", orig, new);
|
||||
goto err;
|
||||
}
|
||||
if (!((new ^ orig) & PCI_COMMAND_INTX_DISABLE)) {
|
||||
dev_warn(&pdev->dev, "Device does not support "
|
||||
"disabling interrupts: unable to bind.\n");
|
||||
err = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
/* Now restore the original value. */
|
||||
pci_write_config_word(pdev, PCI_COMMAND, orig);
|
||||
err:
|
||||
pci_unblock_user_cfg_access(pdev);
|
||||
return err;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __devinit probe(struct pci_dev *pdev,
|
||||
|
@ -138,9 +73,10 @@ static int __devinit probe(struct pci_dev *pdev,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = verify_pci_2_3(pdev);
|
||||
if (err)
|
||||
if (!pci_intx_mask_supported(pdev)) {
|
||||
err = -ENODEV;
|
||||
goto err_verify;
|
||||
}
|
||||
|
||||
gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
|
||||
if (!gdev) {
|
||||
|
|
|
@ -111,7 +111,7 @@ enum {
|
|||
PCI_NUM_RESOURCES,
|
||||
|
||||
/* preserve this for compatibility */
|
||||
DEVICE_COUNT_RESOURCE
|
||||
DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES,
|
||||
};
|
||||
|
||||
typedef int __bitwise pci_power_t;
|
||||
|
@ -308,7 +308,7 @@ struct pci_dev {
|
|||
unsigned int is_added:1;
|
||||
unsigned int is_busmaster:1; /* device is busmaster */
|
||||
unsigned int no_msi:1; /* device may not use msi */
|
||||
unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
|
||||
unsigned int block_cfg_access:1; /* config space access is blocked */
|
||||
unsigned int broken_parity_status:1; /* Device generates false positive parity */
|
||||
unsigned int irq_reroute_variant:2; /* device needs IRQ rerouting variant */
|
||||
unsigned int msi_enabled:1;
|
||||
|
@ -661,17 +661,13 @@ extern struct pci_bus *pci_find_bus(int domain, int busnr);
|
|||
void pci_bus_add_devices(const struct pci_bus *bus);
|
||||
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata);
|
||||
static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
|
||||
void *sysdata)
|
||||
{
|
||||
struct pci_bus *root_bus;
|
||||
root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata);
|
||||
if (root_bus)
|
||||
pci_bus_add_devices(root_bus);
|
||||
return root_bus;
|
||||
}
|
||||
struct pci_bus *pci_create_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata);
|
||||
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
|
||||
struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata,
|
||||
struct list_head *resources);
|
||||
struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata,
|
||||
struct list_head *resources);
|
||||
struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
|
||||
int busnr);
|
||||
void pcie_update_link_speed(struct pci_bus *bus, u16 link_status);
|
||||
|
@ -795,8 +791,11 @@ static inline int pci_is_managed(struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
void pci_disable_device(struct pci_dev *dev);
|
||||
|
||||
extern unsigned int pcibios_max_latency;
|
||||
void pci_set_master(struct pci_dev *dev);
|
||||
void pci_clear_master(struct pci_dev *dev);
|
||||
|
||||
int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);
|
||||
int pci_set_cacheline_size(struct pci_dev *dev);
|
||||
#define HAVE_PCI_SET_MWI
|
||||
|
@ -804,6 +803,9 @@ int __must_check pci_set_mwi(struct pci_dev *dev);
|
|||
int pci_try_set_mwi(struct pci_dev *dev);
|
||||
void pci_clear_mwi(struct pci_dev *dev);
|
||||
void pci_intx(struct pci_dev *dev, int enable);
|
||||
bool pci_intx_mask_supported(struct pci_dev *dev);
|
||||
bool pci_check_and_mask_intx(struct pci_dev *dev);
|
||||
bool pci_check_and_unmask_intx(struct pci_dev *dev);
|
||||
void pci_msi_off(struct pci_dev *dev);
|
||||
int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size);
|
||||
int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask);
|
||||
|
@ -911,6 +913,8 @@ int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *);
|
|||
void pci_release_selected_regions(struct pci_dev *, int);
|
||||
|
||||
/* drivers/pci/bus.c */
|
||||
void pci_add_resource(struct list_head *resources, struct resource *res);
|
||||
void pci_free_resource_list(struct list_head *resources);
|
||||
void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags);
|
||||
struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n);
|
||||
void pci_bus_remove_resources(struct pci_bus *bus);
|
||||
|
@ -1085,8 +1089,9 @@ int ht_create_irq(struct pci_dev *dev, int idx);
|
|||
void ht_destroy_irq(unsigned int irq);
|
||||
#endif /* CONFIG_HT_IRQ */
|
||||
|
||||
extern void pci_block_user_cfg_access(struct pci_dev *dev);
|
||||
extern void pci_unblock_user_cfg_access(struct pci_dev *dev);
|
||||
extern void pci_cfg_access_lock(struct pci_dev *dev);
|
||||
extern bool pci_cfg_access_trylock(struct pci_dev *dev);
|
||||
extern void pci_cfg_access_unlock(struct pci_dev *dev);
|
||||
|
||||
/*
|
||||
* PCI domain support. Sometimes called PCI segment (eg by ACPI),
|
||||
|
@ -1283,10 +1288,13 @@ static inline void pci_release_regions(struct pci_dev *dev)
|
|||
|
||||
#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
|
||||
|
||||
static inline void pci_block_user_cfg_access(struct pci_dev *dev)
|
||||
static inline void pci_block_cfg_access(struct pci_dev *dev)
|
||||
{ }
|
||||
|
||||
static inline void pci_unblock_user_cfg_access(struct pci_dev *dev)
|
||||
static inline int pci_block_cfg_access_in_atomic(struct pci_dev *dev)
|
||||
{ return 0; }
|
||||
|
||||
static inline void pci_unblock_cfg_access(struct pci_dev *dev)
|
||||
{ }
|
||||
|
||||
static inline struct pci_bus *pci_find_next_bus(const struct pci_bus *from)
|
||||
|
@ -1424,10 +1432,10 @@ static inline void pci_fixup_device(enum pci_fixup_pass pass,
|
|||
void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
|
||||
void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr);
|
||||
void __iomem * const *pcim_iomap_table(struct pci_dev *pdev);
|
||||
int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name);
|
||||
int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask,
|
||||
int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name);
|
||||
int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,
|
||||
const char *name);
|
||||
void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask);
|
||||
void pcim_iounmap_regions(struct pci_dev *pdev, int mask);
|
||||
|
||||
extern int pci_pci_problems;
|
||||
#define PCIPCI_FAIL 1 /* No PCI PCI DMA */
|
||||
|
@ -1446,8 +1454,10 @@ extern u8 pci_cache_line_size;
|
|||
extern unsigned long pci_hotplug_io_size;
|
||||
extern unsigned long pci_hotplug_mem_size;
|
||||
|
||||
/* Architecture specific versions may override these (weak) */
|
||||
int pcibios_add_platform_entries(struct pci_dev *dev);
|
||||
void pcibios_disable_device(struct pci_dev *dev);
|
||||
void pcibios_set_master(struct pci_dev *dev);
|
||||
int pcibios_set_pcie_reset_state(struct pci_dev *dev,
|
||||
enum pcie_reset_state state);
|
||||
|
||||
|
|
|
@ -776,6 +776,29 @@
|
|||
#define PCI_DEVICE_ID_ELSA_QS3000 0x3000
|
||||
|
||||
#define PCI_VENDOR_ID_STMICRO 0x104A
|
||||
#define PCI_DEVICE_ID_STMICRO_USB_HOST 0xCC00
|
||||
#define PCI_DEVICE_ID_STMICRO_USB_OHCI 0xCC01
|
||||
#define PCI_DEVICE_ID_STMICRO_USB_OTG 0xCC02
|
||||
#define PCI_DEVICE_ID_STMICRO_UART_HWFC 0xCC03
|
||||
#define PCI_DEVICE_ID_STMICRO_UART_NO_HWFC 0xCC04
|
||||
#define PCI_DEVICE_ID_STMICRO_SOC_DMA 0xCC05
|
||||
#define PCI_DEVICE_ID_STMICRO_SATA 0xCC06
|
||||
#define PCI_DEVICE_ID_STMICRO_I2C 0xCC07
|
||||
#define PCI_DEVICE_ID_STMICRO_SPI_HS 0xCC08
|
||||
#define PCI_DEVICE_ID_STMICRO_MAC 0xCC09
|
||||
#define PCI_DEVICE_ID_STMICRO_SDIO_EMMC 0xCC0A
|
||||
#define PCI_DEVICE_ID_STMICRO_SDIO 0xCC0B
|
||||
#define PCI_DEVICE_ID_STMICRO_GPIO 0xCC0C
|
||||
#define PCI_DEVICE_ID_STMICRO_VIP 0xCC0D
|
||||
#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_DMA 0xCC0E
|
||||
#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_SRCS 0xCC0F
|
||||
#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_MSPS 0xCC10
|
||||
#define PCI_DEVICE_ID_STMICRO_CAN 0xCC11
|
||||
#define PCI_DEVICE_ID_STMICRO_MLB 0xCC12
|
||||
#define PCI_DEVICE_ID_STMICRO_DBP 0xCC13
|
||||
#define PCI_DEVICE_ID_STMICRO_SATA_PHY 0xCC14
|
||||
#define PCI_DEVICE_ID_STMICRO_ESRAM 0xCC15
|
||||
#define PCI_DEVICE_ID_STMICRO_VIC 0xCC16
|
||||
|
||||
#define PCI_VENDOR_ID_BUSLOGIC 0x104B
|
||||
#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
|
||||
|
|
|
@ -392,7 +392,7 @@
|
|||
#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
|
||||
#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
|
||||
#define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */
|
||||
#define PCI_EXP_TYPE_RC_EC 0x10 /* Root Complex Event Collector */
|
||||
#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
|
||||
#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
|
||||
#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
|
||||
#define PCI_EXP_DEVCAP 4 /* Device capabilities */
|
||||
|
|
|
@ -304,7 +304,7 @@ EXPORT_SYMBOL(pcim_iounmap);
|
|||
*
|
||||
* Request and iomap regions specified by @mask.
|
||||
*/
|
||||
int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name)
|
||||
int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name)
|
||||
{
|
||||
void __iomem * const *iomap;
|
||||
int i, rc;
|
||||
|
@ -357,7 +357,7 @@ EXPORT_SYMBOL(pcim_iomap_regions);
|
|||
*
|
||||
* Request all PCI BARs and iomap regions specified by @mask.
|
||||
*/
|
||||
int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask,
|
||||
int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,
|
||||
const char *name)
|
||||
{
|
||||
int request_mask = ((1 << 6) - 1) & ~mask;
|
||||
|
@ -381,7 +381,7 @@ EXPORT_SYMBOL(pcim_iomap_regions_request_all);
|
|||
*
|
||||
* Unmap and release regions specified by @mask.
|
||||
*/
|
||||
void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask)
|
||||
void pcim_iounmap_regions(struct pci_dev *pdev, int mask)
|
||||
{
|
||||
void __iomem * const *iomap;
|
||||
int i;
|
||||
|
|
Загрузка…
Ссылка в новой задаче