Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'timers_urgent_for_v6.11_rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fixes from Borislav Petkov:

- Remove percpu irq related code in the timer-of initialization routine
as it is broken but also unused (Daniel Lezcano)

- Fix return -ETIME when delta exceeds INT_MAX and the next event not
taking effect sometimes (Jacky Bai)

* tag 'timers_urgent_for_v6.11_rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
clocksource/drivers/imx-tpm: Fix next event not taking effect sometime
clocksource/drivers/imx-tpm: Fix return -ETIME when delta exceeds INT_MAX
clocksource/drivers/timer-of: Remove percpu irq related code

+16 -18
+12 -4
drivers/clocksource/timer-imx-tpm.c
··· 83 83 static int tpm_set_next_event(unsigned long delta, 84 84 struct clock_event_device *evt) 85 85 { 86 - unsigned long next, now; 86 + unsigned long next, prev, now; 87 87 88 - next = tpm_read_counter(); 89 - next += delta; 88 + prev = tpm_read_counter(); 89 + next = prev + delta; 90 90 writel(next, timer_base + TPM_C0V); 91 91 now = tpm_read_counter(); 92 + 93 + /* 94 + * Need to wait CNT increase at least 1 cycle to make sure 95 + * the C0V has been updated into HW. 96 + */ 97 + if ((next & 0xffffffff) != readl(timer_base + TPM_C0V)) 98 + while (now == tpm_read_counter()) 99 + ; 92 100 93 101 /* 94 102 * NOTE: We observed in a very small probability, the bus fabric ··· 104 96 * of writing CNT registers which may cause the min_delta event got 105 97 * missed, so we need add a ETIME check here in case it happened. 106 98 */ 107 - return (int)(next - now) <= 0 ? -ETIME : 0; 99 + return (now - prev) >= delta ? -ETIME : 0; 108 100 } 109 101 110 102 static int tpm_set_state_oneshot(struct clock_event_device *evt)
+4 -13
drivers/clocksource/timer-of.c
··· 25 25 26 26 struct clock_event_device *clkevt = &to->clkevt; 27 27 28 - if (of_irq->percpu) 29 - free_percpu_irq(of_irq->irq, clkevt); 30 - else 31 - free_irq(of_irq->irq, clkevt); 28 + free_irq(of_irq->irq, clkevt); 32 29 } 33 30 34 31 /** ··· 38 41 * 39 42 * - Get interrupt number by name 40 43 * - Get interrupt number by index 41 - * 42 - * When the interrupt is per CPU, 'request_percpu_irq()' is called, 43 - * otherwise 'request_irq()' is used. 44 44 * 45 45 * Returns 0 on success, < 0 otherwise 46 46 */ ··· 63 69 return -EINVAL; 64 70 } 65 71 66 - ret = of_irq->percpu ? 67 - request_percpu_irq(of_irq->irq, of_irq->handler, 68 - np->full_name, clkevt) : 69 - request_irq(of_irq->irq, of_irq->handler, 70 - of_irq->flags ? of_irq->flags : IRQF_TIMER, 71 - np->full_name, clkevt); 72 + ret = request_irq(of_irq->irq, of_irq->handler, 73 + of_irq->flags ? of_irq->flags : IRQF_TIMER, 74 + np->full_name, clkevt); 72 75 if (ret) { 73 76 pr_err("Failed to request irq %d for %pOF\n", of_irq->irq, np); 74 77 return ret;
-1
drivers/clocksource/timer-of.h
··· 11 11 struct of_timer_irq { 12 12 int irq; 13 13 int index; 14 - int percpu; 15 14 const char *name; 16 15 unsigned long flags; 17 16 irq_handler_t handler;