@@ -94,6 +94,11 @@ static struct lpi_constraints *lpi_constraints_table;
94
94
static int lpi_constraints_table_size ;
95
95
static int rev_id ;
96
96
97
+ #define for_each_lpi_constraint (entry ) \
98
+ for (int i = 0; \
99
+ entry = &lpi_constraints_table[i], i < lpi_constraints_table_size; \
100
+ i++)
101
+
97
102
static void lpi_device_get_constraints_amd (void )
98
103
{
99
104
union acpi_object * out_obj ;
@@ -113,6 +118,12 @@ static void lpi_device_get_constraints_amd(void)
113
118
union acpi_object * package = & out_obj -> package .elements [i ];
114
119
115
120
if (package -> type == ACPI_TYPE_PACKAGE ) {
121
+ if (lpi_constraints_table ) {
122
+ acpi_handle_err (lps0_device_handle ,
123
+ "Duplicate constraints list\n" );
124
+ goto free_acpi_buffer ;
125
+ }
126
+
116
127
lpi_constraints_table = kcalloc (package -> package .count ,
117
128
sizeof (* lpi_constraints_table ),
118
129
GFP_KERNEL );
@@ -123,17 +134,16 @@ static void lpi_device_get_constraints_amd(void)
123
134
acpi_handle_debug (lps0_device_handle ,
124
135
"LPI: constraints list begin:\n" );
125
136
126
- for (j = 0 ; j < package -> package .count ; ++ j ) {
137
+ for (j = 0 ; j < package -> package .count ; j ++ ) {
127
138
union acpi_object * info_obj = & package -> package .elements [j ];
128
139
struct lpi_device_constraint_amd dev_info = {};
129
140
struct lpi_constraints * list ;
130
141
acpi_status status ;
131
142
132
- for (k = 0 ; k < info_obj -> package .count ; ++ k ) {
133
- union acpi_object * obj = & info_obj -> package .elements [k ];
143
+ list = & lpi_constraints_table [lpi_constraints_table_size ];
134
144
135
- list = & lpi_constraints_table [ lpi_constraints_table_size ];
136
- list -> min_dstate = -1 ;
145
+ for ( k = 0 ; k < info_obj -> package . count ; k ++ ) {
146
+ union acpi_object * obj = & info_obj -> package . elements [ k ] ;
137
147
138
148
switch (k ) {
139
149
case 0 :
@@ -149,27 +159,25 @@ static void lpi_device_get_constraints_amd(void)
149
159
dev_info .min_dstate = obj -> integer .value ;
150
160
break ;
151
161
}
162
+ }
152
163
153
- if (!dev_info .enabled || !dev_info .name ||
154
- !dev_info .min_dstate )
155
- continue ;
164
+ acpi_handle_debug (lps0_device_handle ,
165
+ "Name:%s, Enabled: %d, States: %d, MinDstate: %d\n" ,
166
+ dev_info .name ,
167
+ dev_info .enabled ,
168
+ dev_info .function_states ,
169
+ dev_info .min_dstate );
156
170
157
- status = acpi_get_handle (NULL , dev_info .name ,
158
- & list -> handle );
159
- if (ACPI_FAILURE (status ))
160
- continue ;
171
+ if (!dev_info .enabled || !dev_info .name ||
172
+ !dev_info .min_dstate )
173
+ continue ;
161
174
162
- acpi_handle_debug (lps0_device_handle ,
163
- "Name:%s\n" , dev_info .name );
175
+ status = acpi_get_handle (NULL , dev_info .name , & list -> handle );
176
+ if (ACPI_FAILURE (status ))
177
+ continue ;
164
178
165
- list -> min_dstate = dev_info .min_dstate ;
179
+ list -> min_dstate = dev_info .min_dstate ;
166
180
167
- if (list -> min_dstate < 0 ) {
168
- acpi_handle_debug (lps0_device_handle ,
169
- "Incomplete constraint defined\n" );
170
- continue ;
171
- }
172
- }
173
181
lpi_constraints_table_size ++ ;
174
182
}
175
183
}
@@ -214,7 +222,7 @@ static void lpi_device_get_constraints(void)
214
222
if (!package )
215
223
continue ;
216
224
217
- for (j = 0 ; j < package -> package .count ; ++ j ) {
225
+ for (j = 0 ; j < package -> package .count ; j ++ ) {
218
226
union acpi_object * element =
219
227
& (package -> package .elements [j ]);
220
228
@@ -246,7 +254,7 @@ static void lpi_device_get_constraints(void)
246
254
247
255
constraint -> min_dstate = -1 ;
248
256
249
- for (j = 0 ; j < package_count ; ++ j ) {
257
+ for (j = 0 ; j < package_count ; j ++ ) {
250
258
union acpi_object * info_obj = & info .package [j ];
251
259
union acpi_object * cnstr_pkg ;
252
260
union acpi_object * obj ;
@@ -291,32 +299,55 @@ static void lpi_device_get_constraints(void)
291
299
ACPI_FREE (out_obj );
292
300
}
293
301
302
+ /**
303
+ * acpi_get_lps0_constraint - Get the LPS0 constraint for a device.
304
+ * @adev: Device to get the constraint for.
305
+ *
306
+ * The LPS0 constraint is the shallowest (minimum) power state in which the
307
+ * device can be so as to allow the platform as a whole to achieve additional
308
+ * energy conservation by utilizing a system-wide low-power state.
309
+ *
310
+ * Returns:
311
+ * - ACPI power state value of the constraint for @adev on success.
312
+ * - Otherwise, ACPI_STATE_UNKNOWN.
313
+ */
314
+ int acpi_get_lps0_constraint (struct acpi_device * adev )
315
+ {
316
+ struct lpi_constraints * entry ;
317
+
318
+ for_each_lpi_constraint (entry ) {
319
+ if (adev -> handle == entry -> handle )
320
+ return entry -> min_dstate ;
321
+ }
322
+
323
+ return ACPI_STATE_UNKNOWN ;
324
+ }
325
+
294
326
static void lpi_check_constraints (void )
295
327
{
296
- int i ;
328
+ struct lpi_constraints * entry ;
297
329
298
- for (i = 0 ; i < lpi_constraints_table_size ; ++ i ) {
299
- acpi_handle handle = lpi_constraints_table [i ].handle ;
300
- struct acpi_device * adev = acpi_fetch_acpi_dev (handle );
330
+ for_each_lpi_constraint (entry ) {
331
+ struct acpi_device * adev = acpi_fetch_acpi_dev (entry -> handle );
301
332
302
333
if (!adev )
303
334
continue ;
304
335
305
- acpi_handle_debug (handle ,
336
+ acpi_handle_debug (entry -> handle ,
306
337
"LPI: required min power state:%s current power state:%s\n" ,
307
- acpi_power_state_string (lpi_constraints_table [ i ]. min_dstate ),
338
+ acpi_power_state_string (entry -> min_dstate ),
308
339
acpi_power_state_string (adev -> power .state ));
309
340
310
341
if (!adev -> flags .power_manageable ) {
311
- acpi_handle_info (handle , "LPI: Device not power manageable\n" );
312
- lpi_constraints_table [ i ]. handle = NULL ;
342
+ acpi_handle_info (entry -> handle , "LPI: Device not power manageable\n" );
343
+ entry -> handle = NULL ;
313
344
continue ;
314
345
}
315
346
316
- if (adev -> power .state < lpi_constraints_table [ i ]. min_dstate )
317
- acpi_handle_info (handle ,
347
+ if (adev -> power .state < entry -> min_dstate )
348
+ acpi_handle_info (entry -> handle ,
318
349
"LPI: Constraint not met; min power state:%s current power state:%s\n" ,
319
- acpi_power_state_string (lpi_constraints_table [ i ]. min_dstate ),
350
+ acpi_power_state_string (entry -> min_dstate ),
320
351
acpi_power_state_string (adev -> power .state ));
321
352
}
322
353
}
0 commit comments