diff options
author | David S. Miller <davem@davemloft.net> | 2008-09-13 22:47:43 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-09-19 21:18:02 -0700 |
commit | 8bd8deead7f00006781c366887da8cf6a02c69ce (patch) | |
tree | 79a964a943a01990ba676d4a5cc49988a82fa26d /arch/sparc/kernel | |
parent | 45bb5a7cbfa28dedc07730d6ecedbd574faf5459 (diff) |
sparc32: Use PROM device probing for sun4c timers.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/sun4c_irq.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c index 8033132eda8..92096ba31d5 100644 --- a/arch/sparc/kernel/sun4c_irq.c +++ b/arch/sparc/kernel/sun4c_irq.c @@ -119,16 +119,18 @@ static void sun4c_enable_irq(unsigned int irq_nr) local_irq_restore(flags); } -#define TIMER_IRQ 10 /* Also at level 14, but we ignore that one. */ -#define PROFILE_IRQ 14 /* Level14 ticker.. used by OBP for polling */ +struct sun4c_timer_info { + u32 l10_count; + u32 l10_limit; + u32 l14_count; + u32 l14_limit; +}; -volatile struct sun4c_timer_info *sun4c_timers; +static struct sun4c_timer_info __iomem *sun4c_timers; static void sun4c_clear_clock_irq(void) { - volatile unsigned int clear_intr; - - clear_intr = sun4c_timers->timer_limit10; + sbus_readl(&sun4c_timers->l10_limit); } static void sun4c_load_profile_irq(int cpu, unsigned int limit) @@ -138,32 +140,49 @@ static void sun4c_load_profile_irq(int cpu, unsigned int limit) static void __init sun4c_init_timers(irq_handler_t counter_fn) { - int irq; + const struct linux_prom_irqs *irq; + struct device_node *dp; + const u32 *addr; + int err; - /* Map the Timer chip, this is implemented in hardware inside - * the cache chip on the sun4c. - */ - sun4c_timers = ioremap(SUN_TIMER_PHYSADDR, - sizeof(struct sun4c_timer_info)); + dp = of_find_node_by_name(NULL, "counter-timer"); + if (!dp) { + prom_printf("sun4c_init_timers: Unable to find counter-timer\n"); + prom_halt(); + } + + addr = of_get_property(dp, "address", NULL); + if (!addr) { + prom_printf("sun4c_init_timers: No address property\n"); + prom_halt(); + } + + sun4c_timers = (void __iomem *) (unsigned long) addr[0]; + + irq = of_get_property(dp, "intr", NULL); + if (!irq) { + prom_printf("sun4c_init_timers: No intr property\n"); + prom_halt(); + } /* Have the level 10 timer tick at 100HZ. We don't touch the * level 14 timer limit since we are letting the prom handle * them until we have a real console driver so L1-A works. */ - sun4c_timers->timer_limit10 = (((1000000/HZ) + 1) << 10); - master_l10_counter = &sun4c_timers->cur_count10; - master_l10_limit = &sun4c_timers->timer_limit10; + sbus_writel((((1000000/HZ) + 1) << 10), &sun4c_timers->l10_limit); + + master_l10_counter = &sun4c_timers->l10_count; + master_l10_limit = &sun4c_timers->l10_limit; - irq = request_irq(TIMER_IRQ, - counter_fn, + err = request_irq(irq[0].pri, counter_fn, (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); - if (irq) { - prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ); + if (err) { + prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err); prom_halt(); } - sun4c_disable_irq(PROFILE_IRQ); + sun4c_disable_irq(irq[1].pri); } #ifdef CONFIG_SMP |