root/include/linux/io-mapping.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. io_mapping_init_wc
  2. io_mapping_fini
  3. io_mapping_map_atomic_wc
  4. io_mapping_unmap_atomic
  5. io_mapping_map_wc
  6. io_mapping_unmap
  7. io_mapping_init_wc
  8. io_mapping_fini
  9. io_mapping_map_wc
  10. io_mapping_unmap
  11. io_mapping_map_atomic_wc
  12. io_mapping_unmap_atomic
  13. io_mapping_create_wc
  14. io_mapping_free

   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * Copyright © 2008 Keith Packard <keithp@keithp.com>
   4  */
   5 
   6 #ifndef _LINUX_IO_MAPPING_H
   7 #define _LINUX_IO_MAPPING_H
   8 
   9 #include <linux/types.h>
  10 #include <linux/slab.h>
  11 #include <linux/bug.h>
  12 #include <linux/io.h>
  13 #include <asm/page.h>
  14 
  15 /*
  16  * The io_mapping mechanism provides an abstraction for mapping
  17  * individual pages from an io device to the CPU in an efficient fashion.
  18  *
  19  * See Documentation/io-mapping.txt
  20  */
  21 
  22 struct io_mapping {
  23         resource_size_t base;
  24         unsigned long size;
  25         pgprot_t prot;
  26         void __iomem *iomem;
  27 };
  28 
  29 #ifdef CONFIG_HAVE_ATOMIC_IOMAP
  30 
  31 #include <asm/iomap.h>
  32 /*
  33  * For small address space machines, mapping large objects
  34  * into the kernel virtual space isn't practical. Where
  35  * available, use fixmap support to dynamically map pages
  36  * of the object at run time.
  37  */
  38 
  39 static inline struct io_mapping *
  40 io_mapping_init_wc(struct io_mapping *iomap,
  41                    resource_size_t base,
  42                    unsigned long size)
  43 {
  44         pgprot_t prot;
  45 
  46         if (iomap_create_wc(base, size, &prot))
  47                 return NULL;
  48 
  49         iomap->base = base;
  50         iomap->size = size;
  51         iomap->prot = prot;
  52         return iomap;
  53 }
  54 
  55 static inline void
  56 io_mapping_fini(struct io_mapping *mapping)
  57 {
  58         iomap_free(mapping->base, mapping->size);
  59 }
  60 
  61 /* Atomic map/unmap */
  62 static inline void __iomem *
  63 io_mapping_map_atomic_wc(struct io_mapping *mapping,
  64                          unsigned long offset)
  65 {
  66         resource_size_t phys_addr;
  67         unsigned long pfn;
  68 
  69         BUG_ON(offset >= mapping->size);
  70         phys_addr = mapping->base + offset;
  71         pfn = (unsigned long) (phys_addr >> PAGE_SHIFT);
  72         return iomap_atomic_prot_pfn(pfn, mapping->prot);
  73 }
  74 
  75 static inline void
  76 io_mapping_unmap_atomic(void __iomem *vaddr)
  77 {
  78         iounmap_atomic(vaddr);
  79 }
  80 
  81 static inline void __iomem *
  82 io_mapping_map_wc(struct io_mapping *mapping,
  83                   unsigned long offset,
  84                   unsigned long size)
  85 {
  86         resource_size_t phys_addr;
  87 
  88         BUG_ON(offset >= mapping->size);
  89         phys_addr = mapping->base + offset;
  90 
  91         return ioremap_wc(phys_addr, size);
  92 }
  93 
  94 static inline void
  95 io_mapping_unmap(void __iomem *vaddr)
  96 {
  97         iounmap(vaddr);
  98 }
  99 
 100 #else
 101 
 102 #include <linux/uaccess.h>
 103 #include <asm/pgtable.h>
 104 
 105 /* Create the io_mapping object*/
 106 static inline struct io_mapping *
 107 io_mapping_init_wc(struct io_mapping *iomap,
 108                    resource_size_t base,
 109                    unsigned long size)
 110 {
 111         iomap->base = base;
 112         iomap->size = size;
 113         iomap->iomem = ioremap_wc(base, size);
 114 #if defined(pgprot_noncached_wc) /* archs can't agree on a name ... */
 115         iomap->prot = pgprot_noncached_wc(PAGE_KERNEL);
 116 #elif defined(pgprot_writecombine)
 117         iomap->prot = pgprot_writecombine(PAGE_KERNEL);
 118 #else
 119         iomap->prot = pgprot_noncached(PAGE_KERNEL);
 120 #endif
 121 
 122         return iomap;
 123 }
 124 
 125 static inline void
 126 io_mapping_fini(struct io_mapping *mapping)
 127 {
 128         iounmap(mapping->iomem);
 129 }
 130 
 131 /* Non-atomic map/unmap */
 132 static inline void __iomem *
 133 io_mapping_map_wc(struct io_mapping *mapping,
 134                   unsigned long offset,
 135                   unsigned long size)
 136 {
 137         return mapping->iomem + offset;
 138 }
 139 
 140 static inline void
 141 io_mapping_unmap(void __iomem *vaddr)
 142 {
 143 }
 144 
 145 /* Atomic map/unmap */
 146 static inline void __iomem *
 147 io_mapping_map_atomic_wc(struct io_mapping *mapping,
 148                          unsigned long offset)
 149 {
 150         preempt_disable();
 151         pagefault_disable();
 152         return io_mapping_map_wc(mapping, offset, PAGE_SIZE);
 153 }
 154 
 155 static inline void
 156 io_mapping_unmap_atomic(void __iomem *vaddr)
 157 {
 158         io_mapping_unmap(vaddr);
 159         pagefault_enable();
 160         preempt_enable();
 161 }
 162 
 163 #endif /* HAVE_ATOMIC_IOMAP */
 164 
 165 static inline struct io_mapping *
 166 io_mapping_create_wc(resource_size_t base,
 167                      unsigned long size)
 168 {
 169         struct io_mapping *iomap;
 170 
 171         iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
 172         if (!iomap)
 173                 return NULL;
 174 
 175         if (!io_mapping_init_wc(iomap, base, size)) {
 176                 kfree(iomap);
 177                 return NULL;
 178         }
 179 
 180         return iomap;
 181 }
 182 
 183 static inline void
 184 io_mapping_free(struct io_mapping *iomap)
 185 {
 186         io_mapping_fini(iomap);
 187         kfree(iomap);
 188 }
 189 
 190 #endif /* _LINUX_IO_MAPPING_H */

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