X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Falpha%2Fkernel%2Fcore_marvel.c;h=bb4fe0498390e0fb775e84a4174180523900c196;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=9bde638e8fc79692f6f3033012710c58a69e939c;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index 9bde638e8..bb4fe0498 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c @@ -610,11 +610,84 @@ marvel_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) csrs->POx_SG_TBIA.csr; } + + +/* + * 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; +} + /* * 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 - - -/* - * 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 /* * NUMA Support