root/arch/powerpc/kernel/io.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _insb
  2. _outsb
  3. _insw_ns
  4. _outsw_ns
  5. _insl_ns
  6. _outsl_ns
  7. _memset_io
  8. _memcpy_fromio
  9. _memcpy_toio

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * I/O string operations
   4  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
   5  *    Copyright (C) 2006 IBM Corporation
   6  *
   7  * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
   8  * and Paul Mackerras.
   9  *
  10  * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
  11  * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
  12  *
  13  * Rewritten in C by Stephen Rothwell.
  14  */
  15 #include <linux/kernel.h>
  16 #include <linux/types.h>
  17 #include <linux/compiler.h>
  18 #include <linux/export.h>
  19 
  20 #include <asm/io.h>
  21 #include <asm/firmware.h>
  22 #include <asm/bug.h>
  23 
  24 /* See definition in io.h */
  25 bool isa_io_special;
  26 
  27 void _insb(const volatile u8 __iomem *port, void *buf, long count)
  28 {
  29         u8 *tbuf = buf;
  30         u8 tmp;
  31 
  32         if (unlikely(count <= 0))
  33                 return;
  34         asm volatile("sync");
  35         do {
  36                 tmp = *port;
  37                 eieio();
  38                 *tbuf++ = tmp;
  39         } while (--count != 0);
  40         asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
  41 }
  42 EXPORT_SYMBOL(_insb);
  43 
  44 void _outsb(volatile u8 __iomem *port, const void *buf, long count)
  45 {
  46         const u8 *tbuf = buf;
  47 
  48         if (unlikely(count <= 0))
  49                 return;
  50         asm volatile("sync");
  51         do {
  52                 *port = *tbuf++;
  53         } while (--count != 0);
  54         asm volatile("sync");
  55 }
  56 EXPORT_SYMBOL(_outsb);
  57 
  58 void _insw_ns(const volatile u16 __iomem *port, void *buf, long count)
  59 {
  60         u16 *tbuf = buf;
  61         u16 tmp;
  62 
  63         if (unlikely(count <= 0))
  64                 return;
  65         asm volatile("sync");
  66         do {
  67                 tmp = *port;
  68                 eieio();
  69                 *tbuf++ = tmp;
  70         } while (--count != 0);
  71         asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
  72 }
  73 EXPORT_SYMBOL(_insw_ns);
  74 
  75 void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
  76 {
  77         const u16 *tbuf = buf;
  78 
  79         if (unlikely(count <= 0))
  80                 return;
  81         asm volatile("sync");
  82         do {
  83                 *port = *tbuf++;
  84         } while (--count != 0);
  85         asm volatile("sync");
  86 }
  87 EXPORT_SYMBOL(_outsw_ns);
  88 
  89 void _insl_ns(const volatile u32 __iomem *port, void *buf, long count)
  90 {
  91         u32 *tbuf = buf;
  92         u32 tmp;
  93 
  94         if (unlikely(count <= 0))
  95                 return;
  96         asm volatile("sync");
  97         do {
  98                 tmp = *port;
  99                 eieio();
 100                 *tbuf++ = tmp;
 101         } while (--count != 0);
 102         asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
 103 }
 104 EXPORT_SYMBOL(_insl_ns);
 105 
 106 void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
 107 {
 108         const u32 *tbuf = buf;
 109 
 110         if (unlikely(count <= 0))
 111                 return;
 112         asm volatile("sync");
 113         do {
 114                 *port = *tbuf++;
 115         } while (--count != 0);
 116         asm volatile("sync");
 117 }
 118 EXPORT_SYMBOL(_outsl_ns);
 119 
 120 #define IO_CHECK_ALIGN(v,a) ((((unsigned long)(v)) & ((a) - 1)) == 0)
 121 
 122 notrace void
 123 _memset_io(volatile void __iomem *addr, int c, unsigned long n)
 124 {
 125         void *p = (void __force *)addr;
 126         u32 lc = c;
 127         lc |= lc << 8;
 128         lc |= lc << 16;
 129 
 130         __asm__ __volatile__ ("sync" : : : "memory");
 131         while(n && !IO_CHECK_ALIGN(p, 4)) {
 132                 *((volatile u8 *)p) = c;
 133                 p++;
 134                 n--;
 135         }
 136         while(n >= 4) {
 137                 *((volatile u32 *)p) = lc;
 138                 p += 4;
 139                 n -= 4;
 140         }
 141         while(n) {
 142                 *((volatile u8 *)p) = c;
 143                 p++;
 144                 n--;
 145         }
 146         __asm__ __volatile__ ("sync" : : : "memory");
 147 }
 148 EXPORT_SYMBOL(_memset_io);
 149 
 150 void _memcpy_fromio(void *dest, const volatile void __iomem *src,
 151                     unsigned long n)
 152 {
 153         void *vsrc = (void __force *) src;
 154 
 155         __asm__ __volatile__ ("sync" : : : "memory");
 156         while(n && (!IO_CHECK_ALIGN(vsrc, 4) || !IO_CHECK_ALIGN(dest, 4))) {
 157                 *((u8 *)dest) = *((volatile u8 *)vsrc);
 158                 eieio();
 159                 vsrc++;
 160                 dest++;
 161                 n--;
 162         }
 163         while(n >= 4) {
 164                 *((u32 *)dest) = *((volatile u32 *)vsrc);
 165                 eieio();
 166                 vsrc += 4;
 167                 dest += 4;
 168                 n -= 4;
 169         }
 170         while(n) {
 171                 *((u8 *)dest) = *((volatile u8 *)vsrc);
 172                 eieio();
 173                 vsrc++;
 174                 dest++;
 175                 n--;
 176         }
 177         __asm__ __volatile__ ("sync" : : : "memory");
 178 }
 179 EXPORT_SYMBOL(_memcpy_fromio);
 180 
 181 void _memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
 182 {
 183         void *vdest = (void __force *) dest;
 184 
 185         __asm__ __volatile__ ("sync" : : : "memory");
 186         while(n && (!IO_CHECK_ALIGN(vdest, 4) || !IO_CHECK_ALIGN(src, 4))) {
 187                 *((volatile u8 *)vdest) = *((u8 *)src);
 188                 src++;
 189                 vdest++;
 190                 n--;
 191         }
 192         while(n >= 4) {
 193                 *((volatile u32 *)vdest) = *((volatile u32 *)src);
 194                 src += 4;
 195                 vdest += 4;
 196                 n-=4;
 197         }
 198         while(n) {
 199                 *((volatile u8 *)vdest) = *((u8 *)src);
 200                 src++;
 201                 vdest++;
 202                 n--;
 203         }
 204         __asm__ __volatile__ ("sync" : : : "memory");
 205 }
 206 EXPORT_SYMBOL(_memcpy_toio);

/* [<][>][^][v][top][bottom][index][help] */