Add a platform device into eeepc_wmi context structure and use it as the parent device of all sub-devices. Signed-off-by: Yong Wang <yong.y.wang@xxxxxxxxx> --- drivers/platform/x86/eeepc-wmi.c | 144 +++++++++++++++++++++++++++----------- 1 files changed, 104 insertions(+), 40 deletions(-) diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index f030410..0f5ab6a 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c @@ -30,6 +30,7 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/input/sparse-keymap.h> +#include <linux/platform_device.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> @@ -59,9 +60,50 @@ static const struct key_entry eeepc_wmi_keymap[] = { }; struct eeepc_wmi { + struct platform_device *platform_dev; struct input_dev *input_dev; }; +static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc_wmi) +{ + int err; + + eeepc_wmi->input_dev = input_allocate_device(); + if (!eeepc_wmi->input_dev) + return -ENOMEM; + + eeepc_wmi->input_dev->name = "Eee PC WMI hotkeys"; + eeepc_wmi->input_dev->phys = "wmi/input0"; + eeepc_wmi->input_dev->id.bustype = BUS_HOST; + eeepc_wmi->input_dev->dev.parent = &eeepc_wmi->platform_dev->dev; + + err = sparse_keymap_setup(eeepc_wmi->input_dev, eeepc_wmi_keymap, NULL); + if (err) + goto err_free_dev; + + err = input_register_device(eeepc_wmi->input_dev); + if (err) + goto err_free_keymap; + + return 0; + +err_free_keymap: + sparse_keymap_free(eeepc_wmi->input_dev); +err_free_dev: + input_free_device(eeepc_wmi->input_dev); + return err; +} + +static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc_wmi) +{ + if (eeepc_wmi->input_dev) { + sparse_keymap_free(eeepc_wmi->input_dev); + input_unregister_device(eeepc_wmi->input_dev); + } + + eeepc_wmi->input_dev = NULL; +} + static void eeepc_wmi_notify(u32 value, void *context) { struct eeepc_wmi *eeepc_wmi = (struct eeepc_wmi *)context; @@ -94,50 +136,59 @@ static void eeepc_wmi_notify(u32 value, void *context) kfree(obj); } -static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc_wmi) +static int __devinit eeepc_wmi_platform_probe(struct platform_device *device) { + struct eeepc_wmi *eeepc_wmi; int err; + acpi_status status; - eeepc_wmi->input_dev = input_allocate_device(); - if (!eeepc_wmi->input_dev) - return -ENOMEM; - - eeepc_wmi->input_dev->name = "Eee PC WMI hotkeys"; - eeepc_wmi->input_dev->phys = "wmi/input0"; - eeepc_wmi->input_dev->id.bustype = BUS_HOST; + eeepc_wmi = wmi_get_driver_data(EEEPC_WMI_EVENT_GUID); - err = sparse_keymap_setup(eeepc_wmi->input_dev, eeepc_wmi_keymap, NULL); + err = eeepc_wmi_input_init(eeepc_wmi); if (err) - goto err_free_dev; + return err; - err = input_register_device(eeepc_wmi->input_dev); - if (err) - goto err_free_keymap; + status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID, + eeepc_wmi_notify, eeepc_wmi); + if (ACPI_FAILURE(status)) { + pr_err("EEEPC WMI: Unable to register notify handler - %d\n", + status); + err = -ENODEV; + goto error_wmi; + } return 0; -err_free_keymap: - sparse_keymap_free(eeepc_wmi->input_dev); -err_free_dev: - input_free_device(eeepc_wmi->input_dev); +error_wmi: + eeepc_wmi_input_exit(eeepc_wmi); + return err; } -static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc_wmi) +static int __devexit eeepc_wmi_platform_remove(struct platform_device *device) { - if (eeepc_wmi->input_dev) { - sparse_keymap_free(eeepc_wmi->input_dev); - input_unregister_device(eeepc_wmi->input_dev); - } + struct eeepc_wmi *eeepc_wmi; - eeepc_wmi->input_dev = NULL; + eeepc_wmi = wmi_get_driver_data(EEEPC_WMI_EVENT_GUID); + wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID); + eeepc_wmi_input_exit(eeepc_wmi); + + return 0; } +static struct platform_driver platform_driver = { + .driver = { + .name = "eeepc-wmi", + .owner = THIS_MODULE, + }, + .probe = eeepc_wmi_platform_probe, + .remove = __devexit_p(eeepc_wmi_platform_remove), +}; + static int __init eeepc_wmi_init(void) { - static struct eeepc_wmi *eeepc_wmi; + struct eeepc_wmi *eeepc_wmi; int err; - acpi_status status; if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID)) { pr_warning("EEEPC WMI: No known WMI GUID found\n"); @@ -150,34 +201,47 @@ static int __init eeepc_wmi_init(void) return -ENOMEM; } - wmi_set_driver_data(EEEPC_WMI_EVENT_GUID, eeepc_wmi); - err = eeepc_wmi_input_init(eeepc_wmi); + eeepc_wmi->platform_dev = platform_device_alloc("eeepc-wmi", -1); + if (!eeepc_wmi->platform_dev) { + pr_warning("EEEPC WMI: Unable to allocate platform device\n"); + err = -ENOMEM; + goto fail_platform; + } + + err = platform_device_add(eeepc_wmi->platform_dev); if (err) { - kfree(eeepc_wmi); - return err; + pr_warning("EEEPC WMI: Unable to add platform device\n"); + goto put_dev; } - status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID, - eeepc_wmi_notify, eeepc_wmi); - if (ACPI_FAILURE(status)) { - pr_err("EEEPC WMI: Unable to register notify handler - %d\n", - status); - eeepc_wmi_input_exit(eeepc_wmi); - kfree(eeepc_wmi); - return -ENODEV; + wmi_set_driver_data(EEEPC_WMI_EVENT_GUID, eeepc_wmi); + + err = platform_driver_register(&platform_driver); + if (err) { + pr_warning("EEEPC WMI: Unable to register platform driver\n"); + goto del_dev; } return 0; + +del_dev: + platform_device_del(eeepc_wmi->platform_dev); +put_dev: + platform_device_put(eeepc_wmi->platform_dev); +fail_platform: + kfree(eeepc_wmi); + + return err; } static void __exit eeepc_wmi_exit(void) { - static struct eeepc_wmi *eeepc_wmi; + struct eeepc_wmi *eeepc_wmi; eeepc_wmi = wmi_get_driver_data(EEEPC_WMI_EVENT_GUID); - wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID); - eeepc_wmi_input_exit(eeepc_wmi); + platform_driver_unregister(&platform_driver); + platform_device_unregister(eeepc_wmi->platform_dev); kfree(eeepc_wmi); } -- 1.5.5.1 -- To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html