diff options
author | Yong Wang <yong.y.wang@linux.intel.com> | 2010-04-10 21:27:19 -0400 |
---|---|---|
committer | Matthew Garrett <mjg@redhat.com> | 2010-04-12 13:02:43 -0400 |
commit | 45f2c6937ed6066c9a177c4d37f6bd76daa607c0 (patch) | |
tree | 4d2b3cca640ea0ab46a24ed6e1321542b73365e0 /drivers/platform | |
parent | 8124888940be5d9d73a6e04970d73eaec7c582b7 (diff) |
eeepc-wmi: use a platform device as parent device of all sub-devices
Add a platform device and use it as the parent device of all sub-devices.
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>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/eeepc-wmi.c | 102 |
1 files changed, 86 insertions, 16 deletions
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index daed4a476b39..0c9596c97a0f 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
@@ -32,9 +32,12 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/input.h> | 33 | #include <linux/input.h> |
34 | #include <linux/input/sparse-keymap.h> | 34 | #include <linux/input/sparse-keymap.h> |
35 | #include <linux/platform_device.h> | ||
35 | #include <acpi/acpi_bus.h> | 36 | #include <acpi/acpi_bus.h> |
36 | #include <acpi/acpi_drivers.h> | 37 | #include <acpi/acpi_drivers.h> |
37 | 38 | ||
39 | #define EEEPC_WMI_FILE "eeepc-wmi" | ||
40 | |||
38 | MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>"); | 41 | MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>"); |
39 | MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver"); | 42 | MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver"); |
40 | MODULE_LICENSE("GPL"); | 43 | MODULE_LICENSE("GPL"); |
@@ -64,7 +67,7 @@ struct eeepc_wmi { | |||
64 | struct input_dev *inputdev; | 67 | struct input_dev *inputdev; |
65 | }; | 68 | }; |
66 | 69 | ||
67 | static struct eeepc_wmi *eeepc; | 70 | static struct platform_device *platform_device; |
68 | 71 | ||
69 | static void eeepc_wmi_notify(u32 value, void *context) | 72 | static void eeepc_wmi_notify(u32 value, void *context) |
70 | { | 73 | { |
@@ -107,8 +110,9 @@ static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc) | |||
107 | return -ENOMEM; | 110 | return -ENOMEM; |
108 | 111 | ||
109 | eeepc->inputdev->name = "Eee PC WMI hotkeys"; | 112 | eeepc->inputdev->name = "Eee PC WMI hotkeys"; |
110 | eeepc->inputdev->phys = "wmi/input0"; | 113 | eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0"; |
111 | eeepc->inputdev->id.bustype = BUS_HOST; | 114 | eeepc->inputdev->id.bustype = BUS_HOST; |
115 | eeepc->inputdev->dev.parent = &platform_device->dev; | ||
112 | 116 | ||
113 | err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL); | 117 | err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL); |
114 | if (err) | 118 | if (err) |
@@ -137,11 +141,60 @@ static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc) | |||
137 | eeepc->inputdev = NULL; | 141 | eeepc->inputdev = NULL; |
138 | } | 142 | } |
139 | 143 | ||
140 | static int __init eeepc_wmi_init(void) | 144 | static int __devinit eeepc_wmi_platform_probe(struct platform_device *device) |
141 | { | 145 | { |
146 | struct eeepc_wmi *eeepc; | ||
142 | int err; | 147 | int err; |
143 | acpi_status status; | 148 | acpi_status status; |
144 | 149 | ||
150 | eeepc = platform_get_drvdata(device); | ||
151 | |||
152 | err = eeepc_wmi_input_init(eeepc); | ||
153 | if (err) | ||
154 | return err; | ||
155 | |||
156 | status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID, | ||
157 | eeepc_wmi_notify, eeepc); | ||
158 | if (ACPI_FAILURE(status)) { | ||
159 | pr_err("Unable to register notify handler - %d\n", | ||
160 | status); | ||
161 | err = -ENODEV; | ||
162 | goto error_wmi; | ||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | |||
167 | error_wmi: | ||
168 | eeepc_wmi_input_exit(eeepc); | ||
169 | |||
170 | return err; | ||
171 | } | ||
172 | |||
173 | static int __devexit eeepc_wmi_platform_remove(struct platform_device *device) | ||
174 | { | ||
175 | struct eeepc_wmi *eeepc; | ||
176 | |||
177 | eeepc = platform_get_drvdata(device); | ||
178 | wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID); | ||
179 | eeepc_wmi_input_exit(eeepc); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static struct platform_driver platform_driver = { | ||
185 | .driver = { | ||
186 | .name = EEEPC_WMI_FILE, | ||
187 | .owner = THIS_MODULE, | ||
188 | }, | ||
189 | .probe = eeepc_wmi_platform_probe, | ||
190 | .remove = __devexit_p(eeepc_wmi_platform_remove), | ||
191 | }; | ||
192 | |||
193 | static int __init eeepc_wmi_init(void) | ||
194 | { | ||
195 | struct eeepc_wmi *eeepc; | ||
196 | int err; | ||
197 | |||
145 | if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID)) { | 198 | if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID)) { |
146 | pr_warning("No known WMI GUID found\n"); | 199 | pr_warning("No known WMI GUID found\n"); |
147 | return -ENODEV; | 200 | return -ENODEV; |
@@ -151,29 +204,46 @@ static int __init eeepc_wmi_init(void) | |||
151 | if (!eeepc) | 204 | if (!eeepc) |
152 | return -ENOMEM; | 205 | return -ENOMEM; |
153 | 206 | ||
154 | err = eeepc_wmi_input_init(eeepc); | 207 | platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1); |
208 | if (!platform_device) { | ||
209 | pr_warning("Unable to allocate platform device\n"); | ||
210 | err = -ENOMEM; | ||
211 | goto fail_platform; | ||
212 | } | ||
213 | |||
214 | err = platform_device_add(platform_device); | ||
155 | if (err) { | 215 | if (err) { |
156 | kfree(eeepc); | 216 | pr_warning("Unable to add platform device\n"); |
157 | return err; | 217 | goto put_dev; |
158 | } | 218 | } |
159 | 219 | ||
160 | status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID, | 220 | platform_set_drvdata(platform_device, eeepc); |
161 | eeepc_wmi_notify, eeepc); | 221 | |
162 | if (ACPI_FAILURE(status)) { | 222 | err = platform_driver_register(&platform_driver); |
163 | pr_err("Unable to register notify handler - %d\n", | 223 | if (err) { |
164 | status); | 224 | pr_warning("Unable to register platform driver\n"); |
165 | eeepc_wmi_input_exit(eeepc); | 225 | goto del_dev; |
166 | kfree(eeepc); | ||
167 | return -ENODEV; | ||
168 | } | 226 | } |
169 | 227 | ||
170 | return 0; | 228 | return 0; |
229 | |||
230 | del_dev: | ||
231 | platform_device_del(platform_device); | ||
232 | put_dev: | ||
233 | platform_device_put(platform_device); | ||
234 | fail_platform: | ||
235 | kfree(eeepc); | ||
236 | |||
237 | return err; | ||
171 | } | 238 | } |
172 | 239 | ||
173 | static void __exit eeepc_wmi_exit(void) | 240 | static void __exit eeepc_wmi_exit(void) |
174 | { | 241 | { |
175 | wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID); | 242 | struct eeepc_wmi *eeepc; |
176 | eeepc_wmi_input_exit(eeepc); | 243 | |
244 | eeepc = platform_get_drvdata(platform_device); | ||
245 | platform_driver_unregister(&platform_driver); | ||
246 | platform_device_unregister(platform_device); | ||
177 | kfree(eeepc); | 247 | kfree(eeepc); |
178 | } | 248 | } |
179 | 249 | ||