gator: Prevent BUG() when no device-tree cpu nodes present.
[android-sdk/arm-ds5-gator.git] / driver / gator_iks.c
1 /**
2  * Copyright (C) ARM Limited 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 #if GATOR_IKS_SUPPORT
12 #include <linux/of.h>
13 #include <asm/bL_switcher.h>
14 #include <asm/smp_plat.h>
15 #include <trace/events/power_cpu_migrate.h>
17 static bool map_cpuids;
18 static int mpidr_cpuids[NR_CPUS];
19 static int __lcpu_to_pcpu[NR_CPUS];
21 static void calc_first_cluster_size(void)
22 {
23         int len;
24         const u32 *val;
25         struct device_node *cn = NULL;
26         int mpidr_cpuids_count = 0;
28         // Zero is a valid cpuid, so initialize the array to 0xff's
29         memset(&mpidr_cpuids, 0xff, sizeof(mpidr_cpuids));
31         while ((cn = of_find_node_by_type(cn, "cpu"))) {
32                 BUG_ON(mpidr_cpuids_count >= NR_CPUS);
34                 val = of_get_property(cn, "reg", &len);
35                 if (!val || len != 4) {
36                         pr_err("%s missing reg property\n", cn->full_name);
37                         continue;
38                 }
40                 mpidr_cpuids[mpidr_cpuids_count] = be32_to_cpup(val);
41                 ++mpidr_cpuids_count;
42         }
44         map_cpuids = (mpidr_cpuids_count == nr_cpu_ids);
45 }
47 static int linearize_mpidr(int mpidr)
48 {
49         int i;
50         for (i = 0; i < nr_cpu_ids; ++i) {
51                 if (mpidr_cpuids[i] == mpidr) {
52                         return i;
53                 }
54         }
56         BUG();
57 }
59 int lcpu_to_pcpu(const int lcpu)
60 {
61         int pcpu;
63         if (!map_cpuids)
64                 return lcpu;
66         BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
67         pcpu = __lcpu_to_pcpu[lcpu];
68         BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
69         return pcpu;
70 }
72 int pcpu_to_lcpu(const int pcpu)
73 {
74         int lcpu;
76         if (!map_cpuids)
77                 return pcpu;
79         BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
80         for (lcpu = 0; lcpu < nr_cpu_ids; ++lcpu) {
81                 if (__lcpu_to_pcpu[lcpu] == pcpu) {
82                         BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
83                         return lcpu;
84                 }
85         }
86         BUG();
87 }
89 static void gator_update_cpu_mapping(u32 cpu_hwid)
90 {
91         int lcpu = smp_processor_id();
92         int pcpu = linearize_mpidr(cpu_hwid & MPIDR_HWID_BITMASK);
93         BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
94         BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
95         __lcpu_to_pcpu[lcpu] = pcpu;
96 }
98 GATOR_DEFINE_PROBE(cpu_migrate_begin, TP_PROTO(u64 timestamp, u32 cpu_hwid))
99 {
100         const int cpu = get_physical_cpu();
102         gator_timer_offline((void *)1);
103         gator_timer_offline_dispatch(cpu, true);
106 GATOR_DEFINE_PROBE(cpu_migrate_finish, TP_PROTO(u64 timestamp, u32 cpu_hwid))
108         int cpu;
110         gator_update_cpu_mapping(cpu_hwid);
112         // get_physical_cpu must be called after gator_update_cpu_mapping
113         cpu = get_physical_cpu();
114         gator_timer_online_dispatch(cpu, true);
115         gator_timer_online((void *)1);
118 GATOR_DEFINE_PROBE(cpu_migrate_current, TP_PROTO(u64 timestamp, u32 cpu_hwid))
120         gator_update_cpu_mapping(cpu_hwid);
123 static int gator_migrate_start(void)
125         int retval = 0;
127         if (!map_cpuids)
128                 return retval;
130         if (retval == 0)
131                 retval = GATOR_REGISTER_TRACE(cpu_migrate_begin);
132         if (retval == 0)
133                 retval = GATOR_REGISTER_TRACE(cpu_migrate_finish);
134         if (retval == 0)
135                 retval = GATOR_REGISTER_TRACE(cpu_migrate_current);
136         if (retval == 0) {
137                 // Initialize the logical to physical cpu mapping
138                 memset(&__lcpu_to_pcpu, 0xff, sizeof(__lcpu_to_pcpu));
139                 bL_switcher_trace_trigger();
140         }
141         return retval;
144 static void gator_migrate_stop(void)
146         if (!map_cpuids)
147                 return;
149         GATOR_UNREGISTER_TRACE(cpu_migrate_current);
150         GATOR_UNREGISTER_TRACE(cpu_migrate_finish);
151         GATOR_UNREGISTER_TRACE(cpu_migrate_begin);
154 #else
156 #define calc_first_cluster_size()
157 #define gator_migrate_start() 0
158 #define gator_migrate_stop()
160 #endif