diff options
author | 2014-02-07 11:27:30 -0800 | |
---|---|---|
committer | 2014-02-07 11:27:30 -0800 | |
commit | a3b072cd180c12e8fe0ece9487b9065808327640 (patch) | |
tree | 62b982041be84748852d77cdf6ca5639ef40858f /drivers/acpi/container.c | |
parent | x86, microcode, AMD: Unify valid container checks (diff) | |
parent | x86/efi: Allow mapping BGRT on x86-32 (diff) | |
download | wireguard-linux-a3b072cd180c12e8fe0ece9487b9065808327640.tar.xz wireguard-linux-a3b072cd180c12e8fe0ece9487b9065808327640.zip |
Merge tag 'efi-urgent' into x86/urgent
* Avoid WARN_ON() when mapping BGRT on Baytrail (EFI 32-bit).
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'drivers/acpi/container.c')
-rw-r--r-- | drivers/acpi/container.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index e23151667655..0b6ae6eb5c4a 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -27,8 +27,7 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/acpi.h> - -#include "internal.h" +#include <linux/container.h> #include "internal.h" @@ -44,19 +43,65 @@ static const struct acpi_device_id container_device_ids[] = { {"", 0}, }; -static int container_device_attach(struct acpi_device *device, +static int acpi_container_offline(struct container_dev *cdev) +{ + struct acpi_device *adev = ACPI_COMPANION(&cdev->dev); + struct acpi_device *child; + + /* Check all of the dependent devices' physical companions. */ + list_for_each_entry(child, &adev->children, node) + if (!acpi_scan_is_offline(child, false)) + return -EBUSY; + + return 0; +} + +static void acpi_container_release(struct device *dev) +{ + kfree(to_container_dev(dev)); +} + +static int container_device_attach(struct acpi_device *adev, const struct acpi_device_id *not_used) { - /* This is necessary for container hotplug to work. */ + struct container_dev *cdev; + struct device *dev; + int ret; + + cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + if (!cdev) + return -ENOMEM; + + cdev->offline = acpi_container_offline; + dev = &cdev->dev; + dev->bus = &container_subsys; + dev_set_name(dev, "%s", dev_name(&adev->dev)); + ACPI_COMPANION_SET(dev, adev); + dev->release = acpi_container_release; + ret = device_register(dev); + if (ret) + return ret; + + adev->driver_data = dev; return 1; } +static void container_device_detach(struct acpi_device *adev) +{ + struct device *dev = acpi_driver_data(adev); + + adev->driver_data = NULL; + if (dev) + device_unregister(dev); +} + static struct acpi_scan_handler container_handler = { .ids = container_device_ids, .attach = container_device_attach, + .detach = container_device_detach, .hotplug = { .enabled = true, - .mode = AHM_CONTAINER, + .demand_offline = true, }, }; |