Commit e12aa828 authored by Andrew Bresticker's avatar Andrew Bresticker Committed by Ralf Baechle
Browse files

clocksource: mips-gic: Add device-tree support



Parse the GIC timer frequency and interrupt from the device-tree.

Signed-off-by: default avatarAndrew Bresticker <abrestic@chromium.org>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: John Crispin <blogic@openwrt.org>
Cc: David Daney <ddaney.cavm@gmail.com>
Cc: Qais Yousef <qais.yousef@imgtec.com>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/8421/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent a7057270
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -226,5 +226,6 @@ config CLKSRC_VERSATILE
config CLKSRC_MIPS_GIC
	bool
	depends on MIPS_GIC
	select CLKSRC_OF

endmenu
+34 −7
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/interrupt.h>
#include <linux/irqchip/mips-gic.h>
#include <linux/notifier.h>
#include <linux/of_irq.h>
#include <linux/percpu.h>
#include <linux/smp.h>
#include <linux/time.h>
@@ -101,8 +102,6 @@ static int gic_clockevent_init(void)
	if (!cpu_has_counter || !gic_frequency)
		return -ENXIO;

	gic_timer_irq = MIPS_GIC_IRQ_BASE +
		GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
	setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction);

	register_cpu_notifier(&gic_cpu_nb);
@@ -123,17 +122,45 @@ static struct clocksource gic_clocksource = {
	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
};

void __init gic_clocksource_init(unsigned int frequency)
static void __init __gic_clocksource_init(void)
{
	gic_frequency = frequency;

	/* Set clocksource mask. */
	gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width());

	/* Calculate a somewhat reasonable rating value. */
	gic_clocksource.rating = 200 + frequency / 10000000;
	gic_clocksource.rating = 200 + gic_frequency / 10000000;

	clocksource_register_hz(&gic_clocksource, frequency);
	clocksource_register_hz(&gic_clocksource, gic_frequency);

	gic_clockevent_init();
}

void __init gic_clocksource_init(unsigned int frequency)
{
	gic_frequency = frequency;
	gic_timer_irq = MIPS_GIC_IRQ_BASE +
		GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);

	__gic_clocksource_init();
}

static void __init gic_clocksource_of_init(struct device_node *node)
{
	if (WARN_ON(!gic_present || !node->parent ||
		    !of_device_is_compatible(node->parent, "mti,gic")))
		return;

	if (of_property_read_u32(node, "clock-frequency", &gic_frequency)) {
		pr_err("GIC frequency not specified.\n");
		return;
	}
	gic_timer_irq = irq_of_parse_and_map(node, 0);
	if (!gic_timer_irq) {
		pr_err("GIC timer IRQ not specified.\n");
		return;
	}

	__gic_clocksource_init();
}
CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer",
		       gic_clocksource_of_init);