platform-drivers-x86 for v5.4-1
* ASUS WMI driver got couple of worth to mention updates, i.e. support of FAN is fixed for recent products and the charge threshold support has been added. * Two uknown key events for Dell laptops are being ignored now to avoid spam user with harmless messages. * HP ZBook 17 G5 and ASUS Zenbook UX430UNR have got accelerometer support. * Intel CherryTrail platforms got a regression with wake up. Now it's fixed. * Intel PMC driver got fixed in order to work nicely in Xen environment. * Intel Speed Select driver provides bucket vs core count relationship. Besides that the tools has been updated for better output. * The PrivacyGuard is enabled on Lenovo ThinkPad laptops. * Three tablets, i.e. Trekstor Primebook C11B 2-in-1, Irbis TW90 and Chuwi Surbook Mini, have got touchscreen support. The following is an automated git shortlog grouped by driver: acer-wmi: - Switch to acpi_dev_get_first_match_dev() asus-nb-wmi: - Support ALS on the Zenbook UX430UNR asus-wmi: - Refactor charge threshold to use the battery hooking API - Rename CHARGE_THRESHOLD to RSOC - Reorder ASUS_WMI_CHARGE_THRESHOLD - Fix condition in charge_threshold_store() - Remove unnecessary blank lines - Drop indentation level by inverting conditionals - Use clamp_val() instead of open coded variant - Replace sscanf() with kstrtoint() - Refactor charge_threshold_store() - Add support for charge threshold - fix CPU fan control on recent products - add a helper for device presence - cleanup AGFN fan handling - Use kmemdup rather than duplicating its implementation compal-laptop: - Initialize "value" in ec_read_u8() dell-wmi: - Use existing defined KBD_LED_* magic values - Ignore keyboard backlight change KBD_LED_AUTO_TOKEN - Ignore keyboard backlight change KBD_LED_ON_TOKEN hp_accel: - Add support for HP ZBook 17 G5 i2c-multi-instantiate: - Use struct_size() helper intel_bxtwc_tmu: - Remove dev_err() usage after platform_get_irq() intel_int0002_vgpio: - Use device_init_wakeup - Fix wakeups not working on Cherry Trail - Remove dev_err() usage after platform_get_irq() intel_pmc_core: - Do not ioremap RAM intel_pmc_core_pltdrv: - Module removal warning fix intel_pmc_ipc: - Remove dev_err() usage after platform_get_irq() ISST: - Allow additional TRL MSRs - Use dev_get_drvdata MAINTAINERS: - Switch PDx86 subsystem status to Odd Fixes pcengines-apuv2: - wire up simswitch gpio as led - add mpcie reset gpio export platform/mellanox: - mlxreg-hotplug: Remove dev_err() usage after platform_get_irq() pmc_atom: - Add Siemens SIMATIC IPC227E to critclk_systems DMI table thinkpad_acpi: - Add ThinkPad PrivacyGuard - Use kmemdup rather than duplicating its implementation tools/power/x86/intel-speed-select: - Display core count for bucket - Fix memory leak - Output success/failed for command output - Output human readable CPU list - Change turbo ratio output to maximum turbo frequency - Switch output to MHz - Simplify output for turbo-freq and base-freq - Fix cpu-count output - Fix help option typo - Fix package typo - Fix a read overflow in isst_set_tdp_level_msr() touchscreen_dmi: - Add info for the Trekstor Primebook C11B 2-in-1 - Add info for the Irbis TW90 tablet - Add info for the Chuwi Surbook Mini tablet wmi: - Remove acpi_has_method() call -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEqaflIX74DDDzMJJtb7wzTHR8rCgFAl17y/4ACgkQb7wzTHR8 rCjMyA//Zgv//XuQUqAPon/UAxu2FhDC40VBicm4AuNUtkqbN2cE04ZosyVQWLr9 ZNVgTu5CU2HR5HIuA6Xn3+FIadLYe/qpXhOvCTKQa/SrbvZLKxeoEBzoqIOgxvpN 90xkoKIp6GB+N2zjeKAhyuiJ2wce2RKok3mWOEdaEBqsrTT3LFToCpF+crpbKv81 UECMUet7ymdq+ryNYjCW4O2YmQYUpI3aGvv0MRJ9uQJrUfdN0Pa/lsXqmd5/agyi 6J5RP0LDSUJat8lOzxzWWF7pHa7dbVuDVzKlfKt6yIOmK4YqiwE9OLoVEDmpyCNx 22/pIDsJcPcdeUaAzwNEO7ao+UKQ2jXmh0IhkO9DkFziJfLz73Ucv47ZJzdPYhEo bQtr9FlcttJ5Xxw/j6tQTSGasmSZCXElfiVJObujxRu47bSqlH/846PRK3kcWrga AgFlIpvqO5J+ZkEZTohQltRPEfnJC4GbpjHnNOFvk0bowBc7KWk3EzDsJ6GvyIIX z9pKpQ6OmjmiVZmA+aIxMbxYvgYobNGjCeUH20duqgLaMtzqZ3MgU4NXnuSbzX5t 8AL9irGE4JclJ7gkOh7SGIKdibXTjeUC9bPV0efqHn2P8sEigsYtDfaUA67XMDZ/ xYvKxC4XR/msJMkz4hRk9WyTEFAXbLW/teLE9nLBEBTguWemDuk= =HItn -----END PGP SIGNATURE----- Merge tag 'platform-drivers-x86-v5.4-1' of git://git.infradead.org/linux-platform-drivers-x86 Pull x86 platform-drivers updates from Andy Shevchenko: - ASUS WMI driver got a couple of updates, i.e. support of FAN is fixed for recent products and the charge threshold support has been added - Two uknown key events for Dell laptops are being ignored now to avoid spamming users with harmless messages - HP ZBook 17 G5 and ASUS Zenbook UX430UNR got accelerometer support. - Intel CherryTrail platforms had a regression with wake up. Now it's fixed - Intel PMC driver got fixed in order to work nicely in Xen environment - Intel Speed Select driver provides bucket vs core count relationship. Besides that the tools has been updated for better output - The PrivacyGuard is enabled on Lenovo ThinkPad laptops - Three tablets - Trekstor Primebook C11B 2-in-1, Irbis TW90 and Chuwi Surbook Mini - got touchscreen support * tag 'platform-drivers-x86-v5.4-1' of git://git.infradead.org/linux-platform-drivers-x86: (53 commits) MAINTAINERS: Switch PDx86 subsystem status to Odd Fixes platform/x86: asus-wmi: Refactor charge threshold to use the battery hooking API platform/x86: asus-wmi: Rename CHARGE_THRESHOLD to RSOC platform/x86: asus-wmi: Reorder ASUS_WMI_CHARGE_THRESHOLD tools/power/x86/intel-speed-select: Display core count for bucket platform/x86: ISST: Allow additional TRL MSRs tools/power/x86/intel-speed-select: Fix memory leak tools/power/x86/intel-speed-select: Output success/failed for command output tools/power/x86/intel-speed-select: Output human readable CPU list tools/power/x86/intel-speed-select: Change turbo ratio output to maximum turbo frequency tools/power/x86/intel-speed-select: Switch output to MHz tools/power/x86/intel-speed-select: Simplify output for turbo-freq and base-freq tools/power/x86/intel-speed-select: Fix cpu-count output tools/power/x86/intel-speed-select: Fix help option typo tools/power/x86/intel-speed-select: Fix package typo tools/power/x86/intel-speed-select: Fix a read overflow in isst_set_tdp_level_msr() platform/x86: intel_int0002_vgpio: Use device_init_wakeup platform/x86: intel_int0002_vgpio: Fix wakeups not working on Cherry Trail platform/x86: compal-laptop: Initialize "value" in ec_read_u8() platform/x86: touchscreen_dmi: Add info for the Trekstor Primebook C11B 2-in-1 ...
This commit is contained in:
Коммит
ad06219573
|
@ -49,6 +49,7 @@ detailed description):
|
|||
- Fan control and monitoring: fan speed, fan enable/disable
|
||||
- WAN enable and disable
|
||||
- UWB enable and disable
|
||||
- LCD Shadow (PrivacyGuard) enable and disable
|
||||
|
||||
A compatibility table by model and feature is maintained on the web
|
||||
site, http://ibm-acpi.sf.net/. I appreciate any success or failure
|
||||
|
@ -1409,6 +1410,28 @@ Sysfs notes
|
|||
Documentation/driver-api/rfkill.rst for details.
|
||||
|
||||
|
||||
LCD Shadow control
|
||||
------------------
|
||||
|
||||
procfs: /proc/acpi/ibm/lcdshadow
|
||||
|
||||
Some newer T480s and T490s ThinkPads provide a feature called
|
||||
PrivacyGuard. By turning this feature on, the usable vertical and
|
||||
horizontal viewing angles of the LCD can be limited (as if some privacy
|
||||
screen was applied manually in front of the display).
|
||||
|
||||
procfs notes
|
||||
^^^^^^^^^^^^
|
||||
|
||||
The available commands are::
|
||||
|
||||
echo '0' >/proc/acpi/ibm/lcdshadow
|
||||
echo '1' >/proc/acpi/ibm/lcdshadow
|
||||
|
||||
The first command ensures the best viewing angle and the latter one turns
|
||||
on the feature, restricting the viewing angles.
|
||||
|
||||
|
||||
EXPERIMENTAL: UWB
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -17512,7 +17512,7 @@ M: Darren Hart <dvhart@infradead.org>
|
|||
M: Andy Shevchenko <andy@infradead.org>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
T: git git://git.infradead.org/linux-platform-drivers-x86.git
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: drivers/platform/x86/
|
||||
F: drivers/platform/olpc/
|
||||
|
||||
|
|
|
@ -642,11 +642,8 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev)
|
|||
priv->irq = pdata->irq;
|
||||
} else {
|
||||
priv->irq = platform_get_irq(pdev, 0);
|
||||
if (priv->irq < 0) {
|
||||
dev_err(&pdev->dev, "Failed to get platform irq: %d\n",
|
||||
priv->irq);
|
||||
if (priv->irq < 0)
|
||||
return priv->irq;
|
||||
}
|
||||
}
|
||||
|
||||
priv->regmap = pdata->regmap;
|
||||
|
|
|
@ -1881,52 +1881,17 @@ static int __init acer_wmi_enable_rf_button(void)
|
|||
return status;
|
||||
}
|
||||
|
||||
#define ACER_WMID_ACCEL_HID "BST0001"
|
||||
|
||||
static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level,
|
||||
void *ctx, void **retval)
|
||||
{
|
||||
struct acpi_device *dev;
|
||||
|
||||
if (!strcmp(ctx, "SENR")) {
|
||||
if (acpi_bus_get_device(ah, &dev))
|
||||
return AE_OK;
|
||||
if (strcmp(ACER_WMID_ACCEL_HID, acpi_device_hid(dev)))
|
||||
return AE_OK;
|
||||
} else
|
||||
return AE_OK;
|
||||
|
||||
*(acpi_handle *)retval = ah;
|
||||
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
static int __init acer_wmi_get_handle(const char *name, const char *prop,
|
||||
acpi_handle *ah)
|
||||
{
|
||||
acpi_status status;
|
||||
acpi_handle handle;
|
||||
|
||||
BUG_ON(!name || !ah);
|
||||
|
||||
handle = NULL;
|
||||
status = acpi_get_devices(prop, acer_wmi_get_handle_cb,
|
||||
(void *)name, &handle);
|
||||
if (ACPI_SUCCESS(status) && handle) {
|
||||
*ah = handle;
|
||||
return 0;
|
||||
} else {
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
static int __init acer_wmi_accel_setup(void)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
int err;
|
||||
|
||||
err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle);
|
||||
if (err)
|
||||
return err;
|
||||
adev = acpi_dev_get_first_match_dev("BST0001", NULL, -1);
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
gsensor_handle = acpi_device_handle(adev);
|
||||
acpi_dev_put(adev);
|
||||
|
||||
interface->capability |= ACER_CAP_ACCEL;
|
||||
|
||||
|
|
|
@ -402,6 +402,15 @@ static const struct dmi_system_id asus_quirks[] = {
|
|||
},
|
||||
.driver_data = &quirk_asus_forceals,
|
||||
},
|
||||
{
|
||||
.callback = dmi_matched,
|
||||
.ident = "ASUSTeK COMPUTER INC. UX430UNR",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "UX430UNR"),
|
||||
},
|
||||
.driver_data = &quirk_asus_forceals,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/rfkill.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_hotplug.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
@ -35,6 +36,8 @@
|
|||
#include <linux/thermal.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#include <acpi/battery.h>
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "asus-wmi.h"
|
||||
|
@ -65,6 +68,9 @@ MODULE_LICENSE("GPL");
|
|||
#define ASUS_FAN_MFUN 0x13
|
||||
#define ASUS_FAN_SFUN_READ 0x06
|
||||
#define ASUS_FAN_SFUN_WRITE 0x07
|
||||
|
||||
/* Based on standard hwmon pwmX_enable values */
|
||||
#define ASUS_FAN_CTRL_FULLSPEED 0
|
||||
#define ASUS_FAN_CTRL_MANUAL 1
|
||||
#define ASUS_FAN_CTRL_AUTO 2
|
||||
|
||||
|
@ -120,7 +126,7 @@ struct agfn_args {
|
|||
} __packed;
|
||||
|
||||
/* struct used for calling fan read and write methods */
|
||||
struct fan_args {
|
||||
struct agfn_fan_args {
|
||||
struct agfn_args agfn; /* common fields */
|
||||
u8 fan; /* fan number: 0: set auto mode 1: 1st fan */
|
||||
u32 speed; /* read: RPM/100 - write: 0-255 */
|
||||
|
@ -148,6 +154,12 @@ struct asus_rfkill {
|
|||
u32 dev_id;
|
||||
};
|
||||
|
||||
enum fan_type {
|
||||
FAN_TYPE_NONE = 0,
|
||||
FAN_TYPE_AGFN, /* deprecated on newer platforms */
|
||||
FAN_TYPE_SPEC83, /* starting in Spec 8.3, use CPU_FAN_CTRL */
|
||||
};
|
||||
|
||||
struct asus_wmi {
|
||||
int dsts_id;
|
||||
int spec;
|
||||
|
@ -178,14 +190,17 @@ struct asus_wmi {
|
|||
struct asus_rfkill gps;
|
||||
struct asus_rfkill uwb;
|
||||
|
||||
bool asus_hwmon_fan_manual_mode;
|
||||
int asus_hwmon_num_fans;
|
||||
int asus_hwmon_pwm;
|
||||
enum fan_type fan_type;
|
||||
int fan_pwm_mode;
|
||||
int agfn_pwm;
|
||||
|
||||
bool fan_boost_mode_available;
|
||||
u8 fan_boost_mode_mask;
|
||||
u8 fan_boost_mode;
|
||||
|
||||
// The RSOC controls the maximum charging percentage.
|
||||
bool battery_rsoc_available;
|
||||
|
||||
struct hotplug_slot hotplug_slot;
|
||||
struct mutex hotplug_lock;
|
||||
struct mutex wmi_lock;
|
||||
|
@ -292,12 +307,11 @@ static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args)
|
|||
* Copy to dma capable address otherwise memory corruption occurs as
|
||||
* bios has to be able to access it.
|
||||
*/
|
||||
input.pointer = kzalloc(args.length, GFP_DMA | GFP_KERNEL);
|
||||
input.pointer = kmemdup(args.pointer, args.length, GFP_DMA | GFP_KERNEL);
|
||||
input.length = args.length;
|
||||
if (!input.pointer)
|
||||
return -ENOMEM;
|
||||
phys_addr = virt_to_phys(input.pointer);
|
||||
memcpy(input.pointer, args.pointer, args.length);
|
||||
|
||||
status = asus_wmi_evaluate_method(ASUS_WMI_METHODID_AGFN,
|
||||
phys_addr, 0, &retval);
|
||||
|
@ -331,7 +345,6 @@ static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
|
|||
int err;
|
||||
|
||||
err = asus_wmi_get_devstate(asus, dev_id, &retval);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -352,6 +365,105 @@ static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id)
|
|||
ASUS_WMI_DSTS_STATUS_BIT);
|
||||
}
|
||||
|
||||
static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
|
||||
{
|
||||
u32 retval;
|
||||
int status = asus_wmi_get_devstate(asus, dev_id, &retval);
|
||||
|
||||
return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT);
|
||||
}
|
||||
|
||||
/* Battery ********************************************************************/
|
||||
|
||||
/* The battery maximum charging percentage */
|
||||
static int charge_end_threshold;
|
||||
|
||||
static ssize_t charge_control_end_threshold_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int value, ret, rv;
|
||||
|
||||
ret = kstrtouint(buf, 10, &value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (value < 0 || value > 100)
|
||||
return -EINVAL;
|
||||
|
||||
ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, value, &rv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (rv != 1)
|
||||
return -EIO;
|
||||
|
||||
/* There isn't any method in the DSDT to read the threshold, so we
|
||||
* save the threshold.
|
||||
*/
|
||||
charge_end_threshold = value;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t charge_control_end_threshold_show(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", charge_end_threshold);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(charge_control_end_threshold);
|
||||
|
||||
static int asus_wmi_battery_add(struct power_supply *battery)
|
||||
{
|
||||
/* The WMI method does not provide a way to specific a battery, so we
|
||||
* just assume it is the first battery.
|
||||
*/
|
||||
if (strcmp(battery->desc->name, "BAT0") != 0)
|
||||
return -ENODEV;
|
||||
|
||||
if (device_create_file(&battery->dev,
|
||||
&dev_attr_charge_control_end_threshold))
|
||||
return -ENODEV;
|
||||
|
||||
/* The charge threshold is only reset when the system is power cycled,
|
||||
* and we can't get the current threshold so let set it to 100% when
|
||||
* a battery is added.
|
||||
*/
|
||||
asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, 100, NULL);
|
||||
charge_end_threshold = 100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int asus_wmi_battery_remove(struct power_supply *battery)
|
||||
{
|
||||
device_remove_file(&battery->dev,
|
||||
&dev_attr_charge_control_end_threshold);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct acpi_battery_hook battery_hook = {
|
||||
.add_battery = asus_wmi_battery_add,
|
||||
.remove_battery = asus_wmi_battery_remove,
|
||||
.name = "ASUS Battery Extension",
|
||||
};
|
||||
|
||||
static void asus_wmi_battery_init(struct asus_wmi *asus)
|
||||
{
|
||||
asus->battery_rsoc_available = false;
|
||||
if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_RSOC)) {
|
||||
asus->battery_rsoc_available = true;
|
||||
battery_hook_register(&battery_hook);
|
||||
}
|
||||
}
|
||||
|
||||
static void asus_wmi_battery_exit(struct asus_wmi *asus)
|
||||
{
|
||||
if (asus->battery_rsoc_available)
|
||||
battery_hook_unregister(&battery_hook);
|
||||
}
|
||||
|
||||
/* LEDs ***********************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -427,15 +539,14 @@ static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
|
|||
if (retval == 0x8000)
|
||||
retval = 0;
|
||||
|
||||
if (retval >= 0) {
|
||||
if (level)
|
||||
*level = retval & 0x7F;
|
||||
if (env)
|
||||
*env = (retval >> 8) & 0x7F;
|
||||
retval = 0;
|
||||
}
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
return retval;
|
||||
if (level)
|
||||
*level = retval & 0x7F;
|
||||
if (env)
|
||||
*env = (retval >> 8) & 0x7F;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_kbd_led_set(struct led_classdev *led_cdev, int value)
|
||||
|
@ -446,12 +557,7 @@ static void do_kbd_led_set(struct led_classdev *led_cdev, int value)
|
|||
asus = container_of(led_cdev, struct asus_wmi, kbd_led);
|
||||
max_level = asus->kbd_led.max_brightness;
|
||||
|
||||
if (value > max_level)
|
||||
value = max_level;
|
||||
else if (value < 0)
|
||||
value = 0;
|
||||
|
||||
asus->kbd_led_wk = value;
|
||||
asus->kbd_led_wk = clamp_val(value, 0, max_level);
|
||||
kbd_led_update(asus);
|
||||
}
|
||||
|
||||
|
@ -481,7 +587,6 @@ static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
|
|||
asus = container_of(led_cdev, struct asus_wmi, kbd_led);
|
||||
|
||||
retval = kbd_led_read(asus, &value, NULL);
|
||||
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
|
@ -497,15 +602,6 @@ static int wlan_led_unknown_state(struct asus_wmi *asus)
|
|||
return result & ASUS_WMI_DSTS_UNKNOWN_BIT;
|
||||
}
|
||||
|
||||
static int wlan_led_presence(struct asus_wmi *asus)
|
||||
{
|
||||
u32 result;
|
||||
|
||||
asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, &result);
|
||||
|
||||
return result & ASUS_WMI_DSTS_PRESENCE_BIT;
|
||||
}
|
||||
|
||||
static void wlan_led_update(struct work_struct *work)
|
||||
{
|
||||
int ctrl_param;
|
||||
|
@ -572,15 +668,6 @@ static enum led_brightness lightbar_led_get(struct led_classdev *led_cdev)
|
|||
return result & ASUS_WMI_DSTS_LIGHTBAR_MASK;
|
||||
}
|
||||
|
||||
static int lightbar_led_presence(struct asus_wmi *asus)
|
||||
{
|
||||
u32 result;
|
||||
|
||||
asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_LIGHTBAR, &result);
|
||||
|
||||
return result & ASUS_WMI_DSTS_PRESENCE_BIT;
|
||||
}
|
||||
|
||||
static void asus_wmi_led_exit(struct asus_wmi *asus)
|
||||
{
|
||||
if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
|
||||
|
@ -631,7 +718,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (wlan_led_presence(asus) && (asus->driver->quirks->wapf > 0)) {
|
||||
if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_WIRELESS_LED)
|
||||
&& (asus->driver->quirks->wapf > 0)) {
|
||||
INIT_WORK(&asus->wlan_led_work, wlan_led_update);
|
||||
|
||||
asus->wlan_led.name = "asus::wlan";
|
||||
|
@ -648,7 +736,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (lightbar_led_presence(asus)) {
|
||||
if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_LIGHTBAR)) {
|
||||
INIT_WORK(&asus->lightbar_led_work, lightbar_led_update);
|
||||
|
||||
asus->lightbar_led.name = "asus::lightbar";
|
||||
|
@ -771,16 +859,14 @@ static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node)
|
|||
acpi_handle handle;
|
||||
|
||||
status = acpi_get_handle(NULL, node, &handle);
|
||||
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
status = acpi_install_notify_handler(handle,
|
||||
ACPI_SYSTEM_NOTIFY,
|
||||
asus_rfkill_notify, asus);
|
||||
if (ACPI_FAILURE(status))
|
||||
pr_warn("Failed to register notify on %s\n", node);
|
||||
} else
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
|
||||
asus_rfkill_notify, asus);
|
||||
if (ACPI_FAILURE(status))
|
||||
pr_warn("Failed to register notify on %s\n", node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -790,15 +876,13 @@ static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
|
|||
acpi_handle handle;
|
||||
|
||||
status = acpi_get_handle(NULL, node, &handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
status = acpi_remove_notify_handler(handle,
|
||||
ACPI_SYSTEM_NOTIFY,
|
||||
asus_rfkill_notify);
|
||||
if (ACPI_FAILURE(status))
|
||||
pr_err("Error removing rfkill notify handler %s\n",
|
||||
node);
|
||||
}
|
||||
status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
|
||||
asus_rfkill_notify);
|
||||
if (ACPI_FAILURE(status))
|
||||
pr_err("Error removing rfkill notify handler %s\n", node);
|
||||
}
|
||||
|
||||
static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
|
||||
|
@ -1126,10 +1210,10 @@ static void asus_wmi_set_als(void)
|
|||
|
||||
/* Hwmon device ***************************************************************/
|
||||
|
||||
static int asus_hwmon_agfn_fan_speed_read(struct asus_wmi *asus, int fan,
|
||||
static int asus_agfn_fan_speed_read(struct asus_wmi *asus, int fan,
|
||||
int *speed)
|
||||
{
|
||||
struct fan_args args = {
|
||||
struct agfn_fan_args args = {
|
||||
.agfn.len = sizeof(args),
|
||||
.agfn.mfun = ASUS_FAN_MFUN,
|
||||
.agfn.sfun = ASUS_FAN_SFUN_READ,
|
||||
|
@ -1153,10 +1237,10 @@ static int asus_hwmon_agfn_fan_speed_read(struct asus_wmi *asus, int fan,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int asus_hwmon_agfn_fan_speed_write(struct asus_wmi *asus, int fan,
|
||||
static int asus_agfn_fan_speed_write(struct asus_wmi *asus, int fan,
|
||||
int *speed)
|
||||
{
|
||||
struct fan_args args = {
|
||||
struct agfn_fan_args args = {
|
||||
.agfn.len = sizeof(args),
|
||||
.agfn.mfun = ASUS_FAN_MFUN,
|
||||
.agfn.sfun = ASUS_FAN_SFUN_WRITE,
|
||||
|
@ -1176,7 +1260,7 @@ static int asus_hwmon_agfn_fan_speed_write(struct asus_wmi *asus, int fan,
|
|||
return -ENXIO;
|
||||
|
||||
if (speed && fan == 1)
|
||||
asus->asus_hwmon_pwm = *speed;
|
||||
asus->agfn_pwm = *speed;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1185,87 +1269,94 @@ static int asus_hwmon_agfn_fan_speed_write(struct asus_wmi *asus, int fan,
|
|||
* Check if we can read the speed of one fan. If true we assume we can also
|
||||
* control it.
|
||||
*/
|
||||
static int asus_hwmon_get_fan_number(struct asus_wmi *asus, int *num_fans)
|
||||
static bool asus_wmi_has_agfn_fan(struct asus_wmi *asus)
|
||||
{
|
||||
int status;
|
||||
int speed = 0;
|
||||
int speed;
|
||||
u32 value;
|
||||
|
||||
*num_fans = 0;
|
||||
status = asus_agfn_fan_speed_read(asus, 1, &speed);
|
||||
if (status != 0)
|
||||
return false;
|
||||
|
||||
status = asus_hwmon_agfn_fan_speed_read(asus, 1, &speed);
|
||||
if (!status)
|
||||
*num_fans = 1;
|
||||
status = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
|
||||
if (status != 0)
|
||||
return false;
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* We need to find a better way, probably using sfun,
|
||||
* bits or spec ...
|
||||
* Currently we disable it if:
|
||||
* - ASUS_WMI_UNSUPPORTED_METHOD is returned
|
||||
* - reverved bits are non-zero
|
||||
* - sfun and presence bit are not set
|
||||
*/
|
||||
return !(value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
|
||||
|| (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)));
|
||||
}
|
||||
|
||||
static int asus_hwmon_fan_set_auto(struct asus_wmi *asus)
|
||||
static int asus_fan_set_auto(struct asus_wmi *asus)
|
||||
{
|
||||
int status;
|
||||
u32 retval;
|
||||
|
||||
status = asus_hwmon_agfn_fan_speed_write(asus, 0, NULL);
|
||||
if (status)
|
||||
switch (asus->fan_type) {
|
||||
case FAN_TYPE_SPEC83:
|
||||
status = asus_wmi_set_devstate(ASUS_WMI_DEVID_CPU_FAN_CTRL,
|
||||
0, &retval);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (retval != 1)
|
||||
return -EIO;
|
||||
break;
|
||||
|
||||
case FAN_TYPE_AGFN:
|
||||
status = asus_agfn_fan_speed_write(asus, 0, NULL);
|
||||
if (status)
|
||||
return -ENXIO;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
asus->asus_hwmon_fan_manual_mode = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int asus_hwmon_fan_rpm_show(struct device *dev, int fan)
|
||||
{
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
int value;
|
||||
int ret;
|
||||
|
||||
/* no speed readable on manual mode */
|
||||
if (asus->asus_hwmon_fan_manual_mode)
|
||||
return -ENXIO;
|
||||
|
||||
ret = asus_hwmon_agfn_fan_speed_read(asus, fan+1, &value);
|
||||
if (ret) {
|
||||
pr_warn("reading fan speed failed: %d\n", ret);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void asus_hwmon_pwm_show(struct asus_wmi *asus, int fan, int *value)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (asus->asus_hwmon_pwm >= 0) {
|
||||
*value = asus->asus_hwmon_pwm;
|
||||
return;
|
||||
}
|
||||
|
||||
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, value);
|
||||
if (err < 0)
|
||||
return;
|
||||
|
||||
*value &= 0xFF;
|
||||
|
||||
if (*value == 1) /* Low Speed */
|
||||
*value = 85;
|
||||
else if (*value == 2)
|
||||
*value = 170;
|
||||
else if (*value == 3)
|
||||
*value = 255;
|
||||
else if (*value) {
|
||||
pr_err("Unknown fan speed %#x\n", *value);
|
||||
*value = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t pwm1_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
int err;
|
||||
int value;
|
||||
|
||||
asus_hwmon_pwm_show(asus, 0, &value);
|
||||
/* If we already set a value then just return it */
|
||||
if (asus->agfn_pwm >= 0)
|
||||
return sprintf(buf, "%d\n", asus->agfn_pwm);
|
||||
|
||||
/*
|
||||
* If we haven't set already set a value through the AGFN interface,
|
||||
* we read a current value through the (now-deprecated) FAN_CTRL device.
|
||||
*/
|
||||
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
value &= 0xFF;
|
||||
|
||||
if (value == 1) /* Low Speed */
|
||||
value = 85;
|
||||
else if (value == 2)
|
||||
value = 170;
|
||||
else if (value == 3)
|
||||
value = 255;
|
||||
else if (value) {
|
||||
pr_err("Unknown fan speed %#x\n", value);
|
||||
value = -1;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%d\n", value);
|
||||
}
|
||||
|
@ -1279,17 +1370,16 @@ static ssize_t pwm1_store(struct device *dev,
|
|||
int ret;
|
||||
|
||||
ret = kstrtouint(buf, 10, &value);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
value = clamp(value, 0, 255);
|
||||
|
||||
state = asus_hwmon_agfn_fan_speed_write(asus, 1, &value);
|
||||
state = asus_agfn_fan_speed_write(asus, 1, &value);
|
||||
if (state)
|
||||
pr_warn("Setting fan speed failed: %d\n", state);
|
||||
else
|
||||
asus->asus_hwmon_fan_manual_mode = true;
|
||||
asus->fan_pwm_mode = ASUS_FAN_CTRL_MANUAL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -1298,10 +1388,37 @@ static ssize_t fan1_input_show(struct device *dev,
|
|||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int value = asus_hwmon_fan_rpm_show(dev, 0);
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
int value;
|
||||
int ret;
|
||||
|
||||
switch (asus->fan_type) {
|
||||
case FAN_TYPE_SPEC83:
|
||||
ret = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_CPU_FAN_CTRL,
|
||||
&value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
value &= 0xffff;
|
||||
break;
|
||||
|
||||
case FAN_TYPE_AGFN:
|
||||
/* no speed readable on manual mode */
|
||||
if (asus->fan_pwm_mode == ASUS_FAN_CTRL_MANUAL)
|
||||
return -ENXIO;
|
||||
|
||||
ret = asus_agfn_fan_speed_read(asus, 1, &value);
|
||||
if (ret) {
|
||||
pr_warn("reading fan speed failed: %d\n", ret);
|
||||
return -ENXIO;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%d\n", value < 0 ? -1 : value*100);
|
||||
|
||||
}
|
||||
|
||||
static ssize_t pwm1_enable_show(struct device *dev,
|
||||
|
@ -1310,10 +1427,16 @@ static ssize_t pwm1_enable_show(struct device *dev,
|
|||
{
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
|
||||
if (asus->asus_hwmon_fan_manual_mode)
|
||||
return sprintf(buf, "%d\n", ASUS_FAN_CTRL_MANUAL);
|
||||
|
||||
return sprintf(buf, "%d\n", ASUS_FAN_CTRL_AUTO);
|
||||
/*
|
||||
* Just read back the cached pwm mode.
|
||||
*
|
||||
* For the CPU_FAN device, the spec indicates that we should be
|
||||
* able to read the device status and consult bit 19 to see if we
|
||||
* are in Full On or Automatic mode. However, this does not work
|
||||
* in practice on X532FL at least (the bit is always 0) and there's
|
||||
* also nothing in the DSDT to indicate that this behaviour exists.
|
||||
*/
|
||||
return sprintf(buf, "%d\n", asus->fan_pwm_mode);
|
||||
}
|
||||
|
||||
static ssize_t pwm1_enable_store(struct device *dev,
|
||||
|
@ -1323,21 +1446,50 @@ static ssize_t pwm1_enable_store(struct device *dev,
|
|||
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||
int status = 0;
|
||||
int state;
|
||||
int value;
|
||||
int ret;
|
||||
u32 retval;
|
||||
|
||||
ret = kstrtouint(buf, 10, &state);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (state == ASUS_FAN_CTRL_MANUAL)
|
||||
asus->asus_hwmon_fan_manual_mode = true;
|
||||
else
|
||||
status = asus_hwmon_fan_set_auto(asus);
|
||||
if (asus->fan_type == FAN_TYPE_SPEC83) {
|
||||
switch (state) { /* standard documented hwmon values */
|
||||
case ASUS_FAN_CTRL_FULLSPEED:
|
||||
value = 1;
|
||||
break;
|
||||
case ASUS_FAN_CTRL_AUTO:
|
||||
value = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_CPU_FAN_CTRL,
|
||||
value, &retval);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (retval != 1)
|
||||
return -EIO;
|
||||
} else if (asus->fan_type == FAN_TYPE_AGFN) {
|
||||
switch (state) {
|
||||
case ASUS_FAN_CTRL_MANUAL:
|
||||
break;
|
||||
|
||||
case ASUS_FAN_CTRL_AUTO:
|
||||
status = asus_fan_set_auto(asus);
|
||||
if (status)
|
||||
return status;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
asus->fan_pwm_mode = state;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -1357,7 +1509,6 @@ static ssize_t asus_hwmon_temp1(struct device *dev,
|
|||
int err;
|
||||
|
||||
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1390,59 +1541,33 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
|
|||
{
|
||||
struct device *dev = container_of(kobj, struct device, kobj);
|
||||
struct asus_wmi *asus = dev_get_drvdata(dev->parent);
|
||||
int dev_id = -1;
|
||||
int fan_attr = -1;
|
||||
u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
|
||||
bool ok = true;
|
||||
|
||||
if (attr == &dev_attr_pwm1.attr)
|
||||
dev_id = ASUS_WMI_DEVID_FAN_CTRL;
|
||||
else if (attr == &dev_attr_temp1_input.attr)
|
||||
dev_id = ASUS_WMI_DEVID_THERMAL_CTRL;
|
||||
|
||||
|
||||
if (attr == &dev_attr_fan1_input.attr
|
||||
if (attr == &dev_attr_pwm1.attr) {
|
||||
if (asus->fan_type != FAN_TYPE_AGFN)
|
||||
return 0;
|
||||
} else if (attr == &dev_attr_fan1_input.attr
|
||||
|| attr == &dev_attr_fan1_label.attr
|
||||
|| attr == &dev_attr_pwm1.attr
|
||||
|| attr == &dev_attr_pwm1_enable.attr) {
|
||||
fan_attr = 1;
|
||||
}
|
||||
if (asus->fan_type == FAN_TYPE_NONE)
|
||||
return 0;
|
||||
} else if (attr == &dev_attr_temp1_input.attr) {
|
||||
int err = asus_wmi_get_devstate(asus,
|
||||
ASUS_WMI_DEVID_THERMAL_CTRL,
|
||||
&value);
|
||||
|
||||
if (dev_id != -1) {
|
||||
int err = asus_wmi_get_devstate(asus, dev_id, &value);
|
||||
|
||||
if (err < 0 && fan_attr == -1)
|
||||
if (err < 0)
|
||||
return 0; /* can't return negative here */
|
||||
}
|
||||
|
||||
if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) {
|
||||
/*
|
||||
* We need to find a better way, probably using sfun,
|
||||
* bits or spec ...
|
||||
* Currently we disable it if:
|
||||
* - ASUS_WMI_UNSUPPORTED_METHOD is returned
|
||||
* - reverved bits are non-zero
|
||||
* - sfun and presence bit are not set
|
||||
*/
|
||||
if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
|
||||
|| (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)))
|
||||
ok = false;
|
||||
else
|
||||
ok = fan_attr <= asus->asus_hwmon_num_fans;
|
||||
} else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) {
|
||||
/*
|
||||
* If the temperature value in deci-Kelvin is near the absolute
|
||||
* zero temperature, something is clearly wrong
|
||||
*/
|
||||
if (value == 0 || value == 1)
|
||||
ok = false;
|
||||
} else if (fan_attr <= asus->asus_hwmon_num_fans && fan_attr != -1) {
|
||||
ok = true;
|
||||
} else {
|
||||
ok = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ok ? attr->mode : 0;
|
||||
return attr->mode;
|
||||
}
|
||||
|
||||
static const struct attribute_group hwmon_attribute_group = {
|
||||
|
@ -1468,20 +1593,19 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus)
|
|||
|
||||
static int asus_wmi_fan_init(struct asus_wmi *asus)
|
||||
{
|
||||
int status;
|
||||
asus->fan_type = FAN_TYPE_NONE;
|
||||
asus->agfn_pwm = -1;
|
||||
|
||||
asus->asus_hwmon_pwm = -1;
|
||||
asus->asus_hwmon_num_fans = -1;
|
||||
asus->asus_hwmon_fan_manual_mode = false;
|
||||
if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CPU_FAN_CTRL))
|
||||
asus->fan_type = FAN_TYPE_SPEC83;
|
||||
else if (asus_wmi_has_agfn_fan(asus))
|
||||
asus->fan_type = FAN_TYPE_AGFN;
|
||||
|
||||
status = asus_hwmon_get_fan_number(asus, &asus->asus_hwmon_num_fans);
|
||||
if (status) {
|
||||
asus->asus_hwmon_num_fans = 0;
|
||||
pr_warn("Could not determine number of fans: %d\n", status);
|
||||
return -ENXIO;
|
||||
}
|
||||
if (asus->fan_type == FAN_TYPE_NONE)
|
||||
return -ENODEV;
|
||||
|
||||
pr_info("Number of fans: %d\n", asus->asus_hwmon_num_fans);
|
||||
asus_fan_set_auto(asus);
|
||||
asus->fan_pwm_mode = ASUS_FAN_CTRL_AUTO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1523,7 +1647,6 @@ static int fan_boost_mode_write(struct asus_wmi *asus)
|
|||
pr_info("Set fan boost mode: %u\n", value);
|
||||
err = asus_wmi_set_devstate(ASUS_WMI_DEVID_FAN_BOOST_MODE, value,
|
||||
&retval);
|
||||
|
||||
if (err) {
|
||||
pr_warn("Failed to set fan boost mode: %d\n", err);
|
||||
return err;
|
||||
|
@ -1606,6 +1729,7 @@ static DEVICE_ATTR_RW(fan_boost_mode);
|
|||
static int read_backlight_power(struct asus_wmi *asus)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (asus->driver->quirks->store_backlight_power)
|
||||
ret = !asus->driver->panel_power;
|
||||
else
|
||||
|
@ -1624,7 +1748,6 @@ static int read_brightness_max(struct asus_wmi *asus)
|
|||
int err;
|
||||
|
||||
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1644,7 +1767,6 @@ static int read_brightness(struct backlight_device *bd)
|
|||
int err;
|
||||
|
||||
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1734,7 +1856,6 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus)
|
|||
return max;
|
||||
|
||||
power = read_backlight_power(asus);
|
||||
|
||||
if (power == -ENODEV)
|
||||
power = FB_BLANK_UNBLANK;
|
||||
else if (power < 0)
|
||||
|
@ -1900,7 +2021,6 @@ static void asus_wmi_notify(u32 value, void *context)
|
|||
|
||||
for (i = 0; i < WMI_EVENT_QUEUE_SIZE + 1; i++) {
|
||||
code = asus_wmi_get_event_code(value);
|
||||
|
||||
if (code < 0) {
|
||||
pr_warn("Failed to get notify code: %d\n", code);
|
||||
return;
|
||||
|
@ -1929,7 +2049,6 @@ static int asus_wmi_notify_queue_flush(struct asus_wmi *asus)
|
|||
|
||||
for (i = 0; i < WMI_EVENT_QUEUE_SIZE + 1; i++) {
|
||||
code = asus_wmi_get_event_code(WMI_EVENT_VALUE_ATK);
|
||||
|
||||
if (code < 0) {
|
||||
pr_warn("Failed to get event during flush: %d\n", code);
|
||||
return code;
|
||||
|
@ -1945,32 +2064,25 @@ static int asus_wmi_notify_queue_flush(struct asus_wmi *asus)
|
|||
|
||||
/* Sysfs **********************************************************************/
|
||||
|
||||
static int parse_arg(const char *buf, unsigned long count, int *val)
|
||||
{
|
||||
if (!count)
|
||||
return 0;
|
||||
if (sscanf(buf, "%i", val) != 1)
|
||||
return -EINVAL;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
u32 retval;
|
||||
int rv, err, value;
|
||||
int err, value;
|
||||
|
||||
value = asus_wmi_get_devstate_simple(asus, devid);
|
||||
if (value < 0)
|
||||
return value;
|
||||
|
||||
rv = parse_arg(buf, count, &value);
|
||||
err = asus_wmi_set_devstate(devid, value, &retval);
|
||||
err = kstrtoint(buf, 0, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = asus_wmi_set_devstate(devid, value, &retval);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return rv;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf)
|
||||
|
@ -2019,8 +2131,10 @@ static ssize_t cpufv_store(struct device *dev, struct device_attribute *attr,
|
|||
{
|
||||
int value, rv;
|
||||
|
||||
if (!count || sscanf(buf, "%i", &value) != 1)
|
||||
return -EINVAL;
|
||||
rv = kstrtoint(buf, 0, &value);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (value < 0 || value > 2)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -2181,7 +2295,6 @@ static int show_dsts(struct seq_file *m, void *data)
|
|||
u32 retval = -1;
|
||||
|
||||
err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -2198,7 +2311,6 @@ static int show_devs(struct seq_file *m, void *data)
|
|||
|
||||
err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
|
||||
&retval);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -2334,7 +2446,6 @@ static int asus_wmi_add(struct platform_device *pdev)
|
|||
goto fail_input;
|
||||
|
||||
err = asus_wmi_fan_init(asus); /* probably no problems on error */
|
||||
asus_hwmon_fan_set_auto(asus);
|
||||
|
||||
err = asus_wmi_hwmon_init(asus);
|
||||
if (err)
|
||||
|
@ -2392,6 +2503,8 @@ static int asus_wmi_add(struct platform_device *pdev)
|
|||
goto fail_wmi_handler;
|
||||
}
|
||||
|
||||
asus_wmi_battery_init(asus);
|
||||
|
||||
asus_wmi_debugfs_init(asus);
|
||||
|
||||
return 0;
|
||||
|
@ -2426,7 +2539,8 @@ static int asus_wmi_remove(struct platform_device *device)
|
|||
asus_wmi_rfkill_exit(asus);
|
||||
asus_wmi_debugfs_exit(asus);
|
||||
asus_wmi_sysfs_exit(asus->platform_device);
|
||||
asus_hwmon_fan_set_auto(asus);
|
||||
asus_fan_set_auto(asus);
|
||||
asus_wmi_battery_exit(asus);
|
||||
|
||||
kfree(asus);
|
||||
return 0;
|
||||
|
|
|
@ -226,7 +226,7 @@ static const unsigned char pwm_lookup_table[256] = {
|
|||
/* General access */
|
||||
static u8 ec_read_u8(u8 addr)
|
||||
{
|
||||
u8 value;
|
||||
u8 value = 0;
|
||||
ec_read(addr, &value);
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -311,11 +311,13 @@ static const struct key_entry dell_wmi_keymap_type_0011[] = {
|
|||
{ KE_IGNORE, 0xfff1, { KEY_RESERVED } },
|
||||
|
||||
/* Keyboard backlight level changed */
|
||||
{ KE_IGNORE, 0x01e1, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, 0x02ea, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, 0x02eb, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, 0x02ec, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, 0x02f6, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, KBD_LED_OFF_TOKEN, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, KBD_LED_ON_TOKEN, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, KBD_LED_AUTO_TOKEN, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, KBD_LED_AUTO_25_TOKEN, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, KBD_LED_AUTO_50_TOKEN, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, KBD_LED_AUTO_75_TOKEN, { KEY_RESERVED } },
|
||||
{ KE_IGNORE, KBD_LED_AUTO_100_TOKEN, { KEY_RESERVED } },
|
||||
};
|
||||
|
||||
static void dell_wmi_process_key(struct wmi_device *wdev, int type, int code)
|
||||
|
|
|
@ -240,6 +240,7 @@ static const struct dmi_system_id lis3lv02d_dmi_ids[] = {
|
|||
AXIS_DMI_MATCH("HPB64xx", "HP EliteBook 84", xy_swap),
|
||||
AXIS_DMI_MATCH("HPB65xx", "HP ProBook 65", x_inverted),
|
||||
AXIS_DMI_MATCH("HPZBook15", "HP ZBook 15", x_inverted),
|
||||
AXIS_DMI_MATCH("HPZBook17G5", "HP ZBook 17 G5", x_inverted),
|
||||
AXIS_DMI_MATCH("HPZBook17", "HP ZBook 17", xy_swap_yz_inverted),
|
||||
{ NULL, }
|
||||
/* Laptop models without axis info (yet):
|
||||
|
|
|
@ -81,9 +81,7 @@ static int i2c_multi_inst_probe(struct platform_device *pdev)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
multi = devm_kmalloc(dev,
|
||||
offsetof(struct i2c_multi_inst_data, clients[ret]),
|
||||
GFP_KERNEL);
|
||||
multi = devm_kmalloc(dev, struct_size(multi, clients, ret), GFP_KERNEL);
|
||||
if (!multi)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -60,11 +60,8 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev)
|
|||
wctmu->regmap = pmic->regmap;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "invalid irq %d\n", irq);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
regmap_irq_chip = pmic->irq_chip_data_tmu;
|
||||
virq = regmap_irq_get_virq(regmap_irq_chip, irq);
|
||||
|
|
|
@ -122,7 +122,7 @@ static irqreturn_t int0002_irq(int irq, void *data)
|
|||
generic_handle_irq(irq_find_mapping(chip->irq.domain,
|
||||
GPE0A_PME_B0_VIRT_GPIO_PIN));
|
||||
|
||||
pm_system_wakeup();
|
||||
pm_wakeup_hard_event(chip->parent);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -144,6 +144,7 @@ static struct irq_chip int0002_cht_irqchip = {
|
|||
* No set_wake, on CHT the IRQ is typically shared with the ACPI SCI
|
||||
* and we don't want to mess with the ACPI SCI irq settings.
|
||||
*/
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id int0002_cpu_ids[] = {
|
||||
|
@ -173,10 +174,8 @@ static int int0002_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "Error getting IRQ: %d\n", irq);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
|
@ -221,6 +220,13 @@ static int int0002_probe(struct platform_device *pdev)
|
|||
|
||||
gpiochip_set_chained_irqchip(chip, irq_chip, irq, NULL);
|
||||
|
||||
device_init_wakeup(dev, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int int0002_remove(struct platform_device *pdev)
|
||||
{
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -236,6 +242,7 @@ static struct platform_driver int0002_driver = {
|
|||
.acpi_match_table = int0002_acpi_ids,
|
||||
},
|
||||
.probe = int0002_probe,
|
||||
.remove = int0002_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(int0002_driver);
|
||||
|
|
|
@ -878,10 +878,14 @@ static int pmc_core_probe(struct platform_device *pdev)
|
|||
if (pmcdev->map == &spt_reg_map && !pci_dev_present(pmc_pci_ids))
|
||||
pmcdev->map = &cnp_reg_map;
|
||||
|
||||
if (lpit_read_residency_count_address(&slp_s0_addr))
|
||||
if (lpit_read_residency_count_address(&slp_s0_addr)) {
|
||||
pmcdev->base_addr = PMC_BASE_ADDR_DEFAULT;
|
||||
else
|
||||
|
||||
if (page_is_ram(PHYS_PFN(pmcdev->base_addr)))
|
||||
return -ENODEV;
|
||||
} else {
|
||||
pmcdev->base_addr = slp_s0_addr - pmcdev->map->slp_s0_offset;
|
||||
}
|
||||
|
||||
pmcdev->regbase = ioremap(pmcdev->base_addr,
|
||||
pmcdev->map->regmap_length);
|
||||
|
|
|
@ -18,8 +18,16 @@
|
|||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/intel-family.h>
|
||||
|
||||
static void intel_pmc_core_release(struct device *dev)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
static struct platform_device pmc_core_device = {
|
||||
.name = "intel_pmc_core",
|
||||
.dev = {
|
||||
.release = intel_pmc_core_release,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -936,10 +936,8 @@ static int ipc_plat_probe(struct platform_device *pdev)
|
|||
spin_lock_init(&ipcdev.gcr_lock);
|
||||
|
||||
ipcdev.irq = platform_get_irq(pdev, 0);
|
||||
if (ipcdev.irq < 0) {
|
||||
dev_err(&pdev->dev, "Failed to get irq\n");
|
||||
if (ipcdev.irq < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ipc_plat_get_res(pdev);
|
||||
if (ret) {
|
||||
|
|
|
@ -29,6 +29,8 @@ static struct isst_if_cmd_cb punit_callbacks[ISST_IF_DEV_MAX];
|
|||
static int punit_msr_white_list[] = {
|
||||
MSR_TURBO_RATIO_LIMIT,
|
||||
MSR_CONFIG_TDP_CONTROL,
|
||||
MSR_TURBO_RATIO_LIMIT1,
|
||||
MSR_TURBO_RATIO_LIMIT2,
|
||||
};
|
||||
|
||||
struct isst_valid_cmd_ranges {
|
||||
|
|
|
@ -132,11 +132,9 @@ static void isst_if_remove(struct pci_dev *pdev)
|
|||
|
||||
static int __maybe_unused isst_if_suspend(struct device *device)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(device);
|
||||
struct isst_if_device *punit_dev;
|
||||
struct isst_if_device *punit_dev = dev_get_drvdata(device);
|
||||
int i;
|
||||
|
||||
punit_dev = pci_get_drvdata(pdev);
|
||||
for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
|
||||
punit_dev->range_0[i] = readl(punit_dev->punit_mmio +
|
||||
mmio_range[0].beg + 4 * i);
|
||||
|
@ -149,11 +147,9 @@ static int __maybe_unused isst_if_suspend(struct device *device)
|
|||
|
||||
static int __maybe_unused isst_if_resume(struct device *device)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(device);
|
||||
struct isst_if_device *punit_dev;
|
||||
struct isst_if_device *punit_dev = dev_get_drvdata(device);
|
||||
int i;
|
||||
|
||||
punit_dev = pci_get_drvdata(pdev);
|
||||
for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
|
||||
writel(punit_dev->range_0[i], punit_dev->punit_mmio +
|
||||
mmio_range[0].beg + 4 * i);
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#define APU2_GPIO_REG_LED3 AMD_FCH_GPIO_REG_GPIO59_DEVSLP1
|
||||
#define APU2_GPIO_REG_MODESW AMD_FCH_GPIO_REG_GPIO32_GE1
|
||||
#define APU2_GPIO_REG_SIMSWAP AMD_FCH_GPIO_REG_GPIO33_GE2
|
||||
#define APU2_GPIO_REG_MPCIE2 AMD_FCH_GPIO_REG_GPIO59_DEVSLP0
|
||||
#define APU2_GPIO_REG_MPCIE3 AMD_FCH_GPIO_REG_GPIO51
|
||||
|
||||
/* order in which the gpio lines are defined in the register list */
|
||||
#define APU2_GPIO_LINE_LED1 0
|
||||
|
@ -39,6 +41,8 @@
|
|||
#define APU2_GPIO_LINE_LED3 2
|
||||
#define APU2_GPIO_LINE_MODESW 3
|
||||
#define APU2_GPIO_LINE_SIMSWAP 4
|
||||
#define APU2_GPIO_LINE_MPCIE2 5
|
||||
#define APU2_GPIO_LINE_MPCIE3 6
|
||||
|
||||
/* gpio device */
|
||||
|
||||
|
@ -48,6 +52,8 @@ static int apu2_gpio_regs[] = {
|
|||
[APU2_GPIO_LINE_LED3] = APU2_GPIO_REG_LED3,
|
||||
[APU2_GPIO_LINE_MODESW] = APU2_GPIO_REG_MODESW,
|
||||
[APU2_GPIO_LINE_SIMSWAP] = APU2_GPIO_REG_SIMSWAP,
|
||||
[APU2_GPIO_LINE_MPCIE2] = APU2_GPIO_REG_MPCIE2,
|
||||
[APU2_GPIO_LINE_MPCIE3] = APU2_GPIO_REG_MPCIE3,
|
||||
};
|
||||
|
||||
static const char * const apu2_gpio_names[] = {
|
||||
|
@ -56,6 +62,8 @@ static const char * const apu2_gpio_names[] = {
|
|||
[APU2_GPIO_LINE_LED3] = "front-led3",
|
||||
[APU2_GPIO_LINE_MODESW] = "front-button",
|
||||
[APU2_GPIO_LINE_SIMSWAP] = "simswap",
|
||||
[APU2_GPIO_LINE_MPCIE2] = "mpcie2_reset",
|
||||
[APU2_GPIO_LINE_MPCIE3] = "mpcie3_reset",
|
||||
};
|
||||
|
||||
static const struct amd_fch_gpio_pdata board_apu2 = {
|
||||
|
@ -69,7 +77,8 @@ static const struct amd_fch_gpio_pdata board_apu2 = {
|
|||
static const struct gpio_led apu2_leds[] = {
|
||||
{ .name = "apu:green:1" },
|
||||
{ .name = "apu:green:2" },
|
||||
{ .name = "apu:green:3" }
|
||||
{ .name = "apu:green:3" },
|
||||
{ .name = "apu:simswap" },
|
||||
};
|
||||
|
||||
static const struct gpio_led_platform_data apu2_leds_pdata = {
|
||||
|
@ -86,6 +95,8 @@ static struct gpiod_lookup_table gpios_led_table = {
|
|||
NULL, 1, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_LINE_LED3,
|
||||
NULL, 2, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_REG_SIMSWAP,
|
||||
NULL, 3, GPIO_ACTIVE_LOW),
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -415,6 +415,13 @@ static const struct dmi_system_id critclk_systems[] = {
|
|||
DMI_MATCH(DMI_BOARD_NAME, "CB6363"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "SIMATIC IPC227E",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SIEMENS AG"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "6ES7647-8B"),
|
||||
},
|
||||
},
|
||||
{ /*sentinel*/ }
|
||||
};
|
||||
|
||||
|
|
|
@ -3647,22 +3647,19 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
|||
goto err_exit;
|
||||
|
||||
/* Set up key map */
|
||||
hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (!hotkey_keycode_map) {
|
||||
pr_err("failed to allocate memory for key map\n");
|
||||
res = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,
|
||||
ARRAY_SIZE(tpacpi_keymap_qtable));
|
||||
BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps));
|
||||
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
|
||||
"using keymap number %lu\n", keymap_id);
|
||||
|
||||
memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id],
|
||||
TPACPI_HOTKEY_MAP_SIZE);
|
||||
hotkey_keycode_map = kmemdup(&tpacpi_keymaps[keymap_id],
|
||||
TPACPI_HOTKEY_MAP_SIZE, GFP_KERNEL);
|
||||
if (!hotkey_keycode_map) {
|
||||
pr_err("failed to allocate memory for key map\n");
|
||||
res = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
|
||||
tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
|
||||
|
@ -9714,6 +9711,107 @@ static struct ibm_struct battery_driver_data = {
|
|||
.exit = tpacpi_battery_exit,
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
* LCD Shadow subdriver, for the Lenovo PrivacyGuard feature
|
||||
*/
|
||||
|
||||
static int lcdshadow_state;
|
||||
|
||||
static int lcdshadow_on_off(bool state)
|
||||
{
|
||||
acpi_handle set_shadow_handle;
|
||||
int output;
|
||||
|
||||
if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "SSSS", &set_shadow_handle))) {
|
||||
pr_warn("Thinkpad ACPI has no %s interface.\n", "SSSS");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!acpi_evalf(set_shadow_handle, &output, NULL, "dd", (int)state))
|
||||
return -EIO;
|
||||
|
||||
lcdshadow_state = state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcdshadow_set(bool on)
|
||||
{
|
||||
if (lcdshadow_state < 0)
|
||||
return lcdshadow_state;
|
||||
if (lcdshadow_state == on)
|
||||
return 0;
|
||||
return lcdshadow_on_off(on);
|
||||
}
|
||||
|
||||
static int tpacpi_lcdshadow_init(struct ibm_init_struct *iibm)
|
||||
{
|
||||
acpi_handle get_shadow_handle;
|
||||
int output;
|
||||
|
||||
if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "GSSS", &get_shadow_handle))) {
|
||||
lcdshadow_state = -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!acpi_evalf(get_shadow_handle, &output, NULL, "dd", 0)) {
|
||||
lcdshadow_state = -EIO;
|
||||
return -EIO;
|
||||
}
|
||||
if (!(output & 0x10000)) {
|
||||
lcdshadow_state = -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
lcdshadow_state = output & 0x1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lcdshadow_resume(void)
|
||||
{
|
||||
if (lcdshadow_state >= 0)
|
||||
lcdshadow_on_off(lcdshadow_state);
|
||||
}
|
||||
|
||||
static int lcdshadow_read(struct seq_file *m)
|
||||
{
|
||||
if (lcdshadow_state < 0) {
|
||||
seq_puts(m, "status:\t\tnot supported\n");
|
||||
} else {
|
||||
seq_printf(m, "status:\t\t%d\n", lcdshadow_state);
|
||||
seq_puts(m, "commands:\t0, 1\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcdshadow_write(char *buf)
|
||||
{
|
||||
char *cmd;
|
||||
int state = -1;
|
||||
|
||||
if (lcdshadow_state < 0)
|
||||
return -ENODEV;
|
||||
|
||||
while ((cmd = next_cmd(&buf))) {
|
||||
if (strlencmp(cmd, "0") == 0)
|
||||
state = 0;
|
||||
else if (strlencmp(cmd, "1") == 0)
|
||||
state = 1;
|
||||
}
|
||||
|
||||
if (state == -1)
|
||||
return -EINVAL;
|
||||
|
||||
return lcdshadow_set(state);
|
||||
}
|
||||
|
||||
static struct ibm_struct lcdshadow_driver_data = {
|
||||
.name = "lcdshadow",
|
||||
.resume = lcdshadow_resume,
|
||||
.read = lcdshadow_read,
|
||||
.write = lcdshadow_write,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************
|
||||
*
|
||||
|
@ -10195,6 +10293,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {
|
|||
.init = tpacpi_battery_init,
|
||||
.data = &battery_driver_data,
|
||||
},
|
||||
{
|
||||
.init = tpacpi_lcdshadow_init,
|
||||
.data = &lcdshadow_driver_data,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init set_ibm_param(const char *val, const struct kernel_param *kp)
|
||||
|
|
|
@ -136,6 +136,22 @@ static const struct ts_dmi_data chuwi_vi10_data = {
|
|||
.properties = chuwi_vi10_props,
|
||||
};
|
||||
|
||||
static const struct property_entry chuwi_surbook_mini_props[] = {
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-x", 88),
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-y", 13),
|
||||
PROPERTY_ENTRY_U32("touchscreen-size-x", 2040),
|
||||
PROPERTY_ENTRY_U32("touchscreen-size-y", 1524),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-surbook-mini.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct ts_dmi_data chuwi_surbook_mini_data = {
|
||||
.acpi_name = "MSSL1680:00",
|
||||
.properties = chuwi_surbook_mini_props,
|
||||
};
|
||||
|
||||
static const struct property_entry connect_tablet9_props[] = {
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-x", 9),
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-y", 10),
|
||||
|
@ -230,6 +246,24 @@ static const struct ts_dmi_data gp_electronic_t701_data = {
|
|||
.properties = gp_electronic_t701_props,
|
||||
};
|
||||
|
||||
static const struct property_entry irbis_tw90_props[] = {
|
||||
PROPERTY_ENTRY_U32("touchscreen-size-x", 1720),
|
||||
PROPERTY_ENTRY_U32("touchscreen-size-y", 1138),
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-x", 8),
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-y", 14),
|
||||
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
|
||||
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-irbis_tw90.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
PROPERTY_ENTRY_BOOL("silead,home-button"),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct ts_dmi_data irbis_tw90_data = {
|
||||
.acpi_name = "MSSL1680:00",
|
||||
.properties = irbis_tw90_props,
|
||||
};
|
||||
|
||||
static const struct property_entry itworks_tw891_props[] = {
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-y", 5),
|
||||
|
@ -646,6 +680,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "S165"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Chuwi Surbook Mini (CWI540) */
|
||||
.driver_data = (void *)&chuwi_surbook_mini_data,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "C3W6_AP108_4G"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Connect Tablet 9 */
|
||||
.driver_data = (void *)&connect_tablet9_data,
|
||||
|
@ -708,6 +750,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
|
|||
DMI_MATCH(DMI_BIOS_VERSION, "itWORKS.G.WI71C.JGBMRB"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Irbis TW90 */
|
||||
.driver_data = (void *)&irbis_tw90_data,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TW90"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* I.T.Works TW891 */
|
||||
.driver_data = (void *)&itworks_tw891_data,
|
||||
|
@ -883,6 +933,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C11"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Trekstor Primebook C11B (same touchscreen as the C11) */
|
||||
.driver_data = (void *)&trekstor_primebook_c11_data,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "PRIMEBOOK C11B"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Trekstor Primebook C13 */
|
||||
.driver_data = (void *)&trekstor_primebook_c13_data,
|
||||
|
|
|
@ -340,9 +340,7 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
|
|||
* expensive, but have no corresponding WCxx method. So we
|
||||
* should not fail if this happens.
|
||||
*/
|
||||
if (acpi_has_method(handle, wc_method))
|
||||
wc_status = acpi_execute_simple_method(handle,
|
||||
wc_method, 1);
|
||||
wc_status = acpi_execute_simple_method(handle, wc_method, 1);
|
||||
}
|
||||
|
||||
strcpy(method, "WQ");
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */
|
||||
#define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */
|
||||
#define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */
|
||||
#define ASUS_WMI_METHODID_AGFN 0x4E464741 /* FaN? */
|
||||
#define ASUS_WMI_METHODID_AGFN 0x4E464741 /* Atk Generic FuNction */
|
||||
#define ASUS_WMI_METHODID_SFUN 0x4E554653 /* FUNCtionalities */
|
||||
#define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */
|
||||
#define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */
|
||||
|
@ -72,7 +72,8 @@
|
|||
|
||||
/* Fan, Thermal */
|
||||
#define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011
|
||||
#define ASUS_WMI_DEVID_FAN_CTRL 0x00110012
|
||||
#define ASUS_WMI_DEVID_FAN_CTRL 0x00110012 /* deprecated */
|
||||
#define ASUS_WMI_DEVID_CPU_FAN_CTRL 0x00110013
|
||||
|
||||
/* Power */
|
||||
#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012
|
||||
|
@ -80,6 +81,9 @@
|
|||
/* Deep S3 / Resume on LID open */
|
||||
#define ASUS_WMI_DEVID_LID_RESUME 0x00120031
|
||||
|
||||
/* Maximum charging percentage */
|
||||
#define ASUS_WMI_DEVID_RSOC 0x00120057
|
||||
|
||||
/* DSTS masks */
|
||||
#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
|
||||
#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
|
||||
|
|
|
@ -304,7 +304,7 @@ static void set_cpu_present_cpu_mask(void)
|
|||
int get_cpu_count(int pkg_id, int die_id)
|
||||
{
|
||||
if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE)
|
||||
return cpu_cnt[pkg_id][die_id] + 1;
|
||||
return cpu_cnt[pkg_id][die_id];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -603,6 +603,10 @@ static int isst_fill_platform_info(void)
|
|||
|
||||
close(fd);
|
||||
|
||||
if (isst_platform_info.api_version > supported_api_ver) {
|
||||
printf("Incompatible API versions; Upgrade of tool is required\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1491,7 +1495,7 @@ static void usage(void)
|
|||
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("\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("\nFor additional help on each command for a feature, use --h|--help\n");
|
||||
|
@ -1514,7 +1518,6 @@ static void usage(void)
|
|||
printf("\tResult display uses a common format for each command:\n");
|
||||
printf("\tResults are formatted in text/JSON with\n");
|
||||
printf("\t\tPackage, Die, CPU, and command specific results.\n");
|
||||
printf("\t\t\tFor Set commands, status is 0 for success and rest for failures\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -1529,6 +1532,7 @@ static void cmdline(int argc, char **argv)
|
|||
{
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
int ret;
|
||||
|
||||
static struct option long_options[] = {
|
||||
{ "cpu", required_argument, 0, 'c' },
|
||||
|
@ -1590,13 +1594,14 @@ static void cmdline(int argc, char **argv)
|
|||
set_max_cpu_num();
|
||||
set_cpu_present_cpu_mask();
|
||||
set_cpu_target_cpu_mask();
|
||||
isst_fill_platform_info();
|
||||
if (isst_platform_info.api_version > supported_api_ver) {
|
||||
printf("Incompatible API versions; Upgrade of tool is required\n");
|
||||
exit(0);
|
||||
}
|
||||
ret = isst_fill_platform_info();
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
process_command(argc, argv);
|
||||
out:
|
||||
free_cpu_set(present_cpumask);
|
||||
free_cpu_set(target_cpumask);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
|
@ -188,8 +188,27 @@ int isst_get_get_trl(int cpu, int level, int avx_level, int *trl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int isst_get_trl_bucket_info(int cpu, unsigned long long *buckets_info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
debug_printf("cpu:%d bucket info via MSR\n", cpu);
|
||||
|
||||
*buckets_info = 0;
|
||||
|
||||
ret = isst_send_msr_command(cpu, 0x1ae, 0, buckets_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", cpu,
|
||||
*buckets_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isst_set_tdp_level_msr(int cpu, int tdp_level)
|
||||
{
|
||||
unsigned long long level = tdp_level;
|
||||
int ret;
|
||||
|
||||
debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level);
|
||||
|
@ -202,8 +221,7 @@ int isst_set_tdp_level_msr(int cpu, int tdp_level)
|
|||
if (tdp_level > 2)
|
||||
return -1; /* invalid value */
|
||||
|
||||
ret = isst_send_msr_command(cpu, 0x64b, 1,
|
||||
(unsigned long long *)&tdp_level);
|
||||
ret = isst_send_msr_command(cpu, 0x64b, 1, &level);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -563,6 +581,10 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = isst_get_get_trl(cpu, i, 0,
|
||||
ctdp_level->trl_sse_active_cores);
|
||||
if (ret)
|
||||
|
|
|
@ -6,7 +6,34 @@
|
|||
|
||||
#include "isst.h"
|
||||
|
||||
#define DISP_FREQ_MULTIPLIER 100000
|
||||
#define DISP_FREQ_MULTIPLIER 100
|
||||
|
||||
static void printcpulist(int str_len, char *str, int mask_size,
|
||||
cpu_set_t *cpu_mask)
|
||||
{
|
||||
int i, first, curr_index, index;
|
||||
|
||||
if (!CPU_COUNT_S(mask_size, cpu_mask)) {
|
||||
snprintf(str, str_len, "none");
|
||||
return;
|
||||
}
|
||||
|
||||
curr_index = 0;
|
||||
first = 1;
|
||||
for (i = 0; i < get_topo_max_cpus(); ++i) {
|
||||
if (!CPU_ISSET_S(i, mask_size, cpu_mask))
|
||||
continue;
|
||||
if (!first) {
|
||||
index = snprintf(&str[curr_index],
|
||||
str_len - curr_index, ",");
|
||||
curr_index += index;
|
||||
}
|
||||
index = snprintf(&str[curr_index], str_len - curr_index, "%d",
|
||||
i);
|
||||
curr_index += index;
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void printcpumask(int str_len, char *str, int mask_size,
|
||||
cpu_set_t *cpu_mask)
|
||||
|
@ -133,7 +160,7 @@ static void format_and_print(FILE *outf, int level, char *header, char *value)
|
|||
last_level = level;
|
||||
}
|
||||
|
||||
static void print_packag_info(int cpu, FILE *outf)
|
||||
static void print_package_info(int cpu, FILE *outf)
|
||||
{
|
||||
char header[256];
|
||||
|
||||
|
@ -156,7 +183,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
|
|||
snprintf(header, sizeof(header), "speed-select-base-freq");
|
||||
format_and_print(outf, disp_level, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "high-priority-base-frequency(KHz)");
|
||||
snprintf(header, sizeof(header), "high-priority-base-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
pbf_info->p1_high * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, disp_level + 1, header, value);
|
||||
|
@ -166,7 +193,13 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
|
|||
pbf_info->core_cpumask);
|
||||
format_and_print(outf, disp_level + 1, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "low-priority-base-frequency(KHz)");
|
||||
snprintf(header, sizeof(header), "high-priority-cpu-list");
|
||||
printcpulist(sizeof(value), value,
|
||||
pbf_info->core_cpumask_size,
|
||||
pbf_info->core_cpumask);
|
||||
format_and_print(outf, disp_level + 1, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "low-priority-base-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
pbf_info->p1_low * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, disp_level + 1, header, value);
|
||||
|
@ -209,7 +242,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
|
|||
|
||||
if (fact_avx & 0x01) {
|
||||
snprintf(header, sizeof(header),
|
||||
"high-priority-max-frequency(KHz)");
|
||||
"high-priority-max-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 2, header, value);
|
||||
|
@ -217,7 +250,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
|
|||
|
||||
if (fact_avx & 0x02) {
|
||||
snprintf(header, sizeof(header),
|
||||
"high-priority-max-avx2-frequency(KHz)");
|
||||
"high-priority-max-avx2-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 2, header, value);
|
||||
|
@ -225,7 +258,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
|
|||
|
||||
if (fact_avx & 0x04) {
|
||||
snprintf(header, sizeof(header),
|
||||
"high-priority-max-avx512-frequency(KHz)");
|
||||
"high-priority-max-avx512-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
bucket_info[j].avx512_trl *
|
||||
DISP_FREQ_MULTIPLIER);
|
||||
|
@ -235,19 +268,19 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
|
|||
snprintf(header, sizeof(header),
|
||||
"speed-select-turbo-freq-clip-frequencies");
|
||||
format_and_print(outf, base_level + 1, header, NULL);
|
||||
snprintf(header, sizeof(header), "low-priority-max-frequency(KHz)");
|
||||
snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
fact_info->lp_clipping_ratio_license_sse *
|
||||
DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 2, header, value);
|
||||
snprintf(header, sizeof(header),
|
||||
"low-priority-max-avx2-frequency(KHz)");
|
||||
"low-priority-max-avx2-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
fact_info->lp_clipping_ratio_license_avx2 *
|
||||
DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 2, header, value);
|
||||
snprintf(header, sizeof(header),
|
||||
"low-priority-max-avx512-frequency(KHz)");
|
||||
"low-priority-max-avx512-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
fact_info->lp_clipping_ratio_license_avx512 *
|
||||
DISP_FREQ_MULTIPLIER);
|
||||
|
@ -261,7 +294,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
|||
char value[256];
|
||||
int i, base_level = 1;
|
||||
|
||||
print_packag_info(cpu, outf);
|
||||
print_package_info(cpu, outf);
|
||||
|
||||
for (i = 0; i <= pkg_dev->levels; ++i) {
|
||||
struct isst_pkg_ctdp_level_info *ctdp_level;
|
||||
|
@ -287,33 +320,41 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
|||
ctdp_level->core_cpumask);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "enable-cpu-list");
|
||||
printcpulist(sizeof(value), value,
|
||||
ctdp_level->core_cpumask_size,
|
||||
ctdp_level->core_cpumask);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "thermal-design-power-ratio");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "base-frequency(KHz)");
|
||||
snprintf(header, sizeof(header), "base-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header),
|
||||
"speed-select-turbo-freq-support");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->fact_support);
|
||||
"speed-select-turbo-freq");
|
||||
if (ctdp_level->fact_support) {
|
||||
if (ctdp_level->fact_enabled)
|
||||
snprintf(value, sizeof(value), "enabled");
|
||||
else
|
||||
snprintf(value, sizeof(value), "disabled");
|
||||
} else
|
||||
snprintf(value, sizeof(value), "unsupported");
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header),
|
||||
"speed-select-base-freq-support");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->pbf_support);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header),
|
||||
"speed-select-base-freq-enabled");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->pbf_enabled);
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header),
|
||||
"speed-select-turbo-freq-enabled");
|
||||
snprintf(value, sizeof(value), "%d", ctdp_level->fact_enabled);
|
||||
"speed-select-base-freq");
|
||||
if (ctdp_level->pbf_support) {
|
||||
if (ctdp_level->pbf_enabled)
|
||||
snprintf(value, sizeof(value), "enabled");
|
||||
else
|
||||
snprintf(value, sizeof(value), "disabled");
|
||||
} else
|
||||
snprintf(value, sizeof(value), "unsupported");
|
||||
format_and_print(outf, base_level + 4, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "thermal-design-power(W)");
|
||||
|
@ -331,12 +372,14 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
|||
format_and_print(outf, base_level + 5, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "core-count");
|
||||
snprintf(value, sizeof(value), "%d", j);
|
||||
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "turbo-ratio");
|
||||
snprintf(header, sizeof(header),
|
||||
"max-turbo-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->trl_sse_active_cores[j]);
|
||||
ctdp_level->trl_sse_active_cores[j] *
|
||||
DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
}
|
||||
snprintf(header, sizeof(header), "turbo-ratio-limits-avx");
|
||||
|
@ -346,12 +389,14 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
|||
format_and_print(outf, base_level + 5, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "core-count");
|
||||
snprintf(value, sizeof(value), "%d", j);
|
||||
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "turbo-ratio");
|
||||
snprintf(header, sizeof(header),
|
||||
"max-turbo-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->trl_avx_active_cores[j]);
|
||||
ctdp_level->trl_avx_active_cores[j] *
|
||||
DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
}
|
||||
|
||||
|
@ -362,12 +407,14 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
|
|||
format_and_print(outf, base_level + 5, header, NULL);
|
||||
|
||||
snprintf(header, sizeof(header), "core-count");
|
||||
snprintf(value, sizeof(value), "%d", j);
|
||||
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
|
||||
snprintf(header, sizeof(header), "turbo-ratio");
|
||||
snprintf(header, sizeof(header),
|
||||
"max-turbo-frequency(MHz)");
|
||||
snprintf(value, sizeof(value), "%d",
|
||||
ctdp_level->trl_avx_512_active_cores[j]);
|
||||
ctdp_level->trl_avx_512_active_cores[j] *
|
||||
DISP_FREQ_MULTIPLIER);
|
||||
format_and_print(outf, base_level + 6, header, value);
|
||||
}
|
||||
if (ctdp_level->pbf_support)
|
||||
|
@ -397,7 +444,7 @@ void isst_ctdp_display_information_end(FILE *outf)
|
|||
void isst_pbf_display_information(int cpu, FILE *outf, int level,
|
||||
struct isst_pbf_info *pbf_info)
|
||||
{
|
||||
print_packag_info(cpu, outf);
|
||||
print_package_info(cpu, outf);
|
||||
_isst_pbf_display_information(cpu, outf, level, pbf_info, 4);
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
}
|
||||
|
@ -406,7 +453,7 @@ void isst_fact_display_information(int cpu, FILE *outf, int level,
|
|||
int fact_bucket, int fact_avx,
|
||||
struct isst_fact_info *fact_info)
|
||||
{
|
||||
print_packag_info(cpu, outf);
|
||||
print_package_info(cpu, outf);
|
||||
_isst_fact_display_information(cpu, outf, level, fact_bucket, fact_avx,
|
||||
fact_info, 4);
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
|
@ -472,7 +519,10 @@ void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
|
|||
snprintf(header, sizeof(header), "%s", feature);
|
||||
format_and_print(outf, 4, header, NULL);
|
||||
snprintf(header, sizeof(header), "%s", cmd);
|
||||
snprintf(value, sizeof(value), "%d", result);
|
||||
if (!result)
|
||||
snprintf(value, sizeof(value), "success");
|
||||
else
|
||||
snprintf(value, sizeof(value), "failed(error %d)", result);
|
||||
format_and_print(outf, 5, header, value);
|
||||
|
||||
format_and_print(outf, 1, NULL, NULL);
|
||||
|
|
|
@ -134,6 +134,7 @@ struct isst_pkg_ctdp_level_info {
|
|||
size_t core_cpumask_size;
|
||||
cpu_set_t *core_cpumask;
|
||||
int cpu_count;
|
||||
unsigned long long buckets_info;
|
||||
int trl_sse_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
|
||||
int trl_avx_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
|
||||
int trl_avx_512_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
|
||||
|
|
Загрузка…
Ссылка в новой задаче