sparc: Kill SBUS layer IRQ hooks.
[safe/jmp/linux-2.6] / arch / sparc / kernel / ioport.c
index 79d1771..0e47830 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ioport.c,v 1.45 2001/10/30 04:54:21 davem Exp $
+/*
  * ioport.c:  Simple io mapping allocator.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -25,7 +25,7 @@
  * <zaitcev> Sounds reasonable
  */
 
-#include <linux/config.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -35,6 +35,8 @@
 #include <linux/slab.h>
 #include <linux/pci.h>         /* struct pci_dev */
 #include <linux/proc_fs.h>
+#include <linux/scatterlist.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/vaddrs.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
 #include <asm/dma.h>
+#include <asm/iommu.h>
+#include <asm/io-unit.h>
+
+#include "dma.h"
 
 #define mmu_inval_dma_area(p, l)       /* Anton pulled it out for 2.4.0-xx */
 
-struct resource *_sparc_find_resource(struct resource *r, unsigned long);
+static struct resource *_sparc_find_resource(struct resource *r,
+                                            unsigned long);
 
 static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz);
 static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys,
     unsigned long size, char *name);
 static void _sparc_free_io(struct resource *res);
 
+static void register_proc_sparc_ioport(void);
+
 /* This points to the next to use virtual memory for DVMA mappings */
 static struct resource _sparc_dvma = {
        .name = "sparc_dvma", .start = DVMA_VADDR, .end = DVMA_END - 1
@@ -143,6 +152,21 @@ void __iomem *sbus_ioremap(struct resource *phyres, unsigned long offset,
            phyres->start + offset, size, name);
 }
 
+void __iomem *of_ioremap(struct resource *res, unsigned long offset,
+                        unsigned long size, char *name)
+{
+       return _sparc_alloc_io(res->flags & 0xF,
+                              res->start + offset,
+                              size, name);
+}
+EXPORT_SYMBOL(of_ioremap);
+
+void of_iounmap(struct resource *res, void __iomem *base, unsigned long size)
+{
+       iounmap(base);
+}
+EXPORT_SYMBOL(of_iounmap);
+
 /*
  */
 void sbus_iounmap(volatile void __iomem *addr, unsigned long size)
@@ -226,69 +250,25 @@ static void _sparc_free_io(struct resource *res)
 
 #ifdef CONFIG_SBUS
 
-void sbus_set_sbus64(struct sbus_dev *sdev, int x)
+void sbus_set_sbus64(struct device *dev, int x)
 {
        printk("sbus_set_sbus64: unsupported\n");
 }
 
-extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq);
-void __init sbus_fill_device_irq(struct sbus_dev *sdev)
-{
-       struct linux_prom_irqs irqs[PROMINTR_MAX];
-       int len;
-
-       len = prom_getproperty(sdev->prom_node, "intr",
-                              (char *)irqs, sizeof(irqs));
-       if (len != -1) {
-               sdev->num_irqs = len / 8;
-               if (sdev->num_irqs == 0) {
-                       sdev->irqs[0] = 0;
-               } else if (sparc_cpu_model == sun4d) {
-                       for (len = 0; len < sdev->num_irqs; len++)
-                               sdev->irqs[len] =
-                                       sun4d_build_irq(sdev, irqs[len].pri);
-               } else {
-                       for (len = 0; len < sdev->num_irqs; len++)
-                               sdev->irqs[len] = irqs[len].pri;
-               }
-       } else {
-               int interrupts[PROMINTR_MAX];
-
-               /* No "intr" node found-- check for "interrupts" node.
-                * This node contains SBus interrupt levels, not IPLs
-                * as in "intr", and no vector values.  We convert
-                * SBus interrupt levels to PILs (platform specific).
-                */
-               len = prom_getproperty(sdev->prom_node, "interrupts",
-                                      (char *)interrupts, sizeof(interrupts));
-               if (len == -1) {
-                       sdev->irqs[0] = 0;
-                       sdev->num_irqs = 0;
-               } else {
-                       sdev->num_irqs = len / sizeof(int);
-                       for (len = 0; len < sdev->num_irqs; len++) {
-                               sdev->irqs[len] =
-                                       sbint_to_irq(sdev, interrupts[len]);
-                       }
-               }
-       } 
-}
-
 /*
  * Allocate a chunk of memory suitable for DMA.
  * Typically devices use them for control blocks.
  * CPU may access them without any explicit flushing.
- *
- * XXX Some clever people know that sdev is not used and supply NULL. Watch.
  */
-void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp)
+void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp)
 {
+       struct of_device *op = to_of_device(dev);
        unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
        unsigned long va;
        struct resource *res;
        int order;
 
-       /* XXX why are some lenghts signed, others unsigned? */
+       /* XXX why are some lengths signed, others unsigned? */
        if (len <= 0) {
                return NULL;
        }
@@ -301,9 +281,8 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp)
        if ((va = __get_free_pages(GFP_KERNEL|__GFP_COMP, order)) == 0)
                goto err_nopages;
 
-       if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL)
+       if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL)
                goto err_nomem;
-       memset((char*)res, 0, sizeof(struct resource));
 
        if (allocate_resource(&_sparc_dvma, res, len_total,
            _sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) {
@@ -317,13 +296,10 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp)
         * XXX That's where sdev would be used. Currently we load
         * all iommu tables with the same translations.
         */
-       if (mmu_map_dma_area(dma_addrp, va, res->start, len_total) != 0)
+       if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0)
                goto err_noiommu;
 
-       /* Set the resource name, if known. */
-       if (sdev) {
-               res->name = sdev->prom_name;
-       }
+       res->name = op->node->name;
 
        return (void *)(unsigned long)res->start;
 
@@ -337,7 +313,7 @@ err_nopages:
        return NULL;
 }
 
-void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba)
+void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba)
 {
        struct resource *res;
        struct page *pgv;
@@ -364,8 +340,8 @@ void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba)
        kfree(res);
 
        /* mmu_inval_dma_area(va, n); */ /* it's consistent, isn't it */
-       pgv = mmu_translate_dvma(ba);
-       mmu_unmap_dma_area(ba, n);
+       pgv = virt_to_page(p);
+       mmu_unmap_dma_area(dev, ba, n);
 
        __free_pages(pgv, get_order(n));
 }
@@ -375,9 +351,9 @@ void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba)
  * CPU view of this memory may be inconsistent with
  * a device view and explicit flushing is necessary.
  */
-dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *va, size_t len, int direction)
+dma_addr_t sbus_map_single(struct device *dev, void *va, size_t len, int direction)
 {
-       /* XXX why are some lenghts signed, others unsigned? */
+       /* XXX why are some lengths signed, others unsigned? */
        if (len <= 0) {
                return 0;
        }
@@ -385,17 +361,17 @@ dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *va, size_t len, int dire
        if (len > 256*1024) {                   /* __get_free_pages() limit */
                return 0;
        }
-       return mmu_get_scsi_one(va, len, sdev->bus);
+       return mmu_get_scsi_one(dev, va, len);
 }
 
-void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t ba, size_t n, int direction)
+void sbus_unmap_single(struct device *dev, dma_addr_t ba, size_t n, int direction)
 {
-       mmu_release_scsi_one(ba, n, sdev->bus);
+       mmu_release_scsi_one(dev, ba, n);
 }
 
-int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction)
+int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n, int direction)
 {
-       mmu_get_scsi_sgl(sg, n, sdev->bus);
+       mmu_get_scsi_sgl(dev, sg, n);
 
        /*
         * XXX sparc64 can return a partial length here. sun4c should do this
@@ -404,61 +380,17 @@ int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direct
        return n;
 }
 
-void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction)
+void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, int n, int direction)
 {
-       mmu_release_scsi_sgl(sg, n, sdev->bus);
+       mmu_release_scsi_sgl(dev, sg, n);
 }
 
-/*
- */
-void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction)
+void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba, size_t size, int direction)
 {
-#if 0
-       unsigned long va;
-       struct resource *res;
-
-       /* We do not need the resource, just print a message if invalid. */
-       res = _sparc_find_resource(&_sparc_dvma, ba);
-       if (res == NULL)
-               panic("sbus_dma_sync_single: 0x%x\n", ba);
-
-       va = page_address(mmu_translate_dvma(ba)); /* XXX higmem */
-       /*
-        * XXX This bogosity will be fixed with the iommu rewrite coming soon
-        * to a kernel near you. - Anton
-        */
-       /* mmu_inval_dma_area(va, (size + PAGE_SIZE-1) & PAGE_MASK); */
-#endif
 }
 
-void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction)
+void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, size_t size, int direction)
 {
-#if 0
-       unsigned long va;
-       struct resource *res;
-
-       /* We do not need the resource, just print a message if invalid. */
-       res = _sparc_find_resource(&_sparc_dvma, ba);
-       if (res == NULL)
-               panic("sbus_dma_sync_single: 0x%x\n", ba);
-
-       va = page_address(mmu_translate_dvma(ba)); /* XXX higmem */
-       /*
-        * XXX This bogosity will be fixed with the iommu rewrite coming soon
-        * to a kernel near you. - Anton
-        */
-       /* mmu_inval_dma_area(va, (size + PAGE_SIZE-1) & PAGE_MASK); */
-#endif
-}
-
-void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction)
-{
-       printk("sbus_dma_sync_sg_for_cpu: not implemented yet\n");
-}
-
-void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction)
-{
-       printk("sbus_dma_sync_sg_for_device: not implemented yet\n");
 }
 
 /* Support code for sbus_init().  */
@@ -491,38 +423,21 @@ void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *s
 
 void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
 {
+#ifndef CONFIG_SUN4
        struct device_node *parent = dp->parent;
 
        if (sparc_cpu_model != sun4d &&
            parent != NULL &&
-           !strcmp(parent->name, "iommu")) {
-               extern void iommu_init(int iommu_node, struct sbus_bus *sbus);
+           !strcmp(parent->name, "iommu"))
+               iommu_init(parent, sbus);
 
-               iommu_init(parent->node, sbus);
-       }
-
-       if (sparc_cpu_model == sun4d) {
-               extern void iounit_init(int sbi_node, int iounit_node,
-                                       struct sbus_bus *sbus);
-
-               iounit_init(dp->node, parent->node, sbus);
-       }
-}
-
-void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp)
-{
-       if (sparc_cpu_model == sun4d) {
-               struct device_node *parent = dp->parent;
-
-               sbus->devid = of_getintprop_default(parent, "device-id", 0);
-               sbus->board = of_getintprop_default(parent, "board#", 0);
-       }
+       if (sparc_cpu_model == sun4d)
+               iounit_init(sbus);
+#endif
 }
 
 int __init sbus_arch_preinit(void)
 {
-       extern void register_proc_sparc_ioport(void);
-
        register_proc_sparc_ioport();
 
 #ifdef CONFIG_SUN4
@@ -571,12 +486,11 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba)
                return NULL;
        }
 
-       if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
+       if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
                free_pages(va, order);
                printk("pci_alloc_consistent: no core\n");
                return NULL;
        }
-       memset((char*)res, 0, sizeof(struct resource));
 
        if (allocate_resource(&_sparc_dvma, res, len_total,
            _sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) {
@@ -601,7 +515,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba)
  * size must be the same as what as passed into pci_alloc_consistent,
  * and likewise dma_addr must be the same as what *dma_addrp was set to.
  *
- * References to the memory and mappings assosciated with cpu_addr/dma_addr
+ * References to the memory and mappings associated with cpu_addr/dma_addr
  * past this call are illegal.
  */
 void pci_free_consistent(struct pci_dev *pdev, size_t n, void *p, dma_addr_t ba)
@@ -701,18 +615,18 @@ void pci_unmap_page(struct pci_dev *hwdev,
  * Device ownership issues as mentioned above for pci_map_single are
  * the same here.
  */
-int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
+int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
     int direction)
 {
+       struct scatterlist *sg;
        int n;
 
        BUG_ON(direction == PCI_DMA_NONE);
        /* IIep is write-through, not flushing. */
-       for (n = 0; n < nents; n++) {
-               BUG_ON(page_address(sg->page) == NULL);
-               sg->dvma_address = virt_to_phys(page_address(sg->page));
+       for_each_sg(sgl, sg, nents, n) {
+               BUG_ON(page_address(sg_page(sg)) == NULL);
+               sg->dvma_address = virt_to_phys(sg_virt(sg));
                sg->dvma_length = sg->length;
-               sg++;
        }
        return nents;
 }
@@ -721,19 +635,19 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
  * Again, cpu read rules concerning calls here are the same as for
  * pci_unmap_single() above.
  */
-void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
+void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
     int direction)
 {
+       struct scatterlist *sg;
        int n;
 
        BUG_ON(direction == PCI_DMA_NONE);
        if (direction != PCI_DMA_TODEVICE) {
-               for (n = 0; n < nents; n++) {
-                       BUG_ON(page_address(sg->page) == NULL);
+               for_each_sg(sgl, sg, nents, n) {
+                       BUG_ON(page_address(sg_page(sg)) == NULL);
                        mmu_inval_dma_area(
-                           (unsigned long) page_address(sg->page),
+                           (unsigned long) page_address(sg_page(sg)),
                            (sg->length + PAGE_SIZE-1) & PAGE_MASK);
-                       sg++;
                }
        }
 }
@@ -772,34 +686,34 @@ void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t
  * The same as pci_dma_sync_single_* but for a scatter-gather list,
  * same rules and usage.
  */
-void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction)
 {
+       struct scatterlist *sg;
        int n;
 
        BUG_ON(direction == PCI_DMA_NONE);
        if (direction != PCI_DMA_TODEVICE) {
-               for (n = 0; n < nents; n++) {
-                       BUG_ON(page_address(sg->page) == NULL);
+               for_each_sg(sgl, sg, nents, n) {
+                       BUG_ON(page_address(sg_page(sg)) == NULL);
                        mmu_inval_dma_area(
-                           (unsigned long) page_address(sg->page),
+                           (unsigned long) page_address(sg_page(sg)),
                            (sg->length + PAGE_SIZE-1) & PAGE_MASK);
-                       sg++;
                }
        }
 }
 
-void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction)
 {
+       struct scatterlist *sg;
        int n;
 
        BUG_ON(direction == PCI_DMA_NONE);
        if (direction != PCI_DMA_TODEVICE) {
-               for (n = 0; n < nents; n++) {
-                       BUG_ON(page_address(sg->page) == NULL);
+               for_each_sg(sgl, sg, nents, n) {
+                       BUG_ON(page_address(sg_page(sg)) == NULL);
                        mmu_inval_dma_area(
-                           (unsigned long) page_address(sg->page),
+                           (unsigned long) page_address(sg_page(sg)),
                            (sg->length + PAGE_SIZE-1) & PAGE_MASK);
-                       sg++;
                }
        }
 }
@@ -836,8 +750,8 @@ _sparc_io_get_info(char *buf, char **start, off_t fpos, int length, int *eof,
  * XXX Too slow. Can have 8192 DVMA pages on sun4m in the worst case.
  * This probably warrants some sort of hashing.
  */
-struct resource *
-_sparc_find_resource(struct resource *root, unsigned long hit)
+static struct resource *_sparc_find_resource(struct resource *root,
+                                            unsigned long hit)
 {
         struct resource *tmp;
 
@@ -848,7 +762,7 @@ _sparc_find_resource(struct resource *root, unsigned long hit)
        return NULL;
 }
 
-void register_proc_sparc_ioport(void)
+static void register_proc_sparc_ioport(void)
 {
 #ifdef CONFIG_PROC_FS
        create_proc_read_entry("io_map",0,NULL,_sparc_io_get_info,&sparc_iomap);