0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009
0010 #include <asm/io.h>
0011 #include <asm/byteorder.h>
0012
0013 void outsb(unsigned long __addr, const void *src, unsigned long count)
0014 {
0015 void __iomem *addr = (void __iomem *) __addr;
0016 const u8 *p = src;
0017
0018 while (count--)
0019 __raw_writeb(*p++, addr);
0020 }
0021 EXPORT_SYMBOL(outsb);
0022
0023 void outsw(unsigned long __addr, const void *src, unsigned long count)
0024 {
0025 void __iomem *addr = (void __iomem *) __addr;
0026
0027 while (count--) {
0028 __raw_writew(*(u16 *)src, addr);
0029 src += sizeof(u16);
0030 }
0031 }
0032 EXPORT_SYMBOL(outsw);
0033
0034 void outsl(unsigned long __addr, const void *src, unsigned long count)
0035 {
0036 void __iomem *addr = (void __iomem *) __addr;
0037 u32 l, l2;
0038
0039 if (!count)
0040 return;
0041
0042 switch (((unsigned long)src) & 0x3) {
0043 case 0x0:
0044
0045 while (count--) {
0046 __raw_writel(*(u32 *)src, addr);
0047 src += sizeof(u32);
0048 }
0049 break;
0050 case 0x2:
0051
0052 while (count--) {
0053 l = (*(u16 *)src) << 16;
0054 l |= *(u16 *)(src + sizeof(u16));
0055 __raw_writel(l, addr);
0056 src += sizeof(u32);
0057 }
0058 break;
0059 case 0x1:
0060
0061 l = (*(u8 *)src) << 24;
0062 l |= (*(u16 *)(src + sizeof(u8))) << 8;
0063 src += sizeof(u8) + sizeof(u16);
0064 while (count--) {
0065 l2 = *(u32 *)src;
0066 l |= (l2 >> 24);
0067 __raw_writel(l, addr);
0068 l = l2 << 8;
0069 src += sizeof(u32);
0070 }
0071 break;
0072 case 0x3:
0073
0074 l = (*(u8 *)src) << 24;
0075 src += sizeof(u8);
0076 while (count--) {
0077 l2 = *(u32 *)src;
0078 l |= (l2 >> 8);
0079 __raw_writel(l, addr);
0080 l = l2 << 24;
0081 src += sizeof(u32);
0082 }
0083 break;
0084 }
0085 }
0086 EXPORT_SYMBOL(outsl);
0087
0088 void insb(unsigned long __addr, void *dst, unsigned long count)
0089 {
0090 void __iomem *addr = (void __iomem *) __addr;
0091
0092 if (count) {
0093 u32 *pi;
0094 u8 *pb = dst;
0095
0096 while ((((unsigned long)pb) & 0x3) && count--)
0097 *pb++ = __raw_readb(addr);
0098 pi = (u32 *)pb;
0099 while (count >= 4) {
0100 u32 w;
0101
0102 w = (__raw_readb(addr) << 24);
0103 w |= (__raw_readb(addr) << 16);
0104 w |= (__raw_readb(addr) << 8);
0105 w |= (__raw_readb(addr) << 0);
0106 *pi++ = w;
0107 count -= 4;
0108 }
0109 pb = (u8 *)pi;
0110 while (count--)
0111 *pb++ = __raw_readb(addr);
0112 }
0113 }
0114 EXPORT_SYMBOL(insb);
0115
0116 void insw(unsigned long __addr, void *dst, unsigned long count)
0117 {
0118 void __iomem *addr = (void __iomem *) __addr;
0119
0120 if (count) {
0121 u16 *ps = dst;
0122 u32 *pi;
0123
0124 if (((unsigned long)ps) & 0x2) {
0125 *ps++ = __raw_readw(addr);
0126 count--;
0127 }
0128 pi = (u32 *)ps;
0129 while (count >= 2) {
0130 u32 w;
0131
0132 w = __raw_readw(addr) << 16;
0133 w |= __raw_readw(addr) << 0;
0134 *pi++ = w;
0135 count -= 2;
0136 }
0137 ps = (u16 *)pi;
0138 if (count)
0139 *ps = __raw_readw(addr);
0140 }
0141 }
0142 EXPORT_SYMBOL(insw);
0143
0144 void insl(unsigned long __addr, void *dst, unsigned long count)
0145 {
0146 void __iomem *addr = (void __iomem *) __addr;
0147
0148 if (count) {
0149 if ((((unsigned long)dst) & 0x3) == 0) {
0150 u32 *pi = dst;
0151 while (count--)
0152 *pi++ = __raw_readl(addr);
0153 } else {
0154 u32 l = 0, l2, *pi;
0155 u16 *ps;
0156 u8 *pb;
0157
0158 switch (((unsigned long)dst) & 3) {
0159 case 0x2:
0160 ps = dst;
0161 count -= 1;
0162 l = __raw_readl(addr);
0163 *ps++ = l;
0164 pi = (u32 *)ps;
0165 while (count--) {
0166 l2 = __raw_readl(addr);
0167 *pi++ = (l << 16) | (l2 >> 16);
0168 l = l2;
0169 }
0170 ps = (u16 *)pi;
0171 *ps = l;
0172 break;
0173
0174 case 0x1:
0175 pb = dst;
0176 count -= 1;
0177 l = __raw_readl(addr);
0178 *pb++ = l >> 24;
0179 ps = (u16 *)pb;
0180 *ps++ = ((l >> 8) & 0xffff);
0181 pi = (u32 *)ps;
0182 while (count--) {
0183 l2 = __raw_readl(addr);
0184 *pi++ = (l << 24) | (l2 >> 8);
0185 l = l2;
0186 }
0187 pb = (u8 *)pi;
0188 *pb = l;
0189 break;
0190
0191 case 0x3:
0192 pb = (u8 *)dst;
0193 count -= 1;
0194 l = __raw_readl(addr);
0195 *pb++ = l >> 24;
0196 pi = (u32 *)pb;
0197 while (count--) {
0198 l2 = __raw_readl(addr);
0199 *pi++ = (l << 8) | (l2 >> 24);
0200 l = l2;
0201 }
0202 ps = (u16 *)pi;
0203 *ps++ = ((l >> 8) & 0xffff);
0204 pb = (u8 *)ps;
0205 *pb = l;
0206 break;
0207 }
0208 }
0209 }
0210 }
0211 EXPORT_SYMBOL(insl);
0212