18c2ecf20Sopenharmony_ci========================
28c2ecf20Sopenharmony_ciThe io_mapping functions
38c2ecf20Sopenharmony_ci========================
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ciAPI
68c2ecf20Sopenharmony_ci===
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ciThe io_mapping functions in linux/io-mapping.h provide an abstraction for
98c2ecf20Sopenharmony_ciefficiently mapping small regions of an I/O device to the CPU. The initial
108c2ecf20Sopenharmony_ciusage is to support the large graphics aperture on 32-bit processors where
118c2ecf20Sopenharmony_ciioremap_wc cannot be used to statically map the entire aperture to the CPU
128c2ecf20Sopenharmony_cias it would consume too much of the kernel address space.
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ciA mapping object is created during driver initialization using::
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci	struct io_mapping *io_mapping_create_wc(unsigned long base,
178c2ecf20Sopenharmony_ci						unsigned long size)
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci'base' is the bus address of the region to be made
208c2ecf20Sopenharmony_cimappable, while 'size' indicates how large a mapping region to
218c2ecf20Sopenharmony_cienable. Both are in bytes.
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciThis _wc variant provides a mapping which may only be used
248c2ecf20Sopenharmony_ciwith the io_mapping_map_atomic_wc or io_mapping_map_wc.
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ciWith this mapping object, individual pages can be mapped either atomically
278c2ecf20Sopenharmony_cior not, depending on the necessary scheduling environment. Of course, atomic
288c2ecf20Sopenharmony_cimaps are more efficient::
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	void *io_mapping_map_atomic_wc(struct io_mapping *mapping,
318c2ecf20Sopenharmony_ci				       unsigned long offset)
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci'offset' is the offset within the defined mapping region.
348c2ecf20Sopenharmony_ciAccessing addresses beyond the region specified in the
358c2ecf20Sopenharmony_cicreation function yields undefined results. Using an offset
368c2ecf20Sopenharmony_ciwhich is not page aligned yields an undefined result. The
378c2ecf20Sopenharmony_cireturn value points to a single page in CPU address space.
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ciThis _wc variant returns a write-combining map to the
408c2ecf20Sopenharmony_cipage and may only be used with mappings created by
418c2ecf20Sopenharmony_ciio_mapping_create_wc
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciNote that the task may not sleep while holding this page
448c2ecf20Sopenharmony_cimapped.
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci::
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	void io_mapping_unmap_atomic(void *vaddr)
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci'vaddr' must be the value returned by the last
518c2ecf20Sopenharmony_ciio_mapping_map_atomic_wc call. This unmaps the specified
528c2ecf20Sopenharmony_cipage and allows the task to sleep once again.
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ciIf you need to sleep while holding the lock, you can use the non-atomic
558c2ecf20Sopenharmony_civariant, although they may be significantly slower.
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci::
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	void *io_mapping_map_wc(struct io_mapping *mapping,
608c2ecf20Sopenharmony_ci				unsigned long offset)
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ciThis works like io_mapping_map_atomic_wc except it allows
638c2ecf20Sopenharmony_cithe task to sleep while holding the page mapped.
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci::
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	void io_mapping_unmap(void *vaddr)
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ciThis works like io_mapping_unmap_atomic, except it is used
718c2ecf20Sopenharmony_cifor pages mapped with io_mapping_map_wc.
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ciAt driver close time, the io_mapping object must be freed::
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	void io_mapping_free(struct io_mapping *mapping)
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ciCurrent Implementation
788c2ecf20Sopenharmony_ci======================
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ciThe initial implementation of these functions uses existing mapping
818c2ecf20Sopenharmony_cimechanisms and so provides only an abstraction layer and no new
828c2ecf20Sopenharmony_cifunctionality.
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ciOn 64-bit processors, io_mapping_create_wc calls ioremap_wc for the whole
858c2ecf20Sopenharmony_cirange, creating a permanent kernel-visible mapping to the resource. The
868c2ecf20Sopenharmony_cimap_atomic and map functions add the requested offset to the base of the
878c2ecf20Sopenharmony_civirtual address returned by ioremap_wc.
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ciOn 32-bit processors with HIGHMEM defined, io_mapping_map_atomic_wc uses
908c2ecf20Sopenharmony_cikmap_atomic_pfn to map the specified page in an atomic fashion;
918c2ecf20Sopenharmony_cikmap_atomic_pfn isn't really supposed to be used with device pages, but it
928c2ecf20Sopenharmony_ciprovides an efficient mapping for this usage.
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ciOn 32-bit processors without HIGHMEM defined, io_mapping_map_atomic_wc and
958c2ecf20Sopenharmony_ciio_mapping_map_wc both use ioremap_wc, a terribly inefficient function which
968c2ecf20Sopenharmony_ciperforms an IPI to inform all processors about the new mapping. This results
978c2ecf20Sopenharmony_ciin a significant performance penalty.
98