Merge git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6: (31 commits)
  avr32: Fix typo of IFSR in a comment in the PIO header file
  avr32: Power Management support ("standby" and "mem" modes)
  avr32: Add system device for the internal interrupt controller (intc)
  avr32: Add simple SRAM allocator
  avr32: Enable SDRAMC clock at startup
  rtc-at32ap700x: Enable wakeup
  macb: Basic suspend/resume support
  atmel_serial: Drain console TX shifter before suspending
  atmel_serial: Fix build on avr32 with CONFIG_PM enabled
  avr32: Use a quicklist for PTE allocation as well
  avr32: Use a quicklist for PGD allocation
  avr32: Cover the kernel page tables in the user PGDs
  avr32: Store virtual addresses in the PGD
  avr32: Remove useless zeroing of swapper_pg_dir at startup
  avr32: Clean up and optimize the TLB operations
  avr32: Rename at32ap.c -> pdc.c
  avr32: Move setup_platform() into chip-specific file
  avr32: Kill special exception handler sections
  avr32: Kill unneeded #include <asm/pgalloc.h> from asm/mmu_context.h
  avr32: Clean up time.c #includes
  ...
This commit is contained in:
Linus Torvalds 2008-07-14 13:37:29 -07:00
commit 6c118e43dc
36 changed files with 1093 additions and 280 deletions

View file

@ -8,6 +8,12 @@
#define GPIO_PIN_NONE (-1)
/*
* Clock rates for various on-board oscillators. The number of entries
* in this array is chip-dependent.
*/
extern unsigned long at32_board_osc_rates[];
/* Add basic devices: system manager, interrupt controller, portmuxes, etc. */
void at32_add_system_devices(void);
@ -36,7 +42,8 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n);
struct atmel_lcdfb_info;
struct platform_device *
at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
unsigned long fbmem_start, unsigned long fbmem_len);
unsigned long fbmem_start, unsigned long fbmem_len,
unsigned int pin_config);
struct usba_platform_data;
struct platform_device *
@ -73,6 +80,7 @@ struct platform_device *at32_add_device_twi(unsigned int id,
struct platform_device *at32_add_device_mci(unsigned int id);
struct platform_device *at32_add_device_ac97c(unsigned int id);
struct platform_device *at32_add_device_abdac(unsigned int id);
struct platform_device *at32_add_device_psif(unsigned int id);
struct cf_platform_data {
int detect_pin;

View file

@ -13,10 +13,6 @@
void setup_platform(void);
void setup_board(void);
/* Called by setup_platform */
void at32_clock_init(void);
void at32_portmux_init(void);
void at32_setup_serial_console(unsigned int usart_id);
#endif /* __ASM_AVR32_AT32AP_INIT_H__ */

View file

@ -19,6 +19,7 @@
#ifndef __ASSEMBLY__
extern void cpu_enter_idle(void);
extern void cpu_enter_standby(unsigned long sdramc_base);
extern bool disable_idle_sleep;
@ -43,6 +44,8 @@ static inline void cpu_idle_sleep(void)
else
cpu_enter_idle();
}
void intc_set_suspend_handler(unsigned long offset);
#endif
#endif /* __ASM_AVR32_ARCH_PM_H */

View file

@ -0,0 +1,30 @@
/*
* Simple SRAM allocator
*
* Copyright (C) 2008 Atmel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_AVR32_ARCH_SRAM_H
#define __ASM_AVR32_ARCH_SRAM_H
#include <linux/genalloc.h>
extern struct gen_pool *sram_pool;
static inline unsigned long sram_alloc(size_t len)
{
if (!sram_pool)
return 0UL;
return gen_pool_alloc(sram_pool, len);
}
static inline void sram_free(unsigned long addr, size_t len)
{
return gen_pool_free(sram_pool, addr, len);
}
#endif /* __ASM_AVR32_ARCH_SRAM_H */

View file

@ -13,7 +13,6 @@
#define __ASM_AVR32_MMU_CONTEXT_H
#include <asm/tlbflush.h>
#include <asm/pgalloc.h>
#include <asm/sysreg.h>
#include <asm-generic/mm_hooks.h>

View file

@ -5,4 +5,6 @@
#define PCI_DMA_BUS_IS_PHYS (1)
#include <asm-generic/pci-dma-compat.h>
#endif /* __ASM_AVR32_PCI_H__ */

View file

@ -8,65 +8,79 @@
#ifndef __ASM_AVR32_PGALLOC_H
#define __ASM_AVR32_PGALLOC_H
#include <asm/processor.h>
#include <linux/threads.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/quicklist.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#define pmd_populate_kernel(mm, pmd, pte) \
set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
#define QUICK_PGD 0 /* Preserve kernel mappings over free */
#define QUICK_PT 1 /* Zero on free */
static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
static inline void pmd_populate_kernel(struct mm_struct *mm,
pmd_t *pmd, pte_t *pte)
{
set_pmd(pmd, __pmd((unsigned long)pte));
}
static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
pgtable_t pte)
{
set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte)));
set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
}
#define pmd_pgtable(pmd) pmd_page(pmd)
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));
}
/*
* Allocate and free page tables
*/
static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
return kcalloc(USER_PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL);
return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor);
}
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
kfree(pgd);
quicklist_free(QUICK_PGD, NULL, pgd);
}
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
pte_t *pte;
pte = (pte_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
return pte;
return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL);
}
static inline struct page *pte_alloc_one(struct mm_struct *mm,
static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
unsigned long address)
{
struct page *pte;
struct page *page;
void *pg;
pte = alloc_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
if (!pte)
pg = quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL);
if (!pg)
return NULL;
pgtable_page_ctor(pte);
return pte;
page = virt_to_page(pg);
pgtable_page_ctor(page);
return page;
}
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
free_page((unsigned long)pte);
quicklist_free(QUICK_PT, NULL, pte);
}
static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
{
pgtable_page_dtor(pte);
__free_page(pte);
quicklist_free_page(QUICK_PT, NULL, pte);
}
#define __pte_free_tlb(tlb,pte) \
@ -75,6 +89,10 @@ do { \
tlb_remove_page((tlb), pte); \
} while (0)
#define check_pgt_cache() do { } while(0)
static inline void check_pgt_cache(void)
{
quicklist_trim(QUICK_PGD, NULL, 25, 16);
quicklist_trim(QUICK_PT, NULL, 25, 16);
}
#endif /* __ASM_AVR32_PGALLOC_H */

View file

@ -129,13 +129,6 @@ extern struct page *empty_zero_page;
#define _PAGE_FLAGS_CACHE_MASK (_PAGE_CACHABLE | _PAGE_BUFFER | _PAGE_WT)
/* TODO: Check for saneness */
/* User-mode page table flags (to be set in a pgd or pmd entry) */
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_TYPE_SMALL | _PAGE_RW \
| _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
/* Kernel-mode page table flags */
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_TYPE_SMALL | _PAGE_RW \
| _PAGE_ACCESSED | _PAGE_DIRTY)
/* Flags that may be modified by software */
#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY \
| _PAGE_FLAGS_CACHE_MASK)
@ -262,10 +255,14 @@ static inline pte_t pte_mkspecial(pte_t pte)
}
#define pmd_none(x) (!pmd_val(x))
#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) \
!= _KERNPG_TABLE)
#define pmd_present(x) (pmd_val(x))
static inline void pmd_clear(pmd_t *pmdp)
{
set_pmd(pmdp, __pmd(0));
}
#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK)
/*
* Permanent address of a page. We don't support highmem, so this is
@ -303,19 +300,16 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define page_pte(page) page_pte_prot(page, __pgprot(0))
#define pmd_page_vaddr(pmd) \
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
#define pmd_page(pmd) (phys_to_page(pmd_val(pmd)))
#define pmd_page_vaddr(pmd) pmd_val(pmd)
#define pmd_page(pmd) (virt_to_page(pmd_val(pmd)))
/* to find an entry in a page-table-directory. */
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
#define pgd_offset_current(address) \
((pgd_t *)__mfsr(SYSREG_PTBR) + pgd_index(address))
#define pgd_index(address) (((address) >> PGDIR_SHIFT) \
& (PTRS_PER_PGD - 1))
#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
/* Find an entry in the third-level page table.. */
#define pte_index(address) \

View file

@ -88,6 +88,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_MEMDIE 6
#define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */
#define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */
#define TIF_FREEZE 29
#define TIF_DEBUG 30 /* debugging enabled */
#define TIF_USERSPACE 31 /* true if FS sets userspace */

View file

@ -26,7 +26,6 @@ extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
extern void __flush_tlb_page(unsigned long asid, unsigned long page);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);