summaryrefslogtreecommitdiff
path: root/arch/riscv/kernel/time.c
blob: 23641e82a9df2a244727d9e5b674f8c546299ea2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2012 Regents of the University of California
 * Copyright (C) 2017 SiFive
 */

#include <linux/acpi.h>
#include <linux/of_clk.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/delay.h>
#include <asm/sbi.h>
#include <asm/processor.h>
#include <asm/timex.h>

unsigned long riscv_timebase __ro_after_init;
EXPORT_SYMBOL_GPL(riscv_timebase);

void __init time_init(void)
{
	struct device_node *cpu;
	struct acpi_table_rhct *rhct;
	acpi_status status;
	u32 prop;

	if (acpi_disabled) {
		cpu = of_find_node_by_path("/cpus");
		if (!cpu || of_property_read_u32(cpu, "timebase-frequency", &prop))
			panic("RISC-V system with no 'timebase-frequency' in DTS\n");

		of_node_put(cpu);
		riscv_timebase = prop;
		of_clk_init(NULL);
	} else {
		status = acpi_get_table(ACPI_SIG_RHCT, 0, (struct acpi_table_header **)&rhct);
		if (ACPI_FAILURE(status))
			panic("RISC-V ACPI system with no RHCT table\n");

		riscv_timebase = rhct->time_base_freq;
		acpi_put_table((struct acpi_table_header *)rhct);
	}

	lpj_fine = riscv_timebase / HZ;

	timer_probe();

	tick_setup_hrtimer_broadcast();
}