PageRenderTime 42ms CodeModel.GetById 13ms app.highlight 22ms RepoModel.GetById 2ms app.codeStats 0ms

/arch/sh/cchips/hd6446x/hd64465/io.c

https://bitbucket.org/evzijst/gittest
C | 216 lines | 161 code | 39 blank | 16 comment | 30 complexity | ffccd166fee7a8a7da9b2c3f47126080 MD5 | raw file
  1/*
  2 * $Id: io.c,v 1.4 2003/08/03 03:05:10 lethal Exp $
  3 * by Greg Banks <gbanks@pocketpenguins.com>
  4 * (c) 2000 PocketPenguins Inc
  5 *
  6 * Derived from io_hd64461.c, which bore the message:
  7 * Copyright (C) 2000 YAEGASHI Takeshi
  8 *
  9 * Typical I/O routines for HD64465 system.
 10 */
 11
 12#include <linux/config.h>
 13#include <linux/kernel.h>
 14#include <linux/module.h>
 15#include <asm/io.h>
 16#include <asm/hd64465/hd64465.h>
 17
 18
 19#define HD64465_DEBUG 0
 20
 21#if HD64465_DEBUG
 22#define DPRINTK(args...)	printk(args)
 23#define DIPRINTK(n, args...)	if (hd64465_io_debug>(n)) printk(args)
 24#else
 25#define DPRINTK(args...)
 26#define DIPRINTK(n, args...)
 27#endif
 28
 29
 30
 31/* This is a hack suitable only for debugging IO port problems */
 32int hd64465_io_debug;
 33EXPORT_SYMBOL(hd64465_io_debug);
 34
 35/* Low iomap maps port 0-1K to addresses in 8byte chunks */
 36#define HD64465_IOMAP_LO_THRESH 0x400
 37#define HD64465_IOMAP_LO_SHIFT	3
 38#define HD64465_IOMAP_LO_MASK	((1<<HD64465_IOMAP_LO_SHIFT)-1)
 39#define HD64465_IOMAP_LO_NMAP	(HD64465_IOMAP_LO_THRESH>>HD64465_IOMAP_LO_SHIFT)
 40static unsigned long	hd64465_iomap_lo[HD64465_IOMAP_LO_NMAP];
 41static unsigned char	hd64465_iomap_lo_shift[HD64465_IOMAP_LO_NMAP];
 42
 43/* High iomap maps port 1K-64K to addresses in 1K chunks */
 44#define HD64465_IOMAP_HI_THRESH 0x10000
 45#define HD64465_IOMAP_HI_SHIFT	10
 46#define HD64465_IOMAP_HI_MASK	((1<<HD64465_IOMAP_HI_SHIFT)-1)
 47#define HD64465_IOMAP_HI_NMAP	(HD64465_IOMAP_HI_THRESH>>HD64465_IOMAP_HI_SHIFT)
 48static unsigned long	hd64465_iomap_hi[HD64465_IOMAP_HI_NMAP];
 49static unsigned char	hd64465_iomap_hi_shift[HD64465_IOMAP_HI_NMAP];
 50
 51#ifndef MAX
 52#define MAX(a,b)    ((a)>(b)?(a):(b))
 53#endif
 54
 55#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
 56
 57void hd64465_port_map(unsigned short baseport, unsigned int nports,
 58		      unsigned long addr, unsigned char shift)
 59{
 60    	unsigned int port, endport = baseport + nports;
 61
 62    	DPRINTK("hd64465_port_map(base=0x%04hx, n=0x%04hx, addr=0x%08lx,endport=0x%04x)\n",
 63	    baseport, nports, addr,endport);
 64	    
 65	for (port = baseport ;
 66	     port < endport && port < HD64465_IOMAP_LO_THRESH ;
 67	     port += (1<<HD64465_IOMAP_LO_SHIFT)) {
 68	    DPRINTK("    maplo[0x%x] = 0x%08lx\n", port, addr);
 69    	    hd64465_iomap_lo[port>>HD64465_IOMAP_LO_SHIFT] = addr;
 70    	    hd64465_iomap_lo_shift[port>>HD64465_IOMAP_LO_SHIFT] = shift;
 71	    addr += (1<<(HD64465_IOMAP_LO_SHIFT));
 72	}
 73
 74	for (port = MAX(baseport, HD64465_IOMAP_LO_THRESH) ;
 75	     port < endport && port < HD64465_IOMAP_HI_THRESH ;
 76	     port += (1<<HD64465_IOMAP_HI_SHIFT)) {
 77	    DPRINTK("    maphi[0x%x] = 0x%08lx\n", port, addr);
 78    	    hd64465_iomap_hi[port>>HD64465_IOMAP_HI_SHIFT] = addr;
 79    	    hd64465_iomap_hi_shift[port>>HD64465_IOMAP_HI_SHIFT] = shift;
 80	    addr += (1<<(HD64465_IOMAP_HI_SHIFT));
 81	}
 82}
 83EXPORT_SYMBOL(hd64465_port_map);
 84
 85void hd64465_port_unmap(unsigned short baseport, unsigned int nports)
 86{
 87    	unsigned int port, endport = baseport + nports;
 88	
 89    	DPRINTK("hd64465_port_unmap(base=0x%04hx, n=0x%04hx)\n",
 90	    baseport, nports);
 91
 92	for (port = baseport ;
 93	     port < endport && port < HD64465_IOMAP_LO_THRESH ;
 94	     port += (1<<HD64465_IOMAP_LO_SHIFT)) {
 95    	    hd64465_iomap_lo[port>>HD64465_IOMAP_LO_SHIFT] = 0;
 96	}
 97
 98	for (port = MAX(baseport, HD64465_IOMAP_LO_THRESH) ;
 99	     port < endport && port < HD64465_IOMAP_HI_THRESH ;
100	     port += (1<<HD64465_IOMAP_HI_SHIFT)) {
101    	    hd64465_iomap_hi[port>>HD64465_IOMAP_HI_SHIFT] = 0;
102	}
103}
104EXPORT_SYMBOL(hd64465_port_unmap);
105
106unsigned long hd64465_isa_port2addr(unsigned long port)
107{
108    	unsigned long addr = 0;
109	unsigned char shift;
110
111	/* handle remapping of low IO ports */
112	if (port < HD64465_IOMAP_LO_THRESH) {
113	    addr = hd64465_iomap_lo[port >> HD64465_IOMAP_LO_SHIFT];
114	    shift = hd64465_iomap_lo_shift[port >> HD64465_IOMAP_LO_SHIFT];
115	    if (addr != 0)
116	    	addr += (port & HD64465_IOMAP_LO_MASK) << shift;
117	    else
118		printk(KERN_NOTICE "io_hd64465: access to un-mapped port %lx\n", port);
119	} else if (port < HD64465_IOMAP_HI_THRESH) {
120	    addr = hd64465_iomap_hi[port >> HD64465_IOMAP_HI_SHIFT];
121	    shift = hd64465_iomap_hi_shift[port >> HD64465_IOMAP_HI_SHIFT];
122	    if (addr != 0)
123		addr += (port & HD64465_IOMAP_HI_MASK) << shift;
124	    else
125		printk(KERN_NOTICE "io_hd64465: access to un-mapped port %lx\n", port);
126	}
127	    	
128	/* HD64465 internal devices (0xb0000000) */
129	else if (port < 0x20000)
130	    addr = CONFIG_HD64465_IOBASE + port - 0x10000;
131
132	/* Whole physical address space (0xa0000000) */
133	else
134	    addr = P2SEGADDR(port);
135
136    	DIPRINTK(2, "PORT2ADDR(0x%08lx) = 0x%08lx\n", port, addr);
137
138	return addr;
139}
140
141static inline void delay(void)
142{
143	ctrl_inw(0xa0000000);
144}
145
146unsigned char hd64465_inb(unsigned long port)
147{
148	unsigned long addr = PORT2ADDR(port);
149	unsigned long b = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
150
151	DIPRINTK(0, "inb(%08lx) = %02x\n", addr, (unsigned)b);
152	return b;
153}
154
155unsigned char hd64465_inb_p(unsigned long port)
156{
157    	unsigned long v;
158	unsigned long addr = PORT2ADDR(port);
159
160	v = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
161	delay();
162	DIPRINTK(0, "inb_p(%08lx) = %02x\n", addr, (unsigned)v);
163	return v;
164}
165
166unsigned short hd64465_inw(unsigned long port)
167{
168    	unsigned long addr = PORT2ADDR(port);
169	unsigned long b = (addr == 0 ? 0 : *(volatile unsigned short*)addr);
170	DIPRINTK(0, "inw(%08lx) = %04lx\n", addr, b);
171	return b;
172}
173
174unsigned int hd64465_inl(unsigned long port)
175{
176    	unsigned long addr = PORT2ADDR(port);
177	unsigned int b = (addr == 0 ? 0 : *(volatile unsigned long*)addr);
178	DIPRINTK(0, "inl(%08lx) = %08x\n", addr, b);
179	return b;
180}
181
182void hd64465_outb(unsigned char b, unsigned long port)
183{
184	unsigned long addr = PORT2ADDR(port);
185
186	DIPRINTK(0, "outb(%02x, %08lx)\n", (unsigned)b, addr);
187	if (addr != 0)
188	    *(volatile unsigned char*)addr = b;
189}
190
191void hd64465_outb_p(unsigned char b, unsigned long port)
192{
193	unsigned long addr = PORT2ADDR(port);
194
195	DIPRINTK(0, "outb_p(%02x, %08lx)\n", (unsigned)b, addr);
196    	if (addr != 0)
197	    *(volatile unsigned char*)addr = b;
198	delay();
199}
200
201void hd64465_outw(unsigned short b, unsigned long port)
202{
203	unsigned long addr = PORT2ADDR(port);
204	DIPRINTK(0, "outw(%04x, %08lx)\n", (unsigned)b, addr);
205	if (addr != 0)
206	    *(volatile unsigned short*)addr = b;
207}
208
209void hd64465_outl(unsigned int b, unsigned long port)
210{
211	unsigned long addr = PORT2ADDR(port);
212	DIPRINTK(0, "outl(%08x, %08lx)\n", b, addr);
213	if (addr != 0)
214            *(volatile unsigned long*)addr = b;
215}
216