aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/dell-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/dell-laptop.c')
-rw-r--r--drivers/platform/x86/dell-laptop.c86
1 files changed, 62 insertions, 24 deletions
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 74909c4aaeea..3780994dc8f2 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -58,6 +58,14 @@ static int da_command_code;
58static int da_num_tokens; 58static int da_num_tokens;
59static struct calling_interface_token *da_tokens; 59static struct calling_interface_token *da_tokens;
60 60
61static struct platform_driver platform_driver = {
62 .driver = {
63 .name = "dell-laptop",
64 .owner = THIS_MODULE,
65 }
66};
67
68static struct platform_device *platform_device;
61static struct backlight_device *dell_backlight_device; 69static struct backlight_device *dell_backlight_device;
62static struct rfkill *wifi_rfkill; 70static struct rfkill *wifi_rfkill;
63static struct rfkill *bluetooth_rfkill; 71static struct rfkill *bluetooth_rfkill;
@@ -74,7 +82,7 @@ static const struct dmi_system_id __initdata dell_device_table[] = {
74 { } 82 { }
75}; 83};
76 84
77static void parse_da_table(const struct dmi_header *dm) 85static void __init parse_da_table(const struct dmi_header *dm)
78{ 86{
79 /* Final token is a terminator, so we don't want to copy it */ 87 /* Final token is a terminator, so we don't want to copy it */
80 int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1; 88 int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1;
@@ -103,7 +111,7 @@ static void parse_da_table(const struct dmi_header *dm)
103 da_num_tokens += tokens; 111 da_num_tokens += tokens;
104} 112}
105 113
106static void find_tokens(const struct dmi_header *dm, void *dummy) 114static void __init find_tokens(const struct dmi_header *dm, void *dummy)
107{ 115{
108 switch (dm->type) { 116 switch (dm->type) {
109 case 0xd4: /* Indexed IO */ 117 case 0xd4: /* Indexed IO */
@@ -197,8 +205,8 @@ static void dell_rfkill_query(struct rfkill *rfkill, void *data)
197 dell_send_request(&buffer, 17, 11); 205 dell_send_request(&buffer, 17, 11);
198 status = buffer.output[1]; 206 status = buffer.output[1];
199 207
200 if (status & BIT(bit)) 208 rfkill_set_sw_state(rfkill, !!(status & BIT(bit)));
201 rfkill_set_hw_state(rfkill, !!(status & BIT(16))); 209 rfkill_set_hw_state(rfkill, !(status & BIT(16)));
202} 210}
203 211
204static const struct rfkill_ops dell_rfkill_ops = { 212static const struct rfkill_ops dell_rfkill_ops = {
@@ -206,7 +214,7 @@ static const struct rfkill_ops dell_rfkill_ops = {
206 .query = dell_rfkill_query, 214 .query = dell_rfkill_query,
207}; 215};
208 216
209static int dell_setup_rfkill(void) 217static int __init dell_setup_rfkill(void)
210{ 218{
211 struct calling_interface_buffer buffer; 219 struct calling_interface_buffer buffer;
212 int status; 220 int status;
@@ -217,7 +225,8 @@ static int dell_setup_rfkill(void)
217 status = buffer.output[1]; 225 status = buffer.output[1];
218 226
219 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { 227 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
220 wifi_rfkill = rfkill_alloc("dell-wifi", NULL, RFKILL_TYPE_WLAN, 228 wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev,
229 RFKILL_TYPE_WLAN,
221 &dell_rfkill_ops, (void *) 1); 230 &dell_rfkill_ops, (void *) 1);
222 if (!wifi_rfkill) { 231 if (!wifi_rfkill) {
223 ret = -ENOMEM; 232 ret = -ENOMEM;
@@ -229,7 +238,8 @@ static int dell_setup_rfkill(void)
229 } 238 }
230 239
231 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { 240 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
232 bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL, 241 bluetooth_rfkill = rfkill_alloc("dell-bluetooth",
242 &platform_device->dev,
233 RFKILL_TYPE_BLUETOOTH, 243 RFKILL_TYPE_BLUETOOTH,
234 &dell_rfkill_ops, (void *) 2); 244 &dell_rfkill_ops, (void *) 2);
235 if (!bluetooth_rfkill) { 245 if (!bluetooth_rfkill) {
@@ -242,7 +252,9 @@ static int dell_setup_rfkill(void)
242 } 252 }
243 253
244 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { 254 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
245 wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN, 255 wwan_rfkill = rfkill_alloc("dell-wwan",
256 &platform_device->dev,
257 RFKILL_TYPE_WWAN,
246 &dell_rfkill_ops, (void *) 3); 258 &dell_rfkill_ops, (void *) 3);
247 if (!wwan_rfkill) { 259 if (!wwan_rfkill) {
248 ret = -ENOMEM; 260 ret = -ENOMEM;
@@ -268,6 +280,22 @@ err_wifi:
268 return ret; 280 return ret;
269} 281}
270 282
283static void dell_cleanup_rfkill(void)
284{
285 if (wifi_rfkill) {
286 rfkill_unregister(wifi_rfkill);
287 rfkill_destroy(wifi_rfkill);
288 }
289 if (bluetooth_rfkill) {
290 rfkill_unregister(bluetooth_rfkill);
291 rfkill_destroy(bluetooth_rfkill);
292 }
293 if (wwan_rfkill) {
294 rfkill_unregister(wwan_rfkill);
295 rfkill_destroy(wwan_rfkill);
296 }
297}
298
271static int dell_send_intensity(struct backlight_device *bd) 299static int dell_send_intensity(struct backlight_device *bd)
272{ 300{
273 struct calling_interface_buffer buffer; 301 struct calling_interface_buffer buffer;
@@ -326,11 +354,23 @@ static int __init dell_init(void)
326 return -ENODEV; 354 return -ENODEV;
327 } 355 }
328 356
357 ret = platform_driver_register(&platform_driver);
358 if (ret)
359 goto fail_platform_driver;
360 platform_device = platform_device_alloc("dell-laptop", -1);
361 if (!platform_device) {
362 ret = -ENOMEM;
363 goto fail_platform_device1;
364 }
365 ret = platform_device_add(platform_device);
366 if (ret)
367 goto fail_platform_device2;
368
329 ret = dell_setup_rfkill(); 369 ret = dell_setup_rfkill();
330 370
331 if (ret) { 371 if (ret) {
332 printk(KERN_WARNING "dell-laptop: Unable to setup rfkill\n"); 372 printk(KERN_WARNING "dell-laptop: Unable to setup rfkill\n");
333 goto out; 373 goto fail_rfkill;
334 } 374 }
335 375
336#ifdef CONFIG_ACPI 376#ifdef CONFIG_ACPI
@@ -352,13 +392,13 @@ static int __init dell_init(void)
352 if (max_intensity) { 392 if (max_intensity) {
353 dell_backlight_device = backlight_device_register( 393 dell_backlight_device = backlight_device_register(
354 "dell_backlight", 394 "dell_backlight",
355 NULL, NULL, 395 &platform_device->dev, NULL,
356 &dell_ops); 396 &dell_ops);
357 397
358 if (IS_ERR(dell_backlight_device)) { 398 if (IS_ERR(dell_backlight_device)) {
359 ret = PTR_ERR(dell_backlight_device); 399 ret = PTR_ERR(dell_backlight_device);
360 dell_backlight_device = NULL; 400 dell_backlight_device = NULL;
361 goto out; 401 goto fail_backlight;
362 } 402 }
363 403
364 dell_backlight_device->props.max_brightness = max_intensity; 404 dell_backlight_device->props.max_brightness = max_intensity;
@@ -368,13 +408,16 @@ static int __init dell_init(void)
368 } 408 }
369 409
370 return 0; 410 return 0;
371out: 411
372 if (wifi_rfkill) 412fail_backlight:
373 rfkill_unregister(wifi_rfkill); 413 dell_cleanup_rfkill();
374 if (bluetooth_rfkill) 414fail_rfkill:
375 rfkill_unregister(bluetooth_rfkill); 415 platform_device_del(platform_device);
376 if (wwan_rfkill) 416fail_platform_device2:
377 rfkill_unregister(wwan_rfkill); 417 platform_device_put(platform_device);
418fail_platform_device1:
419 platform_driver_unregister(&platform_driver);
420fail_platform_driver:
378 kfree(da_tokens); 421 kfree(da_tokens);
379 return ret; 422 return ret;
380} 423}
@@ -382,12 +425,7 @@ out:
382static void __exit dell_exit(void) 425static void __exit dell_exit(void)
383{ 426{
384 backlight_device_unregister(dell_backlight_device); 427 backlight_device_unregister(dell_backlight_device);
385 if (wifi_rfkill) 428 dell_cleanup_rfkill();
386 rfkill_unregister(wifi_rfkill);
387 if (bluetooth_rfkill)
388 rfkill_unregister(bluetooth_rfkill);
389 if (wwan_rfkill)
390 rfkill_unregister(wwan_rfkill);
391} 429}
392 430
393module_init(dell_init); 431module_init(dell_init);