Ejemplo n.º 1
0
static int l4x_rtc_platform_probe(struct platform_device *pdev)
{
	int r;

	if (l4x_re_resolve_name("rtc", &rtc_server)) {
		pr_err("l4x-rtc: Could not find 'rtc' cap.\n");
		return -ENOENT;
	}

	irq_cap = l4x_cap_alloc();
	if (l4_is_invalid_cap(irq_cap)) {
		pr_err("l4x-rtc: Could not allocate irq cap.\n");
		return -ENOMEM;
	}

	if (L4XV_FN_e(l4_factory_create_irq(l4re_env()->factory, irq_cap))) {
		pr_err("l4x-rtc: Could not create user irq.\n");
		r = -ENOMEM;
		goto free_cap;
	}

	if (L4XV_FN_e(l4_icu_bind(rtc_server, 0, irq_cap))) {
		pr_err("l4x-rtc: Error registering for time updates.\n");
		r = -ENOSYS;
		goto free_irq_cap;
	}

	irq = l4x_register_irq(irq_cap);
	if (irq < 0) {
		pr_err("l4x-rtc: Error registering IRQ with L4Linux.\n");
		r = irq;
		goto free_irq_cap;
	}

	r = request_irq(irq, l4x_rtc_int, IRQF_TRIGGER_RISING, "l4x_rtc", NULL);
	if (r) {
		pr_err("l4x-rtc: Could not register IRQ.\n");
		goto unregister_irq;
	}

	if (l4x_rtc_update_offset()) {
		pr_err("l4x-rtc: Could not get the time offset to real time.\n");
		r = -ENOSYS;
		goto free_irq;
	}

	rtc_dev = rtc_device_register(driver_name, &(pdev->dev),
	                              &l4x_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc_dev)) {
		pr_err("l4x-rtc: Could not register as rtc device.\n");
		r = PTR_ERR(rtc_dev);
		goto free_irq;
	}

	INIT_WORK(&w_update_time, l4x_rtc_update_time);

	return 0;

free_irq:
	free_irq(irq, NULL);
unregister_irq:
	l4x_unregister_irq(irq);
free_irq_cap:
	L4XV_FN_v(l4_task_release_cap(L4RE_THIS_TASK_CAP, irq_cap));
free_cap:
	l4x_cap_free(irq_cap);
	return r;
}
Ejemplo n.º 2
0
static int __init l4x_timer_init_ret(void)
{
    int r;
    l4lx_thread_t thread;
    int irq;
    L4XV_V(f);

    timer_irq_cap = l4x_cap_alloc();
    if (l4_is_invalid_cap(timer_irq_cap)) {
        printk(KERN_ERR "l4timer: Failed to alloc\n");
        return -ENOMEM;
    }

    r = L4XV_FN_i(l4_error(l4_factory_create_irq(l4re_env()->factory,
                           timer_irq_cap)));
    if (r) {
        printk(KERN_ERR "l4timer: Failed to create irq: %d\n", r);
        goto out1;
    }

    if ((irq = l4x_register_irq(timer_irq_cap)) < 0) {
        r = -ENOMEM;
        goto out2;
    }

    printk("l4timer: Using IRQ%d\n", irq);

    setup_irq(irq, &l4timer_irq);

    L4XV_L(f);
    thread = l4lx_thread_create
             (timer_thread,                /* thread function */
              smp_processor_id(),          /* cpu */
              NULL,                        /* stack */
              &timer_irq_cap, sizeof(timer_irq_cap), /* data */
              l4x_cap_alloc(),             /* cap */
              PRIO_TIMER,                  /* prio */
              0,                           /* vcpup */
              "timer",                     /* name */
              NULL);
    L4XV_U(f);

    timer_srv = l4lx_thread_get_cap(thread);

    if (!l4lx_thread_is_valid(thread)) {
        printk(KERN_ERR "l4timer: Failed to create thread\n");
        r = -ENOMEM;
        goto out3;
    }


    l4timer_clockevent.irq = irq;
    l4timer_clockevent.mult =
        div_sc(1000000, NSEC_PER_SEC, l4timer_clockevent.shift);
    l4timer_clockevent.max_delta_ns =
        clockevent_delta2ns(0xffffffff, &l4timer_clockevent);
    l4timer_clockevent.min_delta_ns =
        clockevent_delta2ns(0xf, &l4timer_clockevent);
    l4timer_clockevent.cpumask = cpumask_of(0);
    clockevents_register_device(&l4timer_clockevent);

    return 0;

out3:
    l4x_unregister_irq(irq);
out2:
    L4XV_FN_v(l4_task_delete_obj(L4RE_THIS_TASK_CAP, timer_irq_cap));
out1:
    l4x_cap_free(timer_irq_cap);
    return r;
}