Skip to content

Commit

Permalink
hp-wmi: fix handling of platform device
Browse files Browse the repository at this point in the history
The driver will not quite work if someone unbinds the platform device
from the platform driver via sysfs (moreover it will bomb is the driver
built into the kernel as hp_wmi_bios_remove is marked as __exit and will
not be present in the kernel).

To fix it let's use platform_driver_probe() instead of
platform_driver_register(), which disables binding/unbinding via sysfs.
This also allows us to mark hp_wmi_bios_setup as __init and discard it
once module is initialized.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
  • Loading branch information
Dmitry Torokhov authored and Matthew Garrett committed Feb 27, 2013
1 parent 34cf1df commit c165b80
Showing 1 changed file with 30 additions and 39 deletions.
69 changes: 30 additions & 39 deletions drivers/platform/x86/hp-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ enum hp_wmi_event_ids {
HPWMI_LOCK_SWITCH = 7,
};

static int hp_wmi_bios_setup(struct platform_device *device);
static int __exit hp_wmi_bios_remove(struct platform_device *device);
static int hp_wmi_resume_handler(struct device *device);

struct bios_args {
u32 signature;
u32 command;
Expand Down Expand Up @@ -160,21 +156,6 @@ struct rfkill2_device {
static int rfkill2_count;
static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];

static const struct dev_pm_ops hp_wmi_pm_ops = {
.resume = hp_wmi_resume_handler,
.restore = hp_wmi_resume_handler,
};

static struct platform_driver hp_wmi_driver = {
.driver = {
.name = "hp-wmi",
.owner = THIS_MODULE,
.pm = &hp_wmi_pm_ops,
},
.probe = hp_wmi_bios_setup,
.remove = hp_wmi_bios_remove,
};

/*
* hp_wmi_perform_query
*
Expand Down Expand Up @@ -812,7 +793,7 @@ static int hp_wmi_rfkill2_setup(struct platform_device *device)
return err;
}

static int hp_wmi_bios_setup(struct platform_device *device)
static int __init hp_wmi_bios_setup(struct platform_device *device)
{
int err;

Expand Down Expand Up @@ -917,12 +898,29 @@ static int hp_wmi_resume_handler(struct device *device)
return 0;
}

static const struct dev_pm_ops hp_wmi_pm_ops = {
.resume = hp_wmi_resume_handler,
.restore = hp_wmi_resume_handler,
};

static struct platform_driver hp_wmi_driver = {
.driver = {
.name = "hp-wmi",
.owner = THIS_MODULE,
.pm = &hp_wmi_pm_ops,
},
.remove = __exit_p(hp_wmi_bios_remove),
};

static int __init hp_wmi_init(void)
{
int err;
int event_capable = wmi_has_guid(HPWMI_EVENT_GUID);
int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID);

if (!bios_capable && !event_capable)
return -ENODEV;

if (event_capable) {
err = hp_wmi_input_setup();
if (err)
Expand All @@ -933,34 +931,29 @@ static int __init hp_wmi_init(void)
}

if (bios_capable) {
err = platform_driver_register(&hp_wmi_driver);
if (err)
goto err_driver_reg;
hp_wmi_platform_dev = platform_device_alloc("hp-wmi", -1);
if (!hp_wmi_platform_dev) {
err = -ENOMEM;
goto err_device_alloc;
hp_wmi_platform_dev =
platform_device_register_simple("hp-wmi", -1, NULL, 0);
if (IS_ERR(hp_wmi_platform_dev)) {
err = PTR_ERR(hp_wmi_platform_dev);
goto err_destroy_input;
}
err = platform_device_add(hp_wmi_platform_dev);

err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
if (err)
goto err_device_add;
goto err_unregister_device;
}

if (!bios_capable && !event_capable)
return -ENODEV;

return 0;

err_device_add:
platform_device_put(hp_wmi_platform_dev);
err_device_alloc:
platform_driver_unregister(&hp_wmi_driver);
err_driver_reg:
err_unregister_device:
platform_device_unregister(hp_wmi_platform_dev);
err_destroy_input:
if (event_capable)
hp_wmi_input_destroy();

return err;
}
module_init(hp_wmi_init);

static void __exit hp_wmi_exit(void)
{
Expand All @@ -972,6 +965,4 @@ static void __exit hp_wmi_exit(void)
platform_driver_unregister(&hp_wmi_driver);
}
}

module_init(hp_wmi_init);
module_exit(hp_wmi_exit);

0 comments on commit c165b80

Please sign in to comment.