1 /* 2 * linux/arch/sh/kernel/io.c 3 * 4 * Copyright (C) 2000 Stuart Menefy 5 * Copyright (C) 2005 Paul Mundt 6 * 7 * Provide real functions which expand to whatever the header file defined. 8 * Also definitions of machine independent IO functions. 9 * 10 * This file is subject to the terms and conditions of the GNU General Public 11 * License. See the file "COPYING" in the main directory of this archive 12 * for more details. 13 */ 14 #include <linux/module.h> 15 #include <asm/machvec.h> 16 #include <asm/io.h> 17 18 /* 19 * Copy data from IO memory space to "real" memory space. 20 * This needs to be optimized. 21 */ 22 void memcpy_fromio(void *to, volatile void __iomem *from, unsigned long count) 23 { 24 char *p = to; 25 while (count) { 26 count--; 27 *p = readb((void __iomem *)from); 28 p++; 29 from++; 30 } 31 } 32 EXPORT_SYMBOL(memcpy_fromio); 33 34 /* 35 * Copy data from "real" memory space to IO memory space. 36 * This needs to be optimized. 37 */ 38 void memcpy_toio(volatile void __iomem *to, const void *from, unsigned long count) 39 { 40 const char *p = from; 41 while (count) { 42 count--; 43 writeb(*p, (void __iomem *)to); 44 p++; 45 to++; 46 } 47 } 48 EXPORT_SYMBOL(memcpy_toio); 49 50 /* 51 * "memset" on IO memory space. 52 * This needs to be optimized. 53 */ 54 void memset_io(volatile void __iomem *dst, int c, unsigned long count) 55 { 56 while (count) { 57 count--; 58 writeb(c, (void __iomem *)dst); 59 dst++; 60 } 61 } 62 EXPORT_SYMBOL(memset_io); 63 64 void __raw_readsl(unsigned long addr, void *datap, int len) 65 { 66 u32 *data; 67 68 for (data = datap; (len != 0) && (((u32)data & 0x1f) != 0); len--) 69 *data++ = ctrl_inl(addr); 70 71 if (likely(len >= (0x20 >> 2))) { 72 int tmp2, tmp3, tmp4, tmp5, tmp6; 73 74 __asm__ __volatile__( 75 "1: \n\t" 76 "mov.l @%7, r0 \n\t" 77 "mov.l @%7, %2 \n\t" 78 #ifdef CONFIG_CPU_SH4 79 "movca.l r0, @%0 \n\t" 80 #else 81 "mov.l r0, @%0 \n\t" 82 #endif 83 "mov.l @%7, %3 \n\t" 84 "mov.l @%7, %4 \n\t" 85 "mov.l @%7, %5 \n\t" 86 "mov.l @%7, %6 \n\t" 87 "mov.l @%7, r7 \n\t" 88 "mov.l @%7, r0 \n\t" 89 "mov.l %2, @(0x04,%0) \n\t" 90 "mov #0x20>>2, %2 \n\t" 91 "mov.l %3, @(0x08,%0) \n\t" 92 "sub %2, %1 \n\t" 93 "mov.l %4, @(0x0c,%0) \n\t" 94 "cmp/hi %1, %2 ! T if 32 > len \n\t" 95 "mov.l %5, @(0x10,%0) \n\t" 96 "mov.l %6, @(0x14,%0) \n\t" 97 "mov.l r7, @(0x18,%0) \n\t" 98 "mov.l r0, @(0x1c,%0) \n\t" 99 "bf.s 1b \n\t" 100 " add #0x20, %0 \n\t" 101 : "=&r" (data), "=&r" (len), 102 "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4), 103 "=&r" (tmp5), "=&r" (tmp6) 104 : "r"(addr), "0" (data), "1" (len) 105 : "r0", "r7", "t", "memory"); 106 } 107 108 for (; len != 0; len--) 109 *data++ = ctrl_inl(addr); 110 } 111 EXPORT_SYMBOL(__raw_readsl); 112 113 void __raw_writesl(unsigned long addr, const void *data, int len) 114 { 115 if (likely(len != 0)) { 116 int tmp1; 117 118 __asm__ __volatile__ ( 119 "1: \n\t" 120 "mov.l @%0+, %1 \n\t" 121 "dt %3 \n\t" 122 "bf.s 1b \n\t" 123 " mov.l %1, @%4 \n\t" 124 : "=&r" (data), "=&r" (tmp1) 125 : "0" (data), "r" (len), "r"(addr) 126 : "t", "memory"); 127 } 128 } 129 EXPORT_SYMBOL(__raw_writesl); 130 131 void __iomem *ioport_map(unsigned long port, unsigned int nr) 132 { 133 return sh_mv.mv_ioport_map(port, nr); 134 } 135 EXPORT_SYMBOL(ioport_map); 136 137 void ioport_unmap(void __iomem *addr) 138 { 139 sh_mv.mv_ioport_unmap(addr); 140 } 141 EXPORT_SYMBOL(ioport_unmap); 142