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;
}
Exemple #2
0
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;
}
Exemple #3
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
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);
}