1 // SPDX-License-Identifier: GPL-2.0-only 2 /* linux/arch/arm/mach-exynos4/mct.c 3 * 4 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com 6 * 7 * Exynos4 MCT(Multi-Core Timer) support 8 */ 9 10 #include <linux/interrupt.h> 11 #include <linux/irq.h> 12 #include <linux/err.h> 13 #include <linux/clk.h> 14 #include <linux/clockchips.h> 15 #include <linux/cpu.h> 16 #include <linux/delay.h> 17 #include <linux/percpu.h> 18 #include <linux/of.h> 19 #include <linux/of_irq.h> 20 #include <linux/of_address.h> 21 #include <linux/clocksource.h> 22 #include <linux/sched_clock.h> 23 24 #define EXYNOS4_MCTREG(x) (x) 25 #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100) 26 #define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104) 27 #define EXYNOS4_MCT_G_CNT_WSTAT EXYNOS4_MCTREG(0x110) 28 #define EXYNOS4_MCT_G_COMP0_L EXYNOS4_MCTREG(0x200) 29 #define EXYNOS4_MCT_G_COMP0_U EXYNOS4_MCTREG(0x204) 30 #define EXYNOS4_MCT_G_COMP0_ADD_INCR EXYNOS4_MCTREG(0x208) 31 #define EXYNOS4_MCT_G_TCON EXYNOS4_MCTREG(0x240) 32 #define EXYNOS4_MCT_G_INT_CSTAT EXYNOS4_MCTREG(0x244) 33 #define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248) 34 #define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C) 35 #define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300) 36 #define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x)) 37 #define EXYNOS4_MCT_L_MASK (0xffffff00) 38 39 #define MCT_L_TCNTB_OFFSET (0x00) 40 #define MCT_L_ICNTB_OFFSET (0x08) 41 #define MCT_L_TCON_OFFSET (0x20) 42 #define MCT_L_INT_CSTAT_OFFSET (0x30) 43 #define MCT_L_INT_ENB_OFFSET (0x34) 44 #define MCT_L_WSTAT_OFFSET (0x40) 45 #define MCT_G_TCON_START (1 << 8) 46 #define MCT_G_TCON_COMP0_AUTO_INC (1 << 1) 47 #define MCT_G_TCON_COMP0_ENABLE (1 << 0) 48 #define MCT_L_TCON_INTERVAL_MODE (1 << 2) 49 #define MCT_L_TCON_INT_START (1 << 1) 50 #define MCT_L_TCON_TIMER_START (1 << 0) 51 52 #define TICK_BASE_CNT 1 53 54 #ifdef CONFIG_ARM 55 /* Use values higher than ARM arch timer. See 6282edb72bed. */ 56 #define MCT_CLKSOURCE_RATING 450 57 #define MCT_CLKEVENTS_RATING 500 58 #else 59 #define MCT_CLKSOURCE_RATING 350 60 #define MCT_CLKEVENTS_RATING 350 61 #endif 62 63 enum { 64 MCT_INT_SPI, 65 MCT_INT_PPI 66 }; 67 68 enum { 69 MCT_G0_IRQ, 70 MCT_G1_IRQ, 71 MCT_G2_IRQ, 72 MCT_G3_IRQ, 73 MCT_L0_IRQ, 74 MCT_L1_IRQ, 75 MCT_L2_IRQ, 76 MCT_L3_IRQ, 77 MCT_L4_IRQ, 78 MCT_L5_IRQ, 79 MCT_L6_IRQ, 80 MCT_L7_IRQ, 81 MCT_NR_IRQS, 82 }; 83 84 static void __iomem *reg_base; 85 static unsigned long clk_rate; 86 static unsigned int mct_int_type; 87 static int mct_irqs[MCT_NR_IRQS]; 88 89 struct mct_clock_event_device { 90 struct clock_event_device evt; 91 unsigned long base; 92 char name[10]; 93 }; 94 95 static void exynos4_mct_write(unsigned int value, unsigned long offset) 96 { 97 unsigned long stat_addr; 98 u32 mask; 99 u32 i; 100 101 writel_relaxed(value, reg_base + offset); 102 103 if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) { 104 stat_addr = (offset & EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET; 105 switch (offset & ~EXYNOS4_MCT_L_MASK) { 106 case MCT_L_TCON_OFFSET: 107 mask = 1 << 3; /* L_TCON write status */ 108 break; 109 case MCT_L_ICNTB_OFFSET: 110 mask = 1 << 1; /* L_ICNTB write status */ 111 break; 112 case MCT_L_TCNTB_OFFSET: 113 mask = 1 << 0; /* L_TCNTB write status */ 114 break; 115 default: 116 return; 117 } 118 } else { 119 switch (offset) { 120 case EXYNOS4_MCT_G_TCON: 121 stat_addr = EXYNOS4_MCT_G_WSTAT; 122 mask = 1 << 16; /* G_TCON write status */ 123 break; 124 case EXYNOS4_MCT_G_COMP0_L: 125 stat_addr = EXYNOS4_MCT_G_WSTAT; 126 mask = 1 << 0; /* G_COMP0_L write status */ 127 break; 128 case EXYNOS4_MCT_G_COMP0_U: 129 stat_addr = EXYNOS4_MCT_G_WSTAT; 130 mask = 1 << 1; /* G_COMP0_U write status */ 131 break; 132 case EXYNOS4_MCT_G_COMP0_ADD_INCR: 133 stat_addr = EXYNOS4_MCT_G_WSTAT; 134 mask = 1 << 2; /* G_COMP0_ADD_INCR w status */ 135 break; 136 case EXYNOS4_MCT_G_CNT_L: 137 stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; 138 mask = 1 << 0; /* G_CNT_L write status */ 139 break; 140 case EXYNOS4_MCT_G_CNT_U: 141 stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; 142 mask = 1 << 1; /* G_CNT_U write status */ 143 break; 144 default: 145 return; 146 } 147 } 148 149 /* Wait maximum 1 ms until written values are applied */ 150 for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++) 151 if (readl_relaxed(reg_base + stat_addr) & mask) { 152 writel_relaxed(mask, reg_base + stat_addr); 153 return; 154 } 155 156 panic("MCT hangs after writing %d (offset:0x%lx)\n", value, offset); 157 } 158 159 /* Clocksource handling */ 160 static void exynos4_mct_frc_start(void) 161 { 162 u32 reg; 163 164 reg = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON); 165 reg |= MCT_G_TCON_START; 166 exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON); 167 } 168 169 /** 170 * exynos4_read_count_64 - Read all 64-bits of the global counter 171 * 172 * This will read all 64-bits of the global counter taking care to make sure 173 * that the upper and lower half match. Note that reading the MCT can be quite 174 * slow (hundreds of nanoseconds) so you should use the 32-bit (lower half 175 * only) version when possible. 176 * 177 * Returns the number of cycles in the global counter. 178 */ 179 static u64 exynos4_read_count_64(void) 180 { 181 unsigned int lo, hi; 182 u32 hi2 = readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_U); 183 184 do { 185 hi = hi2; 186 lo = readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_L); 187 hi2 = readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_U); 188 } while (hi != hi2); 189 190 return ((u64)hi << 32) | lo; 191 } 192 193 /** 194 * exynos4_read_count_32 - Read the lower 32-bits of the global counter 195 * 196 * This will read just the lower 32-bits of the global counter. This is marked 197 * as notrace so it can be used by the scheduler clock. 198 * 199 * Returns the number of cycles in the global counter (lower 32 bits). 200 */ 201 static u32 notrace exynos4_read_count_32(void) 202 { 203 return readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_L); 204 } 205 206 static u64 exynos4_frc_read(struct clocksource *cs) 207 { 208 return exynos4_read_count_32(); 209 } 210 211 static void exynos4_frc_resume(struct clocksource *cs) 212 { 213 exynos4_mct_frc_start(); 214 } 215 216 static struct clocksource mct_frc = { 217 .name = "mct-frc", 218 .rating = MCT_CLKSOURCE_RATING, 219 .read = exynos4_frc_read, 220 .mask = CLOCKSOURCE_MASK(32), 221 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 222 .resume = exynos4_frc_resume, 223 }; 224 225 static u64 notrace exynos4_read_sched_clock(void) 226 { 227 return exynos4_read_count_32(); 228 } 229 230 #if defined(CONFIG_ARM) 231 static struct delay_timer exynos4_delay_timer; 232 233 static cycles_t exynos4_read_current_timer(void) 234 { 235 BUILD_BUG_ON_MSG(sizeof(cycles_t) != sizeof(u32), 236 "cycles_t needs to move to 32-bit for ARM64 usage"); 237 return exynos4_read_count_32(); 238 } 239 #endif 240 241 static int __init exynos4_clocksource_init(void) 242 { 243 exynos4_mct_frc_start(); 244 245 #if defined(CONFIG_ARM) 246 exynos4_delay_timer.read_current_timer = &exynos4_read_current_timer; 247 exynos4_delay_timer.freq = clk_rate; 248 register_current_timer_delay(&exynos4_delay_timer); 249 #endif 250 251 if (clocksource_register_hz(&mct_frc, clk_rate)) 252 panic("%s: can't register clocksource\n", mct_frc.name); 253 254 sched_clock_register(exynos4_read_sched_clock, 32, clk_rate); 255 256 return 0; 257 } 258 259 static void exynos4_mct_comp0_stop(void) 260 { 261 unsigned int tcon; 262 263 tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON); 264 tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC); 265 266 exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON); 267 exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB); 268 } 269 270 static void exynos4_mct_comp0_start(bool periodic, unsigned long cycles) 271 { 272 unsigned int tcon; 273 u64 comp_cycle; 274 275 tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON); 276 277 if (periodic) { 278 tcon |= MCT_G_TCON_COMP0_AUTO_INC; 279 exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR); 280 } 281 282 comp_cycle = exynos4_read_count_64() + cycles; 283 exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L); 284 exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U); 285 286 exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB); 287 288 tcon |= MCT_G_TCON_COMP0_ENABLE; 289 exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON); 290 } 291 292 static int exynos4_comp_set_next_event(unsigned long cycles, 293 struct clock_event_device *evt) 294 { 295 exynos4_mct_comp0_start(false, cycles); 296 297 return 0; 298 } 299 300 static int mct_set_state_shutdown(struct clock_event_device *evt) 301 { 302 exynos4_mct_comp0_stop(); 303 return 0; 304 } 305 306 static int mct_set_state_periodic(struct clock_event_device *evt) 307 { 308 unsigned long cycles_per_jiffy; 309 310 cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult) 311 >> evt->shift); 312 exynos4_mct_comp0_stop(); 313 exynos4_mct_comp0_start(true, cycles_per_jiffy); 314 return 0; 315 } 316 317 static struct clock_event_device mct_comp_device = { 318 .name = "mct-comp", 319 .features = CLOCK_EVT_FEAT_PERIODIC | 320 CLOCK_EVT_FEAT_ONESHOT, 321 .rating = 250, 322 .set_next_event = exynos4_comp_set_next_event, 323 .set_state_periodic = mct_set_state_periodic, 324 .set_state_shutdown = mct_set_state_shutdown, 325 .set_state_oneshot = mct_set_state_shutdown, 326 .set_state_oneshot_stopped = mct_set_state_shutdown, 327 .tick_resume = mct_set_state_shutdown, 328 }; 329 330 static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id) 331 { 332 struct clock_event_device *evt = dev_id; 333 334 exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT); 335 336 evt->event_handler(evt); 337 338 return IRQ_HANDLED; 339 } 340 341 static int exynos4_clockevent_init(void) 342 { 343 mct_comp_device.cpumask = cpumask_of(0); 344 clockevents_config_and_register(&mct_comp_device, clk_rate, 345 0xf, 0xffffffff); 346 if (request_irq(mct_irqs[MCT_G0_IRQ], exynos4_mct_comp_isr, 347 IRQF_TIMER | IRQF_IRQPOLL, "mct_comp_irq", 348 &mct_comp_device)) 349 pr_err("%s: request_irq() failed\n", "mct_comp_irq"); 350 351 return 0; 352 } 353 354 static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick); 355 356 /* Clock event handling */ 357 static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt) 358 { 359 unsigned long tmp; 360 unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START; 361 unsigned long offset = mevt->base + MCT_L_TCON_OFFSET; 362 363 tmp = readl_relaxed(reg_base + offset); 364 if (tmp & mask) { 365 tmp &= ~mask; 366 exynos4_mct_write(tmp, offset); 367 } 368 } 369 370 static void exynos4_mct_tick_start(unsigned long cycles, 371 struct mct_clock_event_device *mevt) 372 { 373 unsigned long tmp; 374 375 exynos4_mct_tick_stop(mevt); 376 377 tmp = (1 << 31) | cycles; /* MCT_L_UPDATE_ICNTB */ 378 379 /* update interrupt count buffer */ 380 exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET); 381 382 /* enable MCT tick interrupt */ 383 exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET); 384 385 tmp = readl_relaxed(reg_base + mevt->base + MCT_L_TCON_OFFSET); 386 tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START | 387 MCT_L_TCON_INTERVAL_MODE; 388 exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET); 389 } 390 391 static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) 392 { 393 /* Clear the MCT tick interrupt */ 394 if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) 395 exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); 396 } 397 398 static int exynos4_tick_set_next_event(unsigned long cycles, 399 struct clock_event_device *evt) 400 { 401 struct mct_clock_event_device *mevt; 402 403 mevt = container_of(evt, struct mct_clock_event_device, evt); 404 exynos4_mct_tick_start(cycles, mevt); 405 return 0; 406 } 407 408 static int set_state_shutdown(struct clock_event_device *evt) 409 { 410 struct mct_clock_event_device *mevt; 411 412 mevt = container_of(evt, struct mct_clock_event_device, evt); 413 exynos4_mct_tick_stop(mevt); 414 exynos4_mct_tick_clear(mevt); 415 return 0; 416 } 417 418 static int set_state_periodic(struct clock_event_device *evt) 419 { 420 struct mct_clock_event_device *mevt; 421 unsigned long cycles_per_jiffy; 422 423 mevt = container_of(evt, struct mct_clock_event_device, evt); 424 cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult) 425 >> evt->shift); 426 exynos4_mct_tick_stop(mevt); 427 exynos4_mct_tick_start(cycles_per_jiffy, mevt); 428 return 0; 429 } 430 431 static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) 432 { 433 struct mct_clock_event_device *mevt = dev_id; 434 struct clock_event_device *evt = &mevt->evt; 435 436 /* 437 * This is for supporting oneshot mode. 438 * Mct would generate interrupt periodically 439 * without explicit stopping. 440 */ 441 if (!clockevent_state_periodic(&mevt->evt)) 442 exynos4_mct_tick_stop(mevt); 443 444 exynos4_mct_tick_clear(mevt); 445 446 evt->event_handler(evt); 447 448 return IRQ_HANDLED; 449 } 450 451 static int exynos4_mct_starting_cpu(unsigned int cpu) 452 { 453 struct mct_clock_event_device *mevt = 454 per_cpu_ptr(&percpu_mct_tick, cpu); 455 struct clock_event_device *evt = &mevt->evt; 456 457 mevt->base = EXYNOS4_MCT_L_BASE(cpu); 458 snprintf(mevt->name, sizeof(mevt->name), "mct_tick%d", cpu); 459 460 evt->name = mevt->name; 461 evt->cpumask = cpumask_of(cpu); 462 evt->set_next_event = exynos4_tick_set_next_event; 463 evt->set_state_periodic = set_state_periodic; 464 evt->set_state_shutdown = set_state_shutdown; 465 evt->set_state_oneshot = set_state_shutdown; 466 evt->set_state_oneshot_stopped = set_state_shutdown; 467 evt->tick_resume = set_state_shutdown; 468 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | 469 CLOCK_EVT_FEAT_PERCPU; 470 evt->rating = MCT_CLKEVENTS_RATING; 471 472 exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); 473 474 if (mct_int_type == MCT_INT_SPI) { 475 476 if (evt->irq == -1) 477 return -EIO; 478 479 irq_force_affinity(evt->irq, cpumask_of(cpu)); 480 enable_irq(evt->irq); 481 } else { 482 enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); 483 } 484 clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), 485 0xf, 0x7fffffff); 486 487 return 0; 488 } 489 490 static int exynos4_mct_dying_cpu(unsigned int cpu) 491 { 492 struct mct_clock_event_device *mevt = 493 per_cpu_ptr(&percpu_mct_tick, cpu); 494 struct clock_event_device *evt = &mevt->evt; 495 496 evt->set_state_shutdown(evt); 497 if (mct_int_type == MCT_INT_SPI) { 498 if (evt->irq != -1) 499 disable_irq_nosync(evt->irq); 500 exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); 501 } else { 502 disable_percpu_irq(mct_irqs[MCT_L0_IRQ]); 503 } 504 return 0; 505 } 506 507 static int __init exynos4_timer_resources(struct device_node *np) 508 { 509 struct clk *mct_clk, *tick_clk; 510 511 reg_base = of_iomap(np, 0); 512 if (!reg_base) 513 panic("%s: unable to ioremap mct address space\n", __func__); 514 515 tick_clk = of_clk_get_by_name(np, "fin_pll"); 516 if (IS_ERR(tick_clk)) 517 panic("%s: unable to determine tick clock rate\n", __func__); 518 clk_rate = clk_get_rate(tick_clk); 519 520 mct_clk = of_clk_get_by_name(np, "mct"); 521 if (IS_ERR(mct_clk)) 522 panic("%s: unable to retrieve mct clock instance\n", __func__); 523 clk_prepare_enable(mct_clk); 524 525 return 0; 526 } 527 528 static int __init exynos4_timer_interrupts(struct device_node *np, 529 unsigned int int_type) 530 { 531 int nr_irqs, i, err, cpu; 532 533 mct_int_type = int_type; 534 535 /* This driver uses only one global timer interrupt */ 536 mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ); 537 538 /* 539 * Find out the number of local irqs specified. The local 540 * timer irqs are specified after the four global timer 541 * irqs are specified. 542 */ 543 nr_irqs = of_irq_count(np); 544 for (i = MCT_L0_IRQ; i < nr_irqs; i++) 545 mct_irqs[i] = irq_of_parse_and_map(np, i); 546 547 if (mct_int_type == MCT_INT_PPI) { 548 549 err = request_percpu_irq(mct_irqs[MCT_L0_IRQ], 550 exynos4_mct_tick_isr, "MCT", 551 &percpu_mct_tick); 552 WARN(err, "MCT: can't request IRQ %d (%d)\n", 553 mct_irqs[MCT_L0_IRQ], err); 554 } else { 555 for_each_possible_cpu(cpu) { 556 int mct_irq = mct_irqs[MCT_L0_IRQ + cpu]; 557 struct mct_clock_event_device *pcpu_mevt = 558 per_cpu_ptr(&percpu_mct_tick, cpu); 559 560 pcpu_mevt->evt.irq = -1; 561 562 irq_set_status_flags(mct_irq, IRQ_NOAUTOEN); 563 if (request_irq(mct_irq, 564 exynos4_mct_tick_isr, 565 IRQF_TIMER | IRQF_NOBALANCING, 566 pcpu_mevt->name, pcpu_mevt)) { 567 pr_err("exynos-mct: cannot register IRQ (cpu%d)\n", 568 cpu); 569 570 continue; 571 } 572 pcpu_mevt->evt.irq = mct_irq; 573 } 574 } 575 576 /* Install hotplug callbacks which configure the timer on this CPU */ 577 err = cpuhp_setup_state(CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING, 578 "clockevents/exynos4/mct_timer:starting", 579 exynos4_mct_starting_cpu, 580 exynos4_mct_dying_cpu); 581 if (err) 582 goto out_irq; 583 584 return 0; 585 586 out_irq: 587 if (mct_int_type == MCT_INT_PPI) { 588 free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick); 589 } else { 590 for_each_possible_cpu(cpu) { 591 struct mct_clock_event_device *pcpu_mevt = 592 per_cpu_ptr(&percpu_mct_tick, cpu); 593 594 if (pcpu_mevt->evt.irq != -1) { 595 free_irq(pcpu_mevt->evt.irq, pcpu_mevt); 596 pcpu_mevt->evt.irq = -1; 597 } 598 } 599 } 600 return err; 601 } 602 603 static int __init mct_init_dt(struct device_node *np, unsigned int int_type) 604 { 605 int ret; 606 607 ret = exynos4_timer_resources(np); 608 if (ret) 609 return ret; 610 611 ret = exynos4_timer_interrupts(np, int_type); 612 if (ret) 613 return ret; 614 615 ret = exynos4_clocksource_init(); 616 if (ret) 617 return ret; 618 619 return exynos4_clockevent_init(); 620 } 621 622 623 static int __init mct_init_spi(struct device_node *np) 624 { 625 return mct_init_dt(np, MCT_INT_SPI); 626 } 627 628 static int __init mct_init_ppi(struct device_node *np) 629 { 630 return mct_init_dt(np, MCT_INT_PPI); 631 } 632 TIMER_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init_spi); 633 TIMER_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init_ppi); 634