1/* 2 * include/asm-xtensa/pgalloc.h 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 * Copyright (C) 2001-2007 Tensilica Inc. 9 */ 10 11#ifndef _XTENSA_PGALLOC_H 12#define _XTENSA_PGALLOC_H 13 14#ifdef __KERNEL__ 15 16#include <linux/highmem.h> 17#include <linux/slab.h> 18 19/* 20 * Allocating and freeing a pmd is trivial: the 1-entry pmd is 21 * inside the pgd, so has no extra memory associated with it. 22 */ 23 24#define pmd_populate_kernel(mm, pmdp, ptep) \ 25 (pmd_val(*(pmdp)) = ((unsigned long)ptep)) 26#define pmd_populate(mm, pmdp, page) \ 27 (pmd_val(*(pmdp)) = ((unsigned long)page_to_virt(page))) 28#define pmd_pgtable(pmd) pmd_page(pmd) 29 30static inline pgd_t* 31pgd_alloc(struct mm_struct *mm) 32{ 33 return (pgd_t*) __get_free_pages(GFP_KERNEL | __GFP_ZERO, PGD_ORDER); 34} 35 36static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 37{ 38 free_page((unsigned long)pgd); 39} 40 41static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 42 unsigned long address) 43{ 44 pte_t *ptep; 45 int i; 46 47 ptep = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); 48 if (!ptep) 49 return NULL; 50 for (i = 0; i < 1024; i++) 51 pte_clear(NULL, 0, ptep + i); 52 return ptep; 53} 54 55static inline pgtable_t pte_alloc_one(struct mm_struct *mm, 56 unsigned long addr) 57{ 58 pte_t *pte; 59 struct page *page; 60 61 pte = pte_alloc_one_kernel(mm, addr); 62 if (!pte) 63 return NULL; 64 page = virt_to_page(pte); 65 if (!pgtable_page_ctor(page)) { 66 __free_page(page); 67 return NULL; 68 } 69 return page; 70} 71 72static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 73{ 74 free_page((unsigned long)pte); 75} 76 77static inline void pte_free(struct mm_struct *mm, pgtable_t pte) 78{ 79 pgtable_page_dtor(pte); 80 __free_page(pte); 81} 82#define pmd_pgtable(pmd) pmd_page(pmd) 83 84#endif /* __KERNEL__ */ 85#endif /* _XTENSA_PGALLOC_H */ 86