cregit-Linux how code gets into the kernel

Release 4.11 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

PersonTokensPropCommitsCommitProp
Uwe Kleine-König3485.00%150.00%
Viresh Kumar615.00%150.00%
Total40100.00%2100.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

PersonTokensPropCommitsCommitProp
Viresh Kumar3357.89%150.00%
Uwe Kleine-König2442.11%150.00%
Total57100.00%2100.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

PersonTokensPropCommitsCommitProp
Uwe Kleine-König4556.96%150.00%
Viresh Kumar3443.04%150.00%
Total79100.00%2100.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

PersonTokensPropCommitsCommitProp
Uwe Kleine-König66100.00%1100.00%
Total66100.00%1100.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

PersonTokensPropCommitsCommitProp
Uwe Kleine-König46100.00%1100.00%
Total46100.00%1100.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

PersonTokensPropCommitsCommitProp
Uwe Kleine-König214100.00%1100.00%
Total214100.00%1100.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"); 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

PersonTokensPropCommitsCommitProp
Uwe Kleine-König23189.88%133.33%
Daniel Lezcano187.00%133.33%
Yongbae Park83.11%133.33%
Total257100.00%3100.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

PersonTokensPropCommitsCommitProp
Uwe Kleine-König7085.37%150.00%
Daniel Lezcano1214.63%150.00%
Total82100.00%2100.00%

CLOCKSOURCE_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init); CLOCKSOURCE_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init);

Overall Contributors

PersonTokensPropCommitsCommitProp
Uwe Kleine-König94888.27%228.57%
Viresh Kumar868.01%228.57%
Daniel Lezcano322.98%228.57%
Yongbae Park80.74%114.29%
Total1074100.00%7100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.