blob: a291f59659cf10f6c6f7ec8306c75f3470eda19e [file] [log] [blame]
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -07001/*
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
Haavard Skinnemoen5a4d5292008-01-14 23:33:44 +010011#include <linux/quicklist.h>
12#include <asm/page.h>
13#include <asm/pgtable.h>
14
15#define QUICK_PGD 0 /* Preserve kernel mappings over free */
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070016
Haavard Skinnemoencfd23e92008-01-14 22:15:05 +010017static inline void pmd_populate_kernel(struct mm_struct *mm,
18 pmd_t *pmd, pte_t *pte)
19{
20 set_pmd(pmd, __pmd((unsigned long)pte));
21}
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070022
Haavard Skinnemoencfd23e92008-01-14 22:15:05 +010023static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
Martin Schwidefsky2f569af2008-02-08 04:22:04 -080024 pgtable_t pte)
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070025{
Haavard Skinnemoencfd23e92008-01-14 22:15:05 +010026 set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070027}
Martin Schwidefsky2f569af2008-02-08 04:22:04 -080028#define pmd_pgtable(pmd) pmd_page(pmd)
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070029
Haavard Skinnemoen5a4d5292008-01-14 23:33:44 +010030static inline void pgd_ctor(void *x)
31{
32 pgd_t *pgd = x;
33
34 memcpy(pgd + USER_PTRS_PER_PGD,
35 swapper_pg_dir + USER_PTRS_PER_PGD,
36 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
37}
38
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070039/*
40 * Allocate and free page tables
41 */
Haavard Skinnemoencfd23e92008-01-14 22:15:05 +010042static inline pgd_t *pgd_alloc(struct mm_struct *mm)
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070043{
Haavard Skinnemoen5a4d5292008-01-14 23:33:44 +010044 return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor);
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070045}
46
Benjamin Herrenschmidt5e541972008-02-04 22:29:14 -080047static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070048{
Haavard Skinnemoen5a4d5292008-01-14 23:33:44 +010049 quicklist_free(QUICK_PGD, NULL, pgd);
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070050}
51
52static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
53 unsigned long address)
54{
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070055 pte_t *pte;
56
Haavard Skinnemoene7f3bac2007-08-03 13:29:01 +020057 pte = (pte_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070058
59 return pte;
60}
61
62static inline struct page *pte_alloc_one(struct mm_struct *mm,
63 unsigned long address)
64{
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070065 struct page *pte;
66
Haavard Skinnemoene7f3bac2007-08-03 13:29:01 +020067 pte = alloc_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
Martin Schwidefsky2f569af2008-02-08 04:22:04 -080068 if (!pte)
69 return NULL;
70 pgtable_page_ctor(pte);
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070071 return pte;
72}
73
Benjamin Herrenschmidt5e541972008-02-04 22:29:14 -080074static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070075{
76 free_page((unsigned long)pte);
77}
78
Martin Schwidefsky2f569af2008-02-08 04:22:04 -080079static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070080{
Martin Schwidefsky2f569af2008-02-08 04:22:04 -080081 pgtable_page_dtor(pte);
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070082 __free_page(pte);
83}
84
Martin Schwidefsky2f569af2008-02-08 04:22:04 -080085#define __pte_free_tlb(tlb,pte) \
86do { \
87 pgtable_page_dtor(pte); \
88 tlb_remove_page((tlb), pte); \
89} while (0)
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070090
Haavard Skinnemoen5a4d5292008-01-14 23:33:44 +010091static inline void check_pgt_cache(void)
92{
93 quicklist_trim(QUICK_PGD, NULL, 25, 16);
94}
Haavard Skinnemoen5f97f7f2006-09-25 23:32:13 -070095
96#endif /* __ASM_AVR32_PGALLOC_H */