Add basic power management support for DaVinci.
Signed-off-by: Dirk Behme <[EMAIL PROTECTED]>
Index: linux-davinci/arch/arm/mach-davinci/Makefile =================================================================== --- linux-davinci.orig/arch/arm/mach-davinci/Makefile +++ linux-davinci/arch/arm/mach-davinci/Makefile @@ -15,3 +15,6 @@ obj-$(CONFIG_DAVINCI_I2C_EXPANDER) += i2 ifeq ($(CONFIG_LEDS),y) obj-$(CONFIG_MACH_DAVINCI_EVM) += leds-evm.o endif + +# Power Management +obj-$(CONFIG_PM) += pm.o sleep.o tcm.o Index: linux-davinci/arch/arm/mach-davinci/pm.c =================================================================== --- /dev/null +++ linux-davinci/arch/arm/mach-davinci/pm.c @@ -0,0 +1,283 @@ +/* + * linux/arch/arm/mach-davinci/pm.c + * + * DaVinci Power Management Routines + * + * Copyright 2008 Dirk Behme <[EMAIL PROTECTED]> + * + * Based on arch/arm/mach-omap2/pm.c from: + * + * Copyright (C) 2005 Texas Instruments, Inc. + * Copyright (C) 2006 Nokia Corporation + * + * Written by: + * Richard Woodruff <[EMAIL PROTECTED]> + * Tony Lindgren + * Juha Yrjola + * Amit Kucheria <[EMAIL PROTECTED]> + * Igor Stoppa <[EMAIL PROTECTED]> + * + * Based on pm.c for omap1 + * + * 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/suspend.h> +#include <linux/interrupt.h> +#include <linux/sysfs.h> +#include <linux/module.h> + +#include <asm/mach/time.h> +#include <asm/mach/irq.h> + +#include <asm/arch/edma.h> +#include <asm/arch/tcm.h> +#include <asm/arch/pm.h> + +static void (*davinci_tcm_idle)(void); +static void (*davinci_tcm_suspend)(void); +static void (*saved_idle)(void); + +static unsigned short enable_standby; +static unsigned int count_idle; +static unsigned int count_standby; + +static ssize_t davinci_pm_idle_show(struct kset *subsys, char *buf) +{ + return sprintf(buf, "%hu\n", count_idle); +} + +static struct subsys_attribute idle_attr = { + .attr = { + .name = __stringify(count_idle), + .mode = 0644, + }, + .show = davinci_pm_idle_show, +}; + +static ssize_t davinci_pm_standby_show(struct kset *subsys, char *buf) +{ + return sprintf(buf, "%hu\n", count_standby); +} + +static struct subsys_attribute standby_attr = { + .attr = { + .name = __stringify(count_standby), + .mode = 0644, + }, + .show = davinci_pm_standby_show, +}; + +static int davinci_irq_pending(void) +{ + u32 pending, enabled0, enabled1; + + enabled0 = davinci_irq_readl(IRQ_ENT_REG0_OFFSET); + enabled1 = davinci_irq_readl(IRQ_ENT_REG1_OFFSET); + + /* Any enabled FIQ0 pending? */ + pending = davinci_irq_readl(FIQ_REG0_OFFSET); + if (~pending & enabled0) + return 1; + + /* Any enabled FIQ1 pending? */ + pending = davinci_irq_readl(FIQ_REG1_OFFSET); + if (~pending & enabled1) + return 1; + + /* Any enabled IRQ0 pending? */ + pending = davinci_irq_readl(IRQ_REG0_OFFSET); + if (~pending & enabled0) + return 1; + + /* Any enabled IRQ1 pending? */ + pending = davinci_irq_readl(IRQ_REG1_OFFSET); + if (~pending & enabled1) + return 1; + + return 0; +} + +static void davinci_enter_standby(void) +{ + u32 enabled0, enabled1; + + /* ToDo: Disable all unused peripherals using PSC */ + + /* Save irq enable masks */ + enabled0 = davinci_irq_readl(IRQ_ENT_REG0_OFFSET); + enabled1 = davinci_irq_readl(IRQ_ENT_REG1_OFFSET); + + /* Configure wake interrupts. Disable all interrupts + * except wake irqs */ + davinci_irq_writel(1 << IRQ_EMACINT, IRQ_ENT_REG0_OFFSET); + davinci_irq_writel(0x0, IRQ_ENT_REG1_OFFSET); + + /* One last check for pending IRQs to avoid extra latency due + * to sleeping unnecessarily. */ + if (davinci_irq_pending()) + goto no_sleep; + + /* Jump to suspend code in TCM */ + davinci_tcm_suspend(); + + count_standby++; + + enable_standby = 0; + +no_sleep: + /* Reenable interrupts, rewrite saved enable configuration */ + davinci_irq_writel(enabled0, IRQ_ENT_REG0_OFFSET); + davinci_irq_writel(enabled1, IRQ_ENT_REG1_OFFSET); +} + +static void davinci_enter_idle(void) +{ + /* Jump to idle code in TCM */ + davinci_tcm_idle(); + + count_idle++; +} + +static int davinci_can_sleep(void) +{ + if (!enable_standby) + return 0; + if (davinci_dma_running()) + return 0; + + return 1; +} + +static void davinci_pm_idle(void) +{ + local_irq_disable(); + local_fiq_disable(); + + if (!davinci_can_sleep()) { + /* timer_dyn_reprogram() takes about 100-200 us to complete */ + timer_dyn_reprogram(); + if (davinci_irq_pending()) + goto out; + davinci_enter_idle(); + goto out; + } + + /* + * Since an interrupt may set up a timer, we don't want to + * reprogram the hardware timer with interrupts enabled. + * Re-enable interrupts only after returning from idle. + */ + timer_dyn_reprogram(); + + if (davinci_irq_pending()) + goto out; + + davinci_enter_standby(); + +out: + local_fiq_enable(); + local_irq_enable(); +} + +static int davinci_pm_prepare(void) +{ + /* We cannot sleep in idle until we have resumed */ + saved_idle = pm_idle; + pm_idle = NULL; + + return 0; +} + +static int davinci_pm_enter(suspend_state_t state) +{ + int ret = 0; + + switch (state) { + case PM_SUSPEND_STANDBY: + enable_standby = 1; + davinci_pm_idle(); + break; + case PM_SUSPEND_MEM: + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static void davinci_pm_finish(void) +{ + pm_idle = saved_idle; +} + +static int davinci_pm_valid_standby(suspend_state_t state) +{ + return state == PM_SUSPEND_STANDBY; +} + + +static struct platform_suspend_ops davinci_pm_ops = { + .prepare = davinci_pm_prepare, + .enter = davinci_pm_enter, + .finish = davinci_pm_finish, + .valid = davinci_pm_valid_standby, +}; + + +int __init davinci_pm_init(void) +{ + u32 tmp; + + printk(KERN_INFO "Power Management for DaVinci initializing\n"); + + /* Check if TCM is mapped using one 1MB desc, avoid MMU walks while + * running from TCM */ + + /* Get TTB from TTBR */ + asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r" (tmp) :); + + /* Convert TTB to virtual address */ + tmp = (u32)phys_to_virt(tmp & 0xFFFFC000); + + /* Get table entry */ + tmp = *(u32 *) (tmp + (TCM_VIRT >> 18)); + + /* Section bits set ? */ + if ((tmp & 0x3) != 0x2) { + printk(KERN_ERR "TCM not mapped using section descriptor: " \ + "0x%08x\n", tmp); + return -EFAULT; + } + + /* + * We copy the assembler sleep/wakeup routines to ITCM. + * These routines need to be in ITCM as that's the only + * memory the ARM can see when it wakes up if we switch + * main memory (SDRAM) to self refresh. + */ + davinci_tcm_idle = davinci_tcm_push(davinci_idle_loop_suspend, + davinci_idle_loop_suspend_sz); + + davinci_tcm_suspend = davinci_tcm_push(davinci_cpu_suspend, + davinci_cpu_suspend_sz); + + suspend_set_ops(&davinci_pm_ops); + pm_idle = davinci_pm_idle; + + tmp = subsys_create_file(&power_subsys, &idle_attr); + if (tmp) + printk(KERN_ERR "subsys_create_file idle_count failed: %d\n", + tmp); + tmp = subsys_create_file(&power_subsys, &standby_attr); + if (tmp) + printk(KERN_ERR "subsys_create_file standby_count failed: %d\n", + tmp); + + return 0; +} + +late_initcall(davinci_pm_init); Index: linux-davinci/arch/arm/mach-davinci/sleep.S =================================================================== --- /dev/null +++ linux-davinci/arch/arm/mach-davinci/sleep.S @@ -0,0 +1,120 @@ +/* + * linux/arch/arm/mach-davinci/sleep.S + * + * Assembly sleep routines for DaVinci + * + * Copyright 2007 Dirk Behme <[EMAIL PROTECTED]> + * + * Based on arch/arm/mach-omap2/sleep.S from: + * + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <[EMAIL PROTECTED]> + * + * (C) Copyright 2006 Nokia Corporation + * Fixed idle loop sleep + * Igor Stoppa <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/arch/io.h> + + .text + +/* + * Forces DaVinci into idle state + * + * davinci_idle_loop_suspend() - This bit of code just executes the WFI + * for normal idles. + * + * Note: This code get's copied to internal ITCM at boot. When DaVinci + * wakes up it continues execution at the point it went to sleep. + */ +ENTRY(davinci_idle_loop_suspend) + stmfd sp!, {r0, lr} @ save registers on stack + mov r0, #0x0 @ clear for mrc call + mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt + ldmfd sp!, {r0, pc} @ restore regs and return + +ENTRY(davinci_idle_loop_suspend_sz) + .word . - davinci_idle_loop_suspend + +/* + * davinci_cpu_suspend() - Forces DaVinci into sleep state by switching + * SDRAM into self refresh and then enter WFI. + */ +ENTRY(davinci_cpu_suspend) + stmfd sp!, {r0 - r12, lr} @ save registers on stack + +tci_loop: + mrc p15, 0, r15, c7, c14, 3 @ test clean and invalidate DCache + bne tci_loop + + mov r0, #0x0 @ clear for mrc call + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer, + @ hope SDR/DDR finished + nop + nop + + /* ToDo: Currently, we only switch SDRAM to self refresh here. To + * save even more power, we should gate input clocks to the + * memory controller module off. See TI document SPRUE22C + * section 2.15 "Power management" for more details. + */ + + /* Switch SDRAM to selfrefresh */ + ldr r0, ddr2_ctrl_base + ldr r1, self_refresh + ldr r2, [r0] + orr r2, r2, r1 + str r2, [r0] + + /* ToDo: Wait T_CKE+1 cycles */ + mov r2, #0x1000 +loop1: + subs r2, r2, #0x1 + bne loop1 + + /* Sleep */ + mov r2, #0 + mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt + nop + + /* Exit SDRAM selfrefresh, r0 and r1 should be still valid */ + ldr r2, [r0] + bic r2, r2, r1 + str r2, [r0] + + /* ToDo: Wait T_SXNR+1 and/or T_SCRD+1 cylces */ + mov r0, #0x1000 +loop2: + subs r0, r0, #0x1 + bne loop2 + + /* Resume*/ + ldmfd sp!, {r0 - r12, pc} @ restore regs and return + +ddr2_ctrl_base: + .word DDR2_CTRL_VIRT +self_refresh: + .word 0x80000000 + +ENTRY(davinci_cpu_suspend_sz) + .word . - davinci_cpu_suspend + Index: linux-davinci/include/asm-arm/arch-davinci/pm.h =================================================================== --- /dev/null +++ linux-davinci/include/asm-arm/arch-davinci/pm.h @@ -0,0 +1,52 @@ +/* + * linux/include/asm-arm/arch-davinci/pm.h + * + * Header file for DaVinci Power Management Routines + * + * Copyright 2007 Dirk Behme <[EMAIL PROTECTED]> + * + * Based on linux/include/asm-arm/arch-omap/pm.h from: + * + * Author: MontaVista Software, Inc. + * [EMAIL PROTECTED] + * + * Copyright 2002 MontaVista Software Inc. + * + * Cleanup 2004 for Linux 2.6 by Dirk Behme <[EMAIL PROTECTED]> + + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ASM_ARCH_DAVINCI_PM_H +#define __ASM_ARCH_DAVINCI_PM_H + +#ifndef __ASSEMBLER__ + +extern void davinci_cpu_suspend(void); +extern void davinci_idle_loop_suspend(void); + +extern unsigned int davinci_cpu_suspend_sz; +extern unsigned int davinci_idle_loop_suspend_sz; + +extern struct kset power_subsys; + +#endif /* ASSEMBLER */ +#endif /* __ASM_ARCH_DAVINCI_PM_H */ Index: linux-davinci/arch/arm/mach-davinci/tcm.c =================================================================== --- /dev/null +++ linux-davinci/arch/arm/mach-davinci/tcm.c @@ -0,0 +1,75 @@ +/* + * linux/arch/arm/mach-davinci/tcm.c + * + * DaVinci interal TCM detection and management + * + * Copyright 2007 Dirk Behme <[EMAIL PROTECTED]> + * + * Based on arch/arm/plat-omap/sram.c from: + * + * Copyright (C) 2005 Nokia Corporation + * Written by Tony Lindgren <[EMAIL PROTECTED]> + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> + +#include <asm/arch/tcm.h> + +static unsigned long davinci_itcm_base; +static unsigned long davinci_itcm_size; +static unsigned long davinci_itcm_ceil; + +#define ROUND_DOWN(value, boundary) ((value) & (~((boundary)-1))) + +void *davinci_tcm_push(void *start, unsigned long size) +{ + if ((size > davinci_itcm_ceil) || (davinci_itcm_size == 0)) { + printk(KERN_ERR "Not enough space in ITCM\n"); + return NULL; + } + + davinci_itcm_ceil -= size; + davinci_itcm_ceil = ROUND_DOWN(davinci_itcm_ceil, sizeof(void *)); + memcpy((void *)davinci_itcm_ceil, start, size); + + return (void *)davinci_itcm_ceil; +} + +void __init davinci_init_tcm(void) +{ + u32 tmp; + + davinci_itcm_size = 0; + + /* Check for ITCM */ + asm volatile ("mrc p15, 0, %0, c0, c0, 2" : "=r" (tmp) :); + if (!(tmp & 0x1)) { + printk(KERN_ERR "No ITCM found\n"); + return; + } + + /* Check for ITCM size */ + asm volatile ("mrc p15, 0, %0, c9, c1, 1" : "=r" (tmp) :); + /* Wonder: Manual states that ITCM is 16k, i.e. 0x5 + * should be returned? */ + if (((tmp >> 2) & 0xF) != 0x6) { + printk(KERN_ERR "Wrong ITCM size. Not 32k? " \ + "ITCM region reg: 0x%08x\n", tmp); + return; + } + + /* Everything looks okay, enable ITCM */ + tmp = (TCM_PHYS << 12) | 1; + asm volatile ("mcr p15, 0, %0, c9, c1, 1" : : "r" (tmp)); + + davinci_itcm_base = TCM_VIRT; + davinci_itcm_size = SZ_16K; + davinci_itcm_ceil = davinci_itcm_base + davinci_itcm_size; +} Index: linux-davinci/include/asm-arm/arch-davinci/tcm.h =================================================================== --- /dev/null +++ linux-davinci/include/asm-arm/arch-davinci/tcm.h @@ -0,0 +1,19 @@ +/* + * linux/include/asm-arm/arch-davinci/tcm.h + * + * Interface for functions that need to be run in internal TCM + * + * Copyright 2007 Dirk Behme <[EMAIL PROTECTED]> + * + * 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 __ARCH_ARM_DAVINCI_TCM_H +#define __ARCH_ARM_DAVINCI_TCM_H + +extern void *davinci_tcm_push(void *start, unsigned long size); +extern void davinci_init_tcm(void); + +#endif /* __ARCH_ARM_DAVINCI_TCM_H */ Index: linux-davinci/arch/arm/mach-davinci/io.c =================================================================== --- linux-davinci.orig/arch/arm/mach-davinci/io.c +++ linux-davinci/arch/arm/mach-davinci/io.c @@ -18,8 +18,8 @@ #include <asm/mach/map.h> #include <asm/arch/clock.h> - -extern void davinci_check_revision(void); +#include <asm/arch/hardware.h> +#include <asm/arch/tcm.h> /* * The machine specific code may provide the extra mapping besides the @@ -32,6 +32,18 @@ static struct map_desc davinci_io_desc[] .length = IO_SIZE, .type = MT_DEVICE }, + { + .virtual = DDR2_CTRL_VIRT, + .pfn = __phys_to_pfn(DDR2_CTRL_PHYS), + .length = DDR2_CTRL_SIZE, + .type = MT_DEVICE + }, + { + .virtual = TCM_VIRT, + .pfn = __phys_to_pfn(TCM_PHYS), + .length = TCM_SIZE, + .type = MT_DEVICE + }, }; void __init davinci_map_common_io(void) @@ -49,6 +61,12 @@ void __init davinci_map_common_io(void) * IO space mapping must be initialized before we can do that. */ davinci_check_revision(); + davinci_init_tcm(); + + printk(KERN_INFO "TCM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", + __pfn_to_phys(davinci_io_desc[2].pfn), + davinci_io_desc[2].virtual, + davinci_io_desc[2].length); } void __init davinci_init_common_hw(void) Index: linux-davinci/include/asm-arm/arch-davinci/hardware.h =================================================================== --- linux-davinci.orig/include/asm-arm/arch-davinci/hardware.h +++ linux-davinci/include/asm-arm/arch-davinci/hardware.h @@ -14,6 +14,8 @@ /* * Base register addresses */ +#define DAVINCI_TCM_BASE (0x00000000) +#define DAVINCI_ROM_BASE (0x00004000) #define DAVINCI_DMA_3PCC_BASE (0x01C00000) #define DAVINCI_DMA_3PTC0_BASE (0x01C10000) #define DAVINCI_DMA_3PTC1_BASE (0x01C10400) @@ -48,5 +50,11 @@ #define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x06000000) #define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x08000000) #define DAVINCI_VLYNQ_REMOTE_BASE (0x0C000000) +#define DAVINCI_DDR2_CTRL_BASE (0x20000000) +#ifndef __ASSEMBLER__ + +extern void davinci_check_revision(void); + +#endif /* ASSEMBLER */ #endif /* __ASM_ARCH_HARDWARE_H */ Index: linux-davinci/include/asm-arm/arch-davinci/io.h =================================================================== --- linux-davinci.orig/include/asm-arm/arch-davinci/io.h +++ linux-davinci/include/asm-arm/arch-davinci/io.h @@ -1,7 +1,7 @@ /* * DaVinci IO address definitions * - * Copied from include/asm/arm/arch-omap/io.h + * Copied from include/asm-arm/arch-omap/io.h * * 2007 (c) MontaVista Software, Inc. This file is licensed under * the terms of the GNU General Public License version 2. This program @@ -11,6 +11,16 @@ #ifndef __ASM_ARCH_IO_H #define __ASM_ARCH_IO_H +#include <asm/hardware.h> + +#define TCM_PHYS DAVINCI_TCM_BASE /* 0x00000000 */ +#define TCM_VIRT 0xfea00000 +#define TCM_SIZE SZ_1M /* use a section desc */ + +#define DDR2_CTRL_PHYS DAVINCI_DDR2_CTRL_BASE /* 0x20000000 */ +#define DDR2_CTRL_VIRT 0xfeb00000 +#define DDR2_CTRL_SIZE SZ_1M + #define IO_SPACE_LIMIT 0xffffffff /* Index: linux-davinci/arch/arm/mach-davinci/dma.c =================================================================== --- linux-davinci.orig/arch/arm/mach-davinci/dma.c +++ linux-davinci/arch/arm/mach-davinci/dma.c @@ -1442,6 +1442,19 @@ void davinci_stop_dma(int lch) /****************************************************************************** * + * DMA Running - Checks for running DMA + * + * Return: zero if no DMA is ongoing, or 1 if any DMA still runs + * + *****************************************************************************/ +int davinci_dma_running(void) +{ + /* ToDo: Check for running DMA */ + return 0; +} + +/****************************************************************************** + * * DMA channel link - link the two logical channels passed through by linking * the link field of head to the param pointed by the lch_queue. * ARGUMENTS: @@ -1724,6 +1737,7 @@ EXPORT_SYMBOL(davinci_set_dma_dest_param EXPORT_SYMBOL(davinci_set_dma_src_params); EXPORT_SYMBOL(davinci_request_dma); EXPORT_SYMBOL(davinci_stop_dma); +EXPORT_SYMBOL(davinci_dma_running); EXPORT_SYMBOL(davinci_clean_channel); EXPORT_SYMBOL(davinci_free_dma); EXPORT_SYMBOL(davinci_dma_chain_lch); Index: linux-davinci/include/asm-arm/arch-davinci/edma.h =================================================================== --- linux-davinci.orig/include/asm-arm/arch-davinci/edma.h +++ linux-davinci/include/asm-arm/arch-davinci/edma.h @@ -485,6 +485,15 @@ int davinci_start_dma(int lch); void davinci_stop_dma(int lch); /****************************************************************************** + * + * davinci_dma_running - Checks for running DMA + * + * Return: zero if no DMA is ongoing, or 1 if any DMA still runs + * + *****************************************************************************/ +int davinci_dma_running(void); + +/****************************************************************************** * davinci_dma_link_lch - Link two Logical channels * * lch_head - logical channel number, in which the link field is linked to the Index: linux-davinci/include/asm-arm/arch-davinci/irqs.h =================================================================== --- linux-davinci.orig/include/asm-arm/arch-davinci/irqs.h +++ linux-davinci/include/asm-arm/arch-davinci/irqs.h @@ -102,4 +102,21 @@ #define ARCH_TIMER_IRQ IRQ_TINT1_TINT34 +#define FIQ_REG0_OFFSET 0x0000 +#define FIQ_REG1_OFFSET 0x0004 +#define IRQ_REG0_OFFSET 0x0008 +#define IRQ_REG1_OFFSET 0x000C +#define IRQ_ENT_REG0_OFFSET 0x0018 +#define IRQ_ENT_REG1_OFFSET 0x001C +#define IRQ_INCTL_REG_OFFSET 0x0020 +#define IRQ_EABASE_REG_OFFSET 0x0024 +#define IRQ_INTPRI0_REG_OFFSET 0x0030 +#define IRQ_INTPRI7_REG_OFFSET 0x004C + +#ifndef __ASSEMBLER__ + +extern unsigned int davinci_irq_readl(int); +extern void davinci_irq_writel(unsigned long, int); + +#endif /* __ASSEMBLER__ */ #endif /* __ASM_ARCH_IRQS_H */ Index: linux-davinci/arch/arm/mach-davinci/irq.c =================================================================== --- linux-davinci.orig/arch/arm/mach-davinci/irq.c +++ linux-davinci/arch/arm/mach-davinci/irq.c @@ -40,12 +40,12 @@ #define IRQ_INTPRI0_REG_OFFSET 0x0030 #define IRQ_INTPRI7_REG_OFFSET 0x004C -static inline unsigned int davinci_irq_readl(int offset) +inline unsigned int davinci_irq_readl(int offset) { return davinci_readl(DAVINCI_ARM_INTC_BASE + offset); } -static inline void davinci_irq_writel(unsigned long value, int offset) +inline void davinci_irq_writel(unsigned long value, int offset) { davinci_writel(value, DAVINCI_ARM_INTC_BASE + offset); }
_______________________________________________ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source