Merge tag 'platform-drivers-x86-v4.18-1' of git://git.infradead.org/linux-platform...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 14 Jun 2018 07:30:30 +0000 (16:30 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 14 Jun 2018 07:30:30 +0000 (16:30 +0900)
Pull x86 platform driver updates from Darren Hart:
 "Several incremental improvements including new keycodes, new models,
  new quirks, and related documentation. Adds LED platform driver
  activation for Mellanox systems. Some minor optimizations and
  cleanups. Includes several bug fixes, message silencing, mostly minor

  Automated summary:

  acer-wmi:
   -  add another KEY_POWER keycode

  apple-gmux:
   -  fix gmux_get_client_id()'s return type

  asus-laptop:
   -  Simplify getting .drvdata

  asus-wireless:
   -  Fix format specifier

  dell-laptop:
   -  Fix keyboard backlight timeout on XPS 13 9370

  dell-smbios:
   -  Match on www.dell.com in OEM strings too

  dell-wmi:
   -  Ignore new rfkill and fn-lock events
   -  Set correct keycode for Fn + left arrow

  fujitsu-laptop:
   -  Simplify soft key handling

  ideapad-laptop:
   -  Add E42-80 to no_hw_rfkill
   -  Add fn-lock setting
   -  Add MIIX 720-12IKB to no_hw_rfkill

  lib/string_helpers:
   -  Add missed declaration of struct task_struct

  intel_scu_ipc:
   -  Replace mdelay with usleep_range in intel_scu_ipc_i2c_cntrl

  mlx-platform:
   -  Add LED platform driver activation

  platform/mellanox:
   -  Add new ODM system types to mlx-platform
   -  mlxreg-hotplug: add extra cycle for hotplug work queue
   -  mlxreg-hotplug: Document fixes for hotplug private data

  platform_data/mlxreg:
   -  Document fixes for hotplug device

  silead_dmi:
   -  Add entry for Chuwi Hi8 tablet touchscreen
   -  Add touchscreen info for the Onda V891w tablet
   -  Add info for the PoV mobii TAB-P800W (v2.0)
   -  Add touchscreen info for the Jumper EZpad 6 Pro

  thinkpad_acpi:
   -  silence false-positive-prone pr_warn
   -  do not report thermal sensor state for tablet mode switch
   -  silence HKEY 0x6032, 0x60f0, 0x6030"

* tag 'platform-drivers-x86-v4.18-1' of git://git.infradead.org/linux-platform-drivers-x86: (30 commits)
  platform/x86: silead_dmi: Add entry for Chuwi Hi8 tablet touchscreen
  platform/x86: dell-laptop: Fix keyboard backlight timeout on XPS 13 9370
  platform/x86: dell-wmi: Ignore new rfkill and fn-lock events
  platform/x86: mlx-platform: Add LED platform driver activation
  platform/mellanox: Add new ODM system types to mlx-platform
  platform/mellanox: mlxreg-hotplug: add extra cycle for hotplug work queue
  platform/x86: ideapad-laptop: Add E42-80 to no_hw_rfkill
  platform/x86: silead_dmi: Add touchscreen info for the Onda V891w tablet
  platform/x86: silead_dmi: Add info for the PoV mobii TAB-P800W (v2.0)
  platform/x86: silead_dmi: Add touchscreen info for the Jumper EZpad 6 Pro
  platform/x86: asus-wireless: Fix format specifier
  platform/x86: asus-wmi: Fix NULL pointer dereference
  platform/x86: dell-wmi: Set correct keycode for Fn + left arrow
  platform/x86: acer-wmi: add another KEY_POWER keycode
  platform/x86: ideapad-laptop: Add fn-lock setting
  platform/x86: ideapad-laptop: Add MIIX 720-12IKB to no_hw_rfkill
  lib/string_helpers: Add missed declaration of struct task_struct
  platform/x86: DELL_WMI use depends on instead of select for DELL_SMBIOS
  platform/mellanox: mlxreg-hotplug: Document fixes for hotplug private data
  platform_data/mlxreg: Document fixes for hotplug device
  ...

20 files changed:
Documentation/ABI/testing/sysfs-platform-ideapad-laptop
Documentation/laptops/thinkpad-acpi.txt
drivers/platform/mellanox/mlxreg-hotplug.c
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/apple-gmux.c
drivers/platform/x86/asus-laptop.c
drivers/platform/x86/asus-wireless.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/dell-smbios-base.c
drivers/platform/x86/dell-wmi.c
drivers/platform/x86/fujitsu-laptop.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel_scu_ipc.c
drivers/platform/x86/mlx-platform.c
drivers/platform/x86/samsung-laptop.c
drivers/platform/x86/silead_dmi.c
drivers/platform/x86/thinkpad_acpi.c
include/linux/platform_data/mlxreg.h
include/linux/string_helpers.h

index 597a2f3d1efceb7383c85dda040f4b1def8adddf..1b31be3f996a40df66299e4715ee4eb984ec12e1 100644 (file)
@@ -25,3 +25,16 @@ Description:
                Control touchpad mode.
                        * 1 -> Switched On
                        * 0 -> Switched Off
+
+What:          /sys/bus/pci/devices/<bdf>/<device>/VPC2004:00/fn_lock
+Date:          May 2018
+KernelVersion: 4.18
+Contact:       "Oleg Keri <ezhi99@gmail.com>"
+Description:
+               Control fn-lock mode.
+                       * 1 -> Switched On
+                       * 0 -> Switched Off
+
+               For example:
+               # echo "0" >    \
+               /sys/bus/pci/devices/0000:00:1f.0/PNP0C09:00/VPC2004:00/fn_lock
index 00b6dfed573cf595594714df451621eb2f991893..6cced88de6da08134d35c4a3678a3ed119736958 100644 (file)
@@ -540,8 +540,10 @@ 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
+0x6032         Thermal Control command set completion  (DYTC, Windows)
 0x6040         Nvidia Optimus/AC adapter related (TO BE VERIFIED)
 0x60C0         X1 Yoga 2016, Tablet mode status changed
+0x60F0         Thermal Transformation changed (GMTS, Windows)
 
 Battery nearly empty alarms are a last resort attempt to get the
 operating system to hibernate or shutdown cleanly (0x2313), or shutdown
index 36a41ff506f0368be1a33710b6dcef098b16d7f0..ac97aa020db326dfc32ce821943ff37e2d77749c 100644 (file)
 #define MLXREG_HOTPLUG_RST_CNTR                3
 
 #define MLXREG_HOTPLUG_ATTRS_MAX       24
+#define MLXREG_HOTPLUG_NOT_ASSERT      3
 
 /**
  * struct mlxreg_hotplug_priv_data - platform private data:
  * @irq: platform device interrupt number;
+ * @dev: basic device;
  * @pdev: platform device;
  * @plat: platform data;
- * @dwork: delayed work template;
+ * @regmap: register map handle;
+ * @dwork_irq: delayed work template;
  * @lock: spin lock;
  * @hwmon: hwmon device;
  * @mlxreg_hotplug_attr: sysfs attributes array;
@@ -71,6 +74,8 @@
  * @cell: location of top aggregation interrupt register;
  * @mask: top aggregation interrupt common mask;
  * @aggr_cache: last value of aggregation register status;
+ * @after_probe: flag indication probing completion;
+ * @not_asserted: number of entries in workqueue with no signal assertion;
  */
 struct mlxreg_hotplug_priv_data {
        int irq;
@@ -79,7 +84,6 @@ struct mlxreg_hotplug_priv_data {
        struct mlxreg_hotplug_platform_data *plat;
        struct regmap *regmap;
        struct delayed_work dwork_irq;
-       struct delayed_work dwork;
        spinlock_t lock; /* sync with interrupt */
        struct device *hwmon;
        struct attribute *mlxreg_hotplug_attr[MLXREG_HOTPLUG_ATTRS_MAX + 1];
@@ -91,6 +95,7 @@ struct mlxreg_hotplug_priv_data {
        u32 mask;
        u32 aggr_cache;
        bool after_probe;
+       u8 not_asserted;
 };
 
 static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
@@ -409,6 +414,18 @@ static void mlxreg_hotplug_work_handler(struct work_struct *work)
        aggr_asserted = priv->aggr_cache ^ regval;
        priv->aggr_cache = regval;
 
+       /*
+        * Handler is invoked, but no assertion is detected at top aggregation
+        * status level. Set aggr_asserted to mask value to allow handler extra
+        * run over all relevant signals to recover any missed signal.
+        */
+       if (priv->not_asserted == MLXREG_HOTPLUG_NOT_ASSERT) {
+               priv->not_asserted = 0;
+               aggr_asserted = pdata->mask;
+       }
+       if (!aggr_asserted)
+               goto unmask_event;
+
        /* Handle topology and health configuration changes. */
        for (i = 0; i < pdata->counter; i++, item++) {
                if (aggr_asserted & item->aggr_mask) {
@@ -419,27 +436,26 @@ static void mlxreg_hotplug_work_handler(struct work_struct *work)
                }
        }
 
-       if (aggr_asserted) {
-               spin_lock_irqsave(&priv->lock, flags);
+       spin_lock_irqsave(&priv->lock, flags);
 
-               /*
-                * It is possible, that some signals have been inserted, while
-                * interrupt has been masked by mlxreg_hotplug_work_handler.
-                * In this case such signals will be missed. In order to handle
-                * these signals delayed work is canceled and work task
-                * re-scheduled for immediate execution. It allows to handle
-                * missed signals, if any. In other case work handler just
-                * validates that no new signals have been received during
-                * masking.
-                */
-               cancel_delayed_work(&priv->dwork_irq);
-               schedule_delayed_work(&priv->dwork_irq, 0);
+       /*
+        * It is possible, that some signals have been inserted, while
+        * interrupt has been masked by mlxreg_hotplug_work_handler. In this
+        * case such signals will be missed. In order to handle these signals
+        * delayed work is canceled and work task re-scheduled for immediate
+        * execution. It allows to handle missed signals, if any. In other case
+        * work handler just validates that no new signals have been received
+        * during masking.
+        */
+       cancel_delayed_work(&priv->dwork_irq);
+       schedule_delayed_work(&priv->dwork_irq, 0);
 
-               spin_unlock_irqrestore(&priv->lock, flags);
+       spin_unlock_irqrestore(&priv->lock, flags);
 
-               return;
-       }
+       return;
 
+unmask_event:
+       priv->not_asserted++;
        /* Unmask aggregation event (no need acknowledge). */
        ret = regmap_write(priv->regmap, pdata->cell +
                           MLXREG_HOTPLUG_AGGR_MASK_OFF, pdata->mask);
index 1be71f956d5c2872a1c31d77482bf65ddcb733a1..8952173dd380b6e650c6d54dd6498660286f0a27 100644 (file)
@@ -129,6 +129,7 @@ static const struct key_entry acer_wmi_keymap[] __initconst = {
        {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} },
        {KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} },
        {KE_KEY, 0x86, {KEY_WLAN} },
+       {KE_KEY, 0x87, {KEY_POWER} },
        {KE_END, 0}
 };
 
index 7c4eb86c851ed9568cb882d32a9a5fdd3a0d13a0..fd2ffebc868fc7ed6ae2c55a899debbf1c5041bd 100644 (file)
@@ -495,7 +495,7 @@ static int gmux_set_power_state(enum vga_switcheroo_client_id id,
        return gmux_set_discrete_state(apple_gmux_data, state);
 }
 
-static int gmux_get_client_id(struct pci_dev *pdev)
+static enum vga_switcheroo_client_id gmux_get_client_id(struct pci_dev *pdev)
 {
        /*
         * Early Macbook Pros with switchable graphics use nvidia
index c4768be24ba9c402b8d4e0163008e11bc64d4ac1..700c48ddfa7c099b79c8d040954e8b2a35e5164c 100644 (file)
@@ -1593,8 +1593,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
                                    int idx)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
-       struct platform_device *pdev = to_platform_device(dev);
-       struct asus_laptop *asus = platform_get_drvdata(pdev);
+       struct asus_laptop *asus = dev_get_drvdata(dev);
        acpi_handle handle = asus->handle;
        bool supported;
 
index f086469ea740987dec7c9996b982968491fa3140..6afd011de9e514ef05e13c6a5912ff2e78c2be00 100644 (file)
@@ -72,7 +72,7 @@ static u64 asus_wireless_method(acpi_handle handle, const char *method,
                acpi_handle_err(handle,
                                "Failed to eval method %s, param %#x (%d)\n",
                                method, param, s);
-       acpi_handle_debug(handle, "%s returned %#x\n", method, (uint) ret);
+       acpi_handle_debug(handle, "%s returned %#llx\n", method, ret);
        return ret;
 }
 
index ffffb9909ae1527a06ef7d68fc42a6c55b77b7ed..3d523ca6469462f4dba34935904c2ea66326a630 100644 (file)
@@ -1875,8 +1875,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
                                    struct attribute *attr, int idx)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
-       struct platform_device *pdev = to_platform_device(dev);
-       struct asus_wmi *asus = platform_get_drvdata(pdev);
+       struct asus_wmi *asus = dev_get_drvdata(dev);
        bool ok = true;
        int devid = -1;
 
index c52c6723374b50b26041d7681c3d9ae3564d50ce..f1fa8612db406168f53db3d71a025255c0622af0 100644 (file)
@@ -38,6 +38,7 @@
 struct quirk_entry {
        bool touchpad_led;
        bool kbd_led_levels_off_1;
+       bool kbd_missing_ac_tag;
 
        bool needs_kbd_timeouts;
        /*
@@ -68,6 +69,10 @@ static struct quirk_entry quirk_dell_xps13_9333 = {
        .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 },
 };
 
+static struct quirk_entry quirk_dell_xps13_9370 = {
+       .kbd_missing_ac_tag = true,
+};
+
 static struct quirk_entry quirk_dell_latitude_e6410 = {
        .kbd_led_levels_off_1 = true,
 };
@@ -291,6 +296,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
                },
                .driver_data = &quirk_dell_xps13_9333,
        },
+       {
+               .callback = dmi_matched,
+               .ident = "Dell XPS 13 9370",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9370"),
+               },
+               .driver_data = &quirk_dell_xps13_9370,
+       },
        {
                .callback = dmi_matched,
                .ident = "Dell Latitude E6410",
@@ -1401,7 +1415,8 @@ static inline int kbd_init_info(void)
         *       timeout value which is shared for both battery and AC power
         *       settings. So do not try to set AC values on old models.
         */
-       if (dell_smbios_find_token(KBD_LED_AC_TOKEN))
+       if ((quirks && quirks->kbd_missing_ac_tag) ||
+           dell_smbios_find_token(KBD_LED_AC_TOKEN))
                kbd_timeout_ac_supported = true;
 
        kbd_get_state(&state);
index 33fb2a20458a58fba2bee9ce79ad7571c184c7f3..9dc282ed5a9e1db7d926348ea30bd7905893a27c 100644 (file)
@@ -555,11 +555,10 @@ static void free_group(struct platform_device *pdev)
 
 static int __init dell_smbios_init(void)
 {
-       const struct dmi_device *valid;
        int ret, wmi, smm;
 
-       valid = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL);
-       if (!valid) {
+       if (!dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL) &&
+           !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "www.dell.com", NULL)) {
                pr_err("Unable to run on non-Dell system\n");
                return -ENODEV;
        }
index 8d102195a3927fa4bf76f4230d069d6038414923..16c7f3d9a3352ec48d72f877e2e7486ea78250c7 100644 (file)
@@ -233,7 +233,7 @@ static const u16 bios_to_linux_keycode[256] = {
        [18]    = KEY_PROG1,
        [19]    = KEY_BRIGHTNESSDOWN,
        [20]    = KEY_BRIGHTNESSUP,
-       [21]    = KEY_UNKNOWN,
+       [21]    = KEY_BRIGHTNESS_AUTO,
        [22]    = KEY_KBDILLUMTOGGLE,
        [23]    = KEY_UNKNOWN,
        [24]    = KEY_SWITCHVIDEOMODE,
@@ -261,6 +261,12 @@ static const u16 bios_to_linux_keycode[256] = {
  * override them.
  */
 static const struct key_entry dell_wmi_keymap_type_0010[] = {
+       /* Fn-lock switched to function keys */
+       { KE_IGNORE, 0x0, { KEY_RESERVED } },
+
+       /* Fn-lock switched to multimedia keys */
+       { KE_IGNORE, 0x1, { KEY_RESERVED } },
+
        /* Mic mute */
        { KE_KEY, 0x150, { KEY_MICMUTE } },
 
@@ -296,6 +302,14 @@ static const struct key_entry dell_wmi_keymap_type_0010[] = {
        { KE_KEY,    0x851, { KEY_PROG2 } },
        { KE_KEY,    0x852, { KEY_PROG3 } },
 
+       /*
+        * Radio disable (notify only -- there is no model for which the
+        * WMI event is supposed to trigger an action).
+        */
+       { KE_IGNORE, 0xe008, { KEY_RFKILL } },
+
+       /* Fn-lock */
+       { KE_IGNORE, 0xe035, { KEY_RESERVED } },
 };
 
 /*
index cd95b6f3a06405835edadfc6ea92a5b46bab591f..6afeaece2f50ca4deec027577631a787c274b7fb 100644 (file)
@@ -91,6 +91,9 @@
 #define FLAG_RFKILL                    BIT(5)
 #define FLAG_LID                       BIT(8)
 #define FLAG_DOCK                      BIT(9)
+#define FLAG_TOUCHPAD_TOGGLE           BIT(26)
+#define FLAG_MICMUTE                   BIT(29)
+#define FLAG_SOFTKEYS                  (FLAG_RFKILL | FLAG_TOUCHPAD_TOGGLE | FLAG_MICMUTE)
 
 /* FUNC interface - LED control */
 #define FUNC_LED_OFF                   BIT(0)
@@ -456,14 +459,15 @@ static void acpi_fujitsu_bl_notify(struct acpi_device *device, u32 event)
 /* ACPI device for hotkey handling */
 
 static const struct key_entry keymap_default[] = {
-       { KE_KEY, KEY1_CODE, { KEY_PROG1 } },
-       { KE_KEY, KEY2_CODE, { KEY_PROG2 } },
-       { KE_KEY, KEY3_CODE, { KEY_PROG3 } },
-       { KE_KEY, KEY4_CODE, { KEY_PROG4 } },
-       { KE_KEY, KEY5_CODE, { KEY_RFKILL } },
-       { KE_KEY, BIT(5),    { KEY_RFKILL } },
-       { KE_KEY, BIT(26),   { KEY_TOUCHPAD_TOGGLE } },
-       { KE_KEY, BIT(29),   { KEY_MICMUTE } },
+       { KE_KEY, KEY1_CODE,            { KEY_PROG1 } },
+       { KE_KEY, KEY2_CODE,            { KEY_PROG2 } },
+       { KE_KEY, KEY3_CODE,            { KEY_PROG3 } },
+       { KE_KEY, KEY4_CODE,            { KEY_PROG4 } },
+       { KE_KEY, KEY5_CODE,            { KEY_RFKILL } },
+       /* Soft keys read from status flags */
+       { KE_KEY, FLAG_RFKILL,          { KEY_RFKILL } },
+       { KE_KEY, FLAG_TOUCHPAD_TOGGLE, { KEY_TOUCHPAD_TOGGLE } },
+       { KE_KEY, FLAG_MICMUTE,         { KEY_MICMUTE } },
        { KE_END, 0 }
 };
 
@@ -903,7 +907,8 @@ static void acpi_fujitsu_laptop_release(struct acpi_device *device)
 static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
 {
        struct fujitsu_laptop *priv = acpi_driver_data(device);
-       int scancode, i = 0, ret;
+       unsigned long flags;
+       int scancode, i = 0;
        unsigned int irb;
 
        if (event != ACPI_FUJITSU_NOTIFY_CODE) {
@@ -930,21 +935,17 @@ static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
                                         "Unknown GIRB result [%x]\n", irb);
        }
 
-       /* On some models (first seen on the Skylake-based Lifebook
-        * E736/E746/E756), the touchpad toggle hotkey (Fn+F4) is
-        * handled in software; its state is queried using FUNC_FLAGS
+       /*
+        * First seen on the Skylake-based Lifebook E736/E746/E756), the
+        * touchpad toggle hotkey (Fn+F4) is handled in software. Other models
+        * have since added additional "soft keys". These are reported in the
+        * status flags queried using FUNC_FLAGS.
         */
-       if (priv->flags_supported & (BIT(5) | BIT(26) | BIT(29))) {
-               ret = call_fext_func(device, FUNC_FLAGS, 0x1, 0x0, 0x0);
-               if (ret & BIT(5))
-                       sparse_keymap_report_event(priv->input,
-                                                  BIT(5), 1, true);
-               if (ret & BIT(26))
-                       sparse_keymap_report_event(priv->input,
-                                                  BIT(26), 1, true);
-               if (ret & BIT(29))
-                       sparse_keymap_report_event(priv->input,
-                                                  BIT(29), 1, true);
+       if (priv->flags_supported & (FLAG_SOFTKEYS)) {
+               flags = call_fext_func(device, FUNC_FLAGS, 0x1, 0x0, 0x0);
+               flags &= (FLAG_SOFTKEYS);
+               for_each_set_bit(i, &flags, BITS_PER_LONG)
+                       sparse_keymap_report_event(priv->input, BIT(i), 1, true);
        }
 }
 
index 535199c9e6bc6fa182ea9612fcabf85a7ba02ba8..45b7cb01f4101ee8526ac5f4f7f86a626959f220 100644 (file)
@@ -43,6 +43,7 @@
 #define IDEAPAD_RFKILL_DEV_NUM (3)
 
 #define BM_CONSERVATION_BIT (5)
+#define HA_FNLOCK_BIT       (10)
 
 #define CFG_BT_BIT     (16)
 #define CFG_3G_BIT     (17)
@@ -59,6 +60,8 @@ static const char *const ideapad_wmi_fnesc_events[] = {
 enum {
        BMCMD_CONSERVATION_ON = 3,
        BMCMD_CONSERVATION_OFF = 5,
+       HACMD_FNLOCK_ON = 0xe,
+       HACMD_FNLOCK_OFF = 0xf,
 };
 
 enum {
@@ -139,11 +142,11 @@ static int method_gbmd(acpi_handle handle, unsigned long *ret)
        return result;
 }
 
-static int method_sbmc(acpi_handle handle, int cmd)
+static int method_int1(acpi_handle handle, char *method, int cmd)
 {
        acpi_status status;
 
-       status = acpi_execute_simple_method(handle, "SBMC", cmd);
+       status = acpi_execute_simple_method(handle, method, cmd);
        return ACPI_FAILURE(status) ? -1 : 0;
 }
 
@@ -487,7 +490,7 @@ static ssize_t conservation_mode_store(struct device *dev,
        if (ret)
                return ret;
 
-       ret = method_sbmc(priv->adev->handle, state ?
+       ret = method_int1(priv->adev->handle, "SBMC", state ?
                                              BMCMD_CONSERVATION_ON :
                                              BMCMD_CONSERVATION_OFF);
        if (ret < 0)
@@ -497,11 +500,51 @@ static ssize_t conservation_mode_store(struct device *dev,
 
 static DEVICE_ATTR_RW(conservation_mode);
 
+static ssize_t fn_lock_show(struct device *dev,
+                           struct device_attribute *attr,
+                           char *buf)
+{
+       struct ideapad_private *priv = dev_get_drvdata(dev);
+       unsigned long result;
+       int hals;
+       int fail = read_method_int(priv->adev->handle, "HALS", &hals);
+
+       if (fail)
+               return sprintf(buf, "-1\n");
+
+       result = hals;
+       return sprintf(buf, "%u\n", test_bit(HA_FNLOCK_BIT, &result));
+}
+
+static ssize_t fn_lock_store(struct device *dev,
+                            struct device_attribute *attr,
+                            const char *buf, size_t count)
+{
+       struct ideapad_private *priv = dev_get_drvdata(dev);
+       bool state;
+       int ret;
+
+       ret = kstrtobool(buf, &state);
+       if (ret)
+               return ret;
+
+       ret = method_int1(priv->adev->handle, "SALS", state ?
+                         HACMD_FNLOCK_ON :
+                         HACMD_FNLOCK_OFF);
+       if (ret < 0)
+               return -EIO;
+       return count;
+}
+
+static DEVICE_ATTR_RW(fn_lock);
+
+
 static struct attribute *ideapad_attributes[] = {
        &dev_attr_camera_power.attr,
        &dev_attr_fan_mode.attr,
        &dev_attr_touchpad.attr,
        &dev_attr_conservation_mode.attr,
+       &dev_attr_fn_lock.attr,
        NULL
 };
 
@@ -522,6 +565,9 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
        } else if (attr == &dev_attr_conservation_mode.attr) {
                supported = acpi_has_method(priv->adev->handle, "GBMD") &&
                            acpi_has_method(priv->adev->handle, "SBMC");
+       } else if (attr == &dev_attr_fn_lock.attr) {
+               supported = acpi_has_method(priv->adev->handle, "HALS") &&
+                       acpi_has_method(priv->adev->handle, "SALS");
        } else
                supported = true;
 
@@ -1079,6 +1125,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad Y700-17ISK"),
                },
        },
+       {
+               .ident = "Lenovo ideapad MIIX 720-12IKB",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 720-12IKB"),
+               },
+       },
        {
                .ident = "Lenovo Legion Y520-15IKBN",
                .matches = {
@@ -1163,6 +1216,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 920-13IKB"),
                },
        },
+       {
+               .ident = "Lenovo Zhaoyang E42-80",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ZHAOYANG E42-80"),
+               },
+       },
        {}
 };
 
index 2c85f75e32b08b27af3c96fa413fc9ebbccc252c..75c8fef7a482c41717c69aa8ef98b21ef4dd1043 100644 (file)
@@ -584,11 +584,11 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
        if (cmd == IPC_I2C_READ) {
                writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
                /* Write not getting updated without delay */
-               mdelay(1);
+               usleep_range(1000, 2000);
                *data = readl(scu->i2c_base + I2C_DATA_ADDR);
        } else if (cmd == IPC_I2C_WRITE) {
                writel(*data, scu->i2c_base + I2C_DATA_ADDR);
-               mdelay(1);
+               usleep_range(1000, 2000);
                writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
        } else {
                dev_err(scu->dev,
index 7a0bd24c1ae2dcd5304150d52a54d124192e753a..a0fd9aa6d93258f7305dae2dd60506f9f1464689 100644 (file)
 /* LPC bus IO offsets */
 #define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR         0x2000
 #define MLXPLAT_CPLD_LPC_REG_BASE_ADRR         0x2500
+#define MLXPLAT_CPLD_LPC_REG_LED1_OFFSET       0x20
+#define MLXPLAT_CPLD_LPC_REG_LED2_OFFSET       0x21
+#define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET       0x22
+#define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET       0x23
+#define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET       0x24
 #define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET       0x3a
 #define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET  0x3b
 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET     0x40
@@ -84,6 +89,8 @@
 #define MLXPLAT_CPLD_PWR_MASK          GENMASK(1, 0)
 #define MLXPLAT_CPLD_FAN_MASK          GENMASK(3, 0)
 #define MLXPLAT_CPLD_FAN_NG_MASK       GENMASK(5, 0)
+#define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK        GENMASK(7, 4)
+#define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK        GENMASK(3, 0)
 
 /* Default I2C parent bus number */
 #define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR       1
  * @pdev_i2c - i2c controller platform device
  * @pdev_mux - array of mux platform devices
  * @pdev_hotplug - hotplug platform devices
+ * @pdev_led - led platform devices
  */
 struct mlxplat_priv {
        struct platform_device *pdev_i2c;
        struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS];
        struct platform_device *pdev_hotplug;
+       struct platform_device *pdev_led;
 };
 
 /* Regions for LPC I2C controller and LPC base register space */
@@ -592,9 +601,227 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
        .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
 };
 
+/* Platform led default data */
+static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
+       {
+               .label = "status:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "status:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
+       },
+       {
+               .label = "psu:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "psu:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan1:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan1:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan2:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan2:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan3:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan3:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan4:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan4:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+};
+
+static struct mlxreg_core_platform_data mlxplat_default_led_data = {
+               .data = mlxplat_mlxcpld_default_led_data,
+               .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_data),
+};
+
+/* Platform led MSN21xx system family data */
+static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data[] = {
+       {
+               .label = "status:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "status:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
+       },
+       {
+               .label = "fan:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "psu1:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "psu1:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "psu2:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "psu2:red",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "uid:blue",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+};
+
+static struct mlxreg_core_platform_data mlxplat_msn21xx_led_data = {
+               .data = mlxplat_mlxcpld_msn21xx_led_data,
+               .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_led_data),
+};
+
+/* Platform led for default data for 200GbE systems */
+static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = {
+       {
+               .label = "status:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "status:orange",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
+       },
+       {
+               .label = "psu:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "psu:orange",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan1:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan1:orange",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan2:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan2:orange",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan3:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan3:orange",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan4:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan4:orange",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan5:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan5:orange",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+       },
+       {
+               .label = "fan6:green",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+       {
+               .label = "fan6:orange",
+               .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+               .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+       },
+};
+
+static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = {
+               .data = mlxplat_mlxcpld_default_ng_led_data,
+               .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data),
+};
+
+
 static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
+       case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
@@ -611,6 +838,11 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
 static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
+       case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
@@ -632,6 +864,11 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
 static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
+       case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
@@ -692,6 +929,7 @@ static struct resource mlxplat_mlxcpld_resources[] = {
 
 static struct platform_device *mlxplat_dev;
 static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
+static struct mlxreg_core_platform_data *mlxplat_led;
 
 static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
 {
@@ -705,6 +943,7 @@ static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug = &mlxplat_mlxcpld_default_data;
        mlxplat_hotplug->deferred_nr =
                mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
+       mlxplat_led = &mlxplat_default_led_data;
 
        return 1;
 };
@@ -721,6 +960,7 @@ static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug = &mlxplat_mlxcpld_msn21xx_data;
        mlxplat_hotplug->deferred_nr =
                mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
+       mlxplat_led = &mlxplat_msn21xx_led_data;
 
        return 1;
 };
@@ -737,6 +977,7 @@ static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug = &mlxplat_mlxcpld_msn274x_data;
        mlxplat_hotplug->deferred_nr =
                mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
+       mlxplat_led = &mlxplat_default_led_data;
 
        return 1;
 };
@@ -753,6 +994,7 @@ static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug = &mlxplat_mlxcpld_msn201x_data;
        mlxplat_hotplug->deferred_nr =
                mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
+       mlxplat_led = &mlxplat_default_ng_led_data;
 
        return 1;
 };
@@ -769,6 +1011,7 @@ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug = &mlxplat_mlxcpld_default_ng_data;
        mlxplat_hotplug->deferred_nr =
                mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
+       mlxplat_led = &mlxplat_msn21xx_led_data;
 
        return 1;
 };
@@ -844,6 +1087,36 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "SN34"),
                },
        },
+       {
+               .callback = mlxplat_dmi_default_matched,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "VMOD0001"),
+               },
+       },
+       {
+               .callback = mlxplat_dmi_msn21xx_matched,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "VMOD0002"),
+               },
+       },
+       {
+               .callback = mlxplat_dmi_msn274x_matched,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "VMOD0003"),
+               },
+       },
+       {
+               .callback = mlxplat_dmi_msn201x_matched,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "VMOD0004"),
+               },
+       },
+       {
+               .callback = mlxplat_dmi_qmb7xx_matched,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"),
+               },
+       },
        { }
 };
 
@@ -960,14 +1233,27 @@ static int __init mlxplat_init(void)
                goto fail_platform_mux_register;
        }
 
+       /* Add LED driver. */
+       mlxplat_led->regmap = mlxplat_hotplug->regmap;
+       priv->pdev_led = platform_device_register_resndata(
+                               &mlxplat_dev->dev, "leds-mlxreg",
+                               PLATFORM_DEVID_NONE, NULL, 0,
+                               mlxplat_led, sizeof(*mlxplat_led));
+       if (IS_ERR(priv->pdev_led)) {
+               err = PTR_ERR(priv->pdev_led);
+               goto fail_platform_hotplug_register;
+       }
+
        /* Sync registers with hardware. */
        regcache_mark_dirty(mlxplat_hotplug->regmap);
        err = regcache_sync(mlxplat_hotplug->regmap);
        if (err)
-               goto fail_platform_hotplug_register;
+               goto fail_platform_led_register;
 
        return 0;
 
+fail_platform_led_register:
+       platform_device_unregister(priv->pdev_led);
 fail_platform_hotplug_register:
        platform_device_unregister(priv->pdev_hotplug);
 fail_platform_mux_register:
@@ -986,6 +1272,7 @@ static void __exit mlxplat_exit(void)
        struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
        int i;
 
+       platform_device_unregister(priv->pdev_led);
        platform_device_unregister(priv->pdev_hotplug);
 
        for (i = ARRAY_SIZE(mlxplat_mux_data) - 1; i >= 0 ; i--)
index 03305e0b89ff808b5665d474b86baba62539c05e..7b160ee981152992655ff0b6f9357617f44fa18b 100644 (file)
@@ -1216,8 +1216,7 @@ static umode_t samsung_sysfs_is_visible(struct kobject *kobj,
                                        struct attribute *attr, int idx)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
-       struct platform_device *pdev = to_platform_device(dev);
-       struct samsung_laptop *samsung = platform_get_drvdata(pdev);
+       struct samsung_laptop *samsung = dev_get_drvdata(dev);
        bool ok = true;
 
        if (attr == &dev_attr_performance_level.attr)
index 452aacabaa8efc71115bd4c107e485f490fe138d..853a7ce4601cd1f0d508197b27e79455e936e2f1 100644 (file)
@@ -53,6 +53,20 @@ static const struct silead_ts_dmi_data jumper_ezpad_mini3_data = {
        .properties     = jumper_ezpad_mini3_props,
 };
 
+static const struct property_entry jumper_ezpad_6_pro_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct silead_ts_dmi_data jumper_ezpad_6_pro_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = jumper_ezpad_6_pro_props,
+};
+
 static const struct property_entry dexp_ursus_7w_props[] = {
        PROPERTY_ENTRY_U32("touchscreen-size-x", 890),
        PROPERTY_ENTRY_U32("touchscreen-size-y", 630),
@@ -127,7 +141,25 @@ static const struct silead_ts_dmi_data pipo_w2s_data = {
        .properties     = pipo_w2s_props,
 };
 
-static const struct property_entry pov_mobii_wintab_p800w_props[] = {
+static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 32),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1692),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1146),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl3680-pov-mobii-wintab-p800w-v20.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct silead_ts_dmi_data pov_mobii_wintab_p800w_v20_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = pov_mobii_wintab_p800w_v20_props,
+};
+
+static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
        PROPERTY_ENTRY_U32("touchscreen-size-x", 1800),
        PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
        PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
@@ -137,9 +169,9 @@ static const struct property_entry pov_mobii_wintab_p800w_props[] = {
        { }
 };
 
-static const struct silead_ts_dmi_data pov_mobii_wintab_p800w_data = {
+static const struct silead_ts_dmi_data pov_mobii_wintab_p800w_v21_data = {
        .acpi_name      = "MSSL1680:00",
-       .properties     = pov_mobii_wintab_p800w_props,
+       .properties     = pov_mobii_wintab_p800w_v21_props,
 };
 
 static const struct property_entry itworks_tw891_props[] = {
@@ -277,6 +309,23 @@ static const struct silead_ts_dmi_data teclast_x3_plus_data = {
        .properties     = teclast_x3_plus_props,
 };
 
+static const struct property_entry onda_v891w_v1_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 46),
+       PROPERTY_ENTRY_U32("touchscreen-min-y",  8),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1676),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1130),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl3680-onda-v891w-v1.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct silead_ts_dmi_data onda_v891w_v1_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = onda_v891w_v1_props,
+};
+
 static const struct dmi_system_id silead_ts_dmi_table[] = {
        {
                /* CUBE iwork8 Air */
@@ -296,6 +345,17 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
                        DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
                },
        },
+       {
+               /* Jumper EZpad 6 Pro */
+               .driver_data = (void *)&jumper_ezpad_6_pro_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Jumper"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "5.12"),
+                       /* Above matches are too generic, add bios-date match */
+                       DMI_MATCH(DMI_BIOS_DATE, "08/18/2017"),
+               },
+       },
        {
                /* DEXP Ursus 7W */
                .driver_data = (void *)&dexp_ursus_7w_data,
@@ -361,8 +421,19 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
                },
        },
        {
-               /* Point of View mobii wintab p800w */
-               .driver_data = (void *)&pov_mobii_wintab_p800w_data,
+               /* Point of View mobii wintab p800w (v2.0) */
+               .driver_data = (void *)&pov_mobii_wintab_p800w_v20_data,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
+                       /* Above matches are too generic, add bios-date match */
+                       DMI_MATCH(DMI_BIOS_DATE, "10/24/2014"),
+               },
+       },
+       {
+               /* Point of View mobii wintab p800w (v2.1) */
+               .driver_data = (void *)&pov_mobii_wintab_p800w_v21_data,
                .matches = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
                        DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
@@ -412,6 +483,15 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
                },
        },
+       {
+               /* Chuwi Hi8 (H1D_S806_206) */
+               .driver_data = (void *)&chuwi_hi8_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "H1D_S806_206"),
+               },
+       },
        {
                /* Chuwi Vi8 (CWI506) */
                .driver_data = (void *)&chuwi_vi8_data,
@@ -463,6 +543,17 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Y8W81"),
                },
        },
+       {
+               /* ONDA V891w revision P891WBEBV1B00 aka v1 */
+               .driver_data = (void *)&onda_v891w_v1_data,
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
+                       DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONDA Tablet"),
+                       DMI_EXACT_MATCH(DMI_BOARD_VERSION, "V001"),
+                       /* Exact match, different versions need different fw */
+                       DMI_EXACT_MATCH(DMI_BIOS_VERSION, "ONDA.W89EBBN08"),
+               },
+       },
        { },
 };
 
index ab2d28867c52178fae4778a615f78d0b798c624b..cae9b059569229d7c937e2f7101040969d9c7d5f 100644 (file)
@@ -212,7 +212,12 @@ enum tpacpi_hkey_event_t {
        TP_HKEY_EV_ALARM_BAT_XHOT       = 0x6012, /* battery critically hot */
        TP_HKEY_EV_ALARM_SENSOR_HOT     = 0x6021, /* sensor too hot */
        TP_HKEY_EV_ALARM_SENSOR_XHOT    = 0x6022, /* sensor critically hot */
-       TP_HKEY_EV_THM_TABLE_CHANGED    = 0x6030, /* thermal table changed */
+       TP_HKEY_EV_THM_TABLE_CHANGED    = 0x6030, /* windows; thermal table changed */
+       TP_HKEY_EV_THM_CSM_COMPLETED    = 0x6032, /* windows; thermal control set
+                                                  * command completed. Related to
+                                                  * AML DYTC */
+       TP_HKEY_EV_THM_TRANSFM_CHANGED  = 0x60F0, /* windows; thermal transformation
+                                                  * changed. Related to AML GMTS */
 
        /* AC-related events */
        TP_HKEY_EV_AC_CHANGED           = 0x6040, /* AC status changed */
@@ -4034,15 +4039,23 @@ static bool hotkey_notify_6xxx(const u32 hkey,
                                 bool *send_acpi_ev,
                                 bool *ignore_acpi_ev)
 {
-       bool known = true;
-
        /* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */
        *send_acpi_ev = true;
        *ignore_acpi_ev = false;
 
        switch (hkey) {
        case TP_HKEY_EV_THM_TABLE_CHANGED:
-               pr_info("EC reports that Thermal Table has changed\n");
+               pr_debug("EC reports: Thermal Table has changed\n");
+               /* recommended action: do nothing, we don't have
+                * Lenovo ATM information */
+               return true;
+       case TP_HKEY_EV_THM_CSM_COMPLETED:
+               pr_debug("EC reports: Thermal Control Command set completed (DYTC)\n");
+               /* recommended action: do nothing, we don't have
+                * Lenovo ATM information */
+               return true;
+       case TP_HKEY_EV_THM_TRANSFM_CHANGED:
+               pr_debug("EC reports: Thermal Transformation changed (GMTS)\n");
                /* recommended action: do nothing, we don't have
                 * Lenovo ATM information */
                return true;
@@ -4083,7 +4096,7 @@ static bool hotkey_notify_6xxx(const u32 hkey,
                tpacpi_input_send_tabletsw();
                hotkey_tablet_mode_notify_change();
                *send_acpi_ev = false;
-               break;
+               return true;
 
        case TP_HKEY_EV_PALM_DETECTED:
        case TP_HKEY_EV_PALM_UNDETECTED:
@@ -4092,13 +4105,12 @@ static bool hotkey_notify_6xxx(const u32 hkey,
                return true;
 
        default:
-               pr_warn("unknown possible thermal alarm or keyboard event received\n");
-               known = false;
+               /* report simply as unknown, no sensor dump */
+               return false;
        }
 
        thermal_dump_all_sensors();
-
-       return known;
+       return true;
 }
 
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
index 2744cff1b297e198041e6982700d2dc9fb9d8c58..19f5cb618c55dbf7bd54f9b6785f2892aecbc28a 100644 (file)
@@ -58,11 +58,10 @@ struct mlxreg_hotplug_device {
  * struct mlxreg_core_data - attributes control data:
  *
  * @label: attribute label;
- * @label: attribute register offset;
  * @reg: attribute register;
  * @mask: attribute access mask;
- * @mode: access mode;
  * @bit: attribute effective bit;
+ * @mode: access mode;
  * @np - pointer to node platform associated with attribute;
  * @hpdev - hotplug device data;
  * @health_cntr: dynamic device health indication counter;
index 4397c52ec4a496f61f7c26599a515276c0acc3ee..d23c5030901a2fe91a436a1e449273a543e015ca 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/types.h>
 
 struct file;
+struct task_struct;
 
 /* Descriptions of the types of units to
  * print in */