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