mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 09:30:52 +07:00
platform-drivers-x86 for v5.7-1
* 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. The following is an automated git shortlog grouped by driver: asus-wmi: - Support laptops where the first battery is named BATT - Fix return value of fan_boost_mode_store dell_rbu: - Unify format of the printed messages - Use max_t() to get rid of casting - Simplify cleanup code in create_packet() - don't open code list_for_each_entry*() - Use sysfs_create_group() API GPD pocket fan: - Fix error message when temp-limits are out of range i2c-multi-instantiate: - Replace zero-length array with flexible-array member intel-hid: - Move MODULE_DEVICE_TABLE() closer to the table intel_pmc_core: - Make pmc_core_substate_res_show() generic - Make pmc_core_lpm_display() generic for platforms that support sub-states - Add slp_s0_offset attribute back to tgl_reg_map - Remove duplicate 'if' to create debugfs entry - Relocate pmc_core_*_display() to outside of CONFIG_DEBUG_FS - Add debugfs support to access live status registers - Dump low power status registers on an S0ix.y failure - Add an additional parameter to pmc_core_lpm_display() - Remove slp_s0 attributes from tgl_reg_map - Refactor the driver by removing redundant code - Add debugfs entry for low power mode status registers - Add debugfs entry to access sub-state residencies - Add Atom based Jasper Lake (JSL) platform support intel-vbtn: - Move MODULE_DEVICE_TABLE() closer to the table ISST: - Fix wrong unregister type PDx86: - Kconfig: Fix a typo - Kconfig: Group modules by companies and functions - MAINTAINERS: Sort entries in database for PDx86 - Makefile: Group modules by companies and functions platform/x86/intel-uncore-freq: - Add release callback - Fix static checker issue and potential race condition pmc_atom: - Add Lex 2I385SW to critclk_systems DMI table sony-laptop: - Use scnprintf() for avoiding potential buffer overflow surface3_power: - Fix always true condition in mshw0011_space_handler() - Fix Kconfig section ordering - Add missed headers - Reformat GUID assignment - Drop useless macro ACPI_PTR() - Prefix POLL_INTERVAL with SURFACE_3 - Simplify mshw0011_adp_psr() to one liner - Use dev_err() instead of pr_err() - Drop unused structure definition - MSHW0011 rev-eng implementation tools/power/x86/intel-speed-select: - Fix a typo in error message - Update version - Avoid duplicate Package strings for json - Add display for enabled cpus count - Print friendly warning for bad command line - Fix avx options for turbo-freq feature - Improve CLX commands - Show error for invalid CPUs in the options - Improve core-power result and error display - Kernel interface error handling - Improve error display for turbo-freq feature - Improve error display for base-freq feature - Improve output of perf-profile commands - Enhance help for core-power assoc - Display error for invalid priority type - Check feature status first - Improve error display for perf-profile feature - Add an API for error/information print - Enhance --info option - Enhance help - Helpful warning for missing kernel interface - Store topology information - Max CPU count calculation when CPU0 is offline - Special handling for CPU 0 online/offline - Use more verbiage for clos information - Enhance core-power info command - Make target CPU optional for core-power info - Warn for invalid package id - Fix last cpu number - Fix mailbox usage for CLOS_PM_QOS_CONFIG - Avoid duplicate names for json parsing - Fix display for turbo-freq auto mode -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEqaflIX74DDDzMJJtb7wzTHR8rCgFAl6DMoEACgkQb7wzTHR8 rChW3w//WgzlhbKCl3EO8WjfSGmQHwszLq/Zcj+LLzoPQOl7t1nel1cEIWv7Y4+P /I24l2pqAD2JRgs03hNDg9i/YovPuqhLtS7t7hDNKFfNGdOhIJQkMwhrjXcapbBj UgE5cFbzXjf4400Tv1EkOylIZhOlpTmv5eGk/Dbw+5adTOlTH3MYLntv8ZfBulOh A6Dolto+zPvrbCyrMrgJSpQRIx1Rd8JV3YDXQRTpimmdsTJ7VFC55i1RLJSQ5sGw rF2qAekMExKScezSV8Yy9npDGJ1qUolhj/PciLPr71rmIuWqfdqc8eLeLmsJzIfY WO4TIQ3CTTY1FlZsOZyoeh+Kla//hRyaUoHAU0xEWDD9xKJBdzOIMEs4O/islWYL ILHs7ZdZPrHFI63mxyF0Mw5SgsSG1c6VNa19+H+YxpC4Pp8hbo891RRF7+7hBbdT YRT5yaQMD2M8QowMgxJQ7Xt3Kyz/jRO/8L59v202v3RzJvJ0UJhT+fmHV6OSz5MD SLOmLsXcWvgteNxM8TQ5yxmuDJdQVRuJqQpvPhysqlUEyhoTSLsII5evu/U/jXA4 vIx+QfUejDiy0vMeQu2xUOzxIzSzja6gLO6hKgiAw2cvUMqbOi2CIG7qwbRZkIis uj/GxlwiNfIsEKUE4728ivOHwT9Yke1x+QLl/oVwMh7zSgb+noE= =G0jF -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
dba43fc4ba
82
MAINTAINERS
82
MAINTAINERS
@ -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>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
# 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
|
||||
|
||||
# toshiba_acpi must link after wmi to ensure that wmi devices are found
|
||||
# before toshiba_acpi initializes
|
||||
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
|
||||
|
||||
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
|
||||
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_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/
|
||||
# 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_INTEL_UNCORE_FREQ_CONTROL) += intel-uncore-frequency.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_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_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_bin_attrs[] = {
|
||||
&bin_attr_data,
|
||||
&bin_attr_image_type,
|
||||
&bin_attr_packet_size,
|
||||
NULL
|
||||
};
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
589
drivers/platform/x86/surface3_power.c
Normal file
589
drivers/platform/x86/surface3_power.c
Normal file
@ -0,0 +1,589 @@
|
||||
// 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");
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -158,10 +158,17 @@ static void format_and_print(FILE *outf, int level, char *header, char *value)
|
||||
last_level = level;
|
||||
}
|
||||
|
||||
static void print_package_info(int cpu, FILE *outf)
|
||||
static int print_package_info(int cpu, FILE *outf)
|
||||
{
|
||||
char header[256];
|
||||
|
||||
if (out_format_is_json()) {
|
||||
snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d",
|
||||
get_physical_package_id(cpu), get_physical_die_id(cpu),
|
||||
cpu);
|
||||
format_and_print(outf, 1, header, NULL);
|
||||
return 1;
|
||||
}
|
||||
snprintf(header, sizeof(header), "package-%d",
|
||||
get_physical_package_id(cpu));
|
||||
format_and_print(outf, 1, header, NULL);
|
||||
@ -169,6 +176,8 @@ static void print_package_info(int cpu, FILE *outf)
|
||||
format_and_print(outf, 2, header, NULL);
|
||||
snprintf(header, sizeof(header), "cpu-%d", cpu);
|
||||
format_and_print(outf, 3, header, NULL);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
|
||||
@ -178,7 +187,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
|
||||
char header[256];
|
||||
char value[256];
|
||||
|
||||
snprintf(header, sizeof(header), "speed-select-base-freq");
|
||||
snprintf(header, sizeof(header), "speed-select-base-freq-properties");
|
||||
format_and_print(outf, disp_level, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "high-priority-base-frequency(MHz)");
|
||||
@ -222,9 +231,23 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
|
||||
struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info;
|
||||
char header[256];
|
||||
char value[256];
|
||||
int j;
|
||||
int print = 0, j;
|
||||
|
||||
snprintf(header, sizeof(header), "speed-select-turbo-freq");
|
||||
for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
|
||||
if (fact_bucket != 0xff && fact_bucket != j)
|
||||
continue;
|
||||
|
||||
if (!bucket_info[j].high_priority_cores_count)
|
||||
break;
|
||||
|
||||
print = 1;
|
||||
}
|
||||
if (!print) {
|
||||
fprintf(stderr, "Invalid bucket\n");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(header, sizeof(header), "speed-select-turbo-freq-properties");
|
||||
format_and_print(outf, base_level, header, NULL);
|
||||
for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
|
||||
if (fact_bucket != 0xff && fact_bucket != j)
|
||||
@ -289,7 +312,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
|
||||
}
|
||||
|
||||
void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix,
|
||||
unsigned int val)
|
||||
unsigned int val, char *str0, char *str1)
|
||||
{
|
||||
char header[256];
|
||||
char value[256];
|
||||
@ -301,8 +324,12 @@ void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix,
|
||||
format_and_print(outf, 2, header, NULL);
|
||||
snprintf(header, sizeof(header), "cpu-%d", cpu);
|
||||
format_and_print(outf, 3, header, NULL);
|
||||
|
||||
snprintf(value, sizeof(value), "%u", val);
|
||||
if (str0 && !val)
|
||||
snprintf(value, sizeof(value), "%s", str0);
|
||||
else if (str1 && val)
|
||||
snprintf(value, sizeof(value), "%s", str1);
|
||||
else
|
||||
snprintf(value, sizeof(value), "%u", val);
|
||||
format_and_print(outf, 4, prefix, value);
|
||||
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
@ -313,10 +340,11 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
||||
{
|
||||
char header[256];
|
||||
char value[256];
|
||||
int i, base_level = 1;
|
||||
static int level;
|
||||
int i;
|
||||
|
||||
if (pkg_dev->processed)
|
||||
print_package_info(cpu, outf);
|
||||
level = print_package_info(cpu, outf);
|
||||
|
||||
for (i = 0; i <= pkg_dev->levels; ++i) {
|
||||
struct isst_pkg_ctdp_level_info *ctdp_level;
|
||||
@ -328,72 +356,80 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
||||
|
||||
snprintf(header, sizeof(header), "perf-profile-level-%d",
|
||||
ctdp_level->level);
|
||||
format_and_print(outf, base_level + 3, header, NULL);
|
||||
format_and_print(outf, level + 1, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "cpu-count");
|
||||
j = get_cpu_count(get_physical_die_id(cpu),
|
||||
get_physical_die_id(cpu));
|
||||
snprintf(value, sizeof(value), "%d", j);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
j = CPU_COUNT_S(ctdp_level->core_cpumask_size,
|
||||
ctdp_level->core_cpumask);
|
||||
if (j) {
|
||||
snprintf(header, sizeof(header), "enable-cpu-count");
|
||||
snprintf(value, sizeof(value), "%d", j);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
}
|
||||
|
||||
if (ctdp_level->core_cpumask_size) {
|
||||
snprintf(header, sizeof(header), "enable-cpu-mask");
|
||||
printcpumask(sizeof(value), value,
|
||||
ctdp_level->core_cpumask_size,
|
||||
ctdp_level->core_cpumask);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "enable-cpu-list");
|
||||
printcpulist(sizeof(value), value,
|
||||
ctdp_level->core_cpumask_size,
|
||||
ctdp_level->core_cpumask);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
}
|
||||
|
||||
snprintf(header, sizeof(header), "thermal-design-power-ratio");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "base-frequency(MHz)");
|
||||
if (!ctdp_level->sse_p1)
|
||||
ctdp_level->sse_p1 = ctdp_level->tdp_ratio;
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->sse_p1 * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
if (ctdp_level->avx2_p1) {
|
||||
snprintf(header, sizeof(header), "base-frequency-avx2(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->avx2_p1 * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
}
|
||||
|
||||
if (ctdp_level->avx512_p1) {
|
||||
snprintf(header, sizeof(header), "base-frequency-avx512(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->avx512_p1 * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
}
|
||||
|
||||
if (ctdp_level->uncore_p1) {
|
||||
snprintf(header, sizeof(header), "uncore-frequency-min(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->uncore_p1 * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
}
|
||||
|
||||
if (ctdp_level->uncore_p0) {
|
||||
snprintf(header, sizeof(header), "uncore-frequency-max(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->uncore_p0 * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
}
|
||||
|
||||
if (ctdp_level->mem_freq) {
|
||||
snprintf(header, sizeof(header), "mem-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->mem_freq * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
}
|
||||
|
||||
snprintf(header, sizeof(header),
|
||||
@ -405,7 +441,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
||||
snprintf(value, sizeof(value), "disabled");
|
||||
} else
|
||||
snprintf(value, sizeof(value), "unsupported");
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header),
|
||||
"speed-select-base-freq");
|
||||
@ -416,7 +452,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
||||
snprintf(value, sizeof(value), "disabled");
|
||||
} else
|
||||
snprintf(value, sizeof(value), "unsupported");
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header),
|
||||
"speed-select-core-power");
|
||||
@ -427,110 +463,115 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
||||
snprintf(value, sizeof(value), "disabled");
|
||||
} else
|
||||
snprintf(value, sizeof(value), "unsupported");
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
if (is_clx_n_platform()) {
|
||||
if (ctdp_level->pbf_support)
|
||||
_isst_pbf_display_information(cpu, outf,
|
||||
tdp_level,
|
||||
&ctdp_level->pbf_info,
|
||||
base_level + 4);
|
||||
level + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctdp_level->pkg_tdp) {
|
||||
snprintf(header, sizeof(header), "thermal-design-power(W)");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
}
|
||||
|
||||
if (ctdp_level->t_proc_hot) {
|
||||
snprintf(header, sizeof(header), "tjunction-max(C)");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
}
|
||||
|
||||
snprintf(header, sizeof(header), "turbo-ratio-limits-sse");
|
||||
format_and_print(outf, base_level + 4, header, NULL);
|
||||
format_and_print(outf, level + 2, header, NULL);
|
||||
for (j = 0; j < 8; ++j) {
|
||||
snprintf(header, sizeof(header), "bucket-%d", j);
|
||||
format_and_print(outf, base_level + 5, header, NULL);
|
||||
format_and_print(outf, level + 3, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "core-count");
|
||||
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
format_and_print(outf, level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header),
|
||||
"max-turbo-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->trl_sse_active_cores[j] *
|
||||
DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
format_and_print(outf, level + 4, header, value);
|
||||
}
|
||||
|
||||
if (ctdp_level->trl_avx_active_cores[0]) {
|
||||
snprintf(header, sizeof(header), "turbo-ratio-limits-avx2");
|
||||
format_and_print(outf, base_level + 4, header, NULL);
|
||||
format_and_print(outf, level + 2, header, NULL);
|
||||
for (j = 0; j < 8; ++j) {
|
||||
snprintf(header, sizeof(header), "bucket-%d", j);
|
||||
format_and_print(outf, base_level + 5, header, NULL);
|
||||
format_and_print(outf, level + 3, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "core-count");
|
||||
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
format_and_print(outf, level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "max-turbo-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_active_cores[j] * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
format_and_print(outf, level + 4, header, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctdp_level->trl_avx_512_active_cores[0]) {
|
||||
snprintf(header, sizeof(header), "turbo-ratio-limits-avx512");
|
||||
format_and_print(outf, base_level + 4, header, NULL);
|
||||
format_and_print(outf, level + 2, header, NULL);
|
||||
for (j = 0; j < 8; ++j) {
|
||||
snprintf(header, sizeof(header), "bucket-%d", j);
|
||||
format_and_print(outf, base_level + 5, header, NULL);
|
||||
format_and_print(outf, level + 3, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "core-count");
|
||||
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
format_and_print(outf, level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "max-turbo-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_512_active_cores[j] * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
format_and_print(outf, level + 4, header, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctdp_level->pbf_support)
|
||||
_isst_pbf_display_information(cpu, outf, i,
|
||||
&ctdp_level->pbf_info,
|
||||
base_level + 4);
|
||||
level + 2);
|
||||
if (ctdp_level->fact_support)
|
||||
_isst_fact_display_information(cpu, outf, i, 0xff, 0xff,
|
||||
&ctdp_level->fact_info,
|
||||
base_level + 4);
|
||||
level + 2);
|
||||
}
|
||||
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
static int start;
|
||||
void isst_ctdp_display_information_start(FILE *outf)
|
||||
{
|
||||
last_level = 0;
|
||||
format_and_print(outf, 0, "start", NULL);
|
||||
start = 1;
|
||||
}
|
||||
|
||||
void isst_ctdp_display_information_end(FILE *outf)
|
||||
{
|
||||
format_and_print(outf, 0, NULL, NULL);
|
||||
start = 0;
|
||||
}
|
||||
|
||||
void isst_pbf_display_information(int cpu, FILE *outf, int level,
|
||||
struct isst_pbf_info *pbf_info)
|
||||
{
|
||||
print_package_info(cpu, outf);
|
||||
_isst_pbf_display_information(cpu, outf, level, pbf_info, 4);
|
||||
int _level;
|
||||
|
||||
_level = print_package_info(cpu, outf);
|
||||
_isst_pbf_display_information(cpu, outf, level, pbf_info, _level + 1);
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
@ -538,9 +579,11 @@ void isst_fact_display_information(int cpu, FILE *outf, int level,
|
||||
int fact_bucket, int fact_avx,
|
||||
struct isst_fact_info *fact_info)
|
||||
{
|
||||
print_package_info(cpu, outf);
|
||||
int _level;
|
||||
|
||||
_level = print_package_info(cpu, outf);
|
||||
_isst_fact_display_information(cpu, outf, level, fact_bucket, fact_avx,
|
||||
fact_info, 4);
|
||||
fact_info, _level + 1);
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
@ -549,94 +592,103 @@ void isst_clos_display_information(int cpu, FILE *outf, int clos,
|
||||
{
|
||||
char header[256];
|
||||
char value[256];
|
||||
int level;
|
||||
|
||||
snprintf(header, sizeof(header), "package-%d",
|
||||
get_physical_package_id(cpu));
|
||||
format_and_print(outf, 1, header, NULL);
|
||||
snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
|
||||
format_and_print(outf, 2, header, NULL);
|
||||
snprintf(header, sizeof(header), "cpu-%d", cpu);
|
||||
format_and_print(outf, 3, header, NULL);
|
||||
level = print_package_info(cpu, outf);
|
||||
|
||||
snprintf(header, sizeof(header), "core-power");
|
||||
format_and_print(outf, 4, header, NULL);
|
||||
format_and_print(outf, level + 1, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "clos");
|
||||
snprintf(value, sizeof(value), "%d", clos);
|
||||
format_and_print(outf, 5, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "epp");
|
||||
snprintf(value, sizeof(value), "%d", clos_config->epp);
|
||||
format_and_print(outf, 5, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "clos-proportional-priority");
|
||||
snprintf(value, sizeof(value), "%d", clos_config->clos_prop_prio);
|
||||
format_and_print(outf, 5, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "clos-min");
|
||||
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, 5, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "clos-max");
|
||||
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, 5, header, value);
|
||||
if (clos_config->clos_max == 0xff)
|
||||
snprintf(value, sizeof(value), "Max Turbo frequency");
|
||||
else
|
||||
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "clos-desired");
|
||||
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, 5, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
format_and_print(outf, level, NULL, NULL);
|
||||
}
|
||||
|
||||
void isst_clos_display_clos_information(int cpu, FILE *outf,
|
||||
int clos_enable, int type)
|
||||
int clos_enable, int type,
|
||||
int state, int cap)
|
||||
{
|
||||
char header[256];
|
||||
char value[256];
|
||||
int level;
|
||||
|
||||
snprintf(header, sizeof(header), "package-%d",
|
||||
get_physical_package_id(cpu));
|
||||
format_and_print(outf, 1, header, NULL);
|
||||
snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
|
||||
format_and_print(outf, 2, header, NULL);
|
||||
snprintf(header, sizeof(header), "cpu-%d", cpu);
|
||||
format_and_print(outf, 3, header, NULL);
|
||||
level = print_package_info(cpu, outf);
|
||||
|
||||
snprintf(header, sizeof(header), "core-power");
|
||||
format_and_print(outf, 4, header, NULL);
|
||||
format_and_print(outf, level + 1, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "support-status");
|
||||
if (cap)
|
||||
snprintf(value, sizeof(value), "supported");
|
||||
else
|
||||
snprintf(value, sizeof(value), "unsupported");
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "enable-status");
|
||||
snprintf(value, sizeof(value), "%d", clos_enable);
|
||||
format_and_print(outf, 5, header, value);
|
||||
if (state)
|
||||
snprintf(value, sizeof(value), "enabled");
|
||||
else
|
||||
snprintf(value, sizeof(value), "disabled");
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "clos-enable-status");
|
||||
if (clos_enable)
|
||||
snprintf(value, sizeof(value), "enabled");
|
||||
else
|
||||
snprintf(value, sizeof(value), "disabled");
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "priority-type");
|
||||
snprintf(value, sizeof(value), "%d", type);
|
||||
format_and_print(outf, 5, header, value);
|
||||
if (type)
|
||||
snprintf(value, sizeof(value), "ordered");
|
||||
else
|
||||
snprintf(value, sizeof(value), "proportional");
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
format_and_print(outf, level, NULL, NULL);
|
||||
}
|
||||
|
||||
void isst_clos_display_assoc_information(int cpu, FILE *outf, int clos)
|
||||
{
|
||||
char header[256];
|
||||
char value[256];
|
||||
int level;
|
||||
|
||||
snprintf(header, sizeof(header), "package-%d",
|
||||
get_physical_package_id(cpu));
|
||||
format_and_print(outf, 1, header, NULL);
|
||||
snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
|
||||
format_and_print(outf, 2, header, NULL);
|
||||
snprintf(header, sizeof(header), "cpu-%d", cpu);
|
||||
format_and_print(outf, 3, header, NULL);
|
||||
level = print_package_info(cpu, outf);
|
||||
|
||||
snprintf(header, sizeof(header), "get-assoc");
|
||||
format_and_print(outf, 4, header, NULL);
|
||||
format_and_print(outf, level + 1, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "clos");
|
||||
snprintf(value, sizeof(value), "%d", clos);
|
||||
format_and_print(outf, 5, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
format_and_print(outf, level, NULL, NULL);
|
||||
}
|
||||
|
||||
void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
|
||||
@ -644,24 +696,60 @@ void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
|
||||
{
|
||||
char header[256];
|
||||
char value[256];
|
||||
int level = 3;
|
||||
|
||||
if (cpu >= 0)
|
||||
level = print_package_info(cpu, outf);
|
||||
|
||||
if (cpu >= 0) {
|
||||
snprintf(header, sizeof(header), "package-%d",
|
||||
get_physical_package_id(cpu));
|
||||
format_and_print(outf, 1, header, NULL);
|
||||
snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
|
||||
format_and_print(outf, 2, header, NULL);
|
||||
snprintf(header, sizeof(header), "cpu-%d", cpu);
|
||||
format_and_print(outf, 3, header, NULL);
|
||||
}
|
||||
snprintf(header, sizeof(header), "%s", feature);
|
||||
format_and_print(outf, 4, header, NULL);
|
||||
format_and_print(outf, level + 1, header, NULL);
|
||||
snprintf(header, sizeof(header), "%s", cmd);
|
||||
if (!result)
|
||||
snprintf(value, sizeof(value), "success");
|
||||
else
|
||||
snprintf(value, sizeof(value), "failed(error %d)", result);
|
||||
format_and_print(outf, 5, header, value);
|
||||
format_and_print(outf, level + 2, header, value);
|
||||
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
format_and_print(outf, level, NULL, NULL);
|
||||
}
|
||||
|
||||
void isst_display_error_info_message(int error, char *msg, int arg_valid, int arg)
|
||||
{
|
||||
FILE *outf = get_output_file();
|
||||
static int error_index;
|
||||
char header[256];
|
||||
char value[256];
|
||||
|
||||
if (!out_format_is_json()) {
|
||||
if (arg_valid)
|
||||
snprintf(value, sizeof(value), "%s %d", msg, arg);
|
||||
else
|
||||
snprintf(value, sizeof(value), "%s", msg);
|
||||
|
||||
if (error)
|
||||
fprintf(outf, "Error: %s\n", value);
|
||||
else
|
||||
fprintf(outf, "Information: %s\n", value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!start)
|
||||
format_and_print(outf, 0, "start", NULL);
|
||||
|
||||
if (error)
|
||||
snprintf(header, sizeof(header), "Error%d", error_index++);
|
||||
else
|
||||
snprintf(header, sizeof(header), "Information:%d", error_index++);
|
||||
format_and_print(outf, 1, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "message");
|
||||
if (arg_valid)
|
||||
snprintf(value, sizeof(value), "%s %d", msg, arg);
|
||||
else
|
||||
snprintf(value, sizeof(value), "%s", msg);
|
||||
|
||||
format_and_print(outf, 2, header, value);
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
if (!start)
|
||||
format_and_print(outf, 0, NULL, NULL);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user