You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'clockevents/4.12' of https://git.linaro.org/people/daniel.lezcano/linux into timers/core
Pull clockevents updates from Daniel Lezcano - Provide a framework to handle errata gracefuly for arm_arch_timer (Mark Zyngier) - Clarify the DT properties for the rockchip timer and add the clocksource as an alternative to the bogus architected timer (Alexander Kochetkov) - Rename the Gemini timer to Faraday timer fttmr010 and provide a specific initialization for Gemini (Linus Walleij) - Add missing newlines in the error message in the timers (Rafał Miłecki) - Read the clock once and implement the delay timer on Orion (Russell King)
This commit is contained in:
@@ -54,6 +54,7 @@ stable kernels.
|
||||
| ARM | Cortex-A57 | #852523 | N/A |
|
||||
| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
|
||||
| ARM | Cortex-A72 | #853709 | N/A |
|
||||
| ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
|
||||
| ARM | MMU-500 | #841119,#826419 | N/A |
|
||||
| | | | |
|
||||
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
Cortina Systems Gemini timer
|
||||
|
||||
This timer is embedded in the Cortina Systems Gemini SoCs.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : Must be "cortina,gemini-timer"
|
||||
- reg : Should contain registers location and length
|
||||
- interrupts : Should contain the three timer interrupts with
|
||||
flags for rising edge
|
||||
- syscon : a phandle to the global Gemini system controller
|
||||
|
||||
Example:
|
||||
|
||||
timer@43000000 {
|
||||
compatible = "cortina,gemini-timer";
|
||||
reg = <0x43000000 0x1000>;
|
||||
interrupts = <14 IRQ_TYPE_EDGE_RISING>, /* Timer 1 */
|
||||
<15 IRQ_TYPE_EDGE_RISING>, /* Timer 2 */
|
||||
<16 IRQ_TYPE_EDGE_RISING>; /* Timer 3 */
|
||||
syscon = <&syscon>;
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
Faraday Technology timer
|
||||
|
||||
This timer is a generic IP block from Faraday Technology, embedded in the
|
||||
Cortina Systems Gemini SoCs and other designs.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : Must be one of
|
||||
"faraday,fttmr010"
|
||||
"cortina,gemini-timer"
|
||||
- reg : Should contain registers location and length
|
||||
- interrupts : Should contain the three timer interrupts usually with
|
||||
flags for falling edge
|
||||
|
||||
Optionally required properties:
|
||||
|
||||
- clocks : a clock to provide the tick rate for "faraday,fttmr010"
|
||||
- clock-names : should be "EXTCLK" and "PCLK" for the external tick timer
|
||||
and peripheral clock respectively, for "faraday,fttmr010"
|
||||
- syscon : a phandle to the global Gemini system controller if the compatible
|
||||
type is "cortina,gemini-timer"
|
||||
|
||||
Example:
|
||||
|
||||
timer@43000000 {
|
||||
compatible = "faraday,fttmr010";
|
||||
reg = <0x43000000 0x1000>;
|
||||
interrupts = <14 IRQ_TYPE_EDGE_FALLING>, /* Timer 1 */
|
||||
<15 IRQ_TYPE_EDGE_FALLING>, /* Timer 2 */
|
||||
<16 IRQ_TYPE_EDGE_FALLING>; /* Timer 3 */
|
||||
clocks = <&extclk>, <&pclk>;
|
||||
clock-names = "EXTCLK", "PCLK";
|
||||
};
|
||||
@@ -1,9 +1,15 @@
|
||||
Rockchip rk timer
|
||||
|
||||
Required properties:
|
||||
- compatible: shall be one of:
|
||||
"rockchip,rk3288-timer" - for rk3066, rk3036, rk3188, rk322x, rk3288, rk3368
|
||||
"rockchip,rk3399-timer" - for rk3399
|
||||
- compatible: should be:
|
||||
"rockchip,rk3036-timer", "rockchip,rk3288-timer": for Rockchip RK3036
|
||||
"rockchip,rk3066-timer", "rockchip,rk3288-timer": for Rockchip RK3066
|
||||
"rockchip,rk3188-timer", "rockchip,rk3288-timer": for Rockchip RK3188
|
||||
"rockchip,rk3228-timer", "rockchip,rk3288-timer": for Rockchip RK3228
|
||||
"rockchip,rk3229-timer", "rockchip,rk3288-timer": for Rockchip RK3229
|
||||
"rockchip,rk3288-timer": for Rockchip RK3288
|
||||
"rockchip,rk3368-timer", "rockchip,rk3288-timer": for Rockchip RK3368
|
||||
"rockchip,rk3399-timer": for Rockchip RK3399
|
||||
- reg: base address of the timer register starting with TIMERS CONTROL register
|
||||
- interrupts: should contain the interrupts for Timer0
|
||||
- clocks : must contain an entry for each entry in clock-names
|
||||
|
||||
@@ -106,6 +106,22 @@
|
||||
};
|
||||
};
|
||||
|
||||
timer3: timer@2000e000 {
|
||||
compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer";
|
||||
reg = <0x2000e000 0x20>;
|
||||
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru SCLK_TIMER3>, <&cru PCLK_TIMER3>;
|
||||
clock-names = "timer", "pclk";
|
||||
};
|
||||
|
||||
timer6: timer@200380a0 {
|
||||
compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer";
|
||||
reg = <0x200380a0 0x20>;
|
||||
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru SCLK_TIMER6>, <&cru PCLK_TIMER0>;
|
||||
clock-names = "timer", "pclk";
|
||||
};
|
||||
|
||||
i2s0: i2s@1011a000 {
|
||||
compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s";
|
||||
reg = <0x1011a000 0x2000>;
|
||||
@@ -530,6 +546,7 @@
|
||||
|
||||
&global_timer {
|
||||
interrupts = <GIC_PPI 11 0xf04>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&local_timer {
|
||||
|
||||
@@ -325,7 +325,7 @@
|
||||
};
|
||||
|
||||
timer: timer@110c0000 {
|
||||
compatible = "rockchip,rk3288-timer";
|
||||
compatible = "rockchip,rk3228-timer", "rockchip,rk3288-timer";
|
||||
reg = <0x110c0000 0x20>;
|
||||
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&xin24m>, <&cru PCLK_TIMER>;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/bug.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <clocksource/arm_arch_timer.h>
|
||||
@@ -37,24 +38,44 @@ extern struct static_key_false arch_timer_read_ool_enabled;
|
||||
#define needs_unstable_timer_counter_workaround() false
|
||||
#endif
|
||||
|
||||
enum arch_timer_erratum_match_type {
|
||||
ate_match_dt,
|
||||
ate_match_local_cap_id,
|
||||
ate_match_acpi_oem_info,
|
||||
};
|
||||
|
||||
struct clock_event_device;
|
||||
|
||||
struct arch_timer_erratum_workaround {
|
||||
const char *id; /* Indicate the Erratum ID */
|
||||
enum arch_timer_erratum_match_type match_type;
|
||||
const void *id;
|
||||
const char *desc;
|
||||
u32 (*read_cntp_tval_el0)(void);
|
||||
u32 (*read_cntv_tval_el0)(void);
|
||||
u64 (*read_cntvct_el0)(void);
|
||||
int (*set_next_event_phys)(unsigned long, struct clock_event_device *);
|
||||
int (*set_next_event_virt)(unsigned long, struct clock_event_device *);
|
||||
};
|
||||
|
||||
extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround;
|
||||
DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
|
||||
timer_unstable_counter_workaround);
|
||||
|
||||
#define arch_timer_reg_read_stable(reg) \
|
||||
({ \
|
||||
u64 _val; \
|
||||
if (needs_unstable_timer_counter_workaround()) \
|
||||
_val = timer_unstable_counter_workaround->read_##reg();\
|
||||
else \
|
||||
_val = read_sysreg(reg); \
|
||||
_val; \
|
||||
#define arch_timer_reg_read_stable(reg) \
|
||||
({ \
|
||||
u64 _val; \
|
||||
if (needs_unstable_timer_counter_workaround()) { \
|
||||
const struct arch_timer_erratum_workaround *wa; \
|
||||
preempt_disable(); \
|
||||
wa = __this_cpu_read(timer_unstable_counter_workaround); \
|
||||
if (wa && wa->read_##reg) \
|
||||
_val = wa->read_##reg(); \
|
||||
else \
|
||||
_val = read_sysreg(reg); \
|
||||
preempt_enable(); \
|
||||
} else { \
|
||||
_val = read_sysreg(reg); \
|
||||
} \
|
||||
_val; \
|
||||
})
|
||||
|
||||
/*
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
#define ARM64_HAS_NO_FPSIMD 16
|
||||
#define ARM64_WORKAROUND_REPEAT_TLBI 17
|
||||
#define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18
|
||||
#define ARM64_WORKAROUND_858921 19
|
||||
|
||||
#define ARM64_NCAPS 19
|
||||
#define ARM64_NCAPS 20
|
||||
|
||||
#endif /* __ASM_CPUCAPS_H */
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
#define ARM_CPU_PART_FOUNDATION 0xD00
|
||||
#define ARM_CPU_PART_CORTEX_A57 0xD07
|
||||
#define ARM_CPU_PART_CORTEX_A53 0xD03
|
||||
#define ARM_CPU_PART_CORTEX_A73 0xD09
|
||||
|
||||
#define APM_CPU_PART_POTENZA 0x000
|
||||
|
||||
@@ -92,6 +93,7 @@
|
||||
|
||||
#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
|
||||
#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
|
||||
#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
|
||||
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
||||
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
|
||||
#define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1)
|
||||
|
||||
@@ -175,6 +175,8 @@
|
||||
#define ESR_ELx_SYS64_ISS_SYS_CTR_READ (ESR_ELx_SYS64_ISS_SYS_CTR | \
|
||||
ESR_ELx_SYS64_ISS_DIR_READ)
|
||||
|
||||
#define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \
|
||||
ESR_ELx_SYS64_ISS_DIR_READ)
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/types.h>
|
||||
|
||||
|
||||
@@ -53,6 +53,13 @@ static int cpu_enable_trap_ctr_access(void *__unused)
|
||||
.midr_range_min = min, \
|
||||
.midr_range_max = max
|
||||
|
||||
#define MIDR_ALL_VERSIONS(model) \
|
||||
.def_scope = SCOPE_LOCAL_CPU, \
|
||||
.matches = is_affected_midr_range, \
|
||||
.midr_model = model, \
|
||||
.midr_range_min = 0, \
|
||||
.midr_range_max = (MIDR_VARIANT_MASK | MIDR_REVISION_MASK)
|
||||
|
||||
const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
#if defined(CONFIG_ARM64_ERRATUM_826319) || \
|
||||
defined(CONFIG_ARM64_ERRATUM_827319) || \
|
||||
@@ -150,6 +157,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
MIDR_CPU_VAR_REV(0, 0),
|
||||
MIDR_CPU_VAR_REV(0, 0)),
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_ERRATUM_858921
|
||||
{
|
||||
/* Cortex-A73 all versions */
|
||||
.desc = "ARM erratum 858921",
|
||||
.capability = ARM64_WORKAROUND_858921,
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
|
||||
},
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1090,20 +1090,29 @@ static void __init setup_feature_capabilities(void)
|
||||
* Check if the current CPU has a given feature capability.
|
||||
* Should be called from non-preemptible context.
|
||||
*/
|
||||
bool this_cpu_has_cap(unsigned int cap)
|
||||
static bool __this_cpu_has_cap(const struct arm64_cpu_capabilities *cap_array,
|
||||
unsigned int cap)
|
||||
{
|
||||
const struct arm64_cpu_capabilities *caps;
|
||||
|
||||
if (WARN_ON(preemptible()))
|
||||
return false;
|
||||
|
||||
for (caps = arm64_features; caps->desc; caps++)
|
||||
for (caps = cap_array; caps->desc; caps++)
|
||||
if (caps->capability == cap && caps->matches)
|
||||
return caps->matches(caps, SCOPE_LOCAL_CPU);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
extern const struct arm64_cpu_capabilities arm64_errata[];
|
||||
|
||||
bool this_cpu_has_cap(unsigned int cap)
|
||||
{
|
||||
return (__this_cpu_has_cap(arm64_features, cap) ||
|
||||
__this_cpu_has_cap(arm64_errata, cap));
|
||||
}
|
||||
|
||||
void __init setup_cpu_features(void)
|
||||
{
|
||||
u32 cwg;
|
||||
|
||||
@@ -505,6 +505,14 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs)
|
||||
regs->pc += 4;
|
||||
}
|
||||
|
||||
static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
|
||||
{
|
||||
int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
|
||||
|
||||
pt_regs_write_reg(regs, rt, arch_counter_get_cntvct());
|
||||
regs->pc += 4;
|
||||
}
|
||||
|
||||
struct sys64_hook {
|
||||
unsigned int esr_mask;
|
||||
unsigned int esr_val;
|
||||
@@ -523,6 +531,12 @@ static struct sys64_hook sys64_hooks[] = {
|
||||
.esr_val = ESR_ELx_SYS64_ISS_SYS_CTR_READ,
|
||||
.handler = ctr_read_handler,
|
||||
},
|
||||
{
|
||||
/* Trap read access to CNTVCT_EL0 */
|
||||
.esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK,
|
||||
.esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCT,
|
||||
.handler = cntvct_read_handler,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
@@ -67,20 +67,22 @@ config DW_APB_TIMER_OF
|
||||
select DW_APB_TIMER
|
||||
select CLKSRC_OF
|
||||
|
||||
config GEMINI_TIMER
|
||||
bool "Cortina Gemini timer driver" if COMPILE_TEST
|
||||
config FTTMR010_TIMER
|
||||
bool "Faraday Technology timer driver" if COMPILE_TEST
|
||||
depends on GENERIC_CLOCKEVENTS
|
||||
depends on HAS_IOMEM
|
||||
select CLKSRC_MMIO
|
||||
select CLKSRC_OF
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Enables support for the Gemini timer
|
||||
Enables support for the Faraday Technology timer block
|
||||
FTTMR010.
|
||||
|
||||
config ROCKCHIP_TIMER
|
||||
bool "Rockchip timer driver" if COMPILE_TEST
|
||||
depends on ARM || ARM64
|
||||
select CLKSRC_OF
|
||||
select CLKSRC_MMIO
|
||||
help
|
||||
Enables the support for the rockchip timer driver.
|
||||
|
||||
@@ -366,6 +368,17 @@ config HISILICON_ERRATUM_161010101
|
||||
161010101. The workaround will be active if the hisilicon,erratum-161010101
|
||||
property is found in the timer node.
|
||||
|
||||
config ARM64_ERRATUM_858921
|
||||
bool "Workaround for Cortex-A73 erratum 858921"
|
||||
default y
|
||||
select ARM_ARCH_TIMER_OOL_WORKAROUND
|
||||
depends on ARM_ARCH_TIMER && ARM64
|
||||
help
|
||||
This option enables a workaround applicable to Cortex-A73
|
||||
(all versions), whose counter may return incorrect values.
|
||||
The workaround will be dynamically enabled when an affected
|
||||
core is detected.
|
||||
|
||||
config ARM_GLOBAL_TIMER
|
||||
bool "Support for the ARM global timer" if COMPILE_TEST
|
||||
select CLKSRC_OF if OF
|
||||
|
||||
@@ -17,7 +17,7 @@ obj-$(CONFIG_CLKSRC_MMIO) += mmio.o
|
||||
obj-$(CONFIG_DIGICOLOR_TIMER) += timer-digicolor.o
|
||||
obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
|
||||
obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o
|
||||
obj-$(CONFIG_GEMINI_TIMER) += timer-gemini.o
|
||||
obj-$(CONFIG_FTTMR010_TIMER) += timer-fttmr010.o
|
||||
obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
|
||||
obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o
|
||||
obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
|
||||
|
||||
@@ -37,7 +37,7 @@ static int noinline arc_get_timer_clk(struct device_node *node)
|
||||
|
||||
clk = of_clk_get(node, 0);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("timer missing clk");
|
||||
pr_err("timer missing clk\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ static int __init arc_cs_setup_gfrc(struct device_node *node)
|
||||
|
||||
READ_BCR(ARC_REG_MCIP_BCR, mp);
|
||||
if (!mp.gfrc) {
|
||||
pr_warn("Global-64-bit-Ctr clocksource not detected");
|
||||
pr_warn("Global-64-bit-Ctr clocksource not detected\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@@ -140,13 +140,13 @@ static int __init arc_cs_setup_rtc(struct device_node *node)
|
||||
|
||||
READ_BCR(ARC_REG_TIMERS_BCR, timer);
|
||||
if (!timer.rtc) {
|
||||
pr_warn("Local-64-bit-Ctr clocksource not detected");
|
||||
pr_warn("Local-64-bit-Ctr clocksource not detected\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Local to CPU hence not usable in SMP */
|
||||
if (IS_ENABLED(CONFIG_SMP)) {
|
||||
pr_warn("Local-64-bit-Ctr not usable in SMP");
|
||||
pr_warn("Local-64-bit-Ctr not usable in SMP\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -290,13 +290,13 @@ static int __init arc_clockevent_setup(struct device_node *node)
|
||||
|
||||
arc_timer_irq = irq_of_parse_and_map(node, 0);
|
||||
if (arc_timer_irq <= 0) {
|
||||
pr_err("clockevent: missing irq");
|
||||
pr_err("clockevent: missing irq\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = arc_get_timer_clk(node);
|
||||
if (ret) {
|
||||
pr_err("clockevent: missing clk");
|
||||
pr_err("clockevent: missing clk\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ static int __init arc_clockevent_setup(struct device_node *node)
|
||||
arc_timer_starting_cpu,
|
||||
arc_timer_dying_cpu);
|
||||
if (ret) {
|
||||
pr_err("Failed to setup hotplug state");
|
||||
pr_err("Failed to setup hotplug state\n");
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -193,7 +193,7 @@ static int __init asm9260_timer_init(struct device_node *np)
|
||||
|
||||
priv.base = of_io_request_and_map(np, 0, np->name);
|
||||
if (IS_ERR(priv.base)) {
|
||||
pr_err("%s: unable to map resource", np->name);
|
||||
pr_err("%s: unable to map resource\n", np->name);
|
||||
return PTR_ERR(priv.base);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,13 +89,13 @@ static int __init bcm2835_timer_init(struct device_node *node)
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("Can't remap registers");
|
||||
pr_err("Can't remap registers\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "clock-frequency", &freq);
|
||||
if (ret) {
|
||||
pr_err("Can't read clock-frequency");
|
||||
pr_err("Can't read clock-frequency\n");
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ static int __init bcm2835_timer_init(struct device_node *node)
|
||||
|
||||
irq = irq_of_parse_and_map(node, DEFAULT_TIMER);
|
||||
if (irq <= 0) {
|
||||
pr_err("Can't parse IRQ");
|
||||
pr_err("Can't parse IRQ\n");
|
||||
ret = -EINVAL;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ static int __init kona_timer_init(struct device_node *node)
|
||||
} else if (!of_property_read_u32(node, "clock-frequency", &freq)) {
|
||||
arch_timer_rate = freq;
|
||||
} else {
|
||||
pr_err("Kona Timer v1 unable to determine clock-frequency");
|
||||
pr_err("Kona Timer v1 unable to determine clock-frequency\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user