Loading arch/sparc/include/asm/timer_32.h +0 −13 Original line number Original line Diff line number Diff line Loading @@ -35,19 +35,6 @@ struct sun4c_timer_info { #define SUN_TIMER_PHYSADDR 0xf3000000 #define SUN_TIMER_PHYSADDR 0xf3000000 #define SUN4D_PRM_CNT_L 0x80000000 #define SUN4D_PRM_CNT_LVALUE 0x7FFFFC00 struct sun4d_timer_regs { volatile unsigned int l10_timer_limit; volatile unsigned int l10_cur_countx; volatile unsigned int l10_limit_noclear; volatile unsigned int ctrl; volatile unsigned int l10_cur_count; }; extern struct sun4d_timer_regs *sun4d_timers; extern __volatile__ unsigned int *master_l10_counter; extern __volatile__ unsigned int *master_l10_counter; extern __volatile__ unsigned int *master_l10_limit; extern __volatile__ unsigned int *master_l10_limit; Loading arch/sparc/kernel/sun4d_irq.c +83 −56 Original line number Original line Diff line number Diff line Loading @@ -45,7 +45,16 @@ /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ /* #define DISTRIBUTE_IRQS */ /* #define DISTRIBUTE_IRQS */ struct sun4d_timer_regs *sun4d_timers; struct sun4d_timer_regs { u32 l10_timer_limit; u32 l10_cur_countx; u32 l10_limit_noclear; u32 ctrl; u32 l10_cur_count; }; static struct sun4d_timer_regs __iomem *sun4d_timers; #define TIMER_IRQ 10 #define TIMER_IRQ 10 #define MAX_STATIC_ALLOC 4 #define MAX_STATIC_ALLOC 4 Loading Loading @@ -446,8 +455,7 @@ void __init sun4d_distribute_irqs(void) static void sun4d_clear_clock_irq(void) static void sun4d_clear_clock_irq(void) { { volatile unsigned int clear_intr; sbus_readl(&sun4d_timers->l10_timer_limit); clear_intr = sun4d_timers->l10_timer_limit; } } static void sun4d_clear_profile_irq(int cpu) static void sun4d_clear_profile_irq(int cpu) Loading @@ -460,48 +468,19 @@ static void sun4d_load_profile_irq(int cpu, unsigned int limit) bw_set_prof_limit(cpu, limit); bw_set_prof_limit(cpu, limit); } } static void __init sun4d_init_timers(irq_handler_t counter_fn) static void __init sun4d_load_profile_irqs(void) { { int irq; int cpu = 0, mid; int cpu; struct resource r; int mid; /* Map the User Timer registers. */ memset(&r, 0, sizeof(r)); #ifdef CONFIG_SMP r.start = CSR_BASE(boot_cpu_id)+BW_TIMER_LIMIT; #else r.start = CSR_BASE(0)+BW_TIMER_LIMIT; #endif r.flags = 0xf; sun4d_timers = (struct sun4d_timer_regs *) of_ioremap(&r, 0, PAGE_SIZE, "user timer"); sun4d_timers->l10_timer_limit = (((1000000/HZ) + 1) << 10); master_l10_counter = &sun4d_timers->l10_cur_count; master_l10_limit = &sun4d_timers->l10_timer_limit; irq = request_irq(TIMER_IRQ, counter_fn, (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); if (irq) { prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ); prom_halt(); } /* Enable user timer free run for CPU 0 in BW */ /* bw_set_ctrl(0, bw_get_ctrl(0) | BW_CTRL_USER_TIMER); */ cpu = 0; while (!cpu_find_by_instance(cpu, NULL, &mid)) { while (!cpu_find_by_instance(cpu, NULL, &mid)) { sun4d_load_profile_irq(mid >> 3, 0); sun4d_load_profile_irq(mid >> 3, 0); cpu++; cpu++; } } } #ifdef CONFIG_SMP static void __init sun4d_fixup_trap_table(void) { { #ifdef CONFIG_SMP unsigned long flags; unsigned long flags; extern unsigned long lvl14_save[4]; extern unsigned long lvl14_save[4]; struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; Loading @@ -523,10 +502,58 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn) trap_table->inst_four = lvl14_save[3]; trap_table->inst_four = lvl14_save[3]; local_flush_cache_all(); local_flush_cache_all(); local_irq_restore(flags); local_irq_restore(flags); } #endif #endif } } static void __init sun4d_init_timers(irq_handler_t counter_fn) { struct device_node *dp; struct resource res; const u32 *reg; int err; dp = of_find_node_by_name(NULL, "cpu-unit"); if (!dp) { prom_printf("sun4d_init_timers: Unable to find cpu-unit\n"); prom_halt(); } /* Which cpu-unit we use is arbitrary, we can view the bootbus timer * registers via any cpu's mapping. The first 'reg' property is the * bootbus. */ reg = of_get_property(dp, "reg", NULL); if (!reg) { prom_printf("sun4d_init_timers: No reg property\n"); prom_halt(); } res.start = reg[1]; res.end = reg[2] - 1; res.flags = reg[0] & 0xff; sun4d_timers = of_ioremap(&res, BW_TIMER_LIMIT, sizeof(struct sun4d_timer_regs), "user timer"); if (!sun4d_timers) { prom_printf("sun4d_init_timers: Can't map timer regs\n"); prom_halt(); } sbus_writel((((1000000/HZ) + 1) << 10), &sun4d_timers->l10_timer_limit); master_l10_counter = &sun4d_timers->l10_cur_count; master_l10_limit = &sun4d_timers->l10_timer_limit; err = request_irq(TIMER_IRQ, counter_fn, (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); if (err) { prom_printf("sun4d_init_timers: request_irq() failed with %d\n", err); prom_halt(); } sun4d_load_profile_irqs(); sun4d_fixup_trap_table(); } void __init sun4d_init_sbi_irq(void) void __init sun4d_init_sbi_irq(void) { { struct device_node *dp; struct device_node *dp; Loading Loading
arch/sparc/include/asm/timer_32.h +0 −13 Original line number Original line Diff line number Diff line Loading @@ -35,19 +35,6 @@ struct sun4c_timer_info { #define SUN_TIMER_PHYSADDR 0xf3000000 #define SUN_TIMER_PHYSADDR 0xf3000000 #define SUN4D_PRM_CNT_L 0x80000000 #define SUN4D_PRM_CNT_LVALUE 0x7FFFFC00 struct sun4d_timer_regs { volatile unsigned int l10_timer_limit; volatile unsigned int l10_cur_countx; volatile unsigned int l10_limit_noclear; volatile unsigned int ctrl; volatile unsigned int l10_cur_count; }; extern struct sun4d_timer_regs *sun4d_timers; extern __volatile__ unsigned int *master_l10_counter; extern __volatile__ unsigned int *master_l10_counter; extern __volatile__ unsigned int *master_l10_limit; extern __volatile__ unsigned int *master_l10_limit; Loading
arch/sparc/kernel/sun4d_irq.c +83 −56 Original line number Original line Diff line number Diff line Loading @@ -45,7 +45,16 @@ /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ /* #define DISTRIBUTE_IRQS */ /* #define DISTRIBUTE_IRQS */ struct sun4d_timer_regs *sun4d_timers; struct sun4d_timer_regs { u32 l10_timer_limit; u32 l10_cur_countx; u32 l10_limit_noclear; u32 ctrl; u32 l10_cur_count; }; static struct sun4d_timer_regs __iomem *sun4d_timers; #define TIMER_IRQ 10 #define TIMER_IRQ 10 #define MAX_STATIC_ALLOC 4 #define MAX_STATIC_ALLOC 4 Loading Loading @@ -446,8 +455,7 @@ void __init sun4d_distribute_irqs(void) static void sun4d_clear_clock_irq(void) static void sun4d_clear_clock_irq(void) { { volatile unsigned int clear_intr; sbus_readl(&sun4d_timers->l10_timer_limit); clear_intr = sun4d_timers->l10_timer_limit; } } static void sun4d_clear_profile_irq(int cpu) static void sun4d_clear_profile_irq(int cpu) Loading @@ -460,48 +468,19 @@ static void sun4d_load_profile_irq(int cpu, unsigned int limit) bw_set_prof_limit(cpu, limit); bw_set_prof_limit(cpu, limit); } } static void __init sun4d_init_timers(irq_handler_t counter_fn) static void __init sun4d_load_profile_irqs(void) { { int irq; int cpu = 0, mid; int cpu; struct resource r; int mid; /* Map the User Timer registers. */ memset(&r, 0, sizeof(r)); #ifdef CONFIG_SMP r.start = CSR_BASE(boot_cpu_id)+BW_TIMER_LIMIT; #else r.start = CSR_BASE(0)+BW_TIMER_LIMIT; #endif r.flags = 0xf; sun4d_timers = (struct sun4d_timer_regs *) of_ioremap(&r, 0, PAGE_SIZE, "user timer"); sun4d_timers->l10_timer_limit = (((1000000/HZ) + 1) << 10); master_l10_counter = &sun4d_timers->l10_cur_count; master_l10_limit = &sun4d_timers->l10_timer_limit; irq = request_irq(TIMER_IRQ, counter_fn, (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); if (irq) { prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ); prom_halt(); } /* Enable user timer free run for CPU 0 in BW */ /* bw_set_ctrl(0, bw_get_ctrl(0) | BW_CTRL_USER_TIMER); */ cpu = 0; while (!cpu_find_by_instance(cpu, NULL, &mid)) { while (!cpu_find_by_instance(cpu, NULL, &mid)) { sun4d_load_profile_irq(mid >> 3, 0); sun4d_load_profile_irq(mid >> 3, 0); cpu++; cpu++; } } } #ifdef CONFIG_SMP static void __init sun4d_fixup_trap_table(void) { { #ifdef CONFIG_SMP unsigned long flags; unsigned long flags; extern unsigned long lvl14_save[4]; extern unsigned long lvl14_save[4]; struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; Loading @@ -523,10 +502,58 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn) trap_table->inst_four = lvl14_save[3]; trap_table->inst_four = lvl14_save[3]; local_flush_cache_all(); local_flush_cache_all(); local_irq_restore(flags); local_irq_restore(flags); } #endif #endif } } static void __init sun4d_init_timers(irq_handler_t counter_fn) { struct device_node *dp; struct resource res; const u32 *reg; int err; dp = of_find_node_by_name(NULL, "cpu-unit"); if (!dp) { prom_printf("sun4d_init_timers: Unable to find cpu-unit\n"); prom_halt(); } /* Which cpu-unit we use is arbitrary, we can view the bootbus timer * registers via any cpu's mapping. The first 'reg' property is the * bootbus. */ reg = of_get_property(dp, "reg", NULL); if (!reg) { prom_printf("sun4d_init_timers: No reg property\n"); prom_halt(); } res.start = reg[1]; res.end = reg[2] - 1; res.flags = reg[0] & 0xff; sun4d_timers = of_ioremap(&res, BW_TIMER_LIMIT, sizeof(struct sun4d_timer_regs), "user timer"); if (!sun4d_timers) { prom_printf("sun4d_init_timers: Can't map timer regs\n"); prom_halt(); } sbus_writel((((1000000/HZ) + 1) << 10), &sun4d_timers->l10_timer_limit); master_l10_counter = &sun4d_timers->l10_cur_count; master_l10_limit = &sun4d_timers->l10_timer_limit; err = request_irq(TIMER_IRQ, counter_fn, (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); if (err) { prom_printf("sun4d_init_timers: request_irq() failed with %d\n", err); prom_halt(); } sun4d_load_profile_irqs(); sun4d_fixup_trap_table(); } void __init sun4d_init_sbi_irq(void) void __init sun4d_init_sbi_irq(void) { { struct device_node *dp; struct device_node *dp; Loading