mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-06 05:06:29 +00:00
platform-drivers-x86 for v5.15-1
Highlights: - Move all the Intel drivers into their own subdir(s) (mostly Kate's work) - New meraki-mx100 platform driver - Asus WMI driver enhancements, including /sys/firmware/acpi/platform_profile support - New BIOS SAR driver for Intel M.2 WWAM modems - Alder Lake support for the Intel PMC driver - A whole bunch of cleanups + fixes all over the place The following is an automated git shortlog grouped by driver: BIOS SAR driver for Intel M.2 Modem: - BIOS SAR driver for Intel M.2 Modem ISST: - use semi-colons instead of commas - Fix optimization with use of numa Replace deprecated CPU-hotplug functions.: - Replace deprecated CPU-hotplug functions. Update Mario Limonciello's email address in the docs: - Update Mario Limonciello's email address in the docs acer-wmi: - Add Turbo Mode support for Acer PH315-53 add meraki-mx100 platform driver: - add meraki-mx100 platform driver asus-nb-wmi: - Add tablet_mode_sw=lid-flip quirk for the TP200s - Allow configuring SW_TABLET_MODE method with a module option asus-wmi: - Fix "unsigned 'retval' is never less than zero" smatch warning - Delete impossible condition - Add support for platform_profile - Add egpu enable method - Add dgpu disable method - Add panel overdrive functionality dell-smbios: - Remove unused dmi_system_id table dell-smbios-wmi: - Add missing kfree in error-exit from run_smbios_call - Avoid false-positive memcpy() warning dell-smo8800: - Convert to be a platform driver dual_accel_detect: - Use the new i2c_acpi_client_count() helper gigabyte-wmi: - add support for B450M S2H V2 - add support for X570 GAMING X hp_accel: - Convert to be a platform driver - Remove _INI method call i2c: - acpi: Add an i2c_acpi_client_count() helper function i2c-multi-instantiate: - Use the new i2c_acpi_client_count() helper ideapad-laptop: - Fix Legion 5 Fn lock LED intel-hid: - Move to intel sub-directory intel-rst: - Move to intel sub-directory intel-smartconnect: - Move to intel sub-directory intel-uncore-frequency: - Move to intel sub-directory intel-vbtn: - Move to intel sub-directory intel-wmi-sbl-fw-update: - Move to intel sub-directory intel-wmi-thunderbolt: - Move to intel sub-directory intel_atomisp2: - Move to intel sub-directory intel_bxtwc_tmu: - Move to intel sub-directory intel_cht_int33fe: - Use the new i2c_acpi_client_count() helper intel_chtdc_ti_pwrbtn: - Move to intel sub-directory intel_int0002_vgpio: - Move to intel sub-directory intel_mrfld_pwrbtn: - Move to intel sub-directory intel_oaktrail: - Move to intel sub-directory intel_pmc_core: - Move to intel sub-directory - Prevent possibile overflow intel_pmt_telemetry: - Ignore zero sized entries intel_punit_ipc: - Move to intel sub-directory intel_scu_ipc: - Fix doc of intel_scu_ipc_dev_command_with_size() intel_speed_select_if: - Move to intel sub-directory intel_telemetry: - Move to intel sub-directory intel_turbo_max_3: - Move to intel sub-directory lg-laptop: - Use correct event for keyboard backlight FN-key - Use correct event for touchpad toggle FN-key - Support for battery charge limit on newer models platform/mellanox: - mlxbf-pmc: fix kernel-doc notation platform/surface: - aggregator: Use y instead of objs in Makefile - surface3_power: Use i2c_acpi_get_i2c_resource() helper platform/x86/intel: - pmc/core: Add GBE Package C10 fix for Alder Lake PCH - pmc/core: Add Alder Lake low power mode support for pmc core - pmc/core: Add Latency Tolerance Reporting (LTR) support to Alder Lake - pmc/core: Add Alderlake support to pmc core driver - int3472: Use y instead of objs in Makefile - pmt: Use y instead of objs in Makefile - int33fe: Use y instead of objs in Makefile - Move Intel PMT drivers to new subfolder thermal/drivers/intel: - Move intel_menlow to thermal drivers think-lmi: - add debug_cmd -----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEEuvA7XScYQRpenhd+kuxHeUQDJ9wFAmEw1KAUHGhkZWdvZWRl QHJlZGhhdC5jb20ACgkQkuxHeUQDJ9wk7Qf/dsaaDgx7aC6DfKzdcMgfeLIdTaGm a6svNXM2t/JFdvhjYzxA+4QlQgco7zkN06iRlWbObEonSUsHlGlwEOHX60VgcopO qJaqnznmfdXUocFTnA+5acJXabNaw7xkKHS0K61UWgk+mm6aMuygpKxULnNTa4X+ p3HoU6uXFckpoA/Jstzo5UfegNYhg11bflNd7XN4F3rMCbbNHAsWlf4oVr2YsEHa wECW+1e8wZl4BInUzoXQhilRoybJWXWJ8sLsvQfDXLs9aNoLdDqu9p0MuXEW5QqE wNt26SNNAP2L49BD6kaJszV5Ry/jNSEtVkWwkrzHbGTZoOEyMYas8pm6Uw== =iK1W -----END PGP SIGNATURE----- Merge tag 'platform-drivers-x86-v5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86 Pull x86 platform driver updates from Hans de Goede: "Highlights: - Move all the Intel drivers into their own subdir(s) (mostly Kate's work) - New meraki-mx100 platform driver - Asus WMI driver enhancements, including support for /sys/firmware/acpi/platform_profile - New BIOS SAR driver for Intel M.2 WWAM modems - Alder Lake support for the Intel PMC driver - A whole bunch of cleanups + fixes all over the place" * tag 'platform-drivers-x86-v5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: (65 commits) platform/x86: dell-smbios-wmi: Add missing kfree in error-exit from run_smbios_call platform/x86: dell-smbios-wmi: Avoid false-positive memcpy() warning platform/x86: ISST: use semi-colons instead of commas platform/x86: asus-wmi: Fix "unsigned 'retval' is never less than zero" smatch warning platform/x86: asus-wmi: Delete impossible condition platform/x86: hp_accel: Convert to be a platform driver platform/x86: hp_accel: Remove _INI method call platform/mellanox: mlxbf-pmc: fix kernel-doc notation platform/x86/intel: pmc/core: Add GBE Package C10 fix for Alder Lake PCH platform/x86/intel: pmc/core: Add Alder Lake low power mode support for pmc core platform/x86/intel: pmc/core: Add Latency Tolerance Reporting (LTR) support to Alder Lake platform/x86/intel: pmc/core: Add Alderlake support to pmc core driver platform/x86: intel-wmi-thunderbolt: Move to intel sub-directory platform/x86: intel-wmi-sbl-fw-update: Move to intel sub-directory platform/x86: intel-vbtn: Move to intel sub-directory platform/x86: intel_oaktrail: Move to intel sub-directory platform/x86: intel_int0002_vgpio: Move to intel sub-directory platform/x86: intel-hid: Move to intel sub-directory platform/x86: intel_atomisp2: Move to intel sub-directory platform/x86: intel_speed_select_if: Move to intel sub-directory ...
This commit is contained in:
commit
7ba88a2a09
@ -1,7 +1,7 @@
|
||||
What: /dev/wmi/dell-smbios
|
||||
Date: November 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: "Mario Limonciello" <mario.limonciello@dell.com>
|
||||
Contact: Dell.Client.Kernel@dell.com
|
||||
Description:
|
||||
Perform SMBIOS calls on supported Dell machines.
|
||||
through the Dell ACPI-WMI interface.
|
||||
|
@ -232,7 +232,7 @@ Description: When new NVM image is written to the non-active NVM
|
||||
What: /sys/bus/thunderbolt/devices/.../nvm_authenticate_on_disconnect
|
||||
Date: Oct 2020
|
||||
KernelVersion: v5.9
|
||||
Contact: Mario Limonciello <mario.limonciello@dell.com>
|
||||
Contact: Mario Limonciello <mario.limonciello@outlook.com>
|
||||
Description: For supported devices, automatically authenticate the new Thunderbolt
|
||||
image when the device is disconnected from the host system.
|
||||
|
||||
|
@ -2,8 +2,8 @@ What: /sys/class/firmware-attributes/*/attributes/*/
|
||||
Date: February 2021
|
||||
KernelVersion: 5.11
|
||||
Contact: Divya Bharathi <Divya.Bharathi@Dell.com>,
|
||||
Mario Limonciello <mario.limonciello@dell.com>,
|
||||
Prasanth KSR <prasanth.ksr@dell.com>
|
||||
Dell.Client.Kernel@dell.com
|
||||
Description:
|
||||
A sysfs interface for systems management software to enable
|
||||
configuration capability on supported systems. This directory
|
||||
@ -130,8 +130,8 @@ What: /sys/class/firmware-attributes/*/authentication/
|
||||
Date: February 2021
|
||||
KernelVersion: 5.11
|
||||
Contact: Divya Bharathi <Divya.Bharathi@Dell.com>,
|
||||
Mario Limonciello <mario.limonciello@dell.com>,
|
||||
Prasanth KSR <prasanth.ksr@dell.com>
|
||||
Dell.Client.Kernel@dell.com
|
||||
Description:
|
||||
Devices support various authentication mechanisms which can be exposed
|
||||
as a separate configuration object.
|
||||
@ -220,8 +220,8 @@ What: /sys/class/firmware-attributes/*/attributes/pending_reboot
|
||||
Date: February 2021
|
||||
KernelVersion: 5.11
|
||||
Contact: Divya Bharathi <Divya.Bharathi@Dell.com>,
|
||||
Mario Limonciello <mario.limonciello@dell.com>,
|
||||
Prasanth KSR <prasanth.ksr@dell.com>
|
||||
Dell.Client.Kernel@dell.com
|
||||
Description:
|
||||
A read-only attribute reads 1 if a reboot is necessary to apply
|
||||
pending BIOS attribute changes. Also, an uevent_KOBJ_CHANGE is
|
||||
@ -249,8 +249,8 @@ What: /sys/class/firmware-attributes/*/attributes/reset_bios
|
||||
Date: February 2021
|
||||
KernelVersion: 5.11
|
||||
Contact: Divya Bharathi <Divya.Bharathi@Dell.com>,
|
||||
Mario Limonciello <mario.limonciello@dell.com>,
|
||||
Prasanth KSR <prasanth.ksr@dell.com>
|
||||
Dell.Client.Kernel@dell.com
|
||||
Description:
|
||||
This attribute can be used to reset the BIOS Configuration.
|
||||
Specifically, it tells which type of reset BIOS configuration is being
|
||||
@ -272,3 +272,14 @@ Description:
|
||||
|
||||
Note that any changes to this attribute requires a reboot
|
||||
for changes to take effect.
|
||||
|
||||
What: /sys/class/firmware-attributes/*/attributes/debug_cmd
|
||||
Date: July 2021
|
||||
KernelVersion: 5.14
|
||||
Contact: Mark Pearson <markpearson@lenovo.com>
|
||||
Description:
|
||||
This write only attribute can be used to send debug commands to the BIOS.
|
||||
This should only be used when recommended by the BIOS vendor. Vendors may
|
||||
use it to enable extra debug attributes or BIOS features for testing purposes.
|
||||
|
||||
Note that any changes to this attribute requires a reboot for changes to take effect.
|
||||
|
54
Documentation/ABI/testing/sysfs-driver-intc_sar
Normal file
54
Documentation/ABI/testing/sysfs-driver-intc_sar
Normal file
@ -0,0 +1,54 @@
|
||||
What: /sys/bus/platform/devices/INTC1092:00/intc_reg
|
||||
Date: August 2021
|
||||
KernelVersion: 5.15
|
||||
Contact: Shravan S <s.shravan@intel.com>,
|
||||
An Sudhakar <sudhakar.an@intel.com>
|
||||
Description:
|
||||
Specific Absorption Rate (SAR) regulatory mode is typically
|
||||
derived based on information like mcc (Mobile Country Code) and
|
||||
mnc (Mobile Network Code) that is available for the currently
|
||||
attached LTE network. A userspace application is required to set
|
||||
the current SAR regulatory mode on the Dynamic SAR driver using
|
||||
this sysfs node. Such an application can also read back using
|
||||
this sysfs node, the currently configured regulatory mode value
|
||||
from the Dynamic SAR driver.
|
||||
|
||||
Acceptable regulatory modes are:
|
||||
== ====
|
||||
0 FCC
|
||||
1 CE
|
||||
2 ISED
|
||||
== ====
|
||||
|
||||
- The regulatory mode value has one of the above values.
|
||||
- The default regulatory mode used in the driver is 0.
|
||||
|
||||
What: /sys/bus/platform/devices/INTC1092:00/intc_data
|
||||
Date: August 2021
|
||||
KernelVersion: 5.15
|
||||
Contact: Shravan S <s.shravan@intel.com>,
|
||||
An Sudhakar <sudhakar.an@intel.com>
|
||||
Description:
|
||||
This sysfs entry is used to retrieve Dynamic SAR information
|
||||
emitted/maintained by a BIOS that supports Dynamic SAR.
|
||||
|
||||
The retrieved information is in the order given below:
|
||||
- device_mode
|
||||
- bandtable_index
|
||||
- antennatable_index
|
||||
- sartable_index
|
||||
|
||||
The above information is sent as integer values separated
|
||||
by a single space. This information can then be pushed to a
|
||||
WWAN modem that uses this to control the transmit signal
|
||||
level using the Band/Antenna/SAR table index information.
|
||||
These parameters are derived/decided by aggregating
|
||||
device-mode like laptop/tablet/clamshell etc. and the
|
||||
proximity-sensor data available to the embedded controller on
|
||||
given host. The regulatory mode configured on Dynamic SAR
|
||||
driver also influences these values.
|
||||
|
||||
The userspace applications can poll for changes to this file
|
||||
using POLLPRI event on file-descriptor (fd) obtained by opening
|
||||
this sysfs entry. Application can then read this information from
|
||||
the sysfs node and consume the given information.
|
@ -1,7 +1,7 @@
|
||||
What: /sys/devices/platform/<platform>/tokens/*
|
||||
Date: November 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: "Mario Limonciello" <mario.limonciello@dell.com>
|
||||
Contact: Dell.Client.Kernel@dell.com
|
||||
Description:
|
||||
A read-only description of Dell platform tokens
|
||||
available on the machine.
|
||||
|
@ -1,7 +1,7 @@
|
||||
What: /sys/devices/platform/<platform>/force_power
|
||||
Date: September 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: "Mario Limonciello" <mario.limonciello@dell.com>
|
||||
Contact: "Mario Limonciello" <mario.limonciello@outlook.com>
|
||||
Description:
|
||||
Modify the platform force power state, influencing
|
||||
Thunderbolt controllers to turn on or off when no
|
||||
|
@ -295,7 +295,7 @@ Description:
|
||||
|
||||
What: /sys/power/resume_offset
|
||||
Date: April 2018
|
||||
Contact: Mario Limonciello <mario.limonciello@dell.com>
|
||||
Contact: Mario Limonciello <mario.limonciello@outlook.com>
|
||||
Description:
|
||||
This file is used for telling the kernel an offset into a disk
|
||||
to use when hibernating the system such as with a swap file.
|
||||
|
@ -13,10 +13,8 @@ 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-F5 (Touchpad toggle) - Generates F21
|
||||
- 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 keys work without a need for a special driver.
|
||||
|
35
MAINTAINERS
35
MAINTAINERS
@ -9269,13 +9269,20 @@ 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
|
||||
F: drivers/platform/x86/intel/atomisp2/pm.c
|
||||
|
||||
INTEL ATOMISP2 LED DRIVER
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/intel_atomisp2_led.c
|
||||
F: drivers/platform/x86/intel/atomisp2/led.c
|
||||
|
||||
INTEL BIOS SAR INT1092 DRIVER
|
||||
M: Shravan S <s.shravan@intel.com>
|
||||
M: Intel Corporation <linuxwwan@intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/intel/int1092/
|
||||
|
||||
INTEL BROXTON PMC DRIVER
|
||||
M: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
@ -9371,7 +9378,7 @@ INTEL HID EVENT DRIVER
|
||||
M: Alex Hung <alex.hung@canonical.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/intel-hid.c
|
||||
F: drivers/platform/x86/intel/hid.c
|
||||
|
||||
INTEL I/OAT DMA DRIVER
|
||||
M: Dave Jiang <dave.jiang@intel.com>
|
||||
@ -9515,17 +9522,17 @@ F: include/linux/mfd/intel-m10-bmc.h
|
||||
|
||||
INTEL MENLOW THERMAL DRIVER
|
||||
M: Sujith Thomas <sujith.thomas@intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://01.org/linux-acpi
|
||||
F: drivers/platform/x86/intel_menlow.c
|
||||
F: drivers/thermal/intel/intel_menlow.c
|
||||
|
||||
INTEL P-Unit IPC DRIVER
|
||||
M: Zha Qipeng <qipeng.zha@intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: arch/x86/include/asm/intel_punit_ipc.h
|
||||
F: drivers/platform/x86/intel_punit_ipc.c
|
||||
F: drivers/platform/x86/intel/punit_ipc.c
|
||||
|
||||
INTEL PMC CORE DRIVER
|
||||
M: Rajneesh Bhardwaj <irenic.rajneesh@gmail.com>
|
||||
@ -9533,7 +9540,7 @@ M: David E Box <david.e.box@intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-platform-intel-pmc
|
||||
F: drivers/platform/x86/intel_pmc_core*
|
||||
F: drivers/platform/x86/intel/pmc/
|
||||
|
||||
INTEL PMIC GPIO DRIVERS
|
||||
M: Andy Shevchenko <andy@kernel.org>
|
||||
@ -9551,7 +9558,7 @@ INTEL PMT DRIVER
|
||||
M: "David E. Box" <david.e.box@linux.intel.com>
|
||||
S: Maintained
|
||||
F: drivers/mfd/intel_pmt.c
|
||||
F: drivers/platform/x86/intel_pmt_*
|
||||
F: drivers/platform/x86/intel/pmt/
|
||||
|
||||
INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT
|
||||
M: Stanislav Yakovlev <stas.yakovlev@gmail.com>
|
||||
@ -9588,7 +9595,7 @@ INTEL SPEED SELECT TECHNOLOGY
|
||||
M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/intel_speed_select_if/
|
||||
F: drivers/platform/x86/intel/speed_select_if/
|
||||
F: include/uapi/linux/isst_if.h
|
||||
F: tools/power/x86/intel-speed-select/
|
||||
|
||||
@ -9609,19 +9616,19 @@ 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
|
||||
F: drivers/platform/x86/intel_telemetry*
|
||||
F: drivers/platform/x86/intel/telemetry/
|
||||
|
||||
INTEL UNCORE FREQUENCY CONTROL
|
||||
M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/intel-uncore-frequency.c
|
||||
F: drivers/platform/x86/intel/uncore-frequency.c
|
||||
|
||||
INTEL VIRTUAL BUTTON DRIVER
|
||||
M: AceLan Kao <acelan.kao@canonical.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/intel-vbtn.c
|
||||
F: drivers/platform/x86/intel/vbtn.c
|
||||
|
||||
INTEL WIRELESS 3945ABG/BG, 4965AGN (iwlegacy)
|
||||
M: Stanislaw Gruszka <stf_xl@wp.pl>
|
||||
@ -9642,12 +9649,12 @@ M: Jithu Joseph <jithu.joseph@intel.com>
|
||||
R: Maurice Ma <maurice.ma@intel.com>
|
||||
S: Maintained
|
||||
W: https://slimbootloader.github.io/security/firmware-update.html
|
||||
F: drivers/platform/x86/intel-wmi-sbl-fw-update.c
|
||||
F: drivers/platform/x86/intel/wmi/sbl-fw-update.c
|
||||
|
||||
INTEL WMI THUNDERBOLT FORCE POWER DRIVER
|
||||
L: Dell.Client.Kernel@dell.com
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/intel-wmi-thunderbolt.c
|
||||
F: drivers/platform/x86/intel/wmi/thunderbolt.c
|
||||
|
||||
INTEL WWAN IOSM DRIVER
|
||||
M: M Chetan Kumar <m.chetan.kumar@intel.com>
|
||||
|
@ -69,6 +69,38 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_acpi_get_i2c_resource);
|
||||
|
||||
static int i2c_acpi_resource_count(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct acpi_resource_i2c_serialbus *sb;
|
||||
int *count = data;
|
||||
|
||||
if (i2c_acpi_get_i2c_resource(ares, &sb))
|
||||
*count = *count + 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* i2c_acpi_client_count - Count the number of I2cSerialBus resources
|
||||
* @adev: ACPI device
|
||||
*
|
||||
* Returns the number of I2cSerialBus resources in the ACPI-device's
|
||||
* resource-list; or a negative error code.
|
||||
*/
|
||||
int i2c_acpi_client_count(struct acpi_device *adev)
|
||||
{
|
||||
int ret, count = 0;
|
||||
LIST_HEAD(r);
|
||||
|
||||
ret = acpi_dev_get_resources(adev, &r, i2c_acpi_resource_count, &count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
acpi_dev_free_resource_list(&r);
|
||||
return count;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_acpi_client_count);
|
||||
|
||||
static int i2c_acpi_fill_info(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct i2c_acpi_lookup *lookup = data;
|
||||
|
@ -271,7 +271,6 @@ struct lis3lv02d {
|
||||
int regs_size;
|
||||
u8 *reg_cache;
|
||||
bool regs_stored;
|
||||
bool init_required;
|
||||
u8 odr_mask; /* ODR bit mask */
|
||||
u8 whoami; /* indicates measurement precision */
|
||||
s16 (*read_data) (struct lis3lv02d *lis3, int reg);
|
||||
|
@ -79,7 +79,8 @@
|
||||
#define MLXBF_PMC_L3C_PERF_CNT_HIGH_VAL GENMASK(24, 0)
|
||||
|
||||
/**
|
||||
* Structure to hold attribute and block info for each sysfs entry
|
||||
* struct mlxbf_pmc_attribute - Structure to hold attribute and block info
|
||||
* for each sysfs entry
|
||||
* @dev_attr: Device attribute struct
|
||||
* @index: index to identify counter number within a block
|
||||
* @nr: block number to which the sysfs belongs
|
||||
@ -91,7 +92,7 @@ struct mlxbf_pmc_attribute {
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure to hold info for each HW block
|
||||
* struct mlxbf_pmc_block_info - Structure to hold info for each HW block
|
||||
*
|
||||
* @mmio_base: The VA at which the PMC block is mapped
|
||||
* @blk_size: Size of each mapped region
|
||||
@ -102,7 +103,7 @@ struct mlxbf_pmc_attribute {
|
||||
* @attr_event_list: Attributes for "event_list" sysfs files
|
||||
* @attr_enable: Attributes for "enable" sysfs files
|
||||
* @block_attr: All attributes needed for the block
|
||||
* @blcok_attr_grp: Attribute group for the block
|
||||
* @block_attr_grp: Attribute group for the block
|
||||
*/
|
||||
struct mlxbf_pmc_block_info {
|
||||
void __iomem *mmio_base;
|
||||
@ -118,7 +119,7 @@ struct mlxbf_pmc_block_info {
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure to hold PMC context info
|
||||
* struct mlxbf_pmc_context - Structure to hold PMC context info
|
||||
*
|
||||
* @pdev: The kernel structure representing the device
|
||||
* @total_blocks: Total number of blocks
|
||||
@ -127,7 +128,7 @@ struct mlxbf_pmc_block_info {
|
||||
* @block_name: Block name
|
||||
* @block: Block info
|
||||
* @groups: Attribute groups from each block
|
||||
* @sv_sreg_support: Whether SMCs are used to access performance registers
|
||||
* @svc_sreg_support: Whether SMCs are used to access performance registers
|
||||
* @sreg_tbl_perf: Secure register access table number
|
||||
* @event_set: Event set to use
|
||||
*/
|
||||
@ -145,7 +146,7 @@ struct mlxbf_pmc_context {
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure to hold supported events for each block
|
||||
* struct mlxbf_pmc_events - Structure to hold supported events for each block
|
||||
* @evt_num: Event number used to program counters
|
||||
* @evt_name: Name of the event
|
||||
*/
|
||||
|
@ -6,12 +6,9 @@ CFLAGS_core.o = -I$(src)
|
||||
|
||||
obj-$(CONFIG_SURFACE_AGGREGATOR) += surface_aggregator.o
|
||||
|
||||
surface_aggregator-objs := core.o
|
||||
surface_aggregator-objs += ssh_parser.o
|
||||
surface_aggregator-objs += ssh_packet_layer.o
|
||||
surface_aggregator-objs += ssh_request_layer.o
|
||||
surface_aggregator-objs += controller.o
|
||||
|
||||
ifeq ($(CONFIG_SURFACE_AGGREGATOR_BUS),y)
|
||||
surface_aggregator-objs += bus.o
|
||||
endif
|
||||
surface_aggregator-y := core.o
|
||||
surface_aggregator-y += ssh_parser.o
|
||||
surface_aggregator-y += ssh_packet_layer.o
|
||||
surface_aggregator-y += ssh_request_layer.o
|
||||
surface_aggregator-$(CONFIG_SURFACE_AGGREGATOR_BUS) += bus.o
|
||||
surface_aggregator-y += controller.o
|
||||
|
@ -384,13 +384,7 @@ mshw0011_space_handler(u32 function, acpi_physical_address command,
|
||||
if (ACPI_FAILURE(ret))
|
||||
return ret;
|
||||
|
||||
if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
|
||||
ret = AE_BAD_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
sb = &ares->data.i2c_serial_bus;
|
||||
if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
|
||||
if (!value64 || !i2c_acpi_get_i2c_resource(ares, &sb)) {
|
||||
ret = AE_BAD_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
|
@ -77,28 +77,6 @@ config UV_SYSFS
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called uv_sysfs.
|
||||
|
||||
config INTEL_WMI_SBL_FW_UPDATE
|
||||
tristate "Intel WMI Slim Bootloader firmware update signaling driver"
|
||||
depends on ACPI_WMI
|
||||
help
|
||||
Say Y here if you want to be able to use the WMI interface to signal
|
||||
Slim Bootloader to trigger update on next reboot.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel-wmi-sbl-fw-update.
|
||||
|
||||
config INTEL_WMI_THUNDERBOLT
|
||||
tristate "Intel WMI thunderbolt force power driver"
|
||||
depends on ACPI_WMI
|
||||
help
|
||||
Say Y here if you want to be able to use the WMI interface on select
|
||||
systems to force the power control of Intel Thunderbolt controllers.
|
||||
This is useful for updating the firmware when devices are not plugged
|
||||
into the controller.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel-wmi-thunderbolt.
|
||||
|
||||
config MXM_WMI
|
||||
tristate "WMI support for MXM Laptop Graphics"
|
||||
depends on ACPI_WMI
|
||||
@ -281,6 +259,7 @@ config ASUS_WMI
|
||||
select INPUT_SPARSEKMAP
|
||||
select LEDS_CLASS
|
||||
select NEW_LEDS
|
||||
select ACPI_PLATFORM_PROFILE
|
||||
help
|
||||
Say Y here if you have a WMI aware Asus laptop (like Eee PCs or new
|
||||
Asus Notebooks).
|
||||
@ -302,6 +281,19 @@ config ASUS_NB_WMI
|
||||
If you have an ACPI-WMI compatible Asus Notebook, say Y or M
|
||||
here.
|
||||
|
||||
config MERAKI_MX100
|
||||
tristate "Cisco Meraki MX100 Platform Driver"
|
||||
depends on GPIOLIB
|
||||
depends on GPIO_ICH
|
||||
depends on LEDS_CLASS
|
||||
select LEDS_GPIO
|
||||
help
|
||||
This driver provides support for the front button and LEDs on
|
||||
the Cisco Meraki MX100 (Tinkerbell) 1U appliance.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called meraki-mx100.
|
||||
|
||||
config EEEPC_LAPTOP
|
||||
tristate "Eee PC Hotkey Driver"
|
||||
depends on ACPI
|
||||
@ -654,105 +646,6 @@ config THINKPAD_LMI
|
||||
|
||||
source "drivers/platform/x86/intel/Kconfig"
|
||||
|
||||
config INTEL_ATOMISP2_LED
|
||||
tristate "Intel AtomISP2 camera LED driver"
|
||||
depends on GPIOLIB && LEDS_GPIO
|
||||
help
|
||||
Many Bay Trail and Cherry Trail devices come with a camera attached
|
||||
to Intel's Image Signal Processor. Linux currently does not have a
|
||||
driver for these, so they do not work as a camera. Some of these
|
||||
camera's have a LED which is controlled through a GPIO.
|
||||
|
||||
Some of these devices have a firmware issue where the LED gets turned
|
||||
on at boot. This driver will turn the LED off at boot and also allows
|
||||
controlling the LED (repurposing it) through the sysfs LED interface.
|
||||
|
||||
Which GPIO is attached to the LED is usually not described in the
|
||||
ACPI tables, so this driver contains per-system info about the GPIO
|
||||
inside the driver, this means that this driver only works on systems
|
||||
the driver knows about.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_atomisp2_led.
|
||||
|
||||
config INTEL_ATOMISP2_PM
|
||||
tristate "Intel AtomISP2 dummy / power-management driver"
|
||||
depends on PCI && IOSF_MBI && PM
|
||||
depends on !INTEL_ATOMISP
|
||||
help
|
||||
Power-management driver for Intel's Image Signal Processor found on
|
||||
Bay Trail 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.
|
||||
|
||||
config INTEL_HID_EVENT
|
||||
tristate "INTEL HID Event"
|
||||
depends on ACPI
|
||||
depends on INPUT
|
||||
depends on I2C
|
||||
select INPUT_SPARSEKMAP
|
||||
help
|
||||
This driver provides support for the Intel HID Event hotkey interface.
|
||||
Some laptops require this driver for hotkey support.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel_hid.
|
||||
|
||||
config INTEL_INT0002_VGPIO
|
||||
tristate "Intel ACPI INT0002 Virtual GPIO driver"
|
||||
depends on GPIOLIB && ACPI && PM_SLEEP
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
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 explicitly
|
||||
clear the PME bus 0 status bit in the GPE0a_STS register to avoid an
|
||||
IRQ storm on IRQ 9.
|
||||
|
||||
This is modelled in ACPI through the INT0002 ACPI device, which is
|
||||
called a "Virtual GPIO controller" in ACPI because it defines the
|
||||
event handler to call when the PME triggers through _AEI and _L02
|
||||
methods as would be done for a real GPIO interrupt in ACPI.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel_int0002_vgpio.
|
||||
|
||||
config INTEL_MENLOW
|
||||
tristate "Thermal Management driver for Intel menlow platform"
|
||||
depends on ACPI_THERMAL
|
||||
select THERMAL
|
||||
help
|
||||
ACPI thermal management enhancement driver on
|
||||
Intel Menlow platform.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config INTEL_OAKTRAIL
|
||||
tristate "Intel Oaktrail Platform Extras"
|
||||
depends on ACPI
|
||||
depends on ACPI_VIDEO || ACPI_VIDEO = n
|
||||
depends on RFKILL && BACKLIGHT_CLASS_DEVICE && ACPI
|
||||
help
|
||||
Intel Oaktrail platform need this driver to provide interfaces to
|
||||
enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y
|
||||
here; it will only load on supported platforms.
|
||||
|
||||
config INTEL_VBTN
|
||||
tristate "INTEL VIRTUAL BUTTON"
|
||||
depends on ACPI
|
||||
depends on INPUT
|
||||
depends on I2C
|
||||
select INPUT_SPARSEKMAP
|
||||
help
|
||||
This driver provides support for the Intel Virtual Button interface.
|
||||
Some laptops require this driver for power button support.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel_vbtn.
|
||||
|
||||
config MSI_LAPTOP
|
||||
tristate "MSI Laptop Extras"
|
||||
depends on ACPI
|
||||
@ -1106,150 +999,6 @@ config INTEL_IPS
|
||||
functionality. If in doubt, say Y here; it will only load on
|
||||
supported platforms.
|
||||
|
||||
config INTEL_RST
|
||||
tristate "Intel Rapid Start Technology Driver"
|
||||
depends on ACPI
|
||||
help
|
||||
This driver provides support for modifying parameters on systems
|
||||
equipped with Intel's Rapid Start Technology. When put in an ACPI
|
||||
sleep state, these devices will wake after either a configured
|
||||
timeout or when the system battery reaches a critical state,
|
||||
automatically copying memory contents to disk. On resume, the
|
||||
firmware will copy the memory contents back to RAM and resume the OS
|
||||
as usual.
|
||||
|
||||
config INTEL_SMARTCONNECT
|
||||
tristate "Intel Smart Connect disabling driver"
|
||||
depends on ACPI
|
||||
help
|
||||
Intel Smart Connect is a technology intended to permit devices to
|
||||
update state by resuming for a short period of time at regular
|
||||
intervals. If a user enables this functionality under Windows and
|
||||
then reboots into Linux, the system may remain configured to resume
|
||||
on suspend. In the absence of any userspace to support it, the system
|
||||
will then remain awake until something triggers another suspend.
|
||||
|
||||
This driver checks to determine whether the device has Intel Smart
|
||||
Connect enabled, and if so disables it.
|
||||
|
||||
source "drivers/platform/x86/intel_speed_select_if/Kconfig"
|
||||
|
||||
config INTEL_TURBO_MAX_3
|
||||
bool "Intel Turbo Boost Max Technology 3.0 enumeration driver"
|
||||
depends on X86_64 && SCHED_MC_PRIO
|
||||
help
|
||||
This driver reads maximum performance ratio of each CPU and set up
|
||||
the scheduler priority metrics. In this way scheduler can prefer
|
||||
CPU with higher performance to schedule tasks.
|
||||
This driver is only required when the system is not using Hardware
|
||||
P-States (HWP). In HWP mode, priority can be read from ACPI tables.
|
||||
|
||||
config INTEL_UNCORE_FREQ_CONTROL
|
||||
tristate "Intel Uncore frequency control driver"
|
||||
depends on X86_64
|
||||
help
|
||||
This driver allows control of uncore frequency limits on
|
||||
supported server platforms.
|
||||
Uncore frequency controls RING/LLC (last-level cache) clocks.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel-uncore-frequency.
|
||||
|
||||
config INTEL_BXTWC_PMIC_TMU
|
||||
tristate "Intel BXT Whiskey Cove TMU Driver"
|
||||
depends on REGMAP
|
||||
depends on MFD_INTEL_PMC_BXT
|
||||
depends on INTEL_SOC_PMIC_BXTWC
|
||||
help
|
||||
Select this driver to use Intel BXT Whiskey Cove PMIC TMU feature.
|
||||
This driver enables the alarm wakeup functionality in the TMU unit
|
||||
of Whiskey Cove PMIC.
|
||||
|
||||
config INTEL_CHTDC_TI_PWRBTN
|
||||
tristate "Intel Cherry Trail Dollar Cove TI power button driver"
|
||||
depends on INTEL_SOC_PMIC_CHTDC_TI
|
||||
depends on INPUT
|
||||
help
|
||||
This option adds a power button driver driver for Dollar Cove TI
|
||||
PMIC on Intel Cherry Trail devices.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_chtdc_ti_pwrbtn.
|
||||
|
||||
config INTEL_MRFLD_PWRBTN
|
||||
tristate "Intel Merrifield Basin Cove power button driver"
|
||||
depends on INTEL_SOC_PMIC_MRFLD
|
||||
depends on INPUT
|
||||
help
|
||||
This option adds a power button driver for Basin Cove PMIC
|
||||
on Intel Merrifield devices.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_mrfld_pwrbtn.
|
||||
|
||||
config INTEL_PMC_CORE
|
||||
tristate "Intel PMC Core driver"
|
||||
depends on PCI
|
||||
depends on ACPI
|
||||
help
|
||||
The Intel Platform Controller Hub for Intel Core SoCs provides access
|
||||
to Power Management Controller registers via various interfaces. This
|
||||
driver can utilize debugging capabilities and supported features as
|
||||
exposed by the Power Management Controller. It also may perform some
|
||||
tasks in the PMC in order to enable transition into the SLPS0 state.
|
||||
It should be selected on all Intel platforms supported by the driver.
|
||||
|
||||
Supported features:
|
||||
- SLP_S0_RESIDENCY counter
|
||||
- PCH IP Power Gating status
|
||||
- LTR Ignore / LTR Show
|
||||
- MPHY/PLL gating status (Sunrisepoint PCH only)
|
||||
- SLPS0 Debug registers (Cannonlake/Icelake PCH)
|
||||
- Low Power Mode registers (Tigerlake and beyond)
|
||||
- PMC quirks as needed to enable SLPS0/S0ix
|
||||
|
||||
config INTEL_PMT_CLASS
|
||||
tristate
|
||||
help
|
||||
The Intel Platform Monitoring Technology (PMT) class driver provides
|
||||
the basic sysfs interface and file hierarchy used by PMT devices.
|
||||
|
||||
For more information, see:
|
||||
<file:Documentation/ABI/testing/sysfs-class-intel_pmt>
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_pmt_class.
|
||||
|
||||
config INTEL_PMT_TELEMETRY
|
||||
tristate "Intel Platform Monitoring Technology (PMT) Telemetry driver"
|
||||
depends on MFD_INTEL_PMT
|
||||
select INTEL_PMT_CLASS
|
||||
help
|
||||
The Intel Platform Monitory Technology (PMT) Telemetry driver provides
|
||||
access to hardware telemetry metrics on devices that support the
|
||||
feature.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_pmt_telemetry.
|
||||
|
||||
config INTEL_PMT_CRASHLOG
|
||||
tristate "Intel Platform Monitoring Technology (PMT) Crashlog driver"
|
||||
depends on MFD_INTEL_PMT
|
||||
select INTEL_PMT_CLASS
|
||||
help
|
||||
The Intel Platform Monitoring Technology (PMT) crashlog driver provides
|
||||
access to hardware crashlog capabilities on devices that support the
|
||||
feature.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_pmt_crashlog.
|
||||
|
||||
config INTEL_PUNIT_IPC
|
||||
tristate "Intel P-Unit IPC Driver"
|
||||
help
|
||||
This driver provides support for Intel P-Unit Mailbox IPC mechanism,
|
||||
which is used to bridge the communications between kernel and P-Unit.
|
||||
|
||||
config INTEL_SCU_IPC
|
||||
bool
|
||||
|
||||
@ -1297,18 +1046,6 @@ config INTEL_SCU_IPC_UTIL
|
||||
low level access for debug work and updating the firmware. Say
|
||||
N unless you will be doing this on an Intel MID platform.
|
||||
|
||||
config INTEL_TELEMETRY
|
||||
tristate "Intel SoC Telemetry Driver"
|
||||
depends on X86_64
|
||||
depends on MFD_INTEL_PMC_BXT
|
||||
depends on INTEL_PUNIT_IPC
|
||||
help
|
||||
This driver provides interfaces to configure and use
|
||||
telemetry for INTEL SoC from APL onwards. It is also
|
||||
used to get various SoC events and parameters
|
||||
directly via debugfs files. Various tools may use
|
||||
this interface for SoC state monitoring.
|
||||
|
||||
endif # X86_PLATFORM_DEVICES
|
||||
|
||||
config PMC_ATOM
|
||||
|
@ -10,8 +10,6 @@ obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o
|
||||
|
||||
# WMI drivers
|
||||
obj-$(CONFIG_HUAWEI_WMI) += huawei-wmi.o
|
||||
obj-$(CONFIG_INTEL_WMI_SBL_FW_UPDATE) += intel-wmi-sbl-fw-update.o
|
||||
obj-$(CONFIG_INTEL_WMI_THUNDERBOLT) += intel-wmi-thunderbolt.o
|
||||
obj-$(CONFIG_MXM_WMI) += mxm-wmi.o
|
||||
obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o
|
||||
obj-$(CONFIG_XIAOMI_WMI) += xiaomi-wmi.o
|
||||
@ -39,6 +37,9 @@ obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o
|
||||
obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
|
||||
obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o
|
||||
|
||||
# Cisco/Meraki
|
||||
obj-$(CONFIG_MERAKI_MX100) += meraki-mx100.o
|
||||
|
||||
# Dell
|
||||
obj-$(CONFIG_X86_PLATFORM_DRIVERS_DELL) += dell/
|
||||
|
||||
@ -68,14 +69,6 @@ obj-$(CONFIG_THINKPAD_LMI) += think-lmi.o
|
||||
# Intel
|
||||
obj-$(CONFIG_X86_PLATFORM_DRIVERS_INTEL) += intel/
|
||||
|
||||
obj-$(CONFIG_INTEL_ATOMISP2_LED) += intel_atomisp2_led.o
|
||||
obj-$(CONFIG_INTEL_ATOMISP2_PM) += intel_atomisp2_pm.o
|
||||
obj-$(CONFIG_INTEL_HID_EVENT) += intel-hid.o
|
||||
obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
|
||||
obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o
|
||||
obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
|
||||
obj-$(CONFIG_INTEL_VBTN) += intel-vbtn.o
|
||||
|
||||
# MSI
|
||||
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
|
||||
obj-$(CONFIG_MSI_WMI) += msi-wmi.o
|
||||
@ -118,27 +111,11 @@ obj-$(CONFIG_WIRELESS_HOTKEY) += wireless-hotkey.o
|
||||
|
||||
# Intel uncore drivers
|
||||
obj-$(CONFIG_INTEL_IPS) += intel_ips.o
|
||||
obj-$(CONFIG_INTEL_RST) += intel-rst.o
|
||||
obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o
|
||||
obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += intel_speed_select_if/
|
||||
obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
|
||||
obj-$(CONFIG_INTEL_UNCORE_FREQ_CONTROL) += intel-uncore-frequency.o
|
||||
|
||||
# Intel PMIC / PMC / P-Unit devices
|
||||
obj-$(CONFIG_INTEL_BXTWC_PMIC_TMU) += intel_bxtwc_tmu.o
|
||||
obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o
|
||||
obj-$(CONFIG_INTEL_MRFLD_PWRBTN) += intel_mrfld_pwrbtn.o
|
||||
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o intel_pmc_core_pltdrv.o
|
||||
obj-$(CONFIG_INTEL_PMT_CLASS) += intel_pmt_class.o
|
||||
obj-$(CONFIG_INTEL_PMT_TELEMETRY) += intel_pmt_telemetry.o
|
||||
obj-$(CONFIG_INTEL_PMT_CRASHLOG) += intel_pmt_crashlog.o
|
||||
obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o
|
||||
obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
|
||||
obj-$(CONFIG_INTEL_SCU_PCI) += intel_scu_pcidrv.o
|
||||
obj-$(CONFIG_INTEL_SCU_PLATFORM) += intel_scu_pltdrv.o
|
||||
obj-$(CONFIG_INTEL_SCU_WDT) += intel_scu_wdt.o
|
||||
obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
|
||||
obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
|
||||
intel_telemetry_pltdrv.o \
|
||||
intel_telemetry_debugfs.o
|
||||
obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
|
||||
|
@ -60,6 +60,11 @@ MODULE_LICENSE("GPL");
|
||||
#define ACER_WMID_GET_THREEG_METHODID 10
|
||||
#define ACER_WMID_SET_THREEG_METHODID 11
|
||||
|
||||
#define ACER_WMID_SET_GAMING_LED_METHODID 2
|
||||
#define ACER_WMID_GET_GAMING_LED_METHODID 4
|
||||
#define ACER_WMID_SET_GAMING_FAN_BEHAVIOR 14
|
||||
#define ACER_WMID_SET_GAMING_MISC_SETTING_METHODID 22
|
||||
|
||||
/*
|
||||
* Acer ACPI method GUIDs
|
||||
*/
|
||||
@ -68,6 +73,7 @@ MODULE_LICENSE("GPL");
|
||||
#define WMID_GUID1 "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
|
||||
#define WMID_GUID2 "95764E09-FB56-4E83-B31A-37761F60994A"
|
||||
#define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
|
||||
#define WMID_GUID4 "7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56"
|
||||
|
||||
/*
|
||||
* Acer ACPI event GUIDs
|
||||
@ -81,6 +87,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
|
||||
enum acer_wmi_event_ids {
|
||||
WMID_HOTKEY_EVENT = 0x1,
|
||||
WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5,
|
||||
WMID_GAMING_TURBO_KEY_EVENT = 0x7,
|
||||
};
|
||||
|
||||
static const struct key_entry acer_wmi_keymap[] __initconst = {
|
||||
@ -215,6 +222,9 @@ struct hotkey_function_type_aa {
|
||||
#define ACER_CAP_THREEG BIT(4)
|
||||
#define ACER_CAP_SET_FUNCTION_MODE BIT(5)
|
||||
#define ACER_CAP_KBD_DOCK BIT(6)
|
||||
#define ACER_CAP_TURBO_OC BIT(7)
|
||||
#define ACER_CAP_TURBO_LED BIT(8)
|
||||
#define ACER_CAP_TURBO_FAN BIT(9)
|
||||
|
||||
/*
|
||||
* Interface type flags
|
||||
@ -301,6 +311,9 @@ struct quirk_entry {
|
||||
u8 mailled;
|
||||
s8 brightness;
|
||||
u8 bluetooth;
|
||||
u8 turbo;
|
||||
u8 cpu_fans;
|
||||
u8 gpu_fans;
|
||||
};
|
||||
|
||||
static struct quirk_entry *quirks;
|
||||
@ -312,6 +325,10 @@ static void __init set_quirks(void)
|
||||
|
||||
if (quirks->brightness)
|
||||
interface->capability |= ACER_CAP_BRIGHTNESS;
|
||||
|
||||
if (quirks->turbo)
|
||||
interface->capability |= ACER_CAP_TURBO_OC | ACER_CAP_TURBO_LED
|
||||
| ACER_CAP_TURBO_FAN;
|
||||
}
|
||||
|
||||
static int __init dmi_matched(const struct dmi_system_id *dmi)
|
||||
@ -340,6 +357,12 @@ static struct quirk_entry quirk_acer_travelmate_2490 = {
|
||||
.mailled = 1,
|
||||
};
|
||||
|
||||
static struct quirk_entry quirk_acer_predator_ph315_53 = {
|
||||
.turbo = 1,
|
||||
.cpu_fans = 1,
|
||||
.gpu_fans = 1,
|
||||
};
|
||||
|
||||
/* This AMW0 laptop has no bluetooth */
|
||||
static struct quirk_entry quirk_medion_md_98300 = {
|
||||
.wireless = 1,
|
||||
@ -507,6 +530,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
|
||||
},
|
||||
.driver_data = &quirk_acer_travelmate_2490,
|
||||
},
|
||||
{
|
||||
.callback = dmi_matched,
|
||||
.ident = "Acer Predator PH315-53",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH315-53"),
|
||||
},
|
||||
.driver_data = &quirk_acer_predator_ph315_53,
|
||||
},
|
||||
{
|
||||
.callback = set_force_caps,
|
||||
.ident = "Acer Aspire Switch 10E SW3-016",
|
||||
@ -1344,6 +1376,114 @@ static struct wmi_interface wmid_v2_interface = {
|
||||
.type = ACER_WMID_v2,
|
||||
};
|
||||
|
||||
/*
|
||||
* WMID Gaming interface
|
||||
*/
|
||||
|
||||
static acpi_status
|
||||
WMI_gaming_execute_u64(u32 method_id, u64 in, u64 *out)
|
||||
{
|
||||
struct acpi_buffer input = { (acpi_size) sizeof(u64), (void *)(&in) };
|
||||
struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *obj;
|
||||
u32 tmp = 0;
|
||||
acpi_status status;
|
||||
|
||||
status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
obj = (union acpi_object *) result.pointer;
|
||||
|
||||
if (obj) {
|
||||
if (obj->type == ACPI_TYPE_BUFFER) {
|
||||
if (obj->buffer.length == sizeof(u32))
|
||||
tmp = *((u32 *) obj->buffer.pointer);
|
||||
else if (obj->buffer.length == sizeof(u64))
|
||||
tmp = *((u64 *) obj->buffer.pointer);
|
||||
} else if (obj->type == ACPI_TYPE_INTEGER) {
|
||||
tmp = (u64) obj->integer.value;
|
||||
}
|
||||
}
|
||||
|
||||
if (out)
|
||||
*out = tmp;
|
||||
|
||||
kfree(result.pointer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static acpi_status WMID_gaming_set_u64(u64 value, u32 cap)
|
||||
{
|
||||
u32 method_id = 0;
|
||||
|
||||
if (!(interface->capability & cap))
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
switch (cap) {
|
||||
case ACER_CAP_TURBO_LED:
|
||||
method_id = ACER_WMID_SET_GAMING_LED_METHODID;
|
||||
break;
|
||||
case ACER_CAP_TURBO_FAN:
|
||||
method_id = ACER_WMID_SET_GAMING_FAN_BEHAVIOR;
|
||||
break;
|
||||
case ACER_CAP_TURBO_OC:
|
||||
method_id = ACER_WMID_SET_GAMING_MISC_SETTING_METHODID;
|
||||
break;
|
||||
default:
|
||||
return AE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
return WMI_gaming_execute_u64(method_id, value, NULL);
|
||||
}
|
||||
|
||||
static acpi_status WMID_gaming_get_u64(u64 *value, u32 cap)
|
||||
{
|
||||
acpi_status status;
|
||||
u64 result;
|
||||
u64 input;
|
||||
u32 method_id;
|
||||
|
||||
if (!(interface->capability & cap))
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
switch (cap) {
|
||||
case ACER_CAP_TURBO_LED:
|
||||
method_id = ACER_WMID_GET_GAMING_LED_METHODID;
|
||||
input = 0x1;
|
||||
break;
|
||||
default:
|
||||
return AE_BAD_PARAMETER;
|
||||
}
|
||||
status = WMI_gaming_execute_u64(method_id, input, &result);
|
||||
if (ACPI_SUCCESS(status))
|
||||
*value = (u64) result;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void WMID_gaming_set_fan_mode(u8 fan_mode)
|
||||
{
|
||||
/* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
|
||||
u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
|
||||
int i;
|
||||
|
||||
if (quirks->cpu_fans > 0)
|
||||
gpu_fan_config2 |= 1;
|
||||
for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
|
||||
gpu_fan_config2 |= 1 << (i + 1);
|
||||
for (i = 0; i < quirks->gpu_fans; ++i)
|
||||
gpu_fan_config2 |= 1 << (i + 3);
|
||||
if (quirks->cpu_fans > 0)
|
||||
gpu_fan_config1 |= fan_mode;
|
||||
for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
|
||||
gpu_fan_config1 |= fan_mode << (2 * i + 2);
|
||||
for (i = 0; i < quirks->gpu_fans; ++i)
|
||||
gpu_fan_config1 |= fan_mode << (2 * i + 6);
|
||||
WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic Device (interface-independent)
|
||||
*/
|
||||
@ -1575,6 +1715,41 @@ static int acer_gsensor_event(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Predator series turbo button
|
||||
*/
|
||||
static int acer_toggle_turbo(void)
|
||||
{
|
||||
u64 turbo_led_state;
|
||||
|
||||
/* Get current state from turbo button */
|
||||
if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state, ACER_CAP_TURBO_LED)))
|
||||
return -1;
|
||||
|
||||
if (turbo_led_state) {
|
||||
/* Turn off turbo led */
|
||||
WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED);
|
||||
|
||||
/* Set FAN mode to auto */
|
||||
WMID_gaming_set_fan_mode(0x1);
|
||||
|
||||
/* Set OC to normal */
|
||||
WMID_gaming_set_u64(0x5, ACER_CAP_TURBO_OC);
|
||||
WMID_gaming_set_u64(0x7, ACER_CAP_TURBO_OC);
|
||||
} else {
|
||||
/* Turn on turbo led */
|
||||
WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED);
|
||||
|
||||
/* Set FAN mode to turbo */
|
||||
WMID_gaming_set_fan_mode(0x2);
|
||||
|
||||
/* Set OC to turbo mode */
|
||||
WMID_gaming_set_u64(0x205, ACER_CAP_TURBO_OC);
|
||||
WMID_gaming_set_u64(0x207, ACER_CAP_TURBO_OC);
|
||||
}
|
||||
return turbo_led_state;
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch series keyboard dock status
|
||||
*/
|
||||
@ -1872,6 +2047,10 @@ static void acer_wmi_notify(u32 value, void *context)
|
||||
acer_gsensor_event();
|
||||
acer_kbd_dock_event(&return_value);
|
||||
break;
|
||||
case WMID_GAMING_TURBO_KEY_EVENT:
|
||||
if (return_value.key_num == 0x4)
|
||||
acer_toggle_turbo();
|
||||
break;
|
||||
default:
|
||||
pr_warn("Unknown function number - %d - %d\n",
|
||||
return_value.function, return_value.key_num);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/rfkill.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_hotplug.h>
|
||||
#include <linux/platform_profile.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
@ -210,12 +211,24 @@ struct asus_wmi {
|
||||
u8 fan_boost_mode_mask;
|
||||
u8 fan_boost_mode;
|
||||
|
||||
bool egpu_enable_available; // 0 = enable
|
||||
bool egpu_enable;
|
||||
|
||||
bool dgpu_disable_available;
|
||||
bool dgpu_disable;
|
||||
|
||||
bool throttle_thermal_policy_available;
|
||||
u8 throttle_thermal_policy_mode;
|
||||
|
||||
struct platform_profile_handler platform_profile_handler;
|
||||
bool platform_profile_support;
|
||||
|
||||
// The RSOC controls the maximum charging percentage.
|
||||
bool battery_rsoc_available;
|
||||
|
||||
bool panel_overdrive_available;
|
||||
bool panel_overdrive;
|
||||
|
||||
struct hotplug_slot hotplug_slot;
|
||||
struct mutex hotplug_lock;
|
||||
struct mutex wmi_lock;
|
||||
@ -424,6 +437,181 @@ static void lid_flip_tablet_mode_get_state(struct asus_wmi *asus)
|
||||
}
|
||||
}
|
||||
|
||||
/* dGPU ********************************************************************/
|
||||
static int dgpu_disable_check_present(struct asus_wmi *asus)
|
||||
{
|
||||
u32 result;
|
||||
int err;
|
||||
|
||||
asus->dgpu_disable_available = false;
|
||||
|
||||
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_DGPU, &result);
|
||||
if (err) {
|
||||
if (err == -ENODEV)
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
|
||||
asus->dgpu_disable_available = true;
|
||||
asus->dgpu_disable = result & ASUS_WMI_DSTS_STATUS_BIT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dgpu_disable_write(struct asus_wmi *asus)
|
||||
{
|
||||
u32 retval;
|
||||
u8 value;
|
||||
int err;
|
||||
|
||||
/* Don't rely on type conversion */
|
||||
value = asus->dgpu_disable ? 1 : 0;
|
||||
|
||||
err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, value, &retval);
|
||||
if (err) {
|
||||
pr_warn("Failed to set dgpu disable: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (retval > 1) {
|
||||
pr_warn("Failed to set dgpu disable (retval): 0x%x\n", retval);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "dgpu_disable");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t dgpu_disable_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
u8 mode = asus->dgpu_disable;
|
||||
|
||||
return sysfs_emit(buf, "%d\n", mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* A user may be required to store the value twice, typcial store first, then
|
||||
* rescan PCI bus to activate power, then store a second time to save correctly.
|
||||
* The reason for this is that an extra code path in the ACPI is enabled when
|
||||
* the device and bus are powered.
|
||||
*/
|
||||
static ssize_t dgpu_disable_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
bool disable;
|
||||
int result;
|
||||
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
|
||||
result = kstrtobool(buf, &disable);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
asus->dgpu_disable = disable;
|
||||
|
||||
result = dgpu_disable_write(asus);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(dgpu_disable);
|
||||
|
||||
/* eGPU ********************************************************************/
|
||||
static int egpu_enable_check_present(struct asus_wmi *asus)
|
||||
{
|
||||
u32 result;
|
||||
int err;
|
||||
|
||||
asus->egpu_enable_available = false;
|
||||
|
||||
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_EGPU, &result);
|
||||
if (err) {
|
||||
if (err == -ENODEV)
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
|
||||
asus->egpu_enable_available = true;
|
||||
asus->egpu_enable = result & ASUS_WMI_DSTS_STATUS_BIT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int egpu_enable_write(struct asus_wmi *asus)
|
||||
{
|
||||
u32 retval;
|
||||
u8 value;
|
||||
int err;
|
||||
|
||||
/* Don't rely on type conversion */
|
||||
value = asus->egpu_enable ? 1 : 0;
|
||||
|
||||
err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, value, &retval);
|
||||
|
||||
if (err) {
|
||||
pr_warn("Failed to set egpu disable: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (retval > 1) {
|
||||
pr_warn("Failed to set egpu disable (retval): 0x%x\n", retval);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "egpu_enable");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t egpu_enable_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
bool mode = asus->egpu_enable;
|
||||
|
||||
return sysfs_emit(buf, "%d\n", mode);
|
||||
}
|
||||
|
||||
/* The ACPI call to enable the eGPU also disables the internal dGPU */
|
||||
static ssize_t egpu_enable_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
bool enable;
|
||||
int result;
|
||||
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
|
||||
result = kstrtobool(buf, &enable);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
asus->egpu_enable = enable;
|
||||
|
||||
result = egpu_enable_write(asus);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
/* Ensure that the kernel status of dgpu is updated */
|
||||
result = dgpu_disable_check_present(asus);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(egpu_enable);
|
||||
|
||||
/* Battery ********************************************************************/
|
||||
|
||||
/* The battery maximum charging percentage */
|
||||
@ -1221,6 +1409,87 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Panel Overdrive ************************************************************/
|
||||
static int panel_od_check_present(struct asus_wmi *asus)
|
||||
{
|
||||
u32 result;
|
||||
int err;
|
||||
|
||||
asus->panel_overdrive_available = false;
|
||||
|
||||
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_PANEL_OD, &result);
|
||||
if (err) {
|
||||
if (err == -ENODEV)
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
|
||||
asus->panel_overdrive_available = true;
|
||||
asus->panel_overdrive = result & ASUS_WMI_DSTS_STATUS_BIT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int panel_od_write(struct asus_wmi *asus)
|
||||
{
|
||||
u32 retval;
|
||||
u8 value;
|
||||
int err;
|
||||
|
||||
/* Don't rely on type conversion */
|
||||
value = asus->panel_overdrive ? 1 : 0;
|
||||
|
||||
err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PANEL_OD, value, &retval);
|
||||
|
||||
if (err) {
|
||||
pr_warn("Failed to set panel overdrive: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (retval > 1) {
|
||||
pr_warn("Failed to set panel overdrive (retval): 0x%x\n", retval);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "panel_od");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t panel_od_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", asus->panel_overdrive);
|
||||
}
|
||||
|
||||
static ssize_t panel_od_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
bool overdrive;
|
||||
int result;
|
||||
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
|
||||
result = kstrtobool(buf, &overdrive);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
asus->panel_overdrive = overdrive;
|
||||
result = panel_od_write(asus);
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(panel_od);
|
||||
|
||||
/* Quirks *********************************************************************/
|
||||
|
||||
static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
|
||||
@ -1838,12 +2107,23 @@ static int throttle_thermal_policy_set_default(struct asus_wmi *asus)
|
||||
static int throttle_thermal_policy_switch_next(struct asus_wmi *asus)
|
||||
{
|
||||
u8 new_mode = asus->throttle_thermal_policy_mode + 1;
|
||||
int err;
|
||||
|
||||
if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
|
||||
new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
|
||||
|
||||
asus->throttle_thermal_policy_mode = new_mode;
|
||||
return throttle_thermal_policy_write(asus);
|
||||
err = throttle_thermal_policy_write(asus);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* Ensure that platform_profile updates userspace with the change to ensure
|
||||
* that platform_profile and throttle_thermal_policy_mode are in sync.
|
||||
*/
|
||||
platform_profile_notify();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t throttle_thermal_policy_show(struct device *dev,
|
||||
@ -1859,9 +2139,10 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int result;
|
||||
u8 new_mode;
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
u8 new_mode;
|
||||
int result;
|
||||
int err;
|
||||
|
||||
result = kstrtou8(buf, 10, &new_mode);
|
||||
if (result < 0)
|
||||
@ -1871,7 +2152,15 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
|
||||
return -EINVAL;
|
||||
|
||||
asus->throttle_thermal_policy_mode = new_mode;
|
||||
throttle_thermal_policy_write(asus);
|
||||
err = throttle_thermal_policy_write(asus);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* Ensure that platform_profile updates userspace with the change to ensure
|
||||
* that platform_profile and throttle_thermal_policy_mode are in sync.
|
||||
*/
|
||||
platform_profile_notify();
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -1879,6 +2168,91 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
|
||||
// Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
|
||||
static DEVICE_ATTR_RW(throttle_thermal_policy);
|
||||
|
||||
/* Platform profile ***********************************************************/
|
||||
static int platform_profile_get(struct platform_profile_handler *pprof,
|
||||
enum platform_profile_option *profile)
|
||||
{
|
||||
struct asus_wmi *asus;
|
||||
int tp;
|
||||
|
||||
asus = container_of(pprof, struct asus_wmi, platform_profile_handler);
|
||||
|
||||
tp = asus->throttle_thermal_policy_mode;
|
||||
|
||||
switch (tp) {
|
||||
case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT:
|
||||
*profile = PLATFORM_PROFILE_BALANCED;
|
||||
break;
|
||||
case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST:
|
||||
*profile = PLATFORM_PROFILE_PERFORMANCE;
|
||||
break;
|
||||
case ASUS_THROTTLE_THERMAL_POLICY_SILENT:
|
||||
*profile = PLATFORM_PROFILE_QUIET;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int platform_profile_set(struct platform_profile_handler *pprof,
|
||||
enum platform_profile_option profile)
|
||||
{
|
||||
struct asus_wmi *asus;
|
||||
int tp;
|
||||
|
||||
asus = container_of(pprof, struct asus_wmi, platform_profile_handler);
|
||||
|
||||
switch (profile) {
|
||||
case PLATFORM_PROFILE_PERFORMANCE:
|
||||
tp = ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST;
|
||||
break;
|
||||
case PLATFORM_PROFILE_BALANCED:
|
||||
tp = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
|
||||
break;
|
||||
case PLATFORM_PROFILE_QUIET:
|
||||
tp = ASUS_THROTTLE_THERMAL_POLICY_SILENT;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
asus->throttle_thermal_policy_mode = tp;
|
||||
return throttle_thermal_policy_write(asus);
|
||||
}
|
||||
|
||||
static int platform_profile_setup(struct asus_wmi *asus)
|
||||
{
|
||||
struct device *dev = &asus->platform_device->dev;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Not an error if a component platform_profile relies on is unavailable
|
||||
* so early return, skipping the setup of platform_profile.
|
||||
*/
|
||||
if (!asus->throttle_thermal_policy_available)
|
||||
return 0;
|
||||
|
||||
dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n");
|
||||
|
||||
asus->platform_profile_handler.profile_get = platform_profile_get;
|
||||
asus->platform_profile_handler.profile_set = platform_profile_set;
|
||||
|
||||
set_bit(PLATFORM_PROFILE_QUIET, asus->platform_profile_handler.choices);
|
||||
set_bit(PLATFORM_PROFILE_BALANCED,
|
||||
asus->platform_profile_handler.choices);
|
||||
set_bit(PLATFORM_PROFILE_PERFORMANCE,
|
||||
asus->platform_profile_handler.choices);
|
||||
|
||||
err = platform_profile_register(&asus->platform_profile_handler);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
asus->platform_profile_support = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backlight ******************************************************************/
|
||||
|
||||
static int read_backlight_power(struct asus_wmi *asus)
|
||||
@ -2328,10 +2702,13 @@ static struct attribute *platform_attributes[] = {
|
||||
&dev_attr_camera.attr,
|
||||
&dev_attr_cardr.attr,
|
||||
&dev_attr_touchpad.attr,
|
||||
&dev_attr_egpu_enable.attr,
|
||||
&dev_attr_dgpu_disable.attr,
|
||||
&dev_attr_lid_resume.attr,
|
||||
&dev_attr_als_enable.attr,
|
||||
&dev_attr_fan_boost_mode.attr,
|
||||
&dev_attr_throttle_thermal_policy.attr,
|
||||
&dev_attr_panel_od.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -2353,10 +2730,16 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
|
||||
devid = ASUS_WMI_DEVID_LID_RESUME;
|
||||
else if (attr == &dev_attr_als_enable.attr)
|
||||
devid = ASUS_WMI_DEVID_ALS_ENABLE;
|
||||
else if (attr == &dev_attr_egpu_enable.attr)
|
||||
ok = asus->egpu_enable_available;
|
||||
else if (attr == &dev_attr_dgpu_disable.attr)
|
||||
ok = asus->dgpu_disable_available;
|
||||
else if (attr == &dev_attr_fan_boost_mode.attr)
|
||||
ok = asus->fan_boost_mode_available;
|
||||
else if (attr == &dev_attr_throttle_thermal_policy.attr)
|
||||
ok = asus->throttle_thermal_policy_available;
|
||||
else if (attr == &dev_attr_panel_od.attr)
|
||||
ok = asus->panel_overdrive_available;
|
||||
|
||||
if (devid != -1)
|
||||
ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
|
||||
@ -2612,6 +2995,14 @@ static int asus_wmi_add(struct platform_device *pdev)
|
||||
if (err)
|
||||
goto fail_platform;
|
||||
|
||||
err = egpu_enable_check_present(asus);
|
||||
if (err)
|
||||
goto fail_egpu_enable;
|
||||
|
||||
err = dgpu_disable_check_present(asus);
|
||||
if (err)
|
||||
goto fail_dgpu_disable;
|
||||
|
||||
err = fan_boost_mode_check_present(asus);
|
||||
if (err)
|
||||
goto fail_fan_boost_mode;
|
||||
@ -2622,6 +3013,14 @@ static int asus_wmi_add(struct platform_device *pdev)
|
||||
else
|
||||
throttle_thermal_policy_set_default(asus);
|
||||
|
||||
err = platform_profile_setup(asus);
|
||||
if (err)
|
||||
goto fail_platform_profile_setup;
|
||||
|
||||
err = panel_od_check_present(asus);
|
||||
if (err)
|
||||
goto fail_panel_od;
|
||||
|
||||
err = asus_wmi_sysfs_init(asus->platform_device);
|
||||
if (err)
|
||||
goto fail_sysfs;
|
||||
@ -2707,8 +3106,14 @@ static int asus_wmi_add(struct platform_device *pdev)
|
||||
asus_wmi_sysfs_exit(asus->platform_device);
|
||||
fail_sysfs:
|
||||
fail_throttle_thermal_policy:
|
||||
fail_platform_profile_setup:
|
||||
if (asus->platform_profile_support)
|
||||
platform_profile_remove();
|
||||
fail_fan_boost_mode:
|
||||
fail_egpu_enable:
|
||||
fail_dgpu_disable:
|
||||
fail_platform:
|
||||
fail_panel_od:
|
||||
kfree(asus);
|
||||
return err;
|
||||
}
|
||||
@ -2728,6 +3133,9 @@ static int asus_wmi_remove(struct platform_device *device)
|
||||
asus_fan_set_auto(asus);
|
||||
asus_wmi_battery_exit(asus);
|
||||
|
||||
if (asus->platform_profile_support)
|
||||
platform_profile_remove();
|
||||
|
||||
kfree(asus);
|
||||
return 0;
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ config DELL_SMBIOS_SMM
|
||||
config DELL_SMO8800
|
||||
tristate "Dell Latitude freefall driver (ACPI SMO88XX)"
|
||||
default m
|
||||
depends on ACPI
|
||||
depends on ACPI || COMPILE_TEST
|
||||
help
|
||||
Say Y here if you want to support SMO88XX freefall devices
|
||||
on Dell Latitude laptops.
|
||||
|
@ -278,9 +278,9 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd)
|
||||
}
|
||||
|
||||
/* SMI requires CPU 0 */
|
||||
get_online_cpus();
|
||||
cpus_read_lock();
|
||||
ret = smp_call_on_cpu(0, raise_smi, smi_cmd, true);
|
||||
put_online_cpus();
|
||||
cpus_read_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -24,37 +24,6 @@ static struct calling_interface_buffer *buffer;
|
||||
static struct platform_device *platform_device;
|
||||
static DEFINE_MUTEX(smm_mutex);
|
||||
|
||||
static const struct dmi_system_id dell_device_table[] __initconst = {
|
||||
{
|
||||
.ident = "Dell laptop",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_CHASSIS_TYPE, "8"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /*Laptop*/
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /*Notebook*/
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Dell Computer Corporation",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
|
||||
DMI_MATCH(DMI_CHASSIS_TYPE, "8"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(dmi, dell_device_table);
|
||||
|
||||
static void parse_da_table(const struct dmi_header *dm)
|
||||
{
|
||||
struct calling_interface_structure *table =
|
||||
|
@ -69,9 +69,10 @@ static int run_smbios_call(struct wmi_device *wdev)
|
||||
if (obj->type == ACPI_TYPE_INTEGER)
|
||||
dev_dbg(&wdev->dev, "SMBIOS call failed: %llu\n",
|
||||
obj->integer.value);
|
||||
kfree(output.pointer);
|
||||
return -EIO;
|
||||
}
|
||||
memcpy(&priv->buf->std, obj->buffer.pointer, obj->buffer.length);
|
||||
memcpy(input.pointer, obj->buffer.pointer, obj->buffer.length);
|
||||
dev_dbg(&wdev->dev, "result: [%08x,%08x,%08x,%08x]\n",
|
||||
priv->buf->std.output[0], priv->buf->std.output[1],
|
||||
priv->buf->std.output[2], priv->buf->std.output[3]);
|
||||
|
@ -10,13 +10,14 @@
|
||||
|
||||
#define DRIVER_NAME "smo8800"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
struct smo8800_device {
|
||||
u32 irq; /* acpi device irq */
|
||||
@ -44,37 +45,6 @@ static irqreturn_t smo8800_interrupt_thread(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static acpi_status smo8800_get_resource(struct acpi_resource *resource,
|
||||
void *context)
|
||||
{
|
||||
struct acpi_resource_extended_irq *irq;
|
||||
|
||||
if (resource->type != ACPI_RESOURCE_TYPE_EXTENDED_IRQ)
|
||||
return AE_OK;
|
||||
|
||||
irq = &resource->data.extended_irq;
|
||||
if (!irq || !irq->interrupt_count)
|
||||
return AE_OK;
|
||||
|
||||
*((u32 *)context) = irq->interrupts[0];
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
static u32 smo8800_get_irq(struct acpi_device *device)
|
||||
{
|
||||
u32 irq = 0;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
|
||||
smo8800_get_resource, &irq);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(&device->dev, "acpi_walk_resources failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
static ssize_t smo8800_misc_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
@ -136,7 +106,7 @@ static const struct file_operations smo8800_misc_fops = {
|
||||
.release = smo8800_misc_release,
|
||||
};
|
||||
|
||||
static int smo8800_add(struct acpi_device *device)
|
||||
static int smo8800_probe(struct platform_device *device)
|
||||
{
|
||||
int err;
|
||||
struct smo8800_device *smo8800;
|
||||
@ -160,14 +130,12 @@ static int smo8800_add(struct acpi_device *device)
|
||||
return err;
|
||||
}
|
||||
|
||||
device->driver_data = smo8800;
|
||||
platform_set_drvdata(device, smo8800);
|
||||
|
||||
smo8800->irq = smo8800_get_irq(device);
|
||||
if (!smo8800->irq) {
|
||||
dev_err(&device->dev, "failed to obtain IRQ\n");
|
||||
err = -EINVAL;
|
||||
err = platform_get_irq(device, 0);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
}
|
||||
smo8800->irq = err;
|
||||
|
||||
err = request_threaded_irq(smo8800->irq, smo8800_interrupt_quick,
|
||||
smo8800_interrupt_thread,
|
||||
@ -189,9 +157,9 @@ static int smo8800_add(struct acpi_device *device)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int smo8800_remove(struct acpi_device *device)
|
||||
static int smo8800_remove(struct platform_device *device)
|
||||
{
|
||||
struct smo8800_device *smo8800 = device->driver_data;
|
||||
struct smo8800_device *smo8800 = platform_get_drvdata(device);
|
||||
|
||||
free_irq(smo8800->irq, smo8800);
|
||||
misc_deregister(&smo8800->miscdev);
|
||||
@ -211,21 +179,17 @@ static const struct acpi_device_id smo8800_ids[] = {
|
||||
{ "SMO8831", 0 },
|
||||
{ "", 0 },
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(acpi, smo8800_ids);
|
||||
|
||||
static struct acpi_driver smo8800_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.class = "Latitude",
|
||||
.ids = smo8800_ids,
|
||||
.ops = {
|
||||
.add = smo8800_add,
|
||||
.remove = smo8800_remove,
|
||||
static struct platform_driver smo8800_driver = {
|
||||
.probe = smo8800_probe,
|
||||
.remove = smo8800_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.acpi_match_table = smo8800_ids,
|
||||
},
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
module_acpi_driver(smo8800_driver);
|
||||
module_platform_driver(smo8800_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Dell Latitude freefall driver (ACPI SMO88XX)");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -17,30 +17,6 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
static int dual_accel_i2c_resource_count(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct acpi_resource_i2c_serialbus *sb;
|
||||
int *count = data;
|
||||
|
||||
if (i2c_acpi_get_i2c_resource(ares, &sb))
|
||||
*count = *count + 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dual_accel_i2c_client_count(struct acpi_device *adev)
|
||||
{
|
||||
int ret, count = 0;
|
||||
LIST_HEAD(r);
|
||||
|
||||
ret = acpi_dev_get_resources(adev, &r, dual_accel_i2c_resource_count, &count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
acpi_dev_free_resource_list(&r);
|
||||
return count;
|
||||
}
|
||||
|
||||
static bool dual_accel_detect_bosc0200(void)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
@ -50,7 +26,7 @@ static bool dual_accel_detect_bosc0200(void)
|
||||
if (!adev)
|
||||
return false;
|
||||
|
||||
count = dual_accel_i2c_client_count(adev);
|
||||
count = i2c_acpi_client_count(adev);
|
||||
|
||||
acpi_dev_put(adev);
|
||||
|
||||
|
@ -28,9 +28,6 @@
|
||||
#include <linux/serio.h>
|
||||
#include "../../misc/lis3lv02d/lis3lv02d.h"
|
||||
|
||||
#define DRIVER_NAME "hp_accel"
|
||||
#define ACPI_MDPS_CLASS "accelerometer"
|
||||
|
||||
/* Delayed LEDs infrastructure ------------------------------------ */
|
||||
|
||||
/* Special LED class that can defer work */
|
||||
@ -78,23 +75,14 @@ static const struct acpi_device_id lis3lv02d_device_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
|
||||
|
||||
|
||||
/**
|
||||
* lis3lv02d_acpi_init - ACPI _INI method: initialize the device.
|
||||
* lis3lv02d_acpi_init - initialize the device for ACPI
|
||||
* @lis3: pointer to the device struct
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
static int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
|
||||
{
|
||||
struct acpi_device *dev = lis3->bus_priv;
|
||||
if (!lis3->init_required)
|
||||
return 0;
|
||||
|
||||
if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI,
|
||||
NULL, NULL) != AE_OK)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -278,30 +266,6 @@ static struct delayed_led_classdev hpled_led = {
|
||||
.set_brightness = hpled_set,
|
||||
};
|
||||
|
||||
static acpi_status
|
||||
lis3lv02d_get_resource(struct acpi_resource *resource, void *context)
|
||||
{
|
||||
if (resource->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
|
||||
struct acpi_resource_extended_irq *irq;
|
||||
u32 *device_irq = context;
|
||||
|
||||
irq = &resource->data.extended_irq;
|
||||
*device_irq = irq->interrupts[0];
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static void lis3lv02d_enum_resources(struct acpi_device *device)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
|
||||
lis3lv02d_get_resource, &lis3_dev.irq);
|
||||
if (ACPI_FAILURE(status))
|
||||
printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
|
||||
}
|
||||
|
||||
static bool hp_accel_i8042_filter(unsigned char data, unsigned char str,
|
||||
struct serio *port)
|
||||
{
|
||||
@ -331,23 +295,19 @@ static bool hp_accel_i8042_filter(unsigned char data, unsigned char str,
|
||||
return false;
|
||||
}
|
||||
|
||||
static int lis3lv02d_add(struct acpi_device *device)
|
||||
static int lis3lv02d_probe(struct platform_device *device)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
lis3_dev.bus_priv = device;
|
||||
lis3_dev.bus_priv = ACPI_COMPANION(&device->dev);
|
||||
lis3_dev.init = lis3lv02d_acpi_init;
|
||||
lis3_dev.read = lis3lv02d_acpi_read;
|
||||
lis3_dev.write = lis3lv02d_acpi_write;
|
||||
strcpy(acpi_device_name(device), DRIVER_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
|
||||
device->driver_data = &lis3_dev;
|
||||
|
||||
/* obtain IRQ number of our device from ACPI */
|
||||
lis3lv02d_enum_resources(device);
|
||||
ret = platform_get_irq_optional(device, 0);
|
||||
if (ret > 0)
|
||||
lis3_dev.irq = ret;
|
||||
|
||||
/* If possible use a "standard" axes order */
|
||||
if (lis3_dev.ac.x && lis3_dev.ac.y && lis3_dev.ac.z) {
|
||||
@ -359,7 +319,6 @@ static int lis3lv02d_add(struct acpi_device *device)
|
||||
}
|
||||
|
||||
/* call the core layer do its init */
|
||||
lis3_dev.init_required = true;
|
||||
ret = lis3lv02d_init_device(&lis3_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -381,11 +340,8 @@ static int lis3lv02d_add(struct acpi_device *device)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lis3lv02d_remove(struct acpi_device *device)
|
||||
static int lis3lv02d_remove(struct platform_device *device)
|
||||
{
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
i8042_remove_filter(hp_accel_i8042_filter);
|
||||
lis3lv02d_joystick_disable(&lis3_dev);
|
||||
lis3lv02d_poweroff(&lis3_dev);
|
||||
@ -396,7 +352,6 @@ static int lis3lv02d_remove(struct acpi_device *device)
|
||||
return lis3lv02d_remove_fs(&lis3_dev);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int lis3lv02d_suspend(struct device *dev)
|
||||
{
|
||||
@ -407,14 +362,12 @@ static int lis3lv02d_suspend(struct device *dev)
|
||||
|
||||
static int lis3lv02d_resume(struct device *dev)
|
||||
{
|
||||
lis3_dev.init_required = false;
|
||||
lis3lv02d_poweron(&lis3_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lis3lv02d_restore(struct device *dev)
|
||||
{
|
||||
lis3_dev.init_required = true;
|
||||
lis3lv02d_poweron(&lis3_dev);
|
||||
return 0;
|
||||
}
|
||||
@ -434,17 +387,16 @@ static const struct dev_pm_ops hp_accel_pm = {
|
||||
#endif
|
||||
|
||||
/* For the HP MDPS aka 3D Driveguard */
|
||||
static struct acpi_driver lis3lv02d_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.class = ACPI_MDPS_CLASS,
|
||||
.ids = lis3lv02d_device_ids,
|
||||
.ops = {
|
||||
.add = lis3lv02d_add,
|
||||
.remove = lis3lv02d_remove,
|
||||
static struct platform_driver lis3lv02d_driver = {
|
||||
.probe = lis3lv02d_probe,
|
||||
.remove = lis3lv02d_remove,
|
||||
.driver = {
|
||||
.name = "hp_accel",
|
||||
.pm = HP_ACCEL_PM,
|
||||
.acpi_match_table = lis3lv02d_device_ids,
|
||||
},
|
||||
.drv.pm = HP_ACCEL_PM,
|
||||
};
|
||||
module_acpi_driver(lis3lv02d_driver);
|
||||
module_platform_driver(lis3lv02d_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED.");
|
||||
MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
|
||||
|
@ -32,31 +32,6 @@ struct i2c_multi_inst_data {
|
||||
struct i2c_client *clients[];
|
||||
};
|
||||
|
||||
static int i2c_multi_inst_count(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct acpi_resource_i2c_serialbus *sb;
|
||||
int *count = data;
|
||||
|
||||
if (i2c_acpi_get_i2c_resource(ares, &sb))
|
||||
*count = *count + 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int i2c_multi_inst_count_resources(struct acpi_device *adev)
|
||||
{
|
||||
LIST_HEAD(r);
|
||||
int count = 0;
|
||||
int ret;
|
||||
|
||||
ret = acpi_dev_get_resources(adev, &r, i2c_multi_inst_count, &count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
acpi_dev_free_resource_list(&r);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int i2c_multi_inst_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_multi_inst_data *multi;
|
||||
@ -76,7 +51,7 @@ static int i2c_multi_inst_probe(struct platform_device *pdev)
|
||||
adev = ACPI_COMPANION(dev);
|
||||
|
||||
/* Count number of clients to instantiate */
|
||||
ret = i2c_multi_inst_count_resources(adev);
|
||||
ret = i2c_acpi_client_count(adev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
static const char *const ideapad_wmi_fnesc_events[] = {
|
||||
"26CAB2E5-5CF1-46AE-AAC3-4A12B6BA50E6", /* Yoga 3 */
|
||||
"56322276-8493-4CE8-A783-98C991274F5E", /* Yoga 700 */
|
||||
"8FC0DE0C-B4E4-43FD-B0F3-8871711C1294", /* Legion 5 */
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -1459,11 +1460,19 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data)
|
||||
static void ideapad_wmi_notify(u32 value, void *context)
|
||||
{
|
||||
struct ideapad_private *priv = context;
|
||||
unsigned long result;
|
||||
|
||||
switch (value) {
|
||||
case 128:
|
||||
ideapad_input_report(priv, value);
|
||||
break;
|
||||
case 208:
|
||||
if (!eval_hals(priv->adev->handle, &result)) {
|
||||
bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result);
|
||||
|
||||
exec_sals(priv->adev->handle, state ? SALS_FNLOCK_ON : SALS_FNLOCK_OFF);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_info(&priv->platform_device->dev,
|
||||
"Unknown WMI event: %u\n", value);
|
||||
|
@ -16,7 +16,156 @@ menuconfig X86_PLATFORM_DRIVERS_INTEL
|
||||
|
||||
if X86_PLATFORM_DRIVERS_INTEL
|
||||
|
||||
source "drivers/platform/x86/intel/atomisp2/Kconfig"
|
||||
source "drivers/platform/x86/intel/int1092/Kconfig"
|
||||
source "drivers/platform/x86/intel/int33fe/Kconfig"
|
||||
source "drivers/platform/x86/intel/int3472/Kconfig"
|
||||
source "drivers/platform/x86/intel/pmc/Kconfig"
|
||||
source "drivers/platform/x86/intel/pmt/Kconfig"
|
||||
source "drivers/platform/x86/intel/speed_select_if/Kconfig"
|
||||
source "drivers/platform/x86/intel/telemetry/Kconfig"
|
||||
source "drivers/platform/x86/intel/wmi/Kconfig"
|
||||
|
||||
config INTEL_HID_EVENT
|
||||
tristate "Intel HID Event"
|
||||
depends on ACPI
|
||||
depends on INPUT
|
||||
depends on I2C
|
||||
select INPUT_SPARSEKMAP
|
||||
help
|
||||
This driver provides support for the Intel HID Event hotkey interface.
|
||||
Some laptops require this driver for hotkey support.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel_hid.
|
||||
|
||||
config INTEL_VBTN
|
||||
tristate "Intel Virtual Button"
|
||||
depends on ACPI
|
||||
depends on INPUT
|
||||
depends on I2C
|
||||
select INPUT_SPARSEKMAP
|
||||
help
|
||||
This driver provides support for the Intel Virtual Button interface.
|
||||
Some laptops require this driver for power button support.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel_vbtn.
|
||||
|
||||
config INTEL_INT0002_VGPIO
|
||||
tristate "Intel ACPI INT0002 Virtual GPIO driver"
|
||||
depends on GPIOLIB && ACPI && PM_SLEEP
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
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 explicitly
|
||||
clear the PME bus 0 status bit in the GPE0a_STS register to avoid an
|
||||
IRQ storm on IRQ 9.
|
||||
|
||||
This is modelled in ACPI through the INT0002 ACPI device, which is
|
||||
called a "Virtual GPIO controller" in ACPI because it defines the
|
||||
event handler to call when the PME triggers through _AEI and _L02
|
||||
methods as would be done for a real GPIO interrupt in ACPI.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel_int0002_vgpio.
|
||||
|
||||
config INTEL_OAKTRAIL
|
||||
tristate "Intel Oaktrail Platform Extras"
|
||||
depends on ACPI
|
||||
depends on ACPI_VIDEO || ACPI_VIDEO=n
|
||||
depends on RFKILL && BACKLIGHT_CLASS_DEVICE && ACPI
|
||||
help
|
||||
Intel Oaktrail platform need this driver to provide interfaces to
|
||||
enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y
|
||||
here; it will only load on supported platforms.
|
||||
|
||||
config INTEL_BXTWC_PMIC_TMU
|
||||
tristate "Intel Broxton Whiskey Cove TMU Driver"
|
||||
depends on INTEL_SOC_PMIC_BXTWC
|
||||
depends on MFD_INTEL_PMC_BXT
|
||||
select REGMAP
|
||||
help
|
||||
Select this driver to use Intel Broxton Whiskey Cove PMIC TMU feature.
|
||||
This driver enables the alarm wakeup functionality in the TMU unit of
|
||||
Whiskey Cove PMIC.
|
||||
|
||||
config INTEL_CHTDC_TI_PWRBTN
|
||||
tristate "Intel Cherry Trail Dollar Cove TI power button driver"
|
||||
depends on INTEL_SOC_PMIC_CHTDC_TI
|
||||
depends on INPUT
|
||||
help
|
||||
This option adds a power button driver for Dollar Cove TI
|
||||
PMIC on Intel Cherry Trail devices.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_chtdc_ti_pwrbtn.
|
||||
|
||||
config INTEL_MRFLD_PWRBTN
|
||||
tristate "Intel Merrifield Basin Cove power button driver"
|
||||
depends on INTEL_SOC_PMIC_MRFLD
|
||||
depends on INPUT
|
||||
help
|
||||
This option adds a power button driver for Basin Cove PMIC
|
||||
on Intel Merrifield devices.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_mrfld_pwrbtn.
|
||||
|
||||
config INTEL_PUNIT_IPC
|
||||
tristate "Intel P-Unit IPC Driver"
|
||||
help
|
||||
This driver provides support for Intel P-Unit Mailbox IPC mechanism,
|
||||
which is used to bridge the communications between kernel and P-Unit.
|
||||
|
||||
config INTEL_RST
|
||||
tristate "Intel Rapid Start Technology Driver"
|
||||
depends on ACPI
|
||||
help
|
||||
This driver provides support for modifying parameters on systems
|
||||
equipped with Intel's Rapid Start Technology. When put in an ACPI
|
||||
sleep state, these devices will wake after either a configured
|
||||
timeout or when the system battery reaches a critical state,
|
||||
automatically copying memory contents to disk. On resume, the
|
||||
firmware will copy the memory contents back to RAM and resume the OS
|
||||
as usual.
|
||||
|
||||
config INTEL_SMARTCONNECT
|
||||
tristate "Intel Smart Connect disabling driver"
|
||||
depends on ACPI
|
||||
help
|
||||
Intel Smart Connect is a technology intended to permit devices to
|
||||
update state by resuming for a short period of time at regular
|
||||
intervals. If a user enables this functionality under Windows and
|
||||
then reboots into Linux, the system may remain configured to resume
|
||||
on suspend. In the absence of any userspace to support it, the system
|
||||
will then remain awake until something triggers another suspend.
|
||||
|
||||
This driver checks to determine whether the device has Intel Smart
|
||||
Connect enabled, and if so disables it.
|
||||
|
||||
config INTEL_TURBO_MAX_3
|
||||
bool "Intel Turbo Boost Max Technology 3.0 enumeration driver"
|
||||
depends on X86_64 && SCHED_MC_PRIO
|
||||
help
|
||||
This driver reads maximum performance ratio of each CPU and set up
|
||||
the scheduler priority metrics. In this way scheduler can prefer
|
||||
CPU with higher performance to schedule tasks.
|
||||
|
||||
This driver is only required when the system is not using Hardware
|
||||
P-States (HWP). In HWP mode, priority can be read from ACPI tables.
|
||||
|
||||
config INTEL_UNCORE_FREQ_CONTROL
|
||||
tristate "Intel Uncore frequency control driver"
|
||||
depends on X86_64
|
||||
help
|
||||
This driver allows control of Uncore frequency limits on
|
||||
supported server platforms.
|
||||
|
||||
Uncore frequency controls RING/LLC (last-level cache) clocks.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel-uncore-frequency.
|
||||
|
||||
endif # X86_PLATFORM_DRIVERS_INTEL
|
||||
|
@ -4,5 +4,44 @@
|
||||
# Intel x86 Platform-Specific Drivers
|
||||
#
|
||||
|
||||
obj-$(CONFIG_INTEL_ATOMISP2_PDX86) += atomisp2/
|
||||
obj-$(CONFIG_INTEL_SAR_INT1092) += int1092/
|
||||
obj-$(CONFIG_INTEL_CHT_INT33FE) += int33fe/
|
||||
obj-$(CONFIG_INTEL_SKL_INT3472) += int3472/
|
||||
obj-$(CONFIG_INTEL_PMC_CORE) += pmc/
|
||||
obj-$(CONFIG_INTEL_PMT_CLASS) += pmt/
|
||||
obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += speed_select_if/
|
||||
obj-$(CONFIG_INTEL_TELEMETRY) += telemetry/
|
||||
obj-$(CONFIG_INTEL_WMI) += wmi/
|
||||
|
||||
# Intel input drivers
|
||||
intel-hid-y := hid.o
|
||||
obj-$(CONFIG_INTEL_HID_EVENT) += intel-hid.o
|
||||
intel-vbtn-y := vbtn.o
|
||||
obj-$(CONFIG_INTEL_VBTN) += intel-vbtn.o
|
||||
|
||||
# Intel miscellaneous drivers
|
||||
intel_int0002_vgpio-y := int0002_vgpio.o
|
||||
obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
|
||||
intel_oaktrail-y := oaktrail.o
|
||||
obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
|
||||
|
||||
# Intel PMIC / PMC / P-Unit drivers
|
||||
intel_bxtwc_tmu-y := bxtwc_tmu.o
|
||||
obj-$(CONFIG_INTEL_BXTWC_PMIC_TMU) += intel_bxtwc_tmu.o
|
||||
intel_chtdc_ti_pwrbtn-y := chtdc_ti_pwrbtn.o
|
||||
obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o
|
||||
intel_mrfld_pwrbtn-y := mrfld_pwrbtn.o
|
||||
obj-$(CONFIG_INTEL_MRFLD_PWRBTN) += intel_mrfld_pwrbtn.o
|
||||
intel_punit_ipc-y := punit_ipc.o
|
||||
obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o
|
||||
|
||||
# Intel Uncore drivers
|
||||
intel-rst-y := rst.o
|
||||
obj-$(CONFIG_INTEL_RST) += intel-rst.o
|
||||
intel-smartconnect-y := smartconnect.o
|
||||
obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o
|
||||
intel_turbo_max_3-y := turbo_max_3.o
|
||||
obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
|
||||
intel-uncore-frequency-y := uncore-frequency.o
|
||||
obj-$(CONFIG_INTEL_UNCORE_FREQ_CONTROL) += intel-uncore-frequency.o
|
||||
|
43
drivers/platform/x86/intel/atomisp2/Kconfig
Normal file
43
drivers/platform/x86/intel/atomisp2/Kconfig
Normal file
@ -0,0 +1,43 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Intel x86 Platform Specific Drivers
|
||||
#
|
||||
|
||||
config INTEL_ATOMISP2_PDX86
|
||||
bool
|
||||
|
||||
config INTEL_ATOMISP2_LED
|
||||
tristate "Intel AtomISP v2 camera LED driver"
|
||||
depends on GPIOLIB && LEDS_GPIO
|
||||
select INTEL_ATOMISP2_PDX86
|
||||
help
|
||||
Many Bay Trail and Cherry Trail devices come with a camera attached
|
||||
to Intel's Image Signal Processor. Linux currently does not have a
|
||||
driver for these, so they do not work as a camera. Some of these
|
||||
camera's have a LED which is controlled through a GPIO.
|
||||
|
||||
Some of these devices have a firmware issue where the LED gets turned
|
||||
on at boot. This driver will turn the LED off at boot and also allows
|
||||
controlling the LED (repurposing it) through the sysfs LED interface.
|
||||
|
||||
Which GPIO is attached to the LED is usually not described in the
|
||||
ACPI tables, so this driver contains per-system info about the GPIO
|
||||
inside the driver, this means that this driver only works on systems
|
||||
the driver knows about.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_atomisp2_led.
|
||||
|
||||
config INTEL_ATOMISP2_PM
|
||||
tristate "Intel AtomISP v2 dummy / power-management driver"
|
||||
depends on PCI && IOSF_MBI && PM
|
||||
depends on !INTEL_ATOMISP
|
||||
select INTEL_ATOMISP2_PDX86
|
||||
help
|
||||
Power-management driver for Intel's Image Signal Processor found on
|
||||
Bay Trail 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.
|
9
drivers/platform/x86/intel/atomisp2/Makefile
Normal file
9
drivers/platform/x86/intel/atomisp2/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Intel x86 Platform Specific Drivers
|
||||
#
|
||||
|
||||
intel_atomisp2_led-y := led.o
|
||||
obj-$(CONFIG_INTEL_ATOMISP2_LED) += intel_atomisp2_led.o
|
||||
intel_atomisp2_pm-y += pm.o
|
||||
obj-$(CONFIG_INTEL_ATOMISP2_PM) += intel_atomisp2_pm.o
|
@ -14,7 +14,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/suspend.h>
|
||||
#include "dual_accel_detect.h"
|
||||
#include "../dual_accel_detect.h"
|
||||
|
||||
/* When NOT in tablet mode, VGBS returns with the flag 0x40 */
|
||||
#define TABLET_MODE_FLAG BIT(6)
|
14
drivers/platform/x86/intel/int1092/Kconfig
Normal file
14
drivers/platform/x86/intel/int1092/Kconfig
Normal file
@ -0,0 +1,14 @@
|
||||
config INTEL_SAR_INT1092
|
||||
tristate "Intel Specific Absorption Rate Driver"
|
||||
depends on ACPI
|
||||
help
|
||||
This driver helps to limit the exposure of human body to RF frequency by
|
||||
providing information to userspace application that will inform the Intel
|
||||
M.2 modem to regulate the RF power based on SAR data obtained from the
|
||||
sensors captured in the BIOS. ACPI interface exposes this data from the BIOS
|
||||
to SAR driver. The front end application in userspace will interact with SAR
|
||||
driver to obtain information like the device mode, Antenna index, baseband index,
|
||||
SAR table index and use available communication like MBIM interface to enable
|
||||
data communication to modem for RF power regulation. Enable this config when
|
||||
given platform needs to support "Dynamic SAR" configuration for a modem available
|
||||
on the platform.
|
1
drivers/platform/x86/intel/int1092/Makefile
Normal file
1
drivers/platform/x86/intel/int1092/Makefile
Normal file
@ -0,0 +1 @@
|
||||
obj-$(CONFIG_INTEL_SAR_INT1092) += intel_sar.o
|
316
drivers/platform/x86/intel/int1092/intel_sar.c
Normal file
316
drivers/platform/x86/intel/int1092/intel_sar.c
Normal file
@ -0,0 +1,316 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, Intel Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include "intel_sar.h"
|
||||
|
||||
/**
|
||||
* get_int_value: Retrieve integer values from ACPI Object
|
||||
* @obj: acpi_object pointer which has the integer value
|
||||
* @out: output pointer will get integer value
|
||||
*
|
||||
* Function is used to retrieve integer value from acpi object.
|
||||
*
|
||||
* Return:
|
||||
* * 0 on success
|
||||
* * -EIO if there is an issue in acpi_object passed.
|
||||
*/
|
||||
static int get_int_value(union acpi_object *obj, int *out)
|
||||
{
|
||||
if (!obj || obj->type != ACPI_TYPE_INTEGER)
|
||||
return -EIO;
|
||||
*out = (int)obj->integer.value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* update_sar_data: sar data is updated based on regulatory mode
|
||||
* @context: pointer to driver context structure
|
||||
*
|
||||
* sar_data is updated based on regulatory value
|
||||
* context->reg_value will never exceed MAX_REGULATORY
|
||||
*/
|
||||
static void update_sar_data(struct wwan_sar_context *context)
|
||||
{
|
||||
struct wwan_device_mode_configuration *config =
|
||||
&context->config_data[context->reg_value];
|
||||
|
||||
if (config->device_mode_info &&
|
||||
context->sar_data.device_mode < config->total_dev_mode) {
|
||||
struct wwan_device_mode_info *dev_mode =
|
||||
&config->device_mode_info[context->sar_data.device_mode];
|
||||
|
||||
context->sar_data.antennatable_index = dev_mode->antennatable_index;
|
||||
context->sar_data.bandtable_index = dev_mode->bandtable_index;
|
||||
context->sar_data.sartable_index = dev_mode->sartable_index;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* parse_package: parse acpi package for retrieving SAR information
|
||||
* @context: pointer to driver context structure
|
||||
* @item : acpi_object pointer
|
||||
*
|
||||
* Given acpi_object is iterated to retrieve information for each device mode.
|
||||
* If a given package corresponding to a specific device mode is faulty, it is
|
||||
* skipped and the specific entry in context structure will have the default value
|
||||
* of zero. Decoding of subsequent device modes is realized by having "continue"
|
||||
* statements in the for loop on encountering error in parsing given device mode.
|
||||
*
|
||||
* Return:
|
||||
* AE_OK if success
|
||||
* AE_ERROR on error
|
||||
*/
|
||||
static acpi_status parse_package(struct wwan_sar_context *context, union acpi_object *item)
|
||||
{
|
||||
struct wwan_device_mode_configuration *data;
|
||||
int value, itr, reg;
|
||||
union acpi_object *num;
|
||||
|
||||
num = &item->package.elements[0];
|
||||
if (get_int_value(num, &value) || value < 0 || value >= MAX_REGULATORY)
|
||||
return AE_ERROR;
|
||||
|
||||
reg = value;
|
||||
|
||||
data = &context->config_data[reg];
|
||||
if (data->total_dev_mode > MAX_DEV_MODES || data->total_dev_mode == 0 ||
|
||||
item->package.count <= data->total_dev_mode)
|
||||
return AE_ERROR;
|
||||
|
||||
data->device_mode_info = kmalloc_array(data->total_dev_mode,
|
||||
sizeof(struct wwan_device_mode_info), GFP_KERNEL);
|
||||
if (!data->device_mode_info)
|
||||
return AE_ERROR;
|
||||
|
||||
for (itr = 0; itr < data->total_dev_mode; itr++) {
|
||||
struct wwan_device_mode_info temp = { 0 };
|
||||
|
||||
num = &item->package.elements[itr + 1];
|
||||
if (num->type != ACPI_TYPE_PACKAGE || num->package.count < TOTAL_DATA)
|
||||
continue;
|
||||
if (get_int_value(&num->package.elements[0], &temp.device_mode))
|
||||
continue;
|
||||
if (get_int_value(&num->package.elements[1], &temp.bandtable_index))
|
||||
continue;
|
||||
if (get_int_value(&num->package.elements[2], &temp.antennatable_index))
|
||||
continue;
|
||||
if (get_int_value(&num->package.elements[3], &temp.sartable_index))
|
||||
continue;
|
||||
data->device_mode_info[itr] = temp;
|
||||
}
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* sar_get_device_mode: Extraction of information from BIOS via DSM calls
|
||||
* @device: ACPI device for which to retrieve the data
|
||||
*
|
||||
* Retrieve the current device mode information from the BIOS.
|
||||
*
|
||||
* Return:
|
||||
* AE_OK on success
|
||||
* AE_ERROR on error
|
||||
*/
|
||||
static acpi_status sar_get_device_mode(struct platform_device *device)
|
||||
{
|
||||
struct wwan_sar_context *context = dev_get_drvdata(&device->dev);
|
||||
acpi_status status = AE_OK;
|
||||
union acpi_object *out;
|
||||
u32 rev = 0;
|
||||
int value;
|
||||
|
||||
out = acpi_evaluate_dsm(context->handle, &context->guid, rev,
|
||||
COMMAND_ID_DEV_MODE, NULL);
|
||||
if (get_int_value(out, &value)) {
|
||||
dev_err(&device->dev, "DSM cmd:%d Failed to retrieve value\n", COMMAND_ID_DEV_MODE);
|
||||
status = AE_ERROR;
|
||||
goto dev_mode_error;
|
||||
}
|
||||
context->sar_data.device_mode = value;
|
||||
update_sar_data(context);
|
||||
sysfs_notify(&device->dev.kobj, NULL, SYSFS_DATANAME);
|
||||
|
||||
dev_mode_error:
|
||||
ACPI_FREE(out);
|
||||
return status;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id sar_device_ids[] = {
|
||||
{ "INTC1092", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, sar_device_ids);
|
||||
|
||||
static ssize_t intc_data_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct wwan_sar_context *context = dev_get_drvdata(dev);
|
||||
|
||||
return sysfs_emit(buf, "%d %d %d %d\n", context->sar_data.device_mode,
|
||||
context->sar_data.bandtable_index,
|
||||
context->sar_data.antennatable_index,
|
||||
context->sar_data.sartable_index);
|
||||
}
|
||||
static DEVICE_ATTR_RO(intc_data);
|
||||
|
||||
static ssize_t intc_reg_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct wwan_sar_context *context = dev_get_drvdata(dev);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", context->reg_value);
|
||||
}
|
||||
|
||||
static ssize_t intc_reg_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct wwan_sar_context *context = dev_get_drvdata(dev);
|
||||
unsigned int value;
|
||||
int read;
|
||||
|
||||
if (!count)
|
||||
return -EINVAL;
|
||||
read = kstrtouint(buf, 10, &value);
|
||||
if (read < 0)
|
||||
return read;
|
||||
if (value >= MAX_REGULATORY)
|
||||
return -EOVERFLOW;
|
||||
context->reg_value = value;
|
||||
update_sar_data(context);
|
||||
sysfs_notify(&dev->kobj, NULL, SYSFS_DATANAME);
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_RW(intc_reg);
|
||||
|
||||
static struct attribute *intcsar_attrs[] = {
|
||||
&dev_attr_intc_data.attr,
|
||||
&dev_attr_intc_reg.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group intcsar_group = {
|
||||
.attrs = intcsar_attrs,
|
||||
};
|
||||
|
||||
static void sar_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct platform_device *device = data;
|
||||
|
||||
if (event == SAR_EVENT) {
|
||||
if (sar_get_device_mode(device) != AE_OK)
|
||||
dev_err(&device->dev, "sar_get_device_mode error");
|
||||
}
|
||||
}
|
||||
|
||||
static void sar_get_data(int reg, struct wwan_sar_context *context)
|
||||
{
|
||||
union acpi_object *out, req;
|
||||
u32 rev = 0;
|
||||
|
||||
req.type = ACPI_TYPE_INTEGER;
|
||||
req.integer.value = reg;
|
||||
out = acpi_evaluate_dsm(context->handle, &context->guid, rev,
|
||||
COMMAND_ID_CONFIG_TABLE, &req);
|
||||
if (!out)
|
||||
return;
|
||||
if (out->type == ACPI_TYPE_PACKAGE && out->package.count >= 3 &&
|
||||
out->package.elements[0].type == ACPI_TYPE_INTEGER &&
|
||||
out->package.elements[1].type == ACPI_TYPE_INTEGER &&
|
||||
out->package.elements[2].type == ACPI_TYPE_PACKAGE &&
|
||||
out->package.elements[2].package.count > 0) {
|
||||
context->config_data[reg].version = out->package.elements[0].integer.value;
|
||||
context->config_data[reg].total_dev_mode =
|
||||
out->package.elements[1].integer.value;
|
||||
if (context->config_data[reg].total_dev_mode <= 0 ||
|
||||
context->config_data[reg].total_dev_mode > MAX_DEV_MODES) {
|
||||
ACPI_FREE(out);
|
||||
return;
|
||||
}
|
||||
parse_package(context, &out->package.elements[2]);
|
||||
}
|
||||
ACPI_FREE(out);
|
||||
}
|
||||
|
||||
static int sar_probe(struct platform_device *device)
|
||||
{
|
||||
struct wwan_sar_context *context;
|
||||
int reg;
|
||||
int result;
|
||||
|
||||
context = kzalloc(sizeof(*context), GFP_KERNEL);
|
||||
if (!context)
|
||||
return -ENOMEM;
|
||||
|
||||
context->sar_device = device;
|
||||
context->handle = ACPI_HANDLE(&device->dev);
|
||||
dev_set_drvdata(&device->dev, context);
|
||||
|
||||
result = guid_parse(SAR_DSM_UUID, &context->guid);
|
||||
if (result) {
|
||||
dev_err(&device->dev, "SAR UUID parse error: %d\n", result);
|
||||
goto r_free;
|
||||
}
|
||||
|
||||
for (reg = 0; reg < MAX_REGULATORY; reg++)
|
||||
sar_get_data(reg, context);
|
||||
|
||||
if (sar_get_device_mode(device) != AE_OK) {
|
||||
dev_err(&device->dev, "Failed to get device mode\n");
|
||||
result = -EIO;
|
||||
goto r_free;
|
||||
}
|
||||
|
||||
result = sysfs_create_group(&device->dev.kobj, &intcsar_group);
|
||||
if (result) {
|
||||
dev_err(&device->dev, "sysfs creation failed\n");
|
||||
goto r_free;
|
||||
}
|
||||
|
||||
if (acpi_install_notify_handler(ACPI_HANDLE(&device->dev), ACPI_DEVICE_NOTIFY,
|
||||
sar_notify, (void *)device) != AE_OK) {
|
||||
dev_err(&device->dev, "Failed acpi_install_notify_handler\n");
|
||||
result = -EIO;
|
||||
goto r_sys;
|
||||
}
|
||||
return 0;
|
||||
|
||||
r_sys:
|
||||
sysfs_remove_group(&device->dev.kobj, &intcsar_group);
|
||||
r_free:
|
||||
kfree(context);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sar_remove(struct platform_device *device)
|
||||
{
|
||||
struct wwan_sar_context *context = dev_get_drvdata(&device->dev);
|
||||
int reg;
|
||||
|
||||
acpi_remove_notify_handler(ACPI_HANDLE(&device->dev),
|
||||
ACPI_DEVICE_NOTIFY, sar_notify);
|
||||
sysfs_remove_group(&device->dev.kobj, &intcsar_group);
|
||||
for (reg = 0; reg < MAX_REGULATORY; reg++)
|
||||
kfree(context->config_data[reg].device_mode_info);
|
||||
|
||||
kfree(context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver sar_driver = {
|
||||
.probe = sar_probe,
|
||||
.remove = sar_remove,
|
||||
.driver = {
|
||||
.name = DRVNAME,
|
||||
.owner = THIS_MODULE,
|
||||
.acpi_match_table = ACPI_PTR(sar_device_ids)
|
||||
}
|
||||
};
|
||||
module_platform_driver(sar_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Platform device driver for INTEL MODEM BIOS SAR");
|
||||
MODULE_AUTHOR("Shravan S <s.shravan@intel.com>");
|
86
drivers/platform/x86/intel/int1092/intel_sar.h
Normal file
86
drivers/platform/x86/intel/int1092/intel_sar.h
Normal file
@ -0,0 +1,86 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, Intel Corporation.
|
||||
*/
|
||||
#ifndef INTEL_SAR_H
|
||||
#define INTEL_SAR_H
|
||||
|
||||
#define COMMAND_ID_DEV_MODE 1
|
||||
#define COMMAND_ID_CONFIG_TABLE 2
|
||||
#define DRVNAME "intc_sar"
|
||||
#define MAX_DEV_MODES 50
|
||||
#define MAX_REGULATORY 3
|
||||
#define SAR_DSM_UUID "82737E72-3A33-4C45-A9C7-57C0411A5F13"
|
||||
#define SAR_EVENT 0x80
|
||||
#define SYSFS_DATANAME "intc_data"
|
||||
#define TOTAL_DATA 4
|
||||
|
||||
/**
|
||||
* Structure wwan_device_mode_info - device mode information
|
||||
* Holds the data that needs to be passed to userspace.
|
||||
* The data is updated from the BIOS sensor information.
|
||||
* @device_mode: Specific mode of the device
|
||||
* @bandtable_index: Index of RF band
|
||||
* @antennatable_index: Index of antenna
|
||||
* @sartable_index: Index of SAR
|
||||
*/
|
||||
struct wwan_device_mode_info {
|
||||
int device_mode;
|
||||
int bandtable_index;
|
||||
int antennatable_index;
|
||||
int sartable_index;
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure wwan_device_mode_configuration - device configuration
|
||||
* Holds the data that is configured and obtained on probe event.
|
||||
* The data is updated from the BIOS sensor information.
|
||||
* @version: Mode configuration version
|
||||
* @total_dev_mode: Total number of device modes
|
||||
* @device_mode_info: pointer to structure wwan_device_mode_info
|
||||
*/
|
||||
struct wwan_device_mode_configuration {
|
||||
int version;
|
||||
int total_dev_mode;
|
||||
struct wwan_device_mode_info *device_mode_info;
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure wwan_supported_info - userspace datastore
|
||||
* Holds the data that is obtained from userspace
|
||||
* The data is updated from the userspace and send value back in the
|
||||
* structure format that is mentioned here.
|
||||
* @reg_mode_needed: regulatory mode set by user for tests
|
||||
* @bios_table_revision: Version of SAR table
|
||||
* @num_supported_modes: Total supported modes based on reg_mode
|
||||
*/
|
||||
struct wwan_supported_info {
|
||||
int reg_mode_needed;
|
||||
int bios_table_revision;
|
||||
int num_supported_modes;
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure wwan_sar_context - context of SAR
|
||||
* Holds the complete context as long as the driver is in existence
|
||||
* The context holds instance of the data used for different cases.
|
||||
* @guid: Group id
|
||||
* @handle: store acpi handle
|
||||
* @reg_value: regulatory value
|
||||
* Regulatory 0: FCC, 1: CE, 2: ISED
|
||||
* @sar_device: platform_device type
|
||||
* @sar_kobject: kobject for sysfs
|
||||
* @supported_data: wwan_supported_info struct
|
||||
* @sar_data: wwan_device_mode_info struct
|
||||
* @config_data: wwan_device_mode_configuration array struct
|
||||
*/
|
||||
struct wwan_sar_context {
|
||||
guid_t guid;
|
||||
acpi_handle handle;
|
||||
int reg_value;
|
||||
struct platform_device *sar_device;
|
||||
struct wwan_supported_info supported_data;
|
||||
struct wwan_device_mode_info sar_data;
|
||||
struct wwan_device_mode_configuration config_data[MAX_REGULATORY];
|
||||
};
|
||||
#endif /* INTEL_SAR_H */
|
@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_INTEL_CHT_INT33FE) += intel_cht_int33fe.o
|
||||
intel_cht_int33fe-objs := intel_cht_int33fe_common.o \
|
||||
intel_cht_int33fe-y := intel_cht_int33fe_common.o \
|
||||
intel_cht_int33fe_typec.o \
|
||||
intel_cht_int33fe_microb.o
|
||||
|
@ -16,33 +16,6 @@
|
||||
|
||||
#define EXPECTED_PTYPE 4
|
||||
|
||||
static int cht_int33fe_i2c_res_filter(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct acpi_resource_i2c_serialbus *sb;
|
||||
int *count = data;
|
||||
|
||||
if (i2c_acpi_get_i2c_resource(ares, &sb))
|
||||
(*count)++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cht_int33fe_count_i2c_clients(struct device *dev)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
LIST_HEAD(resource_list);
|
||||
int count = 0;
|
||||
int ret;
|
||||
|
||||
ret = acpi_dev_get_resources(adev, &resource_list,
|
||||
cht_int33fe_i2c_res_filter, &count);
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int cht_int33fe_check_hw_type(struct device *dev)
|
||||
{
|
||||
unsigned long long ptyp;
|
||||
@ -69,7 +42,7 @@ static int cht_int33fe_check_hw_type(struct device *dev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = cht_int33fe_count_i2c_clients(dev);
|
||||
ret = i2c_acpi_client_count(ACPI_COMPANION(dev));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472.o
|
||||
intel_skl_int3472-objs := intel_skl_int3472_common.o \
|
||||
intel_skl_int3472-y := intel_skl_int3472_common.o \
|
||||
intel_skl_int3472_discrete.o \
|
||||
intel_skl_int3472_tps68470.o \
|
||||
intel_skl_int3472_clk_and_regulator.o
|
||||
|
25
drivers/platform/x86/intel/pmc/Kconfig
Normal file
25
drivers/platform/x86/intel/pmc/Kconfig
Normal file
@ -0,0 +1,25 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Intel x86 Platform-Specific Drivers
|
||||
#
|
||||
|
||||
config INTEL_PMC_CORE
|
||||
tristate "Intel PMC Core driver"
|
||||
depends on PCI
|
||||
depends on ACPI
|
||||
help
|
||||
The Intel Platform Controller Hub for Intel Core SoCs provides access
|
||||
to Power Management Controller registers via various interfaces. This
|
||||
driver can utilize debugging capabilities and supported features as
|
||||
exposed by the Power Management Controller. It also may perform some
|
||||
tasks in the PMC in order to enable transition into the SLPS0 state.
|
||||
It should be selected on all Intel platforms supported by the driver.
|
||||
|
||||
Supported features:
|
||||
- SLP_S0_RESIDENCY counter
|
||||
- PCH IP Power Gating status
|
||||
- LTR Ignore / LTR Show
|
||||
- MPHY/PLL gating status (Sunrisepoint PCH only)
|
||||
- SLPS0 Debug registers (Cannonlake/Icelake PCH)
|
||||
- Low Power Mode registers (Tigerlake and beyond)
|
||||
- PMC quirks as needed to enable SLPS0/S0ix
|
9
drivers/platform/x86/intel/pmc/Makefile
Normal file
9
drivers/platform/x86/intel/pmc/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Intel x86 Platform-Specific Drivers
|
||||
#
|
||||
|
||||
intel_pmc_core-y := core.o
|
||||
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o
|
||||
intel_pmc_core_pltdrv-y := pltdrv.o
|
||||
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core_pltdrv.o
|
@ -31,7 +31,7 @@
|
||||
#include <asm/msr.h>
|
||||
#include <asm/tsc.h>
|
||||
|
||||
#include "intel_pmc_core.h"
|
||||
#include "core.h"
|
||||
|
||||
#define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708-ff13b2508972"
|
||||
#define ACPI_GET_LOW_MODE_REGISTERS 1
|
||||
@ -645,6 +645,306 @@ static void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev)
|
||||
ACPI_FREE(out_obj);
|
||||
}
|
||||
|
||||
/* Alder Lake: PGD PFET Enable Ack Status Register(s) bitmap */
|
||||
static const struct pmc_bit_map adl_pfear_map[] = {
|
||||
{"SPI/eSPI", BIT(2)},
|
||||
{"XHCI", BIT(3)},
|
||||
{"SPA", BIT(4)},
|
||||
{"SPB", BIT(5)},
|
||||
{"SPC", BIT(6)},
|
||||
{"GBE", BIT(7)},
|
||||
|
||||
{"SATA", BIT(0)},
|
||||
{"HDA_PGD0", BIT(1)},
|
||||
{"HDA_PGD1", BIT(2)},
|
||||
{"HDA_PGD2", BIT(3)},
|
||||
{"HDA_PGD3", BIT(4)},
|
||||
{"SPD", BIT(5)},
|
||||
{"LPSS", BIT(6)},
|
||||
|
||||
{"SMB", BIT(0)},
|
||||
{"ISH", BIT(1)},
|
||||
{"ITH", BIT(3)},
|
||||
|
||||
{"XDCI", BIT(1)},
|
||||
{"DCI", BIT(2)},
|
||||
{"CSE", BIT(3)},
|
||||
{"CSME_KVM", BIT(4)},
|
||||
{"CSME_PMT", BIT(5)},
|
||||
{"CSME_CLINK", BIT(6)},
|
||||
{"CSME_PTIO", BIT(7)},
|
||||
|
||||
{"CSME_USBR", BIT(0)},
|
||||
{"CSME_SUSRAM", BIT(1)},
|
||||
{"CSME_SMT1", BIT(2)},
|
||||
{"CSME_SMS2", BIT(4)},
|
||||
{"CSME_SMS1", BIT(5)},
|
||||
{"CSME_RTC", BIT(6)},
|
||||
{"CSME_PSF", BIT(7)},
|
||||
|
||||
{"CNVI", BIT(3)},
|
||||
|
||||
{"HDA_PGD4", BIT(2)},
|
||||
{"HDA_PGD5", BIT(3)},
|
||||
{"HDA_PGD6", BIT(4)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map *ext_adl_pfear_map[] = {
|
||||
/*
|
||||
* Check intel_pmc_core_ids[] users of cnp_reg_map for
|
||||
* a list of core SoCs using this.
|
||||
*/
|
||||
adl_pfear_map,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_ltr_show_map[] = {
|
||||
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
|
||||
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
|
||||
{"SATA", CNP_PMC_LTR_SATA},
|
||||
{"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE},
|
||||
{"XHCI", CNP_PMC_LTR_XHCI},
|
||||
{"SOUTHPORT_F", ADL_PMC_LTR_SPF},
|
||||
{"ME", CNP_PMC_LTR_ME},
|
||||
/* EVA is Enterprise Value Add, doesn't really exist on PCH */
|
||||
{"SATA1", CNP_PMC_LTR_EVA},
|
||||
{"SOUTHPORT_C", CNP_PMC_LTR_SPC},
|
||||
{"HD_AUDIO", CNP_PMC_LTR_AZ},
|
||||
{"CNV", CNP_PMC_LTR_CNV},
|
||||
{"LPSS", CNP_PMC_LTR_LPSS},
|
||||
{"SOUTHPORT_D", CNP_PMC_LTR_SPD},
|
||||
{"SOUTHPORT_E", CNP_PMC_LTR_SPE},
|
||||
{"SATA2", CNP_PMC_LTR_CAM},
|
||||
{"ESPI", CNP_PMC_LTR_ESPI},
|
||||
{"SCC", CNP_PMC_LTR_SCC},
|
||||
{"ISH", CNP_PMC_LTR_ISH},
|
||||
{"UFSX2", CNP_PMC_LTR_UFSX2},
|
||||
{"EMMC", CNP_PMC_LTR_EMMC},
|
||||
/*
|
||||
* Check intel_pmc_core_ids[] users of cnp_reg_map for
|
||||
* a list of core SoCs using this.
|
||||
*/
|
||||
{"WIGIG", ICL_PMC_LTR_WIGIG},
|
||||
{"THC0", TGL_PMC_LTR_THC0},
|
||||
{"THC1", TGL_PMC_LTR_THC1},
|
||||
{"SOUTHPORT_G", CNP_PMC_LTR_RESERVED},
|
||||
|
||||
/* Below two cannot be used for LTR_IGNORE */
|
||||
{"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT},
|
||||
{"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_clocksource_status_map[] = {
|
||||
{"CLKPART1_OFF_STS", BIT(0)},
|
||||
{"CLKPART2_OFF_STS", BIT(1)},
|
||||
{"CLKPART3_OFF_STS", BIT(2)},
|
||||
{"CLKPART4_OFF_STS", BIT(3)},
|
||||
{"CLKPART5_OFF_STS", BIT(4)},
|
||||
{"CLKPART6_OFF_STS", BIT(5)},
|
||||
{"CLKPART7_OFF_STS", BIT(6)},
|
||||
{"CLKPART8_OFF_STS", BIT(7)},
|
||||
{"PCIE0PLL_OFF_STS", BIT(10)},
|
||||
{"PCIE1PLL_OFF_STS", BIT(11)},
|
||||
{"PCIE2PLL_OFF_STS", BIT(12)},
|
||||
{"PCIE3PLL_OFF_STS", BIT(13)},
|
||||
{"PCIE4PLL_OFF_STS", BIT(14)},
|
||||
{"PCIE5PLL_OFF_STS", BIT(15)},
|
||||
{"PCIE6PLL_OFF_STS", BIT(16)},
|
||||
{"USB2PLL_OFF_STS", BIT(18)},
|
||||
{"OCPLL_OFF_STS", BIT(22)},
|
||||
{"AUDIOPLL_OFF_STS", BIT(23)},
|
||||
{"GBEPLL_OFF_STS", BIT(24)},
|
||||
{"Fast_XTAL_Osc_OFF_STS", BIT(25)},
|
||||
{"AC_Ring_Osc_OFF_STS", BIT(26)},
|
||||
{"MC_Ring_Osc_OFF_STS", BIT(27)},
|
||||
{"SATAPLL_OFF_STS", BIT(29)},
|
||||
{"USB3PLL_OFF_STS", BIT(31)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_power_gating_status_0_map[] = {
|
||||
{"PMC_PGD0_PG_STS", BIT(0)},
|
||||
{"DMI_PGD0_PG_STS", BIT(1)},
|
||||
{"ESPISPI_PGD0_PG_STS", BIT(2)},
|
||||
{"XHCI_PGD0_PG_STS", BIT(3)},
|
||||
{"SPA_PGD0_PG_STS", BIT(4)},
|
||||
{"SPB_PGD0_PG_STS", BIT(5)},
|
||||
{"SPC_PGD0_PG_STS", BIT(6)},
|
||||
{"GBE_PGD0_PG_STS", BIT(7)},
|
||||
{"SATA_PGD0_PG_STS", BIT(8)},
|
||||
{"DSP_PGD0_PG_STS", BIT(9)},
|
||||
{"DSP_PGD1_PG_STS", BIT(10)},
|
||||
{"DSP_PGD2_PG_STS", BIT(11)},
|
||||
{"DSP_PGD3_PG_STS", BIT(12)},
|
||||
{"SPD_PGD0_PG_STS", BIT(13)},
|
||||
{"LPSS_PGD0_PG_STS", BIT(14)},
|
||||
{"SMB_PGD0_PG_STS", BIT(16)},
|
||||
{"ISH_PGD0_PG_STS", BIT(17)},
|
||||
{"NPK_PGD0_PG_STS", BIT(19)},
|
||||
{"PECI_PGD0_PG_STS", BIT(21)},
|
||||
{"XDCI_PGD0_PG_STS", BIT(25)},
|
||||
{"EXI_PGD0_PG_STS", BIT(26)},
|
||||
{"CSE_PGD0_PG_STS", BIT(27)},
|
||||
{"KVMCC_PGD0_PG_STS", BIT(28)},
|
||||
{"PMT_PGD0_PG_STS", BIT(29)},
|
||||
{"CLINK_PGD0_PG_STS", BIT(30)},
|
||||
{"PTIO_PGD0_PG_STS", BIT(31)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_power_gating_status_1_map[] = {
|
||||
{"USBR0_PGD0_PG_STS", BIT(0)},
|
||||
{"SMT1_PGD0_PG_STS", BIT(2)},
|
||||
{"CSMERTC_PGD0_PG_STS", BIT(6)},
|
||||
{"CSMEPSF_PGD0_PG_STS", BIT(7)},
|
||||
{"CNVI_PGD0_PG_STS", BIT(19)},
|
||||
{"DSP_PGD4_PG_STS", BIT(26)},
|
||||
{"SPG_PGD0_PG_STS", BIT(27)},
|
||||
{"SPE_PGD0_PG_STS", BIT(28)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_power_gating_status_2_map[] = {
|
||||
{"THC0_PGD0_PG_STS", BIT(7)},
|
||||
{"THC1_PGD0_PG_STS", BIT(8)},
|
||||
{"SPF_PGD0_PG_STS", BIT(14)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_d3_status_0_map[] = {
|
||||
{"ISH_D3_STS", BIT(2)},
|
||||
{"LPSS_D3_STS", BIT(3)},
|
||||
{"XDCI_D3_STS", BIT(4)},
|
||||
{"XHCI_D3_STS", BIT(5)},
|
||||
{"SPA_D3_STS", BIT(12)},
|
||||
{"SPB_D3_STS", BIT(13)},
|
||||
{"SPC_D3_STS", BIT(14)},
|
||||
{"SPD_D3_STS", BIT(15)},
|
||||
{"SPE_D3_STS", BIT(16)},
|
||||
{"DSP_D3_STS", BIT(19)},
|
||||
{"SATA_D3_STS", BIT(20)},
|
||||
{"DMI_D3_STS", BIT(22)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_d3_status_1_map[] = {
|
||||
{"GBE_D3_STS", BIT(19)},
|
||||
{"CNVI_D3_STS", BIT(27)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_d3_status_2_map[] = {
|
||||
{"CSMERTC_D3_STS", BIT(1)},
|
||||
{"CSE_D3_STS", BIT(4)},
|
||||
{"KVMCC_D3_STS", BIT(5)},
|
||||
{"USBR0_D3_STS", BIT(6)},
|
||||
{"SMT1_D3_STS", BIT(8)},
|
||||
{"PTIO_D3_STS", BIT(16)},
|
||||
{"PMT_D3_STS", BIT(17)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_d3_status_3_map[] = {
|
||||
{"THC0_D3_STS", BIT(14)},
|
||||
{"THC1_D3_STS", BIT(15)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_vnn_req_status_0_map[] = {
|
||||
{"ISH_VNN_REQ_STS", BIT(2)},
|
||||
{"ESPISPI_VNN_REQ_STS", BIT(18)},
|
||||
{"DSP_VNN_REQ_STS", BIT(19)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_vnn_req_status_1_map[] = {
|
||||
{"NPK_VNN_REQ_STS", BIT(4)},
|
||||
{"EXI_VNN_REQ_STS", BIT(9)},
|
||||
{"GBE_VNN_REQ_STS", BIT(19)},
|
||||
{"SMB_VNN_REQ_STS", BIT(25)},
|
||||
{"CNVI_VNN_REQ_STS", BIT(27)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_vnn_req_status_2_map[] = {
|
||||
{"CSMERTC_VNN_REQ_STS", BIT(1)},
|
||||
{"CSE_VNN_REQ_STS", BIT(4)},
|
||||
{"SMT1_VNN_REQ_STS", BIT(8)},
|
||||
{"CLINK_VNN_REQ_STS", BIT(14)},
|
||||
{"GPIOCOM4_VNN_REQ_STS", BIT(20)},
|
||||
{"GPIOCOM3_VNN_REQ_STS", BIT(21)},
|
||||
{"GPIOCOM2_VNN_REQ_STS", BIT(22)},
|
||||
{"GPIOCOM1_VNN_REQ_STS", BIT(23)},
|
||||
{"GPIOCOM0_VNN_REQ_STS", BIT(24)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_vnn_req_status_3_map[] = {
|
||||
{"GPIOCOM5_VNN_REQ_STS", BIT(11)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map adl_vnn_misc_status_map[] = {
|
||||
{"CPU_C10_REQ_STS", BIT(0)},
|
||||
{"PCIe_LPM_En_REQ_STS", BIT(3)},
|
||||
{"ITH_REQ_STS", BIT(5)},
|
||||
{"CNVI_REQ_STS", BIT(6)},
|
||||
{"ISH_REQ_STS", BIT(7)},
|
||||
{"USB2_SUS_PG_Sys_REQ_STS", BIT(10)},
|
||||
{"PCIe_Clk_REQ_STS", BIT(12)},
|
||||
{"MPHY_Core_DL_REQ_STS", BIT(16)},
|
||||
{"Break-even_En_REQ_STS", BIT(17)},
|
||||
{"MPHY_SUS_REQ_STS", BIT(22)},
|
||||
{"xDCI_attached_REQ_STS", BIT(24)},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pmc_bit_map *adl_lpm_maps[] = {
|
||||
adl_clocksource_status_map,
|
||||
adl_power_gating_status_0_map,
|
||||
adl_power_gating_status_1_map,
|
||||
adl_power_gating_status_2_map,
|
||||
adl_d3_status_0_map,
|
||||
adl_d3_status_1_map,
|
||||
adl_d3_status_2_map,
|
||||
adl_d3_status_3_map,
|
||||
adl_vnn_req_status_0_map,
|
||||
adl_vnn_req_status_1_map,
|
||||
adl_vnn_req_status_2_map,
|
||||
adl_vnn_req_status_3_map,
|
||||
adl_vnn_misc_status_map,
|
||||
tgl_signal_status_map,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct pmc_reg_map adl_reg_map = {
|
||||
.pfear_sts = ext_adl_pfear_map,
|
||||
.slp_s0_offset = ADL_PMC_SLP_S0_RES_COUNTER_OFFSET,
|
||||
.slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
|
||||
.ltr_show_sts = adl_ltr_show_map,
|
||||
.msr_sts = msr_map,
|
||||
.ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
|
||||
.regmap_length = CNP_PMC_MMIO_REG_LEN,
|
||||
.ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
|
||||
.ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES,
|
||||
.pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
|
||||
.pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
|
||||
.ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED,
|
||||
.lpm_num_modes = ADL_LPM_NUM_MODES,
|
||||
.lpm_num_maps = ADL_LPM_NUM_MAPS,
|
||||
.lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
|
||||
.etr3_offset = ETR3_OFFSET,
|
||||
.lpm_sts_latch_en_offset = ADL_LPM_STATUS_LATCH_EN_OFFSET,
|
||||
.lpm_priority_offset = ADL_LPM_PRI_OFFSET,
|
||||
.lpm_en_offset = ADL_LPM_EN_OFFSET,
|
||||
.lpm_residency_offset = ADL_LPM_RESIDENCY_OFFSET,
|
||||
.lpm_sts = adl_lpm_maps,
|
||||
.lpm_status_offset = ADL_LPM_STATUS_OFFSET,
|
||||
.lpm_live_status_offset = ADL_LPM_LIVE_STATUS_OFFSET,
|
||||
};
|
||||
|
||||
static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int reg_offset)
|
||||
{
|
||||
return readl(pmcdev->regbase + reg_offset);
|
||||
@ -1449,9 +1749,42 @@ static int pmc_core_pkgc_show(struct seq_file *s, void *unused)
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(pmc_core_pkgc);
|
||||
|
||||
static void pmc_core_get_low_power_modes(struct pmc_dev *pmcdev)
|
||||
static bool pmc_core_pri_verify(u32 lpm_pri, u8 *mode_order)
|
||||
{
|
||||
u8 lpm_priority[LPM_MAX_NUM_MODES];
|
||||
int i, j;
|
||||
|
||||
if (!lpm_pri)
|
||||
return false;
|
||||
/*
|
||||
* Each byte contains the priority level for 2 modes (7:4 and 3:0).
|
||||
* In a 32 bit register this allows for describing 8 modes. Store the
|
||||
* levels and look for values out of range.
|
||||
*/
|
||||
for (i = 0; i < 8; i++) {
|
||||
int level = lpm_pri & GENMASK(3, 0);
|
||||
|
||||
if (level >= LPM_MAX_NUM_MODES)
|
||||
return false;
|
||||
|
||||
mode_order[i] = level;
|
||||
lpm_pri >>= 4;
|
||||
}
|
||||
|
||||
/* Check that we have unique values */
|
||||
for (i = 0; i < LPM_MAX_NUM_MODES - 1; i++)
|
||||
for (j = i + 1; j < LPM_MAX_NUM_MODES; j++)
|
||||
if (mode_order[i] == mode_order[j])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void pmc_core_get_low_power_modes(struct platform_device *pdev)
|
||||
{
|
||||
struct pmc_dev *pmcdev = platform_get_drvdata(pdev);
|
||||
u8 pri_order[LPM_MAX_NUM_MODES] = LPM_DEFAULT_PRI;
|
||||
u8 mode_order[LPM_MAX_NUM_MODES];
|
||||
u32 lpm_pri;
|
||||
u32 lpm_en;
|
||||
int mode, i, p;
|
||||
|
||||
@ -1462,24 +1795,28 @@ static void pmc_core_get_low_power_modes(struct pmc_dev *pmcdev)
|
||||
lpm_en = pmc_core_reg_read(pmcdev, pmcdev->map->lpm_en_offset);
|
||||
pmcdev->num_lpm_modes = hweight32(lpm_en);
|
||||
|
||||
/* Each byte contains information for 2 modes (7:4 and 3:0) */
|
||||
for (mode = 0; mode < LPM_MAX_NUM_MODES; mode += 2) {
|
||||
u8 priority = pmc_core_reg_read_byte(pmcdev,
|
||||
pmcdev->map->lpm_priority_offset + (mode / 2));
|
||||
int pri0 = GENMASK(3, 0) & priority;
|
||||
int pri1 = (GENMASK(7, 4) & priority) >> 4;
|
||||
/* Read 32 bit LPM_PRI register */
|
||||
lpm_pri = pmc_core_reg_read(pmcdev, pmcdev->map->lpm_priority_offset);
|
||||
|
||||
lpm_priority[pri0] = mode;
|
||||
lpm_priority[pri1] = mode + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop though all modes from lowest to highest priority,
|
||||
* If lpm_pri value passes verification, then override the default
|
||||
* modes here. Otherwise stick with the default.
|
||||
*/
|
||||
if (pmc_core_pri_verify(lpm_pri, mode_order))
|
||||
/* Get list of modes in priority order */
|
||||
for (mode = 0; mode < LPM_MAX_NUM_MODES; mode++)
|
||||
pri_order[mode_order[mode]] = mode;
|
||||
else
|
||||
dev_warn(&pdev->dev, "Assuming a default substate order for this platform\n");
|
||||
|
||||
/*
|
||||
* Loop through all modes from lowest to highest priority,
|
||||
* and capture all enabled modes in order
|
||||
*/
|
||||
i = 0;
|
||||
for (p = LPM_MAX_NUM_MODES - 1; p >= 0; p--) {
|
||||
int mode = lpm_priority[p];
|
||||
int mode = pri_order[p];
|
||||
|
||||
if (!(BIT(mode) & lpm_en))
|
||||
continue;
|
||||
@ -1574,6 +1911,7 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, &icl_reg_map),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &tgl_reg_map),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &tgl_reg_map),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_reg_map),
|
||||
{}
|
||||
};
|
||||
|
||||
@ -1675,17 +2013,17 @@ static int pmc_core_probe(struct platform_device *pdev)
|
||||
mutex_init(&pmcdev->lock);
|
||||
|
||||
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(pmcdev);
|
||||
pmc_core_get_low_power_modes(pmcdev);
|
||||
pmc_core_get_low_power_modes(pdev);
|
||||
pmc_core_do_dmi_quirks(pmcdev);
|
||||
|
||||
if (pmcdev->map == &tgl_reg_map)
|
||||
pmc_core_get_tgl_lpm_reqs(pdev);
|
||||
|
||||
/*
|
||||
* On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when
|
||||
* a cable is attached. Tell the PMC to ignore it.
|
||||
* On TGL and ADL, due to a hardware limitation, the GBE LTR blocks PC10
|
||||
* when a cable is attached. Tell the PMC to ignore it.
|
||||
*/
|
||||
if (pmcdev->map == &tgl_reg_map) {
|
||||
if (pmcdev->map == &tgl_reg_map || pmcdev->map == &adl_reg_map) {
|
||||
dev_dbg(&pdev->dev, "ignoring GBE LTR\n");
|
||||
pmc_core_send_ltr_ignore(pmcdev, 3);
|
||||
}
|
@ -188,6 +188,8 @@ enum ppfear_regs {
|
||||
#define ICL_PMC_SLP_S0_RES_COUNTER_STEP 0x64
|
||||
|
||||
#define LPM_MAX_NUM_MODES 8
|
||||
#define LPM_DEFAULT_PRI { 7, 6, 2, 5, 4, 1, 3, 0 }
|
||||
|
||||
#define GET_X2_COUNTER(v) ((v) >> 1)
|
||||
#define LPM_STS_LATCH_MODE BIT(31)
|
||||
|
||||
@ -197,6 +199,10 @@ enum ppfear_regs {
|
||||
#define TGL_NUM_IP_IGN_ALLOWED 23
|
||||
#define TGL_PMC_LPM_RES_COUNTER_STEP_X2 61 /* 30.5us * 2 */
|
||||
|
||||
#define ADL_PMC_LTR_SPF 0x1C00
|
||||
#define ADL_NUM_IP_IGN_ALLOWED 23
|
||||
#define ADL_PMC_SLP_S0_RES_COUNTER_OFFSET 0x1098
|
||||
|
||||
/*
|
||||
* Tigerlake Power Management Controller register offsets
|
||||
*/
|
||||
@ -218,6 +224,18 @@ enum ppfear_regs {
|
||||
/* Extended Test Mode Register LPM bits (TGL and later */
|
||||
#define ETR3_CLEAR_LPM_EVENTS BIT(28)
|
||||
|
||||
/* Alder Lake Power Management Controller register offsets */
|
||||
#define ADL_LPM_EN_OFFSET 0x179C
|
||||
#define ADL_LPM_RESIDENCY_OFFSET 0x17A4
|
||||
#define ADL_LPM_NUM_MODES 2
|
||||
#define ADL_LPM_NUM_MAPS 14
|
||||
|
||||
/* Alder Lake Low Power Mode debug registers */
|
||||
#define ADL_LPM_STATUS_OFFSET 0x170C
|
||||
#define ADL_LPM_PRI_OFFSET 0x17A0
|
||||
#define ADL_LPM_STATUS_LATCH_EN_OFFSET 0x1704
|
||||
#define ADL_LPM_LIVE_STATUS_OFFSET 0x1764
|
||||
|
||||
const char *pmc_lpm_modes[] = {
|
||||
"S0i2.0",
|
||||
"S0i2.1",
|
||||
@ -277,6 +295,7 @@ struct pmc_reg_map {
|
||||
const u32 pm_vric1_offset;
|
||||
/* Low Power Mode registers */
|
||||
const int lpm_num_maps;
|
||||
const int lpm_num_modes;
|
||||
const int lpm_res_counter_step_x2;
|
||||
const u32 lpm_sts_latch_en_offset;
|
||||
const u32 lpm_en_offset;
|
40
drivers/platform/x86/intel/pmt/Kconfig
Normal file
40
drivers/platform/x86/intel/pmt/Kconfig
Normal file
@ -0,0 +1,40 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Intel Platform Monitoring Technology drivers
|
||||
#
|
||||
|
||||
config INTEL_PMT_CLASS
|
||||
tristate
|
||||
help
|
||||
The Intel Platform Monitoring Technology (PMT) class driver provides
|
||||
the basic sysfs interface and file hierarchy used by PMT devices.
|
||||
|
||||
For more information, see:
|
||||
<file:Documentation/ABI/testing/sysfs-class-intel_pmt>
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_pmt_class.
|
||||
|
||||
config INTEL_PMT_TELEMETRY
|
||||
tristate "Intel Platform Monitoring Technology (PMT) Telemetry driver"
|
||||
depends on MFD_INTEL_PMT
|
||||
select INTEL_PMT_CLASS
|
||||
help
|
||||
The Intel Platform Monitory Technology (PMT) Telemetry driver provides
|
||||
access to hardware telemetry metrics on devices that support the
|
||||
feature.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_pmt_telemetry.
|
||||
|
||||
config INTEL_PMT_CRASHLOG
|
||||
tristate "Intel Platform Monitoring Technology (PMT) Crashlog driver"
|
||||
depends on MFD_INTEL_PMT
|
||||
select INTEL_PMT_CLASS
|
||||
help
|
||||
The Intel Platform Monitoring Technology (PMT) crashlog driver provides
|
||||
access to hardware crashlog capabilities on devices that support the
|
||||
feature.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_pmt_crashlog.
|
12
drivers/platform/x86/intel/pmt/Makefile
Normal file
12
drivers/platform/x86/intel/pmt/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Makefile for linux/drivers/platform/x86/intel/pmt
|
||||
# Intel Platform Monitoring Technology Drivers
|
||||
#
|
||||
|
||||
obj-$(CONFIG_INTEL_PMT_CLASS) += pmt_class.o
|
||||
pmt_class-y := class.o
|
||||
obj-$(CONFIG_INTEL_PMT_TELEMETRY) += pmt_telemetry.o
|
||||
pmt_telemetry-y := telemetry.o
|
||||
obj-$(CONFIG_INTEL_PMT_CRASHLOG) += pmt_crashlog.o
|
||||
pmt_crashlog-y := crashlog.o
|
@ -13,7 +13,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "intel_pmt_class.h"
|
||||
#include "class.h"
|
||||
|
||||
#define PMT_XA_START 0
|
||||
#define PMT_XA_MAX INT_MAX
|
@ -15,7 +15,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
#include "intel_pmt_class.h"
|
||||
#include "class.h"
|
||||
|
||||
#define DRV_NAME "pmt_crashlog"
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
#include "intel_pmt_class.h"
|
||||
#include "class.h"
|
||||
|
||||
#define TELEM_DEV_NAME "pmt_telemetry"
|
||||
|
||||
@ -61,6 +61,14 @@ static int pmt_telem_header_decode(struct intel_pmt_entry *entry,
|
||||
/* Size is measured in DWORDS, but accessor returns bytes */
|
||||
header->size = TELEM_SIZE(readl(disc_table));
|
||||
|
||||
/*
|
||||
* Some devices may expose non-functioning entries that are
|
||||
* reserved for future use. They have zero size. Do not fail
|
||||
* probe for these. Just ignore them.
|
||||
*/
|
||||
if (header->size == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -265,9 +265,9 @@ static int isst_if_get_platform_info(void __user *argp)
|
||||
{
|
||||
struct isst_if_platform_info info;
|
||||
|
||||
info.api_version = ISST_IF_API_VERSION,
|
||||
info.driver_version = ISST_IF_DRIVER_VERSION,
|
||||
info.max_cmds_per_ioctl = ISST_IF_CMD_LIMIT,
|
||||
info.api_version = ISST_IF_API_VERSION;
|
||||
info.driver_version = ISST_IF_DRIVER_VERSION;
|
||||
info.max_cmds_per_ioctl = ISST_IF_CMD_LIMIT;
|
||||
info.mbox_supported = punit_callbacks[ISST_IF_DEV_MBOX].registered;
|
||||
info.mmio_supported = punit_callbacks[ISST_IF_DEV_MMIO].registered;
|
||||
|
||||
@ -379,6 +379,8 @@ static int isst_if_cpu_online(unsigned int cpu)
|
||||
u64 data;
|
||||
int ret;
|
||||
|
||||
isst_cpu_info[cpu].numa_node = cpu_to_node(cpu);
|
||||
|
||||
ret = rdmsrl_safe(MSR_CPU_BUS_NUMBER, &data);
|
||||
if (ret) {
|
||||
/* This is not a fatal error on MSR mailbox only I/F */
|
||||
@ -397,7 +399,6 @@ static int isst_if_cpu_online(unsigned int cpu)
|
||||
return ret;
|
||||
}
|
||||
isst_cpu_info[cpu].punit_cpu_id = data;
|
||||
isst_cpu_info[cpu].numa_node = cpu_to_node(cpu);
|
||||
|
||||
isst_restore_msr_local(cpu);
|
||||
|
16
drivers/platform/x86/intel/telemetry/Kconfig
Normal file
16
drivers/platform/x86/intel/telemetry/Kconfig
Normal file
@ -0,0 +1,16 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Intel x86 Platform Specific Drivers
|
||||
#
|
||||
|
||||
config INTEL_TELEMETRY
|
||||
tristate "Intel SoC Telemetry driver"
|
||||
depends on X86_64
|
||||
depends on MFD_INTEL_PMC_BXT
|
||||
depends on INTEL_PUNIT_IPC
|
||||
help
|
||||
This driver provides interfaces to configure and use
|
||||
telemetry for Intel SoC from Apollo Lake onwards.
|
||||
It is also used to get various SoC events and parameters
|
||||
directly via debugfs files. Various tools may use
|
||||
this interface for SoC state monitoring.
|
11
drivers/platform/x86/intel/telemetry/Makefile
Normal file
11
drivers/platform/x86/intel/telemetry/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Intel x86 Platform Specific Drivers
|
||||
#
|
||||
|
||||
intel_telemetry_core-y := core.o
|
||||
obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o
|
||||
intel_telemetry_pltdrv-y := pltdrv.o
|
||||
obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_pltdrv.o
|
||||
intel_telemetry_debugfs-y := debugfs.o
|
||||
obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_debugfs.o
|
@ -14,7 +14,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/suspend.h>
|
||||
#include "dual_accel_detect.h"
|
||||
#include "../dual_accel_detect.h"
|
||||
|
||||
/* Returned when NOT in tablet mode on some HP Stream x360 11 models */
|
||||
#define VGBS_TABLET_MODE_FLAG_ALT 0x10
|
31
drivers/platform/x86/intel/wmi/Kconfig
Normal file
31
drivers/platform/x86/intel/wmi/Kconfig
Normal file
@ -0,0 +1,31 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Intel x86 Platform Specific Drivers
|
||||
#
|
||||
|
||||
config INTEL_WMI
|
||||
bool
|
||||
|
||||
config INTEL_WMI_SBL_FW_UPDATE
|
||||
tristate "Intel WMI Slim Bootloader firmware update signaling driver"
|
||||
depends on ACPI_WMI
|
||||
select INTEL_WMI
|
||||
help
|
||||
Say Y here if you want to be able to use the WMI interface to signal
|
||||
Slim Bootloader to trigger update on next reboot.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel-wmi-sbl-fw-update.
|
||||
|
||||
config INTEL_WMI_THUNDERBOLT
|
||||
tristate "Intel WMI thunderbolt force power driver"
|
||||
depends on ACPI_WMI
|
||||
select INTEL_WMI
|
||||
help
|
||||
Say Y here if you want to be able to use the WMI interface on select
|
||||
systems to force the power control of Intel Thunderbolt controllers.
|
||||
This is useful for updating the firmware when devices are not plugged
|
||||
into the controller.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called intel-wmi-thunderbolt.
|
9
drivers/platform/x86/intel/wmi/Makefile
Normal file
9
drivers/platform/x86/intel/wmi/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Intel x86 Platform Specific Drivers
|
||||
#
|
||||
|
||||
intel-wmi-sbl-fw-update-y := sbl-fw-update.o
|
||||
obj-$(CONFIG_INTEL_WMI_SBL_FW_UPDATE) += intel-wmi-sbl-fw-update.o
|
||||
intel-wmi-thunderbolt-y := thunderbolt.o
|
||||
obj-$(CONFIG_INTEL_WMI_THUNDERBOLT) += intel-wmi-thunderbolt.o
|
@ -457,7 +457,7 @@ int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd,
|
||||
EXPORT_SYMBOL(intel_scu_ipc_dev_simple_command);
|
||||
|
||||
/**
|
||||
* intel_scu_ipc_command_with_size() - Command with data
|
||||
* intel_scu_ipc_dev_command_with_size() - Command with data
|
||||
* @scu: Optional SCU IPC instance
|
||||
* @cmd: Command
|
||||
* @sub: Sub type
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/sparse-keymap.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -16,11 +17,12 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define LED_DEVICE(_name, max) struct led_classdev _name = { \
|
||||
#define LED_DEVICE(_name, max, flag) struct led_classdev _name = { \
|
||||
.name = __stringify(_name), \
|
||||
.max_brightness = max, \
|
||||
.brightness_set = _name##_set, \
|
||||
.brightness_get = _name##_get, \
|
||||
.flags = flag, \
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Matan Ziv-Av");
|
||||
@ -69,9 +71,13 @@ static u32 inited;
|
||||
#define INIT_INPUT_ACPI 0x04
|
||||
#define INIT_SPARSE_KEYMAP 0x80
|
||||
|
||||
static int battery_limit_use_wmbb;
|
||||
static struct led_classdev kbd_backlight;
|
||||
static enum led_brightness get_kbd_backlight_level(void);
|
||||
|
||||
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, 0x74, {KEY_F21} }, /* 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
|
||||
@ -214,10 +220,16 @@ static void wmi_notify(u32 value, void *context)
|
||||
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);
|
||||
if (eventcode == 0x10000000) {
|
||||
led_classdev_notify_brightness_hw_changed(
|
||||
&kbd_backlight, get_kbd_backlight_level());
|
||||
} else {
|
||||
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,
|
||||
@ -461,7 +473,10 @@ static ssize_t battery_care_limit_store(struct device *dev,
|
||||
if (value == 100 || value == 80) {
|
||||
union acpi_object *r;
|
||||
|
||||
r = lg_wmab(WM_BATT_LIMIT, WM_SET, value);
|
||||
if (battery_limit_use_wmbb)
|
||||
r = lg_wmbb(WMBB_BATT_LIMIT, WM_SET, value);
|
||||
else
|
||||
r = lg_wmab(WM_BATT_LIMIT, WM_SET, value);
|
||||
if (!r)
|
||||
return -EIO;
|
||||
|
||||
@ -479,16 +494,29 @@ static ssize_t battery_care_limit_show(struct device *dev,
|
||||
unsigned int status;
|
||||
union acpi_object *r;
|
||||
|
||||
r = lg_wmab(WM_BATT_LIMIT, WM_GET, 0);
|
||||
if (!r)
|
||||
return -EIO;
|
||||
if (battery_limit_use_wmbb) {
|
||||
r = lg_wmbb(WMBB_BATT_LIMIT, WM_GET, 0);
|
||||
if (!r)
|
||||
return -EIO;
|
||||
|
||||
if (r->type != ACPI_TYPE_INTEGER) {
|
||||
kfree(r);
|
||||
return -EIO;
|
||||
if (r->type != ACPI_TYPE_BUFFER) {
|
||||
kfree(r);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
status = r->buffer.pointer[0x10];
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
status = r->integer.value;
|
||||
kfree(r);
|
||||
if (status != 80 && status != 100)
|
||||
status = 0;
|
||||
@ -529,7 +557,7 @@ 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 LED_DEVICE(tpad_led, 1, 0);
|
||||
|
||||
static void kbd_backlight_set(struct led_classdev *cdev,
|
||||
enum led_brightness brightness)
|
||||
@ -546,7 +574,7 @@ static void kbd_backlight_set(struct led_classdev *cdev,
|
||||
kfree(r);
|
||||
}
|
||||
|
||||
static enum led_brightness kbd_backlight_get(struct led_classdev *cdev)
|
||||
static enum led_brightness get_kbd_backlight_level(void)
|
||||
{
|
||||
union acpi_object *r;
|
||||
int val;
|
||||
@ -577,7 +605,12 @@ static enum led_brightness kbd_backlight_get(struct led_classdev *cdev)
|
||||
return val;
|
||||
}
|
||||
|
||||
static LED_DEVICE(kbd_backlight, 255);
|
||||
static enum led_brightness kbd_backlight_get(struct led_classdev *cdev)
|
||||
{
|
||||
return get_kbd_backlight_level();
|
||||
}
|
||||
|
||||
static LED_DEVICE(kbd_backlight, 255, LED_BRIGHT_HW_CHANGED);
|
||||
|
||||
static void wmi_input_destroy(void)
|
||||
{
|
||||
@ -602,6 +635,8 @@ static struct platform_driver pf_driver = {
|
||||
static int acpi_add(struct acpi_device *device)
|
||||
{
|
||||
int ret;
|
||||
const char *product;
|
||||
int year = 2017;
|
||||
|
||||
if (pf_device)
|
||||
return 0;
|
||||
@ -619,6 +654,42 @@ static int acpi_add(struct acpi_device *device)
|
||||
pr_err("unable to register platform device\n");
|
||||
goto out_platform_registered;
|
||||
}
|
||||
product = dmi_get_system_info(DMI_PRODUCT_NAME);
|
||||
if (strlen(product) > 4)
|
||||
switch (product[4]) {
|
||||
case '5':
|
||||
case '6':
|
||||
year = 2016;
|
||||
break;
|
||||
case '7':
|
||||
year = 2017;
|
||||
break;
|
||||
case '8':
|
||||
year = 2018;
|
||||
break;
|
||||
case '9':
|
||||
year = 2019;
|
||||
break;
|
||||
case '0':
|
||||
if (strlen(product) > 5)
|
||||
switch (product[5]) {
|
||||
case 'N':
|
||||
year = 2020;
|
||||
break;
|
||||
case 'P':
|
||||
year = 2021;
|
||||
break;
|
||||
default:
|
||||
year = 2022;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
year = 2019;
|
||||
}
|
||||
pr_info("product: %s year: %d\n", product, year);
|
||||
|
||||
if (year >= 2019)
|
||||
battery_limit_use_wmbb = 1;
|
||||
|
||||
ret = sysfs_create_group(&pf_device->dev.kobj, &dev_attribute_group);
|
||||
if (ret)
|
||||
|
230
drivers/platform/x86/meraki-mx100.c
Normal file
230
drivers/platform/x86/meraki-mx100.c
Normal file
@ -0,0 +1,230 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/*
|
||||
* Cisco Meraki MX100 (Tinkerbell) board platform driver
|
||||
*
|
||||
* Based off of arch/x86/platform/meraki/tink.c from the
|
||||
* Meraki GPL release meraki-firmware-sources-r23-20150601
|
||||
*
|
||||
* Format inspired by platform/x86/pcengines-apuv2.c
|
||||
*
|
||||
* Copyright (C) 2021 Chris Blake <chrisrblake93@gmail.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define TINK_GPIO_DRIVER_NAME "gpio_ich"
|
||||
|
||||
/* LEDs */
|
||||
static const struct gpio_led tink_leds[] = {
|
||||
{
|
||||
.name = "mx100:green:internet",
|
||||
.default_trigger = "default-on",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan2",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan3",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan4",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan5",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan6",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan7",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan8",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan9",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan10",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:lan11",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:ha",
|
||||
},
|
||||
{
|
||||
.name = "mx100:orange:ha",
|
||||
},
|
||||
{
|
||||
.name = "mx100:green:usb",
|
||||
},
|
||||
{
|
||||
.name = "mx100:orange:usb",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct gpio_led_platform_data tink_leds_pdata = {
|
||||
.num_leds = ARRAY_SIZE(tink_leds),
|
||||
.leds = tink_leds,
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table tink_leds_table = {
|
||||
.dev_id = "leds-gpio",
|
||||
.table = {
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 11,
|
||||
NULL, 0, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 18,
|
||||
NULL, 1, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 20,
|
||||
NULL, 2, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 22,
|
||||
NULL, 3, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 23,
|
||||
NULL, 4, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 32,
|
||||
NULL, 5, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 34,
|
||||
NULL, 6, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 35,
|
||||
NULL, 7, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 36,
|
||||
NULL, 8, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 37,
|
||||
NULL, 9, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 48,
|
||||
NULL, 10, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 16,
|
||||
NULL, 11, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 7,
|
||||
NULL, 12, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 21,
|
||||
NULL, 13, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 19,
|
||||
NULL, 14, GPIO_ACTIVE_LOW),
|
||||
{} /* Terminating entry */
|
||||
}
|
||||
};
|
||||
|
||||
/* Reset Button */
|
||||
static struct gpio_keys_button tink_buttons[] = {
|
||||
{
|
||||
.desc = "Reset",
|
||||
.type = EV_KEY,
|
||||
.code = KEY_RESTART,
|
||||
.active_low = 1,
|
||||
.debounce_interval = 100,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct gpio_keys_platform_data tink_buttons_pdata = {
|
||||
.buttons = tink_buttons,
|
||||
.nbuttons = ARRAY_SIZE(tink_buttons),
|
||||
.poll_interval = 20,
|
||||
.rep = 0,
|
||||
.name = "mx100-keys",
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table tink_keys_table = {
|
||||
.dev_id = "gpio-keys-polled",
|
||||
.table = {
|
||||
GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 60,
|
||||
NULL, 0, GPIO_ACTIVE_LOW),
|
||||
{} /* Terminating entry */
|
||||
}
|
||||
};
|
||||
|
||||
/* Board setup */
|
||||
static const struct dmi_system_id tink_systems[] __initconst = {
|
||||
{
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Cisco"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MX100-HW"),
|
||||
},
|
||||
},
|
||||
{} /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(dmi, tink_systems);
|
||||
|
||||
static struct platform_device *tink_leds_pdev;
|
||||
static struct platform_device *tink_keys_pdev;
|
||||
|
||||
static struct platform_device * __init tink_create_dev(
|
||||
const char *name, const void *pdata, size_t sz)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
|
||||
pdev = platform_device_register_data(NULL,
|
||||
name, PLATFORM_DEVID_NONE, pdata, sz);
|
||||
if (IS_ERR(pdev))
|
||||
pr_err("failed registering %s: %ld\n", name, PTR_ERR(pdev));
|
||||
|
||||
return pdev;
|
||||
}
|
||||
|
||||
static int __init tink_board_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!dmi_first_match(tink_systems))
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* We need to make sure that GPIO60 isn't set to native mode as is default since it's our
|
||||
* Reset Button. To do this, write to GPIO_USE_SEL2 to have GPIO60 set to GPIO mode.
|
||||
* This is documented on page 1609 of the PCH datasheet, order number 327879-005US
|
||||
*/
|
||||
outl(inl(0x530) | BIT(28), 0x530);
|
||||
|
||||
gpiod_add_lookup_table(&tink_leds_table);
|
||||
gpiod_add_lookup_table(&tink_keys_table);
|
||||
|
||||
tink_leds_pdev = tink_create_dev("leds-gpio",
|
||||
&tink_leds_pdata, sizeof(tink_leds_pdata));
|
||||
if (IS_ERR(tink_leds_pdev)) {
|
||||
ret = PTR_ERR(tink_leds_pdev);
|
||||
goto err;
|
||||
}
|
||||
|
||||
tink_keys_pdev = tink_create_dev("gpio-keys-polled",
|
||||
&tink_buttons_pdata, sizeof(tink_buttons_pdata));
|
||||
if (IS_ERR(tink_keys_pdev)) {
|
||||
ret = PTR_ERR(tink_keys_pdev);
|
||||
platform_device_unregister(tink_leds_pdev);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
gpiod_remove_lookup_table(&tink_keys_table);
|
||||
gpiod_remove_lookup_table(&tink_leds_table);
|
||||
return ret;
|
||||
}
|
||||
module_init(tink_board_init);
|
||||
|
||||
static void __exit tink_board_exit(void)
|
||||
{
|
||||
platform_device_unregister(tink_keys_pdev);
|
||||
platform_device_unregister(tink_leds_pdev);
|
||||
gpiod_remove_lookup_table(&tink_keys_table);
|
||||
gpiod_remove_lookup_table(&tink_leds_table);
|
||||
}
|
||||
module_exit(tink_board_exit);
|
||||
|
||||
MODULE_AUTHOR("Chris Blake <chrisrblake93@gmail.com>");
|
||||
MODULE_DESCRIPTION("Cisco Meraki MX100 Platform Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:meraki-mx100");
|
@ -20,6 +20,10 @@
|
||||
#include "firmware_attributes_class.h"
|
||||
#include "think-lmi.h"
|
||||
|
||||
static bool debug_support;
|
||||
module_param(debug_support, bool, 0444);
|
||||
MODULE_PARM_DESC(debug_support, "Enable debug command support");
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* Lenovo_BiosSetting
|
||||
@ -116,6 +120,14 @@
|
||||
*/
|
||||
#define LENOVO_GET_BIOS_SELECTIONS_GUID "7364651A-132F-4FE7-ADAA-40C6C7EE2E3B"
|
||||
|
||||
/*
|
||||
* Name:
|
||||
* Lenovo_DebugCmdGUID
|
||||
* Description
|
||||
* Debug entry GUID method for entering debug commands to the BIOS
|
||||
*/
|
||||
#define LENOVO_DEBUG_CMD_GUID "7FF47003-3B6C-4E5E-A227-E979824A85D1"
|
||||
|
||||
#define TLMI_POP_PWD (1 << 0)
|
||||
#define TLMI_PAP_PWD (1 << 1)
|
||||
#define to_tlmi_pwd_setting(kobj) container_of(kobj, struct tlmi_pwd_setting, kobj)
|
||||
@ -660,6 +672,64 @@ static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *
|
||||
|
||||
static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
|
||||
|
||||
/* ---- Debug interface--------------------------------------------------------- */
|
||||
static ssize_t debug_cmd_store(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
char *set_str = NULL, *new_setting = NULL;
|
||||
char *auth_str = NULL;
|
||||
char *p;
|
||||
int ret;
|
||||
|
||||
if (!tlmi_priv.can_debug_cmd)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
new_setting = kstrdup(buf, GFP_KERNEL);
|
||||
if (!new_setting)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Strip out CR if one is present */
|
||||
p = strchrnul(new_setting, '\n');
|
||||
*p = '\0';
|
||||
|
||||
if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
|
||||
auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
|
||||
tlmi_priv.pwd_admin->password,
|
||||
encoding_options[tlmi_priv.pwd_admin->encoding],
|
||||
tlmi_priv.pwd_admin->kbdlang);
|
||||
if (!auth_str) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (auth_str)
|
||||
set_str = kasprintf(GFP_KERNEL, "%s,%s", new_setting, auth_str);
|
||||
else
|
||||
set_str = kasprintf(GFP_KERNEL, "%s;", new_setting);
|
||||
if (!set_str) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = tlmi_simple_call(LENOVO_DEBUG_CMD_GUID, set_str);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (!ret && !tlmi_priv.pending_changes) {
|
||||
tlmi_priv.pending_changes = true;
|
||||
/* let userland know it may need to check reboot pending again */
|
||||
kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
|
||||
}
|
||||
out:
|
||||
kfree(auth_str);
|
||||
kfree(set_str);
|
||||
kfree(new_setting);
|
||||
return ret ?: count;
|
||||
}
|
||||
|
||||
static struct kobj_attribute debug_cmd = __ATTR_WO(debug_cmd);
|
||||
|
||||
/* ---- Initialisation --------------------------------------------------------- */
|
||||
static void tlmi_release_attr(void)
|
||||
{
|
||||
@ -673,6 +743,8 @@ static void tlmi_release_attr(void)
|
||||
}
|
||||
}
|
||||
sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr);
|
||||
if (tlmi_priv.can_debug_cmd && debug_support)
|
||||
sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr);
|
||||
kset_unregister(tlmi_priv.attribute_kset);
|
||||
|
||||
/* Authentication structures */
|
||||
@ -737,6 +809,11 @@ static int tlmi_sysfs_init(void)
|
||||
if (ret)
|
||||
goto fail_create_attr;
|
||||
|
||||
if (tlmi_priv.can_debug_cmd && debug_support) {
|
||||
ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr);
|
||||
if (ret)
|
||||
goto fail_create_attr;
|
||||
}
|
||||
/* Create authentication entries */
|
||||
tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL,
|
||||
&tlmi_priv.class_dev->kobj);
|
||||
@ -793,6 +870,9 @@ static int tlmi_analyze(void)
|
||||
if (wmi_has_guid(LENOVO_BIOS_PASSWORD_SETTINGS_GUID))
|
||||
tlmi_priv.can_get_password_settings = true;
|
||||
|
||||
if (wmi_has_guid(LENOVO_DEBUG_CMD_GUID))
|
||||
tlmi_priv.can_debug_cmd = true;
|
||||
|
||||
/*
|
||||
* Try to find the number of valid settings of this machine
|
||||
* and use it to create sysfs attributes.
|
||||
|
@ -61,6 +61,7 @@ struct think_lmi {
|
||||
bool can_set_bios_password;
|
||||
bool can_get_password_settings;
|
||||
bool pending_changes;
|
||||
bool can_debug_cmd;
|
||||
|
||||
struct tlmi_attr_setting *setting[TLMI_SETTINGS_COUNT];
|
||||
struct device *class_dev;
|
||||
|
@ -90,3 +90,12 @@ config INTEL_TCC_COOLING
|
||||
Note that, on different platforms, the behavior might be different
|
||||
on how fast the setting takes effect, and how much the CPU frequency
|
||||
is reduced.
|
||||
|
||||
config INTEL_MENLOW
|
||||
tristate "Thermal Management driver for Intel menlow platform"
|
||||
depends on ACPI_THERMAL
|
||||
help
|
||||
ACPI thermal management enhancement driver on
|
||||
Intel Menlow platform.
|
||||
|
||||
If unsure, say N.
|
||||
|
@ -12,3 +12,4 @@ obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
|
||||
obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o
|
||||
obj-$(CONFIG_INTEL_TCC_COOLING) += intel_tcc_cooling.o
|
||||
obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o
|
||||
obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o
|
||||
|
@ -1010,6 +1010,7 @@ struct acpi_resource_i2c_serialbus;
|
||||
#if IS_ENABLED(CONFIG_ACPI)
|
||||
bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
|
||||
struct acpi_resource_i2c_serialbus **i2c);
|
||||
int i2c_acpi_client_count(struct acpi_device *adev);
|
||||
u32 i2c_acpi_find_bus_speed(struct device *dev);
|
||||
struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
|
||||
struct i2c_board_info *info);
|
||||
@ -1020,6 +1021,10 @@ static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline int i2c_acpi_client_count(struct acpi_device *adev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline u32 i2c_acpi_find_bus_speed(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
|
@ -61,6 +61,7 @@
|
||||
#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075
|
||||
|
||||
/* Misc */
|
||||
#define ASUS_WMI_DEVID_PANEL_OD 0x00050019
|
||||
#define ASUS_WMI_DEVID_CAMERA 0x00060013
|
||||
#define ASUS_WMI_DEVID_LID_FLIP 0x00060062
|
||||
|
||||
@ -89,6 +90,12 @@
|
||||
/* Keyboard dock */
|
||||
#define ASUS_WMI_DEVID_KBD_DOCK 0x00120063
|
||||
|
||||
/* dgpu on/off */
|
||||
#define ASUS_WMI_DEVID_EGPU 0x00090019
|
||||
|
||||
/* dgpu on/off */
|
||||
#define ASUS_WMI_DEVID_DGPU 0x00090020
|
||||
|
||||
/* DSTS masks */
|
||||
#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
|
||||
#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
|
||||
|
Loading…
Reference in New Issue
Block a user