- use dvma code inside dma api for SUN3/SUN3X
- make ioremap use mappings through tt1 for SUN3x
- add platform device for converted sun3x_esp driver

Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]>
---

This is the first step to get Sun3x back to life. I have a working
kernel with these changes (tested on a Sun 3/80). The missing pieces
are for the console driver, which is still too hackish to submit, yet.

 arch/m68k/kernel/dma.c         |   43 +++++++++++++++++++++++++++++++++++++++-
 arch/m68k/mm/kmap.c            |   24 ++++++++++++++++-----
 arch/m68k/sun3x/config.c       |   31 ++++++++++++++++++++++++++++
 include/asm-m68k/dma-mapping.h |   25 ++++++++++++++++++----
 include/asm-m68k/sun3xprom.h   |    5 ++++
 5 files changed, 116 insertions(+), 12 deletions(-)

diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 6f8c080..0b9b818 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -13,6 +13,7 @@
 #include <linux/vmalloc.h>
 
 #include <asm/pgalloc.h>
+#include <asm/dvma.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
                         dma_addr_t *handle, gfp_t flag)
@@ -31,7 +32,11 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
        if (!page)
                return NULL;
 
-       *handle = page_to_phys(page);
+       if (MACH_IS_SUN3 || MACH_IS_SUN3X)
+               *handle = dvma_map(page_to_phys(page), size);
+       else
+               *handle = page_to_phys(page);
+
        map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA);
        if (!map) {
                __free_pages(page, order);
@@ -62,6 +67,8 @@ void dma_free_coherent(struct device *dev, size_t size,
                       void *addr, dma_addr_t handle)
 {
        pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
+       if (MACH_IS_SUN3 || MACH_IS_SUN3X)
+               dvma_unmap((void *)handle);
        vfree(addr);
 }
 EXPORT_SYMBOL(dma_free_coherent);
@@ -100,6 +107,8 @@ dma_addr_t dma_map_single(struct device *dev, void *addr, 
size_t size,
        dma_addr_t handle = virt_to_bus(addr);
 
        dma_sync_single_for_device(dev, handle, size, dir);
+       if (MACH_IS_SUN3 || MACH_IS_SUN3X)
+               handle = dvma_map(handle, size);
        return handle;
 }
 EXPORT_SYMBOL(dma_map_single);
@@ -111,6 +120,8 @@ dma_addr_t dma_map_page(struct device *dev, struct page 
*page,
        dma_addr_t handle = page_to_phys(page) + offset;
 
        dma_sync_single_for_device(dev, handle, size, dir);
+       if (MACH_IS_SUN3 || MACH_IS_SUN3X)
+               handle = dvma_map(handle, size);
        return handle;
 }
 EXPORT_SYMBOL(dma_map_page);
@@ -123,7 +134,37 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, 
int nents,
        for (i = 0; i < nents; sg++, i++) {
                sg->dma_address = sg_phys(sg);
                dma_sync_single_for_device(dev, sg->dma_address, sg->length, 
dir);
+               if (MACH_IS_SUN3 || MACH_IS_SUN3X)
+                       sg->dma_address = dvma_map(sg->dma_address, sg->length);
        }
        return nents;
 }
 EXPORT_SYMBOL(dma_map_sg);
+
+#if defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
+void dma_unmap_single(struct device *dev, dma_addr_t addr,
+                                   size_t size, enum dma_data_direction dir)
+{
+       if (MACH_IS_SUN3 || MACH_IS_SUN3X)
+               dvma_unmap((void *)addr);
+}
+
+
+void dma_unmap_page(struct device *dev, dma_addr_t addr,
+                                 size_t size, enum dma_data_direction dir)
+{
+       if (MACH_IS_SUN3 || MACH_IS_SUN3X)
+               dvma_unmap((void *)addr);
+}
+
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+                               int nents, enum dma_data_direction dir)
+{
+       int i;
+
+       if (MACH_IS_SUN3 || MACH_IS_SUN3X)
+               for (i = 0; i < nents; sg++, i++)
+                       dvma_unmap((void *)sg->dma_address);
+}
+#endif
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 46b7d60..e76cb5e 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -124,6 +124,13 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned 
long size, int cachefla
                        return (void __iomem *)physaddr;
        }
 #endif
+#ifdef CONFIG_SUN3X
+       if (MACH_IS_SUN3X) {
+               if ((physaddr >= 0x40000000) && (physaddr + size < 0x80000000)
+                   && (cacheflag == IOMAP_NOCACHE_SER))
+                       return (void __iomem *)physaddr;
+       }
+#endif
 
 #ifdef DEBUG
        printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);
@@ -228,13 +235,18 @@ EXPORT_SYMBOL(__ioremap);
 void iounmap(void __iomem *addr)
 {
 #ifdef CONFIG_AMIGA
-       if ((!MACH_IS_AMIGA) ||
-           (((unsigned long)addr < 0x40000000) ||
-            ((unsigned long)addr > 0x60000000)))
-                       free_io_area((__force void *)addr);
-#else
-       free_io_area((__force void *)addr);
+       if (MACH_IS_AMIGA &&
+           (((unsigned long)addr >= 0x40000000) &&
+            ((unsigned long)addr < 0x60000000)))
+               return;
 #endif
+#ifdef CONFIG_SUN3X
+       if (MACH_IS_SUN3X &&
+           (((unsigned long)addr >= 0x40000000) &&
+            ((unsigned long)addr < 0x80000000)))
+               return;
+#endif
+       free_io_area((__force void *)addr);
 }
 EXPORT_SYMBOL(iounmap);
 
diff --git a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c
index 9878917..e021873 100644
--- a/arch/m68k/sun3x/config.c
+++ b/arch/m68k/sun3x/config.c
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <linux/console.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/machdep.h>
@@ -21,6 +22,30 @@
 
 #include "time.h"
 
+static struct resource sun3x_esp_rsrc[] = {
+       {
+               .start = SUN3X_ESP_BASE,
+               .end   = SUN3X_ESP_BASE + 31,
+               .flags = IORESOURCE_MEM
+       },
+       {
+               .start = SUN3X_ESP_DMA,
+               .end   = SUN3X_ESP_DMA + 15,
+               .flags = IORESOURCE_MEM
+       },
+       {
+               .start = 2,
+               .end   = 2,
+               .flags = IORESOURCE_IRQ
+       }
+};
+
+static struct platform_device sun3x_esp_pdev = {
+       .name           = "sun3x_esp",
+       .num_resources  = ARRAY_SIZE(sun3x_esp_rsrc),
+       .resource       = sun3x_esp_rsrc
+};
+
 volatile char *clock_va;
 extern volatile unsigned char *sun3_intreg;
 
@@ -82,6 +107,12 @@ void __init config_sun3x(void)
                break;
        }
 #endif
+       add_preferred_console("ttyS", 0, "9600");
+}
 
+static int __init sun3x_devinit(void)
+{
+       platform_device_register(&sun3x_esp_pdev);
 }
 
+device_initcall(sun3x_devinit);
diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h
index a26cdeb..72e44d9 100644
--- a/include/asm-m68k/dma-mapping.h
+++ b/include/asm-m68k/dma-mapping.h
@@ -49,25 +49,40 @@ static inline void dma_cache_sync(struct device *dev, void 
*vaddr, size_t size,
 
 extern dma_addr_t dma_map_single(struct device *, void *, size_t,
                                 enum dma_data_direction);
+
+extern dma_addr_t dma_map_page(struct device *, struct page *,
+                              unsigned long, size_t size,
+                              enum dma_data_direction);
+
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
+                     enum dma_data_direction);
+
+#if defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
+extern void dma_unmap_single(struct device *dev, dma_addr_t addr,
+                                   size_t size, enum dma_data_direction dir);
+
+extern void dma_unmap_page(struct device *dev, dma_addr_t addr,
+                                 size_t size, enum dma_data_direction dir);
+
+extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+                               int nents, enum dma_data_direction dir);
+
+#else
 static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
                                    size_t size, enum dma_data_direction dir)
 {
 }
 
-extern dma_addr_t dma_map_page(struct device *, struct page *,
-                              unsigned long, size_t size,
-                              enum dma_data_direction);
 static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
                                  size_t size, enum dma_data_direction dir)
 {
 }
 
-extern int dma_map_sg(struct device *, struct scatterlist *, int,
-                     enum dma_data_direction);
 static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
                                int nhwentries, enum dma_data_direction dir)
 {
 }
+#endif
 
 extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
                                       enum dma_data_direction);
diff --git a/include/asm-m68k/sun3xprom.h b/include/asm-m68k/sun3xprom.h
index 6735efc..15bd5c0 100644
--- a/include/asm-m68k/sun3xprom.h
+++ b/include/asm-m68k/sun3xprom.h
@@ -25,6 +25,11 @@ unsigned long sun3x_prom_ptov(unsigned long pa, unsigned 
long size);
 #define SUN3X_IDPROM      0x640007d8
 #define SUN3X_VIDEO_BASE  0x50400000
 #define SUN3X_VIDEO_REGS  0x50300000
+#define SUN3X_ESP_BASE    0x66000000
+#define SUN3X_ESP_DMA     0x66001000
+#define SUN3X_FDC         0x6e000000
+#define SUN3X_FDC_FCR     0x6e000400
+#define SUN3X_FDC_FVR     0x6e000800
 
 /* vector table */
 #define SUN3X_PROM_BASE   0xfefe0000
-
To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to