MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / nios2nommu / kernel / io.c
blobe1b0b12942771d9a3d9861f7a9e3c88e78ae234e
1 /*--------------------------------------------------------------------
3 * Optimized IO string functions.
5 * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
7 * Copyright (C) 2004 Microtronix Datacom Ltd
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
20 * Jan/20/2004 dgt NiosII
22 ---------------------------------------------------------------------*/
25 #include <asm/io.h>
27 void insl(unsigned long port, void *dst, unsigned long count)
29 unsigned long read32;
31 if ((unsigned long)dst & 2){
32 /* Unaligned destination pointer, need to do
33 * two 16 bit writes for each read.
35 unsigned short *p=(unsigned short*)dst;
36 while (count--){
37 read32 = inl(port);
38 *p++ = read32 & 0xFFFF;
39 *p++ = read32 >> 16;
42 else {
43 unsigned long *p=(unsigned long*)dst;
44 while (count--)
45 *p++ = inl(port);
49 void insw(unsigned long port, void *dst, unsigned long count)
51 unsigned long dst1=(unsigned long)dst;
52 if (count > 8) {
53 /* Long word align buffer ptr */
54 if (dst1 & 2) {
55 *(unsigned short*)dst1 = inw(port);
56 dst1 += sizeof(unsigned short);
57 count--;
60 /* Input pairs of short and store as longs */
61 while (count >= 8) {
62 *((unsigned long *)dst1) = inw(port) + (inw(port) << 16); dst1+=sizeof(unsigned long);
63 *((unsigned long *)dst1) = inw(port) + (inw(port) << 16); dst1+=sizeof(unsigned long);
64 *((unsigned long *)dst1) = inw(port) + (inw(port) << 16); dst1+=sizeof(unsigned long);
65 *((unsigned long *)dst1) = inw(port) + (inw(port) << 16); dst1+=sizeof(unsigned long);
66 count -= 8;
70 /* Input remaining shorts */
71 while (count--) {
72 *((unsigned short *)dst1) = inw(port);
73 dst1 += sizeof(unsigned short);
78 void outsl(unsigned long port, void *src, unsigned long count)
80 unsigned long src1=(unsigned long)src;
81 unsigned long write32;
83 if (src1 & 2){
84 /* Unaligned source pointer, need to read
85 * two 16 bit shorts before writing to register.
87 while (count--){
88 write32 = *(unsigned short *)src1;
89 src1+=sizeof(unsigned short);
90 write32 |= *((unsigned short *)src1) << 16;
91 src1+=sizeof(unsigned short);
92 outl(write32,port);
95 else {
96 while (count--) {
97 outl(*(unsigned long *)src1,port);
98 src1+=sizeof(unsigned long);
103 void outsw(unsigned long port, void *src, unsigned long count)
105 unsigned int lw;
106 unsigned long src1=(unsigned long)src;
108 if (count > 8) {
109 /* Long word align buffer ptr */
110 if (src1 & 2) {
111 outw( *(unsigned short *)src1, port );
112 count--;
113 src1 += sizeof(unsigned short);
116 /* Read long words and output as pairs of short */
117 while (count >= 8) {
118 lw = *(unsigned long *)src1;
119 src1+=sizeof(unsigned long);
120 outw(lw, port);
121 outw((lw >> 16), port);
122 lw = *(unsigned long *)src1;
123 src1+=sizeof(unsigned long);
124 outw(lw, port);
125 outw((lw >> 16), port);
126 lw = *(unsigned long *)src1;
127 src1+=sizeof(unsigned long);
128 outw(lw, port);
129 outw((lw >> 16), port);
130 lw = *(unsigned long *)src1;
131 src1+=sizeof(unsigned long);
132 outw(lw, port);
133 outw((lw >> 16), port);
134 count -= 8;
138 /* Output remaining shorts */
139 while (count--) {
140 outw( *(unsigned short *)src1, port );
141 src1 += sizeof(unsigned short);