sparc64: broken %tick frequency on spitfire cpus

After early boot time stamps project the %tick frequency is detected
incorrectly on spittfire cpus.

We must use cpuid of boot cpu to find corresponding cpu node in OpenBoot,
and extract clock-frequency property from there.

Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Pavel Tatashin 2017-06-15 10:40:59 -04:00 committed by David S. Miller
parent fca4afe400
commit eea9833453

View File

@ -162,9 +162,34 @@ static unsigned long tick_add_tick(unsigned long adj)
return new_tick;
}
/* Searches for cpu clock frequency with given cpuid in OpenBoot tree */
static unsigned long cpuid_to_freq(phandle node, int cpuid)
{
bool is_cpu_node = false;
unsigned long freq = 0;
char type[128];
if (!node)
return freq;
if (prom_getproperty(node, "device_type", type, sizeof(type)) != -1)
is_cpu_node = (strcmp(type, "cpu") == 0);
/* try upa-portis then cpuid to get cpuid, see prom_64.c */
if (is_cpu_node && (prom_getint(node, "upa-portis") == cpuid ||
prom_getint(node, "cpuid") == cpuid))
freq = prom_getintdefault(node, "clock-frequency", 0);
if (!freq)
freq = cpuid_to_freq(prom_getchild(node), cpuid);
if (!freq)
freq = cpuid_to_freq(prom_getsibling(node), cpuid);
return freq;
}
static unsigned long tick_get_frequency(void)
{
return local_cpu_data().clock_tick;
return cpuid_to_freq(prom_root_node, hard_smp_processor_id());
}
static struct sparc64_tick_ops tick_operations __cacheline_aligned = {