linux/arch/m32r/platforms/mappi/io.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/m32r/platforms/mappi/io.c
   3 *
   4 *  Typical I/O routines for Mappi board.
   5 *
   6 *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
   7 *                           Hitoshi Yamamoto
   8 */
   9
  10#include <asm/m32r.h>
  11#include <asm/page.h>
  12#include <asm/io.h>
  13#include <asm/byteorder.h>
  14
  15#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
  16#include <linux/types.h>
  17
  18#define M32R_PCC_IOMAP_SIZE 0x1000
  19
  20#define M32R_PCC_IOSTART0 0x1000
  21#define M32R_PCC_IOEND0   (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1)
  22#define M32R_PCC_IOSTART1 0x2000
  23#define M32R_PCC_IOEND1   (M32R_PCC_IOSTART1 + M32R_PCC_IOMAP_SIZE - 1)
  24
  25extern void pcc_ioread(int, unsigned long, void *, size_t, size_t, int);
  26extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
  27#endif /* CONFIG_PCMCIA && CONFIG_M32R_PCC */
  28
  29#define PORT2ADDR(port)  _port2addr(port)
  30
  31static inline void *_port2addr(unsigned long port)
  32{
  33        return (void *)(port | NONCACHE_OFFSET);
  34}
  35
  36static inline void *_port2addr_ne(unsigned long port)
  37{
  38        return (void *)((port<<1) + NONCACHE_OFFSET + 0x0C000000);
  39}
  40
  41static inline void delay(void)
  42{
  43        __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
  44}
  45
  46/*
  47 * NIC I/O function
  48 */
  49
  50#define PORT2ADDR_NE(port)  _port2addr_ne(port)
  51
  52static inline unsigned char _ne_inb(void *portp)
  53{
  54        return (unsigned char) *(volatile unsigned short *)portp;
  55}
  56
  57static inline unsigned short _ne_inw(void *portp)
  58{
  59        unsigned short tmp;
  60
  61        tmp = *(volatile unsigned short *)portp;
  62        return le16_to_cpu(tmp);
  63}
  64
  65static inline void _ne_outb(unsigned char b, void *portp)
  66{
  67        *(volatile unsigned short *)portp = (unsigned short)b;
  68}
  69
  70static inline void _ne_outw(unsigned short w, void *portp)
  71{
  72        *(volatile unsigned short *)portp = cpu_to_le16(w);
  73}
  74
  75unsigned char _inb(unsigned long port)
  76{
  77        if (port >= 0x300 && port < 0x320)
  78                return _ne_inb(PORT2ADDR_NE(port));
  79        else
  80#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
  81        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
  82                unsigned char b;
  83                pcc_ioread(0, port, &b, sizeof(b), 1, 0);
  84                return b;
  85        } else  if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
  86                unsigned char b;
  87                pcc_ioread(1, port, &b, sizeof(b), 1, 0);
  88                return b;
  89        } else
  90#endif
  91
  92        return *(volatile unsigned char *)PORT2ADDR(port);
  93}
  94
  95unsigned short _inw(unsigned long port)
  96{
  97        if (port >= 0x300 && port < 0x320)
  98                return _ne_inw(PORT2ADDR_NE(port));
  99        else
 100#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
 101        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 102                unsigned short w;
 103                pcc_ioread(0, port, &w, sizeof(w), 1, 0);
 104                return w;
 105        } else  if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
 106                unsigned short w;
 107                pcc_ioread(1, port, &w, sizeof(w), 1, 0);
 108                return w;
 109        } else
 110#endif
 111        return *(volatile unsigned short *)PORT2ADDR(port);
 112}
 113
 114unsigned long _inl(unsigned long port)
 115{
 116#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
 117        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 118                unsigned long l;
 119                pcc_ioread(0, port, &l, sizeof(l), 1, 0);
 120                return l;
 121        } else  if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
 122                unsigned short l;
 123                pcc_ioread(1, port, &l, sizeof(l), 1, 0);
 124                return l;
 125        } else
 126#endif
 127        return *(volatile unsigned long *)PORT2ADDR(port);
 128}
 129
 130unsigned char _inb_p(unsigned long port)
 131{
 132        unsigned char v = _inb(port);
 133        delay();
 134        return (v);
 135}
 136
 137unsigned short _inw_p(unsigned long port)
 138{
 139        unsigned short v = _inw(port);
 140        delay();
 141        return (v);
 142}
 143
 144unsigned long _inl_p(unsigned long port)
 145{
 146        unsigned long v = _inl(port);
 147        delay();
 148        return (v);
 149}
 150
 151void _outb(unsigned char b, unsigned long port)
 152{
 153        if (port >= 0x300 && port < 0x320)
 154                _ne_outb(b, PORT2ADDR_NE(port));
 155        else
 156#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
 157        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 158                pcc_iowrite(0, port, &b, sizeof(b), 1, 0);
 159        } else  if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
 160                pcc_iowrite(1, port, &b, sizeof(b), 1, 0);
 161        } else
 162#endif
 163                *(volatile unsigned char *)PORT2ADDR(port) = b;
 164}
 165
 166void _outw(unsigned short w, unsigned long port)
 167{
 168        if (port >= 0x300 && port < 0x320)
 169                _ne_outw(w, PORT2ADDR_NE(port));
 170        else
 171#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
 172        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 173                pcc_iowrite(0, port, &w, sizeof(w), 1, 0);
 174        } else  if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
 175                pcc_iowrite(1, port, &w, sizeof(w), 1, 0);
 176        } else
 177#endif
 178                *(volatile unsigned short *)PORT2ADDR(port) = w;
 179}
 180
 181void _outl(unsigned long l, unsigned long port)
 182{
 183#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
 184        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 185                pcc_iowrite(0, port, &l, sizeof(l), 1, 0);
 186        } else  if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
 187                pcc_iowrite(1, port, &l, sizeof(l), 1, 0);
 188        } else
 189#endif
 190        *(volatile unsigned long *)PORT2ADDR(port) = l;
 191}
 192
 193void _outb_p(unsigned char b, unsigned long port)
 194{
 195        _outb(b, port);
 196        delay();
 197}
 198
 199void _outw_p(unsigned short w, unsigned long port)
 200{
 201        _outw(w, port);
 202        delay();
 203}
 204
 205void _outl_p(unsigned long l, unsigned long port)
 206{
 207        _outl(l, port);
 208        delay();
 209}
 210
 211void _insb(unsigned int port, void *addr, unsigned long count)
 212{
 213        unsigned short *buf = addr;
 214        unsigned short *portp;
 215
 216        if (port >= 0x300 && port < 0x320){
 217                portp = PORT2ADDR_NE(port);
 218                while (count--)
 219                        *buf++ = *(volatile unsigned char *)portp;
 220#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
 221        } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 222                pcc_ioread(0, port, (void *)addr, sizeof(unsigned char),
 223                           count, 1);
 224        } else  if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
 225                pcc_ioread(1, port, (void *)addr, sizeof(unsigned char),
 226                           count, 1);
 227#endif
 228        } else {
 229                portp = PORT2ADDR(port);
 230                while (count--)
 231                        *buf++ = *(volatile unsigned char *)portp;
 232        }
 233}
 234
 235void _insw(unsigned int port, void *addr, unsigned long count)
 236{
 237        unsigned short *buf = addr;
 238        unsigned short *portp;
 239
 240        if (port >= 0x300 && port < 0x320) {
 241                portp = PORT2ADDR_NE(port);
 242                while (count--)
 243                        *buf++ = _ne_inw(portp);
 244#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
 245        } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 246                pcc_ioread(0, port, (void *)addr, sizeof(unsigned short),
 247                           count, 1);
 248        } else  if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
 249                pcc_ioread(1, port, (void *)addr, sizeof(unsigned short),
 250                           count, 1);
 251#endif
 252        } else {
 253                portp = PORT2ADDR(port);
 254                while (count--)
 255                        *buf++ = *(volatile unsigned short *)portp;
 256        }
 257}
 258
 259void _insl(unsigned int port, void *addr, unsigned long count)
 260{
 261        unsigned long *buf = addr;
 262        unsigned long *portp;
 263
 264        portp = PORT2ADDR(port);
 265        while (count--)
 266                *buf++ = *(volatile unsigned long *)portp;
 267}
 268
 269void _outsb(unsigned int port, const void *addr, unsigned long count)
 270{
 271        const unsigned char *buf = addr;
 272        unsigned char *portp;
 273
 274        if (port >= 0x300 && port < 0x320) {
 275                portp = PORT2ADDR_NE(port);
 276                while (count--)
 277                        _ne_outb(*buf++, portp);
 278#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
 279        } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 280                pcc_iowrite(0, port, (void *)addr, sizeof(unsigned char),
 281                            count, 1);
 282        } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
 283                pcc_iowrite(1, port, (void *)addr, sizeof(unsigned char),
 284                            count, 1);
 285#endif
 286        } else {
 287                portp = PORT2ADDR(port);
 288                while (count--)
 289                        *(volatile unsigned char *)portp = *buf++;
 290        }
 291}
 292
 293void _outsw(unsigned int port, const void *addr, unsigned long count)
 294{
 295        const unsigned short *buf = addr;
 296        unsigned short *portp;
 297
 298        if (port >= 0x300 && port < 0x320) {
 299                portp = PORT2ADDR_NE(port);
 300                while (count--)
 301                        _ne_outw(*buf++, portp);
 302#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
 303        } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 304                pcc_iowrite(0, port, (void *)addr, sizeof(unsigned short),
 305                            count, 1);
 306        } else  if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
 307                pcc_iowrite(1, port, (void *)addr, sizeof(unsigned short),
 308                            count, 1);
 309#endif
 310        } else {
 311                portp = PORT2ADDR(port);
 312                while (count--)
 313                        *(volatile unsigned short *)portp = *buf++;
 314        }
 315}
 316
 317void _outsl(unsigned int port, const void *addr, unsigned long count)
 318{
 319        const unsigned long *buf = addr;
 320        unsigned char *portp;
 321
 322        portp = PORT2ADDR(port);
 323        while (count--)
 324                *(volatile unsigned long *)portp = *buf++;
 325}
 326