2008-09-15 16:44:55 -04:00
# ifndef _ASM_HIGHMEM_H
# define _ASM_HIGHMEM_H
# include <asm/kmap_types.h>
# define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE)
# define LAST_PKMAP PTRS_PER_PTE
# define LAST_PKMAP_MASK (LAST_PKMAP - 1)
# define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
# define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
# define kmap_prot PAGE_KERNEL
2010-03-29 21:46:02 +01:00
# define flush_cache_kmaps() \
do { \
if ( cache_is_vivt ( ) ) \
flush_cache_all ( ) ; \
} while ( 0 )
2008-09-15 16:44:55 -04:00
extern pte_t * pkmap_page_table ;
2011-01-25 21:35:38 +01:00
extern void * kmap_high ( struct page * page ) ;
extern void kunmap_high ( struct page * page ) ;
/*
* The reason for kmap_high_get ( ) is to ensure that the currently kmap ' d
* page usage count does not decrease to zero while we ' re using its
* existing virtual mapping in an atomic context . With a VIVT cache this
* is essential to do , but with a VIPT cache this is only an optimization
* so not to pay the price of establishing a second mapping if an existing
* one can be used . However , on platforms without hardware TLB maintenance
* broadcast , we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since
* the locking involved must also disable IRQs which is incompatible with
* the IPI mechanism used by global TLB operations .
*/
2009-03-12 22:52:09 -04:00
# define ARCH_NEEDS_KMAP_HIGH_GET
2011-01-25 21:35:38 +01:00
# if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6)
# undef ARCH_NEEDS_KMAP_HIGH_GET
# if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT)
# error "The sum of features in your kernel config cannot be supported together"
# endif
# endif
2009-03-12 22:52:09 -04:00
2013-03-26 23:35:04 +01:00
/*
* Needed to be able to broadcast the TLB invalidation for kmap .
*/
# ifdef CONFIG_ARM_ERRATA_798181
# undef ARCH_NEEDS_KMAP_HIGH_GET
# endif
2011-01-25 21:35:38 +01:00
# ifdef ARCH_NEEDS_KMAP_HIGH_GET
2009-03-12 22:52:09 -04:00
extern void * kmap_high_get ( struct page * page ) ;
2011-01-25 21:35:38 +01:00
# else
static inline void * kmap_high_get ( struct page * page )
{
return NULL ;
}
# endif
2008-09-15 16:44:55 -04:00
2010-03-29 21:46:02 +01:00
/*
* The following functions are already defined by < linux / highmem . h >
* when CONFIG_HIGHMEM is not set .
*/
# ifdef CONFIG_HIGHMEM
2008-09-15 16:44:55 -04:00
extern void * kmap ( struct page * page ) ;
extern void kunmap ( struct page * page ) ;
2011-11-26 10:53:39 +08:00
extern void * kmap_atomic ( struct page * page ) ;
2010-10-26 14:21:51 -07:00
extern void __kunmap_atomic ( void * kvaddr ) ;
extern void * kmap_atomic_pfn ( unsigned long pfn ) ;
2008-09-15 16:44:55 -04:00
extern struct page * kmap_atomic_to_page ( const void * ptr ) ;
2010-03-29 21:46:02 +01:00
# endif
2008-09-15 16:44:55 -04:00
# endif