History

Merge tag 'platform-drivers-x86-v4.17-1' of git://git.infradead.org/linux-platform-drivers-x86

Pull x86 platform driver updates from Andy Shevchenko: - Dell SMBIOS driver fixed against memory leaks. - The fujitsu-laptop driver is cleaned up and now supports hotkeys for Lifebook U7x7 models. Besides that the typo introduced by one of previous clean up series has been fixed. - Specific to x86-based laptops HID device now supports KEY_ROTATE_LOCK_TOGGLE event which is emitted, for example, by Wacom MobileStudio Pro 13. - Turbo MAX 3 technology is enabled for the rest of platforms that support Hardware-P-States feature which have core priority described by ACPI CPPC table. - Mellanox on x86 gets better support of I2C bus in use including support of hotpluggable ones. - Silead touchscreen is enabled on two tablet models, i.e Yours Y8W81 and I.T.Works TW701. - From now on the second fan on Thinkpad P50 is supported. - The topstar-laptop driver is reworked to support new models, in particular Topstar U931. * tag 'platform-drivers-x86-v4.17-1' of git://git.infradead.org/linux-platform-drivers-x86: (41 commits) platform/x86: thinkpad_acpi: Add 2nd Fan Support for Thinkpad P50 platform/x86: dell-smbios: Fix memory leaks in build_tokens_sysfs() intel-hid: support KEY_ROTATE_LOCK_TOGGLE intel-hid: clean up and sort header files platform/x86: silead_dmi: Add entry for the Yours Y8W81 tablet platform/x86: fujitsu-laptop: Support Lifebook U7x7 hotkeys platform/x86: mlx-platform: Add physical bus number auto detection platform/mellanox: mlxreg-hotplug: Change input for device create routine platform/x86: mlx-platform: Add deffered bus functionality platform/x86: mlx-platform: Use define for the channel numbers platform/x86: fujitsu-laptop: Revert UNSUPPORTED_CMD back to an int platform/x86: Fix dell driver init order platform/x86: dell-smbios: Resolve dependency error on ACPI_WMI platform/x86: dell-smbios: Resolve dependency error on DCDBAS platform/x86: Allow for SMBIOS backend defaults platform/x86: dell-smbios: Link all dell-smbios-* modules together platform/x86: dell-smbios: Rename dell-smbios source to dell-smbios-base platform/x86: dell-smbios: Correct some style warnings platform/x86: wmi: Fix misuse of vsprintf extension %pULL platform/x86: intel-hid: Reset wakeup capable flag on removal ...

Linus Torvalds committed 8 years ago

Commit a7726f62 parents 1b02dcb a986c7513 files · +529 −212Browse files

Unified · Split

13 files
  1. drivers/platform/mellanox/mlxreg-hotplug.c +21 −10
  2. drivers/platform/x86/Kconfig +3 −0
  3. drivers/platform/x86/dell-smbios-base.c +2 −2
  4. drivers/platform/x86/fujitsu-laptop.c +106 −93
  5. drivers/platform/x86/gpd-pocket-fan.c +2 −2
  6. drivers/platform/x86/intel-hid.c +6 −8
  7. drivers/platform/x86/intel_turbo_max_3.c +0 −3
  8. drivers/platform/x86/mlx-platform.c +65 −3
  9. drivers/platform/x86/silead_dmi.c +17 −0
  10. drivers/platform/x86/thinkpad_acpi.c +8 −0
  11. drivers/platform/x86/topstar-laptop.c +289 −74
  12. drivers/platform/x86/wmi.c +6 −17
  13. include/linux/platform_data/mlxreg.h +4 −0
drivers/platform/mellanox/mlxreg-hotplug.c+21−10
@@ -93,9 +93,11 @@ struct mlxreg_hotplug_priv_data { · 92 unmodified lines
9393 bool after_probe;
9494 };
9595
96−static int mlxreg_hotplug_device_create(struct device *dev,
96+static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
9797 struct mlxreg_core_data *data)
9898 {
99+ struct mlxreg_core_hotplug_platform_data *pdata;
100+
99101 /*
100102 * Return if adapter number is negative. It could be in case hotplug
101103 * event is not associated with hotplug device.
@@ -103,19 +105,21 @@ static int mlxreg_hotplug_device_create(struct device *dev, · 1 unmodified line
103105 if (data->hpdev.nr < 0)
104106 return 0;
105107
106− data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
108+ pdata = dev_get_platdata(&priv->pdev->dev);
109+ data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr +
110+ pdata->shift_nr);
107111 if (!data->hpdev.adapter) {
108− dev_err(dev, "Failed to get adapter for bus %d\n",
109− data->hpdev.nr);
112+ dev_err(priv->dev, "Failed to get adapter for bus %d\n",
113+ data->hpdev.nr + pdata->shift_nr);
110114 return -EFAULT;
111115 }
112116
113117 data->hpdev.client = i2c_new_device(data->hpdev.adapter,
114118 data->hpdev.brdinfo);
115119 if (!data->hpdev.client) {
116− dev_err(dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
117− data->hpdev.brdinfo->type, data->hpdev.nr,
118− data->hpdev.brdinfo->addr);
120+ dev_err(priv->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
121+ data->hpdev.brdinfo->type, data->hpdev.nr +
122+ pdata->shift_nr, data->hpdev.brdinfo->addr);
119123
120124 i2c_put_adapter(data->hpdev.adapter);
121125 data->hpdev.adapter = NULL;
@@ -270,10 +274,10 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv, · 148 unmodified lines
270274 if (item->inversed)
271275 mlxreg_hotplug_device_destroy(data);
272276 else
273− mlxreg_hotplug_device_create(priv->dev, data);
277+ mlxreg_hotplug_device_create(priv, data);
274278 } else {
275279 if (item->inversed)
276− mlxreg_hotplug_device_create(priv->dev, data);
280+ mlxreg_hotplug_device_create(priv, data);
277281 else
278282 mlxreg_hotplug_device_destroy(data);
279283 }
@@ -319,7 +323,7 @@ mlxreg_hotplug_health_work_helper(struct mlxreg_hotplug_priv_data *priv, · 39 unmodified lines
319323 if (regval == MLXREG_HOTPLUG_HEALTH_MASK) {
320324 if ((data->health_cntr++ == MLXREG_HOTPLUG_RST_CNTR) ||
321325 !priv->after_probe) {
322− mlxreg_hotplug_device_create(priv->dev, data);
326+ mlxreg_hotplug_device_create(priv, data);
323327 data->attached = true;
324328 }
325329 } else {
@@ -550,6 +554,7 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev) · 224 unmodified lines
550554 {
551555 struct mlxreg_core_hotplug_platform_data *pdata;
552556 struct mlxreg_hotplug_priv_data *priv;
557+ struct i2c_adapter *deferred_adap;
553558 int err;
554559
555560 pdata = dev_get_platdata(&pdev->dev);
@@ -558,6 +563,12 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev) · 2 unmodified lines
558563 return -EINVAL;
559564 }
560565
566+ /* Defer probing if the necessary adapter is not configured yet. */
567+ deferred_adap = i2c_get_adapter(pdata->deferred_nr);
568+ if (!deferred_adap)
569+ return -EPROBE_DEFER;
570+ i2c_put_adapter(deferred_adap);
571+
561572 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
562573 if (!priv)
563574 return -ENOMEM;
drivers/platform/x86/Kconfig+3−0
@@ -757,6 +757,8 @@ config TOPSTAR_LAPTOP · 756 unmodified lines
757757 depends on ACPI
758758 depends on INPUT
759759 select INPUT_SPARSEKMAP
760+ select LEDS_CLASS
761+ select NEW_LEDS
760762 ---help---
761763 This driver adds support for hotkeys found on Topstar laptops.
762764
@@ -1174,6 +1176,7 @@ config INTEL_TELEMETRY · 411 unmodified lines
11741176
11751177 config MLX_PLATFORM
11761178 tristate "Mellanox Technologies platform support"
1179+ depends on I2C && REGMAP
11771180 ---help---
11781181 This option enables system support for the Mellanox Technologies
11791182 platform. The Mellanox systems provide data center networking
drivers/platform/x86/dell-smbios-base.c+2−2
@@ -514,7 +514,7 @@ static int build_tokens_sysfs(struct platform_device *dev) · 513 unmodified lines
514514 continue;
515515
516516 loop_fail_create_value:
517− kfree(value_name);
517+ kfree(location_name);
518518 goto out_unwind_strings;
519519 }
520520 smbios_attribute_group.attrs = token_attrs;
@@ -525,7 +525,7 @@ loop_fail_create_value: · 4 unmodified lines
525525 return 0;
526526
527527 out_unwind_strings:
528− for (i = i-1; i > 0; i--) {
528+ while (i--) {
529529 kfree(token_location_attrs[i].attr.name);
530530 kfree(token_value_attrs[i].attr.name);
531531 }
drivers/platform/x86/fujitsu-laptop.c+106−93
@@ -53,6 +53,7 @@ · 52 unmodified lines
5353 #include <linux/kernel.h>
5454 #include <linux/init.h>
5555 #include <linux/acpi.h>
56+#include <linux/bitops.h>
5657 #include <linux/dmi.h>
5758 #include <linux/backlight.h>
5859 #include <linux/fb.h>
@@ -61,12 +62,11 @@ · 2 unmodified lines
6162 #include <linux/kfifo.h>
6263 #include <linux/leds.h>
6364 #include <linux/platform_device.h>
64−#include <linux/slab.h>
6565 #include <acpi/video.h>
6666
67−#define FUJITSU_DRIVER_VERSION "0.6.0"
67+#define FUJITSU_DRIVER_VERSION "0.6.0"
6868
69−#define FUJITSU_LCD_N_LEVELS 8
69+#define FUJITSU_LCD_N_LEVELS 8
7070
7171 #define ACPI_FUJITSU_CLASS "fujitsu"
7272 #define ACPI_FUJITSU_BL_HID "FUJ02B1"
@@ -76,41 +76,51 @@ · 3 unmodified lines
7676 #define ACPI_FUJITSU_LAPTOP_DRIVER_NAME "Fujitsu laptop FUJ02E3 ACPI hotkeys driver"
7777 #define ACPI_FUJITSU_LAPTOP_DEVICE_NAME "Fujitsu FUJ02E3"
7878
79−#define ACPI_FUJITSU_NOTIFY_CODE1 0x80
79+#define ACPI_FUJITSU_NOTIFY_CODE 0x80
8080
8181 /* FUNC interface - command values */
82−#define FUNC_FLAGS 0x1000
83−#define FUNC_LEDS 0x1001
84−#define FUNC_BUTTONS 0x1002
85−#define FUNC_BACKLIGHT 0x1004
82+#define FUNC_FLAGS BIT(12)
83+#define FUNC_LEDS (BIT(12) | BIT(0))
84+#define FUNC_BUTTONS (BIT(12) | BIT(1))
85+#define FUNC_BACKLIGHT (BIT(12) | BIT(2))
8686
8787 /* FUNC interface - responses */
88−#define UNSUPPORTED_CMD 0x80000000
88+#define UNSUPPORTED_CMD 0x80000000
8989
9090 /* FUNC interface - status flags */
91−#define FLAG_RFKILL 0x020
92−#define FLAG_LID 0x100
93−#define FLAG_DOCK 0x200
91+#define FLAG_RFKILL BIT(5)
92+#define FLAG_LID BIT(8)
93+#define FLAG_DOCK BIT(9)
9494
9595 /* FUNC interface - LED control */
96−#define FUNC_LED_OFF 0x1
97−#define FUNC_LED_ON 0x30001
98−#define KEYBOARD_LAMPS 0x100
99−#define LOGOLAMP_POWERON 0x2000
100−#define LOGOLAMP_ALWAYS 0x4000
101−#define RADIO_LED_ON 0x20
102−#define ECO_LED 0x10000
103−#define ECO_LED_ON 0x80000
104−
105−/* Hotkey details */
106−#define KEY1_CODE 0x410 /* codes for the keys in the GIRB register */
107−#define KEY2_CODE 0x411
108−#define KEY3_CODE 0x412
109−#define KEY4_CODE 0x413
110−#define KEY5_CODE 0x420
111−
112−#define MAX_HOTKEY_RINGBUFFER_SIZE 100
113−#define RINGBUFFERSIZE 40
96+#define FUNC_LED_OFF BIT(0)
97+#define FUNC_LED_ON (BIT(0) | BIT(16) | BIT(17))
98+#define LOGOLAMP_POWERON BIT(13)
99+#define LOGOLAMP_ALWAYS BIT(14)
100+#define KEYBOARD_LAMPS BIT(8)
101+#define RADIO_LED_ON BIT(5)
102+#define ECO_LED BIT(16)
103+#define ECO_LED_ON BIT(19)
104+
105+/* FUNC interface - backlight power control */
106+#define BACKLIGHT_PARAM_POWER BIT(2)
107+#define BACKLIGHT_OFF (BIT(0) | BIT(1))
108+#define BACKLIGHT_ON 0
109+
110+/* Scancodes read from the GIRB register */
111+#define KEY1_CODE 0x410
112+#define KEY2_CODE 0x411
113+#define KEY3_CODE 0x412
114+#define KEY4_CODE 0x413
115+#define KEY5_CODE 0x420
116+
117+/* Hotkey ringbuffer limits */
118+#define MAX_HOTKEY_RINGBUFFER_SIZE 100
119+#define RINGBUFFERSIZE 40
120+
121+/* Module parameters */
122+static int use_alt_lcd_levels = -1;
123+static bool disable_brightness_adjust;
114124
115125 /* Device controlling the backlight and associated keys */
116126 struct fujitsu_bl {
@@ -122,8 +132,6 @@ struct fujitsu_bl { · 5 unmodified lines
122132 };
123133
124134 static struct fujitsu_bl *fujitsu_bl;
125−static int use_alt_lcd_levels = -1;
126−static bool disable_brightness_adjust;
127135
128136 /* Device used to access hotkeys and other features on the laptop */
129137 struct fujitsu_laptop {
@@ -256,9 +264,11 @@ static int bl_update_status(struct backlight_device *b) · 126 unmodified lines
256264
257265 if (fext) {
258266 if (b->props.power == FB_BLANK_POWERDOWN)
259− call_fext_func(fext, FUNC_BACKLIGHT, 0x1, 0x4, 0x3);
267+ call_fext_func(fext, FUNC_BACKLIGHT, 0x1,
268+ BACKLIGHT_PARAM_POWER, BACKLIGHT_OFF);
260269 else
261− call_fext_func(fext, FUNC_BACKLIGHT, 0x1, 0x4, 0x0);
270+ call_fext_func(fext, FUNC_BACKLIGHT, 0x1,
271+ BACKLIGHT_PARAM_POWER, BACKLIGHT_ON);
262272 }
263273
264274 return set_lcd_level(device, b->props.brightness);
@@ -385,7 +395,7 @@ static int fujitsu_backlight_register(struct acpi_device *device) · 120 unmodified lines
385395 static int acpi_fujitsu_bl_add(struct acpi_device *device)
386396 {
387397 struct fujitsu_bl *priv;
388− int error;
398+ int ret;
389399
390400 if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
391401 return -ENODEV;
@@ -399,10 +409,6 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device) · 7 unmodified lines
399409 strcpy(acpi_device_class(device), ACPI_FUJITSU_CLASS);
400410 device->driver_data = priv;
401411
402− error = acpi_fujitsu_bl_input_setup(device);
403− if (error)
404− return error;
405−
406412 pr_info("ACPI: %s [%s]\n",
407413 acpi_device_name(device), acpi_device_bid(device));
408414
@@ -410,11 +416,11 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device) · 1 unmodified line
410416 priv->max_brightness = FUJITSU_LCD_N_LEVELS;
411417 get_lcd_level(device);
412418
413− error = fujitsu_backlight_register(device);
414− if (error)
415− return error;
419+ ret = acpi_fujitsu_bl_input_setup(device);
420+ if (ret)
421+ return ret;
416422
417− return 0;
423+ return fujitsu_backlight_register(device);
418424 }
419425
420426 /* Brightness notify */
@@ -424,7 +430,7 @@ static void acpi_fujitsu_bl_notify(struct acpi_device *device, u32 event) · 3 unmodified lines
424430 struct fujitsu_bl *priv = acpi_driver_data(device);
425431 int oldb, newb;
426432
427− if (event != ACPI_FUJITSU_NOTIFY_CODE1) {
433+ if (event != ACPI_FUJITSU_NOTIFY_CODE) {
428434 acpi_handle_info(device->handle, "unsupported event [0x%x]\n",
429435 event);
430436 sparse_keymap_report_event(priv->input, -1, 1, true);
@@ -455,7 +461,9 @@ static const struct key_entry keymap_default[] = { · 24 unmodified lines
455461 { KE_KEY, KEY3_CODE, { KEY_PROG3 } },
456462 { KE_KEY, KEY4_CODE, { KEY_PROG4 } },
457463 { KE_KEY, KEY5_CODE, { KEY_RFKILL } },
464+ { KE_KEY, BIT(5), { KEY_RFKILL } },
458465 { KE_KEY, BIT(26), { KEY_TOUCHPAD_TOGGLE } },
466+ { KE_KEY, BIT(29), { KEY_MICMUTE } },
459467 { KE_END, 0 }
460468 };
461469
@@ -693,7 +701,7 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device) · 231 unmodified lines
693701 {
694702 struct fujitsu_laptop *priv = acpi_driver_data(device);
695703 struct led_classdev *led;
696− int result;
704+ int ret;
697705
698706 if (call_fext_func(device,
699707 FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
@@ -704,9 +712,9 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device) · 4 unmodified lines
704712 led->name = "fujitsu::logolamp";
705713 led->brightness_set_blocking = logolamp_set;
706714 led->brightness_get = logolamp_get;
707− result = devm_led_classdev_register(&device->dev, led);
708− if (result)
709− return result;
715+ ret = devm_led_classdev_register(&device->dev, led);
716+ if (ret)
717+ return ret;
710718 }
711719
712720 if ((call_fext_func(device,
@@ -719,9 +727,9 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device) · 6 unmodified lines
719727 led->name = "fujitsu::kblamps";
720728 led->brightness_set_blocking = kblamps_set;
721729 led->brightness_get = kblamps_get;
722− result = devm_led_classdev_register(&device->dev, led);
723− if (result)
724− return result;
730+ ret = devm_led_classdev_register(&device->dev, led);
731+ if (ret)
732+ return ret;
725733 }
726734
727735 /*
@@ -742,9 +750,9 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device) · 14 unmodified lines
742750 led->brightness_set_blocking = radio_led_set;
743751 led->brightness_get = radio_led_get;
744752 led->default_trigger = "rfkill-any";
745− result = devm_led_classdev_register(&device->dev, led);
746− if (result)
747− return result;
753+ ret = devm_led_classdev_register(&device->dev, led);
754+ if (ret)
755+ return ret;
748756 }
749757
750758 /* Support for eco led is not always signaled in bit corresponding
@@ -762,9 +770,9 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device) · 11 unmodified lines
762770 led->name = "fujitsu::eco_led";
763771 led->brightness_set_blocking = eco_led_set;
764772 led->brightness_get = eco_led_get;
765− result = devm_led_classdev_register(&device->dev, led);
766− if (result)
767− return result;
773+ ret = devm_led_classdev_register(&device->dev, led);
774+ if (ret)
775+ return ret;
768776 }
769777
770778 return 0;
@@ -773,8 +781,7 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device) · 2 unmodified lines
773781 static int acpi_fujitsu_laptop_add(struct acpi_device *device)
774782 {
775783 struct fujitsu_laptop *priv;
776− int error;
777− int i;
784+ int ret, i = 0;
778785
779786 priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
780787 if (!priv)
@@ -789,23 +796,16 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device) · 8 unmodified lines
789796
790797 /* kfifo */
791798 spin_lock_init(&priv->fifo_lock);
792− error = kfifo_alloc(&priv->fifo, RINGBUFFERSIZE * sizeof(int),
793− GFP_KERNEL);
794− if (error) {
795− pr_err("kfifo_alloc failed\n");
796− goto err_stop;
797− }
798−
799− error = acpi_fujitsu_laptop_input_setup(device);
800− if (error)
801− goto err_free_fifo;
799+ ret = kfifo_alloc(&priv->fifo, RINGBUFFERSIZE * sizeof(int),
800+ GFP_KERNEL);
801+ if (ret)
802+ return ret;
802803
803804 pr_info("ACPI: %s [%s]\n",
804805 acpi_device_name(device), acpi_device_bid(device));
805806
806− i = 0;
807− while (call_fext_func(device, FUNC_BUTTONS, 0x1, 0x0, 0x0) != 0
808− && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE)
807+ while (call_fext_func(device, FUNC_BUTTONS, 0x1, 0x0, 0x0) != 0 &&
808+ i++ < MAX_HOTKEY_RINGBUFFER_SIZE)
809809 ; /* No action, result is discarded */
810810 acpi_handle_debug(device->handle, "Discarded %i ringbuffer entries\n",
811811 i);
@@ -829,26 +829,31 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device) · 17 unmodified lines
829829 /* Sync backlight power status */
830830 if (fujitsu_bl && fujitsu_bl->bl_device &&
831831 acpi_video_get_backlight_type() == acpi_backlight_vendor) {
832− if (call_fext_func(fext, FUNC_BACKLIGHT, 0x2, 0x4, 0x0) == 3)
832+ if (call_fext_func(fext, FUNC_BACKLIGHT, 0x2,
833+ BACKLIGHT_PARAM_POWER, 0x0) == BACKLIGHT_OFF)
833834 fujitsu_bl->bl_device->props.power = FB_BLANK_POWERDOWN;
834835 else
835836 fujitsu_bl->bl_device->props.power = FB_BLANK_UNBLANK;
836837 }
837838
838− error = acpi_fujitsu_laptop_leds_register(device);
839− if (error)
839+ ret = acpi_fujitsu_laptop_input_setup(device);
840+ if (ret)
841+ goto err_free_fifo;
842+
843+ ret = acpi_fujitsu_laptop_leds_register(device);
844+ if (ret)
840845 goto err_free_fifo;
841846
842− error = fujitsu_laptop_platform_add(device);
843− if (error)
847+ ret = fujitsu_laptop_platform_add(device);
848+ if (ret)
844849 goto err_free_fifo;
845850
846851 return 0;
847852
848853 err_free_fifo:
849854 kfifo_free(&priv->fifo);
850−err_stop:
851− return error;
855+
856+ return ret;
852857 }
853858
854859 static int acpi_fujitsu_laptop_remove(struct acpi_device *device)
@@ -865,11 +870,11 @@ static int acpi_fujitsu_laptop_remove(struct acpi_device *device) · 10 unmodified lines
865870 static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode)
866871 {
867872 struct fujitsu_laptop *priv = acpi_driver_data(device);
868− int status;
873+ int ret;
869874
870− status = kfifo_in_locked(&priv->fifo, (unsigned char *)&scancode,
871− sizeof(scancode), &priv->fifo_lock);
872− if (status != sizeof(scancode)) {
875+ ret = kfifo_in_locked(&priv->fifo, (unsigned char *)&scancode,
876+ sizeof(scancode), &priv->fifo_lock);
877+ if (ret != sizeof(scancode)) {
873878 dev_info(&priv->input->dev, "Could not push scancode [0x%x]\n",
874879 scancode);
875880 return;
@@ -882,13 +887,12 @@ static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode) · 6 unmodified lines
882887 static void acpi_fujitsu_laptop_release(struct acpi_device *device)
883888 {
884889 struct fujitsu_laptop *priv = acpi_driver_data(device);
885− int scancode, status;
890+ int scancode, ret;
886891
887892 while (true) {
888− status = kfifo_out_locked(&priv->fifo,
889− (unsigned char *)&scancode,
890− sizeof(scancode), &priv->fifo_lock);
891− if (status != sizeof(scancode))
893+ ret = kfifo_out_locked(&priv->fifo, (unsigned char *)&scancode,
894+ sizeof(scancode), &priv->fifo_lock);
895+ if (ret != sizeof(scancode))
892896 return;
893897 sparse_keymap_report_event(priv->input, scancode, 0, false);
894898 dev_dbg(&priv->input->dev,
@@ -899,10 +903,10 @@ static void acpi_fujitsu_laptop_release(struct acpi_device *device) · 4 unmodified lines
899903 static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
900904 {
901905 struct fujitsu_laptop *priv = acpi_driver_data(device);
902− int scancode, i = 0;
906+ int scancode, i = 0, ret;
903907 unsigned int irb;
904908
905− if (event != ACPI_FUJITSU_NOTIFY_CODE1) {
909+ if (event != ACPI_FUJITSU_NOTIFY_CODE) {
906910 acpi_handle_info(device->handle, "Unsupported event [0x%x]\n",
907911 event);
908912 sparse_keymap_report_event(priv->input, -1, 1, true);
@@ -930,9 +934,18 @@ static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event) · 21 unmodified lines
930934 * E736/E746/E756), the touchpad toggle hotkey (Fn+F4) is
931935 * handled in software; its state is queried using FUNC_FLAGS
932936 */
933− if ((priv->flags_supported & BIT(26)) &&
934− (call_fext_func(device, FUNC_FLAGS, 0x1, 0x0, 0x0) & BIT(26)))
935− sparse_keymap_report_event(priv->input, BIT(26), 1, true);
937+ if (priv->flags_supported & (BIT(5) | BIT(26) | BIT(29))) {
938+ ret = call_fext_func(device, FUNC_FLAGS, 0x1, 0x0, 0x0);
939+ if (ret & BIT(5))
940+ sparse_keymap_report_event(priv->input,
941+ BIT(5), 1, true);
942+ if (ret & BIT(26))
943+ sparse_keymap_report_event(priv->input,
944+ BIT(26), 1, true);
945+ if (ret & BIT(29))
946+ sparse_keymap_report_event(priv->input,
947+ BIT(29), 1, true);
948+ }
936949 }
937950
938951 /* Initialization */
drivers/platform/x86/gpd-pocket-fan.c+2−2
@@ -19,12 +19,12 @@ · 18 unmodified lines
1919 static int temp_limits[3] = { 55000, 60000, 65000 };
2020 module_param_array(temp_limits, int, NULL, 0444);
2121 MODULE_PARM_DESC(temp_limits,
22− "Milli-celcius values above which the fan speed increases");
22+ "Millicelsius values above which the fan speed increases");
2323
2424 static int hysteresis = 3000;
2525 module_param(hysteresis, int, 0444);
2626 MODULE_PARM_DESC(hysteresis,
27− "Hysteresis in milli-celcius before lowering the fan speed");
27+ "Hysteresis in millicelsius before lowering the fan speed");
2828
2929 static int speed_on_ac = 2;
3030 module_param(speed_on_ac, int, 0444);
drivers/platform/x86/intel-hid.c+6−8
@@ -16,16 +16,14 @@ · 15 unmodified lines
1616 *
1717 */
1818
19+#include <linux/acpi.h>
20+#include <linux/dmi.h>
21+#include <linux/input.h>
22+#include <linux/input/sparse-keymap.h>
1923 #include <linux/kernel.h>
2024 #include <linux/module.h>
21−#include <linux/init.h>
22−#include <linux/input.h>
2325 #include <linux/platform_device.h>
24−#include <linux/input/sparse-keymap.h>
25−#include <linux/acpi.h>
2626 #include <linux/suspend.h>
27−#include <acpi/acpi_bus.h>
28−#include <linux/dmi.h>
2927
3028 MODULE_LICENSE("GPL");
3129 MODULE_AUTHOR("Alex Hung");
@@ -67,8 +65,8 @@ static const struct key_entry intel_array_keymap[] = { · 35 unmodified lines
6765 { KE_IGNORE, 0xC5, { KEY_VOLUMEUP } }, /* Release */
6866 { KE_KEY, 0xC6, { KEY_VOLUMEDOWN } }, /* Press */
6967 { KE_IGNORE, 0xC7, { KEY_VOLUMEDOWN } }, /* Release */
70− { KE_SW, 0xC8, { .sw = { SW_ROTATE_LOCK, 1 } } }, /* Press */
71− { KE_SW, 0xC9, { .sw = { SW_ROTATE_LOCK, 0 } } }, /* Release */
68+ { KE_KEY, 0xC8, { KEY_ROTATE_LOCK_TOGGLE } }, /* Press */
69+ { KE_IGNORE, 0xC9, { KEY_ROTATE_LOCK_TOGGLE } }, /* Release */
7270 { KE_KEY, 0xCE, { KEY_POWER } }, /* Press */
7371 { KE_IGNORE, 0xCF, { KEY_POWER } }, /* Release */
7472 { KE_END },
drivers/platform/x86/intel_turbo_max_3.c+0−3
@@ -138,9 +138,6 @@ static int __init itmt_legacy_init(void) · 137 unmodified lines
138138 if (!id)
139139 return -ENODEV;
140140
141− if (boot_cpu_has(X86_FEATURE_HWP))
142− return -ENODEV;
143−
144141 ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
145142 "platform/x86/turbo_max_3:online",
146143 itmt_legacy_cpu_online, NULL);
drivers/platform/x86/mlx-platform.c+65−3
@@ -85,6 +85,15 @@ · 84 unmodified lines
8585 #define MLXPLAT_CPLD_FAN_MASK GENMASK(3, 0)
8686 #define MLXPLAT_CPLD_FAN_NG_MASK GENMASK(5, 0)
8787
88+/* Default I2C parent bus number */
89+#define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR 1
90+
91+/* Maximum number of possible physical buses equipped on system */
92+#define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM 16
93+
94+/* Number of channels in group */
95+#define MLXPLAT_CPLD_GRP_CHNL_NUM 8
96+
8897 /* Start channel numbers */
8998 #define MLXPLAT_CPLD_CH1 2
9099 #define MLXPLAT_CPLD_CH2 10
@@ -124,7 +133,7 @@ static const struct resource mlxplat_lpc_resources[] = { · 33 unmodified lines
124133 };
125134
126135 /* Platform default channels */
127−static const int mlxplat_default_channels[][8] = {
136+static const int mlxplat_default_channels[][MLXPLAT_CPLD_GRP_CHNL_NUM] = {
128137 {
129138 MLXPLAT_CPLD_CH1, MLXPLAT_CPLD_CH1 + 1, MLXPLAT_CPLD_CH1 + 2,
130139 MLXPLAT_CPLD_CH1 + 3, MLXPLAT_CPLD_CH1 + 4, MLXPLAT_CPLD_CH1 +
@@ -694,6 +703,8 @@ static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi) · 563 unmodified lines
694703 ARRAY_SIZE(mlxplat_default_channels[i]);
695704 }
696705 mlxplat_hotplug = &mlxplat_mlxcpld_default_data;
706+ mlxplat_hotplug->deferred_nr =
707+ mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
697708
698709 return 1;
699710 };
@@ -708,6 +719,8 @@ static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi) · 8 unmodified lines
708719 ARRAY_SIZE(mlxplat_msn21xx_channels);
709720 }
710721 mlxplat_hotplug = &mlxplat_mlxcpld_msn21xx_data;
722+ mlxplat_hotplug->deferred_nr =
723+ mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
711724
712725 return 1;
713726 };
@@ -722,6 +735,8 @@ static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi) · 8 unmodified lines
722735 ARRAY_SIZE(mlxplat_msn21xx_channels);
723736 }
724737 mlxplat_hotplug = &mlxplat_mlxcpld_msn274x_data;
738+ mlxplat_hotplug->deferred_nr =
739+ mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
725740
726741 return 1;
727742 };
@@ -736,6 +751,8 @@ static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi) · 8 unmodified lines
736751 ARRAY_SIZE(mlxplat_msn21xx_channels);
737752 }
738753 mlxplat_hotplug = &mlxplat_mlxcpld_msn201x_data;
754+ mlxplat_hotplug->deferred_nr =
755+ mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
739756
740757 return 1;
741758 };
@@ -750,6 +767,8 @@ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi) · 8 unmodified lines
750767 ARRAY_SIZE(mlxplat_msn21xx_channels);
751768 }
752769 mlxplat_hotplug = &mlxplat_mlxcpld_default_ng_data;
770+ mlxplat_hotplug->deferred_nr =
771+ mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
753772
754773 return 1;
755774 };
@@ -830,10 +849,48 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = { · 74 unmodified lines
830849
831850 MODULE_DEVICE_TABLE(dmi, mlxplat_dmi_table);
832851
852+static int mlxplat_mlxcpld_verify_bus_topology(int *nr)
853+{
854+ struct i2c_adapter *search_adap;
855+ int shift, i;
856+
857+ /* Scan adapters from expected id to verify it is free. */
858+ *nr = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR;
859+ for (i = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR; i <
860+ MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM; i++) {
861+ search_adap = i2c_get_adapter(i);
862+ if (search_adap) {
863+ i2c_put_adapter(search_adap);
864+ continue;
865+ }
866+
867+ /* Return if expected parent adapter is free. */
868+ if (i == MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR)
869+ return 0;
870+ break;
871+ }
872+
873+ /* Return with error if free id for adapter is not found. */
874+ if (i == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM)
875+ return -ENODEV;
876+
877+ /* Shift adapter ids, since expected parent adapter is not free. */
878+ *nr = i;
879+ for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
880+ shift = *nr - mlxplat_mux_data[i].parent;
881+ mlxplat_mux_data[i].parent = *nr;
882+ mlxplat_mux_data[i].base_nr += shift;
883+ if (shift > 0)
884+ mlxplat_hotplug->shift_nr = shift;
885+ }
886+
887+ return 0;
888+}
889+
833890 static int __init mlxplat_init(void)
834891 {
835892 struct mlxplat_priv *priv;
836− int i, err;
893+ int i, nr, err;
837894
838895 if (!dmi_check_system(mlxplat_dmi_table))
839896 return -ENODEV;
@@ -853,7 +910,12 @@ static int __init mlxplat_init(void) · 13 unmodified lines
853910 }
854911 platform_set_drvdata(mlxplat_dev, priv);
855912
856− priv->pdev_i2c = platform_device_register_simple("i2c_mlxcpld", -1,
913+ err = mlxplat_mlxcpld_verify_bus_topology(&nr);
914+ if (nr < 0)
915+ goto fail_alloc;
916+
917+ nr = (nr == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM) ? -1 : nr;
918+ priv->pdev_i2c = platform_device_register_simple("i2c_mlxcpld", nr,
857919 NULL, 0);
858920 if (IS_ERR(priv->pdev_i2c)) {
859921 err = PTR_ERR(priv->pdev_i2c);
drivers/platform/x86/silead_dmi.c+17−0
@@ -446,6 +446,23 @@ static const struct dmi_system_id silead_ts_dmi_table[] = { · 445 unmodified lines
446446 DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
447447 },
448448 },
449+ {
450+ /* I.T.Works TW701 */
451+ .driver_data = (void *)&surftab_wintron70_st70416_6_data,
452+ .matches = {
453+ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
454+ DMI_MATCH(DMI_PRODUCT_NAME, "i71c"),
455+ DMI_MATCH(DMI_BIOS_VERSION, "itWORKS.G.WI71C.JGBMRB"),
456+ },
457+ },
458+ {
459+ /* Yours Y8W81, same case and touchscreen as Chuwi Vi8 */
460+ .driver_data = (void *)&chuwi_vi8_data,
461+ .matches = {
462+ DMI_MATCH(DMI_SYS_VENDOR, "YOURS"),
463+ DMI_MATCH(DMI_PRODUCT_NAME, "Y8W81"),
464+ },
465+ },
449466 { },
450467 };
451468
drivers/platform/x86/thinkpad_acpi.c+8−0
@@ -8703,16 +8703,24 @@ static const struct attribute_group fan_attr_group = { · 8702 unmodified lines
87038703 .ec = TPID(__id1, __id2), \
87048704 .quirks = __quirks }
87058705
8706+#define TPACPI_FAN_QB(__id1, __id2, __quirks) \
8707+ { .vendor = PCI_VENDOR_ID_LENOVO, \
8708+ .bios = TPID(__id1, __id2), \
8709+ .ec = TPACPI_MATCH_ANY, \
8710+ .quirks = __quirks }
8711+
87068712 static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
87078713 TPACPI_FAN_QI('1', 'Y', TPACPI_FAN_Q1),
87088714 TPACPI_FAN_QI('7', '8', TPACPI_FAN_Q1),
87098715 TPACPI_FAN_QI('7', '6', TPACPI_FAN_Q1),
87108716 TPACPI_FAN_QI('7', '0', TPACPI_FAN_Q1),
87118717 TPACPI_FAN_QL('7', 'M', TPACPI_FAN_2FAN),
8718+ TPACPI_FAN_QB('N', '1', TPACPI_FAN_2FAN),
87128719 };
87138720
87148721 #undef TPACPI_FAN_QL
87158722 #undef TPACPI_FAN_QI
8723+#undef TPACPI_FAN_QB
87168724
87178725 static int __init fan_init(struct ibm_init_struct *iibm)
87188726 {
drivers/platform/x86/topstar-laptop.c+289−74
@@ -1,14 +1,12 @@
1+// SPDX-License-Identifier: GPL-2.0
12 /*
2− * ACPI driver for Topstar notebooks (hotkeys support only)
3+ * Topstar Laptop ACPI Extras driver
34 *
45 * Copyright (c) 2009 Herton Ronaldo Krzesinski <herton@mandriva.com.br>
6+ * Copyright (c) 2018 Guillaume Douézan-Grard
57 *
68 * Implementation inspired by existing x86 platform drivers, in special
7− * asus/eepc/fujitsu-laptop, thanks to their authors
8− *
9− * This program is free software; you can redistribute it and/or modify
10− * it under the terms of the GNU General Public License version 2 as
11− * published by the Free Software Foundation.
9+ * asus/eepc/fujitsu-laptop, thanks to their authors.
1210 */
1311
1412 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -18,15 +16,93 @@ · 3 unmodified lines
1816 #include <linux/init.h>
1917 #include <linux/slab.h>
2018 #include <linux/acpi.h>
19+#include <linux/dmi.h>
2120 #include <linux/input.h>
2221 #include <linux/input/sparse-keymap.h>
22+#include <linux/leds.h>
23+#include <linux/platform_device.h>
2324
24−#define ACPI_TOPSTAR_CLASS "topstar"
25+#define TOPSTAR_LAPTOP_CLASS "topstar"
2526
26−struct topstar_hkey {
27− struct input_dev *inputdev;
27+struct topstar_laptop {
28+ struct acpi_device *device;
29+ struct platform_device *platform;
30+ struct input_dev *input;
31+ struct led_classdev led;
2832 };
2933
34+/*
35+ * LED
36+ */
37+
38+static enum led_brightness topstar_led_get(struct led_classdev *led)
39+{
40+ return led->brightness;
41+}
42+
43+static int topstar_led_set(struct led_classdev *led,
44+ enum led_brightness state)
45+{
46+ struct topstar_laptop *topstar = container_of(led,
47+ struct topstar_laptop, led);
48+
49+ struct acpi_object_list params;
50+ union acpi_object in_obj;
51+ unsigned long long int ret;
52+ acpi_status status;
53+
54+ params.count = 1;
55+ params.pointer = &in_obj;
56+ in_obj.type = ACPI_TYPE_INTEGER;
57+ in_obj.integer.value = 0x83;
58+
59+ /*
60+ * Topstar ACPI returns 0x30001 when the LED is ON and 0x30000 when it
61+ * is OFF.
62+ */
63+ status = acpi_evaluate_integer(topstar->device->handle,
64+ "GETX", &params, &ret);
65+ if (ACPI_FAILURE(status))
66+ return -1;
67+
68+ /*
69+ * FNCX(0x83) toggles the LED (more precisely, it is supposed to
70+ * act as an hardware switch and disconnect the WLAN adapter but
71+ * it seems to be faulty on some models like the Topstar U931
72+ * Notebook).
73+ */
74+ if ((ret == 0x30001 && state == LED_OFF)
75+ || (ret == 0x30000 && state != LED_OFF)) {
76+ status = acpi_execute_simple_method(topstar->device->handle,
77+ "FNCX", 0x83);
78+ if (ACPI_FAILURE(status))
79+ return -1;
80+ }
81+
82+ return 0;
83+}
84+
85+static int topstar_led_init(struct topstar_laptop *topstar)
86+{
87+ topstar->led = (struct led_classdev) {
88+ .default_trigger = "rfkill0",
89+ .brightness_get = topstar_led_get,
90+ .brightness_set_blocking = topstar_led_set,
91+ .name = TOPSTAR_LAPTOP_CLASS "::wlan",
92+ };
93+
94+ return led_classdev_register(&topstar->platform->dev, &topstar->led);
95+}
96+
97+static void topstar_led_exit(struct topstar_laptop *topstar)
98+{
99+ led_classdev_unregister(&topstar->led);
100+}
101+
102+/*
103+ * Input
104+ */
105+
30106 static const struct key_entry topstar_keymap[] = {
31107 { KE_KEY, 0x80, { KEY_BRIGHTNESSUP } },
32108 { KE_KEY, 0x81, { KEY_BRIGHTNESSDOWN } },
@@ -57,107 +133,217 @@ static const struct key_entry topstar_keymap[] = { · 24 unmodified lines
57133 { KE_END, 0 }
58134 };
59135
60−static void acpi_topstar_notify(struct acpi_device *device, u32 event)
136+static void topstar_input_notify(struct topstar_laptop *topstar, int event)
61137 {
62− static bool dup_evnt[2];
63− bool *dup;
64− struct topstar_hkey *hkey = acpi_driver_data(device);
65−
66− /* 0x83 and 0x84 key events comes duplicated... */
67− if (event == 0x83 || event == 0x84) {
68− dup = &dup_evnt[event - 0x83];
69− if (*dup) {
70− *dup = false;
71− return;
72− }
73− *dup = true;
74− }
75−
76− if (!sparse_keymap_report_event(hkey->inputdev, event, 1, true))
138+ if (!sparse_keymap_report_event(topstar->input, event, 1, true))
77139 pr_info("unknown event = 0x%02x\n", event);
78140 }
79141
80−static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state)
81−{
82− acpi_status status;
83−
84− status = acpi_execute_simple_method(device->handle, "FNCX",
85− state ? 0x86 : 0x87);
86− if (ACPI_FAILURE(status)) {
87− pr_err("Unable to switch FNCX notifications\n");
88− return -ENODEV;
89− }
90−
91− return 0;
92−}
93−
94−static int acpi_topstar_init_hkey(struct topstar_hkey *hkey)
142+static int topstar_input_init(struct topstar_laptop *topstar)
95143 {
96144 struct input_dev *input;
97− int error;
145+ int err;
98146
99147 input = input_allocate_device();
100148 if (!input)
101149 return -ENOMEM;
102150
103151 input->name = "Topstar Laptop extra buttons";
104− input->phys = "topstar/input0";
152+ input->phys = TOPSTAR_LAPTOP_CLASS "/input0";
105153 input->id.bustype = BUS_HOST;
154+ input->dev.parent = &topstar->platform->dev;
106155
107− error = sparse_keymap_setup(input, topstar_keymap, NULL);
108− if (error) {
156+ err = sparse_keymap_setup(input, topstar_keymap, NULL);
157+ if (err) {
109158 pr_err("Unable to setup input device keymap\n");
110159 goto err_free_dev;
111160 }
112161
113− error = input_register_device(input);
114− if (error) {
162+ err = input_register_device(input);
163+ if (err) {
115164 pr_err("Unable to register input device\n");
116165 goto err_free_dev;
117166 }
118167
119− hkey->inputdev = input;
168+ topstar->input = input;
120169 return 0;
121170
122− err_free_dev:
171+err_free_dev:
123172 input_free_device(input);
124− return error;
173+ return err;
125174 }
126175
127−static int acpi_topstar_add(struct acpi_device *device)
176+static void topstar_input_exit(struct topstar_laptop *topstar)
128177 {
129− struct topstar_hkey *tps_hkey;
178+ input_unregister_device(topstar->input);
179+}
130180
131− tps_hkey = kzalloc(sizeof(struct topstar_hkey), GFP_KERNEL);
132− if (!tps_hkey)
181+/*
182+ * Platform
183+ */
184+
185+static struct platform_driver topstar_platform_driver = {
186+ .driver = {
187+ .name = TOPSTAR_LAPTOP_CLASS,
188+ },
189+};
190+
191+static int topstar_platform_init(struct topstar_laptop *topstar)
192+{
193+ int err;
194+
195+ topstar->platform = platform_device_alloc(TOPSTAR_LAPTOP_CLASS, -1);
196+ if (!topstar->platform)
133197 return -ENOMEM;
134198
135− strcpy(acpi_device_name(device), "Topstar TPSACPI");
136− strcpy(acpi_device_class(device), ACPI_TOPSTAR_CLASS);
199+ platform_set_drvdata(topstar->platform, topstar);
200+
201+ err = platform_device_add(topstar->platform);
202+ if (err)
203+ goto err_device_put;
204+
205+ return 0;
137206
138− if (acpi_topstar_fncx_switch(device, true))
139− goto add_err;
207+err_device_put:
208+ platform_device_put(topstar->platform);
209+ return err;
210+}
211+
212+static void topstar_platform_exit(struct topstar_laptop *topstar)
213+{
214+ platform_device_unregister(topstar->platform);
215+}
216+
217+/*
218+ * ACPI
219+ */
220+
221+static int topstar_acpi_fncx_switch(struct acpi_device *device, bool state)
222+{
223+ acpi_status status;
224+ u64 arg = state ? 0x86 : 0x87;
140225
141− if (acpi_topstar_init_hkey(tps_hkey))
142− goto add_err;
226+ status = acpi_execute_simple_method(device->handle, "FNCX", arg);
227+ if (ACPI_FAILURE(status)) {
228+ pr_err("Unable to switch FNCX notifications\n");
229+ return -ENODEV;
230+ }
143231
144− device->driver_data = tps_hkey;
145232 return 0;
233+}
146234
147−add_err:
148− kfree(tps_hkey);
149− return -ENODEV;
235+static void topstar_acpi_notify(struct acpi_device *device, u32 event)
236+{
237+ struct topstar_laptop *topstar = acpi_driver_data(device);
238+ static bool dup_evnt[2];
239+ bool *dup;
240+
241+ /* 0x83 and 0x84 key events comes duplicated... */
242+ if (event == 0x83 || event == 0x84) {
243+ dup = &dup_evnt[event - 0x83];
244+ if (*dup) {
245+ *dup = false;
246+ return;
247+ }
248+ *dup = true;
249+ }
250+
251+ topstar_input_notify(topstar, event);
150252 }
151253
152−static int acpi_topstar_remove(struct acpi_device *device)
254+static int topstar_acpi_init(struct topstar_laptop *topstar)
153255 {
154− struct topstar_hkey *tps_hkey = acpi_driver_data(device);
256+ return topstar_acpi_fncx_switch(topstar->device, true);
257+}
155258
156− acpi_topstar_fncx_switch(device, false);
259+static void topstar_acpi_exit(struct topstar_laptop *topstar)
260+{
261+ topstar_acpi_fncx_switch(topstar->device, false);
262+}
157263
158− input_unregister_device(tps_hkey->inputdev);
159− kfree(tps_hkey);
264+/*
265+ * Enable software-based WLAN LED control on systems with defective
266+ * hardware switch.
267+ */
268+static bool led_workaround;
160269
270+static int dmi_led_workaround(const struct dmi_system_id *id)
271+{
272+ led_workaround = true;
273+ return 0;
274+}
275+
276+static const struct dmi_system_id topstar_dmi_ids[] = {
277+ {
278+ .callback = dmi_led_workaround,
279+ .ident = "Topstar U931/RVP7",
280+ .matches = {
281+ DMI_MATCH(DMI_BOARD_NAME, "U931"),
282+ DMI_MATCH(DMI_BOARD_VERSION, "RVP7"),
283+ },
284+ },
285+ {}
286+};
287+
288+static int topstar_acpi_add(struct acpi_device *device)
289+{
290+ struct topstar_laptop *topstar;
291+ int err;
292+
293+ dmi_check_system(topstar_dmi_ids);
294+
295+ topstar = kzalloc(sizeof(struct topstar_laptop), GFP_KERNEL);
296+ if (!topstar)
297+ return -ENOMEM;
298+
299+ strcpy(acpi_device_name(device), "Topstar TPSACPI");
300+ strcpy(acpi_device_class(device), TOPSTAR_LAPTOP_CLASS);
301+ device->driver_data = topstar;
302+ topstar->device = device;
303+
304+ err = topstar_acpi_init(topstar);
305+ if (err)
306+ goto err_free;
307+
308+ err = topstar_platform_init(topstar);
309+ if (err)
310+ goto err_acpi_exit;
311+
312+ err = topstar_input_init(topstar);
313+ if (err)
314+ goto err_platform_exit;
315+
316+ if (led_workaround) {
317+ err = topstar_led_init(topstar);
318+ if (err)
319+ goto err_input_exit;
320+ }
321+
322+ return 0;
323+
324+err_input_exit:
325+ topstar_input_exit(topstar);
326+err_platform_exit:
327+ topstar_platform_exit(topstar);
328+err_acpi_exit:
329+ topstar_acpi_exit(topstar);
330+err_free:
331+ kfree(topstar);
332+ return err;
333+}
334+
335+static int topstar_acpi_remove(struct acpi_device *device)
336+{
337+ struct topstar_laptop *topstar = acpi_driver_data(device);
338+
339+ if (led_workaround)
340+ topstar_led_exit(topstar);
341+
342+ topstar_input_exit(topstar);
343+ topstar_platform_exit(topstar);
344+ topstar_acpi_exit(topstar);
345+
346+ kfree(topstar);
161347 return 0;
162348 }
163349
@@ -168,18 +354,47 @@ static const struct acpi_device_id topstar_device_ids[] = { · 4 unmodified lines
168354 };
169355 MODULE_DEVICE_TABLE(acpi, topstar_device_ids);
170356
171−static struct acpi_driver acpi_topstar_driver = {
357+static struct acpi_driver topstar_acpi_driver = {
172358 .name = "Topstar laptop ACPI driver",
173− .class = ACPI_TOPSTAR_CLASS,
359+ .class = TOPSTAR_LAPTOP_CLASS,
174360 .ids = topstar_device_ids,
175361 .ops = {
176− .add = acpi_topstar_add,
177− .remove = acpi_topstar_remove,
178− .notify = acpi_topstar_notify,
362+ .add = topstar_acpi_add,
363+ .remove = topstar_acpi_remove,
364+ .notify = topstar_acpi_notify,
179365 },
180366 };
181−module_acpi_driver(acpi_topstar_driver);
367+
368+static int __init topstar_laptop_init(void)
369+{
370+ int ret;
371+
372+ ret = platform_driver_register(&topstar_platform_driver);
373+ if (ret < 0)
374+ return ret;
375+
376+ ret = acpi_bus_register_driver(&topstar_acpi_driver);
377+ if (ret < 0)
378+ goto err_driver_unreg;
379+
380+ pr_info("ACPI extras driver loaded\n");
381+ return 0;
382+
383+err_driver_unreg:
384+ platform_driver_unregister(&topstar_platform_driver);
385+ return ret;
386+}
387+
388+static void __exit topstar_laptop_exit(void)
389+{
390+ acpi_bus_unregister_driver(&topstar_acpi_driver);
391+ platform_driver_unregister(&topstar_platform_driver);
392+}
393+
394+module_init(topstar_laptop_init);
395+module_exit(topstar_laptop_exit);
182396
183397 MODULE_AUTHOR("Herton Ronaldo Krzesinski");
398+MODULE_AUTHOR("Guillaume Douézan-Grard");
184399 MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver");
185400 MODULE_LICENSE("GPL");
drivers/platform/x86/wmi.c+6−17
@@ -130,13 +130,11 @@ static bool find_guid(const char *guid_string, struct wmi_block **out) · 129 unmodified lines
130130 uuid_le guid_input;
131131 struct wmi_block *wblock;
132132 struct guid_block *block;
133− struct list_head *p;
134133
135134 if (uuid_le_to_bin(guid_string, &guid_input))
136135 return false;
137136
138− list_for_each(p, &wmi_block_list) {
139− wblock = list_entry(p, struct wmi_block, list);
137+ list_for_each_entry(wblock, &wmi_block_list, list) {
140138 block = &wblock->gblock;
141139
142140 if (memcmp(block->guid, &guid_input, 16) == 0) {
@@ -519,7 +517,6 @@ wmi_notify_handler handler, void *data) · 376 unmodified lines
519517 struct wmi_block *block;
520518 acpi_status status = AE_NOT_EXIST;
521519 uuid_le guid_input;
522− struct list_head *p;
523520
524521 if (!guid || !handler)
525522 return AE_BAD_PARAMETER;
@@ -527,9 +524,8 @@ wmi_notify_handler handler, void *data) · 1 unmodified line
527524 if (uuid_le_to_bin(guid, &guid_input))
528525 return AE_BAD_PARAMETER;
529526
530− list_for_each(p, &wmi_block_list) {
527+ list_for_each_entry(block, &wmi_block_list, list) {
531528 acpi_status wmi_status;
532− block = list_entry(p, struct wmi_block, list);
533529
534530 if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
535531 if (block->handler &&
@@ -560,7 +556,6 @@ acpi_status wmi_remove_notify_handler(const char *guid) · 24 unmodified lines
560556 struct wmi_block *block;
561557 acpi_status status = AE_NOT_EXIST;
562558 uuid_le guid_input;
563− struct list_head *p;
564559
565560 if (!guid)
566561 return AE_BAD_PARAMETER;
@@ -568,9 +563,8 @@ acpi_status wmi_remove_notify_handler(const char *guid) · 1 unmodified line
568563 if (uuid_le_to_bin(guid, &guid_input))
569564 return AE_BAD_PARAMETER;
570565
571− list_for_each(p, &wmi_block_list) {
566+ list_for_each_entry(block, &wmi_block_list, list) {
572567 acpi_status wmi_status;
573− block = list_entry(p, struct wmi_block, list);
574568
575569 if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
576570 if (!block->handler ||
@@ -610,15 +604,13 @@ acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out) · 33 unmodified lines
610604 union acpi_object params[1];
611605 struct guid_block *gblock;
612606 struct wmi_block *wblock;
613− struct list_head *p;
614607
615608 input.count = 1;
616609 input.pointer = params;
617610 params[0].type = ACPI_TYPE_INTEGER;
618611 params[0].integer.value = event;
619612
620− list_for_each(p, &wmi_block_list) {
621− wblock = list_entry(p, struct wmi_block, list);
613+ list_for_each_entry(wblock, &wmi_block_list, list) {
622614 gblock = &wblock->gblock;
623615
624616 if ((gblock->flags & ACPI_WMI_EVENT) &&
@@ -933,12 +925,11 @@ static int wmi_dev_probe(struct device *dev) · 308 unmodified lines
933925 goto probe_failure;
934926 }
935927
936− buf = kmalloc(strlen(wdriver->driver.name) + 5, GFP_KERNEL);
928+ buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name);
937929 if (!buf) {
938930 ret = -ENOMEM;
939931 goto probe_string_failure;
940932 }
941− sprintf(buf, "wmi/%s", wdriver->driver.name);
942933 wblock->char_dev.minor = MISC_DYNAMIC_MINOR;
943934 wblock->char_dev.name = buf;
944935 wblock->char_dev.fops = &wmi_fops;
@@ -1261,11 +1252,9 @@ static void acpi_wmi_notify_handler(acpi_handle handle, u32 event, · 316 unmodified lines
12611252 {
12621253 struct guid_block *block;
12631254 struct wmi_block *wblock;
1264− struct list_head *p;
12651255 bool found_it = false;
12661256
1267− list_for_each(p, &wmi_block_list) {
1268− wblock = list_entry(p, struct wmi_block, list);
1257+ list_for_each_entry(wblock, &wmi_block_list, list) {
12691258 block = &wblock->gblock;
12701259
12711260 if (wblock->acpi_device->handle == handle &&
include/linux/platform_data/mlxreg.h+4−0
@@ -129,6 +129,8 @@ struct mlxreg_core_platform_data { · 128 unmodified lines
129129 * @mask: top aggregation interrupt common mask;
130130 * @cell_low: location of low aggregation interrupt register;
131131 * @mask_low: low aggregation interrupt common mask;
132+ * @deferred_nr: I2C adapter number must be exist prior probing execution;
133+ * @shift_nr: I2C adapter numbers must be incremented by this value;
132134 */
133135 struct mlxreg_core_hotplug_platform_data {
134136 struct mlxreg_core_item *items;
@@ -139,6 +141,8 @@ struct mlxreg_core_hotplug_platform_data { · 4 unmodified lines
139141 u32 mask;
140142 u32 cell_low;
141143 u32 mask_low;
144+ int deferred_nr;
145+ int shift_nr;
142146 };
143147
144148 #endif /* __LINUX_PLATFORM_DATA_MLXREG_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t