]> git.neil.brown.name Git - history.git/commitdiff
ia64: Switch over to using ACPI PCI support routines. This gets rid of much of the
authorDavid Mosberger <davidm@tiger.hpl.hp.com>
Fri, 20 Sep 2002 18:25:56 +0000 (11:25 -0700)
committerDavid Mosberger <davidm@tiger.hpl.hp.com>
Fri, 20 Sep 2002 18:25:56 +0000 (11:25 -0700)
code-duplication that existed between ACPI and the ia64 IOSAPIC code.
To make this work, the Makefiles had to be re-organized to ensure that
the ACPI subsystem is initialized before PCI (even though both are called
via subsys-initcalls).

20 files changed:
arch/ia64/Makefile
arch/ia64/config.in
arch/ia64/hp/Makefile
arch/ia64/hp/common/Makefile
arch/ia64/hp/zx1/Makefile
arch/ia64/hp/zx1/hpzx1_misc.c
arch/ia64/kernel/Makefile
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/mca.c
arch/ia64/kernel/pci.c [deleted file]
arch/ia64/mm/Makefile
arch/ia64/pci/Makefile [new file with mode: 0644]
arch/ia64/pci/pci.c [new file with mode: 0644]
include/asm-ia64/machvec.h
include/asm-ia64/machvec_dig.h
include/asm-ia64/machvec_hpsim.h
include/asm-ia64/machvec_hpzx1.h
include/asm-ia64/machvec_sn1.h
include/asm-ia64/machvec_sn2.h
include/asm-ia64/tlb.h

index 3935c5616648af19952dea3be71136008078e4c9..788ebf4c8dd1fa2d7eaa21894dcf555a7318dca2 100644 (file)
@@ -86,11 +86,10 @@ endif
 
 HEAD := arch/$(ARCH)/kernel/head.o arch/ia64/kernel/init_task.o
 
-SUBDIRS := arch/$(ARCH)/tools arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib $(SUBDIRS)
-CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o $(CORE_FILES)
-
-LIBS := $(TOPDIR)/arch/$(ARCH)/lib/lib.a $(LIBS) \
-       $(TOPDIR)/arch/$(ARCH)/lib/lib.a
+libs-y                         += arch/$(ARCH)/lib/
+core-y                         += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
+drivers-$(CONFIG_PCI)          += arch/$(ARCH)/pci/
+drivers-$(CONFIG_IA64_HP_ZX1)  += arch/$(ARCH)/hp/common/ arch/$(ARCH)/hp/zx1/
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
index 4175396f361b964d0a1a6c0b32ff52f038246d3d..28eedb1a74ad7c3462c475ccba1329bd0a869a21 100644 (file)
@@ -68,6 +68,7 @@ if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_DIG" = "y" -o "$CONFIG_IA64_H
 then
        bool '  Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA
        define_bool CONFIG_PM y
+       define_bool CONFIG_IOSAPIC y
 fi
 
 if [ "$CONFIG_IA64_SGI_SN1" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then
index 2dd12a0e1f81c7d109215acd662fca2458c5ed57..24f848aa78741ca4b14ee93d3873d239715cd9de 100644 (file)
@@ -7,7 +7,6 @@ O_TARGET := hp.o
 
 subdir-$(CONFIG_IA64_GENERIC) += $(ALL_SUB_DIRS)
 subdir-$(CONFIG_IA64_HP_SIM) += sim
-subdir-$(CONFIG_IA64_HP_ZX1) += zx1 common
 
 SUB_DIRS := $(subdir-y)
 obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
index 58b60abd89b3af3b8e0a92504faeac5f9d802788..511d57358430ebb7bd94c662001d67bdb1541b6d 100644 (file)
@@ -5,8 +5,6 @@
 # Copyright (C) Alex Williamson (alex_williamson@hp.com)
 #
 
-O_TARGET := common.o
-
 export-objs := sba_iommu.o
 
 obj-y := sba_iommu.o
index d33e138631564a7732ddb83de17589d2e9c52ab1..b6023d947fd7bbe80b03c609c6018957c09f9541 100644 (file)
@@ -1,12 +1,10 @@
 #
-# ia64/platform/hp/zx1/Makefile
+# ia64/hp/zx1/Makefile
 #
 # Copyright (C) 2002 Hewlett Packard
 # Copyright (C) Alex Williamson (alex_williamson@hp.com)
 #
 
-O_TARGET := zx1.o
-
 obj-y := hpzx1_misc.o
 obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o
 
index 433e50cb0887e9bfb8ff48cda9f0c006b9fbc288..727ccb3ffb4b78b6e3d3dd96600201e2c4bd80b4 100644 (file)
@@ -335,19 +335,14 @@ hpzx1_acpi_dev_init(void)
 
 extern void sba_init(void);
 
-void
-hpzx1_pci_fixup (int phase)
+static void
+hpzx1_init (void)
 {
-       iosapic_pci_fixup(phase);
-       switch (phase) {
-             case 0:
-               /* zx1 has a hardware I/O TLB which lets us DMA from any device to any address */
-               MAX_DMA_ADDRESS = ~0UL;
-               break;
+       /* zx1 has a hardware I/O TLB which lets us DMA from any device to any address */
+       MAX_DMA_ADDRESS = ~0UL;
 
-             case 1:
-               hpzx1_acpi_dev_init();
-               sba_init();
-               break;
-       }
+       hpzx1_acpi_dev_init();
+       sba_init();
 }
+
+subsys_initcall(hpzx1_init);
index 1739e76f6ba5134c80ad57fce8263567c7bf6867..aec9c40599b3b54094622a249fa38ac16e0bb74d 100644 (file)
@@ -2,7 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-O_TARGET       := kernel.o
 EXTRA_TARGETS  := head.o init_task.o
 
 export-objs := ia64_ksyms.o
@@ -10,12 +9,9 @@ export-objs := ia64_ksyms.o
 obj-y := acpi.o entry.o gate.o efi.o efi_stub.o ia64_ksyms.o irq.o irq_ia64.o irq_lsapic.o ivt.o \
         machvec.o pal.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o \
         signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
-obj-$(CONFIG_IA64_GENERIC) += iosapic.o
-obj-$(CONFIG_IA64_HP_ZX1) += iosapic.o
-obj-$(CONFIG_IA64_DIG) += iosapic.o
+obj-$(CONFIG_IOSAPIC) += iosapic.o
 obj-$(CONFIG_IA64_PALINFO) += palinfo.o
 obj-$(CONFIG_EFI_VARS) += efivars.o
-obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_SMP) += smp.o smpboot.o
 obj-$(CONFIG_IA64_MCA) += mca.o mca_asm.o
 obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
index 65fc6c85b4cad0ba3c777566bdccf5f981f01199..9a2d84ae3243fa89acd1e7143e01d2a517d3558c 100644 (file)
@@ -27,8 +27,8 @@
  * 02/04/30    J.I. Lee        bug fix in find_iosapic to fix ACPI PCI IRQ to IOSAPIC mapping
  *                             error
  * 02/07/29    T. Kochi        Allocate interrupt vectors dynamically
- * 02/08/04    T. Kochi        Cleaned up terminology (irq, global system interrupt, vector,
- *                             etc.)
+ * 02/08/04    T. Kochi        Cleaned up terminology (irq, global system interrupt, vector, etc.)
+ * 02/09/20    D. Mosberger    Simplified by taking advantage of ACPI's pci_irq code.
  */
 /*
  * Here is what the interrupt logic between a PCI device and the kernel looks like:
@@ -51,7 +51,7 @@
  *     architecture-independent interrupt handling mechanism in Linux.  As an
  *     IRQ is a number, we have to have IA-64 interrupt vector number <-> IRQ number
  *     mapping.  On smaller systems, we use one-to-one mapping between IA-64 vector and
- *     IRQ.  A platform can implemnent platform_irq_to_vector(irq) and
+ *     IRQ.  A platform can implement platform_irq_to_vector(irq) and
  *     platform_local_vector_to_irq(vector) APIs to differentiate the mapping.
  *     Please see also include/asm-ia64/hw_irq.h for those APIs.
  *
  */
 #include <linux/config.h>
 
-#include <linux/kernel.h>
+#include <linux/acpi.h>
 #include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/string.h>
-#include <linux/irq.h>
-#include <linux/acpi.h>
 
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
 
 static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
 
-/* PCI pin to GSI routing information.  This info typically comes from ACPI. */
-
-static struct {
-       int num_routes;
-       struct pci_vector_struct *route;
-} pci_irq;
-
 /* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
 
 static struct iosapic_intr_info {
@@ -146,11 +140,11 @@ find_iosapic (unsigned int gsi)
 int
 gsi_to_vector (unsigned int gsi)
 {
-       int vector;
+       struct iosapic_intr_info *info;
 
-       for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
-               if (iosapic_intr_info[vector].gsi_base + iosapic_intr_info[vector].rte_index == gsi)
-                       return vector;
+       for (info = iosapic_intr_info; info < iosapic_intr_info + IA64_NUM_VECTORS; ++info)
+               if (info->gsi_base + info->rte_index == gsi)
+                       return info - iosapic_intr_info;
        return -1;
 }
 
@@ -163,7 +157,7 @@ set_rte (unsigned int vector, unsigned int dest)
        int rte_index;
        char redir;
 
-       DBG(KERN_DEBUG "%s: routing vector %d to %x\n", __FUNCTION__, vector, dest);
+       DBG(KERN_DEBUG"IOSAPIC: routing vector %d to %x\n", vector, dest);
 
        rte_index = iosapic_intr_info[vector].rte_index;
        if (rte_index < 0)
@@ -584,7 +578,8 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
        index = find_iosapic(gsi);
 
        if (index < 0) {
-               printk("ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n", isa_irq, gsi);
+               printk("ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n",
+                      isa_irq, gsi);
                return;
        }
 
@@ -604,75 +599,6 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
        set_rte(vector, dest);
 }
 
-/*
- * Map PCI pin to the corresponding GSI.
- * If no such mapping exists, return -1.
- */
-static int
-pci_pin_to_gsi (int bus, int slot, int pci_pin, unsigned int *gsi)
-{
-       struct pci_vector_struct *r;
-
-       for (r = pci_irq.route; r < pci_irq.route + pci_irq.num_routes; ++r)
-               if (r->bus == bus &&
-                   (r->pci_id >> 16) == slot && r->pin == pci_pin) {
-                       *gsi = r->irq;
-                       return 0;
-               }
-
-       return -1;
-}
-
-/*
- * Map PCI pin to the corresponding IA-64 interrupt vector.  If no such mapping exists,
- * try to allocate a new vector.  If it fails, return -1.
- */
-static int
-pci_pin_to_vector (int bus, int slot, int pci_pin)
-{
-       int index, vector;
-       int gsi_base, pcat_compat;
-       char *addr;
-       unsigned int gsi;
-
-       if (pci_pin_to_gsi(bus, slot, pci_pin, &gsi) < 0) {
-               printk("PCI: no interrupt route for %02x:%02x pin %c\n", bus, slot, 'A' + pci_pin);
-               return -1;
-       }
-
-       vector = gsi_to_vector(gsi);
-
-       if (vector < 0) {
-               /* we should allocate a vector for this interrupt line */
-
-               index = find_iosapic(gsi);
-
-               if (index < 0) {
-                       printk("PCI: GSI 0x%x has no IOSAPIC mapping\n", gsi);
-                       return -1;
-               }
-
-               addr = iosapic_lists[index].addr;
-               gsi_base = iosapic_lists[index].gsi_base;
-               pcat_compat = iosapic_lists[index].pcat_compat;
-
-               if (pcat_compat && (gsi < 16))
-                       vector = isa_irq_to_vector(gsi);
-               else {
-                       /* new GSI; allocate a vector for it */
-                       vector = ia64_alloc_vector();
-               }
-
-               register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
-                             0, 0, gsi_base, addr);
-
-               DBG("PCI: (%02x:%02x INT%c) -> GSI 0x%x -> vector %d\n",
-                   bus, slot, 'A' + pci_pin, gsi, vector);
-       }
-
-       return vector;
-}
-
 void __devinit
 iosapic_init (unsigned long phys_addr, unsigned int gsi_base, int pcat_compat)
 {
@@ -713,7 +639,7 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base, int pcat_compat)
        iosapic_lists[num_iosapic].num_rte = num_rte;
        num_iosapic++;
 
-       printk("IOSAPIC: version %x.%x, address 0x%lx, GSIs 0x%x-0x%x\n",
+       printk(KERN_INFO"  IOSAPIC v%x.%x, address 0x%lx, GSIs 0x%x-0x%x\n",
               (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, gsi_base, gsi_base + num_rte - 1);
 
        if ((gsi_base == 0) && pcat_compat) {
@@ -740,122 +666,93 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base, int pcat_compat)
        }
 }
 
-
-/*
- * Set allocated interrupt vector to dev->irq and
- * program IOSAPIC to deliver interrupts
- */
-void
-iosapic_fixup_pci_interrupt (struct pci_dev *dev)
+static void
+fixup_vector (int vector, unsigned int gsi, const char *pci_id)
 {
-       unsigned char pci_pin;
-       int vector;
-       unsigned int dest;
-       struct hw_interrupt_type *irq_type;
+       struct hw_interrupt_type *irq_type = &irq_type_iosapic_level;
        irq_desc_t *idesc;
+       unsigned int dest;
 
-       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pci_pin);
-       if (pci_pin) {
-               pci_pin--; /* interrupt pins are numberd starting from 1 */
-
-               vector = pci_pin_to_vector(dev->bus->number, PCI_SLOT(dev->devfn), pci_pin);
-
-               if (vector < 0 && dev->bus->parent) {
-                       /* go back to the bridge */
-                       struct pci_dev *bridge = dev->bus->self;
-
-                       if (bridge) {
-                               /* allow for multiple bridges on an adapter */
-                               do {
-                                       /* do the bridge swizzle... */
-                                       pci_pin = (pci_pin + PCI_SLOT(dev->devfn)) % 4;
-                                       vector = pci_pin_to_vector(bridge->bus->number,
-                                                                  PCI_SLOT(bridge->devfn),
-                                                                  pci_pin);
-                               } while (vector < 0 && (bridge = bridge->bus->self));
-                       }
-                       if (vector >= 0)
-                               printk(KERN_WARNING
-                                      "PCI: using PPB (%s INT%c) to get vector %d\n",
-                                      dev->slot_name, 'A' + pci_pin,
-                                      vector);
-                       else
-                               printk(KERN_WARNING
-                                      "PCI: Couldn't map irq for (%s INT%c)\n",
-                                      dev->slot_name, 'A' + pci_pin);
-               }
-
-               if (vector >= 0) {
-                       dev->irq = vector;
-
-                       irq_type = &irq_type_iosapic_level;
-                       idesc = irq_desc(vector);
-                       if (idesc->handler != irq_type) {
-                               if (idesc->handler != &no_irq_type)
-                                       printk("%s: changing vector %d from %s to %s\n",
-                                              __FUNCTION__, vector,
-                                              idesc->handler->typename,
-                                              irq_type->typename);
-                               idesc->handler = irq_type;
-                       }
+       idesc = irq_desc(vector);
+       if (idesc->handler != irq_type) {
+               if (idesc->handler != &no_irq_type)
+                       printk("IOSAPIC: changing vector %d from %s to %s\n",
+                              vector, idesc->handler->typename, irq_type->typename);
+               idesc->handler = irq_type;
+       }
 #ifdef CONFIG_SMP
-                       /*
-                        * For platforms that do not support interrupt redirect
-                        * via the XTP interface, we can round-robin the PCI
-                        * device interrupts to the processors
-                        */
-                       if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
-                               static int cpu_index = 0;
-
-                               while (!cpu_online(cpu_index))
-                                       if (++cpu_index >= NR_CPUS)
-                                               cpu_index = 0;
-
-                               dest = cpu_physical_id(cpu_index) & 0xffff;
-                       } else {
-                               /*
-                                * Direct the interrupt vector to the current cpu,
-                                * platform redirection will distribute them.
-                                */
-                               dest = (ia64_get_lid() >> 16) & 0xffff;
-                       }
+       /*
+        * For platforms that do not support interrupt redirect via the XTP interface, we
+        * can round-robin the PCI device interrupts to the processors
+        */
+       if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
+               static int cpu_index = -1;
+
+               do
+                       if (++cpu_index >= NR_CPUS)
+                               cpu_index = 0;
+               while (!cpu_online(cpu_index));
+
+               dest = cpu_physical_id(cpu_index) & 0xffff;
+       } else {
+               /*
+                * Direct the interrupt vector to the current cpu, platform redirection
+                * will distribute them.
+                */
+               dest = (ia64_get_lid() >> 16) & 0xffff;
+       }
 #else
-                       /* direct the interrupt vector to the running cpu id */
-                       dest = (ia64_get_lid() >> 16) & 0xffff;
+       /* direct the interrupt vector to the running cpu id */
+       dest = (ia64_get_lid() >> 16) & 0xffff;
 #endif
+       set_rte(vector, dest);
 
-                       printk("PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n",
-                              dev->slot_name, 'A' + pci_pin, dest, vector);
-                       set_rte(vector, dest);
-               }
-       }
+       printk("IOSAPIC: %s -> GSI 0x%x -> CPU 0x%04x vector %d\n", pci_id, gsi, dest, vector);
 }
 
-
-void
-iosapic_pci_fixup (int phase)
+void __init
+iosapic_parse_prt (void)
 {
-       struct  pci_dev *dev;
+       struct acpi_prt_entry *entry;
+       struct list_head *node;
+       unsigned int gsi, gsi_base;
+       int index, vector, pcat_compat;
+       char pci_id[16];
+       char *addr;
 
-       if (phase == 0) {
-               if (acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) {
-                       printk("%s: acpi_get_prt failed\n", __FILE__);
-               }
-               return;
-       }
+       list_for_each(node, &acpi_prt.entries) {
+               entry = list_entry(node, struct acpi_prt_entry, node);
 
-       if (phase != 1)
-               return;
+               /* We're only interested in static (non-link) entries.  */
+               if (entry->link.handle)
+                       continue;
 
-       pci_for_each_dev(dev) {
-               /* fixup dev->irq and program IOSAPIC */
-               iosapic_fixup_pci_interrupt(dev);
+               gsi = entry->link.index;
 
-               /*
-                * Nothing to fixup
-                * Fix out-of-range IRQ numbers
-                */
-               if (dev->irq >= IA64_NUM_VECTORS)
-                       dev->irq = 15;  /* Spurious interrupts */
+               vector = gsi_to_vector(gsi);
+               if (vector < 0) {
+                       /* allocate a vector for this interrupt line */
+                       index = find_iosapic(gsi);
+
+                       if (index < 0) {
+                               printk(KERN_WARNING"IOSAPIC: GSI 0x%x has no IOSAPIC!\n", gsi);
+                               return;
+                       }
+                       addr = iosapic_lists[index].addr;
+                       gsi_base = iosapic_lists[index].gsi_base;
+                       pcat_compat = iosapic_lists[index].pcat_compat;
+
+                       if (pcat_compat && (gsi < 16))
+                               vector = isa_irq_to_vector(gsi);
+                       else
+                               /* new GSI; allocate a vector for it */
+                               vector = ia64_alloc_vector();
+
+                       register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, 0, 0, gsi_base, addr);
+               }
+               snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]",
+                        entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin);
+
+               fixup_vector(vector, gsi, pci_id);
        }
 }
index 82cf7becd0d1a265293e07479bf42b9eb4d1dc31..d43d6aef24f0bc65b1e6cfaebe008d5a7cda1896 100644 (file)
@@ -208,6 +208,8 @@ ia64_mca_check_errors (void)
        ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
 }
 
+device_initcall(ia64_mca_check_errors);
+
 /*
  * ia64_mca_register_cpev
  *
diff --git a/arch/ia64/kernel/pci.c b/arch/ia64/kernel/pci.c
deleted file mode 100644 (file)
index 8f17f53..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * pci.c - Low-Level PCI Access in IA-64
- *
- * Derived from bios32.c of i386 tree.
- *
- * Copyright (C) 2002 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Note: Above list of copyright holders is incomplete...
- */
-#include <linux/config.h>
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/spinlock.h>
-
-#include <asm/machvec.h>
-#include <asm/page.h>
-#include <asm/segment.h>
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include <asm/sal.h>
-
-
-#ifdef CONFIG_SMP
-# include <asm/smp.h>
-#endif
-#include <asm/irq.h>
-
-
-#undef DEBUG
-#define DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-#ifdef CONFIG_IA64_MCA
-extern void ia64_mca_check_errors( void );
-#endif
-
-struct pci_fixup pcibios_fixups[1];
-
-/*
- * Low-level SAL-based PCI configuration access functions. Note that SAL
- * calls are already serialized (via sal_lock), so we don't need another
- * synchronization mechanism here.  Not using segment number (yet).
- */
-
-#define PCI_SAL_ADDRESS(bus, dev, fn, reg) \
-       ((u64)(bus << 16) | (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg))
-
-static int
-__pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
-{
-       int result = 0;
-       u64 data = 0;
-
-       if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
-               return -EINVAL;
-
-       result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(bus, dev, fn, reg), len, &data);
-
-       *value = (u32) data;
-
-       return result;
-}
-
-static int
-__pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
-{
-       if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
-               return -EINVAL;
-
-       return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(bus, dev, fn, reg), len, value);
-}
-
-
-static int
-pci_sal_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
-       return __pci_sal_read(0, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                             where, size, value);
-}
-
-static int
-pci_sal_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
-       return __pci_sal_write(0, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                              where, size, value);
-}
-
-struct pci_ops pci_sal_ops = {
-       .read =         pci_sal_read,
-       .write =        pci_sal_write,
-};
-
-struct pci_ops *pci_root_ops = &pci_sal_ops;   /* default to SAL */
-
-struct pci_bus *
-pcibios_scan_root (int bus)
-{
-       struct list_head *list = NULL;
-       struct pci_bus *pci_bus = NULL;
-
-       list_for_each(list, &pci_root_buses) {
-               pci_bus = pci_bus_b(list);
-               if (pci_bus->number == bus) {
-                       /* Already scanned */
-                       printk("PCI: Bus (%02x) already probed\n", bus);
-                       return pci_bus;
-               }
-       }
-
-       printk("PCI: Probing PCI hardware on bus (%02x)\n", bus);
-       return pci_scan_bus(bus, pci_root_ops, NULL);
-}
-
-static int __init
-pcibios_init (void)
-{
-#      define PCI_BUSES_TO_SCAN 255
-       int i = 0;
-
-acpi_init();   /* hackedy hack hack... */
-
-#ifdef CONFIG_IA64_MCA
-       ia64_mca_check_errors();    /* For post-failure MCA error logging */
-#endif
-
-       platform_pci_fixup(0);  /* phase 0 fixups (before buses scanned) */
-
-       printk("PCI: Probing PCI hardware\n");
-       for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
-               pci_scan_bus(i, pci_root_ops, NULL);
-
-       platform_pci_fixup(1);  /* phase 1 fixups (after buses scanned) */
-       return 0;
-}
-
-subsys_initcall(pcibios_init);
-
-/*
- *  Called after each bus is probed, but before its children
- *  are examined.
- */
-void __init
-pcibios_fixup_bus (struct pci_bus *b)
-{
-       return;
-}
-
-void __init
-pcibios_update_resource (struct pci_dev *dev, struct resource *root,
-                        struct resource *res, int resource)
-{
-       unsigned long where, size;
-       u32 reg;
-
-       where = PCI_BASE_ADDRESS_0 + (resource * 4);
-       size = res->end - res->start;
-       pci_read_config_dword(dev, where, &reg);
-       reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
-       pci_write_config_dword(dev, where, reg);
-
-       /* ??? FIXME -- record old value for shutdown.  */
-}
-
-void __init
-pcibios_update_irq (struct pci_dev *dev, int irq)
-{
-       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-
-       /* ??? FIXME -- record old value for shutdown.  */
-}
-
-void __init
-pcibios_fixup_pbus_ranges (struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
-{
-}
-
-static inline int
-pcibios_enable_resources (struct pci_dev *dev, int mask)
-{
-       u16 cmd, old_cmd;
-       int idx;
-       struct resource *r;
-
-       if (!dev)
-               return -EINVAL;
-
-       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-       old_cmd = cmd;
-       for (idx=0; idx<6; idx++) {
-               /* Only set up the desired resources.  */
-               if (!(mask & (1 << idx)))
-                       continue;
-
-               r = &dev->resource[idx];
-               if (!r->start && r->end) {
-                       printk(KERN_ERR
-                              "PCI: Device %s not available because of resource collisions\n",
-                              dev->slot_name);
-                       return -EINVAL;
-               }
-               if (r->flags & IORESOURCE_IO)
-                       cmd |= PCI_COMMAND_IO;
-               if (r->flags & IORESOURCE_MEM)
-                       cmd |= PCI_COMMAND_MEMORY;
-       }
-       if (dev->resource[PCI_ROM_RESOURCE].start)
-               cmd |= PCI_COMMAND_MEMORY;
-       if (cmd != old_cmd) {
-               printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
-               pci_write_config_word(dev, PCI_COMMAND, cmd);
-       }
-       return 0;
-}
-
-int
-pcibios_enable_device (struct pci_dev *dev, int mask)
-{
-       int ret;
-
-       ret = pcibios_enable_resources(dev, mask);
-       if (ret < 0)
-               return ret;
-
-       printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name);
-       return 0;
-}
-
-void
-pcibios_align_resource (void *data, struct resource *res,
-                       unsigned long size, unsigned long align)
-{
-}
-
-/*
- * PCI BIOS setup, always defaults to SAL interface
- */
-char * __init
-pcibios_setup (char *str)
-{
-       return NULL;
-}
-
-int
-pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
-                    enum pci_mmap_state mmap_state, int write_combine)
-{
-       /*
-        * I/O space cannot be accessed via normal processor loads and stores on this
-        * platform.
-        */
-       if (mmap_state == pci_mmap_io)
-               /*
-                * XXX we could relax this for I/O spaces for which ACPI indicates that
-                * the space is 1-to-1 mapped.  But at the moment, we don't support
-                * multiple PCI address spaces and the legacy I/O space is not 1-to-1
-                * mapped, so this is moot.
-                */
-               return -EINVAL;
-
-       /*
-        * Leave vm_pgoff as-is, the PCI space address is the physical address on this
-        * platform.
-        */
-       vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
-
-       if (write_combine)
-               vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-       else
-               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-       if (remap_page_range(vma, vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
-                            vma->vm_end - vma->vm_start, vma->vm_page_prot))
-               return -EAGAIN;
-
-       return 0;
-}
index 68df36842a4d058c5009d4da88d99cf4838d6409..8b87a79b3ff752a3dbd0ca84a898baaac136e6e6 100644 (file)
@@ -7,8 +7,6 @@
 #
 # Note 2! The CFLAGS definition is now in the main makefile...
 
-O_TARGET := mm.o
-
 obj-y   := init.o fault.o tlb.o extable.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 
diff --git a/arch/ia64/pci/Makefile b/arch/ia64/pci/Makefile
new file mode 100644 (file)
index 0000000..395a0ec
--- /dev/null
@@ -0,0 +1,3 @@
+obj-y          := pci.o
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
new file mode 100644 (file)
index 0000000..dc4cfb2
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * pci.c - Low-Level PCI Access in IA-64
+ *
+ * Derived from bios32.c of i386 tree.
+ *
+ * Copyright (C) 2002 Hewlett-Packard Co
+ *     David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * Note: Above list of copyright holders is incomplete...
+ */
+#include <linux/config.h>
+
+#include <linux/acpi.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+
+#include <asm/machvec.h>
+#include <asm/page.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include <asm/sal.h>
+
+
+#ifdef CONFIG_SMP
+# include <asm/smp.h>
+#endif
+#include <asm/irq.h>
+
+
+#undef DEBUG
+#define DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#ifdef CONFIG_IA64_MCA
+extern void ia64_mca_check_errors( void );
+#endif
+
+struct pci_fixup pcibios_fixups[1];
+
+/*
+ * Low-level SAL-based PCI configuration access functions. Note that SAL
+ * calls are already serialized (via sal_lock), so we don't need another
+ * synchronization mechanism here.  Not using segment number (yet).
+ */
+
+#define PCI_SAL_ADDRESS(bus, dev, fn, reg) \
+       ((u64)(bus << 16) | (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg))
+
+static int
+__pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+       int result = 0;
+       u64 data = 0;
+
+       if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+               return -EINVAL;
+
+       result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(bus, dev, fn, reg), len, &data);
+
+       *value = (u32) data;
+
+       return result;
+}
+
+static int
+__pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+       if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+               return -EINVAL;
+
+       return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(bus, dev, fn, reg), len, value);
+}
+
+
+static int
+pci_sal_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
+{
+       return __pci_sal_read(0, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                             where, size, value);
+}
+
+static int
+pci_sal_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
+{
+       return __pci_sal_write(0, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                              where, size, value);
+}
+
+struct pci_ops pci_sal_ops = {
+       .read =         pci_sal_read,
+       .write =        pci_sal_write
+};
+
+struct pci_ops *pci_root_ops = &pci_sal_ops;   /* default to SAL */
+
+static int __init
+pci_acpi_init (void)
+{
+       if (!acpi_pci_irq_init())
+               printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+       else
+               printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n");
+       return 0;
+}
+
+subsys_initcall(pci_acpi_init);
+
+/* Called by ACPI when it finds a new root bus.  */
+struct pci_bus *
+pcibios_scan_root (int bus)
+{
+       struct list_head *list;
+       struct pci_bus *pci_bus;
+
+       list_for_each(list, &pci_root_buses) {
+               pci_bus = pci_bus_b(list);
+               if (pci_bus->number == bus) {
+                       /* Already scanned */
+                       printk("PCI: Bus (%02x) already probed\n", bus);
+                       return pci_bus;
+               }
+       }
+
+       printk("PCI: Probing PCI hardware on bus (%02x)\n", bus);
+       return pci_scan_bus(bus, pci_root_ops, NULL);
+}
+
+/*
+ *  Called after each bus is probed, but before its children are examined.
+ */
+void __init
+pcibios_fixup_bus (struct pci_bus *b)
+{
+       return;
+}
+
+void __init
+pcibios_update_resource (struct pci_dev *dev, struct resource *root,
+                        struct resource *res, int resource)
+{
+       unsigned long where, size;
+       u32 reg;
+
+       where = PCI_BASE_ADDRESS_0 + (resource * 4);
+       size = res->end - res->start;
+       pci_read_config_dword(dev, where, &reg);
+       reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+       pci_write_config_dword(dev, where, reg);
+
+       /* ??? FIXME -- record old value for shutdown.  */
+}
+
+void __init
+pcibios_update_irq (struct pci_dev *dev, int irq)
+{
+       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+
+       /* ??? FIXME -- record old value for shutdown.  */
+}
+
+void __init
+pcibios_fixup_pbus_ranges (struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
+{
+}
+
+static inline int
+pcibios_enable_resources (struct pci_dev *dev, int mask)
+{
+       u16 cmd, old_cmd;
+       int idx;
+       struct resource *r;
+
+       if (!dev)
+               return -EINVAL;
+
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       old_cmd = cmd;
+       for (idx=0; idx<6; idx++) {
+               /* Only set up the desired resources.  */
+               if (!(mask & (1 << idx)))
+                       continue;
+
+               r = &dev->resource[idx];
+               if (!r->start && r->end) {
+                       printk(KERN_ERR
+                              "PCI: Device %s not available because of resource collisions\n",
+                              dev->slot_name);
+                       return -EINVAL;
+               }
+               if (r->flags & IORESOURCE_IO)
+                       cmd |= PCI_COMMAND_IO;
+               if (r->flags & IORESOURCE_MEM)
+                       cmd |= PCI_COMMAND_MEMORY;
+       }
+       if (dev->resource[PCI_ROM_RESOURCE].start)
+               cmd |= PCI_COMMAND_MEMORY;
+       if (cmd != old_cmd) {
+               printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
+               pci_write_config_word(dev, PCI_COMMAND, cmd);
+       }
+       return 0;
+}
+
+int
+pcibios_enable_device (struct pci_dev *dev, int mask)
+{
+       int ret;
+
+       ret = pcibios_enable_resources(dev, mask);
+       if (ret < 0)
+               return ret;
+
+       printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name);
+       return acpi_pci_irq_enable(dev);
+}
+
+void
+pcibios_align_resource (void *data, struct resource *res,
+                       unsigned long size, unsigned long align)
+{
+}
+
+/*
+ * PCI BIOS setup, always defaults to SAL interface
+ */
+char * __init
+pcibios_setup (char *str)
+{
+       return NULL;
+}
+
+int
+pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
+                    enum pci_mmap_state mmap_state, int write_combine)
+{
+       /*
+        * I/O space cannot be accessed via normal processor loads and stores on this
+        * platform.
+        */
+       if (mmap_state == pci_mmap_io)
+               /*
+                * XXX we could relax this for I/O spaces for which ACPI indicates that
+                * the space is 1-to-1 mapped.  But at the moment, we don't support
+                * multiple PCI address spaces and the legacy I/O space is not 1-to-1
+                * mapped, so this is moot.
+                */
+               return -EINVAL;
+
+       /*
+        * Leave vm_pgoff as-is, the PCI space address is the physical address on this
+        * platform.
+        */
+       vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
+
+       if (write_combine)
+               vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+       else
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+       if (remap_page_range(vma, vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
+                            vma->vm_end - vma->vm_start, vma->vm_page_prot))
+               return -EAGAIN;
+
+       return 0;
+}
index 82500a98d1be2a1c38a8885a50bef4ba8b39a7bf..88e6d56f191ea3826c0ef7a533aa680580a87a4a 100644 (file)
@@ -86,12 +86,10 @@ extern void machvec_noop (void);
 #  define platform_setup       ia64_mv.setup
 #  define platform_cpu_init    ia64_mv.cpu_init
 #  define platform_irq_init    ia64_mv.irq_init
-#  define platform_map_nr      ia64_mv.map_nr
 #  define platform_mca_init    ia64_mv.mca_init
 #  define platform_mca_handler ia64_mv.mca_handler
 #  define platform_cmci_handler        ia64_mv.cmci_handler
 #  define platform_log_print   ia64_mv.log_print
-#  define platform_pci_fixup   ia64_mv.pci_fixup
 #  define platform_send_ipi    ia64_mv.send_ipi
 #  define platform_global_tlb_purge    ia64_mv.global_tlb_purge
 #  define platform_pci_dma_init                ia64_mv.dma_init
@@ -159,8 +157,6 @@ struct ia64_machine_vector {
        platform_setup,                         \
        platform_cpu_init,                      \
        platform_irq_init,                      \
-       platform_pci_fixup,                     \
-       platform_map_nr,                        \
        platform_mca_init,                      \
        platform_mca_handler,                   \
        platform_cmci_handler,                  \
@@ -237,9 +233,6 @@ extern ia64_mv_pci_dma_supported swiotlb_pci_dma_supported;
 #ifndef platform_log_print
 # define platform_log_print    ((ia64_mv_log_print_t *) machvec_noop)
 #endif
-#ifndef platform_pci_fixup
-# define platform_pci_fixup    ((ia64_mv_pci_fixup_t *) machvec_noop)
-#endif
 #ifndef platform_send_ipi
 # define platform_send_ipi     ia64_send_ipi   /* default to architected version */
 #endif
index 5401fcfb744f13eda425c0dba441c702ce87b1fb..d66f9d01b03dd5ce5297004555585ea997f68c72 100644 (file)
@@ -16,7 +16,5 @@ extern ia64_mv_map_nr_t map_nr_dense;
 #define platform_name          "dig"
 #define platform_setup         dig_setup
 #define platform_irq_init      dig_irq_init
-#define platform_pci_fixup     iosapic_pci_fixup
-#define platform_map_nr                map_nr_dense
 
 #endif /* _ASM_IA64_MACHVEC_DIG_h */
index 9afb30cb507d462a6557560471e8a8f9fcc138f3..7afe88066e74c8dc387cef6576255edf65ba4003 100644 (file)
@@ -15,6 +15,5 @@ extern ia64_mv_map_nr_t map_nr_dense;
 #define platform_name          "hpsim"
 #define platform_setup         hpsim_setup
 #define platform_irq_init      hpsim_irq_init
-#define platform_map_nr                map_nr_dense
 
 #endif /* _ASM_IA64_MACHVEC_HPSIM_h */
index 7d734652509e02f2854b76b8a0eac9a60364694d..fa25e320f71aa73a38ce01f93ce47efee815631b 100644 (file)
@@ -22,8 +22,6 @@ extern ia64_mv_pci_dma_supported sba_dma_supported;
  */
 #define platform_name                  "hpzx1"
 #define platform_setup                 dig_setup
-#define platform_pci_fixup             hpzx1_pci_fixup
-#define platform_map_nr                        map_nr_dense
 #define platform_pci_dma_init          ((ia64_mv_pci_dma_init *) machvec_noop)
 #define platform_pci_alloc_consistent  sba_alloc_consistent
 #define platform_pci_free_consistent   sba_free_consistent
index b3cefbff022465b15e1ea1feae4bcbf7dd19d41b..3a5bf2254087d4cc77a9d7284f46d960860c55cc 100644 (file)
@@ -68,10 +68,8 @@ extern ia64_mv_pci_dma_address               sn1_dma_address;
 #define platform_setup         sn1_setup
 #define platform_cpu_init      sn_cpu_init
 #define platform_irq_init      sn1_irq_init
-#define platform_map_nr                sn1_map_nr
 #define platform_send_ipi      sn1_send_IPI
 #define platform_global_tlb_purge       sn1_global_tlb_purge
-#define platform_pci_fixup     sn1_pci_fixup
 #define platform_inb           sn1_inb
 #define platform_inw           sn1_inw
 #define platform_inl           sn1_inl
index d2e34731fc5896df4f5b89139d9e11d6a78b148f..2e015dec31eb32fa4ea6646d9a141de0df9d7e2a 100644 (file)
@@ -73,10 +73,8 @@ extern ia64_mv_pci_dma_address               sn1_dma_address;
 #define platform_setup         sn1_setup
 #define platform_cpu_init      sn_cpu_init
 #define platform_irq_init      sn1_irq_init
-#define platform_map_nr                sn2_map_nr
 #define platform_send_ipi      sn2_send_IPI
 #define platform_global_tlb_purge       sn2_global_tlb_purge
-#define platform_pci_fixup     sn1_pci_fixup
 #ifdef Colin /* We are using the same is Generic IA64 calls defined in io.h */
 #define platform_inb           sn1_inb
 #define platform_inw           sn1_inw
index fcf977e30740651489541e96fcc5da6201d9263b..55b8aefa828d3ff2c03f4612b13a3fc197b5b04f 100644 (file)
@@ -81,7 +81,7 @@ ia64_tlb_flush_mmu (mmu_gather_t *tlb, unsigned long start, unsigned long end)
                 */
                flush_tlb_mm(tlb->mm);
        } else if (unlikely (end - start >= 1024*1024*1024*1024UL
-                     || REGION_NUMBER(start) != REGION_NUMBER(end - 1)))
+                            || REGION_NUMBER(start) != REGION_NUMBER(end - 1)))
        {
                /*
                 * If we flush more than a tera-byte or across regions, we're probably