Merge branch 'clockevents/3.13-fixes' of git://git.linaro.org/people/daniel.lezcano/linux into timers/urgent

Pull clock driver fix from Daniel Lezcano:

" * Soren Brinkmann fixed the cadence_ttc driver where a call to
clk_get_rate happens in an interrupt context. More precisely in an IPI
when the broadcast timer is initialized for each cpu in the cpuidle
driver. "

Signed-off-by: Ingo Molnar <mingo@kernel.org>

+13 -8
+13 -8
drivers/clocksource/cadence_ttc_timer.c
··· 67 * struct ttc_timer - This definition defines local timer structure 68 * 69 * @base_addr: Base address of timer 70 * @clk: Associated clock source 71 * @clk_rate_change_nb Notifier block for clock rate changes 72 */ 73 struct ttc_timer { 74 void __iomem *base_addr; 75 struct clk *clk; 76 struct notifier_block clk_rate_change_nb; 77 }; ··· 198 199 switch (mode) { 200 case CLOCK_EVT_MODE_PERIODIC: 201 - ttc_set_interval(timer, 202 - DIV_ROUND_CLOSEST(clk_get_rate(ttce->ttc.clk), 203 - PRESCALE * HZ)); 204 break; 205 case CLOCK_EVT_MODE_ONESHOT: 206 case CLOCK_EVT_MODE_UNUSED: ··· 274 return; 275 } 276 277 ttccs->ttc.clk_rate_change_nb.notifier_call = 278 ttc_rate_change_clocksource_cb; 279 ttccs->ttc.clk_rate_change_nb.next = NULL; ··· 301 __raw_writel(CNT_CNTRL_RESET, 302 ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); 303 304 - err = clocksource_register_hz(&ttccs->cs, 305 - clk_get_rate(ttccs->ttc.clk) / PRESCALE); 306 if (WARN_ON(err)) { 307 kfree(ttccs); 308 return; 309 } 310 311 ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; 312 - setup_sched_clock(ttc_sched_clock_read, 16, 313 - clk_get_rate(ttccs->ttc.clk) / PRESCALE); 314 } 315 316 static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, ··· 334 clockevents_update_freq(&ttcce->ce, 335 ndata->new_rate / PRESCALE); 336 local_irq_restore(flags); 337 338 /* fall through */ 339 } ··· 371 if (clk_notifier_register(ttcce->ttc.clk, 372 &ttcce->ttc.clk_rate_change_nb)) 373 pr_warn("Unable to register clock notifier.\n"); 374 375 ttcce->ttc.base_addr = base; 376 ttcce->ce.name = "ttc_clockevent"; ··· 401 } 402 403 clockevents_config_and_register(&ttcce->ce, 404 - clk_get_rate(ttcce->ttc.clk) / PRESCALE, 1, 0xfffe); 405 } 406 407 /**
··· 67 * struct ttc_timer - This definition defines local timer structure 68 * 69 * @base_addr: Base address of timer 70 + * @freq: Timer input clock frequency 71 * @clk: Associated clock source 72 * @clk_rate_change_nb Notifier block for clock rate changes 73 */ 74 struct ttc_timer { 75 void __iomem *base_addr; 76 + unsigned long freq; 77 struct clk *clk; 78 struct notifier_block clk_rate_change_nb; 79 }; ··· 196 197 switch (mode) { 198 case CLOCK_EVT_MODE_PERIODIC: 199 + ttc_set_interval(timer, DIV_ROUND_CLOSEST(ttce->ttc.freq, 200 + PRESCALE * HZ)); 201 break; 202 case CLOCK_EVT_MODE_ONESHOT: 203 case CLOCK_EVT_MODE_UNUSED: ··· 273 return; 274 } 275 276 + ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk); 277 + 278 ttccs->ttc.clk_rate_change_nb.notifier_call = 279 ttc_rate_change_clocksource_cb; 280 ttccs->ttc.clk_rate_change_nb.next = NULL; ··· 298 __raw_writel(CNT_CNTRL_RESET, 299 ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); 300 301 + err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE); 302 if (WARN_ON(err)) { 303 kfree(ttccs); 304 return; 305 } 306 307 ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; 308 + setup_sched_clock(ttc_sched_clock_read, 16, ttccs->ttc.freq / PRESCALE); 309 } 310 311 static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, ··· 333 clockevents_update_freq(&ttcce->ce, 334 ndata->new_rate / PRESCALE); 335 local_irq_restore(flags); 336 + 337 + /* update cached frequency */ 338 + ttc->freq = ndata->new_rate; 339 340 /* fall through */ 341 } ··· 367 if (clk_notifier_register(ttcce->ttc.clk, 368 &ttcce->ttc.clk_rate_change_nb)) 369 pr_warn("Unable to register clock notifier.\n"); 370 + ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); 371 372 ttcce->ttc.base_addr = base; 373 ttcce->ce.name = "ttc_clockevent"; ··· 396 } 397 398 clockevents_config_and_register(&ttcce->ce, 399 + ttcce->ttc.freq / PRESCALE, 1, 0xfffe); 400 } 401 402 /**