linux/arch/m68k/include/asm/raw_io.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * linux/include/asm-m68k/raw_io.h
   4 *
   5 * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace
   6 *
   7 */
   8
   9#ifndef _RAW_IO_H
  10#define _RAW_IO_H
  11
  12#ifdef __KERNEL__
  13
  14#include <asm/byteorder.h>
  15
  16/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
  17 * two accesses to memory, which may be undesirable for some devices.
  18 */
  19#define in_8(addr) \
  20    ({ u8 __v = (*(__force volatile u8 *) (unsigned long)(addr)); __v; })
  21#define in_be16(addr) \
  22    ({ u16 __v = (*(__force volatile u16 *) (unsigned long)(addr)); __v; })
  23#define in_be32(addr) \
  24    ({ u32 __v = (*(__force volatile u32 *) (unsigned long)(addr)); __v; })
  25#define in_le16(addr) \
  26    ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (unsigned long)(addr)); __v; })
  27#define in_le32(addr) \
  28    ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (unsigned long)(addr)); __v; })
  29
  30#define out_8(addr,b) (void)((*(__force volatile u8 *) (unsigned long)(addr)) = (b))
  31#define out_be16(addr,w) (void)((*(__force volatile u16 *) (unsigned long)(addr)) = (w))
  32#define out_be32(addr,l) (void)((*(__force volatile u32 *) (unsigned long)(addr)) = (l))
  33#define out_le16(addr,w) (void)((*(__force volatile __le16 *) (unsigned long)(addr)) = cpu_to_le16(w))
  34#define out_le32(addr,l) (void)((*(__force volatile __le32 *) (unsigned long)(addr)) = cpu_to_le32(l))
  35
  36#define raw_inb in_8
  37#define raw_inw in_be16
  38#define raw_inl in_be32
  39#define __raw_readb in_8
  40#define __raw_readw in_be16
  41#define __raw_readl in_be32
  42
  43#define raw_outb(val,port) out_8((port),(val))
  44#define raw_outw(val,port) out_be16((port),(val))
  45#define raw_outl(val,port) out_be32((port),(val))
  46#define __raw_writeb(val,addr) out_8((addr),(val))
  47#define __raw_writew(val,addr) out_be16((addr),(val))
  48#define __raw_writel(val,addr) out_be32((addr),(val))
  49
  50/*
  51 * Atari ROM port (cartridge port) ISA adapter, used for the EtherNEC NE2000
  52 * network card driver.
  53 * The ISA adapter connects address lines A9-A13 to ISA address lines A0-A4,
  54 * and hardwires the rest of the ISA addresses for a base address of 0x300.
  55 *
  56 * Data lines D8-D15 are connected to ISA data lines D0-D7 for reading.
  57 * For writes, address lines A1-A8 are latched to ISA data lines D0-D7
  58 * (meaning the bit pattern on A1-A8 can be read back as byte).
  59 *
  60 * Read and write operations are distinguished by the base address used:
  61 * reads are from the ROM A side range, writes are through the B side range
  62 * addresses (A side base + 0x10000).
  63 *
  64 * Reads and writes are byte only.
  65 *
  66 * 16 bit reads and writes are necessary for the NetUSBee adapter's USB
  67 * chipset - 16 bit words are read straight off the ROM port while 16 bit
  68 * reads are split into two byte writes. The low byte is latched to the
  69 * NetUSBee buffer by a read from the _read_ window (with the data pattern
  70 * asserted as A1-A8 address pattern). The high byte is then written to the
  71 * write range as usual, completing the write cycle.
  72 */
  73
  74#if defined(CONFIG_ATARI_ROM_ISA)
  75#define rom_in_8(addr) \
  76        ({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
  77#define rom_in_be16(addr) \
  78        ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
  79#define rom_in_le16(addr) \
  80        ({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; })
  81
  82#define rom_out_8(addr, b)      \
  83        ({u8 __maybe_unused __w, __v = (b);  u32 _addr = ((u32) (addr)); \
  84        __w = ((*(__force volatile u8 *)  ((_addr | 0x10000) + (__v<<1)))); })
  85#define rom_out_be16(addr, w)   \
  86        ({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \
  87        __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v & 0xFF)<<1)))); \
  88        __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v >> 8)<<1)))); })
  89#define rom_out_le16(addr, w)   \
  90        ({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \
  91        __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v >> 8)<<1)))); \
  92        __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v & 0xFF)<<1)))); })
  93
  94#define raw_rom_inb rom_in_8
  95#define raw_rom_inw rom_in_be16
  96
  97#define raw_rom_outb(val, port) rom_out_8((port), (val))
  98#define raw_rom_outw(val, port) rom_out_be16((port), (val))
  99#endif /* CONFIG_ATARI_ROM_ISA */
 100
 101static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
 102{
 103        unsigned int i;
 104
 105        for (i = 0; i < len; i++)
 106                *buf++ = in_8(port);
 107}
 108
 109static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf,
 110                             unsigned int nr)
 111{
 112        unsigned int tmp;
 113
 114        if (nr & 15) {
 115                tmp = (nr & 15) - 1;
 116                asm volatile (
 117                        "1: moveb %0@+,%2@; dbra %1,1b"
 118                        : "=a" (buf), "=d" (tmp)
 119                        : "a" (port), "0" (buf),
 120                          "1" (tmp));
 121        }
 122        if (nr >> 4) {
 123                tmp = (nr >> 4) - 1;
 124                asm volatile (
 125                        "1: "
 126                        "moveb %0@+,%2@; "
 127                        "moveb %0@+,%2@; "
 128                        "moveb %0@+,%2@; "
 129                        "moveb %0@+,%2@; "
 130                        "moveb %0@+,%2@; "
 131                        "moveb %0@+,%2@; "
 132                        "moveb %0@+,%2@; "
 133                        "moveb %0@+,%2@; "
 134                        "moveb %0@+,%2@; "
 135                        "moveb %0@+,%2@; "
 136                        "moveb %0@+,%2@; "
 137                        "moveb %0@+,%2@; "
 138                        "moveb %0@+,%2@; "
 139                        "moveb %0@+,%2@; "
 140                        "moveb %0@+,%2@; "
 141                        "moveb %0@+,%2@; "
 142                        "dbra %1,1b"
 143                        : "=a" (buf), "=d" (tmp)
 144                        : "a" (port), "0" (buf),
 145                          "1" (tmp));
 146        }
 147}
 148
 149static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr)
 150{
 151        unsigned int tmp;
 152
 153        if (nr & 15) {
 154                tmp = (nr & 15) - 1;
 155                asm volatile (
 156                        "1: movew %2@,%0@+; dbra %1,1b"
 157                        : "=a" (buf), "=d" (tmp)
 158                        : "a" (port), "0" (buf),
 159                          "1" (tmp));
 160        }
 161        if (nr >> 4) {
 162                tmp = (nr >> 4) - 1;
 163                asm volatile (
 164                        "1: "
 165                        "movew %2@,%0@+; "
 166                        "movew %2@,%0@+; "
 167                        "movew %2@,%0@+; "
 168                        "movew %2@,%0@+; "
 169                        "movew %2@,%0@+; "
 170                        "movew %2@,%0@+; "
 171                        "movew %2@,%0@+; "
 172                        "movew %2@,%0@+; "
 173                        "movew %2@,%0@+; "
 174                        "movew %2@,%0@+; "
 175                        "movew %2@,%0@+; "
 176                        "movew %2@,%0@+; "
 177                        "movew %2@,%0@+; "
 178                        "movew %2@,%0@+; "
 179                        "movew %2@,%0@+; "
 180                        "movew %2@,%0@+; "
 181                        "dbra %1,1b"
 182                        : "=a" (buf), "=d" (tmp)
 183                        : "a" (port), "0" (buf),
 184                          "1" (tmp));
 185        }
 186}
 187
 188static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf,
 189                             unsigned int nr)
 190{
 191        unsigned int tmp;
 192
 193        if (nr & 15) {
 194                tmp = (nr & 15) - 1;
 195                asm volatile (
 196                        "1: movew %0@+,%2@; dbra %1,1b"
 197                        : "=a" (buf), "=d" (tmp)
 198                        : "a" (port), "0" (buf),
 199                          "1" (tmp));
 200        }
 201        if (nr >> 4) {
 202                tmp = (nr >> 4) - 1;
 203                asm volatile (
 204                        "1: "
 205                        "movew %0@+,%2@; "
 206                        "movew %0@+,%2@; "
 207                        "movew %0@+,%2@; "
 208                        "movew %0@+,%2@; "
 209                        "movew %0@+,%2@; "
 210                        "movew %0@+,%2@; "
 211                        "movew %0@+,%2@; "
 212                        "movew %0@+,%2@; "
 213                        "movew %0@+,%2@; "
 214                        "movew %0@+,%2@; "
 215                        "movew %0@+,%2@; "
 216                        "movew %0@+,%2@; "
 217                        "movew %0@+,%2@; "
 218                        "movew %0@+,%2@; "
 219                        "movew %0@+,%2@; "
 220                        "movew %0@+,%2@; "
 221                        "dbra %1,1b"
 222                        : "=a" (buf), "=d" (tmp)
 223                        : "a" (port), "0" (buf),
 224                          "1" (tmp));
 225        }
 226}
 227
 228static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr)
 229{
 230        unsigned int tmp;
 231
 232        if (nr & 15) {
 233                tmp = (nr & 15) - 1;
 234                asm volatile (
 235                        "1: movel %2@,%0@+; dbra %1,1b"
 236                        : "=a" (buf), "=d" (tmp)
 237                        : "a" (port), "0" (buf),
 238                          "1" (tmp));
 239        }
 240        if (nr >> 4) {
 241                tmp = (nr >> 4) - 1;
 242                asm volatile (
 243                        "1: "
 244                        "movel %2@,%0@+; "
 245                        "movel %2@,%0@+; "
 246                        "movel %2@,%0@+; "
 247                        "movel %2@,%0@+; "
 248                        "movel %2@,%0@+; "
 249                        "movel %2@,%0@+; "
 250                        "movel %2@,%0@+; "
 251                        "movel %2@,%0@+; "
 252                        "movel %2@,%0@+; "
 253                        "movel %2@,%0@+; "
 254                        "movel %2@,%0@+; "
 255                        "movel %2@,%0@+; "
 256                        "movel %2@,%0@+; "
 257                        "movel %2@,%0@+; "
 258                        "movel %2@,%0@+; "
 259                        "movel %2@,%0@+; "
 260                        "dbra %1,1b"
 261                        : "=a" (buf), "=d" (tmp)
 262                        : "a" (port), "0" (buf),
 263                          "1" (tmp));
 264        }
 265}
 266
 267static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf,
 268                             unsigned int nr)
 269{
 270        unsigned int tmp;
 271
 272        if (nr & 15) {
 273                tmp = (nr & 15) - 1;
 274                asm volatile (
 275                        "1: movel %0@+,%2@; dbra %1,1b"
 276                        : "=a" (buf), "=d" (tmp)
 277                        : "a" (port), "0" (buf),
 278                          "1" (tmp));
 279        }
 280        if (nr >> 4) {
 281                tmp = (nr >> 4) - 1;
 282                asm volatile (
 283                        "1: "
 284                        "movel %0@+,%2@; "
 285                        "movel %0@+,%2@; "
 286                        "movel %0@+,%2@; "
 287                        "movel %0@+,%2@; "
 288                        "movel %0@+,%2@; "
 289                        "movel %0@+,%2@; "
 290                        "movel %0@+,%2@; "
 291                        "movel %0@+,%2@; "
 292                        "movel %0@+,%2@; "
 293                        "movel %0@+,%2@; "
 294                        "movel %0@+,%2@; "
 295                        "movel %0@+,%2@; "
 296                        "movel %0@+,%2@; "
 297                        "movel %0@+,%2@; "
 298                        "movel %0@+,%2@; "
 299                        "movel %0@+,%2@; "
 300                        "dbra %1,1b"
 301                        : "=a" (buf), "=d" (tmp)
 302                        : "a" (port), "0" (buf),
 303                          "1" (tmp));
 304        }
 305}
 306
 307
 308static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf,
 309                                  unsigned int nr)
 310{
 311    if ((nr) % 8)
 312        __asm__ __volatile__
 313               ("\tmovel %0,%/a0\n\t"
 314                "movel %1,%/a1\n\t"
 315                "movel %2,%/d6\n\t"
 316                "subql #1,%/d6\n"
 317                "1:\tmovew %/a0@,%/d0\n\t"
 318                "rolw  #8,%/d0\n\t"
 319                "movew %/d0,%/a1@+\n\t"
 320                "dbra %/d6,1b"
 321                :
 322                : "g" (port), "g" (buf), "g" (nr)
 323                : "d0", "a0", "a1", "d6");
 324    else
 325        __asm__ __volatile__
 326               ("movel %0,%/a0\n\t"
 327                "movel %1,%/a1\n\t"
 328                "movel %2,%/d6\n\t"
 329                "lsrl  #3,%/d6\n\t"
 330                "subql #1,%/d6\n"
 331                "1:\tmovew %/a0@,%/d0\n\t"
 332                "rolw  #8,%/d0\n\t"
 333                "movew %/d0,%/a1@+\n\t"
 334                "movew %/a0@,%/d0\n\t"
 335                "rolw  #8,%/d0\n\t"
 336                "movew %/d0,%/a1@+\n\t"
 337                "movew %/a0@,%/d0\n\t"
 338                "rolw  #8,%/d0\n\t"
 339                "movew %/d0,%/a1@+\n\t"
 340                "movew %/a0@,%/d0\n\t"
 341                "rolw  #8,%/d0\n\t"
 342                "movew %/d0,%/a1@+\n\t"
 343                "movew %/a0@,%/d0\n\t"
 344                "rolw  #8,%/d0\n\t"
 345                "movew %/d0,%/a1@+\n\t"
 346                "movew %/a0@,%/d0\n\t"
 347                "rolw  #8,%/d0\n\t"
 348                "movew %/d0,%/a1@+\n\t"
 349                "movew %/a0@,%/d0\n\t"
 350                "rolw  #8,%/d0\n\t"
 351                "movew %/d0,%/a1@+\n\t"
 352                "movew %/a0@,%/d0\n\t"
 353                "rolw  #8,%/d0\n\t"
 354                "movew %/d0,%/a1@+\n\t"
 355                "dbra %/d6,1b"
 356                :
 357                : "g" (port), "g" (buf), "g" (nr)
 358                : "d0", "a0", "a1", "d6");
 359}
 360
 361static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
 362                                   unsigned int nr)
 363{
 364    if ((nr) % 8)
 365        __asm__ __volatile__
 366               ("movel %0,%/a0\n\t"
 367                "movel %1,%/a1\n\t"
 368                "movel %2,%/d6\n\t"
 369                "subql #1,%/d6\n"
 370                "1:\tmovew %/a1@+,%/d0\n\t"
 371                "rolw  #8,%/d0\n\t"
 372                "movew %/d0,%/a0@\n\t"
 373                "dbra %/d6,1b"
 374                :
 375                : "g" (port), "g" (buf), "g" (nr)
 376                : "d0", "a0", "a1", "d6");
 377    else
 378        __asm__ __volatile__
 379               ("movel %0,%/a0\n\t"
 380                "movel %1,%/a1\n\t"
 381                "movel %2,%/d6\n\t"
 382                "lsrl  #3,%/d6\n\t"
 383                "subql #1,%/d6\n"
 384                "1:\tmovew %/a1@+,%/d0\n\t"
 385                "rolw  #8,%/d0\n\t"
 386                "movew %/d0,%/a0@\n\t"
 387                "movew %/a1@+,%/d0\n\t"
 388                "rolw  #8,%/d0\n\t"
 389                "movew %/d0,%/a0@\n\t"
 390                "movew %/a1@+,%/d0\n\t"
 391                "rolw  #8,%/d0\n\t"
 392                "movew %/d0,%/a0@\n\t"
 393                "movew %/a1@+,%/d0\n\t"
 394                "rolw  #8,%/d0\n\t"
 395                "movew %/d0,%/a0@\n\t"
 396                "movew %/a1@+,%/d0\n\t"
 397                "rolw  #8,%/d0\n\t"
 398                "movew %/d0,%/a0@\n\t"
 399                "movew %/a1@+,%/d0\n\t"
 400                "rolw  #8,%/d0\n\t"
 401                "movew %/d0,%/a0@\n\t"
 402                "movew %/a1@+,%/d0\n\t"
 403                "rolw  #8,%/d0\n\t"
 404                "movew %/d0,%/a0@\n\t"
 405                "movew %/a1@+,%/d0\n\t"
 406                "rolw  #8,%/d0\n\t"
 407                "movew %/d0,%/a0@\n\t"
 408                "dbra %/d6,1b"
 409                :
 410                : "g" (port), "g" (buf), "g" (nr)
 411                : "d0", "a0", "a1", "d6");
 412}
 413
 414
 415#if defined(CONFIG_ATARI_ROM_ISA)
 416static inline void raw_rom_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
 417{
 418        unsigned int i;
 419
 420        for (i = 0; i < len; i++)
 421                *buf++ = rom_in_8(port);
 422}
 423
 424static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf,
 425                             unsigned int len)
 426{
 427        unsigned int i;
 428
 429        for (i = 0; i < len; i++)
 430                rom_out_8(port, *buf++);
 431}
 432
 433static inline void raw_rom_insw(volatile u16 __iomem *port, u16 *buf,
 434                                   unsigned int nr)
 435{
 436        unsigned int i;
 437
 438        for (i = 0; i < nr; i++)
 439                *buf++ = rom_in_be16(port);
 440}
 441
 442static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf,
 443                                   unsigned int nr)
 444{
 445        unsigned int i;
 446
 447        for (i = 0; i < nr; i++)
 448                rom_out_be16(port, *buf++);
 449}
 450
 451static inline void raw_rom_insw_swapw(volatile u16 __iomem *port, u16 *buf,
 452                                   unsigned int nr)
 453{
 454        unsigned int i;
 455
 456        for (i = 0; i < nr; i++)
 457                *buf++ = rom_in_le16(port);
 458}
 459
 460static inline void raw_rom_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
 461                                   unsigned int nr)
 462{
 463        unsigned int i;
 464
 465        for (i = 0; i < nr; i++)
 466                rom_out_le16(port, *buf++);
 467}
 468#endif /* CONFIG_ATARI_ROM_ISA */
 469
 470#endif /* __KERNEL__ */
 471
 472#endif /* _RAW_IO_H */
 473