Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * @file timer_int.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * @remark Copyright 2002 OProfile authors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * @remark Read the file COPYING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * @author John Levon <levon@movementarian.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/oprofile.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/profile.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/hrtimer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/irq_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "oprof.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static DEFINE_PER_CPU(struct hrtimer, oprofile_hrtimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static int ctr_running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static enum hrtimer_restart oprofile_hrtimer_notify(struct hrtimer *hrtimer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	oprofile_add_sample(get_irq_regs(), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	hrtimer_forward_now(hrtimer, ns_to_ktime(TICK_NSEC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	return HRTIMER_RESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static void __oprofile_hrtimer_start(void *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct hrtimer *hrtimer = this_cpu_ptr(&oprofile_hrtimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	if (!ctr_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	hrtimer->function = oprofile_hrtimer_notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	hrtimer_start(hrtimer, ns_to_ktime(TICK_NSEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		      HRTIMER_MODE_REL_PINNED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static int oprofile_hrtimer_start(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	get_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	ctr_running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	on_each_cpu(__oprofile_hrtimer_start, NULL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static void __oprofile_hrtimer_stop(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	struct hrtimer *hrtimer = &per_cpu(oprofile_hrtimer, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	if (!ctr_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	hrtimer_cancel(hrtimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static void oprofile_hrtimer_stop(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	get_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	for_each_online_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		__oprofile_hrtimer_stop(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	ctr_running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static int oprofile_timer_online(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	__oprofile_hrtimer_start(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static int oprofile_timer_prep_down(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	__oprofile_hrtimer_stop(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) static enum cpuhp_state hp_online;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static int oprofile_hrtimer_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 					"oprofile/timer:online",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 					oprofile_timer_online,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 					oprofile_timer_prep_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	hp_online = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void oprofile_hrtimer_shutdown(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	cpuhp_remove_state_nocalls(hp_online);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int oprofile_timer_init(struct oprofile_operations *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	ops->create_files	= NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	ops->setup		= oprofile_hrtimer_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	ops->shutdown		= oprofile_hrtimer_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	ops->start		= oprofile_hrtimer_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	ops->stop		= oprofile_hrtimer_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	ops->cpu_type		= "timer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	printk(KERN_INFO "oprofile: using timer interrupt.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }