KVM: PPC: Export __giveup_vsx
[safe/jmp/linux-2.6] / arch / powerpc / kernel / setup_64.c
index e29b275..6568406 100644 (file)
@@ -12,7 +12,6 @@
 
 #undef DEBUG
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/sched.h>
@@ -21,7 +20,6 @@
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/initrd.h>
-#include <linux/ide.h>
 #include <linux/seq_file.h>
 #include <linux/ioport.h>
 #include <linux/console.h>
@@ -34,6 +32,9 @@
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
 #include <linux/bootmem.h>
+#include <linux/pci.h>
+#include <linux/lockdep.h>
+#include <linux/lmb.h>
 #include <asm/io.h>
 #include <asm/kdump.h>
 #include <asm/prom.h>
 #include <asm/cache.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
-#include <asm/lmb.h>
-#include <asm/iseries/it_lp_naca.h>
 #include <asm/firmware.h>
 #include <asm/xmon.h>
 #include <asm/udbg.h>
 #include <asm/kexec.h>
+#include <asm/swiotlb.h>
+#include <asm/mmu_context.h>
 
 #include "setup.h"
 
 #define DBG(fmt...)
 #endif
 
-int have_of = 1;
 int boot_cpuid = 0;
-int boot_cpuid_phys = 0;
-dev_t boot_dev;
 u64 ppc64_pft_size;
 
 /* Pick defaults since we might want to patch instructions
  * before we've read this from the device tree.
  */
 struct ppc64_caches ppc64_caches = {
-       .dline_size = 0x80,
-       .log_dline_size = 7,
-       .iline_size = 0x80,
-       .log_iline_size = 7
+       .dline_size = 0x40,
+       .log_dline_size = 6,
+       .iline_size = 0x40,
+       .log_iline_size = 6
 };
 EXPORT_SYMBOL_GPL(ppc64_caches);
 
@@ -96,22 +94,6 @@ int dcache_bsize;
 int icache_bsize;
 int ucache_bsize;
 
-/* The main machine-dep calls structure
- */
-struct machdep_calls ppc_md;
-EXPORT_SYMBOL(ppc_md);
-
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned long SYSRQ_KEY;
-#endif /* CONFIG_MAGIC_SYSRQ */
-
-
-static int ppc64_panic_event(struct notifier_block *, unsigned long, void *);
-static struct notifier_block ppc64_panic_block = {
-       .notifier_call = ppc64_panic_event,
-       .priority = INT_MIN /* may not return; must be done last */
-};
-
 #ifdef CONFIG_SMP
 
 static int smt_enabled_cmdline;
@@ -120,7 +102,7 @@ static int smt_enabled_cmdline;
 static void check_smt_enabled(void)
 {
        struct device_node *dn;
-       char *smt_option;
+       const char *smt_option;
 
        /* Allow the command line to overrule the OF option */
        if (smt_enabled_cmdline)
@@ -129,7 +111,7 @@ static void check_smt_enabled(void)
        dn = of_find_node_by_path("/options");
 
        if (dn) {
-               smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL);
+               smt_option = of_get_property(dn, "ibm,smt-enabled", NULL);
 
                 if (smt_option) {
                        if (!strcmp(smt_option, "on"))
@@ -161,31 +143,15 @@ early_param("smt-enabled", early_smt_enabled);
 #define check_smt_enabled()
 #endif /* CONFIG_SMP */
 
-extern struct machdep_calls pSeries_md;
-extern struct machdep_calls pmac_md;
-extern struct machdep_calls maple_md;
-extern struct machdep_calls cell_md;
-extern struct machdep_calls iseries_md;
-
-/* Ultimately, stuff them in an elf section like initcalls... */
-static struct machdep_calls __initdata *machines[] = {
-#ifdef CONFIG_PPC_PSERIES
-       &pSeries_md,
-#endif /* CONFIG_PPC_PSERIES */
-#ifdef CONFIG_PPC_PMAC
-       &pmac_md,
-#endif /* CONFIG_PPC_PMAC */
-#ifdef CONFIG_PPC_MAPLE
-       &maple_md,
-#endif /* CONFIG_PPC_MAPLE */
-#ifdef CONFIG_PPC_CELL
-       &cell_md,
-#endif
-#ifdef CONFIG_PPC_ISERIES
-       &iseries_md,
+/* Put the paca pointer into r13 and SPRG_PACA */
+void __init setup_paca(int cpu)
+{
+       local_paca = &paca[cpu];
+       mtspr(SPRN_SPRG_PACA, local_paca);
+#ifdef CONFIG_PPC_BOOK3E
+       mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
 #endif
-       NULL
-};
+}
 
 /*
  * Early initialization entry point. This is called by head.S
@@ -208,60 +174,49 @@ static struct machdep_calls __initdata *machines[] = {
 
 void __init early_setup(unsigned long dt_ptr)
 {
-       struct paca_struct *lpaca = get_paca();
-       static struct machdep_calls **mach;
+       /* -------- printk is _NOT_ safe to use here ! ------- */
+
+       /* Fill in any unititialised pacas */
+       initialise_pacas();
+
+       /* Identify CPU type */
+       identify_cpu(0, mfspr(SPRN_PVR));
+
+       /* Assume we're on cpu 0 for now. Don't write to the paca yet! */
+       setup_paca(0);
+
+       /* Initialize lockdep early or else spinlocks will blow */
+       lockdep_init();
+
+       /* -------- printk is now safe to use ------- */
 
        /* Enable early debugging if any specified (see udbg.h) */
        udbg_early_init();
 
-       DBG(" -> early_setup()\n");
+       DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr);
 
        /*
-        * Do early initializations using the flattened device
-        * tree, like retreiving the physical memory map or
-        * calculating/retreiving the hash table size
+        * Do early initialization using the flattened device
+        * tree, such as retrieving the physical memory map or
+        * calculating/retrieving the hash table size.
         */
        early_init_devtree(__va(dt_ptr));
 
-       /*
-        * Iterate all ppc_md structures until we find the proper
-        * one for the current machine type
-        */
-       DBG("Probing machine type for platform %x...\n", _machine);
+       /* Now we know the logical id of our boot cpu, setup the paca. */
+       setup_paca(boot_cpuid);
 
-       for (mach = machines; *mach; mach++) {
-               if ((*mach)->probe(_machine))
-                       break;
-       }
-       /* What can we do if we didn't find ? */
-       if (*mach == NULL) {
-               DBG("No suitable machine found !\n");
-               for (;;);
-       }
-       ppc_md = **mach;
+       /* Fix up paca fields required for the boot cpu */
+       get_paca()->cpu_start = 1;
 
-#ifdef CONFIG_CRASH_DUMP
-       kdump_setup();
-#endif
+       /* Probe the machine type */
+       probe_machine();
+
+       setup_kdump_trampoline();
 
        DBG("Found, Initializing memory management...\n");
 
-       /*
-        * Initialize the MMU Hash table and create the linear mapping
-        * of memory. Has to be done before stab/slb initialization as
-        * this is currently where the page size encoding is obtained
-        */
-       htab_initialize();
-
-       /*
-        * Initialize stab / SLB management except on iSeries
-        */
-       if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
-               if (cpu_has_feature(CPU_FTR_SLB))
-                       slb_initialize();
-               else
-                       stab_initialize(lpaca->stab_real);
-       }
+       /* Initialize the hash table or TLB handling */
+       early_init_mmu();
 
        DBG(" <- early_setup()\n");
 }
@@ -269,22 +224,11 @@ void __init early_setup(unsigned long dt_ptr)
 #ifdef CONFIG_SMP
 void early_setup_secondary(void)
 {
-       struct paca_struct *lpaca = get_paca();
+       /* Mark interrupts enabled in PACA */
+       get_paca()->soft_enabled = 0;
 
-       /* Mark enabled in PACA */
-       lpaca->proc_enabled = 0;
-
-       /* Initialize hash table for that CPU */
-       htab_initialize_secondary();
-
-       /* Initialize STAB/SLB. We use a virtual address as it works
-        * in real mode on pSeries and we want a virutal address on
-        * iSeries anyway
-        */
-       if (cpu_has_feature(CPU_FTR_SLB))
-               slb_initialize();
-       else
-               stab_initialize(lpaca->stab_addr);
+       /* Initialize the hash table or TLB handling */
+       early_init_mmu_secondary();
 }
 
 #endif /* CONFIG_SMP */
@@ -292,7 +236,6 @@ void early_setup_secondary(void)
 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
 void smp_release_cpus(void)
 {
-       extern unsigned long __secondary_hold_spinloop;
        unsigned long *ptr;
 
        DBG(" -> smp_release_cpus()\n");
@@ -301,18 +244,15 @@ void smp_release_cpus(void)
         * all now so they can start to spin on their individual paca
         * spinloops. For non SMP kernels, the secondary cpus never get out
         * of the common spinloop.
-        * This is useless but harmless on iSeries, secondaries are already
-        * waiting on their paca spinloops. */
+        */
 
        ptr  = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
                        - PHYSICAL_START);
-       *ptr = 1;
+       *ptr = __pa(generic_secondary_smp_init);
        mb();
 
        DBG(" <- smp_release_cpus()\n");
 }
-#else
-#define smp_release_cpus()
 #endif /* CONFIG_SMP || CONFIG_KEXEC */
 
 /*
@@ -337,25 +277,18 @@ static void __init initialize_cache_info(void)
                 */
 
                if ( num_cpus == 1 ) {
-                       u32 *sizep, *lsizep;
+                       const u32 *sizep, *lsizep;
                        u32 size, lsize;
-                       const char *dc, *ic;
-
-                       /* Then read cache informations */
-                       if (_machine == PLATFORM_POWERMAC) {
-                               dc = "d-cache-block-size";
-                               ic = "i-cache-block-size";
-                       } else {
-                               dc = "d-cache-line-size";
-                               ic = "i-cache-line-size";
-                       }
 
                        size = 0;
                        lsize = cur_cpu_spec->dcache_bsize;
-                       sizep = (u32 *)get_property(np, "d-cache-size", NULL);
+                       sizep = of_get_property(np, "d-cache-size", NULL);
                        if (sizep != NULL)
                                size = *sizep;
-                       lsizep = (u32 *) get_property(np, dc, NULL);
+                       lsizep = of_get_property(np, "d-cache-block-size", NULL);
+                       /* fallback if block size missing */
+                       if (lsizep == NULL)
+                               lsizep = of_get_property(np, "d-cache-line-size", NULL);
                        if (lsizep != NULL)
                                lsize = *lsizep;
                        if (sizep == 0 || lsizep == 0)
@@ -369,10 +302,12 @@ static void __init initialize_cache_info(void)
 
                        size = 0;
                        lsize = cur_cpu_spec->icache_bsize;
-                       sizep = (u32 *)get_property(np, "i-cache-size", NULL);
+                       sizep = of_get_property(np, "i-cache-size", NULL);
                        if (sizep != NULL)
                                size = *sizep;
-                       lsizep = (u32 *)get_property(np, ic, NULL);
+                       lsizep = of_get_property(np, "i-cache-block-size", NULL);
+                       if (lsizep == NULL)
+                               lsizep = of_get_property(np, "i-cache-line-size", NULL);
                        if (lsizep != NULL)
                                lsize = *lsizep;
                        if (sizep == 0 || lsizep == 0)
@@ -398,24 +333,26 @@ void __init setup_system(void)
 {
        DBG(" -> setup_system()\n");
 
+       /* Apply the CPUs-specific and firmware specific fixups to kernel
+        * text (nop out sections not relevant to this CPU or this firmware)
+        */
+       do_feature_fixups(cur_cpu_spec->cpu_features,
+                         &__start___ftr_fixup, &__stop___ftr_fixup);
+       do_feature_fixups(cur_cpu_spec->mmu_features,
+                         &__start___mmu_ftr_fixup, &__stop___mmu_ftr_fixup);
+       do_feature_fixups(powerpc_firmware_features,
+                         &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
+       do_lwsync_fixups(cur_cpu_spec->cpu_features,
+                        &__start___lwsync_fixup, &__stop___lwsync_fixup);
+
        /*
         * Unflatten the device-tree passed by prom_init or kexec
         */
        unflatten_device_tree();
 
-#ifdef CONFIG_KEXEC
-       kexec_setup();  /* requires unflattened device tree. */
-#endif
-
        /*
         * Fill the ppc64_caches & systemcfg structures with informations
-        * retrieved from the device-tree. Need to be called before
-        * finish_device_tree() since the later requires some of the
-        * informations filled up here to properly parse the interrupt
-        * tree.
-        * It also sets up the cache line sizes which allows to call
-        * routines like flush_icache_range (used by the hash init
-        * later on).
+        * retrieved from the device-tree.
         */
        initialize_cache_info();
 
@@ -436,7 +373,8 @@ void __init setup_system(void)
         * setting up the hash table pointers. It also sets up some interrupt-mapping
         * related options that will be used by finish_device_tree()
         */
-       ppc_md.init_early();
+       if (ppc_md.init_early)
+               ppc_md.init_early();
 
        /*
         * We can discover serial ports now since the above did setup the
@@ -446,66 +384,49 @@ void __init setup_system(void)
        find_legacy_serial_ports();
 
        /*
-        * "Finish" the device-tree, that is do the actual parsing of
-        * some of the properties like the interrupt map
+        * Register early console
         */
-       finish_device_tree();
+       register_early_udbg_console();
 
        /*
         * Initialize xmon
         */
-#ifdef CONFIG_XMON_DEFAULT
-       xmon_init(1);
-#endif
-       /*
-        * Register early console
-        */
-       register_early_udbg_console();
-
-       /* Save unparsed command line copy for /proc/cmdline */
-       strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
-
-       parse_early_param();
+       xmon_setup();
 
        check_smt_enabled();
        smp_setup_cpu_maps();
 
+#ifdef CONFIG_SMP
        /* Release secondary cpus out of their spinloops at 0x60 now that
         * we can map physical -> logical CPU ids
         */
        smp_release_cpus();
+#endif
 
-       printk("Starting Linux PPC64 %s\n", system_utsname.version);
+       printk("Starting Linux PPC64 %s\n", init_utsname()->version);
 
        printk("-----------------------------------------------------\n");
-       printk("ppc64_pft_size                = 0x%lx\n", ppc64_pft_size);
-       printk("ppc64_interrupt_controller    = 0x%ld\n",
-              ppc64_interrupt_controller);
-       printk("platform                      = 0x%x\n", _machine);
-       printk("physicalMemorySize            = 0x%lx\n", lmb_phys_mem_size());
-       printk("ppc64_caches.dcache_line_size = 0x%x\n",
-              ppc64_caches.dline_size);
-       printk("ppc64_caches.icache_line_size = 0x%x\n",
-              ppc64_caches.iline_size);
-       printk("htab_address                  = 0x%p\n", htab_address);
+       printk("ppc64_pft_size                = 0x%llx\n", ppc64_pft_size);
+       printk("physicalMemorySize            = 0x%llx\n", lmb_phys_mem_size());
+       if (ppc64_caches.dline_size != 0x80)
+               printk("ppc64_caches.dcache_line_size = 0x%x\n",
+                      ppc64_caches.dline_size);
+       if (ppc64_caches.iline_size != 0x80)
+               printk("ppc64_caches.icache_line_size = 0x%x\n",
+                      ppc64_caches.iline_size);
+#ifdef CONFIG_PPC_STD_MMU_64
+       if (htab_address)
+               printk("htab_address                  = 0x%p\n", htab_address);
        printk("htab_hash_mask                = 0x%lx\n", htab_hash_mask);
-#if PHYSICAL_START > 0
-       printk("physical_start                = 0x%x\n", PHYSICAL_START);
-#endif
+#endif /* CONFIG_PPC_STD_MMU_64 */
+       if (PHYSICAL_START > 0)
+               printk("physical_start                = 0x%llx\n",
+                      (unsigned long long)PHYSICAL_START);
        printk("-----------------------------------------------------\n");
 
-       mm_init_ppc64();
-
        DBG(" <- setup_system()\n");
 }
 
-static int ppc64_panic_event(struct notifier_block *this,
-                             unsigned long event, void *ptr)
-{
-       ppc_md.panic((char *)ptr);  /* May not return */
-       return NOTIFY_DONE;
-}
-
 #ifdef CONFIG_IRQSTACKS
 static void __init irqstack_early_init(void)
 {
@@ -515,7 +436,7 @@ static void __init irqstack_early_init(void)
         * interrupt stacks must be under 256MB, we cannot afford to take
         * SLB misses on them.
         */
-       for_each_cpu(i) {
+       for_each_possible_cpu(i) {
                softirq_ctx[i] = (struct thread_info *)
                        __va(lmb_alloc_base(THREAD_SIZE,
                                            THREAD_SIZE, 0x10000000));
@@ -528,6 +449,24 @@ static void __init irqstack_early_init(void)
 #define irqstack_early_init()
 #endif
 
+#ifdef CONFIG_PPC_BOOK3E
+static void __init exc_lvl_early_init(void)
+{
+       unsigned int i;
+
+       for_each_possible_cpu(i) {
+               critirq_ctx[i] = (struct thread_info *)
+                       __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+               dbgirq_ctx[i] = (struct thread_info *)
+                       __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+               mcheckirq_ctx[i] = (struct thread_info *)
+                       __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+       }
+}
+#else
+#define exc_lvl_early_init()
+#endif
+
 /*
  * Stack space used when we detect a bad kernel stack pointer, and
  * early in SMP boots before relocation is enabled.
@@ -546,11 +485,14 @@ static void __init emergency_stack_init(void)
         * bringup, we need to get at them in real mode. This means they
         * must also be within the RMO region.
         */
-       limit = min(0x10000000UL, lmb.rmo_size);
+       limit = min(0x10000000ULL, lmb.rmo_size);
 
-       for_each_cpu(i)
-               paca[i].emergency_sp =
-               __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE;
+       for_each_possible_cpu(i) {
+               unsigned long sp;
+               sp  = lmb_alloc_base(THREAD_SIZE, THREAD_SIZE, limit);
+               sp += THREAD_SIZE;
+               paca[i].emergency_sp = __va(sp);
+       }
 }
 
 /*
@@ -560,8 +502,6 @@ static void __init emergency_stack_init(void)
  */
 void __init setup_arch(char **cmdline_p)
 {
-       extern void do_init_bootmem(void);
-
        ppc64_boot_msg(0x12, "Setup Arch");
 
        *cmdline_p = cmd_line;
@@ -578,18 +518,20 @@ void __init setup_arch(char **cmdline_p)
        panic_timeout = 180;
 
        if (ppc_md.panic)
-               notifier_chain_register(&panic_notifier_list, &ppc64_panic_block);
+               setup_panic();
 
-       init_mm.start_code = PAGE_OFFSET;
+       init_mm.start_code = (unsigned long)_stext;
        init_mm.end_code = (unsigned long) _etext;
        init_mm.end_data = (unsigned long) _edata;
        init_mm.brk = klimit;
        
        irqstack_early_init();
+       exc_lvl_early_init();
        emergency_stack_init();
 
+#ifdef CONFIG_PPC_STD_MMU_64
        stabs_alloc();
-
+#endif
        /* set up the bootmem stuff with available memory */
        do_init_bootmem();
        sparse_init();
@@ -598,15 +540,19 @@ void __init setup_arch(char **cmdline_p)
        conswitchp = &dummy_con;
 #endif
 
-       ppc_md.setup_arch();
+       if (ppc_md.setup_arch)
+               ppc_md.setup_arch();
 
-       /* Use the default idle loop if the platform hasn't provided one. */
-       if (NULL == ppc_md.idle_loop) {
-               ppc_md.idle_loop = default_idle;
-               printk(KERN_INFO "Using default idle loop\n");
-       }
+#ifdef CONFIG_SWIOTLB
+       if (ppc_swiotlb_enable)
+               swiotlb_init(1);
+#endif
 
        paging_init();
+
+       /* Initialize the MMU context management stuff */
+       mmu_context_init();
+
        ppc64_boot_msg(0x15, "Setup Done");
 }
 
@@ -635,48 +581,66 @@ void ppc64_boot_msg(unsigned int src, const char *msg)
        printk("[boot]%04x %s\n", src, msg);
 }
 
-/* Print a termination message (print only -- does not stop the kernel) */
-void ppc64_terminate_msg(unsigned int src, const char *msg)
+void cpu_die(void)
 {
-       ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg);
-       printk("[terminate]%04x %s\n", src, msg);
+       if (ppc_md.cpu_die)
+               ppc_md.cpu_die();
 }
 
-int check_legacy_ioport(unsigned long base_port)
+#ifdef CONFIG_SMP
+#define PCPU_DYN_SIZE          ()
+
+static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
 {
-       if (ppc_md.check_legacy_ioport == NULL)
-               return 0;
-       return ppc_md.check_legacy_ioport(base_port);
+       return __alloc_bootmem_node(NODE_DATA(cpu_to_node(cpu)), size, align,
+                                   __pa(MAX_DMA_ADDRESS));
 }
-EXPORT_SYMBOL(check_legacy_ioport);
 
-void cpu_die(void)
+static void __init pcpu_fc_free(void *ptr, size_t size)
 {
-       if (ppc_md.cpu_die)
-               ppc_md.cpu_die();
+       free_bootmem(__pa(ptr), size);
+}
+
+static int pcpu_cpu_distance(unsigned int from, unsigned int to)
+{
+       if (cpu_to_node(from) == cpu_to_node(to))
+               return LOCAL_DISTANCE;
+       else
+               return REMOTE_DISTANCE;
 }
 
-#ifdef CONFIG_SMP
 void __init setup_per_cpu_areas(void)
 {
-       int i;
-       unsigned long size;
-       char *ptr;
-
-       /* Copy section for each CPU (we discard the original) */
-       size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
-#ifdef CONFIG_MODULES
-       if (size < PERCPU_ENOUGH_ROOM)
-               size = PERCPU_ENOUGH_ROOM;
-#endif
+       const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
+       size_t atom_size;
+       unsigned long delta;
+       unsigned int cpu;
+       int rc;
 
-       for_each_cpu(i) {
-               ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size);
-               if (!ptr)
-                       panic("Cannot allocate cpu data for CPU %d\n", i);
+       /*
+        * Linear mapping is one of 4K, 1M and 16M.  For 4K, no need
+        * to group units.  For larger mappings, use 1M atom which
+        * should be large enough to contain a number of units.
+        */
+       if (mmu_linear_psize == MMU_PAGE_4K)
+               atom_size = PAGE_SIZE;
+       else
+               atom_size = 1 << 20;
 
-               paca[i].data_offset = ptr - __per_cpu_start;
-               memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
-       }
+       rc = pcpu_embed_first_chunk(0, dyn_size, atom_size, pcpu_cpu_distance,
+                                   pcpu_fc_alloc, pcpu_fc_free);
+       if (rc < 0)
+               panic("cannot initialize percpu area (err=%d)", rc);
+
+       delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
+       for_each_possible_cpu(cpu)
+               paca[cpu].data_offset = delta + pcpu_unit_offsets[cpu];
 }
 #endif
+
+
+#ifdef CONFIG_PPC_INDIRECT_IO
+struct ppc_pci_io ppc_pci_io;
+EXPORT_SYMBOL(ppc_pci_io);
+#endif /* CONFIG_PPC_INDIRECT_IO */
+