提交 eb7046e9 编写于 作者: L Linus Torvalds

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
  ...
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.
.. 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.
......@@ -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 @@ static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
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 = {
......
// 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>
......
// 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;
......
// 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);
// 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");
// SPDX-License-Identifier: GPL-2.0
/*
* Dummy driver for Intel's Image Signal Processor found on Bay and Cherry
* Trail devices. The sole purpose of this driver is to allow the ISP to
* be put in D3.
*
* Copyright (C) 2018 Hans de Goede <hdegoede@redhat.com>
*
* Based on various non upstream patches for ISP support:
* Copyright (C) 2010-2017 Intel Corporation. All rights reserved.
* Copyright (c) 2010 Silicon Hive www.siliconhive.com.
*/
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <asm/iosf_mbi.h>
/* PCI configuration regs */
#define PCI_INTERRUPT_CTRL 0x9c
#define PCI_CSI_CONTROL 0xe8
#define PCI_CSI_CONTROL_PORTS_OFF_MASK 0x7
/* IOSF BT_MBI_UNIT_PMC regs */
#define ISPSSPM0 0x39
#define ISPSSPM0_ISPSSC_OFFSET 0
#define ISPSSPM0_ISPSSC_MASK 0x00000003
#define ISPSSPM0_ISPSSS_OFFSET 24
#define ISPSSPM0_ISPSSS_MASK 0x03000000
#define ISPSSPM0_IUNIT_POWER_ON 0x0
#define ISPSSPM0_IUNIT_POWER_OFF 0x3
static int isp_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
unsigned long timeout;
u32 val;
pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, 0);
/*
* MRFLD IUNIT DPHY is located in an always-power-on island
* MRFLD HW design need all CSI ports are disabled before
* powering down the IUNIT.
*/
pci_read_config_dword(dev, PCI_CSI_CONTROL, &val);
val |= PCI_CSI_CONTROL_PORTS_OFF_MASK;
pci_write_config_dword(dev, PCI_CSI_CONTROL, val);
/* Write 0x3 to ISPSSPM0 bit[1:0] to power off the IUNIT */
iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM0,
ISPSSPM0_IUNIT_POWER_OFF, ISPSSPM0_ISPSSC_MASK);
/*
* There should be no IUNIT access while power-down is
* in progress HW sighting: 4567865
* Wait up to 50 ms for the IUNIT to shut down.
*/
timeout = jiffies + msecs_to_jiffies(50);
while (1) {
/* Wait until ISPSSPM0 bit[25:24] shows 0x3 */
iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM0, &val);
val = (val & ISPSSPM0_ISPSSS_MASK) >> ISPSSPM0_ISPSSS_OFFSET;
if (val == ISPSSPM0_IUNIT_POWER_OFF)
break;
if (time_after(jiffies, timeout)) {
dev_err(&dev->dev, "IUNIT power-off timeout.\n");
return -EBUSY;
}
usleep_range(1000, 2000);
}
pm_runtime_allow(&dev->dev);
pm_runtime_put_sync_suspend(&dev->dev);
return 0;
}
static void isp_remove(struct pci_dev *dev)
{
pm_runtime_get_sync(&dev->dev);
pm_runtime_forbid(&dev->dev);
}
static int isp_pci_suspend(struct device *dev)
{
return 0;
}
static int isp_pci_resume(struct device *dev)
{
return 0;
}
static UNIVERSAL_DEV_PM_OPS(isp_pm_ops, isp_pci_suspend,
isp_pci_resume, NULL);
static const struct pci_device_id isp_id_table[] = {
{ PCI_VDEVICE(INTEL, 0x22b8), },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, isp_id_table);
static struct pci_driver isp_pci_driver = {
.name = "intel_atomisp2_pm",
.id_table = isp_id_table,
.probe = isp_probe,
.remove = isp_remove,
.driver.pm = &isp_pm_ops,
};
module_pci_driver(isp_pci_driver);
MODULE_DESCRIPTION("Intel AtomISP2 dummy / power-management drv (for suspend)");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* intel_bxtwc_tmu.c - Intel BXT Whiskey Cove PMIC TMU driver
* Intel BXT Whiskey Cove PMIC TMU driver
*
* Copyright (C) 2016 Intel Corporation. All rights reserved.
*
* This driver adds TMU (Time Management Unit) support for Intel BXT platform.
* It enables the alarm wake-up functionality in the TMU unit of Whiskey Cove
* PMIC.
*
* 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.
*
*/
#include <linux/module.h>
......
// SPDX-License-Identifier: GPL-2.0
/*
* Intel Cherry Trail ACPI INT33FE pseudo device driver
*
* Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
*
* 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.
*
* Some Intel Cherry Trail based device which ship with Windows 10, have
* this weird INT33FE ACPI device with a CRS table with 4 I2cSerialBusV2
* resources, for 4 different chips attached to various i2c busses:
......@@ -257,4 +254,4 @@ module_platform_driver(cht_int33fe_driver);
MODULE_DESCRIPTION("Intel Cherry Trail ACPI INT33FE pseudo device driver");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* Power-button driver for Dollar Cove TI PMIC
* Copyright (C) 2014 Intel Corp
......
// SPDX-License-Identifier: GPL-2.0
/*
* Intel INT0002 "Virtual GPIO" driver
*
......@@ -9,10 +10,6 @@
*
* Author: Dyut Kumar Sil <dyut.k.sil@intel.com>
*
* 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.
*
* Some peripherals on Bay Trail and Cherry Trail platforms signal a Power
* Management Event (PME) to the Power Management Controller (PMC) to wakeup
* the system. When this happens software needs to clear the PME bus 0 status
......@@ -57,11 +54,7 @@
#define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, }
static const struct x86_cpu_id int0002_cpu_ids[] = {
/*
* Limit ourselves to Cherry Trail for now, until testing shows we
* need to handle the INT0002 device on Baytrail too.
* ICPU(INTEL_FAM6_ATOM_SILVERMONT), * Valleyview, Bay Trail *
*/
ICPU(INTEL_FAM6_ATOM_SILVERMONT), /* Valleyview, Bay Trail */
ICPU(INTEL_FAM6_ATOM_AIRMONT), /* Braswell, Cherry Trail */
{}
};
......@@ -110,6 +103,21 @@ static void int0002_irq_mask(struct irq_data *data)
outl(gpe_en_reg, GPE0A_EN_PORT);
}
static int int0002_irq_set_wake(struct irq_data *data, unsigned int on)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct platform_device *pdev = to_platform_device(chip->parent);
int irq = platform_get_irq(pdev, 0);
/* Propagate to parent irq */
if (on)
enable_irq_wake(irq);
else
disable_irq_wake(irq);
return 0;
}
static irqreturn_t int0002_irq(int irq, void *data)
{
struct gpio_chip *chip = data;
......@@ -132,6 +140,7 @@ static struct irq_chip int0002_irqchip = {
.irq_ack = int0002_irq_ack,
.irq_mask = int0002_irq_mask,
.irq_unmask = int0002_irq_unmask,
.irq_set_wake = int0002_irq_set_wake,
};
static int int0002_probe(struct platform_device *pdev)
......@@ -216,4 +225,4 @@ module_platform_driver(int0002_driver);
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("Intel INT0002 Virtual GPIO driver");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2009-2010 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
* Authors:
* Jesse Barnes <jbarnes@virtuousgeek.org>
*/
......@@ -1697,6 +1686,6 @@ static struct pci_driver ips_pci_driver = {
module_pci_driver(ips_pci_driver);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Jesse Barnes <jbarnes@virtuousgeek.org>");
MODULE_DESCRIPTION("Intelligent Power Sharing Driver");
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2010 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*/
void ips_link_to_i915_driver(void);
// SPDX-License-Identifier: GPL-2.0
/*
* intel_menlow.c - Intel menlow Driver for thermal management extension
* Intel menlow Driver for thermal management extension
*
* Copyright (C) 2008 Intel Corp
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 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; version 2 of the License.
*
* 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.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This driver creates the sys I/F for programming the sensors.
* It also implements the driver for intel menlow memory controller (hardware
......@@ -29,20 +14,19 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/acpi.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include <linux/acpi.h>
#include <linux/types.h>
MODULE_AUTHOR("Thomas Sujith");
MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION("Intel Menlow platform specific driver");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
/*
* Memory controller device control
......
// SPDX-License-Identifier: GPL-2.0
/*
* Power button driver for Intel MID platforms.
*
......@@ -5,18 +6,8 @@
*
* Author: Hong Liu <hong.liu@intel.com>
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*
* 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; version 2 of the License.
*
* 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/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/mfd/intel_msic.h>
......@@ -121,12 +112,9 @@ static const struct mid_pb_ddata mrfld_ddata = {
.setup = mrfld_setup,
};
#define ICPU(model, ddata) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (kernel_ulong_t)&ddata }
static const struct x86_cpu_id mid_pb_cpu_ids[] = {
ICPU(INTEL_FAM6_ATOM_SALTWELL_MID, mfld_ddata),
ICPU(INTEL_FAM6_ATOM_SILVERMONT_MID, mrfld_ddata),
INTEL_CPU_FAM6(ATOM_SALTWELL_MID, mfld_ddata),
INTEL_CPU_FAM6(ATOM_SILVERMONT_MID, mrfld_ddata),
{}
};
......
// SPDX-License-Identifier: GPL-2.0
/*
* intel_mid_thermal.c - Intel MID platform thermal driver
* Intel MID platform thermal driver
*
* Copyright (C) 2011 Intel Corporation
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 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; version 2 of the License.
*
* 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.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Author: Durgadoss R <durgadoss.r@intel.com>
*/
#define pr_fmt(fmt) "intel_mid_thermal: " fmt
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/mfd/intel_msic.h>
#include <linux/module.h>
#include <linux/param.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include <linux/mfd/intel_msic.h>
/* Number of thermal sensors */
#define MSIC_THERMAL_SENSORS 4
......@@ -567,4 +551,4 @@ module_platform_driver(mid_thermal_driver);
MODULE_AUTHOR("Durgadoss R <durgadoss.r@intel.com>");
MODULE_DESCRIPTION("Intel Medfield Platform Thermal Driver");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0+
/*
* intel_oaktrail.c - Intel OakTrail Platform support.
* Intel OakTrail Platform support
*
* Copyright (C) 2010-2011 Intel Corporation
* Author: Yin Kangkai (kangkai.yin@intel.com)
......@@ -8,21 +9,6 @@
* <cezary.jackiewicz (at) gmail.com>, based on MSI driver
* Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
*
* 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.
*
* This driver does below things:
* 1. registers itself in the Linux backlight control in
* /sys/class/backlight/intel_oaktrail/
......@@ -38,18 +24,18 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/fb.h>
#include <linux/mutex.h>
#include <linux/backlight.h>
#include <linux/dmi.h>
#include <linux/err.h>
#include <linux/fb.h>
#include <linux/i2c.h>
#include <linux/backlight.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/dmi.h>
#include <linux/rfkill.h>
#include <acpi/video.h>
#define DRIVER_NAME "intel_oaktrail"
......
// SPDX-License-Identifier: GPL-2.0
/*
* Intel Core SoC Power Management Controller Driver
*
......@@ -6,16 +7,6 @@
*
* Authors: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
* Vishwanath Somayaji <vishwanath.somayaji@intel.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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
......
// SPDX-License-Identifier: GPL-2.0
/*
* Intel Core SoC Power Management Controller Header File
*
......@@ -6,16 +7,6 @@
*
* Authors: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
* Vishwanath Somayaji <vishwanath.somayaji@intel.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
*/
#ifndef PMC_CORE_H
......
// SPDX-License-Identifier: GPL-2.0
/*
* intel_pmc_ipc.c: Driver for the Intel PMC IPC mechanism
* Driver for the Intel PMC IPC mechanism
*
* (C) Copyright 2014-2015 Intel Corporation
*
* This driver is based on Intel SCU IPC driver(intel_scu_opc.c) by
* This driver is based on Intel SCU IPC driver(intel_scu_ipc.c) by
* Sreedhara DS <sreedhara.ds@intel.com>
*
* 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; version 2
* of the License.
*
* PMC running in ARC processor communicates with other entity running in IA
* core through IPC mechanism which in turn messaging between IA core ad PMC.
*/
#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/pm.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/pm_qos.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/sched.h>
#include <linux/atomic.h>
#include <linux/notifier.h>
#include <linux/suspend.h>
#include <linux/acpi.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/spinlock.h>
#include <linux/suspend.h>
#include <asm/intel_pmc_ipc.h>
......@@ -1029,7 +1024,7 @@ static void __exit intel_pmc_ipc_exit(void)
MODULE_AUTHOR("Zha Qipeng <qipeng.zha@intel.com>");
MODULE_DESCRIPTION("Intel PMC IPC driver");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
/* Some modules are dependent on this, so init earlier */
fs_initcall(intel_pmc_ipc_init);
......
// SPDX-License-Identifier: GPL-2.0
/*
* Driver for the Intel P-Unit Mailbox IPC mechanism
*
* (C) Copyright 2015 Intel Corporation
*
* 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.
*
* The heart of the P-Unit is the Foxton microcontroller and its firmware,
* which provide mailbox interface for power management usage.
*/
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <asm/intel_punit_ipc.h>
/* IPC Mailbox registers */
......
// SPDX-License-Identifier: GPL-2.0
/*
* intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism
* Driver for the Intel SCU IPC mechanism
*
* (C) Copyright 2008-2010,2015 Intel Corporation
* Author: Sreedhara DS (sreedhara.ds@intel.com)
*
* 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; version 2
* of the License.
*
* SCU running in ARC processor communicates with other entity running in IA
* core through IPC mechanism which in turn messaging between IA core ad SCU.
* SCU has two IPC mechanism IPC-1 and IPC-2. IPC-1 is used between IA32 and
......@@ -16,14 +12,16 @@
* IPC-1 Driver provides an API for power control unit registers (e.g. MSIC)
* along with other APIs.
*/
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/pm.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/sfi.h>
#include <asm/intel-mid.h>
#include <asm/intel_scu_ipc.h>
......
// SPDX-License-Identifier: GPL-2.0
/*
* intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism
* Driver for the Intel SCU IPC mechanism
*
* (C) Copyright 2008-2010 Intel Corporation
* Author: Sreedhara DS (sreedhara.ds@intel.com)
*
* 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; version 2
* of the License.
*
* This driver provides ioctl interfaces to call intel scu ipc driver api
* This driver provides IOCTL interfaces to call Intel SCU IPC driver API.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <asm/intel_scu_ipc.h>
static int major;
/* ioctl commnds */
/* IOCTL commands */
#define INTE_SCU_IPC_REGISTER_READ 0
#define INTE_SCU_IPC_REGISTER_WRITE 1
#define INTE_SCU_IPC_REGISTER_UPDATE 2
......
// SPDX-License-Identifier: GPL-2.0
/*
* Intel SoC Core Telemetry Driver
* Copyright (C) 2015, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* Telemetry Framework provides platform related PM and performance statistics.
* This file provides the core telemetry API implementation.
*/
......@@ -460,4 +452,4 @@ module_exit(telemetry_module_exit);
MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* Intel SOC Telemetry debugfs Driver: Currently supports APL
* Copyright (c) 2015, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* This file provides the debugfs interfaces for telemetry.
* /sys/kernel/debug/telemetry/pss_info: Shows Primary Control Sub-Sys Counters
* /sys/kernel/debug/telemetry/ioss_info: Shows IO Sub-System Counters
......@@ -72,9 +64,6 @@
#define TELEM_IOSS_DX_D0IX_EVTS 25
#define TELEM_IOSS_PG_EVTS 30
#define TELEM_DEBUGFS_CPU(model, data) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&data}
#define TELEM_CHECK_AND_PARSE_EVTS(EVTID, EVTNUM, BUF, EVTLOG, EVTDAT, MASK) { \
if (evtlog[index].telem_evtid == (EVTID)) { \
for (idx = 0; idx < (EVTNUM); idx++) \
......@@ -319,8 +308,8 @@ static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
};
static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_debugfs_conf),
TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GOLDMONT_PLUS, telem_apl_debugfs_conf),
INTEL_CPU_FAM6(ATOM_GOLDMONT, telem_apl_debugfs_conf),
INTEL_CPU_FAM6(ATOM_GOLDMONT_PLUS, telem_apl_debugfs_conf),
{}
};
......@@ -951,12 +940,16 @@ static int __init telemetry_debugfs_init(void)
debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
err = telemetry_pltconfig_valid();
if (err < 0)
if (err < 0) {
pr_info("Invalid pltconfig, ensure IPC1 device is enabled in BIOS\n");
return -ENODEV;
}
err = telemetry_debugfs_check_evts();
if (err < 0)
if (err < 0) {
pr_info("telemetry_debugfs_check_evts failed\n");
return -EINVAL;
}
register_pm_notifier(&pm_notifier);
......@@ -1037,4 +1030,4 @@ module_exit(telemetry_debugfs_exit);
MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface");
MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* Intel SOC Telemetry Platform Driver: Currently supports APL
* Copyright (c) 2015, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* This file provides the platform specific telemetry implementation for APL.
* It used the PUNIT and PMC IPC interfaces for configuring the counters.
* The accumulated results are fetched from SRAM.
......@@ -1242,4 +1234,4 @@ module_exit(telemetry_module_exit);
MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver");
MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/*
* Intel Turbo Boost Max Technology 3.0 legacy (non HWP) enumeration driver
* Copyright (c) 2017, Intel Corporation.
* All rights reserved.
*
* Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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
#include <linux/kernel.h>
#include <linux/cpufeature.h>
#include <linux/cpuhotplug.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/topology.h>
#include <linux/workqueue.h>
#include <linux/cpuhotplug.h>
#include <linux/cpufeature.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
......
// SPDX-License-Identifier: GPL-2.0+
/*
* lg-laptop.c - LG Gram ACPI features and hotkeys Driver
*
* Copyright (C) 2018 Matan Ziv-Av <matan@svgalib.org>
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/acpi.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#define LED_DEVICE(_name, max) struct led_classdev _name = { \
.name = __stringify(_name), \
.max_brightness = max, \
.brightness_set = _name##_set, \
.brightness_get = _name##_get, \
}
MODULE_AUTHOR("Matan Ziv-Av");
MODULE_DESCRIPTION("LG WMI Hotkey Driver");
MODULE_LICENSE("GPL");
#define WMI_EVENT_GUID0 "E4FB94F9-7F2B-4173-AD1A-CD1D95086248"
#define WMI_EVENT_GUID1 "023B133E-49D1-4E10-B313-698220140DC2"
#define WMI_EVENT_GUID2 "37BE1AC0-C3F2-4B1F-BFBE-8FDEAF2814D6"
#define WMI_EVENT_GUID3 "911BAD44-7DF8-4FBB-9319-BABA1C4B293B"
#define WMI_METHOD_WMAB "C3A72B38-D3EF-42D3-8CBB-D5A57049F66D"
#define WMI_METHOD_WMBB "2B4F501A-BD3C-4394-8DCF-00A7D2BC8210"
#define WMI_EVENT_GUID WMI_EVENT_GUID0
#define WMAB_METHOD "\\XINI.WMAB"
#define WMBB_METHOD "\\XINI.WMBB"
#define SB_GGOV_METHOD "\\_SB.GGOV"
#define GOV_TLED 0x2020008
#define WM_GET 1
#define WM_SET 2
#define WM_KEY_LIGHT 0x400
#define WM_TLED 0x404
#define WM_FN_LOCK 0x407
#define WM_BATT_LIMIT 0x61
#define WM_READER_MODE 0xBF
#define WM_FAN_MODE 0x33
#define WMBB_USB_CHARGE 0x10B
#define WMBB_BATT_LIMIT 0x10C
#define PLATFORM_NAME "lg-laptop"
MODULE_ALIAS("wmi:" WMI_EVENT_GUID0);
MODULE_ALIAS("wmi:" WMI_EVENT_GUID1);
MODULE_ALIAS("wmi:" WMI_EVENT_GUID2);
MODULE_ALIAS("wmi:" WMI_EVENT_GUID3);
MODULE_ALIAS("wmi:" WMI_METHOD_WMAB);
MODULE_ALIAS("wmi:" WMI_METHOD_WMBB);
MODULE_ALIAS("acpi*:LGEX0815:*");
static struct platform_device *pf_device;
static struct input_dev *wmi_input_dev;
static u32 inited;
#define INIT_INPUT_WMI_0 0x01
#define INIT_INPUT_WMI_2 0x02
#define INIT_INPUT_ACPI 0x04
#define INIT_TPAD_LED 0x08
#define INIT_KBD_LED 0x10
#define INIT_SPARSE_KEYMAP 0x80
static const struct key_entry wmi_keymap[] = {
{KE_KEY, 0x70, {KEY_F15} }, /* LG control panel (F1) */
{KE_KEY, 0x74, {KEY_F13} }, /* Touchpad toggle (F5) */
{KE_KEY, 0xf020000, {KEY_F14} }, /* Read mode (F9) */
{KE_KEY, 0x10000000, {KEY_F16} },/* Keyboard backlight (F8) - pressing
* this key both sends an event and
* changes backlight level.
*/
{KE_KEY, 0x80, {KEY_RFKILL} },
{KE_END, 0}
};
static int ggov(u32 arg0)
{
union acpi_object args[1];
union acpi_object *r;
acpi_status status;
acpi_handle handle;
struct acpi_object_list arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
int res;
args[0].type = ACPI_TYPE_INTEGER;
args[0].integer.value = arg0;
status = acpi_get_handle(NULL, (acpi_string) SB_GGOV_METHOD, &handle);
if (ACPI_FAILURE(status)) {
pr_err("Cannot get handle");
return -ENODEV;
}
arg.count = 1;
arg.pointer = args;
status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
if (ACPI_FAILURE(status)) {
acpi_handle_err(handle, "GGOV: call failed.\n");
return -EINVAL;
}
r = buffer.pointer;
if (r->type != ACPI_TYPE_INTEGER) {
kfree(r);
return -EINVAL;
}
res = r->integer.value;
kfree(r);
return res;
}
static union acpi_object *lg_wmab(u32 method, u32 arg1, u32 arg2)
{
union acpi_object args[3];
acpi_status status;
acpi_handle handle;
struct acpi_object_list arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
args[0].type = ACPI_TYPE_INTEGER;
args[0].integer.value = method;
args[1].type = ACPI_TYPE_INTEGER;
args[1].integer.value = arg1;
args[2].type = ACPI_TYPE_INTEGER;
args[2].integer.value = arg2;
status = acpi_get_handle(NULL, (acpi_string) WMAB_METHOD, &handle);
if (ACPI_FAILURE(status)) {
pr_err("Cannot get handle");
return NULL;
}
arg.count = 3;
arg.pointer = args;
status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
if (ACPI_FAILURE(status)) {
acpi_handle_err(handle, "WMAB: call failed.\n");
return NULL;
}
return buffer.pointer;
}
static union acpi_object *lg_wmbb(u32 method_id, u32 arg1, u32 arg2)
{
union acpi_object args[3];
acpi_status status;
acpi_handle handle;
struct acpi_object_list arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
u8 buf[32];
*(u32 *)buf = method_id;
*(u32 *)(buf + 4) = arg1;
*(u32 *)(buf + 16) = arg2;
args[0].type = ACPI_TYPE_INTEGER;
args[0].integer.value = 0; /* ignored */
args[1].type = ACPI_TYPE_INTEGER;
args[1].integer.value = 1; /* Must be 1 or 2. Does not matter which */
args[2].type = ACPI_TYPE_BUFFER;
args[2].buffer.length = 32;
args[2].buffer.pointer = buf;
status = acpi_get_handle(NULL, (acpi_string)WMBB_METHOD, &handle);
if (ACPI_FAILURE(status)) {
pr_err("Cannot get handle");
return NULL;
}
arg.count = 3;
arg.pointer = args;
status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
if (ACPI_FAILURE(status)) {
acpi_handle_err(handle, "WMAB: call failed.\n");
return NULL;
}
return (union acpi_object *)buffer.pointer;
}
static void wmi_notify(u32 value, void *context)
{
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
acpi_status status;
long data = (long)context;
pr_debug("event guid %li\n", data);
status = wmi_get_event_data(value, &response);
if (ACPI_FAILURE(status)) {
pr_err("Bad event status 0x%x\n", status);
return;
}
obj = (union acpi_object *)response.pointer;
if (!obj)
return;
if (obj->type == ACPI_TYPE_INTEGER) {
int eventcode = obj->integer.value;
struct key_entry *key;
key =
sparse_keymap_entry_from_scancode(wmi_input_dev, eventcode);
if (key && key->type == KE_KEY)
sparse_keymap_report_entry(wmi_input_dev, key, 1, true);
}
pr_debug("Type: %i Eventcode: 0x%llx\n", obj->type,
obj->integer.value);
kfree(response.pointer);
}
static void wmi_input_setup(void)
{
acpi_status status;
wmi_input_dev = input_allocate_device();
if (wmi_input_dev) {
wmi_input_dev->name = "LG WMI hotkeys";
wmi_input_dev->phys = "wmi/input0";
wmi_input_dev->id.bustype = BUS_HOST;
if (sparse_keymap_setup(wmi_input_dev, wmi_keymap, NULL) ||
input_register_device(wmi_input_dev)) {
pr_info("Cannot initialize input device");
input_free_device(wmi_input_dev);
return;
}
inited |= INIT_SPARSE_KEYMAP;
status = wmi_install_notify_handler(WMI_EVENT_GUID0, wmi_notify,
(void *)0);
if (ACPI_SUCCESS(status))
inited |= INIT_INPUT_WMI_0;
status = wmi_install_notify_handler(WMI_EVENT_GUID2, wmi_notify,
(void *)2);
if (ACPI_SUCCESS(status))
inited |= INIT_INPUT_WMI_2;
} else {
pr_info("Cannot allocate input device");
}
}
static void acpi_notify(struct acpi_device *device, u32 event)
{
struct key_entry *key;
acpi_handle_debug(device->handle, "notify: %d\n", event);
if (inited & INIT_SPARSE_KEYMAP) {
key = sparse_keymap_entry_from_scancode(wmi_input_dev, 0x80);
if (key && key->type == KE_KEY)
sparse_keymap_report_entry(wmi_input_dev, key, 1, true);
}
}
static ssize_t fan_mode_store(struct device *dev,
struct device_attribute *attr,
const char *buffer, size_t count)
{
bool value;
union acpi_object *r;
u32 m;
int ret;
ret = kstrtobool(buffer, &value);
if (ret)
return ret;
r = lg_wmab(WM_FAN_MODE, WM_GET, 0);
if (!r)
return -EIO;
if (r->type != ACPI_TYPE_INTEGER) {
kfree(r);
return -EIO;
}
m = r->integer.value;
kfree(r);
r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xffffff0f) | (value << 4));
kfree(r);
r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xfffffff0) | value);
kfree(r);
return count;
}
static ssize_t fan_mode_show(struct device *dev,
struct device_attribute *attr, char *buffer)
{
unsigned int status;
union acpi_object *r;
r = lg_wmab(WM_FAN_MODE, WM_GET, 0);
if (!r)
return -EIO;
if (r->type != ACPI_TYPE_INTEGER) {
kfree(r);
return -EIO;
}
status = r->integer.value & 0x01;
kfree(r);
return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}
static ssize_t usb_charge_store(struct device *dev,
struct device_attribute *attr,
const char *buffer, size_t count)
{
bool value;
union acpi_object *r;
int ret;
ret = kstrtobool(buffer, &value);
if (ret)
return ret;
r = lg_wmbb(WMBB_USB_CHARGE, WM_SET, value);
if (!r)
return -EIO;
kfree(r);
return count;
}
static ssize_t usb_charge_show(struct device *dev,
struct device_attribute *attr, char *buffer)
{
unsigned int status;
union acpi_object *r;
r = lg_wmbb(WMBB_USB_CHARGE, WM_GET, 0);
if (!r)
return -EIO;
if (r->type != ACPI_TYPE_BUFFER) {
kfree(r);
return -EIO;
}
status = !!r->buffer.pointer[0x10];
kfree(r);
return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}
static ssize_t reader_mode_store(struct device *dev,
struct device_attribute *attr,
const char *buffer, size_t count)
{
bool value;
union acpi_object *r;
int ret;
ret = kstrtobool(buffer, &value);
if (ret)
return ret;
r = lg_wmab(WM_READER_MODE, WM_SET, value);
if (!r)
return -EIO;
kfree(r);
return count;
}
static ssize_t reader_mode_show(struct device *dev,
struct device_attribute *attr, char *buffer)
{
unsigned int status;
union acpi_object *r;
r = lg_wmab(WM_READER_MODE, WM_GET, 0);
if (!r)
return -EIO;
if (r->type != ACPI_TYPE_INTEGER) {
kfree(r);
return -EIO;
}
status = !!r->integer.value;
kfree(r);
return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}
static ssize_t fn_lock_store(struct device *dev,
struct device_attribute *attr,
const char *buffer, size_t count)
{
bool value;
union acpi_object *r;
int ret;
ret = kstrtobool(buffer, &value);
if (ret)
return ret;
r = lg_wmab(WM_FN_LOCK, WM_SET, value);
if (!r)
return -EIO;
kfree(r);
return count;
}
static ssize_t fn_lock_show(struct device *dev,
struct device_attribute *attr, char *buffer)
{
unsigned int status;
union acpi_object *r;
r = lg_wmab(WM_FN_LOCK, WM_GET, 0);
if (!r)
return -EIO;
if (r->type != ACPI_TYPE_BUFFER) {
kfree(r);
return -EIO;
}
status = !!r->buffer.pointer[0];
kfree(r);
return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}
static ssize_t battery_care_limit_store(struct device *dev,
struct device_attribute *attr,
const char *buffer, size_t count)
{
unsigned long value;
int ret;
ret = kstrtoul(buffer, 10, &value);
if (ret)
return ret;
if (value == 100 || value == 80) {
union acpi_object *r;
r = lg_wmab(WM_BATT_LIMIT, WM_SET, value);
if (!r)
return -EIO;
kfree(r);
return count;
}
return -EINVAL;
}
static ssize_t battery_care_limit_show(struct device *dev,
struct device_attribute *attr,
char *buffer)
{
unsigned int status;
union acpi_object *r;
r = lg_wmab(WM_BATT_LIMIT, WM_GET, 0);
if (!r)
return -EIO;
if (r->type != ACPI_TYPE_INTEGER) {
kfree(r);
return -EIO;
}
status = r->integer.value;
kfree(r);
if (status != 80 && status != 100)
status = 0;
return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}
static DEVICE_ATTR_RW(fan_mode);
static DEVICE_ATTR_RW(usb_charge);
static DEVICE_ATTR_RW(reader_mode);
static DEVICE_ATTR_RW(fn_lock);
static DEVICE_ATTR_RW(battery_care_limit);
static struct attribute *dev_attributes[] = {
&dev_attr_fan_mode.attr,
&dev_attr_usb_charge.attr,
&dev_attr_reader_mode.attr,
&dev_attr_fn_lock.attr,
&dev_attr_battery_care_limit.attr,
NULL
};
static const struct attribute_group dev_attribute_group = {
.attrs = dev_attributes,
};
static void tpad_led_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
union acpi_object *r;
r = lg_wmab(WM_TLED, WM_SET, brightness > LED_OFF);
kfree(r);
}
static enum led_brightness tpad_led_get(struct led_classdev *cdev)
{
return ggov(GOV_TLED) > 0 ? LED_ON : LED_OFF;
}
static LED_DEVICE(tpad_led, 1);
static void kbd_backlight_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
u32 val;
union acpi_object *r;
val = 0x22;
if (brightness <= LED_OFF)
val = 0;
if (brightness >= LED_FULL)
val = 0x24;
r = lg_wmab(WM_KEY_LIGHT, WM_SET, val);
kfree(r);
}
static enum led_brightness kbd_backlight_get(struct led_classdev *cdev)
{
union acpi_object *r;
int val;
r = lg_wmab(WM_KEY_LIGHT, WM_GET, 0);
if (!r)
return LED_OFF;
if (r->type != ACPI_TYPE_BUFFER || r->buffer.pointer[1] != 0x05) {
kfree(r);
return LED_OFF;
}
switch (r->buffer.pointer[0] & 0x27) {
case 0x24:
val = LED_FULL;
break;
case 0x22:
val = LED_HALF;
break;
default:
val = LED_OFF;
}
kfree(r);
return val;
}
static LED_DEVICE(kbd_backlight, 255);
static void wmi_input_destroy(void)
{
if (inited & INIT_INPUT_WMI_2)
wmi_remove_notify_handler(WMI_EVENT_GUID2);
if (inited & INIT_INPUT_WMI_0)
wmi_remove_notify_handler(WMI_EVENT_GUID0);
if (inited & INIT_SPARSE_KEYMAP)
input_unregister_device(wmi_input_dev);
inited &= ~(INIT_INPUT_WMI_0 | INIT_INPUT_WMI_2 | INIT_SPARSE_KEYMAP);
}
static struct platform_driver pf_driver = {
.driver = {
.name = PLATFORM_NAME,
}
};
static int acpi_add(struct acpi_device *device)
{
int ret;
if (pf_device)
return 0;
ret = platform_driver_register(&pf_driver);
if (ret)
return ret;
pf_device = platform_device_register_simple(PLATFORM_NAME,
PLATFORM_DEVID_NONE,
NULL, 0);
if (IS_ERR(pf_device)) {
ret = PTR_ERR(pf_device);
pf_device = NULL;
pr_err("unable to register platform device\n");
goto out_platform_registered;
}
ret = sysfs_create_group(&pf_device->dev.kobj, &dev_attribute_group);
if (ret)
goto out_platform_device;
if (!led_classdev_register(&pf_device->dev, &kbd_backlight))
inited |= INIT_KBD_LED;
if (!led_classdev_register(&pf_device->dev, &tpad_led))
inited |= INIT_TPAD_LED;
wmi_input_setup();
return 0;
out_platform_device:
platform_device_unregister(pf_device);
out_platform_registered:
platform_driver_unregister(&pf_driver);
return ret;
}
static int acpi_remove(struct acpi_device *device)
{
sysfs_remove_group(&pf_device->dev.kobj, &dev_attribute_group);
if (inited & INIT_KBD_LED)
led_classdev_unregister(&kbd_backlight);
if (inited & INIT_TPAD_LED)
led_classdev_unregister(&tpad_led);
wmi_input_destroy();
platform_device_unregister(pf_device);
pf_device = NULL;
platform_driver_unregister(&pf_driver);
return 0;
}
static const struct acpi_device_id device_ids[] = {
{"LGEX0815", 0},
{"", 0}
};
MODULE_DEVICE_TABLE(acpi, device_ids);
static struct acpi_driver acpi_driver = {
.name = "LG Gram Laptop Support",
.class = "lg-laptop",
.ids = device_ids,
.ops = {
.add = acpi_add,
.remove = acpi_remove,
.notify = acpi_notify,
},
.owner = THIS_MODULE,
};
static int __init acpi_init(void)
{
int result;
result = acpi_bus_register_driver(&acpi_driver);
if (result < 0) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error registering driver\n"));
return -ENODEV;
}
return 0;
}
static void __exit acpi_exit(void)
{
acpi_bus_unregister_driver(&acpi_driver);
}
module_init(acpi_init);
module_exit(acpi_exit);
......@@ -575,7 +575,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items[] = {
static
struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data = {
.items = mlxplat_mlxcpld_msn21xx_items,
.items = mlxplat_mlxcpld_msn201x_items,
.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items),
.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
......
......@@ -42,10 +42,13 @@ static const struct ts_dmi_data chuwi_hi8_data = {
};
static const struct property_entry chuwi_hi8_pro_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 6),
PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-hi8-pro.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"),
{ }
};
......@@ -56,6 +59,8 @@ static const struct ts_dmi_data chuwi_hi8_pro_data = {
};
static const struct property_entry chuwi_vi8_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
PROPERTY_ENTRY_U32("touchscreen-min-y", 6),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1724),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
......@@ -88,9 +93,9 @@ static const struct ts_dmi_data chuwi_vi10_data = {
static const struct property_entry connect_tablet9_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 9),
PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
PROPERTY_ENTRY_U32("touchscreen-min-y", 10),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1664),
PROPERTY_ENTRY_U32("touchscreen-size-y", 878),
PROPERTY_ENTRY_U32("touchscreen-size-y", 880),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-connect-tablet9.fw"),
......@@ -104,8 +109,10 @@ static const struct ts_dmi_data connect_tablet9_data = {
};
static const struct property_entry cube_iwork8_air_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
PROPERTY_ENTRY_U32("touchscreen-size-y", 900),
PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1664),
PROPERTY_ENTRY_U32("touchscreen-size-y", 896),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-cube-iwork8-air.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
......@@ -179,11 +186,14 @@ static const struct ts_dmi_data gp_electronic_t701_data = {
};
static const struct property_entry itworks_tw891_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
PROPERTY_ENTRY_U32("touchscreen-min-y", 5),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
PROPERTY_ENTRY_U32("touchscreen-size-y", 890),
PROPERTY_ENTRY_U32("touchscreen-size-y", 896),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-itworks-tw891.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ }
};
......@@ -207,8 +217,10 @@ static const struct ts_dmi_data jumper_ezpad_6_pro_data = {
};
static const struct property_entry jumper_ezpad_mini3_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 23),
PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1700),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1138),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
......@@ -237,6 +249,24 @@ static const struct ts_dmi_data onda_obook_20_plus_data = {
.properties = onda_obook_20_plus_props,
};
static const struct property_entry onda_v80_plus_v3_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 22),
PROPERTY_ENTRY_U32("touchscreen-min-y", 15),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1698),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name",
"gsl3676-onda-v80-plus-v3.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"),
{ }
};
static const struct ts_dmi_data onda_v80_plus_v3_data = {
.acpi_name = "MSSL1680:00",
.properties = onda_v80_plus_v3_props,
};
static const struct property_entry onda_v820w_32g_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
......@@ -322,11 +352,14 @@ static const struct ts_dmi_data pov_mobii_wintab_p800w_v20_data = {
};
static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1800),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1794),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name",
"gsl3692-pov-mobii-wintab-p800w.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"),
{ }
};
......@@ -366,6 +399,22 @@ static const struct ts_dmi_data teclast_x98plus2_data = {
.properties = teclast_x98plus2_props,
};
static const struct property_entry trekstor_primebook_c11_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1970),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1530),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name",
"gsl1680-trekstor-primebook-c11.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"),
{ }
};
static const struct ts_dmi_data trekstor_primebook_c11_data = {
.acpi_name = "MSSL1680:00",
.properties = trekstor_primebook_c11_props,
};
static const struct property_entry trekstor_primebook_c13_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
......@@ -381,6 +430,22 @@ static const struct ts_dmi_data trekstor_primebook_c13_data = {
.properties = trekstor_primebook_c13_props,
};
static const struct property_entry trekstor_primetab_t13b_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 2500),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1900),
PROPERTY_ENTRY_STRING("firmware-name",
"gsl1680-trekstor-primetab-t13b.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
{ }
};
static const struct ts_dmi_data trekstor_primetab_t13b_data = {
.acpi_name = "MSSL1680:00",
.properties = trekstor_primetab_t13b_props,
};
static const struct property_entry trekstor_surftab_twin_10_1_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
......@@ -397,6 +462,8 @@ static const struct ts_dmi_data trekstor_surftab_twin_10_1_data = {
};
static const struct property_entry trekstor_surftab_wintron70_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 12),
PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
PROPERTY_ENTRY_STRING("firmware-name",
......@@ -555,6 +622,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "OBOOK 20 PLUS"),
},
},
{
/* ONDA V80 plus v3 (P80PSBG9V3A01501) */
.driver_data = (void *)&onda_v80_plus_v3_data,
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONDA"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "V80 PLUS")
},
},
{
/* ONDA V820w DualOS */
.driver_data = (void *)&onda_v820w_32g_data,
......@@ -640,6 +715,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
},
},
{
/* Trekstor Primebook C11 */
.driver_data = (void *)&trekstor_primebook_c11_data,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C11"),
},
},
{
/* Trekstor Primebook C13 */
.driver_data = (void *)&trekstor_primebook_c13_data,
......@@ -648,6 +731,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
},
},
{
/* Trekstor Primetab T13B */
.driver_data = (void *)&trekstor_primetab_t13b_data,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
DMI_MATCH(DMI_PRODUCT_NAME, "Primetab T13B"),
},
},
{
/* TrekStor SurfTab twin 10.1 ST10432-8 */
.driver_data = (void *)&trekstor_surftab_twin_10_1_data,
......
......@@ -987,19 +987,19 @@ static struct bus_type wmi_bus_type = {
.remove = wmi_dev_remove,
};
static struct device_type wmi_type_event = {
static const struct device_type wmi_type_event = {
.name = "event",
.groups = wmi_event_groups,
.release = wmi_dev_release,
};
static struct device_type wmi_type_method = {
static const struct device_type wmi_type_method = {
.name = "method",
.groups = wmi_method_groups,
.release = wmi_dev_release,
};
static struct device_type wmi_type_data = {
static const struct device_type wmi_type_data = {
.name = "data",
.groups = wmi_data_groups,
.release = wmi_dev_release,
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PLATFORM_DATA_X86_ASUS_WMI_H
#define __PLATFORM_DATA_X86_ASUS_WMI_H
#include <linux/errno.h>
#include <linux/types.h>
/* 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
#if IS_REACHABLE(CONFIG_ASUS_WMI)
int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval);
#else
static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
u32 *retval)
{
return -ENODEV;
}
#endif
#endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */
......@@ -115,7 +115,7 @@ static int module_trace_bprintk_format_notify(struct notifier_block *self,
* section, then we need to read the link list pointers. The trick is
* we pass the address of the string to the seq function just like
* we do for the kernel core formats. To get back the structure that
* holds the format, we simply use containerof() and then go to the
* holds the format, we simply use container_of() and then go to the
* next format in the list.
*/
static const char **
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册