1/* 2 * linux/arch/sh/boards/renesas/systemh/io.c 3 * 4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel 5 * Based largely on io_se.c. 6 * 7 * I/O routine for Hitachi 7751 Systemh. 8 */ 9#include <linux/kernel.h> 10#include <linux/types.h> 11#include <linux/pci.h> 12#include <asm/systemh7751.h> 13#include <asm/addrspace.h> 14#include <asm/io.h> 15 16#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area 17 of smc lan chip*/ 18static inline volatile __u16 * 19port2adr(unsigned int port) 20{ 21 if (port >= 0x2000) 22 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); 23 maybebadio((unsigned long)port); 24 return (volatile __u16*)port; 25} 26 27/* 28 * General outline: remap really low stuff [eventually] to SuperIO, 29 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) 30 * is mapped through the PCI IO window. Stuff with high bits (PXSEG) 31 * should be way beyond the window, and is used w/o translation for 32 * compatibility. 33 */ 34unsigned char sh7751systemh_inb(unsigned long port) 35{ 36 if (PXSEG(port)) 37 return *(volatile unsigned char *)port; 38 else if (is_pci_ioaddr(port)) 39 return *(volatile unsigned char *)pci_ioaddr(port); 40 else if (port <= 0x3F1) 41 return *(volatile unsigned char *)ETHER_IOMAP(port); 42 else 43 return (*port2adr(port))&0xff; 44} 45 46unsigned char sh7751systemh_inb_p(unsigned long port) 47{ 48 unsigned char v; 49 50 if (PXSEG(port)) 51 v = *(volatile unsigned char *)port; 52 else if (is_pci_ioaddr(port)) 53 v = *(volatile unsigned char *)pci_ioaddr(port); 54 else if (port <= 0x3F1) 55 v = *(volatile unsigned char *)ETHER_IOMAP(port); 56 else 57 v = (*port2adr(port))&0xff; 58 ctrl_delay(); 59 return v; 60} 61 62unsigned short sh7751systemh_inw(unsigned long port) 63{ 64 if (PXSEG(port)) 65 return *(volatile unsigned short *)port; 66 else if (is_pci_ioaddr(port)) 67 return *(volatile unsigned short *)pci_ioaddr(port); 68 else if (port >= 0x2000) 69 return *port2adr(port); 70 else if (port <= 0x3F1) 71 return *(volatile unsigned int *)ETHER_IOMAP(port); 72 else 73 maybebadio(port); 74 return 0; 75} 76 77unsigned int sh7751systemh_inl(unsigned long port) 78{ 79 if (PXSEG(port)) 80 return *(volatile unsigned long *)port; 81 else if (is_pci_ioaddr(port)) 82 return *(volatile unsigned int *)pci_ioaddr(port); 83 else if (port >= 0x2000) 84 return *port2adr(port); 85 else if (port <= 0x3F1) 86 return *(volatile unsigned int *)ETHER_IOMAP(port); 87 else 88 maybebadio(port); 89 return 0; 90} 91 92void sh7751systemh_outb(unsigned char value, unsigned long port) 93{ 94 95 if (PXSEG(port)) 96 *(volatile unsigned char *)port = value; 97 else if (is_pci_ioaddr(port)) 98 *((unsigned char*)pci_ioaddr(port)) = value; 99 else if (port <= 0x3F1) 100 *(volatile unsigned char *)ETHER_IOMAP(port) = value; 101 else 102 *(port2adr(port)) = value; 103} 104 105void sh7751systemh_outb_p(unsigned char value, unsigned long port) 106{ 107 if (PXSEG(port)) 108 *(volatile unsigned char *)port = value; 109 else if (is_pci_ioaddr(port)) 110 *((unsigned char*)pci_ioaddr(port)) = value; 111 else if (port <= 0x3F1) 112 *(volatile unsigned char *)ETHER_IOMAP(port) = value; 113 else 114 *(port2adr(port)) = value; 115 ctrl_delay(); 116} 117 118void sh7751systemh_outw(unsigned short value, unsigned long port) 119{ 120 if (PXSEG(port)) 121 *(volatile unsigned short *)port = value; 122 else if (is_pci_ioaddr(port)) 123 *((unsigned short *)pci_ioaddr(port)) = value; 124 else if (port >= 0x2000) 125 *port2adr(port) = value; 126 else if (port <= 0x3F1) 127 *(volatile unsigned short *)ETHER_IOMAP(port) = value; 128 else 129 maybebadio(port); 130} 131 132void sh7751systemh_outl(unsigned int value, unsigned long port) 133{ 134 if (PXSEG(port)) 135 *(volatile unsigned long *)port = value; 136 else if (is_pci_ioaddr(port)) 137 *((unsigned long*)pci_ioaddr(port)) = value; 138 else 139 maybebadio(port); 140} 141 142void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) 143{ 144 unsigned char *p = addr; 145 while (count--) *p++ = sh7751systemh_inb(port); 146} 147 148void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count) 149{ 150 unsigned short *p = addr; 151 while (count--) *p++ = sh7751systemh_inw(port); 152} 153 154void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) 155{ 156 maybebadio(port); 157} 158 159void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) 160{ 161 unsigned char *p = (unsigned char*)addr; 162 while (count--) sh7751systemh_outb(*p++, port); 163} 164 165void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count) 166{ 167 unsigned short *p = (unsigned short*)addr; 168 while (count--) sh7751systemh_outw(*p++, port); 169} 170 171void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count) 172{ 173 maybebadio(port); 174} 175