aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-01 23:48:54 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-01 23:48:54 -0400
commit1ed4395035a6791ebbbf618429a58ab9c207cc83 (patch)
treea34158c5dd3c4ca70f140da5a484ca6142a3b8c3 /arch/ia64/kernel
parent878701db07db3f0b59f14f0c525b681e4ca81551 (diff)
parentb718f91c14604e4ab5cdfe8d3baff8111425ea7d (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6: [IA64] ITC: Reduce rating for ITC clock if ITCs are drifty [IA64] SN2: Fix up sn2_rtc clock [IA64] Fix wrong access to irq_desc[] in iosapic_register_intr(). [IA64] Fix possible race in destroy_and_reserve_irq() [IA64] Fix registered interrupt check [IA64] Remove a few duplicate includes [IA64] Allow smp_call_function_single() to current cpu [IA64] fix a few section mismatch warnings
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r--arch/ia64/kernel/iosapic.c19
-rw-r--r--arch/ia64/kernel/irq_ia64.c17
-rw-r--r--arch/ia64/kernel/mca.c17
-rw-r--r--arch/ia64/kernel/setup.c1
-rw-r--r--arch/ia64/kernel/smp.c8
-rw-r--r--arch/ia64/kernel/time.c16
6 files changed, 47 insertions, 31 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 91e6dc1e7baf..cfe4654838f4 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -142,7 +142,7 @@ struct iosapic_rte_info {
142static struct iosapic_intr_info { 142static struct iosapic_intr_info {
143 struct list_head rtes; /* RTEs using this vector (empty => 143 struct list_head rtes; /* RTEs using this vector (empty =>
144 * not an IOSAPIC interrupt) */ 144 * not an IOSAPIC interrupt) */
145 int count; /* # of RTEs that shares this vector */ 145 int count; /* # of registered RTEs */
146 u32 low32; /* current value of low word of 146 u32 low32; /* current value of low word of
147 * Redirection table entry */ 147 * Redirection table entry */
148 unsigned int dest; /* destination CPU physical ID */ 148 unsigned int dest; /* destination CPU physical ID */
@@ -313,7 +313,7 @@ mask_irq (unsigned int irq)
313 int rte_index; 313 int rte_index;
314 struct iosapic_rte_info *rte; 314 struct iosapic_rte_info *rte;
315 315
316 if (list_empty(&iosapic_intr_info[irq].rtes)) 316 if (!iosapic_intr_info[irq].count)
317 return; /* not an IOSAPIC interrupt! */ 317 return; /* not an IOSAPIC interrupt! */
318 318
319 /* set only the mask bit */ 319 /* set only the mask bit */
@@ -331,7 +331,7 @@ unmask_irq (unsigned int irq)
331 int rte_index; 331 int rte_index;
332 struct iosapic_rte_info *rte; 332 struct iosapic_rte_info *rte;
333 333
334 if (list_empty(&iosapic_intr_info[irq].rtes)) 334 if (!iosapic_intr_info[irq].count)
335 return; /* not an IOSAPIC interrupt! */ 335 return; /* not an IOSAPIC interrupt! */
336 336
337 low32 = iosapic_intr_info[irq].low32 &= ~IOSAPIC_MASK; 337 low32 = iosapic_intr_info[irq].low32 &= ~IOSAPIC_MASK;
@@ -363,7 +363,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
363 363
364 dest = cpu_physical_id(first_cpu(mask)); 364 dest = cpu_physical_id(first_cpu(mask));
365 365
366 if (list_empty(&iosapic_intr_info[irq].rtes)) 366 if (!iosapic_intr_info[irq].count)
367 return; /* not an IOSAPIC interrupt */ 367 return; /* not an IOSAPIC interrupt */
368 368
369 set_irq_affinity_info(irq, dest, redir); 369 set_irq_affinity_info(irq, dest, redir);
@@ -542,7 +542,7 @@ iosapic_reassign_vector (int irq)
542{ 542{
543 int new_irq; 543 int new_irq;
544 544
545 if (!list_empty(&iosapic_intr_info[irq].rtes)) { 545 if (iosapic_intr_info[irq].count) {
546 new_irq = create_irq(); 546 new_irq = create_irq();
547 if (new_irq < 0) 547 if (new_irq < 0)
548 panic("%s: out of interrupt vectors!\n", __FUNCTION__); 548 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
@@ -560,7 +560,7 @@ iosapic_reassign_vector (int irq)
560 } 560 }
561} 561}
562 562
563static struct iosapic_rte_info *iosapic_alloc_rte (void) 563static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void)
564{ 564{
565 int i; 565 int i;
566 struct iosapic_rte_info *rte; 566 struct iosapic_rte_info *rte;
@@ -677,7 +677,7 @@ get_target_cpu (unsigned int gsi, int irq)
677 * In case of vector shared by multiple RTEs, all RTEs that 677 * In case of vector shared by multiple RTEs, all RTEs that
678 * share the vector need to use the same destination CPU. 678 * share the vector need to use the same destination CPU.
679 */ 679 */
680 if (!list_empty(&iosapic_intr_info[irq].rtes)) 680 if (iosapic_intr_info[irq].count)
681 return iosapic_intr_info[irq].dest; 681 return iosapic_intr_info[irq].dest;
682 682
683 /* 683 /*
@@ -794,8 +794,9 @@ iosapic_register_intr (unsigned int gsi,
794 err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, 794 err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY,
795 polarity, trigger); 795 polarity, trigger);
796 if (err < 0) { 796 if (err < 0) {
797 spin_unlock(&irq_desc[irq].lock);
797 irq = err; 798 irq = err;
798 goto unlock_all; 799 goto unlock_iosapic_lock;
799 } 800 }
800 801
801 /* 802 /*
@@ -811,7 +812,7 @@ iosapic_register_intr (unsigned int gsi,
811 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), 812 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
812 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), 813 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
813 cpu_logical_id(dest), dest, irq_to_vector(irq)); 814 cpu_logical_id(dest), dest, irq_to_vector(irq));
814 unlock_all: 815
815 spin_unlock(&irq_desc[irq].lock); 816 spin_unlock(&irq_desc[irq].lock);
816 unlock_iosapic_lock: 817 unlock_iosapic_lock:
817 spin_unlock_irqrestore(&iosapic_lock, flags); 818 spin_unlock_irqrestore(&iosapic_lock, flags);
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 9386b955eed1..c47c8acc96e3 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -101,15 +101,6 @@ int check_irq_used(int irq)
101 return -1; 101 return -1;
102} 102}
103 103
104static void reserve_irq(unsigned int irq)
105{
106 unsigned long flags;
107
108 spin_lock_irqsave(&vector_lock, flags);
109 irq_status[irq] = IRQ_RSVD;
110 spin_unlock_irqrestore(&vector_lock, flags);
111}
112
113static inline int find_unassigned_irq(void) 104static inline int find_unassigned_irq(void)
114{ 105{
115 int irq; 106 int irq;
@@ -302,10 +293,14 @@ static cpumask_t vector_allocation_domain(int cpu)
302 293
303void destroy_and_reserve_irq(unsigned int irq) 294void destroy_and_reserve_irq(unsigned int irq)
304{ 295{
296 unsigned long flags;
297
305 dynamic_irq_cleanup(irq); 298 dynamic_irq_cleanup(irq);
306 299
307 clear_irq_vector(irq); 300 spin_lock_irqsave(&vector_lock, flags);
308 reserve_irq(irq); 301 __clear_irq_vector(irq);
302 irq_status[irq] = IRQ_RSVD;
303 spin_unlock_irqrestore(&vector_lock, flags);
309} 304}
310 305
311static int __reassign_irq_vector(int irq, int cpu) 306static int __reassign_irq_vector(int irq, int cpu)
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 4b5daa3cc0fe..ff28620cb992 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -1750,8 +1750,17 @@ format_mca_init_stack(void *mca_data, unsigned long offset,
1750 strncpy(p->comm, type, sizeof(p->comm)-1); 1750 strncpy(p->comm, type, sizeof(p->comm)-1);
1751} 1751}
1752 1752
1753/* Do per-CPU MCA-related initialization. */ 1753/* Caller prevents this from being called after init */
1754static void * __init_refok mca_bootmem(void)
1755{
1756 void *p;
1754 1757
1758 p = alloc_bootmem(sizeof(struct ia64_mca_cpu) * NR_CPUS +
1759 KERNEL_STACK_SIZE);
1760 return (void *)ALIGN((unsigned long)p, KERNEL_STACK_SIZE);
1761}
1762
1763/* Do per-CPU MCA-related initialization. */
1755void __cpuinit 1764void __cpuinit
1756ia64_mca_cpu_init(void *cpu_data) 1765ia64_mca_cpu_init(void *cpu_data)
1757{ 1766{
@@ -1763,11 +1772,7 @@ ia64_mca_cpu_init(void *cpu_data)
1763 int cpu; 1772 int cpu;
1764 1773
1765 first_time = 0; 1774 first_time = 0;
1766 mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu) 1775 mca_data = mca_bootmem();
1767 * NR_CPUS + KERNEL_STACK_SIZE);
1768 mca_data = (void *)(((unsigned long)mca_data +
1769 KERNEL_STACK_SIZE - 1) &
1770 (-KERNEL_STACK_SIZE));
1771 for (cpu = 0; cpu < NR_CPUS; cpu++) { 1776 for (cpu = 0; cpu < NR_CPUS; cpu++) {
1772 format_mca_init_stack(mca_data, 1777 format_mca_init_stack(mca_data,
1773 offsetof(struct ia64_mca_cpu, mca_stack), 1778 offsetof(struct ia64_mca_cpu, mca_stack),
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 7cecd2964200..cd9a37a552c3 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -60,7 +60,6 @@
60#include <asm/smp.h> 60#include <asm/smp.h>
61#include <asm/system.h> 61#include <asm/system.h>
62#include <asm/unistd.h> 62#include <asm/unistd.h>
63#include <asm/system.h>
64 63
65#if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE) 64#if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
66# error "struct cpuinfo_ia64 too big!" 65# error "struct cpuinfo_ia64 too big!"
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index 0982882bfb80..4e446aa5f4ac 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -346,7 +346,7 @@ smp_flush_tlb_mm (struct mm_struct *mm)
346} 346}
347 347
348/* 348/*
349 * Run a function on another CPU 349 * Run a function on a specific CPU
350 * <func> The function to run. This must be fast and non-blocking. 350 * <func> The function to run. This must be fast and non-blocking.
351 * <info> An arbitrary pointer to pass to the function. 351 * <info> An arbitrary pointer to pass to the function.
352 * <nonatomic> Currently unused. 352 * <nonatomic> Currently unused.
@@ -366,9 +366,11 @@ smp_call_function_single (int cpuid, void (*func) (void *info), void *info, int
366 int me = get_cpu(); /* prevent preemption and reschedule on another processor */ 366 int me = get_cpu(); /* prevent preemption and reschedule on another processor */
367 367
368 if (cpuid == me) { 368 if (cpuid == me) {
369 printk(KERN_INFO "%s: trying to call self\n", __FUNCTION__); 369 local_irq_disable();
370 func(info);
371 local_irq_enable();
370 put_cpu(); 372 put_cpu();
371 return -EBUSY; 373 return 0;
372 } 374 }
373 375
374 data.func = func; 376 data.func = func;
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 6c0e9e2e1b82..98cfc90cab1d 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -240,7 +240,21 @@ ia64_init_itm (void)
240 if (!nojitter) 240 if (!nojitter)
241 itc_jitter_data.itc_jitter = 1; 241 itc_jitter_data.itc_jitter = 1;
242#endif 242#endif
243 } 243 } else
244 /*
245 * ITC is drifty and we have not synchronized the ITCs in smpboot.c.
246 * ITC values may fluctuate significantly between processors.
247 * Clock should not be used for hrtimers. Mark itc as only
248 * useful for boot and testing.
249 *
250 * Note that jitter compensation is off! There is no point of
251 * synchronizing ITCs since they may be large differentials
252 * that change over time.
253 *
254 * The only way to fix this would be to repeatedly sync the
255 * ITCs. Until that time we have to avoid ITC.
256 */
257 clocksource_itc.rating = 50;
244 258
245 /* Setup the CPU local timer tick */ 259 /* Setup the CPU local timer tick */
246 ia64_cpu_local_tick(); 260 ia64_cpu_local_tick();