Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / ia64 / sn / pci / tioca_provider.c
index 8dae9eb..be01769 100644 (file)
 #include <linux/pci.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
+#include <asm/sn/io.h>
 #include <asm/sn/pcidev.h>
 #include <asm/sn/pcibus_provider_defs.h>
 #include <asm/sn/tioca_provider.h>
 
-uint32_t tioca_gart_found;
+u32 tioca_gart_found;
 EXPORT_SYMBOL(tioca_gart_found);       /* used by agp-sgi */
 
 LIST_HEAD(tioca_list);
@@ -33,14 +34,14 @@ static int tioca_gart_init(struct tioca_kernel *);
 static int
 tioca_gart_init(struct tioca_kernel *tioca_kern)
 {
-       uint64_t ap_reg;
-       uint64_t offset;
+       u64 ap_reg;
+       u64 offset;
        struct page *tmp;
        struct tioca_common *tioca_common;
-       volatile struct tioca *ca_base;
+       struct tioca __iomem *ca_base;
 
        tioca_common = tioca_kern->ca_common;
-       ca_base = (struct tioca *)tioca_common->ca_common.bs_base;
+       ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
 
        if (list_empty(tioca_kern->ca_devices))
                return 0;
@@ -148,7 +149,7 @@ tioca_gart_init(struct tioca_kernel *tioca_kern)
        tioca_kern->ca_pcigart_entries =
            tioca_kern->ca_pciap_size / tioca_kern->ca_ap_pagesize;
        tioca_kern->ca_pcigart_pagemap =
-           kcalloc(1, tioca_kern->ca_pcigart_entries / 8, GFP_KERNEL);
+           kzalloc(tioca_kern->ca_pcigart_entries / 8, GFP_KERNEL);
        if (!tioca_kern->ca_pcigart_pagemap) {
                free_pages((unsigned long)tioca_kern->ca_gart,
                           get_order(tioca_kern->ca_gart_size));
@@ -174,27 +175,29 @@ tioca_gart_init(struct tioca_kernel *tioca_kern)
         *      DISABLE GART PREFETCHING due to hw bug tracked in SGI PV930029
         */
 
-       ca_base->ca_control1 |= CA_AGPDMA_OP_ENB_COMBDELAY;     /* PV895469 ? */
-       ca_base->ca_control2 &= ~(CA_GART_MEM_PARAM);
-       ca_base->ca_control2 |= (0x2ull << CA_GART_MEM_PARAM_SHFT);
+       __sn_setq_relaxed(&ca_base->ca_control1,
+                       CA_AGPDMA_OP_ENB_COMBDELAY);    /* PV895469 ? */
+       __sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
+       __sn_setq_relaxed(&ca_base->ca_control2,
+                       (0x2ull << CA_GART_MEM_PARAM_SHFT));
        tioca_kern->ca_gart_iscoherent = 1;
-       ca_base->ca_control2 &=
-           ~(CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB);
+       __sn_clrq_relaxed(&ca_base->ca_control2,
+                       (CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB));
 
        /*
         * Unmask GART fetch error interrupts.  Clear residual errors first.
         */
 
-       ca_base->ca_int_status_alias = CA_GART_FETCH_ERR;
-       ca_base->ca_mult_error_alias = CA_GART_FETCH_ERR;
-       ca_base->ca_int_mask &= ~CA_GART_FETCH_ERR;
+       writeq(CA_GART_FETCH_ERR, &ca_base->ca_int_status_alias);
+       writeq(CA_GART_FETCH_ERR, &ca_base->ca_mult_error_alias);
+       __sn_clrq_relaxed(&ca_base->ca_int_mask, CA_GART_FETCH_ERR);
 
        /*
         * Program the aperature and gart registers in TIOCA
         */
 
-       ca_base->ca_gart_aperature = ap_reg;
-       ca_base->ca_gart_ptr_table = tioca_kern->ca_gart_coretalk_addr | 1;
+       writeq(ap_reg, &ca_base->ca_gart_aperature);
+       writeq(tioca_kern->ca_gart_coretalk_addr|1, &ca_base->ca_gart_ptr_table);
 
        return 0;
 }
@@ -211,9 +214,8 @@ void
 tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
 {
        int cap_ptr;
-       uint64_t ca_control1;
-       uint32_t reg;
-       struct tioca *tioca_base;
+       u32 reg;
+       struct tioca __iomem *tioca_base;
        struct pci_dev *pdev;
        struct tioca_common *common;
 
@@ -255,10 +257,8 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
         * Set ca's fw to match
         */
 
-       tioca_base = (struct tioca *)common->ca_common.bs_base;
-       ca_control1 = tioca_base->ca_control1;
-       ca_control1 |= CA_AGP_FW_ENABLE;
-       tioca_base->ca_control1 = ca_control1;
+       tioca_base = (struct tioca __iomem*)common->ca_common.bs_base;
+       __sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE);
 }
 
 EXPORT_SYMBOL(tioca_fastwrite_enable); /* used by agp-sgi */
@@ -276,7 +276,7 @@ EXPORT_SYMBOL(tioca_fastwrite_enable);      /* used by agp-sgi */
  *                                 We will always use 0x1
  * 55:55 - Swap bytes             Currently unused
  */
-static uint64_t
+static u64
 tioca_dma_d64(unsigned long paddr)
 {
        dma_addr_t bus_addr;
@@ -318,25 +318,25 @@ tioca_dma_d64(unsigned long paddr)
  * and so a given CA can only directly target nodes in the range
  * xxx - xxx+255.
  */
-static uint64_t
-tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr)
+static u64
+tioca_dma_d48(struct pci_dev *pdev, u64 paddr)
 {
        struct tioca_common *tioca_common;
-       struct tioca *ca_base;
-       uint64_t ct_addr;
+       struct tioca __iomem *ca_base;
+       u64 ct_addr;
        dma_addr_t bus_addr;
-       uint32_t node_upper;
-       uint64_t agp_dma_extn;
+       u32 node_upper;
+       u64 agp_dma_extn;
        struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
 
        tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
-       ca_base = (struct tioca *)tioca_common->ca_common.bs_base;
+       ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
 
        ct_addr = PHYS_TO_TIODMA(paddr);
        if (!ct_addr)
                return 0;
 
-       bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffff);
+       bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL);
        node_upper = ct_addr >> 48;
 
        if (node_upper > 64) {
@@ -345,7 +345,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr)
                return 0;
        }
 
-       agp_dma_extn = ca_base->ca_agp_dma_addr_extn;
+       agp_dma_extn = __sn_readq_relaxed(&ca_base->ca_agp_dma_addr_extn);
        if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) {
                printk(KERN_ERR "%s:  coretalk upper node (%u) "
                       "mismatch with ca_agp_dma_addr_extn (%lu)\n",
@@ -367,17 +367,17 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr)
  * dma_addr_t is guarenteed to be contiguous in CA bus space.
  */
 static dma_addr_t
-tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size)
+tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size)
 {
        int i, ps, ps_shift, entry, entries, mapsize, last_entry;
-       uint64_t xio_addr, end_xio_addr;
+       u64 xio_addr, end_xio_addr;
        struct tioca_common *tioca_common;
        struct tioca_kernel *tioca_kern;
        dma_addr_t bus_addr = 0;
        struct tioca_dmamap *ca_dmamap;
        void *map;
        unsigned long flags;
-       struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);;
+       struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
 
        tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
        tioca_kern = (struct tioca_kernel *)tioca_common->ca_kernel_private;
@@ -392,7 +392,7 @@ tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size)
         * allocate a map struct
         */
 
-       ca_dmamap = kcalloc(1, sizeof(struct tioca_dmamap), GFP_ATOMIC);
+       ca_dmamap = kzalloc(sizeof(struct tioca_dmamap), GFP_ATOMIC);
        if (!ca_dmamap)
                goto map_return;
 
@@ -464,7 +464,7 @@ map_return:
  * For mappings created using the direct modes (64 or 48) there are no
  * resources to release.
  */
-void
+static void
 tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
 {
        int i, entry;
@@ -514,10 +514,10 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
  * The mapping mode used is based on the devices dma_mask.  As a last resort
  * use the GART mapped mode.
  */
-uint64_t
-tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count)
+static u64
+tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count)
 {
-       uint64_t mapaddr;
+       u64 mapaddr;
 
        /*
         * If card is 64 or 48 bit addresable, use a direct mapping.  32
@@ -554,12 +554,12 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
 {
        struct tioca_common *soft = arg;
        struct ia64_sal_retval ret_stuff;
-       uint64_t segment;
-       uint64_t busnum;
+       u64 segment;
+       u64 busnum;
        ret_stuff.status = 0;
        ret_stuff.v0 = 0;
 
-       segment = 0;
+       segment = soft->ca_common.bs_persist_segment;
        busnum = soft->ca_common.bs_persist_busnum;
 
        SAL_CALL_NOLOCK(ret_stuff,
@@ -580,8 +580,8 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
  * On successful setup, returns the kernel version of tioca_common back to
  * the caller.
  */
-void *
-tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
+static void *
+tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
 {
        struct tioca_common *tioca_common;
        struct tioca_kernel *tioca_kern;
@@ -589,8 +589,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
 
        /* sanity check prom rev */
 
-       if (sn_sal_rev_major() < 4 ||
-           (sn_sal_rev_major() == 4 && sn_sal_rev_minor() < 6)) {
+       if (sn_sal_rev() < 0x0406) {
                printk
                    (KERN_ERR "%s:  SGI prom rev 4.06 or greater required "
                     "for tioca support\n", __FUNCTION__);
@@ -601,7 +600,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
         * Allocate kernel bus soft and copy from prom.
         */
 
-       tioca_common = kcalloc(1, sizeof(struct tioca_common), GFP_KERNEL);
+       tioca_common = kzalloc(sizeof(struct tioca_common), GFP_KERNEL);
        if (!tioca_common)
                return NULL;
 
@@ -610,7 +609,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
 
        /* init kernel-private area */
 
-       tioca_kern = kcalloc(1, sizeof(struct tioca_kernel), GFP_KERNEL);
+       tioca_kern = kzalloc(sizeof(struct tioca_kernel), GFP_KERNEL);
        if (!tioca_kern) {
                kfree(tioca_common);
                return NULL;
@@ -621,9 +620,10 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
        INIT_LIST_HEAD(&tioca_kern->ca_dmamaps);
        tioca_kern->ca_closest_node =
            nasid_to_cnodeid(tioca_common->ca_closest_nasid);
-       tioca_common->ca_kernel_private = (uint64_t) tioca_kern;
+       tioca_common->ca_kernel_private = (u64) tioca_kern;
 
-       bus = pci_find_bus(0, tioca_common->ca_common.bs_persist_busnum);
+       bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment,
+               tioca_common->ca_common.bs_persist_busnum);
        BUG_ON(!bus);
        tioca_kern->ca_devices = &bus->devices;
 
@@ -647,6 +647,8 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
                       __FUNCTION__, SGI_TIOCA_ERROR,
                       (int)tioca_common->ca_common.bs_persist_busnum);
 
+       /* Setup locality information */
+       controller->node = tioca_kern->ca_closest_node;
        return tioca_common;
 }
 
@@ -655,6 +657,8 @@ static struct sn_pcibus_provider tioca_pci_interfaces = {
        .dma_map_consistent = tioca_dma_map,
        .dma_unmap = tioca_dma_unmap,
        .bus_fixup = tioca_bus_fixup,
+       .force_interrupt = NULL,
+       .target_interrupt = NULL
 };
 
 /**