Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ccd63ce4 authored by Marc Gonzalez's avatar Marc Gonzalez Committed by Daniel Lezcano
Browse files

clocksource/drivers/tango_xtal: Add new timer for Tango SoCs



Sigma Designs Tango platforms provide a 27 MHz crystal oscillator.
Use it for clocksource, sched_clock, and delay_timer.

Signed-off-by: default avatarMarc Gonzalez <marc_gonzalez@sigmadesigns.com>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
parent f1c08c9b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -279,6 +279,10 @@ config CLKSRC_MIPS_GIC
	depends on MIPS_GIC
	select CLKSRC_OF

config CLKSRC_TANGO_XTAL
	bool
	select CLKSRC_OF

config CLKSRC_PXA
	def_bool y if ARCH_PXA || ARCH_SA1100
	select CLKSRC_OF if OF
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
obj-$(CONFIG_ARCH_INTEGRATOR_AP)	+= timer-integrator-ap.o
obj-$(CONFIG_CLKSRC_VERSATILE)		+= versatile.o
obj-$(CONFIG_CLKSRC_MIPS_GIC)		+= mips-gic-timer.o
obj-$(CONFIG_CLKSRC_TANGO_XTAL)		+= tango_xtal.o
obj-$(CONFIG_CLKSRC_IMX_GPT)		+= timer-imx-gpt.o
obj-$(CONFIG_ASM9260_TIMER)		+= asm9260_timer.o
obj-$(CONFIG_H8300)			+= h8300_timer8.o
+66 −0
Original line number Diff line number Diff line
#include <linux/clocksource.h>
#include <linux/sched_clock.h>
#include <linux/of_address.h>
#include <linux/printk.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/clk.h>

static void __iomem *xtal_in_cnt;
static struct delay_timer delay_timer;

static unsigned long notrace read_xtal_counter(void)
{
	return readl_relaxed(xtal_in_cnt);
}

static u64 notrace read_sched_clock(void)
{
	return read_xtal_counter();
}

static cycle_t read_clocksource(struct clocksource *cs)
{
	return read_xtal_counter();
}

static struct clocksource tango_xtal = {
	.name	= "tango-xtal",
	.rating	= 350,
	.read	= read_clocksource,
	.mask	= CLOCKSOURCE_MASK(32),
	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
};

static void __init tango_clocksource_init(struct device_node *np)
{
	struct clk *clk;
	int xtal_freq, ret;

	xtal_in_cnt = of_iomap(np, 0);
	if (xtal_in_cnt == NULL) {
		pr_err("%s: invalid address\n", np->full_name);
		return;
	}

	clk = of_clk_get(np, 0);
	if (IS_ERR(clk)) {
		pr_err("%s: invalid clock\n", np->full_name);
		return;
	}

	xtal_freq = clk_get_rate(clk);
	delay_timer.freq = xtal_freq;
	delay_timer.read_current_timer = read_xtal_counter;

	ret = clocksource_register_hz(&tango_xtal, xtal_freq);
	if (ret != 0) {
		pr_err("%s: registration failed\n", np->full_name);
		return;
	}

	sched_clock_register(read_sched_clock, 32, xtal_freq);
	register_current_timer_delay(&delay_timer);
}

CLOCKSOURCE_OF_DECLARE(tango, "sigma,tick-counter", tango_clocksource_init);