lkml.org 
[lkml]   [2015]   [Nov]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH 09/28] lkl: timers, time and delay support
    Date
    Clockevent driver based on host timer operations and clocksource
    driver and udelay support based on host time operations.

    Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
    ---
    arch/lkl/kernel/time.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++
    1 file changed, 125 insertions(+)
    create mode 100644 arch/lkl/kernel/time.c

    diff --git a/arch/lkl/kernel/time.c b/arch/lkl/kernel/time.c
    new file mode 100644
    index 0000000..d099736
    --- /dev/null
    +++ b/arch/lkl/kernel/time.c
    @@ -0,0 +1,125 @@
    +#include <linux/clocksource.h>
    +#include <linux/clockchips.h>
    +#include <linux/jiffies.h>
    +#include <linux/module.h>
    +#include <linux/init.h>
    +#include <linux/interrupt.h>
    +#include <linux/irq.h>
    +#include <asm/host_ops.h>
    +
    +void __ndelay(unsigned long nsecs)
    +{
    + unsigned long long start = lkl_ops->time();
    +
    + while (lkl_ops->time() < start + nsecs)
    + ;
    +}
    +
    +void __udelay(unsigned long usecs)
    +{
    + __ndelay(usecs * NSEC_PER_USEC);
    +}
    +
    +void __const_udelay(unsigned long xloops)
    +{
    + __udelay(xloops / 5);
    +}
    +
    +void calibrate_delay(void)
    +{
    +}
    +
    +static cycle_t clock_read(struct clocksource *cs)
    +{
    + return lkl_ops->time();
    +}
    +
    +static struct clocksource clocksource = {
    + .name = "lkl",
    + .rating = 499,
    + .read = clock_read,
    + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
    + .mask = CLOCKSOURCE_MASK(64),
    +};
    +
    +static void *timer;
    +
    +static int timer_irq;
    +
    +static void timer_fn(void *arg)
    +{
    + lkl_trigger_irq(timer_irq, NULL);
    +}
    +
    +static int clockevent_set_state_shutdown(struct clock_event_device *evt)
    +{
    + if (timer) {
    + lkl_ops->timer_free(timer);
    + timer = NULL;
    + }
    +
    + return 0;
    +}
    +
    +static int clockevent_set_state_oneshot(struct clock_event_device *evt)
    +{
    + timer = lkl_ops->timer_alloc(timer_fn, NULL);
    + if (!timer)
    + return -ENOMEM;
    +
    + return 0;
    +}
    +
    +static irqreturn_t timer_irq_handler(int irq, void *dev_id)
    +{
    + struct clock_event_device *dev = (struct clock_event_device *)dev_id;
    +
    + dev->event_handler(dev);
    +
    + return IRQ_HANDLED;
    +}
    +
    +static int clockevent_next_event(unsigned long hz,
    + struct clock_event_device *evt)
    +{
    + unsigned long ns = 1000000000 * hz / HZ;
    +
    + return lkl_ops->timer_set_oneshot(timer, ns);
    +}
    +
    +static struct clock_event_device clockevent = {
    + .name = "lkl",
    + .features = CLOCK_EVT_FEAT_ONESHOT,
    + .set_state_oneshot = clockevent_set_state_oneshot,
    + .set_next_event = clockevent_next_event,
    + .set_state_shutdown = clockevent_set_state_shutdown,
    +};
    +
    +static struct irqaction irq0 = {
    + .handler = timer_irq_handler,
    + .flags = IRQF_NOBALANCING | IRQF_TIMER,
    + .dev_id = &clockevent,
    + .name = "timer"
    +};
    +
    +void __init time_init(void)
    +{
    + int ret;
    +
    + if (!lkl_ops->timer_alloc || !lkl_ops->timer_free ||
    + !lkl_ops->timer_set_oneshot || !lkl_ops->time) {
    + pr_err("lkl: no time or timer support provided by host\n");
    + return;
    + }
    +
    + timer_irq = lkl_get_free_irq("timer");
    + setup_irq(timer_irq, &irq0);
    +
    + ret = clocksource_register_khz(&clocksource, 1000000);
    + if (ret)
    + pr_err("lkl: unable to register clocksource\n");
    +
    + clockevents_config_and_register(&clockevent, HZ, 0, 0xffffffff);
    +
    + pr_info("lkl: time and timers initialized\n");
    +}
    --
    2.1.0


    \
     
     \ /
      Last update: 2015-11-03 21:41    [W:4.501 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site