Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dell-laptop: Remove rfkill code

The interface just doesn't work on some machines, and Dell haven't been
able to tell us either which machines those are or what we should be
doing instead. This would be fine, except it results in userspace ending
up confused and general sadness. So let's just rip it out for now.

Signed-off-by: Matthew Garrett <mjg@redhat.com>

-289
-289
drivers/platform/x86/dell-laptop.c
··· 21 21 #include <linux/err.h> 22 22 #include <linux/dmi.h> 23 23 #include <linux/io.h> 24 - #include <linux/rfkill.h> 25 24 #include <linux/power_supply.h> 26 25 #include <linux/acpi.h> 27 26 #include <linux/mm.h> ··· 89 90 90 91 static struct platform_device *platform_device; 91 92 static struct backlight_device *dell_backlight_device; 92 - static struct rfkill *wifi_rfkill; 93 - static struct rfkill *bluetooth_rfkill; 94 - static struct rfkill *wwan_rfkill; 95 93 96 94 static const struct dmi_system_id dell_device_table[] __initconst = { 97 95 { ··· 114 118 { } 115 119 }; 116 120 MODULE_DEVICE_TABLE(dmi, dell_device_table); 117 - 118 - static struct dmi_system_id __devinitdata dell_blacklist[] = { 119 - /* Supported by compal-laptop */ 120 - { 121 - .ident = "Dell Mini 9", 122 - .matches = { 123 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 124 - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 910"), 125 - }, 126 - }, 127 - { 128 - .ident = "Dell Mini 10", 129 - .matches = { 130 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 131 - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1010"), 132 - }, 133 - }, 134 - { 135 - .ident = "Dell Mini 10v", 136 - .matches = { 137 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 138 - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"), 139 - }, 140 - }, 141 - { 142 - .ident = "Dell Mini 1012", 143 - .matches = { 144 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 145 - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"), 146 - }, 147 - }, 148 - { 149 - .ident = "Dell Inspiron 11z", 150 - .matches = { 151 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 152 - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1110"), 153 - }, 154 - }, 155 - { 156 - .ident = "Dell Mini 12", 157 - .matches = { 158 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 159 - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1210"), 160 - }, 161 - }, 162 - {} 163 - }; 164 121 165 122 static struct dmi_system_id __devinitdata dell_quirks[] = { 166 123 { ··· 299 350 return buffer; 300 351 } 301 352 302 - /* Derived from information in DellWirelessCtl.cpp: 303 - Class 17, select 11 is radio control. It returns an array of 32-bit values. 304 - 305 - Input byte 0 = 0: Wireless information 306 - 307 - result[0]: return code 308 - result[1]: 309 - Bit 0: Hardware switch supported 310 - Bit 1: Wifi locator supported 311 - Bit 2: Wifi is supported 312 - Bit 3: Bluetooth is supported 313 - Bit 4: WWAN is supported 314 - Bit 5: Wireless keyboard supported 315 - Bits 6-7: Reserved 316 - Bit 8: Wifi is installed 317 - Bit 9: Bluetooth is installed 318 - Bit 10: WWAN is installed 319 - Bits 11-15: Reserved 320 - Bit 16: Hardware switch is on 321 - Bit 17: Wifi is blocked 322 - Bit 18: Bluetooth is blocked 323 - Bit 19: WWAN is blocked 324 - Bits 20-31: Reserved 325 - result[2]: NVRAM size in bytes 326 - result[3]: NVRAM format version number 327 - 328 - Input byte 0 = 2: Wireless switch configuration 329 - result[0]: return code 330 - result[1]: 331 - Bit 0: Wifi controlled by switch 332 - Bit 1: Bluetooth controlled by switch 333 - Bit 2: WWAN controlled by switch 334 - Bits 3-6: Reserved 335 - Bit 7: Wireless switch config locked 336 - Bit 8: Wifi locator enabled 337 - Bits 9-14: Reserved 338 - Bit 15: Wifi locator setting locked 339 - Bits 16-31: Reserved 340 - */ 341 - 342 - static int dell_rfkill_set(void *data, bool blocked) 343 - { 344 - int disable = blocked ? 1 : 0; 345 - unsigned long radio = (unsigned long)data; 346 - int hwswitch_bit = (unsigned long)data - 1; 347 - int ret = 0; 348 - 349 - get_buffer(); 350 - dell_send_request(buffer, 17, 11); 351 - 352 - /* If the hardware switch controls this radio, and the hardware 353 - switch is disabled, don't allow changing the software state */ 354 - if ((hwswitch_state & BIT(hwswitch_bit)) && 355 - !(buffer->output[1] & BIT(16))) { 356 - ret = -EINVAL; 357 - goto out; 358 - } 359 - 360 - buffer->input[0] = (1 | (radio<<8) | (disable << 16)); 361 - dell_send_request(buffer, 17, 11); 362 - 363 - out: 364 - release_buffer(); 365 - return ret; 366 - } 367 - 368 - static void dell_rfkill_query(struct rfkill *rfkill, void *data) 369 - { 370 - int status; 371 - int bit = (unsigned long)data + 16; 372 - int hwswitch_bit = (unsigned long)data - 1; 373 - 374 - get_buffer(); 375 - dell_send_request(buffer, 17, 11); 376 - status = buffer->output[1]; 377 - release_buffer(); 378 - 379 - rfkill_set_sw_state(rfkill, !!(status & BIT(bit))); 380 - 381 - if (hwswitch_state & (BIT(hwswitch_bit))) 382 - rfkill_set_hw_state(rfkill, !(status & BIT(16))); 383 - } 384 - 385 - static const struct rfkill_ops dell_rfkill_ops = { 386 - .set_block = dell_rfkill_set, 387 - .query = dell_rfkill_query, 388 - }; 389 - 390 353 static struct dentry *dell_laptop_dir; 391 354 392 355 static int dell_debugfs_show(struct seq_file *s, void *data) ··· 367 506 .llseek = seq_lseek, 368 507 .release = single_release, 369 508 }; 370 - 371 - static void dell_update_rfkill(struct work_struct *ignored) 372 - { 373 - if (wifi_rfkill) 374 - dell_rfkill_query(wifi_rfkill, (void *)1); 375 - if (bluetooth_rfkill) 376 - dell_rfkill_query(bluetooth_rfkill, (void *)2); 377 - if (wwan_rfkill) 378 - dell_rfkill_query(wwan_rfkill, (void *)3); 379 - } 380 - static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill); 381 - 382 - 383 - static int __init dell_setup_rfkill(void) 384 - { 385 - int status; 386 - int ret; 387 - 388 - if (dmi_check_system(dell_blacklist)) { 389 - pr_info("Blacklisted hardware detected - not enabling rfkill\n"); 390 - return 0; 391 - } 392 - 393 - get_buffer(); 394 - dell_send_request(buffer, 17, 11); 395 - status = buffer->output[1]; 396 - buffer->input[0] = 0x2; 397 - dell_send_request(buffer, 17, 11); 398 - hwswitch_state = buffer->output[1]; 399 - release_buffer(); 400 - 401 - if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { 402 - wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, 403 - RFKILL_TYPE_WLAN, 404 - &dell_rfkill_ops, (void *) 1); 405 - if (!wifi_rfkill) { 406 - ret = -ENOMEM; 407 - goto err_wifi; 408 - } 409 - ret = rfkill_register(wifi_rfkill); 410 - if (ret) 411 - goto err_wifi; 412 - } 413 - 414 - if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { 415 - bluetooth_rfkill = rfkill_alloc("dell-bluetooth", 416 - &platform_device->dev, 417 - RFKILL_TYPE_BLUETOOTH, 418 - &dell_rfkill_ops, (void *) 2); 419 - if (!bluetooth_rfkill) { 420 - ret = -ENOMEM; 421 - goto err_bluetooth; 422 - } 423 - ret = rfkill_register(bluetooth_rfkill); 424 - if (ret) 425 - goto err_bluetooth; 426 - } 427 - 428 - if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { 429 - wwan_rfkill = rfkill_alloc("dell-wwan", 430 - &platform_device->dev, 431 - RFKILL_TYPE_WWAN, 432 - &dell_rfkill_ops, (void *) 3); 433 - if (!wwan_rfkill) { 434 - ret = -ENOMEM; 435 - goto err_wwan; 436 - } 437 - ret = rfkill_register(wwan_rfkill); 438 - if (ret) 439 - goto err_wwan; 440 - } 441 - 442 - return 0; 443 - err_wwan: 444 - rfkill_destroy(wwan_rfkill); 445 - if (bluetooth_rfkill) 446 - rfkill_unregister(bluetooth_rfkill); 447 - err_bluetooth: 448 - rfkill_destroy(bluetooth_rfkill); 449 - if (wifi_rfkill) 450 - rfkill_unregister(wifi_rfkill); 451 - err_wifi: 452 - rfkill_destroy(wifi_rfkill); 453 - 454 - return ret; 455 - } 456 - 457 - static void dell_cleanup_rfkill(void) 458 - { 459 - if (wifi_rfkill) { 460 - rfkill_unregister(wifi_rfkill); 461 - rfkill_destroy(wifi_rfkill); 462 - } 463 - if (bluetooth_rfkill) { 464 - rfkill_unregister(bluetooth_rfkill); 465 - rfkill_destroy(bluetooth_rfkill); 466 - } 467 - if (wwan_rfkill) { 468 - rfkill_unregister(wwan_rfkill); 469 - rfkill_destroy(wwan_rfkill); 470 - } 471 - } 472 509 473 510 static int dell_send_intensity(struct backlight_device *bd) 474 511 { ··· 459 700 led_classdev_unregister(&touchpad_led); 460 701 } 461 702 462 - static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str, 463 - struct serio *port) 464 - { 465 - static bool extended; 466 - 467 - if (str & 0x20) 468 - return false; 469 - 470 - if (unlikely(data == 0xe0)) { 471 - extended = true; 472 - return false; 473 - } else if (unlikely(extended)) { 474 - switch (data) { 475 - case 0x8: 476 - schedule_delayed_work(&dell_rfkill_work, 477 - round_jiffies_relative(HZ)); 478 - break; 479 - } 480 - extended = false; 481 - } 482 - 483 - return false; 484 - } 485 - 486 703 static int __init dell_init(void) 487 704 { 488 705 int max_intensity = 0; ··· 500 765 goto fail_buffer; 501 766 buffer = page_address(bufferpage); 502 767 503 - ret = dell_setup_rfkill(); 504 - 505 - if (ret) { 506 - pr_warn("Unable to setup rfkill\n"); 507 - goto fail_rfkill; 508 - } 509 - 510 - ret = i8042_install_filter(dell_laptop_i8042_filter); 511 - if (ret) { 512 - pr_warn("Unable to install key filter\n"); 513 - goto fail_filter; 514 - } 515 - 516 768 if (quirks && quirks->touchpad_led) 517 769 touchpad_led_init(&platform_device->dev); 518 770 519 771 dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); 520 - if (dell_laptop_dir != NULL) 521 - debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, 522 - &dell_debugfs_fops); 523 772 524 773 #ifdef CONFIG_ACPI 525 774 /* In the event of an ACPI backlight being available, don't ··· 546 827 return 0; 547 828 548 829 fail_backlight: 549 - i8042_remove_filter(dell_laptop_i8042_filter); 550 - cancel_delayed_work_sync(&dell_rfkill_work); 551 - fail_filter: 552 - dell_cleanup_rfkill(); 553 - fail_rfkill: 554 830 free_page((unsigned long)bufferpage); 555 831 fail_buffer: 556 832 platform_device_del(platform_device); ··· 563 849 debugfs_remove_recursive(dell_laptop_dir); 564 850 if (quirks && quirks->touchpad_led) 565 851 touchpad_led_exit(); 566 - i8042_remove_filter(dell_laptop_i8042_filter); 567 - cancel_delayed_work_sync(&dell_rfkill_work); 568 852 backlight_device_unregister(dell_backlight_device); 569 - dell_cleanup_rfkill(); 570 853 if (platform_device) { 571 854 platform_device_unregister(platform_device); 572 855 platform_driver_unregister(&platform_driver);