aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--arch/powerpc/sysdev/mpic.c39
-rw-r--r--include/asm-powerpc/cputime.h18
3 files changed, 48 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index 11a850cffd3..82f76a96cfe 100644
--- a/Makefile
+++ b/Makefile
@@ -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);