Skip to content

Commit

Permalink
eeepc-laptop: Use ACPI handle to identify rfkill port
Browse files Browse the repository at this point in the history
The ACPI notification we get from rfkill events on these machines gives
us all the information we need to identify the port that's changed. Do
so rather than assuming that it's always bus 1.

Signed-off-by: Matthew Garrett <[email protected]>
  • Loading branch information
Matthew Garrett committed May 9, 2011
1 parent 62d2f23 commit 14fdb15
Showing 1 changed file with 41 additions and 16 deletions.
57 changes: 41 additions & 16 deletions drivers/platform/x86/eeepc-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,8 +585,9 @@ static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
return true;
}

static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
{
struct pci_dev *port;
struct pci_dev *dev;
struct pci_bus *bus;
bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
Expand All @@ -599,16 +600,24 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
mutex_lock(&eeepc->hotplug_lock);

if (eeepc->hotplug_slot) {
bus = pci_find_bus(0, 1);
port = acpi_get_pci_dev(handle);
if (!port) {
pr_warning("Unable to find port\n");
goto out_unlock;
}

bus = port->subordinate;

if (!bus) {
pr_warning("Unable to find PCI bus 1?\n");
pr_warning("Unable to find PCI bus?\n");
goto out_unlock;
}

if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
pr_err("Unable to read PCI config space?\n");
goto out_unlock;
}

absent = (l == 0xffffffff);

if (blocked != absent) {
Expand Down Expand Up @@ -647,14 +656,25 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
mutex_unlock(&eeepc->hotplug_lock);
}

static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
{
acpi_status status = AE_OK;
acpi_handle handle;

status = acpi_get_handle(NULL, node, &handle);

if (ACPI_SUCCESS(status))
eeepc_rfkill_hotplug(eeepc, handle);
}

static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
{
struct eeepc_laptop *eeepc = data;

if (event != ACPI_NOTIFY_BUS_CHECK)
return;

eeepc_rfkill_hotplug(eeepc);
eeepc_rfkill_hotplug(eeepc, handle);
}

static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
Expand All @@ -672,6 +692,11 @@ static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
eeepc);
if (ACPI_FAILURE(status))
pr_warning("Failed to register notify on %s\n", node);
/*
* Refresh pci hotplug in case the rfkill state was
* changed during setup.
*/
eeepc_rfkill_hotplug(eeepc, handle);
} else
return -ENODEV;

Expand All @@ -693,6 +718,12 @@ static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
if (ACPI_FAILURE(status))
pr_err("Error removing rfkill notify handler %s\n",
node);
/*
* Refresh pci hotplug in case the rfkill
* state was changed after
* eeepc_unregister_rfkill_notifier()
*/
eeepc_rfkill_hotplug(eeepc, handle);
}
}

Expand Down Expand Up @@ -816,11 +847,7 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
rfkill_destroy(eeepc->wlan_rfkill);
eeepc->wlan_rfkill = NULL;
}
/*
* Refresh pci hotplug in case the rfkill state was changed after
* eeepc_unregister_rfkill_notifier()
*/
eeepc_rfkill_hotplug(eeepc);

if (eeepc->hotplug_slot)
pci_hp_deregister(eeepc->hotplug_slot);

Expand Down Expand Up @@ -889,11 +916,6 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
/*
* Refresh pci hotplug in case the rfkill state was changed during
* setup.
*/
eeepc_rfkill_hotplug(eeepc);

exit:
if (result && result != -ENODEV)
Expand Down Expand Up @@ -928,8 +950,11 @@ static int eeepc_hotk_restore(struct device *device)
struct eeepc_laptop *eeepc = dev_get_drvdata(device);

/* Refresh both wlan rfkill state and pci hotplug */
if (eeepc->wlan_rfkill)
eeepc_rfkill_hotplug(eeepc);
if (eeepc->wlan_rfkill) {
eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5");
eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6");
eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7");
}

if (eeepc->bluetooth_rfkill)
rfkill_set_sw_state(eeepc->bluetooth_rfkill,
Expand Down

0 comments on commit 14fdb15

Please sign in to comment.