static int __init arch_timer_register(void) { int err; int ppi; arch_timer_evt = alloc_percpu(struct clock_event_device); if (!arch_timer_evt) { err = -ENOMEM; goto out; } if (arch_timer_use_virtual) { ppi = arch_timer_ppi[VIRT_PPI]; err = request_percpu_irq(ppi, arch_timer_handler_virt, "arch_timer", arch_timer_evt); } else { ppi = arch_timer_ppi[PHYS_SECURE_PPI]; err = request_percpu_irq(ppi, arch_timer_handler_phys, "arch_timer", arch_timer_evt); if (!err && arch_timer_ppi[PHYS_NONSECURE_PPI]) { ppi = arch_timer_ppi[PHYS_NONSECURE_PPI]; err = request_percpu_irq(ppi, arch_timer_handler_phys, "arch_timer", arch_timer_evt); if (err) free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], arch_timer_evt); } } if (err) { pr_err("arch_timer: can't register interrupt %d (%d)\n", ppi, err); goto out_free; } err = register_cpu_notifier(&arch_timer_cpu_nb); if (err) goto out_free_irq; /* Immediately configure the timer on the boot CPU */ arch_timer_setup(this_cpu_ptr(arch_timer_evt)); return 0; out_free_irq: if (arch_timer_use_virtual) free_percpu_irq(arch_timer_ppi[VIRT_PPI], arch_timer_evt); else { free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], arch_timer_evt); if (arch_timer_ppi[PHYS_NONSECURE_PPI]) free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], arch_timer_evt); } out_free: free_percpu(arch_timer_evt); out: return err; }
int __init metag_generic_timer_init(void) { /* * On Meta 2 SoCs, the actual frequency of the timer is based on the * Meta core clock speed divided by an integer, so it is only * approximately 1MHz. Calculating the real frequency here drastically * reduces clock skew on these SoCs. */ #ifdef CONFIG_METAG_META21 hwtimer_freq = get_coreclock() / (metag_in32(EXPAND_TIMER_DIV) + 1); #endif pr_info("Timer frequency: %u Hz\n", hwtimer_freq); clocksource_register_hz(&clocksource_metag, hwtimer_freq); setup_irq(tbisig_map(TBID_SIGNUM_TRT), &metag_timer_irq); /* Configure timer on boot CPU */ arch_timer_setup(smp_processor_id()); /* Hook cpu boot to configure other CPU's timers */ register_cpu_notifier(&arch_timer_cpu_nb); return 0; }
static int arch_timer_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { int cpu = (long)hcpu; switch (action) { case CPU_STARTING: case CPU_STARTING_FROZEN: arch_timer_setup(cpu); break; } return NOTIFY_OK; }
static int arch_timer_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { /* * Grab cpu pointer in each case to avoid spurious * preemptible warnings */ switch (action & ~CPU_TASKS_FROZEN) { case CPU_STARTING: arch_timer_setup(this_cpu_ptr(arch_timer_evt)); break; case CPU_DYING: arch_timer_stop(this_cpu_ptr(arch_timer_evt)); break; } return NOTIFY_OK; }
int __init arm_generic_timer_init(void) { struct device_node *np; int err; u32 freq; np = of_find_matching_node(NULL, arch_timer_of_match); if (!np) { pr_err("arch_timer: can't find DT node\n"); return -ENODEV; } /* Try to determine the frequency from the device tree or CNTFRQ */ if (!of_property_read_u32(np, "clock-frequency", &freq)) arch_timer_rate = freq; arch_timer_calibrate(); arch_timer_ppi = irq_of_parse_and_map(np, 0); pr_info("arch_timer: found %s irq %d\n", np->name, arch_timer_ppi); err = request_percpu_irq(arch_timer_ppi, arch_timer_handle_irq, np->name, &arch_timer_evt); if (err) { pr_err("arch_timer: can't register interrupt %d (%d)\n", arch_timer_ppi, err); return err; } clocksource_register_hz(&clocksource_counter, arch_timer_rate); /* Calibrate the delay loop directly */ lpj_fine = arch_timer_rate / HZ; /* Immediately configure the timer on the boot CPU */ arch_timer_setup(per_cpu_ptr(&arch_timer_evt, smp_processor_id())); register_cpu_notifier(&arch_timer_cpu_nb); return 0; }
static int __cpuinit arch_timer_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { int cpu = (long)hcpu; struct clock_event_device *clk = per_cpu_ptr(&arch_timer_evt, cpu); switch(action) { case CPU_STARTING: case CPU_STARTING_FROZEN: arch_timer_setup(clk); break; case CPU_DYING: case CPU_DYING_FROZEN: pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", clk->irq, cpu); disable_percpu_irq(clk->irq); arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk); break; } return NOTIFY_OK; }
int __cpuinit local_timer_setup(struct clock_event_device *evt) { return arch_timer_setup(evt); }