diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 39 | ||||
-rw-r--r-- | include/asm-powerpc/cputime.h | 18 |
3 files changed, 48 insertions, 11 deletions
@@ -528,7 +528,7 @@ export MODLIB ifdef INSTALL_MOD_STRIP ifeq ($(INSTALL_MOD_STRIP),1) -mod_strip_cmd = $STRIP) --strip-debug +mod_strip_cmd = $(STRIP) --strip-debug else mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) endif # INSTALL_MOD_STRIP=1 diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 7d31d7cc392..9cecebaa036 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -405,20 +405,22 @@ static void mpic_unmask_irq(unsigned int irq) unsigned int loops = 100000; struct mpic *mpic = mpic_from_irq(irq); unsigned int src = mpic_irq_to_hw(irq); + unsigned long flags; DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); + spin_lock_irqsave(&mpic_lock, flags); mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK); - /* make sure mask gets to controller before we return to user */ do { if (!loops--) { printk(KERN_ERR "mpic_enable_irq timeout\n"); break; } - } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); + } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); + spin_unlock_irqrestore(&mpic_lock, flags); } static void mpic_mask_irq(unsigned int irq) @@ -426,9 +428,11 @@ static void mpic_mask_irq(unsigned int irq) unsigned int loops = 100000; struct mpic *mpic = mpic_from_irq(irq); unsigned int src = mpic_irq_to_hw(irq); + unsigned long flags; DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); + spin_lock_irqsave(&mpic_lock, flags); mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK); @@ -440,6 +444,7 @@ static void mpic_mask_irq(unsigned int irq) break; } } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); + spin_unlock_irqrestore(&mpic_lock, flags); } static void mpic_end_irq(unsigned int irq) @@ -624,9 +629,10 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, struct irq_desc *desc = get_irq_desc(virq); struct irq_chip *chip; struct mpic *mpic = h->host_data; - unsigned int vecpri = MPIC_VECPRI_SENSE_LEVEL | + u32 v, vecpri = MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE; int level; + unsigned long iflags; pr_debug("mpic: map virq %d, hwirq 0x%lx, flags: 0x%x\n", virq, hw, flags); @@ -668,11 +674,21 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, } #endif - /* Reconfigure irq */ - vecpri |= MPIC_VECPRI_MASK | hw | (8 << MPIC_VECPRI_PRIORITY_SHIFT); - mpic_irq_write(hw, MPIC_IRQ_VECTOR_PRI, vecpri); - - pr_debug("mpic: mapping as IRQ\n"); + /* Reconfigure irq. We must preserve the mask bit as we can be called + * while the interrupt is still active (This may change in the future + * but for now, it is the case). + */ + spin_lock_irqsave(&mpic_lock, iflags); + v = mpic_irq_read(hw, MPIC_IRQ_VECTOR_PRI); + vecpri = (v & + ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK)) | + vecpri; + if (vecpri != v) + mpic_irq_write(hw, MPIC_IRQ_VECTOR_PRI, vecpri); + spin_unlock_irqrestore(&mpic_lock, iflags); + + pr_debug("mpic: mapping as IRQ, vecpri = 0x%08x (was 0x%08x)\n", + vecpri, v); set_irq_chip_data(virq, mpic); set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq); @@ -904,8 +920,8 @@ void __init mpic_init(struct mpic *mpic) /* do senses munging */ if (mpic->senses && i < mpic->senses_count) - vecpri = mpic_flags_to_vecpri(mpic->senses[i], - &level); + vecpri |= mpic_flags_to_vecpri(mpic->senses[i], + &level); else vecpri |= MPIC_VECPRI_SENSE_LEVEL; @@ -955,14 +971,17 @@ void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) void __init mpic_set_serial_int(struct mpic *mpic, int enable) { + unsigned long flags; u32 v; + spin_lock_irqsave(&mpic_lock, flags); v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1); if (enable) v |= MPIC_GREG_GLOBAL_CONF_1_SIE; else v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE; mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v); + spin_unlock_irqrestore(&mpic_lock, flags); } void mpic_irq_set_priority(unsigned int irq, unsigned int pri) diff --git a/include/asm-powerpc/cputime.h b/include/asm-powerpc/cputime.h index a21185d4788..31080448520 100644 --- a/include/asm-powerpc/cputime.h +++ b/include/asm-powerpc/cputime.h @@ -43,6 +43,7 @@ typedef u64 cputime64_t; #define cputime64_zero ((cputime64_t)0) #define cputime64_add(__a, __b) ((__a) + (__b)) +#define cputime64_sub(__a, __b) ((__a) - (__b)) #define cputime_to_cputime64(__ct) (__ct) #ifdef __KERNEL__ @@ -74,6 +75,23 @@ static inline cputime_t jiffies_to_cputime(const unsigned long jif) return ct; } +static inline cputime64_t jiffies64_to_cputime64(const u64 jif) +{ + cputime_t ct; + u64 sec; + + /* have to be a little careful about overflow */ + ct = jif % HZ; + sec = jif / HZ; + if (ct) { + ct *= tb_ticks_per_sec; + do_div(ct, HZ); + } + if (sec) + ct += (cputime_t) sec * tb_ticks_per_sec; + return ct; +} + static inline u64 cputime64_to_jiffies64(const cputime_t ct) { return mulhdu(ct, __cputime_jiffies_factor); |