timer-clint.c (00af6729b52ede86a08173c8d5f2c8cd9fa3390d) timer-clint.c (d5be89a8d118a8e8d09cd74a921a808f17fbdd09)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2020 Western Digital Corporation or its affiliates.
4 *
5 * Most of the M-mode (i.e. NoMMU) RISC-V systems usually have a
6 * CLINT MMIO timer device.
7 */
8

--- 5 unchanged lines hidden (view full) ---

14#include <linux/delay.h>
15#include <linux/module.h>
16#include <linux/of_address.h>
17#include <linux/sched_clock.h>
18#include <linux/io-64-nonatomic-lo-hi.h>
19#include <linux/interrupt.h>
20#include <linux/of_irq.h>
21#include <linux/smp.h>
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2020 Western Digital Corporation or its affiliates.
4 *
5 * Most of the M-mode (i.e. NoMMU) RISC-V systems usually have a
6 * CLINT MMIO timer device.
7 */
8

--- 5 unchanged lines hidden (view full) ---

14#include <linux/delay.h>
15#include <linux/module.h>
16#include <linux/of_address.h>
17#include <linux/sched_clock.h>
18#include <linux/io-64-nonatomic-lo-hi.h>
19#include <linux/interrupt.h>
20#include <linux/of_irq.h>
21#include <linux/smp.h>
22#include <linux/timex.h>
22
23
24#ifndef CONFIG_RISCV_M_MODE
25#include <asm/clint.h>
26#endif
27
23#define CLINT_IPI_OFF 0
24#define CLINT_TIMER_CMP_OFF 0x4000
25#define CLINT_TIMER_VAL_OFF 0xbff8
26
27/* CLINT manages IPI and Timer for RISC-V M-mode */
28static u32 __iomem *clint_ipi_base;
29static u64 __iomem *clint_timer_cmp;
30static u64 __iomem *clint_timer_val;
31static unsigned long clint_timer_freq;
32static unsigned int clint_timer_irq;
33
28#define CLINT_IPI_OFF 0
29#define CLINT_TIMER_CMP_OFF 0x4000
30#define CLINT_TIMER_VAL_OFF 0xbff8
31
32/* CLINT manages IPI and Timer for RISC-V M-mode */
33static u32 __iomem *clint_ipi_base;
34static u64 __iomem *clint_timer_cmp;
35static u64 __iomem *clint_timer_val;
36static unsigned long clint_timer_freq;
37static unsigned int clint_timer_irq;
38
39#ifdef CONFIG_RISCV_M_MODE
40u64 __iomem *clint_time_val;
41#endif
42
34static void clint_send_ipi(const struct cpumask *target)
35{
36 unsigned int cpu;
37
38 for_each_cpu(cpu, target)
39 writel(1, clint_ipi_base + cpuid_to_hartid_map(cpu));
40}
41

--- 137 unchanged lines hidden (view full) ---

179 return -ENODEV;
180 }
181
182 clint_ipi_base = base + CLINT_IPI_OFF;
183 clint_timer_cmp = base + CLINT_TIMER_CMP_OFF;
184 clint_timer_val = base + CLINT_TIMER_VAL_OFF;
185 clint_timer_freq = riscv_timebase;
186
43static void clint_send_ipi(const struct cpumask *target)
44{
45 unsigned int cpu;
46
47 for_each_cpu(cpu, target)
48 writel(1, clint_ipi_base + cpuid_to_hartid_map(cpu));
49}
50

--- 137 unchanged lines hidden (view full) ---

188 return -ENODEV;
189 }
190
191 clint_ipi_base = base + CLINT_IPI_OFF;
192 clint_timer_cmp = base + CLINT_TIMER_CMP_OFF;
193 clint_timer_val = base + CLINT_TIMER_VAL_OFF;
194 clint_timer_freq = riscv_timebase;
195
196#ifdef CONFIG_RISCV_M_MODE
197 /*
198 * Yes, that's an odd naming scheme. time_val is public, but hopefully
199 * will die in favor of something cleaner.
200 */
201 clint_time_val = clint_timer_val;
202#endif
203
187 pr_info("%pOFP: timer running at %ld Hz\n", np, clint_timer_freq);
188
189 rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq);
190 if (rc) {
191 pr_err("%pOFP: clocksource register failed [%d]\n", np, rc);
192 goto fail_iounmap;
193 }
194

--- 32 unchanged lines hidden ---
204 pr_info("%pOFP: timer running at %ld Hz\n", np, clint_timer_freq);
205
206 rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq);
207 if (rc) {
208 pr_err("%pOFP: clocksource register failed [%d]\n", np, rc);
209 goto fail_iounmap;
210 }
211

--- 32 unchanged lines hidden ---