aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/pci.c')
-rw-r--r--arch/ppc64/kernel/pci.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index 446b4654883..8447dcc2c2b 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -21,6 +21,7 @@
21#include <linux/bootmem.h> 21#include <linux/bootmem.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/syscalls.h>
24 25
25#include <asm/processor.h> 26#include <asm/processor.h>
26#include <asm/io.h> 27#include <asm/io.h>
@@ -984,3 +985,62 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
984} 985}
985 986
986#endif /* CONFIG_PPC_MULTIPLATFORM */ 987#endif /* CONFIG_PPC_MULTIPLATFORM */
988
989
990#define IOBASE_BRIDGE_NUMBER 0
991#define IOBASE_MEMORY 1
992#define IOBASE_IO 2
993#define IOBASE_ISA_IO 3
994#define IOBASE_ISA_MEM 4
995
996long sys_pciconfig_iobase(long which, unsigned long in_bus,
997 unsigned long in_devfn)
998{
999 struct pci_controller* hose;
1000 struct list_head *ln;
1001 struct pci_bus *bus = NULL;
1002 struct device_node *hose_node;
1003
1004 /* Argh ! Please forgive me for that hack, but that's the
1005 * simplest way to get existing XFree to not lockup on some
1006 * G5 machines... So when something asks for bus 0 io base
1007 * (bus 0 is HT root), we return the AGP one instead.
1008 */
1009#ifdef CONFIG_PPC_PMAC
1010 if (systemcfg->platform == PLATFORM_POWERMAC &&
1011 machine_is_compatible("MacRISC4"))
1012 if (in_bus == 0)
1013 in_bus = 0xf0;
1014#endif /* CONFIG_PPC_PMAC */
1015
1016 /* That syscall isn't quite compatible with PCI domains, but it's
1017 * used on pre-domains setup. We return the first match
1018 */
1019
1020 for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
1021 bus = pci_bus_b(ln);
1022 if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
1023 break;
1024 bus = NULL;
1025 }
1026 if (bus == NULL || bus->sysdata == NULL)
1027 return -ENODEV;
1028
1029 hose_node = (struct device_node *)bus->sysdata;
1030 hose = PCI_DN(hose_node)->phb;
1031
1032 switch (which) {
1033 case IOBASE_BRIDGE_NUMBER:
1034 return (long)hose->first_busno;
1035 case IOBASE_MEMORY:
1036 return (long)hose->pci_mem_offset;
1037 case IOBASE_IO:
1038 return (long)hose->io_base_phys;
1039 case IOBASE_ISA_IO:
1040 return (long)isa_io_base;
1041 case IOBASE_ISA_MEM:
1042 return -EINVAL;
1043 }
1044
1045 return -EOPNOTSUPP;
1046}