Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platf...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Jul 2011 19:47:09 +0000 (12:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Jul 2011 19:47:09 +0000 (12:47 -0700)
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86:
  hp-wmi: fix use after free
  dell-laptop - using buffer without mutex_lock
  Revert: "dell-laptop: Toggle the unsupported hardware killswitch"
  platform-drivers-x86: set backlight type to BACKLIGHT_PLATFORM
  thinkpad-acpi: handle HKEY 0x4010, 0x4011 events
  drivers/platform/x86: Fix memory leak
  thinkpad-acpi: handle some new HKEY 0x60xx events
  acer-wmi: fix bitwise bug when set device state
  acer-wmi: Only update rfkill status for associated hotkey events

Documentation/laptops/thinkpad-acpi.txt
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/compal-laptop.c
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/intel_oaktrail.c
drivers/platform/x86/thinkpad_acpi.c

index 1565eef..6181548 100644 (file)
@@ -534,6 +534,8 @@ Events that are never propagated by the driver:
 0x2404         System is waking up from hibernation to undock
 0x2405         System is waking up from hibernation to eject bay
 0x5010         Brightness level changed/control event
+0x6000         KEYBOARD: Numlock key pressed
+0x6005         KEYBOARD: Fn key pressed (TO BE VERIFIED)
 
 Events that are propagated by the driver to userspace:
 
@@ -545,6 +547,8 @@ Events that are propagated by the driver to userspace:
 0x3006         Bay hotplug request (hint to power up SATA link when
                the optical drive tray is ejected)
 0x4003         Undocked (see 0x2x04), can sleep again
+0x4010         Docked into hotplug port replicator (non-ACPI dock)
+0x4011         Undocked from hotplug port replicator (non-ACPI dock)
 0x500B         Tablet pen inserted into its storage bay
 0x500C         Tablet pen removed from its storage bay
 0x6011         ALARM: battery is too hot
@@ -552,6 +556,7 @@ Events that are propagated by the driver to userspace:
 0x6021         ALARM: a sensor is too hot
 0x6022         ALARM: a sensor is extremely hot
 0x6030         System thermal table changed
+0x6040         Nvidia Optimus/AC adapter related (TO BE VERIFIED)
 
 Battery nearly empty alarms are a last resort attempt to get the
 operating system to hibernate or shutdown cleanly (0x2313), or shutdown
index 005417b..e1c4938 100644 (file)
@@ -1156,9 +1156,9 @@ static acpi_status wmid3_set_device_status(u32 value, u16 device)
        struct wmid3_gds_input_param params = {
                .function_num = 0x1,
                .hotkey_number = 0x01,
-               .devices = ACER_WMID3_GDS_WIRELESS &
-                               ACER_WMID3_GDS_THREEG &
-                               ACER_WMID3_GDS_WIMAX &
+               .devices = ACER_WMID3_GDS_WIRELESS |
+                               ACER_WMID3_GDS_THREEG |
+                               ACER_WMID3_GDS_WIMAX |
                                ACER_WMID3_GDS_BLUETOOTH,
        };
        struct acpi_buffer input = {
@@ -1445,6 +1445,8 @@ static void acer_wmi_notify(u32 value, void *context)
        union acpi_object *obj;
        struct event_return_value return_value;
        acpi_status status;
+       u16 device_state;
+       const struct key_entry *key;
 
        status = wmi_get_event_data(value, &response);
        if (status != AE_OK) {
@@ -1472,23 +1474,32 @@ static void acer_wmi_notify(u32 value, void *context)
 
        switch (return_value.function) {
        case WMID_HOTKEY_EVENT:
-               if (return_value.device_state) {
-                       u16 device_state = return_value.device_state;
-                       pr_debug("device state: 0x%x\n", device_state);
-                       if (has_cap(ACER_CAP_WIRELESS))
-                               rfkill_set_sw_state(wireless_rfkill,
-                               !(device_state & ACER_WMID3_GDS_WIRELESS));
-                       if (has_cap(ACER_CAP_BLUETOOTH))
-                               rfkill_set_sw_state(bluetooth_rfkill,
-                               !(device_state & ACER_WMID3_GDS_BLUETOOTH));
-                       if (has_cap(ACER_CAP_THREEG))
-                               rfkill_set_sw_state(threeg_rfkill,
-                               !(device_state & ACER_WMID3_GDS_THREEG));
-               }
-               if (!sparse_keymap_report_event(acer_wmi_input_dev,
-                               return_value.key_num, 1, true))
+               device_state = return_value.device_state;
+               pr_debug("device state: 0x%x\n", device_state);
+
+               key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev,
+                                                       return_value.key_num);
+               if (!key) {
                        pr_warn("Unknown key number - 0x%x\n",
                                return_value.key_num);
+               } else {
+                       switch (key->keycode) {
+                       case KEY_WLAN:
+                       case KEY_BLUETOOTH:
+                               if (has_cap(ACER_CAP_WIRELESS))
+                                       rfkill_set_sw_state(wireless_rfkill,
+                                               !(device_state & ACER_WMID3_GDS_WIRELESS));
+                               if (has_cap(ACER_CAP_THREEG))
+                                       rfkill_set_sw_state(threeg_rfkill,
+                                               !(device_state & ACER_WMID3_GDS_THREEG));
+                               if (has_cap(ACER_CAP_BLUETOOTH))
+                                       rfkill_set_sw_state(bluetooth_rfkill,
+                                               !(device_state & ACER_WMID3_GDS_BLUETOOTH));
+                               break;
+                       }
+                       sparse_keymap_report_entry(acer_wmi_input_dev, key,
+                                                  1, true);
+               }
                break;
        default:
                pr_warn("Unknown function number - %d - %d\n",
index 00460cb..3c7857c 100644 (file)
@@ -1025,6 +1025,7 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus)
                return power;
 
        memset(&props, 0, sizeof(struct backlight_properties));
+       props.type = BACKLIGHT_PLATFORM;
        props.max_brightness = max;
        bd = backlight_device_register(asus->driver->name,
                                       &asus->platform_device->dev, asus,
index 3f204fd..8877b83 100644 (file)
@@ -1030,8 +1030,10 @@ static int __devinit compal_probe(struct platform_device *pdev)
        initialize_fan_control_data(data);
 
        err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group);
-       if (err)
+       if (err) {
+               kfree(data);
                return err;
+       }
 
        data->hwmon_dev = hwmon_device_register(&pdev->dev);
        if (IS_ERR(data->hwmon_dev)) {
index d3841de..e39ab1d 100644 (file)
@@ -292,12 +292,9 @@ static int dell_rfkill_set(void *data, bool blocked)
        dell_send_request(buffer, 17, 11);
 
        /* If the hardware switch controls this radio, and the hardware
-          switch is disabled, don't allow changing the software state.
-          If the hardware switch is reported as not supported, always
-          fire the SMI to toggle the killswitch. */
+          switch is disabled, don't allow changing the software state */
        if ((hwswitch_state & BIT(hwswitch_bit)) &&
-           !(buffer->output[1] & BIT(16)) &&
-           (buffer->output[1] & BIT(0))) {
+           !(buffer->output[1] & BIT(16))) {
                ret = -EINVAL;
                goto out;
        }
@@ -403,23 +400,6 @@ static const struct file_operations dell_debugfs_fops = {
 
 static void dell_update_rfkill(struct work_struct *ignored)
 {
-       int status;
-
-       get_buffer();
-       dell_send_request(buffer, 17, 11);
-       status = buffer->output[1];
-       release_buffer();
-
-       /* if hardware rfkill is not supported, set it explicitly */
-       if (!(status & BIT(0))) {
-               if (wifi_rfkill)
-                       dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17));
-               if (bluetooth_rfkill)
-                       dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18));
-               if (wwan_rfkill)
-                       dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19));
-       }
-
        if (wifi_rfkill)
                dell_rfkill_query(wifi_rfkill, (void *)1);
        if (bluetooth_rfkill)
@@ -560,11 +540,11 @@ static int dell_get_intensity(struct backlight_device *bd)
        else
                dell_send_request(buffer, 0, 1);
 
+       ret = buffer->output[1];
+
 out:
        release_buffer();
-       if (ret)
-               return ret;
-       return buffer->output[1];
+       return ret;
 }
 
 static const struct backlight_ops dell_ops = {
index f94017b..e2faa3c 100644 (file)
@@ -207,6 +207,7 @@ static int hp_wmi_perform_query(int query, int write, void *buffer,
        };
        struct acpi_buffer input = { sizeof(struct bios_args), &args };
        struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+       u32 rc;
 
        if (WARN_ON(insize > sizeof(args.data)))
                return -EINVAL;
@@ -224,13 +225,13 @@ static int hp_wmi_perform_query(int query, int write, void *buffer,
        }
 
        bios_return = (struct bios_return *)obj->buffer.pointer;
+       rc = bios_return->return_code;
 
-       if (bios_return->return_code) {
-               if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE)
-                       pr_warn("query 0x%x returned error 0x%x\n",
-                               query, bios_return->return_code);
+       if (rc) {
+               if (rc != HPWMI_RET_UNKNOWN_CMDTYPE)
+                       pr_warn("query 0x%x returned error 0x%x\n", query, rc);
                kfree(obj);
-               return bios_return->return_code;
+               return rc;
        }
 
        if (!outsize) {
index e936364..7f88c79 100644 (file)
@@ -250,6 +250,7 @@ static int oaktrail_backlight_init(void)
        struct backlight_properties props;
 
        memset(&props, 0, sizeof(struct backlight_properties));
+       props.type = BACKLIGHT_PLATFORM;
        props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX;
        bd = backlight_device_register(DRIVER_NAME,
                                       &oaktrail_device->dev, NULL,
index 77f6e70..26c5b11 100644 (file)
@@ -184,6 +184,10 @@ enum tpacpi_hkey_event_t {
 
        /* Misc bay events */
        TP_HKEY_EV_OPTDRV_EJ            = 0x3006, /* opt. drive tray ejected */
+       TP_HKEY_EV_HOTPLUG_DOCK         = 0x4010, /* docked into hotplug dock
+                                                    or port replicator */
+       TP_HKEY_EV_HOTPLUG_UNDOCK       = 0x4011, /* undocked from hotplug
+                                                    dock or port replicator */
 
        /* User-interface events */
        TP_HKEY_EV_LID_CLOSE            = 0x5001, /* laptop lid closed */
@@ -194,6 +198,10 @@ enum tpacpi_hkey_event_t {
        TP_HKEY_EV_PEN_REMOVED          = 0x500c, /* tablet pen removed */
        TP_HKEY_EV_BRGHT_CHANGED        = 0x5010, /* backlight control event */
 
+       /* Key-related user-interface events */
+       TP_HKEY_EV_KEY_NUMLOCK          = 0x6000, /* NumLock key pressed */
+       TP_HKEY_EV_KEY_FN               = 0x6005, /* Fn key pressed? E420 */
+
        /* Thermal events */
        TP_HKEY_EV_ALARM_BAT_HOT        = 0x6011, /* battery too hot */
        TP_HKEY_EV_ALARM_BAT_XHOT       = 0x6012, /* battery critically hot */
@@ -201,6 +209,10 @@ enum tpacpi_hkey_event_t {
        TP_HKEY_EV_ALARM_SENSOR_XHOT    = 0x6022, /* sensor critically hot */
        TP_HKEY_EV_THM_TABLE_CHANGED    = 0x6030, /* thermal table changed */
 
+       TP_HKEY_EV_UNK_6040             = 0x6040, /* Related to AC change?
+                                                    some sort of APM hint,
+                                                    W520 */
+
        /* Misc */
        TP_HKEY_EV_RFKILL_CHANGED       = 0x7000, /* rfkill switch changed */
 };
@@ -3513,6 +3525,34 @@ static bool hotkey_notify_wakeup(const u32 hkey,
        return true;
 }
 
+static bool hotkey_notify_dockevent(const u32 hkey,
+                                bool *send_acpi_ev,
+                                bool *ignore_acpi_ev)
+{
+       /* 0x4000-0x4FFF: dock-related events */
+       *send_acpi_ev = true;
+       *ignore_acpi_ev = false;
+
+       switch (hkey) {
+       case TP_HKEY_EV_UNDOCK_ACK:
+               /* ACPI undock operation completed after wakeup */
+               hotkey_autosleep_ack = 1;
+               pr_info("undocked\n");
+               hotkey_wakeup_hotunplug_complete_notify_change();
+               return true;
+
+       case TP_HKEY_EV_HOTPLUG_DOCK: /* docked to port replicator */
+               pr_info("docked into hotplug port replicator\n");
+               return true;
+       case TP_HKEY_EV_HOTPLUG_UNDOCK: /* undocked from port replicator */
+               pr_info("undocked from hotplug port replicator\n");
+               return true;
+
+       default:
+               return false;
+       }
+}
+
 static bool hotkey_notify_usrevent(const u32 hkey,
                                 bool *send_acpi_ev,
                                 bool *ignore_acpi_ev)
@@ -3547,13 +3587,13 @@ static bool hotkey_notify_usrevent(const u32 hkey,
 
 static void thermal_dump_all_sensors(void);
 
-static bool hotkey_notify_thermal(const u32 hkey,
+static bool hotkey_notify_6xxx(const u32 hkey,
                                 bool *send_acpi_ev,
                                 bool *ignore_acpi_ev)
 {
        bool known = true;
 
-       /* 0x6000-0x6FFF: thermal alarms */
+       /* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */
        *send_acpi_ev = true;
        *ignore_acpi_ev = false;
 
@@ -3582,8 +3622,17 @@ static bool hotkey_notify_thermal(const u32 hkey,
                         "a sensor reports something is extremely hot!\n");
                /* recommended action: immediate sleep/hibernate */
                break;
+
+       case TP_HKEY_EV_KEY_NUMLOCK:
+       case TP_HKEY_EV_KEY_FN:
+               /* key press events, we just ignore them as long as the EC
+                * is still reporting them in the normal keyboard stream */
+               *send_acpi_ev = false;
+               *ignore_acpi_ev = true;
+               return true;
+
        default:
-               pr_alert("THERMAL ALERT: unknown thermal alarm received\n");
+               pr_warn("unknown possible thermal alarm or keyboard event received\n");
                known = false;
        }
 
@@ -3652,15 +3701,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
                        }
                        break;
                case 4:
-                       /* 0x4000-0x4FFF: dock-related wakeups */
-                       if (hkey == TP_HKEY_EV_UNDOCK_ACK) {
-                               hotkey_autosleep_ack = 1;
-                               pr_info("undocked\n");
-                               hotkey_wakeup_hotunplug_complete_notify_change();
-                               known_ev = true;
-                       } else {
-                               known_ev = false;
-                       }
+                       /* 0x4000-0x4FFF: dock-related events */
+                       known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev,
+                                               &ignore_acpi_ev);
                        break;
                case 5:
                        /* 0x5000-0x5FFF: human interface helpers */
@@ -3668,8 +3711,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
                                                 &ignore_acpi_ev);
                        break;
                case 6:
-                       /* 0x6000-0x6FFF: thermal alarms */
-                       known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev,
+                       /* 0x6000-0x6FFF: thermal alarms/notices and
+                        *                keyboard events */
+                       known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev,
                                                 &ignore_acpi_ev);
                        break;
                case 7: