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-core-2020-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer updates from Thomas Gleixner:
"Time, timers and related driver updates:

- Prevent unnecessary timer softirq invocations by extending the
tracking of the next expiring timer in the timer wheel beyond the
existing NOHZ functionality.

The tracking overhead at enqueue time is within the noise, but on
sensitive workloads the avoidance of the soft interrupt invocation
is a measurable improvement.

- The obligatory new clocksource driver for Ingenic X100 OST

- The usual fixes, improvements, cleanups and extensions for newer
chip variants all over the driver space"

* tag 'timers-core-2020-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (28 commits)
timers: Recalculate next timer interrupt only when necessary
clocksource/drivers/ingenic: Add support for the Ingenic X1000 OST.
dt-bindings: timer: Add Ingenic X1000 OST bindings.
clocksource/drivers: Replace HTTP links with HTTPS ones
clocksource/drivers/nomadik-mtu: Handle 32kHz clock
clocksource/drivers/sh_cmt: Use "kHz" for kilohertz
clocksource/drivers/imx: Add support for i.MX TPM driver with ARM64
clocksource/drivers/ingenic: Add high resolution timer support for SMP/SMT.
timers: Lower base clock forwarding threshold
timers: Remove must_forward_clk
timers: Spare timer softirq until next expiry
timers: Expand clk forward logic beyond nohz
timers: Reuse next expiry cache after nohz exit
timers: Always keep track of next expiry
timers: Optimize _next_timer_interrupt() level iteration
timers: Add comments about calc_index() ceiling work
timers: Move trigger_dyntick_cpu() to enqueue_timer()
timers: Use only bucket expiry for base->next_expiry value
timers: Preserve higher bits of expiration on index calculation
clocksource/drivers/timer-atmel-tcb: Add sama5d2 support
...

+1106 -325
-56
Documentation/devicetree/bindings/mfd/atmel-tcb.txt
··· 1 - * Device tree bindings for Atmel Timer Counter Blocks 2 - - compatible: Should be "atmel,<chip>-tcb", "simple-mfd", "syscon". 3 - <chip> can be "at91rm9200" or "at91sam9x5" 4 - - reg: Should contain registers location and length 5 - - #address-cells: has to be 1 6 - - #size-cells: has to be 0 7 - - interrupts: Should contain all interrupts for the TC block 8 - Note that you can specify several interrupt cells if the TC 9 - block has one interrupt per channel. 10 - - clock-names: tuple listing input clock names. 11 - Required elements: "t0_clk", "slow_clk" 12 - Optional elements: "t1_clk", "t2_clk" 13 - - clocks: phandles to input clocks. 14 - 15 - The TCB can expose multiple subdevices: 16 - * a timer 17 - - compatible: Should be "atmel,tcb-timer" 18 - - reg: Should contain the TCB channels to be used. If the 19 - counter width is 16 bits (at91rm9200-tcb), two consecutive 20 - channels are needed. Else, only one channel will be used. 21 - 22 - Examples: 23 - 24 - One interrupt per TC block: 25 - tcb0: timer@fff7c000 { 26 - compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon"; 27 - #address-cells = <1>; 28 - #size-cells = <0>; 29 - reg = <0xfff7c000 0x100>; 30 - interrupts = <18 4>; 31 - clocks = <&tcb0_clk>, <&clk32k>; 32 - clock-names = "t0_clk", "slow_clk"; 33 - 34 - timer@0 { 35 - compatible = "atmel,tcb-timer"; 36 - reg = <0>, <1>; 37 - }; 38 - 39 - timer@2 { 40 - compatible = "atmel,tcb-timer"; 41 - reg = <2>; 42 - }; 43 - }; 44 - 45 - One interrupt per TC channel in a TC block: 46 - tcb1: timer@fffdc000 { 47 - compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon"; 48 - #address-cells = <1>; 49 - #size-cells = <0>; 50 - reg = <0xfffdc000 0x100>; 51 - interrupts = <26 4>, <27 4>, <28 4>; 52 - clocks = <&tcb1_clk>, <&clk32k>; 53 - clock-names = "t0_clk", "slow_clk"; 54 - }; 55 - 56 -
+155
Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: "http://devicetree.org/schemas/soc/microchip/atmel,at91rm9200-tcb.yaml#" 5 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 + 7 + title: Atmel Timer Counter Block 8 + 9 + maintainers: 10 + - Alexandre Belloni <alexandre.belloni@bootlin.com> 11 + 12 + description: | 13 + The Atmel (now Microchip) SoCs have timers named Timer Counter Block. Each 14 + timer has three channels with two counters each. 15 + 16 + properties: 17 + compatible: 18 + items: 19 + - enum: 20 + - atmel,at91rm9200-tcb 21 + - atmel,at91sam9x5-tcb 22 + - atmel,sama5d2-tcb 23 + - const: simple-mfd 24 + - const: syscon 25 + 26 + reg: 27 + maxItems: 1 28 + 29 + interrupts: 30 + description: 31 + List of interrupts. One interrupt per TCB channel if available or one 32 + interrupt for the TC block 33 + minItems: 1 34 + maxItems: 3 35 + 36 + clock-names: 37 + description: 38 + List of clock names. Always includes t0_clk and slow clk. Also includes 39 + t1_clk and t2_clk if a clock per channel is available. 40 + minItems: 2 41 + maxItems: 4 42 + 43 + clocks: 44 + minItems: 2 45 + maxItems: 4 46 + 47 + '#address-cells': 48 + const: 1 49 + 50 + '#size-cells': 51 + const: 0 52 + 53 + patternProperties: 54 + "^timer@[0-2]$": 55 + description: The timer block channels that are used as timers. 56 + type: object 57 + properties: 58 + compatible: 59 + const: atmel,tcb-timer 60 + reg: 61 + description: 62 + List of channels to use for this particular timer. 63 + minItems: 1 64 + maxItems: 3 65 + 66 + required: 67 + - compatible 68 + - reg 69 + 70 + allOf: 71 + - if: 72 + properties: 73 + compatible: 74 + contains: 75 + const: atmel,sama5d2-tcb 76 + then: 77 + properties: 78 + clocks: 79 + minItems: 3 80 + maxItems: 3 81 + clock-names: 82 + items: 83 + - const: t0_clk 84 + - const: gclk 85 + - const: slow_clk 86 + else: 87 + properties: 88 + clocks: 89 + minItems: 2 90 + maxItems: 4 91 + clock-names: 92 + oneOf: 93 + - items: 94 + - const: t0_clk 95 + - const: slow_clk 96 + - items: 97 + - const: t0_clk 98 + - const: t1_clk 99 + - const: t2_clk 100 + - const: slow_clk 101 + 102 + required: 103 + - compatible 104 + - reg 105 + - interrupts 106 + - clocks 107 + - clock-names 108 + - '#address-cells' 109 + - '#size-cells' 110 + 111 + additionalProperties: false 112 + 113 + examples: 114 + - | 115 + /* One interrupt per TC block: */ 116 + tcb0: timer@fff7c000 { 117 + compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon"; 118 + #address-cells = <1>; 119 + #size-cells = <0>; 120 + reg = <0xfff7c000 0x100>; 121 + interrupts = <18 4>; 122 + clocks = <&tcb0_clk>, <&clk32k>; 123 + clock-names = "t0_clk", "slow_clk"; 124 + 125 + timer@0 { 126 + compatible = "atmel,tcb-timer"; 127 + reg = <0>, <1>; 128 + }; 129 + 130 + timer@2 { 131 + compatible = "atmel,tcb-timer"; 132 + reg = <2>; 133 + }; 134 + }; 135 + 136 + /* One interrupt per TC channel in a TC block: */ 137 + tcb1: timer@fffdc000 { 138 + compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon"; 139 + #address-cells = <1>; 140 + #size-cells = <0>; 141 + reg = <0xfffdc000 0x100>; 142 + interrupts = <26 4>, <27 4>, <28 4>; 143 + clocks = <&tcb1_clk>, <&clk32k>; 144 + clock-names = "t0_clk", "slow_clk"; 145 + 146 + timer@0 { 147 + compatible = "atmel,tcb-timer"; 148 + reg = <0>; 149 + }; 150 + 151 + timer@1 { 152 + compatible = "atmel,tcb-timer"; 153 + reg = <1>; 154 + }; 155 + };
+63
Documentation/devicetree/bindings/timer/ingenic,sysost.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/timer/ingenic,sysost.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Bindings for SYSOST in Ingenic XBurst family SoCs 8 + 9 + maintainers: 10 + - 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> 11 + 12 + description: 13 + The SYSOST in an Ingenic SoC provides one 64bit timer for clocksource 14 + and one or more 32bit timers for clockevent. 15 + 16 + properties: 17 + "#clock-cells": 18 + const: 1 19 + 20 + compatible: 21 + enum: 22 + - ingenic,x1000-ost 23 + - ingenic,x2000-ost 24 + 25 + reg: 26 + maxItems: 1 27 + 28 + clocks: 29 + maxItems: 1 30 + 31 + clock-names: 32 + const: ost 33 + 34 + interrupts: 35 + maxItems: 1 36 + 37 + required: 38 + - "#clock-cells" 39 + - compatible 40 + - reg 41 + - clocks 42 + - clock-names 43 + - interrupts 44 + 45 + additionalProperties: false 46 + 47 + examples: 48 + - | 49 + #include <dt-bindings/clock/x1000-cgu.h> 50 + 51 + ost: timer@12000000 { 52 + compatible = "ingenic,x1000-ost"; 53 + reg = <0x12000000 0x3c>; 54 + 55 + #clock-cells = <1>; 56 + 57 + clocks = <&cgu X1000_CLK_OST>; 58 + clock-names = "ost"; 59 + 60 + interrupt-parent = <&cpuintc>; 61 + interrupts = <3>; 62 + }; 63 + ...
+1 -1
Documentation/devicetree/bindings/timer/ti,keystone-timer.txt
··· 10 10 when the counter reaches preset counter values. 11 11 12 12 Documentation: 13 - http://www.ti.com/lit/ug/sprugv5a/sprugv5a.pdf 13 + https://www.ti.com/lit/ug/sprugv5a/sprugv5a.pdf 14 14 15 15 Required properties: 16 16
+6 -6
arch/arm/boot/dts/sama5d2.dtsi
··· 375 375 }; 376 376 377 377 tcb0: timer@f800c000 { 378 - compatible = "atmel,at91sam9x5-tcb", "simple-mfd", "syscon"; 378 + compatible = "atmel,sama5d2-tcb", "simple-mfd", "syscon"; 379 379 #address-cells = <1>; 380 380 #size-cells = <0>; 381 381 reg = <0xf800c000 0x100>; 382 382 interrupts = <35 IRQ_TYPE_LEVEL_HIGH 0>; 383 - clocks = <&pmc PMC_TYPE_PERIPHERAL 35>, <&clk32k>; 384 - clock-names = "t0_clk", "slow_clk"; 383 + clocks = <&pmc PMC_TYPE_PERIPHERAL 35>, <&pmc PMC_TYPE_GCK 35>, <&clk32k>; 384 + clock-names = "t0_clk", "gclk", "slow_clk"; 385 385 }; 386 386 387 387 tcb1: timer@f8010000 { 388 - compatible = "atmel,at91sam9x5-tcb", "simple-mfd", "syscon"; 388 + compatible = "atmel,sama5d2-tcb", "simple-mfd", "syscon"; 389 389 #address-cells = <1>; 390 390 #size-cells = <0>; 391 391 reg = <0xf8010000 0x100>; 392 392 interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; 393 - clocks = <&pmc PMC_TYPE_PERIPHERAL 36>, <&clk32k>; 394 - clock-names = "t0_clk", "slow_clk"; 393 + clocks = <&pmc PMC_TYPE_PERIPHERAL 36>, <&pmc PMC_TYPE_GCK 36>, <&clk32k>; 394 + clock-names = "t0_clk", "gclk", "slow_clk"; 395 395 }; 396 396 397 397 hsmc: hsmc@f8014000 {
+13 -2
drivers/clocksource/Kconfig
··· 616 616 617 617 config CLKSRC_IMX_TPM 618 618 bool "Clocksource using i.MX TPM" if COMPILE_TEST 619 - depends on ARM && CLKDEV_LOOKUP 619 + depends on (ARM || ARM64) && CLKDEV_LOOKUP 620 620 select CLKSRC_MMIO 621 + select TIMER_OF 621 622 help 622 623 Enable this option to use IMX Timer/PWM Module (TPM) timer as 623 624 clocksource. ··· 697 696 help 698 697 Support for the timer/counter unit of the Ingenic JZ SoCs. 699 698 699 + config INGENIC_SYSOST 700 + bool "Clocksource/timer using the SYSOST in Ingenic X SoCs" 701 + depends on MIPS || COMPILE_TEST 702 + depends on COMMON_CLK 703 + select MFD_SYSCON 704 + select TIMER_OF 705 + select IRQ_DOMAIN 706 + help 707 + Support for the SYSOST of the Ingenic X Series SoCs. 708 + 700 709 config INGENIC_OST 701 - bool "Clocksource for Ingenic OS Timer" 710 + bool "Clocksource using the OST in Ingenic JZ SoCs" 702 711 depends on MIPS || COMPILE_TEST 703 712 depends on COMMON_CLK 704 713 select MFD_SYSCON
+1
drivers/clocksource/Makefile
··· 82 82 obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o 83 83 obj-$(CONFIG_H8300_TPU) += h8300_tpu.o 84 84 obj-$(CONFIG_INGENIC_OST) += ingenic-ost.o 85 + obj-$(CONFIG_INGENIC_SYSOST) += ingenic-sysost.o 85 86 obj-$(CONFIG_INGENIC_TIMER) += ingenic-timer.o 86 87 obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o 87 88 obj-$(CONFIG_X86_NUMACHIP) += numachip.o
+539
drivers/clocksource/ingenic-sysost.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Ingenic XBurst SoCs SYSOST clocks driver 4 + * Copyright (c) 2020 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> 5 + */ 6 + 7 + #include <linux/bitops.h> 8 + #include <linux/clk.h> 9 + #include <linux/clk-provider.h> 10 + #include <linux/clockchips.h> 11 + #include <linux/clocksource.h> 12 + #include <linux/interrupt.h> 13 + #include <linux/mfd/syscon.h> 14 + #include <linux/of_address.h> 15 + #include <linux/of_irq.h> 16 + #include <linux/sched_clock.h> 17 + #include <linux/slab.h> 18 + #include <linux/syscore_ops.h> 19 + 20 + #include <dt-bindings/clock/ingenic,sysost.h> 21 + 22 + /* OST register offsets */ 23 + #define OST_REG_OSTCCR 0x00 24 + #define OST_REG_OSTCR 0x08 25 + #define OST_REG_OSTFR 0x0c 26 + #define OST_REG_OSTMR 0x10 27 + #define OST_REG_OST1DFR 0x14 28 + #define OST_REG_OST1CNT 0x18 29 + #define OST_REG_OST2CNTL 0x20 30 + #define OST_REG_OSTCNT2HBUF 0x24 31 + #define OST_REG_OSTESR 0x34 32 + #define OST_REG_OSTECR 0x38 33 + 34 + /* bits within the OSTCCR register */ 35 + #define OSTCCR_PRESCALE1_MASK 0x3 36 + #define OSTCCR_PRESCALE2_MASK 0xc 37 + #define OSTCCR_PRESCALE1_LSB 0 38 + #define OSTCCR_PRESCALE2_LSB 2 39 + 40 + /* bits within the OSTCR register */ 41 + #define OSTCR_OST1CLR BIT(0) 42 + #define OSTCR_OST2CLR BIT(1) 43 + 44 + /* bits within the OSTFR register */ 45 + #define OSTFR_FFLAG BIT(0) 46 + 47 + /* bits within the OSTMR register */ 48 + #define OSTMR_FMASK BIT(0) 49 + 50 + /* bits within the OSTESR register */ 51 + #define OSTESR_OST1ENS BIT(0) 52 + #define OSTESR_OST2ENS BIT(1) 53 + 54 + /* bits within the OSTECR register */ 55 + #define OSTECR_OST1ENC BIT(0) 56 + #define OSTECR_OST2ENC BIT(1) 57 + 58 + struct ingenic_soc_info { 59 + unsigned int num_channels; 60 + }; 61 + 62 + struct ingenic_ost_clk_info { 63 + struct clk_init_data init_data; 64 + u8 ostccr_reg; 65 + }; 66 + 67 + struct ingenic_ost_clk { 68 + struct clk_hw hw; 69 + unsigned int idx; 70 + struct ingenic_ost *ost; 71 + const struct ingenic_ost_clk_info *info; 72 + }; 73 + 74 + struct ingenic_ost { 75 + void __iomem *base; 76 + const struct ingenic_soc_info *soc_info; 77 + struct clk *clk, *percpu_timer_clk, *global_timer_clk; 78 + struct clock_event_device cevt; 79 + struct clocksource cs; 80 + char name[20]; 81 + 82 + struct clk_hw_onecell_data *clocks; 83 + }; 84 + 85 + static struct ingenic_ost *ingenic_ost; 86 + 87 + static inline struct ingenic_ost_clk *to_ost_clk(struct clk_hw *hw) 88 + { 89 + return container_of(hw, struct ingenic_ost_clk, hw); 90 + } 91 + 92 + static unsigned long ingenic_ost_percpu_timer_recalc_rate(struct clk_hw *hw, 93 + unsigned long parent_rate) 94 + { 95 + struct ingenic_ost_clk *ost_clk = to_ost_clk(hw); 96 + const struct ingenic_ost_clk_info *info = ost_clk->info; 97 + unsigned int prescale; 98 + 99 + prescale = readl(ost_clk->ost->base + info->ostccr_reg); 100 + 101 + prescale = (prescale & OSTCCR_PRESCALE1_MASK) >> OSTCCR_PRESCALE1_LSB; 102 + 103 + return parent_rate >> (prescale * 2); 104 + } 105 + 106 + static unsigned long ingenic_ost_global_timer_recalc_rate(struct clk_hw *hw, 107 + unsigned long parent_rate) 108 + { 109 + struct ingenic_ost_clk *ost_clk = to_ost_clk(hw); 110 + const struct ingenic_ost_clk_info *info = ost_clk->info; 111 + unsigned int prescale; 112 + 113 + prescale = readl(ost_clk->ost->base + info->ostccr_reg); 114 + 115 + prescale = (prescale & OSTCCR_PRESCALE2_MASK) >> OSTCCR_PRESCALE2_LSB; 116 + 117 + return parent_rate >> (prescale * 2); 118 + } 119 + 120 + static u8 ingenic_ost_get_prescale(unsigned long rate, unsigned long req_rate) 121 + { 122 + u8 prescale; 123 + 124 + for (prescale = 0; prescale < 2; prescale++) 125 + if ((rate >> (prescale * 2)) <= req_rate) 126 + return prescale; 127 + 128 + return 2; /* /16 divider */ 129 + } 130 + 131 + static long ingenic_ost_round_rate(struct clk_hw *hw, unsigned long req_rate, 132 + unsigned long *parent_rate) 133 + { 134 + unsigned long rate = *parent_rate; 135 + u8 prescale; 136 + 137 + if (req_rate > rate) 138 + return rate; 139 + 140 + prescale = ingenic_ost_get_prescale(rate, req_rate); 141 + 142 + return rate >> (prescale * 2); 143 + } 144 + 145 + static int ingenic_ost_percpu_timer_set_rate(struct clk_hw *hw, unsigned long req_rate, 146 + unsigned long parent_rate) 147 + { 148 + struct ingenic_ost_clk *ost_clk = to_ost_clk(hw); 149 + const struct ingenic_ost_clk_info *info = ost_clk->info; 150 + u8 prescale = ingenic_ost_get_prescale(parent_rate, req_rate); 151 + int val; 152 + 153 + val = readl(ost_clk->ost->base + info->ostccr_reg); 154 + val = (val & ~OSTCCR_PRESCALE1_MASK) | (prescale << OSTCCR_PRESCALE1_LSB); 155 + writel(val, ost_clk->ost->base + info->ostccr_reg); 156 + 157 + return 0; 158 + } 159 + 160 + static int ingenic_ost_global_timer_set_rate(struct clk_hw *hw, unsigned long req_rate, 161 + unsigned long parent_rate) 162 + { 163 + struct ingenic_ost_clk *ost_clk = to_ost_clk(hw); 164 + const struct ingenic_ost_clk_info *info = ost_clk->info; 165 + u8 prescale = ingenic_ost_get_prescale(parent_rate, req_rate); 166 + int val; 167 + 168 + val = readl(ost_clk->ost->base + info->ostccr_reg); 169 + val = (val & ~OSTCCR_PRESCALE2_MASK) | (prescale << OSTCCR_PRESCALE2_LSB); 170 + writel(val, ost_clk->ost->base + info->ostccr_reg); 171 + 172 + return 0; 173 + } 174 + 175 + static const struct clk_ops ingenic_ost_percpu_timer_ops = { 176 + .recalc_rate = ingenic_ost_percpu_timer_recalc_rate, 177 + .round_rate = ingenic_ost_round_rate, 178 + .set_rate = ingenic_ost_percpu_timer_set_rate, 179 + }; 180 + 181 + static const struct clk_ops ingenic_ost_global_timer_ops = { 182 + .recalc_rate = ingenic_ost_global_timer_recalc_rate, 183 + .round_rate = ingenic_ost_round_rate, 184 + .set_rate = ingenic_ost_global_timer_set_rate, 185 + }; 186 + 187 + static const char * const ingenic_ost_clk_parents[] = { "ext" }; 188 + 189 + static const struct ingenic_ost_clk_info ingenic_ost_clk_info[] = { 190 + [OST_CLK_PERCPU_TIMER] = { 191 + .init_data = { 192 + .name = "percpu timer", 193 + .parent_names = ingenic_ost_clk_parents, 194 + .num_parents = ARRAY_SIZE(ingenic_ost_clk_parents), 195 + .ops = &ingenic_ost_percpu_timer_ops, 196 + .flags = CLK_SET_RATE_UNGATE, 197 + }, 198 + .ostccr_reg = OST_REG_OSTCCR, 199 + }, 200 + 201 + [OST_CLK_GLOBAL_TIMER] = { 202 + .init_data = { 203 + .name = "global timer", 204 + .parent_names = ingenic_ost_clk_parents, 205 + .num_parents = ARRAY_SIZE(ingenic_ost_clk_parents), 206 + .ops = &ingenic_ost_global_timer_ops, 207 + .flags = CLK_SET_RATE_UNGATE, 208 + }, 209 + .ostccr_reg = OST_REG_OSTCCR, 210 + }, 211 + }; 212 + 213 + static u64 notrace ingenic_ost_global_timer_read_cntl(void) 214 + { 215 + struct ingenic_ost *ost = ingenic_ost; 216 + unsigned int count; 217 + 218 + count = readl(ost->base + OST_REG_OST2CNTL); 219 + 220 + return count; 221 + } 222 + 223 + static u64 notrace ingenic_ost_clocksource_read(struct clocksource *cs) 224 + { 225 + return ingenic_ost_global_timer_read_cntl(); 226 + } 227 + 228 + static inline struct ingenic_ost *to_ingenic_ost(struct clock_event_device *evt) 229 + { 230 + return container_of(evt, struct ingenic_ost, cevt); 231 + } 232 + 233 + static int ingenic_ost_cevt_set_state_shutdown(struct clock_event_device *evt) 234 + { 235 + struct ingenic_ost *ost = to_ingenic_ost(evt); 236 + 237 + writel(OSTECR_OST1ENC, ost->base + OST_REG_OSTECR); 238 + 239 + return 0; 240 + } 241 + 242 + static int ingenic_ost_cevt_set_next(unsigned long next, 243 + struct clock_event_device *evt) 244 + { 245 + struct ingenic_ost *ost = to_ingenic_ost(evt); 246 + 247 + writel((u32)~OSTFR_FFLAG, ost->base + OST_REG_OSTFR); 248 + writel(next, ost->base + OST_REG_OST1DFR); 249 + writel(OSTCR_OST1CLR, ost->base + OST_REG_OSTCR); 250 + writel(OSTESR_OST1ENS, ost->base + OST_REG_OSTESR); 251 + writel((u32)~OSTMR_FMASK, ost->base + OST_REG_OSTMR); 252 + 253 + return 0; 254 + } 255 + 256 + static irqreturn_t ingenic_ost_cevt_cb(int irq, void *dev_id) 257 + { 258 + struct clock_event_device *evt = dev_id; 259 + struct ingenic_ost *ost = to_ingenic_ost(evt); 260 + 261 + writel(OSTECR_OST1ENC, ost->base + OST_REG_OSTECR); 262 + 263 + if (evt->event_handler) 264 + evt->event_handler(evt); 265 + 266 + return IRQ_HANDLED; 267 + } 268 + 269 + static int __init ingenic_ost_register_clock(struct ingenic_ost *ost, 270 + unsigned int idx, const struct ingenic_ost_clk_info *info, 271 + struct clk_hw_onecell_data *clocks) 272 + { 273 + struct ingenic_ost_clk *ost_clk; 274 + int val, err; 275 + 276 + ost_clk = kzalloc(sizeof(*ost_clk), GFP_KERNEL); 277 + if (!ost_clk) 278 + return -ENOMEM; 279 + 280 + ost_clk->hw.init = &info->init_data; 281 + ost_clk->idx = idx; 282 + ost_clk->info = info; 283 + ost_clk->ost = ost; 284 + 285 + /* Reset clock divider */ 286 + val = readl(ost->base + info->ostccr_reg); 287 + val &= ~(OSTCCR_PRESCALE1_MASK | OSTCCR_PRESCALE2_MASK); 288 + writel(val, ost->base + info->ostccr_reg); 289 + 290 + err = clk_hw_register(NULL, &ost_clk->hw); 291 + if (err) { 292 + kfree(ost_clk); 293 + return err; 294 + } 295 + 296 + clocks->hws[idx] = &ost_clk->hw; 297 + 298 + return 0; 299 + } 300 + 301 + static struct clk * __init ingenic_ost_get_clock(struct device_node *np, int id) 302 + { 303 + struct of_phandle_args args; 304 + 305 + args.np = np; 306 + args.args_count = 1; 307 + args.args[0] = id; 308 + 309 + return of_clk_get_from_provider(&args); 310 + } 311 + 312 + static int __init ingenic_ost_percpu_timer_init(struct device_node *np, 313 + struct ingenic_ost *ost) 314 + { 315 + unsigned int timer_virq, channel = OST_CLK_PERCPU_TIMER; 316 + unsigned long rate; 317 + int err; 318 + 319 + ost->percpu_timer_clk = ingenic_ost_get_clock(np, channel); 320 + if (IS_ERR(ost->percpu_timer_clk)) 321 + return PTR_ERR(ost->percpu_timer_clk); 322 + 323 + err = clk_prepare_enable(ost->percpu_timer_clk); 324 + if (err) 325 + goto err_clk_put; 326 + 327 + rate = clk_get_rate(ost->percpu_timer_clk); 328 + if (!rate) { 329 + err = -EINVAL; 330 + goto err_clk_disable; 331 + } 332 + 333 + timer_virq = of_irq_get(np, 0); 334 + if (!timer_virq) { 335 + err = -EINVAL; 336 + goto err_clk_disable; 337 + } 338 + 339 + snprintf(ost->name, sizeof(ost->name), "OST percpu timer"); 340 + 341 + err = request_irq(timer_virq, ingenic_ost_cevt_cb, IRQF_TIMER, 342 + ost->name, &ost->cevt); 343 + if (err) 344 + goto err_irq_dispose_mapping; 345 + 346 + ost->cevt.cpumask = cpumask_of(smp_processor_id()); 347 + ost->cevt.features = CLOCK_EVT_FEAT_ONESHOT; 348 + ost->cevt.name = ost->name; 349 + ost->cevt.rating = 400; 350 + ost->cevt.set_state_shutdown = ingenic_ost_cevt_set_state_shutdown; 351 + ost->cevt.set_next_event = ingenic_ost_cevt_set_next; 352 + 353 + clockevents_config_and_register(&ost->cevt, rate, 4, 0xffffffff); 354 + 355 + return 0; 356 + 357 + err_irq_dispose_mapping: 358 + irq_dispose_mapping(timer_virq); 359 + err_clk_disable: 360 + clk_disable_unprepare(ost->percpu_timer_clk); 361 + err_clk_put: 362 + clk_put(ost->percpu_timer_clk); 363 + return err; 364 + } 365 + 366 + static int __init ingenic_ost_global_timer_init(struct device_node *np, 367 + struct ingenic_ost *ost) 368 + { 369 + unsigned int channel = OST_CLK_GLOBAL_TIMER; 370 + struct clocksource *cs = &ost->cs; 371 + unsigned long rate; 372 + int err; 373 + 374 + ost->global_timer_clk = ingenic_ost_get_clock(np, channel); 375 + if (IS_ERR(ost->global_timer_clk)) 376 + return PTR_ERR(ost->global_timer_clk); 377 + 378 + err = clk_prepare_enable(ost->global_timer_clk); 379 + if (err) 380 + goto err_clk_put; 381 + 382 + rate = clk_get_rate(ost->global_timer_clk); 383 + if (!rate) { 384 + err = -EINVAL; 385 + goto err_clk_disable; 386 + } 387 + 388 + /* Clear counter CNT registers */ 389 + writel(OSTCR_OST2CLR, ost->base + OST_REG_OSTCR); 390 + 391 + /* Enable OST channel */ 392 + writel(OSTESR_OST2ENS, ost->base + OST_REG_OSTESR); 393 + 394 + cs->name = "ingenic-ost"; 395 + cs->rating = 400; 396 + cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; 397 + cs->mask = CLOCKSOURCE_MASK(32); 398 + cs->read = ingenic_ost_clocksource_read; 399 + 400 + err = clocksource_register_hz(cs, rate); 401 + if (err) 402 + goto err_clk_disable; 403 + 404 + return 0; 405 + 406 + err_clk_disable: 407 + clk_disable_unprepare(ost->global_timer_clk); 408 + err_clk_put: 409 + clk_put(ost->global_timer_clk); 410 + return err; 411 + } 412 + 413 + static const struct ingenic_soc_info x1000_soc_info = { 414 + .num_channels = 2, 415 + }; 416 + 417 + static const struct of_device_id __maybe_unused ingenic_ost_of_match[] __initconst = { 418 + { .compatible = "ingenic,x1000-ost", .data = &x1000_soc_info, }, 419 + { /* sentinel */ } 420 + }; 421 + 422 + static int __init ingenic_ost_probe(struct device_node *np) 423 + { 424 + const struct of_device_id *id = of_match_node(ingenic_ost_of_match, np); 425 + struct ingenic_ost *ost; 426 + unsigned int i; 427 + int ret; 428 + 429 + ost = kzalloc(sizeof(*ost), GFP_KERNEL); 430 + if (!ost) 431 + return -ENOMEM; 432 + 433 + ost->base = of_io_request_and_map(np, 0, of_node_full_name(np)); 434 + if (IS_ERR(ost->base)) { 435 + pr_err("%s: Failed to map OST registers\n", __func__); 436 + ret = PTR_ERR(ost->base); 437 + goto err_free_ost; 438 + } 439 + 440 + ost->clk = of_clk_get_by_name(np, "ost"); 441 + if (IS_ERR(ost->clk)) { 442 + ret = PTR_ERR(ost->clk); 443 + pr_crit("%s: Cannot get OST clock\n", __func__); 444 + goto err_free_ost; 445 + } 446 + 447 + ret = clk_prepare_enable(ost->clk); 448 + if (ret) { 449 + pr_crit("%s: Unable to enable OST clock\n", __func__); 450 + goto err_put_clk; 451 + } 452 + 453 + ost->soc_info = id->data; 454 + 455 + ost->clocks = kzalloc(struct_size(ost->clocks, hws, ost->soc_info->num_channels), 456 + GFP_KERNEL); 457 + if (!ost->clocks) { 458 + ret = -ENOMEM; 459 + goto err_clk_disable; 460 + } 461 + 462 + ost->clocks->num = ost->soc_info->num_channels; 463 + 464 + for (i = 0; i < ost->clocks->num; i++) { 465 + ret = ingenic_ost_register_clock(ost, i, &ingenic_ost_clk_info[i], ost->clocks); 466 + if (ret) { 467 + pr_crit("%s: Cannot register clock %d\n", __func__, i); 468 + goto err_unregister_ost_clocks; 469 + } 470 + } 471 + 472 + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, ost->clocks); 473 + if (ret) { 474 + pr_crit("%s: Cannot add OF clock provider\n", __func__); 475 + goto err_unregister_ost_clocks; 476 + } 477 + 478 + ingenic_ost = ost; 479 + 480 + return 0; 481 + 482 + err_unregister_ost_clocks: 483 + for (i = 0; i < ost->clocks->num; i++) 484 + if (ost->clocks->hws[i]) 485 + clk_hw_unregister(ost->clocks->hws[i]); 486 + kfree(ost->clocks); 487 + err_clk_disable: 488 + clk_disable_unprepare(ost->clk); 489 + err_put_clk: 490 + clk_put(ost->clk); 491 + err_free_ost: 492 + kfree(ost); 493 + return ret; 494 + } 495 + 496 + static int __init ingenic_ost_init(struct device_node *np) 497 + { 498 + struct ingenic_ost *ost; 499 + unsigned long rate; 500 + int ret; 501 + 502 + ret = ingenic_ost_probe(np); 503 + if (ret) { 504 + pr_crit("%s: Failed to initialize OST clocks: %d\n", __func__, ret); 505 + return ret; 506 + } 507 + 508 + of_node_clear_flag(np, OF_POPULATED); 509 + 510 + ost = ingenic_ost; 511 + if (IS_ERR(ost)) 512 + return PTR_ERR(ost); 513 + 514 + ret = ingenic_ost_global_timer_init(np, ost); 515 + if (ret) { 516 + pr_crit("%s: Unable to init global timer: %x\n", __func__, ret); 517 + goto err_free_ingenic_ost; 518 + } 519 + 520 + ret = ingenic_ost_percpu_timer_init(np, ost); 521 + if (ret) 522 + goto err_ost_global_timer_cleanup; 523 + 524 + /* Register the sched_clock at the end as there's no way to undo it */ 525 + rate = clk_get_rate(ost->global_timer_clk); 526 + sched_clock_register(ingenic_ost_global_timer_read_cntl, 32, rate); 527 + 528 + return 0; 529 + 530 + err_ost_global_timer_cleanup: 531 + clocksource_unregister(&ost->cs); 532 + clk_disable_unprepare(ost->global_timer_clk); 533 + clk_put(ost->global_timer_clk); 534 + err_free_ingenic_ost: 535 + kfree(ost); 536 + return ret; 537 + } 538 + 539 + TIMER_OF_DECLARE(x1000_ost, "ingenic,x1000-ost", ingenic_ost_init);
+125 -59
drivers/clocksource/ingenic-timer.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * JZ47xx SoCs TCU IRQ driver 3 + * Ingenic SoCs TCU IRQ driver 4 4 * Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net> 5 + * Copyright (C) 2020 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> 5 6 */ 6 7 7 8 #include <linux/bitops.h> ··· 16 15 #include <linux/of_address.h> 17 16 #include <linux/of_irq.h> 18 17 #include <linux/of_platform.h> 18 + #include <linux/overflow.h> 19 19 #include <linux/platform_device.h> 20 20 #include <linux/regmap.h> 21 21 #include <linux/sched_clock.h> 22 22 23 23 #include <dt-bindings/clock/ingenic,tcu.h> 24 24 25 + static DEFINE_PER_CPU(call_single_data_t, ingenic_cevt_csd); 26 + 25 27 struct ingenic_soc_info { 26 28 unsigned int num_channels; 27 29 }; 28 30 31 + struct ingenic_tcu_timer { 32 + unsigned int cpu; 33 + unsigned int channel; 34 + struct clock_event_device cevt; 35 + struct clk *clk; 36 + char name[8]; 37 + }; 38 + 29 39 struct ingenic_tcu { 30 40 struct regmap *map; 31 - struct clk *timer_clk, *cs_clk; 32 - unsigned int timer_channel, cs_channel; 33 - struct clock_event_device cevt; 41 + struct device_node *np; 42 + struct clk *cs_clk; 43 + unsigned int cs_channel; 34 44 struct clocksource cs; 35 - char name[4]; 36 45 unsigned long pwm_channels_mask; 46 + struct ingenic_tcu_timer timers[]; 37 47 }; 38 48 39 49 static struct ingenic_tcu *ingenic_tcu; ··· 64 52 return ingenic_tcu_timer_read(); 65 53 } 66 54 67 - static inline struct ingenic_tcu *to_ingenic_tcu(struct clock_event_device *evt) 55 + static inline struct ingenic_tcu * 56 + to_ingenic_tcu(struct ingenic_tcu_timer *timer) 68 57 { 69 - return container_of(evt, struct ingenic_tcu, cevt); 58 + return container_of(timer, struct ingenic_tcu, timers[timer->cpu]); 59 + } 60 + 61 + static inline struct ingenic_tcu_timer * 62 + to_ingenic_tcu_timer(struct clock_event_device *evt) 63 + { 64 + return container_of(evt, struct ingenic_tcu_timer, cevt); 70 65 } 71 66 72 67 static int ingenic_tcu_cevt_set_state_shutdown(struct clock_event_device *evt) 73 68 { 74 - struct ingenic_tcu *tcu = to_ingenic_tcu(evt); 69 + struct ingenic_tcu_timer *timer = to_ingenic_tcu_timer(evt); 70 + struct ingenic_tcu *tcu = to_ingenic_tcu(timer); 75 71 76 - regmap_write(tcu->map, TCU_REG_TECR, BIT(tcu->timer_channel)); 72 + regmap_write(tcu->map, TCU_REG_TECR, BIT(timer->channel)); 77 73 78 74 return 0; 79 75 } ··· 89 69 static int ingenic_tcu_cevt_set_next(unsigned long next, 90 70 struct clock_event_device *evt) 91 71 { 92 - struct ingenic_tcu *tcu = to_ingenic_tcu(evt); 72 + struct ingenic_tcu_timer *timer = to_ingenic_tcu_timer(evt); 73 + struct ingenic_tcu *tcu = to_ingenic_tcu(timer); 93 74 94 75 if (next > 0xffff) 95 76 return -EINVAL; 96 77 97 - regmap_write(tcu->map, TCU_REG_TDFRc(tcu->timer_channel), next); 98 - regmap_write(tcu->map, TCU_REG_TCNTc(tcu->timer_channel), 0); 99 - regmap_write(tcu->map, TCU_REG_TESR, BIT(tcu->timer_channel)); 78 + regmap_write(tcu->map, TCU_REG_TDFRc(timer->channel), next); 79 + regmap_write(tcu->map, TCU_REG_TCNTc(timer->channel), 0); 80 + regmap_write(tcu->map, TCU_REG_TESR, BIT(timer->channel)); 100 81 101 82 return 0; 102 83 } 103 84 85 + static void ingenic_per_cpu_event_handler(void *info) 86 + { 87 + struct clock_event_device *cevt = (struct clock_event_device *) info; 88 + 89 + cevt->event_handler(cevt); 90 + } 91 + 104 92 static irqreturn_t ingenic_tcu_cevt_cb(int irq, void *dev_id) 105 93 { 106 - struct clock_event_device *evt = dev_id; 107 - struct ingenic_tcu *tcu = to_ingenic_tcu(evt); 94 + struct ingenic_tcu_timer *timer = dev_id; 95 + struct ingenic_tcu *tcu = to_ingenic_tcu(timer); 96 + call_single_data_t *csd; 108 97 109 - regmap_write(tcu->map, TCU_REG_TECR, BIT(tcu->timer_channel)); 98 + regmap_write(tcu->map, TCU_REG_TECR, BIT(timer->channel)); 110 99 111 - if (evt->event_handler) 112 - evt->event_handler(evt); 100 + if (timer->cevt.event_handler) { 101 + csd = &per_cpu(ingenic_cevt_csd, timer->cpu); 102 + csd->info = (void *) &timer->cevt; 103 + csd->func = ingenic_per_cpu_event_handler; 104 + smp_call_function_single_async(timer->cpu, csd); 105 + } 113 106 114 107 return IRQ_HANDLED; 115 108 } ··· 138 105 return of_clk_get_from_provider(&args); 139 106 } 140 107 141 - static int __init ingenic_tcu_timer_init(struct device_node *np, 142 - struct ingenic_tcu *tcu) 108 + static int ingenic_tcu_setup_cevt(unsigned int cpu) 143 109 { 144 - unsigned int timer_virq, channel = tcu->timer_channel; 110 + struct ingenic_tcu *tcu = ingenic_tcu; 111 + struct ingenic_tcu_timer *timer = &tcu->timers[cpu]; 112 + unsigned int timer_virq; 145 113 struct irq_domain *domain; 146 114 unsigned long rate; 147 115 int err; 148 116 149 - tcu->timer_clk = ingenic_tcu_get_clock(np, channel); 150 - if (IS_ERR(tcu->timer_clk)) 151 - return PTR_ERR(tcu->timer_clk); 117 + timer->clk = ingenic_tcu_get_clock(tcu->np, timer->channel); 118 + if (IS_ERR(timer->clk)) 119 + return PTR_ERR(timer->clk); 152 120 153 - err = clk_prepare_enable(tcu->timer_clk); 121 + err = clk_prepare_enable(timer->clk); 154 122 if (err) 155 123 goto err_clk_put; 156 124 157 - rate = clk_get_rate(tcu->timer_clk); 125 + rate = clk_get_rate(timer->clk); 158 126 if (!rate) { 159 127 err = -EINVAL; 160 128 goto err_clk_disable; 161 129 } 162 130 163 - domain = irq_find_host(np); 131 + domain = irq_find_host(tcu->np); 164 132 if (!domain) { 165 133 err = -ENODEV; 166 134 goto err_clk_disable; 167 135 } 168 136 169 - timer_virq = irq_create_mapping(domain, channel); 137 + timer_virq = irq_create_mapping(domain, timer->channel); 170 138 if (!timer_virq) { 171 139 err = -EINVAL; 172 140 goto err_clk_disable; 173 141 } 174 142 175 - snprintf(tcu->name, sizeof(tcu->name), "TCU"); 143 + snprintf(timer->name, sizeof(timer->name), "TCU%u", timer->channel); 176 144 177 145 err = request_irq(timer_virq, ingenic_tcu_cevt_cb, IRQF_TIMER, 178 - tcu->name, &tcu->cevt); 146 + timer->name, timer); 179 147 if (err) 180 148 goto err_irq_dispose_mapping; 181 149 182 - tcu->cevt.cpumask = cpumask_of(smp_processor_id()); 183 - tcu->cevt.features = CLOCK_EVT_FEAT_ONESHOT; 184 - tcu->cevt.name = tcu->name; 185 - tcu->cevt.rating = 200; 186 - tcu->cevt.set_state_shutdown = ingenic_tcu_cevt_set_state_shutdown; 187 - tcu->cevt.set_next_event = ingenic_tcu_cevt_set_next; 150 + timer->cpu = smp_processor_id(); 151 + timer->cevt.cpumask = cpumask_of(smp_processor_id()); 152 + timer->cevt.features = CLOCK_EVT_FEAT_ONESHOT; 153 + timer->cevt.name = timer->name; 154 + timer->cevt.rating = 200; 155 + timer->cevt.set_state_shutdown = ingenic_tcu_cevt_set_state_shutdown; 156 + timer->cevt.set_next_event = ingenic_tcu_cevt_set_next; 188 157 189 - clockevents_config_and_register(&tcu->cevt, rate, 10, 0xffff); 158 + clockevents_config_and_register(&timer->cevt, rate, 10, 0xffff); 190 159 191 160 return 0; 192 161 193 162 err_irq_dispose_mapping: 194 163 irq_dispose_mapping(timer_virq); 195 164 err_clk_disable: 196 - clk_disable_unprepare(tcu->timer_clk); 165 + clk_disable_unprepare(timer->clk); 197 166 err_clk_put: 198 - clk_put(tcu->timer_clk); 167 + clk_put(timer->clk); 199 168 return err; 200 169 } 201 170 ··· 273 238 { 274 239 const struct of_device_id *id = of_match_node(ingenic_tcu_of_match, np); 275 240 const struct ingenic_soc_info *soc_info = id->data; 241 + struct ingenic_tcu_timer *timer; 276 242 struct ingenic_tcu *tcu; 277 243 struct regmap *map; 244 + unsigned int cpu; 245 + int ret, last_bit = -1; 278 246 long rate; 279 - int ret; 280 247 281 248 of_node_clear_flag(np, OF_POPULATED); 282 249 ··· 286 249 if (IS_ERR(map)) 287 250 return PTR_ERR(map); 288 251 289 - tcu = kzalloc(sizeof(*tcu), GFP_KERNEL); 252 + tcu = kzalloc(struct_size(tcu, timers, num_possible_cpus()), 253 + GFP_KERNEL); 290 254 if (!tcu) 291 255 return -ENOMEM; 292 256 293 - /* Enable all TCU channels for PWM use by default except channels 0/1 */ 294 - tcu->pwm_channels_mask = GENMASK(soc_info->num_channels - 1, 2); 257 + /* 258 + * Enable all TCU channels for PWM use by default except channels 0/1, 259 + * and channel 2 if target CPU is JZ4780/X2000 and SMP is selected. 260 + */ 261 + tcu->pwm_channels_mask = GENMASK(soc_info->num_channels - 1, 262 + num_possible_cpus() + 1); 295 263 of_property_read_u32(np, "ingenic,pwm-channels-mask", 296 264 (u32 *)&tcu->pwm_channels_mask); 297 265 298 - /* Verify that we have at least two free channels */ 299 - if (hweight8(tcu->pwm_channels_mask) > soc_info->num_channels - 2) { 266 + /* Verify that we have at least num_possible_cpus() + 1 free channels */ 267 + if (hweight8(tcu->pwm_channels_mask) > 268 + soc_info->num_channels - num_possible_cpus() + 1) { 300 269 pr_crit("%s: Invalid PWM channel mask: 0x%02lx\n", __func__, 301 270 tcu->pwm_channels_mask); 302 271 ret = -EINVAL; ··· 310 267 } 311 268 312 269 tcu->map = map; 270 + tcu->np = np; 313 271 ingenic_tcu = tcu; 314 272 315 - tcu->timer_channel = find_first_zero_bit(&tcu->pwm_channels_mask, 316 - soc_info->num_channels); 273 + for (cpu = 0; cpu < num_possible_cpus(); cpu++) { 274 + timer = &tcu->timers[cpu]; 275 + 276 + timer->cpu = cpu; 277 + timer->channel = find_next_zero_bit(&tcu->pwm_channels_mask, 278 + soc_info->num_channels, 279 + last_bit + 1); 280 + last_bit = timer->channel; 281 + } 282 + 317 283 tcu->cs_channel = find_next_zero_bit(&tcu->pwm_channels_mask, 318 284 soc_info->num_channels, 319 - tcu->timer_channel + 1); 285 + last_bit + 1); 320 286 321 287 ret = ingenic_tcu_clocksource_init(np, tcu); 322 288 if (ret) { ··· 333 281 goto err_free_ingenic_tcu; 334 282 } 335 283 336 - ret = ingenic_tcu_timer_init(np, tcu); 337 - if (ret) 284 + /* Setup clock events on each CPU core */ 285 + ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "Ingenic XBurst: online", 286 + ingenic_tcu_setup_cevt, NULL); 287 + if (ret < 0) { 288 + pr_crit("%s: Unable to start CPU timers: %d\n", __func__, ret); 338 289 goto err_tcu_clocksource_cleanup; 290 + } 339 291 340 292 /* Register the sched_clock at the end as there's no way to undo it */ 341 293 rate = clk_get_rate(tcu->cs_clk); ··· 371 315 static int __maybe_unused ingenic_tcu_suspend(struct device *dev) 372 316 { 373 317 struct ingenic_tcu *tcu = dev_get_drvdata(dev); 318 + unsigned int cpu; 374 319 375 320 clk_disable(tcu->cs_clk); 376 - clk_disable(tcu->timer_clk); 321 + 322 + for (cpu = 0; cpu < num_online_cpus(); cpu++) 323 + clk_disable(tcu->timers[cpu].clk); 324 + 377 325 return 0; 378 326 } 379 327 380 328 static int __maybe_unused ingenic_tcu_resume(struct device *dev) 381 329 { 382 330 struct ingenic_tcu *tcu = dev_get_drvdata(dev); 331 + unsigned int cpu; 383 332 int ret; 384 333 385 - ret = clk_enable(tcu->timer_clk); 386 - if (ret) 387 - return ret; 388 - 389 - ret = clk_enable(tcu->cs_clk); 390 - if (ret) { 391 - clk_disable(tcu->timer_clk); 392 - return ret; 334 + for (cpu = 0; cpu < num_online_cpus(); cpu++) { 335 + ret = clk_enable(tcu->timers[cpu].clk); 336 + if (ret) 337 + goto err_timer_clk_disable; 393 338 } 394 339 340 + ret = clk_enable(tcu->cs_clk); 341 + if (ret) 342 + goto err_timer_clk_disable; 343 + 395 344 return 0; 345 + 346 + err_timer_clk_disable: 347 + for (; cpu > 0; cpu--) 348 + clk_disable(tcu->timers[cpu - 1].clk); 349 + return ret; 396 350 } 397 351 398 352 static const struct dev_pm_ops __maybe_unused ingenic_tcu_pm_ops = {
+9 -2
drivers/clocksource/nomadik-mtu.c
··· 186 186 { 187 187 unsigned long rate; 188 188 int ret; 189 + int min_ticks; 189 190 190 191 mtu_base = base; 191 192 ··· 195 194 196 195 /* 197 196 * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz 198 - * for ux500. 197 + * for ux500, and in one specific Ux500 case 32768 Hz. 198 + * 199 199 * Use a divide-by-16 counter if the tick rate is more than 32MHz. 200 200 * At 32 MHz, the timer (with 32 bit counter) can be programmed 201 201 * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer ··· 232 230 pr_err("%s: request_irq() failed\n", "Nomadik Timer Tick"); 233 231 nmdk_clkevt.cpumask = cpumask_of(0); 234 232 nmdk_clkevt.irq = irq; 235 - clockevents_config_and_register(&nmdk_clkevt, rate, 2, 0xffffffffU); 233 + if (rate < 100000) 234 + min_ticks = 5; 235 + else 236 + min_ticks = 2; 237 + clockevents_config_and_register(&nmdk_clkevt, rate, min_ticks, 238 + 0xffffffffU); 236 239 237 240 mtu_delay_timer.read_current_timer = &nmdk_timer_read_current_timer; 238 241 mtu_delay_timer.freq = rate;
+1 -1
drivers/clocksource/sh_cmt.c
··· 349 349 350 350 /* 351 351 * According to the sh73a0 user's manual, as CMCNT can be operated 352 - * only by the RCLK (Pseudo 32 KHz), there's one restriction on 352 + * only by the RCLK (Pseudo 32 kHz), there's one restriction on 353 353 * modifying CMCNT register; two RCLK cycles are necessary before 354 354 * this register is either read or any modification of the value 355 355 * it holds is reflected in the LSI's actual operation.
+59 -44
drivers/clocksource/timer-atmel-tcb.c
··· 27 27 * - Some chips support 32 bit counter. A single channel is used for 28 28 * this 32 bit free-running counter. the second channel is not used. 29 29 * 30 - * - The third channel may be used to provide a 16-bit clockevent 31 - * source, used in either periodic or oneshot mode. This runs 32 - * at 32 KiHZ, and can handle delays of up to two seconds. 30 + * - The third channel may be used to provide a clockevent source, used in 31 + * either periodic or oneshot mode. For 16-bit counter its runs at 32 KiHZ, 32 + * and can handle delays of up to two seconds. For 32-bit counters, it runs at 33 + * the same rate as the clocksource 33 34 * 34 35 * REVISIT behavior during system suspend states... we should disable 35 36 * all clocks and save the power. Easily done for clockevent devices, ··· 47 46 bool clken; 48 47 } tcb_cache[3]; 49 48 static u32 bmr_cache; 49 + 50 + static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128 }; 50 51 51 52 static u64 tc_get_cycles(struct clocksource *cs) 52 53 { ··· 146 143 struct tc_clkevt_device { 147 144 struct clock_event_device clkevt; 148 145 struct clk *clk; 146 + u32 rate; 149 147 void __iomem *regs; 150 148 }; 151 149 ··· 155 151 return container_of(clkevt, struct tc_clkevt_device, clkevt); 156 152 } 157 153 158 - /* For now, we always use the 32K clock ... this optimizes for NO_HZ, 159 - * because using one of the divided clocks would usually mean the 160 - * tick rate can never be less than several dozen Hz (vs 0.5 Hz). 161 - * 162 - * A divided clock could be good for high resolution timers, since 163 - * 30.5 usec resolution can seem "low". 164 - */ 165 154 static u32 timer_clock; 166 155 167 156 static int tc_shutdown(struct clock_event_device *d) ··· 180 183 181 184 clk_enable(tcd->clk); 182 185 183 - /* slow clock, count up to RC, then irq and stop */ 186 + /* count up to RC, then irq and stop */ 184 187 writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | 185 188 ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR)); 186 189 writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); ··· 202 205 */ 203 206 clk_enable(tcd->clk); 204 207 205 - /* slow clock, count up to RC, then irq and restart */ 208 + /* count up to RC, then irq and restart */ 206 209 writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, 207 210 regs + ATMEL_TC_REG(2, CMR)); 208 - writel((32768 + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); 211 + writel((tcd->rate + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); 209 212 210 213 /* Enable clock and interrupts on RC compare */ 211 214 writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); ··· 253 256 return IRQ_NONE; 254 257 } 255 258 256 - static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) 259 + static int __init setup_clkevents(struct atmel_tc *tc, int divisor_idx) 257 260 { 258 261 int ret; 259 262 struct clk *t2_clk = tc->clk[2]; 260 263 int irq = tc->irq[2]; 261 - 262 - ret = clk_prepare_enable(tc->slow_clk); 263 - if (ret) 264 - return ret; 264 + int bits = tc->tcb_config->counter_width; 265 265 266 266 /* try to enable t2 clk to avoid future errors in mode change */ 267 267 ret = clk_prepare_enable(t2_clk); 268 - if (ret) { 269 - clk_disable_unprepare(tc->slow_clk); 268 + if (ret) 270 269 return ret; 271 - } 272 - 273 - clk_disable(t2_clk); 274 270 275 271 clkevt.regs = tc->regs; 276 272 clkevt.clk = t2_clk; 277 273 278 - timer_clock = clk32k_divisor_idx; 274 + if (bits == 32) { 275 + timer_clock = divisor_idx; 276 + clkevt.rate = clk_get_rate(t2_clk) / atmel_tcb_divisors[divisor_idx]; 277 + } else { 278 + ret = clk_prepare_enable(tc->slow_clk); 279 + if (ret) { 280 + clk_disable_unprepare(t2_clk); 281 + return ret; 282 + } 283 + 284 + clkevt.rate = clk_get_rate(tc->slow_clk); 285 + timer_clock = ATMEL_TC_TIMER_CLOCK5; 286 + } 287 + 288 + clk_disable(t2_clk); 279 289 280 290 clkevt.clkevt.cpumask = cpumask_of(0); 281 291 282 292 ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt); 283 293 if (ret) { 284 294 clk_unprepare(t2_clk); 285 - clk_disable_unprepare(tc->slow_clk); 295 + if (bits != 32) 296 + clk_disable_unprepare(tc->slow_clk); 286 297 return ret; 287 298 } 288 299 289 - clockevents_config_and_register(&clkevt.clkevt, 32768, 1, 0xffff); 300 + clockevents_config_and_register(&clkevt.clkevt, clkevt.rate, 1, BIT(bits) - 1); 290 301 291 302 return ret; 292 303 } 293 304 294 305 #else /* !CONFIG_GENERIC_CLOCKEVENTS */ 295 306 296 - static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) 307 + static int __init setup_clkevents(struct atmel_tc *tc, int divisor_idx) 297 308 { 298 309 /* NOTHING */ 299 310 return 0; ··· 351 346 writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); 352 347 } 353 348 354 - static const u8 atmel_tcb_divisors[5] = { 2, 8, 32, 128, 0, }; 349 + static struct atmel_tcb_config tcb_rm9200_config = { 350 + .counter_width = 16, 351 + }; 352 + 353 + static struct atmel_tcb_config tcb_sam9x5_config = { 354 + .counter_width = 32, 355 + }; 356 + 357 + static struct atmel_tcb_config tcb_sama5d2_config = { 358 + .counter_width = 32, 359 + .has_gclk = 1, 360 + }; 355 361 356 362 static const struct of_device_id atmel_tcb_of_match[] = { 357 - { .compatible = "atmel,at91rm9200-tcb", .data = (void *)16, }, 358 - { .compatible = "atmel,at91sam9x5-tcb", .data = (void *)32, }, 363 + { .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config, }, 364 + { .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config, }, 365 + { .compatible = "atmel,sama5d2-tcb", .data = &tcb_sama5d2_config, }, 359 366 { /* sentinel */ } 360 367 }; 361 368 ··· 379 362 u64 (*tc_sched_clock)(void); 380 363 u32 rate, divided_rate = 0; 381 364 int best_divisor_idx = -1; 382 - int clk32k_divisor_idx = -1; 383 365 int bits; 384 366 int i; 385 367 int ret; ··· 415 399 } 416 400 417 401 match = of_match_node(atmel_tcb_of_match, node->parent); 418 - bits = (uintptr_t)match->data; 402 + if (!match) 403 + return -ENODEV; 404 + 405 + tc.tcb_config = match->data; 406 + bits = tc.tcb_config->counter_width; 419 407 420 408 for (i = 0; i < ARRAY_SIZE(tc.irq); i++) 421 409 writel(ATMEL_TC_ALL_IRQ, tc.regs + ATMEL_TC_REG(i, IDR)); ··· 432 412 433 413 /* How fast will we be counting? Pick something over 5 MHz. */ 434 414 rate = (u32) clk_get_rate(t0_clk); 435 - for (i = 0; i < ARRAY_SIZE(atmel_tcb_divisors); i++) { 415 + i = 0; 416 + if (tc.tcb_config->has_gclk) 417 + i = 1; 418 + for (; i < ARRAY_SIZE(atmel_tcb_divisors); i++) { 436 419 unsigned divisor = atmel_tcb_divisors[i]; 437 420 unsigned tmp; 438 421 439 - /* remember 32 KiHz clock for later */ 440 - if (!divisor) { 441 - clk32k_divisor_idx = i; 442 - continue; 443 - } 444 - 445 422 tmp = rate / divisor; 446 423 pr_debug("TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp); 447 - if (best_divisor_idx > 0) { 448 - if (tmp < 5 * 1000 * 1000) 449 - continue; 450 - } 424 + if ((best_divisor_idx >= 0) && (tmp < 5 * 1000 * 1000)) 425 + break; 451 426 divided_rate = tmp; 452 427 best_divisor_idx = i; 453 428 } ··· 482 467 goto err_disable_t1; 483 468 484 469 /* channel 2: periodic and oneshot timer support */ 485 - ret = setup_clkevents(&tc, clk32k_divisor_idx); 470 + ret = setup_clkevents(&tc, best_divisor_idx); 486 471 if (ret) 487 472 goto err_unregister_clksrc; 488 473
+1 -1
drivers/clocksource/timer-ti-32k.c
··· 21 21 * Roughly modelled after the OMAP1 MPU timer code. 22 22 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> 23 23 * 24 - * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com 24 + * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com 25 25 */ 26 26 27 27 #include <linux/clk.h>
+1 -1
drivers/clocksource/timer-ti-dm.c
··· 4 4 * 5 5 * OMAP Dual-Mode Timers 6 6 * 7 - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 7 + * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/ 8 8 * Tarun Kanti DebBarma <tarun.kanti@ti.com> 9 9 * Thara Gopinath <thara@ti.com> 10 10 *
+12
include/dt-bindings/clock/ingenic,sysost.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * This header provides clock numbers for the ingenic,tcu DT binding. 4 + */ 5 + 6 + #ifndef __DT_BINDINGS_CLOCK_INGENIC_OST_H__ 7 + #define __DT_BINDINGS_CLOCK_INGENIC_OST_H__ 8 + 9 + #define OST_CLK_PERCPU_TIMER 0 10 + #define OST_CLK_GLOBAL_TIMER 1 11 + 12 + #endif /* __DT_BINDINGS_CLOCK_INGENIC_OST_H__ */
+5
include/soc/at91/atmel_tcb.h
··· 36 36 /** 37 37 * struct atmel_tcb_config - SoC data for a Timer/Counter Block 38 38 * @counter_width: size in bits of a timer counter register 39 + * @has_gclk: boolean indicating if a timer counter has a generic clock 40 + * @has_qdec: boolean indicating if a timer counter has a quadrature 41 + * decoder. 39 42 */ 40 43 struct atmel_tcb_config { 41 44 size_t counter_width; 45 + bool has_gclk; 46 + bool has_qdec; 42 47 }; 43 48 44 49 /**
+115 -152
kernel/time/timer.c
··· 157 157 158 158 /* 159 159 * The time start value for each level to select the bucket at enqueue 160 - * time. 160 + * time. We start from the last possible delta of the previous level 161 + * so that we can later add an extra LVL_GRAN(n) to n (see calc_index()). 161 162 */ 162 163 #define LVL_START(n) ((LVL_SIZE - 1) << (((n) - 1) * LVL_CLK_SHIFT)) 163 164 ··· 205 204 unsigned long clk; 206 205 unsigned long next_expiry; 207 206 unsigned int cpu; 207 + bool next_expiry_recalc; 208 208 bool is_idle; 209 - bool must_forward_clk; 210 209 DECLARE_BITMAP(pending_map, WHEEL_SIZE); 211 210 struct hlist_head vectors[WHEEL_SIZE]; 212 211 } ____cacheline_aligned; ··· 489 488 * Helper function to calculate the array index for a given expiry 490 489 * time. 491 490 */ 492 - static inline unsigned calc_index(unsigned expires, unsigned lvl) 491 + static inline unsigned calc_index(unsigned long expires, unsigned lvl, 492 + unsigned long *bucket_expiry) 493 493 { 494 + 495 + /* 496 + * The timer wheel has to guarantee that a timer does not fire 497 + * early. Early expiry can happen due to: 498 + * - Timer is armed at the edge of a tick 499 + * - Truncation of the expiry time in the outer wheel levels 500 + * 501 + * Round up with level granularity to prevent this. 502 + */ 494 503 expires = (expires + LVL_GRAN(lvl)) >> LVL_SHIFT(lvl); 504 + *bucket_expiry = expires << LVL_SHIFT(lvl); 495 505 return LVL_OFFS(lvl) + (expires & LVL_MASK); 496 506 } 497 507 498 - static int calc_wheel_index(unsigned long expires, unsigned long clk) 508 + static int calc_wheel_index(unsigned long expires, unsigned long clk, 509 + unsigned long *bucket_expiry) 499 510 { 500 511 unsigned long delta = expires - clk; 501 512 unsigned int idx; 502 513 503 514 if (delta < LVL_START(1)) { 504 - idx = calc_index(expires, 0); 515 + idx = calc_index(expires, 0, bucket_expiry); 505 516 } else if (delta < LVL_START(2)) { 506 - idx = calc_index(expires, 1); 517 + idx = calc_index(expires, 1, bucket_expiry); 507 518 } else if (delta < LVL_START(3)) { 508 - idx = calc_index(expires, 2); 519 + idx = calc_index(expires, 2, bucket_expiry); 509 520 } else if (delta < LVL_START(4)) { 510 - idx = calc_index(expires, 3); 521 + idx = calc_index(expires, 3, bucket_expiry); 511 522 } else if (delta < LVL_START(5)) { 512 - idx = calc_index(expires, 4); 523 + idx = calc_index(expires, 4, bucket_expiry); 513 524 } else if (delta < LVL_START(6)) { 514 - idx = calc_index(expires, 5); 525 + idx = calc_index(expires, 5, bucket_expiry); 515 526 } else if (delta < LVL_START(7)) { 516 - idx = calc_index(expires, 6); 527 + idx = calc_index(expires, 6, bucket_expiry); 517 528 } else if (LVL_DEPTH > 8 && delta < LVL_START(8)) { 518 - idx = calc_index(expires, 7); 529 + idx = calc_index(expires, 7, bucket_expiry); 519 530 } else if ((long) delta < 0) { 520 531 idx = clk & LVL_MASK; 532 + *bucket_expiry = clk; 521 533 } else { 522 534 /* 523 535 * Force expire obscene large timeouts to expire at the ··· 539 525 if (delta >= WHEEL_TIMEOUT_CUTOFF) 540 526 expires = clk + WHEEL_TIMEOUT_MAX; 541 527 542 - idx = calc_index(expires, LVL_DEPTH - 1); 528 + idx = calc_index(expires, LVL_DEPTH - 1, bucket_expiry); 543 529 } 544 530 return idx; 545 - } 546 - 547 - /* 548 - * Enqueue the timer into the hash bucket, mark it pending in 549 - * the bitmap and store the index in the timer flags. 550 - */ 551 - static void enqueue_timer(struct timer_base *base, struct timer_list *timer, 552 - unsigned int idx) 553 - { 554 - hlist_add_head(&timer->entry, base->vectors + idx); 555 - __set_bit(idx, base->pending_map); 556 - timer_set_idx(timer, idx); 557 - 558 - trace_timer_start(timer, timer->expires, timer->flags); 559 - } 560 - 561 - static void 562 - __internal_add_timer(struct timer_base *base, struct timer_list *timer) 563 - { 564 - unsigned int idx; 565 - 566 - idx = calc_wheel_index(timer->expires, base->clk); 567 - enqueue_timer(base, timer, idx); 568 531 } 569 532 570 533 static void ··· 565 574 * timer is not deferrable. If the other CPU is on the way to idle 566 575 * then it can't set base->is_idle as we hold the base lock: 567 576 */ 568 - if (!base->is_idle) 569 - return; 570 - 571 - /* Check whether this is the new first expiring timer: */ 572 - if (time_after_eq(timer->expires, base->next_expiry)) 573 - return; 574 - 575 - /* 576 - * Set the next expiry time and kick the CPU so it can reevaluate the 577 - * wheel: 578 - */ 579 - if (time_before(timer->expires, base->clk)) { 580 - /* 581 - * Prevent from forward_timer_base() moving the base->clk 582 - * backward 583 - */ 584 - base->next_expiry = base->clk; 585 - } else { 586 - base->next_expiry = timer->expires; 587 - } 588 - wake_up_nohz_cpu(base->cpu); 577 + if (base->is_idle) 578 + wake_up_nohz_cpu(base->cpu); 589 579 } 590 580 591 - static void 592 - internal_add_timer(struct timer_base *base, struct timer_list *timer) 581 + /* 582 + * Enqueue the timer into the hash bucket, mark it pending in 583 + * the bitmap, store the index in the timer flags then wake up 584 + * the target CPU if needed. 585 + */ 586 + static void enqueue_timer(struct timer_base *base, struct timer_list *timer, 587 + unsigned int idx, unsigned long bucket_expiry) 593 588 { 594 - __internal_add_timer(base, timer); 595 - trigger_dyntick_cpu(base, timer); 589 + 590 + hlist_add_head(&timer->entry, base->vectors + idx); 591 + __set_bit(idx, base->pending_map); 592 + timer_set_idx(timer, idx); 593 + 594 + trace_timer_start(timer, timer->expires, timer->flags); 595 + 596 + /* 597 + * Check whether this is the new first expiring timer. The 598 + * effective expiry time of the timer is required here 599 + * (bucket_expiry) instead of timer->expires. 600 + */ 601 + if (time_before(bucket_expiry, base->next_expiry)) { 602 + /* 603 + * Set the next expiry time and kick the CPU so it 604 + * can reevaluate the wheel: 605 + */ 606 + base->next_expiry = bucket_expiry; 607 + base->next_expiry_recalc = false; 608 + trigger_dyntick_cpu(base, timer); 609 + } 610 + } 611 + 612 + static void internal_add_timer(struct timer_base *base, struct timer_list *timer) 613 + { 614 + unsigned long bucket_expiry; 615 + unsigned int idx; 616 + 617 + idx = calc_wheel_index(timer->expires, base->clk, &bucket_expiry); 618 + enqueue_timer(base, timer, idx, bucket_expiry); 596 619 } 597 620 598 621 #ifdef CONFIG_DEBUG_OBJECTS_TIMERS ··· 839 834 if (!timer_pending(timer)) 840 835 return 0; 841 836 842 - if (hlist_is_singular_node(&timer->entry, base->vectors + idx)) 837 + if (hlist_is_singular_node(&timer->entry, base->vectors + idx)) { 843 838 __clear_bit(idx, base->pending_map); 839 + base->next_expiry_recalc = true; 840 + } 844 841 845 842 detach_timer(timer, clear_pending); 846 843 return 1; ··· 892 885 893 886 static inline void forward_timer_base(struct timer_base *base) 894 887 { 895 - #ifdef CONFIG_NO_HZ_COMMON 896 - unsigned long jnow; 888 + unsigned long jnow = READ_ONCE(jiffies); 897 889 898 890 /* 899 - * We only forward the base when we are idle or have just come out of 900 - * idle (must_forward_clk logic), and have a delta between base clock 901 - * and jiffies. In the common case, run_timers will take care of it. 891 + * No need to forward if we are close enough below jiffies. 892 + * Also while executing timers, base->clk is 1 offset ahead 893 + * of jiffies to avoid endless requeuing to current jffies. 902 894 */ 903 - if (likely(!base->must_forward_clk)) 904 - return; 905 - 906 - jnow = READ_ONCE(jiffies); 907 - base->must_forward_clk = base->is_idle; 908 - if ((long)(jnow - base->clk) < 2) 895 + if ((long)(jnow - base->clk) < 1) 909 896 return; 910 897 911 898 /* ··· 913 912 return; 914 913 base->clk = base->next_expiry; 915 914 } 916 - #endif 917 915 } 918 916 919 917 ··· 960 960 static inline int 961 961 __mod_timer(struct timer_list *timer, unsigned long expires, unsigned int options) 962 962 { 963 + unsigned long clk = 0, flags, bucket_expiry; 963 964 struct timer_base *base, *new_base; 964 965 unsigned int idx = UINT_MAX; 965 - unsigned long clk = 0, flags; 966 966 int ret = 0; 967 967 968 968 BUG_ON(!timer->function); ··· 1001 1001 } 1002 1002 1003 1003 clk = base->clk; 1004 - idx = calc_wheel_index(expires, clk); 1004 + idx = calc_wheel_index(expires, clk, &bucket_expiry); 1005 1005 1006 1006 /* 1007 1007 * Retrieve and compare the array index of the pending ··· 1054 1054 /* 1055 1055 * If 'idx' was calculated above and the base time did not advance 1056 1056 * between calculating 'idx' and possibly switching the base, only 1057 - * enqueue_timer() and trigger_dyntick_cpu() is required. Otherwise 1058 - * we need to (re)calculate the wheel index via 1059 - * internal_add_timer(). 1057 + * enqueue_timer() is required. Otherwise we need to (re)calculate 1058 + * the wheel index via internal_add_timer(). 1060 1059 */ 1061 - if (idx != UINT_MAX && clk == base->clk) { 1062 - enqueue_timer(base, timer, idx); 1063 - trigger_dyntick_cpu(base, timer); 1064 - } else { 1060 + if (idx != UINT_MAX && clk == base->clk) 1061 + enqueue_timer(base, timer, idx, bucket_expiry); 1062 + else 1065 1063 internal_add_timer(base, timer); 1066 - } 1067 1064 1068 1065 out_unlock: 1069 1066 raw_spin_unlock_irqrestore(&base->lock, flags); ··· 1463 1466 } 1464 1467 } 1465 1468 1466 - static int __collect_expired_timers(struct timer_base *base, 1467 - struct hlist_head *heads) 1469 + static int collect_expired_timers(struct timer_base *base, 1470 + struct hlist_head *heads) 1468 1471 { 1469 - unsigned long clk = base->clk; 1472 + unsigned long clk = base->clk = base->next_expiry; 1470 1473 struct hlist_head *vec; 1471 1474 int i, levels = 0; 1472 1475 unsigned int idx; ··· 1488 1491 return levels; 1489 1492 } 1490 1493 1491 - #ifdef CONFIG_NO_HZ_COMMON 1492 1494 /* 1493 1495 * Find the next pending bucket of a level. Search from level start (@offset) 1494 1496 * + @clk upwards and if nothing there, search from start of the level ··· 1520 1524 clk = base->clk; 1521 1525 for (lvl = 0; lvl < LVL_DEPTH; lvl++, offset += LVL_SIZE) { 1522 1526 int pos = next_pending_bucket(base, offset, clk & LVL_MASK); 1527 + unsigned long lvl_clk = clk & LVL_CLK_MASK; 1523 1528 1524 1529 if (pos >= 0) { 1525 1530 unsigned long tmp = clk + (unsigned long) pos; ··· 1528 1531 tmp <<= LVL_SHIFT(lvl); 1529 1532 if (time_before(tmp, next)) 1530 1533 next = tmp; 1534 + 1535 + /* 1536 + * If the next expiration happens before we reach 1537 + * the next level, no need to check further. 1538 + */ 1539 + if (pos <= ((LVL_CLK_DIV - lvl_clk) & LVL_CLK_MASK)) 1540 + break; 1531 1541 } 1532 1542 /* 1533 1543 * Clock for the next level. If the current level clock lower ··· 1572 1568 * So the simple check whether the lower bits of the current 1573 1569 * level are 0 or not is sufficient for all cases. 1574 1570 */ 1575 - adj = clk & LVL_CLK_MASK ? 1 : 0; 1571 + adj = lvl_clk ? 1 : 0; 1576 1572 clk >>= LVL_CLK_SHIFT; 1577 1573 clk += adj; 1578 1574 } 1575 + 1576 + base->next_expiry_recalc = false; 1577 + 1579 1578 return next; 1580 1579 } 1581 1580 1581 + #ifdef CONFIG_NO_HZ_COMMON 1582 1582 /* 1583 1583 * Check, if the next hrtimer event is before the next timer wheel 1584 1584 * event: ··· 1639 1631 return expires; 1640 1632 1641 1633 raw_spin_lock(&base->lock); 1642 - nextevt = __next_timer_interrupt(base); 1634 + if (base->next_expiry_recalc) 1635 + base->next_expiry = __next_timer_interrupt(base); 1636 + nextevt = base->next_expiry; 1643 1637 is_max_delta = (nextevt == base->clk + NEXT_TIMER_MAX_DELTA); 1644 - base->next_expiry = nextevt; 1638 + 1645 1639 /* 1646 1640 * We have a fresh next event. Check whether we can forward the 1647 1641 * base. We can only do that when @basej is past base->clk ··· 1669 1659 * logic is only maintained for the BASE_STD base, deferrable 1670 1660 * timers may still see large granularity skew (by design). 1671 1661 */ 1672 - if ((expires - basem) > TICK_NSEC) { 1673 - base->must_forward_clk = true; 1662 + if ((expires - basem) > TICK_NSEC) 1674 1663 base->is_idle = true; 1675 - } 1676 1664 } 1677 1665 raw_spin_unlock(&base->lock); 1678 1666 ··· 1693 1685 * the lock in the exit from idle path. 1694 1686 */ 1695 1687 base->is_idle = false; 1696 - } 1697 - 1698 - static int collect_expired_timers(struct timer_base *base, 1699 - struct hlist_head *heads) 1700 - { 1701 - unsigned long now = READ_ONCE(jiffies); 1702 - 1703 - /* 1704 - * NOHZ optimization. After a long idle sleep we need to forward the 1705 - * base to current jiffies. Avoid a loop by searching the bitfield for 1706 - * the next expiring timer. 1707 - */ 1708 - if ((long)(now - base->clk) > 2) { 1709 - unsigned long next = __next_timer_interrupt(base); 1710 - 1711 - /* 1712 - * If the next timer is ahead of time forward to current 1713 - * jiffies, otherwise forward to the next expiry time: 1714 - */ 1715 - if (time_after(next, now)) { 1716 - /* 1717 - * The call site will increment base->clk and then 1718 - * terminate the expiry loop immediately. 1719 - */ 1720 - base->clk = now; 1721 - return 0; 1722 - } 1723 - base->clk = next; 1724 - } 1725 - return __collect_expired_timers(base, heads); 1726 - } 1727 - #else 1728 - static inline int collect_expired_timers(struct timer_base *base, 1729 - struct hlist_head *heads) 1730 - { 1731 - return __collect_expired_timers(base, heads); 1732 1688 } 1733 1689 #endif 1734 1690 ··· 1733 1761 struct hlist_head heads[LVL_DEPTH]; 1734 1762 int levels; 1735 1763 1736 - if (!time_after_eq(jiffies, base->clk)) 1764 + if (time_before(jiffies, base->next_expiry)) 1737 1765 return; 1738 1766 1739 1767 timer_base_lock_expiry(base); 1740 1768 raw_spin_lock_irq(&base->lock); 1741 1769 1742 - /* 1743 - * timer_base::must_forward_clk must be cleared before running 1744 - * timers so that any timer functions that call mod_timer() will 1745 - * not try to forward the base. Idle tracking / clock forwarding 1746 - * logic is only used with BASE_STD timers. 1747 - * 1748 - * The must_forward_clk flag is cleared unconditionally also for 1749 - * the deferrable base. The deferrable base is not affected by idle 1750 - * tracking and never forwarded, so clearing the flag is a NOOP. 1751 - * 1752 - * The fact that the deferrable base is never forwarded can cause 1753 - * large variations in granularity for deferrable timers, but they 1754 - * can be deferred for long periods due to idle anyway. 1755 - */ 1756 - base->must_forward_clk = false; 1757 - 1758 - while (time_after_eq(jiffies, base->clk)) { 1759 - 1770 + while (time_after_eq(jiffies, base->clk) && 1771 + time_after_eq(jiffies, base->next_expiry)) { 1760 1772 levels = collect_expired_timers(base, heads); 1773 + /* 1774 + * The only possible reason for not finding any expired 1775 + * timer at this clk is that all matching timers have been 1776 + * dequeued. 1777 + */ 1778 + WARN_ON_ONCE(!levels && !base->next_expiry_recalc); 1761 1779 base->clk++; 1780 + base->next_expiry = __next_timer_interrupt(base); 1762 1781 1763 1782 while (levels--) 1764 1783 expire_timers(base, heads + levels); ··· 1779 1816 1780 1817 hrtimer_run_queues(); 1781 1818 /* Raise the softirq only if required. */ 1782 - if (time_before(jiffies, base->clk)) { 1819 + if (time_before(jiffies, base->next_expiry)) { 1783 1820 if (!IS_ENABLED(CONFIG_NO_HZ_COMMON)) 1784 1821 return; 1785 1822 /* CPU is awake, so check the deferrable base. */ 1786 1823 base++; 1787 - if (time_before(jiffies, base->clk)) 1824 + if (time_before(jiffies, base->next_expiry)) 1788 1825 return; 1789 1826 } 1790 1827 raise_softirq(TIMER_SOFTIRQ); ··· 1949 1986 base->clk = jiffies; 1950 1987 base->next_expiry = base->clk + NEXT_TIMER_MAX_DELTA; 1951 1988 base->is_idle = false; 1952 - base->must_forward_clk = true; 1953 1989 } 1954 1990 return 0; 1955 1991 } ··· 2001 2039 base->cpu = cpu; 2002 2040 raw_spin_lock_init(&base->lock); 2003 2041 base->clk = jiffies; 2042 + base->next_expiry = base->clk + NEXT_TIMER_MAX_DELTA; 2004 2043 timer_base_init_expiry_lock(base); 2005 2044 } 2006 2045 }