vserver 1.9.3
[linux-2.6.git] / arch / alpha / kernel / core_marvel.c
index 9bde638..bb4fe04 100644 (file)
@@ -610,11 +610,84 @@ marvel_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
        csrs->POx_SG_TBIA.csr;
 }
 
+\f
+\f
+/*
+ * RTC Support
+ */
+struct marvel_rtc_access_info {
+       unsigned long function;
+       unsigned long index;
+       unsigned long data;
+};
+
+static void
+__marvel_access_rtc(void *info)
+{
+       struct marvel_rtc_access_info *rtc_access = info;
+
+       register unsigned long __r0 __asm__("$0");
+       register unsigned long __r16 __asm__("$16") = rtc_access->function;
+       register unsigned long __r17 __asm__("$17") = rtc_access->index;
+       register unsigned long __r18 __asm__("$18") = rtc_access->data;
+       
+       __asm__ __volatile__(
+               "call_pal %4 # cserve rtc"
+               : "=r"(__r16), "=r"(__r17), "=r"(__r18), "=r"(__r0)
+               : "i"(PAL_cserve), "0"(__r16), "1"(__r17), "2"(__r18)
+               : "$1", "$22", "$23", "$24", "$25");
+
+       rtc_access->data = __r0;
+}
+
+static u8
+__marvel_rtc_io(u8 b, unsigned long addr, int write)
+{
+       static u8 index = 0;
+
+       struct marvel_rtc_access_info rtc_access;
+       u8 ret = 0;
+
+       switch(addr) {
+       case 0x70:                                      /* RTC_PORT(0) */
+               if (write) index = b;
+               ret = index;
+               break;
+
+       case 0x71:                                      /* RTC_PORT(1) */
+               rtc_access.index = index;
+               rtc_access.data = BCD_TO_BIN(b);
+               rtc_access.function = 0x48 + !write;    /* GET/PUT_TOY */
+
+#ifdef CONFIG_SMP
+               if (smp_processor_id() != boot_cpuid)
+                       smp_call_function_on_cpu(__marvel_access_rtc,
+                                                &rtc_access, 1, 1,
+                                                cpumask_of_cpu(boot_cpuid));
+               else
+                       __marvel_access_rtc(&rtc_access);
+#else
+               __marvel_access_rtc(&rtc_access);
+#endif
+               ret = BIN_TO_BCD(rtc_access.data);
+               break;
+
+       default:
+               printk(KERN_WARNING "Illegal RTC port %lx\n", addr);
+               break;
+       }
+
+       return ret;
+}
+
 \f
 /*
  * IO map support.
  */
-unsigned long
+
+#define __marvel_is_mem_vga(a) (((a) >= 0xa0000) && ((a) <= 0xc0000))
+
+void __iomem *
 marvel_ioremap(unsigned long addr, unsigned long size)
 {
        struct pci_controller *hose;
@@ -633,8 +706,6 @@ marvel_ioremap(unsigned long addr, unsigned long size)
        }
 #endif
 
-       if (!marvel_is_ioaddr(addr)) return 0UL;
-
        /*
         * Find the hose.
         */
@@ -643,7 +714,7 @@ marvel_ioremap(unsigned long addr, unsigned long size)
                        break; 
        }
        if (!hose)
-               return 0UL;
+               return NULL;
 
        /*
         * We have the hose - calculate the bus limits.
@@ -655,15 +726,17 @@ marvel_ioremap(unsigned long addr, unsigned long size)
         * Is it direct-mapped?
         */
        if ((baddr >= __direct_map_base) && 
-           ((baddr + size - 1) < __direct_map_base + __direct_map_size)) 
-               return IDENT_ADDR | (baddr - __direct_map_base);
+           ((baddr + size - 1) < __direct_map_base + __direct_map_size)) {
+               addr = IDENT_ADDR | (baddr - __direct_map_base);
+               return (void __iomem *) addr;
+       }
 
        /* 
         * Check the scatter-gather arena.
         */
        if (hose->sg_pci &&
            baddr >= (unsigned long)hose->sg_pci->dma_base &&
-           last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size){
+           last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size) {
 
                /*
                 * Adjust the limits (mappings must be page aligned)
@@ -677,7 +750,9 @@ marvel_ioremap(unsigned long addr, unsigned long size)
                 * Map it.
                 */
                area = get_vm_area(size, VM_IOREMAP);
-               if (!area) return (unsigned long)NULL;
+               if (!area)
+                       return NULL;
+
                ptes = hose->sg_pci->ptes;
                for (vaddr = (unsigned long)area->addr; 
                    baddr <= last; 
@@ -686,7 +761,7 @@ marvel_ioremap(unsigned long addr, unsigned long size)
                        if (!(pfn & 1)) {
                                printk("ioremap failed... pte not valid...\n");
                                vfree(area->addr);
-                               return 0UL;
+                               return NULL;
                        }
                        pfn >>= 1;      /* make it a true pfn */
                        
@@ -695,7 +770,7 @@ marvel_ioremap(unsigned long addr, unsigned long size)
                                                     PAGE_SIZE, 0)) {
                                printk("FAILED to map...\n");
                                vfree(area->addr);
-                               return 0UL;
+                               return NULL;
                        }
                }
 
@@ -703,101 +778,81 @@ marvel_ioremap(unsigned long addr, unsigned long size)
 
                vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);
 
-               return vaddr;
+               return (void __iomem *) vaddr;
        }
 
-       /*
-        * Not found - assume legacy ioremap.
-        */
-       return addr;
+       return NULL;
 }
 
 void
-marvel_iounmap(unsigned long addr)
+marvel_iounmap(volatile void __iomem *xaddr)
 {
-       if (((long)addr >> 41) == -2)
-               return; /* kseg map, nothing to do */
-       if (addr)
+       unsigned long addr = (unsigned long) xaddr;
+       if (addr >= VMALLOC_START)
                vfree((void *)(PAGE_MASK & addr)); 
 }
 
-#ifndef CONFIG_ALPHA_GENERIC
-EXPORT_SYMBOL(marvel_ioremap);
-EXPORT_SYMBOL(marvel_iounmap);
-#endif
-
-\f
-/*
- * RTC Support
- */
-struct marvel_rtc_access_info {
-       unsigned long function;
-       unsigned long index;
-       unsigned long data;
-};
-
-static void
-__marvel_access_rtc(void *info)
+int
+marvel_is_mmio(const volatile void __iomem *xaddr)
 {
-       struct marvel_rtc_access_info *rtc_access = info;
-
-       register unsigned long __r0 __asm__("$0");
-       register unsigned long __r16 __asm__("$16") = rtc_access->function;
-       register unsigned long __r17 __asm__("$17") = rtc_access->index;
-       register unsigned long __r18 __asm__("$18") = rtc_access->data;
-       
-       __asm__ __volatile__(
-               "call_pal %4 # cserve rtc"
-               : "=r"(__r16), "=r"(__r17), "=r"(__r18), "=r"(__r0)
-               : "i"(PAL_cserve), "0"(__r16), "1"(__r17), "2"(__r18)
-               : "$1", "$22", "$23", "$24", "$25");
+       unsigned long addr = (unsigned long) xaddr;
 
-       rtc_access->data = __r0;
+       if (addr >= VMALLOC_START)
+               return 1;
+       else
+               return (addr & 0xFF000000UL) == 0;
 }
 
-u8
-__marvel_rtc_io(int write, u8 b, unsigned long addr)
-{
-       struct marvel_rtc_access_info rtc_access = {0, };
-       static u8 index = 0;
-       u8 ret = 0;
-
-       switch(addr) {
-       case 0x70:                                      /* RTC_PORT(0) */
-               if (write) index = b;
-               ret = index;
-               break;
+#define __marvel_is_port_vga(a)        \
+  (((a) >= 0x3b0) && ((a) < 0x3e0) && ((a) != 0x3b3) && ((a) != 0x3d3))
+#define __marvel_is_port_kbd(a)        (((a) == 0x60) || ((a) == 0x64))
+#define __marvel_is_port_rtc(a)        (((a) == 0x70) || ((a) == 0x71))
 
-       case 0x71:                                      /* RTC_PORT(1) */
-               rtc_access.index = index;
-               rtc_access.data = BCD_TO_BIN(b);
-               rtc_access.function = 0x49;             /* GET_TOY */
-               if (write) rtc_access.function = 0x48;  /* PUT_TOY */
-
-#ifdef CONFIG_SMP
-               if (smp_processor_id() != boot_cpuid)
-                       smp_call_function_on_cpu(__marvel_access_rtc,
-                                                &rtc_access,
-                                                1,     /* retry */
-                                                1,     /* wait  */
-                                                1UL << boot_cpuid);
-               else
-                       __marvel_access_rtc(&rtc_access);
-#else
-               __marvel_access_rtc(&rtc_access);
+void __iomem *marvel_ioportmap (unsigned long addr)
+{
+       if (__marvel_is_port_rtc (addr) || __marvel_is_port_kbd(addr))
+               ;
+#ifdef CONFIG_VGA_HOSE
+       else if (__marvel_is_port_vga (addr) && pci_vga_hose)
+               addr += pci_vga_hose->io_space->start;
 #endif
-               ret = BIN_TO_BCD(rtc_access.data);
-               
-               break;
+       else
+               return NULL;
+       return (void __iomem *)addr;
+}
 
-       default:
-               printk(KERN_WARNING "Illegal RTC port %lx\n", addr);
-               break;
-       }
+unsigned int
+marvel_ioread8(void __iomem *xaddr)
+{
+       unsigned long addr = (unsigned long) xaddr;
+       if (__marvel_is_port_kbd(addr))
+               return 0;
+       else if (__marvel_is_port_rtc(addr))
+               return __marvel_rtc_io(0, addr, 0);
+       else
+               return __kernel_ldbu(*(vucp)addr);
+}
 
-       return ret;
+void
+marvel_iowrite8(u8 b, void __iomem *xaddr)
+{
+       unsigned long addr = (unsigned long) xaddr;
+       if (__marvel_is_port_kbd(addr))
+               return;
+       else if (__marvel_is_port_rtc(addr)) 
+               __marvel_rtc_io(b, addr, 1);
+       else
+               __kernel_stb(b, *(vucp)addr);
 }
 
+#ifndef CONFIG_ALPHA_GENERIC
+EXPORT_SYMBOL(marvel_ioremap);
+EXPORT_SYMBOL(marvel_iounmap);
+EXPORT_SYMBOL(marvel_is_mmio);
+EXPORT_SYMBOL(marvel_ioportmap);
+EXPORT_SYMBOL(marvel_ioread8);
+EXPORT_SYMBOL(marvel_iowrite8);
+#endif
 \f
 /*
  * NUMA Support