1fcd68072SPragat Pandya======================== 2fcd68072SPragat PandyaThe io_mapping functions 3fcd68072SPragat Pandya======================== 4fcd68072SPragat Pandya 5fcd68072SPragat PandyaAPI 6fcd68072SPragat Pandya=== 7fcd68072SPragat Pandya 8fcd68072SPragat PandyaThe io_mapping functions in linux/io-mapping.h provide an abstraction for 9fcd68072SPragat Pandyaefficiently mapping small regions of an I/O device to the CPU. The initial 10fcd68072SPragat Pandyausage is to support the large graphics aperture on 32-bit processors where 11fcd68072SPragat Pandyaioremap_wc cannot be used to statically map the entire aperture to the CPU 12fcd68072SPragat Pandyaas it would consume too much of the kernel address space. 13fcd68072SPragat Pandya 14fcd68072SPragat PandyaA mapping object is created during driver initialization using:: 15fcd68072SPragat Pandya 16fcd68072SPragat Pandya struct io_mapping *io_mapping_create_wc(unsigned long base, 17fcd68072SPragat Pandya unsigned long size) 18fcd68072SPragat Pandya 19fcd68072SPragat Pandya'base' is the bus address of the region to be made 20fcd68072SPragat Pandyamappable, while 'size' indicates how large a mapping region to 21fcd68072SPragat Pandyaenable. Both are in bytes. 22fcd68072SPragat Pandya 23e66f6e09SThomas GleixnerThis _wc variant provides a mapping which may only be used with 24e66f6e09SThomas Gleixnerio_mapping_map_atomic_wc(), io_mapping_map_local_wc() or 25e66f6e09SThomas Gleixnerio_mapping_map_wc(). 26fcd68072SPragat Pandya 27e66f6e09SThomas GleixnerWith this mapping object, individual pages can be mapped either temporarily 28e66f6e09SThomas Gleixneror long term, depending on the requirements. Of course, temporary maps are 29e66f6e09SThomas Gleixnermore efficient. They come in two flavours:: 30e66f6e09SThomas Gleixner 31e66f6e09SThomas Gleixner void *io_mapping_map_local_wc(struct io_mapping *mapping, 32e66f6e09SThomas Gleixner unsigned long offset) 33fcd68072SPragat Pandya 34fcd68072SPragat Pandya void *io_mapping_map_atomic_wc(struct io_mapping *mapping, 35fcd68072SPragat Pandya unsigned long offset) 36fcd68072SPragat Pandya 37e66f6e09SThomas Gleixner'offset' is the offset within the defined mapping region. Accessing 38e66f6e09SThomas Gleixneraddresses beyond the region specified in the creation function yields 39e66f6e09SThomas Gleixnerundefined results. Using an offset which is not page aligned yields an 40e66f6e09SThomas Gleixnerundefined result. The return value points to a single page in CPU address 41e66f6e09SThomas Gleixnerspace. 42fcd68072SPragat Pandya 43e66f6e09SThomas GleixnerThis _wc variant returns a write-combining map to the page and may only be 44e66f6e09SThomas Gleixnerused with mappings created by io_mapping_create_wc() 45fcd68072SPragat Pandya 46e66f6e09SThomas GleixnerTemporary mappings are only valid in the context of the caller. The mapping 47*7852fe3aSRandy Dunlapis not guaranteed to be globally visible. 48fcd68072SPragat Pandya 49e66f6e09SThomas Gleixnerio_mapping_map_local_wc() has a side effect on X86 32bit as it disables 50e66f6e09SThomas Gleixnermigration to make the mapping code work. No caller can rely on this side 51e66f6e09SThomas Gleixnereffect. 52fcd68072SPragat Pandya 53e66f6e09SThomas Gleixnerio_mapping_map_atomic_wc() has the side effect of disabling preemption and 54e66f6e09SThomas Gleixnerpagefaults. Don't use in new code. Use io_mapping_map_local_wc() instead. 55e66f6e09SThomas Gleixner 56e66f6e09SThomas GleixnerNested mappings need to be undone in reverse order because the mapping 57e66f6e09SThomas Gleixnercode uses a stack for keeping track of them:: 58e66f6e09SThomas Gleixner 59e66f6e09SThomas Gleixner addr1 = io_mapping_map_local_wc(map1, offset1); 60e66f6e09SThomas Gleixner addr2 = io_mapping_map_local_wc(map2, offset2); 61e66f6e09SThomas Gleixner ... 62e66f6e09SThomas Gleixner io_mapping_unmap_local(addr2); 63e66f6e09SThomas Gleixner io_mapping_unmap_local(addr1); 64e66f6e09SThomas Gleixner 65e66f6e09SThomas GleixnerThe mappings are released with:: 66e66f6e09SThomas Gleixner 67e66f6e09SThomas Gleixner void io_mapping_unmap_local(void *vaddr) 68fcd68072SPragat Pandya void io_mapping_unmap_atomic(void *vaddr) 69fcd68072SPragat Pandya 70e66f6e09SThomas Gleixner'vaddr' must be the value returned by the last io_mapping_map_local_wc() or 71e66f6e09SThomas Gleixnerio_mapping_map_atomic_wc() call. This unmaps the specified mapping and 72e66f6e09SThomas Gleixnerundoes the side effects of the mapping functions. 73fcd68072SPragat Pandya 74e66f6e09SThomas GleixnerIf you need to sleep while holding a mapping, you can use the regular 75e66f6e09SThomas Gleixnervariant, although this may be significantly slower:: 76fcd68072SPragat Pandya 77fcd68072SPragat Pandya void *io_mapping_map_wc(struct io_mapping *mapping, 78fcd68072SPragat Pandya unsigned long offset) 79fcd68072SPragat Pandya 80e66f6e09SThomas GleixnerThis works like io_mapping_map_atomic/local_wc() except it has no side 81*7852fe3aSRandy Dunlapeffects and the pointer is globally visible. 82fcd68072SPragat Pandya 83e66f6e09SThomas GleixnerThe mappings are released with:: 84fcd68072SPragat Pandya 85fcd68072SPragat Pandya void io_mapping_unmap(void *vaddr) 86fcd68072SPragat Pandya 87e66f6e09SThomas GleixnerUse for pages mapped with io_mapping_map_wc(). 88fcd68072SPragat Pandya 89fcd68072SPragat PandyaAt driver close time, the io_mapping object must be freed:: 90fcd68072SPragat Pandya 91fcd68072SPragat Pandya void io_mapping_free(struct io_mapping *mapping) 92