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

Pull timer fixes from Thomas Gleixner:
"A rather small update for the time(r) subsystem:

- A new clocksource driver IMX-TPM

- Minor fixes to the alarmtimer facility

- Device tree cleanups for Renesas drivers

- A new kselftest and fixes for the timer related tests

- Conversion of the clocksource drivers to use %pOF

- Use the proper helpers to access rlimits in the posix-cpu-timer
code"

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
alarmtimer: Ensure RTC module is not unloaded
clocksource: Convert to using %pOF instead of full_name
clocksource/drivers/bcm2835: Remove message for a memory allocation failure
devicetree: bindings: Remove deprecated properties
devicetree: bindings: Remove unused 32-bit CMT bindings
devicetree: bindings: Deprecate property, update example
devicetree: bindings: r8a73a4 and R-Car Gen2 CMT bindings
devicetree: bindings: R-Car Gen2 CMT0 and CMT1 bindings
devicetree: bindings: Remove sh7372 CMT binding
clocksource/drivers/imx-tpm: Add imx tpm timer support
dt-bindings: timer: Add nxp tpm timer binding doc
posix-cpu-timers: Use dedicated helper to access rlimit values
alarmtimer: Fix unavailable wake-up source in sysfs
timekeeping: Use proper timekeeper for debug code
kselftests: timers: set-timer-lat: Add one-shot timer test cases
kselftests: timers: set-timer-lat: Tweak reporting when timer fires early
kselftests: timers: freq-step: Fix build warning
kselftests: timers: freq-step: Define ADJ_SETOFFSET if device has older kernel headers

+439 -83
+28
Documentation/devicetree/bindings/timer/nxp,tpm-timer.txt
··· 1 + NXP Low Power Timer/Pulse Width Modulation Module (TPM) 2 + 3 + The Timer/PWM Module (TPM) supports input capture, output compare, 4 + and the generation of PWM signals to control electric motor and power 5 + management applications. The counter, compare and capture registers 6 + are clocked by an asynchronous clock that can remain enabled in low 7 + power modes. TPM can support global counter bus where one TPM drives 8 + the counter bus for the others, provided bit width is the same. 9 + 10 + Required properties: 11 + 12 + - compatible : should be "fsl,imx7ulp-tpm" 13 + - reg : Specifies base physical address and size of the register sets 14 + for the clock event device and clock source device. 15 + - interrupts : Should be the clock event device interrupt. 16 + - clocks : The clocks provided by the SoC to drive the timer, must contain 17 + an entry for each entry in clock-names. 18 + - clock-names : Must include the following entries: "igp" and "per". 19 + 20 + Example: 21 + tpm5: tpm@40260000 { 22 + compatible = "fsl,imx7ulp-tpm"; 23 + reg = <0x40260000 0x1000>; 24 + interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; 25 + clocks = <&clks IMX7ULP_CLK_NIC1_BUS_DIV>, 26 + <&clks IMX7ULP_CLK_LPTPM5>; 27 + clock-names = "ipg", "per"; 28 + };
+32 -41
Documentation/devicetree/bindings/timer/renesas,cmt.txt
··· 12 12 Required Properties: 13 13 14 14 - compatible: must contain one or more of the following: 15 - - "renesas,cmt-32-r8a7740" for the r8a7740 32-bit CMT 16 - (CMT0) 17 - - "renesas,cmt-32-sh7372" for the sh7372 32-bit CMT 18 - (CMT0) 19 - - "renesas,cmt-32-sh73a0" for the sh73a0 32-bit CMT 20 - (CMT0) 21 - - "renesas,cmt-32" for all 32-bit CMT without fast clock support 22 - (CMT0 on sh7372, sh73a0 and r8a7740) 23 - This is a fallback for the above renesas,cmt-32-* entries. 24 - 25 - - "renesas,cmt-32-fast-r8a7740" for the r8a7740 32-bit CMT with fast 26 - clock support (CMT[234]) 27 - - "renesas,cmt-32-fast-sh7372" for the sh7372 32-bit CMT with fast 28 - clock support (CMT[234]) 29 - - "renesas,cmt-32-fast-sh73a0" for the sh73A0 32-bit CMT with fast 30 - clock support (CMT[234]) 31 - - "renesas,cmt-32-fast" for all 32-bit CMT with fast clock support 32 - (CMT[234] on sh7372, sh73a0 and r8a7740) 33 - This is a fallback for the above renesas,cmt-32-fast-* entries. 34 - 35 - - "renesas,cmt-48-sh7372" for the sh7372 48-bit CMT 36 - (CMT1) 37 15 - "renesas,cmt-48-sh73a0" for the sh73A0 48-bit CMT 38 16 (CMT1) 39 17 - "renesas,cmt-48-r8a7740" for the r8a7740 48-bit CMT 40 18 (CMT1) 41 19 - "renesas,cmt-48" for all non-second generation 48-bit CMT 42 - (CMT1 on sh7372, sh73a0 and r8a7740) 20 + (CMT1 on sh73a0 and r8a7740) 43 21 This is a fallback for the above renesas,cmt-48-* entries. 44 22 45 - - "renesas,cmt-48-r8a73a4" for the r8a73a4 48-bit CMT 46 - (CMT[01]) 47 - - "renesas,cmt-48-r8a7790" for the r8a7790 48-bit CMT 48 - (CMT[01]) 49 - - "renesas,cmt-48-r8a7791" for the r8a7791 48-bit CMT 50 - (CMT[01]) 51 - - "renesas,cmt-48-gen2" for all second generation 48-bit CMT 52 - (CMT[01] on r8a73a4, r8a7790 and r8a7791) 53 - This is a fallback for the renesas,cmt-48-r8a73a4, 54 - renesas,cmt-48-r8a7790 and renesas,cmt-48-r8a7791 entries. 23 + - "renesas,cmt0-r8a73a4" for the 32-bit CMT0 device included in r8a73a4. 24 + - "renesas,cmt1-r8a73a4" for the 48-bit CMT1 device included in r8a73a4. 25 + - "renesas,cmt0-r8a7790" for the 32-bit CMT0 device included in r8a7790. 26 + - "renesas,cmt1-r8a7790" for the 48-bit CMT1 device included in r8a7790. 27 + - "renesas,cmt0-r8a7791" for the 32-bit CMT0 device included in r8a7791. 28 + - "renesas,cmt1-r8a7791" for the 48-bit CMT1 device included in r8a7791. 29 + - "renesas,cmt0-r8a7793" for the 32-bit CMT0 device included in r8a7793. 30 + - "renesas,cmt1-r8a7793" for the 48-bit CMT1 device included in r8a7793. 31 + - "renesas,cmt0-r8a7794" for the 32-bit CMT0 device included in r8a7794. 32 + - "renesas,cmt1-r8a7794" for the 48-bit CMT1 device included in r8a7794. 33 + 34 + - "renesas,rcar-gen2-cmt0" for 32-bit CMT0 devices included in R-Car Gen2. 35 + - "renesas,rcar-gen2-cmt1" for 48-bit CMT1 devices included in R-Car Gen2. 36 + These are fallbacks for r8a73a4 and all the R-Car Gen2 37 + entries listed above. 55 38 56 39 - reg: base address and length of the registers block for the timer module. 57 40 - interrupts: interrupt-specifier for the timer, one per channel. ··· 42 59 in clock-names. 43 60 - clock-names: must contain "fck" for the functional clock. 44 61 45 - - renesas,channels-mask: bitmask of the available channels. 46 62 47 - 48 - Example: R8A7790 (R-Car H2) CMT0 node 49 - 50 - CMT0 on R8A7790 implements hardware channels 5 and 6 only and names 51 - them channels 0 and 1 in the documentation. 63 + Example: R8A7790 (R-Car H2) CMT0 and CMT1 nodes 52 64 53 65 cmt0: timer@ffca0000 { 54 - compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2"; 66 + compatible = "renesas,cmt0-r8a7790", "renesas,rcar-gen2-cmt0"; 55 67 reg = <0 0xffca0000 0 0x1004>; 56 68 interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, 57 69 <0 142 IRQ_TYPE_LEVEL_HIGH>; 58 70 clocks = <&mstp1_clks R8A7790_CLK_CMT0>; 59 71 clock-names = "fck"; 72 + }; 60 73 61 - renesas,channels-mask = <0x60>; 74 + cmt1: timer@e6130000 { 75 + compatible = "renesas,cmt1-r8a7790", "renesas,rcar-gen2-cmt1"; 76 + reg = <0 0xe6130000 0 0x1004>; 77 + interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, 78 + <0 121 IRQ_TYPE_LEVEL_HIGH>, 79 + <0 122 IRQ_TYPE_LEVEL_HIGH>, 80 + <0 123 IRQ_TYPE_LEVEL_HIGH>, 81 + <0 124 IRQ_TYPE_LEVEL_HIGH>, 82 + <0 125 IRQ_TYPE_LEVEL_HIGH>, 83 + <0 126 IRQ_TYPE_LEVEL_HIGH>, 84 + <0 127 IRQ_TYPE_LEVEL_HIGH>; 85 + clocks = <&mstp3_clks R8A7790_CLK_CMT1>; 86 + clock-names = "fck"; 62 87 };
+8
drivers/clocksource/Kconfig
··· 598 598 depends on ARM && CLKDEV_LOOKUP 599 599 select CLKSRC_MMIO 600 600 601 + config CLKSRC_IMX_TPM 602 + bool "Clocksource using i.MX TPM" if COMPILE_TEST 603 + depends on ARM && CLKDEV_LOOKUP && GENERIC_CLOCKEVENTS 604 + select CLKSRC_MMIO 605 + help 606 + Enable this option to use IMX Timer/PWM Module (TPM) timer as 607 + clocksource. 608 + 601 609 config CLKSRC_ST_LPC 602 610 bool "Low power clocksource found in the LPC" if COMPILE_TEST 603 611 select TIMER_OF if OF
+1
drivers/clocksource/Makefile
··· 67 67 obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o 68 68 obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o 69 69 obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o 70 + obj-$(CONFIG_CLKSRC_IMX_TPM) += timer-imx-tpm.o 70 71 obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o 71 72 obj-$(CONFIG_H8300_TMR8) += h8300_timer8.o 72 73 obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o
-1
drivers/clocksource/bcm2835_timer.c
··· 114 114 115 115 timer = kzalloc(sizeof(*timer), GFP_KERNEL); 116 116 if (!timer) { 117 - pr_err("Can't allocate timer struct\n"); 118 117 ret = -ENOMEM; 119 118 goto err_iounmap; 120 119 }
+3 -3
drivers/clocksource/tango_xtal.c
··· 26 26 27 27 xtal_in_cnt = of_iomap(np, 0); 28 28 if (xtal_in_cnt == NULL) { 29 - pr_err("%s: invalid address\n", np->full_name); 29 + pr_err("%pOF: invalid address\n", np); 30 30 return -ENXIO; 31 31 } 32 32 33 33 clk = of_clk_get(np, 0); 34 34 if (IS_ERR(clk)) { 35 - pr_err("%s: invalid clock\n", np->full_name); 35 + pr_err("%pOF: invalid clock\n", np); 36 36 return PTR_ERR(clk); 37 37 } 38 38 ··· 43 43 ret = clocksource_mmio_init(xtal_in_cnt, "tango-xtal", xtal_freq, 350, 44 44 32, clocksource_mmio_readl_up); 45 45 if (ret) { 46 - pr_err("%s: registration failed\n", np->full_name); 46 + pr_err("%pOF: registration failed\n", np); 47 47 return ret; 48 48 } 49 49
+239
drivers/clocksource/timer-imx-tpm.c
··· 1 + /* 2 + * Copyright 2016 Freescale Semiconductor, Inc. 3 + * Copyright 2017 NXP 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + */ 10 + 11 + #include <linux/clk.h> 12 + #include <linux/clockchips.h> 13 + #include <linux/clocksource.h> 14 + #include <linux/delay.h> 15 + #include <linux/interrupt.h> 16 + #include <linux/of_address.h> 17 + #include <linux/of_irq.h> 18 + #include <linux/sched_clock.h> 19 + 20 + #define TPM_SC 0x10 21 + #define TPM_SC_CMOD_INC_PER_CNT (0x1 << 3) 22 + #define TPM_SC_CMOD_DIV_DEFAULT 0x3 23 + #define TPM_CNT 0x14 24 + #define TPM_MOD 0x18 25 + #define TPM_STATUS 0x1c 26 + #define TPM_STATUS_CH0F BIT(0) 27 + #define TPM_C0SC 0x20 28 + #define TPM_C0SC_CHIE BIT(6) 29 + #define TPM_C0SC_MODE_SHIFT 2 30 + #define TPM_C0SC_MODE_MASK 0x3c 31 + #define TPM_C0SC_MODE_SW_COMPARE 0x4 32 + #define TPM_C0V 0x24 33 + 34 + static void __iomem *timer_base; 35 + static struct clock_event_device clockevent_tpm; 36 + 37 + static inline void tpm_timer_disable(void) 38 + { 39 + unsigned int val; 40 + 41 + /* channel disable */ 42 + val = readl(timer_base + TPM_C0SC); 43 + val &= ~(TPM_C0SC_MODE_MASK | TPM_C0SC_CHIE); 44 + writel(val, timer_base + TPM_C0SC); 45 + } 46 + 47 + static inline void tpm_timer_enable(void) 48 + { 49 + unsigned int val; 50 + 51 + /* channel enabled in sw compare mode */ 52 + val = readl(timer_base + TPM_C0SC); 53 + val |= (TPM_C0SC_MODE_SW_COMPARE << TPM_C0SC_MODE_SHIFT) | 54 + TPM_C0SC_CHIE; 55 + writel(val, timer_base + TPM_C0SC); 56 + } 57 + 58 + static inline void tpm_irq_acknowledge(void) 59 + { 60 + writel(TPM_STATUS_CH0F, timer_base + TPM_STATUS); 61 + } 62 + 63 + static struct delay_timer tpm_delay_timer; 64 + 65 + static inline unsigned long tpm_read_counter(void) 66 + { 67 + return readl(timer_base + TPM_CNT); 68 + } 69 + 70 + static unsigned long tpm_read_current_timer(void) 71 + { 72 + return tpm_read_counter(); 73 + } 74 + 75 + static u64 notrace tpm_read_sched_clock(void) 76 + { 77 + return tpm_read_counter(); 78 + } 79 + 80 + static int __init tpm_clocksource_init(unsigned long rate) 81 + { 82 + tpm_delay_timer.read_current_timer = &tpm_read_current_timer; 83 + tpm_delay_timer.freq = rate; 84 + register_current_timer_delay(&tpm_delay_timer); 85 + 86 + sched_clock_register(tpm_read_sched_clock, 32, rate); 87 + 88 + return clocksource_mmio_init(timer_base + TPM_CNT, "imx-tpm", 89 + rate, 200, 32, clocksource_mmio_readl_up); 90 + } 91 + 92 + static int tpm_set_next_event(unsigned long delta, 93 + struct clock_event_device *evt) 94 + { 95 + unsigned long next, now; 96 + 97 + next = tpm_read_counter(); 98 + next += delta; 99 + writel(next, timer_base + TPM_C0V); 100 + now = tpm_read_counter(); 101 + 102 + /* 103 + * NOTE: We observed in a very small probability, the bus fabric 104 + * contention between GPU and A7 may results a few cycles delay 105 + * of writing CNT registers which may cause the min_delta event got 106 + * missed, so we need add a ETIME check here in case it happened. 107 + */ 108 + return (int)((next - now) <= 0) ? -ETIME : 0; 109 + } 110 + 111 + static int tpm_set_state_oneshot(struct clock_event_device *evt) 112 + { 113 + tpm_timer_enable(); 114 + 115 + return 0; 116 + } 117 + 118 + static int tpm_set_state_shutdown(struct clock_event_device *evt) 119 + { 120 + tpm_timer_disable(); 121 + 122 + return 0; 123 + } 124 + 125 + static irqreturn_t tpm_timer_interrupt(int irq, void *dev_id) 126 + { 127 + struct clock_event_device *evt = dev_id; 128 + 129 + tpm_irq_acknowledge(); 130 + 131 + evt->event_handler(evt); 132 + 133 + return IRQ_HANDLED; 134 + } 135 + 136 + static struct clock_event_device clockevent_tpm = { 137 + .name = "i.MX7ULP TPM Timer", 138 + .features = CLOCK_EVT_FEAT_ONESHOT, 139 + .set_state_oneshot = tpm_set_state_oneshot, 140 + .set_next_event = tpm_set_next_event, 141 + .set_state_shutdown = tpm_set_state_shutdown, 142 + .rating = 200, 143 + }; 144 + 145 + static int __init tpm_clockevent_init(unsigned long rate, int irq) 146 + { 147 + int ret; 148 + 149 + ret = request_irq(irq, tpm_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL, 150 + "i.MX7ULP TPM Timer", &clockevent_tpm); 151 + 152 + clockevent_tpm.cpumask = cpumask_of(0); 153 + clockevent_tpm.irq = irq; 154 + clockevents_config_and_register(&clockevent_tpm, 155 + rate, 300, 0xfffffffe); 156 + 157 + return ret; 158 + } 159 + 160 + static int __init tpm_timer_init(struct device_node *np) 161 + { 162 + struct clk *ipg, *per; 163 + int irq, ret; 164 + u32 rate; 165 + 166 + timer_base = of_iomap(np, 0); 167 + if (!timer_base) { 168 + pr_err("tpm: failed to get base address\n"); 169 + return -ENXIO; 170 + } 171 + 172 + irq = irq_of_parse_and_map(np, 0); 173 + if (!irq) { 174 + pr_err("tpm: failed to get irq\n"); 175 + ret = -ENOENT; 176 + goto err_iomap; 177 + } 178 + 179 + ipg = of_clk_get_by_name(np, "ipg"); 180 + per = of_clk_get_by_name(np, "per"); 181 + if (IS_ERR(ipg) || IS_ERR(per)) { 182 + pr_err("tpm: failed to get igp or per clk\n"); 183 + ret = -ENODEV; 184 + goto err_clk_get; 185 + } 186 + 187 + /* enable clk before accessing registers */ 188 + ret = clk_prepare_enable(ipg); 189 + if (ret) { 190 + pr_err("tpm: ipg clock enable failed (%d)\n", ret); 191 + goto err_clk_get; 192 + } 193 + 194 + ret = clk_prepare_enable(per); 195 + if (ret) { 196 + pr_err("tpm: per clock enable failed (%d)\n", ret); 197 + goto err_per_clk_enable; 198 + } 199 + 200 + /* 201 + * Initialize tpm module to a known state 202 + * 1) Counter disabled 203 + * 2) TPM counter operates in up counting mode 204 + * 3) Timer Overflow Interrupt disabled 205 + * 4) Channel0 disabled 206 + * 5) DMA transfers disabled 207 + */ 208 + writel(0, timer_base + TPM_SC); 209 + writel(0, timer_base + TPM_CNT); 210 + writel(0, timer_base + TPM_C0SC); 211 + 212 + /* increase per cnt, div 8 by default */ 213 + writel(TPM_SC_CMOD_INC_PER_CNT | TPM_SC_CMOD_DIV_DEFAULT, 214 + timer_base + TPM_SC); 215 + 216 + /* set MOD register to maximum for free running mode */ 217 + writel(0xffffffff, timer_base + TPM_MOD); 218 + 219 + rate = clk_get_rate(per) >> 3; 220 + ret = tpm_clocksource_init(rate); 221 + if (ret) 222 + goto err_per_clk_enable; 223 + 224 + ret = tpm_clockevent_init(rate, irq); 225 + if (ret) 226 + goto err_per_clk_enable; 227 + 228 + return 0; 229 + 230 + err_per_clk_enable: 231 + clk_disable_unprepare(ipg); 232 + err_clk_get: 233 + clk_put(per); 234 + clk_put(ipg); 235 + err_iomap: 236 + iounmap(timer_base); 237 + return ret; 238 + } 239 + TIMER_OF_DECLARE(imx7ulp, "fsl,imx7ulp-tpm", tpm_timer_init);
+5 -6
drivers/clocksource/timer-of.c
··· 52 52 of_irq->irq = irq_of_parse_and_map(np, of_irq->index); 53 53 } 54 54 if (!of_irq->irq) { 55 - pr_err("Failed to map interrupt for %s\n", np->full_name); 55 + pr_err("Failed to map interrupt for %pOF\n", np); 56 56 return -EINVAL; 57 57 } 58 58 ··· 63 63 of_irq->flags ? of_irq->flags : IRQF_TIMER, 64 64 np->full_name, clkevt); 65 65 if (ret) { 66 - pr_err("Failed to request irq %d for %s\n", of_irq->irq, 67 - np->full_name); 66 + pr_err("Failed to request irq %d for %pOF\n", of_irq->irq, np); 68 67 return ret; 69 68 } 70 69 ··· 87 88 of_clk->clk = of_clk->name ? of_clk_get_by_name(np, of_clk->name) : 88 89 of_clk_get(np, of_clk->index); 89 90 if (IS_ERR(of_clk->clk)) { 90 - pr_err("Failed to get clock for %s\n", np->full_name); 91 + pr_err("Failed to get clock for %pOF\n", np); 91 92 return PTR_ERR(of_clk->clk); 92 93 } 93 94 94 95 ret = clk_prepare_enable(of_clk->clk); 95 96 if (ret) { 96 - pr_err("Failed for enable clock for %s\n", np->full_name); 97 + pr_err("Failed for enable clock for %pOF\n", np); 97 98 goto out_clk_put; 98 99 } 99 100 100 101 of_clk->rate = clk_get_rate(of_clk->clk); 101 102 if (!of_clk->rate) { 102 103 ret = -EINVAL; 103 - pr_err("Failed to get clock rate for %s\n", np->full_name); 104 + pr_err("Failed to get clock rate for %pOF\n", np); 104 105 goto out_clk_disable; 105 106 } 106 107
+1 -2
drivers/clocksource/timer-probe.c
··· 40 40 41 41 ret = init_func_ret(np); 42 42 if (ret) { 43 - pr_err("Failed to initialize '%s': %d\n", 44 - of_node_full_name(np), ret); 43 + pr_err("Failed to initialize '%pOF': %d\n", np, ret); 45 44 continue; 46 45 } 47 46
+4 -4
drivers/clocksource/timer-stm32.c
··· 138 138 irq = irq_of_parse_and_map(np, 0); 139 139 if (!irq) { 140 140 ret = -EINVAL; 141 - pr_err("%s: failed to get irq.\n", np->full_name); 141 + pr_err("%pOF: failed to get irq.\n", np); 142 142 goto err_get_irq; 143 143 } 144 144 ··· 168 168 ret = request_irq(irq, stm32_clock_event_handler, IRQF_TIMER, 169 169 "stm32 clockevent", data); 170 170 if (ret) { 171 - pr_err("%s: failed to request irq.\n", np->full_name); 171 + pr_err("%pOF: failed to request irq.\n", np); 172 172 goto err_get_irq; 173 173 } 174 174 175 - pr_info("%s: STM32 clockevent driver initialized (%d bits)\n", 176 - np->full_name, bits); 175 + pr_info("%pOF: STM32 clockevent driver initialized (%d bits)\n", 176 + np, bits); 177 177 178 178 return ret; 179 179
+15 -2
kernel/time/alarmtimer.c
··· 28 28 #include <linux/workqueue.h> 29 29 #include <linux/freezer.h> 30 30 #include <linux/compat.h> 31 + #include <linux/module.h> 31 32 32 33 #include "posix-timers.h" 33 34 ··· 57 56 static DEFINE_SPINLOCK(freezer_delta_lock); 58 57 #endif 59 58 59 + #ifdef CONFIG_RTC_CLASS 60 60 static struct wakeup_source *ws; 61 61 62 - #ifdef CONFIG_RTC_CLASS 63 62 /* rtc timer and device for setting alarm wakeups at suspend */ 64 63 static struct rtc_timer rtctimer; 65 64 static struct rtc_device *rtcdev; ··· 90 89 { 91 90 unsigned long flags; 92 91 struct rtc_device *rtc = to_rtc_device(dev); 92 + struct wakeup_source *__ws; 93 93 94 94 if (rtcdev) 95 95 return -EBUSY; ··· 100 98 if (!device_may_wakeup(rtc->dev.parent)) 101 99 return -1; 102 100 101 + __ws = wakeup_source_register("alarmtimer"); 102 + 103 103 spin_lock_irqsave(&rtcdev_lock, flags); 104 104 if (!rtcdev) { 105 + if (!try_module_get(rtc->owner)) { 106 + spin_unlock_irqrestore(&rtcdev_lock, flags); 107 + return -1; 108 + } 109 + 105 110 rtcdev = rtc; 106 111 /* hold a reference so it doesn't go away */ 107 112 get_device(dev); 113 + ws = __ws; 114 + __ws = NULL; 108 115 } 109 116 spin_unlock_irqrestore(&rtcdev_lock, flags); 117 + 118 + wakeup_source_unregister(__ws); 119 + 110 120 return 0; 111 121 } 112 122 ··· 874 860 error = PTR_ERR(pdev); 875 861 goto out_drv; 876 862 } 877 - ws = wakeup_source_register("alarmtimer"); 878 863 return 0; 879 864 880 865 out_drv:
+6 -8
kernel/time/posix-cpu-timers.c
··· 799 799 struct list_head *firing) 800 800 { 801 801 struct list_head *timers = tsk->cpu_timers; 802 - struct signal_struct *const sig = tsk->signal; 803 802 struct task_cputime *tsk_expires = &tsk->cputime_expires; 804 803 u64 expires; 805 804 unsigned long soft; ··· 822 823 /* 823 824 * Check for the special case thread timers. 824 825 */ 825 - soft = READ_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur); 826 + soft = task_rlimit(tsk, RLIMIT_RTTIME); 826 827 if (soft != RLIM_INFINITY) { 827 - unsigned long hard = 828 - READ_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_max); 828 + unsigned long hard = task_rlimit_max(tsk, RLIMIT_RTTIME); 829 829 830 830 if (hard != RLIM_INFINITY && 831 831 tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) { ··· 845 847 */ 846 848 if (soft < hard) { 847 849 soft += USEC_PER_SEC; 848 - sig->rlim[RLIMIT_RTTIME].rlim_cur = soft; 850 + tsk->signal->rlim[RLIMIT_RTTIME].rlim_cur = 851 + soft; 849 852 } 850 853 if (print_fatal_signals) { 851 854 pr_info("RT Watchdog Timeout (soft): %s[%d]\n", ··· 937 938 SIGPROF); 938 939 check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, 939 940 SIGVTALRM); 940 - soft = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur); 941 + soft = task_rlimit(tsk, RLIMIT_CPU); 941 942 if (soft != RLIM_INFINITY) { 942 943 unsigned long psecs = div_u64(ptime, NSEC_PER_SEC); 943 - unsigned long hard = 944 - READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_max); 944 + unsigned long hard = task_rlimit_max(tsk, RLIMIT_CPU); 945 945 u64 x; 946 946 if (psecs >= hard) { 947 947 /*
+1 -1
kernel/time/timekeeping.c
··· 2064 2064 goto out; 2065 2065 2066 2066 /* Do some additional sanity checking */ 2067 - timekeeping_check_update(real_tk, offset); 2067 + timekeeping_check_update(tk, offset); 2068 2068 2069 2069 /* 2070 2070 * With NO_HZ we may have to accumulate many cycle_intervals
+6 -2
tools/testing/selftests/timers/freq-step.c
··· 33 33 #define MAX_FREQ_ERROR 10e-6 34 34 #define MAX_STDDEV 1000e-9 35 35 36 + #ifndef ADJ_SETOFFSET 37 + #define ADJ_SETOFFSET 0x0100 38 + #endif 39 + 36 40 struct sample { 37 41 double offset; 38 42 double time; ··· 265 261 set_frequency(0.0); 266 262 267 263 if (fails) 268 - ksft_exit_fail(); 264 + return ksft_exit_fail(); 269 265 270 - ksft_exit_pass(); 266 + return ksft_exit_pass(); 271 267 }
+90 -13
tools/testing/selftests/timers/set-timer-lat.c
··· 20 20 */ 21 21 22 22 23 + #include <errno.h> 23 24 #include <stdio.h> 24 25 #include <unistd.h> 25 26 #include <time.h> ··· 64 63 int clock_id; 65 64 struct timespec start_time; 66 65 long long max_latency_ns; 66 + int timer_fired_early; 67 67 68 68 char *clockstring(int clockid) 69 69 { ··· 117 115 delta_ns -= NSEC_PER_SEC * TIMER_SECS * alarmcount; 118 116 119 117 if (delta_ns < 0) 120 - printf("%s timer fired early: FAIL\n", clockstring(clock_id)); 118 + timer_fired_early = 1; 121 119 122 120 if (delta_ns > max_latency_ns) 123 121 max_latency_ns = delta_ns; 124 122 } 125 123 126 - int do_timer(int clock_id, int flags) 124 + void describe_timer(int flags, int interval) 125 + { 126 + printf("%-22s %s %s ", 127 + clockstring(clock_id), 128 + flags ? "ABSTIME":"RELTIME", 129 + interval ? "PERIODIC":"ONE-SHOT"); 130 + } 131 + 132 + int setup_timer(int clock_id, int flags, int interval, timer_t *tm1) 127 133 { 128 134 struct sigevent se; 129 - timer_t tm1; 130 135 struct itimerspec its1, its2; 131 136 int err; 132 137 ··· 145 136 146 137 max_latency_ns = 0; 147 138 alarmcount = 0; 139 + timer_fired_early = 0; 148 140 149 - err = timer_create(clock_id, &se, &tm1); 141 + err = timer_create(clock_id, &se, tm1); 150 142 if (err) { 151 143 if ((clock_id == CLOCK_REALTIME_ALARM) || 152 144 (clock_id == CLOCK_BOOTTIME_ALARM)) { ··· 168 158 its1.it_value.tv_sec = TIMER_SECS; 169 159 its1.it_value.tv_nsec = 0; 170 160 } 171 - its1.it_interval.tv_sec = TIMER_SECS; 161 + its1.it_interval.tv_sec = interval; 172 162 its1.it_interval.tv_nsec = 0; 173 163 174 - err = timer_settime(tm1, flags, &its1, &its2); 164 + err = timer_settime(*tm1, flags, &its1, &its2); 175 165 if (err) { 176 166 printf("%s - timer_settime() failed\n", clockstring(clock_id)); 177 167 return -1; 178 168 } 179 169 180 - while (alarmcount < 5) 181 - sleep(1); 170 + return 0; 171 + } 182 172 183 - printf("%-22s %s max latency: %10lld ns : ", 184 - clockstring(clock_id), 185 - flags ? "ABSTIME":"RELTIME", 186 - max_latency_ns); 173 + int check_timer_latency(int flags, int interval) 174 + { 175 + int err = 0; 187 176 188 - timer_delete(tm1); 177 + describe_timer(flags, interval); 178 + printf("timer fired early: %7d : ", timer_fired_early); 179 + if (!timer_fired_early) { 180 + printf("[OK]\n"); 181 + } else { 182 + printf("[FAILED]\n"); 183 + err = -1; 184 + } 185 + 186 + describe_timer(flags, interval); 187 + printf("max latency: %10lld ns : ", max_latency_ns); 188 + 189 189 if (max_latency_ns < UNRESONABLE_LATENCY) { 190 + printf("[OK]\n"); 191 + } else { 192 + printf("[FAILED]\n"); 193 + err = -1; 194 + } 195 + return err; 196 + } 197 + 198 + int check_alarmcount(int flags, int interval) 199 + { 200 + describe_timer(flags, interval); 201 + printf("count: %19d : ", alarmcount); 202 + if (alarmcount == 1) { 190 203 printf("[OK]\n"); 191 204 return 0; 192 205 } 193 206 printf("[FAILED]\n"); 194 207 return -1; 208 + } 209 + 210 + int do_timer(int clock_id, int flags) 211 + { 212 + timer_t tm1; 213 + const int interval = TIMER_SECS; 214 + int err; 215 + 216 + err = setup_timer(clock_id, flags, interval, &tm1); 217 + if (err) 218 + return err; 219 + 220 + while (alarmcount < 5) 221 + sleep(1); 222 + 223 + timer_delete(tm1); 224 + return check_timer_latency(flags, interval); 225 + } 226 + 227 + int do_timer_oneshot(int clock_id, int flags) 228 + { 229 + timer_t tm1; 230 + const int interval = 0; 231 + struct timeval timeout; 232 + fd_set fds; 233 + int err; 234 + 235 + err = setup_timer(clock_id, flags, interval, &tm1); 236 + if (err) 237 + return err; 238 + 239 + memset(&timeout, 0, sizeof(timeout)); 240 + timeout.tv_sec = 5; 241 + FD_ZERO(&fds); 242 + do { 243 + err = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); 244 + } while (err == -1 && errno == EINTR); 245 + 246 + timer_delete(tm1); 247 + err = check_timer_latency(flags, interval); 248 + err |= check_alarmcount(flags, interval); 249 + return err; 195 250 } 196 251 197 252 int main(void) ··· 284 209 285 210 ret |= do_timer(clock_id, TIMER_ABSTIME); 286 211 ret |= do_timer(clock_id, 0); 212 + ret |= do_timer_oneshot(clock_id, TIMER_ABSTIME); 213 + ret |= do_timer_oneshot(clock_id, 0); 287 214 } 288 215 if (ret) 289 216 return ksft_exit_fail();