diff options
author | Ezequiel Garcia <ezequiel.garcia@imgtec.com> | 2015-07-27 10:00:15 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-09-03 06:08:07 -0400 |
commit | fc6a6772f888ee8ab4c5428854f7f1d3abda13df (patch) | |
tree | b154290d7b15a373873b5ed9ee759e4fb81cb65d /drivers/clocksource/mips-gic-timer.c | |
parent | 42b002ab73e00b24356be4f01954fa961fea4d82 (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.c | 31 |
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 | ||
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 | static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, | 89 | static 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 | ||
104 | static 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 | |||
97 | static struct notifier_block gic_cpu_nb = { | 116 | static struct notifier_block gic_cpu_nb = { |
98 | .notifier_call = gic_cpu_notifier, | 117 | .notifier_call = gic_cpu_notifier, |
99 | }; | 118 | }; |
100 | 119 | ||
120 | static struct notifier_block gic_clk_nb = { | ||
121 | .notifier_call = gic_clk_notifier, | ||
122 | }; | ||
123 | |||
101 | static int gic_clockevent_init(void) | 124 | static 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) | |||
160 | static void __init gic_clocksource_of_init(struct device_node *node) | 183 | static 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(); |