Commit dba43fc4 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull x86 platform driver updates from Andy Shevchenko:

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

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

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

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

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

 - Clean up of Dell RBU driver.

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

* tag 'platform-drivers-x86-v5.7-1' of git://git.infradead.org/linux-platform-drivers-x86: (75 commits)
  platform/x86: surface3_power: Fix always true condition in mshw0011_space_handler()
  platform/x86: surface3_power: Fix Kconfig section ordering
  platform/x86: surface3_power: Add missed headers
  platform/x86: surface3_power: Reformat GUID assignment
  platform/x86: surface3_power: Drop useless macro ACPI_PTR()
  platform/x86: surface3_power: Prefix POLL_INTERVAL with SURFACE_3
  platform/x86: surface3_power: Simplify mshw0011_adp_psr() to one liner
  platform/x86: surface3_power: Use dev_err() instead of pr_err()
  platform/x86: surface3_power: Drop unused structure definition
  platform/x86: surface3_power: MSHW0011 rev-eng implementation
  platform/x86: intel_pmc_core: Make pmc_core_substate_res_show() generic
  platform/x86: intel_pmc_core: Make pmc_core_lpm_display() generic for platforms that support sub-states
  tools/power/x86/intel-speed-select: Fix a typo in error message
  tools/power/x86/intel-speed-select: Update version
  tools/power/x86/intel-speed-select: Avoid duplicate Package strings for json
  tools/power/x86/intel-speed-select: Add display for enabled cpus count
  tools/power/x86/intel-speed-select: Print friendly warning for bad command line
  tools/power/x86/intel-speed-select: Fix avx options for turbo-freq feature
  tools/power/x86/intel-speed-select: Improve CLX commands
  tools/power/x86/intel-speed-select: Show error for invalid CPUs in the options
  ...
parents 1f944f97 d878bdfb
...@@ -303,8 +303,8 @@ F: drivers/net/ethernet/alteon/acenic* ...@@ -303,8 +303,8 @@ F: drivers/net/ethernet/alteon/acenic*
ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER
M: Peter Kaestle <peter@piie.net> M: Peter Kaestle <peter@piie.net>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
W: http://piie.net/?section=acerhdf
S: Maintained S: Maintained
W: http://piie.net/?section=acerhdf
F: drivers/platform/x86/acerhdf.c F: drivers/platform/x86/acerhdf.c
ACER WMI LAPTOP EXTRAS ACER WMI LAPTOP EXTRAS
...@@ -2766,8 +2766,8 @@ ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS ...@@ -2766,8 +2766,8 @@ ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS
M: Corentin Chary <corentin.chary@gmail.com> M: Corentin Chary <corentin.chary@gmail.com>
L: acpi4asus-user@lists.sourceforge.net L: acpi4asus-user@lists.sourceforge.net
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
W: http://acpi4asus.sf.net
S: Maintained S: Maintained
W: http://acpi4asus.sf.net
F: drivers/platform/x86/asus*.c F: drivers/platform/x86/asus*.c
F: drivers/platform/x86/eeepc*.c F: drivers/platform/x86/eeepc*.c
...@@ -4745,26 +4745,6 @@ S: Maintained ...@@ -4745,26 +4745,6 @@ S: Maintained
F: drivers/media/platform/sunxi/sun8i-di/ F: drivers/media/platform/sunxi/sun8i-di/
F: Documentation/devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml 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 DEFZA FDDI NETWORK DRIVER
M: "Maciej W. Rozycki" <macro@linux-mips.org> M: "Maciej W. Rozycki" <macro@linux-mips.org>
S: Maintained S: Maintained
...@@ -4787,17 +4767,37 @@ M: Pali Rohár <pali.rohar@gmail.com> ...@@ -4787,17 +4767,37 @@ M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained S: Maintained
F: drivers/platform/x86/dell-rbtn.* 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 DELL REMOTE BIOS UPDATE DRIVER
M: Stuart Hayes <stuart.w.hayes@gmail.com> M: Stuart Hayes <stuart.w.hayes@gmail.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Maintained S: Maintained
F: drivers/platform/x86/dell_rbu.c F: drivers/platform/x86/dell_rbu.c
DELL LAPTOP SMM DRIVER DELL SMBIOS DRIVER
M: Pali Rohár <pali.rohar@gmail.com> M: Pali Rohár <pali.rohar@gmail.com>
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained S: Maintained
F: drivers/hwmon/dell-smm-hwmon.c F: drivers/platform/x86/dell-smbios.*
F: include/uapi/linux/i8k.h
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) DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
M: Stuart Hayes <stuart.w.hayes@gmail.com> M: Stuart Hayes <stuart.w.hayes@gmail.com>
...@@ -4806,17 +4806,17 @@ S: Maintained ...@@ -4806,17 +4806,17 @@ S: Maintained
F: Documentation/driver-api/dcdbas.rst F: Documentation/driver-api/dcdbas.rst
F: drivers/platform/x86/dcdbas.* 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 DELL WMI NOTIFICATIONS DRIVER
M: Matthew Garrett <mjg59@srcf.ucam.org> M: Matthew Garrett <mjg59@srcf.ucam.org>
M: Pali Rohár <pali.rohar@gmail.com> M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained S: Maintained
F: drivers/platform/x86/dell-wmi.c 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 DELTA ST MEDIA DRIVER
M: Hugues Fruchet <hugues.fruchet@st.com> M: Hugues Fruchet <hugues.fruchet@st.com>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
...@@ -7375,8 +7375,8 @@ F: drivers/media/usb/hackrf/ ...@@ -7375,8 +7375,8 @@ F: drivers/media/usb/hackrf/
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
M: Frank Seidel <frank@f-seidel.de> M: Frank Seidel <frank@f-seidel.de>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
S: Maintained S: Maintained
W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
F: drivers/platform/x86/hdaps.c F: drivers/platform/x86/hdaps.c
HARDWARE MONITORING HARDWARE MONITORING
...@@ -8119,15 +8119,15 @@ F: drivers/ide/ide-cd* ...@@ -8119,15 +8119,15 @@ F: drivers/ide/ide-cd*
IDEAPAD LAPTOP EXTRAS DRIVER IDEAPAD LAPTOP EXTRAS DRIVER
M: Ike Panhc <ike.pan@canonical.com> M: Ike Panhc <ike.pan@canonical.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
W: http://launchpad.net/ideapad-laptop
S: Maintained S: Maintained
W: http://launchpad.net/ideapad-laptop
F: drivers/platform/x86/ideapad-laptop.c F: drivers/platform/x86/ideapad-laptop.c
IDEAPAD LAPTOP SLIDEBAR DRIVER IDEAPAD LAPTOP SLIDEBAR DRIVER
M: Andrey Moiseev <o2g.org.ru@gmail.com> M: Andrey Moiseev <o2g.org.ru@gmail.com>
L: linux-input@vger.kernel.org L: linux-input@vger.kernel.org
W: https://github.com/o2genum/ideapad-slidebar
S: Maintained S: Maintained
W: https://github.com/o2genum/ideapad-slidebar
F: drivers/input/misc/ideapad_slidebar.c F: drivers/input/misc/ideapad_slidebar.c
IDT VersaClock 5 CLOCK DRIVER IDT VersaClock 5 CLOCK DRIVER
...@@ -8593,8 +8593,8 @@ F: samples/mei/* ...@@ -8593,8 +8593,8 @@ F: samples/mei/*
INTEL MENLOW THERMAL DRIVER INTEL MENLOW THERMAL DRIVER
M: Sujith Thomas <sujith.thomas@intel.com> M: Sujith Thomas <sujith.thomas@intel.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
W: https://01.org/linux-acpi
S: Supported S: Supported
W: https://01.org/linux-acpi
F: drivers/platform/x86/intel_menlow.c F: drivers/platform/x86/intel_menlow.c
INTEL MIC DRIVERS (mic) INTEL MIC DRIVERS (mic)
...@@ -8624,10 +8624,10 @@ INTEL PMC/P-Unit IPC DRIVER ...@@ -8624,10 +8624,10 @@ INTEL PMC/P-Unit IPC DRIVER
M: Zha Qipeng<qipeng.zha@intel.com> M: Zha Qipeng<qipeng.zha@intel.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Maintained 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_pmc_ipc.h
F: arch/x86/include/asm/intel_punit_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 INTEL PMIC GPIO DRIVERS
M: Andy Shevchenko <andy@kernel.org> M: Andy Shevchenko <andy@kernel.org>
...@@ -8672,8 +8672,8 @@ M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> ...@@ -8672,8 +8672,8 @@ M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Maintained S: Maintained
F: drivers/platform/x86/intel_speed_select_if/ F: drivers/platform/x86/intel_speed_select_if/
F: tools/power/x86/intel-speed-select/
F: include/uapi/linux/isst_if.h F: include/uapi/linux/isst_if.h
F: tools/power/x86/intel-speed-select/
INTEL STRATIX10 FIRMWARE DRIVERS INTEL STRATIX10 FIRMWARE DRIVERS
M: Richard Gong <richard.gong@linux.intel.com> M: Richard Gong <richard.gong@linux.intel.com>
...@@ -15626,8 +15626,8 @@ F: include/linux/memstick.h ...@@ -15626,8 +15626,8 @@ F: include/linux/memstick.h
SONY VAIO CONTROL DEVICE DRIVER SONY VAIO CONTROL DEVICE DRIVER
M: Mattia Dongili <malattia@linux.it> M: Mattia Dongili <malattia@linux.it>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers
S: Maintained S: Maintained
W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers
F: Documentation/admin-guide/laptops/sony-laptop.rst F: Documentation/admin-guide/laptops/sony-laptop.rst
F: drivers/char/sonypi.c F: drivers/char/sonypi.c
F: drivers/platform/x86/sony-laptop.c F: drivers/platform/x86/sony-laptop.c
...@@ -16602,10 +16602,10 @@ THINKPAD ACPI EXTRAS DRIVER ...@@ -16602,10 +16602,10 @@ THINKPAD ACPI EXTRAS DRIVER
M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
L: ibm-acpi-devel@lists.sourceforge.net L: ibm-acpi-devel@lists.sourceforge.net
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Maintained
W: http://ibm-acpi.sourceforge.net W: http://ibm-acpi.sourceforge.net
W: http://thinkwiki.org/wiki/Ibm-acpi 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 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 F: drivers/platform/x86/thinkpad_acpi.c
THUNDERBOLT DRIVER THUNDERBOLT DRIVER
...@@ -18250,10 +18250,10 @@ X86 PLATFORM DRIVERS ...@@ -18250,10 +18250,10 @@ X86 PLATFORM DRIVERS
M: Darren Hart <dvhart@infradead.org> M: Darren Hart <dvhart@infradead.org>
M: Andy Shevchenko <andy@infradead.org> M: Andy Shevchenko <andy@infradead.org>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
T: git git://git.infradead.org/linux-platform-drivers-x86.git
S: Odd Fixes 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/olpc/
F: drivers/platform/x86/
X86 PLATFORM DRIVERS - ARCH X86 PLATFORM DRIVERS - ARCH
R: Darren Hart <dvhart@infradead.org> R: Darren Hart <dvhart@infradead.org>
......
...@@ -16,40 +16,103 @@ menuconfig X86_PLATFORM_DEVICES ...@@ -16,40 +16,103 @@ menuconfig X86_PLATFORM_DEVICES
if X86_PLATFORM_DEVICES if X86_PLATFORM_DEVICES
config ACER_WMI config ACPI_WMI
tristate "Acer WMI Laptop Extras" tristate "WMI"
depends on ACPI
help
This driver adds support for the ACPI-WMI (Windows Management
Instrumentation) mapper device (PNP0C14) found on some systems.
ACPI-WMI is a proprietary extension to ACPI to expose parts of the
ACPI firmware to userspace - this is done through various vendor
defined methods and data blocks in a PNP0C14 device, which are then
made available for userspace to call.
The implementation of this in Linux currently only exposes this to
other kernel space drivers.
This driver is a required dependency to build the firmware specific
drivers needed on many machines, including Acer and HP laptops.
It is safe to enable this driver even if your DSDT doesn't define
any ACPI-WMI devices.
config WMI_BMOF
tristate "WMI embedded Binary MOF driver"
depends on ACPI_WMI
default ACPI_WMI
---help---
Say Y here if you want to be able to read a firmware-embedded
WMI Binary MOF data. Using this requires userspace tools and may be
rather tedious.
To compile this driver as a module, choose M here: the module will
be called wmi-bmof.
config ALIENWARE_WMI
tristate "Alienware Special feature control"
depends on ACPI depends on ACPI
depends on LEDS_CLASS
depends on NEW_LEDS
depends on ACPI_WMI
---help---
This is a driver for controlling Alienware BIOS driven
features. It exposes an interface for controlling the AlienFX
zones on Alienware machines that don't contain a dedicated AlienFX
USB MCU such as the X51 and X51-R2.
config HUAWEI_WMI
tristate "Huawei WMI laptop extras driver"
depends on ACPI_BATTERY
depends on ACPI_WMI
depends on INPUT
select INPUT_SPARSEKMAP
select LEDS_CLASS select LEDS_CLASS
select LEDS_TRIGGERS
select LEDS_TRIGGER_AUDIO
select NEW_LEDS select NEW_LEDS
depends on BACKLIGHT_CLASS_DEVICE help
depends on SERIO_I8042 This driver provides support for Huawei WMI hotkeys, battery charge
depends on INPUT control, fn-lock, mic-mute LED, and other extra features.
depends on RFKILL || RFKILL = n
To compile this driver as a module, choose M here: the module
will be called huawei-wmi.
config INTEL_WMI_THUNDERBOLT
tristate "Intel WMI thunderbolt force power driver"
depends on ACPI_WMI depends on ACPI_WMI
select INPUT_SPARSEKMAP
# Acer WMI depends on ACPI_VIDEO when ACPI is enabled
select ACPI_VIDEO if ACPI
---help--- ---help---
This is a driver for newer Acer (and Wistron) laptops. It adds Say Y here if you want to be able to use the WMI interface on select
wireless radio and bluetooth control, and on some laptops, systems to force the power control of Intel Thunderbolt controllers.
exposes the mail LED and LCD backlight. This is useful for updating the firmware when devices are not plugged
into the controller.
If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M To compile this driver as a module, choose M here: the module will
here. be called intel-wmi-thunderbolt.
config ACER_WIRELESS config MXM_WMI
tristate "Acer Wireless Radio Control Driver" tristate "WMI support for MXM Laptop Graphics"
depends on ACPI depends on ACPI_WMI
depends on INPUT ---help---
---help--- MXM is a standard for laptop graphics cards, the WMI interface
The Acer Wireless Radio Control handles the airplane mode hotkey is required for switchable nvidia graphics machines
present on new Acer laptops.
Say Y or M here if you have an Acer notebook with an airplane mode config PEAQ_WMI
hotkey. tristate "PEAQ 2-in-1 WMI hotkey driver"
depends on ACPI_WMI
depends on INPUT
help
Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
If you choose to compile this driver as a module the module will be config XIAOMI_WMI
called acer-wireless. tristate "Xiaomi WMI key driver"
depends on ACPI_WMI
depends on INPUT
help
Say Y here if you want to support WMI-based keys on Xiaomi notebooks.
To compile this driver as a module, choose M here: the module will
be called xiaomi-wmi.
config ACERHDF config ACERHDF
tristate "Acer Aspire One temperature and fan driver" tristate "Acer Aspire One temperature and fan driver"
...@@ -72,17 +135,53 @@ config ACERHDF ...@@ -72,17 +135,53 @@ config ACERHDF
If you have an Acer Aspire One netbook, say Y or M If you have an Acer Aspire One netbook, say Y or M
here. here.
config ALIENWARE_WMI config ACER_WIRELESS
tristate "Alienware Special feature control" tristate "Acer Wireless Radio Control Driver"
depends on ACPI
depends on INPUT
---help---
The Acer Wireless Radio Control handles the airplane mode hotkey
present on new Acer laptops.
Say Y or M here if you have an Acer notebook with an airplane mode
hotkey.
If you choose to compile this driver as a module the module will be
called acer-wireless.
config ACER_WMI
tristate "Acer WMI Laptop Extras"
depends on ACPI depends on ACPI
depends on LEDS_CLASS select LEDS_CLASS
depends on NEW_LEDS select NEW_LEDS
depends on BACKLIGHT_CLASS_DEVICE
depends on SERIO_I8042
depends on INPUT
depends on RFKILL || RFKILL = n
depends on ACPI_WMI depends on ACPI_WMI
select INPUT_SPARSEKMAP
# Acer WMI depends on ACPI_VIDEO when ACPI is enabled
select ACPI_VIDEO if ACPI
---help--- ---help---
This is a driver for controlling Alienware BIOS driven This is a driver for newer Acer (and Wistron) laptops. It adds
features. It exposes an interface for controlling the AlienFX wireless radio and bluetooth control, and on some laptops,
zones on Alienware machines that don't contain a dedicated AlienFX exposes the mail LED and LCD backlight.
USB MCU such as the X51 and X51-R2.
If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M
here.
config APPLE_GMUX
tristate "Apple Gmux Driver"
depends on ACPI && PCI
depends on PNP
depends on BACKLIGHT_CLASS_DEVICE
depends on BACKLIGHT_APPLE=n || BACKLIGHT_APPLE
depends on ACPI_VIDEO=n || ACPI_VIDEO
---help---
This driver provides support for the gmux device found on many
Apple laptops, which controls the display mux for the hybrid
graphics as well as the backlight. Currently only backlight
control is supported by the driver.
config ASUS_LAPTOP config ASUS_LAPTOP
tristate "Asus Laptop Extras" tristate "Asus Laptop Extras"
...@@ -108,6 +207,91 @@ config ASUS_LAPTOP ...@@ -108,6 +207,91 @@ config ASUS_LAPTOP
If you have an ACPI-compatible ASUS laptop, say Y or M here. If you have an ACPI-compatible ASUS laptop, say Y or M here.
config ASUS_WIRELESS
tristate "Asus Wireless Radio Control Driver"
depends on ACPI
depends on INPUT
select NEW_LEDS
select LEDS_CLASS
---help---
The Asus Wireless Radio Control handles the airplane mode hotkey
present on some Asus laptops.
Say Y or M here if you have an ASUS notebook with an airplane mode
hotkey.
If you choose to compile this driver as a module the module will be
called asus-wireless.
config ASUS_WMI
tristate "ASUS WMI Driver"
depends on ACPI_WMI
depends on ACPI_BATTERY
depends on INPUT
depends on HWMON
depends on BACKLIGHT_CLASS_DEVICE
depends on RFKILL || RFKILL = n
depends on HOTPLUG_PCI
depends on ACPI_VIDEO || ACPI_VIDEO = n
select INPUT_SPARSEKMAP
select LEDS_CLASS
select NEW_LEDS
---help---
Say Y here if you have a WMI aware Asus laptop (like Eee PCs or new
Asus Notebooks).
To compile this driver as a module, choose M here: the module will
be called asus-wmi.
config ASUS_NB_WMI
tristate "Asus Notebook WMI Driver"
depends on ASUS_WMI
depends on SERIO_I8042 || SERIO_I8042 = n
---help---
This is a driver for newer Asus notebooks. It adds extra features
like wireless radio and bluetooth control, leds, hotkeys, backlight...
For more information, see
<file:Documentation/ABI/testing/sysfs-platform-asus-wmi>
If you have an ACPI-WMI compatible Asus Notebook, say Y or M
here.
config EEEPC_LAPTOP
tristate "Eee PC Hotkey Driver"
depends on ACPI
depends on INPUT
depends on RFKILL || RFKILL = n
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on HOTPLUG_PCI
depends on BACKLIGHT_CLASS_DEVICE
select HWMON
select LEDS_CLASS
select NEW_LEDS
select INPUT_SPARSEKMAP
---help---
This driver supports the Fn-Fx keys on Eee PC laptops.
It also gives access to some extra laptop functionalities like
Bluetooth, backlight and allows powering on/off some other
devices.
If you have an Eee PC laptop, say Y or M here. If this driver
doesn't work on your Eee PC, try eeepc-wmi instead.
config EEEPC_WMI
tristate "Eee PC WMI Driver"
depends on ASUS_WMI
---help---
This is a driver for newer Eee PC laptops. It adds extra features
like wireless radio and bluetooth control, leds, hotkeys, backlight...
For more information, see
<file:Documentation/ABI/testing/sysfs-platform-asus-wmi>
If you have an ACPI-WMI compatible Eee PC laptop (>= 1000), say Y or M
here.
config DCDBAS config DCDBAS
tristate "Dell Systems Management Base Driver" tristate "Dell Systems Management Base Driver"
depends on X86 depends on X86
...@@ -183,10 +367,48 @@ config DELL_LAPTOP ...@@ -183,10 +367,48 @@ config DELL_LAPTOP
This driver adds support for rfkill and backlight control to Dell This driver adds support for rfkill and backlight control to Dell
laptops (except for some models covered by the Compal driver). laptops (except for some models covered by the Compal driver).
config DELL_WMI config DELL_RBTN
tristate "Dell WMI notifications" tristate "Dell Airplane Mode Switch driver"
depends on ACPI_WMI depends on ACPI
depends on DMI depends on INPUT
depends on RFKILL
---help---
Say Y here if you want to support Dell Airplane Mode Switch ACPI
device on Dell laptops. Sometimes it has names: DELLABCE or DELRBTN.
This driver register rfkill device or input hotkey device depending
on hardware type (hw switch slider or keyboard toggle button). For
rfkill devices it receive HW switch events and set correct hard
rfkill state.
To compile this driver as a module, choose M here: the module will
be called dell-rbtn.
config DELL_RBU
tristate "BIOS update support for DELL systems via sysfs"
depends on X86
select FW_LOADER
select FW_LOADER_USER_HELPER
help
Say m if you want to have the option of updating the BIOS for your
DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
supporting application to communicate with the BIOS regarding the new
image for the image update to take effect.
See <file:Documentation/admin-guide/dell_rbu.rst> for more details on the driver.
config DELL_SMO8800
tristate "Dell Latitude freefall driver (ACPI SMO88XX)"
depends on ACPI
---help---
Say Y here if you want to support SMO88XX freefall devices
on Dell Latitude laptops.
To compile this driver as a module, choose M here: the module will
be called dell-smo8800.
config DELL_WMI
tristate "Dell WMI notifications"
depends on ACPI_WMI
depends on DMI
depends on INPUT depends on INPUT
depends on ACPI_VIDEO || ACPI_VIDEO = n depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on DELL_SMBIOS depends on DELL_SMBIOS
...@@ -222,44 +444,13 @@ config DELL_WMI_LED ...@@ -222,44 +444,13 @@ config DELL_WMI_LED
This adds support for the Latitude 2100 and similar This adds support for the Latitude 2100 and similar
notebooks that have an external LED. notebooks that have an external LED.
config DELL_SMO8800 config AMILO_RFKILL
tristate "Dell Latitude freefall driver (ACPI SMO88XX)" tristate "Fujitsu-Siemens Amilo rfkill support"
depends on ACPI
---help---
Say Y here if you want to support SMO88XX freefall devices
on Dell Latitude laptops.
To compile this driver as a module, choose M here: the module will
be called dell-smo8800.
config DELL_RBTN
tristate "Dell Airplane Mode Switch driver"
depends on ACPI
depends on INPUT
depends on RFKILL depends on RFKILL
depends on SERIO_I8042
---help--- ---help---
Say Y here if you want to support Dell Airplane Mode Switch ACPI This is a driver for enabling wifi on some Fujitsu-Siemens Amilo
device on Dell laptops. Sometimes it has names: DELLABCE or DELRBTN. laptops.
This driver register rfkill device or input hotkey device depending
on hardware type (hw switch slider or keyboard toggle button). For
rfkill devices it receive HW switch events and set correct hard
rfkill state.
To compile this driver as a module, choose M here: the module will
be called dell-rbtn.
config DELL_RBU
tristate "BIOS update support for DELL systems via sysfs"
depends on X86
select FW_LOADER
select FW_LOADER_USER_HELPER
help
Say m if you want to have the option of updating the BIOS for your
DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
supporting application to communicate with the BIOS regarding the new
image for the image update to take effect.
See <file:Documentation/admin-guide/dell_rbu.rst> for more details on the driver.
config FUJITSU_LAPTOP config FUJITSU_LAPTOP
tristate "Fujitsu Laptop Extras" tristate "Fujitsu Laptop Extras"
...@@ -297,14 +488,6 @@ config FUJITSU_TABLET ...@@ -297,14 +488,6 @@ config FUJITSU_TABLET
If you have a Fujitsu convertible or slate, say Y or M here. If you have a Fujitsu convertible or slate, say Y or M here.
config AMILO_RFKILL
tristate "Fujitsu-Siemens Amilo rfkill support"
depends on RFKILL
depends on SERIO_I8042
---help---
This is a driver for enabling wifi on some Fujitsu-Siemens Amilo
laptops.
config GPD_POCKET_FAN config GPD_POCKET_FAN
tristate "GPD Pocket Fan Controller support" tristate "GPD Pocket Fan Controller support"
depends on ACPI depends on ACPI
...@@ -317,15 +500,6 @@ config GPD_POCKET_FAN ...@@ -317,15 +500,6 @@ config GPD_POCKET_FAN
of the CPU temperature. Say Y or M if the kernel may be used on a of the CPU temperature. Say Y or M if the kernel may be used on a
GPD pocket. GPD pocket.
config TC1100_WMI
tristate "HP Compaq TC1100 Tablet WMI Extras"
depends on !X86_64
depends on ACPI
depends on ACPI_WMI
---help---
This is a driver for the WMI extensions (wireless and bluetooth power
control) of the HP Compaq TC1100 tablet.
config HP_ACCEL config HP_ACCEL
tristate "HP laptop accelerometer" tristate "HP laptop accelerometer"
depends on INPUT && ACPI depends on INPUT && ACPI
...@@ -369,91 +543,30 @@ config HP_WMI ...@@ -369,91 +543,30 @@ config HP_WMI
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called hp-wmi. be called hp-wmi.
config LG_LAPTOP config TC1100_WMI
tristate "LG Laptop Extras" tristate "HP Compaq TC1100 Tablet WMI Extras"
depends on !X86_64
depends on ACPI depends on ACPI
depends on ACPI_WMI depends on ACPI_WMI
depends on INPUT
select INPUT_SPARSEKMAP
select LEDS_CLASS
help
This driver adds support for hotkeys as well as control of keyboard
backlight, battery maximum charge level and various other ACPI
features.
If you have an LG Gram laptop, say Y or M here.
config MSI_LAPTOP
tristate "MSI Laptop Extras"
depends on ACPI
depends on BACKLIGHT_CLASS_DEVICE
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on RFKILL
depends on INPUT && SERIO_I8042
select INPUT_SPARSEKMAP
---help---
This is a driver for laptops built by MSI (MICRO-STAR
INTERNATIONAL):
MSI MegaBook S270 (MS-1013)
Cytron/TCM/Medion/Tchibo MD96100/SAM2000
It adds support for Bluetooth, WLAN and LCD brightness control.
More information about this driver is available at
<http://0pointer.de/lennart/tchibo.html>.
If you have an MSI S270 laptop, say Y or M here.
config PANASONIC_LAPTOP
tristate "Panasonic Laptop Extras"
depends on INPUT && ACPI
depends on BACKLIGHT_CLASS_DEVICE
select INPUT_SPARSEKMAP
---help--- ---help---
This driver adds support for access to backlight control and hotkeys This is a driver for the WMI extensions (wireless and bluetooth power
on Panasonic Let's Note laptops. control) of the HP Compaq TC1100 tablet.
If you have a Panasonic Let's note laptop (such as the R1(N variant),
R2, R3, R5, T2, W2 and Y2 series), say Y.
config COMPAL_LAPTOP config IBM_RTL
tristate "Compal (and others) Laptop Extras" tristate "Device driver to enable PRTL support"
depends on ACPI depends on PCI
depends on BACKLIGHT_CLASS_DEVICE
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on RFKILL
depends on HWMON
depends on POWER_SUPPLY
---help--- ---help---
This is a driver for laptops built by Compal, and some models by Enable support for IBM Premium Real Time Mode (PRTM).
other brands (e.g. Dell, Toshiba). This module will allow you the enter and exit PRTM in the BIOS via
sysfs on platforms that support this feature. System in PRTM will
It adds support for rfkill, Bluetooth, WLAN, LCD brightness, hwmon not receive CPU-generated SMIs for recoverable errors. Use of this
and battery charging level control. feature without proper support may void your hardware warranty.
config SONY_LAPTOP
tristate "Sony Laptop Extras"
depends on ACPI
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on BACKLIGHT_CLASS_DEVICE
depends on INPUT
depends on RFKILL
---help---
This mini-driver drives the SNC and SPIC devices present in the ACPI
BIOS of the Sony Vaio laptops.
It gives access to some extra laptop functionalities like Bluetooth,
screen brightness control, Fn keys and allows powering on/off some
devices.
Read <file:Documentation/admin-guide/laptops/sony-laptop.rst> for more information.
config SONYPI_COMPAT If the proper BIOS support is found the driver will load and create
bool "Sonypi compatibility" /sys/devices/system/ibm_rtl/. The "state" variable will indicate
depends on SONY_LAPTOP whether or not the BIOS is in PRTM.
---help--- state = 0 (BIOS SMIs on)
Build the sonypi driver compatibility code into the sony-laptop driver. state = 1 (BIOS SMIs off)
config IDEAPAD_LAPTOP config IDEAPAD_LAPTOP
tristate "Lenovo IdeaPad Laptop Extras" tristate "Lenovo IdeaPad Laptop Extras"
...@@ -468,17 +581,23 @@ config IDEAPAD_LAPTOP ...@@ -468,17 +581,23 @@ config IDEAPAD_LAPTOP
This is a driver for Lenovo IdeaPad netbooks contains drivers for This is a driver for Lenovo IdeaPad netbooks contains drivers for
rfkill switch, hotkey, fan control and backlight control. rfkill switch, hotkey, fan control and backlight control.
config SURFACE3_WMI config SENSORS_HDAPS
tristate "Surface 3 WMI Driver" tristate "Thinkpad Hard Drive Active Protection System (hdaps)"
depends on ACPI_WMI
depends on DMI
depends on INPUT depends on INPUT
depends on SPI help
---help--- This driver provides support for the IBM Hard Drive Active Protection
Say Y here if you have a Surface 3. System (hdaps), which provides an accelerometer and other misc. data.
ThinkPads starting with the R50, T41, and X40 are supported. The
accelerometer data is readable via sysfs.
To compile this driver as a module, choose M here: the module will This driver also provides an absolute input class device, allowing
be called surface3-wmi. the laptop to act as a pinball machine-esque joystick.
If your ThinkPad is not recognized by the driver, please update to latest
BIOS. This is especially the case for some R52 ThinkPads.
Say Y here if you have an applicable laptop and want to experience
the awesome power of hdaps.
config THINKPAD_ACPI config THINKPAD_ACPI
tristate "ThinkPad ACPI Laptop Extras" tristate "ThinkPad ACPI Laptop Extras"
...@@ -619,173 +738,157 @@ config THINKPAD_ACPI_HOTKEY_POLL ...@@ -619,173 +738,157 @@ config THINKPAD_ACPI_HOTKEY_POLL
If you are not sure, say Y here. The driver enables polling only if If you are not sure, say Y here. The driver enables polling only if
it is strictly necessary to do so. it is strictly necessary to do so.
config SENSORS_HDAPS config INTEL_ATOMISP2_PM
tristate "Thinkpad Hard Drive Active Protection System (hdaps)" tristate "Intel AtomISP2 dummy / power-management driver"
depends on INPUT depends on PCI && IOSF_MBI && PM
help help
This driver provides support for the IBM Hard Drive Active Protection Power-management driver for Intel's Image Signal Processor found on
System (hdaps), which provides an accelerometer and other misc. data. Bay Trail and Cherry Trail devices. This dummy driver's sole purpose
ThinkPads starting with the R50, T41, and X40 are supported. The is to turn the ISP off (put it in D3) to save power and to allow
accelerometer data is readable via sysfs. entering of S0ix modes.
This driver also provides an absolute input class device, allowing
the laptop to act as a pinball machine-esque joystick.
If your ThinkPad is not recognized by the driver, please update to latest
BIOS. This is especially the case for some R52 ThinkPads.
Say Y here if you have an applicable laptop and want to experience To compile this driver as a module, choose M here: the module
the awesome power of hdaps. will be called intel_atomisp2_pm.
config INTEL_MENLOW config INTEL_CHT_INT33FE
tristate "Thermal Management driver for Intel menlow platform" tristate "Intel Cherry Trail ACPI INT33FE Driver"
depends on ACPI_THERMAL depends on X86 && ACPI && I2C && REGULATOR
select THERMAL depends on CHARGER_BQ24190=y || (CHARGER_BQ24190=m && m)
depends on USB_ROLES_INTEL_XHCI=y || (USB_ROLES_INTEL_XHCI=m && m)
depends on TYPEC_MUX_PI3USB30532=y || (TYPEC_MUX_PI3USB30532=m && m)
---help--- ---help---
ACPI thermal management enhancement driver on This driver add support for the INT33FE ACPI device found on
Intel Menlow platform. some Intel Cherry Trail devices.
If unsure, say N.
config EEEPC_LAPTOP There are two kinds of INT33FE ACPI device possible: for hardware
tristate "Eee PC Hotkey Driver" with USB Type-C and Micro-B connectors. This driver supports both.
depends on ACPI
depends on INPUT
depends on RFKILL || RFKILL = n
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on HOTPLUG_PCI
depends on BACKLIGHT_CLASS_DEVICE
select HWMON
select LEDS_CLASS
select NEW_LEDS
select INPUT_SPARSEKMAP
---help---
This driver supports the Fn-Fx keys on Eee PC laptops.
It also gives access to some extra laptop functionalities like The INT33FE ACPI device has a CRS table with I2cSerialBusV2
Bluetooth, backlight and allows powering on/off some other resources for Fuel Gauge Controller and (in the Type-C variant)
devices. FUSB302 USB Type-C Controller and PI3USB30532 USB switch.
This driver instantiates i2c-clients for these, so that standard
i2c drivers for these chips can bind to the them.
If you have an Eee PC laptop, say Y or M here. If this driver If you enable this driver it is advised to also select
doesn't work on your Eee PC, try eeepc-wmi instead. CONFIG_BATTERY_BQ27XXX=m or CONFIG_BATTERY_BQ27XXX_I2C=m for Micro-B
device and CONFIG_TYPEC_FUSB302=m and CONFIG_BATTERY_MAX17042=m
for Type-C device.
config ASUS_WMI config INTEL_HID_EVENT
tristate "ASUS WMI Driver" tristate "INTEL HID Event"
depends on ACPI_WMI depends on ACPI
depends on ACPI_BATTERY
depends on INPUT depends on INPUT
depends on HWMON
depends on BACKLIGHT_CLASS_DEVICE
depends on RFKILL || RFKILL = n
depends on HOTPLUG_PCI
depends on ACPI_VIDEO || ACPI_VIDEO = n
select INPUT_SPARSEKMAP select INPUT_SPARSEKMAP
select LEDS_CLASS help
select NEW_LEDS This driver provides support for the Intel HID Event hotkey interface.
---help--- Some laptops require this driver for hotkey support.
Say Y here if you have a WMI aware Asus laptop (like Eee PCs or new
Asus Notebooks).
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called asus-wmi. be called intel_hid.
config ASUS_NB_WMI config INTEL_INT0002_VGPIO
tristate "Asus Notebook WMI Driver" tristate "Intel ACPI INT0002 Virtual GPIO driver"
depends on ASUS_WMI depends on GPIOLIB && ACPI
depends on SERIO_I8042 || SERIO_I8042 = n select GPIOLIB_IRQCHIP
---help--- ---help---
This is a driver for newer Asus notebooks. It adds extra features Some peripherals on Bay Trail and Cherry Trail platforms signal a
like wireless radio and bluetooth control, leds, hotkeys, backlight... Power Management Event (PME) to the Power Management Controller (PMC)
to wakeup the system. When this happens software needs to explicitly
clear the PME bus 0 status bit in the GPE0a_STS register to avoid an
IRQ storm on IRQ 9.
For more information, see This is modelled in ACPI through the INT0002 ACPI device, which is
<file:Documentation/ABI/testing/sysfs-platform-asus-wmi> called a "Virtual GPIO controller" in ACPI because it defines the
event handler to call when the PME triggers through _AEI and _L02
methods as would be done for a real GPIO interrupt in ACPI.
If you have an ACPI-WMI compatible Asus Notebook, say Y or M To compile this driver as a module, choose M here: the module will
here. be called intel_int0002_vgpio.
config EEEPC_WMI config INTEL_MENLOW
tristate "Eee PC WMI Driver" tristate "Thermal Management driver for Intel menlow platform"
depends on ASUS_WMI depends on ACPI_THERMAL
select THERMAL
---help--- ---help---
This is a driver for newer Eee PC laptops. It adds extra features ACPI thermal management enhancement driver on
like wireless radio and bluetooth control, leds, hotkeys, backlight... Intel Menlow platform.
For more information, see
<file:Documentation/ABI/testing/sysfs-platform-asus-wmi>
If you have an ACPI-WMI compatible Eee PC laptop (>= 1000), say Y or M If unsure, say N.
here.
config ASUS_WIRELESS config INTEL_OAKTRAIL
tristate "Asus Wireless Radio Control Driver" tristate "Intel Oaktrail Platform Extras"
depends on ACPI depends on ACPI
depends on INPUT depends on ACPI_VIDEO || ACPI_VIDEO = n
select NEW_LEDS depends on RFKILL && BACKLIGHT_CLASS_DEVICE && ACPI
select LEDS_CLASS
---help--- ---help---
The Asus Wireless Radio Control handles the airplane mode hotkey Intel Oaktrail platform need this driver to provide interfaces to
present on some Asus laptops. enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y
here; it will only load on supported platforms.
Say Y or M here if you have an ASUS notebook with an airplane mode
hotkey.
If you choose to compile this driver as a module the module will be
called asus-wireless.
config ACPI_WMI config INTEL_VBTN
tristate "WMI" tristate "INTEL VIRTUAL BUTTON"
depends on ACPI depends on ACPI
depends on INPUT
select INPUT_SPARSEKMAP
help help
This driver adds support for the ACPI-WMI (Windows Management This driver provides support for the Intel Virtual Button interface.
Instrumentation) mapper device (PNP0C14) found on some systems. Some laptops require this driver for power button support.
ACPI-WMI is a proprietary extension to ACPI to expose parts of the
ACPI firmware to userspace - this is done through various vendor
defined methods and data blocks in a PNP0C14 device, which are then
made available for userspace to call.
The implementation of this in Linux currently only exposes this to
other kernel space drivers.
This driver is a required dependency to build the firmware specific
drivers needed on many machines, including Acer and HP laptops.
It is safe to enable this driver even if your DSDT doesn't define To compile this driver as a module, choose M here: the module will
any ACPI-WMI devices. be called intel_vbtn.
config WMI_BMOF config SURFACE3_WMI
tristate "WMI embedded Binary MOF driver" tristate "Surface 3 WMI Driver"
depends on ACPI_WMI depends on ACPI_WMI
default ACPI_WMI depends on DMI
depends on INPUT
depends on SPI
---help--- ---help---
Say Y here if you want to be able to read a firmware-embedded Say Y here if you have a Surface 3.
WMI Binary MOF data. Using this requires userspace tools and may be
rather tedious.
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called wmi-bmof. be called surface3-wmi.
config INTEL_WMI_THUNDERBOLT config SURFACE_3_BUTTON
tristate "Intel WMI thunderbolt force power driver" tristate "Power/home/volume buttons driver for Microsoft Surface 3 tablet"
depends on ACPI_WMI depends on ACPI && KEYBOARD_GPIO && I2C
---help--- ---help---
Say Y here if you want to be able to use the WMI interface on select This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet.
systems to force the power control of Intel Thunderbolt controllers.
This is useful for updating the firmware when devices are not plugged
into the controller.
To compile this driver as a module, choose M here: the module will config SURFACE_3_POWER_OPREGION
be called intel-wmi-thunderbolt. tristate "Surface 3 battery platform operation region support"
depends on ACPI && I2C
help
This driver provides support for ACPI operation
region of the Surface 3 battery platform driver.
config XIAOMI_WMI config SURFACE_PRO3_BUTTON
tristate "Xiaomi WMI key driver" tristate "Power/home/volume buttons driver for Microsoft Surface Pro 3/4 tablet"
depends on ACPI_WMI depends on ACPI && INPUT
depends on INPUT ---help---
help This driver handles the power/home/volume buttons on the Microsoft Surface Pro 3/4 tablet.
Say Y here if you want to support WMI-based keys on Xiaomi notebooks.
To compile this driver as a module, choose M here: the module will config MSI_LAPTOP
be called xiaomi-wmi. tristate "MSI Laptop Extras"
depends on ACPI
depends on BACKLIGHT_CLASS_DEVICE
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on RFKILL
depends on INPUT && SERIO_I8042
select INPUT_SPARSEKMAP
---help---
This is a driver for laptops built by MSI (MICRO-STAR
INTERNATIONAL):
MSI MegaBook S270 (MS-1013)
Cytron/TCM/Medion/Tchibo MD96100/SAM2000
It adds support for Bluetooth, WLAN and LCD brightness control.
More information about this driver is available at
<http://0pointer.de/lennart/tchibo.html>.
If you have an MSI S270 laptop, say Y or M here.
config MSI_WMI config MSI_WMI
tristate "MSI WMI extras" tristate "MSI WMI extras"
...@@ -800,27 +903,66 @@ config MSI_WMI ...@@ -800,27 +903,66 @@ config MSI_WMI
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called msi-wmi. be called msi-wmi.
config PEAQ_WMI config XO15_EBOOK
tristate "PEAQ 2-in-1 WMI hotkey driver" tristate "OLPC XO-1.5 ebook switch"
depends on ACPI_WMI depends on OLPC || COMPILE_TEST
depends on INPUT depends on ACPI && INPUT
---help---
Support for the ebook switch on the OLPC XO-1.5 laptop.
This switch is triggered as the screen is rotated and folded down to
convert the device into ebook form.
config XO1_RFKILL
tristate "OLPC XO-1 software RF kill switch"
depends on OLPC || COMPILE_TEST
depends on RFKILL
---help---
Support for enabling/disabling the WLAN interface on the OLPC XO-1
laptop.
config PCENGINES_APU2
tristate "PC Engines APUv2/3 front button and LEDs driver"
depends on INPUT && INPUT_KEYBOARD && GPIOLIB
depends on LEDS_CLASS
select GPIO_AMD_FCH
select KEYBOARD_GPIO_POLLED
select LEDS_GPIO
help help
Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s. This driver provides support for the front button and LEDs on
PC Engines APUv2/APUv3 board.
config TOPSTAR_LAPTOP To compile this driver as a module, choose M here: the module
tristate "Topstar Laptop Extras" will be called pcengines-apuv2.
depends on ACPI
depends on INPUT config SAMSUNG_LAPTOP
select INPUT_SPARSEKMAP tristate "Samsung Laptop driver"
depends on RFKILL || RFKILL = n
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on BACKLIGHT_CLASS_DEVICE
select LEDS_CLASS select LEDS_CLASS
select NEW_LEDS select NEW_LEDS
---help--- ---help---
This driver adds support for hotkeys found on Topstar laptops. This module implements a driver for a wide range of different
Samsung laptops. It offers control over the different
function keys, wireless LED, LCD backlight level.
If you have a Topstar laptop, say Y or M here. It may also provide some sysfs files described in
<file:Documentation/ABI/testing/sysfs-driver-samsung-laptop>
config ACPI_TOSHIBA To compile this driver as a module, choose M here: the module
tristate "Toshiba Laptop Extras" will be called samsung-laptop.
config SAMSUNG_Q10
tristate "Samsung Q10 Extras"
depends on ACPI
select BACKLIGHT_CLASS_DEVICE
---help---
This driver provides support for backlight control on Samsung Q10
and related laptops, including Dell Latitude X200.
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on ACPI depends on ACPI
depends on ACPI_WMI depends on ACPI_WMI
select LEDS_CLASS select LEDS_CLASS
...@@ -917,115 +1059,129 @@ config ACPI_CMPC ...@@ -917,115 +1059,129 @@ config ACPI_CMPC
keys as input device, backlight device, tablet and accelerometer keys as input device, backlight device, tablet and accelerometer
devices. devices.
config INTEL_CHT_INT33FE config COMPAL_LAPTOP
tristate "Intel Cherry Trail ACPI INT33FE Driver" tristate "Compal (and others) Laptop Extras"
depends on X86 && ACPI && I2C && REGULATOR depends on ACPI
depends on CHARGER_BQ24190=y || (CHARGER_BQ24190=m && m) depends on BACKLIGHT_CLASS_DEVICE
depends on USB_ROLES_INTEL_XHCI=y || (USB_ROLES_INTEL_XHCI=m && m) depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on TYPEC_MUX_PI3USB30532=y || (TYPEC_MUX_PI3USB30532=m && m) depends on RFKILL
depends on HWMON
depends on POWER_SUPPLY
---help--- ---help---
This driver add support for the INT33FE ACPI device found on This is a driver for laptops built by Compal, and some models by
some Intel Cherry Trail devices. other brands (e.g. Dell, Toshiba).
There are two kinds of INT33FE ACPI device possible: for hardware It adds support for rfkill, Bluetooth, WLAN, LCD brightness, hwmon
with USB Type-C and Micro-B connectors. This driver supports both. and battery charging level control.
The INT33FE ACPI device has a CRS table with I2cSerialBusV2 config LG_LAPTOP
resources for Fuel Gauge Controller and (in the Type-C variant) tristate "LG Laptop Extras"
FUSB302 USB Type-C Controller and PI3USB30532 USB switch. depends on ACPI
This driver instantiates i2c-clients for these, so that standard depends on ACPI_WMI
i2c drivers for these chips can bind to the them. depends on INPUT
select INPUT_SPARSEKMAP
select LEDS_CLASS
help
This driver adds support for hotkeys as well as control of keyboard
backlight, battery maximum charge level and various other ACPI
features.
If you enable this driver it is advised to also select If you have an LG Gram laptop, say Y or M here.
CONFIG_BATTERY_BQ27XXX=m or CONFIG_BATTERY_BQ27XXX_I2C=m for Micro-B
device and CONFIG_TYPEC_FUSB302=m and CONFIG_BATTERY_MAX17042=m config PANASONIC_LAPTOP
for Type-C device. tristate "Panasonic Laptop Extras"
depends on INPUT && ACPI
depends on BACKLIGHT_CLASS_DEVICE
select INPUT_SPARSEKMAP
---help---
This driver adds support for access to backlight control and hotkeys
on Panasonic Let's Note laptops.
If you have a Panasonic Let's note laptop (such as the R1(N variant),
R2, R3, R5, T2, W2 and Y2 series), say Y.
config INTEL_INT0002_VGPIO config SONY_LAPTOP
tristate "Intel ACPI INT0002 Virtual GPIO driver" tristate "Sony Laptop Extras"
depends on GPIOLIB && ACPI depends on ACPI
select GPIOLIB_IRQCHIP depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on BACKLIGHT_CLASS_DEVICE
depends on INPUT
depends on RFKILL
---help--- ---help---
Some peripherals on Bay Trail and Cherry Trail platforms signal a This mini-driver drives the SNC and SPIC devices present in the ACPI
Power Management Event (PME) to the Power Management Controller (PMC) BIOS of the Sony Vaio laptops.
to wakeup the system. When this happens software needs to explicitly
clear the PME bus 0 status bit in the GPE0a_STS register to avoid an
IRQ storm on IRQ 9.
This is modelled in ACPI through the INT0002 ACPI device, which is It gives access to some extra laptop functionalities like Bluetooth,
called a "Virtual GPIO controller" in ACPI because it defines the screen brightness control, Fn keys and allows powering on/off some
event handler to call when the PME triggers through _AEI and _L02 devices.
methods as would be done for a real GPIO interrupt in ACPI.
To compile this driver as a module, choose M here: the module will Read <file:Documentation/admin-guide/laptops/sony-laptop.rst> for more information.
be called intel_int0002_vgpio.
config INTEL_HID_EVENT config SONYPI_COMPAT
tristate "INTEL HID Event" bool "Sonypi compatibility"
depends on SONY_LAPTOP
---help---
Build the sonypi driver compatibility code into the sony-laptop driver.
config SYSTEM76_ACPI
tristate "System76 ACPI Driver"
depends on ACPI depends on ACPI
depends on INPUT select NEW_LEDS
select INPUT_SPARSEKMAP select LEDS_CLASS
select LEDS_TRIGGERS
help help
This driver provides support for the Intel HID Event hotkey interface. This is a driver for System76 laptops running open firmware. It adds
Some laptops require this driver for hotkey support. support for Fn-Fx key combinations, keyboard backlight, and airplane mode
LEDs.
To compile this driver as a module, choose M here: the module will If you have a System76 laptop running open firmware, say Y or M here.
be called intel_hid.
config INTEL_VBTN config TOPSTAR_LAPTOP
tristate "INTEL VIRTUAL BUTTON" tristate "Topstar Laptop Extras"
depends on ACPI depends on ACPI
depends on INPUT depends on INPUT
select INPUT_SPARSEKMAP select INPUT_SPARSEKMAP
help select LEDS_CLASS
This driver provides support for the Intel Virtual Button interface. select NEW_LEDS
Some laptops require this driver for power button support.
To compile this driver as a module, choose M here: the module will
be called intel_vbtn.
config INTEL_SCU_IPC
bool "Intel SCU IPC Support"
depends on X86_INTEL_MID
default y
---help--- ---help---
IPC is used to bridge the communications between kernel and SCU on This driver adds support for hotkeys found on Topstar laptops.
some embedded Intel x86 platforms. This is not needed for PC-type
machines.
config INTEL_SCU_IPC_UTIL If you have a Topstar laptop, say Y or M here.
tristate "Intel SCU IPC utility driver"
depends on INTEL_SCU_IPC
---help---
The IPC Util driver provides an interface with the SCU enabling
low level access for debug work and updating the firmware. Say
N unless you will be doing this on an Intel MID platform.
config INTEL_MID_POWER_BUTTON config I2C_MULTI_INSTANTIATE
tristate "power button driver for Intel MID platforms" tristate "I2C multi instantiate pseudo device driver"
depends on INTEL_SCU_IPC && INPUT depends on I2C && ACPI
help help
This driver handles the power button on the Intel MID platforms. Some ACPI-based systems list multiple i2c-devices in a single ACPI
firmware-node. This driver will instantiate separate i2c-clients
for each device in the firmware-node.
If unsure, say N. To compile this driver as a module, choose M here: the module
will be called i2c-multi-instantiate.
config INTEL_MFLD_THERMAL config MLX_PLATFORM
tristate "Thermal driver for Intel Medfield platform" tristate "Mellanox Technologies platform support"
depends on MFD_INTEL_MSIC && THERMAL depends on I2C && REGMAP
help ---help---
Say Y here to enable thermal driver support for the Intel Medfield This option enables system support for the Mellanox Technologies
platform. platform. The Mellanox systems provide data center networking
solutions based on Virtual Protocol Interconnect (VPI) technology
enable seamless connectivity to 56/100Gb/s InfiniBand or 10/40/56GbE
connection.
config INTEL_IPS If you have a Mellanox system, say Y or M here.
tristate "Intel Intelligent Power Sharing"
depends on ACPI && PCI config TOUCHSCREEN_DMI
bool "DMI based touchscreen configuration info"
depends on ACPI && DMI && I2C=y && TOUCHSCREEN_SILEAD
select EFI_EMBEDDED_FIRMWARE if EFI
---help--- ---help---
Intel Calpella platforms support dynamic power sharing between the Certain ACPI based tablets with e.g. Silead or Chipone touchscreens
CPU and GPU, maximizing performance in a given TDP. This driver, do not have enough data in ACPI tables for the touchscreen driver to
along with the CPU frequency and i915 drivers, provides that handle the touchscreen properly, as OEMs expect the data to be baked
functionality. If in doubt, say Y here; it will only load on into the tablet model specific version of the driver shipped with the
supported platforms. the OS-image for the device. This option supplies the missing info.
Enable this for x86 tablets with Silead or Chipone touchscreens.
config INTEL_IMR config INTEL_IMR
bool "Intel Isolated Memory Region support" bool "Intel Isolated Memory Region support"
...@@ -1039,128 +1195,33 @@ config INTEL_IMR ...@@ -1039,128 +1195,33 @@ config INTEL_IMR
IMRs make it possible to control read/write access to an address IMRs make it possible to control read/write access to an address
by hardware agents inside the SoC. Read and write masks can be by hardware agents inside the SoC. Read and write masks can be
defined for: defined for:
- eSRAM flush - eSRAM flush
- Dirty CPU snoop (write only) - Dirty CPU snoop (write only)
- RMU access - RMU access
- PCI Virtual Channel 0/Virtual Channel 1 - PCI Virtual Channel 0/Virtual Channel 1
- SMM mode - SMM mode
- Non SMM mode - Non SMM mode
Quark contains a set of eight IMR registers and makes use of those
registers during its bootup process.
If you are running on a Galileo/Quark say Y here.
config INTEL_PMC_CORE
tristate "Intel PMC Core driver"
depends on PCI
---help---
The Intel Platform Controller Hub for Intel Core SoCs provides access
to Power Management Controller registers via a PCI interface. This
driver can utilize debugging capabilities and supported features as
exposed by the Power Management Controller.
Supported features:
- SLP_S0_RESIDENCY counter
- PCH IP Power Gating status
- LTR Ignore
- MPHY/PLL gating status (Sunrisepoint PCH only)
config IBM_RTL
tristate "Device driver to enable PRTL support"
depends on PCI
---help---
Enable support for IBM Premium Real Time Mode (PRTM).
This module will allow you the enter and exit PRTM in the BIOS via
sysfs on platforms that support this feature. System in PRTM will
not receive CPU-generated SMIs for recoverable errors. Use of this
feature without proper support may void your hardware warranty.
If the proper BIOS support is found the driver will load and create
/sys/devices/system/ibm_rtl/. The "state" variable will indicate
whether or not the BIOS is in PRTM.
state = 0 (BIOS SMIs on)
state = 1 (BIOS SMIs off)
config XO1_RFKILL
tristate "OLPC XO-1 software RF kill switch"
depends on OLPC || COMPILE_TEST
depends on RFKILL
---help---
Support for enabling/disabling the WLAN interface on the OLPC XO-1
laptop.
config XO15_EBOOK
tristate "OLPC XO-1.5 ebook switch"
depends on OLPC || COMPILE_TEST
depends on ACPI && INPUT
---help---
Support for the ebook switch on the OLPC XO-1.5 laptop.
This switch is triggered as the screen is rotated and folded down to
convert the device into ebook form.
config SAMSUNG_LAPTOP
tristate "Samsung Laptop driver"
depends on RFKILL || RFKILL = n
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on BACKLIGHT_CLASS_DEVICE
select LEDS_CLASS
select NEW_LEDS
---help---
This module implements a driver for a wide range of different
Samsung laptops. It offers control over the different
function keys, wireless LED, LCD backlight level.
It may also provide some sysfs files described in
<file:Documentation/ABI/testing/sysfs-driver-samsung-laptop>
To compile this driver as a module, choose M here: the module
will be called samsung-laptop.
config MXM_WMI
tristate "WMI support for MXM Laptop Graphics"
depends on ACPI_WMI
---help---
MXM is a standard for laptop graphics cards, the WMI interface
is required for switchable nvidia graphics machines
config INTEL_OAKTRAIL
tristate "Intel Oaktrail Platform Extras"
depends on ACPI
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on RFKILL && BACKLIGHT_CLASS_DEVICE && ACPI
---help---
Intel Oaktrail platform need this driver to provide interfaces to
enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y
here; it will only load on supported platforms.
config SAMSUNG_Q10 Quark contains a set of eight IMR registers and makes use of those
tristate "Samsung Q10 Extras" registers during its bootup process.
depends on ACPI
select BACKLIGHT_CLASS_DEVICE
---help---
This driver provides support for backlight control on Samsung Q10
and related laptops, including Dell Latitude X200.
config APPLE_GMUX If you are running on a Galileo/Quark say Y here.
tristate "Apple Gmux Driver"
config INTEL_IPS
tristate "Intel Intelligent Power Sharing"
depends on ACPI && PCI depends on ACPI && PCI
depends on PNP
depends on BACKLIGHT_CLASS_DEVICE
depends on BACKLIGHT_APPLE=n || BACKLIGHT_APPLE
depends on ACPI_VIDEO=n || ACPI_VIDEO
---help--- ---help---
This driver provides support for the gmux device found on many Intel Calpella platforms support dynamic power sharing between the
Apple laptops, which controls the display mux for the hybrid CPU and GPU, maximizing performance in a given TDP. This driver,
graphics as well as the backlight. Currently only backlight along with the CPU frequency and i915 drivers, provides that
control is supported by the driver. functionality. If in doubt, say Y here; it will only load on
supported platforms.
config INTEL_RST config INTEL_RST
tristate "Intel Rapid Start Technology Driver" tristate "Intel Rapid Start Technology Driver"
depends on ACPI depends on ACPI
---help--- ---help---
This driver provides support for modifying paramaters on systems This driver provides support for modifying parameters on systems
equipped with Intel's Rapid Start Technology. When put in an ACPI equipped with Intel's Rapid Start Technology. When put in an ACPI
sleep state, these devices will wake after either a configured sleep state, these devices will wake after either a configured
timeout or when the system battery reaches a critical state, timeout or when the system battery reaches a critical state,
...@@ -1182,62 +1243,7 @@ config INTEL_SMARTCONNECT ...@@ -1182,62 +1243,7 @@ config INTEL_SMARTCONNECT
This driver checks to determine whether the device has Intel Smart This driver checks to determine whether the device has Intel Smart
Connect enabled, and if so disables it. Connect enabled, and if so disables it.
config INTEL_PMC_IPC source "drivers/platform/x86/intel_speed_select_if/Kconfig"
tristate "Intel PMC IPC Driver"
depends on ACPI && PCI
---help---
This driver provides support for PMC control on some Intel platforms.
The PMC is an ARC processor which defines IPC commands for communication
with other entities in the CPU.
config INTEL_BXTWC_PMIC_TMU
tristate "Intel BXT Whiskey Cove TMU Driver"
depends on REGMAP
depends on INTEL_SOC_PMIC_BXTWC && INTEL_PMC_IPC
---help---
Select this driver to use Intel BXT Whiskey Cove PMIC TMU feature.
This driver enables the alarm wakeup functionality in the TMU unit
of Whiskey Cove PMIC.
config SURFACE_PRO3_BUTTON
tristate "Power/home/volume buttons driver for Microsoft Surface Pro 3/4 tablet"
depends on ACPI && INPUT
---help---
This driver handles the power/home/volume buttons on the Microsoft Surface Pro 3/4 tablet.
config SURFACE_3_BUTTON
tristate "Power/home/volume buttons driver for Microsoft Surface 3 tablet"
depends on ACPI && KEYBOARD_GPIO && I2C
---help---
This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet.
config INTEL_PUNIT_IPC
tristate "Intel P-Unit IPC Driver"
---help---
This driver provides support for Intel P-Unit Mailbox IPC mechanism,
which is used to bridge the communications between kernel and P-Unit.
config INTEL_TELEMETRY
tristate "Intel SoC Telemetry Driver"
depends on INTEL_PMC_IPC && INTEL_PUNIT_IPC && X86_64
---help---
This driver provides interfaces to configure and use
telemetry for INTEL SoC from APL onwards. It is also
used to get various SoC events and parameters
directly via debugfs files. Various tools may use
this interface for SoC state monitoring.
config MLX_PLATFORM
tristate "Mellanox Technologies platform support"
depends on I2C && REGMAP
---help---
This option enables system support for the Mellanox Technologies
platform. The Mellanox systems provide data center networking
solutions based on Virtual Protocol Interconnect (VPI) technology
enable seamless connectivity to 56/100Gb/s InfiniBand or 10/40/56GbE
connection.
If you have a Mellanox system, say Y or M here.
config INTEL_TURBO_MAX_3 config INTEL_TURBO_MAX_3
bool "Intel Turbo Boost Max Technology 3.0 enumeration driver" bool "Intel Turbo Boost Max Technology 3.0 enumeration driver"
...@@ -1249,17 +1255,25 @@ config INTEL_TURBO_MAX_3 ...@@ -1249,17 +1255,25 @@ config INTEL_TURBO_MAX_3
This driver is only required when the system is not using Hardware This driver is only required when the system is not using Hardware
P-States (HWP). In HWP mode, priority can be read from ACPI tables. P-States (HWP). In HWP mode, priority can be read from ACPI tables.
config TOUCHSCREEN_DMI config INTEL_UNCORE_FREQ_CONTROL
bool "DMI based touchscreen configuration info" tristate "Intel Uncore frequency control driver"
depends on ACPI && DMI && I2C=y && TOUCHSCREEN_SILEAD depends on X86_64
select EFI_EMBEDDED_FIRMWARE if EFI help
This driver allows control of uncore frequency limits on
supported server platforms.
Uncore frequency controls RING/LLC (last-level cache) clocks.
To compile this driver as a module, choose M here: the module
will be called intel-uncore-frequency.
config INTEL_BXTWC_PMIC_TMU
tristate "Intel BXT Whiskey Cove TMU Driver"
depends on REGMAP
depends on INTEL_SOC_PMIC_BXTWC && INTEL_PMC_IPC
---help--- ---help---
Certain ACPI based tablets with e.g. Silead or Chipone touchscreens Select this driver to use Intel BXT Whiskey Cove PMIC TMU feature.
do not have enough data in ACPI tables for the touchscreen driver to This driver enables the alarm wakeup functionality in the TMU unit
handle the touchscreen properly, as OEMs expect the data to be baked of Whiskey Cove PMIC.
into the tablet model specific version of the driver shipped with the
the OS-image for the device. This option supplies the missing info.
Enable this for x86 tablets with Silead or Chipone touchscreens.
config INTEL_CHTDC_TI_PWRBTN config INTEL_CHTDC_TI_PWRBTN
tristate "Intel Cherry Trail Dollar Cove TI power button driver" tristate "Intel Cherry Trail Dollar Cove TI power button driver"
...@@ -1272,6 +1286,21 @@ config INTEL_CHTDC_TI_PWRBTN ...@@ -1272,6 +1286,21 @@ config INTEL_CHTDC_TI_PWRBTN
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called intel_chtdc_ti_pwrbtn. will be called intel_chtdc_ti_pwrbtn.
config INTEL_MFLD_THERMAL
tristate "Thermal driver for Intel Medfield platform"
depends on MFD_INTEL_MSIC && THERMAL
help
Say Y here to enable thermal driver support for the Intel Medfield
platform.
config INTEL_MID_POWER_BUTTON
tristate "power button driver for Intel MID platforms"
depends on INTEL_SCU_IPC && INPUT
help
This driver handles the power button on the Intel MID platforms.
If unsure, say N.
config INTEL_MRFLD_PWRBTN config INTEL_MRFLD_PWRBTN
tristate "Intel Merrifield Basin Cove power button driver" tristate "Intel Merrifield Basin Cove power button driver"
depends on INTEL_SOC_PMIC_MRFLD depends on INTEL_SOC_PMIC_MRFLD
...@@ -1283,85 +1312,61 @@ config INTEL_MRFLD_PWRBTN ...@@ -1283,85 +1312,61 @@ config INTEL_MRFLD_PWRBTN
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called intel_mrfld_pwrbtn. will be called intel_mrfld_pwrbtn.
config I2C_MULTI_INSTANTIATE config INTEL_PMC_CORE
tristate "I2C multi instantiate pseudo device driver" tristate "Intel PMC Core driver"
depends on I2C && ACPI depends on PCI
help ---help---
Some ACPI-based systems list multiple i2c-devices in a single ACPI The Intel Platform Controller Hub for Intel Core SoCs provides access
firmware-node. This driver will instantiate separate i2c-clients to Power Management Controller registers via a PCI interface. This
for each device in the firmware-node. driver can utilize debugging capabilities and supported features as
exposed by the Power Management Controller.
To compile this driver as a module, choose M here: the module
will be called i2c-multi-instantiate.
config INTEL_ATOMISP2_PM
tristate "Intel AtomISP2 dummy / power-management driver"
depends on PCI && IOSF_MBI && PM
help
Power-management driver for Intel's Image Signal Processor found on
Bay Trail and Cherry Trail devices. This dummy driver's sole purpose
is to turn the ISP off (put it in D3) to save power and to allow
entering of S0ix modes.
To compile this driver as a module, choose M here: the module
will be called intel_atomisp2_pm.
config HUAWEI_WMI
tristate "Huawei WMI laptop extras driver"
depends on ACPI_BATTERY
depends on ACPI_WMI
depends on INPUT
select INPUT_SPARSEKMAP
select LEDS_CLASS
select LEDS_TRIGGERS
select LEDS_TRIGGER_AUDIO
select NEW_LEDS
help
This driver provides support for Huawei WMI hotkeys, battery charge
control, fn-lock, mic-mute LED, and other extra features.
To compile this driver as a module, choose M here: the module
will be called huawei-wmi.
config PCENGINES_APU2
tristate "PC Engines APUv2/3 front button and LEDs driver"
depends on INPUT && INPUT_KEYBOARD && GPIOLIB
depends on LEDS_CLASS
select GPIO_AMD_FCH
select KEYBOARD_GPIO_POLLED
select LEDS_GPIO
help
This driver provides support for the front button and LEDs on
PC Engines APUv2/APUv3 board.
To compile this driver as a module, choose M here: the module Supported features:
will be called pcengines-apuv2. - SLP_S0_RESIDENCY counter
- PCH IP Power Gating status
- LTR Ignore
- MPHY/PLL gating status (Sunrisepoint PCH only)
config INTEL_UNCORE_FREQ_CONTROL config INTEL_PMC_IPC
tristate "Intel Uncore frequency control driver" tristate "Intel PMC IPC Driver"
depends on X86_64 depends on ACPI && PCI
help ---help---
This driver allows control of uncore frequency limits on This driver provides support for PMC control on some Intel platforms.
supported server platforms. The PMC is an ARC processor which defines IPC commands for communication
Uncore frequency controls RING/LLC (last-level cache) clocks. with other entities in the CPU.
To compile this driver as a module, choose M here: the module config INTEL_PUNIT_IPC
will be called intel-uncore-frequency. tristate "Intel P-Unit IPC Driver"
---help---
This driver provides support for Intel P-Unit Mailbox IPC mechanism,
which is used to bridge the communications between kernel and P-Unit.
source "drivers/platform/x86/intel_speed_select_if/Kconfig" config INTEL_SCU_IPC
bool "Intel SCU IPC Support"
depends on X86_INTEL_MID
default y
---help---
IPC is used to bridge the communications between kernel and SCU on
some embedded Intel x86 platforms. This is not needed for PC-type
machines.
config SYSTEM76_ACPI config INTEL_SCU_IPC_UTIL
tristate "System76 ACPI Driver" tristate "Intel SCU IPC utility driver"
depends on ACPI depends on INTEL_SCU_IPC
select NEW_LEDS ---help---
select LEDS_CLASS The IPC Util driver provides an interface with the SCU enabling
select LEDS_TRIGGERS low level access for debug work and updating the firmware. Say
help N unless you will be doing this on an Intel MID platform.
This is a driver for System76 laptops running open firmware. It adds
support for Fn-Fx key combinations, keyboard backlight, and airplane mode
LEDs.
If you have a System76 laptop running open firmware, say Y or M here. config INTEL_TELEMETRY
tristate "Intel SoC Telemetry Driver"
depends on INTEL_PMC_IPC && INTEL_PUNIT_IPC && X86_64
---help---
This driver provides interfaces to configure and use
telemetry for INTEL SoC from APL onwards. It is also
used to get various SoC events and parameters
directly via debugfs files. Various tools may use
this interface for SoC state monitoring.
endif # X86_PLATFORM_DEVICES endif # X86_PLATFORM_DEVICES
......
...@@ -3,106 +3,146 @@ ...@@ -3,106 +3,146 @@
# Makefile for linux/drivers/platform/x86 # Makefile for linux/drivers/platform/x86
# x86 Platform-Specific Drivers # 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_LAPTOP) += asus-laptop.o
obj-$(CONFIG_ASUS_WIRELESS) += asus-wireless.o
obj-$(CONFIG_ASUS_WMI) += asus-wmi.o obj-$(CONFIG_ASUS_WMI) += asus-wmi.o
obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-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_LAPTOP) += eeepc-laptop.o
obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o
obj-$(CONFIG_LG_LAPTOP) += lg-laptop.o
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o # Dell
obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o obj-$(CONFIG_DCDBAS) += dcdbas.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o
obj-$(CONFIG_DCDBAS) += dcdbas.o dell-smbios-objs := dell-smbios-base.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_WMI) += dell-smbios-wmi.o
dell-smbios-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o dell-smbios-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o
obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
obj-$(CONFIG_DELL_WMI) += dell-wmi.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_DESCRIPTOR) += dell-wmi-descriptor.o
obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o # Fujitsu
obj-$(CONFIG_DELL_RBU) += dell_rbu.o obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o
obj-$(CONFIG_ACER_WIRELESS) += acer-wireless.o obj-$(CONFIG_FUJITSU_TABLET) += fujitsu-tablet.o
obj-$(CONFIG_ACERHDF) += acerhdf.o
# GPD
obj-$(CONFIG_GPD_POCKET_FAN) += gpd-pocket-fan.o
# Hewlett Packard
obj-$(CONFIG_HP_ACCEL) += hp_accel.o obj-$(CONFIG_HP_ACCEL) += hp_accel.o
obj-$(CONFIG_HP_WIRELESS) += hp-wireless.o obj-$(CONFIG_HP_WIRELESS) += hp-wireless.o
obj-$(CONFIG_HP_WMI) += hp-wmi.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_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_IDEAPAD_LAPTOP) += ideapad-laptop.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
obj-$(CONFIG_FUJITSU_TABLET) += fujitsu-tablet.o
obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o # Intel
obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o obj-$(CONFIG_INTEL_ATOMISP2_PM) += intel_atomisp2_pm.o
obj-$(CONFIG_ACPI_WMI) += 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_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_MSI_WMI) += msi-wmi.o
obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o
obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o
obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o
obj-$(CONFIG_INTEL_WMI_THUNDERBOLT) += intel-wmi-thunderbolt.o
obj-$(CONFIG_XIAOMI_WMI) += xiaomi-wmi.o
# toshiba_acpi must link after wmi to ensure that wmi devices are found # OLPC
# before toshiba_acpi initializes obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.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_BT_RFKILL) += toshiba_bluetooth.o
obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o
obj-$(CONFIG_TOSHIBA_WMI) += toshiba-wmi.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 # toshiba_acpi must link after wmi to ensure that wmi devices are found
obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o # before toshiba_acpi initializes
obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o
obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o # Laptop drivers
obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_LG_LAPTOP) += lg-laptop.o
obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
obj-$(CONFIG_SYSTEM76_ACPI) += system76_acpi.o
obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
# Platform drivers
obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o
obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o
# Intel uncore drivers
obj-$(CONFIG_INTEL_IPS) += intel_ips.o
obj-$(CONFIG_INTEL_RST) += intel-rst.o
obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o
obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += intel_speed_select_if/
obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
obj-$(CONFIG_INTEL_UNCORE_FREQ_CONTROL) += intel-uncore-frequency.o
# Intel PMIC / PMC / P-Unit devices
obj-$(CONFIG_INTEL_BXTWC_PMIC_TMU) += intel_bxtwc_tmu.o obj-$(CONFIG_INTEL_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_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_MRFLD_PWRBTN) += intel_mrfld_pwrbtn.o
obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o intel_pmc_core_pltdrv.o
obj-$(CONFIG_INTEL_ATOMISP2_PM) += intel_atomisp2_pm.o obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o
obj-$(CONFIG_PCENGINES_APU2) += pcengines-apuv2.o obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o
obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += intel_speed_select_if/ obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
obj-$(CONFIG_SYSTEM76_ACPI) += system76_acpi.o obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
obj-$(CONFIG_INTEL_UNCORE_FREQ_CONTROL) += intel-uncore-frequency.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) ...@@ -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 /* The WMI method does not provide a way to specific a battery, so we
* just assume it is the first battery. * 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; return -ENODEV;
if (device_create_file(&battery->dev, if (device_create_file(&battery->dev,
...@@ -1719,7 +1722,7 @@ static ssize_t fan_boost_mode_store(struct device *dev, ...@@ -1719,7 +1722,7 @@ static ssize_t fan_boost_mode_store(struct device *dev,
asus->fan_boost_mode = new_mode; asus->fan_boost_mode = new_mode;
fan_boost_mode_write(asus); fan_boost_mode_write(asus);
return result; return count;
} }
// Fan boost mode: 0 - normal, 1 - overboost, 2 - silent // Fan boost mode: 0 - normal, 1 - overboost, 2 - silent
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
* *
* See Documentation/admin-guide/dell_rbu.rst for more info. * See Documentation/admin-guide/dell_rbu.rst for more info.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -61,13 +64,11 @@ static struct _rbu_data { ...@@ -61,13 +64,11 @@ static struct _rbu_data {
static char image_type[MAX_IMAGE_LENGTH + 1] = "mono"; static char image_type[MAX_IMAGE_LENGTH + 1] = "mono";
module_param_string(image_type, image_type, sizeof (image_type), 0); module_param_string(image_type, image_type, sizeof (image_type), 0);
MODULE_PARM_DESC(image_type, MODULE_PARM_DESC(image_type, "BIOS image type. choose- mono or packet or init");
"BIOS image type. choose- mono or packet or init");
static unsigned long allocation_floor = 0x100000; static unsigned long allocation_floor = 0x100000;
module_param(allocation_floor, ulong, 0644); module_param(allocation_floor, ulong, 0644);
MODULE_PARM_DESC(allocation_floor, MODULE_PARM_DESC(allocation_floor, "Minimum address for allocations when using Packet mode");
"Minimum address for allocations when using Packet mode");
struct packet_data { struct packet_data {
struct list_head list; struct list_head list;
...@@ -100,10 +101,10 @@ static int create_packet(void *data, size_t length) ...@@ -100,10 +101,10 @@ static int create_packet(void *data, size_t length)
void *packet_data_temp_buf = NULL; void *packet_data_temp_buf = NULL;
unsigned int idx = 0; unsigned int idx = 0;
pr_debug("create_packet: entry \n"); pr_debug("entry\n");
if (!rbu_data.packetsize) { if (!rbu_data.packetsize) {
pr_debug("create_packet: packetsize not specified\n"); pr_debug("packetsize not specified\n");
retval = -EINVAL; retval = -EINVAL;
goto out_noalloc; goto out_noalloc;
} }
...@@ -113,9 +114,7 @@ static int create_packet(void *data, size_t length) ...@@ -113,9 +114,7 @@ static int create_packet(void *data, size_t length)
newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL); newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL);
if (!newpacket) { if (!newpacket) {
printk(KERN_WARNING pr_warn("failed to allocate new packet\n");
"dell_rbu:%s: failed to allocate new "
"packet\n", __func__);
retval = -ENOMEM; retval = -ENOMEM;
spin_lock(&rbu_data.lock); spin_lock(&rbu_data.lock);
goto out_noalloc; goto out_noalloc;
...@@ -134,17 +133,12 @@ static int create_packet(void *data, size_t length) ...@@ -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 * due to BIOS errata. This shouldn't be used for higher floors
* or you will run out of mem trying to allocate the array. * or you will run out of mem trying to allocate the array.
*/ */
packet_array_size = max( packet_array_size = max_t(unsigned int, allocation_floor / rbu_data.packetsize, 1);
(unsigned int)(allocation_floor / rbu_data.packetsize),
(unsigned int)1);
invalid_addr_packet_array = kcalloc(packet_array_size, sizeof(void *), invalid_addr_packet_array = kcalloc(packet_array_size, sizeof(void *),
GFP_KERNEL); GFP_KERNEL);
if (!invalid_addr_packet_array) { if (!invalid_addr_packet_array) {
printk(KERN_WARNING pr_warn("failed to allocate invalid_addr_packet_array\n");
"dell_rbu:%s: failed to allocate "
"invalid_addr_packet_array \n",
__func__);
retval = -ENOMEM; retval = -ENOMEM;
spin_lock(&rbu_data.lock); spin_lock(&rbu_data.lock);
goto out_alloc_packet; goto out_alloc_packet;
...@@ -154,9 +148,7 @@ static int create_packet(void *data, size_t length) ...@@ -154,9 +148,7 @@ static int create_packet(void *data, size_t length)
packet_data_temp_buf = (unsigned char *) packet_data_temp_buf = (unsigned char *)
__get_free_pages(GFP_KERNEL, ordernum); __get_free_pages(GFP_KERNEL, ordernum);
if (!packet_data_temp_buf) { if (!packet_data_temp_buf) {
printk(KERN_WARNING pr_warn("failed to allocate new packet\n");
"dell_rbu:%s: failed to allocate new "
"packet\n", __func__);
retval = -ENOMEM; retval = -ENOMEM;
spin_lock(&rbu_data.lock); spin_lock(&rbu_data.lock);
goto out_alloc_packet_array; goto out_alloc_packet_array;
...@@ -164,7 +156,7 @@ static int create_packet(void *data, size_t length) ...@@ -164,7 +156,7 @@ static int create_packet(void *data, size_t length)
if ((unsigned long)virt_to_phys(packet_data_temp_buf) if ((unsigned long)virt_to_phys(packet_data_temp_buf)
< allocation_floor) { < 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( (unsigned long)virt_to_phys(
packet_data_temp_buf), packet_data_temp_buf),
allocation_floor); allocation_floor);
...@@ -181,7 +173,7 @@ static int create_packet(void *data, size_t length) ...@@ -181,7 +173,7 @@ static int create_packet(void *data, size_t length)
newpacket->data = packet_data_temp_buf; 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)); (unsigned long)virt_to_phys(newpacket->data));
/* packets may not have fixed size */ /* packets may not have fixed size */
...@@ -195,16 +187,14 @@ static int create_packet(void *data, size_t length) ...@@ -195,16 +187,14 @@ static int create_packet(void *data, size_t length)
memcpy(newpacket->data, data, length); memcpy(newpacket->data, data, length);
pr_debug("create_packet: exit \n"); pr_debug("exit\n");
out_alloc_packet_array: out_alloc_packet_array:
/* always free packet array */ /* always free packet array */
for (;idx>0;idx--) { while (idx--) {
pr_debug("freeing unused packet below floor 0x%lx.\n", pr_debug("freeing unused packet below floor 0x%lx\n",
(unsigned long)virt_to_phys( (unsigned long)virt_to_phys(invalid_addr_packet_array[idx]));
invalid_addr_packet_array[idx-1])); free_pages((unsigned long)invalid_addr_packet_array[idx], ordernum);
free_pages((unsigned long)invalid_addr_packet_array[idx-1],
ordernum);
} }
kfree(invalid_addr_packet_array); kfree(invalid_addr_packet_array);
...@@ -224,10 +214,9 @@ static int packetize_data(const u8 *data, size_t length) ...@@ -224,10 +214,9 @@ static int packetize_data(const u8 *data, size_t length)
int packet_length; int packet_length;
u8 *temp; u8 *temp;
u8 *end = (u8 *) data + length; 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) { if (!rbu_data.packetsize) {
printk(KERN_WARNING pr_warn("packetsize not specified\n");
"dell_rbu: packetsize not specified\n");
return -EIO; return -EIO;
} }
...@@ -255,15 +244,13 @@ static int packetize_data(const u8 *data, size_t length) ...@@ -255,15 +244,13 @@ static int packetize_data(const u8 *data, size_t length)
return rc; 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) int length, int bytes_read, int *list_read_count)
{ {
void *ptemp_buf; void *ptemp_buf;
struct packet_data *newpacket = NULL;
int bytes_copied = 0; int bytes_copied = 0;
int j = 0; int j = 0;
newpacket = list_entry(ptemp_list, struct packet_data, list);
*list_read_count += newpacket->length; *list_read_count += newpacket->length;
if (*list_read_count > bytes_read) { if (*list_read_count > bytes_read) {
...@@ -291,7 +278,7 @@ static int do_packet_read(char *data, struct list_head *ptemp_list, ...@@ -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) 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 temp_count = 0;
int bytes_copied = 0; int bytes_copied = 0;
int bytes_read = 0; int bytes_read = 0;
...@@ -305,9 +292,8 @@ static int packet_read_list(char *data, size_t * pread_length) ...@@ -305,9 +292,8 @@ static int packet_read_list(char *data, size_t * pread_length)
remaining_bytes = *pread_length; remaining_bytes = *pread_length;
bytes_read = rbu_data.packet_read_count; bytes_read = rbu_data.packet_read_count;
ptemp_list = (&packet_data_head.list)->next; list_for_each_entry(newpacket, (&packet_data_head.list)->next, list) {
while (!list_empty(ptemp_list)) { bytes_copied = do_packet_read(pdest, newpacket,
bytes_copied = do_packet_read(pdest, ptemp_list,
remaining_bytes, bytes_read, &temp_count); remaining_bytes, bytes_read, &temp_count);
remaining_bytes -= bytes_copied; remaining_bytes -= bytes_copied;
bytes_read += bytes_copied; bytes_read += bytes_copied;
...@@ -318,8 +304,6 @@ static int packet_read_list(char *data, size_t * pread_length) ...@@ -318,8 +304,6 @@ static int packet_read_list(char *data, size_t * pread_length)
*/ */
if (remaining_bytes == 0) if (remaining_bytes == 0)
break; break;
ptemp_list = ptemp_list->next;
} }
/*finally set the bytes read */ /*finally set the bytes read */
*pread_length = bytes_read - rbu_data.packet_read_count; *pread_length = bytes_read - rbu_data.packet_read_count;
...@@ -329,17 +313,11 @@ static int packet_read_list(char *data, size_t * pread_length) ...@@ -329,17 +313,11 @@ static int packet_read_list(char *data, size_t * pread_length)
static void packet_empty_list(void) static void packet_empty_list(void)
{ {
struct list_head *ptemp_list; struct packet_data *newpacket, *tmp;
struct list_head *pnext_list;
struct packet_data *newpacket; 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 * zero out the RBU packet memory before freeing
* to make sure there are no stale RBU packets left in memory * to make sure there are no stale RBU packets left in memory
...@@ -407,8 +385,7 @@ static int img_update_realloc(unsigned long size) ...@@ -407,8 +385,7 @@ static int img_update_realloc(unsigned long size)
* check for corruption * check for corruption
*/ */
if ((size != 0) && (rbu_data.image_update_buffer == NULL)) { if ((size != 0) && (rbu_data.image_update_buffer == NULL)) {
printk(KERN_ERR "dell_rbu:%s: corruption " pr_err("corruption check failed\n");
"check failed\n", __func__);
return -EINVAL; return -EINVAL;
} }
/* /*
...@@ -430,8 +407,7 @@ static int img_update_realloc(unsigned long size) ...@@ -430,8 +407,7 @@ static int img_update_realloc(unsigned long size)
(unsigned char *)__get_free_pages(GFP_DMA32, ordernum); (unsigned char *)__get_free_pages(GFP_DMA32, ordernum);
spin_lock(&rbu_data.lock); spin_lock(&rbu_data.lock);
if (!image_update_buffer) { if (!image_update_buffer) {
pr_debug("Not enough memory for image update:" pr_debug("Not enough memory for image update: size = %ld\n", size);
"size = %ld\n", size);
return -ENOMEM; return -ENOMEM;
} }
...@@ -455,15 +431,14 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count) ...@@ -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 */ /* check to see if we have something to return */
if (rbu_data.num_packets == 0) { if (rbu_data.num_packets == 0) {
pr_debug("read_packet_data: no packets written\n"); pr_debug("no packets written\n");
retval = -ENOMEM; retval = -ENOMEM;
goto read_rbu_data_exit; goto read_rbu_data_exit;
} }
if (pos > rbu_data.imagesize) { if (pos > rbu_data.imagesize) {
retval = 0; retval = 0;
printk(KERN_WARNING "dell_rbu:read_packet_data: " pr_warn("data underrun\n");
"data underrun\n");
goto read_rbu_data_exit; goto read_rbu_data_exit;
} }
...@@ -489,8 +464,7 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count) ...@@ -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 */ /* check to see if we have something to return */
if ((rbu_data.image_update_buffer == NULL) || if ((rbu_data.image_update_buffer == NULL) ||
(rbu_data.bios_image_size == 0)) { (rbu_data.bios_image_size == 0)) {
pr_debug("read_rbu_data_mono: image_update_buffer %p ," pr_debug("image_update_buffer %p, bios_image_size %lu\n",
"bios_image_size %lu\n",
rbu_data.image_update_buffer, rbu_data.image_update_buffer,
rbu_data.bios_image_size); rbu_data.bios_image_size);
return -ENOMEM; return -ENOMEM;
...@@ -500,9 +474,9 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count) ...@@ -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); rbu_data.image_update_buffer, rbu_data.bios_image_size);
} }
static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj, static ssize_t data_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count) char *buffer, loff_t pos, size_t count)
{ {
ssize_t ret_count = 0; ssize_t ret_count = 0;
...@@ -513,11 +487,12 @@ static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj, ...@@ -513,11 +487,12 @@ static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj,
else if (!strcmp(image_type, "packet")) else if (!strcmp(image_type, "packet"))
ret_count = read_packet_data(buffer, pos, count); ret_count = read_packet_data(buffer, pos, count);
else else
pr_debug("read_rbu_data: invalid image type specified\n"); pr_debug("invalid image type specified\n");
spin_unlock(&rbu_data.lock); spin_unlock(&rbu_data.lock);
return ret_count; return ret_count;
} }
static BIN_ATTR_RO(data, 0);
static void callbackfn_rbu(const struct firmware *fw, void *context) static void callbackfn_rbu(const struct firmware *fw, void *context)
{ {
...@@ -548,15 +523,15 @@ 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(); packet_empty_list();
} else } else
pr_debug("invalid image type specified.\n"); pr_debug("invalid image type specified\n");
spin_unlock(&rbu_data.lock); spin_unlock(&rbu_data.lock);
out: out:
release_firmware(fw); release_firmware(fw);
} }
static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj, static ssize_t image_type_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count) char *buffer, loff_t pos, size_t count)
{ {
int size = 0; int size = 0;
if (!pos) if (!pos)
...@@ -564,9 +539,9 @@ static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj, ...@@ -564,9 +539,9 @@ static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
return size; return size;
} }
static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, static ssize_t image_type_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count) char *buffer, loff_t pos, size_t count)
{ {
int rc = count; int rc = count;
int req_firm_rc = 0; int req_firm_rc = 0;
...@@ -602,9 +577,7 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, ...@@ -602,9 +577,7 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
&rbu_device->dev, GFP_KERNEL, &context, &rbu_device->dev, GFP_KERNEL, &context,
callbackfn_rbu); callbackfn_rbu);
if (req_firm_rc) { if (req_firm_rc) {
printk(KERN_ERR pr_err("request_firmware_nowait failed %d\n", rc);
"dell_rbu:%s request_firmware_nowait"
" failed %d\n", __func__, rc);
rc = -EIO; rc = -EIO;
} else } else
rbu_data.entry_created = 1; rbu_data.entry_created = 1;
...@@ -612,7 +585,7 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, ...@@ -612,7 +585,7 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
spin_lock(&rbu_data.lock); spin_lock(&rbu_data.lock);
} }
} else { } else {
printk(KERN_WARNING "dell_rbu: image_type is invalid\n"); pr_warn("image_type is invalid\n");
spin_unlock(&rbu_data.lock); spin_unlock(&rbu_data.lock);
return -EINVAL; return -EINVAL;
} }
...@@ -624,10 +597,11 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, ...@@ -624,10 +597,11 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
return rc; return rc;
} }
static BIN_ATTR_RW(image_type, 0);
static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj, static ssize_t packet_size_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count) char *buffer, loff_t pos, size_t count)
{ {
int size = 0; int size = 0;
if (!pos) { if (!pos) {
...@@ -638,9 +612,9 @@ static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj, ...@@ -638,9 +612,9 @@ static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj,
return size; return size;
} }
static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj, static ssize_t packet_size_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count) char *buffer, loff_t pos, size_t count)
{ {
unsigned long temp; unsigned long temp;
spin_lock(&rbu_data.lock); spin_lock(&rbu_data.lock);
...@@ -652,22 +626,17 @@ static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj, ...@@ -652,22 +626,17 @@ static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj,
spin_unlock(&rbu_data.lock); spin_unlock(&rbu_data.lock);
return count; return count;
} }
static BIN_ATTR_RW(packet_size, 0);
static struct bin_attribute rbu_data_attr = { static struct bin_attribute *rbu_bin_attrs[] = {
.attr = {.name = "data", .mode = 0444}, &bin_attr_data,
.read = read_rbu_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 = { static const struct attribute_group rbu_group = {
.attr = {.name = "packet_size", .mode = 0644}, .bin_attrs = rbu_bin_attrs,
.read = read_rbu_packet_size,
.write = write_rbu_packet_size,
}; };
static int __init dcdrbu_init(void) static int __init dcdrbu_init(void)
...@@ -678,30 +647,17 @@ static int __init dcdrbu_init(void) ...@@ -678,30 +647,17 @@ static int __init dcdrbu_init(void)
init_packet_head(); init_packet_head();
rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0); rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0);
if (IS_ERR(rbu_device)) { if (IS_ERR(rbu_device)) {
printk(KERN_ERR pr_err("platform_device_register_simple failed\n");
"dell_rbu:%s:platform_device_register_simple "
"failed\n", __func__);
return PTR_ERR(rbu_device); 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) if (rc)
goto out_devreg; 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; rbu_data.entry_created = 0;
return 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: out_devreg:
platform_device_unregister(rbu_device); platform_device_unregister(rbu_device);
return rc; return rc;
...@@ -713,6 +669,7 @@ static __exit void dcdrbu_exit(void) ...@@ -713,6 +669,7 @@ static __exit void dcdrbu_exit(void)
packet_empty_list(); packet_empty_list();
img_update_free(); img_update_free();
spin_unlock(&rbu_data.lock); spin_unlock(&rbu_data.lock);
sysfs_remove_group(&rbu_device->dev.kobj, &rbu_group);
platform_device_unregister(rbu_device); platform_device_unregister(rbu_device);
} }
......
...@@ -128,7 +128,7 @@ static int gpd_pocket_fan_probe(struct platform_device *pdev) ...@@ -128,7 +128,7 @@ static int gpd_pocket_fan_probe(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(temp_limits); i++) { for (i = 0; i < ARRAY_SIZE(temp_limits); i++) {
if (temp_limits[i] < 20000 || temp_limits[i] > 90000) { 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[i]);
temp_limits[0] = TEMP_LIMIT0_DEFAULT; temp_limits[0] = TEMP_LIMIT0_DEFAULT;
temp_limits[1] = TEMP_LIMIT1_DEFAULT; temp_limits[1] = TEMP_LIMIT1_DEFAULT;
......
...@@ -28,7 +28,7 @@ struct i2c_inst_data { ...@@ -28,7 +28,7 @@ struct i2c_inst_data {
struct i2c_multi_inst_data { struct i2c_multi_inst_data {
int num_clients; int num_clients;
struct i2c_client *clients[0]; struct i2c_client *clients[];
}; };
static int i2c_multi_inst_count(struct acpi_resource *ares, void *data) 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[] = { ...@@ -23,6 +23,7 @@ static const struct acpi_device_id intel_hid_ids[] = {
{"INT33D5", 0}, {"INT33D5", 0},
{"", 0}, {"", 0},
}; };
MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
/* In theory, these are HID usages. */ /* In theory, these are HID usages. */
static const struct key_entry intel_hid_keymap[] = { static const struct key_entry intel_hid_keymap[] = {
...@@ -541,7 +542,6 @@ static struct platform_driver intel_hid_pl_driver = { ...@@ -541,7 +542,6 @@ static struct platform_driver intel_hid_pl_driver = {
.probe = intel_hid_probe, .probe = intel_hid_probe,
.remove = intel_hid_remove, .remove = intel_hid_remove,
}; };
MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
/* /*
* Unfortunately, some laptops provide a _HID="INT33D5" device with * Unfortunately, some laptops provide a _HID="INT33D5" device with
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
*/ */
struct uncore_data { struct uncore_data {
struct kobject kobj; struct kobject kobj;
struct completion kobj_unregister;
u64 stored_uncore_data; u64 stored_uncore_data;
u32 initial_min_freq_khz; u32 initial_min_freq_khz;
u32 initial_max_freq_khz; u32 initial_max_freq_khz;
...@@ -52,7 +53,7 @@ static int uncore_max_entries __read_mostly; ...@@ -52,7 +53,7 @@ static int uncore_max_entries __read_mostly;
/* Storage for uncore data for all instances */ /* Storage for uncore data for all instances */
static struct uncore_data *uncore_instances; static struct uncore_data *uncore_instances;
/* Root of the all uncore sysfs kobjs */ /* 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 */ /* Stores the CPU mask of the target CPUs to use during uncore read/write */
static cpumask_t uncore_cpu_mask; static cpumask_t uncore_cpu_mask;
/* CPU online callback register instance */ /* CPU online callback register instance */
...@@ -97,6 +98,9 @@ static int uncore_read_ratio(struct uncore_data *data, unsigned int *min, ...@@ -97,6 +98,9 @@ static int uncore_read_ratio(struct uncore_data *data, unsigned int *min,
u64 cap; u64 cap;
int ret; int ret;
if (data->control_cpu < 0)
return -ENXIO;
ret = rdmsrl_on_cpu(data->control_cpu, MSR_UNCORE_RATIO_LIMIT, &cap); ret = rdmsrl_on_cpu(data->control_cpu, MSR_UNCORE_RATIO_LIMIT, &cap);
if (ret) if (ret)
return ret; return ret;
...@@ -116,6 +120,11 @@ static int uncore_write_ratio(struct uncore_data *data, unsigned int input, ...@@ -116,6 +120,11 @@ static int uncore_write_ratio(struct uncore_data *data, unsigned int input,
mutex_lock(&uncore_lock); mutex_lock(&uncore_lock);
if (data->control_cpu < 0) {
ret = -ENXIO;
goto finish_write;
}
input /= UNCORE_FREQ_KHZ_MULTIPLIER; input /= UNCORE_FREQ_KHZ_MULTIPLIER;
if (!input || input > 0x7F) { if (!input || input > 0x7F) {
ret = -EINVAL; ret = -EINVAL;
...@@ -217,15 +226,19 @@ static struct attribute *uncore_attrs[] = { ...@@ -217,15 +226,19 @@ static struct attribute *uncore_attrs[] = {
NULL 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 = { static struct kobj_type uncore_ktype = {
.release = uncore_sysfs_entry_release,
.sysfs_ops = &kobj_sysfs_ops, .sysfs_ops = &kobj_sysfs_ops,
.default_attrs = uncore_attrs, .default_attrs = uncore_attrs,
}; };
static struct kobj_type uncore_root_ktype = {
.sysfs_ops = &kobj_sysfs_ops,
};
/* Caller provides protection */ /* Caller provides protection */
static struct uncore_data *uncore_get_instance(unsigned int cpu) static struct uncore_data *uncore_get_instance(unsigned int cpu)
{ {
...@@ -263,8 +276,10 @@ static void uncore_add_die_entry(int cpu) ...@@ -263,8 +276,10 @@ static void uncore_add_die_entry(int cpu)
uncore_read_ratio(data, &data->initial_min_freq_khz, uncore_read_ratio(data, &data->initial_min_freq_khz,
&data->initial_max_freq_khz); &data->initial_max_freq_khz);
init_completion(&data->kobj_unregister);
ret = kobject_init_and_add(&data->kobj, &uncore_ktype, ret = kobject_init_and_add(&data->kobj, &uncore_ktype,
&uncore_root_kobj, str); uncore_root_kobj, str);
if (!ret) { if (!ret) {
data->control_cpu = cpu; data->control_cpu = cpu;
data->valid = true; data->valid = true;
...@@ -273,18 +288,15 @@ static void uncore_add_die_entry(int cpu) ...@@ -273,18 +288,15 @@ static void uncore_add_die_entry(int cpu)
mutex_unlock(&uncore_lock); 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) static void uncore_remove_die_entry(int cpu)
{ {
struct uncore_data *data; struct uncore_data *data;
mutex_lock(&uncore_lock); mutex_lock(&uncore_lock);
data = uncore_get_instance(cpu); data = uncore_get_instance(cpu);
if (data) { if (data)
kobject_put(&data->kobj);
data->control_cpu = -1; data->control_cpu = -1;
data->valid = false;
}
mutex_unlock(&uncore_lock); mutex_unlock(&uncore_lock);
} }
...@@ -384,11 +396,12 @@ static int __init intel_uncore_init(void) ...@@ -384,11 +396,12 @@ static int __init intel_uncore_init(void)
if (!uncore_instances) if (!uncore_instances)
return -ENOMEM; return -ENOMEM;
ret = kobject_init_and_add(&uncore_root_kobj, &uncore_root_ktype, uncore_root_kobj = kobject_create_and_add("intel_uncore_frequency",
&cpu_subsys.dev_root->kobj, &cpu_subsys.dev_root->kobj);
"intel_uncore_frequency"); if (!uncore_root_kobj) {
if (ret) ret = -ENOMEM;
goto err_free; goto err_free;
}
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
"platform/x86/uncore-freq:online", "platform/x86/uncore-freq:online",
...@@ -408,7 +421,7 @@ static int __init intel_uncore_init(void) ...@@ -408,7 +421,7 @@ static int __init intel_uncore_init(void)
err_rem_state: err_rem_state:
cpuhp_remove_state(uncore_hp_state); cpuhp_remove_state(uncore_hp_state);
err_rem_kobj: err_rem_kobj:
kobject_put(&uncore_root_kobj); kobject_put(uncore_root_kobj);
err_free: err_free:
kfree(uncore_instances); kfree(uncore_instances);
...@@ -423,10 +436,12 @@ static void __exit intel_uncore_exit(void) ...@@ -423,10 +436,12 @@ static void __exit intel_uncore_exit(void)
unregister_pm_notifier(&uncore_pm_nb); unregister_pm_notifier(&uncore_pm_nb);
cpuhp_remove_state(uncore_hp_state); cpuhp_remove_state(uncore_hp_state);
for (i = 0; i < uncore_max_entries; ++i) { for (i = 0; i < uncore_max_entries; ++i) {
if (uncore_instances[i].valid) if (uncore_instances[i].valid) {
kobject_put(&uncore_instances[i].kobj); 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); kfree(uncore_instances);
} }
module_exit(intel_uncore_exit) module_exit(intel_uncore_exit)
......
...@@ -26,6 +26,7 @@ static const struct acpi_device_id intel_vbtn_ids[] = { ...@@ -26,6 +26,7 @@ static const struct acpi_device_id intel_vbtn_ids[] = {
{"INT33D6", 0}, {"INT33D6", 0},
{"", 0}, {"", 0},
}; };
MODULE_DEVICE_TABLE(acpi, intel_vbtn_ids);
/* In theory, these are HID usages. */ /* In theory, these are HID usages. */
static const struct key_entry intel_vbtn_keymap[] = { static const struct key_entry intel_vbtn_keymap[] = {
...@@ -239,7 +240,6 @@ static struct platform_driver intel_vbtn_pl_driver = { ...@@ -239,7 +240,6 @@ static struct platform_driver intel_vbtn_pl_driver = {
.probe = intel_vbtn_probe, .probe = intel_vbtn_probe,
.remove = intel_vbtn_remove, .remove = intel_vbtn_remove,
}; };
MODULE_DEVICE_TABLE(acpi, intel_vbtn_ids);
static acpi_status __init static acpi_status __init
check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv) check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
...@@ -193,7 +194,7 @@ static const struct pmc_bit_map cnp_pfear_map[] = { ...@@ -193,7 +194,7 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{"Fuse", BIT(6)}, {"Fuse", BIT(6)},
/* /*
* Reserved for Cannon Lake but valid for Ice Lake, Comet Lake, * 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)}, {"SBR8", BIT(7)},
...@@ -240,7 +241,7 @@ static const struct pmc_bit_map cnp_pfear_map[] = { ...@@ -240,7 +241,7 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{"HDA_PGD6", BIT(4)}, {"HDA_PGD6", BIT(4)},
/* /*
* Reserved for Cannon Lake but valid for Ice Lake, Comet Lake, * 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)}, {"PSF6", BIT(5)},
{"PSF7", BIT(6)}, {"PSF7", BIT(6)},
...@@ -273,7 +274,7 @@ static const struct pmc_bit_map *ext_icl_pfear_map[] = { ...@@ -273,7 +274,7 @@ static const struct pmc_bit_map *ext_icl_pfear_map[] = {
}; };
static const struct pmc_bit_map tgl_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)}, {"PSF9", BIT(0)},
{"RES_66", BIT(1)}, {"RES_66", BIT(1)},
{"RES_67", BIT(2)}, {"RES_67", BIT(2)},
...@@ -408,13 +409,157 @@ static const struct pmc_reg_map icl_reg_map = { ...@@ -408,13 +409,157 @@ static const struct pmc_reg_map icl_reg_map = {
.ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED, .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 = { static const struct pmc_reg_map tgl_reg_map = {
.pfear_sts = ext_tgl_pfear_map, .pfear_sts = ext_tgl_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slps0_dbg_maps = cnp_slps0_dbg_maps,
.ltr_show_sts = cnp_ltr_show_map, .ltr_show_sts = cnp_ltr_show_map,
.msr_sts = msr_map, .msr_sts = msr_map,
.slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET,
.ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
.regmap_length = CNP_PMC_MMIO_REG_LEN, .regmap_length = CNP_PMC_MMIO_REG_LEN,
.ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
...@@ -422,6 +567,12 @@ static const struct pmc_reg_map tgl_reg_map = { ...@@ -422,6 +567,12 @@ static const struct pmc_reg_map tgl_reg_map = {
.pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
.pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
.ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED, .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) 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) ...@@ -463,6 +614,84 @@ static int pmc_core_check_read_lock_bit(void)
return value & BIT(pmcdev->map->pm_read_disable_bit); 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) #if IS_ENABLED(CONFIG_DEBUG_FS)
static bool slps0_dbg_latch; static bool slps0_dbg_latch;
...@@ -698,27 +927,11 @@ static void pmc_core_slps0_dbg_latch(struct pmc_dev *pmcdev, bool reset) ...@@ -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) static int pmc_core_slps0_dbg_show(struct seq_file *s, void *unused)
{ {
struct pmc_dev *pmcdev = s->private; 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); pmc_core_slps0_dbg_latch(pmcdev, false);
offset = pmcdev->map->slps0_dbg_offset; pmc_core_slps0_display(pmcdev, NULL, s);
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_dbg_latch(pmcdev, true); pmc_core_slps0_dbg_latch(pmcdev, true);
return 0; return 0;
} }
DEFINE_SHOW_ATTRIBUTE(pmc_core_slps0_dbg); DEFINE_SHOW_ATTRIBUTE(pmc_core_slps0_dbg);
...@@ -794,6 +1007,51 @@ static int pmc_core_ltr_show(struct seq_file *s, void *unused) ...@@ -794,6 +1007,51 @@ static int pmc_core_ltr_show(struct seq_file *s, void *unused)
} }
DEFINE_SHOW_ATTRIBUTE(pmc_core_ltr); 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) static int pmc_core_pkgc_show(struct seq_file *s, void *unused)
{ {
struct pmc_dev *pmcdev = s->private; struct pmc_dev *pmcdev = s->private;
...@@ -859,6 +1117,21 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev) ...@@ -859,6 +1117,21 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
debugfs_create_bool("slp_s0_dbg_latch", 0644, debugfs_create_bool("slp_s0_dbg_latch", 0644,
dir, &slps0_dbg_latch); 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 #else
static inline void pmc_core_dbgfs_register(struct pmc_dev *pmcdev) 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[] = { ...@@ -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_L, &tgl_reg_map),
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &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, &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) ...@@ -1047,10 +1321,8 @@ static inline bool pmc_core_is_s0ix_failed(struct pmc_dev *pmcdev)
static int pmc_core_resume(struct device *dev) static int pmc_core_resume(struct device *dev)
{ {
struct pmc_dev *pmcdev = dev_get_drvdata(dev); struct pmc_dev *pmcdev = dev_get_drvdata(dev);
const struct pmc_bit_map **maps = pmcdev->map->slps0_dbg_maps; const struct pmc_bit_map **maps = pmcdev->map->lpm_sts;
int offset = pmcdev->map->slps0_dbg_offset; int offset = pmcdev->map->lpm_status_offset;
const struct pmc_bit_map *map;
u32 data;
if (!pmcdev->check_counters) if (!pmcdev->check_counters)
return 0; return 0;
...@@ -1068,18 +1340,11 @@ static int pmc_core_resume(struct device *dev) ...@@ -1068,18 +1340,11 @@ static int pmc_core_resume(struct device *dev)
/* The real interesting case - S0ix failed - lets ask PMC why. */ /* The real interesting case - S0ix failed - lets ask PMC why. */
dev_warn(dev, "CPU did not enter SLP_S0!!! (S0ix cnt=%llu)\n", dev_warn(dev, "CPU did not enter SLP_S0!!! (S0ix cnt=%llu)\n",
pmcdev->s0ix_counter); pmcdev->s0ix_counter);
while (*maps) { if (pmcdev->map->slps0_dbg_maps)
map = *maps; pmc_core_slps0_display(pmcdev, dev, NULL);
data = pmc_core_reg_read(pmcdev, offset); if (pmcdev->map->lpm_sts)
offset += 4; pmc_core_lpm_display(pmcdev, dev, NULL, offset, "STATUS", maps);
while (map->name) {
dev_dbg(dev, "SLP_S0_DBG: %-32s\tState: %s\n",
map->name,
data & map->bit_mask ? "Yes" : "No");
map++;
}
maps++;
}
return 0; return 0;
} }
......
...@@ -188,6 +188,28 @@ enum ppfear_regs { ...@@ -188,6 +188,28 @@ enum ppfear_regs {
#define TGL_NUM_IP_IGN_ALLOWED 22 #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 { struct pmc_bit_map {
const char *name; const char *name;
u32 bit_mask; u32 bit_mask;
...@@ -221,6 +243,7 @@ struct pmc_reg_map { ...@@ -221,6 +243,7 @@ struct pmc_reg_map {
const struct pmc_bit_map **slps0_dbg_maps; const struct pmc_bit_map **slps0_dbg_maps;
const struct pmc_bit_map *ltr_show_sts; const struct pmc_bit_map *ltr_show_sts;
const struct pmc_bit_map *msr_sts; const struct pmc_bit_map *msr_sts;
const struct pmc_bit_map **lpm_sts;
const u32 slp_s0_offset; const u32 slp_s0_offset;
const u32 ltr_ignore_offset; const u32 ltr_ignore_offset;
const int regmap_length; const int regmap_length;
...@@ -231,6 +254,12 @@ struct pmc_reg_map { ...@@ -231,6 +254,12 @@ struct pmc_reg_map {
const u32 slps0_dbg_offset; const u32 slps0_dbg_offset;
const u32 ltr_ignore_max; const u32 ltr_ignore_max;
const u32 pm_vric1_offset; 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) ...@@ -126,7 +126,7 @@ static void isst_if_remove(struct pci_dev *pdev)
struct isst_if_device *punit_dev; struct isst_if_device *punit_dev;
punit_dev = pci_get_drvdata(pdev); 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); mutex_destroy(&punit_dev->mutex);
} }
......
...@@ -383,6 +383,14 @@ static const struct dmi_system_id critclk_systems[] = { ...@@ -383,6 +383,14 @@ static const struct dmi_system_id critclk_systems[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "3I380D"), 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 */ /* pmc_plt_clk* - are used for ethernet controllers */
.ident = "Beckhoff CB3163", .ident = "Beckhoff CB3163",
......
...@@ -827,10 +827,10 @@ static ssize_t sony_nc_handles_show(struct device *dev, ...@@ -827,10 +827,10 @@ static ssize_t sony_nc_handles_show(struct device *dev,
int i; int i;
for (i = 0; i < ARRAY_SIZE(handles->cap); 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]); handles->cap[i]);
} }
len += snprintf(buffer + len, PAGE_SIZE - len, "\n"); len += scnprintf(buffer + len, PAGE_SIZE - len, "\n");
return len; return len;
} }
...@@ -2187,10 +2187,10 @@ static ssize_t sony_nc_thermal_profiles_show(struct device *dev, ...@@ -2187,10 +2187,10 @@ static ssize_t sony_nc_thermal_profiles_show(struct device *dev,
for (cnt = 0; cnt < THM_PROFILE_MAX; cnt++) { for (cnt = 0; cnt < THM_PROFILE_MAX; cnt++) {
if (!cnt || (th_handle->profiles & 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]); snc_thermal_profiles[cnt]);
} }
idx += snprintf(buffer + idx, PAGE_SIZE - idx, "\n"); idx += scnprintf(buffer + idx, PAGE_SIZE - idx, "\n");
return idx; return idx;
} }
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Supports for the power IC on the Surface 3 tablet.
*
* (C) Copyright 2016-2018 Red Hat, Inc
* (C) Copyright 2016-2018 Benjamin Tissoires <benjamin.tissoires@gmail.com>
* (C) Copyright 2016 Stephen Just <stephenjust@gmail.com>
*
* This driver has been reverse-engineered by parsing the DSDT of the Surface 3
* and looking at the registers of the chips.
*
* The DSDT allowed to find out that:
* - the driver is required for the ACPI BAT0 device to communicate to the chip
* through an operation region.
* - the various defines for the operation region functions to communicate with
* this driver
* - the DSM 3f99e367-6220-4955-8b0f-06ef2ae79412 allows to trigger ACPI
* events to BAT0 (the code is all available in the DSDT).
*
* Further findings regarding the 2 chips declared in the MSHW0011 are:
* - there are 2 chips declared:
* . 0x22 seems to control the ADP1 line status (and probably the charger)
* . 0x55 controls the battery directly
* - the battery chip uses a SMBus protocol (using plain SMBus allows non
* destructive commands):
* . the commands/registers used are in the range 0x00..0x7F
* . if bit 8 (0x80) is set in the SMBus command, the returned value is the
* same as when it is not set. There is a high chance this bit is the
* read/write
* . the various registers semantic as been deduced by observing the register
* dumps.
*/
#include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/freezer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uuid.h>
#include <asm/unaligned.h>
#define SURFACE_3_POLL_INTERVAL (2 * HZ)
#define SURFACE_3_STRLEN 10
struct mshw0011_data {
struct i2c_client *adp1;
struct i2c_client *bat0;
unsigned short notify_mask;
struct task_struct *poll_task;
bool kthread_running;
bool charging;
bool bat_charging;
u8 trip_point;
s32 full_capacity;
};
struct mshw0011_handler_data {
struct acpi_connection_info info;
struct i2c_client *client;
};
struct bix {
u32 revision;
u32 power_unit;
u32 design_capacity;
u32 last_full_charg_capacity;
u32 battery_technology;
u32 design_voltage;
u32 design_capacity_of_warning;
u32 design_capacity_of_low;
u32 cycle_count;
u32 measurement_accuracy;
u32 max_sampling_time;
u32 min_sampling_time;
u32 max_average_interval;
u32 min_average_interval;
u32 battery_capacity_granularity_1;
u32 battery_capacity_granularity_2;
char model[SURFACE_3_STRLEN];
char serial[SURFACE_3_STRLEN];
char type[SURFACE_3_STRLEN];
char OEM[SURFACE_3_STRLEN];
} __packed;
struct bst {
u32 battery_state;
s32 battery_present_rate;
u32 battery_remaining_capacity;
u32 battery_present_voltage;
} __packed;
struct gsb_command {
u8 arg0;
u8 arg1;
u8 arg2;
} __packed;
struct gsb_buffer {
u8 status;
u8 len;
u8 ret;
union {
struct gsb_command cmd;
struct bst bst;
struct bix bix;
} __packed;
} __packed;
#define ACPI_BATTERY_STATE_DISCHARGING BIT(0)
#define ACPI_BATTERY_STATE_CHARGING BIT(1)
#define ACPI_BATTERY_STATE_CRITICAL BIT(2)
#define MSHW0011_CMD_DEST_BAT0 0x01
#define MSHW0011_CMD_DEST_ADP1 0x03
#define MSHW0011_CMD_BAT0_STA 0x01
#define MSHW0011_CMD_BAT0_BIX 0x02
#define MSHW0011_CMD_BAT0_BCT 0x03
#define MSHW0011_CMD_BAT0_BTM 0x04
#define MSHW0011_CMD_BAT0_BST 0x05
#define MSHW0011_CMD_BAT0_BTP 0x06
#define MSHW0011_CMD_ADP1_PSR 0x07
#define MSHW0011_CMD_BAT0_PSOC 0x09
#define MSHW0011_CMD_BAT0_PMAX 0x0a
#define MSHW0011_CMD_BAT0_PSRC 0x0b
#define MSHW0011_CMD_BAT0_CHGI 0x0c
#define MSHW0011_CMD_BAT0_ARTG 0x0d
#define MSHW0011_NOTIFY_GET_VERSION 0x00
#define MSHW0011_NOTIFY_ADP1 0x01
#define MSHW0011_NOTIFY_BAT0_BST 0x02
#define MSHW0011_NOTIFY_BAT0_BIX 0x05
#define MSHW0011_ADP1_REG_PSR 0x04
#define MSHW0011_BAT0_REG_CAPACITY 0x0c
#define MSHW0011_BAT0_REG_FULL_CHG_CAPACITY 0x0e
#define MSHW0011_BAT0_REG_DESIGN_CAPACITY 0x40
#define MSHW0011_BAT0_REG_VOLTAGE 0x08
#define MSHW0011_BAT0_REG_RATE 0x14
#define MSHW0011_BAT0_REG_OEM 0x45
#define MSHW0011_BAT0_REG_TYPE 0x4e
#define MSHW0011_BAT0_REG_SERIAL_NO 0x56
#define MSHW0011_BAT0_REG_CYCLE_CNT 0x6e
#define MSHW0011_EV_2_5_MASK GENMASK(8, 0)
/* 3f99e367-6220-4955-8b0f-06ef2ae79412 */
static const guid_t mshw0011_guid =
GUID_INIT(0x3F99E367, 0x6220, 0x4955, 0x8B, 0x0F, 0x06, 0xEF,
0x2A, 0xE7, 0x94, 0x12);
static int
mshw0011_notify(struct mshw0011_data *cdata, u8 arg1, u8 arg2,
unsigned int *ret_value)
{
union acpi_object *obj;
struct acpi_device *adev;
acpi_handle handle;
unsigned int i;
handle = ACPI_HANDLE(&cdata->adp1->dev);
if (!handle || acpi_bus_get_device(handle, &adev))
return -ENODEV;
obj = acpi_evaluate_dsm_typed(handle, &mshw0011_guid, arg1, arg2, NULL,
ACPI_TYPE_BUFFER);
if (!obj) {
dev_err(&cdata->adp1->dev, "device _DSM execution failed\n");
return -ENODEV;
}
*ret_value = 0;
for (i = 0; i < obj->buffer.length; i++)
*ret_value |= obj->buffer.pointer[i] << (i * 8);
ACPI_FREE(obj);
return 0;
}
static const struct bix default_bix = {
.revision = 0x00,
.power_unit = 0x01,
.design_capacity = 0x1dca,
.last_full_charg_capacity = 0x1dca,
.battery_technology = 0x01,
.design_voltage = 0x10df,
.design_capacity_of_warning = 0x8f,
.design_capacity_of_low = 0x47,
.cycle_count = 0xffffffff,
.measurement_accuracy = 0x00015f90,
.max_sampling_time = 0x03e8,
.min_sampling_time = 0x03e8,
.max_average_interval = 0x03e8,
.min_average_interval = 0x03e8,
.battery_capacity_granularity_1 = 0x45,
.battery_capacity_granularity_2 = 0x11,
.model = "P11G8M",
.serial = "",
.type = "LION",
.OEM = "",
};
static int mshw0011_bix(struct mshw0011_data *cdata, struct bix *bix)
{
struct i2c_client *client = cdata->bat0;
char buf[SURFACE_3_STRLEN];
int ret;
*bix = default_bix;
/* get design capacity */
ret = i2c_smbus_read_word_data(client,
MSHW0011_BAT0_REG_DESIGN_CAPACITY);
if (ret < 0) {
dev_err(&client->dev, "Error reading design capacity: %d\n",
ret);
return ret;
}
bix->design_capacity = ret;
/* get last full charge capacity */
ret = i2c_smbus_read_word_data(client,
MSHW0011_BAT0_REG_FULL_CHG_CAPACITY);
if (ret < 0) {
dev_err(&client->dev,
"Error reading last full charge capacity: %d\n", ret);
return ret;
}
bix->last_full_charg_capacity = ret;
/* get serial number */
ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO,
sizeof(buf), buf);
if (ret != sizeof(buf)) {
dev_err(&client->dev, "Error reading serial no: %d\n", ret);
return ret;
}
snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf);
/* get cycle count */
ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT);
if (ret < 0) {
dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
return ret;
}
bix->cycle_count = ret;
/* get OEM name */
ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_OEM,
4, buf);
if (ret != 4) {
dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
return ret;
}
snprintf(bix->OEM, ARRAY_SIZE(bix->OEM), "%3pE", buf);
return 0;
}
static int mshw0011_bst(struct mshw0011_data *cdata, struct bst *bst)
{
struct i2c_client *client = cdata->bat0;
int rate, capacity, voltage, state;
s16 tmp;
rate = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_RATE);
if (rate < 0)
return rate;
capacity = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CAPACITY);
if (capacity < 0)
return capacity;
voltage = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_VOLTAGE);
if (voltage < 0)
return voltage;
tmp = rate;
bst->battery_present_rate = abs((s32)tmp);
state = 0;
if ((s32) tmp > 0)
state |= ACPI_BATTERY_STATE_CHARGING;
else if ((s32) tmp < 0)
state |= ACPI_BATTERY_STATE_DISCHARGING;
bst->battery_state = state;
bst->battery_remaining_capacity = capacity;
bst->battery_present_voltage = voltage;
return 0;
}
static int mshw0011_adp_psr(struct mshw0011_data *cdata)
{
return i2c_smbus_read_byte_data(cdata->adp1, MSHW0011_ADP1_REG_PSR);
}
static int mshw0011_isr(struct mshw0011_data *cdata)
{
struct bst bst;
struct bix bix;
int ret;
bool status, bat_status;
ret = mshw0011_adp_psr(cdata);
if (ret < 0)
return ret;
status = ret;
if (status != cdata->charging)
mshw0011_notify(cdata, cdata->notify_mask,
MSHW0011_NOTIFY_ADP1, &ret);
cdata->charging = status;
ret = mshw0011_bst(cdata, &bst);
if (ret < 0)
return ret;
bat_status = bst.battery_state;
if (bat_status != cdata->bat_charging)
mshw0011_notify(cdata, cdata->notify_mask,
MSHW0011_NOTIFY_BAT0_BST, &ret);
cdata->bat_charging = bat_status;
ret = mshw0011_bix(cdata, &bix);
if (ret < 0)
return ret;
if (bix.last_full_charg_capacity != cdata->full_capacity)
mshw0011_notify(cdata, cdata->notify_mask,
MSHW0011_NOTIFY_BAT0_BIX, &ret);
cdata->full_capacity = bix.last_full_charg_capacity;
return 0;
}
static int mshw0011_poll_task(void *data)
{
struct mshw0011_data *cdata = data;
int ret = 0;
cdata->kthread_running = true;
set_freezable();
while (!kthread_should_stop()) {
schedule_timeout_interruptible(SURFACE_3_POLL_INTERVAL);
try_to_freeze();
ret = mshw0011_isr(data);
if (ret)
break;
}
cdata->kthread_running = false;
return ret;
}
static acpi_status
mshw0011_space_handler(u32 function, acpi_physical_address command,
u32 bits, u64 *value64,
void *handler_context, void *region_context)
{
struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
struct mshw0011_handler_data *data = handler_context;
struct acpi_connection_info *info = &data->info;
struct acpi_resource_i2c_serialbus *sb;
struct i2c_client *client = data->client;
struct mshw0011_data *cdata = i2c_get_clientdata(client);
struct acpi_resource *ares;
u32 accessor_type = function >> 16;
acpi_status ret;
int status = 1;
ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
if (ACPI_FAILURE(ret))
return ret;
if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
ret = AE_BAD_PARAMETER;
goto err;
}
sb = &ares->data.i2c_serial_bus;
if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
ret = AE_BAD_PARAMETER;
goto err;
}
if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
ret = AE_BAD_PARAMETER;
goto err;
}
if (gsb->cmd.arg0 == MSHW0011_CMD_DEST_ADP1 &&
gsb->cmd.arg1 == MSHW0011_CMD_ADP1_PSR) {
status = mshw0011_adp_psr(cdata);
if (status >= 0) {
ret = AE_OK;
goto out;
} else {
ret = AE_ERROR;
goto err;
}
}
if (gsb->cmd.arg0 != MSHW0011_CMD_DEST_BAT0) {
ret = AE_BAD_PARAMETER;
goto err;
}
switch (gsb->cmd.arg1) {
case MSHW0011_CMD_BAT0_STA:
break;
case MSHW0011_CMD_BAT0_BIX:
ret = mshw0011_bix(cdata, &gsb->bix);
break;
case MSHW0011_CMD_BAT0_BTP:
cdata->trip_point = gsb->cmd.arg2;
break;
case MSHW0011_CMD_BAT0_BST:
ret = mshw0011_bst(cdata, &gsb->bst);
break;
default:
dev_info(&cdata->bat0->dev, "command(0x%02x) is not supported.\n", gsb->cmd.arg1);
ret = AE_BAD_PARAMETER;
goto err;
}
out:
gsb->ret = status;
gsb->status = 0;
err:
ACPI_FREE(ares);
return ret;
}
static int mshw0011_install_space_handler(struct i2c_client *client)
{
acpi_handle handle;
struct mshw0011_handler_data *data;
acpi_status status;
handle = ACPI_HANDLE(&client->dev);
if (!handle)
return -ENODEV;
data = kzalloc(sizeof(struct mshw0011_handler_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
data->client = client;
status = acpi_bus_attach_private_data(handle, (void *)data);
if (ACPI_FAILURE(status)) {
kfree(data);
return -ENOMEM;
}
status = acpi_install_address_space_handler(handle,
ACPI_ADR_SPACE_GSBUS,
&mshw0011_space_handler,
NULL,
data);
if (ACPI_FAILURE(status)) {
dev_err(&client->dev, "Error installing i2c space handler\n");
acpi_bus_detach_private_data(handle);
kfree(data);
return -ENOMEM;
}
acpi_walk_dep_device_list(handle);
return 0;
}
static void mshw0011_remove_space_handler(struct i2c_client *client)
{
struct mshw0011_handler_data *data;
acpi_handle handle;
acpi_status status;
handle = ACPI_HANDLE(&client->dev);
if (!handle)
return;
acpi_remove_address_space_handler(handle,
ACPI_ADR_SPACE_GSBUS,
&mshw0011_space_handler);
status = acpi_bus_get_private_data(handle, (void **)&data);
if (ACPI_SUCCESS(status))
kfree(data);
acpi_bus_detach_private_data(handle);
}
static int mshw0011_probe(struct i2c_client *client)
{
struct i2c_board_info board_info;
struct device *dev = &client->dev;
struct i2c_client *bat0;
struct mshw0011_data *data;
int error, mask;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->adp1 = client;
i2c_set_clientdata(client, data);
memset(&board_info, 0, sizeof(board_info));
strlcpy(board_info.type, "MSHW0011-bat0", I2C_NAME_SIZE);
bat0 = i2c_acpi_new_device(dev, 1, &board_info);
if (!bat0)
return -ENOMEM;
data->bat0 = bat0;
i2c_set_clientdata(bat0, data);
error = mshw0011_notify(data, 1, MSHW0011_NOTIFY_GET_VERSION, &mask);
if (error)
goto out_err;
data->notify_mask = mask == MSHW0011_EV_2_5_MASK;
data->poll_task = kthread_run(mshw0011_poll_task, data, "mshw0011_adp");
if (IS_ERR(data->poll_task)) {
error = PTR_ERR(data->poll_task);
dev_err(&client->dev, "Unable to run kthread err %d\n", error);
goto out_err;
}
error = mshw0011_install_space_handler(client);
if (error)
goto out_err;
return 0;
out_err:
if (data->kthread_running)
kthread_stop(data->poll_task);
i2c_unregister_device(data->bat0);
return error;
}
static int mshw0011_remove(struct i2c_client *client)
{
struct mshw0011_data *cdata = i2c_get_clientdata(client);
mshw0011_remove_space_handler(client);
if (cdata->kthread_running)
kthread_stop(cdata->poll_task);
i2c_unregister_device(cdata->bat0);
return 0;
}
static const struct acpi_device_id mshw0011_acpi_match[] = {
{ "MSHW0011", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, mshw0011_acpi_match);
static struct i2c_driver mshw0011_driver = {
.probe_new = mshw0011_probe,
.remove = mshw0011_remove,
.driver = {
.name = "mshw0011",
.acpi_match_table = mshw0011_acpi_match,
},
};
module_i2c_driver(mshw0011_driver);
MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
MODULE_DESCRIPTION("mshw0011 driver");
MODULE_LICENSE("GPL v2");
...@@ -15,7 +15,7 @@ struct process_cmd_struct { ...@@ -15,7 +15,7 @@ struct process_cmd_struct {
int arg; int arg;
}; };
static const char *version_str = "v1.2"; static const char *version_str = "v1.3";
static const int supported_api_ver = 1; static const int supported_api_ver = 1;
static struct isst_if_platform_info isst_platform_info; static struct isst_if_platform_info isst_platform_info;
static char *progname; static char *progname;
...@@ -42,6 +42,7 @@ static int out_format_json; ...@@ -42,6 +42,7 @@ static int out_format_json;
static int cmd_help; static int cmd_help;
static int force_online_offline; static int force_online_offline;
static int auto_mode; static int auto_mode;
static int fact_enable_fail;
/* clos related */ /* clos related */
static int current_clos = -1; static int current_clos = -1;
...@@ -61,6 +62,18 @@ struct _cpu_map { ...@@ -61,6 +62,18 @@ struct _cpu_map {
}; };
struct _cpu_map *cpu_map; struct _cpu_map *cpu_map;
struct cpu_topology {
short cpu;
short core_id;
short pkg_id;
short die_id;
};
FILE *get_output_file(void)
{
return outf;
}
void debug_printf(const char *format, ...) void debug_printf(const char *format, ...)
{ {
va_list args; va_list args;
...@@ -82,6 +95,14 @@ int is_clx_n_platform(void) ...@@ -82,6 +95,14 @@ int is_clx_n_platform(void)
return 0; return 0;
} }
int is_skx_based_platform(void)
{
if (cpu_model == 0x55)
return 1;
return 0;
}
static int update_cpu_model(void) static int update_cpu_model(void)
{ {
unsigned int ebx, ecx, edx; unsigned int ebx, ecx, edx;
...@@ -175,25 +196,137 @@ int out_format_is_json(void) ...@@ -175,25 +196,137 @@ int out_format_is_json(void)
return out_format_json; return out_format_json;
} }
static int get_stored_topology_info(int cpu, int *core_id, int *pkg_id, int *die_id)
{
const char *pathname = "/tmp/isst_cpu_topology.dat";
struct cpu_topology cpu_top;
FILE *fp;
int ret;
fp = fopen(pathname, "rb");
if (!fp)
return -1;
ret = fseek(fp, cpu * sizeof(cpu_top), SEEK_SET);
if (ret)
goto err_ret;
ret = fread(&cpu_top, sizeof(cpu_top), 1, fp);
if (ret != 1) {
ret = -1;
goto err_ret;
}
*pkg_id = cpu_top.pkg_id;
*core_id = cpu_top.core_id;
*die_id = cpu_top.die_id;
ret = 0;
err_ret:
fclose(fp);
return ret;
}
static void store_cpu_topology(void)
{
const char *pathname = "/tmp/isst_cpu_topology.dat";
FILE *fp;
int i;
fp = fopen(pathname, "rb");
if (fp) {
/* Mapping already exists */
fclose(fp);
return;
}
fp = fopen(pathname, "wb");
if (!fp) {
fprintf(stderr, "Can't create file:%s\n", pathname);
return;
}
for (i = 0; i < topo_max_cpus; ++i) {
struct cpu_topology cpu_top;
cpu_top.core_id = parse_int_file(0,
"/sys/devices/system/cpu/cpu%d/topology/core_id", i);
if (cpu_top.core_id < 0)
cpu_top.core_id = -1;
cpu_top.pkg_id = parse_int_file(0,
"/sys/devices/system/cpu/cpu%d/topology/physical_package_id", i);
if (cpu_top.pkg_id < 0)
cpu_top.pkg_id = -1;
cpu_top.die_id = parse_int_file(0,
"/sys/devices/system/cpu/cpu%d/topology/die_id", i);
if (cpu_top.die_id < 0)
cpu_top.die_id = -1;
cpu_top.cpu = i;
if (fwrite(&cpu_top, sizeof(cpu_top), 1, fp) != 1) {
fprintf(stderr, "Can't write to:%s\n", pathname);
break;
}
}
fclose(fp);
}
int get_physical_package_id(int cpu) int get_physical_package_id(int cpu)
{ {
return parse_int_file( int ret;
0, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id",
cpu); ret = parse_int_file(0,
"/sys/devices/system/cpu/cpu%d/topology/physical_package_id",
cpu);
if (ret < 0) {
int core_id, pkg_id, die_id;
ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id);
if (!ret)
return pkg_id;
}
return ret;
} }
int get_physical_core_id(int cpu) int get_physical_core_id(int cpu)
{ {
return parse_int_file( int ret;
0, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
ret = parse_int_file(0,
"/sys/devices/system/cpu/cpu%d/topology/core_id",
cpu);
if (ret < 0) {
int core_id, pkg_id, die_id;
ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id);
if (!ret)
return core_id;
}
return ret;
} }
int get_physical_die_id(int cpu) int get_physical_die_id(int cpu)
{ {
int ret; int ret;
ret = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/topology/die_id", ret = parse_int_file(0,
cpu); "/sys/devices/system/cpu/cpu%d/topology/die_id",
cpu);
if (ret < 0) {
int core_id, pkg_id, die_id;
ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id);
if (!ret)
return die_id;
}
if (ret < 0) if (ret < 0)
ret = 0; ret = 0;
...@@ -219,8 +352,14 @@ static void set_cpu_online_offline(int cpu, int state) ...@@ -219,8 +352,14 @@ static void set_cpu_online_offline(int cpu, int state)
"/sys/devices/system/cpu/cpu%d/online", cpu); "/sys/devices/system/cpu/cpu%d/online", cpu);
fd = open(buffer, O_WRONLY); fd = open(buffer, O_WRONLY);
if (fd < 0) if (fd < 0) {
if (!cpu && state) {
fprintf(stderr, "This system is not configured for CPU 0 online/offline\n");
fprintf(stderr, "Ignoring online request for CPU 0 as this is already online\n");
return;
}
err(-1, "%s open failed", buffer); err(-1, "%s open failed", buffer);
}
if (state) if (state)
ret = write(fd, "1\n", 2); ret = write(fd, "1\n", 2);
...@@ -259,7 +398,12 @@ static void for_each_online_package_in_set(void (*callback)(int, void *, void *, ...@@ -259,7 +398,12 @@ static void for_each_online_package_in_set(void (*callback)(int, void *, void *,
die_id = get_physical_die_id(i); die_id = get_physical_die_id(i);
if (die_id < 0) if (die_id < 0)
die_id = 0; die_id = 0;
pkg_id = get_physical_package_id(i);
pkg_id = parse_int_file(0,
"/sys/devices/system/cpu/cpu%d/topology/physical_package_id", i);
if (pkg_id < 0)
continue;
/* Create an unique id for package, die combination to store */ /* Create an unique id for package, die combination to store */
pkg_id = (MAX_PACKAGE_COUNT * pkg_id + die_id); pkg_id = (MAX_PACKAGE_COUNT * pkg_id + die_id);
...@@ -281,7 +425,7 @@ static void for_each_online_target_cpu_in_set( ...@@ -281,7 +425,7 @@ static void for_each_online_target_cpu_in_set(
void (*callback)(int, void *, void *, void *, void *), void *arg1, void (*callback)(int, void *, void *, void *, void *), void *arg1,
void *arg2, void *arg3, void *arg4) void *arg2, void *arg3, void *arg4)
{ {
int i; int i, found = 0;
for (i = 0; i < topo_max_cpus; ++i) { for (i = 0; i < topo_max_cpus; ++i) {
int online; int online;
...@@ -295,9 +439,14 @@ static void for_each_online_target_cpu_in_set( ...@@ -295,9 +439,14 @@ static void for_each_online_target_cpu_in_set(
online = online =
1; /* online entry for CPU 0 needs some special configs */ 1; /* online entry for CPU 0 needs some special configs */
if (online && callback) if (online && callback) {
callback(i, arg1, arg2, arg3, arg4); callback(i, arg1, arg2, arg3, arg4);
found = 1;
}
} }
if (!found)
fprintf(stderr, "No valid CPU in the list\n");
} }
#define BITMASK_SIZE 32 #define BITMASK_SIZE 32
...@@ -305,14 +454,27 @@ static void set_max_cpu_num(void) ...@@ -305,14 +454,27 @@ static void set_max_cpu_num(void)
{ {
FILE *filep; FILE *filep;
unsigned long dummy; unsigned long dummy;
int i;
topo_max_cpus = 0; topo_max_cpus = 0;
filep = fopen_or_exit( for (i = 0; i < 256; ++i) {
"/sys/devices/system/cpu/cpu0/topology/thread_siblings", "r"); char path[256];
snprintf(path, sizeof(path),
"/sys/devices/system/cpu/cpu%d/topology/thread_siblings", i);
filep = fopen(path, "r");
if (filep)
break;
}
if (!filep) {
fprintf(stderr, "Can't get max cpu number\n");
exit(0);
}
while (fscanf(filep, "%lx,", &dummy) == 1) while (fscanf(filep, "%lx,", &dummy) == 1)
topo_max_cpus += BITMASK_SIZE; topo_max_cpus += BITMASK_SIZE;
fclose(filep); fclose(filep);
topo_max_cpus--; /* 0 based */
debug_printf("max cpus %d\n", topo_max_cpus); debug_printf("max cpus %d\n", topo_max_cpus);
} }
...@@ -362,6 +524,10 @@ static void set_cpu_present_cpu_mask(void) ...@@ -362,6 +524,10 @@ static void set_cpu_present_cpu_mask(void)
die_id = 0; die_id = 0;
pkg_id = get_physical_package_id(i); pkg_id = get_physical_package_id(i);
if (pkg_id < 0) {
fprintf(stderr, "Failed to get package id, CPU %d may be offline\n", i);
continue;
}
if (pkg_id < MAX_PACKAGE_COUNT && if (pkg_id < MAX_PACKAGE_COUNT &&
die_id < MAX_DIE_PER_PACKAGE) { die_id < MAX_DIE_PER_PACKAGE) {
int core_id = get_physical_core_id(i); int core_id = get_physical_core_id(i);
...@@ -542,7 +708,11 @@ static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write, ...@@ -542,7 +708,11 @@ static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write,
} }
if (ioctl(fd, cmd, &io_regs) == -1) { if (ioctl(fd, cmd, &io_regs) == -1) {
perror("ISST_IF_IO_CMD"); if (errno == ENOTTY) {
perror("ISST_IF_IO_COMMAND\n");
fprintf(stderr, "Check presence of kernel modules: isst_if_mmio\n");
exit(0);
}
fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n", fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n",
cpu, reg, write); cpu, reg, write);
} else { } else {
...@@ -571,7 +741,8 @@ int isst_send_mbox_command(unsigned int cpu, unsigned char command, ...@@ -571,7 +741,8 @@ int isst_send_mbox_command(unsigned int cpu, unsigned char command,
"mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n",
cpu, command, sub_command, parameter, req_data); cpu, command, sub_command, parameter, req_data);
if (isst_platform_info.mmio_supported && command == CONFIG_CLOS) { if (!is_skx_based_platform() && command == CONFIG_CLOS &&
sub_command != CLOS_PM_QOS_CONFIG) {
unsigned int value; unsigned int value;
int write = 0; int write = 0;
int clos_id, core_id, ret = 0; int clos_id, core_id, ret = 0;
...@@ -620,10 +791,14 @@ int isst_send_mbox_command(unsigned int cpu, unsigned char command, ...@@ -620,10 +791,14 @@ int isst_send_mbox_command(unsigned int cpu, unsigned char command,
err(-1, "%s open failed", pathname); err(-1, "%s open failed", pathname);
if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) { if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) {
perror("ISST_IF_MBOX_COMMAND"); if (errno == ENOTTY) {
fprintf(outf, perror("ISST_IF_MBOX_COMMAND\n");
"Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", fprintf(stderr, "Check presence of kernel modules: isst_if_mbox_pci or isst_if_mbox_msr\n");
cpu, command, sub_command, parameter, req_data); exit(0);
}
debug_printf(
"Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x errorno:%d\n",
cpu, command, sub_command, parameter, req_data, errno);
return -1; return -1;
} else { } else {
*resp = mbox_cmds.mbox_cmd[0].resp_data; *resp = mbox_cmds.mbox_cmd[0].resp_data;
...@@ -656,7 +831,7 @@ int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write, ...@@ -656,7 +831,7 @@ int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write,
msr_cmds.msr_cmd[0].data = *req_resp; msr_cmds.msr_cmd[0].data = *req_resp;
if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) { if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) {
perror("ISST_IF_MSR_COMMAD"); perror("ISST_IF_MSR_COMMAND");
fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n", fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n",
cpu, msr, write); cpu, msr, write);
} else { } else {
...@@ -697,12 +872,85 @@ static int isst_fill_platform_info(void) ...@@ -697,12 +872,85 @@ static int isst_fill_platform_info(void)
return 0; return 0;
} }
static void isst_print_extended_platform_info(void)
{
int cp_state, cp_cap, fact_support = 0, pbf_support = 0;
struct isst_pkg_ctdp_level_info ctdp_level;
struct isst_pkg_ctdp pkg_dev;
int ret, i, j;
FILE *filep;
for (i = 0; i < 256; ++i) {
char path[256];
snprintf(path, sizeof(path),
"/sys/devices/system/cpu/cpu%d/topology/thread_siblings", i);
filep = fopen(path, "r");
if (filep)
break;
}
if (!filep)
return;
fclose(filep);
ret = isst_get_ctdp_levels(i, &pkg_dev);
if (ret)
return;
if (pkg_dev.enabled) {
fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is supported\n");
} else {
fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is not supported\n");
fprintf(outf, "Only performance level 0 (base level) is present\n");
}
if (pkg_dev.locked)
fprintf(outf, "TDP level change control is locked\n");
else
fprintf(outf, "TDP level change control is unlocked, max level: %d \n", pkg_dev.levels);
for (j = 0; j <= pkg_dev.levels; ++j) {
ret = isst_get_ctdp_control(i, j, &ctdp_level);
if (ret)
continue;
if (!fact_support && ctdp_level.fact_support)
fact_support = 1;
if (!pbf_support && ctdp_level.pbf_support)
pbf_support = 1;
}
if (fact_support)
fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is supported\n");
else
fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is not supported\n");
if (pbf_support)
fprintf(outf, "Intel(R) SST-BF (feature base-freq) is supported\n");
else
fprintf(outf, "Intel(R) SST-BF (feature base-freq) is not supported\n");
ret = isst_read_pm_config(i, &cp_state, &cp_cap);
if (cp_cap)
fprintf(outf, "Intel(R) SST-CP (feature core-power) is supported\n");
else
fprintf(outf, "Intel(R) SST-CP (feature core-power) is not supported\n");
}
static void isst_print_platform_information(void) static void isst_print_platform_information(void)
{ {
struct isst_if_platform_info platform_info; struct isst_if_platform_info platform_info;
const char *pathname = "/dev/isst_interface"; const char *pathname = "/dev/isst_interface";
int fd; int fd;
if (is_clx_n_platform()) {
fprintf(stderr, "\nThis option in not supported on this platform\n");
exit(0);
}
fd = open(pathname, O_RDWR); fd = open(pathname, O_RDWR);
if (fd < 0) if (fd < 0)
err(-1, "%s open failed", pathname); err(-1, "%s open failed", pathname);
...@@ -718,6 +966,7 @@ static void isst_print_platform_information(void) ...@@ -718,6 +966,7 @@ static void isst_print_platform_information(void)
platform_info.mbox_supported); platform_info.mbox_supported);
fprintf(outf, "Platform: mmio supported : %d\n", fprintf(outf, "Platform: mmio supported : %d\n",
platform_info.mmio_supported); platform_info.mmio_supported);
isst_print_extended_platform_info();
} }
close(fd); close(fd);
...@@ -725,6 +974,7 @@ static void isst_print_platform_information(void) ...@@ -725,6 +974,7 @@ static void isst_print_platform_information(void)
exit(0); exit(0);
} }
static char *local_str0, *local_str1;
static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3, static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3,
void *arg4) void *arg4)
{ {
...@@ -734,13 +984,14 @@ static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -734,13 +984,14 @@ static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3,
fn_ptr = arg1; fn_ptr = arg1;
ret = fn_ptr(cpu, arg2); ret = fn_ptr(cpu, arg2);
if (ret) if (ret)
perror("get_tdp_*"); isst_display_error_info_message(1, "get_tdp_* failed", 0, 0);
else else
isst_ctdp_display_core_info(cpu, outf, arg3, isst_ctdp_display_core_info(cpu, outf, arg3,
*(unsigned int *)arg4); *(unsigned int *)arg4,
local_str0, local_str1);
} }
#define _get_tdp_level(desc, suffix, object, help) \ #define _get_tdp_level(desc, suffix, object, help, str0, str1) \
static void get_tdp_##object(int arg) \ static void get_tdp_##object(int arg) \
{ \ { \
struct isst_pkg_ctdp ctdp; \ struct isst_pkg_ctdp ctdp; \
...@@ -751,6 +1002,8 @@ static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -751,6 +1002,8 @@ static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3,
help); \ help); \
exit(0); \ exit(0); \
} \ } \
local_str0 = str0; \
local_str1 = str1; \
isst_ctdp_display_information_start(outf); \ isst_ctdp_display_information_start(outf); \
if (max_target_cpus) \ if (max_target_cpus) \
for_each_online_target_cpu_in_set( \ for_each_online_target_cpu_in_set( \
...@@ -764,12 +1017,12 @@ static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -764,12 +1017,12 @@ static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3,
isst_ctdp_display_information_end(outf); \ isst_ctdp_display_information_end(outf); \
} }
_get_tdp_level("get-config-levels", levels, levels, "TDP levels"); _get_tdp_level("get-config-levels", levels, levels, "Max TDP level", NULL, NULL);
_get_tdp_level("get-config-version", levels, version, "TDP version"); _get_tdp_level("get-config-version", levels, version, "TDP version", NULL, NULL);
_get_tdp_level("get-config-enabled", levels, enabled, "TDP enable status"); _get_tdp_level("get-config-enabled", levels, enabled, "perf-profile enable status", "disabled", "enabled");
_get_tdp_level("get-config-current_level", levels, current_level, _get_tdp_level("get-config-current_level", levels, current_level,
"Current TDP Level"); "Current TDP Level", NULL, NULL);
_get_tdp_level("get-lock-status", levels, locked, "TDP lock status"); _get_tdp_level("get-lock-status", levels, locked, "TDP lock status", "unlocked", "locked");
struct isst_pkg_ctdp clx_n_pkg_dev; struct isst_pkg_ctdp clx_n_pkg_dev;
...@@ -902,9 +1155,14 @@ static void dump_clx_n_config_for_cpu(int cpu, void *arg1, void *arg2, ...@@ -902,9 +1155,14 @@ static void dump_clx_n_config_for_cpu(int cpu, void *arg1, void *arg2,
{ {
int ret; int ret;
if (tdp_level != 0xff && tdp_level != 0) {
isst_display_error_info_message(1, "Invalid level", 1, tdp_level);
exit(0);
}
ret = clx_n_config(cpu); ret = clx_n_config(cpu);
if (ret) { if (ret) {
perror("isst_get_process_ctdp"); debug_printf("clx_n_config failed");
} else { } else {
struct isst_pkg_ctdp_level_info *ctdp_level; struct isst_pkg_ctdp_level_info *ctdp_level;
struct isst_pbf_info *pbf_info; struct isst_pbf_info *pbf_info;
...@@ -926,7 +1184,9 @@ static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2, ...@@ -926,7 +1184,9 @@ static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2,
memset(&pkg_dev, 0, sizeof(pkg_dev)); memset(&pkg_dev, 0, sizeof(pkg_dev));
ret = isst_get_process_ctdp(cpu, tdp_level, &pkg_dev); ret = isst_get_process_ctdp(cpu, tdp_level, &pkg_dev);
if (ret) { if (ret) {
perror("isst_get_process_ctdp"); isst_display_error_info_message(1, "Failed to get perf-profile info on cpu", 1, cpu);
isst_ctdp_display_information_end(outf);
exit(1);
} else { } else {
isst_ctdp_display_information(cpu, outf, tdp_level, &pkg_dev); isst_ctdp_display_information(cpu, outf, tdp_level, &pkg_dev);
isst_get_process_ctdp_complete(cpu, &pkg_dev); isst_get_process_ctdp_complete(cpu, &pkg_dev);
...@@ -969,9 +1229,11 @@ static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -969,9 +1229,11 @@ static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
int ret; int ret;
ret = isst_set_tdp_level(cpu, tdp_level); ret = isst_set_tdp_level(cpu, tdp_level);
if (ret) if (ret) {
perror("set_tdp_level_for_cpu"); isst_display_error_info_message(1, "Set TDP level failed", 0, 0);
else { isst_ctdp_display_information_end(outf);
exit(1);
} else {
isst_display_result(cpu, outf, "perf-profile", "set_tdp_level", isst_display_result(cpu, outf, "perf-profile", "set_tdp_level",
ret); ret);
if (force_online_offline) { if (force_online_offline) {
...@@ -1009,11 +1271,13 @@ static void set_tdp_level(int arg) ...@@ -1009,11 +1271,13 @@ static void set_tdp_level(int arg)
"\t Arguments: -l|--level : Specify tdp level\n"); "\t Arguments: -l|--level : Specify tdp level\n");
fprintf(stderr, fprintf(stderr,
"\t Optional Arguments: -o | online : online/offline for the tdp level\n"); "\t Optional Arguments: -o | online : online/offline for the tdp level\n");
fprintf(stderr,
"\t online/offline operation has limitations, refer to Linux hotplug documentation\n");
exit(0); exit(0);
} }
if (tdp_level == 0xff) { if (tdp_level == 0xff) {
fprintf(outf, "Invalid command: specify tdp_level\n"); isst_display_error_info_message(1, "Invalid command: specify tdp_level", 0, 0);
exit(1); exit(1);
} }
isst_ctdp_display_information_start(outf); isst_ctdp_display_information_start(outf);
...@@ -1033,7 +1297,7 @@ static void clx_n_dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, ...@@ -1033,7 +1297,7 @@ static void clx_n_dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2,
ret = clx_n_config(cpu); ret = clx_n_config(cpu);
if (ret) { if (ret) {
perror("isst_get_process_ctdp"); isst_display_error_info_message(1, "clx_n_config failed", 0, 0);
} else { } else {
struct isst_pkg_ctdp_level_info *ctdp_level; struct isst_pkg_ctdp_level_info *ctdp_level;
struct isst_pbf_info *pbf_info; struct isst_pbf_info *pbf_info;
...@@ -1054,7 +1318,9 @@ static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1054,7 +1318,9 @@ static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
ret = isst_get_pbf_info(cpu, tdp_level, &pbf_info); ret = isst_get_pbf_info(cpu, tdp_level, &pbf_info);
if (ret) { if (ret) {
perror("isst_get_pbf_info"); isst_display_error_info_message(1, "Failed to get base-freq info at this level", 1, tdp_level);
isst_ctdp_display_information_end(outf);
exit(1);
} else { } else {
isst_pbf_display_information(cpu, outf, tdp_level, &pbf_info); isst_pbf_display_information(cpu, outf, tdp_level, &pbf_info);
isst_get_pbf_info_complete(&pbf_info); isst_get_pbf_info_complete(&pbf_info);
...@@ -1074,7 +1340,7 @@ static void dump_pbf_config(int arg) ...@@ -1074,7 +1340,7 @@ static void dump_pbf_config(int arg)
} }
if (tdp_level == 0xff) { if (tdp_level == 0xff) {
fprintf(outf, "Invalid command: specify tdp_level\n"); isst_display_error_info_message(1, "Invalid command: specify tdp_level", 0, 0);
exit(1); exit(1);
} }
...@@ -1100,7 +1366,7 @@ static int set_clos_param(int cpu, int clos, int epp, int wt, int min, int max) ...@@ -1100,7 +1366,7 @@ static int set_clos_param(int cpu, int clos, int epp, int wt, int min, int max)
ret = isst_pm_get_clos(cpu, clos, &clos_config); ret = isst_pm_get_clos(cpu, clos, &clos_config);
if (ret) { if (ret) {
perror("isst_pm_get_clos"); isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0);
return ret; return ret;
} }
clos_config.clos_min = min; clos_config.clos_min = min;
...@@ -1109,7 +1375,7 @@ static int set_clos_param(int cpu, int clos, int epp, int wt, int min, int max) ...@@ -1109,7 +1375,7 @@ static int set_clos_param(int cpu, int clos, int epp, int wt, int min, int max)
clos_config.clos_prop_prio = wt; clos_config.clos_prop_prio = wt;
ret = isst_set_clos(cpu, clos, &clos_config); ret = isst_set_clos(cpu, clos, &clos_config);
if (ret) { if (ret) {
perror("isst_pm_set_clos"); isst_display_error_info_message(1, "isst_set_clos failed", 0, 0);
return ret; return ret;
} }
...@@ -1153,7 +1419,7 @@ static int set_clx_pbf_cpufreq_scaling_min_max(int cpu) ...@@ -1153,7 +1419,7 @@ static int set_clx_pbf_cpufreq_scaling_min_max(int cpu)
ret = clx_n_config(cpu); ret = clx_n_config(cpu);
if (ret) { if (ret) {
perror("set_clx_pbf_cpufreq_scaling_min_max"); debug_printf("cpufreq_scaling_min_max failed for CLX");
return ret; return ret;
} }
...@@ -1316,7 +1582,7 @@ static int set_core_priority_and_min(int cpu, int mask_size, ...@@ -1316,7 +1582,7 @@ static int set_core_priority_and_min(int cpu, int mask_size,
debug_printf("Associate cpu: %d clos: %d\n", i, clos); debug_printf("Associate cpu: %d clos: %d\n", i, clos);
ret = isst_clos_associate(i, clos); ret = isst_clos_associate(i, clos);
if (ret) { if (ret) {
perror("isst_clos_associate"); isst_display_error_info_message(1, "isst_clos_associate failed", 0, 0);
return ret; return ret;
} }
} }
...@@ -1332,14 +1598,14 @@ static int set_pbf_core_power(int cpu) ...@@ -1332,14 +1598,14 @@ static int set_pbf_core_power(int cpu)
ret = isst_get_ctdp_levels(cpu, &pkg_dev); ret = isst_get_ctdp_levels(cpu, &pkg_dev);
if (ret) { if (ret) {
perror("isst_get_ctdp_levels"); debug_printf("isst_get_ctdp_levels failed");
return ret; return ret;
} }
debug_printf("Current_level: %d\n", pkg_dev.current_level); debug_printf("Current_level: %d\n", pkg_dev.current_level);
ret = isst_get_pbf_info(cpu, pkg_dev.current_level, &pbf_info); ret = isst_get_pbf_info(cpu, pkg_dev.current_level, &pbf_info);
if (ret) { if (ret) {
perror("isst_get_pbf_info"); debug_printf("isst_get_pbf_info failed");
return ret; return ret;
} }
debug_printf("p1_high: %d p1_low: %d\n", pbf_info.p1_high, debug_printf("p1_high: %d p1_low: %d\n", pbf_info.p1_high,
...@@ -1349,13 +1615,13 @@ static int set_pbf_core_power(int cpu) ...@@ -1349,13 +1615,13 @@ static int set_pbf_core_power(int cpu)
pbf_info.core_cpumask, pbf_info.core_cpumask,
pbf_info.p1_high, pbf_info.p1_low); pbf_info.p1_high, pbf_info.p1_low);
if (ret) { if (ret) {
perror("set_core_priority_and_min"); debug_printf("set_core_priority_and_min failed");
return ret; return ret;
} }
ret = isst_pm_qos_config(cpu, 1, 1); ret = isst_pm_qos_config(cpu, 1, 1);
if (ret) { if (ret) {
perror("isst_pm_qos_config"); debug_printf("isst_pm_qos_config failed");
return ret; return ret;
} }
...@@ -1369,17 +1635,13 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1369,17 +1635,13 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
int status = *(int *)arg4; int status = *(int *)arg4;
if (is_clx_n_platform()) { if (is_clx_n_platform()) {
ret = 0;
if (status) { if (status) {
ret = 0; set_clx_pbf_cpufreq_scaling_min_max(cpu);
if (auto_mode)
set_clx_pbf_cpufreq_scaling_min_max(cpu);
} else { } else {
ret = -1; set_scaling_max_to_cpuinfo_max(cpu);
if (auto_mode) { set_scaling_min_to_cpuinfo_min(cpu);
set_scaling_max_to_cpuinfo_max(cpu);
set_scaling_min_to_cpuinfo_min(cpu);
}
} }
goto disp_result; goto disp_result;
} }
...@@ -1392,7 +1654,7 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1392,7 +1654,7 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
ret = isst_set_pbf_fact_status(cpu, 1, status); ret = isst_set_pbf_fact_status(cpu, 1, status);
if (ret) { if (ret) {
perror("isst_set_pbf"); debug_printf("isst_set_pbf_fact_status failed");
if (auto_mode) if (auto_mode)
isst_pm_qos_config(cpu, 0, 0); isst_pm_qos_config(cpu, 0, 0);
} else { } else {
...@@ -1405,7 +1667,7 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1405,7 +1667,7 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
} }
if (auto_mode && !status) if (auto_mode && !status)
isst_pm_qos_config(cpu, 0, 0); isst_pm_qos_config(cpu, 0, 1);
disp_result: disp_result:
if (status) if (status)
...@@ -1424,10 +1686,25 @@ static void set_pbf_enable(int arg) ...@@ -1424,10 +1686,25 @@ static void set_pbf_enable(int arg)
if (enable) { if (enable) {
fprintf(stderr, fprintf(stderr,
"Enable Intel Speed Select Technology base frequency feature\n"); "Enable Intel Speed Select Technology base frequency feature\n");
if (is_clx_n_platform()) {
fprintf(stderr,
"\tOn this platform this command doesn't enable feature in the hardware.\n");
fprintf(stderr,
"\tIt updates the cpufreq scaling_min_freq to match cpufreq base_frequency.\n");
exit(0);
}
fprintf(stderr, fprintf(stderr,
"\tOptional Arguments: -a|--auto : Use priority of cores to set core-power associations\n"); "\tOptional Arguments: -a|--auto : Use priority of cores to set core-power associations\n");
} else { } else {
if (is_clx_n_platform()) {
fprintf(stderr,
"\tOn this platform this command doesn't disable feature in the hardware.\n");
fprintf(stderr,
"\tIt updates the cpufreq scaling_min_freq to match cpuinfo_min_freq\n");
exit(0);
}
fprintf(stderr, fprintf(stderr,
"Disable Intel Speed Select Technology base frequency feature\n"); "Disable Intel Speed Select Technology base frequency feature\n");
fprintf(stderr, fprintf(stderr,
...@@ -1452,12 +1729,15 @@ static void dump_fact_config_for_cpu(int cpu, void *arg1, void *arg2, ...@@ -1452,12 +1729,15 @@ static void dump_fact_config_for_cpu(int cpu, void *arg1, void *arg2,
struct isst_fact_info fact_info; struct isst_fact_info fact_info;
int ret; int ret;
ret = isst_get_fact_info(cpu, tdp_level, &fact_info); ret = isst_get_fact_info(cpu, tdp_level, fact_bucket, &fact_info);
if (ret) if (ret) {
perror("isst_get_fact_bucket_info"); isst_display_error_info_message(1, "Failed to get turbo-freq info at this level", 1, tdp_level);
else isst_ctdp_display_information_end(outf);
exit(1);
} else {
isst_fact_display_information(cpu, outf, tdp_level, fact_bucket, isst_fact_display_information(cpu, outf, tdp_level, fact_bucket,
fact_avx, &fact_info); fact_avx, &fact_info);
}
} }
static void dump_fact_config(int arg) static void dump_fact_config(int arg)
...@@ -1475,7 +1755,7 @@ static void dump_fact_config(int arg) ...@@ -1475,7 +1755,7 @@ static void dump_fact_config(int arg)
} }
if (tdp_level == 0xff) { if (tdp_level == 0xff) {
fprintf(outf, "Invalid command: specify tdp_level\n"); isst_display_error_info_message(1, "Invalid command: specify tdp_level\n", 0, 0);
exit(1); exit(1);
} }
...@@ -1503,7 +1783,7 @@ static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1503,7 +1783,7 @@ static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
ret = isst_set_pbf_fact_status(cpu, 0, status); ret = isst_set_pbf_fact_status(cpu, 0, status);
if (ret) { if (ret) {
perror("isst_set_fact"); debug_printf("isst_set_pbf_fact_status failed");
if (auto_mode) if (auto_mode)
isst_pm_qos_config(cpu, 0, 0); isst_pm_qos_config(cpu, 0, 0);
...@@ -1527,6 +1807,8 @@ static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1527,6 +1807,8 @@ static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
disp_results: disp_results:
if (status) { if (status) {
isst_display_result(cpu, outf, "turbo-freq", "enable", ret); isst_display_result(cpu, outf, "turbo-freq", "enable", ret);
if (ret)
fact_enable_fail = ret;
} else { } else {
/* Since we modified TRL during Fact enable, restore it */ /* Since we modified TRL during Fact enable, restore it */
isst_set_trl_from_current_tdp(cpu, fact_trl); isst_set_trl_from_current_tdp(cpu, fact_trl);
...@@ -1568,7 +1850,7 @@ static void set_fact_enable(int arg) ...@@ -1568,7 +1850,7 @@ static void set_fact_enable(int arg)
NULL, &enable); NULL, &enable);
isst_ctdp_display_information_end(outf); isst_ctdp_display_information_end(outf);
if (enable && auto_mode) { if (!fact_enable_fail && enable && auto_mode) {
/* /*
* When we adjust CLOS param, we have to set for siblings also. * When we adjust CLOS param, we have to set for siblings also.
* So for the each user specified CPU, also add the sibling * So for the each user specified CPU, also add the sibling
...@@ -1652,9 +1934,12 @@ static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1652,9 +1934,12 @@ static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3,
int ret; int ret;
int status = *(int *)arg4; int status = *(int *)arg4;
if (is_skx_based_platform())
clos_priority_type = 1;
ret = isst_pm_qos_config(cpu, status, clos_priority_type); ret = isst_pm_qos_config(cpu, status, clos_priority_type);
if (ret) if (ret)
perror("isst_pm_qos_config"); isst_display_error_info_message(1, "isst_pm_qos_config failed", 0, 0);
if (status) if (status)
isst_display_result(cpu, outf, "core-power", "enable", isst_display_result(cpu, outf, "core-power", "enable",
...@@ -1672,9 +1957,11 @@ static void set_clos_enable(int arg) ...@@ -1672,9 +1957,11 @@ static void set_clos_enable(int arg)
if (enable) { if (enable) {
fprintf(stderr, fprintf(stderr,
"Enable core-power for a package/die\n"); "Enable core-power for a package/die\n");
fprintf(stderr, if (!is_skx_based_platform()) {
"\tClos Enable: Specify priority type with [--priority|-p]\n"); fprintf(stderr,
fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n"); "\tClos Enable: Specify priority type with [--priority|-p]\n");
fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n");
}
} else { } else {
fprintf(stderr, fprintf(stderr,
"Disable core-power: [No command arguments are required]\n"); "Disable core-power: [No command arguments are required]\n");
...@@ -1705,7 +1992,7 @@ static void dump_clos_config_for_cpu(int cpu, void *arg1, void *arg2, ...@@ -1705,7 +1992,7 @@ static void dump_clos_config_for_cpu(int cpu, void *arg1, void *arg2,
ret = isst_pm_get_clos(cpu, current_clos, &clos_config); ret = isst_pm_get_clos(cpu, current_clos, &clos_config);
if (ret) if (ret)
perror("isst_pm_get_clos"); isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0);
else else
isst_clos_display_information(cpu, outf, current_clos, isst_clos_display_information(cpu, outf, current_clos,
&clos_config); &clos_config);
...@@ -1721,7 +2008,8 @@ static void dump_clos_config(int arg) ...@@ -1721,7 +2008,8 @@ static void dump_clos_config(int arg)
exit(0); exit(0);
} }
if (current_clos < 0 || current_clos > 3) { if (current_clos < 0 || current_clos > 3) {
fprintf(stderr, "Invalid clos id\n"); isst_display_error_info_message(1, "Invalid clos id\n", 0, 0);
isst_ctdp_display_information_end(outf);
exit(0); exit(0);
} }
...@@ -1742,9 +2030,14 @@ static void get_clos_info_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1742,9 +2030,14 @@ static void get_clos_info_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
ret = isst_clos_get_clos_information(cpu, &enable, &prio_type); ret = isst_clos_get_clos_information(cpu, &enable, &prio_type);
if (ret) if (ret)
perror("isst_clos_get_info"); isst_display_error_info_message(1, "isst_clos_get_info failed", 0, 0);
else else {
isst_clos_display_clos_information(cpu, outf, enable, prio_type); int cp_state, cp_cap;
isst_read_pm_config(cpu, &cp_state, &cp_cap);
isst_clos_display_clos_information(cpu, outf, enable, prio_type,
cp_state, cp_cap);
}
} }
static void dump_clos_info(int arg) static void dump_clos_info(int arg)
...@@ -1752,19 +2045,17 @@ static void dump_clos_info(int arg) ...@@ -1752,19 +2045,17 @@ static void dump_clos_info(int arg)
if (cmd_help) { if (cmd_help) {
fprintf(stderr, fprintf(stderr,
"Print Intel Speed Select Technology core power information\n"); "Print Intel Speed Select Technology core power information\n");
fprintf(stderr, "\tSpecify targeted cpu id with [--cpu|-c]\n"); fprintf(stderr, "\t Optionally specify targeted cpu id with [--cpu|-c]\n");
exit(0);
}
if (!max_target_cpus) {
fprintf(stderr,
"Invalid target cpu. Specify with [-c|--cpu]\n");
exit(0); exit(0);
} }
isst_ctdp_display_information_start(outf); isst_ctdp_display_information_start(outf);
for_each_online_target_cpu_in_set(get_clos_info_for_cpu, NULL, if (max_target_cpus)
NULL, NULL, NULL); for_each_online_target_cpu_in_set(get_clos_info_for_cpu, NULL,
NULL, NULL, NULL);
else
for_each_online_package_in_set(get_clos_info_for_cpu, NULL,
NULL, NULL, NULL);
isst_ctdp_display_information_end(outf); isst_ctdp_display_information_end(outf);
} }
...@@ -1785,7 +2076,7 @@ static void set_clos_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1785,7 +2076,7 @@ static void set_clos_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
clos_config.clos_desired = clos_desired; clos_config.clos_desired = clos_desired;
ret = isst_set_clos(cpu, current_clos, &clos_config); ret = isst_set_clos(cpu, current_clos, &clos_config);
if (ret) if (ret)
perror("isst_set_clos"); isst_display_error_info_message(1, "isst_set_clos failed", 0, 0);
else else
isst_display_result(cpu, outf, "core-power", "config", ret); isst_display_result(cpu, outf, "core-power", "config", ret);
} }
...@@ -1797,26 +2088,27 @@ static void set_clos_config(int arg) ...@@ -1797,26 +2088,27 @@ static void set_clos_config(int arg)
"Set core-power configuration for one of the four clos ids\n"); "Set core-power configuration for one of the four clos ids\n");
fprintf(stderr, fprintf(stderr,
"\tSpecify targeted clos id with [--clos|-c]\n"); "\tSpecify targeted clos id with [--clos|-c]\n");
fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n"); if (!is_skx_based_platform()) {
fprintf(stderr, fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n");
"\tSpecify clos Proportional Priority [--weight|-w]\n"); fprintf(stderr,
"\tSpecify clos Proportional Priority [--weight|-w]\n");
}
fprintf(stderr, "\tSpecify clos min in MHz with [--min|-n]\n"); fprintf(stderr, "\tSpecify clos min in MHz with [--min|-n]\n");
fprintf(stderr, "\tSpecify clos max in MHz with [--max|-m]\n"); fprintf(stderr, "\tSpecify clos max in MHz with [--max|-m]\n");
fprintf(stderr, "\tSpecify clos desired in MHz with [--desired|-d]\n");
exit(0); exit(0);
} }
if (current_clos < 0 || current_clos > 3) { if (current_clos < 0 || current_clos > 3) {
fprintf(stderr, "Invalid clos id\n"); isst_display_error_info_message(1, "Invalid clos id\n", 0, 0);
exit(0); exit(0);
} }
if (clos_epp < 0 || clos_epp > 0x0F) { if (!is_skx_based_platform() && (clos_epp < 0 || clos_epp > 0x0F)) {
fprintf(stderr, "clos epp is not specified, default: 0\n"); fprintf(stderr, "clos epp is not specified or invalid, default: 0\n");
clos_epp = 0; clos_epp = 0;
} }
if (clos_prop_prio < 0 || clos_prop_prio > 0x0F) { if (!is_skx_based_platform() && (clos_prop_prio < 0 || clos_prop_prio > 0x0F)) {
fprintf(stderr, fprintf(stderr,
"clos frequency weight is not specified, default: 0\n"); "clos frequency weight is not specified or invalid, default: 0\n");
clos_prop_prio = 0; clos_prop_prio = 0;
} }
if (clos_min < 0) { if (clos_min < 0) {
...@@ -1824,11 +2116,11 @@ static void set_clos_config(int arg) ...@@ -1824,11 +2116,11 @@ static void set_clos_config(int arg)
clos_min = 0; clos_min = 0;
} }
if (clos_max < 0) { if (clos_max < 0) {
fprintf(stderr, "clos max is not specified, default: 25500 MHz\n"); fprintf(stderr, "clos max is not specified, default: Max frequency (ratio 0xff)\n");
clos_max = 0xff; clos_max = 0xff;
} }
if (clos_desired < 0) { if (clos_desired) {
fprintf(stderr, "clos desired is not specified, default: 0\n"); fprintf(stderr, "clos desired is not supported on this platform\n");
clos_desired = 0x00; clos_desired = 0x00;
} }
...@@ -1849,7 +2141,7 @@ static void set_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1849,7 +2141,7 @@ static void set_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
ret = isst_clos_associate(cpu, current_clos); ret = isst_clos_associate(cpu, current_clos);
if (ret) if (ret)
perror("isst_clos_associate"); debug_printf("isst_clos_associate failed");
else else
isst_display_result(cpu, outf, "core-power", "assoc", ret); isst_display_result(cpu, outf, "core-power", "assoc", ret);
} }
...@@ -1860,19 +2152,22 @@ static void set_clos_assoc(int arg) ...@@ -1860,19 +2152,22 @@ static void set_clos_assoc(int arg)
fprintf(stderr, "Associate a clos id to a CPU\n"); fprintf(stderr, "Associate a clos id to a CPU\n");
fprintf(stderr, fprintf(stderr,
"\tSpecify targeted clos id with [--clos|-c]\n"); "\tSpecify targeted clos id with [--clos|-c]\n");
fprintf(stderr,
"\tFor example to associate clos 1 to CPU 0: issue\n");
fprintf(stderr,
"\tintel-speed-select --cpu 0 core-power assoc --clos 1\n");
exit(0); exit(0);
} }
if (current_clos < 0 || current_clos > 3) { if (current_clos < 0 || current_clos > 3) {
fprintf(stderr, "Invalid clos id\n"); isst_display_error_info_message(1, "Invalid clos id\n", 0, 0);
exit(0); exit(0);
} }
if (max_target_cpus) if (max_target_cpus)
for_each_online_target_cpu_in_set(set_clos_assoc_for_cpu, NULL, for_each_online_target_cpu_in_set(set_clos_assoc_for_cpu, NULL,
NULL, NULL, NULL); NULL, NULL, NULL);
else { else {
fprintf(stderr, isst_display_error_info_message(1, "Invalid target cpu. Specify with [-c|--cpu]", 0, 0);
"Invalid target cpu. Specify with [-c|--cpu]\n");
} }
} }
...@@ -1883,7 +2178,7 @@ static void get_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ...@@ -1883,7 +2178,7 @@ static void get_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
ret = isst_clos_get_assoc_status(cpu, &clos); ret = isst_clos_get_assoc_status(cpu, &clos);
if (ret) if (ret)
perror("isst_clos_get_assoc_status"); isst_display_error_info_message(1, "isst_clos_get_assoc_status failed", 0, 0);
else else
isst_clos_display_assoc_information(cpu, outf, clos); isst_clos_display_assoc_information(cpu, outf, clos);
} }
...@@ -1897,8 +2192,7 @@ static void get_clos_assoc(int arg) ...@@ -1897,8 +2192,7 @@ static void get_clos_assoc(int arg)
} }
if (!max_target_cpus) { if (!max_target_cpus) {
fprintf(stderr, isst_display_error_info_message(1, "Invalid target cpu. Specify with [-c|--cpu]", 0, 0);
"Invalid target cpu. Specify with [-c|--cpu]\n");
exit(0); exit(0);
} }
...@@ -2035,7 +2329,7 @@ static void parse_cmd_args(int argc, int start, char **argv) ...@@ -2035,7 +2329,7 @@ static void parse_cmd_args(int argc, int start, char **argv)
option_index = start; option_index = start;
optind = start + 1; optind = start + 1;
while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:hoa", while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:r:hoa",
long_options, &option_index)) != -1) { long_options, &option_index)) != -1) {
switch (opt) { switch (opt) {
case 'a': case 'a':
...@@ -2061,7 +2355,7 @@ static void parse_cmd_args(int argc, int start, char **argv) ...@@ -2061,7 +2355,7 @@ static void parse_cmd_args(int argc, int start, char **argv)
fact_avx = 0x01; fact_avx = 0x01;
} else if (!strncmp(optarg, "avx2", 4)) { } else if (!strncmp(optarg, "avx2", 4)) {
fact_avx = 0x02; fact_avx = 0x02;
} else if (!strncmp(optarg, "avx512", 4)) { } else if (!strncmp(optarg, "avx512", 6)) {
fact_avx = 0x04; fact_avx = 0x04;
} else { } else {
fprintf(outf, "Invalid sse,avx options\n"); fprintf(outf, "Invalid sse,avx options\n");
...@@ -2078,6 +2372,10 @@ static void parse_cmd_args(int argc, int start, char **argv) ...@@ -2078,6 +2372,10 @@ static void parse_cmd_args(int argc, int start, char **argv)
break; break;
case 'e': case 'e':
clos_epp = atoi(optarg); clos_epp = atoi(optarg);
if (is_skx_based_platform()) {
isst_display_error_info_message(1, "epp can't be specified on this platform", 0, 0);
exit(0);
}
break; break;
case 'n': case 'n':
clos_min = atoi(optarg); clos_min = atoi(optarg);
...@@ -2089,14 +2387,25 @@ static void parse_cmd_args(int argc, int start, char **argv) ...@@ -2089,14 +2387,25 @@ static void parse_cmd_args(int argc, int start, char **argv)
break; break;
case 'p': case 'p':
clos_priority_type = atoi(optarg); clos_priority_type = atoi(optarg);
if (is_skx_based_platform() && !clos_priority_type) {
isst_display_error_info_message(1, "Invalid clos priority type: proportional for this platform", 0, 0);
exit(0);
}
break; break;
case 'w': case 'w':
clos_prop_prio = atoi(optarg); clos_prop_prio = atoi(optarg);
if (is_skx_based_platform()) {
isst_display_error_info_message(1, "weight can't be specified on this platform", 0, 0);
exit(0);
}
break; break;
default: default:
printf("no match\n"); printf("Unknown option: ignore\n");
} }
} }
if (argv[optind])
printf("Garbage at the end of command: ignore\n");
} }
static void isst_help(void) static void isst_help(void)
...@@ -2214,11 +2523,18 @@ void process_command(int argc, char **argv, ...@@ -2214,11 +2523,18 @@ void process_command(int argc, char **argv,
static void usage(void) static void usage(void)
{ {
printf("Intel(R) Speed Select Technology\n"); if (is_clx_n_platform()) {
fprintf(stderr, "\nThere is limited support of Intel Speed Select features on this platform.\n");
fprintf(stderr, "Everything is pre-configured using BIOS options, this tool can't enable any feature in the hardware.\n\n");
}
printf("\nUsage:\n"); printf("\nUsage:\n");
printf("intel-speed-select [OPTIONS] FEATURE COMMAND COMMAND_ARGUMENTS\n"); printf("intel-speed-select [OPTIONS] FEATURE COMMAND COMMAND_ARGUMENTS\n");
printf("\nUse this tool to enumerate and control the Intel Speed Select Technology features,\n"); printf("\nUse this tool to enumerate and control the Intel Speed Select Technology features:\n");
printf("\nFEATURE : [perf-profile|base-freq|turbo-freq|core-power]\n"); if (is_clx_n_platform())
printf("\nFEATURE : [perf-profile|base-freq]\n");
else
printf("\nFEATURE : [perf-profile|base-freq|turbo-freq|core-power]\n");
printf("\nFor help on each feature, use -h|--help\n"); printf("\nFor help on each feature, use -h|--help\n");
printf("\tFor example: intel-speed-select perf-profile -h\n"); printf("\tFor example: intel-speed-select perf-profile -h\n");
...@@ -2231,17 +2547,29 @@ static void usage(void) ...@@ -2231,17 +2547,29 @@ static void usage(void)
printf("\t\tDefault: Die scoped for all dies in the system with multiple dies/package\n"); printf("\t\tDefault: Die scoped for all dies in the system with multiple dies/package\n");
printf("\t\t\t Or Package scoped for all Packages when each package contains one die\n"); printf("\t\t\t Or Package scoped for all Packages when each package contains one die\n");
printf("\t[-d|--debug] : Debug mode\n"); printf("\t[-d|--debug] : Debug mode\n");
printf("\t[-f|--format] : output format [json|text]. Default: text\n");
printf("\t[-h|--help] : Print help\n"); printf("\t[-h|--help] : Print help\n");
printf("\t[-i|--info] : Print platform information\n"); printf("\t[-i|--info] : Print platform information\n");
printf("\t[-o|--out] : Output file\n"); printf("\t[-o|--out] : Output file\n");
printf("\t\t\tDefault : stderr\n"); printf("\t\t\tDefault : stderr\n");
printf("\t[-f|--format] : output format [json|text]. Default: text\n");
printf("\t[-v|--version] : Print version\n"); printf("\t[-v|--version] : Print version\n");
printf("\nResult format\n"); printf("\nResult format\n");
printf("\tResult display uses a common format for each command:\n"); printf("\tResult display uses a common format for each command:\n");
printf("\tResults are formatted in text/JSON with\n"); printf("\tResults are formatted in text/JSON with\n");
printf("\t\tPackage, Die, CPU, and command specific results.\n"); printf("\t\tPackage, Die, CPU, and command specific results.\n");
printf("\nExamples\n");
printf("\tTo get platform information:\n");
printf("\t\tintel-speed-select --info\n");
printf("\tTo get full perf-profile information dump:\n");
printf("\t\tintel-speed-select perf-profile info\n");
printf("\tTo get full base-freq information dump:\n");
printf("\t\tintel-speed-select base-freq info -l 0\n");
if (!is_clx_n_platform()) {
printf("\tTo get full turbo-freq information dump:\n");
printf("\t\tintel-speed-select turbo-freq info -l 0\n");
}
exit(1); exit(1);
} }
...@@ -2254,6 +2582,8 @@ static void print_version(void) ...@@ -2254,6 +2582,8 @@ static void print_version(void)
static void cmdline(int argc, char **argv) static void cmdline(int argc, char **argv)
{ {
const char *pathname = "/dev/isst_interface";
FILE *fp;
int opt; int opt;
int option_index = 0; int option_index = 0;
int ret; int ret;
...@@ -2269,6 +2599,28 @@ static void cmdline(int argc, char **argv) ...@@ -2269,6 +2599,28 @@ static void cmdline(int argc, char **argv)
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
if (geteuid() != 0) {
fprintf(stderr, "Must run as root\n");
exit(0);
}
ret = update_cpu_model();
if (ret)
err(-1, "Invalid CPU model (%d)\n", cpu_model);
printf("Intel(R) Speed Select Technology\n");
printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model);
if (!is_clx_n_platform()) {
fp = fopen(pathname, "rb");
if (!fp) {
fprintf(stderr, "Intel speed select drivers are not loaded on this system.\n");
fprintf(stderr, "Verify that kernel config includes CONFIG_INTEL_SPEED_SELECT_INTERFACE.\n");
fprintf(stderr, "If the config is included then this is not a supported platform.\n");
exit(0);
}
fclose(fp);
}
progname = argv[0]; progname = argv[0];
while ((opt = getopt_long_only(argc, argv, "+c:df:hio:v", long_options, while ((opt = getopt_long_only(argc, argv, "+c:df:hio:v", long_options,
&option_index)) != -1) { &option_index)) != -1) {
...@@ -2303,21 +2655,12 @@ static void cmdline(int argc, char **argv) ...@@ -2303,21 +2655,12 @@ static void cmdline(int argc, char **argv)
} }
} }
if (geteuid() != 0) {
fprintf(stderr, "Must run as root\n");
exit(0);
}
if (optind > (argc - 2)) { if (optind > (argc - 2)) {
fprintf(stderr, "Feature name and|or command not specified\n"); usage();
exit(0); exit(0);
} }
ret = update_cpu_model();
if (ret)
err(-1, "Invalid CPU model (%d)\n", cpu_model);
printf("Intel(R) Speed Select Technology\n");
printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model);
set_max_cpu_num(); set_max_cpu_num();
store_cpu_topology();
set_cpu_present_cpu_mask(); set_cpu_present_cpu_mask();
set_cpu_target_cpu_mask(); set_cpu_target_cpu_mask();
......
...@@ -114,8 +114,10 @@ int isst_get_tdp_info(int cpu, int config_index, ...@@ -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, ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO,
0, config_index, &resp); 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; return ret;
}
ctdp_level->pkg_tdp = resp & GENMASK(14, 0); ctdp_level->pkg_tdp = resp & GENMASK(14, 0);
ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16; ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16;
...@@ -352,7 +354,7 @@ int isst_set_tdp_level_msr(int cpu, int tdp_level) ...@@ -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); debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level);
if (isst_get_config_tdp_lock_status(cpu)) { 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; return -1;
} }
...@@ -373,19 +375,50 @@ int isst_set_tdp_level(int cpu, int tdp_level) ...@@ -373,19 +375,50 @@ int isst_set_tdp_level(int cpu, int tdp_level)
unsigned int resp; unsigned int resp;
int ret; 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, ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0,
tdp_level, &resp); tdp_level, &resp);
if (ret) if (ret) {
return isst_set_tdp_level_msr(cpu, tdp_level); isst_display_error_info_message(1, "Set TDP level failed for level", 1, tdp_level);
return ret;
}
return 0; return 0;
} }
int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info) 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; int i, ret, core_cnt, max;
unsigned int req, resp; 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); 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)); 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) ...@@ -481,6 +514,10 @@ int isst_set_pbf_fact_status(int cpu, int pbf, int enable)
else else
req &= ~BIT(17); req &= ~BIT(17);
} else { } 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) if (ctdp_level.pbf_enabled)
req = BIT(17); req = BIT(17);
...@@ -566,10 +603,32 @@ int isst_get_fact_bucket_info(int cpu, int level, ...@@ -566,10 +603,32 @@ int isst_get_fact_bucket_info(int cpu, int level,
return 0; 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; 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, ret = isst_send_mbox_command(cpu, CONFIG_TDP,
CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0, 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) ...@@ -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; fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff;
ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info); 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) 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) ...@@ -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 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) if (pkg_dev->processed)
return 0; return 0;
...@@ -684,6 +760,14 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) ...@@ -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, cpu, pkg_dev->enabled, pkg_dev->current_level,
pkg_dev->levels); 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) { for (i = 0; i <= pkg_dev->levels; ++i) {
struct isst_pkg_ctdp_level_info *ctdp_level; 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) ...@@ -703,6 +787,7 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
if (ret) if (ret)
continue; continue;
valid = 1;
pkg_dev->processed = 1; pkg_dev->processed = 1;
ctdp_level->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) ...@@ -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) { if (ctdp_level->fact_support) {
ret = isst_get_fact_info(cpu, i, ret = isst_get_fact_info(cpu, i, 0xff,
&ctdp_level->fact_info); &ctdp_level->fact_info);
if (ret) if (ret)
return ret; return ret;
...@@ -775,6 +860,9 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) ...@@ -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); 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; return 0;
} }
...@@ -829,17 +917,19 @@ int isst_pm_qos_config(int cpu, int enable_clos, int priority_type) ...@@ -829,17 +917,19 @@ int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
} }
ret = isst_write_pm_config(cpu, 0); ret = isst_write_pm_config(cpu, 0);
if (ret) 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 { } else {
ret = isst_write_pm_config(cpu, 1); ret = isst_write_pm_config(cpu, 1);
if (ret) 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, ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
&resp); &resp);
if (ret) if (ret) {
isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0);
return ret; return ret;
}
debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp); 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) ...@@ -850,6 +940,9 @@ int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
else else
req = req & ~BIT(1); 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) if (priority_type)
req = req | BIT(2); req = req | BIT(2);
else else
......
...@@ -158,10 +158,17 @@ static void format_and_print(FILE *outf, int level, char *header, char *value) ...@@ -158,10 +158,17 @@ static void format_and_print(FILE *outf, int level, char *header, char *value)
last_level = level; last_level = level;
} }
static void print_package_info(int cpu, FILE *outf) static int print_package_info(int cpu, FILE *outf)
{ {
char header[256]; 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", snprintf(header, sizeof(header), "package-%d",
get_physical_package_id(cpu)); get_physical_package_id(cpu));
format_and_print(outf, 1, header, NULL); format_and_print(outf, 1, header, NULL);
...@@ -169,6 +176,8 @@ static void print_package_info(int cpu, FILE *outf) ...@@ -169,6 +176,8 @@ static void print_package_info(int cpu, FILE *outf)
format_and_print(outf, 2, header, NULL); format_and_print(outf, 2, header, NULL);
snprintf(header, sizeof(header), "cpu-%d", cpu); snprintf(header, sizeof(header), "cpu-%d", cpu);
format_and_print(outf, 3, header, NULL); format_and_print(outf, 3, header, NULL);
return 3;
} }
static void _isst_pbf_display_information(int cpu, FILE *outf, int level, 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, ...@@ -178,7 +187,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
char header[256]; char header[256];
char value[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); format_and_print(outf, disp_level, header, NULL);
snprintf(header, sizeof(header), "high-priority-base-frequency(MHz)"); 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, ...@@ -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; struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info;
char header[256]; char header[256];
char value[256]; char value[256];
int j; int print = 0, j;
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;
snprintf(header, sizeof(header), "speed-select-turbo-freq"); 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); format_and_print(outf, base_level, header, NULL);
for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) { for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
if (fact_bucket != 0xff && fact_bucket != j) if (fact_bucket != 0xff && fact_bucket != j)
...@@ -289,7 +312,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level, ...@@ -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, 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 header[256];
char value[256]; char value[256];
...@@ -301,8 +324,12 @@ void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix, ...@@ -301,8 +324,12 @@ void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix,
format_and_print(outf, 2, header, NULL); format_and_print(outf, 2, header, NULL);
snprintf(header, sizeof(header), "cpu-%d", cpu); snprintf(header, sizeof(header), "cpu-%d", cpu);
format_and_print(outf, 3, header, NULL); format_and_print(outf, 3, header, NULL);
if (str0 && !val)
snprintf(value, sizeof(value), "%u", 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, 4, prefix, value);
format_and_print(outf, 1, NULL, NULL); format_and_print(outf, 1, NULL, NULL);
...@@ -313,10 +340,11 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, ...@@ -313,10 +340,11 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
{ {
char header[256]; char header[256];
char value[256]; char value[256];
int i, base_level = 1; static int level;
int i;
if (pkg_dev->processed) if (pkg_dev->processed)
print_package_info(cpu, outf); level = print_package_info(cpu, outf);
for (i = 0; i <= pkg_dev->levels; ++i) { for (i = 0; i <= pkg_dev->levels; ++i) {
struct isst_pkg_ctdp_level_info *ctdp_level; struct isst_pkg_ctdp_level_info *ctdp_level;
...@@ -328,72 +356,80 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_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", snprintf(header, sizeof(header), "perf-profile-level-%d",
ctdp_level->level); 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"); snprintf(header, sizeof(header), "cpu-count");
j = get_cpu_count(get_physical_die_id(cpu), j = get_cpu_count(get_physical_die_id(cpu),
get_physical_die_id(cpu)); get_physical_die_id(cpu));
snprintf(value, sizeof(value), "%d", j); 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) { if (ctdp_level->core_cpumask_size) {
snprintf(header, sizeof(header), "enable-cpu-mask"); snprintf(header, sizeof(header), "enable-cpu-mask");
printcpumask(sizeof(value), value, printcpumask(sizeof(value), value,
ctdp_level->core_cpumask_size, ctdp_level->core_cpumask_size,
ctdp_level->core_cpumask); 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"); snprintf(header, sizeof(header), "enable-cpu-list");
printcpulist(sizeof(value), value, printcpulist(sizeof(value), value,
ctdp_level->core_cpumask_size, ctdp_level->core_cpumask_size,
ctdp_level->core_cpumask); 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(header, sizeof(header), "thermal-design-power-ratio");
snprintf(value, sizeof(value), "%d", ctdp_level->tdp_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)"); snprintf(header, sizeof(header), "base-frequency(MHz)");
if (!ctdp_level->sse_p1) if (!ctdp_level->sse_p1)
ctdp_level->sse_p1 = ctdp_level->tdp_ratio; ctdp_level->sse_p1 = ctdp_level->tdp_ratio;
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
ctdp_level->sse_p1 * DISP_FREQ_MULTIPLIER); 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) { if (ctdp_level->avx2_p1) {
snprintf(header, sizeof(header), "base-frequency-avx2(MHz)"); snprintf(header, sizeof(header), "base-frequency-avx2(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
ctdp_level->avx2_p1 * DISP_FREQ_MULTIPLIER); 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) { if (ctdp_level->avx512_p1) {
snprintf(header, sizeof(header), "base-frequency-avx512(MHz)"); snprintf(header, sizeof(header), "base-frequency-avx512(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
ctdp_level->avx512_p1 * DISP_FREQ_MULTIPLIER); 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) { if (ctdp_level->uncore_p1) {
snprintf(header, sizeof(header), "uncore-frequency-min(MHz)"); snprintf(header, sizeof(header), "uncore-frequency-min(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
ctdp_level->uncore_p1 * DISP_FREQ_MULTIPLIER); 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) { if (ctdp_level->uncore_p0) {
snprintf(header, sizeof(header), "uncore-frequency-max(MHz)"); snprintf(header, sizeof(header), "uncore-frequency-max(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
ctdp_level->uncore_p0 * DISP_FREQ_MULTIPLIER); 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) { if (ctdp_level->mem_freq) {
snprintf(header, sizeof(header), "mem-frequency(MHz)"); snprintf(header, sizeof(header), "mem-frequency(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
ctdp_level->mem_freq * DISP_FREQ_MULTIPLIER); 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), snprintf(header, sizeof(header),
...@@ -405,7 +441,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, ...@@ -405,7 +441,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
snprintf(value, sizeof(value), "disabled"); snprintf(value, sizeof(value), "disabled");
} else } else
snprintf(value, sizeof(value), "unsupported"); 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), snprintf(header, sizeof(header),
"speed-select-base-freq"); "speed-select-base-freq");
...@@ -416,7 +452,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, ...@@ -416,7 +452,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
snprintf(value, sizeof(value), "disabled"); snprintf(value, sizeof(value), "disabled");
} else } else
snprintf(value, sizeof(value), "unsupported"); 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), snprintf(header, sizeof(header),
"speed-select-core-power"); "speed-select-core-power");
...@@ -427,110 +463,115 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, ...@@ -427,110 +463,115 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
snprintf(value, sizeof(value), "disabled"); snprintf(value, sizeof(value), "disabled");
} else } else
snprintf(value, sizeof(value), "unsupported"); 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 (is_clx_n_platform()) {
if (ctdp_level->pbf_support) if (ctdp_level->pbf_support)
_isst_pbf_display_information(cpu, outf, _isst_pbf_display_information(cpu, outf,
tdp_level, tdp_level,
&ctdp_level->pbf_info, &ctdp_level->pbf_info,
base_level + 4); level + 1);
continue; continue;
} }
if (ctdp_level->pkg_tdp) { if (ctdp_level->pkg_tdp) {
snprintf(header, sizeof(header), "thermal-design-power(W)"); snprintf(header, sizeof(header), "thermal-design-power(W)");
snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp); 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) { if (ctdp_level->t_proc_hot) {
snprintf(header, sizeof(header), "tjunction-max(C)"); snprintf(header, sizeof(header), "tjunction-max(C)");
snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot); 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"); 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) { for (j = 0; j < 8; ++j) {
snprintf(header, sizeof(header), "bucket-%d", 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(header, sizeof(header), "core-count");
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); 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), snprintf(header, sizeof(header),
"max-turbo-frequency(MHz)"); "max-turbo-frequency(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
ctdp_level->trl_sse_active_cores[j] * ctdp_level->trl_sse_active_cores[j] *
DISP_FREQ_MULTIPLIER); 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]) { if (ctdp_level->trl_avx_active_cores[0]) {
snprintf(header, sizeof(header), "turbo-ratio-limits-avx2"); 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) { for (j = 0; j < 8; ++j) {
snprintf(header, sizeof(header), "bucket-%d", 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(header, sizeof(header), "core-count");
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); 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(header, sizeof(header), "max-turbo-frequency(MHz)");
snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_active_cores[j] * DISP_FREQ_MULTIPLIER); 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]) { if (ctdp_level->trl_avx_512_active_cores[0]) {
snprintf(header, sizeof(header), "turbo-ratio-limits-avx512"); 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) { for (j = 0; j < 8; ++j) {
snprintf(header, sizeof(header), "bucket-%d", 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(header, sizeof(header), "core-count");
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); 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(header, sizeof(header), "max-turbo-frequency(MHz)");
snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_512_active_cores[j] * DISP_FREQ_MULTIPLIER); 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) if (ctdp_level->pbf_support)
_isst_pbf_display_information(cpu, outf, i, _isst_pbf_display_information(cpu, outf, i,
&ctdp_level->pbf_info, &ctdp_level->pbf_info,
base_level + 4); level + 2);
if (ctdp_level->fact_support) if (ctdp_level->fact_support)
_isst_fact_display_information(cpu, outf, i, 0xff, 0xff, _isst_fact_display_information(cpu, outf, i, 0xff, 0xff,
&ctdp_level->fact_info, &ctdp_level->fact_info,
base_level + 4); level + 2);
} }
format_and_print(outf, 1, NULL, NULL); format_and_print(outf, 1, NULL, NULL);
} }
static int start;
void isst_ctdp_display_information_start(FILE *outf) void isst_ctdp_display_information_start(FILE *outf)
{ {
last_level = 0; last_level = 0;
format_and_print(outf, 0, "start", NULL); format_and_print(outf, 0, "start", NULL);
start = 1;
} }
void isst_ctdp_display_information_end(FILE *outf) void isst_ctdp_display_information_end(FILE *outf)
{ {
format_and_print(outf, 0, NULL, NULL); format_and_print(outf, 0, NULL, NULL);
start = 0;
} }
void isst_pbf_display_information(int cpu, FILE *outf, int level, void isst_pbf_display_information(int cpu, FILE *outf, int level,
struct isst_pbf_info *pbf_info) struct isst_pbf_info *pbf_info)
{ {
print_package_info(cpu, outf); int _level;
_isst_pbf_display_information(cpu, outf, level, pbf_info, 4);
_level = print_package_info(cpu, outf);
_isst_pbf_display_information(cpu, outf, level, pbf_info, _level + 1);
format_and_print(outf, 1, NULL, NULL); format_and_print(outf, 1, NULL, NULL);
} }
...@@ -538,9 +579,11 @@ void isst_fact_display_information(int cpu, FILE *outf, int level, ...@@ -538,9 +579,11 @@ void isst_fact_display_information(int cpu, FILE *outf, int level,
int fact_bucket, int fact_avx, int fact_bucket, int fact_avx,
struct isst_fact_info *fact_info) 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, _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); format_and_print(outf, 1, NULL, NULL);
} }
...@@ -549,94 +592,103 @@ void isst_clos_display_information(int cpu, FILE *outf, int clos, ...@@ -549,94 +592,103 @@ void isst_clos_display_information(int cpu, FILE *outf, int clos,
{ {
char header[256]; char header[256];
char value[256]; char value[256];
int level;
snprintf(header, sizeof(header), "package-%d", level = print_package_info(cpu, outf);
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), "core-power"); 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(header, sizeof(header), "clos");
snprintf(value, sizeof(value), "%d", 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(header, sizeof(header), "epp");
snprintf(value, sizeof(value), "%d", clos_config->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(header, sizeof(header), "clos-proportional-priority");
snprintf(value, sizeof(value), "%d", clos_config->clos_prop_prio); 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(header, sizeof(header), "clos-min");
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * DISP_FREQ_MULTIPLIER); 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(header, sizeof(header), "clos-max");
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * DISP_FREQ_MULTIPLIER); if (clos_config->clos_max == 0xff)
format_and_print(outf, 5, header, value); 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(header, sizeof(header), "clos-desired");
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * DISP_FREQ_MULTIPLIER); 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, 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 header[256];
char value[256]; char value[256];
int level;
snprintf(header, sizeof(header), "package-%d", level = print_package_info(cpu, outf);
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), "core-power"); 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(header, sizeof(header), "enable-status");
snprintf(value, sizeof(value), "%d", clos_enable); if (state)
format_and_print(outf, 5, header, value); 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(header, sizeof(header), "priority-type");
snprintf(value, sizeof(value), "%d", type); if (type)
format_and_print(outf, 5, header, value); 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) void isst_clos_display_assoc_information(int cpu, FILE *outf, int clos)
{ {
char header[256]; char header[256];
char value[256]; char value[256];
int level;
snprintf(header, sizeof(header), "package-%d", level = print_package_info(cpu, outf);
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), "get-assoc"); 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(header, sizeof(header), "clos");
snprintf(value, sizeof(value), "%d", 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, 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, ...@@ -644,24 +696,60 @@ void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
{ {
char header[256]; char header[256];
char value[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); 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); snprintf(header, sizeof(header), "%s", cmd);
if (!result) if (!result)
snprintf(value, sizeof(value), "success"); snprintf(value, sizeof(value), "success");
else else
snprintf(value, sizeof(value), "failed(error %d)", result); 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, 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); 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); ...@@ -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); extern int get_core_count(int pkg_id, int die_id);
/* Common interfaces */ /* Common interfaces */
FILE *get_output_file(void);
extern void debug_printf(const char *format, ...); extern void debug_printf(const char *format, ...);
extern int out_format_is_json(void); extern int out_format_is_json(void);
extern int get_physical_package_id(int cpu); extern int get_physical_package_id(int cpu);
...@@ -196,6 +197,8 @@ extern int isst_send_msr_command(unsigned int cpu, unsigned int command, ...@@ -196,6 +197,8 @@ extern int isst_send_msr_command(unsigned int cpu, unsigned int command,
int write, unsigned long long *req_resp); 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_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, extern int isst_get_coremask_info(int cpu, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level); struct isst_pkg_ctdp_level_info *ctdp_level);
extern int isst_get_process_ctdp(int cpu, int tdp_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, ...@@ -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, extern void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
struct isst_pkg_ctdp *pkg_dev); struct isst_pkg_ctdp *pkg_dev);
extern void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix, 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_start(FILE *outf);
extern void isst_ctdp_display_information_end(FILE *outf); extern void isst_ctdp_display_information_end(FILE *outf);
extern void isst_pbf_display_information(int cpu, FILE *outf, int level, 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); ...@@ -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, extern int isst_get_pbf_info(int cpu, int level,
struct isst_pbf_info *pbf_info); struct isst_pbf_info *pbf_info);
extern void isst_get_pbf_info_complete(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); struct isst_fact_info *fact_info);
extern int isst_get_fact_bucket_info(int cpu, int level, extern int isst_get_fact_bucket_info(int cpu, int level,
struct isst_fact_bucket_info *bucket_info); struct isst_fact_bucket_info *bucket_info);
...@@ -245,7 +248,10 @@ extern void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, ...@@ -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 int isst_clos_get_clos_information(int cpu, int *enable, int *type);
extern void isst_clos_display_clos_information(int cpu, FILE *outf, 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 is_clx_n_platform(void);
extern int get_cpufreq_base_freq(int cpu); 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 #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment