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

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

Pull x86 platform driver updates from Andy Shevchenko:

 - Fix for improper handling of fan_boost_mode in sysfs for ASUS
   laptops.

 - On newer ASUS laptops the 1st battery is named differently, here is a
   fix.

 - Fix Lex 2I385SW to allow both network cards to be used.

 - The power integrated circuit driver for Surface 3 has been added.

 - Refactor and clean up of Intel PMC driver and enable it on Intel
   Jasper Lake.

 - Clean up of Dell RBU driver.

 - Big update for Intel Speed Select technology support tool and driver.

* tag 'platform-drivers-x86-v5.7-1' of git://git.infradead.org/linux-platform-drivers-x86: (75 commits)
  platform/x86: surface3_power: Fix always true condition in mshw0011_space_handler()
  platform/x86: surface3_power: Fix Kconfig section ordering
  platform/x86: surface3_power: Add missed headers
  platform/x86: surface3_power: Reformat GUID assignment
  platform/x86: surface3_power: Drop useless macro ACPI_PTR()
  platform/x86: surface3_power: Prefix POLL_INTERVAL with SURFACE_3
  platform/x86: surface3_power: Simplify mshw0011_adp_psr() to one liner
  platform/x86: surface3_power: Use dev_err() instead of pr_err()
  platform/x86: surface3_power: Drop unused structure definition
  platform/x86: surface3_power: MSHW0011 rev-eng implementation
  platform/x86: intel_pmc_core: Make pmc_core_substate_res_show() generic
  platform/x86: intel_pmc_core: Make pmc_core_lpm_display() generic for platforms that support sub-states
  tools/power/x86/intel-speed-select: Fix a typo in error message
  tools/power/x86/intel-speed-select: Update version
  tools/power/x86/intel-speed-select: Avoid duplicate Package strings for json
  tools/power/x86/intel-speed-select: Add display for enabled cpus count
  tools/power/x86/intel-speed-select: Print friendly warning for bad command line
  tools/power/x86/intel-speed-select: Fix avx options for turbo-freq feature
  tools/power/x86/intel-speed-select: Improve CLX commands
  tools/power/x86/intel-speed-select: Show error for invalid CPUs in the options
  ...
......@@ -303,8 +303,8 @@ F: drivers/net/ethernet/alteon/acenic*
ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER
M: Peter Kaestle <peter@piie.net>
L: platform-driver-x86@vger.kernel.org
W: http://piie.net/?section=acerhdf
S: Maintained
W: http://piie.net/?section=acerhdf
F: drivers/platform/x86/acerhdf.c
ACER WMI LAPTOP EXTRAS
......@@ -2766,8 +2766,8 @@ ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS
M: Corentin Chary <corentin.chary@gmail.com>
L: acpi4asus-user@lists.sourceforge.net
L: platform-driver-x86@vger.kernel.org
W: http://acpi4asus.sf.net
S: Maintained
W: http://acpi4asus.sf.net
F: drivers/platform/x86/asus*.c
F: drivers/platform/x86/eeepc*.c
......@@ -4745,26 +4745,6 @@ S: Maintained
F: drivers/media/platform/sunxi/sun8i-di/
F: Documentation/devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml
DELL SMBIOS DRIVER
M: Pali Rohár <pali.rohar@gmail.com>
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell-smbios.*
DELL SMBIOS SMM DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell-smbios-smm.c
DELL SMBIOS WMI DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell-smbios-wmi.c
F: tools/wmi/dell-smbios-example.c
DEFZA FDDI NETWORK DRIVER
M: "Maciej W. Rozycki" <macro@linux-mips.org>
S: Maintained
......@@ -4787,17 +4767,37 @@ M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained
F: drivers/platform/x86/dell-rbtn.*
DELL LAPTOP SMM DRIVER
M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained
F: drivers/hwmon/dell-smm-hwmon.c
F: include/uapi/linux/i8k.h
DELL REMOTE BIOS UPDATE DRIVER
M: Stuart Hayes <stuart.w.hayes@gmail.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell_rbu.c
DELL LAPTOP SMM DRIVER
DELL SMBIOS DRIVER
M: Pali Rohár <pali.rohar@gmail.com>
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/hwmon/dell-smm-hwmon.c
F: include/uapi/linux/i8k.h
F: drivers/platform/x86/dell-smbios.*
DELL SMBIOS SMM DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell-smbios-smm.c
DELL SMBIOS WMI DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell-smbios-wmi.c
F: tools/wmi/dell-smbios-example.c
DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
M: Stuart Hayes <stuart.w.hayes@gmail.com>
......@@ -4806,17 +4806,17 @@ S: Maintained
F: Documentation/driver-api/dcdbas.rst
F: drivers/platform/x86/dcdbas.*
DELL WMI DESCRIPTOR DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
S: Maintained
F: drivers/platform/x86/dell-wmi-descriptor.c
DELL WMI NOTIFICATIONS DRIVER
M: Matthew Garrett <mjg59@srcf.ucam.org>
M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained
F: drivers/platform/x86/dell-wmi.c
DELL WMI DESCRIPTOR DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
S: Maintained
F: drivers/platform/x86/dell-wmi-descriptor.c
DELTA ST MEDIA DRIVER
M: Hugues Fruchet <hugues.fruchet@st.com>
L: linux-media@vger.kernel.org
......@@ -7375,8 +7375,8 @@ F: drivers/media/usb/hackrf/
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
M: Frank Seidel <frank@f-seidel.de>
L: platform-driver-x86@vger.kernel.org
W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
S: Maintained
W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
F: drivers/platform/x86/hdaps.c
HARDWARE MONITORING
......@@ -8119,15 +8119,15 @@ F: drivers/ide/ide-cd*
IDEAPAD LAPTOP EXTRAS DRIVER
M: Ike Panhc <ike.pan@canonical.com>
L: platform-driver-x86@vger.kernel.org
W: http://launchpad.net/ideapad-laptop
S: Maintained
W: http://launchpad.net/ideapad-laptop
F: drivers/platform/x86/ideapad-laptop.c
IDEAPAD LAPTOP SLIDEBAR DRIVER
M: Andrey Moiseev <o2g.org.ru@gmail.com>
L: linux-input@vger.kernel.org
W: https://github.com/o2genum/ideapad-slidebar
S: Maintained
W: https://github.com/o2genum/ideapad-slidebar
F: drivers/input/misc/ideapad_slidebar.c
IDT VersaClock 5 CLOCK DRIVER
......@@ -8593,8 +8593,8 @@ F: samples/mei/*
INTEL MENLOW THERMAL DRIVER
M: Sujith Thomas <sujith.thomas@intel.com>
L: platform-driver-x86@vger.kernel.org
W: https://01.org/linux-acpi
S: Supported
W: https://01.org/linux-acpi
F: drivers/platform/x86/intel_menlow.c
INTEL MIC DRIVERS (mic)
......@@ -8624,10 +8624,10 @@ INTEL PMC/P-Unit IPC DRIVER
M: Zha Qipeng<qipeng.zha@intel.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/intel_pmc_ipc.c
F: drivers/platform/x86/intel_punit_ipc.c
F: arch/x86/include/asm/intel_pmc_ipc.h
F: arch/x86/include/asm/intel_punit_ipc.h
F: drivers/platform/x86/intel_pmc_ipc.c
F: drivers/platform/x86/intel_punit_ipc.c
INTEL PMIC GPIO DRIVERS
M: Andy Shevchenko <andy@kernel.org>
......@@ -8672,8 +8672,8 @@ 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: tools/power/x86/intel-speed-select/
F: include/uapi/linux/isst_if.h
F: tools/power/x86/intel-speed-select/
INTEL STRATIX10 FIRMWARE DRIVERS
M: Richard Gong <richard.gong@linux.intel.com>
......@@ -15626,8 +15626,8 @@ F: include/linux/memstick.h
SONY VAIO CONTROL DEVICE DRIVER
M: Mattia Dongili <malattia@linux.it>
L: platform-driver-x86@vger.kernel.org
W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers
S: Maintained
W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers
F: Documentation/admin-guide/laptops/sony-laptop.rst
F: drivers/char/sonypi.c
F: drivers/platform/x86/sony-laptop.c
......@@ -16602,10 +16602,10 @@ THINKPAD ACPI EXTRAS DRIVER
M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
L: ibm-acpi-devel@lists.sourceforge.net
L: platform-driver-x86@vger.kernel.org
S: Maintained
W: http://ibm-acpi.sourceforge.net
W: http://thinkwiki.org/wiki/Ibm-acpi
T: git git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
S: Maintained
F: drivers/platform/x86/thinkpad_acpi.c
THUNDERBOLT DRIVER
......@@ -18250,10 +18250,10 @@ X86 PLATFORM DRIVERS
M: Darren Hart <dvhart@infradead.org>
M: Andy Shevchenko <andy@infradead.org>
L: platform-driver-x86@vger.kernel.org
T: git git://git.infradead.org/linux-platform-drivers-x86.git
S: Odd Fixes
F: drivers/platform/x86/
T: git git://git.infradead.org/linux-platform-drivers-x86.git
F: drivers/platform/olpc/
F: drivers/platform/x86/
X86 PLATFORM DRIVERS - ARCH
R: Darren Hart <dvhart@infradead.org>
......
此差异已折叠。
......@@ -3,106 +3,146 @@
# Makefile for linux/drivers/platform/x86
# x86 Platform-Specific Drivers
#
# Windows Management Interface
obj-$(CONFIG_ACPI_WMI) += wmi.o
obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o
# WMI drivers
obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o
obj-$(CONFIG_HUAWEI_WMI) += huawei-wmi.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
# Acer
obj-$(CONFIG_ACERHDF) += acerhdf.o
obj-$(CONFIG_ACER_WIRELESS) += acer-wireless.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
# Apple
obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
# ASUS
obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
obj-$(CONFIG_ASUS_WIRELESS) += asus-wireless.o
obj-$(CONFIG_ASUS_WMI) += asus-wmi.o
obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o
obj-$(CONFIG_ASUS_WIRELESS) += asus-wireless.o
obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o
obj-$(CONFIG_LG_LAPTOP) += lg-laptop.o
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_DCDBAS) += dcdbas.o
obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o
dell-smbios-objs := dell-smbios-base.o
# Dell
obj-$(CONFIG_DCDBAS) += dcdbas.o
obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o
dell-smbios-objs := dell-smbios-base.o
dell-smbios-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o
dell-smbios-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o
obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
obj-$(CONFIG_DELL_WMI) += dell-wmi.o
obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o
obj-$(CONFIG_DELL_RBU) += dell_rbu.o
obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
obj-$(CONFIG_DELL_WMI) += dell-wmi.o
obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o
obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o
obj-$(CONFIG_DELL_RBU) += dell_rbu.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_ACER_WIRELESS) += acer-wireless.o
obj-$(CONFIG_ACERHDF) += acerhdf.o
obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
# Fujitsu
obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o
obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o
obj-$(CONFIG_FUJITSU_TABLET) += fujitsu-tablet.o
# GPD
obj-$(CONFIG_GPD_POCKET_FAN) += gpd-pocket-fan.o
# Hewlett Packard
obj-$(CONFIG_HP_ACCEL) += hp_accel.o
obj-$(CONFIG_HP_WIRELESS) += hp-wireless.o
obj-$(CONFIG_HP_WMI) += hp-wmi.o
obj-$(CONFIG_HUAWEI_WMI) += huawei-wmi.o
obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o
obj-$(CONFIG_GPD_POCKET_FAN) += gpd-pocket-fan.o
obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
# IBM Thinkpad and Lenovo
obj-$(CONFIG_IBM_RTL) += ibm_rtl.o
obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o
obj-$(CONFIG_FUJITSU_TABLET) += fujitsu-tablet.o
obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o
obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o
obj-$(CONFIG_ACPI_WMI) += wmi.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
# Intel
obj-$(CONFIG_INTEL_ATOMISP2_PM) += intel_atomisp2_pm.o
obj-$(CONFIG_INTEL_CHT_INT33FE) += intel_cht_int33fe.o
intel_cht_int33fe-objs := intel_cht_int33fe_common.o \
intel_cht_int33fe_typec.o \
intel_cht_int33fe_microb.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
# Microsoft
obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o
obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o
obj-$(CONFIG_SURFACE_3_POWER_OPREGION) += surface3_power.o
obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o
# MSI
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_MSI_WMI) += msi-wmi.o
obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o
obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o
obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o
obj-$(CONFIG_INTEL_WMI_THUNDERBOLT) += intel-wmi-thunderbolt.o
obj-$(CONFIG_XIAOMI_WMI) += xiaomi-wmi.o
# toshiba_acpi must link after wmi to ensure that wmi devices are found
# before toshiba_acpi initializes
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
# OLPC
obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o
obj-$(CONFIG_XO1_RFKILL) += xo1-rfkill.o
# PC Engines
obj-$(CONFIG_PCENGINES_APU2) += pcengines-apuv2.o
# Samsung
obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o
obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
# Toshiba
obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o
obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o
obj-$(CONFIG_TOSHIBA_WMI) += toshiba-wmi.o
obj-$(CONFIG_INTEL_CHT_INT33FE) += intel_cht_int33fe.o
intel_cht_int33fe-objs := intel_cht_int33fe_common.o \
intel_cht_int33fe_typec.o \
intel_cht_int33fe_microb.o
obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
obj-$(CONFIG_INTEL_HID_EVENT) += intel-hid.o
obj-$(CONFIG_INTEL_VBTN) += intel-vbtn.o
obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
obj-$(CONFIG_INTEL_IPS) += intel_ips.o
obj-$(CONFIG_XO1_RFKILL) += xo1-rfkill.o
obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o
obj-$(CONFIG_IBM_RTL) += ibm_rtl.o
obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o
obj-$(CONFIG_MXM_WMI) += mxm-wmi.o
obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o
obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
obj-$(CONFIG_INTEL_RST) += intel-rst.o
obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o
obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o
obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o
obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o
obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o
obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o
obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o
# toshiba_acpi must link after wmi to ensure that wmi devices are found
# before toshiba_acpi initializes
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
# Laptop drivers
obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_LG_LAPTOP) += lg-laptop.o
obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
obj-$(CONFIG_SYSTEM76_ACPI) += system76_acpi.o
obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
# Platform drivers
obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o
obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.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_TELEMETRY) += intel_telemetry_core.o \
intel_telemetry_pltdrv.o \
intel_telemetry_debugfs.o
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o intel_pmc_core_pltdrv.o
obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o
obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o
obj-$(CONFIG_INTEL_MRFLD_PWRBTN) += intel_mrfld_pwrbtn.o
obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o
obj-$(CONFIG_INTEL_ATOMISP2_PM) += intel_atomisp2_pm.o
obj-$(CONFIG_PCENGINES_APU2) += pcengines-apuv2.o
obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += intel_speed_select_if/
obj-$(CONFIG_SYSTEM76_ACPI) += system76_acpi.o
obj-$(CONFIG_INTEL_UNCORE_FREQ_CONTROL) += intel-uncore-frequency.o
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o intel_pmc_core_pltdrv.o
obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o
obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o
obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.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
......@@ -426,8 +426,11 @@ static int asus_wmi_battery_add(struct power_supply *battery)
{
/* The WMI method does not provide a way to specific a battery, so we
* just assume it is the first battery.
* Note: On some newer ASUS laptops (Zenbook UM431DA), the primary/first
* battery is named BATT.
*/
if (strcmp(battery->desc->name, "BAT0") != 0)
if (strcmp(battery->desc->name, "BAT0") != 0 &&
strcmp(battery->desc->name, "BATT") != 0)
return -ENODEV;
if (device_create_file(&battery->dev,
......@@ -1719,7 +1722,7 @@ static ssize_t fan_boost_mode_store(struct device *dev,
asus->fan_boost_mode = new_mode;
fan_boost_mode_write(asus);
return result;
return count;
}
// Fan boost mode: 0 - normal, 1 - overboost, 2 - silent
......
......@@ -26,6 +26,9 @@
*
* See Documentation/admin-guide/dell_rbu.rst for more info.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
......@@ -61,13 +64,11 @@ static struct _rbu_data {
static char image_type[MAX_IMAGE_LENGTH + 1] = "mono";
module_param_string(image_type, image_type, sizeof (image_type), 0);
MODULE_PARM_DESC(image_type,
"BIOS image type. choose- mono or packet or init");
MODULE_PARM_DESC(image_type, "BIOS image type. choose- mono or packet or init");
static unsigned long allocation_floor = 0x100000;
module_param(allocation_floor, ulong, 0644);
MODULE_PARM_DESC(allocation_floor,
"Minimum address for allocations when using Packet mode");
MODULE_PARM_DESC(allocation_floor, "Minimum address for allocations when using Packet mode");
struct packet_data {
struct list_head list;
......@@ -100,10 +101,10 @@ static int create_packet(void *data, size_t length)
void *packet_data_temp_buf = NULL;
unsigned int idx = 0;
pr_debug("create_packet: entry \n");
pr_debug("entry\n");
if (!rbu_data.packetsize) {
pr_debug("create_packet: packetsize not specified\n");
pr_debug("packetsize not specified\n");
retval = -EINVAL;
goto out_noalloc;
}
......@@ -113,9 +114,7 @@ static int create_packet(void *data, size_t length)
newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL);
if (!newpacket) {
printk(KERN_WARNING
"dell_rbu:%s: failed to allocate new "
"packet\n", __func__);
pr_warn("failed to allocate new packet\n");
retval = -ENOMEM;
spin_lock(&rbu_data.lock);
goto out_noalloc;
......@@ -134,17 +133,12 @@ static int create_packet(void *data, size_t length)
* due to BIOS errata. This shouldn't be used for higher floors
* or you will run out of mem trying to allocate the array.
*/
packet_array_size = max(
(unsigned int)(allocation_floor / rbu_data.packetsize),
(unsigned int)1);
packet_array_size = max_t(unsigned int, allocation_floor / rbu_data.packetsize, 1);
invalid_addr_packet_array = kcalloc(packet_array_size, sizeof(void *),
GFP_KERNEL);
if (!invalid_addr_packet_array) {
printk(KERN_WARNING
"dell_rbu:%s: failed to allocate "
"invalid_addr_packet_array \n",
__func__);
pr_warn("failed to allocate invalid_addr_packet_array\n");
retval = -ENOMEM;
spin_lock(&rbu_data.lock);
goto out_alloc_packet;
......@@ -154,9 +148,7 @@ static int create_packet(void *data, size_t length)
packet_data_temp_buf = (unsigned char *)
__get_free_pages(GFP_KERNEL, ordernum);
if (!packet_data_temp_buf) {
printk(KERN_WARNING
"dell_rbu:%s: failed to allocate new "
"packet\n", __func__);
pr_warn("failed to allocate new packet\n");
retval = -ENOMEM;
spin_lock(&rbu_data.lock);
goto out_alloc_packet_array;
......@@ -164,7 +156,7 @@ static int create_packet(void *data, size_t length)
if ((unsigned long)virt_to_phys(packet_data_temp_buf)
< allocation_floor) {
pr_debug("packet 0x%lx below floor at 0x%lx.\n",
pr_debug("packet 0x%lx below floor at 0x%lx\n",
(unsigned long)virt_to_phys(
packet_data_temp_buf),
allocation_floor);
......@@ -181,7 +173,7 @@ static int create_packet(void *data, size_t length)
newpacket->data = packet_data_temp_buf;
pr_debug("create_packet: newpacket at physical addr %lx\n",
pr_debug("newpacket at physical addr %lx\n",
(unsigned long)virt_to_phys(newpacket->data));
/* packets may not have fixed size */
......@@ -195,16 +187,14 @@ static int create_packet(void *data, size_t length)
memcpy(newpacket->data, data, length);
pr_debug("create_packet: exit \n");
pr_debug("exit\n");
out_alloc_packet_array:
/* always free packet array */
for (;idx>0;idx--) {
pr_debug("freeing unused packet below floor 0x%lx.\n",
(unsigned long)virt_to_phys(
invalid_addr_packet_array[idx-1]));
free_pages((unsigned long)invalid_addr_packet_array[idx-1],
ordernum);
while (idx--) {
pr_debug("freeing unused packet below floor 0x%lx\n",
(unsigned long)virt_to_phys(invalid_addr_packet_array[idx]));
free_pages((unsigned long)invalid_addr_packet_array[idx], ordernum);
}
kfree(invalid_addr_packet_array);
......@@ -224,10 +214,9 @@ static int packetize_data(const u8 *data, size_t length)
int packet_length;
u8 *temp;
u8 *end = (u8 *) data + length;
pr_debug("packetize_data: data length %zd\n", length);
pr_debug("data length %zd\n", length);
if (!rbu_data.packetsize) {
printk(KERN_WARNING
"dell_rbu: packetsize not specified\n");
pr_warn("packetsize not specified\n");
return -EIO;
}
......@@ -255,15 +244,13 @@ static int packetize_data(const u8 *data, size_t length)
return rc;
}
static int do_packet_read(char *data, struct list_head *ptemp_list,
static int do_packet_read(char *data, struct packet_data *newpacket,
int length, int bytes_read, int *list_read_count)
{
void *ptemp_buf;
struct packet_data *newpacket = NULL;
int bytes_copied = 0;
int j = 0;
newpacket = list_entry(ptemp_list, struct packet_data, list);
*list_read_count += newpacket->length;
if (*list_read_count > bytes_read) {
......@@ -291,7 +278,7 @@ static int do_packet_read(char *data, struct list_head *ptemp_list,
static int packet_read_list(char *data, size_t * pread_length)
{
struct list_head *ptemp_list;
struct packet_data *newpacket;
int temp_count = 0;
int bytes_copied = 0;
int bytes_read = 0;
......@@ -305,9 +292,8 @@ static int packet_read_list(char *data, size_t * pread_length)
remaining_bytes = *pread_length;
bytes_read = rbu_data.packet_read_count;
ptemp_list = (&packet_data_head.list)->next;
while (!list_empty(ptemp_list)) {
bytes_copied = do_packet_read(pdest, ptemp_list,
list_for_each_entry(newpacket, (&packet_data_head.list)->next, list) {
bytes_copied = do_packet_read(pdest, newpacket,
remaining_bytes, bytes_read, &temp_count);
remaining_bytes -= bytes_copied;
bytes_read += bytes_copied;
......@@ -318,8 +304,6 @@ static int packet_read_list(char *data, size_t * pread_length)
*/
if (remaining_bytes == 0)
break;
ptemp_list = ptemp_list->next;
}
/*finally set the bytes read */
*pread_length = bytes_read - rbu_data.packet_read_count;
......@@ -329,17 +313,11 @@ static int packet_read_list(char *data, size_t * pread_length)
static void packet_empty_list(void)
{
struct list_head *ptemp_list;
struct list_head *pnext_list;
struct packet_data *newpacket;
struct packet_data *newpacket, *tmp;
list_for_each_entry_safe(newpacket, tmp, (&packet_data_head.list)->next, list) {
list_del(&newpacket->list);
ptemp_list = (&packet_data_head.list)->next;
while (!list_empty(ptemp_list)) {
newpacket =
list_entry(ptemp_list, struct packet_data, list);
pnext_list = ptemp_list->next;
list_del(ptemp_list);
ptemp_list = pnext_list;
/*
* zero out the RBU packet memory before freeing
* to make sure there are no stale RBU packets left in memory
......@@ -407,8 +385,7 @@ static int img_update_realloc(unsigned long size)
* check for corruption
*/
if ((size != 0) && (rbu_data.image_update_buffer == NULL)) {
printk(KERN_ERR "dell_rbu:%s: corruption "
"check failed\n", __func__);
pr_err("corruption check failed\n");
return -EINVAL;
}
/*
......@@ -430,8 +407,7 @@ static int img_update_realloc(unsigned long size)
(unsigned char *)__get_free_pages(GFP_DMA32, ordernum);
spin_lock(&rbu_data.lock);
if (!image_update_buffer) {
pr_debug("Not enough memory for image update:"
"size = %ld\n", size);
pr_debug("Not enough memory for image update: size = %ld\n", size);
return -ENOMEM;
}
......@@ -455,15 +431,14 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
/* check to see if we have something to return */
if (rbu_data.num_packets == 0) {
pr_debug("read_packet_data: no packets written\n");
pr_debug("no packets written\n");
retval = -ENOMEM;
goto read_rbu_data_exit;
}
if (pos > rbu_data.imagesize) {
retval = 0;
printk(KERN_WARNING "dell_rbu:read_packet_data: "
"data underrun\n");
pr_warn("data underrun\n");
goto read_rbu_data_exit;
}
......@@ -489,8 +464,7 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
/* check to see if we have something to return */
if ((rbu_data.image_update_buffer == NULL) ||
(rbu_data.bios_image_size == 0)) {
pr_debug("read_rbu_data_mono: image_update_buffer %p ,"
"bios_image_size %lu\n",
pr_debug("image_update_buffer %p, bios_image_size %lu\n",
rbu_data.image_update_buffer,
rbu_data.bios_image_size);
return -ENOMEM;
......@@ -500,9 +474,9 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
rbu_data.image_update_buffer, rbu_data.bios_image_size);
}
static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
static ssize_t data_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
{
ssize_t ret_count = 0;
......@@ -513,11 +487,12 @@ static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj,
else if (!strcmp(image_type, "packet"))
ret_count = read_packet_data(buffer, pos, count);
else
pr_debug("read_rbu_data: invalid image type specified\n");
pr_debug("invalid image type specified\n");
spin_unlock(&rbu_data.lock);
return ret_count;
}
static BIN_ATTR_RO(data, 0);
static void callbackfn_rbu(const struct firmware *fw, void *context)
{
......@@ -548,15 +523,15 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
*/
packet_empty_list();
} else
pr_debug("invalid image type specified.\n");
pr_debug("invalid image type specified\n");
spin_unlock(&rbu_data.lock);
out:
release_firmware(fw);
}
static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
static ssize_t image_type_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
{
int size = 0;
if (!pos)
......@@ -564,9 +539,9 @@ static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
return size;
}
static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
static ssize_t image_type_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
{
int rc = count;
int req_firm_rc = 0;
......@@ -602,9 +577,7 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
&rbu_device->dev, GFP_KERNEL, &context,
callbackfn_rbu);
if (req_firm_rc) {
printk(KERN_ERR
"dell_rbu:%s request_firmware_nowait"
" failed %d\n", __func__, rc);
pr_err("request_firmware_nowait failed %d\n", rc);
rc = -EIO;
} else
rbu_data.entry_created = 1;
......@@ -612,7 +585,7 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
spin_lock(&rbu_data.lock);
}
} else {
printk(KERN_WARNING "dell_rbu: image_type is invalid\n");
pr_warn("image_type is invalid\n");
spin_unlock(&rbu_data.lock);
return -EINVAL;
}
......@@ -624,10 +597,11 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
return rc;
}
static BIN_ATTR_RW(image_type, 0);
static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
static ssize_t packet_size_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
{
int size = 0;
if (!pos) {
......@@ -638,9 +612,9 @@ static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj,
return size;
}
static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
static ssize_t packet_size_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
{
unsigned long temp;
spin_lock(&rbu_data.lock);
......@@ -652,22 +626,17 @@ static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj,
spin_unlock(&rbu_data.lock);
return count;
}
static BIN_ATTR_RW(packet_size, 0);
static struct bin_attribute rbu_data_attr = {
.attr = {.name = "data", .mode = 0444},
.read = read_rbu_data,
};
static struct bin_attribute rbu_image_type_attr = {
.attr = {.name = "image_type", .mode = 0644},
.read = read_rbu_image_type,
.write = write_rbu_image_type,
static struct bin_attribute *rbu_bin_attrs[] = {
&bin_attr_data,
&bin_attr_image_type,
&bin_attr_packet_size,
NULL
};
static struct bin_attribute rbu_packet_size_attr = {
.attr = {.name = "packet_size", .mode = 0644},
.read = read_rbu_packet_size,
.write = write_rbu_packet_size,
static const struct attribute_group rbu_group = {
.bin_attrs = rbu_bin_attrs,
};
static int __init dcdrbu_init(void)
......@@ -678,30 +647,17 @@ static int __init dcdrbu_init(void)
init_packet_head();
rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0);
if (IS_ERR(rbu_device)) {
printk(KERN_ERR
"dell_rbu:%s:platform_device_register_simple "
"failed\n", __func__);
pr_err("platform_device_register_simple failed\n");
return PTR_ERR(rbu_device);
}
rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
rc = sysfs_create_group(&rbu_device->dev.kobj, &rbu_group);
if (rc)
goto out_devreg;
rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
if (rc)
goto out_data;
rc = sysfs_create_bin_file(&rbu_device->dev.kobj,
&rbu_packet_size_attr);
if (rc)
goto out_imtype;
rbu_data.entry_created = 0;
return 0;
out_imtype:
sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
out_data:
sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
out_devreg:
platform_device_unregister(rbu_device);
return rc;
......@@ -713,6 +669,7 @@ static __exit void dcdrbu_exit(void)
packet_empty_list();
img_update_free();
spin_unlock(&rbu_data.lock);
sysfs_remove_group(&rbu_device->dev.kobj, &rbu_group);
platform_device_unregister(rbu_device);
}
......
......@@ -128,7 +128,7 @@ static int gpd_pocket_fan_probe(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(temp_limits); i++) {
if (temp_limits[i] < 20000 || temp_limits[i] > 90000) {
dev_err(&pdev->dev, "Invalid temp-limit %d (must be between 40000 and 70000)\n",
dev_err(&pdev->dev, "Invalid temp-limit %d (must be between 20000 and 90000)\n",
temp_limits[i]);
temp_limits[0] = TEMP_LIMIT0_DEFAULT;
temp_limits[1] = TEMP_LIMIT1_DEFAULT;
......
......@@ -28,7 +28,7 @@ struct i2c_inst_data {
struct i2c_multi_inst_data {
int num_clients;
struct i2c_client *clients[0];
struct i2c_client *clients[];
};
static int i2c_multi_inst_count(struct acpi_resource *ares, void *data)
......
......@@ -23,6 +23,7 @@ static const struct acpi_device_id intel_hid_ids[] = {
{"INT33D5", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
/* In theory, these are HID usages. */
static const struct key_entry intel_hid_keymap[] = {
......@@ -541,7 +542,6 @@ static struct platform_driver intel_hid_pl_driver = {
.probe = intel_hid_probe,
.remove = intel_hid_remove,
};
MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
/*
* Unfortunately, some laptops provide a _HID="INT33D5" device with
......
......@@ -38,6 +38,7 @@
*/
struct uncore_data {
struct kobject kobj;
struct completion kobj_unregister;
u64 stored_uncore_data;
u32 initial_min_freq_khz;
u32 initial_max_freq_khz;
......@@ -52,7 +53,7 @@ static int uncore_max_entries __read_mostly;
/* Storage for uncore data for all instances */
static struct uncore_data *uncore_instances;
/* Root of the all uncore sysfs kobjs */
struct kobject uncore_root_kobj;
struct kobject *uncore_root_kobj;
/* Stores the CPU mask of the target CPUs to use during uncore read/write */
static cpumask_t uncore_cpu_mask;
/* CPU online callback register instance */
......@@ -97,6 +98,9 @@ static int uncore_read_ratio(struct uncore_data *data, unsigned int *min,
u64 cap;
int ret;
if (data->control_cpu < 0)
return -ENXIO;
ret = rdmsrl_on_cpu(data->control_cpu, MSR_UNCORE_RATIO_LIMIT, &cap);
if (ret)
return ret;
......@@ -116,6 +120,11 @@ static int uncore_write_ratio(struct uncore_data *data, unsigned int input,
mutex_lock(&uncore_lock);
if (data->control_cpu < 0) {
ret = -ENXIO;
goto finish_write;
}
input /= UNCORE_FREQ_KHZ_MULTIPLIER;
if (!input || input > 0x7F) {
ret = -EINVAL;
......@@ -217,15 +226,19 @@ static struct attribute *uncore_attrs[] = {
NULL
};
static void uncore_sysfs_entry_release(struct kobject *kobj)
{
struct uncore_data *data = to_uncore_data(kobj);
complete(&data->kobj_unregister);
}
static struct kobj_type uncore_ktype = {
.release = uncore_sysfs_entry_release,
.sysfs_ops = &kobj_sysfs_ops,
.default_attrs = uncore_attrs,
};
static struct kobj_type uncore_root_ktype = {
.sysfs_ops = &kobj_sysfs_ops,
};
/* Caller provides protection */
static struct uncore_data *uncore_get_instance(unsigned int cpu)
{
......@@ -263,8 +276,10 @@ static void uncore_add_die_entry(int cpu)
uncore_read_ratio(data, &data->initial_min_freq_khz,
&data->initial_max_freq_khz);
init_completion(&data->kobj_unregister);
ret = kobject_init_and_add(&data->kobj, &uncore_ktype,
&uncore_root_kobj, str);
uncore_root_kobj, str);
if (!ret) {
data->control_cpu = cpu;
data->valid = true;
......@@ -273,18 +288,15 @@ static void uncore_add_die_entry(int cpu)
mutex_unlock(&uncore_lock);
}
/* Last CPU in this die is offline, so remove sysfs entries */
/* Last CPU in this die is offline, make control cpu invalid */
static void uncore_remove_die_entry(int cpu)
{
struct uncore_data *data;
mutex_lock(&uncore_lock);
data = uncore_get_instance(cpu);
if (data) {
kobject_put(&data->kobj);
if (data)
data->control_cpu = -1;
data->valid = false;
}
mutex_unlock(&uncore_lock);
}
......@@ -384,11 +396,12 @@ static int __init intel_uncore_init(void)
if (!uncore_instances)
return -ENOMEM;
ret = kobject_init_and_add(&uncore_root_kobj, &uncore_root_ktype,
&cpu_subsys.dev_root->kobj,
"intel_uncore_frequency");
if (ret)
uncore_root_kobj = kobject_create_and_add("intel_uncore_frequency",
&cpu_subsys.dev_root->kobj);
if (!uncore_root_kobj) {
ret = -ENOMEM;
goto err_free;
}
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
"platform/x86/uncore-freq:online",
......@@ -408,7 +421,7 @@ static int __init intel_uncore_init(void)
err_rem_state:
cpuhp_remove_state(uncore_hp_state);
err_rem_kobj:
kobject_put(&uncore_root_kobj);
kobject_put(uncore_root_kobj);
err_free:
kfree(uncore_instances);
......@@ -423,10 +436,12 @@ static void __exit intel_uncore_exit(void)
unregister_pm_notifier(&uncore_pm_nb);
cpuhp_remove_state(uncore_hp_state);
for (i = 0; i < uncore_max_entries; ++i) {
if (uncore_instances[i].valid)
if (uncore_instances[i].valid) {
kobject_put(&uncore_instances[i].kobj);
wait_for_completion(&uncore_instances[i].kobj_unregister);
}
}
kobject_put(&uncore_root_kobj);
kobject_put(uncore_root_kobj);
kfree(uncore_instances);
}
module_exit(intel_uncore_exit)
......
......@@ -26,6 +26,7 @@ static const struct acpi_device_id intel_vbtn_ids[] = {
{"INT33D6", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, intel_vbtn_ids);
/* In theory, these are HID usages. */
static const struct key_entry intel_vbtn_keymap[] = {
......@@ -239,7 +240,6 @@ static struct platform_driver intel_vbtn_pl_driver = {
.probe = intel_vbtn_probe,
.remove = intel_vbtn_remove,
};
MODULE_DEVICE_TABLE(acpi, intel_vbtn_ids);
static acpi_status __init
check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
......
......@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/uaccess.h>
......@@ -193,7 +194,7 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{"Fuse", BIT(6)},
/*
* Reserved for Cannon Lake but valid for Ice Lake, Comet Lake,
* Tiger Lake and Elkhart Lake.
* Tiger Lake, Elkhart Lake and Jasper Lake.
*/
{"SBR8", BIT(7)},
......@@ -240,7 +241,7 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{"HDA_PGD6", BIT(4)},
/*
* Reserved for Cannon Lake but valid for Ice Lake, Comet Lake,
* Tiger Lake and ELkhart Lake.
* Tiger Lake, ELkhart Lake and Jasper Lake.
*/
{"PSF6", BIT(5)},
{"PSF7", BIT(6)},
......@@ -273,7 +274,7 @@ static const struct pmc_bit_map *ext_icl_pfear_map[] = {
};
static const struct pmc_bit_map tgl_pfear_map[] = {
/* Tiger Lake and Elkhart Lake generation onwards only */
/* Tiger Lake, Elkhart Lake and Jasper Lake generation onwards only */
{"PSF9", BIT(0)},
{"RES_66", BIT(1)},
{"RES_67", BIT(2)},
......@@ -408,13 +409,157 @@ static const struct pmc_reg_map icl_reg_map = {
.ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED,
};
static const struct pmc_bit_map tgl_lpm0_map[] = {
{"USB2PLL_OFF_STS", BIT(18)},
{"PCIe/USB3.1_Gen2PLL_OFF_STS", BIT(19)},
{"PCIe_Gen3PLL_OFF_STS", BIT(20)},
{"OPIOPLL_OFF_STS", BIT(21)},
{"OCPLL_OFF_STS", BIT(22)},
{"AudioPLL_OFF_STS", BIT(23)},
{"MIPIPLL_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)},
{"XTAL_USB2PLL_OFF_STS", BIT(31)},
{}
};
static const struct pmc_bit_map tgl_lpm1_map[] = {
{"SPI_PG_STS", BIT(2)},
{"xHCI_PG_STS", BIT(3)},
{"PCIe_Ctrller_A_PG_STS", BIT(4)},
{"PCIe_Ctrller_B_PG_STS", BIT(5)},
{"PCIe_Ctrller_C_PG_STS", BIT(6)},
{"GBE_PG_STS", BIT(7)},
{"SATA_PG_STS", BIT(8)},
{"HDA0_PG_STS", BIT(9)},
{"HDA1_PG_STS", BIT(10)},
{"HDA2_PG_STS", BIT(11)},
{"HDA3_PG_STS", BIT(12)},
{"PCIe_Ctrller_D_PG_STS", BIT(13)},
{"ISIO_PG_STS", BIT(14)},
{"SMB_PG_STS", BIT(16)},
{"ISH_PG_STS", BIT(17)},
{"ITH_PG_STS", BIT(19)},
{"SDX_PG_STS", BIT(20)},
{"xDCI_PG_STS", BIT(25)},
{"DCI_PG_STS", BIT(26)},
{"CSME0_PG_STS", BIT(27)},
{"CSME_KVM_PG_STS", BIT(28)},
{"CSME1_PG_STS", BIT(29)},
{"CSME_CLINK_PG_STS", BIT(30)},
{"CSME2_PG_STS", BIT(31)},
{}
};
static const struct pmc_bit_map tgl_lpm2_map[] = {
{"ADSP_D3_STS", BIT(0)},
{"SATA_D3_STS", BIT(1)},
{"xHCI0_D3_STS", BIT(2)},
{"xDCI1_D3_STS", BIT(5)},
{"SDX_D3_STS", BIT(6)},
{"EMMC_D3_STS", BIT(7)},
{"IS_D3_STS", BIT(8)},
{"THC0_D3_STS", BIT(9)},
{"THC1_D3_STS", BIT(10)},
{"GBE_D3_STS", BIT(11)},
{"GBE_TSN_D3_STS", BIT(12)},
{}
};
static const struct pmc_bit_map tgl_lpm3_map[] = {
{"GPIO_COM0_VNN_REQ_STS", BIT(1)},
{"GPIO_COM1_VNN_REQ_STS", BIT(2)},
{"GPIO_COM2_VNN_REQ_STS", BIT(3)},
{"GPIO_COM3_VNN_REQ_STS", BIT(4)},
{"GPIO_COM4_VNN_REQ_STS", BIT(5)},
{"GPIO_COM5_VNN_REQ_STS", BIT(6)},
{"Audio_VNN_REQ_STS", BIT(7)},
{"ISH_VNN_REQ_STS", BIT(8)},
{"CNVI_VNN_REQ_STS", BIT(9)},
{"eSPI_VNN_REQ_STS", BIT(10)},
{"Display_VNN_REQ_STS", BIT(11)},
{"DTS_VNN_REQ_STS", BIT(12)},
{"SMBUS_VNN_REQ_STS", BIT(14)},
{"CSME_VNN_REQ_STS", BIT(15)},
{"SMLINK0_VNN_REQ_STS", BIT(16)},
{"SMLINK1_VNN_REQ_STS", BIT(17)},
{"CLINK_VNN_REQ_STS", BIT(20)},
{"DCI_VNN_REQ_STS", BIT(21)},
{"ITH_VNN_REQ_STS", BIT(22)},
{"CSME_VNN_REQ_STS", BIT(24)},
{"GBE_VNN_REQ_STS", BIT(25)},
{}
};
static const struct pmc_bit_map tgl_lpm4_map[] = {
{"CPU_C10_REQ_STS_0", BIT(0)},
{"PCIe_LPM_En_REQ_STS_3", BIT(3)},
{"ITH_REQ_STS_5", BIT(5)},
{"CNVI_REQ_STS_6", BIT(6)},
{"ISH_REQ_STS_7", BIT(7)},
{"USB2_SUS_PG_Sys_REQ_STS_10", BIT(10)},
{"PCIe_Clk_REQ_STS_12", BIT(12)},
{"MPHY_Core_DL_REQ_STS_16", BIT(16)},
{"Break-even_En_REQ_STS_17", BIT(17)},
{"Auto-demo_En_REQ_STS_18", BIT(18)},
{"MPHY_SUS_REQ_STS_22", BIT(22)},
{"xDCI_attached_REQ_STS_24", BIT(24)},
{}
};
static const struct pmc_bit_map tgl_lpm5_map[] = {
{"LSX_Wake0_En_STS", BIT(0)},
{"LSX_Wake0_Pol_STS", BIT(1)},
{"LSX_Wake1_En_STS", BIT(2)},
{"LSX_Wake1_Pol_STS", BIT(3)},
{"LSX_Wake2_En_STS", BIT(4)},
{"LSX_Wake2_Pol_STS", BIT(5)},
{"LSX_Wake3_En_STS", BIT(6)},
{"LSX_Wake3_Pol_STS", BIT(7)},
{"LSX_Wake4_En_STS", BIT(8)},
{"LSX_Wake4_Pol_STS", BIT(9)},
{"LSX_Wake5_En_STS", BIT(10)},
{"LSX_Wake5_Pol_STS", BIT(11)},
{"LSX_Wake6_En_STS", BIT(12)},
{"LSX_Wake6_Pol_STS", BIT(13)},
{"LSX_Wake7_En_STS", BIT(14)},
{"LSX_Wake7_Pol_STS", BIT(15)},
{"Intel_Se_IO_Wake0_En_STS", BIT(16)},
{"Intel_Se_IO_Wake0_Pol_STS", BIT(17)},
{"Intel_Se_IO_Wake1_En_STS", BIT(18)},
{"Intel_Se_IO_Wake1_Pol_STS", BIT(19)},
{"Int_Timer_SS_Wake0_En_STS", BIT(20)},
{"Int_Timer_SS_Wake0_Pol_STS", BIT(21)},
{"Int_Timer_SS_Wake1_En_STS", BIT(22)},
{"Int_Timer_SS_Wake1_Pol_STS", BIT(23)},
{"Int_Timer_SS_Wake2_En_STS", BIT(24)},
{"Int_Timer_SS_Wake2_Pol_STS", BIT(25)},
{"Int_Timer_SS_Wake3_En_STS", BIT(26)},
{"Int_Timer_SS_Wake3_Pol_STS", BIT(27)},
{"Int_Timer_SS_Wake4_En_STS", BIT(28)},
{"Int_Timer_SS_Wake4_Pol_STS", BIT(29)},
{"Int_Timer_SS_Wake5_En_STS", BIT(30)},
{"Int_Timer_SS_Wake5_Pol_STS", BIT(31)},
{}
};
static const struct pmc_bit_map *tgl_lpm_maps[] = {
tgl_lpm0_map,
tgl_lpm1_map,
tgl_lpm2_map,
tgl_lpm3_map,
tgl_lpm4_map,
tgl_lpm5_map,
NULL
};
static const struct pmc_reg_map tgl_reg_map = {
.pfear_sts = ext_tgl_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slps0_dbg_maps = cnp_slps0_dbg_maps,
.ltr_show_sts = cnp_ltr_show_map,
.msr_sts = msr_map,
.slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET,
.ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
.regmap_length = CNP_PMC_MMIO_REG_LEN,
.ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
......@@ -422,6 +567,12 @@ static const struct pmc_reg_map tgl_reg_map = {
.pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
.pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
.ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED,
.lpm_modes = tgl_lpm_modes,
.lpm_en_offset = TGL_LPM_EN_OFFSET,
.lpm_residency_offset = TGL_LPM_RESIDENCY_OFFSET,
.lpm_sts = tgl_lpm_maps,
.lpm_status_offset = TGL_LPM_STATUS_OFFSET,
.lpm_live_status_offset = TGL_LPM_LIVE_STATUS_OFFSET,
};
static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int reg_offset)
......@@ -463,6 +614,84 @@ static int pmc_core_check_read_lock_bit(void)
return value & BIT(pmcdev->map->pm_read_disable_bit);
}
static void pmc_core_slps0_display(struct pmc_dev *pmcdev, struct device *dev,
struct seq_file *s)
{
const struct pmc_bit_map **maps = pmcdev->map->slps0_dbg_maps;
const struct pmc_bit_map *map;
int offset = pmcdev->map->slps0_dbg_offset;
u32 data;
while (*maps) {
map = *maps;
data = pmc_core_reg_read(pmcdev, offset);
offset += 4;
while (map->name) {
if (dev)
dev_dbg(dev, "SLP_S0_DBG: %-32s\tState: %s\n",
map->name,
data & map->bit_mask ? "Yes" : "No");
if (s)
seq_printf(s, "SLP_S0_DBG: %-32s\tState: %s\n",
map->name,
data & map->bit_mask ? "Yes" : "No");
++map;
}
++maps;
}
}
static int pmc_core_lpm_get_arr_size(const struct pmc_bit_map **maps)
{
int idx;
for (idx = 0; maps[idx]; idx++)
;/* Nothing */
return idx;
}
static void pmc_core_lpm_display(struct pmc_dev *pmcdev, struct device *dev,
struct seq_file *s, u32 offset,
const char *str,
const struct pmc_bit_map **maps)
{
int index, idx, len = 32, bit_mask, arr_size;
u32 *lpm_regs;
arr_size = pmc_core_lpm_get_arr_size(maps);
lpm_regs = kmalloc_array(arr_size, sizeof(*lpm_regs), GFP_KERNEL);
if (!lpm_regs)
return;
for (index = 0; index < arr_size; index++) {
lpm_regs[index] = pmc_core_reg_read(pmcdev, offset);
offset += 4;
}
for (idx = 0; idx < arr_size; idx++) {
if (dev)
dev_dbg(dev, "\nLPM_%s_%d:\t0x%x\n", str, idx,
lpm_regs[idx]);
if (s)
seq_printf(s, "\nLPM_%s_%d:\t0x%x\n", str, idx,
lpm_regs[idx]);
for (index = 0; maps[idx][index].name && index < len; index++) {
bit_mask = maps[idx][index].bit_mask;
if (dev)
dev_dbg(dev, "%-30s %-30d\n",
maps[idx][index].name,
lpm_regs[idx] & bit_mask ? 1 : 0);
if (s)
seq_printf(s, "%-30s %-30d\n",
maps[idx][index].name,
lpm_regs[idx] & bit_mask ? 1 : 0);
}
}
kfree(lpm_regs);
}
#if IS_ENABLED(CONFIG_DEBUG_FS)
static bool slps0_dbg_latch;
......@@ -698,27 +927,11 @@ static void pmc_core_slps0_dbg_latch(struct pmc_dev *pmcdev, bool reset)
static int pmc_core_slps0_dbg_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
const struct pmc_bit_map **maps = pmcdev->map->slps0_dbg_maps;
const struct pmc_bit_map *map;
int offset;
u32 data;
pmc_core_slps0_dbg_latch(pmcdev, false);
offset = pmcdev->map->slps0_dbg_offset;
while (*maps) {
map = *maps;
data = pmc_core_reg_read(pmcdev, offset);
offset += 4;
while (map->name) {
seq_printf(s, "SLP_S0_DBG: %-32s\tState: %s\n",
map->name,
data & map->bit_mask ?
"Yes" : "No");
++map;
}
++maps;
}
pmc_core_slps0_display(pmcdev, NULL, s);
pmc_core_slps0_dbg_latch(pmcdev, true);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_slps0_dbg);
......@@ -794,6 +1007,51 @@ static int pmc_core_ltr_show(struct seq_file *s, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_ltr);
static int pmc_core_substate_res_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
const char **lpm_modes = pmcdev->map->lpm_modes;
u32 offset = pmcdev->map->lpm_residency_offset;
u32 lpm_en;
int index;
lpm_en = pmc_core_reg_read(pmcdev, pmcdev->map->lpm_en_offset);
seq_printf(s, "status substate residency\n");
for (index = 0; lpm_modes[index]; index++) {
seq_printf(s, "%7s %7s %-15u\n",
BIT(index) & lpm_en ? "Enabled" : " ",
lpm_modes[index], pmc_core_reg_read(pmcdev, offset));
offset += 4;
}
return 0;
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_res);
static int pmc_core_substate_sts_regs_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
const struct pmc_bit_map **maps = pmcdev->map->lpm_sts;
u32 offset = pmcdev->map->lpm_status_offset;
pmc_core_lpm_display(pmcdev, NULL, s, offset, "STATUS", maps);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_sts_regs);
static int pmc_core_substate_l_sts_regs_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
const struct pmc_bit_map **maps = pmcdev->map->lpm_sts;
u32 offset = pmcdev->map->lpm_live_status_offset;
pmc_core_lpm_display(pmcdev, NULL, s, offset, "LIVE_STATUS", maps);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_l_sts_regs);
static int pmc_core_pkgc_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
......@@ -859,6 +1117,21 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
debugfs_create_bool("slp_s0_dbg_latch", 0644,
dir, &slps0_dbg_latch);
}
if (pmcdev->map->lpm_en_offset) {
debugfs_create_file("substate_residencies", 0444,
pmcdev->dbgfs_dir, pmcdev,
&pmc_core_substate_res_fops);
}
if (pmcdev->map->lpm_status_offset) {
debugfs_create_file("substate_status_registers", 0444,
pmcdev->dbgfs_dir, pmcdev,
&pmc_core_substate_sts_regs_fops);
debugfs_create_file("substate_live_status_registers", 0444,
pmcdev->dbgfs_dir, pmcdev,
&pmc_core_substate_l_sts_regs_fops);
}
}
#else
static inline void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
......@@ -883,6 +1156,7 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &tgl_reg_map),
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &tgl_reg_map),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, &tgl_reg_map),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, &tgl_reg_map),
{}
};
......@@ -1047,10 +1321,8 @@ static inline bool pmc_core_is_s0ix_failed(struct pmc_dev *pmcdev)
static int pmc_core_resume(struct device *dev)
{
struct pmc_dev *pmcdev = dev_get_drvdata(dev);
const struct pmc_bit_map **maps = pmcdev->map->slps0_dbg_maps;
int offset = pmcdev->map->slps0_dbg_offset;
const struct pmc_bit_map *map;
u32 data;
const struct pmc_bit_map **maps = pmcdev->map->lpm_sts;
int offset = pmcdev->map->lpm_status_offset;
if (!pmcdev->check_counters)
return 0;
......@@ -1068,18 +1340,11 @@ static int pmc_core_resume(struct device *dev)
/* The real interesting case - S0ix failed - lets ask PMC why. */
dev_warn(dev, "CPU did not enter SLP_S0!!! (S0ix cnt=%llu)\n",
pmcdev->s0ix_counter);
while (*maps) {
map = *maps;
data = pmc_core_reg_read(pmcdev, offset);
offset += 4;
while (map->name) {
dev_dbg(dev, "SLP_S0_DBG: %-32s\tState: %s\n",
map->name,
data & map->bit_mask ? "Yes" : "No");
map++;
}
maps++;
}
if (pmcdev->map->slps0_dbg_maps)
pmc_core_slps0_display(pmcdev, dev, NULL);
if (pmcdev->map->lpm_sts)
pmc_core_lpm_display(pmcdev, dev, NULL, offset, "STATUS", maps);
return 0;
}
......
......@@ -188,6 +188,28 @@ enum ppfear_regs {
#define TGL_NUM_IP_IGN_ALLOWED 22
/*
* Tigerlake Power Management Controller register offsets
*/
#define TGL_LPM_EN_OFFSET 0x1C78
#define TGL_LPM_RESIDENCY_OFFSET 0x1C80
/* Tigerlake Low Power Mode debug registers */
#define TGL_LPM_STATUS_OFFSET 0x1C3C
#define TGL_LPM_LIVE_STATUS_OFFSET 0x1C5C
const char *tgl_lpm_modes[] = {
"S0i2.0",
"S0i2.1",
"S0i2.2",
"S0i3.0",
"S0i3.1",
"S0i3.2",
"S0i3.3",
"S0i3.4",
NULL
};
struct pmc_bit_map {
const char *name;
u32 bit_mask;
......@@ -221,6 +243,7 @@ struct pmc_reg_map {
const struct pmc_bit_map **slps0_dbg_maps;
const struct pmc_bit_map *ltr_show_sts;
const struct pmc_bit_map *msr_sts;
const struct pmc_bit_map **lpm_sts;
const u32 slp_s0_offset;
const u32 ltr_ignore_offset;
const int regmap_length;
......@@ -231,6 +254,12 @@ struct pmc_reg_map {
const u32 slps0_dbg_offset;
const u32 ltr_ignore_max;
const u32 pm_vric1_offset;
/* Low Power Mode registers */
const char **lpm_modes;
const u32 lpm_en_offset;
const u32 lpm_residency_offset;
const u32 lpm_status_offset;
const u32 lpm_live_status_offset;
};
/**
......
......@@ -126,7 +126,7 @@ static void isst_if_remove(struct pci_dev *pdev)
struct isst_if_device *punit_dev;
punit_dev = pci_get_drvdata(pdev);
isst_if_cdev_unregister(ISST_IF_DEV_MBOX);
isst_if_cdev_unregister(ISST_IF_DEV_MMIO);
mutex_destroy(&punit_dev->mutex);
}
......
......@@ -383,6 +383,14 @@ static const struct dmi_system_id critclk_systems[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "3I380D"),
},
},
{
/* pmc_plt_clk* - are used for ethernet controllers */
.ident = "Lex 2I385SW",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Lex BayTrail"),
DMI_MATCH(DMI_PRODUCT_NAME, "2I385SW"),
},
},
{
/* pmc_plt_clk* - are used for ethernet controllers */
.ident = "Beckhoff CB3163",
......
......@@ -827,10 +827,10 @@ static ssize_t sony_nc_handles_show(struct device *dev,
int i;
for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
len += snprintf(buffer + len, PAGE_SIZE - len, "0x%.4x ",
len += scnprintf(buffer + len, PAGE_SIZE - len, "0x%.4x ",
handles->cap[i]);
}
len += snprintf(buffer + len, PAGE_SIZE - len, "\n");
len += scnprintf(buffer + len, PAGE_SIZE - len, "\n");
return len;
}
......@@ -2187,10 +2187,10 @@ static ssize_t sony_nc_thermal_profiles_show(struct device *dev,
for (cnt = 0; cnt < THM_PROFILE_MAX; cnt++) {
if (!cnt || (th_handle->profiles & cnt))
idx += snprintf(buffer + idx, PAGE_SIZE - idx, "%s ",
idx += scnprintf(buffer + idx, PAGE_SIZE - idx, "%s ",
snc_thermal_profiles[cnt]);
}
idx += snprintf(buffer + idx, PAGE_SIZE - idx, "\n");
idx += scnprintf(buffer + idx, PAGE_SIZE - idx, "\n");
return idx;
}
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Supports for the power IC on the Surface 3 tablet.
*
* (C) Copyright 2016-2018 Red Hat, Inc
* (C) Copyright 2016-2018 Benjamin Tissoires <benjamin.tissoires@gmail.com>
* (C) Copyright 2016 Stephen Just <stephenjust@gmail.com>
*
* This driver has been reverse-engineered by parsing the DSDT of the Surface 3
* and looking at the registers of the chips.
*
* The DSDT allowed to find out that:
* - the driver is required for the ACPI BAT0 device to communicate to the chip
* through an operation region.
* - the various defines for the operation region functions to communicate with
* this driver
* - the DSM 3f99e367-6220-4955-8b0f-06ef2ae79412 allows to trigger ACPI
* events to BAT0 (the code is all available in the DSDT).
*
* Further findings regarding the 2 chips declared in the MSHW0011 are:
* - there are 2 chips declared:
* . 0x22 seems to control the ADP1 line status (and probably the charger)
* . 0x55 controls the battery directly
* - the battery chip uses a SMBus protocol (using plain SMBus allows non
* destructive commands):
* . the commands/registers used are in the range 0x00..0x7F
* . if bit 8 (0x80) is set in the SMBus command, the returned value is the
* same as when it is not set. There is a high chance this bit is the
* read/write
* . the various registers semantic as been deduced by observing the register
* dumps.
*/
#include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/freezer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uuid.h>
#include <asm/unaligned.h>
#define SURFACE_3_POLL_INTERVAL (2 * HZ)
#define SURFACE_3_STRLEN 10
struct mshw0011_data {
struct i2c_client *adp1;
struct i2c_client *bat0;
unsigned short notify_mask;
struct task_struct *poll_task;
bool kthread_running;
bool charging;
bool bat_charging;
u8 trip_point;
s32 full_capacity;
};
struct mshw0011_handler_data {
struct acpi_connection_info info;
struct i2c_client *client;
};
struct bix {
u32 revision;
u32 power_unit;
u32 design_capacity;
u32 last_full_charg_capacity;
u32 battery_technology;
u32 design_voltage;
u32 design_capacity_of_warning;
u32 design_capacity_of_low;
u32 cycle_count;
u32 measurement_accuracy;
u32 max_sampling_time;
u32 min_sampling_time;
u32 max_average_interval;
u32 min_average_interval;
u32 battery_capacity_granularity_1;
u32 battery_capacity_granularity_2;
char model[SURFACE_3_STRLEN];
char serial[SURFACE_3_STRLEN];
char type[SURFACE_3_STRLEN];
char OEM[SURFACE_3_STRLEN];
} __packed;
struct bst {
u32 battery_state;
s32 battery_present_rate;
u32 battery_remaining_capacity;
u32 battery_present_voltage;
} __packed;
struct gsb_command {
u8 arg0;
u8 arg1;
u8 arg2;
} __packed;
struct gsb_buffer {
u8 status;
u8 len;
u8 ret;
union {
struct gsb_command cmd;
struct bst bst;
struct bix bix;
} __packed;
} __packed;
#define ACPI_BATTERY_STATE_DISCHARGING BIT(0)
#define ACPI_BATTERY_STATE_CHARGING BIT(1)
#define ACPI_BATTERY_STATE_CRITICAL BIT(2)
#define MSHW0011_CMD_DEST_BAT0 0x01
#define MSHW0011_CMD_DEST_ADP1 0x03
#define MSHW0011_CMD_BAT0_STA 0x01
#define MSHW0011_CMD_BAT0_BIX 0x02
#define MSHW0011_CMD_BAT0_BCT 0x03
#define MSHW0011_CMD_BAT0_BTM 0x04
#define MSHW0011_CMD_BAT0_BST 0x05
#define MSHW0011_CMD_BAT0_BTP 0x06
#define MSHW0011_CMD_ADP1_PSR 0x07
#define MSHW0011_CMD_BAT0_PSOC 0x09
#define MSHW0011_CMD_BAT0_PMAX 0x0a
#define MSHW0011_CMD_BAT0_PSRC 0x0b
#define MSHW0011_CMD_BAT0_CHGI 0x0c
#define MSHW0011_CMD_BAT0_ARTG 0x0d
#define MSHW0011_NOTIFY_GET_VERSION 0x00
#define MSHW0011_NOTIFY_ADP1 0x01
#define MSHW0011_NOTIFY_BAT0_BST 0x02
#define MSHW0011_NOTIFY_BAT0_BIX 0x05
#define MSHW0011_ADP1_REG_PSR 0x04
#define MSHW0011_BAT0_REG_CAPACITY 0x0c
#define MSHW0011_BAT0_REG_FULL_CHG_CAPACITY 0x0e
#define MSHW0011_BAT0_REG_DESIGN_CAPACITY 0x40
#define MSHW0011_BAT0_REG_VOLTAGE 0x08
#define MSHW0011_BAT0_REG_RATE 0x14
#define MSHW0011_BAT0_REG_OEM 0x45
#define MSHW0011_BAT0_REG_TYPE 0x4e
#define MSHW0011_BAT0_REG_SERIAL_NO 0x56
#define MSHW0011_BAT0_REG_CYCLE_CNT 0x6e
#define MSHW0011_EV_2_5_MASK GENMASK(8, 0)
/* 3f99e367-6220-4955-8b0f-06ef2ae79412 */
static const guid_t mshw0011_guid =
GUID_INIT(0x3F99E367, 0x6220, 0x4955, 0x8B, 0x0F, 0x06, 0xEF,
0x2A, 0xE7, 0x94, 0x12);
static int
mshw0011_notify(struct mshw0011_data *cdata, u8 arg1, u8 arg2,
unsigned int *ret_value)
{
union acpi_object *obj;
struct acpi_device *adev;
acpi_handle handle;
unsigned int i;
handle = ACPI_HANDLE(&cdata->adp1->dev);
if (!handle || acpi_bus_get_device(handle, &adev))
return -ENODEV;
obj = acpi_evaluate_dsm_typed(handle, &mshw0011_guid, arg1, arg2, NULL,
ACPI_TYPE_BUFFER);
if (!obj) {
dev_err(&cdata->adp1->dev, "device _DSM execution failed\n");
return -ENODEV;
}
*ret_value = 0;
for (i = 0; i < obj->buffer.length; i++)
*ret_value |= obj->buffer.pointer[i] << (i * 8);
ACPI_FREE(obj);
return 0;
}
static const struct bix default_bix = {
.revision = 0x00,
.power_unit = 0x01,
.design_capacity = 0x1dca,
.last_full_charg_capacity = 0x1dca,
.battery_technology = 0x01,
.design_voltage = 0x10df,
.design_capacity_of_warning = 0x8f,
.design_capacity_of_low = 0x47,
.cycle_count = 0xffffffff,
.measurement_accuracy = 0x00015f90,
.max_sampling_time = 0x03e8,
.min_sampling_time = 0x03e8,
.max_average_interval = 0x03e8,
.min_average_interval = 0x03e8,
.battery_capacity_granularity_1 = 0x45,
.battery_capacity_granularity_2 = 0x11,
.model = "P11G8M",
.serial = "",
.type = "LION",
.OEM = "",
};
static int mshw0011_bix(struct mshw0011_data *cdata, struct bix *bix)
{
struct i2c_client *client = cdata->bat0;
char buf[SURFACE_3_STRLEN];
int ret;
*bix = default_bix;
/* get design capacity */
ret = i2c_smbus_read_word_data(client,
MSHW0011_BAT0_REG_DESIGN_CAPACITY);
if (ret < 0) {
dev_err(&client->dev, "Error reading design capacity: %d\n",
ret);
return ret;
}
bix->design_capacity = ret;
/* get last full charge capacity */
ret = i2c_smbus_read_word_data(client,
MSHW0011_BAT0_REG_FULL_CHG_CAPACITY);
if (ret < 0) {
dev_err(&client->dev,
"Error reading last full charge capacity: %d\n", ret);
return ret;
}
bix->last_full_charg_capacity = ret;
/* get serial number */
ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO,
sizeof(buf), buf);
if (ret != sizeof(buf)) {
dev_err(&client->dev, "Error reading serial no: %d\n", ret);
return ret;
}
snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf);
/* get cycle count */
ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT);
if (ret < 0) {
dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
return ret;
}
bix->cycle_count = ret;
/* get OEM name */
ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_OEM,
4, buf);
if (ret != 4) {
dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
return ret;
}
snprintf(bix->OEM, ARRAY_SIZE(bix->OEM), "%3pE", buf);
return 0;
}
static int mshw0011_bst(struct mshw0011_data *cdata, struct bst *bst)
{
struct i2c_client *client = cdata->bat0;
int rate, capacity, voltage, state;
s16 tmp;
rate = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_RATE);
if (rate < 0)
return rate;
capacity = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CAPACITY);
if (capacity < 0)
return capacity;
voltage = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_VOLTAGE);
if (voltage < 0)
return voltage;
tmp = rate;
bst->battery_present_rate = abs((s32)tmp);
state = 0;
if ((s32) tmp > 0)
state |= ACPI_BATTERY_STATE_CHARGING;
else if ((s32) tmp < 0)
state |= ACPI_BATTERY_STATE_DISCHARGING;
bst->battery_state = state;
bst->battery_remaining_capacity = capacity;
bst->battery_present_voltage = voltage;
return 0;
}
static int mshw0011_adp_psr(struct mshw0011_data *cdata)
{
return i2c_smbus_read_byte_data(cdata->adp1, MSHW0011_ADP1_REG_PSR);
}
static int mshw0011_isr(struct mshw0011_data *cdata)
{
struct bst bst;
struct bix bix;
int ret;
bool status, bat_status;
ret = mshw0011_adp_psr(cdata);
if (ret < 0)
return ret;
status = ret;
if (status != cdata->charging)
mshw0011_notify(cdata, cdata->notify_mask,
MSHW0011_NOTIFY_ADP1, &ret);
cdata->charging = status;
ret = mshw0011_bst(cdata, &bst);
if (ret < 0)
return ret;
bat_status = bst.battery_state;
if (bat_status != cdata->bat_charging)
mshw0011_notify(cdata, cdata->notify_mask,
MSHW0011_NOTIFY_BAT0_BST, &ret);
cdata->bat_charging = bat_status;
ret = mshw0011_bix(cdata, &bix);
if (ret < 0)
return ret;
if (bix.last_full_charg_capacity != cdata->full_capacity)
mshw0011_notify(cdata, cdata->notify_mask,
MSHW0011_NOTIFY_BAT0_BIX, &ret);
cdata->full_capacity = bix.last_full_charg_capacity;
return 0;
}
static int mshw0011_poll_task(void *data)
{
struct mshw0011_data *cdata = data;
int ret = 0;
cdata->kthread_running = true;
set_freezable();
while (!kthread_should_stop()) {
schedule_timeout_interruptible(SURFACE_3_POLL_INTERVAL);
try_to_freeze();
ret = mshw0011_isr(data);
if (ret)
break;
}
cdata->kthread_running = false;
return ret;
}
static acpi_status
mshw0011_space_handler(u32 function, acpi_physical_address command,
u32 bits, u64 *value64,
void *handler_context, void *region_context)
{
struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
struct mshw0011_handler_data *data = handler_context;
struct acpi_connection_info *info = &data->info;
struct acpi_resource_i2c_serialbus *sb;
struct i2c_client *client = data->client;
struct mshw0011_data *cdata = i2c_get_clientdata(client);
struct acpi_resource *ares;
u32 accessor_type = function >> 16;
acpi_status ret;
int status = 1;
ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
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) {
ret = AE_BAD_PARAMETER;
goto err;
}
if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
ret = AE_BAD_PARAMETER;
goto err;
}
if (gsb->cmd.arg0 == MSHW0011_CMD_DEST_ADP1 &&
gsb->cmd.arg1 == MSHW0011_CMD_ADP1_PSR) {
status = mshw0011_adp_psr(cdata);
if (status >= 0) {
ret = AE_OK;
goto out;
} else {
ret = AE_ERROR;
goto err;
}
}
if (gsb->cmd.arg0 != MSHW0011_CMD_DEST_BAT0) {
ret = AE_BAD_PARAMETER;
goto err;
}
switch (gsb->cmd.arg1) {
case MSHW0011_CMD_BAT0_STA:
break;
case MSHW0011_CMD_BAT0_BIX:
ret = mshw0011_bix(cdata, &gsb->bix);
break;
case MSHW0011_CMD_BAT0_BTP:
cdata->trip_point = gsb->cmd.arg2;
break;
case MSHW0011_CMD_BAT0_BST:
ret = mshw0011_bst(cdata, &gsb->bst);
break;
default:
dev_info(&cdata->bat0->dev, "command(0x%02x) is not supported.\n", gsb->cmd.arg1);
ret = AE_BAD_PARAMETER;
goto err;
}
out:
gsb->ret = status;
gsb->status = 0;
err:
ACPI_FREE(ares);
return ret;
}
static int mshw0011_install_space_handler(struct i2c_client *client)
{
acpi_handle handle;
struct mshw0011_handler_data *data;
acpi_status status;
handle = ACPI_HANDLE(&client->dev);
if (!handle)
return -ENODEV;
data = kzalloc(sizeof(struct mshw0011_handler_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
data->client = client;
status = acpi_bus_attach_private_data(handle, (void *)data);
if (ACPI_FAILURE(status)) {
kfree(data);
return -ENOMEM;
}
status = acpi_install_address_space_handler(handle,
ACPI_ADR_SPACE_GSBUS,
&mshw0011_space_handler,
NULL,
data);
if (ACPI_FAILURE(status)) {
dev_err(&client->dev, "Error installing i2c space handler\n");
acpi_bus_detach_private_data(handle);
kfree(data);
return -ENOMEM;
}
acpi_walk_dep_device_list(handle);
return 0;
}
static void mshw0011_remove_space_handler(struct i2c_client *client)
{
struct mshw0011_handler_data *data;
acpi_handle handle;
acpi_status status;
handle = ACPI_HANDLE(&client->dev);
if (!handle)
return;
acpi_remove_address_space_handler(handle,
ACPI_ADR_SPACE_GSBUS,
&mshw0011_space_handler);
status = acpi_bus_get_private_data(handle, (void **)&data);
if (ACPI_SUCCESS(status))
kfree(data);
acpi_bus_detach_private_data(handle);
}
static int mshw0011_probe(struct i2c_client *client)
{
struct i2c_board_info board_info;
struct device *dev = &client->dev;
struct i2c_client *bat0;
struct mshw0011_data *data;
int error, mask;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->adp1 = client;
i2c_set_clientdata(client, data);
memset(&board_info, 0, sizeof(board_info));
strlcpy(board_info.type, "MSHW0011-bat0", I2C_NAME_SIZE);
bat0 = i2c_acpi_new_device(dev, 1, &board_info);
if (!bat0)
return -ENOMEM;
data->bat0 = bat0;
i2c_set_clientdata(bat0, data);
error = mshw0011_notify(data, 1, MSHW0011_NOTIFY_GET_VERSION, &mask);
if (error)
goto out_err;
data->notify_mask = mask == MSHW0011_EV_2_5_MASK;
data->poll_task = kthread_run(mshw0011_poll_task, data, "mshw0011_adp");
if (IS_ERR(data->poll_task)) {
error = PTR_ERR(data->poll_task);
dev_err(&client->dev, "Unable to run kthread err %d\n", error);
goto out_err;
}
error = mshw0011_install_space_handler(client);
if (error)
goto out_err;
return 0;
out_err:
if (data->kthread_running)
kthread_stop(data->poll_task);
i2c_unregister_device(data->bat0);
return error;
}
static int mshw0011_remove(struct i2c_client *client)
{
struct mshw0011_data *cdata = i2c_get_clientdata(client);
mshw0011_remove_space_handler(client);
if (cdata->kthread_running)
kthread_stop(cdata->poll_task);
i2c_unregister_device(cdata->bat0);
return 0;
}
static const struct acpi_device_id mshw0011_acpi_match[] = {
{ "MSHW0011", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, mshw0011_acpi_match);
static struct i2c_driver mshw0011_driver = {
.probe_new = mshw0011_probe,
.remove = mshw0011_remove,
.driver = {
.name = "mshw0011",
.acpi_match_table = mshw0011_acpi_match,
},
};
module_i2c_driver(mshw0011_driver);
MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
MODULE_DESCRIPTION("mshw0011 driver");
MODULE_LICENSE("GPL v2");
......@@ -114,8 +114,10 @@ int isst_get_tdp_info(int cpu, int config_index,
ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO,
0, config_index, &resp);
if (ret)
if (ret) {
isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index);
return ret;
}
ctdp_level->pkg_tdp = resp & GENMASK(14, 0);
ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16;
......@@ -352,7 +354,7 @@ int isst_set_tdp_level_msr(int cpu, int tdp_level)
debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level);
if (isst_get_config_tdp_lock_status(cpu)) {
debug_printf("cpu: tdp_locked %d\n", cpu);
isst_display_error_info_message(1, "tdp_locked", 0, 0);
return -1;
}
......@@ -373,19 +375,50 @@ int isst_set_tdp_level(int cpu, int tdp_level)
unsigned int resp;
int ret;
if (isst_get_config_tdp_lock_status(cpu)) {
isst_display_error_info_message(1, "TDP is locked", 0, 0);
return -1;
}
ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0,
tdp_level, &resp);
if (ret)
return isst_set_tdp_level_msr(cpu, tdp_level);
if (ret) {
isst_display_error_info_message(1, "Set TDP level failed for level", 1, tdp_level);
return ret;
}
return 0;
}
int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info)
{
struct isst_pkg_ctdp_level_info ctdp_level;
struct isst_pkg_ctdp pkg_dev;
int i, ret, core_cnt, max;
unsigned int req, resp;
ret = isst_get_ctdp_levels(cpu, &pkg_dev);
if (ret) {
isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
return ret;
}
if (level > pkg_dev.levels) {
isst_display_error_info_message(1, "Invalid level", 1, level);
return -1;
}
ret = isst_get_ctdp_control(cpu, level, &ctdp_level);
if (ret)
return ret;
if (!ctdp_level.pbf_support) {
isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, level);
return -1;
}
pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
core_cnt = get_core_count(get_physical_package_id(cpu), get_physical_die_id(cpu));
......@@ -481,6 +514,10 @@ int isst_set_pbf_fact_status(int cpu, int pbf, int enable)
else
req &= ~BIT(17);
} else {
if (enable && !ctdp_level.sst_cp_enabled)
isst_display_error_info_message(0, "Make sure to execute before: core-power enable", 0, 0);
if (ctdp_level.pbf_enabled)
req = BIT(17);
......@@ -566,10 +603,32 @@ int isst_get_fact_bucket_info(int cpu, int level,
return 0;
}
int isst_get_fact_info(int cpu, int level, struct isst_fact_info *fact_info)
int isst_get_fact_info(int cpu, int level, int fact_bucket, struct isst_fact_info *fact_info)
{
struct isst_pkg_ctdp_level_info ctdp_level;
struct isst_pkg_ctdp pkg_dev;
unsigned int resp;
int ret;
int j, ret, print;
ret = isst_get_ctdp_levels(cpu, &pkg_dev);
if (ret) {
isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
return ret;
}
if (level > pkg_dev.levels) {
isst_display_error_info_message(1, "Invalid level", 1, level);
return -1;
}
ret = isst_get_ctdp_control(cpu, level, &ctdp_level);
if (ret)
return ret;
if (!ctdp_level.fact_support) {
isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, level);
return -1;
}
ret = isst_send_mbox_command(cpu, CONFIG_TDP,
CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0,
......@@ -585,8 +644,25 @@ int isst_get_fact_info(int cpu, int level, struct isst_fact_info *fact_info)
fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff;
ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info);
if (ret)
return ret;
return ret;
print = 0;
for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
if (fact_bucket != 0xff && fact_bucket != j)
continue;
if (!fact_info->bucket_info[j].high_priority_cores_count)
break;
print = 1;
}
if (!print) {
isst_display_error_info_message(1, "Invalid bucket", 0, 0);
return -1;
}
return 0;
}
int isst_set_trl(int cpu, unsigned long long trl)
......@@ -671,7 +747,7 @@ void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev)
int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
{
int i, ret;
int i, ret, valid = 0;
if (pkg_dev->processed)
return 0;
......@@ -684,6 +760,14 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
cpu, pkg_dev->enabled, pkg_dev->current_level,
pkg_dev->levels);
if (tdp_level != 0xff && tdp_level > pkg_dev->levels) {
isst_display_error_info_message(1, "Invalid level", 0, 0);
return -1;
}
if (!pkg_dev->enabled)
isst_display_error_info_message(0, "perf-profile feature is not supported, just base-config level 0 is valid", 0, 0);
for (i = 0; i <= pkg_dev->levels; ++i) {
struct isst_pkg_ctdp_level_info *ctdp_level;
......@@ -703,6 +787,7 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
if (ret)
continue;
valid = 1;
pkg_dev->processed = 1;
ctdp_level->processed = 1;
......@@ -713,7 +798,7 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
}
if (ctdp_level->fact_support) {
ret = isst_get_fact_info(cpu, i,
ret = isst_get_fact_info(cpu, i, 0xff,
&ctdp_level->fact_info);
if (ret)
return ret;
......@@ -775,6 +860,9 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
isst_get_uncore_mem_freq(cpu, i, ctdp_level);
}
if (!valid)
isst_display_error_info_message(0, "Invalid level, Can't get TDP control information at specified levels on cpu", 1, cpu);
return 0;
}
......@@ -829,17 +917,19 @@ int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
}
ret = isst_write_pm_config(cpu, 0);
if (ret)
perror("isst_write_pm_config\n");
isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error\n", 0, 0);
} else {
ret = isst_write_pm_config(cpu, 1);
if (ret)
perror("isst_write_pm_config\n");
isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error\n", 0, 0);
}
ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
&resp);
if (ret)
if (ret) {
isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0);
return ret;
}
debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
......@@ -850,6 +940,9 @@ int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
else
req = req & ~BIT(1);
if (priority_type > 1)
isst_display_error_info_message(1, "Invalid priority type: Changing type to ordered", 0, 0);
if (priority_type)
req = req | BIT(2);
else
......
......@@ -172,6 +172,7 @@ extern int get_cpu_count(int pkg_id, int die_id);
extern int get_core_count(int pkg_id, int die_id);
/* Common interfaces */
FILE *get_output_file(void);
extern void debug_printf(const char *format, ...);
extern int out_format_is_json(void);
extern int get_physical_package_id(int cpu);
......@@ -196,6 +197,8 @@ extern int isst_send_msr_command(unsigned int cpu, unsigned int command,
int write, unsigned long long *req_resp);
extern int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev);
extern int isst_get_ctdp_control(int cpu, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level);
extern int isst_get_coremask_info(int cpu, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level);
extern int isst_get_process_ctdp(int cpu, int tdp_level,
......@@ -205,7 +208,7 @@ extern void isst_get_process_ctdp_complete(int cpu,
extern void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
struct isst_pkg_ctdp *pkg_dev);
extern void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix,
unsigned int val);
unsigned int val, char *str0, char *str1);
extern void isst_ctdp_display_information_start(FILE *outf);
extern void isst_ctdp_display_information_end(FILE *outf);
extern void isst_pbf_display_information(int cpu, FILE *outf, int level,
......@@ -216,7 +219,7 @@ extern int isst_set_pbf_fact_status(int cpu, int pbf, int enable);
extern int isst_get_pbf_info(int cpu, int level,
struct isst_pbf_info *pbf_info);
extern void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info);
extern int isst_get_fact_info(int cpu, int level,
extern int isst_get_fact_info(int cpu, int level, int fact_bucket,
struct isst_fact_info *fact_info);
extern int isst_get_fact_bucket_info(int cpu, int level,
struct isst_fact_bucket_info *bucket_info);
......@@ -245,7 +248,10 @@ extern void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
extern int isst_clos_get_clos_information(int cpu, int *enable, int *type);
extern void isst_clos_display_clos_information(int cpu, FILE *outf,
int clos_enable, int type);
int clos_enable, int type,
int state, int cap);
extern int is_clx_n_platform(void);
extern int get_cpufreq_base_freq(int cpu);
extern int isst_read_pm_config(int cpu, int *cp_state, int *cp_cap);
extern void isst_display_error_info_message(int error, char *msg, int arg_valid, int arg);
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册