hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/clocksource/exynos_mct.c
....@@ -1,23 +1,18 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* linux/arch/arm/mach-exynos4/mct.c
23 *
34 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
45 * http://www.samsung.com
56 *
6
- * EXYNOS4 MCT(Multi-Core Timer) support
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License version 2 as
10
- * published by the Free Software Foundation.
7
+ * Exynos4 MCT(Multi-Core Timer) support
118 */
129
13
-#include <linux/sched.h>
1410 #include <linux/interrupt.h>
1511 #include <linux/irq.h>
1612 #include <linux/err.h>
1713 #include <linux/clk.h>
1814 #include <linux/clockchips.h>
1915 #include <linux/cpu.h>
20
-#include <linux/platform_device.h>
2116 #include <linux/delay.h>
2217 #include <linux/percpu.h>
2318 #include <linux/of.h>
....@@ -334,19 +329,15 @@
334329 return IRQ_HANDLED;
335330 }
336331
337
-static struct irqaction mct_comp_event_irq = {
338
- .name = "mct_comp_irq",
339
- .flags = IRQF_TIMER | IRQF_IRQPOLL,
340
- .handler = exynos4_mct_comp_isr,
341
- .dev_id = &mct_comp_device,
342
-};
343
-
344332 static int exynos4_clockevent_init(void)
345333 {
346334 mct_comp_device.cpumask = cpumask_of(0);
347335 clockevents_config_and_register(&mct_comp_device, clk_rate,
348336 0xf, 0xffffffff);
349
- setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq);
337
+ if (request_irq(mct_irqs[MCT_G0_IRQ], exynos4_mct_comp_isr,
338
+ IRQF_TIMER | IRQF_IRQPOLL, "mct_comp_irq",
339
+ &mct_comp_device))
340
+ pr_err("%s: request_irq() failed\n", "mct_comp_irq");
350341
351342 return 0;
352343 }
....@@ -503,25 +494,50 @@
503494 return 0;
504495 }
505496
506
-static int __init exynos4_timer_resources(struct device_node *np, void __iomem *base)
497
+static int __init exynos4_timer_resources(struct device_node *np)
507498 {
508
- int err, cpu;
509499 struct clk *mct_clk, *tick_clk;
510500
511
- tick_clk = np ? of_clk_get_by_name(np, "fin_pll") :
512
- clk_get(NULL, "fin_pll");
501
+ reg_base = of_iomap(np, 0);
502
+ if (!reg_base)
503
+ panic("%s: unable to ioremap mct address space\n", __func__);
504
+
505
+ tick_clk = of_clk_get_by_name(np, "fin_pll");
513506 if (IS_ERR(tick_clk))
514507 panic("%s: unable to determine tick clock rate\n", __func__);
515508 clk_rate = clk_get_rate(tick_clk);
516509
517
- mct_clk = np ? of_clk_get_by_name(np, "mct") : clk_get(NULL, "mct");
510
+ mct_clk = of_clk_get_by_name(np, "mct");
518511 if (IS_ERR(mct_clk))
519512 panic("%s: unable to retrieve mct clock instance\n", __func__);
520513 clk_prepare_enable(mct_clk);
521514
522
- reg_base = base;
523
- if (!reg_base)
524
- panic("%s: unable to ioremap mct address space\n", __func__);
515
+ return 0;
516
+}
517
+
518
+static int __init exynos4_timer_interrupts(struct device_node *np,
519
+ unsigned int int_type)
520
+{
521
+ int nr_irqs, i, err, cpu;
522
+
523
+ mct_int_type = int_type;
524
+
525
+ /* This driver uses only one global timer interrupt */
526
+ mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ);
527
+
528
+ /*
529
+ * Find out the number of local irqs specified. The local
530
+ * timer irqs are specified after the four global timer
531
+ * irqs are specified.
532
+ */
533
+ nr_irqs = of_irq_count(np);
534
+ if (nr_irqs > ARRAY_SIZE(mct_irqs)) {
535
+ pr_err("exynos-mct: too many (%d) interrupts configured in DT\n",
536
+ nr_irqs);
537
+ nr_irqs = ARRAY_SIZE(mct_irqs);
538
+ }
539
+ for (i = MCT_L0_IRQ; i < nr_irqs; i++)
540
+ mct_irqs[i] = irq_of_parse_and_map(np, i);
525541
526542 if (mct_int_type == MCT_INT_PPI) {
527543
....@@ -532,11 +548,14 @@
532548 mct_irqs[MCT_L0_IRQ], err);
533549 } else {
534550 for_each_possible_cpu(cpu) {
535
- int mct_irq = mct_irqs[MCT_L0_IRQ + cpu];
551
+ int mct_irq;
536552 struct mct_clock_event_device *pcpu_mevt =
537553 per_cpu_ptr(&percpu_mct_tick, cpu);
538554
539555 pcpu_mevt->evt.irq = -1;
556
+ if (MCT_L0_IRQ + cpu >= ARRAY_SIZE(mct_irqs))
557
+ break;
558
+ mct_irq = mct_irqs[MCT_L0_IRQ + cpu];
540559
541560 irq_set_status_flags(mct_irq, IRQ_NOAUTOEN);
542561 if (request_irq(mct_irq,
....@@ -581,28 +600,13 @@
581600
582601 static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
583602 {
584
- u32 nr_irqs, i;
585603 int ret;
586604
587
- mct_int_type = int_type;
605
+ ret = exynos4_timer_resources(np);
606
+ if (ret)
607
+ return ret;
588608
589
- /* This driver uses only one global timer interrupt */
590
- mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ);
591
-
592
- /*
593
- * Find out the number of local irqs specified. The local
594
- * timer irqs are specified after the four global timer
595
- * irqs are specified.
596
- */
597
-#ifdef CONFIG_OF
598
- nr_irqs = of_irq_count(np);
599
-#else
600
- nr_irqs = 0;
601
-#endif
602
- for (i = MCT_L0_IRQ; i < nr_irqs; i++)
603
- mct_irqs[i] = irq_of_parse_and_map(np, i);
604
-
605
- ret = exynos4_timer_resources(np, of_iomap(np, 0));
609
+ ret = exynos4_timer_interrupts(np, int_type);
606610 if (ret)
607611 return ret;
608612