aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/xtensa/include/asm/highmem.h40
-rw-r--r--arch/xtensa/mm/highmem.c18
2 files changed, 56 insertions, 2 deletions
diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h
index 2653ef5d55f1..2c7901edffaf 100644
--- a/arch/xtensa/include/asm/highmem.h
+++ b/arch/xtensa/include/asm/highmem.h
@@ -12,19 +12,55 @@
12#ifndef _XTENSA_HIGHMEM_H 12#ifndef _XTENSA_HIGHMEM_H
13#define _XTENSA_HIGHMEM_H 13#define _XTENSA_HIGHMEM_H
14 14
15#include <linux/wait.h>
15#include <asm/cacheflush.h> 16#include <asm/cacheflush.h>
16#include <asm/fixmap.h> 17#include <asm/fixmap.h>
17#include <asm/kmap_types.h> 18#include <asm/kmap_types.h>
18#include <asm/pgtable.h> 19#include <asm/pgtable.h>
19 20
20#define PKMAP_BASE (FIXADDR_START - PMD_SIZE) 21#define PKMAP_BASE ((FIXADDR_START - \
21#define LAST_PKMAP PTRS_PER_PTE 22 (LAST_PKMAP + 1) * PAGE_SIZE) & PMD_MASK)
23#define LAST_PKMAP (PTRS_PER_PTE * DCACHE_N_COLORS)
22#define LAST_PKMAP_MASK (LAST_PKMAP - 1) 24#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
23#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) 25#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
24#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) 26#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
25 27
26#define kmap_prot PAGE_KERNEL 28#define kmap_prot PAGE_KERNEL
27 29
30#if DCACHE_WAY_SIZE > PAGE_SIZE
31#define get_pkmap_color get_pkmap_color
32static inline int get_pkmap_color(struct page *page)
33{
34 return DCACHE_ALIAS(page_to_phys(page));
35}
36
37extern unsigned int last_pkmap_nr_arr[];
38
39static inline unsigned int get_next_pkmap_nr(unsigned int color)
40{
41 last_pkmap_nr_arr[color] =
42 (last_pkmap_nr_arr[color] + DCACHE_N_COLORS) & LAST_PKMAP_MASK;
43 return last_pkmap_nr_arr[color] + color;
44}
45
46static inline int no_more_pkmaps(unsigned int pkmap_nr, unsigned int color)
47{
48 return pkmap_nr < DCACHE_N_COLORS;
49}
50
51static inline int get_pkmap_entries_count(unsigned int color)
52{
53 return LAST_PKMAP / DCACHE_N_COLORS;
54}
55
56extern wait_queue_head_t pkmap_map_wait_arr[];
57
58static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color)
59{
60 return pkmap_map_wait_arr + color;
61}
62#endif
63
28extern pte_t *pkmap_page_table; 64extern pte_t *pkmap_page_table;
29 65
30void *kmap_high(struct page *page); 66void *kmap_high(struct page *page);
diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c
index 466abaed5382..8cfb71ec0937 100644
--- a/arch/xtensa/mm/highmem.c
+++ b/arch/xtensa/mm/highmem.c
@@ -14,6 +14,23 @@
14 14
15static pte_t *kmap_pte; 15static pte_t *kmap_pte;
16 16
17#if DCACHE_WAY_SIZE > PAGE_SIZE
18unsigned int last_pkmap_nr_arr[DCACHE_N_COLORS];
19wait_queue_head_t pkmap_map_wait_arr[DCACHE_N_COLORS];
20
21static void __init kmap_waitqueues_init(void)
22{
23 unsigned int i;
24
25 for (i = 0; i < ARRAY_SIZE(pkmap_map_wait_arr); ++i)
26 init_waitqueue_head(pkmap_map_wait_arr + i);
27}
28#else
29static inline void kmap_waitqueues_init(void)
30{
31}
32#endif
33
17static inline enum fixed_addresses kmap_idx(int type, unsigned long color) 34static inline enum fixed_addresses kmap_idx(int type, unsigned long color)
18{ 35{
19 return (type + KM_TYPE_NR * smp_processor_id()) * DCACHE_N_COLORS + 36 return (type + KM_TYPE_NR * smp_processor_id()) * DCACHE_N_COLORS +
@@ -72,4 +89,5 @@ void __init kmap_init(void)
72 /* cache the first kmap pte */ 89 /* cache the first kmap pte */
73 kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); 90 kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
74 kmap_pte = kmap_get_fixmap_pte(kmap_vstart); 91 kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
92 kmap_waitqueues_init();
75} 93}