Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fixes from Ingo Molnar: "Two clocksource driver fixes, and an idle loop RCU warning fix" * 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: clocksource/drivers/sun5i: Fix cpufreq interaction with sched_clock() clocksource/drivers: Fix various !CONFIG_HAS_IOMEM build errors timers/tick/broadcast-hrtimer: Fix suspicious RCU usage in idle loop
This commit is contained in:
Коммит
4a89452e70
|
@ -192,6 +192,7 @@ config SYS_SUPPORTS_EM_STI
|
||||||
config SH_TIMER_CMT
|
config SH_TIMER_CMT
|
||||||
bool "Renesas CMT timer driver" if COMPILE_TEST
|
bool "Renesas CMT timer driver" if COMPILE_TEST
|
||||||
depends on GENERIC_CLOCKEVENTS
|
depends on GENERIC_CLOCKEVENTS
|
||||||
|
depends on HAS_IOMEM
|
||||||
default SYS_SUPPORTS_SH_CMT
|
default SYS_SUPPORTS_SH_CMT
|
||||||
help
|
help
|
||||||
This enables build of a clocksource and clockevent driver for
|
This enables build of a clocksource and clockevent driver for
|
||||||
|
@ -201,6 +202,7 @@ config SH_TIMER_CMT
|
||||||
config SH_TIMER_MTU2
|
config SH_TIMER_MTU2
|
||||||
bool "Renesas MTU2 timer driver" if COMPILE_TEST
|
bool "Renesas MTU2 timer driver" if COMPILE_TEST
|
||||||
depends on GENERIC_CLOCKEVENTS
|
depends on GENERIC_CLOCKEVENTS
|
||||||
|
depends on HAS_IOMEM
|
||||||
default SYS_SUPPORTS_SH_MTU2
|
default SYS_SUPPORTS_SH_MTU2
|
||||||
help
|
help
|
||||||
This enables build of a clockevent driver for the Multi-Function
|
This enables build of a clockevent driver for the Multi-Function
|
||||||
|
@ -210,6 +212,7 @@ config SH_TIMER_MTU2
|
||||||
config SH_TIMER_TMU
|
config SH_TIMER_TMU
|
||||||
bool "Renesas TMU timer driver" if COMPILE_TEST
|
bool "Renesas TMU timer driver" if COMPILE_TEST
|
||||||
depends on GENERIC_CLOCKEVENTS
|
depends on GENERIC_CLOCKEVENTS
|
||||||
|
depends on HAS_IOMEM
|
||||||
default SYS_SUPPORTS_SH_TMU
|
default SYS_SUPPORTS_SH_TMU
|
||||||
help
|
help
|
||||||
This enables build of a clocksource and clockevent driver for
|
This enables build of a clocksource and clockevent driver for
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/irqreturn.h>
|
#include <linux/irqreturn.h>
|
||||||
#include <linux/reset.h>
|
#include <linux/reset.h>
|
||||||
#include <linux/sched_clock.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
|
@ -137,11 +136,6 @@ static struct irqaction sun5i_timer_irq = {
|
||||||
.dev_id = &sun5i_clockevent,
|
.dev_id = &sun5i_clockevent,
|
||||||
};
|
};
|
||||||
|
|
||||||
static u64 sun5i_timer_sched_read(void)
|
|
||||||
{
|
|
||||||
return ~readl(timer_base + TIMER_CNTVAL_LO_REG(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init sun5i_timer_init(struct device_node *node)
|
static void __init sun5i_timer_init(struct device_node *node)
|
||||||
{
|
{
|
||||||
struct reset_control *rstc;
|
struct reset_control *rstc;
|
||||||
|
@ -172,7 +166,6 @@ static void __init sun5i_timer_init(struct device_node *node)
|
||||||
writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
|
writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
|
||||||
timer_base + TIMER_CTL_REG(1));
|
timer_base + TIMER_CTL_REG(1));
|
||||||
|
|
||||||
sched_clock_register(sun5i_timer_sched_read, 32, rate);
|
|
||||||
clocksource_mmio_init(timer_base + TIMER_CNTVAL_LO_REG(1), node->name,
|
clocksource_mmio_init(timer_base + TIMER_CNTVAL_LO_REG(1), node->name,
|
||||||
rate, 340, 32, clocksource_mmio_readl_down);
|
rate, 340, 32, clocksource_mmio_readl_down);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ static void bc_set_mode(enum clock_event_mode mode,
|
||||||
*/
|
*/
|
||||||
static int bc_set_next(ktime_t expires, struct clock_event_device *bc)
|
static int bc_set_next(ktime_t expires, struct clock_event_device *bc)
|
||||||
{
|
{
|
||||||
|
int bc_moved;
|
||||||
/*
|
/*
|
||||||
* We try to cancel the timer first. If the callback is on
|
* We try to cancel the timer first. If the callback is on
|
||||||
* flight on some other cpu then we let it handle it. If we
|
* flight on some other cpu then we let it handle it. If we
|
||||||
|
@ -60,9 +61,15 @@ static int bc_set_next(ktime_t expires, struct clock_event_device *bc)
|
||||||
* restart the timer because we are in the callback, but we
|
* restart the timer because we are in the callback, but we
|
||||||
* can set the expiry time and let the callback return
|
* can set the expiry time and let the callback return
|
||||||
* HRTIMER_RESTART.
|
* HRTIMER_RESTART.
|
||||||
|
*
|
||||||
|
* Since we are in the idle loop at this point and because
|
||||||
|
* hrtimer_{start/cancel} functions call into tracing,
|
||||||
|
* calls to these functions must be bound within RCU_NONIDLE.
|
||||||
*/
|
*/
|
||||||
if (hrtimer_try_to_cancel(&bctimer) >= 0) {
|
RCU_NONIDLE(bc_moved = (hrtimer_try_to_cancel(&bctimer) >= 0) ?
|
||||||
hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED);
|
!hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED) :
|
||||||
|
0);
|
||||||
|
if (bc_moved) {
|
||||||
/* Bind the "device" to the cpu */
|
/* Bind the "device" to the cpu */
|
||||||
bc->bound_on = smp_processor_id();
|
bc->bound_on = smp_processor_id();
|
||||||
} else if (bc->bound_on == smp_processor_id()) {
|
} else if (bc->bound_on == smp_processor_id()) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче