diff options
| author | Yong Wang <yong.y.wang@linux.intel.com> | 2010-04-10 21:26:33 -0400 |
|---|---|---|
| committer | Matthew Garrett <mjg@redhat.com> | 2010-04-12 13:02:21 -0400 |
| commit | 8124888940be5d9d73a6e04970d73eaec7c582b7 (patch) | |
| tree | 7de1ad583294c8d43975f697a8565be8b5bc8d83 | |
| parent | 0eddb519b9127c73d53db4bf3ec1d45b13f844d1 (diff) | |
eeepc-wmi: add an eeepc_wmi context structure
Add an eeepc_wmi context structure to manage all the sub-devices
that will be implemented later on. Put input device into it first.
Signed-off-by: Yong Wang <yong.y.wang@intel.com>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Reviewed-by: Corentin Chary <corentincj@iksaif.net>
| -rw-r--r-- | drivers/platform/x86/eeepc-wmi.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index 9f8822658fd7..daed4a476b39 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 27 | |||
| 26 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| 27 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 28 | #include <linux/init.h> | 30 | #include <linux/init.h> |
| @@ -58,10 +60,15 @@ static const struct key_entry eeepc_wmi_keymap[] = { | |||
| 58 | { KE_END, 0}, | 60 | { KE_END, 0}, |
| 59 | }; | 61 | }; |
| 60 | 62 | ||
| 61 | static struct input_dev *eeepc_wmi_input_dev; | 63 | struct eeepc_wmi { |
| 64 | struct input_dev *inputdev; | ||
| 65 | }; | ||
| 66 | |||
| 67 | static struct eeepc_wmi *eeepc; | ||
| 62 | 68 | ||
| 63 | static void eeepc_wmi_notify(u32 value, void *context) | 69 | static void eeepc_wmi_notify(u32 value, void *context) |
| 64 | { | 70 | { |
| 71 | struct eeepc_wmi *eeepc = context; | ||
| 65 | struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; | 72 | struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 66 | union acpi_object *obj; | 73 | union acpi_object *obj; |
| 67 | acpi_status status; | 74 | acpi_status status; |
| @@ -69,7 +76,7 @@ static void eeepc_wmi_notify(u32 value, void *context) | |||
| 69 | 76 | ||
| 70 | status = wmi_get_event_data(value, &response); | 77 | status = wmi_get_event_data(value, &response); |
| 71 | if (status != AE_OK) { | 78 | if (status != AE_OK) { |
| 72 | pr_err("EEEPC WMI: bad event status 0x%x\n", status); | 79 | pr_err("bad event status 0x%x\n", status); |
| 73 | return; | 80 | return; |
| 74 | } | 81 | } |
| 75 | 82 | ||
| @@ -83,64 +90,80 @@ static void eeepc_wmi_notify(u32 value, void *context) | |||
| 83 | else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX) | 90 | else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX) |
| 84 | code = NOTIFY_BRNDOWN_MIN; | 91 | code = NOTIFY_BRNDOWN_MIN; |
| 85 | 92 | ||
| 86 | if (!sparse_keymap_report_event(eeepc_wmi_input_dev, | 93 | if (!sparse_keymap_report_event(eeepc->inputdev, |
| 87 | code, 1, true)) | 94 | code, 1, true)) |
| 88 | pr_info("EEEPC WMI: Unknown key %x pressed\n", code); | 95 | pr_info("Unknown key %x pressed\n", code); |
| 89 | } | 96 | } |
| 90 | 97 | ||
| 91 | kfree(obj); | 98 | kfree(obj); |
| 92 | } | 99 | } |
| 93 | 100 | ||
| 94 | static int eeepc_wmi_input_setup(void) | 101 | static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc) |
| 95 | { | 102 | { |
| 96 | int err; | 103 | int err; |
| 97 | 104 | ||
| 98 | eeepc_wmi_input_dev = input_allocate_device(); | 105 | eeepc->inputdev = input_allocate_device(); |
| 99 | if (!eeepc_wmi_input_dev) | 106 | if (!eeepc->inputdev) |
| 100 | return -ENOMEM; | 107 | return -ENOMEM; |
| 101 | 108 | ||
| 102 | eeepc_wmi_input_dev->name = "Eee PC WMI hotkeys"; | 109 | eeepc->inputdev->name = "Eee PC WMI hotkeys"; |
| 103 | eeepc_wmi_input_dev->phys = "wmi/input0"; | 110 | eeepc->inputdev->phys = "wmi/input0"; |
| 104 | eeepc_wmi_input_dev->id.bustype = BUS_HOST; | 111 | eeepc->inputdev->id.bustype = BUS_HOST; |
| 105 | 112 | ||
| 106 | err = sparse_keymap_setup(eeepc_wmi_input_dev, eeepc_wmi_keymap, NULL); | 113 | err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL); |
| 107 | if (err) | 114 | if (err) |
| 108 | goto err_free_dev; | 115 | goto err_free_dev; |
| 109 | 116 | ||
| 110 | err = input_register_device(eeepc_wmi_input_dev); | 117 | err = input_register_device(eeepc->inputdev); |
| 111 | if (err) | 118 | if (err) |
| 112 | goto err_free_keymap; | 119 | goto err_free_keymap; |
| 113 | 120 | ||
| 114 | return 0; | 121 | return 0; |
| 115 | 122 | ||
| 116 | err_free_keymap: | 123 | err_free_keymap: |
| 117 | sparse_keymap_free(eeepc_wmi_input_dev); | 124 | sparse_keymap_free(eeepc->inputdev); |
| 118 | err_free_dev: | 125 | err_free_dev: |
| 119 | input_free_device(eeepc_wmi_input_dev); | 126 | input_free_device(eeepc->inputdev); |
| 120 | return err; | 127 | return err; |
| 121 | } | 128 | } |
| 122 | 129 | ||
| 130 | static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc) | ||
| 131 | { | ||
| 132 | if (eeepc->inputdev) { | ||
| 133 | sparse_keymap_free(eeepc->inputdev); | ||
| 134 | input_unregister_device(eeepc->inputdev); | ||
| 135 | } | ||
| 136 | |||
| 137 | eeepc->inputdev = NULL; | ||
| 138 | } | ||
| 139 | |||
| 123 | static int __init eeepc_wmi_init(void) | 140 | static int __init eeepc_wmi_init(void) |
| 124 | { | 141 | { |
| 125 | int err; | 142 | int err; |
| 126 | acpi_status status; | 143 | acpi_status status; |
| 127 | 144 | ||
| 128 | if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID)) { | 145 | if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID)) { |
| 129 | pr_warning("EEEPC WMI: No known WMI GUID found\n"); | 146 | pr_warning("No known WMI GUID found\n"); |
| 130 | return -ENODEV; | 147 | return -ENODEV; |
| 131 | } | 148 | } |
| 132 | 149 | ||
| 133 | err = eeepc_wmi_input_setup(); | 150 | eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL); |
| 134 | if (err) | 151 | if (!eeepc) |
| 152 | return -ENOMEM; | ||
| 153 | |||
| 154 | err = eeepc_wmi_input_init(eeepc); | ||
| 155 | if (err) { | ||
| 156 | kfree(eeepc); | ||
| 135 | return err; | 157 | return err; |
| 158 | } | ||
| 136 | 159 | ||
| 137 | status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID, | 160 | status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID, |
| 138 | eeepc_wmi_notify, NULL); | 161 | eeepc_wmi_notify, eeepc); |
| 139 | if (ACPI_FAILURE(status)) { | 162 | if (ACPI_FAILURE(status)) { |
| 140 | sparse_keymap_free(eeepc_wmi_input_dev); | 163 | pr_err("Unable to register notify handler - %d\n", |
| 141 | input_unregister_device(eeepc_wmi_input_dev); | ||
| 142 | pr_err("EEEPC WMI: Unable to register notify handler - %d\n", | ||
| 143 | status); | 164 | status); |
| 165 | eeepc_wmi_input_exit(eeepc); | ||
| 166 | kfree(eeepc); | ||
| 144 | return -ENODEV; | 167 | return -ENODEV; |
| 145 | } | 168 | } |
| 146 | 169 | ||
| @@ -150,8 +173,8 @@ static int __init eeepc_wmi_init(void) | |||
| 150 | static void __exit eeepc_wmi_exit(void) | 173 | static void __exit eeepc_wmi_exit(void) |
| 151 | { | 174 | { |
| 152 | wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID); | 175 | wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID); |
| 153 | sparse_keymap_free(eeepc_wmi_input_dev); | 176 | eeepc_wmi_input_exit(eeepc); |
| 154 | input_unregister_device(eeepc_wmi_input_dev); | 177 | kfree(eeepc); |
| 155 | } | 178 | } |
| 156 | 179 | ||
| 157 | module_init(eeepc_wmi_init); | 180 | module_init(eeepc_wmi_init); |
