Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
Acked-by: Daniel 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: Ralf Baechle <ralf@linux-mips.org>

authored by

Ezequiel Garcia and committed by
Ralf Baechle
fc6a6772 42b002ab

+30 -1
+30 -1
drivers/clocksource/mips-gic-timer.c
··· 79 79 disable_percpu_irq(gic_timer_irq); 80 80 } 81 81 82 + static void gic_update_frequency(void *data) 83 + { 84 + unsigned long rate = (unsigned long)data; 85 + 86 + clockevents_update_freq(this_cpu_ptr(&gic_clockevent_device), rate); 87 + } 88 + 82 89 static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, 83 90 void *data) 84 91 { ··· 101 94 return NOTIFY_OK; 102 95 } 103 96 97 + static int gic_clk_notifier(struct notifier_block *nb, unsigned long action, 98 + void *data) 99 + { 100 + struct clk_notifier_data *cnd = data; 101 + 102 + if (action == POST_RATE_CHANGE) 103 + on_each_cpu(gic_update_frequency, (void *)cnd->new_rate, 1); 104 + 105 + return NOTIFY_OK; 106 + } 107 + 108 + 104 109 static struct notifier_block gic_cpu_nb = { 105 110 .notifier_call = gic_cpu_notifier, 111 + }; 112 + 113 + static struct notifier_block gic_clk_nb = { 114 + .notifier_call = gic_clk_notifier, 106 115 }; 107 116 108 117 static int gic_clockevent_init(void) ··· 183 160 static void __init gic_clocksource_of_init(struct device_node *node) 184 161 { 185 162 struct clk *clk; 163 + int ret; 186 164 187 165 if (WARN_ON(!gic_present || !node->parent || 188 166 !of_device_is_compatible(node->parent, "mti,gic"))) ··· 210 186 } 211 187 212 188 __gic_clocksource_init(); 213 - gic_clockevent_init(); 189 + 190 + ret = gic_clockevent_init(); 191 + if (!ret && !IS_ERR(clk)) { 192 + if (clk_notifier_register(clk, &gic_clk_nb) < 0) 193 + pr_warn("GIC: Unable to register clock notifier\n"); 194 + } 214 195 215 196 /* And finally start the counter */ 216 197 gic_start_count();