From 6d4476219a0c922e2dba05fa854f29243dc60106 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 19 Nov 2008 17:10:50 +0000 Subject: tracking-2.6.27-rc2-fix-fiq.patch Signed-off-by: Andy Green --- arch/arm/include/asm/fiq.h | 4 ++-- arch/arm/mach-s3c2440/fiq_c_isr.c | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h index 2242ce22ec6..a0cc0c084b8 100644 --- a/arch/arm/include/asm/fiq.h +++ b/arch/arm/include/asm/fiq.h @@ -29,8 +29,8 @@ struct fiq_handler { extern int claim_fiq(struct fiq_handler *f); extern void release_fiq(struct fiq_handler *f); extern void set_fiq_handler(void *start, unsigned int length); -extern void set_fiq_regs(struct pt_regs *regs); -extern void get_fiq_regs(struct pt_regs *regs); +extern void __attribute__((naked)) set_fiq_regs(struct pt_regs *regs); +extern void __attribute__((naked)) get_fiq_regs(struct pt_regs *regs); extern void enable_fiq(int fiq); extern void disable_fiq(int fiq); diff --git a/arch/arm/mach-s3c2440/fiq_c_isr.c b/arch/arm/mach-s3c2440/fiq_c_isr.c index 6f90d234299..a5a8cddcd77 100644 --- a/arch/arm/mach-s3c2440/fiq_c_isr.c +++ b/arch/arm/mach-s3c2440/fiq_c_isr.c @@ -11,6 +11,7 @@ #include "fiq_c_isr.h" #include #include +#include #include #include @@ -72,7 +73,7 @@ static int _fiq_irq; /* private ; irq index we were started with, or 0 */ struct s3c2410_pwm pwm_timer_fiq; int _fiq_timer_index; u16 _fiq_timer_divisor; - +u8 fiq_ready; /* this function must live in the monolithic kernel somewhere! A module is * NOT good enough! @@ -178,6 +179,11 @@ void fiq_kick(void) unsigned long flags; u32 tcon; + if (!fiq_ready) { + printk(KERN_ERR "fiq_kick called before fiq probed\n"); + return; + } + /* we have to take care about FIQ because this modification is * non-atomic, FIQ could come in after the read and before the * writeback and its changes to the register would be lost @@ -206,6 +212,7 @@ EXPORT_SYMBOL_GPL(fiq_kick); static int __init sc32440_fiq_probe(struct platform_device *pdev) { struct resource *r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + int ret; if (!r) return -EIO; @@ -215,7 +222,11 @@ static int __init sc32440_fiq_probe(struct platform_device *pdev) fiq_init_irq_source(r->start); - return sysfs_create_group(&pdev->dev.kobj, &s3c2440_fiq_attr_group); + ret = sysfs_create_group(&pdev->dev.kobj, &s3c2440_fiq_attr_group); + + fiq_ready = 1; + + return ret; } static int sc32440_fiq_remove(struct platform_device *pdev) @@ -233,8 +244,11 @@ static void fiq_set_vector_and_regs(void) memset(®s, 0, sizeof(regs)); regs.ARM_r8 = (unsigned long)s3c2440_fiq_isr; regs.ARM_sp = (unsigned long)u8aFiqStack + sizeof(u8aFiqStack) - 4; + /* set up the special FIQ-mode-only registers from our regs */ + set_fiq_regs(®s); + /* copy our jump to the real ISR into the hard vector address */ set_fiq_handler(s3c2440_FIQ_Branch, SIZEOF_FIQ_JUMP); } -- cgit v1.2.3