summaryrefslogtreecommitdiff
path: root/arch/alpha/kernel/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/alpha/kernel/pci.c')
-rw-r--r--arch/alpha/kernel/pci.c86
1 files changed, 55 insertions, 31 deletions
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index edb4e0097b75..8e9b4ac86b7e 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* linux/arch/alpha/kernel/pci.c
*
@@ -17,10 +18,11 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/module.h>
#include <linux/cache.h>
#include <linux/slab.h>
+#include <linux/syscalls.h>
#include <asm/machvec.h>
#include "proto.h"
@@ -196,9 +198,16 @@ pcibios_init(void)
subsys_initcall(pcibios_init);
#ifdef ALPHA_RESTORE_SRM_SETUP
+/* Store PCI device configuration left by SRM here. */
+struct pdev_srm_saved_conf
+{
+ struct pdev_srm_saved_conf *next;
+ struct pci_dev *dev;
+};
+
static struct pdev_srm_saved_conf *srm_saved_configs;
-void pdev_save_srm_config(struct pci_dev *dev)
+static void pdev_save_srm_config(struct pci_dev *dev)
{
struct pdev_srm_saved_conf *tmp;
static int printed = 0;
@@ -238,6 +247,8 @@ pci_restore_srm_config(void)
pci_restore_state(tmp->dev);
}
}
+#else
+#define pdev_save_srm_config(dev) do {} while (0)
#endif
void pcibios_fixup_bus(struct pci_bus *bus)
@@ -245,21 +256,15 @@ void pcibios_fixup_bus(struct pci_bus *bus)
struct pci_dev *dev = bus->self;
if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
- (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
- pci_read_bridge_bases(bus);
- }
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ pci_read_bridge_bases(bus);
+ }
list_for_each_entry(dev, &bus->devices, bus_list) {
pdev_save_srm_config(dev);
}
}
-int
-pcibios_enable_device(struct pci_dev *dev, int mask)
-{
- return pci_enable_resources(dev, mask);
-}
-
/*
* If we set up a device for bus mastering, we need to check the latency
* timer as certain firmware forgets to set it properly, as seen
@@ -283,16 +288,19 @@ pcibios_claim_one_bus(struct pci_bus *b)
struct pci_bus *child_bus;
list_for_each_entry(dev, &b->devices, bus_list) {
+ struct resource *r;
int i;
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- struct resource *r = &dev->resource[i];
-
+ pci_dev_for_each_resource(dev, r, i) {
if (r->parent || !r->start || !r->flags)
continue;
if (pci_has_flag(PCI_PROBE_ONLY) ||
- (r->flags & IORESOURCE_PCI_FIXED))
- pci_claim_resource(dev, i);
+ (r->flags & IORESOURCE_PCI_FIXED)) {
+ if (pci_claim_resource(dev, i) == 0)
+ continue;
+
+ pci_claim_bridge_resource(dev, i);
+ }
}
}
@@ -314,8 +322,9 @@ common_init_pci(void)
{
struct pci_controller *hose;
struct list_head resources;
+ struct pci_host_bridge *bridge;
struct pci_bus *bus;
- int next_busno;
+ int ret, next_busno;
int need_domain_info = 0;
u32 pci_mem_end;
u32 sg_base;
@@ -338,9 +347,25 @@ common_init_pci(void)
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);
- hose->bus = bus;
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ continue;
+
+ list_splice_init(&resources, &bridge->windows);
+ bridge->dev.parent = NULL;
+ bridge->sysdata = hose;
+ bridge->busnr = next_busno;
+ bridge->ops = alpha_mv.pci_ops;
+ bridge->swizzle_irq = alpha_mv.pci_swizzle;
+ bridge->map_irq = alpha_mv.pci_map_irq;
+
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret) {
+ pci_free_host_bridge(bridge);
+ continue;
+ }
+
+ bus = hose->bus = bridge->bus;
hose->need_domain_info = need_domain_info;
next_busno = bus->busn_res.end + 1;
/* Don't allow 8-bit bus number overflow inside the hose -
@@ -354,16 +379,19 @@ common_init_pci(void)
pcibios_claim_console_setup();
pci_assign_unassigned_resources();
- pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
+ for (hose = hose_head; hose; hose = hose->next) {
+ bus = hose->bus;
+ if (bus)
+ pci_bus_add_devices(bus);
+ }
}
-
struct pci_controller * __init
alloc_pci_controller(void)
{
struct pci_controller *hose;
- hose = alloc_bootmem(sizeof(*hose));
+ hose = memblock_alloc_or_panic(sizeof(*hose), SMP_CACHE_BYTES);
*hose_tail = hose;
hose_tail = &hose->next;
@@ -374,19 +402,15 @@ alloc_pci_controller(void)
struct resource * __init
alloc_resource(void)
{
- struct resource *res;
-
- res = alloc_bootmem(sizeof(*res));
-
- return res;
+ return memblock_alloc_or_panic(sizeof(struct resource), SMP_CACHE_BYTES);
}
/* Provide information on locations of various I/O regions in physical
memory. Do this on a per-card basis so that we choose the right hose. */
-asmlinkage long
-sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn)
+SYSCALL_DEFINE3(pciconfig_iobase, long, which, unsigned long, bus,
+ unsigned long, dfn)
{
struct pci_controller *hose;
struct pci_dev *dev;
@@ -401,7 +425,7 @@ sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn)
if (bus == 0 && dfn == 0) {
hose = pci_isa_hose;
} else {
- dev = pci_get_bus_and_slot(bus, dfn);
+ dev = pci_get_domain_bus_and_slot(0, bus, dfn);
if (!dev)
return -ENODEV;
hose = dev->sysdata;