On Fri, Apr 9, 2010 at 5:06 PM, Yong Wang <yong.y.wang@xxxxxxxxxxxxxxx> wrote: > 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; (See my previous comment about style, eeepc-laptop, etc..) We use platform_device in eeepc-laptop and asus-laptop. > 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", Maybe you could use a macro for "eeepc-wmi" as you also use it for platform_device_alloc > + .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 > -- Corentin Chary http://xf.iksaif.net -- 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