1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#ifndef __ASM_AVR32_PGALLOC_H
9#define __ASM_AVR32_PGALLOC_H
10
11#include <asm/processor.h>
12#include <linux/threads.h>
13#include <linux/slab.h>
14#include <linux/mm.h>
15
16#define pmd_populate_kernel(mm, pmd, pte) \
17	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
18
19static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
20				    struct page *pte)
21{
22	set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte)));
23}
24
25/*
26 * Allocate and free page tables
27 */
28static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
29{
30	unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
31	pgd_t *pgd = kmalloc(pgd_size, GFP_KERNEL);
32
33	if (pgd)
34		memset(pgd, 0, pgd_size);
35
36	return pgd;
37}
38
39static inline void pgd_free(pgd_t *pgd)
40{
41	kfree(pgd);
42}
43
44static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
45					  unsigned long address)
46{
47	int count = 0;
48	pte_t *pte;
49
50	do {
51		pte = (pte_t *) __get_free_page(GFP_KERNEL | __GFP_REPEAT);
52		if (pte)
53			clear_page(pte);
54		else {
55			current->state = TASK_UNINTERRUPTIBLE;
56			schedule_timeout(HZ);
57		}
58	} while (!pte && (count++ < 10));
59
60	return pte;
61}
62
63static inline struct page *pte_alloc_one(struct mm_struct *mm,
64					 unsigned long address)
65{
66	int count = 0;
67	struct page *pte;
68
69	do {
70		pte = alloc_pages(GFP_KERNEL, 0);
71		if (pte)
72			clear_page(page_address(pte));
73		else {
74			current->state = TASK_UNINTERRUPTIBLE;
75			schedule_timeout(HZ);
76		}
77	} while (!pte && (count++ < 10));
78
79	return pte;
80}
81
82static inline void pte_free_kernel(pte_t *pte)
83{
84	free_page((unsigned long)pte);
85}
86
87static inline void pte_free(struct page *pte)
88{
89	__free_page(pte);
90}
91
92#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
93
94#define check_pgt_cache() do { } while(0)
95
96#endif /* __ASM_AVR32_PGALLOC_H */
97