Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci
Pull PCI changes (including maintainer change) from Jesse Barnes: "This pull has some good cleanups from Bjorn and Yinghai, as well as some more code from Yinghai to better handle resource re-allocation when enabled. There's also a new initcall_debug feature from Arjan which will print out quirk timing information to help identify slow quirks for fixing or refinement (Yinghai sent in a few patches to do just that once the new debug code landed). Beyond that, I'm handing off PCI maintainership to Bjorn Helgaas. He's been a core PCI and Linux contributor for some time now, and has kindly volunteered to take over. I just don't feel I have the time for PCI review and work that it deserves lately (I've taken on some other projects), and haven't been as responsive lately as I'd like, so I approached Bjorn asking if he'd like to manage things. He's going to give it a try, and I'm confident he'll do at least as well as I have in keeping the tree managed, patches flowing, and keeping things stable." Fix up some fairly trivial conflicts due to other cleanups (mips device resource fixup cleanups clashing with list handling cleanup, ppc iseries removal clashing with pci_probe_only cleanup etc) * 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci: (112 commits) PCI: Bjorn gets PCI hotplug too PCI: hand PCI maintenance over to Bjorn Helgaas unicore32/PCI: move <asm-generic/pci-bridge.h> include to asm/pci.h sparc/PCI: convert devtree and arch-probed bus addresses to resource powerpc/PCI: allow reallocation on PA Semi powerpc/PCI: convert devtree bus addresses to resource powerpc/PCI: compute I/O space bus-to-resource offset consistently arm/PCI: don't export pci_flags PCI: fix bridge I/O window bus-to-resource conversion x86/PCI: add spinlock held check to 'pcibios_fwaddrmap_lookup()' PCI / PCIe: Introduce command line option to disable ARI PCI: make acpihp use __pci_remove_bus_device instead PCI: export __pci_remove_bus_device PCI: Rename pci_remove_behind_bridge to pci_stop_and_remove_behind_bridge PCI: Rename pci_remove_bus_device to pci_stop_and_remove_bus_device PCI: print out PCI device info along with duration PCI: Move "pci reassigndev resource alignment" out of quirks.c PCI: Use class for quirk for usb host controller fixup PCI: Use class for quirk for ti816x class fixup PCI: Use class for quirk for intel e100 interrupt fixup ...
This commit is contained in:
commit
475c77edf8
119 changed files with 1654 additions and 1706 deletions
|
@ -2147,8 +2147,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
the default.
|
||||
off: Turn ECRC off
|
||||
on: Turn ECRC on.
|
||||
realloc reallocate PCI resources if allocations done by BIOS
|
||||
are erroneous.
|
||||
realloc= Enable/disable reallocating PCI bridge resources
|
||||
if allocations done by BIOS are too small to
|
||||
accommodate resources required by all child
|
||||
devices.
|
||||
off: Turn realloc off
|
||||
on: Turn realloc on
|
||||
realloc same as realloc=on
|
||||
noari do not use PCIe ARI.
|
||||
|
||||
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
|
||||
Management.
|
||||
|
@ -2156,6 +2162,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
force Enable ASPM even on devices that claim not to support it.
|
||||
WARNING: Forcing ASPM on may cause system lockups.
|
||||
|
||||
pcie_hp= [PCIE] PCI Express Hotplug driver options:
|
||||
nomsi Do not use MSI for PCI Express Native Hotplug (this
|
||||
makes all PCIe ports use INTx for hotplug services).
|
||||
|
||||
pcie_ports= [PCIE] PCIe ports handling:
|
||||
auto Ask the BIOS whether or not to use native PCIe services
|
||||
associated with PCIe ports (PME, hot-plug, AER). Use
|
||||
|
|
|
@ -5120,7 +5120,7 @@ F: Documentation/PCI/pci-error-recovery.txt
|
|||
F: Documentation/powerpc/eeh-pci-error-recovery.txt
|
||||
|
||||
PCI SUBSYSTEM
|
||||
M: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
M: Bjorn Helgaas <bhelgaas@google.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
Q: http://patchwork.kernel.org/project/linux-pci/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
|
||||
|
@ -5130,7 +5130,7 @@ F: drivers/pci/
|
|||
F: include/linux/pci*
|
||||
|
||||
PCI HOTPLUG
|
||||
M: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
M: Bjorn Helgaas <bhelgaas@google.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/pci/hotplug
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/dma-mapping.h>
|
||||
#include <asm/scatterlist.h>
|
||||
#include <asm/machvec.h>
|
||||
#include <asm-generic/pci-bridge.h>
|
||||
|
||||
/*
|
||||
* The following structure is used to manage multiple PCI busses.
|
||||
|
@ -99,12 +100,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
|
|||
return channel ? 15 : 14;
|
||||
}
|
||||
|
||||
extern void pcibios_resource_to_bus(struct pci_dev *, struct pci_bus_region *,
|
||||
struct resource *);
|
||||
|
||||
extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
|
||||
|
||||
static inline int pci_proc_domain(struct pci_bus *bus)
|
||||
|
|
|
@ -43,12 +43,10 @@ const char *const pci_mem_names[] = {
|
|||
|
||||
const char pci_hae0_name[] = "HAE0";
|
||||
|
||||
/* Indicate whether we respect the PCI setup left by console. */
|
||||
/*
|
||||
* Make this long-lived so that we know when shutting down
|
||||
* whether we probed only or not.
|
||||
* If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource
|
||||
* assignments.
|
||||
*/
|
||||
int pci_probe_only;
|
||||
|
||||
/*
|
||||
* The PCI controller list.
|
||||
|
@ -215,7 +213,7 @@ pdev_save_srm_config(struct pci_dev *dev)
|
|||
struct pdev_srm_saved_conf *tmp;
|
||||
static int printed = 0;
|
||||
|
||||
if (!alpha_using_srm || pci_probe_only)
|
||||
if (!alpha_using_srm || pci_has_flag(PCI_PROBE_ONLY))
|
||||
return;
|
||||
|
||||
if (!printed) {
|
||||
|
@ -242,7 +240,7 @@ pci_restore_srm_config(void)
|
|||
struct pdev_srm_saved_conf *tmp;
|
||||
|
||||
/* No need to restore if probed only. */
|
||||
if (pci_probe_only)
|
||||
if (pci_has_flag(PCI_PROBE_ONLY))
|
||||
return;
|
||||
|
||||
/* Restore SRM config. */
|
||||
|
@ -252,47 +250,18 @@ pci_restore_srm_config(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
void __devinit
|
||||
pcibios_fixup_resource(struct resource *res, struct resource *root)
|
||||
{
|
||||
res->start += root->start;
|
||||
res->end += root->start;
|
||||
}
|
||||
|
||||
void __devinit
|
||||
pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
|
||||
{
|
||||
/* Update device resources. */
|
||||
struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
|
||||
if (!dev->resource[i].start)
|
||||
continue;
|
||||
if (dev->resource[i].flags & IORESOURCE_IO)
|
||||
pcibios_fixup_resource(&dev->resource[i],
|
||||
hose->io_space);
|
||||
else if (dev->resource[i].flags & IORESOURCE_MEM)
|
||||
pcibios_fixup_resource(&dev->resource[i],
|
||||
hose->mem_space);
|
||||
}
|
||||
}
|
||||
|
||||
void __devinit
|
||||
pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev = bus->self;
|
||||
|
||||
if (pci_probe_only && dev &&
|
||||
if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
pci_read_bridge_bases(bus);
|
||||
pcibios_fixup_device_resources(dev, bus);
|
||||
}
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
pdev_save_srm_config(dev);
|
||||
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
|
||||
pcibios_fixup_device_resources(dev, bus);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,42 +271,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
|
|||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
void
|
||||
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
|
||||
unsigned long offset = 0;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
offset = hose->io_space->start;
|
||||
else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->mem_space->start;
|
||||
|
||||
region->start = res->start - offset;
|
||||
region->end = res->end - offset;
|
||||
}
|
||||
|
||||
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
|
||||
unsigned long offset = 0;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
offset = hose->io_space->start;
|
||||
else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->mem_space->start;
|
||||
|
||||
res->start = region->start + offset;
|
||||
res->end = region->end + offset;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
#endif
|
||||
|
||||
int
|
||||
pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
|
@ -374,7 +307,8 @@ pcibios_claim_one_bus(struct pci_bus *b)
|
|||
|
||||
if (r->parent || !r->start || !r->flags)
|
||||
continue;
|
||||
if (pci_probe_only || (r->flags & IORESOURCE_PCI_FIXED))
|
||||
if (pci_has_flag(PCI_PROBE_ONLY) ||
|
||||
(r->flags & IORESOURCE_PCI_FIXED))
|
||||
pci_claim_resource(dev, i);
|
||||
}
|
||||
}
|
||||
|
@ -416,8 +350,10 @@ common_init_pci(void)
|
|||
hose->mem_space->end = end;
|
||||
|
||||
INIT_LIST_HEAD(&resources);
|
||||
pci_add_resource(&resources, hose->io_space);
|
||||
pci_add_resource(&resources, hose->mem_space);
|
||||
pci_add_resource_offset(&resources, hose->io_space,
|
||||
hose->io_space->start);
|
||||
pci_add_resource_offset(&resources, hose->mem_space,
|
||||
hose->mem_space->start);
|
||||
|
||||
bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops,
|
||||
hose, &resources);
|
||||
|
|
|
@ -173,9 +173,6 @@ extern void pci_restore_srm_config(void);
|
|||
extern struct pci_controller *hose_head, **hose_tail;
|
||||
extern struct pci_controller *pci_isa_hose;
|
||||
|
||||
/* Indicate that we trust the console to configure things properly. */
|
||||
extern int pci_probe_only;
|
||||
|
||||
extern unsigned long alpha_agpgart_size;
|
||||
|
||||
extern void common_init_pci(void);
|
||||
|
|
|
@ -384,7 +384,8 @@ marvel_init_pci(void)
|
|||
|
||||
marvel_register_error_handlers();
|
||||
|
||||
pci_probe_only = 1;
|
||||
/* Indicate that we trust the console to configure things properly */
|
||||
pci_set_flags(PCI_PROBE_ONLY);
|
||||
common_init_pci();
|
||||
locate_and_init_vga(NULL);
|
||||
|
||||
|
|
|
@ -331,7 +331,8 @@ titan_init_pci(void)
|
|||
*/
|
||||
titan_late_init();
|
||||
|
||||
pci_probe_only = 1;
|
||||
/* Indicate that we trust the console to configure things properly */
|
||||
pci_set_flags(PCI_PROBE_ONLY);
|
||||
common_init_pci();
|
||||
SMC669_Init(0);
|
||||
locate_and_init_vga(NULL);
|
||||
|
|
|
@ -299,8 +299,8 @@ int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
goto err1;
|
||||
}
|
||||
|
||||
pci_add_resource(&sys->resources, &it8152_io);
|
||||
pci_add_resource(&sys->resources, &it8152_mem);
|
||||
pci_add_resource_offset(&sys->resources, &it8152_io, sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, &it8152_mem, sys->mem_offset);
|
||||
|
||||
if (platform_notify || platform_notify_remove) {
|
||||
printk(KERN_ERR "PCI: Can't use platform_notify\n");
|
||||
|
|
|
@ -57,14 +57,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
|
|||
extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
enum pci_mmap_state mmap_state, int write_combine);
|
||||
|
||||
extern void
|
||||
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res);
|
||||
|
||||
extern void
|
||||
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
/*
|
||||
* Dummy implementation; always return 0.
|
||||
*/
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <asm/mach/pci.h>
|
||||
|
||||
static int debug_pci;
|
||||
static int use_firmware;
|
||||
|
||||
/*
|
||||
* We can't use pci_find_device() here since we are
|
||||
|
@ -294,28 +293,6 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev)
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust the device resources from bus-centric to Linux-centric.
|
||||
*/
|
||||
static void __devinit
|
||||
pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
|
||||
{
|
||||
resource_size_t offset;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
|
||||
if (dev->resource[i].start == 0)
|
||||
continue;
|
||||
if (dev->resource[i].flags & IORESOURCE_MEM)
|
||||
offset = root->mem_offset;
|
||||
else
|
||||
offset = root->io_offset;
|
||||
|
||||
dev->resource[i].start += offset;
|
||||
dev->resource[i].end += offset;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pcibios_fixup_bus - Called after each bus is probed,
|
||||
* but before its children are examined.
|
||||
|
@ -333,8 +310,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
|
|||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
u16 status;
|
||||
|
||||
pdev_fixup_device_resources(root, dev);
|
||||
|
||||
pci_read_config_word(dev, PCI_STATUS, &status);
|
||||
|
||||
/*
|
||||
|
@ -399,43 +374,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
|
|||
EXPORT_SYMBOL(pcibios_fixup_bus);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert from Linux-centric to bus-centric addresses for bridge devices.
|
||||
*/
|
||||
void
|
||||
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
struct pci_sys_data *root = dev->sysdata;
|
||||
unsigned long offset = 0;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
offset = root->io_offset;
|
||||
if (res->flags & IORESOURCE_MEM)
|
||||
offset = root->mem_offset;
|
||||
|
||||
region->start = res->start - offset;
|
||||
region->end = res->end - offset;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
|
||||
void __devinit
|
||||
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
struct pci_sys_data *root = dev->sysdata;
|
||||
unsigned long offset = 0;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
offset = root->io_offset;
|
||||
if (res->flags & IORESOURCE_MEM)
|
||||
offset = root->mem_offset;
|
||||
|
||||
res->start = region->start + offset;
|
||||
res->end = region->end + offset;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
|
||||
/*
|
||||
* Swizzle the device pin each time we cross a bridge.
|
||||
* This might update pin and returns the slot number.
|
||||
|
@ -497,10 +435,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
|
|||
|
||||
if (ret > 0) {
|
||||
if (list_empty(&sys->resources)) {
|
||||
pci_add_resource(&sys->resources,
|
||||
&ioport_resource);
|
||||
pci_add_resource(&sys->resources,
|
||||
&iomem_resource);
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&ioport_resource, sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&iomem_resource, sys->mem_offset);
|
||||
}
|
||||
|
||||
sys->bus = hw->scan(nr, sys);
|
||||
|
@ -525,6 +463,7 @@ void __init pci_common_init(struct hw_pci *hw)
|
|||
|
||||
INIT_LIST_HEAD(&hw->buses);
|
||||
|
||||
pci_add_flags(PCI_REASSIGN_ALL_RSRC);
|
||||
if (hw->preinit)
|
||||
hw->preinit();
|
||||
pcibios_init_hw(hw);
|
||||
|
@ -536,7 +475,7 @@ void __init pci_common_init(struct hw_pci *hw)
|
|||
list_for_each_entry(sys, &hw->buses, node) {
|
||||
struct pci_bus *bus = sys->bus;
|
||||
|
||||
if (!use_firmware) {
|
||||
if (!pci_has_flag(PCI_PROBE_ONLY)) {
|
||||
/*
|
||||
* Size the bridge windows.
|
||||
*/
|
||||
|
@ -573,7 +512,7 @@ char * __init pcibios_setup(char *str)
|
|||
debug_pci = 1;
|
||||
return NULL;
|
||||
} else if (!strcmp(str, "firmware")) {
|
||||
use_firmware = 1;
|
||||
pci_add_flags(PCI_PROBE_ONLY);
|
||||
return NULL;
|
||||
}
|
||||
return str;
|
||||
|
|
|
@ -155,8 +155,8 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
BUG_ON(request_resource(&iomem_resource, res_io) ||
|
||||
request_resource(&iomem_resource, res_mem));
|
||||
|
||||
pci_add_resource(&sys->resources, res_io);
|
||||
pci_add_resource(&sys->resources, res_mem);
|
||||
pci_add_resource_offset(&sys->resources, res_io, sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, res_mem, sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
pci_add_resource(&sys->resources, &pp->res[0]);
|
||||
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM
|
||||
|
@ -88,7 +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");
|
||||
pci_add_resource(&sys->resources, &pp->res[1]);
|
||||
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -275,11 +275,13 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys)
|
|||
allocate_resource(&iomem_resource, &res[0], 0x40000000,
|
||||
0x80000000, 0xffffffff, 0x40000000, NULL, NULL);
|
||||
|
||||
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;
|
||||
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&ioport_resource, sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset);
|
||||
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -378,9 +378,10 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
|
|||
* the mem resource for this bus
|
||||
* the prefetch mem resource for this bus
|
||||
*/
|
||||
pci_add_resource(&sys->resources, &ioport_resource);
|
||||
pci_add_resource(&sys->resources, &non_mem);
|
||||
pci_add_resource(&sys->resources, &pre_mem);
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&ioport_resource, sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
|
||||
pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1084,8 +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]);
|
||||
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -134,11 +134,11 @@ static void ixdp2400_pci_postinit(void)
|
|||
|
||||
if (ixdp2x00_master_npu()) {
|
||||
dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN);
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(dev);
|
||||
} else {
|
||||
dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN);
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(dev);
|
||||
|
||||
ixdp2x00_slave_pci_postinit();
|
||||
|
|
|
@ -262,14 +262,14 @@ int __init ixdp2800_pci_init(void)
|
|||
pci_common_init(&ixdp2800_pci);
|
||||
if (ixdp2x00_master_npu()) {
|
||||
dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(dev);
|
||||
|
||||
ixdp2800_master_enable_slave();
|
||||
ixdp2800_master_wait_for_slave_bus_scan();
|
||||
} else {
|
||||
dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN);
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -239,12 +239,12 @@ void ixdp2x00_slave_pci_postinit(void)
|
|||
* Remove PMC device is there is one
|
||||
*/
|
||||
if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) {
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN);
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -243,8 +243,10 @@ int ixp2000_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
if (nr >= 1)
|
||||
return 0;
|
||||
|
||||
pci_add_resource(&sys->resources, &ixp2000_pci_io_space);
|
||||
pci_add_resource(&sys->resources, &ixp2000_pci_mem_space);
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&ixp2000_pci_io_space, sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&ixp2000_pci_mem_space, sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -281,8 +281,10 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
|
|||
if (nr >= 1)
|
||||
return 0;
|
||||
|
||||
pci_add_resource(&sys->resources, &ixp23xx_pci_io_space);
|
||||
pci_add_resource(&sys->resources, &ixp23xx_pci_mem_space);
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&ixp23xx_pci_io_space, sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&ixp23xx_pci_mem_space, sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -472,8 +472,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
|
|||
request_resource(&ioport_resource, &res[0]);
|
||||
request_resource(&iomem_resource, &res[1]);
|
||||
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
|
||||
|
||||
platform_notify = ixp4xx_pci_platform_notify;
|
||||
platform_notify_remove = ixp4xx_pci_platform_notify_remove;
|
||||
|
|
|
@ -198,9 +198,9 @@ 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);
|
||||
|
||||
pci_add_resource(&sys->resources, &pp->res[0]);
|
||||
pci_add_resource(&sys->resources, &pp->res[1]);
|
||||
sys->io_offset = 0;
|
||||
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
|
||||
|
||||
/*
|
||||
* Generic PCIe unit setup.
|
||||
|
|
|
@ -169,8 +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);
|
||||
|
||||
pci_add_resource(&sys->resources, &pci_io);
|
||||
pci_add_resource(&sys->resources, &pci_mem);
|
||||
pci_add_resource_offset(&sys->resources, &pci_io, sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, &pci_mem, sys->mem_offset);
|
||||
|
||||
/* Assign and enable processor bridge */
|
||||
ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA);
|
||||
|
|
|
@ -155,8 +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);
|
||||
|
||||
pci_add_resource(&sys->resources, &pp->res[0]);
|
||||
pci_add_resource(&sys->resources, &pp->res[1]);
|
||||
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -171,13 +171,14 @@ static int __init pcie_setup(struct pci_sys_data *sys)
|
|||
/*
|
||||
* IORESOURCE_IO
|
||||
*/
|
||||
sys->io_offset = 0;
|
||||
res[0].name = "PCIe I/O Space";
|
||||
res[0].flags = IORESOURCE_IO;
|
||||
res[0].start = ORION5X_PCIE_IO_BUS_BASE;
|
||||
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");
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM
|
||||
|
@ -188,9 +189,7 @@ 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");
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
|
||||
sys->io_offset = 0;
|
||||
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -499,13 +498,14 @@ static int __init pci_setup(struct pci_sys_data *sys)
|
|||
/*
|
||||
* IORESOURCE_IO
|
||||
*/
|
||||
sys->io_offset = 0;
|
||||
res[0].name = "PCI I/O Space";
|
||||
res[0].flags = IORESOURCE_IO;
|
||||
res[0].start = ORION5X_PCI_IO_BUS_BASE;
|
||||
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");
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM
|
||||
|
@ -516,9 +516,7 @@ 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");
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
|
||||
sys->io_offset = 0;
|
||||
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -244,9 +244,11 @@ static int __init pci_nanoengine_setup_resources(struct pci_sys_data *sys)
|
|||
printk(KERN_ERR "PCI: unable to allocate prefetchable\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
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);
|
||||
pci_add_resource_offset(&sys->resources, &pci_io_ports, sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&pci_non_prefetchable_memory, sys->mem_offset);
|
||||
pci_add_resource_offset(&sys->resources,
|
||||
&pci_prefetchable_memory, sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
pci_add_resource(&sys->resources, &pp->res[0]);
|
||||
pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
|
||||
|
||||
/*
|
||||
* 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");
|
||||
pci_add_resource(&sys->resources, &pp->res[1]);
|
||||
pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
|
||||
|
||||
/*
|
||||
* 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");
|
||||
pci_add_resource(&sys->resources, &pp->res[2]);
|
||||
pci_add_resource_offset(&sys->resources, &pp->res[2], sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -219,9 +219,9 @@ static int __init pci_versatile_setup_resources(struct list_head *resources)
|
|||
* the mem resource for this bus
|
||||
* the prefetch mem resource for this bus
|
||||
*/
|
||||
pci_add_resource(resources, &io_mem);
|
||||
pci_add_resource(resources, &non_mem);
|
||||
pci_add_resource(resources, &pre_mem);
|
||||
pci_add_resource_offset(resources, &io_mem, sys->io_offset);
|
||||
pci_add_resource_offset(resources, &non_mem, sys->mem_offset);
|
||||
pci_add_resource_offset(resources, &pre_mem, sys->mem_offset);
|
||||
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -32,9 +32,6 @@ EXPORT_SYMBOL(pcibios_min_io);
|
|||
unsigned long pcibios_min_mem = 0x01000000;
|
||||
EXPORT_SYMBOL(pcibios_min_mem);
|
||||
|
||||
unsigned int pci_flags = PCI_REASSIGN_ALL_RSRC;
|
||||
EXPORT_SYMBOL(pci_flags);
|
||||
|
||||
void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
|
||||
{
|
||||
if ((unsigned long)addr >= VMALLOC_START &&
|
||||
|
|
|
@ -215,8 +215,8 @@ 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;
|
||||
|
||||
pci_add_resource(&sys->resources, &res[0]);
|
||||
pci_add_resource(&sys->resources, &res[1]);
|
||||
pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
|
||||
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -108,12 +108,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
|
|||
return (pci_domain_nr(bus) != 0);
|
||||
}
|
||||
|
||||
extern void pcibios_resource_to_bus(struct pci_dev *dev,
|
||||
struct pci_bus_region *region, struct resource *res);
|
||||
|
||||
extern void pcibios_bus_to_resource(struct pci_dev *dev,
|
||||
struct resource *res, struct pci_bus_region *region);
|
||||
|
||||
static inline struct resource *
|
||||
pcibios_select_root(struct pci_dev *pdev, struct resource *res)
|
||||
{
|
||||
|
|
|
@ -320,7 +320,8 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
|||
* 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);
|
||||
pci_add_resource_offset(&info->resources, &window->resource,
|
||||
window->offset);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
@ -395,54 +396,6 @@ pci_acpi_scan_root(struct acpi_pci_root *root)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void pcibios_resource_to_bus(struct pci_dev *dev,
|
||||
struct pci_bus_region *region, struct resource *res)
|
||||
{
|
||||
struct pci_controller *controller = PCI_CONTROLLER(dev);
|
||||
unsigned long offset = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < controller->windows; i++) {
|
||||
struct pci_window *window = &controller->window[i];
|
||||
if (!(window->resource.flags & res->flags))
|
||||
continue;
|
||||
if (window->resource.start > res->start)
|
||||
continue;
|
||||
if (window->resource.end < res->end)
|
||||
continue;
|
||||
offset = window->offset;
|
||||
break;
|
||||
}
|
||||
|
||||
region->start = res->start - offset;
|
||||
region->end = res->end - offset;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
|
||||
void pcibios_bus_to_resource(struct pci_dev *dev,
|
||||
struct resource *res, struct pci_bus_region *region)
|
||||
{
|
||||
struct pci_controller *controller = PCI_CONTROLLER(dev);
|
||||
unsigned long offset = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < controller->windows; i++) {
|
||||
struct pci_window *window = &controller->window[i];
|
||||
if (!(window->resource.flags & res->flags))
|
||||
continue;
|
||||
if (window->resource.start - window->offset > region->start)
|
||||
continue;
|
||||
if (window->resource.end - window->offset < region->end)
|
||||
continue;
|
||||
offset = window->offset;
|
||||
break;
|
||||
}
|
||||
|
||||
res->start = region->start + offset;
|
||||
res->end = region->end + offset;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
|
||||
static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
|
||||
{
|
||||
unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
|
||||
|
@ -464,15 +417,11 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
|
|||
static void __devinit
|
||||
pcibios_fixup_resources(struct pci_dev *dev, int start, int limit)
|
||||
{
|
||||
struct pci_bus_region region;
|
||||
int i;
|
||||
|
||||
for (i = start; i < limit; i++) {
|
||||
if (!dev->resource[i].flags)
|
||||
continue;
|
||||
region.start = dev->resource[i].start;
|
||||
region.end = dev->resource[i].end;
|
||||
pcibios_bus_to_resource(dev, &dev->resource[i], ®ion);
|
||||
if ((is_valid_resource(dev, i)))
|
||||
pci_claim_resource(dev, i);
|
||||
}
|
||||
|
|
|
@ -297,7 +297,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
|
|||
s64 status = 0;
|
||||
struct pci_controller *controller;
|
||||
struct pcibus_bussoft *prom_bussoft_ptr;
|
||||
|
||||
LIST_HEAD(resources);
|
||||
int i;
|
||||
|
||||
status = sal_get_pcibus_info((u64) segment, (u64) busnum,
|
||||
(u64) ia64_tpa(&prom_bussoft_ptr));
|
||||
|
@ -315,7 +316,15 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
|
|||
*/
|
||||
controller->platform_data = prom_bussoft_ptr;
|
||||
|
||||
bus = pci_scan_bus(busnum, &pci_root_ops, controller);
|
||||
sn_legacy_pci_window_fixup(controller,
|
||||
prom_bussoft_ptr->bs_legacy_io,
|
||||
prom_bussoft_ptr->bs_legacy_mem);
|
||||
for (i = 0; i < controller->windows; i++)
|
||||
pci_add_resource_offset(&resources,
|
||||
&controller->window[i].resource,
|
||||
controller->window[i].offset);
|
||||
bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
|
||||
&resources);
|
||||
if (bus == NULL)
|
||||
goto error_return; /* error, or bus already scanned */
|
||||
|
||||
|
@ -348,9 +357,6 @@ sn_bus_fixup(struct pci_bus *bus)
|
|||
return;
|
||||
}
|
||||
sn_common_bus_fixup(bus, prom_bussoft_ptr);
|
||||
sn_legacy_pci_window_fixup(PCI_CONTROLLER(bus),
|
||||
prom_bussoft_ptr->bs_legacy_io,
|
||||
prom_bussoft_ptr->bs_legacy_mem);
|
||||
}
|
||||
list_for_each_entry(pci_dev, &bus->devices, bus_list) {
|
||||
sn_io_slot_fixup(pci_dev);
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <asm-generic/pci-bridge.h>
|
||||
|
||||
struct device_node;
|
||||
|
||||
|
|
|
@ -94,14 +94,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
|
|||
*/
|
||||
#define PCI_DMA_BUS_IS_PHYS (1)
|
||||
|
||||
extern void pcibios_resource_to_bus(struct pci_dev *dev,
|
||||
struct pci_bus_region *region,
|
||||
struct resource *res);
|
||||
|
||||
extern void pcibios_bus_to_resource(struct pci_dev *dev,
|
||||
struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
|
||||
struct resource *res)
|
||||
{
|
||||
|
|
|
@ -46,9 +46,6 @@ static int global_phb_number; /* Global phb counter */
|
|||
/* ISA Memory physical address */
|
||||
resource_size_t isa_mem_base;
|
||||
|
||||
/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
|
||||
unsigned int pci_flags;
|
||||
|
||||
static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
|
||||
|
||||
unsigned long isa_io_base;
|
||||
|
@ -833,64 +830,7 @@ int pci_proc_domain(struct pci_bus *bus)
|
|||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(bus);
|
||||
|
||||
if (!(pci_flags & PCI_ENABLE_PROC_DOMAINS))
|
||||
return 0;
|
||||
if (pci_flags & PCI_COMPAT_DOMAIN_0)
|
||||
return hose->global_number != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
resource_size_t offset = 0, mask = (resource_size_t)-1;
|
||||
struct pci_controller *hose = pci_bus_to_host(dev->bus);
|
||||
|
||||
if (!hose)
|
||||
return;
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
offset = (unsigned long)hose->io_base_virt - _IO_BASE;
|
||||
mask = 0xffffffffu;
|
||||
} else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->pci_mem_offset;
|
||||
|
||||
region->start = (res->start - offset) & mask;
|
||||
region->end = (res->end - offset) & mask;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
|
||||
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
resource_size_t offset = 0, mask = (resource_size_t)-1;
|
||||
struct pci_controller *hose = pci_bus_to_host(dev->bus);
|
||||
|
||||
if (!hose)
|
||||
return;
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
offset = (unsigned long)hose->io_base_virt - _IO_BASE;
|
||||
mask = 0xffffffffu;
|
||||
} else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->pci_mem_offset;
|
||||
res->start = (region->start + offset) & mask;
|
||||
res->end = (region->end + offset) & mask;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
|
||||
/* Fixup a bus resource into a linux resource */
|
||||
static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(dev->bus);
|
||||
resource_size_t offset = 0, mask = (resource_size_t)-1;
|
||||
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
offset = (unsigned long)hose->io_base_virt - _IO_BASE;
|
||||
mask = 0xffffffffu;
|
||||
} else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->pci_mem_offset;
|
||||
|
||||
res->start = (res->start + offset) & mask;
|
||||
res->end = (res->end + offset) & mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This header fixup will do the resource fixup for all devices as they are
|
||||
|
@ -910,13 +850,7 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
|
|||
struct resource *res = dev->resource + i;
|
||||
if (!res->flags)
|
||||
continue;
|
||||
/* On platforms that have PCI_PROBE_ONLY set, we don't
|
||||
* consider 0 as an unassigned BAR value. It's technically
|
||||
* a valid value, but linux doesn't like it... so when we can
|
||||
* re-assign things, we do so, but if we can't, we keep it
|
||||
* around and hope for the best...
|
||||
*/
|
||||
if (res->start == 0 && !(pci_flags & PCI_PROBE_ONLY)) {
|
||||
if (res->start == 0) {
|
||||
pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]" \
|
||||
"is unassigned\n",
|
||||
pci_name(dev), i,
|
||||
|
@ -929,18 +863,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
|
|||
continue;
|
||||
}
|
||||
|
||||
pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n",
|
||||
pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n",
|
||||
pci_name(dev), i,
|
||||
(unsigned long long)res->start,\
|
||||
(unsigned long long)res->end,
|
||||
(unsigned int)res->flags);
|
||||
|
||||
fixup_resource(res, dev);
|
||||
|
||||
pr_debug("PCI:%s %016llx-%016llx\n",
|
||||
pci_name(dev),
|
||||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end);
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
|
||||
|
@ -959,10 +886,6 @@ static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
|
|||
u16 command;
|
||||
int i;
|
||||
|
||||
/* We don't do anything if PCI_PROBE_ONLY is set */
|
||||
if (pci_flags & PCI_PROBE_ONLY)
|
||||
return 0;
|
||||
|
||||
/* Job is a bit different between memory and IO */
|
||||
if (res->flags & IORESOURCE_MEM) {
|
||||
/* If the BAR is non-0 (res != pci_mem_offset) then it's
|
||||
|
@ -1037,9 +960,6 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
|
|||
(unsigned long long)res->end,
|
||||
(unsigned int)res->flags);
|
||||
|
||||
/* Perform fixup */
|
||||
fixup_resource(res, dev);
|
||||
|
||||
/* Try to detect uninitialized P2P bridge resources,
|
||||
* and clear them out so they get re-assigned later
|
||||
*/
|
||||
|
@ -1107,9 +1027,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus);
|
|||
|
||||
static int skip_isa_ioresource_align(struct pci_dev *dev)
|
||||
{
|
||||
if ((pci_flags & PCI_CAN_SKIP_ISA_ALIGN) &&
|
||||
!(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1236,8 +1153,6 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
|
|||
* and as such ensure proper re-allocation
|
||||
* later.
|
||||
*/
|
||||
if (pci_flags & PCI_REASSIGN_ALL_RSRC)
|
||||
goto clear_resource;
|
||||
pr = pci_find_parent_resource(bus->self, res);
|
||||
if (pr == res) {
|
||||
/* this happens when the generic PCI
|
||||
|
@ -1422,27 +1337,19 @@ void __init pcibios_resource_survey(void)
|
|||
list_for_each_entry(b, &pci_root_buses, node)
|
||||
pcibios_allocate_bus_resources(b);
|
||||
|
||||
if (!(pci_flags & PCI_REASSIGN_ALL_RSRC)) {
|
||||
pcibios_allocate_resources(0);
|
||||
pcibios_allocate_resources(1);
|
||||
}
|
||||
pcibios_allocate_resources(0);
|
||||
pcibios_allocate_resources(1);
|
||||
|
||||
/* Before we start assigning unassigned resource, we try to reserve
|
||||
* the low IO area and the VGA memory area if they intersect the
|
||||
* bus available resources to avoid allocating things on top of them
|
||||
*/
|
||||
if (!(pci_flags & PCI_PROBE_ONLY)) {
|
||||
list_for_each_entry(b, &pci_root_buses, node)
|
||||
pcibios_reserve_legacy_regions(b);
|
||||
}
|
||||
list_for_each_entry(b, &pci_root_buses, node)
|
||||
pcibios_reserve_legacy_regions(b);
|
||||
|
||||
/* Now, if the platform didn't decide to blindly trust the firmware,
|
||||
* we proceed to assigning things that were left unassigned
|
||||
*/
|
||||
if (!(pci_flags & PCI_PROBE_ONLY)) {
|
||||
pr_debug("PCI: Assigning unassigned resources...\n");
|
||||
pci_assign_unassigned_resources();
|
||||
}
|
||||
/* Now proceed to assigning things that were left unassigned */
|
||||
pr_debug("PCI: Assigning unassigned resources...\n");
|
||||
pci_assign_unassigned_resources();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
|
@ -1535,7 +1442,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s
|
|||
res->end = res->start + IO_SPACE_LIMIT;
|
||||
res->flags = IORESOURCE_IO;
|
||||
}
|
||||
pci_add_resource(resources, res);
|
||||
pci_add_resource_offset(resources, res, hose->io_base_virt - _IO_BASE);
|
||||
|
||||
pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n",
|
||||
(unsigned long long)res->start,
|
||||
|
@ -1558,7 +1465,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s
|
|||
res->flags = IORESOURCE_MEM;
|
||||
|
||||
}
|
||||
pci_add_resource(resources, res);
|
||||
pci_add_resource_offset(resources, res, hose->pci_mem_offset);
|
||||
|
||||
pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n",
|
||||
i, (unsigned long long)res->start,
|
||||
|
|
|
@ -92,6 +92,7 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
|||
#include <asm/scatterlist.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm-generic/pci-bridge.h>
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
|
@ -112,12 +113,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
|
|||
}
|
||||
#endif
|
||||
|
||||
extern void pcibios_resource_to_bus(struct pci_dev *dev,
|
||||
struct pci_bus_region *region, struct resource *res);
|
||||
|
||||
extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
|
||||
|
||||
static inline int pci_proc_domain(struct pci_bus *bus)
|
||||
|
@ -145,8 +140,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
|
|||
#define arch_setup_msi_irqs arch_setup_msi_irqs
|
||||
#endif
|
||||
|
||||
extern int pci_probe_only;
|
||||
|
||||
extern char * (*pcibios_plat_setup)(char *str);
|
||||
|
||||
#endif /* _ASM_PCI_H */
|
||||
|
|
|
@ -51,67 +51,6 @@ static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
|
|||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
|
||||
qube_raq_galileo_early_fixup);
|
||||
|
||||
static void __devinit cobalt_legacy_ide_resource_fixup(struct pci_dev *dev,
|
||||
struct resource *res)
|
||||
{
|
||||
struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
|
||||
unsigned long offset = hose->io_offset;
|
||||
struct resource orig = *res;
|
||||
|
||||
if (!(res->flags & IORESOURCE_IO) ||
|
||||
!(res->flags & IORESOURCE_PCI_FIXED))
|
||||
return;
|
||||
|
||||
res->start -= offset;
|
||||
res->end -= offset;
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "converted legacy %pR to bus %pR\n",
|
||||
&orig, res);
|
||||
}
|
||||
|
||||
static void __devinit cobalt_legacy_ide_fixup(struct pci_dev *dev)
|
||||
{
|
||||
u32 class;
|
||||
u8 progif;
|
||||
|
||||
/*
|
||||
* If the IDE controller is in legacy mode, pci_setup_device() fills in
|
||||
* the resources with the legacy addresses that normally appear on the
|
||||
* PCI bus, just as if we had read them from a BAR.
|
||||
*
|
||||
* However, with the GT-64111, those legacy addresses, e.g., 0x1f0,
|
||||
* will never appear on the PCI bus because it converts memory accesses
|
||||
* in the PCI I/O region (which is never at address zero) into I/O port
|
||||
* accesses with no address translation.
|
||||
*
|
||||
* For example, if GT_DEF_PCI0_IO_BASE is 0x10000000, a load or store
|
||||
* to physical address 0x100001f0 will become a PCI access to I/O port
|
||||
* 0x100001f0. There's no way to generate an access to I/O port 0x1f0,
|
||||
* but the VT82C586 IDE controller does respond at 0x100001f0 because
|
||||
* it only decodes the low 24 bits of the address.
|
||||
*
|
||||
* When this quirk runs, the pci_dev resources should contain bus
|
||||
* addresses, not Linux I/O port numbers, so convert legacy addresses
|
||||
* like 0x1f0 to bus addresses like 0x100001f0. Later, we'll convert
|
||||
* them back with pcibios_fixup_bus() or pcibios_bus_to_resource().
|
||||
*/
|
||||
class = dev->class >> 8;
|
||||
if (class != PCI_CLASS_STORAGE_IDE)
|
||||
return;
|
||||
|
||||
pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
|
||||
if ((progif & 1) == 0) {
|
||||
cobalt_legacy_ide_resource_fixup(dev, &dev->resource[0]);
|
||||
cobalt_legacy_ide_resource_fixup(dev, &dev->resource[1]);
|
||||
}
|
||||
if ((progif & 4) == 0) {
|
||||
cobalt_legacy_ide_resource_fixup(dev, &dev->resource[2]);
|
||||
cobalt_legacy_ide_resource_fixup(dev, &dev->resource[3]);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
|
||||
cobalt_legacy_ide_fixup);
|
||||
|
||||
static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
|
||||
{
|
||||
unsigned short cfgword;
|
||||
|
|
|
@ -204,7 +204,7 @@ static int __init bcm1480_pcibios_init(void)
|
|||
uint64_t reg;
|
||||
|
||||
/* CFE will assign PCI resources */
|
||||
pci_probe_only = 1;
|
||||
pci_set_flags(PCI_PROBE_ONLY);
|
||||
|
||||
/* Avoid ISA compat ranges. */
|
||||
PCIBIOS_MIN_IO = 0x00008000UL;
|
||||
|
|
|
@ -50,7 +50,7 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid)
|
|||
bridge_t *bridge;
|
||||
int slot;
|
||||
|
||||
pci_probe_only = 1;
|
||||
pci_set_flags(PCI_PROBE_ONLY);
|
||||
|
||||
printk("a bridge\n");
|
||||
|
||||
|
|
|
@ -270,7 +270,8 @@ static int __devinit ltq_pci_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct ltq_pci_data *ltq_pci_data =
|
||||
(struct ltq_pci_data *) pdev->dev.platform_data;
|
||||
pci_probe_only = 0;
|
||||
|
||||
pci_clear_flags(PCI_PROBE_ONLY);
|
||||
ltq_pci_irq_map = ltq_pci_data->irq;
|
||||
ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE);
|
||||
ltq_pci_mapped_cfg =
|
||||
|
|
|
@ -213,7 +213,7 @@ static int __init sb1250_pcibios_init(void)
|
|||
uint64_t reg;
|
||||
|
||||
/* CFE will assign PCI resources */
|
||||
pci_probe_only = 1;
|
||||
pci_set_flags(PCI_PROBE_ONLY);
|
||||
|
||||
/* Avoid ISA compat ranges. */
|
||||
PCIBIOS_MIN_IO = 0x00008000UL;
|
||||
|
|
|
@ -292,7 +292,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
|
|||
static int __init pcibios_init(void)
|
||||
{
|
||||
/* PSB assigns PCI resources */
|
||||
pci_probe_only = 1;
|
||||
pci_set_flags(PCI_PROBE_ONLY);
|
||||
pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20);
|
||||
|
||||
/* Extend IO port for memory mapped io */
|
||||
|
|
|
@ -20,16 +20,9 @@
|
|||
#include <asm/cpu-info.h>
|
||||
|
||||
/*
|
||||
* Indicate whether we respect the PCI setup left by the firmware.
|
||||
*
|
||||
* Make this long-lived so that we know when shutting down
|
||||
* whether we probed only or not.
|
||||
* If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource
|
||||
* assignments.
|
||||
*/
|
||||
int pci_probe_only;
|
||||
|
||||
#define PCI_ASSIGN_ALL_BUSSES 1
|
||||
|
||||
unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES;
|
||||
|
||||
/*
|
||||
* The PCI controller list.
|
||||
|
@ -92,11 +85,12 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
|
|||
if (!hose->iommu)
|
||||
PCI_DMA_BUS_IS_PHYS = 1;
|
||||
|
||||
if (hose->get_busno && pci_probe_only)
|
||||
if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY))
|
||||
next_busno = (*hose->get_busno)();
|
||||
|
||||
pci_add_resource(&resources, hose->mem_resource);
|
||||
pci_add_resource(&resources, hose->io_resource);
|
||||
pci_add_resource_offset(&resources,
|
||||
hose->mem_resource, hose->mem_offset);
|
||||
pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset);
|
||||
bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
|
||||
&resources);
|
||||
if (!bus)
|
||||
|
@ -115,7 +109,7 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
|
|||
need_domain_info = 1;
|
||||
}
|
||||
|
||||
if (!pci_probe_only) {
|
||||
if (!pci_has_flag(PCI_PROBE_ONLY)) {
|
||||
pci_bus_size_bridges(bus);
|
||||
pci_bus_assign_resources(bus);
|
||||
pci_enable_bridges(bus);
|
||||
|
@ -241,7 +235,7 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
|
|||
|
||||
unsigned int pcibios_assign_all_busses(void)
|
||||
{
|
||||
return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
|
@ -254,42 +248,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
return pcibios_plat_dev_init(dev);
|
||||
}
|
||||
|
||||
static void pcibios_fixup_device_resources(struct pci_dev *dev,
|
||||
struct pci_bus *bus)
|
||||
{
|
||||
/* Update device resources. */
|
||||
struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
|
||||
unsigned long offset = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
|
||||
if (!dev->resource[i].start)
|
||||
continue;
|
||||
if (dev->resource[i].flags & IORESOURCE_IO)
|
||||
offset = hose->io_offset;
|
||||
else if (dev->resource[i].flags & IORESOURCE_MEM)
|
||||
offset = hose->mem_offset;
|
||||
|
||||
dev->resource[i].start += offset;
|
||||
dev->resource[i].end += offset;
|
||||
}
|
||||
}
|
||||
|
||||
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
/* Propagate hose info into the subordinate devices. */
|
||||
|
||||
struct pci_dev *dev = bus->self;
|
||||
|
||||
if (pci_probe_only && dev &&
|
||||
if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
pci_read_bridge_bases(bus);
|
||||
pcibios_fixup_device_resources(dev, bus);
|
||||
}
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
|
||||
pcibios_fixup_device_resources(dev, bus);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,40 +264,7 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
|
|||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
|
||||
unsigned long offset = 0;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
offset = hose->io_offset;
|
||||
else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->mem_offset;
|
||||
|
||||
region->start = res->start - offset;
|
||||
region->end = res->end - offset;
|
||||
}
|
||||
|
||||
void __devinit
|
||||
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
|
||||
unsigned long offset = 0;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
offset = hose->io_offset;
|
||||
else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->mem_offset;
|
||||
|
||||
res->start = region->start + offset;
|
||||
res->end = region->end + offset;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
EXPORT_SYMBOL(PCIBIOS_MIN_IO);
|
||||
EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
|
||||
#endif
|
||||
|
|
|
@ -85,22 +85,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
|||
/* implement the pci_ DMA API in terms of the generic device dma_ one */
|
||||
#include <asm-generic/pci-dma-compat.h>
|
||||
|
||||
/**
|
||||
* pcibios_resource_to_bus - convert resource to PCI bus address
|
||||
* @dev: device which owns this resource
|
||||
* @region: converted bus-centric region (start,end)
|
||||
* @res: resource to convert
|
||||
*
|
||||
* Convert a resource to a PCI device bus address or bus window.
|
||||
*/
|
||||
extern void pcibios_resource_to_bus(struct pci_dev *dev,
|
||||
struct pci_bus_region *region,
|
||||
struct resource *res);
|
||||
|
||||
extern void pcibios_bus_to_resource(struct pci_dev *dev,
|
||||
struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
static inline struct resource *
|
||||
pcibios_select_root(struct pci_dev *pdev, struct resource *res)
|
||||
{
|
||||
|
|
|
@ -32,8 +32,7 @@ struct pci_ops *pci_root_ops;
|
|||
* insert specific PCI bus resources instead of using the platform-level bus
|
||||
* resources directly for the PCI root bus.
|
||||
*
|
||||
* These are configured and inserted by pcibios_init() and are attached to the
|
||||
* root bus by pcibios_fixup_bus().
|
||||
* These are configured and inserted by pcibios_init().
|
||||
*/
|
||||
static struct resource pci_ioport_resource = {
|
||||
.name = "PCI IO",
|
||||
|
@ -77,52 +76,6 @@ static inline int __query(const struct pci_bus *bus, unsigned int devfn)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* translate Linuxcentric addresses to PCI bus addresses
|
||||
*/
|
||||
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
region->start = (res->start & 0x00ffffff);
|
||||
region->end = (res->end & 0x00ffffff);
|
||||
}
|
||||
|
||||
if (res->flags & IORESOURCE_MEM) {
|
||||
region->start = (res->start & 0x03ffffff) | MEM_PAGING_REG;
|
||||
region->end = (res->end & 0x03ffffff) | MEM_PAGING_REG;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printk(KERN_DEBUG "RES->BUS: %lx-%lx => %lx-%lx\n",
|
||||
res->start, res->end, region->start, region->end);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
|
||||
/*
|
||||
* translate PCI bus addresses to Linuxcentric addresses
|
||||
*/
|
||||
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
res->start = (region->start & 0x00ffffff) | 0xbe000000;
|
||||
res->end = (region->end & 0x00ffffff) | 0xbe000000;
|
||||
}
|
||||
|
||||
if (res->flags & IORESOURCE_MEM) {
|
||||
res->start = (region->start & 0x03ffffff) | 0xb8000000;
|
||||
res->end = (region->end & 0x03ffffff) | 0xb8000000;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printk(KERN_INFO "BUS->RES: %lx-%lx => %lx-%lx\n",
|
||||
region->start, region->end, res->start, res->end);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@ -364,9 +317,6 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
|
|||
if (!dev->resource[i].flags)
|
||||
continue;
|
||||
|
||||
region.start = dev->resource[i].start;
|
||||
region.end = dev->resource[i].end;
|
||||
pcibios_bus_to_resource(dev, &dev->resource[i], ®ion);
|
||||
if (is_valid_resource(dev, i))
|
||||
pci_claim_resource(dev, i);
|
||||
}
|
||||
|
@ -397,6 +347,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
|||
*/
|
||||
static int __init pcibios_init(void)
|
||||
{
|
||||
resource_size_t io_offset, mem_offset;
|
||||
LIST_HEAD(resources);
|
||||
|
||||
ioport_resource.start = 0xA0000000;
|
||||
|
@ -420,8 +371,13 @@ static int __init pcibios_init(void)
|
|||
printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n",
|
||||
MEM_PAGING_REG);
|
||||
|
||||
pci_add_resource(&resources, &pci_ioport_resource);
|
||||
pci_add_resource(&resources, &pci_iomem_resource);
|
||||
io_offset = pci_ioport_resource.start -
|
||||
(pci_ioport_resource.start & 0x00ffffff);
|
||||
mem_offset = pci_iomem_resource.start -
|
||||
((pci_iomem_resource.start & 0x03ffffff) | MEM_PAGING_REG);
|
||||
|
||||
pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset);
|
||||
pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset);
|
||||
pci_root_bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL,
|
||||
&resources);
|
||||
|
||||
|
|
|
@ -82,38 +82,8 @@ struct pci_hba_data {
|
|||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define PCI_F_EXTEND 0xffffffff00000000UL
|
||||
#define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a)
|
||||
|
||||
/* We need to know if an address is LMMMIO or GMMIO.
|
||||
* LMMIO requires mangling and GMMIO we must use as-is.
|
||||
*/
|
||||
static __inline__ int pci_is_lmmio(struct pci_hba_data *hba, unsigned long a)
|
||||
{
|
||||
return(((a) & PCI_F_EXTEND) == PCI_F_EXTEND);
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses.
|
||||
** See pci.c for more conversions used by Generic PCI code.
|
||||
**
|
||||
** Platform characteristics/firmware guarantee that
|
||||
** (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO
|
||||
** (2) PA_VIEW == IO_VIEW for GMMIO
|
||||
*/
|
||||
#define PCI_BUS_ADDR(hba,a) (PCI_IS_LMMIO(hba,a) \
|
||||
? ((a) - hba->lmmio_space_offset) /* mangle LMMIO */ \
|
||||
: (a)) /* GMMIO */
|
||||
#define PCI_HOST_ADDR(hba,a) (((a) & PCI_F_EXTEND) == 0 \
|
||||
? (a) + hba->lmmio_space_offset \
|
||||
: (a))
|
||||
|
||||
#else /* !CONFIG_64BIT */
|
||||
|
||||
#define PCI_BUS_ADDR(hba,a) (a)
|
||||
#define PCI_HOST_ADDR(hba,a) (a)
|
||||
#define PCI_F_EXTEND 0UL
|
||||
#define PCI_IS_LMMIO(hba,a) (1) /* 32-bit doesn't support GMMIO */
|
||||
|
||||
#endif /* !CONFIG_64BIT */
|
||||
|
||||
/*
|
||||
|
@ -245,14 +215,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
|
|||
}
|
||||
#endif
|
||||
|
||||
extern void
|
||||
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res);
|
||||
|
||||
extern void
|
||||
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't need to penalize isa irq's */
|
||||
|
|
|
@ -195,58 +195,6 @@ void __init pcibios_init_bus(struct pci_bus *bus)
|
|||
pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
|
||||
}
|
||||
|
||||
/* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */
|
||||
void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
|
||||
struct pci_bus_region *region, struct resource *res)
|
||||
{
|
||||
#ifdef CONFIG_64BIT
|
||||
struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
|
||||
#endif
|
||||
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
/*
|
||||
** I/O space may see busnumbers here. Something
|
||||
** in the form of 0xbbxxxx where bb is the bus num
|
||||
** and xxxx is the I/O port space address.
|
||||
** Remaining address translation are done in the
|
||||
** PCI Host adapter specific code - ie dino_out8.
|
||||
*/
|
||||
region->start = PCI_PORT_ADDR(res->start);
|
||||
region->end = PCI_PORT_ADDR(res->end);
|
||||
} else if (res->flags & IORESOURCE_MEM) {
|
||||
/* Convert MMIO addr to PCI addr (undo global virtualization) */
|
||||
region->start = PCI_BUS_ADDR(hba, res->start);
|
||||
region->end = PCI_BUS_ADDR(hba, res->end);
|
||||
}
|
||||
|
||||
DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n",
|
||||
dev->bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
|
||||
region->start, region->end);
|
||||
}
|
||||
|
||||
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
#ifdef CONFIG_64BIT
|
||||
struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
|
||||
#endif
|
||||
|
||||
if (res->flags & IORESOURCE_MEM) {
|
||||
res->start = PCI_HOST_ADDR(hba, region->start);
|
||||
res->end = PCI_HOST_ADDR(hba, region->end);
|
||||
}
|
||||
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
res->start = region->start;
|
||||
res->end = region->end;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pcibios align resources() is called every time generic PCI code
|
||||
* wants to generate a new address. The process of looking for
|
||||
|
|
|
@ -154,14 +154,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
|
|||
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
extern void pcibios_resource_to_bus(struct pci_dev *dev,
|
||||
struct pci_bus_region *region,
|
||||
struct resource *res);
|
||||
|
||||
extern void pcibios_bus_to_resource(struct pci_dev *dev,
|
||||
struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
extern void pcibios_claim_one_bus(struct pci_bus *b);
|
||||
|
||||
extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
|
||||
|
@ -190,6 +182,7 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
|
|||
const struct resource *rsrc,
|
||||
resource_size_t *start, resource_size_t *end);
|
||||
|
||||
extern resource_size_t pcibios_io_space_offset(struct pci_controller *hose);
|
||||
extern void pcibios_setup_bus_devices(struct pci_bus *bus);
|
||||
extern void pcibios_setup_bus_self(struct pci_bus *bus);
|
||||
extern void pcibios_setup_phb_io_space(struct pci_controller *hose);
|
||||
|
|
|
@ -45,8 +45,6 @@ extern void init_pci_config_tokens (void);
|
|||
extern unsigned long get_phb_buid (struct device_node *);
|
||||
extern int rtas_setup_phb(struct pci_controller *phb);
|
||||
|
||||
extern unsigned long pci_probe_only;
|
||||
|
||||
#ifdef CONFIG_EEH
|
||||
|
||||
void pci_addr_cache_build(void);
|
||||
|
|
|
@ -49,9 +49,6 @@ static int global_phb_number; /* Global phb counter */
|
|||
/* ISA Memory physical address */
|
||||
resource_size_t isa_mem_base;
|
||||
|
||||
/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
|
||||
unsigned int pci_flags = 0;
|
||||
|
||||
|
||||
static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
|
||||
|
||||
|
@ -834,60 +831,6 @@ int pci_proc_domain(struct pci_bus *bus)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
resource_size_t offset = 0, mask = (resource_size_t)-1;
|
||||
struct pci_controller *hose = pci_bus_to_host(dev->bus);
|
||||
|
||||
if (!hose)
|
||||
return;
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
offset = (unsigned long)hose->io_base_virt - _IO_BASE;
|
||||
mask = 0xffffffffu;
|
||||
} else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->pci_mem_offset;
|
||||
|
||||
region->start = (res->start - offset) & mask;
|
||||
region->end = (res->end - offset) & mask;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
|
||||
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
resource_size_t offset = 0, mask = (resource_size_t)-1;
|
||||
struct pci_controller *hose = pci_bus_to_host(dev->bus);
|
||||
|
||||
if (!hose)
|
||||
return;
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
offset = (unsigned long)hose->io_base_virt - _IO_BASE;
|
||||
mask = 0xffffffffu;
|
||||
} else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->pci_mem_offset;
|
||||
res->start = (region->start + offset) & mask;
|
||||
res->end = (region->end + offset) & mask;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
|
||||
/* Fixup a bus resource into a linux resource */
|
||||
static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(dev->bus);
|
||||
resource_size_t offset = 0, mask = (resource_size_t)-1;
|
||||
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
offset = (unsigned long)hose->io_base_virt - _IO_BASE;
|
||||
mask = 0xffffffffu;
|
||||
} else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->pci_mem_offset;
|
||||
|
||||
res->start = (res->start + offset) & mask;
|
||||
res->end = (res->end + offset) & mask;
|
||||
}
|
||||
|
||||
|
||||
/* This header fixup will do the resource fixup for all devices as they are
|
||||
* probed, but not for bridge ranges
|
||||
*/
|
||||
|
@ -927,18 +870,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
|
|||
continue;
|
||||
}
|
||||
|
||||
pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n",
|
||||
pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n",
|
||||
pci_name(dev), i,
|
||||
(unsigned long long)res->start,\
|
||||
(unsigned long long)res->end,
|
||||
(unsigned int)res->flags);
|
||||
|
||||
fixup_resource(res, dev);
|
||||
|
||||
pr_debug("PCI:%s %016llx-%016llx\n",
|
||||
pci_name(dev),
|
||||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end);
|
||||
}
|
||||
|
||||
/* Call machine specific resource fixup */
|
||||
|
@ -1040,27 +976,18 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
|
|||
continue;
|
||||
}
|
||||
|
||||
pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
|
||||
pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x]\n",
|
||||
pci_name(dev), i,
|
||||
(unsigned long long)res->start,\
|
||||
(unsigned long long)res->end,
|
||||
(unsigned int)res->flags);
|
||||
|
||||
/* Perform fixup */
|
||||
fixup_resource(res, dev);
|
||||
|
||||
/* Try to detect uninitialized P2P bridge resources,
|
||||
* and clear them out so they get re-assigned later
|
||||
*/
|
||||
if (pcibios_uninitialized_bridge_resource(bus, res)) {
|
||||
res->flags = 0;
|
||||
pr_debug("PCI:%s (unassigned)\n", pci_name(dev));
|
||||
} else {
|
||||
|
||||
pr_debug("PCI:%s %016llx-%016llx\n",
|
||||
pci_name(dev),
|
||||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1550,6 +1477,11 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
resource_size_t pcibios_io_space_offset(struct pci_controller *hose)
|
||||
{
|
||||
return (unsigned long) hose->io_base_virt - _IO_BASE;
|
||||
}
|
||||
|
||||
static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources)
|
||||
{
|
||||
struct resource *res;
|
||||
|
@ -1574,7 +1506,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s
|
|||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end,
|
||||
(unsigned long)res->flags);
|
||||
pci_add_resource(resources, res);
|
||||
pci_add_resource_offset(resources, res, pcibios_io_space_offset(hose));
|
||||
|
||||
/* Hookup PHB Memory resources */
|
||||
for (i = 0; i < 3; ++i) {
|
||||
|
@ -1597,7 +1529,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s
|
|||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end,
|
||||
(unsigned long)res->flags);
|
||||
pci_add_resource(resources, res);
|
||||
pci_add_resource_offset(resources, res, hose->pci_mem_offset);
|
||||
}
|
||||
|
||||
pr_debug("PCI: PHB MEM offset = %016llx\n",
|
||||
|
|
|
@ -219,9 +219,9 @@ void __devinit pcibios_setup_phb_io_space(struct pci_controller *hose)
|
|||
struct 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;
|
||||
io_offset = pcibios_io_space_offset(hose);
|
||||
res->start += io_offset;
|
||||
res->end += io_offset;
|
||||
}
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include <asm/machdep.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
unsigned long pci_probe_only = 1;
|
||||
|
||||
/* pci_io_base -- the base address from which io bars are offsets.
|
||||
* This is the lowest I/O base address (so bar values are always positive),
|
||||
* and it *must* be the start of ISA space if an ISA bus exists because
|
||||
|
@ -55,9 +53,6 @@ static int __init pcibios_init(void)
|
|||
*/
|
||||
ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
|
||||
|
||||
if (pci_probe_only)
|
||||
pci_add_flags(PCI_PROBE_ONLY);
|
||||
|
||||
/* On ppc64, we always enable PCI domains and we keep domain 0
|
||||
* backward compatible in /proc for video cards
|
||||
*/
|
||||
|
@ -173,7 +168,7 @@ static int __devinit pcibios_map_phb_io_space(struct pci_controller *hose)
|
|||
return -ENOMEM;
|
||||
|
||||
/* Fixup hose IO resource */
|
||||
io_virt_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
|
||||
io_virt_offset = pcibios_io_space_offset(hose);
|
||||
hose->io_resource.start += io_virt_offset;
|
||||
hose->io_resource.end += io_virt_offset;
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
|
|||
{
|
||||
u64 base, size;
|
||||
unsigned int flags;
|
||||
struct pci_bus_region region;
|
||||
struct resource *res;
|
||||
const u32 *addrs;
|
||||
u32 i;
|
||||
|
@ -106,10 +107,11 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
|
|||
printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
|
||||
continue;
|
||||
}
|
||||
res->start = base;
|
||||
res->end = base + size - 1;
|
||||
res->flags = flags;
|
||||
res->name = pci_name(dev);
|
||||
region.start = base;
|
||||
region.end = base + size - 1;
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,6 +211,7 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev)
|
|||
struct pci_bus *bus;
|
||||
const u32 *busrange, *ranges;
|
||||
int len, i, mode;
|
||||
struct pci_bus_region region;
|
||||
struct resource *res;
|
||||
unsigned int flags;
|
||||
u64 size;
|
||||
|
@ -270,9 +273,10 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev)
|
|||
res = bus->resource[i];
|
||||
++i;
|
||||
}
|
||||
res->start = of_read_number(&ranges[1], 2);
|
||||
res->end = res->start + size - 1;
|
||||
res->flags = flags;
|
||||
region.start = of_read_number(&ranges[1], 2);
|
||||
region.end = region.start + size - 1;
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
}
|
||||
sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
|
||||
bus->number);
|
||||
|
|
|
@ -279,7 +279,7 @@ void __init find_and_init_phbs(void)
|
|||
eeh_dev_phb_init();
|
||||
|
||||
/*
|
||||
* pci_probe_only and pci_assign_all_buses can be set via properties
|
||||
* PCI_PROBE_ONLY and PCI_REASSIGN_ALL_BUS can be set via properties
|
||||
* in chosen.
|
||||
*/
|
||||
if (of_chosen) {
|
||||
|
@ -287,8 +287,12 @@ void __init find_and_init_phbs(void)
|
|||
|
||||
prop = of_get_property(of_chosen,
|
||||
"linux,pci-probe-only", NULL);
|
||||
if (prop)
|
||||
pci_probe_only = *prop;
|
||||
if (prop) {
|
||||
if (*prop)
|
||||
pci_add_flags(PCI_PROBE_ONLY);
|
||||
else
|
||||
pci_clear_flags(PCI_PROBE_ONLY);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC32 /* Will be made generic soon */
|
||||
prop = of_get_property(of_chosen,
|
||||
|
|
|
@ -620,7 +620,7 @@ void __init maple_pci_init(void)
|
|||
}
|
||||
|
||||
/* Tell pci.c to not change any resource allocations. */
|
||||
pci_probe_only = 1;
|
||||
pci_add_flags(PCI_PROBE_ONLY);
|
||||
}
|
||||
|
||||
int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel)
|
||||
|
|
|
@ -229,9 +229,6 @@ void __init pas_pci_init(void)
|
|||
|
||||
/* Setup the linkage between OF nodes and PHBs */
|
||||
pci_devs_phb_init();
|
||||
|
||||
/* Use the common resource allocation mechanism */
|
||||
pci_probe_only = 1;
|
||||
}
|
||||
|
||||
void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset)
|
||||
|
|
|
@ -1059,9 +1059,6 @@ void __init pmac_pci_init(void)
|
|||
}
|
||||
/* pmac_check_ht_link(); */
|
||||
|
||||
/* We can allocate missing resources if any */
|
||||
pci_probe_only = 0;
|
||||
|
||||
#else /* CONFIG_PPC64 */
|
||||
init_p2pbridge();
|
||||
init_second_ohare();
|
||||
|
|
|
@ -1299,15 +1299,14 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
|
|||
/* Setup MSI support */
|
||||
pnv_pci_init_ioda_msis(phb);
|
||||
|
||||
/* We set both probe_only and PCI_REASSIGN_ALL_RSRC. This is an
|
||||
/* We set both PCI_PROBE_ONLY and PCI_REASSIGN_ALL_RSRC. This is an
|
||||
* odd combination which essentially means that we skip all resource
|
||||
* fixups and assignments in the generic code, and do it all
|
||||
* ourselves here
|
||||
*/
|
||||
pci_probe_only = 1;
|
||||
ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb;
|
||||
ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook;
|
||||
pci_add_flags(PCI_REASSIGN_ALL_RSRC);
|
||||
pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC);
|
||||
|
||||
/* Reset IODA tables to a clean state */
|
||||
rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET);
|
||||
|
|
|
@ -562,10 +562,7 @@ void __init pnv_pci_init(void)
|
|||
{
|
||||
struct device_node *np;
|
||||
|
||||
pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN);
|
||||
|
||||
/* We do not want to just probe */
|
||||
pci_probe_only = 0;
|
||||
pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN);
|
||||
|
||||
/* OPAL absent, try POPAL first then RTAS detection of PHBs */
|
||||
if (!firmware_has_feature(FW_FEATURE_OPAL)) {
|
||||
|
|
|
@ -84,7 +84,7 @@ void pcibios_remove_pci_devices(struct pci_bus *bus)
|
|||
list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
|
||||
pr_debug(" * Removing %s...\n", pci_name(dev));
|
||||
eeh_remove_bus_device(dev);
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
|
||||
|
|
|
@ -383,6 +383,9 @@ static void __init pSeries_setup_arch(void)
|
|||
|
||||
fwnmi_init();
|
||||
|
||||
/* By default, only probe PCI (can be overriden by rtas_pci) */
|
||||
pci_add_flags(PCI_PROBE_ONLY);
|
||||
|
||||
/* Find and initialize PCI host bridges */
|
||||
init_pci_config_tokens();
|
||||
eeh_pseries_init();
|
||||
|
|
|
@ -682,7 +682,6 @@ static int __init wsp_setup_one_phb(struct device_node *np)
|
|||
/* XXX Force re-assigning of everything for now */
|
||||
pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC |
|
||||
PCI_ENABLE_PROC_DOMAINS);
|
||||
pci_probe_only = 0;
|
||||
|
||||
/* Calculate how the TCE space is divided */
|
||||
phb->dma32_base = 0;
|
||||
|
|
|
@ -37,11 +37,20 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
|
|||
static int next_busno;
|
||||
static int need_domain_info;
|
||||
LIST_HEAD(resources);
|
||||
struct resource *res;
|
||||
resource_size_t offset;
|
||||
int i;
|
||||
struct pci_bus *bus;
|
||||
|
||||
for (i = 0; i < hose->nr_resources; i++)
|
||||
pci_add_resource(&resources, hose->resources + i);
|
||||
for (i = 0; i < hose->nr_resources; i++) {
|
||||
res = hose->resources + i;
|
||||
offset = 0;
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
offset = hose->io_offset;
|
||||
else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->mem_offset;
|
||||
pci_add_resource_offset(&resources, res, offset);
|
||||
}
|
||||
|
||||
bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
|
||||
&resources);
|
||||
|
@ -143,42 +152,12 @@ static int __init pcibios_init(void)
|
|||
}
|
||||
subsys_initcall(pcibios_init);
|
||||
|
||||
static void pcibios_fixup_device_resources(struct pci_dev *dev,
|
||||
struct pci_bus *bus)
|
||||
{
|
||||
/* Update device resources. */
|
||||
struct pci_channel *hose = bus->sysdata;
|
||||
unsigned long offset = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
|
||||
if (!dev->resource[i].start)
|
||||
continue;
|
||||
if (dev->resource[i].flags & IORESOURCE_IO)
|
||||
offset = hose->io_offset;
|
||||
else if (dev->resource[i].flags & IORESOURCE_MEM)
|
||||
offset = hose->mem_offset;
|
||||
|
||||
dev->resource[i].start += offset;
|
||||
dev->resource[i].end += offset;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after each bus is probed, but before its children
|
||||
* are examined.
|
||||
*/
|
||||
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
struct list_head *ln;
|
||||
|
||||
for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
|
||||
dev = pci_dev_b(ln);
|
||||
|
||||
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
|
||||
pcibios_fixup_device_resources(dev, bus);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -208,36 +187,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
|
|||
return start;
|
||||
}
|
||||
|
||||
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
struct pci_channel *hose = dev->sysdata;
|
||||
unsigned long offset = 0;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
offset = hose->io_offset;
|
||||
else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->mem_offset;
|
||||
|
||||
region->start = res->start - offset;
|
||||
region->end = res->end - offset;
|
||||
}
|
||||
|
||||
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
struct pci_channel *hose = dev->sysdata;
|
||||
unsigned long offset = 0;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
offset = hose->io_offset;
|
||||
else if (res->flags & IORESOURCE_MEM)
|
||||
offset = hose->mem_offset;
|
||||
|
||||
res->start = region->start + offset;
|
||||
res->end = region->end + offset;
|
||||
}
|
||||
|
||||
int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
return pci_enable_resources(dev, mask);
|
||||
|
@ -381,8 +330,6 @@ EXPORT_SYMBOL(pci_iounmap);
|
|||
#endif /* CONFIG_GENERIC_IOMAP */
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
EXPORT_SYMBOL(PCIBIOS_MIN_IO);
|
||||
EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
|
||||
#endif
|
||||
|
|
|
@ -114,12 +114,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
|
|||
/* Board-specific fixup routines. */
|
||||
int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin);
|
||||
|
||||
extern void pcibios_resource_to_bus(struct pci_dev *dev,
|
||||
struct pci_bus_region *region, struct resource *res);
|
||||
|
||||
extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
#define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index
|
||||
|
||||
static inline int pci_proc_domain(struct pci_bus *bus)
|
||||
|
|
|
@ -52,14 +52,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
|
|||
* 64Kbytes by the Host controller.
|
||||
*/
|
||||
|
||||
extern void
|
||||
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res);
|
||||
|
||||
extern void
|
||||
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
|
||||
{
|
||||
return PCI_IRQ_NONE;
|
||||
|
|
|
@ -73,14 +73,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
|||
enum pci_mmap_state mmap_state,
|
||||
int write_combine);
|
||||
|
||||
extern void
|
||||
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res);
|
||||
|
||||
extern void
|
||||
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
|
||||
{
|
||||
return PCI_IRQ_NONE;
|
||||
|
|
|
@ -15,14 +15,19 @@
|
|||
|
||||
/* The LEON architecture does not rely on a BIOS or bootloader to setup
|
||||
* PCI for us. The Linux generic routines are used to setup resources,
|
||||
* reset values of confuration-space registers settings ae preseved.
|
||||
* reset values of configuration-space register settings are preserved.
|
||||
*
|
||||
* PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is
|
||||
* accessed through a Window which is translated to low 64KB in PCI space, the
|
||||
* first 4KB is not used so 60KB is available.
|
||||
*/
|
||||
void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
|
||||
{
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *root_bus;
|
||||
|
||||
pci_add_resource(&resources, &info->io_space);
|
||||
pci_add_resource_offset(&resources, &info->io_space,
|
||||
info->io_space.start - 0x1000);
|
||||
pci_add_resource(&resources, &info->mem_space);
|
||||
|
||||
root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info,
|
||||
|
@ -38,44 +43,6 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
|
|||
}
|
||||
}
|
||||
|
||||
/* PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is
|
||||
* accessed through a Window which is translated to low 64KB in PCI space, the
|
||||
* first 4KB is not used so 60KB is available.
|
||||
*
|
||||
* This function is used by generic code to translate resource addresses into
|
||||
* PCI addresses.
|
||||
*/
|
||||
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
struct leon_pci_info *info = dev->bus->sysdata;
|
||||
|
||||
region->start = res->start;
|
||||
region->end = res->end;
|
||||
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
region->start -= (info->io_space.start - 0x1000);
|
||||
region->end -= (info->io_space.start - 0x1000);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
|
||||
/* see pcibios_resource_to_bus() comment */
|
||||
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
struct leon_pci_info *info = dev->bus->sysdata;
|
||||
|
||||
res->start = region->start;
|
||||
res->end = region->end;
|
||||
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
res->start += (info->io_space.start - 0x1000);
|
||||
res->end += (info->io_space.start - 0x1000);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
|
||||
void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
|
||||
{
|
||||
struct leon_pci_info *info = pbus->sysdata;
|
||||
|
|
|
@ -375,13 +375,6 @@ static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p)
|
|||
*last_p = last;
|
||||
}
|
||||
|
||||
static void pci_resource_adjust(struct resource *res,
|
||||
struct resource *root)
|
||||
{
|
||||
res->start += root->start;
|
||||
res->end += root->start;
|
||||
}
|
||||
|
||||
/* For PCI bus devices which lack a 'ranges' property we interrogate
|
||||
* the config space values to set the resources, just like the generic
|
||||
* Linux PCI probing code does.
|
||||
|
@ -390,7 +383,8 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev,
|
|||
struct pci_bus *bus,
|
||||
struct pci_pbm_info *pbm)
|
||||
{
|
||||
struct resource *res;
|
||||
struct pci_bus_region region;
|
||||
struct resource *res, res2;
|
||||
u8 io_base_lo, io_limit_lo;
|
||||
u16 mem_base_lo, mem_limit_lo;
|
||||
unsigned long base, limit;
|
||||
|
@ -412,11 +406,14 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev,
|
|||
res = bus->resource[0];
|
||||
if (base <= limit) {
|
||||
res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
|
||||
res2.flags = res->flags;
|
||||
region.start = base;
|
||||
region.end = limit + 0xfff;
|
||||
pcibios_bus_to_resource(dev, &res2, ®ion);
|
||||
if (!res->start)
|
||||
res->start = base;
|
||||
res->start = res2.start;
|
||||
if (!res->end)
|
||||
res->end = limit + 0xfff;
|
||||
pci_resource_adjust(res, &pbm->io_space);
|
||||
res->end = res2.end;
|
||||
}
|
||||
|
||||
pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
|
||||
|
@ -428,9 +425,9 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev,
|
|||
if (base <= limit) {
|
||||
res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) |
|
||||
IORESOURCE_MEM);
|
||||
res->start = base;
|
||||
res->end = limit + 0xfffff;
|
||||
pci_resource_adjust(res, &pbm->mem_space);
|
||||
region.start = base;
|
||||
region.end = limit + 0xfffff;
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
}
|
||||
|
||||
pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
|
||||
|
@ -459,9 +456,9 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev,
|
|||
if (base <= limit) {
|
||||
res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) |
|
||||
IORESOURCE_MEM | IORESOURCE_PREFETCH);
|
||||
res->start = base;
|
||||
res->end = limit + 0xfffff;
|
||||
pci_resource_adjust(res, &pbm->mem_space);
|
||||
region.start = base;
|
||||
region.end = limit + 0xfffff;
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,6 +469,7 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev,
|
|||
struct pci_bus *bus,
|
||||
struct pci_pbm_info *pbm)
|
||||
{
|
||||
struct pci_bus_region region;
|
||||
struct resource *res;
|
||||
u32 first, last;
|
||||
u8 map;
|
||||
|
@ -479,18 +477,18 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev,
|
|||
pci_read_config_byte(dev, APB_IO_ADDRESS_MAP, &map);
|
||||
apb_calc_first_last(map, &first, &last);
|
||||
res = bus->resource[0];
|
||||
res->start = (first << 21);
|
||||
res->end = (last << 21) + ((1 << 21) - 1);
|
||||
res->flags = IORESOURCE_IO;
|
||||
pci_resource_adjust(res, &pbm->io_space);
|
||||
region.start = (first << 21);
|
||||
region.end = (last << 21) + ((1 << 21) - 1);
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
|
||||
pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map);
|
||||
apb_calc_first_last(map, &first, &last);
|
||||
res = bus->resource[1];
|
||||
res->start = (first << 21);
|
||||
res->end = (last << 21) + ((1 << 21) - 1);
|
||||
res->flags = IORESOURCE_MEM;
|
||||
pci_resource_adjust(res, &pbm->mem_space);
|
||||
region.start = (first << 21);
|
||||
region.end = (last << 21) + ((1 << 21) - 1);
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
}
|
||||
|
||||
static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm,
|
||||
|
@ -506,6 +504,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
|
|||
struct pci_bus *bus;
|
||||
const u32 *busrange, *ranges;
|
||||
int len, i, simba;
|
||||
struct pci_bus_region region;
|
||||
struct resource *res;
|
||||
unsigned int flags;
|
||||
u64 size;
|
||||
|
@ -556,8 +555,6 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
|
|||
}
|
||||
i = 1;
|
||||
for (; len >= 32; len -= 32, ranges += 8) {
|
||||
struct resource *root;
|
||||
|
||||
flags = pci_parse_of_flags(ranges[0]);
|
||||
size = GET_64BIT(ranges, 6);
|
||||
if (flags == 0 || size == 0)
|
||||
|
@ -569,7 +566,6 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
|
|||
" for bridge %s\n", node->full_name);
|
||||
continue;
|
||||
}
|
||||
root = &pbm->io_space;
|
||||
} else {
|
||||
if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
|
||||
printk(KERN_ERR "PCI: too many memory ranges"
|
||||
|
@ -578,18 +574,12 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
|
|||
}
|
||||
res = bus->resource[i];
|
||||
++i;
|
||||
root = &pbm->mem_space;
|
||||
}
|
||||
|
||||
res->start = GET_64BIT(ranges, 1);
|
||||
res->end = res->start + size - 1;
|
||||
res->flags = flags;
|
||||
|
||||
/* Another way to implement this would be to add an of_device
|
||||
* layer routine that can calculate a resource for a given
|
||||
* range property value in a PCI device.
|
||||
*/
|
||||
pci_resource_adjust(res, root);
|
||||
region.start = GET_64BIT(ranges, 1);
|
||||
region.end = region.start + size - 1;
|
||||
pcibios_bus_to_resource(dev, res, ®ion);
|
||||
}
|
||||
after_ranges:
|
||||
sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
|
||||
|
@ -691,8 +681,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
|
|||
|
||||
printk("PCI: Scanning PBM %s\n", node->full_name);
|
||||
|
||||
pci_add_resource(&resources, &pbm->io_space);
|
||||
pci_add_resource(&resources, &pbm->mem_space);
|
||||
pci_add_resource_offset(&resources, &pbm->io_space,
|
||||
pbm->io_space.start);
|
||||
pci_add_resource_offset(&resources, &pbm->mem_space,
|
||||
pbm->mem_space.start);
|
||||
bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
|
||||
pbm, &resources);
|
||||
if (!bus) {
|
||||
|
@ -755,46 +747,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
struct pci_pbm_info *pbm = pdev->bus->sysdata;
|
||||
struct resource zero_res, *root;
|
||||
|
||||
zero_res.start = 0;
|
||||
zero_res.end = 0;
|
||||
zero_res.flags = res->flags;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
root = &pbm->io_space;
|
||||
else
|
||||
root = &pbm->mem_space;
|
||||
|
||||
pci_resource_adjust(&zero_res, root);
|
||||
|
||||
region->start = res->start - zero_res.start;
|
||||
region->end = res->end - zero_res.start;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
|
||||
void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
|
||||
struct pci_bus_region *region)
|
||||
{
|
||||
struct pci_pbm_info *pbm = pdev->bus->sysdata;
|
||||
struct resource *root;
|
||||
|
||||
res->start = region->start;
|
||||
res->end = region->end;
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
root = &pbm->io_space;
|
||||
else
|
||||
root = &pbm->mem_space;
|
||||
|
||||
pci_resource_adjust(res, root);
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
|
||||
char * __devinit pcibios_setup(char *str)
|
||||
{
|
||||
return str;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#ifdef __KERNEL__
|
||||
#include <asm-generic/pci-dma-compat.h>
|
||||
#include <asm-generic/pci-bridge.h>
|
||||
#include <asm-generic/pci.h>
|
||||
#include <mach/hardware.h> /* for PCIBIOS_MIN_* */
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <linux/io.h>
|
||||
|
||||
static int debug_pci;
|
||||
static int use_firmware;
|
||||
|
||||
#define CONFIG_CMD(bus, devfn, where) \
|
||||
(0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
|
||||
|
@ -276,7 +275,7 @@ static int __init pci_common_init(void)
|
|||
|
||||
pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq);
|
||||
|
||||
if (!use_firmware) {
|
||||
if (!pci_has_flag(PCI_PROBE_ONLY)) {
|
||||
/*
|
||||
* Size the bridge windows.
|
||||
*/
|
||||
|
@ -303,7 +302,7 @@ char * __devinit pcibios_setup(char *str)
|
|||
debug_pci = 1;
|
||||
return NULL;
|
||||
} else if (!strcmp(str, "firmware")) {
|
||||
use_firmware = 1;
|
||||
pci_add_flags(PCI_PROBE_ONLY);
|
||||
return NULL;
|
||||
}
|
||||
return str;
|
||||
|
|
|
@ -262,10 +262,11 @@ rootfs_initcall(pci_iommu_init);
|
|||
|
||||
static __devinit void via_no_dac(struct pci_dev *dev)
|
||||
{
|
||||
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
|
||||
if (forbid_dac == 0) {
|
||||
dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n");
|
||||
forbid_dac = 1;
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac);
|
||||
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID,
|
||||
PCI_CLASS_BRIDGE_PCI, 8, via_no_dac);
|
||||
#endif
|
||||
|
|
|
@ -416,7 +416,12 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
|
|||
kfree(sd);
|
||||
} else {
|
||||
get_current_resources(device, busnum, domain, &resources);
|
||||
if (list_empty(&resources))
|
||||
|
||||
/*
|
||||
* _CRS with no apertures is normal, so only fall back to
|
||||
* defaults or native bridge info if we're ignoring _CRS.
|
||||
*/
|
||||
if (!pci_use_crs)
|
||||
x86_pci_root_bus_resources(busnum, &resources);
|
||||
bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd,
|
||||
&resources);
|
||||
|
|
|
@ -164,11 +164,11 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_
|
|||
*/
|
||||
static void __devinit pci_fixup_transparent_bridge(struct pci_dev *dev)
|
||||
{
|
||||
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
|
||||
(dev->device & 0xff00) == 0x2400)
|
||||
if ((dev->device & 0xff00) == 0x2400)
|
||||
dev->transparent = 1;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_bridge);
|
||||
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
|
||||
PCI_CLASS_BRIDGE_PCI, 8, pci_fixup_transparent_bridge);
|
||||
|
||||
/*
|
||||
* Fixup for C1 Halt Disconnect problem on nForce2 systems.
|
||||
|
@ -322,9 +322,6 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
|
|||
struct pci_bus *bus;
|
||||
u16 config;
|
||||
|
||||
if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
|
||||
return;
|
||||
|
||||
/* Is VGA routed to us? */
|
||||
bus = pdev->bus;
|
||||
while (bus) {
|
||||
|
@ -353,7 +350,8 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
|
|||
dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n");
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
|
||||
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
|
||||
PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video);
|
||||
|
||||
|
||||
static const struct dmi_system_id __devinitconst msi_k8t_dmi_table[] = {
|
||||
|
|
|
@ -39,6 +39,87 @@
|
|||
#include <asm/io_apic.h>
|
||||
|
||||
|
||||
/*
|
||||
* This list of dynamic mappings is for temporarily maintaining
|
||||
* original BIOS BAR addresses for possible reinstatement.
|
||||
*/
|
||||
struct pcibios_fwaddrmap {
|
||||
struct list_head list;
|
||||
struct pci_dev *dev;
|
||||
resource_size_t fw_addr[DEVICE_COUNT_RESOURCE];
|
||||
};
|
||||
|
||||
static LIST_HEAD(pcibios_fwaddrmappings);
|
||||
static DEFINE_SPINLOCK(pcibios_fwaddrmap_lock);
|
||||
|
||||
/* Must be called with 'pcibios_fwaddrmap_lock' lock held. */
|
||||
static struct pcibios_fwaddrmap *pcibios_fwaddrmap_lookup(struct pci_dev *dev)
|
||||
{
|
||||
struct pcibios_fwaddrmap *map;
|
||||
|
||||
WARN_ON(!spin_is_locked(&pcibios_fwaddrmap_lock));
|
||||
|
||||
list_for_each_entry(map, &pcibios_fwaddrmappings, list)
|
||||
if (map->dev == dev)
|
||||
return map;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pcibios_save_fw_addr(struct pci_dev *dev, int idx, resource_size_t fw_addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct pcibios_fwaddrmap *map;
|
||||
|
||||
spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags);
|
||||
map = pcibios_fwaddrmap_lookup(dev);
|
||||
if (!map) {
|
||||
spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags);
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
map->dev = pci_dev_get(dev);
|
||||
map->fw_addr[idx] = fw_addr;
|
||||
INIT_LIST_HEAD(&map->list);
|
||||
|
||||
spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags);
|
||||
list_add_tail(&map->list, &pcibios_fwaddrmappings);
|
||||
} else
|
||||
map->fw_addr[idx] = fw_addr;
|
||||
spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags);
|
||||
}
|
||||
|
||||
resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct pcibios_fwaddrmap *map;
|
||||
resource_size_t fw_addr = 0;
|
||||
|
||||
spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags);
|
||||
map = pcibios_fwaddrmap_lookup(dev);
|
||||
if (map)
|
||||
fw_addr = map->fw_addr[idx];
|
||||
spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags);
|
||||
|
||||
return fw_addr;
|
||||
}
|
||||
|
||||
static void pcibios_fw_addr_list_del(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct pcibios_fwaddrmap *entry, *next;
|
||||
|
||||
spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags);
|
||||
list_for_each_entry_safe(entry, next, &pcibios_fwaddrmappings, list) {
|
||||
list_del(&entry->list);
|
||||
pci_dev_put(entry->dev);
|
||||
kfree(entry);
|
||||
}
|
||||
spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
skip_isa_ioresource_align(struct pci_dev *dev) {
|
||||
|
||||
|
@ -182,7 +263,8 @@ static void __init pcibios_allocate_resources(int pass)
|
|||
idx, r, disabled, pass);
|
||||
if (pci_claim_resource(dev, idx) < 0) {
|
||||
/* We'll assign a new address later */
|
||||
dev->fw_addr[idx] = r->start;
|
||||
pcibios_save_fw_addr(dev,
|
||||
idx, r->start);
|
||||
r->end -= r->start;
|
||||
r->start = 0;
|
||||
}
|
||||
|
@ -228,6 +310,7 @@ static int __init pcibios_assign_resources(void)
|
|||
}
|
||||
|
||||
pci_assign_unassigned_resources();
|
||||
pcibios_fw_addr_list_del();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#define PCI_FIXED_BAR_4_SIZE 0x14
|
||||
#define PCI_FIXED_BAR_5_SIZE 0x1c
|
||||
|
||||
static int pci_soc_mode = 0;
|
||||
|
||||
/**
|
||||
* fixed_bar_cap - return the offset of the fixed BAR cap if found
|
||||
* @bus: PCI bus
|
||||
|
@ -148,7 +150,9 @@ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg)
|
|||
*/
|
||||
if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE)
|
||||
return 0;
|
||||
if (bus == 0 && (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(0, 0)))
|
||||
if (bus == 0 && (devfn == PCI_DEVFN(2, 0)
|
||||
|| devfn == PCI_DEVFN(0, 0)
|
||||
|| devfn == PCI_DEVFN(3, 0)))
|
||||
return 1;
|
||||
return 0; /* langwell on others */
|
||||
}
|
||||
|
@ -231,14 +235,43 @@ struct pci_ops pci_mrst_ops = {
|
|||
*/
|
||||
int __init pci_mrst_init(void)
|
||||
{
|
||||
printk(KERN_INFO "Moorestown platform detected, using MRST PCI ops\n");
|
||||
printk(KERN_INFO "Intel MID platform detected, using MID PCI ops\n");
|
||||
pci_mmcfg_late_init();
|
||||
pcibios_enable_irq = mrst_pci_irq_enable;
|
||||
pci_root_ops = pci_mrst_ops;
|
||||
pci_soc_mode = 1;
|
||||
/* Continue with standard init */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Langwell devices are not true pci devices, they are not subject to 10 ms
|
||||
* d3 to d0 delay required by pci spec.
|
||||
*/
|
||||
static void __devinit pci_d3delay_fixup(struct pci_dev *dev)
|
||||
{
|
||||
/* PCI fixups are effectively decided compile time. If we have a dual
|
||||
SoC/non-SoC kernel we don't want to mangle d3 on non SoC devices */
|
||||
if (!pci_soc_mode)
|
||||
return;
|
||||
/* true pci devices in lincroft should allow type 1 access, the rest
|
||||
* are langwell fake pci devices.
|
||||
*/
|
||||
if (type1_access_ok(dev->bus->number, dev->devfn, PCI_DEVICE_ID))
|
||||
return;
|
||||
dev->d3_delay = 0;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3delay_fixup);
|
||||
|
||||
static void __devinit mrst_power_off_unused_dev(struct pci_dev *dev)
|
||||
{
|
||||
pci_set_power_state(dev, PCI_D3cold);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0801, mrst_power_off_unused_dev);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0809, mrst_power_off_unused_dev);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x080C, mrst_power_off_unused_dev);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0812, mrst_power_off_unused_dev);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0815, mrst_power_off_unused_dev);
|
||||
|
||||
/*
|
||||
* Langwell devices reside at fixed offsets, don't try to move them.
|
||||
*/
|
||||
|
@ -248,6 +281,9 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)
|
|||
u32 size;
|
||||
int i;
|
||||
|
||||
if (!pci_soc_mode)
|
||||
return;
|
||||
|
||||
/* Must have extended configuration space */
|
||||
if (dev->cfg_size < PCIE_CAP_OFFSET + 4)
|
||||
return;
|
||||
|
|
|
@ -153,7 +153,7 @@ static void __init pci_controller_apertures(struct pci_controller *pci_ctrl,
|
|||
}
|
||||
res->start += io_offset;
|
||||
res->end += io_offset;
|
||||
pci_add_resource(resources, res);
|
||||
pci_add_resource_offset(resources, res, io_offset);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
res = &pci_ctrl->mem_resources[i];
|
||||
|
@ -200,24 +200,9 @@ subsys_initcall(pcibios_init);
|
|||
|
||||
void __init pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_controller *pci_ctrl = bus->sysdata;
|
||||
struct resource *res;
|
||||
unsigned long io_offset;
|
||||
int i;
|
||||
|
||||
io_offset = (unsigned long)pci_ctrl->io_space.base;
|
||||
if (bus->parent) {
|
||||
/* This is a subordinate bridge */
|
||||
pci_read_bridge_bases(bus);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((res = bus->resource[i]) == NULL || !res->flags)
|
||||
continue;
|
||||
if (io_offset && (res->flags & IORESOURCE_IO)) {
|
||||
res->start += io_offset;
|
||||
res->end += io_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -346,7 +346,7 @@ static int mpt_remove_dead_ioc_func(void *arg)
|
|||
if ((pdev == NULL))
|
||||
return -1;
|
||||
|
||||
pci_remove_bus_device(pdev);
|
||||
pci_stop_and_remove_bus_device(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -553,7 +553,6 @@ dino_fixup_bus(struct pci_bus *bus)
|
|||
struct list_head *ln;
|
||||
struct pci_dev *dev;
|
||||
struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
|
||||
int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
|
||||
|
||||
DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n",
|
||||
__func__, bus, bus->secondary,
|
||||
|
@ -599,8 +598,6 @@ dino_fixup_bus(struct pci_bus *bus)
|
|||
|
||||
|
||||
list_for_each(ln, &bus->devices) {
|
||||
int i;
|
||||
|
||||
dev = pci_dev_b(ln);
|
||||
if (is_card_dino(&dino_dev->hba.dev->id))
|
||||
dino_card_fixup(dev);
|
||||
|
@ -612,21 +609,6 @@ dino_fixup_bus(struct pci_bus *bus)
|
|||
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
|
||||
continue;
|
||||
|
||||
/* Adjust the I/O Port space addresses */
|
||||
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
|
||||
struct resource *res = &dev->resource[i];
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
res->start |= port_base;
|
||||
res->end |= port_base;
|
||||
}
|
||||
#ifdef __LP64__
|
||||
/* Sign Extend MMIO addresses */
|
||||
else if (res->flags & IORESOURCE_MEM) {
|
||||
res->start |= F_EXTEND(0UL);
|
||||
res->end |= F_EXTEND(0UL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* null out the ROM resource if there is one (we don't
|
||||
* care about an expansion rom on parisc, since it
|
||||
* usually contains (x86) bios code) */
|
||||
|
@ -991,11 +973,14 @@ static int __init dino_probe(struct parisc_device *dev)
|
|||
|
||||
dev->dev.platform_data = dino_dev;
|
||||
|
||||
pci_add_resource(&resources, &dino_dev->hba.io_space);
|
||||
pci_add_resource_offset(&resources, &dino_dev->hba.io_space,
|
||||
HBA_PORT_BASE(dino_dev->hba.hba_num));
|
||||
if (dino_dev->hba.lmmio_space.flags)
|
||||
pci_add_resource(&resources, &dino_dev->hba.lmmio_space);
|
||||
pci_add_resource_offset(&resources, &dino_dev->hba.lmmio_space,
|
||||
dino_dev->hba.lmmio_space_offset);
|
||||
if (dino_dev->hba.elmmio_space.flags)
|
||||
pci_add_resource(&resources, &dino_dev->hba.elmmio_space);
|
||||
pci_add_resource_offset(&resources, &dino_dev->hba.elmmio_space,
|
||||
dino_dev->hba.lmmio_space_offset);
|
||||
if (dino_dev->hba.gmmio_space.flags)
|
||||
pci_add_resource(&resources, &dino_dev->hba.gmmio_space);
|
||||
|
||||
|
|
|
@ -635,7 +635,6 @@ lba_fixup_bus(struct pci_bus *bus)
|
|||
u16 status;
|
||||
#endif
|
||||
struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge));
|
||||
int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
|
||||
|
||||
DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n",
|
||||
bus, bus->secondary, bus->bridge->platform_data);
|
||||
|
@ -726,27 +725,6 @@ lba_fixup_bus(struct pci_bus *bus)
|
|||
if (!res->start)
|
||||
continue;
|
||||
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
DBG("lba_fixup_bus() I/O Ports [%lx/%lx] -> ",
|
||||
res->start, res->end);
|
||||
res->start |= lba_portbase;
|
||||
res->end |= lba_portbase;
|
||||
DBG("[%lx/%lx]\n", res->start, res->end);
|
||||
} else if (res->flags & IORESOURCE_MEM) {
|
||||
/*
|
||||
** Convert PCI (IO_VIEW) addresses to
|
||||
** processor (PA_VIEW) addresses
|
||||
*/
|
||||
DBG("lba_fixup_bus() MMIO [%lx/%lx] -> ",
|
||||
res->start, res->end);
|
||||
res->start = PCI_HOST_ADDR(HBA_DATA(ldev), res->start);
|
||||
res->end = PCI_HOST_ADDR(HBA_DATA(ldev), res->end);
|
||||
DBG("[%lx/%lx]\n", res->start, res->end);
|
||||
} else {
|
||||
DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX",
|
||||
res->flags, res->start, res->end);
|
||||
}
|
||||
|
||||
/*
|
||||
** FIXME: this will result in whinging for devices
|
||||
** that share expansion ROMs (think quad tulip), but
|
||||
|
@ -1514,11 +1492,14 @@ lba_driver_probe(struct parisc_device *dev)
|
|||
lba_dev->hba.lmmio_space.flags = 0;
|
||||
}
|
||||
|
||||
pci_add_resource(&resources, &lba_dev->hba.io_space);
|
||||
pci_add_resource_offset(&resources, &lba_dev->hba.io_space,
|
||||
HBA_PORT_BASE(lba_dev->hba.hba_num));
|
||||
if (lba_dev->hba.elmmio_space.start)
|
||||
pci_add_resource(&resources, &lba_dev->hba.elmmio_space);
|
||||
pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space,
|
||||
lba_dev->hba.lmmio_space_offset);
|
||||
if (lba_dev->hba.lmmio_space.flags)
|
||||
pci_add_resource(&resources, &lba_dev->hba.lmmio_space);
|
||||
pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space,
|
||||
lba_dev->hba.lmmio_space_offset);
|
||||
if (lba_dev->hba.gmmio_space.flags)
|
||||
pci_add_resource(&resources, &lba_dev->hba.gmmio_space);
|
||||
|
||||
|
|
|
@ -31,6 +31,19 @@ config PCI_DEBUG
|
|||
|
||||
When in doubt, say N.
|
||||
|
||||
config PCI_REALLOC_ENABLE_AUTO
|
||||
bool "Enable PCI resource re-allocation detection"
|
||||
depends on PCI
|
||||
help
|
||||
Say Y here if you want the PCI core to detect if PCI resource
|
||||
re-allocation needs to be enabled. You can always use pci=realloc=on
|
||||
or pci=realloc=off to override it. Note this feature is a no-op
|
||||
unless PCI_IOV support is also enabled; in that case it will
|
||||
automatically re-allocate PCI resources if SR-IOV BARs have not
|
||||
been allocated by the BIOS.
|
||||
|
||||
When in doubt, say N.
|
||||
|
||||
config PCI_STUB
|
||||
tristate "PCI Stub driver"
|
||||
depends on PCI
|
||||
|
|
|
@ -18,28 +18,36 @@
|
|||
|
||||
#include "pci.h"
|
||||
|
||||
void pci_add_resource(struct list_head *resources, struct resource *res)
|
||||
void pci_add_resource_offset(struct list_head *resources, struct resource *res,
|
||||
resource_size_t offset)
|
||||
{
|
||||
struct pci_bus_resource *bus_res;
|
||||
struct pci_host_bridge_window *window;
|
||||
|
||||
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);
|
||||
window = kzalloc(sizeof(struct pci_host_bridge_window), GFP_KERNEL);
|
||||
if (!window) {
|
||||
printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res);
|
||||
return;
|
||||
}
|
||||
|
||||
bus_res->res = res;
|
||||
list_add_tail(&bus_res->list, resources);
|
||||
window->res = res;
|
||||
window->offset = offset;
|
||||
list_add_tail(&window->list, resources);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_add_resource_offset);
|
||||
|
||||
void pci_add_resource(struct list_head *resources, struct resource *res)
|
||||
{
|
||||
pci_add_resource_offset(resources, res, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_add_resource);
|
||||
|
||||
void pci_free_resource_list(struct list_head *resources)
|
||||
{
|
||||
struct pci_bus_resource *bus_res, *tmp;
|
||||
struct pci_host_bridge_window *window, *tmp;
|
||||
|
||||
list_for_each_entry_safe(bus_res, tmp, resources, list) {
|
||||
list_del(&bus_res->list);
|
||||
kfree(bus_res);
|
||||
list_for_each_entry_safe(window, tmp, resources, list) {
|
||||
list_del(&window->list);
|
||||
kfree(window);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(pci_free_resource_list);
|
||||
|
|
|
@ -800,20 +800,10 @@ static int __ref enable_device(struct acpiphp_slot *slot)
|
|||
if (slot->flags & SLOT_ENABLED)
|
||||
goto err_exit;
|
||||
|
||||
/* sanity check: dev should be NULL when hot-plugged in */
|
||||
dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
|
||||
if (dev) {
|
||||
/* This case shouldn't happen */
|
||||
err("pci_dev structure already exists.\n");
|
||||
pci_dev_put(dev);
|
||||
retval = -1;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
|
||||
if (num == 0) {
|
||||
err("No new device found\n");
|
||||
retval = -1;
|
||||
/* Maybe only part of funcs are added. */
|
||||
dbg("No new device found\n");
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
|
@ -848,11 +838,16 @@ static int __ref enable_device(struct acpiphp_slot *slot)
|
|||
|
||||
pci_bus_add_devices(bus);
|
||||
|
||||
slot->flags |= SLOT_ENABLED;
|
||||
list_for_each_entry(func, &slot->funcs, sibling) {
|
||||
dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
|
||||
func->function));
|
||||
if (!dev)
|
||||
if (!dev) {
|
||||
/* Do not set SLOT_ENABLED flag if some funcs
|
||||
are not added. */
|
||||
slot->flags &= (~SLOT_ENABLED);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
|
||||
dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) {
|
||||
|
@ -867,7 +862,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
|
|||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
slot->flags |= SLOT_ENABLED;
|
||||
|
||||
err_exit:
|
||||
return retval;
|
||||
|
@ -892,9 +886,12 @@ static int disable_device(struct acpiphp_slot *slot)
|
|||
{
|
||||
struct acpiphp_func *func;
|
||||
struct pci_dev *pdev;
|
||||
struct pci_bus *bus = slot->bridge->pci_bus;
|
||||
|
||||
/* is this slot already disabled? */
|
||||
if (!(slot->flags & SLOT_ENABLED))
|
||||
/* The slot will be enabled when func 0 is added, so check
|
||||
func 0 before disable the slot. */
|
||||
pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
|
||||
if (!pdev)
|
||||
goto err_exit;
|
||||
|
||||
list_for_each_entry(func, &slot->funcs, sibling) {
|
||||
|
@ -913,7 +910,7 @@ static int disable_device(struct acpiphp_slot *slot)
|
|||
disable_bridges(pdev->subordinate);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
pci_remove_bus_device(pdev);
|
||||
__pci_remove_bus_device(pdev);
|
||||
pci_dev_put(pdev);
|
||||
}
|
||||
}
|
||||
|
@ -1070,7 +1067,7 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
|
|||
res->end) {
|
||||
/* Could not assign a required resources
|
||||
* for this device, remove it */
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -341,7 +341,7 @@ int cpci_unconfigure_slot(struct slot* slot)
|
|||
dev = pci_get_slot(slot->bus,
|
||||
PCI_DEVFN(PCI_SLOT(slot->devfn), i));
|
||||
if (dev) {
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
|
||||
|
||||
/* local variables */
|
||||
static int debug;
|
||||
static bool debug;
|
||||
static char *bridge;
|
||||
static u8 bridge_busnr;
|
||||
static u8 bridge_slot;
|
||||
|
|
|
@ -127,7 +127,7 @@ int cpqhp_unconfigure_device(struct pci_func* func)
|
|||
struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j));
|
||||
if (temp) {
|
||||
pci_dev_put(temp);
|
||||
pci_remove_bus_device(temp);
|
||||
pci_stop_and_remove_bus_device(temp);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -40,7 +40,7 @@ static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr,
|
|||
|
||||
static void remove_callback(void *data)
|
||||
{
|
||||
pci_remove_bus_device((struct pci_dev *)data);
|
||||
pci_stop_and_remove_bus_device((struct pci_dev *)data);
|
||||
}
|
||||
|
||||
static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr,
|
||||
|
|
|
@ -721,7 +721,7 @@ static void ibm_unconfigure_device(struct pci_func *func)
|
|||
for (j = 0; j < 0x08; j++) {
|
||||
temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
|
||||
if (temp) {
|
||||
pci_remove_bus_device(temp);
|
||||
pci_stop_and_remove_bus_device(temp);
|
||||
pci_dev_put(temp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -368,8 +368,10 @@ int __init ibmphp_access_ebda (void)
|
|||
debug ("rio blk id: %x\n", blk_id);
|
||||
|
||||
rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL);
|
||||
if (!rio_table_ptr)
|
||||
return -ENOMEM;
|
||||
if (!rio_table_ptr) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
rio_table_ptr->ver_num = readb (io_mem + offset);
|
||||
rio_table_ptr->scal_count = readb (io_mem + offset + 1);
|
||||
rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
|
||||
|
|
|
@ -241,34 +241,79 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
|
|||
return retval;
|
||||
}
|
||||
|
||||
static inline int check_link_active(struct controller *ctrl)
|
||||
static bool check_link_active(struct controller *ctrl)
|
||||
{
|
||||
u16 link_status;
|
||||
bool ret = false;
|
||||
u16 lnk_status;
|
||||
|
||||
if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &link_status))
|
||||
return 0;
|
||||
return !!(link_status & PCI_EXP_LNKSTA_DLLLA);
|
||||
if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status))
|
||||
return ret;
|
||||
|
||||
ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
|
||||
|
||||
if (ret)
|
||||
ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pcie_wait_link_active(struct controller *ctrl)
|
||||
static void __pcie_wait_link_active(struct controller *ctrl, bool active)
|
||||
{
|
||||
int timeout = 1000;
|
||||
|
||||
if (check_link_active(ctrl))
|
||||
if (check_link_active(ctrl) == active)
|
||||
return;
|
||||
while (timeout > 0) {
|
||||
msleep(10);
|
||||
timeout -= 10;
|
||||
if (check_link_active(ctrl))
|
||||
if (check_link_active(ctrl) == active)
|
||||
return;
|
||||
}
|
||||
ctrl_dbg(ctrl, "Data Link Layer Link Active not set in 1000 msec\n");
|
||||
ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n",
|
||||
active ? "set" : "cleared");
|
||||
}
|
||||
|
||||
static void pcie_wait_link_active(struct controller *ctrl)
|
||||
{
|
||||
__pcie_wait_link_active(ctrl, true);
|
||||
}
|
||||
|
||||
static void pcie_wait_link_not_active(struct controller *ctrl)
|
||||
{
|
||||
__pcie_wait_link_active(ctrl, false);
|
||||
}
|
||||
|
||||
static bool pci_bus_check_dev(struct pci_bus *bus, int devfn)
|
||||
{
|
||||
u32 l;
|
||||
int count = 0;
|
||||
int delay = 1000, step = 20;
|
||||
bool found = false;
|
||||
|
||||
do {
|
||||
found = pci_bus_read_dev_vendor_id(bus, devfn, &l, 0);
|
||||
count++;
|
||||
|
||||
if (found)
|
||||
break;
|
||||
|
||||
msleep(step);
|
||||
delay -= step;
|
||||
} while (delay > 0);
|
||||
|
||||
if (count > 1 && pciehp_debug)
|
||||
printk(KERN_DEBUG "pci %04x:%02x:%02x.%d id reading try %d times with interval %d ms to get %08x\n",
|
||||
pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
|
||||
PCI_FUNC(devfn), count, step, l);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
int pciehp_check_link_status(struct controller *ctrl)
|
||||
{
|
||||
u16 lnk_status;
|
||||
int retval = 0;
|
||||
bool found = false;
|
||||
|
||||
/*
|
||||
* Data Link Layer Link Active Reporting must be capable for
|
||||
|
@ -280,13 +325,10 @@ int pciehp_check_link_status(struct controller *ctrl)
|
|||
else
|
||||
msleep(1000);
|
||||
|
||||
/*
|
||||
* Need to wait for 1000 ms after Data Link Layer Link Active
|
||||
* (DLLLA) bit reads 1b before sending configuration request.
|
||||
* We need it before checking Link Training (LT) bit becuase
|
||||
* LT is still set even after DLLLA bit is set on some platform.
|
||||
*/
|
||||
msleep(1000);
|
||||
/* wait 100ms before read pci conf, and try in 1s */
|
||||
msleep(100);
|
||||
found = pci_bus_check_dev(ctrl->pcie->port->subordinate,
|
||||
PCI_DEVFN(0, 0));
|
||||
|
||||
retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
|
||||
if (retval) {
|
||||
|
@ -302,19 +344,50 @@ int pciehp_check_link_status(struct controller *ctrl)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the port supports Link speeds greater than 5.0 GT/s, we
|
||||
* must wait for 100 ms after Link training completes before
|
||||
* sending configuration request.
|
||||
*/
|
||||
if (ctrl->pcie->port->subordinate->max_bus_speed > PCIE_SPEED_5_0GT)
|
||||
msleep(100);
|
||||
|
||||
pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
|
||||
|
||||
if (!found && !retval)
|
||||
retval = -1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int __pciehp_link_set(struct controller *ctrl, bool enable)
|
||||
{
|
||||
u16 lnk_ctrl;
|
||||
int retval = 0;
|
||||
|
||||
retval = pciehp_readw(ctrl, PCI_EXP_LNKCTL, &lnk_ctrl);
|
||||
if (retval) {
|
||||
ctrl_err(ctrl, "Cannot read LNKCTRL register\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
lnk_ctrl &= ~PCI_EXP_LNKCTL_LD;
|
||||
else
|
||||
lnk_ctrl |= PCI_EXP_LNKCTL_LD;
|
||||
|
||||
retval = pciehp_writew(ctrl, PCI_EXP_LNKCTL, lnk_ctrl);
|
||||
if (retval) {
|
||||
ctrl_err(ctrl, "Cannot write LNKCTRL register\n");
|
||||
return retval;
|
||||
}
|
||||
ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int pciehp_link_enable(struct controller *ctrl)
|
||||
{
|
||||
return __pciehp_link_set(ctrl, true);
|
||||
}
|
||||
|
||||
static int pciehp_link_disable(struct controller *ctrl)
|
||||
{
|
||||
return __pciehp_link_set(ctrl, false);
|
||||
}
|
||||
|
||||
int pciehp_get_attention_status(struct slot *slot, u8 *status)
|
||||
{
|
||||
struct controller *ctrl = slot->ctrl;
|
||||
|
@ -533,6 +606,10 @@ int pciehp_power_on_slot(struct slot * slot)
|
|||
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
|
||||
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
|
||||
|
||||
retval = pciehp_link_enable(ctrl);
|
||||
if (retval)
|
||||
ctrl_err(ctrl, "%s: Can not enable the link!\n", __func__);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -543,6 +620,14 @@ int pciehp_power_off_slot(struct slot * slot)
|
|||
u16 cmd_mask;
|
||||
int retval;
|
||||
|
||||
/* Disable the link at first */
|
||||
pciehp_link_disable(ctrl);
|
||||
/* wait the link is down */
|
||||
if (ctrl->link_active_reporting)
|
||||
pcie_wait_link_not_active(ctrl);
|
||||
else
|
||||
msleep(1000);
|
||||
|
||||
slot_cmd = POWER_OFF;
|
||||
cmd_mask = PCI_EXP_SLTCTL_PCC;
|
||||
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
|
||||
|
|
|
@ -141,7 +141,7 @@ int pciehp_unconfigure_device(struct slot *p_slot)
|
|||
break;
|
||||
}
|
||||
}
|
||||
pci_remove_bus_device(temp);
|
||||
pci_stop_and_remove_bus_device(temp);
|
||||
/*
|
||||
* Ensure that no new Requests will be generated from
|
||||
* the device.
|
||||
|
|
|
@ -389,7 +389,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
|
|||
BUG_ON(!bus->self);
|
||||
pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self));
|
||||
eeh_remove_bus_device(bus->self);
|
||||
pci_remove_bus_device(bus->self);
|
||||
pci_stop_and_remove_bus_device(bus->self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -554,7 +554,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
|
|||
PCI_FUNC(func)));
|
||||
if (dev) {
|
||||
sn_bus_free_data(dev);
|
||||
pci_remove_bus_device(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ int shpchp_unconfigure_device(struct slot *p_slot)
|
|||
break;
|
||||
}
|
||||
}
|
||||
pci_remove_bus_device(temp);
|
||||
pci_stop_and_remove_bus_device(temp);
|
||||
pci_dev_put(temp);
|
||||
}
|
||||
return rc;
|
||||
|
|
|
@ -142,7 +142,7 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
|
|||
failed1:
|
||||
pci_dev_put(dev);
|
||||
mutex_lock(&iov->dev->sriov->lock);
|
||||
pci_remove_bus_device(virtfn);
|
||||
pci_stop_and_remove_bus_device(virtfn);
|
||||
virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
|
||||
mutex_unlock(&iov->dev->sriov->lock);
|
||||
|
||||
|
@ -173,10 +173,16 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset)
|
|||
|
||||
sprintf(buf, "virtfn%u", id);
|
||||
sysfs_remove_link(&dev->dev.kobj, buf);
|
||||
sysfs_remove_link(&virtfn->dev.kobj, "physfn");
|
||||
/*
|
||||
* pci_stop_dev() could have been called for this virtfn already,
|
||||
* so the directory for the virtfn may have been removed before.
|
||||
* Double check to avoid spurious sysfs warnings.
|
||||
*/
|
||||
if (virtfn->dev.kobj.sd)
|
||||
sysfs_remove_link(&virtfn->dev.kobj, "physfn");
|
||||
|
||||
mutex_lock(&iov->dev->sriov->lock);
|
||||
pci_remove_bus_device(virtfn);
|
||||
pci_stop_and_remove_bus_device(virtfn);
|
||||
virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
|
||||
mutex_unlock(&iov->dev->sriov->lock);
|
||||
|
||||
|
|
|
@ -419,6 +419,16 @@ static void pci_device_shutdown(struct device *dev)
|
|||
drv->shutdown(pci_dev);
|
||||
pci_msi_shutdown(pci_dev);
|
||||
pci_msix_shutdown(pci_dev);
|
||||
|
||||
/*
|
||||
* Devices may be enabled to wake up by runtime PM, but they need not
|
||||
* be supposed to wake up the system from its "power off" state (e.g.
|
||||
* ACPI S5). Therefore disable wakeup for all devices that aren't
|
||||
* supposed to wake up the system at this point. The state argument
|
||||
* will be ignored by pci_enable_wake().
|
||||
*/
|
||||
if (!device_may_wakeup(dev))
|
||||
pci_enable_wake(pci_dev, PCI_UNKNOWN, false);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -330,7 +330,7 @@ static void remove_callback(struct device *dev)
|
|||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
mutex_lock(&pci_remove_rescan_mutex);
|
||||
pci_remove_bus_device(pdev);
|
||||
pci_stop_and_remove_bus_device(pdev);
|
||||
mutex_unlock(&pci_remove_rescan_mutex);
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,10 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
|
|||
|
||||
if (val) {
|
||||
mutex_lock(&pci_remove_rescan_mutex);
|
||||
pci_rescan_bus(bus);
|
||||
if (!pci_is_root_bus(bus) && list_empty(&bus->devices))
|
||||
pci_rescan_bus_bridge_resize(bus->self);
|
||||
else
|
||||
pci_rescan_bus(bus);
|
||||
mutex_unlock(&pci_remove_rescan_mutex);
|
||||
}
|
||||
return count;
|
||||
|
|
|
@ -94,6 +94,9 @@ u8 pci_cache_line_size;
|
|||
*/
|
||||
unsigned int pcibios_max_latency = 255;
|
||||
|
||||
/* If set, the PCIe ARI capability will not be used. */
|
||||
static bool pcie_ari_disabled;
|
||||
|
||||
/**
|
||||
* pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
|
||||
* @bus: pointer to PCI bus structure to search
|
||||
|
@ -825,6 +828,19 @@ EXPORT_SYMBOL(pci_choose_state);
|
|||
#define pcie_cap_has_sltctl2(type, flags) \
|
||||
((flags & PCI_EXP_FLAGS_VERS) > 1)
|
||||
|
||||
static struct pci_cap_saved_state *pci_find_saved_cap(
|
||||
struct pci_dev *pci_dev, char cap)
|
||||
{
|
||||
struct pci_cap_saved_state *tmp;
|
||||
struct hlist_node *pos;
|
||||
|
||||
hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) {
|
||||
if (tmp->cap.cap_nr == cap)
|
||||
return tmp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int pci_save_pcie_state(struct pci_dev *dev)
|
||||
{
|
||||
int pos, i = 0;
|
||||
|
@ -959,6 +975,7 @@ void pci_restore_state(struct pci_dev *dev)
|
|||
{
|
||||
int i;
|
||||
u32 val;
|
||||
int tries;
|
||||
|
||||
if (!dev->state_saved)
|
||||
return;
|
||||
|
@ -973,12 +990,16 @@ 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]) {
|
||||
tries = 10;
|
||||
while (tries && val != dev->saved_config_space[i]) {
|
||||
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,
|
||||
dev->saved_config_space[i]);
|
||||
pci_read_config_dword(dev, i * 4, &val);
|
||||
mdelay(10);
|
||||
tries--;
|
||||
}
|
||||
}
|
||||
pci_restore_pcix_state(dev);
|
||||
|
@ -1864,6 +1885,12 @@ void platform_pci_wakeup_init(struct pci_dev *dev)
|
|||
platform_pci_sleep_wake(dev, false);
|
||||
}
|
||||
|
||||
static void pci_add_saved_cap(struct pci_dev *pci_dev,
|
||||
struct pci_cap_saved_state *new_cap)
|
||||
{
|
||||
hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_add_save_buffer - allocate buffer for saving given capability registers
|
||||
* @dev: the PCI device
|
||||
|
@ -1911,6 +1938,15 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
|
|||
"unable to preallocate PCI-X save buffer\n");
|
||||
}
|
||||
|
||||
void pci_free_cap_save_buffers(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_cap_saved_state *tmp;
|
||||
struct hlist_node *pos, *n;
|
||||
|
||||
hlist_for_each_entry_safe(tmp, pos, n, &dev->saved_cap_space, next)
|
||||
kfree(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_enable_ari - enable ARI forwarding if hardware support it
|
||||
* @dev: the PCI device
|
||||
|
@ -1922,7 +1958,7 @@ void pci_enable_ari(struct pci_dev *dev)
|
|||
u16 flags, ctrl;
|
||||
struct pci_dev *bridge;
|
||||
|
||||
if (!pci_is_pcie(dev) || dev->devfn)
|
||||
if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
|
||||
return;
|
||||
|
||||
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
|
||||
|
@ -3661,6 +3697,68 @@ int pci_is_reassigndev(struct pci_dev *dev)
|
|||
return (pci_specified_resource_alignment(dev) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function disables memory decoding and releases memory resources
|
||||
* of the device specified by kernel's boot parameter 'pci=resource_alignment='.
|
||||
* It also rounds up size to specified alignment.
|
||||
* Later on, the kernel will assign page-aligned memory resource back
|
||||
* to the device.
|
||||
*/
|
||||
void pci_reassigndev_resource_alignment(struct pci_dev *dev)
|
||||
{
|
||||
int i;
|
||||
struct resource *r;
|
||||
resource_size_t align, size;
|
||||
u16 command;
|
||||
|
||||
if (!pci_is_reassigndev(dev))
|
||||
return;
|
||||
|
||||
if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
|
||||
dev_warn(&dev->dev,
|
||||
"Can't reassign resources to host bridge.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dev_info(&dev->dev,
|
||||
"Disabling memory decoding and releasing memory resources.\n");
|
||||
pci_read_config_word(dev, PCI_COMMAND, &command);
|
||||
command &= ~PCI_COMMAND_MEMORY;
|
||||
pci_write_config_word(dev, PCI_COMMAND, command);
|
||||
|
||||
align = pci_specified_resource_alignment(dev);
|
||||
for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
|
||||
r = &dev->resource[i];
|
||||
if (!(r->flags & IORESOURCE_MEM))
|
||||
continue;
|
||||
size = resource_size(r);
|
||||
if (size < align) {
|
||||
size = align;
|
||||
dev_info(&dev->dev,
|
||||
"Rounding up size of resource #%d to %#llx.\n",
|
||||
i, (unsigned long long)size);
|
||||
}
|
||||
r->end = size - 1;
|
||||
r->start = 0;
|
||||
}
|
||||
/* Need to disable bridge's resource window,
|
||||
* to enable the kernel to reassign new resource
|
||||
* window later on.
|
||||
*/
|
||||
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
|
||||
r = &dev->resource[i];
|
||||
if (!(r->flags & IORESOURCE_MEM))
|
||||
continue;
|
||||
r->end = resource_size(r) - 1;
|
||||
r->start = 0;
|
||||
}
|
||||
pci_disable_bridge_window(dev);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t pci_set_resource_alignment_param(const char *buf, size_t count)
|
||||
{
|
||||
if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1)
|
||||
|
@ -3739,10 +3837,14 @@ static int __init pci_setup(char *str)
|
|||
pci_no_msi();
|
||||
} else if (!strcmp(str, "noaer")) {
|
||||
pci_no_aer();
|
||||
} else if (!strncmp(str, "realloc=", 8)) {
|
||||
pci_realloc_get_opt(str + 8);
|
||||
} else if (!strncmp(str, "realloc", 7)) {
|
||||
pci_realloc();
|
||||
pci_realloc_get_opt("on");
|
||||
} else if (!strcmp(str, "nodomains")) {
|
||||
pci_no_domains();
|
||||
} else if (!strncmp(str, "noari", 5)) {
|
||||
pcie_ari_disabled = true;
|
||||
} else if (!strncmp(str, "cbiosize=", 9)) {
|
||||
pci_cardbus_io_size = memparse(str + 9, &str);
|
||||
} else if (!strncmp(str, "cbmemsize=", 10)) {
|
||||
|
|
|
@ -73,6 +73,7 @@ extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
|
|||
extern void pci_pm_init(struct pci_dev *dev);
|
||||
extern void platform_pci_wakeup_init(struct pci_dev *dev);
|
||||
extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
|
||||
void pci_free_cap_save_buffers(struct pci_dev *dev);
|
||||
|
||||
static inline void pci_wakeup_event(struct pci_dev *dev)
|
||||
{
|
||||
|
@ -148,7 +149,7 @@ static inline void pci_no_msi(void) { }
|
|||
static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
|
||||
#endif
|
||||
|
||||
extern void pci_realloc(void);
|
||||
void pci_realloc_get_opt(char *);
|
||||
|
||||
static inline int pci_no_d1d2(struct pci_dev *dev)
|
||||
{
|
||||
|
@ -207,6 +208,8 @@ enum pci_bar_type {
|
|||
pci_bar_mem64, /* A 64-bit memory BAR */
|
||||
};
|
||||
|
||||
bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
|
||||
int crs_timeout);
|
||||
extern int pci_setup_device(struct pci_dev *dev);
|
||||
extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
struct resource *res, unsigned int reg);
|
||||
|
@ -225,11 +228,8 @@ static inline int pci_ari_enabled(struct pci_bus *bus)
|
|||
return bus->self && bus->self->ari_enabled;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_QUIRKS
|
||||
extern int pci_is_reassigndev(struct pci_dev *dev);
|
||||
resource_size_t pci_specified_resource_alignment(struct pci_dev *dev);
|
||||
void pci_reassigndev_resource_alignment(struct pci_dev *dev);
|
||||
extern void pci_disable_bridge_window(struct pci_dev *dev);
|
||||
#endif
|
||||
|
||||
/* Single Root I/O Virtualization */
|
||||
struct pci_sriov {
|
||||
|
|
|
@ -55,6 +55,31 @@ config PCIEASPM_DEBUG
|
|||
This enables PCI Express ASPM debug support. It will add per-device
|
||||
interface to control ASPM.
|
||||
|
||||
choice
|
||||
prompt "Default ASPM policy"
|
||||
default PCIEASPM_DEFAULT
|
||||
depends on PCIEASPM
|
||||
|
||||
config PCIEASPM_DEFAULT
|
||||
bool "BIOS default"
|
||||
depends on PCIEASPM
|
||||
help
|
||||
Use the BIOS defaults for PCI Express ASPM.
|
||||
|
||||
config PCIEASPM_POWERSAVE
|
||||
bool "Powersave"
|
||||
depends on PCIEASPM
|
||||
help
|
||||
Enable PCI Express ASPM L0s and L1 where possible, even if the
|
||||
BIOS did not.
|
||||
|
||||
config PCIEASPM_PERFORMANCE
|
||||
bool "Performance"
|
||||
depends on PCIEASPM
|
||||
help
|
||||
Disable PCI Express ASPM L0s and L1, even if the BIOS enabled them.
|
||||
endchoice
|
||||
|
||||
config PCIE_PME
|
||||
def_bool y
|
||||
depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue