mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'platform-drivers-x86-v4.20-1' of git://git.infradead.org/linux-platform-drivers-x86
Pull x86 platform driver updates from Darren Hart: - Move the Dell dcdbas and dell_rbu drivers into platform/drivers/x86 as they are closely coupled with other drivers in this location. - Improve _init* usage for acerhdf and fix some usage issues with messages and module parameters. - Simplify asus-wmi by calling ACPI/WMI methods directly, eliminating workqueue overhead, eliminate double reporting of keyboard backlight. - Fix wake from USB failure on Bay Trail devices (intel_int0002_vgpio). - Notify intel_telemetry users when IPC1 device is not enabled. - Update various drivers with new laptop model IDs. - Update several intel drivers to use SPDX identifers and order headers alphabetically. * tag 'platform-drivers-x86-v4.20-1' of git://git.infradead.org/linux-platform-drivers-x86: (64 commits) HID: asus: only support backlight when it's not driven by WMI platform/x86: asus-wmi: export function for evaluating WMI methods platform/x86: asus-wmi: Only notify kbd LED hw_change by fn-key pressed platform/x86: wmi: declare device_type structure as constant platform/x86: ideapad: Add Y530-15ICH to no_hw_rfkill platform/x86: Add Intel AtomISP2 dummy / power-management driver platform/x86: touchscreen_dmi: Add min-x and min-y settings for various models platform/x86: touchscreen_dmi: Add info for the Onda V80 Plus v3 tablet platform/x86: touchscreen_dmi: Add info for the Trekstor Primetab T13B tablet platform/x86: intel_telemetry: Get rid of custom macro platform/x86: intel_telemetry: report debugfs failure MAINTAINERS: intel_telemetry: Update maintainers info platform/x86: Add LG Gram laptop special features driver platform/x86: asus-wmi: Simplify the keyboard brightness updating process platform/x86: touchscreen_dmi: Add info for the Trekstor Primebook C11 convertible platform/x86: mlx-platform: Properly use mlxplat_mlxcpld_msn201x_items MAINTAINERS: intel_pmc_core: Update MAINTAINERS firmware: dcdbas: include linux/io.h platform/x86: intel-wmi-thunderbolt: Add dynamic debugging platform/x86: intel-wmi-thunderbolt: Convert to use SPDX identifier ...
This commit is contained in:
35
Documentation/ABI/testing/sysfs-platform-lg-laptop
Normal file
35
Documentation/ABI/testing/sysfs-platform-lg-laptop
Normal file
@@ -0,0 +1,35 @@
|
||||
What: /sys/devices/platform/lg-laptop/reader_mode
|
||||
Date: October 2018
|
||||
KernelVersion: 4.20
|
||||
Contact: "Matan Ziv-Av <matan@svgalib.org>
|
||||
Description:
|
||||
Control reader mode. 1 means on, 0 means off.
|
||||
|
||||
What: /sys/devices/platform/lg-laptop/fn_lock
|
||||
Date: October 2018
|
||||
KernelVersion: 4.20
|
||||
Contact: "Matan Ziv-Av <matan@svgalib.org>
|
||||
Description:
|
||||
Control FN lock mode. 1 means on, 0 means off.
|
||||
|
||||
What: /sys/devices/platform/lg-laptop/battery_care_limit
|
||||
Date: October 2018
|
||||
KernelVersion: 4.20
|
||||
Contact: "Matan Ziv-Av <matan@svgalib.org>
|
||||
Description:
|
||||
Maximal battery charge level. Accepted values are 80 or 100.
|
||||
|
||||
What: /sys/devices/platform/lg-laptop/fan_mode
|
||||
Date: October 2018
|
||||
KernelVersion: 4.20
|
||||
Contact: "Matan Ziv-Av <matan@svgalib.org>
|
||||
Description:
|
||||
Control fan mode. 1 for performance mode, 0 for silent mode.
|
||||
|
||||
What: /sys/devices/platform/lg-laptop/usb_charge
|
||||
Date: October 2018
|
||||
KernelVersion: 4.20
|
||||
Contact: "Matan Ziv-Av <matan@svgalib.org>
|
||||
Description:
|
||||
Control USB port charging when device is turned off.
|
||||
1 means on, 0 means off.
|
||||
81
Documentation/laptops/lg-laptop.rst
Normal file
81
Documentation/laptops/lg-laptop.rst
Normal file
@@ -0,0 +1,81 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
LG Gram laptop extra features
|
||||
=============================
|
||||
|
||||
By Matan Ziv-Av <matan@svgalib.org>
|
||||
|
||||
|
||||
Hotkeys
|
||||
-------
|
||||
|
||||
The following FN keys are ignored by the kernel without this driver:
|
||||
- FN-F1 (LG control panel) - Generates F15
|
||||
- FN-F5 (Touchpad toggle) - Generates F13
|
||||
- FN-F6 (Airplane mode) - Generates RFKILL
|
||||
- FN-F8 (Keyboard backlight) - Generates F16.
|
||||
This key also changes keyboard backlight mode.
|
||||
- FN-F9 (Reader mode) - Generates F14
|
||||
|
||||
The rest of the FN key work without a need for a special driver.
|
||||
|
||||
|
||||
Reader mode
|
||||
-----------
|
||||
|
||||
Writing 0/1 to /sys/devices/platform/lg-laptop/reader_mode disables/enables
|
||||
reader mode. In this mode the screen colors change (blue color reduced),
|
||||
and the reader mode indicator LED (on F9 key) turns on.
|
||||
|
||||
|
||||
FN Lock
|
||||
-------
|
||||
|
||||
Writing 0/1 to /sys/devices/platform/lg-laptop/fn_lock disables/enables
|
||||
FN lock.
|
||||
|
||||
|
||||
Battery care limit
|
||||
------------------
|
||||
|
||||
Writing 80/100 to /sys/devices/platform/lg-laptop/battery_care_limit
|
||||
sets the maximum capacity to charge the battery. Limiting the charge
|
||||
reduces battery capacity loss over time.
|
||||
|
||||
This value is reset to 100 when the kernel boots.
|
||||
|
||||
|
||||
Fan mode
|
||||
--------
|
||||
|
||||
Writing 1/0 to /sys/devices/platform/lg-laptop/fan_mode disables/enables
|
||||
the fan silent mode.
|
||||
|
||||
|
||||
USB charge
|
||||
----------
|
||||
|
||||
Writing 0/1 to /sys/devices/platform/lg-laptop/usb_charge disables/enables
|
||||
charging another device from the USB port while the device is turned off.
|
||||
|
||||
This value is reset to 0 when the kernel boots.
|
||||
|
||||
|
||||
LEDs
|
||||
~~~~
|
||||
|
||||
The are two LED devices supported by the driver:
|
||||
|
||||
Keyboard backlight
|
||||
------------------
|
||||
|
||||
A led device named kbd_led controls the keyboard backlight. There are three
|
||||
lighting level: off (0), low (127) and high (255).
|
||||
|
||||
The keyboard backlight is also controlled by the key combination FN-F8
|
||||
which cycles through those levels.
|
||||
|
||||
|
||||
Touchpad indicator LED
|
||||
----------------------
|
||||
|
||||
On the F5 key. Controlled by led device names tpad_led.
|
||||
31
MAINTAINERS
31
MAINTAINERS
@@ -376,7 +376,7 @@ F: drivers/platform/x86/i2c-multi-instantiate.c
|
||||
ACPI PMIC DRIVERS
|
||||
M: "Rafael J. Wysocki" <rjw@rjwysocki.net>
|
||||
M: Len Brown <lenb@kernel.org>
|
||||
R: Andy Shevchenko <andy@infradead.org>
|
||||
R: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
R: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
L: linux-acpi@vger.kernel.org
|
||||
Q: https://patchwork.kernel.org/project/linux-acpi/list/
|
||||
@@ -4207,6 +4207,12 @@ M: Pali Rohár <pali.rohar@gmail.com>
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/dell-rbtn.*
|
||||
|
||||
DELL REMOTE BIOS UPDATE DRIVER
|
||||
M: Stuart Hayes <stuart.w.hayes@gmail.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/dell_rbu.c
|
||||
|
||||
DELL LAPTOP SMM DRIVER
|
||||
M: Pali Rohár <pali.rohar@gmail.com>
|
||||
S: Maintained
|
||||
@@ -4214,10 +4220,11 @@ F: drivers/hwmon/dell-smm-hwmon.c
|
||||
F: include/uapi/linux/i8k.h
|
||||
|
||||
DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
|
||||
M: Doug Warzecha <Douglas_Warzecha@dell.com>
|
||||
M: Stuart Hayes <stuart.w.hayes@gmail.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/dcdbas.txt
|
||||
F: drivers/firmware/dcdbas.*
|
||||
F: drivers/platform/x86/dcdbas.*
|
||||
|
||||
DELL WMI NOTIFICATIONS DRIVER
|
||||
M: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
@@ -7347,6 +7354,12 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
F: sound/soc/intel/
|
||||
|
||||
INTEL ATOMISP2 DUMMY / POWER-MANAGEMENT DRIVER
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/intel_atomisp2_pm.c
|
||||
|
||||
INTEL C600 SERIES SAS CONTROLLER DRIVER
|
||||
M: Intel SCU Linux support <intel-linux-scu@intel.com>
|
||||
M: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
|
||||
@@ -7533,7 +7546,6 @@ M: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
|
||||
M: Vishwanath Somayaji <vishwanath.somayaji@intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: arch/x86/include/asm/pmc_core.h
|
||||
F: drivers/platform/x86/intel_pmc_core*
|
||||
|
||||
INTEL PMC/P-Unit IPC DRIVER
|
||||
@@ -7577,7 +7589,8 @@ F: drivers/infiniband/hw/i40iw/
|
||||
F: include/uapi/rdma/i40iw-abi.h
|
||||
|
||||
INTEL TELEMETRY DRIVER
|
||||
M: Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>
|
||||
M: Rajneesh Bhardwaj <rajneesh.bhardwaj@linux.intel.com>
|
||||
M: "David E. Box" <david.e.box@linux.intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: arch/x86/include/asm/intel_telemetry.h
|
||||
@@ -8310,6 +8323,14 @@ W: http://legousb.sourceforge.net/
|
||||
S: Maintained
|
||||
F: drivers/usb/misc/legousbtower.c
|
||||
|
||||
LG LAPTOP EXTRAS
|
||||
M: Matan Ziv-Av <matan@svgalib.org>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-platform-lg-laptop
|
||||
F: Documentation/laptops/lg-laptop.rst
|
||||
F: drivers/platform/x86/lg-laptop.c
|
||||
|
||||
LG2160 MEDIA DRIVER
|
||||
M: Michael Krufky <mkrufky@linuxtv.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
||||
@@ -145,34 +145,6 @@ config EFI_PCDP
|
||||
See DIG64_HCDPv20_042804.pdf available from
|
||||
<http://www.dig64.org/specifications/>
|
||||
|
||||
config DELL_RBU
|
||||
tristate "BIOS update support for DELL systems via sysfs"
|
||||
depends on X86
|
||||
select FW_LOADER
|
||||
select FW_LOADER_USER_HELPER
|
||||
help
|
||||
Say m if you want to have the option of updating the BIOS for your
|
||||
DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
|
||||
supporting application to communicate with the BIOS regarding the new
|
||||
image for the image update to take effect.
|
||||
See <file:Documentation/dell_rbu.txt> for more details on the driver.
|
||||
|
||||
config DCDBAS
|
||||
tristate "Dell Systems Management Base Driver"
|
||||
depends on X86
|
||||
help
|
||||
The Dell Systems Management Base Driver provides a sysfs interface
|
||||
for systems management software to perform System Management
|
||||
Interrupts (SMIs) and Host Control Actions (system power cycle or
|
||||
power off after OS shutdown) on certain Dell systems.
|
||||
|
||||
See <file:Documentation/dcdbas.txt> for more details on the driver
|
||||
and the Dell systems on which Dell systems management software makes
|
||||
use of this driver.
|
||||
|
||||
Say Y or M here to enable the driver for use by Dell systems
|
||||
management software such as Dell OpenManage.
|
||||
|
||||
config DMIID
|
||||
bool "Export DMI identification via sysfs to userspace"
|
||||
depends on DMI
|
||||
|
||||
@@ -11,8 +11,6 @@ obj-$(CONFIG_DMI) += dmi_scan.o
|
||||
obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o
|
||||
obj-$(CONFIG_EDD) += edd.o
|
||||
obj-$(CONFIG_EFI_PCDP) += pcdp.o
|
||||
obj-$(CONFIG_DELL_RBU) += dell_rbu.o
|
||||
obj-$(CONFIG_DCDBAS) += dcdbas.o
|
||||
obj-$(CONFIG_DMIID) += dmi-id.o
|
||||
obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
|
||||
obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
|
||||
|
||||
@@ -149,6 +149,7 @@ config HID_APPLEIR
|
||||
config HID_ASUS
|
||||
tristate "Asus"
|
||||
depends on LEDS_CLASS
|
||||
depends on ASUS_WMI || ASUS_WMI=n
|
||||
---help---
|
||||
Support for Asus notebook built-in keyboard and touchpad via i2c, and
|
||||
the Asus Republic of Gamers laptop keyboard special keys.
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_data/x86/asus-wmi.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */
|
||||
|
||||
@@ -349,6 +350,24 @@ static void asus_kbd_backlight_work(struct work_struct *work)
|
||||
hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret);
|
||||
}
|
||||
|
||||
/* WMI-based keyboard backlight LED control (via asus-wmi driver) takes
|
||||
* precedence. We only activate HID-based backlight control when the
|
||||
* WMI control is not available.
|
||||
*/
|
||||
static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
|
||||
{
|
||||
u32 value;
|
||||
int ret;
|
||||
|
||||
ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2,
|
||||
ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
|
||||
hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
return !!(value & ASUS_WMI_DSTS_PRESENCE_BIT);
|
||||
}
|
||||
|
||||
static int asus_kbd_register_leds(struct hid_device *hdev)
|
||||
{
|
||||
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
|
||||
@@ -436,7 +455,9 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
|
||||
|
||||
drvdata->input = input;
|
||||
|
||||
if (drvdata->enable_backlight && asus_kbd_register_leds(hdev))
|
||||
if (drvdata->enable_backlight &&
|
||||
!asus_kbd_wmi_led_control_present(hdev) &&
|
||||
asus_kbd_register_leds(hdev))
|
||||
hid_warn(hdev, "Failed to initialize backlight.\n");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -60,7 +60,10 @@ config ACERHDF
|
||||
|
||||
After loading this driver the BIOS is still in control of the fan.
|
||||
To let the kernel handle the fan, do:
|
||||
echo -n enabled > /sys/class/thermal/thermal_zone0/mode
|
||||
echo -n enabled > /sys/class/thermal/thermal_zoneN/mode
|
||||
where N=0,1,2... depending on the number of thermal nodes and the
|
||||
detection order of your particular system. The "type" parameter
|
||||
in the same node directory will tell you if it is "acerhdf".
|
||||
|
||||
For more information about this driver see
|
||||
<http://piie.net/files/acerhdf_README.txt>
|
||||
@@ -105,6 +108,22 @@ config ASUS_LAPTOP
|
||||
|
||||
If you have an ACPI-compatible ASUS laptop, say Y or M here.
|
||||
|
||||
config DCDBAS
|
||||
tristate "Dell Systems Management Base Driver"
|
||||
depends on X86
|
||||
help
|
||||
The Dell Systems Management Base Driver provides a sysfs interface
|
||||
for systems management software to perform System Management
|
||||
Interrupts (SMIs) and Host Control Actions (system power cycle or
|
||||
power off after OS shutdown) on certain Dell systems.
|
||||
|
||||
See <file:Documentation/dcdbas.txt> for more details on the driver
|
||||
and the Dell systems on which Dell systems management software makes
|
||||
use of this driver.
|
||||
|
||||
Say Y or M here to enable the driver for use by Dell systems
|
||||
management software such as Dell OpenManage.
|
||||
|
||||
#
|
||||
# The DELL_SMBIOS driver depends on ACPI_WMI and/or DCDBAS if those
|
||||
# backends are selected. The "depends" line prevents a configuration
|
||||
@@ -227,6 +246,18 @@ config DELL_RBTN
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called dell-rbtn.
|
||||
|
||||
config DELL_RBU
|
||||
tristate "BIOS update support for DELL systems via sysfs"
|
||||
depends on X86
|
||||
select FW_LOADER
|
||||
select FW_LOADER_USER_HELPER
|
||||
help
|
||||
Say m if you want to have the option of updating the BIOS for your
|
||||
DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
|
||||
supporting application to communicate with the BIOS regarding the new
|
||||
image for the image update to take effect.
|
||||
See <file:Documentation/dell_rbu.txt> for more details on the driver.
|
||||
|
||||
|
||||
config FUJITSU_LAPTOP
|
||||
tristate "Fujitsu Laptop Extras"
|
||||
@@ -336,6 +367,20 @@ config HP_WMI
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called hp-wmi.
|
||||
|
||||
config LG_LAPTOP
|
||||
tristate "LG Laptop Extras"
|
||||
depends on ACPI
|
||||
depends on ACPI_WMI
|
||||
depends on INPUT
|
||||
select INPUT_SPARSEKMAP
|
||||
select LEDS_CLASS
|
||||
help
|
||||
This driver adds support for hotkeys as well as control of keyboard
|
||||
backlight, battery maximum charge level and various other ACPI
|
||||
features.
|
||||
|
||||
If you have an LG Gram laptop, say Y or M here.
|
||||
|
||||
config MSI_LAPTOP
|
||||
tristate "MSI Laptop Extras"
|
||||
depends on ACPI
|
||||
@@ -1231,6 +1276,18 @@ config I2C_MULTI_INSTANTIATE
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called i2c-multi-instantiate.
|
||||
|
||||
config INTEL_ATOMISP2_PM
|
||||
tristate "Intel AtomISP2 dummy / power-management driver"
|
||||
depends on PCI && IOSF_MBI && PM
|
||||
help
|
||||
Power-management driver for Intel's Image Signal Processor found on
|
||||
Bay and Cherry Trail devices. This dummy driver's sole purpose is to
|
||||
turn the ISP off (put it in D3) to save power and to allow entering
|
||||
of S0ix modes.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_atomisp2_pm.
|
||||
|
||||
endif # X86_PLATFORM_DEVICES
|
||||
|
||||
config PMC_ATOM
|
||||
|
||||
@@ -9,9 +9,11 @@ obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o
|
||||
obj-$(CONFIG_ASUS_WIRELESS) += asus-wireless.o
|
||||
obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
|
||||
obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o
|
||||
obj-$(CONFIG_LG_LAPTOP) += lg-laptop.o
|
||||
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
|
||||
obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o
|
||||
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
|
||||
obj-$(CONFIG_DCDBAS) += dcdbas.o
|
||||
obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o
|
||||
dell-smbios-objs := dell-smbios-base.o
|
||||
dell-smbios-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o
|
||||
@@ -23,6 +25,7 @@ obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
|
||||
obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
|
||||
obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
|
||||
obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o
|
||||
obj-$(CONFIG_DELL_RBU) += dell_rbu.o
|
||||
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
|
||||
obj-$(CONFIG_ACER_WIRELESS) += acer-wireless.o
|
||||
obj-$(CONFIG_ACERHDF) += acerhdf.o
|
||||
@@ -92,3 +95,4 @@ obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
|
||||
obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
|
||||
obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o
|
||||
obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o
|
||||
obj-$(CONFIG_INTEL_ATOMISP2_PM) += intel_atomisp2_pm.o
|
||||
|
||||
@@ -86,6 +86,7 @@ static unsigned int interval = 10;
|
||||
static unsigned int fanon = 60000;
|
||||
static unsigned int fanoff = 53000;
|
||||
static unsigned int verbose;
|
||||
static unsigned int list_supported;
|
||||
static unsigned int fanstate = ACERHDF_FAN_AUTO;
|
||||
static char force_bios[16];
|
||||
static char force_product[16];
|
||||
@@ -104,10 +105,12 @@ module_param(fanoff, uint, 0600);
|
||||
MODULE_PARM_DESC(fanoff, "Turn the fan off below this temperature");
|
||||
module_param(verbose, uint, 0600);
|
||||
MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
|
||||
module_param(list_supported, uint, 0600);
|
||||
MODULE_PARM_DESC(list_supported, "List supported models and BIOS versions");
|
||||
module_param_string(force_bios, force_bios, 16, 0);
|
||||
MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check");
|
||||
MODULE_PARM_DESC(force_bios, "Pretend system has this known supported BIOS version");
|
||||
module_param_string(force_product, force_product, 16, 0);
|
||||
MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check");
|
||||
MODULE_PARM_DESC(force_product, "Pretend system is this known supported model");
|
||||
|
||||
/*
|
||||
* cmd_off: to switch the fan completely off and check if the fan is off
|
||||
@@ -130,7 +133,7 @@ static const struct manualcmd mcmd = {
|
||||
.moff = 0xff,
|
||||
};
|
||||
|
||||
/* BIOS settings */
|
||||
/* BIOS settings - only used during probe */
|
||||
struct bios_settings {
|
||||
const char *vendor;
|
||||
const char *product;
|
||||
@@ -141,8 +144,18 @@ struct bios_settings {
|
||||
int mcmd_enable;
|
||||
};
|
||||
|
||||
/* This could be a daughter struct in the above, but not worth the redirect */
|
||||
struct ctrl_settings {
|
||||
u8 fanreg;
|
||||
u8 tempreg;
|
||||
struct fancmd cmd;
|
||||
int mcmd_enable;
|
||||
};
|
||||
|
||||
static struct ctrl_settings ctrl_cfg __read_mostly;
|
||||
|
||||
/* Register addresses and values for different BIOS versions */
|
||||
static const struct bios_settings bios_tbl[] = {
|
||||
static const struct bios_settings bios_tbl[] __initconst = {
|
||||
/* AOA110 */
|
||||
{"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00}, 0},
|
||||
{"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00}, 0},
|
||||
@@ -233,6 +246,7 @@ static const struct bios_settings bios_tbl[] = {
|
||||
{"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0},
|
||||
{"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0},
|
||||
{"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0},
|
||||
{"Gateway", "LT31", "v1.3307", 0x55, 0x58, {0x9e, 0x00}, 0},
|
||||
/* Packard Bell */
|
||||
{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00}, 0},
|
||||
{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0},
|
||||
@@ -256,8 +270,6 @@ static const struct bios_settings bios_tbl[] = {
|
||||
{"", "", "", 0, 0, {0, 0}, 0}
|
||||
};
|
||||
|
||||
static const struct bios_settings *bios_cfg __read_mostly;
|
||||
|
||||
/*
|
||||
* this struct is used to instruct thermal layer to use bang_bang instead of
|
||||
* default governor for acerhdf
|
||||
@@ -270,7 +282,7 @@ static int acerhdf_get_temp(int *temp)
|
||||
{
|
||||
u8 read_temp;
|
||||
|
||||
if (ec_read(bios_cfg->tempreg, &read_temp))
|
||||
if (ec_read(ctrl_cfg.tempreg, &read_temp))
|
||||
return -EINVAL;
|
||||
|
||||
*temp = read_temp * 1000;
|
||||
@@ -282,10 +294,10 @@ static int acerhdf_get_fanstate(int *state)
|
||||
{
|
||||
u8 fan;
|
||||
|
||||
if (ec_read(bios_cfg->fanreg, &fan))
|
||||
if (ec_read(ctrl_cfg.fanreg, &fan))
|
||||
return -EINVAL;
|
||||
|
||||
if (fan != bios_cfg->cmd.cmd_off)
|
||||
if (fan != ctrl_cfg.cmd.cmd_off)
|
||||
*state = ACERHDF_FAN_AUTO;
|
||||
else
|
||||
*state = ACERHDF_FAN_OFF;
|
||||
@@ -306,13 +318,13 @@ static void acerhdf_change_fanstate(int state)
|
||||
state = ACERHDF_FAN_AUTO;
|
||||
}
|
||||
|
||||
cmd = (state == ACERHDF_FAN_OFF) ? bios_cfg->cmd.cmd_off
|
||||
: bios_cfg->cmd.cmd_auto;
|
||||
cmd = (state == ACERHDF_FAN_OFF) ? ctrl_cfg.cmd.cmd_off
|
||||
: ctrl_cfg.cmd.cmd_auto;
|
||||
fanstate = state;
|
||||
|
||||
ec_write(bios_cfg->fanreg, cmd);
|
||||
ec_write(ctrl_cfg.fanreg, cmd);
|
||||
|
||||
if (bios_cfg->mcmd_enable && state == ACERHDF_FAN_OFF) {
|
||||
if (ctrl_cfg.mcmd_enable && state == ACERHDF_FAN_OFF) {
|
||||
if (verbose)
|
||||
pr_notice("turning off fan manually\n");
|
||||
ec_write(mcmd.mreg, mcmd.moff);
|
||||
@@ -615,10 +627,11 @@ static int str_starts_with(const char *str, const char *start)
|
||||
}
|
||||
|
||||
/* check hardware */
|
||||
static int acerhdf_check_hardware(void)
|
||||
static int __init acerhdf_check_hardware(void)
|
||||
{
|
||||
char const *vendor, *version, *product;
|
||||
const struct bios_settings *bt = NULL;
|
||||
int found = 0;
|
||||
|
||||
/* get BIOS data */
|
||||
vendor = dmi_get_system_info(DMI_SYS_VENDOR);
|
||||
@@ -632,6 +645,17 @@ static int acerhdf_check_hardware(void)
|
||||
|
||||
pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER);
|
||||
|
||||
if (list_supported) {
|
||||
pr_info("List of supported Manufacturer/Model/BIOS:\n");
|
||||
pr_info("---------------------------------------------------\n");
|
||||
for (bt = bios_tbl; bt->vendor[0]; bt++) {
|
||||
pr_info("%-13s | %-17s | %-10s\n", bt->vendor,
|
||||
bt->product, bt->version);
|
||||
}
|
||||
pr_info("---------------------------------------------------\n");
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
if (force_bios[0]) {
|
||||
version = force_bios;
|
||||
pr_info("forcing BIOS version: %s\n", version);
|
||||
@@ -657,30 +681,36 @@ static int acerhdf_check_hardware(void)
|
||||
if (str_starts_with(vendor, bt->vendor) &&
|
||||
str_starts_with(product, bt->product) &&
|
||||
str_starts_with(version, bt->version)) {
|
||||
bios_cfg = bt;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bios_cfg) {
|
||||
if (!found) {
|
||||
pr_err("unknown (unsupported) BIOS version %s/%s/%s, please report, aborting!\n",
|
||||
vendor, product, version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Copy control settings from BIOS table before we free it. */
|
||||
ctrl_cfg.fanreg = bt->fanreg;
|
||||
ctrl_cfg.tempreg = bt->tempreg;
|
||||
memcpy(&ctrl_cfg.cmd, &bt->cmd, sizeof(struct fancmd));
|
||||
ctrl_cfg.mcmd_enable = bt->mcmd_enable;
|
||||
|
||||
/*
|
||||
* if started with kernel mode off, prevent the kernel from switching
|
||||
* off the fan
|
||||
*/
|
||||
if (!kernelmode) {
|
||||
pr_notice("Fan control off, to enable do:\n");
|
||||
pr_notice("echo -n \"enabled\" > /sys/class/thermal/thermal_zone0/mode\n");
|
||||
pr_notice("echo -n \"enabled\" > /sys/class/thermal/thermal_zoneN/mode # N=0,1,2...\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acerhdf_register_platform(void)
|
||||
static int __init acerhdf_register_platform(void)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
@@ -712,7 +742,7 @@ static void acerhdf_unregister_platform(void)
|
||||
platform_driver_unregister(&acerhdf_driver);
|
||||
}
|
||||
|
||||
static int acerhdf_register_thermal(void)
|
||||
static int __init acerhdf_register_thermal(void)
|
||||
{
|
||||
cl_dev = thermal_cooling_device_register("acerhdf-fan", NULL,
|
||||
&acerhdf_cooling_ops);
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/platform_data/x86/asus-wmi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/acpi.h>
|
||||
@@ -69,89 +70,6 @@ MODULE_LICENSE("GPL");
|
||||
#define NOTIFY_KBD_BRTDWN 0xc5
|
||||
#define NOTIFY_KBD_BRTTOGGLE 0xc7
|
||||
|
||||
/* WMI Methods */
|
||||
#define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */
|
||||
#define ASUS_WMI_METHODID_SFBD 0x44424653 /* Set First Boot Device */
|
||||
#define ASUS_WMI_METHODID_GLCD 0x44434C47 /* Get LCD status */
|
||||
#define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */
|
||||
#define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */
|
||||
#define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */
|
||||
#define ASUS_WMI_METHODID_AGFN 0x4E464741 /* FaN? */
|
||||
#define ASUS_WMI_METHODID_SFUN 0x4E554653 /* FUNCtionalities */
|
||||
#define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */
|
||||
#define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */
|
||||
#define ASUS_WMI_METHODID_DEVP 0x50564544 /* DEVice Policy */
|
||||
#define ASUS_WMI_METHODID_OSVR 0x5256534F /* OS VeRsion */
|
||||
#define ASUS_WMI_METHODID_DSTS 0x53544344 /* Device STatuS */
|
||||
#define ASUS_WMI_METHODID_DSTS2 0x53545344 /* Device STatuS #2*/
|
||||
#define ASUS_WMI_METHODID_BSTS 0x53545342 /* Bios STatuS ? */
|
||||
#define ASUS_WMI_METHODID_DEVS 0x53564544 /* DEVice Set */
|
||||
#define ASUS_WMI_METHODID_CFVS 0x53564643 /* CPU Frequency Volt Set */
|
||||
#define ASUS_WMI_METHODID_KBFT 0x5446424B /* KeyBoard FilTer */
|
||||
#define ASUS_WMI_METHODID_INIT 0x54494E49 /* INITialize */
|
||||
#define ASUS_WMI_METHODID_HKEY 0x59454B48 /* Hot KEY ?? */
|
||||
|
||||
#define ASUS_WMI_UNSUPPORTED_METHOD 0xFFFFFFFE
|
||||
|
||||
/* Wireless */
|
||||
#define ASUS_WMI_DEVID_HW_SWITCH 0x00010001
|
||||
#define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002
|
||||
#define ASUS_WMI_DEVID_CWAP 0x00010003
|
||||
#define ASUS_WMI_DEVID_WLAN 0x00010011
|
||||
#define ASUS_WMI_DEVID_WLAN_LED 0x00010012
|
||||
#define ASUS_WMI_DEVID_BLUETOOTH 0x00010013
|
||||
#define ASUS_WMI_DEVID_GPS 0x00010015
|
||||
#define ASUS_WMI_DEVID_WIMAX 0x00010017
|
||||
#define ASUS_WMI_DEVID_WWAN3G 0x00010019
|
||||
#define ASUS_WMI_DEVID_UWB 0x00010021
|
||||
|
||||
/* Leds */
|
||||
/* 0x000200XX and 0x000400XX */
|
||||
#define ASUS_WMI_DEVID_LED1 0x00020011
|
||||
#define ASUS_WMI_DEVID_LED2 0x00020012
|
||||
#define ASUS_WMI_DEVID_LED3 0x00020013
|
||||
#define ASUS_WMI_DEVID_LED4 0x00020014
|
||||
#define ASUS_WMI_DEVID_LED5 0x00020015
|
||||
#define ASUS_WMI_DEVID_LED6 0x00020016
|
||||
|
||||
/* Backlight and Brightness */
|
||||
#define ASUS_WMI_DEVID_ALS_ENABLE 0x00050001 /* Ambient Light Sensor */
|
||||
#define ASUS_WMI_DEVID_BACKLIGHT 0x00050011
|
||||
#define ASUS_WMI_DEVID_BRIGHTNESS 0x00050012
|
||||
#define ASUS_WMI_DEVID_KBD_BACKLIGHT 0x00050021
|
||||
#define ASUS_WMI_DEVID_LIGHT_SENSOR 0x00050022 /* ?? */
|
||||
#define ASUS_WMI_DEVID_LIGHTBAR 0x00050025
|
||||
|
||||
/* Misc */
|
||||
#define ASUS_WMI_DEVID_CAMERA 0x00060013
|
||||
|
||||
/* Storage */
|
||||
#define ASUS_WMI_DEVID_CARDREADER 0x00080013
|
||||
|
||||
/* Input */
|
||||
#define ASUS_WMI_DEVID_TOUCHPAD 0x00100011
|
||||
#define ASUS_WMI_DEVID_TOUCHPAD_LED 0x00100012
|
||||
|
||||
/* Fan, Thermal */
|
||||
#define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011
|
||||
#define ASUS_WMI_DEVID_FAN_CTRL 0x00110012
|
||||
|
||||
/* Power */
|
||||
#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012
|
||||
|
||||
/* Deep S3 / Resume on LID open */
|
||||
#define ASUS_WMI_DEVID_LID_RESUME 0x00120031
|
||||
|
||||
/* DSTS masks */
|
||||
#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
|
||||
#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
|
||||
#define ASUS_WMI_DSTS_PRESENCE_BIT 0x00010000
|
||||
#define ASUS_WMI_DSTS_USER_BIT 0x00020000
|
||||
#define ASUS_WMI_DSTS_BIOS_BIT 0x00040000
|
||||
#define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
|
||||
#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
|
||||
#define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F
|
||||
|
||||
#define ASUS_FAN_DESC "cpu_fan"
|
||||
#define ASUS_FAN_MFUN 0x13
|
||||
#define ASUS_FAN_SFUN_READ 0x06
|
||||
@@ -239,7 +157,6 @@ struct asus_wmi {
|
||||
int lightbar_led_wk;
|
||||
struct workqueue_struct *led_workqueue;
|
||||
struct work_struct tpd_led_work;
|
||||
struct work_struct kbd_led_work;
|
||||
struct work_struct wlan_led_work;
|
||||
struct work_struct lightbar_led_work;
|
||||
|
||||
@@ -302,8 +219,7 @@ static void asus_wmi_input_exit(struct asus_wmi *asus)
|
||||
asus->inputdev = NULL;
|
||||
}
|
||||
|
||||
static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
|
||||
u32 *retval)
|
||||
int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval)
|
||||
{
|
||||
struct bios_args args = {
|
||||
.arg0 = arg0,
|
||||
@@ -339,6 +255,7 @@ exit:
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(asus_wmi_evaluate_method);
|
||||
|
||||
static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args)
|
||||
{
|
||||
@@ -456,12 +373,9 @@ static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
|
||||
return read_tpd_led_state(asus);
|
||||
}
|
||||
|
||||
static void kbd_led_update(struct work_struct *work)
|
||||
static void kbd_led_update(struct asus_wmi *asus)
|
||||
{
|
||||
int ctrl_param = 0;
|
||||
struct asus_wmi *asus;
|
||||
|
||||
asus = container_of(work, struct asus_wmi, kbd_led_work);
|
||||
|
||||
/*
|
||||
* bits 0-2: level
|
||||
@@ -471,7 +385,6 @@ static void kbd_led_update(struct work_struct *work)
|
||||
ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
|
||||
|
||||
asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
|
||||
led_classdev_notify_brightness_hw_changed(&asus->kbd_led, asus->kbd_led_wk);
|
||||
}
|
||||
|
||||
static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
|
||||
@@ -516,7 +429,7 @@ static void do_kbd_led_set(struct led_classdev *led_cdev, int value)
|
||||
value = 0;
|
||||
|
||||
asus->kbd_led_wk = value;
|
||||
queue_work(asus->led_workqueue, &asus->kbd_led_work);
|
||||
kbd_led_update(asus);
|
||||
}
|
||||
|
||||
static void kbd_led_set(struct led_classdev *led_cdev,
|
||||
@@ -525,6 +438,14 @@ static void kbd_led_set(struct led_classdev *led_cdev,
|
||||
do_kbd_led_set(led_cdev, value);
|
||||
}
|
||||
|
||||
static void kbd_led_set_by_kbd(struct asus_wmi *asus, enum led_brightness value)
|
||||
{
|
||||
struct led_classdev *led_cdev = &asus->kbd_led;
|
||||
|
||||
do_kbd_led_set(led_cdev, value);
|
||||
led_classdev_notify_brightness_hw_changed(led_cdev, asus->kbd_led_wk);
|
||||
}
|
||||
|
||||
static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
|
||||
{
|
||||
struct asus_wmi *asus;
|
||||
@@ -671,8 +592,6 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
|
||||
|
||||
led_val = kbd_led_read(asus, NULL, NULL);
|
||||
if (led_val >= 0) {
|
||||
INIT_WORK(&asus->kbd_led_work, kbd_led_update);
|
||||
|
||||
asus->kbd_led_wk = led_val;
|
||||
asus->kbd_led.name = "asus::kbd_backlight";
|
||||
asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
|
||||
@@ -1746,18 +1665,18 @@ static void asus_wmi_notify(u32 value, void *context)
|
||||
}
|
||||
|
||||
if (code == NOTIFY_KBD_BRTUP) {
|
||||
do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk + 1);
|
||||
kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
|
||||
goto exit;
|
||||
}
|
||||
if (code == NOTIFY_KBD_BRTDWN) {
|
||||
do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk - 1);
|
||||
kbd_led_set_by_kbd(asus, asus->kbd_led_wk - 1);
|
||||
goto exit;
|
||||
}
|
||||
if (code == NOTIFY_KBD_BRTTOGGLE) {
|
||||
if (asus->kbd_led_wk == asus->kbd_led.max_brightness)
|
||||
do_kbd_led_set(&asus->kbd_led, 0);
|
||||
kbd_led_set_by_kbd(asus, 0);
|
||||
else
|
||||
do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk + 1);
|
||||
kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@@ -2291,7 +2210,7 @@ static int asus_hotk_resume(struct device *device)
|
||||
struct asus_wmi *asus = dev_get_drvdata(device);
|
||||
|
||||
if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
|
||||
queue_work(asus->led_workqueue, &asus->kbd_led_work);
|
||||
kbd_led_update(asus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2327,7 +2246,7 @@ static int asus_hotk_restore(struct device *device)
|
||||
rfkill_set_sw_state(asus->uwb.rfkill, bl);
|
||||
}
|
||||
if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
|
||||
queue_work(asus->led_workqueue, &asus->kbd_led_work);
|
||||
kbd_led_update(asus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -21,11 +21,13 @@
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mc146818rtc.h>
|
||||
#include <linux/module.h>
|
||||
@@ -36,12 +38,11 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "dcdbas.h"
|
||||
|
||||
#define DRIVER_NAME "dcdbas"
|
||||
#define DRIVER_VERSION "5.6.0-3.2"
|
||||
#define DRIVER_VERSION "5.6.0-3.3"
|
||||
#define DRIVER_DESCRIPTION "Dell Systems Management Base Driver"
|
||||
|
||||
static struct platform_device *dcdbas_pdev;
|
||||
@@ -49,19 +50,23 @@ static struct platform_device *dcdbas_pdev;
|
||||
static u8 *smi_data_buf;
|
||||
static dma_addr_t smi_data_buf_handle;
|
||||
static unsigned long smi_data_buf_size;
|
||||
static unsigned long max_smi_data_buf_size = MAX_SMI_DATA_BUF_SIZE;
|
||||
static u32 smi_data_buf_phys_addr;
|
||||
static DEFINE_MUTEX(smi_data_lock);
|
||||
static u8 *eps_buffer;
|
||||
|
||||
static unsigned int host_control_action;
|
||||
static unsigned int host_control_smi_type;
|
||||
static unsigned int host_control_on_shutdown;
|
||||
|
||||
static bool wsmt_enabled;
|
||||
|
||||
/**
|
||||
* smi_data_buf_free: free SMI data buffer
|
||||
*/
|
||||
static void smi_data_buf_free(void)
|
||||
{
|
||||
if (!smi_data_buf)
|
||||
if (!smi_data_buf || wsmt_enabled)
|
||||
return;
|
||||
|
||||
dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n",
|
||||
@@ -86,7 +91,7 @@ static int smi_data_buf_realloc(unsigned long size)
|
||||
if (smi_data_buf_size >= size)
|
||||
return 0;
|
||||
|
||||
if (size > MAX_SMI_DATA_BUF_SIZE)
|
||||
if (size > max_smi_data_buf_size)
|
||||
return -EINVAL;
|
||||
|
||||
/* new buffer is needed */
|
||||
@@ -169,7 +174,7 @@ static ssize_t smi_data_write(struct file *filp, struct kobject *kobj,
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
if ((pos + count) > MAX_SMI_DATA_BUF_SIZE)
|
||||
if ((pos + count) > max_smi_data_buf_size)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&smi_data_lock);
|
||||
@@ -322,8 +327,20 @@ static ssize_t smi_request_store(struct device *dev,
|
||||
ret = count;
|
||||
break;
|
||||
case 1:
|
||||
/* Calling Interface SMI */
|
||||
smi_cmd->ebx = (u32) virt_to_phys(smi_cmd->command_buffer);
|
||||
/*
|
||||
* Calling Interface SMI
|
||||
*
|
||||
* Provide physical address of command buffer field within
|
||||
* the struct smi_cmd to BIOS.
|
||||
*
|
||||
* Because the address that smi_cmd (smi_data_buf) points to
|
||||
* will be from memremap() of a non-memory address if WSMT
|
||||
* is present, we can't use virt_to_phys() on smi_cmd, so
|
||||
* we have to use the physical address that was saved when
|
||||
* the virtual address for smi_cmd was received.
|
||||
*/
|
||||
smi_cmd->ebx = smi_data_buf_phys_addr +
|
||||
offsetof(struct smi_cmd, command_buffer);
|
||||
ret = dcdbas_smi_request(smi_cmd);
|
||||
if (!ret)
|
||||
ret = count;
|
||||
@@ -482,6 +499,93 @@ static void dcdbas_host_control(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* WSMT */
|
||||
|
||||
static u8 checksum(u8 *buffer, u8 length)
|
||||
{
|
||||
u8 sum = 0;
|
||||
u8 *end = buffer + length;
|
||||
|
||||
while (buffer < end)
|
||||
sum += *buffer++;
|
||||
return sum;
|
||||
}
|
||||
|
||||
static inline struct smm_eps_table *check_eps_table(u8 *addr)
|
||||
{
|
||||
struct smm_eps_table *eps = (struct smm_eps_table *)addr;
|
||||
|
||||
if (strncmp(eps->smm_comm_buff_anchor, SMM_EPS_SIG, 4) != 0)
|
||||
return NULL;
|
||||
|
||||
if (checksum(addr, eps->length) != 0)
|
||||
return NULL;
|
||||
|
||||
return eps;
|
||||
}
|
||||
|
||||
static int dcdbas_check_wsmt(void)
|
||||
{
|
||||
struct acpi_table_wsmt *wsmt = NULL;
|
||||
struct smm_eps_table *eps = NULL;
|
||||
u64 remap_size;
|
||||
u8 *addr;
|
||||
|
||||
acpi_get_table(ACPI_SIG_WSMT, 0, (struct acpi_table_header **)&wsmt);
|
||||
if (!wsmt)
|
||||
return 0;
|
||||
|
||||
/* Check if WSMT ACPI table shows that protection is enabled */
|
||||
if (!(wsmt->protection_flags & ACPI_WSMT_FIXED_COMM_BUFFERS) ||
|
||||
!(wsmt->protection_flags & ACPI_WSMT_COMM_BUFFER_NESTED_PTR_PROTECTION))
|
||||
return 0;
|
||||
|
||||
/* Scan for EPS (entry point structure) */
|
||||
for (addr = (u8 *)__va(0xf0000);
|
||||
addr < (u8 *)__va(0x100000 - sizeof(struct smm_eps_table));
|
||||
addr += 16) {
|
||||
eps = check_eps_table(addr);
|
||||
if (eps)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!eps) {
|
||||
dev_dbg(&dcdbas_pdev->dev, "found WSMT, but no EPS found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get physical address of buffer and map to virtual address.
|
||||
* Table gives size in 4K pages, regardless of actual system page size.
|
||||
*/
|
||||
if (upper_32_bits(eps->smm_comm_buff_addr + 8)) {
|
||||
dev_warn(&dcdbas_pdev->dev, "found WSMT, but EPS buffer address is above 4GB\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/*
|
||||
* Limit remap size to MAX_SMI_DATA_BUF_SIZE + 8 (since the first 8
|
||||
* bytes are used for a semaphore, not the data buffer itself).
|
||||
*/
|
||||
remap_size = eps->num_of_4k_pages * PAGE_SIZE;
|
||||
if (remap_size > MAX_SMI_DATA_BUF_SIZE + 8)
|
||||
remap_size = MAX_SMI_DATA_BUF_SIZE + 8;
|
||||
eps_buffer = memremap(eps->smm_comm_buff_addr, remap_size, MEMREMAP_WB);
|
||||
if (!eps_buffer) {
|
||||
dev_warn(&dcdbas_pdev->dev, "found WSMT, but failed to map EPS buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* First 8 bytes is for a semaphore, not part of the smi_data_buf */
|
||||
smi_data_buf_phys_addr = eps->smm_comm_buff_addr + 8;
|
||||
smi_data_buf = eps_buffer + 8;
|
||||
smi_data_buf_size = remap_size - 8;
|
||||
max_smi_data_buf_size = smi_data_buf_size;
|
||||
wsmt_enabled = true;
|
||||
dev_info(&dcdbas_pdev->dev,
|
||||
"WSMT found, using firmware-provided SMI buffer.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* dcdbas_reboot_notify: handle reboot notification for host control
|
||||
*/
|
||||
@@ -548,6 +652,11 @@ static int dcdbas_probe(struct platform_device *dev)
|
||||
|
||||
dcdbas_pdev = dev;
|
||||
|
||||
/* Check if ACPI WSMT table specifies protected SMI buffer address */
|
||||
error = dcdbas_check_wsmt();
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* BIOS SMI calls require buffer addresses be in 32-bit address space.
|
||||
* This is done by setting the DMA mask below.
|
||||
@@ -635,6 +744,8 @@ static void __exit dcdbas_exit(void)
|
||||
*/
|
||||
if (dcdbas_pdev)
|
||||
smi_data_buf_free();
|
||||
if (eps_buffer)
|
||||
memunmap(eps_buffer);
|
||||
platform_device_unregister(dcdbas_pdev_reg);
|
||||
platform_driver_unregister(&dcdbas_driver);
|
||||
}
|
||||
@@ -53,6 +53,7 @@
|
||||
#define EXPIRED_TIMER (0)
|
||||
|
||||
#define SMI_CMD_MAGIC (0x534D4931)
|
||||
#define SMM_EPS_SIG "$SCB"
|
||||
|
||||
#define DCDBAS_DEV_ATTR_RW(_name) \
|
||||
DEVICE_ATTR(_name,0600,_name##_show,_name##_store);
|
||||
@@ -103,5 +104,14 @@ struct apm_cmd {
|
||||
|
||||
int dcdbas_smi_request(struct smi_cmd *smi_cmd);
|
||||
|
||||
struct smm_eps_table {
|
||||
char smm_comm_buff_anchor[4];
|
||||
u8 length;
|
||||
u8 checksum;
|
||||
u8 version;
|
||||
u64 smm_comm_buff_addr;
|
||||
u64 num_of_4k_pages;
|
||||
} __packed;
|
||||
|
||||
#endif /* _DCDBAS_H_ */
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "../../firmware/dcdbas.h"
|
||||
#include "dcdbas.h"
|
||||
#include "dell-smbios.h"
|
||||
|
||||
static int da_command_address;
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/set_memory.h>
|
||||
|
||||
MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
|
||||
MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
|
||||
@@ -181,6 +182,11 @@ static int create_packet(void *data, size_t length)
|
||||
packet_data_temp_buf = NULL;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* set to uncachable or it may never get written back before reboot
|
||||
*/
|
||||
set_memory_uc((unsigned long)packet_data_temp_buf, 1 << ordernum);
|
||||
|
||||
spin_lock(&rbu_data.lock);
|
||||
|
||||
newpacket->data = packet_data_temp_buf;
|
||||
@@ -349,6 +355,8 @@ static void packet_empty_list(void)
|
||||
* to make sure there are no stale RBU packets left in memory
|
||||
*/
|
||||
memset(newpacket->data, 0, rbu_data.packetsize);
|
||||
set_memory_wb((unsigned long)newpacket->data,
|
||||
1 << newpacket->ordernum);
|
||||
free_pages((unsigned long) newpacket->data,
|
||||
newpacket->ordernum);
|
||||
kfree(newpacket);
|
||||
@@ -212,7 +212,7 @@ static int read_ec_data(acpi_handle handle, int cmd, unsigned long *data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pr_err("timeout in read_ec_cmd\n");
|
||||
pr_err("timeout in %s\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1146,6 +1146,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y520-15IKBM"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Lenovo Legion Y530-15ICH",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion Y530-15ICH"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Lenovo Legion Y720-15IKB",
|
||||
.matches = {
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Intel HID event & 5 button array driver
|
||||
*
|
||||
* Copyright (C) 2015 Alex Hung <alex.hung@canonical.com>
|
||||
* Copyright (C) 2015 Andrew Lutomirski <luto@kernel.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
|
||||
@@ -1,26 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -53,12 +38,10 @@ static ssize_t irst_store_wakeup_events(struct device *dev,
|
||||
acpi = to_acpi_device(dev);
|
||||
|
||||
error = kstrtoul(buf, 0, &value);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
status = acpi_execute_simple_method(acpi->handle, "SFFS", value);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -99,12 +82,10 @@ static ssize_t irst_store_wakeup_time(struct device *dev,
|
||||
acpi = to_acpi_device(dev);
|
||||
|
||||
error = kstrtoul(buf, 0, &value);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
status = acpi_execute_simple_method(acpi->handle, "SFTV", value);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -1,25 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -44,6 +29,7 @@ static const struct acpi_device_id smartconnect_ids[] = {
|
||||
{"INT33A0", 0},
|
||||
{"", 0}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, smartconnect_ids);
|
||||
|
||||
static struct acpi_driver smartconnect_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
@@ -56,5 +42,3 @@ static struct acpi_driver smartconnect_driver = {
|
||||
};
|
||||
|
||||
module_acpi_driver(smartconnect_driver);
|
||||
|
||||
MODULE_DEVICE_TABLE(acpi, smartconnect_ids);
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* WMI Thunderbolt driver
|
||||
*
|
||||
* Copyright (C) 2017 Dell Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
@@ -38,12 +30,16 @@ static ssize_t force_power_store(struct device *dev,
|
||||
input.length = sizeof(u8);
|
||||
input.pointer = &mode;
|
||||
mode = hex_to_bin(buf[0]);
|
||||
dev_dbg(dev, "force_power: storing %#x\n", mode);
|
||||
if (mode == 0 || mode == 1) {
|
||||
status = wmi_evaluate_method(INTEL_WMI_THUNDERBOLT_GUID, 0, 1,
|
||||
&input, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_dbg(dev, "force_power: failed to evaluate ACPI method\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
} else {
|
||||
dev_dbg(dev, "force_power: unsupported mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return count;
|
||||
@@ -95,4 +91,4 @@ module_wmi_driver(intel_wmi_thunderbolt_driver);
|
||||
MODULE_ALIAS("wmi:" INTEL_WMI_THUNDERBOLT_GUID);
|
||||
MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
|
||||
MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user