Esempio n. 1
0
static void timer_set_mode(enum clock_event_mode mode,
                           struct clock_event_device *clk)
{
    const l4timer_time_t increment = 1000000 / HZ;
    int r;

    switch (mode) {
    case CLOCK_EVT_MODE_SHUTDOWN:
    case CLOCK_EVT_MODE_ONESHOT:
        r = L4XV_FN_i(l4_error(l4timer_stop(timer_srv)));
        if (r)
            printk(KERN_WARNING "l4timer: stop failed (%d)\n", r);
        while (L4XV_FN_i(l4_ipc_error(l4_irq_receive(timer_irq_cap, L4_IPC_BOTH_TIMEOUT_0), l4_utcb())) != L4_IPC_RETIMEOUT)
            ;
        break;
    case CLOCK_EVT_MODE_PERIODIC:
    case CLOCK_EVT_MODE_RESUME:
        r = L4XV_FN_i(l4_error(l4timer_start(timer_srv, 0,
                                             l4lx_kinfo->clock,
                                             increment)));
        if (r)
            printk(KERN_WARNING "l4timer: start failed (%d)\n", r);
        break;
    case CLOCK_EVT_MODE_UNUSED:
        break;
    default:
        printk("l4timer_set_mode: Unknown mode %d\n", mode);
        break;
    }
}
Esempio n. 2
0
static int __init l4vpci_init(void)
{
	int err;

	vbus = l4re_env_get_cap("vbus");
	if (l4_is_invalid_cap(vbus))
		return -ENOENT;

	err = L4XV_FN_i(l4vbus_get_device_by_hid(vbus, 0, &root_bridge,
	                                         "PNP0A03", 0, 0));
	if (err < 0) {
		printk(KERN_INFO "l4vPCI: no root bridge found, no PCI\n");
		return err;
	}

	printk(KERN_INFO "l4vPCI: L4 root bridge is device %lx\n", root_bridge);

#ifdef CONFIG_X86
	return l4vpci_x86_init();
#endif

#ifdef CONFIG_ARM
	pci_common_init(&l4vpci_pci);
	return 0;
#endif
}
Esempio n. 3
0
int raw_pci_write(unsigned int domain, unsigned int bus,
                  unsigned int devfn, int reg, int len, u32 value)
{
	l4_uint32_t df = (PCI_SLOT(devfn) << 16) | PCI_FUNC(devfn);
	return L4XV_FN_i(l4vbus_pci_cfg_write(vbus, root_bridge,
	                                      bus, df, reg, value, len * 8));
}
Esempio n. 4
0
u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
{
	u32 val;
	if (L4XV_FN_i(l4vbus_pci_cfg_read(vbus, root_bridge,
	                                  bus, (slot << 16) | func,
	                                  offset, &val, 16)))
		return 0;
	return val;
}
Esempio n. 5
0
static int l4x_rtc_update_offset(void)
{
	if (L4XV_FN_i(l4rtc_get_offset_to_realtime(rtc_server,
	                                           &offset_to_realtime))) {
		pr_err("l4x-rtc: Failed getting time offset.\n");
		return -ENOSYS;
	}
	return 0;
}
Esempio n. 6
0
static int l4vpci_irq_enable(struct pci_dev *dev)
{
	unsigned char trigger, polarity;
	int irq;
	u8 pin = 0;
	unsigned flags;
	l4_uint32_t devfn;

	if (!dev)
		return -EINVAL;

	if (dev->msi_enabled || dev->msix_enabled)
		return 0;

	pin = dev->pin;
	if (!pin) {
		dev_warn(&dev->dev,
		         "No interrupt pin configured for device %s\n",
		         pci_name(dev));
		return 0;
	}
	pin--;


	if (!dev->bus) {
		dev_err(&dev->dev, "invalid (NULL) 'bus' field\n");
		return -ENODEV;
	}

	devfn = (PCI_SLOT(dev->devfn) << 16) | PCI_FUNC(dev->devfn);
	irq = L4XV_FN_i(l4vbus_pci_irq_enable(vbus, root_bridge, dev->bus->number,
	                                      devfn, pin, &trigger, &polarity));
	if (irq < 0) {
		dev_warn(&dev->dev, "PCI INT %c: no GSI", 'A' + pin);
		/* Interrupt Line values above 0xF are forbidden */
		return 0;
	}

	switch ((!!trigger) | ((!!polarity) << 1)) {
		case 0: flags = IRQF_TRIGGER_HIGH; break;
		case 1: flags = IRQF_TRIGGER_RISING; break;
		case 2: flags = IRQF_TRIGGER_LOW; break;
		case 3: flags = IRQF_TRIGGER_FALLING; break;
		default: flags = 0; break;
	}

	dev->irq = irq;
	l4lx_irq_set_type(irq_get_irq_data(irq), flags);

	dev_info(&dev->dev, "PCI INT %c -> GSI %u (%s, %s) -> IRQ %d\n",
	         'A' + pin, irq,
	         !trigger ? "level" : "edge",
	         polarity ? "low" : "high", dev->irq);

	return 0;
}
Esempio n. 7
0
static int l4x_rtc_set_time(struct device *dev, struct rtc_time *time)
{
	u64 new_offset_to_realtime;
	long unsigned int seconds;

	rtc_tm_to_time(time, &seconds);
	new_offset_to_realtime = (u64)seconds * 1000000000 - l4rtc_get_timer();
	if (L4XV_FN_i(l4rtc_set_offset_to_realtime(rtc_server,
	                                           new_offset_to_realtime))) {
		pr_err("l4x-rtc: Could not set time.\n");
		return -EAGAIN;
	}
	/*
	 * We do not update our internal offset to realtime here. It will be
	 * updated when the rtc server sends its "time changed" IRQ.
	 */
	return 0;
}
Esempio n. 8
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;
}