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 | |||
528 | 528 | ||
529 | ifdef INSTALL_MOD_STRIP | 529 | ifdef INSTALL_MOD_STRIP |
530 | ifeq ($(INSTALL_MOD_STRIP),1) | 530 | ifeq ($(INSTALL_MOD_STRIP),1) |
531 | mod_strip_cmd = $STRIP) --strip-debug | 531 | mod_strip_cmd = $(STRIP) --strip-debug |
532 | else | 532 | else |
533 | mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) | 533 | mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) |
534 | endif # INSTALL_MOD_STRIP=1 | 534 | endif # INSTALL_MOD_STRIP=1 |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 7d31d7cc392d..9cecebaa0360 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) | |||
405 | unsigned int loops = 100000; | 405 | unsigned int loops = 100000; |
406 | struct mpic *mpic = mpic_from_irq(irq); | 406 | struct mpic *mpic = mpic_from_irq(irq); |
407 | unsigned int src = mpic_irq_to_hw(irq); | 407 | unsigned int src = mpic_irq_to_hw(irq); |
408 | unsigned long flags; | ||
408 | 409 | ||
409 | DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); | 410 | DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); |
410 | 411 | ||
412 | spin_lock_irqsave(&mpic_lock, flags); | ||
411 | mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, | 413 | mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, |
412 | mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & | 414 | mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & |
413 | ~MPIC_VECPRI_MASK); | 415 | ~MPIC_VECPRI_MASK); |
414 | |||
415 | /* make sure mask gets to controller before we return to user */ | 416 | /* make sure mask gets to controller before we return to user */ |
416 | do { | 417 | do { |
417 | if (!loops--) { | 418 | if (!loops--) { |
418 | printk(KERN_ERR "mpic_enable_irq timeout\n"); | 419 | printk(KERN_ERR "mpic_enable_irq timeout\n"); |
419 | break; | 420 | break; |
420 | } | 421 | } |
421 | } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); | 422 | } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); |
423 | spin_unlock_irqrestore(&mpic_lock, flags); | ||
422 | } | 424 | } |
423 | 425 | ||
424 | static void mpic_mask_irq(unsigned int irq) | 426 | static void mpic_mask_irq(unsigned int irq) |
@@ -426,9 +428,11 @@ static void mpic_mask_irq(unsigned int irq) | |||
426 | unsigned int loops = 100000; | 428 | unsigned int loops = 100000; |
427 | struct mpic *mpic = mpic_from_irq(irq); | 429 | struct mpic *mpic = mpic_from_irq(irq); |
428 | unsigned int src = mpic_irq_to_hw(irq); | 430 | unsigned int src = mpic_irq_to_hw(irq); |
431 | unsigned long flags; | ||
429 | 432 | ||
430 | DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); | 433 | DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); |
431 | 434 | ||
435 | spin_lock_irqsave(&mpic_lock, flags); | ||
432 | mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, | 436 | mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, |
433 | mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | | 437 | mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | |
434 | MPIC_VECPRI_MASK); | 438 | MPIC_VECPRI_MASK); |
@@ -440,6 +444,7 @@ static void mpic_mask_irq(unsigned int irq) | |||
440 | break; | 444 | break; |
441 | } | 445 | } |
442 | } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); | 446 | } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); |
447 | spin_unlock_irqrestore(&mpic_lock, flags); | ||
443 | } | 448 | } |
444 | 449 | ||
445 | static void mpic_end_irq(unsigned int irq) | 450 | static void mpic_end_irq(unsigned int irq) |
@@ -624,9 +629,10 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, | |||
624 | struct irq_desc *desc = get_irq_desc(virq); | 629 | struct irq_desc *desc = get_irq_desc(virq); |
625 | struct irq_chip *chip; | 630 | struct irq_chip *chip; |
626 | struct mpic *mpic = h->host_data; | 631 | struct mpic *mpic = h->host_data; |
627 | unsigned int vecpri = MPIC_VECPRI_SENSE_LEVEL | | 632 | u32 v, vecpri = MPIC_VECPRI_SENSE_LEVEL | |
628 | MPIC_VECPRI_POLARITY_NEGATIVE; | 633 | MPIC_VECPRI_POLARITY_NEGATIVE; |
629 | int level; | 634 | int level; |
635 | unsigned long iflags; | ||
630 | 636 | ||
631 | pr_debug("mpic: map virq %d, hwirq 0x%lx, flags: 0x%x\n", | 637 | pr_debug("mpic: map virq %d, hwirq 0x%lx, flags: 0x%x\n", |
632 | virq, hw, flags); | 638 | virq, hw, flags); |
@@ -668,11 +674,21 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, | |||
668 | } | 674 | } |
669 | #endif | 675 | #endif |
670 | 676 | ||
671 | /* Reconfigure irq */ | 677 | /* Reconfigure irq. We must preserve the mask bit as we can be called |
672 | vecpri |= MPIC_VECPRI_MASK | hw | (8 << MPIC_VECPRI_PRIORITY_SHIFT); | 678 | * while the interrupt is still active (This may change in the future |
673 | mpic_irq_write(hw, MPIC_IRQ_VECTOR_PRI, vecpri); | 679 | * but for now, it is the case). |
674 | 680 | */ | |
675 | pr_debug("mpic: mapping as IRQ\n"); | 681 | spin_lock_irqsave(&mpic_lock, iflags); |
682 | v = mpic_irq_read(hw, MPIC_IRQ_VECTOR_PRI); | ||
683 | vecpri = (v & | ||
684 | ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK)) | | ||
685 | vecpri; | ||
686 | if (vecpri != v) | ||
687 | mpic_irq_write(hw, MPIC_IRQ_VECTOR_PRI, vecpri); | ||
688 | spin_unlock_irqrestore(&mpic_lock, iflags); | ||
689 | |||
690 | pr_debug("mpic: mapping as IRQ, vecpri = 0x%08x (was 0x%08x)\n", | ||
691 | vecpri, v); | ||
676 | 692 | ||
677 | set_irq_chip_data(virq, mpic); | 693 | set_irq_chip_data(virq, mpic); |
678 | set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq); | 694 | set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq); |
@@ -904,8 +920,8 @@ void __init mpic_init(struct mpic *mpic) | |||
904 | 920 | ||
905 | /* do senses munging */ | 921 | /* do senses munging */ |
906 | if (mpic->senses && i < mpic->senses_count) | 922 | if (mpic->senses && i < mpic->senses_count) |
907 | vecpri = mpic_flags_to_vecpri(mpic->senses[i], | 923 | vecpri |= mpic_flags_to_vecpri(mpic->senses[i], |
908 | &level); | 924 | &level); |
909 | else | 925 | else |
910 | vecpri |= MPIC_VECPRI_SENSE_LEVEL; | 926 | vecpri |= MPIC_VECPRI_SENSE_LEVEL; |
911 | 927 | ||
@@ -955,14 +971,17 @@ void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) | |||
955 | 971 | ||
956 | void __init mpic_set_serial_int(struct mpic *mpic, int enable) | 972 | void __init mpic_set_serial_int(struct mpic *mpic, int enable) |
957 | { | 973 | { |
974 | unsigned long flags; | ||
958 | u32 v; | 975 | u32 v; |
959 | 976 | ||
977 | spin_lock_irqsave(&mpic_lock, flags); | ||
960 | v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1); | 978 | v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1); |
961 | if (enable) | 979 | if (enable) |
962 | v |= MPIC_GREG_GLOBAL_CONF_1_SIE; | 980 | v |= MPIC_GREG_GLOBAL_CONF_1_SIE; |
963 | else | 981 | else |
964 | v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE; | 982 | v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE; |
965 | mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v); | 983 | mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v); |
984 | spin_unlock_irqrestore(&mpic_lock, flags); | ||
966 | } | 985 | } |
967 | 986 | ||
968 | void mpic_irq_set_priority(unsigned int irq, unsigned int pri) | 987 | 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 a21185d47883..310804485208 100644 --- a/include/asm-powerpc/cputime.h +++ b/include/asm-powerpc/cputime.h | |||
@@ -43,6 +43,7 @@ typedef u64 cputime64_t; | |||
43 | 43 | ||
44 | #define cputime64_zero ((cputime64_t)0) | 44 | #define cputime64_zero ((cputime64_t)0) |
45 | #define cputime64_add(__a, __b) ((__a) + (__b)) | 45 | #define cputime64_add(__a, __b) ((__a) + (__b)) |
46 | #define cputime64_sub(__a, __b) ((__a) - (__b)) | ||
46 | #define cputime_to_cputime64(__ct) (__ct) | 47 | #define cputime_to_cputime64(__ct) (__ct) |
47 | 48 | ||
48 | #ifdef __KERNEL__ | 49 | #ifdef __KERNEL__ |
@@ -74,6 +75,23 @@ static inline cputime_t jiffies_to_cputime(const unsigned long jif) | |||
74 | return ct; | 75 | return ct; |
75 | } | 76 | } |
76 | 77 | ||
78 | static inline cputime64_t jiffies64_to_cputime64(const u64 jif) | ||
79 | { | ||
80 | cputime_t ct; | ||
81 | u64 sec; | ||
82 | |||
83 | /* have to be a little careful about overflow */ | ||
84 | ct = jif % HZ; | ||
85 | sec = jif / HZ; | ||
86 | if (ct) { | ||
87 | ct *= tb_ticks_per_sec; | ||
88 | do_div(ct, HZ); | ||
89 | } | ||
90 | if (sec) | ||
91 | ct += (cputime_t) sec * tb_ticks_per_sec; | ||
92 | return ct; | ||
93 | } | ||
94 | |||
77 | static inline u64 cputime64_to_jiffies64(const cputime_t ct) | 95 | static inline u64 cputime64_to_jiffies64(const cputime_t ct) |
78 | { | 96 | { |
79 | return mulhdu(ct, __cputime_jiffies_factor); | 97 | return mulhdu(ct, __cputime_jiffies_factor); |