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 <linux/quicklist.h> 12#include <asm/page.h> 13#include <asm/pgtable.h> 14 15#define QUICK_PGD 0 /* Preserve kernel mappings over free */ 16#define QUICK_PT 1 /* Zero on free */ 17 18static inline void pmd_populate_kernel(struct mm_struct *mm, 19 pmd_t *pmd, pte_t *pte) 20{ 21 set_pmd(pmd, __pmd((unsigned long)pte)); 22} 23 24static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 25 pgtable_t pte) 26{ 27 set_pmd(pmd, __pmd((unsigned long)page_address(pte))); 28} 29#define pmd_pgtable(pmd) pmd_page(pmd) 30 31static inline void pgd_ctor(void *x) 32{ 33 pgd_t *pgd = x; 34 35 memcpy(pgd + USER_PTRS_PER_PGD, 36 swapper_pg_dir + USER_PTRS_PER_PGD, 37 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 38} 39 40/* 41 * Allocate and free page tables 42 */ 43static inline pgd_t *pgd_alloc(struct mm_struct *mm) 44{ 45 return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor); 46} 47 48static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 49{ 50 quicklist_free(QUICK_PGD, NULL, pgd); 51} 52 53static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 54 unsigned long address) 55{ 56 return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); 57} 58 59static inline pgtable_t pte_alloc_one(struct mm_struct *mm, 60 unsigned long address) 61{ 62 struct page *page; 63 void *pg; 64 65 pg = quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); 66 if (!pg) 67 return NULL; 68 69 page = virt_to_page(pg); 70 pgtable_page_ctor(page); 71 72 return page; 73} 74 75static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 76{ 77 quicklist_free(QUICK_PT, NULL, pte); 78} 79 80static inline void pte_free(struct mm_struct *mm, pgtable_t pte) 81{ 82 pgtable_page_dtor(pte); 83 quicklist_free_page(QUICK_PT, NULL, pte); 84} 85 86#define __pte_free_tlb(tlb,pte,addr) \ 87do { \ 88 pgtable_page_dtor(pte); \ 89 tlb_remove_page((tlb), pte); \ 90} while (0) 91 92static inline void check_pgt_cache(void) 93{ 94 quicklist_trim(QUICK_PGD, NULL, 25, 16); 95 quicklist_trim(QUICK_PT, NULL, 25, 16); 96} 97 98#endif /* __ASM_AVR32_PGALLOC_H */ 99