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.c78
1 files changed, 41 insertions, 37 deletions
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index c608b1d33f4a..fed4111ac31a 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -559,19 +559,45 @@ static void dell_update_rfkill(struct work_struct *ignored)
559} 559}
560static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill); 560static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill);
561 561
562static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
563 struct serio *port)
564{
565 static bool extended;
566
567 if (str & 0x20)
568 return false;
569
570 if (unlikely(data == 0xe0)) {
571 extended = true;
572 return false;
573 } else if (unlikely(extended)) {
574 switch (data) {
575 case 0x8:
576 schedule_delayed_work(&dell_rfkill_work,
577 round_jiffies_relative(HZ / 4));
578 break;
579 }
580 extended = false;
581 }
582
583 return false;
584}
562 585
563static int __init dell_setup_rfkill(void) 586static int __init dell_setup_rfkill(void)
564{ 587{
565 int status; 588 int status, ret, whitelisted;
566 int ret;
567 const char *product; 589 const char *product;
568 590
569 /* 591 /*
570 * rfkill causes trouble on various non Latitudes, according to Dell 592 * rfkill support causes trouble on various models, mostly Inspirons.
571 * actually testing the rfkill functionality is only done on Latitudes. 593 * So we whitelist certain series, and don't support rfkill on others.
572 */ 594 */
595 whitelisted = 0;
573 product = dmi_get_system_info(DMI_PRODUCT_NAME); 596 product = dmi_get_system_info(DMI_PRODUCT_NAME);
574 if (!force_rfkill && (!product || strncmp(product, "Latitude", 8))) 597 if (product && (strncmp(product, "Latitude", 8) == 0 ||
598 strncmp(product, "Precision", 9) == 0))
599 whitelisted = 1;
600 if (!force_rfkill && !whitelisted)
575 return 0; 601 return 0;
576 602
577 get_buffer(); 603 get_buffer();
@@ -633,7 +659,16 @@ static int __init dell_setup_rfkill(void)
633 goto err_wwan; 659 goto err_wwan;
634 } 660 }
635 661
662 ret = i8042_install_filter(dell_laptop_i8042_filter);
663 if (ret) {
664 pr_warn("Unable to install key filter\n");
665 goto err_filter;
666 }
667
636 return 0; 668 return 0;
669err_filter:
670 if (wwan_rfkill)
671 rfkill_unregister(wwan_rfkill);
637err_wwan: 672err_wwan:
638 rfkill_destroy(wwan_rfkill); 673 rfkill_destroy(wwan_rfkill);
639 if (bluetooth_rfkill) 674 if (bluetooth_rfkill)
@@ -684,7 +719,7 @@ static int dell_send_intensity(struct backlight_device *bd)
684 719
685out: 720out:
686 release_buffer(); 721 release_buffer();
687 return 0; 722 return ret;
688} 723}
689 724
690static int dell_get_intensity(struct backlight_device *bd) 725static int dell_get_intensity(struct backlight_device *bd)
@@ -755,30 +790,6 @@ static void touchpad_led_exit(void)
755 led_classdev_unregister(&touchpad_led); 790 led_classdev_unregister(&touchpad_led);
756} 791}
757 792
758static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
759 struct serio *port)
760{
761 static bool extended;
762
763 if (str & 0x20)
764 return false;
765
766 if (unlikely(data == 0xe0)) {
767 extended = true;
768 return false;
769 } else if (unlikely(extended)) {
770 switch (data) {
771 case 0x8:
772 schedule_delayed_work(&dell_rfkill_work,
773 round_jiffies_relative(HZ / 4));
774 break;
775 }
776 extended = false;
777 }
778
779 return false;
780}
781
782static int __init dell_init(void) 793static int __init dell_init(void)
783{ 794{
784 int max_intensity = 0; 795 int max_intensity = 0;
@@ -828,12 +839,6 @@ static int __init dell_init(void)
828 goto fail_rfkill; 839 goto fail_rfkill;
829 } 840 }
830 841
831 ret = i8042_install_filter(dell_laptop_i8042_filter);
832 if (ret) {
833 pr_warn("Unable to install key filter\n");
834 goto fail_filter;
835 }
836
837 if (quirks && quirks->touchpad_led) 842 if (quirks && quirks->touchpad_led)
838 touchpad_led_init(&platform_device->dev); 843 touchpad_led_init(&platform_device->dev);
839 844
@@ -885,7 +890,6 @@ static int __init dell_init(void)
885fail_backlight: 890fail_backlight:
886 i8042_remove_filter(dell_laptop_i8042_filter); 891 i8042_remove_filter(dell_laptop_i8042_filter);
887 cancel_delayed_work_sync(&dell_rfkill_work); 892 cancel_delayed_work_sync(&dell_rfkill_work);
888fail_filter:
889 dell_cleanup_rfkill(); 893 dell_cleanup_rfkill();
890fail_rfkill: 894fail_rfkill:
891 free_page((unsigned long)bufferpage); 895 free_page((unsigned long)bufferpage);