@@ -94,6 +94,11 @@ static struct lpi_constraints *lpi_constraints_table;
9494static int lpi_constraints_table_size ;
9595static int rev_id ;
9696
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+
97102static void lpi_device_get_constraints_amd (void )
98103{
99104 union acpi_object * out_obj ;
@@ -113,6 +118,12 @@ static void lpi_device_get_constraints_amd(void)
113118 union acpi_object * package = & out_obj -> package .elements [i ];
114119
115120 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+
116127 lpi_constraints_table = kcalloc (package -> package .count ,
117128 sizeof (* lpi_constraints_table ),
118129 GFP_KERNEL );
@@ -123,17 +134,16 @@ static void lpi_device_get_constraints_amd(void)
123134 acpi_handle_debug (lps0_device_handle ,
124135 "LPI: constraints list begin:\n" );
125136
126- for (j = 0 ; j < package -> package .count ; ++ j ) {
137+ for (j = 0 ; j < package -> package .count ; j ++ ) {
127138 union acpi_object * info_obj = & package -> package .elements [j ];
128139 struct lpi_device_constraint_amd dev_info = {};
129140 struct lpi_constraints * list ;
130141 acpi_status status ;
131142
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 ];
134144
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 ] ;
137147
138148 switch (k ) {
139149 case 0 :
@@ -149,27 +159,25 @@ static void lpi_device_get_constraints_amd(void)
149159 dev_info .min_dstate = obj -> integer .value ;
150160 break ;
151161 }
162+ }
152163
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 );
156170
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 ;
161174
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 ;
164178
165- list -> min_dstate = dev_info .min_dstate ;
179+ list -> min_dstate = dev_info .min_dstate ;
166180
167- if (list -> min_dstate < 0 ) {
168- acpi_handle_debug (lps0_device_handle ,
169- "Incomplete constraint defined\n" );
170- continue ;
171- }
172- }
173181 lpi_constraints_table_size ++ ;
174182 }
175183 }
@@ -214,7 +222,7 @@ static void lpi_device_get_constraints(void)
214222 if (!package )
215223 continue ;
216224
217- for (j = 0 ; j < package -> package .count ; ++ j ) {
225+ for (j = 0 ; j < package -> package .count ; j ++ ) {
218226 union acpi_object * element =
219227 & (package -> package .elements [j ]);
220228
@@ -246,7 +254,7 @@ static void lpi_device_get_constraints(void)
246254
247255 constraint -> min_dstate = -1 ;
248256
249- for (j = 0 ; j < package_count ; ++ j ) {
257+ for (j = 0 ; j < package_count ; j ++ ) {
250258 union acpi_object * info_obj = & info .package [j ];
251259 union acpi_object * cnstr_pkg ;
252260 union acpi_object * obj ;
@@ -291,32 +299,55 @@ static void lpi_device_get_constraints(void)
291299 ACPI_FREE (out_obj );
292300}
293301
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+
294326static void lpi_check_constraints (void )
295327{
296- int i ;
328+ struct lpi_constraints * entry ;
297329
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 );
301332
302333 if (!adev )
303334 continue ;
304335
305- acpi_handle_debug (handle ,
336+ acpi_handle_debug (entry -> handle ,
306337 "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 ),
308339 acpi_power_state_string (adev -> power .state ));
309340
310341 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 ;
313344 continue ;
314345 }
315346
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 ,
318349 "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 ),
320351 acpi_power_state_string (adev -> power .state ));
321352 }
322353}
0 commit comments