Commit 037d2405 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fixes from Thomas Gleixner:
 "A few updates for timers & co:

   - prevent a livelock in the timekeeping code when debugging is
     enabled

   - prevent out of bounds access in the timekeeping debug code

   - various fixes in clocksource drivers

   - a new maintainers entry"

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  clocksource/drivers/sun4i: Clear interrupts after stopping timer in probe function
  drivers/clocksource/pistachio: Fix memory corruption in init
  clocksource/drivers/timer-atmel-pit: Enable mck clock
  clocksource/drivers/pxa: Fix include files for compilation
  MAINTAINERS: Add ARM ARCHITECTED TIMER entry
  timekeeping: Cap array access in timekeeping_debug
  timekeeping: Avoid taking lock in NMI path with CONFIG_DEBUG_TIMEKEEPING
parents af56ff27 b53e7d00
...@@ -881,6 +881,15 @@ S: Supported ...@@ -881,6 +881,15 @@ S: Supported
F: drivers/gpu/drm/arc/ F: drivers/gpu/drm/arc/
F: Documentation/devicetree/bindings/display/snps,arcpgu.txt F: Documentation/devicetree/bindings/display/snps,arcpgu.txt
ARM ARCHITECTED TIMER DRIVER
M: Mark Rutland <mark.rutland@arm.com>
M: Marc Zyngier <marc.zyngier@arm.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/include/asm/arch_timer.h
F: arch/arm64/include/asm/arch_timer.h
F: drivers/clocksource/arm_arch_timer.c
ARM HDLCD DRM DRIVER ARM HDLCD DRM DRIVER
M: Liviu Dudau <liviu.dudau@arm.com> M: Liviu Dudau <liviu.dudau@arm.com>
S: Supported S: Supported
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/sched_clock.h> #include <linux/sched_clock.h>
#include <clocksource/pxa.h>
#include <asm/div64.h> #include <asm/div64.h>
#define OSMR0 0x00 /* OS Timer 0 Match Register */ #define OSMR0 0x00 /* OS Timer 0 Match Register */
......
...@@ -123,12 +123,16 @@ static struct clock_event_device sun4i_clockevent = { ...@@ -123,12 +123,16 @@ static struct clock_event_device sun4i_clockevent = {
.set_next_event = sun4i_clkevt_next_event, .set_next_event = sun4i_clkevt_next_event,
}; };
static void sun4i_timer_clear_interrupt(void)
{
writel(TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_ST_REG);
}
static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id) static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id)
{ {
struct clock_event_device *evt = (struct clock_event_device *)dev_id; struct clock_event_device *evt = (struct clock_event_device *)dev_id;
writel(0x1, timer_base + TIMER_IRQ_ST_REG); sun4i_timer_clear_interrupt();
evt->event_handler(evt); evt->event_handler(evt);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -208,6 +212,9 @@ static int __init sun4i_timer_init(struct device_node *node) ...@@ -208,6 +212,9 @@ static int __init sun4i_timer_init(struct device_node *node)
/* Make sure timer is stopped before playing with interrupts */ /* Make sure timer is stopped before playing with interrupts */
sun4i_clkevt_time_stop(0); sun4i_clkevt_time_stop(0);
/* clear timer0 interrupt */
sun4i_timer_clear_interrupt();
sun4i_clockevent.cpumask = cpu_possible_mask; sun4i_clockevent.cpumask = cpu_possible_mask;
sun4i_clockevent.irq = irq; sun4i_clockevent.irq = irq;
......
...@@ -202,10 +202,10 @@ static int __init pistachio_clksrc_of_init(struct device_node *node) ...@@ -202,10 +202,10 @@ static int __init pistachio_clksrc_of_init(struct device_node *node)
rate = clk_get_rate(fast_clk); rate = clk_get_rate(fast_clk);
/* Disable irq's for clocksource usage */ /* Disable irq's for clocksource usage */
gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 0); gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 0);
gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 1); gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 1);
gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 2); gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 2);
gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 3); gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 3);
/* Enable timer block */ /* Enable timer block */
writel(TIMER_ME_GLOBAL, pcs_gpt.base); writel(TIMER_ME_GLOBAL, pcs_gpt.base);
......
...@@ -261,6 +261,12 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node) ...@@ -261,6 +261,12 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
return PTR_ERR(data->mck); return PTR_ERR(data->mck);
} }
ret = clk_prepare_enable(data->mck);
if (ret) {
pr_err("Unable to enable mck\n");
return ret;
}
/* Get the interrupts property */ /* Get the interrupts property */
data->irq = irq_of_parse_and_map(node, 0); data->irq = irq_of_parse_and_map(node, 0);
if (!data->irq) { if (!data->irq) {
......
...@@ -401,7 +401,10 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) ...@@ -401,7 +401,10 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf)
do { do {
seq = raw_read_seqcount_latch(&tkf->seq); seq = raw_read_seqcount_latch(&tkf->seq);
tkr = tkf->base + (seq & 0x01); tkr = tkf->base + (seq & 0x01);
now = ktime_to_ns(tkr->base) + timekeeping_get_ns(tkr); now = ktime_to_ns(tkr->base);
now += clocksource_delta(tkr->read(tkr->clock),
tkr->cycle_last, tkr->mask);
} while (read_seqcount_retry(&tkf->seq, seq)); } while (read_seqcount_retry(&tkf->seq, seq));
return now; return now;
......
...@@ -23,7 +23,9 @@ ...@@ -23,7 +23,9 @@
#include "timekeeping_internal.h" #include "timekeeping_internal.h"
static unsigned int sleep_time_bin[32] = {0}; #define NUM_BINS 32
static unsigned int sleep_time_bin[NUM_BINS] = {0};
static int tk_debug_show_sleep_time(struct seq_file *s, void *data) static int tk_debug_show_sleep_time(struct seq_file *s, void *data)
{ {
...@@ -69,6 +71,9 @@ late_initcall(tk_debug_sleep_time_init); ...@@ -69,6 +71,9 @@ late_initcall(tk_debug_sleep_time_init);
void tk_debug_account_sleep_time(struct timespec64 *t) void tk_debug_account_sleep_time(struct timespec64 *t)
{ {
sleep_time_bin[fls(t->tv_sec)]++; /* Cap bin index so we don't overflow the array */
int bin = min(fls(t->tv_sec), NUM_BINS-1);
sleep_time_bin[bin]++;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment