]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/arm-ds5-gator.git/blob - driver/gator_hrtimer_perf.c
gator: Version 5.14
[android-sdk/arm-ds5-gator.git] / driver / gator_hrtimer_perf.c
1 /**
2  * Copyright (C) ARM Limited 2011-2013. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  */
10 // gator_hrtimer_gator.c is used if perf is not supported
11 //   update, gator_hrtimer_gator.c always used until issues resolved with perf hrtimers
12 #if 0
14 // Note: perf Cortex support added in 2.6.35 and PERF_COUNT_SW_CPU_CLOCK/hrtimer broken on 2.6.35 and 2.6.36
15 //       not relevant as this code is not active until 3.0.0, but wanted to document the issue
17 void (*callback)(void);
18 static int profiling_interval;
19 static DEFINE_PER_CPU(struct perf_event *, perf_hrtimer);
20 static DEFINE_PER_CPU(struct perf_event_attr *, perf_hrtimer_attr);
22 static void gator_hrtimer_shutdown(void);
24 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
25 static void hrtimer_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs)
26 #else
27 static void hrtimer_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs)
28 #endif
29 {
30         (*callback)();
31 }
33 static int gator_online_single_hrtimer(int cpu)
34 {
35         if (per_cpu(perf_hrtimer, cpu) != 0 || per_cpu(perf_hrtimer_attr, cpu) == 0)
36                 return 0;
38 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
39         per_cpu(perf_hrtimer, cpu) = perf_event_create_kernel_counter(per_cpu(perf_hrtimer_attr, cpu), cpu, 0, hrtimer_overflow_handler);
40 #else
41         per_cpu(perf_hrtimer, cpu) = perf_event_create_kernel_counter(per_cpu(perf_hrtimer_attr, cpu), cpu, 0, hrtimer_overflow_handler, 0);
42 #endif
43         if (IS_ERR(per_cpu(perf_hrtimer, cpu))) {
44                 per_cpu(perf_hrtimer, cpu) = NULL;
45                 return -1;
46         }
48         if (per_cpu(perf_hrtimer, cpu)->state != PERF_EVENT_STATE_ACTIVE) {
49                 perf_event_release_kernel(per_cpu(perf_hrtimer, cpu));
50                 per_cpu(perf_hrtimer, cpu) = NULL;
51                 return -1;
52         }
54         return 0;
55 }
57 static void gator_hrtimer_online(int cpu)
58 {
59         if (gator_online_single_hrtimer(cpu) < 0) {
60                 pr_debug("gator: unable to online the hrtimer on cpu%d\n", cpu);
61         }
62 }
64 static void gator_hrtimer_offline(int cpu)
65 {
66         if (per_cpu(perf_hrtimer, cpu)) {
67                 perf_event_release_kernel(per_cpu(perf_hrtimer, cpu));
68                 per_cpu(perf_hrtimer, cpu) = NULL;
69         }
70 }
72 static int gator_hrtimer_init(int interval, void (*func)(void))
73 {
74         u32 size = sizeof(struct perf_event_attr);
75         int cpu;
77         callback = func;
79         // calculate profiling interval
80         profiling_interval = 1000000000 / interval;
82         for_each_present_cpu(cpu) {
83                 per_cpu(perf_hrtimer, cpu) = 0;
84                 per_cpu(perf_hrtimer_attr, cpu) = kmalloc(size, GFP_KERNEL);
85                 if (per_cpu(perf_hrtimer_attr, cpu) == 0) {
86                         gator_hrtimer_shutdown();
87                         return -1;
88                 }
90                 memset(per_cpu(perf_hrtimer_attr, cpu), 0, size);
91                 per_cpu(perf_hrtimer_attr, cpu)->type = PERF_TYPE_SOFTWARE;
92                 per_cpu(perf_hrtimer_attr, cpu)->size = size;
93                 per_cpu(perf_hrtimer_attr, cpu)->config = PERF_COUNT_SW_CPU_CLOCK;
94                 per_cpu(perf_hrtimer_attr, cpu)->sample_period = profiling_interval;
95                 per_cpu(perf_hrtimer_attr, cpu)->pinned = 1;
96         }
98         return 0;
99 }
101 static void gator_hrtimer_shutdown(void)
103         int cpu;
105         for_each_present_cpu(cpu) {
106                 if (per_cpu(perf_hrtimer_attr, cpu)) {
107                         kfree(per_cpu(perf_hrtimer_attr, cpu));
108                         per_cpu(perf_hrtimer_attr, cpu) = NULL;
109                 }
110         }
113 #endif