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

ARM: u300: device tree support for the timer

This adds device tree support for the U300 timer, by making
the memory base offset and IRQ dynamically assigned, then
optionally looking them up from the device tree.

Since the timer needs to be registered before any platform
devices are created, we will go into the device tree and look
up the "/timer@c0014000" node and read our base address and
IRQ from there.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

+91 -38
+18
Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt
··· 1 + ST-Ericsson U300 apptimer 2 + 3 + Required properties: 4 + 5 + - compatible : should be "stericsson,u300-apptimer" 6 + - reg : Specifies base physical address and size of the registers. 7 + - interrupts : A list of 4 interrupts; one for each subtimer. These 8 + are, in order: OS (operating system), DD (device driver) both 9 + adopted for EPOC/Symbian with two specific IRQs for these tasks, 10 + then GP1 and GP2, which are general-purpose timers. 11 + 12 + Example: 13 + 14 + timer { 15 + compatible = "stericsson,u300-apptimer"; 16 + reg = <0xc0014000 0x1000>; 17 + interrupts = <24 25 26 27>; 18 + };
+1
arch/arm/Kconfig
··· 821 821 select ARM_VIC 822 822 select CLKDEV_LOOKUP 823 823 select CLKSRC_MMIO 824 + select CLKSRC_OF 824 825 select COMMON_CLK 825 826 select CPU_ARM926T 826 827 select GENERIC_CLOCKEVENTS
+71 -38
arch/arm/mach-u300/timer.c
··· 19 19 #include <linux/err.h> 20 20 #include <linux/irq.h> 21 21 #include <linux/delay.h> 22 + #include <linux/of_address.h> 23 + #include <linux/of_irq.h> 22 24 23 25 #include <mach/hardware.h> 24 26 #include <mach/irqs.h> ··· 192 190 #define TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) 193 191 #define US_PER_TICK ((1000000 + (HZ/2)) / HZ) 194 192 193 + static void __iomem *u300_timer_base; 194 + 195 195 /* 196 196 * The u300_set_mode() function is always called first, if we 197 197 * have oneshot timer active, the oneshot scheduling function ··· 206 202 case CLOCK_EVT_MODE_PERIODIC: 207 203 /* Disable interrupts on GPT1 */ 208 204 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, 209 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); 205 + u300_timer_base + U300_TIMER_APP_GPT1IE); 210 206 /* Disable GP1 while we're reprogramming it. */ 211 207 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, 212 - U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); 208 + u300_timer_base + U300_TIMER_APP_DGPT1); 213 209 /* 214 210 * Set the periodic mode to a certain number of ticks per 215 211 * jiffy. 216 212 */ 217 213 writel(TICKS_PER_JIFFY, 218 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC); 214 + u300_timer_base + U300_TIMER_APP_GPT1TC); 219 215 /* 220 216 * Set continuous mode, so the timer keeps triggering 221 217 * interrupts. 222 218 */ 223 219 writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS, 224 - U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M); 220 + u300_timer_base + U300_TIMER_APP_SGPT1M); 225 221 /* Enable timer interrupts */ 226 222 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, 227 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); 223 + u300_timer_base + U300_TIMER_APP_GPT1IE); 228 224 /* Then enable the OS timer again */ 229 225 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, 230 - U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1); 226 + u300_timer_base + U300_TIMER_APP_EGPT1); 231 227 break; 232 228 case CLOCK_EVT_MODE_ONESHOT: 233 229 /* Just break; here? */ ··· 238 234 */ 239 235 /* Disable interrupts on GPT1 */ 240 236 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, 241 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); 237 + u300_timer_base + U300_TIMER_APP_GPT1IE); 242 238 /* Disable GP1 while we're reprogramming it. */ 243 239 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, 244 - U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); 240 + u300_timer_base + U300_TIMER_APP_DGPT1); 245 241 /* 246 242 * Expire far in the future, u300_set_next_event() will be 247 243 * called soon... 248 244 */ 249 - writel(0xFFFFFFFF, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC); 245 + writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC); 250 246 /* We run one shot per tick here! */ 251 247 writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, 252 - U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M); 248 + u300_timer_base + U300_TIMER_APP_SGPT1M); 253 249 /* Enable interrupts for this timer */ 254 250 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, 255 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); 251 + u300_timer_base + U300_TIMER_APP_GPT1IE); 256 252 /* Enable timer */ 257 253 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, 258 - U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1); 254 + u300_timer_base + U300_TIMER_APP_EGPT1); 259 255 break; 260 256 case CLOCK_EVT_MODE_UNUSED: 261 257 case CLOCK_EVT_MODE_SHUTDOWN: 262 258 /* Disable interrupts on GP1 */ 263 259 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, 264 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); 260 + u300_timer_base + U300_TIMER_APP_GPT1IE); 265 261 /* Disable GP1 */ 266 262 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, 267 - U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); 263 + u300_timer_base + U300_TIMER_APP_DGPT1); 268 264 break; 269 265 case CLOCK_EVT_MODE_RESUME: 270 266 /* Ignore this call */ ··· 286 282 { 287 283 /* Disable interrupts on GPT1 */ 288 284 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, 289 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); 285 + u300_timer_base + U300_TIMER_APP_GPT1IE); 290 286 /* Disable GP1 while we're reprogramming it. */ 291 287 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, 292 - U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); 288 + u300_timer_base + U300_TIMER_APP_DGPT1); 293 289 /* Reset the General Purpose timer 1. */ 294 290 writel(U300_TIMER_APP_RGPT1_TIMER_RESET, 295 - U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1); 291 + u300_timer_base + U300_TIMER_APP_RGPT1); 296 292 /* IRQ in n * cycles */ 297 - writel(cycles, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC); 293 + writel(cycles, u300_timer_base + U300_TIMER_APP_GPT1TC); 298 294 /* 299 295 * We run one shot per tick here! (This is necessary to reconfigure, 300 296 * the timer will tilt if you don't!) 301 297 */ 302 298 writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, 303 - U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M); 299 + u300_timer_base + U300_TIMER_APP_SGPT1M); 304 300 /* Enable timer interrupts */ 305 301 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, 306 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); 302 + u300_timer_base + U300_TIMER_APP_GPT1IE); 307 303 /* Then enable the OS timer again */ 308 304 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, 309 - U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1); 305 + u300_timer_base + U300_TIMER_APP_EGPT1); 310 306 return 0; 311 307 } 312 308 ··· 325 321 { 326 322 struct clock_event_device *evt = &clockevent_u300_1mhz; 327 323 /* ACK/Clear timer IRQ for the APP GPT1 Timer */ 324 + 328 325 writel(U300_TIMER_APP_GPT1IA_IRQ_ACK, 329 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IA); 326 + u300_timer_base + U300_TIMER_APP_GPT1IA); 330 327 evt->event_handler(evt); 331 328 return IRQ_HANDLED; 332 329 } ··· 348 343 349 344 static u32 notrace u300_read_sched_clock(void) 350 345 { 351 - return readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); 346 + return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); 352 347 } 353 348 354 349 static unsigned long u300_read_current_timer(void) 355 350 { 356 - return readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); 351 + return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); 357 352 } 358 353 359 354 static struct delay_timer u300_delay_timer; ··· 361 356 /* 362 357 * This sets up the system timers, clock source and clock event. 363 358 */ 364 - void __init u300_timer_init(void) 359 + static void __init u300_timer_setup(void __iomem *base, int irq) 365 360 { 366 361 struct clk *clk; 367 362 unsigned long rate; 363 + 364 + u300_timer_base = base; 365 + pr_info("U300 GP1 timer @ base: %p, IRQ: %d\n", u300_timer_base, irq); 368 366 369 367 /* Clock the interrupt controller */ 370 368 clk = clk_get_sys("apptimer", NULL); ··· 386 378 * Example usage in cnh1601578 cpu subsystem pd_timer_app.c 387 379 */ 388 380 writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE, 389 - U300_TIMER_APP_VBASE + U300_TIMER_APP_CRC); 381 + u300_timer_base + U300_TIMER_APP_CRC); 390 382 writel(U300_TIMER_APP_ROST_TIMER_RESET, 391 - U300_TIMER_APP_VBASE + U300_TIMER_APP_ROST); 383 + u300_timer_base + U300_TIMER_APP_ROST); 392 384 writel(U300_TIMER_APP_DOST_TIMER_DISABLE, 393 - U300_TIMER_APP_VBASE + U300_TIMER_APP_DOST); 385 + u300_timer_base + U300_TIMER_APP_DOST); 394 386 writel(U300_TIMER_APP_RDDT_TIMER_RESET, 395 - U300_TIMER_APP_VBASE + U300_TIMER_APP_RDDT); 387 + u300_timer_base + U300_TIMER_APP_RDDT); 396 388 writel(U300_TIMER_APP_DDDT_TIMER_DISABLE, 397 - U300_TIMER_APP_VBASE + U300_TIMER_APP_DDDT); 389 + u300_timer_base + U300_TIMER_APP_DDDT); 398 390 399 391 /* Reset the General Purpose timer 1. */ 400 392 writel(U300_TIMER_APP_RGPT1_TIMER_RESET, 401 - U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1); 393 + u300_timer_base + U300_TIMER_APP_RGPT1); 402 394 403 395 /* Set up the IRQ handler */ 404 - setup_irq(IRQ_U300_TIMER_APP_GP1, &u300_timer_irq); 396 + setup_irq(irq, &u300_timer_irq); 405 397 406 398 /* Reset the General Purpose timer 2 */ 407 399 writel(U300_TIMER_APP_RGPT2_TIMER_RESET, 408 - U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT2); 400 + u300_timer_base + U300_TIMER_APP_RGPT2); 409 401 /* Set this timer to run around forever */ 410 - writel(0xFFFFFFFFU, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2TC); 402 + writel(0xFFFFFFFFU, u300_timer_base + U300_TIMER_APP_GPT2TC); 411 403 /* Set continuous mode so it wraps around */ 412 404 writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS, 413 - U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT2M); 405 + u300_timer_base + U300_TIMER_APP_SGPT2M); 414 406 /* Disable timer interrupts */ 415 407 writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE, 416 - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2IE); 408 + u300_timer_base + U300_TIMER_APP_GPT2IE); 417 409 /* Then enable the GP2 timer to use as a free running us counter */ 418 410 writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, 419 - U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); 411 + u300_timer_base + U300_TIMER_APP_EGPT2); 420 412 421 413 /* Use general purpose timer 2 as clock source */ 422 - if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC, 414 + if (clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC, 423 415 "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) 424 416 pr_err("timer: failed to initialize U300 clock source\n"); 425 417 ··· 432 424 * used by hrtimers! 433 425 */ 434 426 } 427 + 428 + 429 + void __init u300_timer_init() 430 + { 431 + u300_timer_setup(U300_TIMER_APP_VBASE, IRQ_U300_TIMER_APP_GP1); 432 + } 433 + 434 + #ifdef CONFIG_OF 435 + 436 + static void __init u300_timer_init_of(struct device_node *np) 437 + { 438 + void __iomem *base; 439 + struct resource irq_res; 440 + int irq; 441 + 442 + base = of_iomap(np, 0); 443 + /* Get the IRQ for the GP1 timer */ 444 + irq = of_irq_to_resource(np, 2, &irq_res); 445 + u300_timer_setup(base, irq); 446 + } 447 + 448 + CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer", 449 + u300_timer_init_of); 450 + 451 + #endif
+1
arch/arm/mach-u300/timer.h
··· 1 1 extern void u300_timer_init(void); 2 +