Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7726f6b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
  ...
parents 1b02dcb9 a986c75a
Loading
Loading
Loading
Loading
+21 −10
Original line number Original line Diff line number Diff line
@@ -93,9 +93,11 @@ struct mlxreg_hotplug_priv_data {
	bool after_probe;
	bool after_probe;
};
};


static int mlxreg_hotplug_device_create(struct device *dev,
static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
					struct mlxreg_core_data *data)
					struct mlxreg_core_data *data)
{
{
	struct mlxreg_core_hotplug_platform_data *pdata;

	/*
	/*
	 * Return if adapter number is negative. It could be in case hotplug
	 * Return if adapter number is negative. It could be in case hotplug
	 * event is not associated with hotplug device.
	 * event is not associated with hotplug device.
@@ -103,19 +105,21 @@ static int mlxreg_hotplug_device_create(struct device *dev,
	if (data->hpdev.nr < 0)
	if (data->hpdev.nr < 0)
		return 0;
		return 0;


	data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
	pdata = dev_get_platdata(&priv->pdev->dev);
	data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr +
					      pdata->shift_nr);
	if (!data->hpdev.adapter) {
	if (!data->hpdev.adapter) {
		dev_err(dev, "Failed to get adapter for bus %d\n",
		dev_err(priv->dev, "Failed to get adapter for bus %d\n",
			data->hpdev.nr);
			data->hpdev.nr + pdata->shift_nr);
		return -EFAULT;
		return -EFAULT;
	}
	}


	data->hpdev.client = i2c_new_device(data->hpdev.adapter,
	data->hpdev.client = i2c_new_device(data->hpdev.adapter,
					    data->hpdev.brdinfo);
					    data->hpdev.brdinfo);
	if (!data->hpdev.client) {
	if (!data->hpdev.client) {
		dev_err(dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
		dev_err(priv->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
			data->hpdev.brdinfo->type, data->hpdev.nr,
			data->hpdev.brdinfo->type, data->hpdev.nr +
			data->hpdev.brdinfo->addr);
			pdata->shift_nr, data->hpdev.brdinfo->addr);


		i2c_put_adapter(data->hpdev.adapter);
		i2c_put_adapter(data->hpdev.adapter);
		data->hpdev.adapter = NULL;
		data->hpdev.adapter = NULL;
@@ -270,10 +274,10 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
			if (item->inversed)
			if (item->inversed)
				mlxreg_hotplug_device_destroy(data);
				mlxreg_hotplug_device_destroy(data);
			else
			else
				mlxreg_hotplug_device_create(priv->dev, data);
				mlxreg_hotplug_device_create(priv, data);
		} else {
		} else {
			if (item->inversed)
			if (item->inversed)
				mlxreg_hotplug_device_create(priv->dev, data);
				mlxreg_hotplug_device_create(priv, data);
			else
			else
				mlxreg_hotplug_device_destroy(data);
				mlxreg_hotplug_device_destroy(data);
		}
		}
@@ -319,7 +323,7 @@ mlxreg_hotplug_health_work_helper(struct mlxreg_hotplug_priv_data *priv,
		if (regval == MLXREG_HOTPLUG_HEALTH_MASK) {
		if (regval == MLXREG_HOTPLUG_HEALTH_MASK) {
			if ((data->health_cntr++ == MLXREG_HOTPLUG_RST_CNTR) ||
			if ((data->health_cntr++ == MLXREG_HOTPLUG_RST_CNTR) ||
			    !priv->after_probe) {
			    !priv->after_probe) {
				mlxreg_hotplug_device_create(priv->dev, data);
				mlxreg_hotplug_device_create(priv, data);
				data->attached = true;
				data->attached = true;
			}
			}
		} else {
		} else {
@@ -550,6 +554,7 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev)
{
{
	struct mlxreg_core_hotplug_platform_data *pdata;
	struct mlxreg_core_hotplug_platform_data *pdata;
	struct mlxreg_hotplug_priv_data *priv;
	struct mlxreg_hotplug_priv_data *priv;
	struct i2c_adapter *deferred_adap;
	int err;
	int err;


	pdata = dev_get_platdata(&pdev->dev);
	pdata = dev_get_platdata(&pdev->dev);
@@ -558,6 +563,12 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev)
		return -EINVAL;
		return -EINVAL;
	}
	}


	/* Defer probing if the necessary adapter is not configured yet. */
	deferred_adap = i2c_get_adapter(pdata->deferred_nr);
	if (!deferred_adap)
		return -EPROBE_DEFER;
	i2c_put_adapter(deferred_adap);

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
	if (!priv)
		return -ENOMEM;
		return -ENOMEM;
+3 −0
Original line number Original line Diff line number Diff line
@@ -757,6 +757,8 @@ config TOPSTAR_LAPTOP
	depends on ACPI
	depends on ACPI
	depends on INPUT
	depends on INPUT
	select INPUT_SPARSEKMAP
	select INPUT_SPARSEKMAP
	select LEDS_CLASS
	select NEW_LEDS
	---help---
	---help---
	  This driver adds support for hotkeys found on Topstar laptops.
	  This driver adds support for hotkeys found on Topstar laptops.


@@ -1174,6 +1176,7 @@ config INTEL_TELEMETRY


config MLX_PLATFORM
config MLX_PLATFORM
	tristate "Mellanox Technologies platform support"
	tristate "Mellanox Technologies platform support"
	depends on I2C && REGMAP
	---help---
	---help---
	  This option enables system support for the Mellanox Technologies
	  This option enables system support for the Mellanox Technologies
	  platform. The Mellanox systems provide data center networking
	  platform. The Mellanox systems provide data center networking
+2 −2
Original line number Original line Diff line number Diff line
@@ -514,7 +514,7 @@ static int build_tokens_sysfs(struct platform_device *dev)
		continue;
		continue;


loop_fail_create_value:
loop_fail_create_value:
		kfree(value_name);
		kfree(location_name);
		goto out_unwind_strings;
		goto out_unwind_strings;
	}
	}
	smbios_attribute_group.attrs = token_attrs;
	smbios_attribute_group.attrs = token_attrs;
@@ -525,7 +525,7 @@ static int build_tokens_sysfs(struct platform_device *dev)
	return 0;
	return 0;


out_unwind_strings:
out_unwind_strings:
	for (i = i-1; i > 0; i--) {
	while (i--) {
		kfree(token_location_attrs[i].attr.name);
		kfree(token_location_attrs[i].attr.name);
		kfree(token_value_attrs[i].attr.name);
		kfree(token_value_attrs[i].attr.name);
	}
	}
+106 −93
Original line number Original line Diff line number Diff line
@@ -53,6 +53,7 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/dmi.h>
#include <linux/dmi.h>
#include <linux/backlight.h>
#include <linux/backlight.h>
#include <linux/fb.h>
#include <linux/fb.h>
@@ -61,7 +62,6 @@
#include <linux/kfifo.h>
#include <linux/kfifo.h>
#include <linux/leds.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <acpi/video.h>
#include <acpi/video.h>


#define FUJITSU_DRIVER_VERSION		"0.6.0"
#define FUJITSU_DRIVER_VERSION		"0.6.0"
@@ -76,42 +76,52 @@
#define ACPI_FUJITSU_LAPTOP_DRIVER_NAME	"Fujitsu laptop FUJ02E3 ACPI hotkeys driver"
#define ACPI_FUJITSU_LAPTOP_DRIVER_NAME	"Fujitsu laptop FUJ02E3 ACPI hotkeys driver"
#define ACPI_FUJITSU_LAPTOP_DEVICE_NAME	"Fujitsu FUJ02E3"
#define ACPI_FUJITSU_LAPTOP_DEVICE_NAME	"Fujitsu FUJ02E3"


#define ACPI_FUJITSU_NOTIFY_CODE1     0x80
#define ACPI_FUJITSU_NOTIFY_CODE	0x80


/* FUNC interface - command values */
/* FUNC interface - command values */
#define FUNC_FLAGS	0x1000
#define FUNC_FLAGS			BIT(12)
#define FUNC_LEDS	0x1001
#define FUNC_LEDS			(BIT(12) | BIT(0))
#define FUNC_BUTTONS	0x1002
#define FUNC_BUTTONS			(BIT(12) | BIT(1))
#define FUNC_BACKLIGHT  0x1004
#define FUNC_BACKLIGHT			(BIT(12) | BIT(2))


/* FUNC interface - responses */
/* FUNC interface - responses */
#define UNSUPPORTED_CMD			0x80000000
#define UNSUPPORTED_CMD			0x80000000


/* FUNC interface - status flags */
/* FUNC interface - status flags */
#define FLAG_RFKILL	0x020
#define FLAG_RFKILL			BIT(5)
#define FLAG_LID	0x100
#define FLAG_LID			BIT(8)
#define FLAG_DOCK	0x200
#define FLAG_DOCK			BIT(9)


/* FUNC interface - LED control */
/* FUNC interface - LED control */
#define FUNC_LED_OFF	0x1
#define FUNC_LED_OFF			BIT(0)
#define FUNC_LED_ON	0x30001
#define FUNC_LED_ON			(BIT(0) | BIT(16) | BIT(17))
#define KEYBOARD_LAMPS	0x100
#define LOGOLAMP_POWERON		BIT(13)
#define LOGOLAMP_POWERON 0x2000
#define LOGOLAMP_ALWAYS			BIT(14)
#define LOGOLAMP_ALWAYS  0x4000
#define KEYBOARD_LAMPS			BIT(8)
#define RADIO_LED_ON	0x20
#define RADIO_LED_ON			BIT(5)
#define ECO_LED	0x10000
#define ECO_LED				BIT(16)
#define ECO_LED_ON	0x80000
#define ECO_LED_ON			BIT(19)


/* Hotkey details */
/* FUNC interface - backlight power control */
#define KEY1_CODE	0x410	/* codes for the keys in the GIRB register */
#define BACKLIGHT_PARAM_POWER		BIT(2)
#define BACKLIGHT_OFF			(BIT(0) | BIT(1))
#define BACKLIGHT_ON			0

/* Scancodes read from the GIRB register */
#define KEY1_CODE			0x410
#define KEY2_CODE			0x411
#define KEY2_CODE			0x411
#define KEY3_CODE			0x412
#define KEY3_CODE			0x412
#define KEY4_CODE			0x413
#define KEY4_CODE			0x413
#define KEY5_CODE			0x420
#define KEY5_CODE			0x420


/* Hotkey ringbuffer limits */
#define MAX_HOTKEY_RINGBUFFER_SIZE	100
#define MAX_HOTKEY_RINGBUFFER_SIZE	100
#define RINGBUFFERSIZE			40
#define RINGBUFFERSIZE			40


/* Module parameters */
static int use_alt_lcd_levels = -1;
static bool disable_brightness_adjust;

/* Device controlling the backlight and associated keys */
/* Device controlling the backlight and associated keys */
struct fujitsu_bl {
struct fujitsu_bl {
	struct input_dev *input;
	struct input_dev *input;
@@ -122,8 +132,6 @@ struct fujitsu_bl {
};
};


static struct fujitsu_bl *fujitsu_bl;
static struct fujitsu_bl *fujitsu_bl;
static int use_alt_lcd_levels = -1;
static bool disable_brightness_adjust;


/* Device used to access hotkeys and other features on the laptop */
/* Device used to access hotkeys and other features on the laptop */
struct fujitsu_laptop {
struct fujitsu_laptop {
@@ -256,9 +264,11 @@ static int bl_update_status(struct backlight_device *b)


	if (fext) {
	if (fext) {
		if (b->props.power == FB_BLANK_POWERDOWN)
		if (b->props.power == FB_BLANK_POWERDOWN)
			call_fext_func(fext, FUNC_BACKLIGHT, 0x1, 0x4, 0x3);
			call_fext_func(fext, FUNC_BACKLIGHT, 0x1,
				       BACKLIGHT_PARAM_POWER, BACKLIGHT_OFF);
		else
		else
			call_fext_func(fext, FUNC_BACKLIGHT, 0x1, 0x4, 0x0);
			call_fext_func(fext, FUNC_BACKLIGHT, 0x1,
				       BACKLIGHT_PARAM_POWER, BACKLIGHT_ON);
	}
	}


	return set_lcd_level(device, b->props.brightness);
	return set_lcd_level(device, b->props.brightness);
@@ -385,7 +395,7 @@ static int fujitsu_backlight_register(struct acpi_device *device)
static int acpi_fujitsu_bl_add(struct acpi_device *device)
static int acpi_fujitsu_bl_add(struct acpi_device *device)
{
{
	struct fujitsu_bl *priv;
	struct fujitsu_bl *priv;
	int error;
	int ret;


	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
		return -ENODEV;
		return -ENODEV;
@@ -399,10 +409,6 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device)
	strcpy(acpi_device_class(device), ACPI_FUJITSU_CLASS);
	strcpy(acpi_device_class(device), ACPI_FUJITSU_CLASS);
	device->driver_data = priv;
	device->driver_data = priv;


	error = acpi_fujitsu_bl_input_setup(device);
	if (error)
		return error;

	pr_info("ACPI: %s [%s]\n",
	pr_info("ACPI: %s [%s]\n",
		acpi_device_name(device), acpi_device_bid(device));
		acpi_device_name(device), acpi_device_bid(device));


@@ -410,11 +416,11 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device)
		priv->max_brightness = FUJITSU_LCD_N_LEVELS;
		priv->max_brightness = FUJITSU_LCD_N_LEVELS;
	get_lcd_level(device);
	get_lcd_level(device);


	error = fujitsu_backlight_register(device);
	ret = acpi_fujitsu_bl_input_setup(device);
	if (error)
	if (ret)
		return error;
		return ret;


	return 0;
	return fujitsu_backlight_register(device);
}
}


/* Brightness notify */
/* Brightness notify */
@@ -424,7 +430,7 @@ static void acpi_fujitsu_bl_notify(struct acpi_device *device, u32 event)
	struct fujitsu_bl *priv = acpi_driver_data(device);
	struct fujitsu_bl *priv = acpi_driver_data(device);
	int oldb, newb;
	int oldb, newb;


	if (event != ACPI_FUJITSU_NOTIFY_CODE1) {
	if (event != ACPI_FUJITSU_NOTIFY_CODE) {
		acpi_handle_info(device->handle, "unsupported event [0x%x]\n",
		acpi_handle_info(device->handle, "unsupported event [0x%x]\n",
				 event);
				 event);
		sparse_keymap_report_event(priv->input, -1, 1, true);
		sparse_keymap_report_event(priv->input, -1, 1, true);
@@ -455,7 +461,9 @@ static const struct key_entry keymap_default[] = {
	{ KE_KEY, KEY3_CODE, { KEY_PROG3 } },
	{ KE_KEY, KEY3_CODE, { KEY_PROG3 } },
	{ KE_KEY, KEY4_CODE, { KEY_PROG4 } },
	{ KE_KEY, KEY4_CODE, { KEY_PROG4 } },
	{ KE_KEY, KEY5_CODE, { KEY_RFKILL } },
	{ KE_KEY, KEY5_CODE, { KEY_RFKILL } },
	{ KE_KEY, BIT(5),    { KEY_RFKILL } },
	{ KE_KEY, BIT(26),   { KEY_TOUCHPAD_TOGGLE } },
	{ KE_KEY, BIT(26),   { KEY_TOUCHPAD_TOGGLE } },
	{ KE_KEY, BIT(29),   { KEY_MICMUTE } },
	{ KE_END, 0 }
	{ KE_END, 0 }
};
};


@@ -693,7 +701,7 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
{
{
	struct fujitsu_laptop *priv = acpi_driver_data(device);
	struct fujitsu_laptop *priv = acpi_driver_data(device);
	struct led_classdev *led;
	struct led_classdev *led;
	int result;
	int ret;


	if (call_fext_func(device,
	if (call_fext_func(device,
			   FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
			   FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
@@ -704,9 +712,9 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
		led->name = "fujitsu::logolamp";
		led->name = "fujitsu::logolamp";
		led->brightness_set_blocking = logolamp_set;
		led->brightness_set_blocking = logolamp_set;
		led->brightness_get = logolamp_get;
		led->brightness_get = logolamp_get;
		result = devm_led_classdev_register(&device->dev, led);
		ret = devm_led_classdev_register(&device->dev, led);
		if (result)
		if (ret)
			return result;
			return ret;
	}
	}


	if ((call_fext_func(device,
	if ((call_fext_func(device,
@@ -719,9 +727,9 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
		led->name = "fujitsu::kblamps";
		led->name = "fujitsu::kblamps";
		led->brightness_set_blocking = kblamps_set;
		led->brightness_set_blocking = kblamps_set;
		led->brightness_get = kblamps_get;
		led->brightness_get = kblamps_get;
		result = devm_led_classdev_register(&device->dev, led);
		ret = devm_led_classdev_register(&device->dev, led);
		if (result)
		if (ret)
			return result;
			return ret;
	}
	}


	/*
	/*
@@ -742,9 +750,9 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
		led->brightness_set_blocking = radio_led_set;
		led->brightness_set_blocking = radio_led_set;
		led->brightness_get = radio_led_get;
		led->brightness_get = radio_led_get;
		led->default_trigger = "rfkill-any";
		led->default_trigger = "rfkill-any";
		result = devm_led_classdev_register(&device->dev, led);
		ret = devm_led_classdev_register(&device->dev, led);
		if (result)
		if (ret)
			return result;
			return ret;
	}
	}


	/* Support for eco led is not always signaled in bit corresponding
	/* 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)
		led->name = "fujitsu::eco_led";
		led->name = "fujitsu::eco_led";
		led->brightness_set_blocking = eco_led_set;
		led->brightness_set_blocking = eco_led_set;
		led->brightness_get = eco_led_get;
		led->brightness_get = eco_led_get;
		result = devm_led_classdev_register(&device->dev, led);
		ret = devm_led_classdev_register(&device->dev, led);
		if (result)
		if (ret)
			return result;
			return ret;
	}
	}


	return 0;
	return 0;
@@ -773,8 +781,7 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
static int acpi_fujitsu_laptop_add(struct acpi_device *device)
static int acpi_fujitsu_laptop_add(struct acpi_device *device)
{
{
	struct fujitsu_laptop *priv;
	struct fujitsu_laptop *priv;
	int error;
	int ret, i = 0;
	int i;


	priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
	priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
	if (!priv)
@@ -789,23 +796,16 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)


	/* kfifo */
	/* kfifo */
	spin_lock_init(&priv->fifo_lock);
	spin_lock_init(&priv->fifo_lock);
	error = kfifo_alloc(&priv->fifo, RINGBUFFERSIZE * sizeof(int),
	ret = kfifo_alloc(&priv->fifo, RINGBUFFERSIZE * sizeof(int),
			  GFP_KERNEL);
			  GFP_KERNEL);
	if (error) {
	if (ret)
		pr_err("kfifo_alloc failed\n");
		return ret;
		goto err_stop;
	}

	error = acpi_fujitsu_laptop_input_setup(device);
	if (error)
		goto err_free_fifo;


	pr_info("ACPI: %s [%s]\n",
	pr_info("ACPI: %s [%s]\n",
		acpi_device_name(device), acpi_device_bid(device));
		acpi_device_name(device), acpi_device_bid(device));


	i = 0;
	while (call_fext_func(device, FUNC_BUTTONS, 0x1, 0x0, 0x0) != 0 &&
	while (call_fext_func(device, FUNC_BUTTONS, 0x1, 0x0, 0x0) != 0
	       i++ < MAX_HOTKEY_RINGBUFFER_SIZE)
		&& (i++) < MAX_HOTKEY_RINGBUFFER_SIZE)
		; /* No action, result is discarded */
		; /* No action, result is discarded */
	acpi_handle_debug(device->handle, "Discarded %i ringbuffer entries\n",
	acpi_handle_debug(device->handle, "Discarded %i ringbuffer entries\n",
			  i);
			  i);
@@ -829,26 +829,31 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
	/* Sync backlight power status */
	/* Sync backlight power status */
	if (fujitsu_bl && fujitsu_bl->bl_device &&
	if (fujitsu_bl && fujitsu_bl->bl_device &&
	    acpi_video_get_backlight_type() == acpi_backlight_vendor) {
	    acpi_video_get_backlight_type() == acpi_backlight_vendor) {
		if (call_fext_func(fext, FUNC_BACKLIGHT, 0x2, 0x4, 0x0) == 3)
		if (call_fext_func(fext, FUNC_BACKLIGHT, 0x2,
				   BACKLIGHT_PARAM_POWER, 0x0) == BACKLIGHT_OFF)
			fujitsu_bl->bl_device->props.power = FB_BLANK_POWERDOWN;
			fujitsu_bl->bl_device->props.power = FB_BLANK_POWERDOWN;
		else
		else
			fujitsu_bl->bl_device->props.power = FB_BLANK_UNBLANK;
			fujitsu_bl->bl_device->props.power = FB_BLANK_UNBLANK;
	}
	}


	error = acpi_fujitsu_laptop_leds_register(device);
	ret = acpi_fujitsu_laptop_input_setup(device);
	if (error)
	if (ret)
		goto err_free_fifo;

	ret = acpi_fujitsu_laptop_leds_register(device);
	if (ret)
		goto err_free_fifo;
		goto err_free_fifo;


	error = fujitsu_laptop_platform_add(device);
	ret = fujitsu_laptop_platform_add(device);
	if (error)
	if (ret)
		goto err_free_fifo;
		goto err_free_fifo;


	return 0;
	return 0;


err_free_fifo:
err_free_fifo:
	kfifo_free(&priv->fifo);
	kfifo_free(&priv->fifo);
err_stop:

	return error;
	return ret;
}
}


static int acpi_fujitsu_laptop_remove(struct acpi_device *device)
static int acpi_fujitsu_laptop_remove(struct acpi_device *device)
@@ -865,11 +870,11 @@ static int acpi_fujitsu_laptop_remove(struct acpi_device *device)
static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode)
static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode)
{
{
	struct fujitsu_laptop *priv = acpi_driver_data(device);
	struct fujitsu_laptop *priv = acpi_driver_data(device);
	int status;
	int ret;


	status = kfifo_in_locked(&priv->fifo, (unsigned char *)&scancode,
	ret = kfifo_in_locked(&priv->fifo, (unsigned char *)&scancode,
			      sizeof(scancode), &priv->fifo_lock);
			      sizeof(scancode), &priv->fifo_lock);
	if (status != sizeof(scancode)) {
	if (ret != sizeof(scancode)) {
		dev_info(&priv->input->dev, "Could not push scancode [0x%x]\n",
		dev_info(&priv->input->dev, "Could not push scancode [0x%x]\n",
			 scancode);
			 scancode);
		return;
		return;
@@ -882,13 +887,12 @@ static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode)
static void acpi_fujitsu_laptop_release(struct acpi_device *device)
static void acpi_fujitsu_laptop_release(struct acpi_device *device)
{
{
	struct fujitsu_laptop *priv = acpi_driver_data(device);
	struct fujitsu_laptop *priv = acpi_driver_data(device);
	int scancode, status;
	int scancode, ret;


	while (true) {
	while (true) {
		status = kfifo_out_locked(&priv->fifo,
		ret = kfifo_out_locked(&priv->fifo, (unsigned char *)&scancode,
					  (unsigned char *)&scancode,
				       sizeof(scancode), &priv->fifo_lock);
				       sizeof(scancode), &priv->fifo_lock);
		if (status != sizeof(scancode))
		if (ret != sizeof(scancode))
			return;
			return;
		sparse_keymap_report_event(priv->input, scancode, 0, false);
		sparse_keymap_report_event(priv->input, scancode, 0, false);
		dev_dbg(&priv->input->dev,
		dev_dbg(&priv->input->dev,
@@ -899,10 +903,10 @@ static void acpi_fujitsu_laptop_release(struct acpi_device *device)
static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
{
{
	struct fujitsu_laptop *priv = acpi_driver_data(device);
	struct fujitsu_laptop *priv = acpi_driver_data(device);
	int scancode, i = 0;
	int scancode, i = 0, ret;
	unsigned int irb;
	unsigned int irb;


	if (event != ACPI_FUJITSU_NOTIFY_CODE1) {
	if (event != ACPI_FUJITSU_NOTIFY_CODE) {
		acpi_handle_info(device->handle, "Unsupported event [0x%x]\n",
		acpi_handle_info(device->handle, "Unsupported event [0x%x]\n",
				 event);
				 event);
		sparse_keymap_report_event(priv->input, -1, 1, true);
		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)
	 * E736/E746/E756), the touchpad toggle hotkey (Fn+F4) is
	 * E736/E746/E756), the touchpad toggle hotkey (Fn+F4) is
	 * handled in software; its state is queried using FUNC_FLAGS
	 * handled in software; its state is queried using FUNC_FLAGS
	 */
	 */
	if ((priv->flags_supported & BIT(26)) &&
	if (priv->flags_supported & (BIT(5) | BIT(26) | BIT(29))) {
	    (call_fext_func(device, FUNC_FLAGS, 0x1, 0x0, 0x0) & BIT(26)))
		ret = call_fext_func(device, FUNC_FLAGS, 0x1, 0x0, 0x0);
		sparse_keymap_report_event(priv->input, BIT(26), 1, true);
		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);
	}
}
}


/* Initialization */
/* Initialization */
+2 −2
Original line number Original line Diff line number Diff line
@@ -19,12 +19,12 @@
static int temp_limits[3] = { 55000, 60000, 65000 };
static int temp_limits[3] = { 55000, 60000, 65000 };
module_param_array(temp_limits, int, NULL, 0444);
module_param_array(temp_limits, int, NULL, 0444);
MODULE_PARM_DESC(temp_limits,
MODULE_PARM_DESC(temp_limits,
		 "Milli-celcius values above which the fan speed increases");
		 "Millicelsius values above which the fan speed increases");


static int hysteresis = 3000;
static int hysteresis = 3000;
module_param(hysteresis, int, 0444);
module_param(hysteresis, int, 0444);
MODULE_PARM_DESC(hysteresis,
MODULE_PARM_DESC(hysteresis,
		 "Hysteresis in milli-celcius before lowering the fan speed");
		 "Hysteresis in millicelsius before lowering the fan speed");


static int speed_on_ac = 2;
static int speed_on_ac = 2;
module_param(speed_on_ac, int, 0444);
module_param(speed_on_ac, int, 0444);
Loading