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 | |
| 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')
| -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(); |
