22
22
#include <asm/page.h>
23
23
#include <asm/hvcall.h>
24
24
#include <asm/firmware.h>
25
+ #include <asm/prom.h>
25
26
26
27
27
28
#define MODULE_VERS "1.0"
@@ -38,26 +39,58 @@ static int sysfs_entries;
38
39
static u32 cpu_to_drc_index (int cpu )
39
40
{
40
41
struct device_node * dn = NULL ;
41
- const int * indexes ;
42
- int i ;
42
+ int thread_index ;
43
43
int rc = 1 ;
44
44
u32 ret = 0 ;
45
45
46
46
dn = of_find_node_by_path ("/cpus" );
47
47
if (dn == NULL )
48
48
goto err ;
49
- indexes = of_get_property (dn , "ibm,drc-indexes" , NULL );
50
- if (indexes == NULL )
51
- goto err_of_node_put ;
49
+
52
50
/* Convert logical cpu number to core number */
53
- i = cpu_core_index_of_thread (cpu );
54
- /*
55
- * The first element indexes[0] is the number of drc_indexes
56
- * returned in the list. Hence i+1 will get the drc_index
57
- * corresponding to core number i.
58
- */
59
- WARN_ON (i > indexes [0 ]);
60
- ret = indexes [i + 1 ];
51
+ thread_index = cpu_core_index_of_thread (cpu );
52
+
53
+ if (firmware_has_feature (FW_FEATURE_DRC_INFO )) {
54
+ struct property * info = NULL ;
55
+ struct of_drc_info drc ;
56
+ int j ;
57
+ u32 num_set_entries ;
58
+ const __be32 * value ;
59
+
60
+ info = of_find_property (dn , "ibm,drc-info" , NULL );
61
+ if (info == NULL )
62
+ goto err_of_node_put ;
63
+
64
+ value = of_prop_next_u32 (info , NULL , & num_set_entries );
65
+ if (!value )
66
+ goto err_of_node_put ;
67
+
68
+ for (j = 0 ; j < num_set_entries ; j ++ ) {
69
+
70
+ of_read_drc_info_cell (& info , & value , & drc );
71
+ if (strncmp (drc .drc_type , "CPU" , 3 ))
72
+ goto err ;
73
+
74
+ if (thread_index < drc .last_drc_index )
75
+ break ;
76
+ }
77
+
78
+ ret = drc .drc_index_start + (thread_index * drc .sequential_inc );
79
+ } else {
80
+ const __be32 * indexes ;
81
+
82
+ indexes = of_get_property (dn , "ibm,drc-indexes" , NULL );
83
+ if (indexes == NULL )
84
+ goto err_of_node_put ;
85
+
86
+ /*
87
+ * The first element indexes[0] is the number of drc_indexes
88
+ * returned in the list. Hence thread_index+1 will get the
89
+ * drc_index corresponding to core number thread_index.
90
+ */
91
+ ret = indexes [thread_index + 1 ];
92
+ }
93
+
61
94
rc = 0 ;
62
95
63
96
err_of_node_put :
@@ -72,34 +105,71 @@ static int drc_index_to_cpu(u32 drc_index)
72
105
{
73
106
struct device_node * dn = NULL ;
74
107
const int * indexes ;
75
- int i , cpu = 0 ;
108
+ int thread_index = 0 , cpu = 0 ;
76
109
int rc = 1 ;
77
110
78
111
dn = of_find_node_by_path ("/cpus" );
79
112
if (dn == NULL )
80
113
goto err ;
81
- indexes = of_get_property (dn , "ibm,drc-indexes" , NULL );
82
- if (indexes == NULL )
83
- goto err_of_node_put ;
84
- /*
85
- * First element in the array is the number of drc_indexes
86
- * returned. Search through the list to find the matching
87
- * drc_index and get the core number
88
- */
89
- for (i = 0 ; i < indexes [0 ]; i ++ ) {
90
- if (indexes [i + 1 ] == drc_index )
114
+
115
+ if (firmware_has_feature (FW_FEATURE_DRC_INFO )) {
116
+ struct property * info = NULL ;
117
+ struct of_drc_info drc ;
118
+ int j ;
119
+ u32 num_set_entries ;
120
+ const __be32 * value ;
121
+
122
+ info = of_find_property (dn , "ibm,drc-info" , NULL );
123
+ if (info == NULL )
124
+ goto err_of_node_put ;
125
+
126
+ value = of_prop_next_u32 (info , NULL , & num_set_entries );
127
+ if (!value )
128
+ goto err_of_node_put ;
129
+
130
+ for (j = 0 ; j < num_set_entries ; j ++ ) {
131
+
132
+ of_read_drc_info_cell (& info , & value , & drc );
133
+ if (strncmp (drc .drc_type , "CPU" , 3 ))
134
+ goto err ;
135
+
136
+ if (drc_index > drc .last_drc_index ) {
137
+ cpu += drc .num_sequential_elems ;
138
+ continue ;
139
+ }
140
+ cpu += ((drc_index - drc .drc_index_start ) /
141
+ drc .sequential_inc );
142
+
143
+ thread_index = cpu_first_thread_of_core (cpu );
144
+ rc = 0 ;
91
145
break ;
146
+ }
147
+ } else {
148
+ unsigned long int i ;
149
+
150
+ indexes = of_get_property (dn , "ibm,drc-indexes" , NULL );
151
+ if (indexes == NULL )
152
+ goto err_of_node_put ;
153
+ /*
154
+ * First element in the array is the number of drc_indexes
155
+ * returned. Search through the list to find the matching
156
+ * drc_index and get the core number
157
+ */
158
+ for (i = 0 ; i < indexes [0 ]; i ++ ) {
159
+ if (indexes [i + 1 ] == drc_index )
160
+ break ;
161
+ }
162
+ /* Convert core number to logical cpu number */
163
+ thread_index = cpu_first_thread_of_core (i );
164
+ rc = 0 ;
92
165
}
93
- /* Convert core number to logical cpu number */
94
- cpu = cpu_first_thread_of_core (i );
95
- rc = 0 ;
96
166
97
167
err_of_node_put :
98
168
of_node_put (dn );
99
169
err :
100
170
if (rc )
101
171
printk (KERN_WARNING "drc_index_to_cpu(%d) failed" , drc_index );
102
- return cpu ;
172
+ return thread_index ;
103
173
}
104
174
105
175
/*
0 commit comments