aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/sun4m_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/sun4m_irq.c')
-rw-r--r--arch/sparc/kernel/sun4m_irq.c58
1 files changed, 20 insertions, 38 deletions
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index e61165161dd3..c5ade9d27a1d 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -112,9 +112,6 @@ struct sun4m_handler_data {
112#define SUN4M_INT_E14 0x00000080 112#define SUN4M_INT_E14 0x00000080
113#define SUN4M_INT_E10 0x00080000 113#define SUN4M_INT_E10 0x00080000
114 114
115#define SUN4M_HARD_INT(x) (0x000000001 << (x))
116#define SUN4M_SOFT_INT(x) (0x000010000 << (x))
117
118#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ 115#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */
119#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ 116#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */
120#define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */ 117#define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */
@@ -282,23 +279,6 @@ out:
282 return irq; 279 return irq;
283} 280}
284 281
285#ifdef CONFIG_SMP
286static void sun4m_send_ipi(int cpu, int level)
287{
288 sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
289}
290
291static void sun4m_clear_ipi(int cpu, int level)
292{
293 sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->clear);
294}
295
296static void sun4m_set_udt(int cpu)
297{
298 sbus_writel(cpu, &sun4m_irq_global->interrupt_target);
299}
300#endif
301
302struct sun4m_timer_percpu { 282struct sun4m_timer_percpu {
303 u32 l14_limit; 283 u32 l14_limit;
304 u32 l14_count; 284 u32 l14_count;
@@ -318,9 +298,6 @@ struct sun4m_timer_global {
318 298
319static struct sun4m_timer_global __iomem *timers_global; 299static struct sun4m_timer_global __iomem *timers_global;
320 300
321
322unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10);
323
324static void sun4m_clear_clock_irq(void) 301static void sun4m_clear_clock_irq(void)
325{ 302{
326 sbus_readl(&timers_global->l10_limit); 303 sbus_readl(&timers_global->l10_limit);
@@ -369,10 +346,11 @@ void sun4m_clear_profile_irq(int cpu)
369 346
370static void sun4m_load_profile_irq(int cpu, unsigned int limit) 347static void sun4m_load_profile_irq(int cpu, unsigned int limit)
371{ 348{
372 sbus_writel(limit, &timers_percpu[cpu]->l14_limit); 349 unsigned int value = limit ? timer_value(limit) : 0;
350 sbus_writel(value, &timers_percpu[cpu]->l14_limit);
373} 351}
374 352
375static void __init sun4m_init_timers(irq_handler_t counter_fn) 353static void __init sun4m_init_timers(void)
376{ 354{
377 struct device_node *dp = of_find_node_by_name(NULL, "counter"); 355 struct device_node *dp = of_find_node_by_name(NULL, "counter");
378 int i, err, len, num_cpu_timers; 356 int i, err, len, num_cpu_timers;
@@ -402,13 +380,22 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
402 /* Every per-cpu timer works in timer mode */ 380 /* Every per-cpu timer works in timer mode */
403 sbus_writel(0x00000000, &timers_global->timer_config); 381 sbus_writel(0x00000000, &timers_global->timer_config);
404 382
405 sbus_writel((((1000000/HZ) + 1) << 10), &timers_global->l10_limit); 383#ifdef CONFIG_SMP
384 sparc_config.cs_period = SBUS_CLOCK_RATE * 2; /* 2 seconds */
385 sparc_config.features |= FEAT_L14_ONESHOT;
386#else
387 sparc_config.cs_period = SBUS_CLOCK_RATE / HZ; /* 1/HZ sec */
388 sparc_config.features |= FEAT_L10_CLOCKEVENT;
389#endif
390 sparc_config.features |= FEAT_L10_CLOCKSOURCE;
391 sbus_writel(timer_value(sparc_config.cs_period),
392 &timers_global->l10_limit);
406 393
407 master_l10_counter = &timers_global->l10_count; 394 master_l10_counter = &timers_global->l10_count;
408 395
409 irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ); 396 irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ);
410 397
411 err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL); 398 err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
412 if (err) { 399 if (err) {
413 printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n", 400 printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n",
414 err); 401 err);
@@ -434,7 +421,7 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
434 trap_table->inst_two = lvl14_save[1]; 421 trap_table->inst_two = lvl14_save[1];
435 trap_table->inst_three = lvl14_save[2]; 422 trap_table->inst_three = lvl14_save[2];
436 trap_table->inst_four = lvl14_save[3]; 423 trap_table->inst_four = lvl14_save[3];
437 local_flush_cache_all(); 424 local_ops->cache_all();
438 local_irq_restore(flags); 425 local_irq_restore(flags);
439 } 426 }
440#endif 427#endif
@@ -475,17 +462,12 @@ void __init sun4m_init_IRQ(void)
475 if (num_cpu_iregs == 4) 462 if (num_cpu_iregs == 4)
476 sbus_writel(0, &sun4m_irq_global->interrupt_target); 463 sbus_writel(0, &sun4m_irq_global->interrupt_target);
477 464
478 BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM); 465 sparc_config.init_timers = sun4m_init_timers;
479 BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM); 466 sparc_config.build_device_irq = sun4m_build_device_irq;
480 467 sparc_config.clock_rate = SBUS_CLOCK_RATE;
481 sparc_irq_config.init_timers = sun4m_init_timers; 468 sparc_config.clear_clock_irq = sun4m_clear_clock_irq;
482 sparc_irq_config.build_device_irq = sun4m_build_device_irq; 469 sparc_config.load_profile_irq = sun4m_load_profile_irq;
483 470
484#ifdef CONFIG_SMP
485 BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM);
486 BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM);
487 BTFIXUPSET_CALL(set_irq_udt, sun4m_set_udt, BTFIXUPCALL_NORM);
488#endif
489 471
490 /* Cannot enable interrupts until OBP ticker is disabled. */ 472 /* Cannot enable interrupts until OBP ticker is disabled. */
491} 473}