1 /*
2  * linux/arch/sh/kernel/io_shmse.c
3  *
4  * Copyright (C) 2003 YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
5  */
6 
7 #include <linux/kernel.h>
8 #include <asm/hitachi_shmse.h>
9 #include <asm/io.h>
10 
11 #define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
12 
13 struct iop {
14 	unsigned long start, end;
15 	unsigned long base;
16 	struct iop *(*check)(struct iop *p, unsigned long port);
17 	unsigned char (*inb)(struct iop *p, unsigned long port);
18 	unsigned short (*inw)(struct iop *p, unsigned long port);
19 	void (*outb)(struct iop *p, unsigned char value, unsigned long port);
20 	void (*outw)(struct iop *p, unsigned short value, unsigned long port);
21 };
22 
simple_check(struct iop * p,unsigned long port)23 struct iop *simple_check(struct iop *p, unsigned long port){
24 	if((p->start <= port) && (port <= p->end))
25 		return p;
26 	else
27 		badio(check, port);
28 }
29 
simple_inw(struct iop * p,unsigned long port)30 unsigned short simple_inw(struct iop *p, unsigned long port){
31 	return *(unsigned short*)(p->base+port);
32 }
33 
simple_outw(struct iop * p,unsigned short value,unsigned long port)34 void simple_outw(struct iop *p, unsigned short value, unsigned long port){
35 	*(unsigned short*)(p->base+port)=value;
36 }
37 
bad_inb(struct iop * p,unsigned long port)38 unsigned char bad_inb(struct iop *p, unsigned long port)
39 {
40 	badio(inb, port);
41 }
42 
bad_outb(struct iop * p,unsigned char value,unsigned long port)43 void bad_outb(struct iop *p, unsigned char value, unsigned long port){
44 	badio(inw, port);
45 }
46 
47 /* MSTLANEX01 LAN at 0xb400:0000 */
48 static struct iop laniop = {
49 	.start = 0x200,	// device is at 0x300, but start here for probing.
50 	.end = 0x30f,
51 	.base = 0xb4000000,
52 	.check = simple_check,
53 	.inb = bad_inb,
54 	.inw = simple_inw,
55 	.outb = bad_outb,
56 	.outw = simple_outw,
57 };
58 
port2iop(unsigned long port)59 static __inline__ struct iop *port2iop(unsigned long port){
60 	if(laniop.check(&laniop, port))
61 		return &laniop;
62 	else
63 		badio(check, port); /* XXX: dummy fallback routine? */
64 }
65 
delay(void)66 static inline void delay(void)
67 {
68 	ctrl_inw(0xac000000);
69 	ctrl_inw(0xac000000);
70 }
71 
shmse_inb(unsigned long port)72 unsigned char shmse_inb(unsigned long port)
73 {
74 	struct iop *p=port2iop(port);
75 	return (p->inb)(p, port);
76 }
77 
shmse_inb_p(unsigned long port)78 unsigned char shmse_inb_p(unsigned long port)
79 {
80 	unsigned char v=shmse_inb(port);
81 	delay();
82 	return v;
83 }
84 
shmse_inw(unsigned long port)85 unsigned short shmse_inw(unsigned long port)
86 {
87 	struct iop *p=port2iop(port);
88 	return (p->inw)(p, port);
89 }
90 
shmse_inl(unsigned long port)91 unsigned int shmse_inl(unsigned long port)
92 {
93 	badio(inl, port);
94 }
95 
shmse_outb(unsigned char value,unsigned long port)96 void shmse_outb(unsigned char value, unsigned long port)
97 {
98 	struct iop *p=port2iop(port);
99 	(p->outb)(p, value, port);
100 }
101 
shmse_outb_p(unsigned char value,unsigned long port)102 void shmse_outb_p(unsigned char value, unsigned long port)
103 {
104 	shmse_outb(value, port);
105 	delay();
106 }
107 
shmse_outw(unsigned short value,unsigned long port)108 void shmse_outw(unsigned short value, unsigned long port)
109 {
110 	struct iop *p=port2iop(port);
111 	(p->outw)(p, value, port);
112 }
113 
shmse_outl(unsigned int value,unsigned long port)114 void shmse_outl(unsigned int value, unsigned long port)
115 {
116 	badio(outl, port);
117 }
118 
shmse_insb(unsigned long port,void * addr,unsigned long count)119 void shmse_insb(unsigned long port, void *addr, unsigned long count)
120 {
121 	unsigned char *a = addr;
122 	struct iop *p=port2iop(port);
123 	while (count--) *a++ = (p->inb)(p, port);
124 }
125 
shmse_insw(unsigned long port,void * addr,unsigned long count)126 void shmse_insw(unsigned long port, void *addr, unsigned long count)
127 {
128 	unsigned short *a = addr;
129 	struct iop *p=port2iop(port);
130 	while (count--) *a++ = (p->inw)(p, port);
131 }
132 
shmse_insl(unsigned long port,void * addr,unsigned long count)133 void shmse_insl(unsigned long port, void *addr, unsigned long count)
134 {
135 	badio(insl, port);
136 }
137 
shmse_outsb(unsigned long port,const void * addr,unsigned long count)138 void shmse_outsb(unsigned long port, const void *addr, unsigned long count)
139 {
140 	unsigned char *a = (unsigned char*)addr;
141 	struct iop *p=port2iop(port);
142 	while (count--) (p->outb)(p, *a++, port);
143 }
144 
shmse_outsw(unsigned long port,const void * addr,unsigned long count)145 void shmse_outsw(unsigned long port, const void *addr, unsigned long count)
146 {
147 	unsigned short *a = (unsigned short*)addr;
148 	struct iop *p=port2iop(port);
149 	while (count--) (p->outw)(p, *a++, port);
150 }
151 
shmse_outsl(unsigned long port,const void * addr,unsigned long count)152 void shmse_outsl(unsigned long port, const void *addr, unsigned long count)
153 {
154 	badio(outsw, port);
155 }
156 
shmse_readb(unsigned long addr)157 unsigned char shmse_readb(unsigned long addr)
158 {
159 	badio(readb, addr);
160 }
161 
shmse_readw(unsigned long addr)162 unsigned short shmse_readw(unsigned long addr)
163 {
164 	badio(readw, addr);
165 }
166 
shmse_readl(unsigned long addr)167 unsigned int shmse_readl(unsigned long addr)
168 {
169 	badio(readl, addr);
170 }
171 
shmse_writeb(unsigned char b,unsigned long addr)172 void shmse_writeb(unsigned char b, unsigned long addr)
173 {
174 	badio(writeb, addr);
175 }
176 
shmse_writew(unsigned short b,unsigned long addr)177 void shmse_writew(unsigned short b, unsigned long addr)
178 {
179 	badio(writew, addr);
180 }
181 
shmse_writel(unsigned int b,unsigned long addr)182 void shmse_writel(unsigned int b, unsigned long addr)
183 {
184 	badio(writel, addr);
185 }
186