Commit ad062195 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 7ac63f6b f690790c
...@@ -49,6 +49,7 @@ detailed description): ...@@ -49,6 +49,7 @@ detailed description):
- Fan control and monitoring: fan speed, fan enable/disable - Fan control and monitoring: fan speed, fan enable/disable
- WAN enable and disable - WAN enable and disable
- UWB 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 A compatibility table by model and feature is maintained on the web
site, http://ibm-acpi.sf.net/. I appreciate any success or failure site, http://ibm-acpi.sf.net/. I appreciate any success or failure
...@@ -1409,6 +1410,28 @@ Sysfs notes ...@@ -1409,6 +1410,28 @@ Sysfs notes
Documentation/driver-api/rfkill.rst for details. 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 EXPERIMENTAL: UWB
----------------- -----------------
......
...@@ -17512,7 +17512,7 @@ M: Darren Hart <dvhart@infradead.org> ...@@ -17512,7 +17512,7 @@ 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 T: git git://git.infradead.org/linux-platform-drivers-x86.git
S: Maintained S: Odd Fixes
F: drivers/platform/x86/ F: drivers/platform/x86/
F: drivers/platform/olpc/ F: drivers/platform/olpc/
......
...@@ -642,11 +642,8 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev) ...@@ -642,11 +642,8 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev)
priv->irq = pdata->irq; priv->irq = pdata->irq;
} else { } else {
priv->irq = platform_get_irq(pdev, 0); priv->irq = platform_get_irq(pdev, 0);
if (priv->irq < 0) { if (priv->irq < 0)
dev_err(&pdev->dev, "Failed to get platform irq: %d\n",
priv->irq);
return priv->irq; return priv->irq;
}
} }
priv->regmap = pdata->regmap; priv->regmap = pdata->regmap;
......
...@@ -1881,52 +1881,17 @@ static int __init acer_wmi_enable_rf_button(void) ...@@ -1881,52 +1881,17 @@ static int __init acer_wmi_enable_rf_button(void)
return status; 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) static int __init acer_wmi_accel_setup(void)
{ {
struct acpi_device *adev;
int err; int err;
err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle); adev = acpi_dev_get_first_match_dev("BST0001", NULL, -1);
if (err) if (!adev)
return err; return -ENODEV;
gsensor_handle = acpi_device_handle(adev);
acpi_dev_put(adev);
interface->capability |= ACER_CAP_ACCEL; interface->capability |= ACER_CAP_ACCEL;
......
...@@ -402,6 +402,15 @@ static const struct dmi_system_id asus_quirks[] = { ...@@ -402,6 +402,15 @@ static const struct dmi_system_id asus_quirks[] = {
}, },
.driver_data = &quirk_asus_forceals, .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 @@ ...@@ -26,6 +26,7 @@
#include <linux/rfkill.h> #include <linux/rfkill.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci_hotplug.h> #include <linux/pci_hotplug.h>
#include <linux/power_supply.h>
#include <linux/hwmon.h> #include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
...@@ -35,6 +36,8 @@ ...@@ -35,6 +36,8 @@
#include <linux/thermal.h> #include <linux/thermal.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <acpi/battery.h>
#include <acpi/video.h> #include <acpi/video.h>
#include "asus-wmi.h" #include "asus-wmi.h"
...@@ -65,6 +68,9 @@ MODULE_LICENSE("GPL"); ...@@ -65,6 +68,9 @@ MODULE_LICENSE("GPL");
#define ASUS_FAN_MFUN 0x13 #define ASUS_FAN_MFUN 0x13
#define ASUS_FAN_SFUN_READ 0x06 #define ASUS_FAN_SFUN_READ 0x06
#define ASUS_FAN_SFUN_WRITE 0x07 #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_MANUAL 1
#define ASUS_FAN_CTRL_AUTO 2 #define ASUS_FAN_CTRL_AUTO 2
...@@ -120,7 +126,7 @@ struct agfn_args { ...@@ -120,7 +126,7 @@ struct agfn_args {
} __packed; } __packed;
/* struct used for calling fan read and write methods */ /* struct used for calling fan read and write methods */
struct fan_args { struct agfn_fan_args {
struct agfn_args agfn; /* common fields */ struct agfn_args agfn; /* common fields */
u8 fan; /* fan number: 0: set auto mode 1: 1st fan */ u8 fan; /* fan number: 0: set auto mode 1: 1st fan */
u32 speed; /* read: RPM/100 - write: 0-255 */ u32 speed; /* read: RPM/100 - write: 0-255 */
...@@ -148,6 +154,12 @@ struct asus_rfkill { ...@@ -148,6 +154,12 @@ struct asus_rfkill {
u32 dev_id; 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 { struct asus_wmi {
int dsts_id; int dsts_id;
int spec; int spec;
...@@ -178,14 +190,17 @@ struct asus_wmi { ...@@ -178,14 +190,17 @@ struct asus_wmi {
struct asus_rfkill gps; struct asus_rfkill gps;
struct asus_rfkill uwb; struct asus_rfkill uwb;
bool asus_hwmon_fan_manual_mode; enum fan_type fan_type;
int asus_hwmon_num_fans; int fan_pwm_mode;
int asus_hwmon_pwm; int agfn_pwm;
bool fan_boost_mode_available; bool fan_boost_mode_available;
u8 fan_boost_mode_mask; u8 fan_boost_mode_mask;
u8 fan_boost_mode; u8 fan_boost_mode;
// The RSOC controls the maximum charging percentage.
bool battery_rsoc_available;
struct hotplug_slot hotplug_slot; struct hotplug_slot hotplug_slot;
struct mutex hotplug_lock; struct mutex hotplug_lock;
struct mutex wmi_lock; struct mutex wmi_lock;
...@@ -292,12 +307,11 @@ static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args) ...@@ -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 * Copy to dma capable address otherwise memory corruption occurs as
* bios has to be able to access it. * 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; input.length = args.length;
if (!input.pointer) if (!input.pointer)
return -ENOMEM; return -ENOMEM;
phys_addr = virt_to_phys(input.pointer); phys_addr = virt_to_phys(input.pointer);
memcpy(input.pointer, args.pointer, args.length);
status = asus_wmi_evaluate_method(ASUS_WMI_METHODID_AGFN, status = asus_wmi_evaluate_method(ASUS_WMI_METHODID_AGFN,
phys_addr, 0, &retval); phys_addr, 0, &retval);
...@@ -331,7 +345,6 @@ static int asus_wmi_get_devstate_bits(struct asus_wmi *asus, ...@@ -331,7 +345,6 @@ static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
int err; int err;
err = asus_wmi_get_devstate(asus, dev_id, &retval); err = asus_wmi_get_devstate(asus, dev_id, &retval);
if (err < 0) if (err < 0)
return err; return err;
...@@ -352,6 +365,105 @@ static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id) ...@@ -352,6 +365,105 @@ static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id)
ASUS_WMI_DSTS_STATUS_BIT); 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 ***********************************************************************/ /* LEDs ***********************************************************************/
/* /*
...@@ -427,15 +539,14 @@ static int kbd_led_read(struct asus_wmi *asus, int *level, int *env) ...@@ -427,15 +539,14 @@ static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
if (retval == 0x8000) if (retval == 0x8000)
retval = 0; retval = 0;
if (retval >= 0) { if (retval < 0)
if (level) return retval;
*level = retval & 0x7F;
if (env)
*env = (retval >> 8) & 0x7F;
retval = 0;
}
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) 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) ...@@ -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); asus = container_of(led_cdev, struct asus_wmi, kbd_led);
max_level = asus->kbd_led.max_brightness; max_level = asus->kbd_led.max_brightness;
if (value > max_level) asus->kbd_led_wk = clamp_val(value, 0, max_level);
value = max_level;
else if (value < 0)
value = 0;
asus->kbd_led_wk = value;
kbd_led_update(asus); kbd_led_update(asus);
} }
...@@ -481,7 +587,6 @@ static enum led_brightness kbd_led_get(struct led_classdev *led_cdev) ...@@ -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); asus = container_of(led_cdev, struct asus_wmi, kbd_led);
retval = kbd_led_read(asus, &value, NULL); retval = kbd_led_read(asus, &value, NULL);
if (retval < 0) if (retval < 0)
return retval; return retval;
...@@ -497,15 +602,6 @@ static int wlan_led_unknown_state(struct asus_wmi *asus) ...@@ -497,15 +602,6 @@ static int wlan_led_unknown_state(struct asus_wmi *asus)
return result & ASUS_WMI_DSTS_UNKNOWN_BIT; 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) static void wlan_led_update(struct work_struct *work)
{ {
int ctrl_param; int ctrl_param;
...@@ -572,15 +668,6 @@ static enum led_brightness lightbar_led_get(struct led_classdev *led_cdev) ...@@ -572,15 +668,6 @@ static enum led_brightness lightbar_led_get(struct led_classdev *led_cdev)
return result & ASUS_WMI_DSTS_LIGHTBAR_MASK; 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) static void asus_wmi_led_exit(struct asus_wmi *asus)
{ {
if (!IS_ERR_OR_NULL(asus->kbd_led.dev)) if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
...@@ -631,7 +718,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus) ...@@ -631,7 +718,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
goto error; 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); INIT_WORK(&asus->wlan_led_work, wlan_led_update);
asus->wlan_led.name = "asus::wlan"; asus->wlan_led.name = "asus::wlan";
...@@ -648,7 +736,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus) ...@@ -648,7 +736,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
goto error; 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); INIT_WORK(&asus->lightbar_led_work, lightbar_led_update);
asus->lightbar_led.name = "asus::lightbar"; asus->lightbar_led.name = "asus::lightbar";
...@@ -771,16 +859,14 @@ static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node) ...@@ -771,16 +859,14 @@ static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node)
acpi_handle handle; acpi_handle handle;
status = acpi_get_handle(NULL, node, &handle); status = acpi_get_handle(NULL, node, &handle);
if (ACPI_FAILURE(status))
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
return -ENODEV; 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; return 0;
} }
...@@ -790,15 +876,13 @@ static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node) ...@@ -790,15 +876,13 @@ static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
acpi_handle handle; acpi_handle handle;
status = acpi_get_handle(NULL, node, &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,
status = acpi_remove_notify_handler(handle, asus_rfkill_notify);
ACPI_SYSTEM_NOTIFY, if (ACPI_FAILURE(status))
asus_rfkill_notify); pr_err("Error removing rfkill notify handler %s\n", node);
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, static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
...@@ -1126,10 +1210,10 @@ static void asus_wmi_set_als(void) ...@@ -1126,10 +1210,10 @@ static void asus_wmi_set_als(void)
/* Hwmon device ***************************************************************/ /* 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) int *speed)
{ {
struct fan_args args = { struct agfn_fan_args args = {
.agfn.len = sizeof(args), .agfn.len = sizeof(args),
.agfn.mfun = ASUS_FAN_MFUN, .agfn.mfun = ASUS_FAN_MFUN,
.agfn.sfun = ASUS_FAN_SFUN_READ, .agfn.sfun = ASUS_FAN_SFUN_READ,
...@@ -1153,10 +1237,10 @@ static int asus_hwmon_agfn_fan_speed_read(struct asus_wmi *asus, int fan, ...@@ -1153,10 +1237,10 @@ static int asus_hwmon_agfn_fan_speed_read(struct asus_wmi *asus, int fan,
return 0; 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) int *speed)
{ {
struct fan_args args = { struct agfn_fan_args args = {
.agfn.len = sizeof(args), .agfn.len = sizeof(args),
.agfn.mfun = ASUS_FAN_MFUN, .agfn.mfun = ASUS_FAN_MFUN,
.agfn.sfun = ASUS_FAN_SFUN_WRITE, .agfn.sfun = ASUS_FAN_SFUN_WRITE,
...@@ -1176,7 +1260,7 @@ static int asus_hwmon_agfn_fan_speed_write(struct asus_wmi *asus, int fan, ...@@ -1176,7 +1260,7 @@ static int asus_hwmon_agfn_fan_speed_write(struct asus_wmi *asus, int fan,
return -ENXIO; return -ENXIO;
if (speed && fan == 1) if (speed && fan == 1)
asus->asus_hwmon_pwm = *speed; asus->agfn_pwm = *speed;
return 0; return 0;
} }
...@@ -1185,77 +1269,60 @@ static int asus_hwmon_agfn_fan_speed_write(struct asus_wmi *asus, int fan, ...@@ -1185,77 +1269,60 @@ 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 * Check if we can read the speed of one fan. If true we assume we can also
* control it. * 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 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); status = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
if (!status) if (status != 0)
*num_fans = 1; 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; int status;
u32 retval;
status = asus_hwmon_agfn_fan_speed_write(asus, 0, NULL); switch (asus->fan_type) {
if (status) case FAN_TYPE_SPEC83:
return -ENXIO; status = asus_wmi_set_devstate(ASUS_WMI_DEVID_CPU_FAN_CTRL,
0, &retval);
asus->asus_hwmon_fan_manual_mode = false; if (status)
return status;
return 0;
}
static int asus_hwmon_fan_rpm_show(struct device *dev, int fan) if (retval != 1)
{ return -EIO;
struct asus_wmi *asus = dev_get_drvdata(dev); break;
int value;
int ret;
/* no speed readable on manual mode */ case FAN_TYPE_AGFN:
if (asus->asus_hwmon_fan_manual_mode) status = asus_agfn_fan_speed_write(asus, 0, NULL);
return -ENXIO; if (status)
return -ENXIO;
break;
ret = asus_hwmon_agfn_fan_speed_read(asus, fan+1, &value); default:
if (ret) {
pr_warn("reading fan speed failed: %d\n", ret);
return -ENXIO; return -ENXIO;
} }
return value;
}
static void asus_hwmon_pwm_show(struct asus_wmi *asus, int fan, int *value) return 0;
{
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, static ssize_t pwm1_show(struct device *dev,
...@@ -1263,9 +1330,33 @@ static ssize_t pwm1_show(struct device *dev, ...@@ -1263,9 +1330,33 @@ static ssize_t pwm1_show(struct device *dev,
char *buf) char *buf)
{ {
struct asus_wmi *asus = dev_get_drvdata(dev); struct asus_wmi *asus = dev_get_drvdata(dev);
int err;
int value; 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); return sprintf(buf, "%d\n", value);
} }
...@@ -1279,17 +1370,16 @@ static ssize_t pwm1_store(struct device *dev, ...@@ -1279,17 +1370,16 @@ static ssize_t pwm1_store(struct device *dev,
int ret; int ret;
ret = kstrtouint(buf, 10, &value); ret = kstrtouint(buf, 10, &value);
if (ret) if (ret)
return ret; return ret;
value = clamp(value, 0, 255); 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) if (state)
pr_warn("Setting fan speed failed: %d\n", state); pr_warn("Setting fan speed failed: %d\n", state);
else else
asus->asus_hwmon_fan_manual_mode = true; asus->fan_pwm_mode = ASUS_FAN_CTRL_MANUAL;
return count; return count;
} }
...@@ -1298,10 +1388,37 @@ static ssize_t fan1_input_show(struct device *dev, ...@@ -1298,10 +1388,37 @@ static ssize_t fan1_input_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
int value = asus_hwmon_fan_rpm_show(dev, 0); struct asus_wmi *asus = dev_get_drvdata(dev);
int value;
int ret;
return sprintf(buf, "%d\n", value < 0 ? -1 : value*100); 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, static ssize_t pwm1_enable_show(struct device *dev,
...@@ -1310,10 +1427,16 @@ 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); struct asus_wmi *asus = dev_get_drvdata(dev);
if (asus->asus_hwmon_fan_manual_mode) /*
return sprintf(buf, "%d\n", ASUS_FAN_CTRL_MANUAL); * Just read back the cached pwm mode.
*
return sprintf(buf, "%d\n", ASUS_FAN_CTRL_AUTO); * 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, static ssize_t pwm1_enable_store(struct device *dev,
...@@ -1323,21 +1446,50 @@ 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); struct asus_wmi *asus = dev_get_drvdata(dev);
int status = 0; int status = 0;
int state; int state;
int value;
int ret; int ret;
u32 retval;
ret = kstrtouint(buf, 10, &state); ret = kstrtouint(buf, 10, &state);
if (ret) if (ret)
return ret; return ret;
if (state == ASUS_FAN_CTRL_MANUAL) if (asus->fan_type == FAN_TYPE_SPEC83) {
asus->asus_hwmon_fan_manual_mode = true; switch (state) { /* standard documented hwmon values */
else case ASUS_FAN_CTRL_FULLSPEED:
status = asus_hwmon_fan_set_auto(asus); value = 1;
break;
case ASUS_FAN_CTRL_AUTO:
value = 0;
break;
default:
return -EINVAL;
}
if (status) ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_CPU_FAN_CTRL,
return status; 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; return count;
} }
...@@ -1357,7 +1509,6 @@ static ssize_t asus_hwmon_temp1(struct device *dev, ...@@ -1357,7 +1509,6 @@ static ssize_t asus_hwmon_temp1(struct device *dev,
int err; int err;
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value); err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value);
if (err < 0) if (err < 0)
return err; return err;
...@@ -1390,59 +1541,33 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, ...@@ -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 device *dev = container_of(kobj, struct device, kobj);
struct asus_wmi *asus = dev_get_drvdata(dev->parent); struct asus_wmi *asus = dev_get_drvdata(dev->parent);
int dev_id = -1;
int fan_attr = -1;
u32 value = ASUS_WMI_UNSUPPORTED_METHOD; u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
bool ok = true;
if (attr == &dev_attr_pwm1.attr) if (attr == &dev_attr_pwm1.attr) {
dev_id = ASUS_WMI_DEVID_FAN_CTRL; if (asus->fan_type != FAN_TYPE_AGFN)
else if (attr == &dev_attr_temp1_input.attr) return 0;
dev_id = ASUS_WMI_DEVID_THERMAL_CTRL; } else if (attr == &dev_attr_fan1_input.attr
if (attr == &dev_attr_fan1_input.attr
|| attr == &dev_attr_fan1_label.attr || attr == &dev_attr_fan1_label.attr
|| attr == &dev_attr_pwm1.attr
|| attr == &dev_attr_pwm1_enable.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) {
if (dev_id != -1) { int err = asus_wmi_get_devstate(asus,
int err = asus_wmi_get_devstate(asus, dev_id, &value); ASUS_WMI_DEVID_THERMAL_CTRL,
&value);
if (err < 0 && fan_attr == -1) if (err < 0)
return 0; /* can't return negative here */ 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 * If the temperature value in deci-Kelvin is near the absolute
* zero temperature, something is clearly wrong * zero temperature, something is clearly wrong
*/ */
if (value == 0 || value == 1) if (value == 0 || value == 1)
ok = false; return 0;
} else if (fan_attr <= asus->asus_hwmon_num_fans && fan_attr != -1) {
ok = true;
} else {
ok = false;
} }
return ok ? attr->mode : 0; return attr->mode;
} }
static const struct attribute_group hwmon_attribute_group = { static const struct attribute_group hwmon_attribute_group = {
...@@ -1468,20 +1593,19 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus) ...@@ -1468,20 +1593,19 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus)
static int asus_wmi_fan_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; if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CPU_FAN_CTRL))
asus->asus_hwmon_num_fans = -1; asus->fan_type = FAN_TYPE_SPEC83;
asus->asus_hwmon_fan_manual_mode = false; 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 (asus->fan_type == FAN_TYPE_NONE)
if (status) { return -ENODEV;
asus->asus_hwmon_num_fans = 0;
pr_warn("Could not determine number of fans: %d\n", status);
return -ENXIO;
}
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; return 0;
} }
...@@ -1523,7 +1647,6 @@ static int fan_boost_mode_write(struct asus_wmi *asus) ...@@ -1523,7 +1647,6 @@ static int fan_boost_mode_write(struct asus_wmi *asus)
pr_info("Set fan boost mode: %u\n", value); pr_info("Set fan boost mode: %u\n", value);
err = asus_wmi_set_devstate(ASUS_WMI_DEVID_FAN_BOOST_MODE, value, err = asus_wmi_set_devstate(ASUS_WMI_DEVID_FAN_BOOST_MODE, value,
&retval); &retval);
if (err) { if (err) {
pr_warn("Failed to set fan boost mode: %d\n", err); pr_warn("Failed to set fan boost mode: %d\n", err);
return err; return err;
...@@ -1606,6 +1729,7 @@ static DEVICE_ATTR_RW(fan_boost_mode); ...@@ -1606,6 +1729,7 @@ static DEVICE_ATTR_RW(fan_boost_mode);
static int read_backlight_power(struct asus_wmi *asus) static int read_backlight_power(struct asus_wmi *asus)
{ {
int ret; int ret;
if (asus->driver->quirks->store_backlight_power) if (asus->driver->quirks->store_backlight_power)
ret = !asus->driver->panel_power; ret = !asus->driver->panel_power;
else else
...@@ -1624,7 +1748,6 @@ static int read_brightness_max(struct asus_wmi *asus) ...@@ -1624,7 +1748,6 @@ static int read_brightness_max(struct asus_wmi *asus)
int err; int err;
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval); err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
if (err < 0) if (err < 0)
return err; return err;
...@@ -1644,7 +1767,6 @@ static int read_brightness(struct backlight_device *bd) ...@@ -1644,7 +1767,6 @@ static int read_brightness(struct backlight_device *bd)
int err; int err;
err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval); err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
if (err < 0) if (err < 0)
return err; return err;
...@@ -1734,7 +1856,6 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus) ...@@ -1734,7 +1856,6 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus)
return max; return max;
power = read_backlight_power(asus); power = read_backlight_power(asus);
if (power == -ENODEV) if (power == -ENODEV)
power = FB_BLANK_UNBLANK; power = FB_BLANK_UNBLANK;
else if (power < 0) else if (power < 0)
...@@ -1900,7 +2021,6 @@ static void asus_wmi_notify(u32 value, void *context) ...@@ -1900,7 +2021,6 @@ static void asus_wmi_notify(u32 value, void *context)
for (i = 0; i < WMI_EVENT_QUEUE_SIZE + 1; i++) { for (i = 0; i < WMI_EVENT_QUEUE_SIZE + 1; i++) {
code = asus_wmi_get_event_code(value); code = asus_wmi_get_event_code(value);
if (code < 0) { if (code < 0) {
pr_warn("Failed to get notify code: %d\n", code); pr_warn("Failed to get notify code: %d\n", code);
return; return;
...@@ -1929,7 +2049,6 @@ static int asus_wmi_notify_queue_flush(struct asus_wmi *asus) ...@@ -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++) { for (i = 0; i < WMI_EVENT_QUEUE_SIZE + 1; i++) {
code = asus_wmi_get_event_code(WMI_EVENT_VALUE_ATK); code = asus_wmi_get_event_code(WMI_EVENT_VALUE_ATK);
if (code < 0) { if (code < 0) {
pr_warn("Failed to get event during flush: %d\n", code); pr_warn("Failed to get event during flush: %d\n", code);
return code; return code;
...@@ -1945,32 +2064,25 @@ static int asus_wmi_notify_queue_flush(struct asus_wmi *asus) ...@@ -1945,32 +2064,25 @@ static int asus_wmi_notify_queue_flush(struct asus_wmi *asus)
/* Sysfs **********************************************************************/ /* 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, static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
const char *buf, size_t count) const char *buf, size_t count)
{ {
u32 retval; u32 retval;
int rv, err, value; int err, value;
value = asus_wmi_get_devstate_simple(asus, devid); value = asus_wmi_get_devstate_simple(asus, devid);
if (value < 0) if (value < 0)
return value; return value;
rv = parse_arg(buf, count, &value); err = kstrtoint(buf, 0, &value);
err = asus_wmi_set_devstate(devid, value, &retval); if (err)
return err;
err = asus_wmi_set_devstate(devid, value, &retval);
if (err < 0) if (err < 0)
return err; return err;
return rv; return count;
} }
static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf) 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, ...@@ -2019,8 +2131,10 @@ static ssize_t cpufv_store(struct device *dev, struct device_attribute *attr,
{ {
int value, rv; int value, rv;
if (!count || sscanf(buf, "%i", &value) != 1) rv = kstrtoint(buf, 0, &value);
return -EINVAL; if (rv)
return rv;
if (value < 0 || value > 2) if (value < 0 || value > 2)
return -EINVAL; return -EINVAL;
...@@ -2181,7 +2295,6 @@ static int show_dsts(struct seq_file *m, void *data) ...@@ -2181,7 +2295,6 @@ static int show_dsts(struct seq_file *m, void *data)
u32 retval = -1; u32 retval = -1;
err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval); err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
if (err < 0) if (err < 0)
return err; return err;
...@@ -2198,7 +2311,6 @@ static int show_devs(struct seq_file *m, void *data) ...@@ -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, err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
&retval); &retval);
if (err < 0) if (err < 0)
return err; return err;
...@@ -2334,7 +2446,6 @@ static int asus_wmi_add(struct platform_device *pdev) ...@@ -2334,7 +2446,6 @@ static int asus_wmi_add(struct platform_device *pdev)
goto fail_input; goto fail_input;
err = asus_wmi_fan_init(asus); /* probably no problems on error */ err = asus_wmi_fan_init(asus); /* probably no problems on error */
asus_hwmon_fan_set_auto(asus);
err = asus_wmi_hwmon_init(asus); err = asus_wmi_hwmon_init(asus);
if (err) if (err)
...@@ -2392,6 +2503,8 @@ static int asus_wmi_add(struct platform_device *pdev) ...@@ -2392,6 +2503,8 @@ static int asus_wmi_add(struct platform_device *pdev)
goto fail_wmi_handler; goto fail_wmi_handler;
} }
asus_wmi_battery_init(asus);
asus_wmi_debugfs_init(asus); asus_wmi_debugfs_init(asus);
return 0; return 0;
...@@ -2426,7 +2539,8 @@ static int asus_wmi_remove(struct platform_device *device) ...@@ -2426,7 +2539,8 @@ static int asus_wmi_remove(struct platform_device *device)
asus_wmi_rfkill_exit(asus); asus_wmi_rfkill_exit(asus);
asus_wmi_debugfs_exit(asus); asus_wmi_debugfs_exit(asus);
asus_wmi_sysfs_exit(asus->platform_device); 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); kfree(asus);
return 0; return 0;
......
...@@ -226,7 +226,7 @@ static const unsigned char pwm_lookup_table[256] = { ...@@ -226,7 +226,7 @@ static const unsigned char pwm_lookup_table[256] = {
/* General access */ /* General access */
static u8 ec_read_u8(u8 addr) static u8 ec_read_u8(u8 addr)
{ {
u8 value; u8 value = 0;
ec_read(addr, &value); ec_read(addr, &value);
return value; return value;
} }
......
...@@ -311,11 +311,13 @@ static const struct key_entry dell_wmi_keymap_type_0011[] = { ...@@ -311,11 +311,13 @@ static const struct key_entry dell_wmi_keymap_type_0011[] = {
{ KE_IGNORE, 0xfff1, { KEY_RESERVED } }, { KE_IGNORE, 0xfff1, { KEY_RESERVED } },
/* Keyboard backlight level changed */ /* Keyboard backlight level changed */
{ KE_IGNORE, 0x01e1, { KEY_RESERVED } }, { KE_IGNORE, KBD_LED_OFF_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, 0x02ea, { KEY_RESERVED } }, { KE_IGNORE, KBD_LED_ON_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, 0x02eb, { KEY_RESERVED } }, { KE_IGNORE, KBD_LED_AUTO_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, 0x02ec, { KEY_RESERVED } }, { KE_IGNORE, KBD_LED_AUTO_25_TOKEN, { KEY_RESERVED } },
{ KE_IGNORE, 0x02f6, { 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) 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[] = { ...@@ -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("HPB64xx", "HP EliteBook 84", xy_swap),
AXIS_DMI_MATCH("HPB65xx", "HP ProBook 65", x_inverted), AXIS_DMI_MATCH("HPB65xx", "HP ProBook 65", x_inverted),
AXIS_DMI_MATCH("HPZBook15", "HP ZBook 15", 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), AXIS_DMI_MATCH("HPZBook17", "HP ZBook 17", xy_swap_yz_inverted),
{ NULL, } { NULL, }
/* Laptop models without axis info (yet): /* Laptop models without axis info (yet):
......
...@@ -81,9 +81,7 @@ static int i2c_multi_inst_probe(struct platform_device *pdev) ...@@ -81,9 +81,7 @@ static int i2c_multi_inst_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
return ret; return ret;
multi = devm_kmalloc(dev, multi = devm_kmalloc(dev, struct_size(multi, clients, ret), GFP_KERNEL);
offsetof(struct i2c_multi_inst_data, clients[ret]),
GFP_KERNEL);
if (!multi) if (!multi)
return -ENOMEM; return -ENOMEM;
......
...@@ -60,11 +60,8 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev) ...@@ -60,11 +60,8 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev)
wctmu->regmap = pmic->regmap; wctmu->regmap = pmic->regmap;
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0)
if (irq < 0) {
dev_err(&pdev->dev, "invalid irq %d\n", irq);
return irq; return irq;
}
regmap_irq_chip = pmic->irq_chip_data_tmu; regmap_irq_chip = pmic->irq_chip_data_tmu;
virq = regmap_irq_get_virq(regmap_irq_chip, irq); virq = regmap_irq_get_virq(regmap_irq_chip, irq);
......
...@@ -122,7 +122,7 @@ static irqreturn_t int0002_irq(int irq, void *data) ...@@ -122,7 +122,7 @@ static irqreturn_t int0002_irq(int irq, void *data)
generic_handle_irq(irq_find_mapping(chip->irq.domain, generic_handle_irq(irq_find_mapping(chip->irq.domain,
GPE0A_PME_B0_VIRT_GPIO_PIN)); GPE0A_PME_B0_VIRT_GPIO_PIN));
pm_system_wakeup(); pm_wakeup_hard_event(chip->parent);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -144,6 +144,7 @@ static struct irq_chip int0002_cht_irqchip = { ...@@ -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 * 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. * 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[] = { static const struct x86_cpu_id int0002_cpu_ids[] = {
...@@ -173,10 +174,8 @@ static int int0002_probe(struct platform_device *pdev) ...@@ -173,10 +174,8 @@ static int int0002_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0)
dev_err(dev, "Error getting IRQ: %d\n", irq);
return irq; return irq;
}
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip) if (!chip)
...@@ -221,6 +220,13 @@ static int int0002_probe(struct platform_device *pdev) ...@@ -221,6 +220,13 @@ static int int0002_probe(struct platform_device *pdev)
gpiochip_set_chained_irqchip(chip, irq_chip, irq, NULL); 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; return 0;
} }
...@@ -236,6 +242,7 @@ static struct platform_driver int0002_driver = { ...@@ -236,6 +242,7 @@ static struct platform_driver int0002_driver = {
.acpi_match_table = int0002_acpi_ids, .acpi_match_table = int0002_acpi_ids,
}, },
.probe = int0002_probe, .probe = int0002_probe,
.remove = int0002_remove,
}; };
module_platform_driver(int0002_driver); module_platform_driver(int0002_driver);
......
...@@ -878,10 +878,14 @@ static int pmc_core_probe(struct platform_device *pdev) ...@@ -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)) if (pmcdev->map == &spt_reg_map && !pci_dev_present(pmc_pci_ids))
pmcdev->map = &cnp_reg_map; 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; 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->base_addr = slp_s0_addr - pmcdev->map->slp_s0_offset;
}
pmcdev->regbase = ioremap(pmcdev->base_addr, pmcdev->regbase = ioremap(pmcdev->base_addr,
pmcdev->map->regmap_length); pmcdev->map->regmap_length);
......
...@@ -18,8 +18,16 @@ ...@@ -18,8 +18,16 @@
#include <asm/cpu_device_id.h> #include <asm/cpu_device_id.h>
#include <asm/intel-family.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 = { static struct platform_device pmc_core_device = {
.name = "intel_pmc_core", .name = "intel_pmc_core",
.dev = {
.release = intel_pmc_core_release,
},
}; };
/* /*
......
...@@ -936,10 +936,8 @@ static int ipc_plat_probe(struct platform_device *pdev) ...@@ -936,10 +936,8 @@ static int ipc_plat_probe(struct platform_device *pdev)
spin_lock_init(&ipcdev.gcr_lock); spin_lock_init(&ipcdev.gcr_lock);
ipcdev.irq = platform_get_irq(pdev, 0); ipcdev.irq = platform_get_irq(pdev, 0);
if (ipcdev.irq < 0) { if (ipcdev.irq < 0)
dev_err(&pdev->dev, "Failed to get irq\n");
return -EINVAL; return -EINVAL;
}
ret = ipc_plat_get_res(pdev); ret = ipc_plat_get_res(pdev);
if (ret) { if (ret) {
......
...@@ -29,6 +29,8 @@ static struct isst_if_cmd_cb punit_callbacks[ISST_IF_DEV_MAX]; ...@@ -29,6 +29,8 @@ static struct isst_if_cmd_cb punit_callbacks[ISST_IF_DEV_MAX];
static int punit_msr_white_list[] = { static int punit_msr_white_list[] = {
MSR_TURBO_RATIO_LIMIT, MSR_TURBO_RATIO_LIMIT,
MSR_CONFIG_TDP_CONTROL, MSR_CONFIG_TDP_CONTROL,
MSR_TURBO_RATIO_LIMIT1,
MSR_TURBO_RATIO_LIMIT2,
}; };
struct isst_valid_cmd_ranges { struct isst_valid_cmd_ranges {
......
...@@ -132,11 +132,9 @@ static void isst_if_remove(struct pci_dev *pdev) ...@@ -132,11 +132,9 @@ static void isst_if_remove(struct pci_dev *pdev)
static int __maybe_unused isst_if_suspend(struct device *device) static int __maybe_unused isst_if_suspend(struct device *device)
{ {
struct pci_dev *pdev = to_pci_dev(device); struct isst_if_device *punit_dev = dev_get_drvdata(device);
struct isst_if_device *punit_dev;
int i; int i;
punit_dev = pci_get_drvdata(pdev);
for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i) for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
punit_dev->range_0[i] = readl(punit_dev->punit_mmio + punit_dev->range_0[i] = readl(punit_dev->punit_mmio +
mmio_range[0].beg + 4 * i); mmio_range[0].beg + 4 * i);
...@@ -149,11 +147,9 @@ static int __maybe_unused isst_if_suspend(struct device *device) ...@@ -149,11 +147,9 @@ static int __maybe_unused isst_if_suspend(struct device *device)
static int __maybe_unused isst_if_resume(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 = dev_get_drvdata(device);
struct isst_if_device *punit_dev;
int i; int i;
punit_dev = pci_get_drvdata(pdev);
for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i) for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
writel(punit_dev->range_0[i], punit_dev->punit_mmio + writel(punit_dev->range_0[i], punit_dev->punit_mmio +
mmio_range[0].beg + 4 * i); mmio_range[0].beg + 4 * i);
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#define APU2_GPIO_REG_LED3 AMD_FCH_GPIO_REG_GPIO59_DEVSLP1 #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_MODESW AMD_FCH_GPIO_REG_GPIO32_GE1
#define APU2_GPIO_REG_SIMSWAP AMD_FCH_GPIO_REG_GPIO33_GE2 #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 */ /* order in which the gpio lines are defined in the register list */
#define APU2_GPIO_LINE_LED1 0 #define APU2_GPIO_LINE_LED1 0
...@@ -39,6 +41,8 @@ ...@@ -39,6 +41,8 @@
#define APU2_GPIO_LINE_LED3 2 #define APU2_GPIO_LINE_LED3 2
#define APU2_GPIO_LINE_MODESW 3 #define APU2_GPIO_LINE_MODESW 3
#define APU2_GPIO_LINE_SIMSWAP 4 #define APU2_GPIO_LINE_SIMSWAP 4
#define APU2_GPIO_LINE_MPCIE2 5
#define APU2_GPIO_LINE_MPCIE3 6
/* gpio device */ /* gpio device */
...@@ -48,6 +52,8 @@ static int apu2_gpio_regs[] = { ...@@ -48,6 +52,8 @@ static int apu2_gpio_regs[] = {
[APU2_GPIO_LINE_LED3] = APU2_GPIO_REG_LED3, [APU2_GPIO_LINE_LED3] = APU2_GPIO_REG_LED3,
[APU2_GPIO_LINE_MODESW] = APU2_GPIO_REG_MODESW, [APU2_GPIO_LINE_MODESW] = APU2_GPIO_REG_MODESW,
[APU2_GPIO_LINE_SIMSWAP] = APU2_GPIO_REG_SIMSWAP, [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[] = { static const char * const apu2_gpio_names[] = {
...@@ -56,6 +62,8 @@ 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_LED3] = "front-led3",
[APU2_GPIO_LINE_MODESW] = "front-button", [APU2_GPIO_LINE_MODESW] = "front-button",
[APU2_GPIO_LINE_SIMSWAP] = "simswap", [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 = { static const struct amd_fch_gpio_pdata board_apu2 = {
...@@ -69,7 +77,8 @@ 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[] = { static const struct gpio_led apu2_leds[] = {
{ .name = "apu:green:1" }, { .name = "apu:green:1" },
{ .name = "apu:green:2" }, { .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 = { static const struct gpio_led_platform_data apu2_leds_pdata = {
...@@ -86,6 +95,8 @@ static struct gpiod_lookup_table gpios_led_table = { ...@@ -86,6 +95,8 @@ static struct gpiod_lookup_table gpios_led_table = {
NULL, 1, GPIO_ACTIVE_LOW), NULL, 1, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_LINE_LED3, GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_LINE_LED3,
NULL, 2, GPIO_ACTIVE_LOW), 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[] = { ...@@ -415,6 +415,13 @@ static const struct dmi_system_id critclk_systems[] = {
DMI_MATCH(DMI_BOARD_NAME, "CB6363"), 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*/ } { /*sentinel*/ }
}; };
......
...@@ -3647,22 +3647,19 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) ...@@ -3647,22 +3647,19 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
goto err_exit; goto err_exit;
/* Set up key map */ /* 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, keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,
ARRAY_SIZE(tpacpi_keymap_qtable)); ARRAY_SIZE(tpacpi_keymap_qtable));
BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps)); BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps));
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using keymap number %lu\n", keymap_id); "using keymap number %lu\n", keymap_id);
memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id], hotkey_keycode_map = kmemdup(&tpacpi_keymaps[keymap_id],
TPACPI_HOTKEY_MAP_SIZE); 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); input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
...@@ -9714,6 +9711,107 @@ static struct ibm_struct battery_driver_data = { ...@@ -9714,6 +9711,107 @@ static struct ibm_struct battery_driver_data = {
.exit = tpacpi_battery_exit, .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 = { ...@@ -10195,6 +10293,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {
.init = tpacpi_battery_init, .init = tpacpi_battery_init,
.data = &battery_driver_data, .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) 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 = { ...@@ -136,6 +136,22 @@ static const struct ts_dmi_data chuwi_vi10_data = {
.properties = chuwi_vi10_props, .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[] = { static const struct property_entry connect_tablet9_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 9), PROPERTY_ENTRY_U32("touchscreen-min-x", 9),
PROPERTY_ENTRY_U32("touchscreen-min-y", 10), PROPERTY_ENTRY_U32("touchscreen-min-y", 10),
...@@ -230,6 +246,24 @@ static const struct ts_dmi_data gp_electronic_t701_data = { ...@@ -230,6 +246,24 @@ static const struct ts_dmi_data gp_electronic_t701_data = {
.properties = gp_electronic_t701_props, .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[] = { static const struct property_entry itworks_tw891_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 1), PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
PROPERTY_ENTRY_U32("touchscreen-min-y", 5), PROPERTY_ENTRY_U32("touchscreen-min-y", 5),
...@@ -646,6 +680,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = { ...@@ -646,6 +680,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "S165"), 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 */ /* Connect Tablet 9 */
.driver_data = (void *)&connect_tablet9_data, .driver_data = (void *)&connect_tablet9_data,
...@@ -708,6 +750,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = { ...@@ -708,6 +750,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_BIOS_VERSION, "itWORKS.G.WI71C.JGBMRB"), 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 */ /* I.T.Works TW891 */
.driver_data = (void *)&itworks_tw891_data, .driver_data = (void *)&itworks_tw891_data,
...@@ -883,6 +933,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = { ...@@ -883,6 +933,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C11"), 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 */ /* Trekstor Primebook C13 */
.driver_data = (void *)&trekstor_primebook_c13_data, .driver_data = (void *)&trekstor_primebook_c13_data,
......
...@@ -340,9 +340,7 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance, ...@@ -340,9 +340,7 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
* expensive, but have no corresponding WCxx method. So we * expensive, but have no corresponding WCxx method. So we
* should not fail if this happens. * 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"); strcpy(method, "WQ");
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */ #define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */
#define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */ #define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */
#define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */ #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_SFUN 0x4E554653 /* FUNCtionalities */
#define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */ #define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */
#define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */ #define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */
...@@ -72,7 +72,8 @@ ...@@ -72,7 +72,8 @@
/* Fan, Thermal */ /* Fan, Thermal */
#define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011 #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 */ /* Power */
#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012 #define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012
...@@ -80,6 +81,9 @@ ...@@ -80,6 +81,9 @@
/* Deep S3 / Resume on LID open */ /* Deep S3 / Resume on LID open */
#define ASUS_WMI_DEVID_LID_RESUME 0x00120031 #define ASUS_WMI_DEVID_LID_RESUME 0x00120031
/* Maximum charging percentage */
#define ASUS_WMI_DEVID_RSOC 0x00120057
/* DSTS masks */ /* DSTS masks */
#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001 #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002 #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
......
...@@ -304,7 +304,7 @@ static void set_cpu_present_cpu_mask(void) ...@@ -304,7 +304,7 @@ static void set_cpu_present_cpu_mask(void)
int get_cpu_count(int pkg_id, int die_id) int get_cpu_count(int pkg_id, int die_id)
{ {
if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE) 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; return 0;
} }
...@@ -603,6 +603,10 @@ static int isst_fill_platform_info(void) ...@@ -603,6 +603,10 @@ static int isst_fill_platform_info(void)
close(fd); 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; return 0;
} }
...@@ -1491,7 +1495,7 @@ static void usage(void) ...@@ -1491,7 +1495,7 @@ static void usage(void)
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"); 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");
printf("\nFor additional help on each command for a feature, use --h|--help\n"); printf("\nFor additional help on each command for a feature, use --h|--help\n");
...@@ -1514,7 +1518,6 @@ static void usage(void) ...@@ -1514,7 +1518,6 @@ static void usage(void)
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("\t\t\tFor Set commands, status is 0 for success and rest for failures\n");
exit(1); exit(1);
} }
...@@ -1529,6 +1532,7 @@ static void cmdline(int argc, char **argv) ...@@ -1529,6 +1532,7 @@ static void cmdline(int argc, char **argv)
{ {
int opt; int opt;
int option_index = 0; int option_index = 0;
int ret;
static struct option long_options[] = { static struct option long_options[] = {
{ "cpu", required_argument, 0, 'c' }, { "cpu", required_argument, 0, 'c' },
...@@ -1590,13 +1594,14 @@ static void cmdline(int argc, char **argv) ...@@ -1590,13 +1594,14 @@ static void cmdline(int argc, char **argv)
set_max_cpu_num(); set_max_cpu_num();
set_cpu_present_cpu_mask(); set_cpu_present_cpu_mask();
set_cpu_target_cpu_mask(); set_cpu_target_cpu_mask();
isst_fill_platform_info(); ret = isst_fill_platform_info();
if (isst_platform_info.api_version > supported_api_ver) { if (ret)
printf("Incompatible API versions; Upgrade of tool is required\n"); goto out;
exit(0);
}
process_command(argc, argv); process_command(argc, argv);
out:
free_cpu_set(present_cpumask);
free_cpu_set(target_cpumask);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
......
...@@ -188,8 +188,27 @@ int isst_get_get_trl(int cpu, int level, int avx_level, int *trl) ...@@ -188,8 +188,27 @@ int isst_get_get_trl(int cpu, int level, int avx_level, int *trl)
return 0; 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) int isst_set_tdp_level_msr(int cpu, int tdp_level)
{ {
unsigned long long level = tdp_level;
int ret; int ret;
debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level); 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) ...@@ -202,8 +221,7 @@ int isst_set_tdp_level_msr(int cpu, int tdp_level)
if (tdp_level > 2) if (tdp_level > 2)
return -1; /* invalid value */ return -1; /* invalid value */
ret = isst_send_msr_command(cpu, 0x64b, 1, ret = isst_send_msr_command(cpu, 0x64b, 1, &level);
(unsigned long long *)&tdp_level);
if (ret) if (ret)
return ret; return ret;
...@@ -563,6 +581,10 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) ...@@ -563,6 +581,10 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
if (ret) if (ret)
return 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, ret = isst_get_get_trl(cpu, i, 0,
ctdp_level->trl_sse_active_cores); ctdp_level->trl_sse_active_cores);
if (ret) if (ret)
......
...@@ -6,7 +6,34 @@ ...@@ -6,7 +6,34 @@
#include "isst.h" #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, static void printcpumask(int str_len, char *str, int mask_size,
cpu_set_t *cpu_mask) cpu_set_t *cpu_mask)
...@@ -133,7 +160,7 @@ static void format_and_print(FILE *outf, int level, char *header, char *value) ...@@ -133,7 +160,7 @@ static void format_and_print(FILE *outf, int level, char *header, char *value)
last_level = level; last_level = level;
} }
static void print_packag_info(int cpu, FILE *outf) static void print_package_info(int cpu, FILE *outf)
{ {
char header[256]; char header[256];
...@@ -156,7 +183,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level, ...@@ -156,7 +183,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
snprintf(header, sizeof(header), "speed-select-base-freq"); snprintf(header, sizeof(header), "speed-select-base-freq");
format_and_print(outf, disp_level, header, NULL); 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", snprintf(value, sizeof(value), "%d",
pbf_info->p1_high * DISP_FREQ_MULTIPLIER); pbf_info->p1_high * DISP_FREQ_MULTIPLIER);
format_and_print(outf, disp_level + 1, header, value); 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, ...@@ -166,7 +193,13 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
pbf_info->core_cpumask); pbf_info->core_cpumask);
format_and_print(outf, disp_level + 1, header, value); 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", snprintf(value, sizeof(value), "%d",
pbf_info->p1_low * DISP_FREQ_MULTIPLIER); pbf_info->p1_low * DISP_FREQ_MULTIPLIER);
format_and_print(outf, disp_level + 1, header, value); 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, ...@@ -209,7 +242,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
if (fact_avx & 0x01) { if (fact_avx & 0x01) {
snprintf(header, sizeof(header), snprintf(header, sizeof(header),
"high-priority-max-frequency(KHz)"); "high-priority-max-frequency(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER); bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER);
format_and_print(outf, base_level + 2, header, value); 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, ...@@ -217,7 +250,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
if (fact_avx & 0x02) { if (fact_avx & 0x02) {
snprintf(header, sizeof(header), snprintf(header, sizeof(header),
"high-priority-max-avx2-frequency(KHz)"); "high-priority-max-avx2-frequency(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER); bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER);
format_and_print(outf, base_level + 2, header, value); 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, ...@@ -225,7 +258,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
if (fact_avx & 0x04) { if (fact_avx & 0x04) {
snprintf(header, sizeof(header), snprintf(header, sizeof(header),
"high-priority-max-avx512-frequency(KHz)"); "high-priority-max-avx512-frequency(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
bucket_info[j].avx512_trl * bucket_info[j].avx512_trl *
DISP_FREQ_MULTIPLIER); DISP_FREQ_MULTIPLIER);
...@@ -235,19 +268,19 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level, ...@@ -235,19 +268,19 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level,
snprintf(header, sizeof(header), snprintf(header, sizeof(header),
"speed-select-turbo-freq-clip-frequencies"); "speed-select-turbo-freq-clip-frequencies");
format_and_print(outf, base_level + 1, header, NULL); 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", snprintf(value, sizeof(value), "%d",
fact_info->lp_clipping_ratio_license_sse * fact_info->lp_clipping_ratio_license_sse *
DISP_FREQ_MULTIPLIER); DISP_FREQ_MULTIPLIER);
format_and_print(outf, base_level + 2, header, value); format_and_print(outf, base_level + 2, header, value);
snprintf(header, sizeof(header), snprintf(header, sizeof(header),
"low-priority-max-avx2-frequency(KHz)"); "low-priority-max-avx2-frequency(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
fact_info->lp_clipping_ratio_license_avx2 * fact_info->lp_clipping_ratio_license_avx2 *
DISP_FREQ_MULTIPLIER); DISP_FREQ_MULTIPLIER);
format_and_print(outf, base_level + 2, header, value); format_and_print(outf, base_level + 2, header, value);
snprintf(header, sizeof(header), snprintf(header, sizeof(header),
"low-priority-max-avx512-frequency(KHz)"); "low-priority-max-avx512-frequency(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
fact_info->lp_clipping_ratio_license_avx512 * fact_info->lp_clipping_ratio_license_avx512 *
DISP_FREQ_MULTIPLIER); DISP_FREQ_MULTIPLIER);
...@@ -261,7 +294,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, ...@@ -261,7 +294,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
char value[256]; char value[256];
int i, base_level = 1; int i, base_level = 1;
print_packag_info(cpu, outf); 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;
...@@ -287,33 +320,41 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, ...@@ -287,33 +320,41 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
ctdp_level->core_cpumask); ctdp_level->core_cpumask);
format_and_print(outf, base_level + 4, header, value); 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(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, base_level + 4, header, value);
snprintf(header, sizeof(header), "base-frequency(KHz)"); snprintf(header, sizeof(header), "base-frequency(MHz)");
snprintf(value, sizeof(value), "%d", snprintf(value, sizeof(value), "%d",
ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER); ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER);
format_and_print(outf, base_level + 4, header, value); format_and_print(outf, base_level + 4, header, value);
snprintf(header, sizeof(header), snprintf(header, sizeof(header),
"speed-select-turbo-freq-support"); "speed-select-turbo-freq");
snprintf(value, sizeof(value), "%d", ctdp_level->fact_support); 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); format_and_print(outf, base_level + 4, header, value);
snprintf(header, sizeof(header), snprintf(header, sizeof(header),
"speed-select-base-freq-support"); "speed-select-base-freq");
snprintf(value, sizeof(value), "%d", ctdp_level->pbf_support); if (ctdp_level->pbf_support) {
format_and_print(outf, base_level + 4, header, value); if (ctdp_level->pbf_enabled)
snprintf(value, sizeof(value), "enabled");
snprintf(header, sizeof(header), else
"speed-select-base-freq-enabled"); snprintf(value, sizeof(value), "disabled");
snprintf(value, sizeof(value), "%d", ctdp_level->pbf_enabled); } else
format_and_print(outf, base_level + 4, header, value); snprintf(value, sizeof(value), "unsupported");
snprintf(header, sizeof(header),
"speed-select-turbo-freq-enabled");
snprintf(value, sizeof(value), "%d", ctdp_level->fact_enabled);
format_and_print(outf, base_level + 4, header, value); format_and_print(outf, base_level + 4, header, value);
snprintf(header, sizeof(header), "thermal-design-power(W)"); snprintf(header, sizeof(header), "thermal-design-power(W)");
...@@ -331,12 +372,14 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, ...@@ -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); format_and_print(outf, base_level + 5, header, NULL);
snprintf(header, sizeof(header), "core-count"); 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); 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", 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); format_and_print(outf, base_level + 6, header, value);
} }
snprintf(header, sizeof(header), "turbo-ratio-limits-avx"); snprintf(header, sizeof(header), "turbo-ratio-limits-avx");
...@@ -346,12 +389,14 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, ...@@ -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); format_and_print(outf, base_level + 5, header, NULL);
snprintf(header, sizeof(header), "core-count"); 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); 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", 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); 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, ...@@ -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); format_and_print(outf, base_level + 5, header, NULL);
snprintf(header, sizeof(header), "core-count"); 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); 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", 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); format_and_print(outf, base_level + 6, header, value);
} }
if (ctdp_level->pbf_support) if (ctdp_level->pbf_support)
...@@ -397,7 +444,7 @@ void isst_ctdp_display_information_end(FILE *outf) ...@@ -397,7 +444,7 @@ void isst_ctdp_display_information_end(FILE *outf)
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_packag_info(cpu, outf); print_package_info(cpu, outf);
_isst_pbf_display_information(cpu, outf, level, pbf_info, 4); _isst_pbf_display_information(cpu, outf, level, pbf_info, 4);
format_and_print(outf, 1, NULL, NULL); format_and_print(outf, 1, NULL, NULL);
} }
...@@ -406,7 +453,7 @@ void isst_fact_display_information(int cpu, FILE *outf, int level, ...@@ -406,7 +453,7 @@ 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_packag_info(cpu, outf); 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, 4);
format_and_print(outf, 1, NULL, NULL); format_and_print(outf, 1, NULL, NULL);
...@@ -472,7 +519,10 @@ void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, ...@@ -472,7 +519,10 @@ void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
snprintf(header, sizeof(header), "%s", feature); snprintf(header, sizeof(header), "%s", feature);
format_and_print(outf, 4, header, NULL); format_and_print(outf, 4, header, NULL);
snprintf(header, sizeof(header), "%s", cmd); 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, 5, header, value);
format_and_print(outf, 1, NULL, NULL); format_and_print(outf, 1, NULL, NULL);
......
...@@ -134,6 +134,7 @@ struct isst_pkg_ctdp_level_info { ...@@ -134,6 +134,7 @@ struct isst_pkg_ctdp_level_info {
size_t core_cpumask_size; size_t core_cpumask_size;
cpu_set_t *core_cpumask; cpu_set_t *core_cpumask;
int cpu_count; int cpu_count;
unsigned long long buckets_info;
int trl_sse_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; int trl_sse_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
int trl_avx_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]; int trl_avx_512_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
......
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