From 8152a74bc087ffd03e024eaaf5a853ecf62d376d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 29 Dec 2009 11:09:30 +0900 Subject: sh: Only provide a PCLK definition for legacy CPG CPUs. As CPUs are migrated over to more fully-featured clock frameworks of their own and off of the legacy CPG code, they no longer have any real need for defining the PCLK value. The PCLK define in itself is already fairly misleading, as many boards get their input clocks from different sources, making this value fairly arbitrary anyways. Outside of the legacy CPG clock framework, the only place where this value is used is for deriving CLOCK_TICK_RATE, which we set back to the legacy PIT value that it was before the PCLK definitions were added in the first place. Signed-off-by: Paul Mundt --- arch/sh/include/asm/timex.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch/sh/include') diff --git a/arch/sh/include/asm/timex.h b/arch/sh/include/asm/timex.h index b556d49e5f2..18bf06d9c76 100644 --- a/arch/sh/include/asm/timex.h +++ b/arch/sh/include/asm/timex.h @@ -6,7 +6,17 @@ #ifndef __ASM_SH_TIMEX_H #define __ASM_SH_TIMEX_H +/* + * Only parts using the legacy CPG code for their clock framework + * implementation need to define their own Pclk value. If provided, this + * can be used for accurately setting CLOCK_TICK_RATE, otherwise we + * simply fall back on the i8253 PIT value. + */ +#ifdef CONFIG_SH_PCLK_FREQ #define CLOCK_TICK_RATE (CONFIG_SH_PCLK_FREQ / 4) /* Underlying HZ */ +#else +#define CLOCK_TICK_RATE 1193180 +#endif #include -- cgit v1.2.3-70-g09d2 From e591a517230a97e93f5edd19e7bef7ec8d22ac2b Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 13 Dec 2009 22:18:09 +0000 Subject: sh: Remove unused functions Apply some TLC to the SH64 header files and remove some functions that are not used anymore. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgtable_64.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'arch/sh/include') diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h index 17cdbecc3ad..dd381588c69 100644 --- a/arch/sh/include/asm/pgtable_64.h +++ b/arch/sh/include/asm/pgtable_64.h @@ -43,11 +43,6 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval) } #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) -static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep) -{ - pmd_val(*pmdp) = (unsigned long) ptep; -} - /* * PGD defines. Top level. */ @@ -202,12 +197,6 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep) #define pgprot_noncached(x) __pgprot(((x).pgprot & ~(_PAGE_CACHABLE)) | _PAGE_DEVICE) #define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE) -/* - * Handling allocation failures during page table setup. - */ -extern void __handle_bad_pmd_kernel(pmd_t * pmd); -#define __handle_bad_pmd(x) __handle_bad_pmd_kernel(x) - /* * PTE level access routines. * -- cgit v1.2.3-70-g09d2 From 3f5ab768164df9a44721660b96e0accb92eb2c24 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 24 Dec 2009 20:38:45 +0000 Subject: sh: Correct the PTRS_PER_PMD and PMD_SHIFT values The previous expressions were wrong which made free_pmd_range() explode when using anything other than 4KB pages (which is why 8KB and 64KB pages were disabled with the 3-level page table layout). The problem was that pmd_offset() was returning an index of non-zero when it should have been returning 0. This non-zero offset was used to calculate the address of the pmd table to free in free_pmd_range(), which ended up trying to free an object that was not aligned on a page boundary. Now 3-level page tables should work with 4KB, 8KB and 64KB pages. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgtable_pmd.h | 4 ++-- arch/sh/mm/Kconfig | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/sh/include') diff --git a/arch/sh/include/asm/pgtable_pmd.h b/arch/sh/include/asm/pgtable_pmd.h index 78dc36e1c2d..42a180e534a 100644 --- a/arch/sh/include/asm/pgtable_pmd.h +++ b/arch/sh/include/asm/pgtable_pmd.h @@ -17,11 +17,11 @@ #define USER_PTRS_PER_PGD 2 /* PMD bits */ -#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3)) +#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTE_MAGNITUDE)) #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -#define PTRS_PER_PMD (PAGE_SIZE / sizeof(pmd_t)) +#define PTRS_PER_PMD ((1 << PGDIR_SHIFT) / PMD_SIZE) #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e)) diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index b3f6c1a30b2..1b436487189 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -220,7 +220,7 @@ config PAGE_SIZE_4KB config PAGE_SIZE_8KB bool "8kB" - depends on !MMU || X2TLB && !PGTABLE_LEVELS_3 + depends on !MMU || X2TLB help This enables 8kB pages as supported by SH-X2 and later MMUs. @@ -232,7 +232,7 @@ config PAGE_SIZE_16KB config PAGE_SIZE_64KB bool "64kB" - depends on !MMU || CPU_SH4 && !PGTABLE_LEVELS_3 || CPU_SH5 + depends on !MMU || CPU_SH4 || CPU_SH5 help This enables support for 64kB pages, possible on all SH-4 CPUs and later. -- cgit v1.2.3-70-g09d2 From 2a5eacca85d39d8b6dffae821d7d260f05584dc7 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 31 Dec 2009 12:19:24 +0000 Subject: sh: Move page table allocation out of line We also switched away from quicklists and instead moved to slab caches. After benchmarking both implementations the difference is negligible. The slab caches suit us better though because the size of a pgd table is just 4 entries when we're using a 3-level page table layout and quicklists always deal with pages. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgalloc.h | 10 ++++--- arch/sh/include/asm/pgalloc_nopmd.h | 30 ------------------- arch/sh/include/asm/pgalloc_pmd.h | 41 -------------------------- arch/sh/include/asm/pgtable.h | 4 +-- arch/sh/mm/Makefile | 2 +- arch/sh/mm/pgtable.c | 57 +++++++++++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 78 deletions(-) delete mode 100644 arch/sh/include/asm/pgalloc_nopmd.h delete mode 100644 arch/sh/include/asm/pgalloc_pmd.h create mode 100644 arch/sh/mm/pgtable.c (limited to 'arch/sh/include') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index 4ea27855c3b..e106474996b 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -6,10 +6,13 @@ #define QUICK_PT 1 /* Other page table pages that are zero on free */ +extern pgd_t *pgd_alloc(struct mm_struct *); +extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); + #ifdef CONFIG_PGTABLE_LEVELS_3 -#include -#else -#include +extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd); +extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address); +extern void pmd_free(struct mm_struct *mm, pmd_t *pmd); #endif static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, @@ -67,7 +70,6 @@ do { \ static inline void check_pgt_cache(void) { - __check_pgt_cache(); quicklist_trim(QUICK_PT, NULL, 25, 16); } diff --git a/arch/sh/include/asm/pgalloc_nopmd.h b/arch/sh/include/asm/pgalloc_nopmd.h deleted file mode 100644 index e4b344c37e7..00000000000 --- a/arch/sh/include/asm/pgalloc_nopmd.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __ASM_SH_PGALLOC_NOPMD_H -#define __ASM_SH_PGALLOC_NOPMD_H - -#define QUICK_PGD 0 /* We preserve special mappings over free */ - -static inline void pgd_ctor(void *x) -{ - pgd_t *pgd = x; - - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); -} - -static inline pgd_t *pgd_alloc(struct mm_struct *mm) -{ - return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor); -} - -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - quicklist_free(QUICK_PGD, NULL, pgd); -} - -static inline void __check_pgt_cache(void) -{ - quicklist_trim(QUICK_PGD, NULL, 25, 16); -} - -#endif /* __ASM_SH_PGALLOC_NOPMD_H */ diff --git a/arch/sh/include/asm/pgalloc_pmd.h b/arch/sh/include/asm/pgalloc_pmd.h deleted file mode 100644 index 20f75cc4eb0..00000000000 --- a/arch/sh/include/asm/pgalloc_pmd.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __ASM_SH_PGALLOC_PMD_H -#define __ASM_SH_PGALLOC_PMD_H - -static inline pgd_t *pgd_alloc(struct mm_struct *mm) -{ - pgd_t *pgd; - int i; - - pgd = kzalloc(sizeof(*pgd) * PTRS_PER_PGD, GFP_KERNEL | __GFP_REPEAT); - - for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) - pgd[i] = swapper_pg_dir[i]; - - return pgd; -} - -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - kfree(pgd); -} - -static inline void __check_pgt_cache(void) -{ -} - -static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) -{ - set_pud(pud, __pud((unsigned long)pmd)); -} - -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) -{ - return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); -} - -static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) -{ - quicklist_free(QUICK_PT, NULL, pmd); -} - -#endif /* __ASM_SH_PGALLOC_PMD_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 9effcc3b0d1..78598ec33d0 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -141,9 +141,9 @@ typedef pte_t *pte_addr_t; #define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) /* - * No page table caches to initialise + * Initialise the page table caches */ -#define pgtable_cache_init() do { } while (0) +extern void pgtable_cache_init(void); struct vm_area_struct; diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 8a70535fa7c..dd5010c708e 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -15,7 +15,7 @@ obj-y += $(cacheops-y) mmu-y := nommu.o extable_32.o mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \ - ioremap_$(BITS).o kmap.o tlbflush_$(BITS).o + ioremap_$(BITS).o kmap.o pgtable.o tlbflush_$(BITS).o obj-y += $(mmu-y) obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c new file mode 100644 index 00000000000..e1bc5483cc0 --- /dev/null +++ b/arch/sh/mm/pgtable.c @@ -0,0 +1,57 @@ +#include + +#define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO + +static struct kmem_cache *pgd_cachep; + +#ifdef CONFIG_PGTABLE_LEVELS_3 +static struct kmem_cache *pmd_cachep; +#endif + +void pgd_ctor(void *x) +{ + pgd_t *pgd = x; + + memcpy(pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); +} + +void pgtable_cache_init(void) +{ + pgd_cachep = kmem_cache_create("pgd_cache", + PTRS_PER_PGD * (1< Date: Tue, 5 Jan 2010 12:35:00 +0900 Subject: sh: Drop down to a single quicklist. We previously had 2 quicklists, one for the PGD case and one for PTEs. Now that the PGD/PMD cases are handled through slab caches due to the multi-level configurability, only the PTE quicklist remains. As such, reduce NR_QUICK to its appropriate size and bump down the PTE quicklist index. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgalloc.h | 2 +- mm/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh/include') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index e106474996b..f8982f4e040 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -4,7 +4,7 @@ #include #include -#define QUICK_PT 1 /* Other page table pages that are zero on free */ +#define QUICK_PT 0 /* Other page table pages that are zero on free */ extern pgd_t *pgd_alloc(struct mm_struct *); extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); diff --git a/mm/Kconfig b/mm/Kconfig index 17b8947aa7d..d34c2b97103 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -195,7 +195,7 @@ config BOUNCE config NR_QUICK int depends on QUICKLIST - default "2" if SUPERH || AVR32 + default "2" if AVR32 default "1" config VIRT_TO_BUS -- cgit v1.2.3-70-g09d2