diff options
Diffstat (limited to 'arch/avr32/mach-at32ap/pm.c')
-rw-r--r-- | arch/avr32/mach-at32ap/pm.c | 243 |
1 files changed, 0 insertions, 243 deletions
diff --git a/arch/avr32/mach-at32ap/pm.c b/arch/avr32/mach-at32ap/pm.c deleted file mode 100644 index db190842b80c..000000000000 --- a/arch/avr32/mach-at32ap/pm.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * AVR32 AP Power Management - * - * 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. - */ -#include <linux/io.h> -#include <linux/suspend.h> -#include <linux/vmalloc.h> - -#include <asm/cacheflush.h> -#include <asm/sysreg.h> - -#include <mach/chip.h> -#include <mach/pm.h> -#include <mach/sram.h> - -#include "sdramc.h" - -#define SRAM_PAGE_FLAGS (SYSREG_BIT(TLBELO_D) | SYSREG_BF(SZ, 1) \ - | SYSREG_BF(AP, 3) | SYSREG_BIT(G)) - - -static unsigned long pm_sram_start; -static size_t pm_sram_size; -static struct vm_struct *pm_sram_area; - -static void (*avr32_pm_enter_standby)(unsigned long sdramc_base); -static void (*avr32_pm_enter_str)(unsigned long sdramc_base); - -/* - * Must be called with interrupts disabled. Exceptions will be masked - * on return (i.e. all exceptions will be "unrecoverable".) - */ -static void *avr32_pm_map_sram(void) -{ - unsigned long vaddr; - unsigned long page_addr; - u32 tlbehi; - u32 mmucr; - - vaddr = (unsigned long)pm_sram_area->addr; - page_addr = pm_sram_start & PAGE_MASK; - - /* - * Mask exceptions and grab the first TLB entry. We won't be - * needing it while sleeping. - */ - asm volatile("ssrf %0" : : "i"(SYSREG_EM_OFFSET) : "memory"); - - mmucr = sysreg_read(MMUCR); - tlbehi = sysreg_read(TLBEHI); - sysreg_write(MMUCR, SYSREG_BFINS(DRP, 0, mmucr)); - - tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); - tlbehi |= vaddr & PAGE_MASK; - tlbehi |= SYSREG_BIT(TLBEHI_V); - - sysreg_write(TLBELO, page_addr | SRAM_PAGE_FLAGS); - sysreg_write(TLBEHI, tlbehi); - __builtin_tlbw(); - - return (void *)(vaddr + pm_sram_start - page_addr); -} - -/* - * Must be called with interrupts disabled. Exceptions will be - * unmasked on return. - */ -static void avr32_pm_unmap_sram(void) -{ - u32 mmucr; - u32 tlbehi; - u32 tlbarlo; - - /* Going to update TLB entry at index 0 */ - mmucr = sysreg_read(MMUCR); - tlbehi = sysreg_read(TLBEHI); - sysreg_write(MMUCR, SYSREG_BFINS(DRP, 0, mmucr)); - - /* Clear the "valid" bit */ - tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); - sysreg_write(TLBEHI, tlbehi); - - /* Mark it as "not accessed" */ - tlbarlo = sysreg_read(TLBARLO); - sysreg_write(TLBARLO, tlbarlo | 0x80000000U); - - /* Update the TLB */ - __builtin_tlbw(); - - /* Unmask exceptions */ - asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET) : "memory"); -} - -static int avr32_pm_valid_state(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_ON: - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - return 1; - - default: - return 0; - } -} - -static int avr32_pm_enter(suspend_state_t state) -{ - u32 lpr_saved; - u32 evba_saved; - void *sram; - - switch (state) { - case PM_SUSPEND_STANDBY: - sram = avr32_pm_map_sram(); - - /* Switch to in-sram exception handlers */ - evba_saved = sysreg_read(EVBA); - sysreg_write(EVBA, (unsigned long)sram); - - /* - * Save the LPR register so that we can re-enable - * SDRAM Low Power mode on resume. - */ - lpr_saved = sdramc_readl(LPR); - pr_debug("%s: Entering standby...\n", __func__); - avr32_pm_enter_standby(SDRAMC_BASE); - sdramc_writel(LPR, lpr_saved); - - /* Switch back to regular exception handlers */ - sysreg_write(EVBA, evba_saved); - - avr32_pm_unmap_sram(); - break; - - case PM_SUSPEND_MEM: - sram = avr32_pm_map_sram(); - - /* Switch to in-sram exception handlers */ - evba_saved = sysreg_read(EVBA); - sysreg_write(EVBA, (unsigned long)sram); - - /* - * Save the LPR register so that we can re-enable - * SDRAM Low Power mode on resume. - */ - lpr_saved = sdramc_readl(LPR); - pr_debug("%s: Entering suspend-to-ram...\n", __func__); - avr32_pm_enter_str(SDRAMC_BASE); - sdramc_writel(LPR, lpr_saved); - - /* Switch back to regular exception handlers */ - sysreg_write(EVBA, evba_saved); - - avr32_pm_unmap_sram(); - break; - - case PM_SUSPEND_ON: - pr_debug("%s: Entering idle...\n", __func__); - cpu_enter_idle(); - break; - - default: - pr_debug("%s: Invalid suspend state %d\n", __func__, state); - goto out; - } - - pr_debug("%s: wakeup\n", __func__); - -out: - return 0; -} - -static const struct platform_suspend_ops avr32_pm_ops = { - .valid = avr32_pm_valid_state, - .enter = avr32_pm_enter, -}; - -static unsigned long __init avr32_pm_offset(void *symbol) -{ - extern u8 pm_exception[]; - - return (unsigned long)symbol - (unsigned long)pm_exception; -} - -static int __init avr32_pm_init(void) -{ - extern u8 pm_exception[]; - extern u8 pm_irq0[]; - extern u8 pm_standby[]; - extern u8 pm_suspend_to_ram[]; - extern u8 pm_sram_end[]; - void *dst; - - /* - * To keep things simple, we depend on not needing more than a - * single page. - */ - pm_sram_size = avr32_pm_offset(pm_sram_end); - if (pm_sram_size > PAGE_SIZE) - goto err; - - pm_sram_start = sram_alloc(pm_sram_size); - if (!pm_sram_start) - goto err_alloc_sram; - - /* Grab a virtual area we can use later on. */ - pm_sram_area = get_vm_area(pm_sram_size, VM_IOREMAP); - if (!pm_sram_area) - goto err_vm_area; - pm_sram_area->phys_addr = pm_sram_start; - - local_irq_disable(); - dst = avr32_pm_map_sram(); - memcpy(dst, pm_exception, pm_sram_size); - flush_dcache_region(dst, pm_sram_size); - invalidate_icache_region(dst, pm_sram_size); - avr32_pm_unmap_sram(); - local_irq_enable(); - - avr32_pm_enter_standby = dst + avr32_pm_offset(pm_standby); - avr32_pm_enter_str = dst + avr32_pm_offset(pm_suspend_to_ram); - intc_set_suspend_handler(avr32_pm_offset(pm_irq0)); - - suspend_set_ops(&avr32_pm_ops); - - printk("AVR32 AP Power Management enabled\n"); - - return 0; - -err_vm_area: - sram_free(pm_sram_start, pm_sram_size); -err_alloc_sram: -err: - pr_err("AVR32 Power Management initialization failed\n"); - return -ENOMEM; -} -arch_initcall(avr32_pm_init); |