Loading Documentation/devicetree/bindings/arm/arch_timer.txt 0 → 100644 +27 −0 Original line number Diff line number Diff line * ARM architected timer ARM Cortex-A7 and Cortex-A15 have a per-core architected timer, which provides per-cpu timers. The timer is attached to a GIC to deliver its per-processor interrupts. ** Timer node properties: - compatible : Should at least contain "arm,armv7-timer". - interrupts : Interrupt list for secure, non-secure, virtual and hypervisor timers, in that order. - clock-frequency : The frequency of the main counter, in Hz. Optional. Example: timer { compatible = "arm,cortex-a15-timer", "arm,armv7-timer"; interrupts = <1 13 0xf08>, <1 14 0xf08>, <1 11 0xf08>, <1 10 0xf08>; clock-frequency = <100000000>; }; arch/arm/include/asm/arch_timer.h +6 −0 Original line number Diff line number Diff line Loading @@ -10,12 +10,18 @@ struct arch_timer { #ifdef CONFIG_ARM_ARCH_TIMER int arch_timer_register(struct arch_timer *); int arch_timer_sched_clock_init(void); int arch_timer_of_register(void); #else static inline int arch_timer_register(struct arch_timer *at) { return -ENXIO; } static inline int arch_timer_of_register(void) { return -ENXIO; } static inline int arch_timer_sched_clock_init(void) { return -ENXIO; Loading arch/arm/kernel/arch_timer.c +46 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/jiffies.h> #include <linux/clockchips.h> #include <linux/interrupt.h> #include <linux/of_irq.h> #include <linux/io.h> #include <asm/cputype.h> Loading Loading @@ -245,13 +246,10 @@ static struct local_timer_ops arch_timer_ops __cpuinitdata = { .stop = arch_timer_stop, }; int __init arch_timer_register(struct arch_timer *at) static int __init arch_timer_common_register(void) { int err; if (at->res[0].start <= 0 || !(at->res[0].flags & IORESOURCE_IRQ)) return -EINVAL; err = arch_timer_available(); if (err) return err; Loading @@ -262,7 +260,6 @@ int __init arch_timer_register(struct arch_timer *at) clocksource_register_hz(&clocksource_counter, arch_timer_rate); arch_timer_ppi = at->res[0].start; err = request_percpu_irq(arch_timer_ppi, arch_timer_handler, "arch_timer", arch_timer_evt); if (err) { Loading @@ -271,8 +268,7 @@ int __init arch_timer_register(struct arch_timer *at) goto out_free; } if (at->res[1].start > 0 || (at->res[1].flags & IORESOURCE_IRQ)) { arch_timer_ppi2 = at->res[1].start; if (arch_timer_ppi2) { err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler, "arch_timer", arch_timer_evt); if (err) { Loading Loading @@ -300,6 +296,49 @@ int __init arch_timer_register(struct arch_timer *at) return err; } int __init arch_timer_register(struct arch_timer *at) { if (at->res[0].start <= 0 || !(at->res[0].flags & IORESOURCE_IRQ)) return -EINVAL; arch_timer_ppi = at->res[0].start; if (at->res[1].start > 0 || (at->res[1].flags & IORESOURCE_IRQ)) arch_timer_ppi2 = at->res[1].start; return arch_timer_common_register(); } #ifdef CONFIG_OF static const struct of_device_id arch_timer_of_match[] __initconst = { { .compatible = "arm,armv7-timer", }, {}, }; int __init arch_timer_of_register(void) { struct device_node *np; u32 freq; np = of_find_matching_node(NULL, arch_timer_of_match); if (!np) { pr_err("arch_timer: can't find DT node\n"); return -ENODEV; } /* Try to determine the frequency from the device tree or CNTFRQ */ if (!of_property_read_u32(np, "clock-frequency", &freq)) arch_timer_rate = freq; arch_timer_ppi = irq_of_parse_and_map(np, 0); arch_timer_ppi2 = irq_of_parse_and_map(np, 1); pr_info("arch_timer: found %s irqs %d %d\n", np->name, arch_timer_ppi, arch_timer_ppi2); return arch_timer_common_register(); } #endif int __init arch_timer_sched_clock_init(void) { int err; Loading Loading
Documentation/devicetree/bindings/arm/arch_timer.txt 0 → 100644 +27 −0 Original line number Diff line number Diff line * ARM architected timer ARM Cortex-A7 and Cortex-A15 have a per-core architected timer, which provides per-cpu timers. The timer is attached to a GIC to deliver its per-processor interrupts. ** Timer node properties: - compatible : Should at least contain "arm,armv7-timer". - interrupts : Interrupt list for secure, non-secure, virtual and hypervisor timers, in that order. - clock-frequency : The frequency of the main counter, in Hz. Optional. Example: timer { compatible = "arm,cortex-a15-timer", "arm,armv7-timer"; interrupts = <1 13 0xf08>, <1 14 0xf08>, <1 11 0xf08>, <1 10 0xf08>; clock-frequency = <100000000>; };
arch/arm/include/asm/arch_timer.h +6 −0 Original line number Diff line number Diff line Loading @@ -10,12 +10,18 @@ struct arch_timer { #ifdef CONFIG_ARM_ARCH_TIMER int arch_timer_register(struct arch_timer *); int arch_timer_sched_clock_init(void); int arch_timer_of_register(void); #else static inline int arch_timer_register(struct arch_timer *at) { return -ENXIO; } static inline int arch_timer_of_register(void) { return -ENXIO; } static inline int arch_timer_sched_clock_init(void) { return -ENXIO; Loading
arch/arm/kernel/arch_timer.c +46 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/jiffies.h> #include <linux/clockchips.h> #include <linux/interrupt.h> #include <linux/of_irq.h> #include <linux/io.h> #include <asm/cputype.h> Loading Loading @@ -245,13 +246,10 @@ static struct local_timer_ops arch_timer_ops __cpuinitdata = { .stop = arch_timer_stop, }; int __init arch_timer_register(struct arch_timer *at) static int __init arch_timer_common_register(void) { int err; if (at->res[0].start <= 0 || !(at->res[0].flags & IORESOURCE_IRQ)) return -EINVAL; err = arch_timer_available(); if (err) return err; Loading @@ -262,7 +260,6 @@ int __init arch_timer_register(struct arch_timer *at) clocksource_register_hz(&clocksource_counter, arch_timer_rate); arch_timer_ppi = at->res[0].start; err = request_percpu_irq(arch_timer_ppi, arch_timer_handler, "arch_timer", arch_timer_evt); if (err) { Loading @@ -271,8 +268,7 @@ int __init arch_timer_register(struct arch_timer *at) goto out_free; } if (at->res[1].start > 0 || (at->res[1].flags & IORESOURCE_IRQ)) { arch_timer_ppi2 = at->res[1].start; if (arch_timer_ppi2) { err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler, "arch_timer", arch_timer_evt); if (err) { Loading Loading @@ -300,6 +296,49 @@ int __init arch_timer_register(struct arch_timer *at) return err; } int __init arch_timer_register(struct arch_timer *at) { if (at->res[0].start <= 0 || !(at->res[0].flags & IORESOURCE_IRQ)) return -EINVAL; arch_timer_ppi = at->res[0].start; if (at->res[1].start > 0 || (at->res[1].flags & IORESOURCE_IRQ)) arch_timer_ppi2 = at->res[1].start; return arch_timer_common_register(); } #ifdef CONFIG_OF static const struct of_device_id arch_timer_of_match[] __initconst = { { .compatible = "arm,armv7-timer", }, {}, }; int __init arch_timer_of_register(void) { struct device_node *np; u32 freq; np = of_find_matching_node(NULL, arch_timer_of_match); if (!np) { pr_err("arch_timer: can't find DT node\n"); return -ENODEV; } /* Try to determine the frequency from the device tree or CNTFRQ */ if (!of_property_read_u32(np, "clock-frequency", &freq)) arch_timer_rate = freq; arch_timer_ppi = irq_of_parse_and_map(np, 0); arch_timer_ppi2 = irq_of_parse_and_map(np, 1); pr_info("arch_timer: found %s irqs %d %d\n", np->name, arch_timer_ppi, arch_timer_ppi2); return arch_timer_common_register(); } #endif int __init arch_timer_sched_clock_init(void) { int err; Loading