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; }
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; }