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

Merge branch 'clockevents/4.4' of http://git.linaro.org/people/daniel.lezcano/linux into timers/core

clockevent updates from Daniel Lezcano:

- Remove unneeded memset in em_sti, sh_cmt and h8300 because there are already
zeroed by a kzalloc (Alexey Klimov)

- Optimize code by replacing this_cpu_ptr by container_of on the exynos_mct (Alexey
Klimov)

- Get immune from a spurious interrupt when enabling the mtk_timer (Daniel Lezcano)

- Use the dynamic irq affinity to optimize wakeup and useless IPI timer on the imx
timer (Lucas Stach)

- Add new timer for Tango SoCs (Marc Gonzalez)

- Implement the timer delay for armada-370-xp (Russell King)

- Use GPT as clock source (Yingjoe Chen)

+111 -21
+4
drivers/clocksource/Kconfig
··· 279 279 depends on MIPS_GIC 280 280 select CLKSRC_OF 281 281 282 + config CLKSRC_TANGO_XTAL 283 + bool 284 + select CLKSRC_OF 285 + 282 286 config CLKSRC_PXA 283 287 def_bool y if ARCH_PXA || ARCH_SA1100 284 288 select CLKSRC_OF if OF
+1
drivers/clocksource/Makefile
··· 56 56 obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o 57 57 obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o 58 58 obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o 59 + obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o 59 60 obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o 60 61 obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o 61 62 obj-$(CONFIG_H8300) += h8300_timer8.o
-2
drivers/clocksource/em_sti.c
··· 228 228 { 229 229 struct clocksource *cs = &p->cs; 230 230 231 - memset(cs, 0, sizeof(*cs)); 232 231 cs->name = dev_name(&p->pdev->dev); 233 232 cs->rating = 200; 234 233 cs->read = em_sti_clocksource_read; ··· 284 285 { 285 286 struct clock_event_device *ced = &p->ced; 286 287 287 - memset(ced, 0, sizeof(*ced)); 288 288 ced->name = dev_name(&p->pdev->dev); 289 289 ced->features = CLOCK_EVT_FEAT_ONESHOT; 290 290 ced->rating = 200;
+8 -4
drivers/clocksource/exynos_mct.c
··· 382 382 static int exynos4_tick_set_next_event(unsigned long cycles, 383 383 struct clock_event_device *evt) 384 384 { 385 - struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); 385 + struct mct_clock_event_device *mevt; 386 386 387 + mevt = container_of(evt, struct mct_clock_event_device, evt); 387 388 exynos4_mct_tick_start(cycles, mevt); 388 - 389 389 return 0; 390 390 } 391 391 392 392 static int set_state_shutdown(struct clock_event_device *evt) 393 393 { 394 - exynos4_mct_tick_stop(this_cpu_ptr(&percpu_mct_tick)); 394 + struct mct_clock_event_device *mevt; 395 + 396 + mevt = container_of(evt, struct mct_clock_event_device, evt); 397 + exynos4_mct_tick_stop(mevt); 395 398 return 0; 396 399 } 397 400 398 401 static int set_state_periodic(struct clock_event_device *evt) 399 402 { 400 - struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); 403 + struct mct_clock_event_device *mevt; 401 404 unsigned long cycles_per_jiffy; 402 405 406 + mevt = container_of(evt, struct mct_clock_event_device, evt); 403 407 cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult) 404 408 >> evt->shift); 405 409 exynos4_mct_tick_stop(mevt);
-1
drivers/clocksource/h8300_timer16.c
··· 153 153 int ret, irq; 154 154 unsigned int ch; 155 155 156 - memset(p, 0, sizeof(*p)); 157 156 p->pdev = pdev; 158 157 159 158 res[REG_CH] = platform_get_resource(p->pdev,
-1
drivers/clocksource/h8300_timer8.c
··· 215 215 int irq; 216 216 int ret; 217 217 218 - memset(p, 0, sizeof(*p)); 219 218 p->pdev = pdev; 220 219 221 220 res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
-1
drivers/clocksource/h8300_tpu.c
··· 123 123 { 124 124 struct resource *res[2]; 125 125 126 - memset(p, 0, sizeof(*p)); 127 126 p->pdev = pdev; 128 127 129 128 res[CH_L] = platform_get_resource(p->pdev, IORESOURCE_MEM, CH_L);
+16 -10
drivers/clocksource/mtk_timer.c
··· 24 24 #include <linux/of.h> 25 25 #include <linux/of_address.h> 26 26 #include <linux/of_irq.h> 27 + #include <linux/sched_clock.h> 27 28 #include <linux/slab.h> 28 29 29 30 #define GPT_IRQ_EN_REG 0x00 ··· 59 58 u32 ticks_per_jiffy; 60 59 struct clock_event_device dev; 61 60 }; 61 + 62 + static void __iomem *gpt_sched_reg __read_mostly; 63 + 64 + static u64 notrace mtk_read_sched_clock(void) 65 + { 66 + return readl_relaxed(gpt_sched_reg); 67 + } 62 68 63 69 static inline struct mtk_clock_event_device *to_mtk_clk( 64 70 struct clock_event_device *c) ··· 149 141 return IRQ_HANDLED; 150 142 } 151 143 152 - static void mtk_timer_global_reset(struct mtk_clock_event_device *evt) 153 - { 154 - /* Disable all interrupts */ 155 - writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG); 156 - /* Acknowledge all interrupts */ 157 - writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG); 158 - } 159 - 160 144 static void 161 145 mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option) 162 146 { ··· 167 167 static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer) 168 168 { 169 169 u32 val; 170 + 171 + /* Disable all interrupts */ 172 + writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG); 173 + 174 + /* Acknowledge all spurious pending interrupts */ 175 + writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG); 170 176 171 177 val = readl(evt->gpt_base + GPT_IRQ_EN_REG); 172 178 writel(val | GPT_IRQ_ENABLE(timer), ··· 226 220 } 227 221 rate = clk_get_rate(clk); 228 222 229 - mtk_timer_global_reset(evt); 230 - 231 223 if (request_irq(evt->dev.irq, mtk_timer_interrupt, 232 224 IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) { 233 225 pr_warn("failed to setup irq %d\n", evt->dev.irq); ··· 238 234 mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN); 239 235 clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC), 240 236 node->name, rate, 300, 32, clocksource_mmio_readl_up); 237 + gpt_sched_reg = evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC); 238 + sched_clock_register(mtk_read_sched_clock, 32, rate); 241 239 242 240 /* Configure clock event */ 243 241 mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT);
-1
drivers/clocksource/sh_cmt.c
··· 962 962 unsigned int i; 963 963 int ret; 964 964 965 - memset(cmt, 0, sizeof(*cmt)); 966 965 cmt->pdev = pdev; 967 966 raw_spin_lock_init(&cmt->lock); 968 967
+66
drivers/clocksource/tango_xtal.c
··· 1 + #include <linux/clocksource.h> 2 + #include <linux/sched_clock.h> 3 + #include <linux/of_address.h> 4 + #include <linux/printk.h> 5 + #include <linux/delay.h> 6 + #include <linux/init.h> 7 + #include <linux/clk.h> 8 + 9 + static void __iomem *xtal_in_cnt; 10 + static struct delay_timer delay_timer; 11 + 12 + static unsigned long notrace read_xtal_counter(void) 13 + { 14 + return readl_relaxed(xtal_in_cnt); 15 + } 16 + 17 + static u64 notrace read_sched_clock(void) 18 + { 19 + return read_xtal_counter(); 20 + } 21 + 22 + static cycle_t read_clocksource(struct clocksource *cs) 23 + { 24 + return read_xtal_counter(); 25 + } 26 + 27 + static struct clocksource tango_xtal = { 28 + .name = "tango-xtal", 29 + .rating = 350, 30 + .read = read_clocksource, 31 + .mask = CLOCKSOURCE_MASK(32), 32 + .flags = CLOCK_SOURCE_IS_CONTINUOUS, 33 + }; 34 + 35 + static void __init tango_clocksource_init(struct device_node *np) 36 + { 37 + struct clk *clk; 38 + int xtal_freq, ret; 39 + 40 + xtal_in_cnt = of_iomap(np, 0); 41 + if (xtal_in_cnt == NULL) { 42 + pr_err("%s: invalid address\n", np->full_name); 43 + return; 44 + } 45 + 46 + clk = of_clk_get(np, 0); 47 + if (IS_ERR(clk)) { 48 + pr_err("%s: invalid clock\n", np->full_name); 49 + return; 50 + } 51 + 52 + xtal_freq = clk_get_rate(clk); 53 + delay_timer.freq = xtal_freq; 54 + delay_timer.read_current_timer = read_xtal_counter; 55 + 56 + ret = clocksource_register_hz(&tango_xtal, xtal_freq); 57 + if (ret != 0) { 58 + pr_err("%s: registration failed\n", np->full_name); 59 + return; 60 + } 61 + 62 + sched_clock_register(read_sched_clock, 32, xtal_freq); 63 + register_current_timer_delay(&delay_timer); 64 + } 65 + 66 + CLOCKSOURCE_OF_DECLARE(tango, "sigma,tick-counter", tango_clocksource_init);
+14
drivers/clocksource/time-armada-370-xp.c
··· 45 45 #include <linux/percpu.h> 46 46 #include <linux/syscore_ops.h> 47 47 48 + #include <asm/delay.h> 49 + 48 50 /* 49 51 * Timer block registers. 50 52 */ ··· 251 249 .resume = armada_370_xp_timer_resume, 252 250 }; 253 251 252 + static unsigned long armada_370_delay_timer_read(void) 253 + { 254 + return ~readl(timer_base + TIMER0_VAL_OFF); 255 + } 256 + 257 + static struct delay_timer armada_370_delay_timer = { 258 + .read_current_timer = armada_370_delay_timer_read, 259 + }; 260 + 254 261 static void __init armada_370_xp_timer_common_init(struct device_node *np) 255 262 { 256 263 u32 clr = 0, set = 0; ··· 297 286 atomic_io_modify(timer_base + TIMER_CTRL_OFF, 298 287 TIMER0_RELOAD_EN | enable_mask, 299 288 TIMER0_RELOAD_EN | enable_mask); 289 + 290 + armada_370_delay_timer.freq = timer_clk; 291 + register_current_timer_delay(&armada_370_delay_timer); 300 292 301 293 /* 302 294 * Set scale and timer for sched_clock.
+2 -1
drivers/clocksource/timer-imx-gpt.c
··· 305 305 struct irqaction *act = &imxtm->act; 306 306 307 307 ced->name = "mxc_timer1"; 308 - ced->features = CLOCK_EVT_FEAT_ONESHOT; 308 + ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ; 309 309 ced->set_state_shutdown = mxc_shutdown; 310 310 ced->set_state_oneshot = mxc_set_oneshot; 311 311 ced->tick_resume = mxc_shutdown; 312 312 ced->set_next_event = imxtm->gpt->set_next_event; 313 313 ced->rating = 200; 314 314 ced->cpumask = cpumask_of(0); 315 + ced->irq = imxtm->irq; 315 316 clockevents_config_and_register(ced, clk_get_rate(imxtm->clk_per), 316 317 0xff, 0xfffffffe); 317 318