int __cpuinit r4k_clockevent_init(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq; if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; if (!c0_compare_int_usable()) #ifdef CONFIG_MIPS_GOLDFISH /* FIXME: this is not a reliable test with QEMU */ ; #else return -ENXIO; #endif /* * With vectored interrupts things are getting platform specific. * get_c0_compare_int is a hook to allow a platform to return the * interrupt number of it's liking. */ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; if (get_c0_compare_int) irq = get_c0_compare_int(); cd = &per_cpu(mips_clockevent_device, cpu); cd->name = "MIPS"; cd->features = CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, mips_hpt_frequency); /* Calculate the min / max delta */ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = mips_next_event; cd->set_mode = mips_set_clock_mode; cd->event_handler = mips_event_handler; clockevents_register_device(cd); if (cp0_timer_irq_installed) return 0; cp0_timer_irq_installed = 1; setup_irq(irq, &c0_compare_irqaction); return 0; }
int __cpuinit mips_clockevent_init(void) { uint64_t mips_freq = mips_hpt_frequency; unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq; if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; if (!c0_compare_int_usable()) return -ENXIO; /* * With vectored interrupts things are getting platform specific. * get_c0_compare_int is a hook to allow a platform to return the * interrupt number of it's liking. */ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; if (get_c0_compare_int) irq = get_c0_compare_int(); cd = &per_cpu(mips_clockevent_device, cpu); cd->name = "MIPS"; cd->features = CLOCK_EVT_FEAT_ONESHOT; /* Calculate the min / max delta */ cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); cd->shift = 32; cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = mips_next_event; cd->set_mode = mips_set_clock_mode; cd->event_handler = mips_event_handler; clockevents_register_device(cd); if (cp0_timer_irq_installed) return 0; cp0_timer_irq_installed = 1; setup_irq(irq, &c0_compare_irqaction); return 0; }
int __cpuinit r4k_clockevent_init(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq; if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; if (!c0_compare_int_usable()) return -ENXIO; /* */ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; if (get_c0_compare_int) irq = get_c0_compare_int(); cd = &per_cpu(mips_clockevent_device, cpu); cd->name = "MIPS"; cd->features = CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, mips_hpt_frequency); /* */ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = mips_next_event; cd->set_mode = mips_set_clock_mode; cd->event_handler = mips_event_handler; clockevents_register_device(cd); if (cp0_timer_irq_installed) return 0; cp0_timer_irq_installed = 1; setup_irq(irq, &c0_compare_irqaction); return 0; }
int __cpuinit r4k_clockevent_init(void) { uint64_t mips_freq = mips_hpt_frequency; unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq; if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; if (!c0_compare_int_usable()) #if defined(CONFIG_MACH_AR934x) || defined(CONFIG_MACH_AR7100) /* * The above test seems to randomly fail on Wasp. This * results in timer isr not getting registered. Later, * when the cpu receives a timer interrupt and tries * to handle it, the corresponding data structures are * not initialzed properly resulting in a panic */ printk("%s: Ignoring int_usable failure\n", __func__); #else return -ENXIO; #endif /* * With vectored interrupts things are getting platform specific. * get_c0_compare_int is a hook to allow a platform to return the * interrupt number of it's liking. */ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; if (get_c0_compare_int) irq = get_c0_compare_int(); cd = &per_cpu(mips_clockevent_device, cpu); cd->name = "MIPS"; cd->features = CLOCK_EVT_FEAT_ONESHOT; /* Calculate the min / max delta */ cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); cd->shift = 32; cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; cd->irq = irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = mips_next_event; cd->set_mode = mips_set_clock_mode; cd->event_handler = mips_event_handler; clockevents_register_device(cd); if (cp0_timer_irq_installed) return 0; cp0_timer_irq_installed = 1; setup_irq(irq, &c0_compare_irqaction); return 0; }
int __cpuinit mips_clockevent_init(void) { uint64_t mips_freq = mips_hpt_frequency; unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq; if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; #ifdef CONFIG_MIPS_MT_SMTC setup_smtc_dummy_clockevent_device(); /* * On SMTC we only register VPE0's compare interrupt as clockevent * device. */ if (cpu) return 0; #endif if (!c0_compare_int_usable()) return -ENXIO; /* * With vectored interrupts things are getting platform specific. * get_c0_compare_int is a hook to allow a platform to return the * interrupt number of it's liking. */ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; if (get_c0_compare_int) irq = get_c0_compare_int(); cd = &per_cpu(mips_clockevent_device, cpu); cd->name = "MIPS"; cd->features = CLOCK_EVT_FEAT_ONESHOT; /* Calculate the min / max delta */ cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); cd->shift = 32; cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; cd->irq = irq; #ifdef CONFIG_MIPS_MT_SMTC cd->cpumask = CPU_MASK_ALL; #else cd->cpumask = cpumask_of_cpu(cpu); #endif cd->set_next_event = mips_next_event; cd->set_mode = mips_set_mode; cd->event_handler = mips_event_handler; clockevents_register_device(cd); if (cp0_timer_irq_installed) return 0; cp0_timer_irq_installed = 1; #ifdef CONFIG_MIPS_MT_SMTC #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); #else setup_irq(irq, &c0_compare_irqaction); #endif return 0; }