Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright © 2008 Keith Packard <keithp@keithp.com>
  3.  *
  4.  * This file is free software; you can redistribute it and/or modify
  5.  * it under the terms of version 2 of the GNU General Public License
  6.  * as published by the Free Software Foundation.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software Foundation,
  15.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
  16.  */
  17.  
  18. #ifndef _LINUX_IO_MAPPING_H
  19. #define _LINUX_IO_MAPPING_H
  20.  
  21. #include <linux/types.h>
  22. #include <linux/slab.h>
  23. #include <linux/bug.h>
  24. #include <linux/io.h>
  25. #include <asm/page.h>
  26.  
  27. /*
  28.  * The io_mapping mechanism provides an abstraction for mapping
  29.  * individual pages from an io device to the CPU in an efficient fashion.
  30.  *
  31.  * See Documentation/io-mapping.txt
  32.  */
  33.  
  34. #ifdef CONFIG_HAVE_ATOMIC_IOMAP
  35.  
  36. #include <asm/iomap.h>
  37.  
  38. struct io_mapping {
  39.     void            *vaddr;
  40.         resource_size_t base;
  41.     unsigned long   size;
  42. };
  43.  
  44. /*
  45.  * For small address space machines, mapping large objects
  46.  * into the kernel virtual space isn't practical. Where
  47.  * available, use fixmap support to dynamically map pages
  48.  * of the object at run time.
  49.  */
  50.  
  51. static inline struct io_mapping *
  52. io_mapping_create_wc(resource_size_t base, unsigned long size)
  53. {
  54.         struct io_mapping *iomap;
  55.  
  56.         iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
  57.         if (!iomap)
  58.                 goto out_err;
  59.  
  60.     iomap->vaddr = AllocKernelSpace(4096);
  61.     if (iomap->vaddr == NULL)
  62.                 goto out_free;
  63.  
  64.         iomap->base = base;
  65.         iomap->size = size;
  66.  
  67.         return iomap;
  68.  
  69. out_free:
  70.         kfree(iomap);
  71. out_err:
  72.         return NULL;
  73. }
  74.  
  75. static inline void
  76. io_mapping_free(struct io_mapping *mapping)
  77. {
  78.     FreeKernelSpace(mapping->vaddr);
  79.         kfree(mapping);
  80. }
  81.  
  82. /* Atomic map/unmap */
  83. static inline void __iomem *
  84. io_mapping_map_atomic_wc(struct io_mapping *mapping,
  85.                          unsigned long offset)
  86. {
  87.     addr_t phys_addr;
  88.  
  89.         BUG_ON(offset >= mapping->size);
  90.     phys_addr = (mapping->base + offset) & PAGE_MASK;
  91.  
  92.     MapPage(mapping->vaddr, phys_addr, PG_WRITEC|PG_SW);
  93.     return mapping->vaddr;
  94. }
  95.  
  96. static inline void
  97. io_mapping_unmap_atomic(void __iomem *vaddr)
  98. {
  99.     MapPage(vaddr, 0, 0);
  100. }
  101.  
  102. static inline void __iomem *
  103. io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
  104. {
  105.     addr_t phys_addr;
  106.  
  107.         BUG_ON(offset >= mapping->size);
  108.     phys_addr = (mapping->base + offset) & PAGE_MASK;
  109.  
  110.     MapPage(mapping->vaddr, phys_addr, PG_WRITEC|PG_SW);
  111.     return mapping->vaddr;
  112. }
  113.  
  114. static inline void
  115. io_mapping_unmap(void __iomem *vaddr)
  116. {
  117.     MapPage(vaddr, 0, 0);
  118. }
  119.  
  120. #else
  121.  
  122. #include <linux/uaccess.h>
  123.  
  124. /* this struct isn't actually defined anywhere */
  125. struct io_mapping;
  126.  
  127. /* Create the io_mapping object*/
  128. static inline struct io_mapping *
  129. io_mapping_create_wc(resource_size_t base, unsigned long size)
  130. {
  131.         return (struct io_mapping __force *) ioremap_wc(base, size);
  132. }
  133.  
  134. static inline void
  135. io_mapping_free(struct io_mapping *mapping)
  136. {
  137.         iounmap((void __force __iomem *) mapping);
  138. }
  139.  
  140. /* Atomic map/unmap */
  141. static inline void __iomem *
  142. io_mapping_map_atomic_wc(struct io_mapping *mapping,
  143.                          unsigned long offset)
  144. {
  145.         preempt_disable();
  146.         pagefault_disable();
  147.         return ((char __force __iomem *) mapping) + offset;
  148. }
  149.  
  150. static inline void
  151. io_mapping_unmap_atomic(void __iomem *vaddr)
  152. {
  153.         pagefault_enable();
  154.         preempt_enable();
  155. }
  156.  
  157. /* Non-atomic map/unmap */
  158. static inline void __iomem *
  159. io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
  160. {
  161.         return ((char __force __iomem *) mapping) + offset;
  162. }
  163.  
  164. static inline void
  165. io_mapping_unmap(void __iomem *vaddr)
  166. {
  167. }
  168.  
  169. #endif /* HAVE_ATOMIC_IOMAP */
  170.  
  171. #endif /* _LINUX_IO_MAPPING_H */
  172.