Release 4.12 drivers/clocksource/time-efm32.c
  
  
  
/*
 * Copyright (C) 2013 Pengutronix
 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation.
 */
#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/clk.h>
#define TIMERn_CTRL			0x00
#define TIMERn_CTRL_PRESC(val)			(((val) & 0xf) << 24)
#define TIMERn_CTRL_PRESC_1024			TIMERn_CTRL_PRESC(10)
#define TIMERn_CTRL_CLKSEL(val)			(((val) & 0x3) << 16)
#define TIMERn_CTRL_CLKSEL_PRESCHFPERCLK	TIMERn_CTRL_CLKSEL(0)
#define TIMERn_CTRL_OSMEN			0x00000010
#define TIMERn_CTRL_MODE(val)			(((val) & 0x3) <<  0)
#define TIMERn_CTRL_MODE_UP			TIMERn_CTRL_MODE(0)
#define TIMERn_CTRL_MODE_DOWN			TIMERn_CTRL_MODE(1)
#define TIMERn_CMD			0x04
#define TIMERn_CMD_START			0x00000001
#define TIMERn_CMD_STOP				0x00000002
#define TIMERn_IEN			0x0c
#define TIMERn_IF			0x10
#define TIMERn_IFS			0x14
#define TIMERn_IFC			0x18
#define TIMERn_IRQ_UF				0x00000002
#define TIMERn_TOP			0x1c
#define TIMERn_CNT			0x24
struct efm32_clock_event_ddata {
	
struct clock_event_device evtdev;
	
void __iomem *base;
	
unsigned periodic_top;
};
static int efm32_clock_event_shutdown(struct clock_event_device *evtdev)
{
	struct efm32_clock_event_ddata *ddata =
		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Uwe Kleine-König | 34 | 85.00% | 1 | 50.00% | 
| Viresh Kumar | 6 | 15.00% | 1 | 50.00% | 
| Total | 40 | 100.00% | 2 | 100.00% | 
static int efm32_clock_event_set_oneshot(struct clock_event_device *evtdev)
{
	struct efm32_clock_event_ddata *ddata =
		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
	writel_relaxed(TIMERn_CTRL_PRESC_1024 |
		       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
		       TIMERn_CTRL_OSMEN |
		       TIMERn_CTRL_MODE_DOWN,
		       ddata->base + TIMERn_CTRL);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Viresh Kumar | 33 | 57.89% | 1 | 50.00% | 
| Uwe Kleine-König | 24 | 42.11% | 1 | 50.00% | 
| Total | 57 | 100.00% | 2 | 100.00% | 
static int efm32_clock_event_set_periodic(struct clock_event_device *evtdev)
{
	struct efm32_clock_event_ddata *ddata =
		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
	writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP);
	writel_relaxed(TIMERn_CTRL_PRESC_1024 |
		       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
		       TIMERn_CTRL_MODE_DOWN,
		       ddata->base + TIMERn_CTRL);
	writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Uwe Kleine-König | 45 | 56.96% | 1 | 50.00% | 
| Viresh Kumar | 34 | 43.04% | 1 | 50.00% | 
| Total | 79 | 100.00% | 2 | 100.00% | 
static int efm32_clock_event_set_next_event(unsigned long evt,
					    struct clock_event_device *evtdev)
{
	struct efm32_clock_event_ddata *ddata =
		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
	writel_relaxed(evt, ddata->base + TIMERn_CNT);
	writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Uwe Kleine-König | 66 | 100.00% | 1 | 100.00% | 
| Total | 66 | 100.00% | 1 | 100.00% | 
static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id)
{
	struct efm32_clock_event_ddata *ddata = dev_id;
	writel_relaxed(TIMERn_IRQ_UF, ddata->base + TIMERn_IFC);
	ddata->evtdev.event_handler(&ddata->evtdev);
	return IRQ_HANDLED;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Uwe Kleine-König | 46 | 100.00% | 1 | 100.00% | 
| Total | 46 | 100.00% | 1 | 100.00% | 
static struct efm32_clock_event_ddata clock_event_ddata = {
	.evtdev = {
		.name = "efm32 clockevent",
		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
		.set_state_shutdown = efm32_clock_event_shutdown,
		.set_state_periodic = efm32_clock_event_set_periodic,
		.set_state_oneshot = efm32_clock_event_set_oneshot,
		.set_next_event = efm32_clock_event_set_next_event,
		.rating = 200,
        },
};
static struct irqaction efm32_clock_event_irq = {
	.name = "efm32 clockevent",
	.flags = IRQF_TIMER,
	.handler = efm32_clock_event_handler,
	.dev_id = &clock_event_ddata,
};
static int __init efm32_clocksource_init(struct device_node *np)
{
	struct clk *clk;
	void __iomem *base;
	unsigned long rate;
	int ret;
	clk = of_clk_get(np, 0);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		pr_err("failed to get clock for clocksource (%d)\n", ret);
		goto err_clk_get;
	}
	ret = clk_prepare_enable(clk);
	if (ret) {
		pr_err("failed to enable timer clock for clocksource (%d)\n",
		       ret);
		goto err_clk_enable;
	}
	rate = clk_get_rate(clk);
	base = of_iomap(np, 0);
	if (!base) {
		ret = -EADDRNOTAVAIL;
		pr_err("failed to map registers for clocksource\n");
		goto err_iomap;
	}
	writel_relaxed(TIMERn_CTRL_PRESC_1024 |
		       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
		       TIMERn_CTRL_MODE_UP, base + TIMERn_CTRL);
	writel_relaxed(TIMERn_CMD_START, base + TIMERn_CMD);
	ret = clocksource_mmio_init(base + TIMERn_CNT, "efm32 timer",
				    DIV_ROUND_CLOSEST(rate, 1024), 200, 16,
				    clocksource_mmio_readl_up);
	if (ret) {
		pr_err("failed to init clocksource (%d)\n", ret);
		goto err_clocksource_init;
	}
	return 0;
err_clocksource_init:
	iounmap(base);
err_iomap:
	clk_disable_unprepare(clk);
err_clk_enable:
	clk_put(clk);
err_clk_get:
	return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Uwe Kleine-König | 214 | 100.00% | 1 | 100.00% | 
| Total | 214 | 100.00% | 1 | 100.00% | 
static int __init efm32_clockevent_init(struct device_node *np)
{
	struct clk *clk;
	void __iomem *base;
	unsigned long rate;
	int irq;
	int ret;
	clk = of_clk_get(np, 0);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		pr_err("failed to get clock for clockevent (%d)\n", ret);
		goto err_clk_get;
	}
	ret = clk_prepare_enable(clk);
	if (ret) {
		pr_err("failed to enable timer clock for clockevent (%d)\n",
		       ret);
		goto err_clk_enable;
	}
	rate = clk_get_rate(clk);
	base = of_iomap(np, 0);
	if (!base) {
		ret = -EADDRNOTAVAIL;
		pr_err("failed to map registers for clockevent\n");
		goto err_iomap;
	}
	irq = irq_of_parse_and_map(np, 0);
	if (!irq) {
		ret = -ENOENT;
		pr_err("failed to get irq for clockevent\n");
		goto err_get_irq;
	}
	writel_relaxed(TIMERn_IRQ_UF, base + TIMERn_IEN);
	clock_event_ddata.base = base;
	clock_event_ddata.periodic_top = DIV_ROUND_CLOSEST(rate, 1024 * HZ);
	clockevents_config_and_register(&clock_event_ddata.evtdev,
					DIV_ROUND_CLOSEST(rate, 1024),
					0xf, 0xffff);
	ret = setup_irq(irq, &efm32_clock_event_irq);
	if (ret) {
		pr_err("Failed setup irq\n");
		goto err_setup_irq;
	}
	return 0;
err_setup_irq:
err_get_irq:
	iounmap(base);
err_iomap:
	clk_disable_unprepare(clk);
err_clk_enable:
	clk_put(clk);
err_clk_get:
	return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Uwe Kleine-König | 231 | 89.88% | 1 | 25.00% | 
| Daniel Lezcano | 17 | 6.61% | 1 | 25.00% | 
| Yongbae Park | 8 | 3.11% | 1 | 25.00% | 
| Rafał Miłecki | 1 | 0.39% | 1 | 25.00% | 
| Total | 257 | 100.00% | 4 | 100.00% | 
/*
 * This function asserts that we have exactly one clocksource and one
 * clock_event_device in the end.
 */
static int __init efm32_timer_init(struct device_node *np)
{
	static int has_clocksource, has_clockevent;
	int ret = 0;
	if (!has_clocksource) {
		ret = efm32_clocksource_init(np);
		if (!ret) {
			has_clocksource = 1;
			return 0;
		}
	}
	if (!has_clockevent) {
		ret = efm32_clockevent_init(np);
		if (!ret) {
			has_clockevent = 1;
			return 0;
		}
	}
	return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Uwe Kleine-König | 70 | 85.37% | 1 | 50.00% | 
| Daniel Lezcano | 12 | 14.63% | 1 | 50.00% | 
| Total | 82 | 100.00% | 2 | 100.00% | 
CLOCKSOURCE_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init);
CLOCKSOURCE_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init);
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Uwe Kleine-König | 948 | 88.27% | 2 | 25.00% | 
| Viresh Kumar | 86 | 8.01% | 2 | 25.00% | 
| Daniel Lezcano | 31 | 2.89% | 2 | 25.00% | 
| Yongbae Park | 8 | 0.74% | 1 | 12.50% | 
| Rafał Miłecki | 1 | 0.09% | 1 | 12.50% | 
| Total | 1074 | 100.00% | 8 | 100.00% | 
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.