mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-07 06:14:24 +08:00
eeepc-laptop: fix ordering of init and exit functions
1. input and backlight devices were registered after acpi notifications are enabled. This left a window where eeepc_hotk_notify() might find these devices in an inconsistent (half-initialized) state. -> Move all device registration into eeepc_hotk_add(), which is called before enabling acpi notifications. 2. input and backlight devices were unregistered before acpi notifications are disabled. This left a window where eeepc_hotk_notify() might find these devices in an inconsistent (half-destroyed) state. -> Move all device unregistration into eeepc_hotk_remove(), which is called after disabling acpi notifications. 3. The acpi driver was not freed if an error occured further down in eeepc_laptop_init(). -> The rest of eeepc_laptop_init() has been moved to eeepc_hotk_add(), so this is no longer a problem. 4. The acpi driver was unregistered before the platform driver. This left a window where a sysfs access could attempt to read the ehotk structure after it had been freed by eeepc_hotk_remove(). -> The acpi driver is now unregistered as the last step in eeepc_laptop_exit(), so this is no longer a problem. Signed-off-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk> Signed-off-by: Corentin Chary <corentincj@iksaif.net> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
07e84aa98f
commit
1e7798547f
@ -847,44 +847,6 @@ error_slot:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int eeepc_hotk_add(struct acpi_device *device)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
pr_notice(EEEPC_HOTK_NAME "\n");
|
||||
ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
|
||||
if (!ehotk)
|
||||
return -ENOMEM;
|
||||
ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
|
||||
ehotk->handle = device->handle;
|
||||
strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
|
||||
device->driver_data = ehotk;
|
||||
ehotk->device = device;
|
||||
result = eeepc_hotk_check();
|
||||
if (result)
|
||||
goto ehotk_fail;
|
||||
|
||||
return 0;
|
||||
|
||||
ehotk_fail:
|
||||
kfree(ehotk);
|
||||
ehotk = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int eeepc_hotk_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
|
||||
kfree(ehotk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eeepc_hotk_resume(struct acpi_device *device)
|
||||
{
|
||||
if (ehotk->wlan_rfkill) {
|
||||
@ -1066,19 +1028,6 @@ static void eeepc_hwmon_exit(void)
|
||||
eeepc_hwmon_device = NULL;
|
||||
}
|
||||
|
||||
static void __exit eeepc_laptop_exit(void)
|
||||
{
|
||||
eeepc_backlight_exit();
|
||||
eeepc_rfkill_exit();
|
||||
eeepc_input_exit();
|
||||
eeepc_hwmon_exit();
|
||||
acpi_bus_unregister_driver(&eeepc_hotk_driver);
|
||||
sysfs_remove_group(&platform_device->dev.kobj,
|
||||
&platform_attribute_group);
|
||||
platform_device_unregister(platform_device);
|
||||
platform_driver_unregister(&platform_driver);
|
||||
}
|
||||
|
||||
static int eeepc_new_rfkill(struct rfkill **rfkill,
|
||||
const char *name, struct device *dev,
|
||||
enum rfkill_type type, int cm)
|
||||
@ -1193,21 +1142,27 @@ static int eeepc_hwmon_init(struct device *dev)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int __init eeepc_laptop_init(void)
|
||||
static int eeepc_hotk_add(struct acpi_device *device)
|
||||
{
|
||||
struct device *dev;
|
||||
int result;
|
||||
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
result = acpi_bus_register_driver(&eeepc_hotk_driver);
|
||||
if (result < 0)
|
||||
return result;
|
||||
if (!ehotk) {
|
||||
acpi_bus_unregister_driver(&eeepc_hotk_driver);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
pr_notice(EEEPC_HOTK_NAME "\n");
|
||||
ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
|
||||
if (!ehotk)
|
||||
return -ENOMEM;
|
||||
ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
|
||||
ehotk->handle = device->handle;
|
||||
strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
|
||||
device->driver_data = ehotk;
|
||||
ehotk->device = device;
|
||||
|
||||
result = eeepc_hotk_check();
|
||||
if (result)
|
||||
goto fail_check;
|
||||
eeepc_enable_camera();
|
||||
|
||||
/* Register platform stuff */
|
||||
@ -1246,6 +1201,7 @@ static int __init eeepc_laptop_init(void)
|
||||
goto fail_rfkill;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_rfkill:
|
||||
eeepc_hwmon_exit();
|
||||
fail_hwmon:
|
||||
@ -1261,8 +1217,50 @@ fail_platform_device1:
|
||||
platform_driver_unregister(&platform_driver);
|
||||
fail_platform_driver:
|
||||
eeepc_input_exit();
|
||||
fail_check:
|
||||
kfree(ehotk);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int eeepc_hotk_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
|
||||
eeepc_backlight_exit();
|
||||
eeepc_rfkill_exit();
|
||||
eeepc_input_exit();
|
||||
eeepc_hwmon_exit();
|
||||
sysfs_remove_group(&platform_device->dev.kobj,
|
||||
&platform_attribute_group);
|
||||
platform_device_unregister(platform_device);
|
||||
platform_driver_unregister(&platform_driver);
|
||||
|
||||
kfree(ehotk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init eeepc_laptop_init(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
result = acpi_bus_register_driver(&eeepc_hotk_driver);
|
||||
if (result < 0)
|
||||
return result;
|
||||
if (!ehotk) {
|
||||
acpi_bus_unregister_driver(&eeepc_hotk_driver);
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit eeepc_laptop_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&eeepc_hotk_driver);
|
||||
}
|
||||
|
||||
module_init(eeepc_laptop_init);
|
||||
module_exit(eeepc_laptop_exit);
|
||||
|
Loading…
Reference in New Issue
Block a user