acer-wmi: check wireless capability flag before register rfkill
authorLee, Chun-Yi <joeyli.kernel@gmail.com>
Thu, 18 Aug 2011 10:47:33 +0000 (18:47 +0800)
committerMatthew Garrett <mjg@redhat.com>
Mon, 24 Oct 2011 14:52:38 +0000 (16:52 +0200)
There will be better to check the wireless capability flag
(ACER_CAP_WIRELESS) before register wireless rfkill because maybe
the machine doesn't have wifi module or the module removed by user.

Tested on Acer Travelmate 8572
Tested on Acer Aspire 4739Z

Tested-by: AceLan Kao <acelan.kao@canonical.com>
Cc: Carlos Corbacho <carlos@strangeworlds.co.uk>
Cc: Matthew Garrett <mjg@redhat.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
Cc: Corentin Chary <corentincj@iksaif.net>
Cc: Thomas Renninger <trenn@suse.de>
Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
drivers/platform/x86/acer-wmi.c

index dac286a..fc7c973 100644 (file)
@@ -1294,12 +1294,13 @@ static void acer_rfkill_update(struct work_struct *ignored)
        u32 state;
        acpi_status status;
 
-       status = get_u32(&state, ACER_CAP_WIRELESS);
-       if (ACPI_SUCCESS(status)) {
-               if (quirks->wireless == 3) {
-                       rfkill_set_hw_state(wireless_rfkill, !state);
-               } else {
-                       rfkill_set_sw_state(wireless_rfkill, !state);
+       if (has_cap(ACER_CAP_WIRELESS)) {
+               status = get_u32(&state, ACER_CAP_WIRELESS);
+               if (ACPI_SUCCESS(status)) {
+                       if (quirks->wireless == 3)
+                               rfkill_set_hw_state(wireless_rfkill, !state);
+                       else
+                               rfkill_set_sw_state(wireless_rfkill, !state);
                }
        }
 
@@ -1368,19 +1369,24 @@ static struct rfkill *acer_rfkill_register(struct device *dev,
 
 static int acer_rfkill_init(struct device *dev)
 {
-       wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
-               "acer-wireless", ACER_CAP_WIRELESS);
-       if (IS_ERR(wireless_rfkill))
-               return PTR_ERR(wireless_rfkill);
+       int err;
+
+       if (has_cap(ACER_CAP_WIRELESS)) {
+               wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
+                       "acer-wireless", ACER_CAP_WIRELESS);
+               if (IS_ERR(wireless_rfkill)) {
+                       err = PTR_ERR(wireless_rfkill);
+                       goto error_wireless;
+               }
+       }
 
        if (has_cap(ACER_CAP_BLUETOOTH)) {
                bluetooth_rfkill = acer_rfkill_register(dev,
                        RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
                        ACER_CAP_BLUETOOTH);
                if (IS_ERR(bluetooth_rfkill)) {
-                       rfkill_unregister(wireless_rfkill);
-                       rfkill_destroy(wireless_rfkill);
-                       return PTR_ERR(bluetooth_rfkill);
+                       err = PTR_ERR(bluetooth_rfkill);
+                       goto error_bluetooth;
                }
        }
 
@@ -1389,30 +1395,44 @@ static int acer_rfkill_init(struct device *dev)
                        RFKILL_TYPE_WWAN, "acer-threeg",
                        ACER_CAP_THREEG);
                if (IS_ERR(threeg_rfkill)) {
-                       rfkill_unregister(wireless_rfkill);
-                       rfkill_destroy(wireless_rfkill);
-                       rfkill_unregister(bluetooth_rfkill);
-                       rfkill_destroy(bluetooth_rfkill);
-                       return PTR_ERR(threeg_rfkill);
+                       err = PTR_ERR(threeg_rfkill);
+                       goto error_threeg;
                }
        }
 
        rfkill_inited = true;
 
-       if (ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID))
+       if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
+           has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
                schedule_delayed_work(&acer_rfkill_work,
                        round_jiffies_relative(HZ));
 
        return 0;
+
+error_threeg:
+       if (has_cap(ACER_CAP_BLUETOOTH)) {
+               rfkill_unregister(bluetooth_rfkill);
+               rfkill_destroy(bluetooth_rfkill);
+       }
+error_bluetooth:
+       if (has_cap(ACER_CAP_WIRELESS)) {
+               rfkill_unregister(wireless_rfkill);
+               rfkill_destroy(wireless_rfkill);
+       }
+error_wireless:
+       return err;
 }
 
 static void acer_rfkill_exit(void)
 {
-       if (ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID))
+       if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
+           has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
                cancel_delayed_work_sync(&acer_rfkill_work);
 
-       rfkill_unregister(wireless_rfkill);
-       rfkill_destroy(wireless_rfkill);
+       if (has_cap(ACER_CAP_WIRELESS)) {
+               rfkill_unregister(wireless_rfkill);
+               rfkill_destroy(wireless_rfkill);
+       }
 
        if (has_cap(ACER_CAP_BLUETOOTH)) {
                rfkill_unregister(bluetooth_rfkill);