aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/mips-gic-timer.c
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel.garcia@imgtec.com>2015-07-27 10:00:15 -0400
committerRalf Baechle <ralf@linux-mips.org>2015-09-03 06:08:07 -0400
commitfc6a6772f888ee8ab4c5428854f7f1d3abda13df (patch)
treeb154290d7b15a373873b5ed9ee759e4fb81cb65d /drivers/clocksource/mips-gic-timer.c
parent42b002ab73e00b24356be4f01954fa961fea4d82 (diff)
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>
Diffstat (limited to 'drivers/clocksource/mips-gic-timer.c')
-rw-r--r--drivers/clocksource/mips-gic-timer.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 22a4daf5f0c8..a155bec06d18 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -79,6 +79,13 @@ static void gic_clockevent_cpu_exit(struct clock_event_device *cd)
79 disable_percpu_irq(gic_timer_irq); 79 disable_percpu_irq(gic_timer_irq);
80} 80}
81 81
82static 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
82static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, 89static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action,
83 void *data) 90 void *data)
84{ 91{
@@ -94,10 +101,26 @@ static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action,
94 return NOTIFY_OK; 101 return NOTIFY_OK;
95} 102}
96 103
104static int gic_clk_notifier(struct notifier_block *nb, unsigned long action,
105 void *data)
106{
107 struct clk_notifier_data *cnd = data;
108
109 if (action == POST_RATE_CHANGE)
110 on_each_cpu(gic_update_frequency, (void *)cnd->new_rate, 1);
111
112 return NOTIFY_OK;
113}
114
115
97static struct notifier_block gic_cpu_nb = { 116static struct notifier_block gic_cpu_nb = {
98 .notifier_call = gic_cpu_notifier, 117 .notifier_call = gic_cpu_notifier,
99}; 118};
100 119
120static struct notifier_block gic_clk_nb = {
121 .notifier_call = gic_clk_notifier,
122};
123
101static int gic_clockevent_init(void) 124static int gic_clockevent_init(void)
102{ 125{
103 int ret; 126 int ret;
@@ -160,6 +183,7 @@ void __init gic_clocksource_init(unsigned int frequency)
160static void __init gic_clocksource_of_init(struct device_node *node) 183static void __init gic_clocksource_of_init(struct device_node *node)
161{ 184{
162 struct clk *clk; 185 struct clk *clk;
186 int ret;
163 187
164 if (WARN_ON(!gic_present || !node->parent || 188 if (WARN_ON(!gic_present || !node->parent ||
165 !of_device_is_compatible(node->parent, "mti,gic"))) 189 !of_device_is_compatible(node->parent, "mti,gic")))
@@ -186,7 +210,12 @@ static void __init gic_clocksource_of_init(struct device_node *node)
186 } 210 }
187 211
188 __gic_clocksource_init(); 212 __gic_clocksource_init();
189 gic_clockevent_init(); 213
214 ret = gic_clockevent_init();
215 if (!ret && !IS_ERR(clk)) {
216 if (clk_notifier_register(clk, &gic_clk_nb) < 0)
217 pr_warn("GIC: Unable to register clock notifier\n");
218 }
190 219
191 /* And finally start the counter */ 220 /* And finally start the counter */
192 gic_start_count(); 221 gic_start_count();