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

Commit fc6a6772 authored by Ezequiel Garcia's avatar Ezequiel Garcia Committed by Ralf Baechle
Browse files

CLOCKSOURCE: mips-gic: Update clockevent frequency on clock rate changes



This commit introduces the clockevent frequency update, using
a clock notifier. It will be used to support CPUFreq on platforms
using MIPS GIC based clockevents.

Signed-off-by: default avatarEzequiel Garcia <ezequiel.garcia@imgtec.com>
Acked-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: devicetree@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Andrew Bresticker <abrestic@chromium.org>
Cc: James Hartley <James.Hartley@imgtec.com>
Cc: Govindraj Raja <Govindraj.Raja@imgtec.com>
Cc: Damien Horsley <Damien.Horsley@imgtec.com>
Cc: James Hogan <James.Hogan@imgtec.com>
Cc: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Patchwork: https://patchwork.linux-mips.org/patch/10782/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 42b002ab
Loading
Loading
Loading
Loading
+30 −1
Original line number Diff line number Diff line
@@ -79,6 +79,13 @@ static void gic_clockevent_cpu_exit(struct clock_event_device *cd)
	disable_percpu_irq(gic_timer_irq);
}

static void gic_update_frequency(void *data)
{
	unsigned long rate = (unsigned long)data;

	clockevents_update_freq(this_cpu_ptr(&gic_clockevent_device), rate);
}

static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action,
				void *data)
{
@@ -94,10 +101,26 @@ static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action,
	return NOTIFY_OK;
}

static int gic_clk_notifier(struct notifier_block *nb, unsigned long action,
			    void *data)
{
	struct clk_notifier_data *cnd = data;

	if (action == POST_RATE_CHANGE)
		on_each_cpu(gic_update_frequency, (void *)cnd->new_rate, 1);

	return NOTIFY_OK;
}


static struct notifier_block gic_cpu_nb = {
	.notifier_call = gic_cpu_notifier,
};

static struct notifier_block gic_clk_nb = {
	.notifier_call = gic_clk_notifier,
};

static int gic_clockevent_init(void)
{
	int ret;
@@ -160,6 +183,7 @@ void __init gic_clocksource_init(unsigned int frequency)
static void __init gic_clocksource_of_init(struct device_node *node)
{
	struct clk *clk;
	int ret;

	if (WARN_ON(!gic_present || !node->parent ||
		    !of_device_is_compatible(node->parent, "mti,gic")))
@@ -186,7 +210,12 @@ static void __init gic_clocksource_of_init(struct device_node *node)
	}

	__gic_clocksource_init();
	gic_clockevent_init();

	ret = gic_clockevent_init();
	if (!ret && !IS_ERR(clk)) {
		if (clk_notifier_register(clk, &gic_clk_nb) < 0)
			pr_warn("GIC: Unable to register clock notifier\n");
	}

	/* And finally start the counter */
	gic_start_count();