@@ -123,24 +123,6 @@ static const void *find_guid_context(struct wmi_block *wblock,
123123 return NULL ;
124124}
125125
126- static acpi_status wmi_method_enable (struct wmi_block * wblock , bool enable )
127- {
128- struct guid_block * block ;
129- char method [5 ];
130- acpi_status status ;
131- acpi_handle handle ;
132-
133- block = & wblock -> gblock ;
134- handle = wblock -> acpi_device -> handle ;
135-
136- snprintf (method , 5 , "WE%02X" , block -> notify_id );
137- status = acpi_execute_simple_method (handle , method , enable );
138- if (status == AE_NOT_FOUND )
139- return AE_OK ;
140-
141- return status ;
142- }
143-
144126#define WMI_ACPI_METHOD_NAME_SIZE 5
145127
146128static inline void get_acpi_method_name (const struct wmi_block * wblock ,
@@ -184,6 +166,44 @@ static int wmidev_match_guid(struct device *dev, const void *data)
184166
185167static const struct bus_type wmi_bus_type ;
186168
169+ static const struct device_type wmi_type_event ;
170+
171+ static const struct device_type wmi_type_method ;
172+
173+ static int wmi_device_enable (struct wmi_device * wdev , bool enable )
174+ {
175+ struct wmi_block * wblock = container_of (wdev , struct wmi_block , dev );
176+ char method [WMI_ACPI_METHOD_NAME_SIZE ];
177+ acpi_handle handle ;
178+ acpi_status status ;
179+
180+ if (!(wblock -> gblock .flags & ACPI_WMI_EXPENSIVE ))
181+ return 0 ;
182+
183+ if (wblock -> dev .dev .type == & wmi_type_method )
184+ return 0 ;
185+
186+ if (wblock -> dev .dev .type == & wmi_type_event )
187+ snprintf (method , sizeof (method ), "WE%02X" , wblock -> gblock .notify_id );
188+ else
189+ get_acpi_method_name (wblock , 'C' , method );
190+
191+ /*
192+ * Not all WMI devices marked as expensive actually implement the
193+ * necessary ACPI method. Ignore this missing ACPI method to match
194+ * the behaviour of the Windows driver.
195+ */
196+ status = acpi_get_handle (wblock -> acpi_device -> handle , method , & handle );
197+ if (ACPI_FAILURE (status ))
198+ return 0 ;
199+
200+ status = acpi_execute_simple_method (handle , NULL , enable );
201+ if (ACPI_FAILURE (status ))
202+ return - EIO ;
203+
204+ return 0 ;
205+ }
206+
187207static struct wmi_device * wmi_find_device_by_guid (const char * guid_string )
188208{
189209 struct device * dev ;
@@ -337,10 +357,8 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
337357{
338358 struct guid_block * block ;
339359 acpi_handle handle ;
340- acpi_status status , wc_status = AE_ERROR ;
341360 struct acpi_object_list input ;
342361 union acpi_object wq_params [1 ];
343- char wc_method [WMI_ACPI_METHOD_NAME_SIZE ];
344362 char method [WMI_ACPI_METHOD_NAME_SIZE ];
345363
346364 if (!out )
@@ -364,40 +382,9 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
364382 if (instance == 0 && test_bit (WMI_READ_TAKES_NO_ARGS , & wblock -> flags ))
365383 input .count = 0 ;
366384
367- /*
368- * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method first to
369- * enable collection.
370- */
371- if (block -> flags & ACPI_WMI_EXPENSIVE ) {
372- get_acpi_method_name (wblock , 'C' , wc_method );
373-
374- /*
375- * Some GUIDs break the specification by declaring themselves
376- * expensive, but have no corresponding WCxx method. So we
377- * should not fail if this happens.
378- */
379- wc_status = acpi_execute_simple_method (handle , wc_method , 1 );
380- }
381-
382385 get_acpi_method_name (wblock , 'Q' , method );
383- status = acpi_evaluate_object (handle , method , & input , out );
384386
385- /*
386- * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if
387- * the WQxx method failed - we should disable collection anyway.
388- */
389- if ((block -> flags & ACPI_WMI_EXPENSIVE ) && ACPI_SUCCESS (wc_status )) {
390- /*
391- * Ignore whether this WCxx call succeeds or not since
392- * the previously executed WQxx method call might have
393- * succeeded, and returning the failing status code
394- * of this call would throw away the result of the WQxx
395- * call, potentially leaking memory.
396- */
397- acpi_execute_simple_method (handle , wc_method , 0 );
398- }
399-
400- return status ;
387+ return acpi_evaluate_object (handle , method , & input , out );
401388}
402389
403390/**
@@ -421,9 +408,15 @@ acpi_status wmi_query_block(const char *guid_string, u8 instance,
421408 if (IS_ERR (wdev ))
422409 return AE_ERROR ;
423410
411+ if (wmi_device_enable (wdev , true) < 0 )
412+ dev_warn (& wdev -> dev , "Failed to enable device\n" );
413+
424414 wblock = container_of (wdev , struct wmi_block , dev );
425415 status = __query_block (wblock , instance , out );
426416
417+ if (wmi_device_enable (wdev , false) < 0 )
418+ dev_warn (& wdev -> dev , "Failed to disable device\n" );
419+
427420 wmi_device_put (wdev );
428421
429422 return status ;
@@ -551,7 +544,7 @@ acpi_status wmi_install_notify_handler(const char *guid,
551544 wblock -> handler = handler ;
552545 wblock -> handler_data = data ;
553546
554- if (ACPI_FAILURE ( wmi_method_enable ( wblock , true)) )
547+ if (wmi_device_enable ( wdev , true) < 0 )
555548 dev_warn (& wblock -> dev .dev , "Failed to enable device\n" );
556549
557550 status = AE_OK ;
@@ -588,7 +581,7 @@ acpi_status wmi_remove_notify_handler(const char *guid)
588581 if (!wblock -> handler ) {
589582 status = AE_NULL_ENTRY ;
590583 } else {
591- if (ACPI_FAILURE ( wmi_method_enable ( wblock , false)) )
584+ if (wmi_device_enable ( wdev , false) < 0 )
592585 dev_warn (& wblock -> dev .dev , "Failed to disable device\n" );
593586
594587 wblock -> handler = NULL ;
@@ -823,10 +816,10 @@ static int wmi_dev_match(struct device *dev, const struct device_driver *driver)
823816
824817static void wmi_dev_disable (void * data )
825818{
826- struct wmi_block * wblock = data ;
819+ struct device * dev = data ;
827820
828- if (ACPI_FAILURE ( wmi_method_enable ( wblock , false)) )
829- dev_warn (& wblock -> dev . dev , "Failed to disable device\n" );
821+ if (wmi_device_enable ( to_wmi_device ( dev ) , false) < 0 )
822+ dev_warn (dev , "Failed to disable device\n" );
830823}
831824
832825static int wmi_dev_probe (struct device * dev )
@@ -852,14 +845,14 @@ static int wmi_dev_probe(struct device *dev)
852845 return - ENODEV ;
853846 }
854847
855- if (ACPI_FAILURE ( wmi_method_enable ( wblock , true)) )
848+ if (wmi_device_enable ( to_wmi_device ( dev ) , true) < 0 )
856849 dev_warn (dev , "failed to enable device -- probing anyway\n" );
857850
858851 /*
859852 * We have to make sure that all devres-managed resources are released first because
860853 * some might still want to access the underlying WMI device.
861854 */
862- ret = devm_add_action_or_reset (dev , wmi_dev_disable , wblock );
855+ ret = devm_add_action_or_reset (dev , wmi_dev_disable , dev );
863856 if (ret < 0 )
864857 return ret ;
865858
@@ -915,7 +908,7 @@ static void wmi_dev_shutdown(struct device *dev)
915908 * We still need to disable the WMI device here since devres-managed resources
916909 * like wmi_dev_disable() will not be release during shutdown.
917910 */
918- if (ACPI_FAILURE ( wmi_method_enable ( wblock , false)) )
911+ if (wmi_device_enable ( to_wmi_device ( dev ) , false) < 0 )
919912 dev_warn (dev , "Failed to disable device\n" );
920913 }
921914}
0 commit comments