platform-drivers-x86 for v4.14-1
Several fixes from static analysis and message noise reduction. Correct WMI core and related drivers to evaluate instance number 0x0 in accordance with the documentation. Add intel-telemetry support for Gemini Lake. Various individual driver fixes noted below. Two commits appear here which were previously merged during the 4.13 RC cycle: -baa5480b05
platform/x86: dell-wmi: Fix driver interface version query -c801603e6d
platform/x86: intel-vbtn: match power button on press rather than release dell-wmi: - Update dell_wmi_check_descriptor_buffer() to new model intel-vbtn: - reduce unnecessary messages for normal users - match power button on press rather than release intel-hid: - reduce unnecessary messages for normal users thinkpad_acpi: - Fix warning about deprecated hwmon_device_register wmi: - Fix check for method instance number ideapad-laptop: - Expose conservation mode switch intel_pmc_core: - Make the driver PCH family agnostic peaq-wmi: - Evaluate wmi method with instance number 0x0 - silence a static checker warning mxm-wmi: - Evaluate wmi method with instance number 0x0 asus-wmi: - Evaluate wmi method with instance number 0x0 intel_scu_ipc: - make intel_scu_ipc_pdata_t const intel_mid_powerbtn: - make mid_pb_ddata const - fix error return code in mid_pb_probe() hp-wmi: - Remove unused macro helper - Correctly determine method id in WMI calls dell-wmi: - Fix driver interface version query intel_telemetry: - remove redundant macro definition - Add GLK PSS Event Table alienware-wmi: - fix format string overflow warning ibm_rtl: - remove unnecessary static in ibm_rtl_write() msi-wmi: - remove unnecessary static in msi_wmi_notify() -----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJZsvdiAAoJEKbMaAwKp364V+UIAI27WP1MKQ6zKiXAt6TTLQww RGbeTrgxsHwxIp1ioo3MZtRa4uTMrJ/A/Es7nzZBSAAp8qPLOCaZYGtsH0tYkzcc zGLw+q5EBEjiMiq8WvkgD+NLq6icdsB0MUuuh06y34/LWiOwpp9wNemszHO9Vo2/ vc5PkgNmMx5K4zJvl6A3JAY98XlXxG65vYMrsIL17EFwZjuixrcCjDY86HKxEnNV tmfJ1Mhiu5HnDniCgRubdRBo4LwAeRdrXXkrsTZip+4RuXvm0gvxHujwgllIY4Ns m6xFXQApaGtXxd9vcSBHXE7whTgWrb7yPhUQzgt/Dd3E6ywF2THfn5jvwJUEflc= =LuAp -----END PGP SIGNATURE----- Merge tag 'platform-drivers-x86-v4.14-1' of git://git.infradead.org/linux-platform-drivers-x86 Pull x86 platform driver updates from Darren Hart: "Several fixes from static analysis and message noise reduction. Correct WMI core and related drivers to evaluate instance number 0x0 in accordance with the documentation. Add intel-telemetry support for Gemini Lake. Various individual driver fixes noted below. dell-wmi: - Update dell_wmi_check_descriptor_buffer() to new model intel-vbtn: - reduce unnecessary messages for normal users - match power button on press rather than release intel-hid: - reduce unnecessary messages for normal users thinkpad_acpi: - Fix warning about deprecated hwmon_device_register wmi: - Fix check for method instance number ideapad-laptop: - Expose conservation mode switch intel_pmc_core: - Make the driver PCH family agnostic peaq-wmi: - Evaluate wmi method with instance number 0x0 - silence a static checker warning mxm-wmi: - Evaluate wmi method with instance number 0x0 asus-wmi: - Evaluate wmi method with instance number 0x0 intel_scu_ipc: - make intel_scu_ipc_pdata_t const intel_mid_powerbtn: - make mid_pb_ddata const - fix error return code in mid_pb_probe() hp-wmi: - Remove unused macro helper - Correctly determine method id in WMI calls dell-wmi: - Fix driver interface version query intel_telemetry: - remove redundant macro definition - Add GLK PSS Event Table alienware-wmi: - fix format string overflow warning ibm_rtl: - remove unnecessary static in ibm_rtl_write() msi-wmi: - remove unnecessary static in msi_wmi_notify()" * tag 'platform-drivers-x86-v4.14-1' of git://git.infradead.org/linux-platform-drivers-x86: (23 commits) platform/x86: dell-wmi: Update dell_wmi_check_descriptor_buffer() to new model platform/x86: intel-vbtn: reduce unnecessary messages for normal users platform/x86: intel-hid: reduce unnecessary messages for normal users platform/x86: thinkpad_acpi: Fix warning about deprecated hwmon_device_register platform/x86: wmi: Fix check for method instance number platform/x86: ideapad-laptop: Expose conservation mode switch platform/x86: intel_pmc_core: Make the driver PCH family agnostic platform/x86: peaq-wmi: Evaluate wmi method with instance number 0x0 platform/x86: mxm-wmi: Evaluate wmi method with instance number 0x0 platform/x86: asus-wmi: Evaluate wmi method with instance number 0x0 platform/x86: intel_scu_ipc: make intel_scu_ipc_pdata_t const platform/x86: intel_mid_powerbtn: make mid_pb_ddata const platform/x86: intel_mid_powerbtn: fix error return code in mid_pb_probe() platform/x86: hp-wmi: Remove unused macro helper platform/x86: hp-wmi: Correctly determine method id in WMI calls platform/x86: intel-vbtn: match power button on press rather than release platform/x86: dell-wmi: Fix driver interface version query platform/x86: intel_telemetry: remove redundant macro definition platform/x86: intel_telemetry: Add GLK PSS Event Table platform/x86: alienware-wmi: fix format string overflow warning ...
This commit is contained in:
Коммит
0e271fd59f
|
@ -121,8 +121,9 @@ space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/.
|
||||||
Sysfs device attributes for the sensors and fan are on the
|
Sysfs device attributes for the sensors and fan are on the
|
||||||
thinkpad_hwmon device's sysfs attribute space, but you should locate it
|
thinkpad_hwmon device's sysfs attribute space, but you should locate it
|
||||||
looking for a hwmon device with the name attribute of "thinkpad", or
|
looking for a hwmon device with the name attribute of "thinkpad", or
|
||||||
better yet, through libsensors.
|
better yet, through libsensors. For 4.14+ sysfs attributes were moved to the
|
||||||
|
hwmon device (/sys/bus/platform/devices/thinkpad_hwmon/hwmon/hwmon? or
|
||||||
|
/sys/class/hwmon/hwmon?).
|
||||||
|
|
||||||
Driver version
|
Driver version
|
||||||
--------------
|
--------------
|
||||||
|
@ -1478,3 +1479,7 @@ Sysfs interface changelog:
|
||||||
0x020700: Support for mute-only mixers.
|
0x020700: Support for mute-only mixers.
|
||||||
Volume control in read-only mode by default.
|
Volume control in read-only mode by default.
|
||||||
Marker for ALSA mixer support.
|
Marker for ALSA mixer support.
|
||||||
|
|
||||||
|
0x030000: Thermal and fan sysfs attributes were moved to the hwmon
|
||||||
|
device instead of being attached to the backing platform
|
||||||
|
device.
|
||||||
|
|
|
@ -255,12 +255,13 @@ static int parse_rgb(const char *buf, struct platform_zone *zone)
|
||||||
|
|
||||||
static struct platform_zone *match_zone(struct device_attribute *attr)
|
static struct platform_zone *match_zone(struct device_attribute *attr)
|
||||||
{
|
{
|
||||||
int i;
|
u8 zone;
|
||||||
for (i = 0; i < quirks->num_zones; i++) {
|
|
||||||
if ((struct device_attribute *)zone_data[i].attr == attr) {
|
for (zone = 0; zone < quirks->num_zones; zone++) {
|
||||||
|
if ((struct device_attribute *)zone_data[zone].attr == attr) {
|
||||||
pr_debug("alienware-wmi: matched zone location: %d\n",
|
pr_debug("alienware-wmi: matched zone location: %d\n",
|
||||||
zone_data[i].location);
|
zone_data[zone].location);
|
||||||
return &zone_data[i];
|
return &zone_data[zone];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -420,7 +421,7 @@ static DEVICE_ATTR(lighting_control_state, 0644, show_control_state,
|
||||||
|
|
||||||
static int alienware_zone_init(struct platform_device *dev)
|
static int alienware_zone_init(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
int i;
|
u8 zone;
|
||||||
char buffer[10];
|
char buffer[10];
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
@ -457,19 +458,19 @@ static int alienware_zone_init(struct platform_device *dev)
|
||||||
if (!zone_data)
|
if (!zone_data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < quirks->num_zones; i++) {
|
for (zone = 0; zone < quirks->num_zones; zone++) {
|
||||||
sprintf(buffer, "zone%02X", i);
|
sprintf(buffer, "zone%02hhX", zone);
|
||||||
name = kstrdup(buffer, GFP_KERNEL);
|
name = kstrdup(buffer, GFP_KERNEL);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
sysfs_attr_init(&zone_dev_attrs[i].attr);
|
sysfs_attr_init(&zone_dev_attrs[zone].attr);
|
||||||
zone_dev_attrs[i].attr.name = name;
|
zone_dev_attrs[zone].attr.name = name;
|
||||||
zone_dev_attrs[i].attr.mode = 0644;
|
zone_dev_attrs[zone].attr.mode = 0644;
|
||||||
zone_dev_attrs[i].show = zone_show;
|
zone_dev_attrs[zone].show = zone_show;
|
||||||
zone_dev_attrs[i].store = zone_set;
|
zone_dev_attrs[zone].store = zone_set;
|
||||||
zone_data[i].location = i;
|
zone_data[zone].location = zone;
|
||||||
zone_attrs[i] = &zone_dev_attrs[i].attr;
|
zone_attrs[zone] = &zone_dev_attrs[zone].attr;
|
||||||
zone_data[i].attr = &zone_dev_attrs[i];
|
zone_data[zone].attr = &zone_dev_attrs[zone];
|
||||||
}
|
}
|
||||||
zone_attrs[quirks->num_zones] = &dev_attr_lighting_control_state.attr;
|
zone_attrs[quirks->num_zones] = &dev_attr_lighting_control_state.attr;
|
||||||
zone_attribute_group.attrs = zone_attrs;
|
zone_attribute_group.attrs = zone_attrs;
|
||||||
|
@ -481,12 +482,13 @@ static int alienware_zone_init(struct platform_device *dev)
|
||||||
|
|
||||||
static void alienware_zone_exit(struct platform_device *dev)
|
static void alienware_zone_exit(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
|
u8 zone;
|
||||||
|
|
||||||
sysfs_remove_group(&dev->dev.kobj, &zone_attribute_group);
|
sysfs_remove_group(&dev->dev.kobj, &zone_attribute_group);
|
||||||
led_classdev_unregister(&global_led);
|
led_classdev_unregister(&global_led);
|
||||||
if (zone_dev_attrs) {
|
if (zone_dev_attrs) {
|
||||||
int i;
|
for (zone = 0; zone < quirks->num_zones; zone++)
|
||||||
for (i = 0; i < quirks->num_zones; i++)
|
kfree(zone_dev_attrs[zone].attr.name);
|
||||||
kfree(zone_dev_attrs[i].attr.name);
|
|
||||||
}
|
}
|
||||||
kfree(zone_dev_attrs);
|
kfree(zone_dev_attrs);
|
||||||
kfree(zone_data);
|
kfree(zone_data);
|
||||||
|
|
|
@ -299,7 +299,7 @@ static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
|
||||||
union acpi_object *obj;
|
union acpi_object *obj;
|
||||||
u32 tmp = 0;
|
u32 tmp = 0;
|
||||||
|
|
||||||
status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id,
|
status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
|
||||||
&input, &output);
|
&input, &output);
|
||||||
|
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
|
@ -1946,7 +1946,7 @@ static int show_call(struct seq_file *m, void *data)
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
|
||||||
status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
|
status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
|
||||||
1, asus->debug.method_id,
|
0, asus->debug.method_id,
|
||||||
&input, &output);
|
&input, &output);
|
||||||
|
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
|
|
|
@ -48,7 +48,6 @@ MODULE_LICENSE("GPL");
|
||||||
#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
|
#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
|
||||||
#define DELL_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492"
|
#define DELL_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492"
|
||||||
|
|
||||||
static u32 dell_wmi_interface_version;
|
|
||||||
static bool wmi_requires_smbios_request;
|
static bool wmi_requires_smbios_request;
|
||||||
|
|
||||||
MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
|
MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
|
||||||
|
@ -56,6 +55,7 @@ MODULE_ALIAS("wmi:"DELL_DESCRIPTOR_GUID);
|
||||||
|
|
||||||
struct dell_wmi_priv {
|
struct dell_wmi_priv {
|
||||||
struct input_dev *input_dev;
|
struct input_dev *input_dev;
|
||||||
|
u32 interface_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init dmi_matched(const struct dmi_system_id *dmi)
|
static int __init dmi_matched(const struct dmi_system_id *dmi)
|
||||||
|
@ -348,6 +348,7 @@ static void dell_wmi_process_key(struct wmi_device *wdev, int type, int code)
|
||||||
static void dell_wmi_notify(struct wmi_device *wdev,
|
static void dell_wmi_notify(struct wmi_device *wdev,
|
||||||
union acpi_object *obj)
|
union acpi_object *obj)
|
||||||
{
|
{
|
||||||
|
struct dell_wmi_priv *priv = dev_get_drvdata(&wdev->dev);
|
||||||
u16 *buffer_entry, *buffer_end;
|
u16 *buffer_entry, *buffer_end;
|
||||||
acpi_size buffer_size;
|
acpi_size buffer_size;
|
||||||
int len, i;
|
int len, i;
|
||||||
|
@ -376,7 +377,7 @@ static void dell_wmi_notify(struct wmi_device *wdev,
|
||||||
* So to prevent reading garbage from buffer we will process only first
|
* So to prevent reading garbage from buffer we will process only first
|
||||||
* one event on devices with WMI interface version 0.
|
* one event on devices with WMI interface version 0.
|
||||||
*/
|
*/
|
||||||
if (dell_wmi_interface_version == 0 && buffer_entry < buffer_end)
|
if (priv->interface_version == 0 && buffer_entry < buffer_end)
|
||||||
if (buffer_end > buffer_entry + buffer_entry[0] + 1)
|
if (buffer_end > buffer_entry + buffer_entry[0] + 1)
|
||||||
buffer_end = buffer_entry + buffer_entry[0] + 1;
|
buffer_end = buffer_entry + buffer_entry[0] + 1;
|
||||||
|
|
||||||
|
@ -626,61 +627,67 @@ static void dell_wmi_input_destroy(struct wmi_device *wdev)
|
||||||
* WMI Interface Version 8 4 <version>
|
* WMI Interface Version 8 4 <version>
|
||||||
* WMI buffer length 12 4 4096
|
* WMI buffer length 12 4 4096
|
||||||
*/
|
*/
|
||||||
static int dell_wmi_check_descriptor_buffer(void)
|
static int dell_wmi_check_descriptor_buffer(struct wmi_device *wdev)
|
||||||
{
|
{
|
||||||
struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
|
struct dell_wmi_priv *priv = dev_get_drvdata(&wdev->dev);
|
||||||
union acpi_object *obj;
|
union acpi_object *obj = NULL;
|
||||||
acpi_status status;
|
struct wmi_device *desc_dev;
|
||||||
u32 *buffer;
|
u32 *buffer;
|
||||||
|
int ret;
|
||||||
|
|
||||||
status = wmi_query_block(DELL_DESCRIPTOR_GUID, 0, &out);
|
desc_dev = wmidev_get_other_guid(wdev, DELL_DESCRIPTOR_GUID);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (!desc_dev) {
|
||||||
pr_err("Cannot read Dell descriptor buffer - %d\n", status);
|
dev_err(&wdev->dev, "Dell WMI descriptor does not exist\n");
|
||||||
return status;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = (union acpi_object *)out.pointer;
|
obj = wmidev_block_query(desc_dev, 0);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
pr_err("Dell descriptor buffer is empty\n");
|
dev_err(&wdev->dev, "failed to read Dell WMI descriptor\n");
|
||||||
return -EINVAL;
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->type != ACPI_TYPE_BUFFER) {
|
if (obj->type != ACPI_TYPE_BUFFER) {
|
||||||
pr_err("Cannot read Dell descriptor buffer\n");
|
dev_err(&wdev->dev, "Dell descriptor has wrong type\n");
|
||||||
kfree(obj);
|
ret = -EINVAL;
|
||||||
return -EINVAL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->buffer.length != 128) {
|
if (obj->buffer.length != 128) {
|
||||||
pr_err("Dell descriptor buffer has invalid length (%d)\n",
|
dev_err(&wdev->dev,
|
||||||
|
"Dell descriptor buffer has invalid length (%d)\n",
|
||||||
obj->buffer.length);
|
obj->buffer.length);
|
||||||
if (obj->buffer.length < 16) {
|
if (obj->buffer.length < 16) {
|
||||||
kfree(obj);
|
ret = -EINVAL;
|
||||||
return -EINVAL;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = (u32 *)obj->buffer.pointer;
|
buffer = (u32 *)obj->buffer.pointer;
|
||||||
|
|
||||||
if (buffer[0] != 0x4C4C4544 && buffer[1] != 0x494D5720)
|
if (buffer[0] != 0x4C4C4544 && buffer[1] != 0x494D5720)
|
||||||
pr_warn("Dell descriptor buffer has invalid signature (%*ph)\n",
|
dev_warn(&wdev->dev, "Dell descriptor buffer has invalid signature (%*ph)\n",
|
||||||
8, buffer);
|
8, buffer);
|
||||||
|
|
||||||
if (buffer[2] != 0 && buffer[2] != 1)
|
if (buffer[2] != 0 && buffer[2] != 1)
|
||||||
pr_warn("Dell descriptor buffer has unknown version (%d)\n",
|
dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%d)\n",
|
||||||
buffer[2]);
|
buffer[2]);
|
||||||
|
|
||||||
if (buffer[3] != 4096)
|
if (buffer[3] != 4096)
|
||||||
pr_warn("Dell descriptor buffer has invalid buffer length (%d)\n",
|
dev_warn(&wdev->dev, "Dell descriptor buffer has invalid buffer length (%d)\n",
|
||||||
buffer[3]);
|
buffer[3]);
|
||||||
|
|
||||||
dell_wmi_interface_version = buffer[2];
|
priv->interface_version = buffer[2];
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
pr_info("Detected Dell WMI interface version %u\n",
|
dev_info(&wdev->dev, "Detected Dell WMI interface version %u\n",
|
||||||
dell_wmi_interface_version);
|
priv->interface_version);
|
||||||
|
|
||||||
|
out:
|
||||||
kfree(obj);
|
kfree(obj);
|
||||||
return 0;
|
put_device(&desc_dev->dev);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -717,17 +724,19 @@ static int dell_wmi_events_set_enabled(bool enable)
|
||||||
|
|
||||||
static int dell_wmi_probe(struct wmi_device *wdev)
|
static int dell_wmi_probe(struct wmi_device *wdev)
|
||||||
{
|
{
|
||||||
|
struct dell_wmi_priv *priv;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
struct dell_wmi_priv *priv = devm_kzalloc(
|
priv = devm_kzalloc(
|
||||||
&wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL);
|
&wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL);
|
||||||
|
if (!priv)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev_set_drvdata(&wdev->dev, priv);
|
||||||
|
|
||||||
err = dell_wmi_check_descriptor_buffer();
|
err = dell_wmi_check_descriptor_buffer(wdev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
dev_set_drvdata(&wdev->dev, priv);
|
|
||||||
|
|
||||||
return dell_wmi_input_setup(wdev);
|
return dell_wmi_input_setup(wdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,13 +107,6 @@ enum hp_wmi_hardware_mask {
|
||||||
HPWMI_TABLET_MASK = 0x04,
|
HPWMI_TABLET_MASK = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BIOS_ARGS_INIT(write, ctype, size) \
|
|
||||||
(struct bios_args) { .signature = 0x55434553, \
|
|
||||||
.command = (write) ? 0x2 : 0x1, \
|
|
||||||
.commandtype = (ctype), \
|
|
||||||
.datasize = (size), \
|
|
||||||
.data = 0 }
|
|
||||||
|
|
||||||
struct bios_return {
|
struct bios_return {
|
||||||
u32 sigpass;
|
u32 sigpass;
|
||||||
u32 return_code;
|
u32 return_code;
|
||||||
|
@ -188,6 +181,22 @@ struct rfkill2_device {
|
||||||
static int rfkill2_count;
|
static int rfkill2_count;
|
||||||
static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
|
static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
|
||||||
|
|
||||||
|
/* map output size to the corresponding WMI method id */
|
||||||
|
static inline int encode_outsize_for_pvsz(int outsize)
|
||||||
|
{
|
||||||
|
if (outsize > 4096)
|
||||||
|
return -EINVAL;
|
||||||
|
if (outsize > 1024)
|
||||||
|
return 5;
|
||||||
|
if (outsize > 128)
|
||||||
|
return 4;
|
||||||
|
if (outsize > 4)
|
||||||
|
return 3;
|
||||||
|
if (outsize > 0)
|
||||||
|
return 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hp_wmi_perform_query
|
* hp_wmi_perform_query
|
||||||
*
|
*
|
||||||
|
@ -211,6 +220,7 @@ static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
|
||||||
static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
|
static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
|
||||||
void *buffer, int insize, int outsize)
|
void *buffer, int insize, int outsize)
|
||||||
{
|
{
|
||||||
|
int mid;
|
||||||
struct bios_return *bios_return;
|
struct bios_return *bios_return;
|
||||||
int actual_outsize;
|
int actual_outsize;
|
||||||
union acpi_object *obj;
|
union acpi_object *obj;
|
||||||
|
@ -225,11 +235,15 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
|
||||||
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
|
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
mid = encode_outsize_for_pvsz(outsize);
|
||||||
|
if (WARN_ON(mid < 0))
|
||||||
|
return mid;
|
||||||
|
|
||||||
if (WARN_ON(insize > sizeof(args.data)))
|
if (WARN_ON(insize > sizeof(args.data)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
memcpy(&args.data, buffer, insize);
|
memcpy(&args.data, buffer, insize);
|
||||||
|
|
||||||
wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output);
|
wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
|
||||||
|
|
||||||
obj = output.pointer;
|
obj = output.pointer;
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ static void rtl_port_unmap(void __iomem *addr)
|
||||||
static int ibm_rtl_write(u8 value)
|
static int ibm_rtl_write(u8 value)
|
||||||
{
|
{
|
||||||
int ret = 0, count = 0;
|
int ret = 0, count = 0;
|
||||||
static u32 cmd_port_val;
|
u32 cmd_port_val;
|
||||||
|
|
||||||
RTL_DEBUG("%s(%d)\n", __func__, value);
|
RTL_DEBUG("%s(%d)\n", __func__, value);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
|
|
||||||
#define IDEAPAD_RFKILL_DEV_NUM (3)
|
#define IDEAPAD_RFKILL_DEV_NUM (3)
|
||||||
|
|
||||||
|
#define BM_CONSERVATION_BIT (5)
|
||||||
|
|
||||||
#define CFG_BT_BIT (16)
|
#define CFG_BT_BIT (16)
|
||||||
#define CFG_3G_BIT (17)
|
#define CFG_3G_BIT (17)
|
||||||
#define CFG_WIFI_BIT (18)
|
#define CFG_WIFI_BIT (18)
|
||||||
|
@ -54,6 +56,11 @@ static const char *const ideapad_wmi_fnesc_events[] = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BMCMD_CONSERVATION_ON = 3,
|
||||||
|
BMCMD_CONSERVATION_OFF = 5,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VPCCMD_R_VPC1 = 0x10,
|
VPCCMD_R_VPC1 = 0x10,
|
||||||
VPCCMD_R_BL_MAX,
|
VPCCMD_R_BL_MAX,
|
||||||
|
@ -123,6 +130,23 @@ static int read_method_int(acpi_handle handle, const char *method, int *val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int method_gbmd(acpi_handle handle, unsigned long *ret)
|
||||||
|
{
|
||||||
|
int result, val;
|
||||||
|
|
||||||
|
result = read_method_int(handle, "GBMD", &val);
|
||||||
|
*ret = val;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int method_sbmc(acpi_handle handle, int cmd)
|
||||||
|
{
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
status = acpi_execute_simple_method(handle, "SBMC", cmd);
|
||||||
|
return ACPI_FAILURE(status) ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int method_vpcr(acpi_handle handle, int cmd, int *ret)
|
static int method_vpcr(acpi_handle handle, int cmd, int *ret)
|
||||||
{
|
{
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
@ -250,6 +274,13 @@ static int debugfs_status_show(struct seq_file *s, void *data)
|
||||||
if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value))
|
if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value))
|
||||||
seq_printf(s, "Camera status:\t%s(%lu)\n",
|
seq_printf(s, "Camera status:\t%s(%lu)\n",
|
||||||
value ? "On" : "Off", value);
|
value ? "On" : "Off", value);
|
||||||
|
seq_puts(s, "=====================\n");
|
||||||
|
|
||||||
|
if (!method_gbmd(priv->adev->handle, &value)) {
|
||||||
|
seq_printf(s, "Conservation mode:\t%s(%lu)\n",
|
||||||
|
test_bit(BM_CONSERVATION_BIT, &value) ? "On" : "Off",
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -456,10 +487,45 @@ static ssize_t __maybe_unused touchpad_store(struct device *dev,
|
||||||
|
|
||||||
static DEVICE_ATTR_RO(touchpad);
|
static DEVICE_ATTR_RO(touchpad);
|
||||||
|
|
||||||
|
static ssize_t conservation_mode_show(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct ideapad_private *priv = dev_get_drvdata(dev);
|
||||||
|
unsigned long result;
|
||||||
|
|
||||||
|
if (method_gbmd(priv->adev->handle, &result))
|
||||||
|
return sprintf(buf, "-1\n");
|
||||||
|
return sprintf(buf, "%u\n", test_bit(BM_CONSERVATION_BIT, &result));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t conservation_mode_store(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct ideapad_private *priv = dev_get_drvdata(dev);
|
||||||
|
bool state;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = kstrtobool(buf, &state);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = method_sbmc(priv->adev->handle, state ?
|
||||||
|
BMCMD_CONSERVATION_ON :
|
||||||
|
BMCMD_CONSERVATION_OFF);
|
||||||
|
if (ret < 0)
|
||||||
|
return -EIO;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR_RW(conservation_mode);
|
||||||
|
|
||||||
static struct attribute *ideapad_attributes[] = {
|
static struct attribute *ideapad_attributes[] = {
|
||||||
&dev_attr_camera_power.attr,
|
&dev_attr_camera_power.attr,
|
||||||
&dev_attr_fan_mode.attr,
|
&dev_attr_fan_mode.attr,
|
||||||
&dev_attr_touchpad.attr,
|
&dev_attr_touchpad.attr,
|
||||||
|
&dev_attr_conservation_mode.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -477,6 +543,9 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
|
supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
|
||||||
&value);
|
&value);
|
||||||
|
} else if (attr == &dev_attr_conservation_mode.attr) {
|
||||||
|
supported = acpi_has_method(priv->adev->handle, "GBMD") &&
|
||||||
|
acpi_has_method(priv->adev->handle, "SBMC");
|
||||||
} else
|
} else
|
||||||
supported = true;
|
supported = true;
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ wakeup:
|
||||||
if (event != 0xc0) {
|
if (event != 0xc0) {
|
||||||
if (!priv->array ||
|
if (!priv->array ||
|
||||||
!sparse_keymap_report_event(priv->array, event, 1, true))
|
!sparse_keymap_report_event(priv->array, event, 1, true))
|
||||||
dev_info(&device->dev, "unknown event 0x%x\n", event);
|
dev_dbg(&device->dev, "unknown event 0x%x\n", event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ wakeup:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sparse_keymap_report_event(priv->input_dev, ev_index, 1, true))
|
if (!sparse_keymap_report_event(priv->input_dev, ev_index, 1, true))
|
||||||
dev_info(&device->dev, "unknown event index 0x%llx\n",
|
dev_dbg(&device->dev, "unknown event index 0x%llx\n",
|
||||||
ev_index);
|
ev_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
|
||||||
} else if (sparse_keymap_report_event(priv->input_dev, event, 1, true)) {
|
} else if (sparse_keymap_report_event(priv->input_dev, event, 1, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dev_info(&device->dev, "unknown event index 0x%x\n", event);
|
dev_dbg(&device->dev, "unknown event index 0x%x\n", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int intel_vbtn_probe(struct platform_device *device)
|
static int intel_vbtn_probe(struct platform_device *device)
|
||||||
|
|
|
@ -108,13 +108,13 @@ static irqreturn_t mid_pb_isr(int irq, void *dev_id)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mid_pb_ddata mfld_ddata = {
|
static const struct mid_pb_ddata mfld_ddata = {
|
||||||
.mirqlvl1_addr = INTEL_MSIC_IRQLVL1MSK,
|
.mirqlvl1_addr = INTEL_MSIC_IRQLVL1MSK,
|
||||||
.pbstat_addr = INTEL_MSIC_PBSTATUS,
|
.pbstat_addr = INTEL_MSIC_PBSTATUS,
|
||||||
.pbstat_mask = MSIC_PB_LEVEL,
|
.pbstat_mask = MSIC_PB_LEVEL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mid_pb_ddata mrfld_ddata = {
|
static const struct mid_pb_ddata mrfld_ddata = {
|
||||||
.mirqlvl1_addr = BCOVE_IRQLVL1MSK,
|
.mirqlvl1_addr = BCOVE_IRQLVL1MSK,
|
||||||
.pbstat_addr = BCOVE_PBSTATUS,
|
.pbstat_addr = BCOVE_PBSTATUS,
|
||||||
.pbstat_mask = BCOVE_PB_LEVEL,
|
.pbstat_mask = BCOVE_PB_LEVEL,
|
||||||
|
@ -142,8 +142,10 @@ static int mid_pb_probe(struct platform_device *pdev)
|
||||||
if (!id)
|
if (!id)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (irq < 0)
|
if (irq < 0) {
|
||||||
return -EINVAL;
|
dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq);
|
||||||
|
return irq;
|
||||||
|
}
|
||||||
|
|
||||||
input = devm_input_allocate_device(&pdev->dev);
|
input = devm_input_allocate_device(&pdev->dev);
|
||||||
if (!input)
|
if (!input)
|
||||||
|
|
|
@ -110,6 +110,13 @@ static const struct pmc_reg_map spt_reg_map = {
|
||||||
.pfear_sts = spt_pfear_map,
|
.pfear_sts = spt_pfear_map,
|
||||||
.mphy_sts = spt_mphy_map,
|
.mphy_sts = spt_mphy_map,
|
||||||
.pll_sts = spt_pll_map,
|
.pll_sts = spt_pll_map,
|
||||||
|
.slp_s0_offset = SPT_PMC_SLP_S0_RES_COUNTER_OFFSET,
|
||||||
|
.ltr_ignore_offset = SPT_PMC_LTR_IGNORE_OFFSET,
|
||||||
|
.regmap_length = SPT_PMC_MMIO_REG_LEN,
|
||||||
|
.ppfear0_offset = SPT_PMC_XRAM_PPFEAR0A,
|
||||||
|
.ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES,
|
||||||
|
.pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET,
|
||||||
|
.pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pci_device_id pmc_pci_ids[] = {
|
static const struct pci_device_id pmc_pci_ids[] = {
|
||||||
|
@ -157,12 +164,13 @@ static inline u32 pmc_core_adjust_slp_s0_step(u32 value)
|
||||||
int intel_pmc_slp_s0_counter_read(u32 *data)
|
int intel_pmc_slp_s0_counter_read(u32 *data)
|
||||||
{
|
{
|
||||||
struct pmc_dev *pmcdev = &pmc;
|
struct pmc_dev *pmcdev = &pmc;
|
||||||
|
const struct pmc_reg_map *map = pmcdev->map;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
if (!pmcdev->has_slp_s0_res)
|
if (!pmcdev->has_slp_s0_res)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
value = pmc_core_reg_read(pmcdev, SPT_PMC_SLP_S0_RES_COUNTER_OFFSET);
|
value = pmc_core_reg_read(pmcdev, map->slp_s0_offset);
|
||||||
*data = pmc_core_adjust_slp_s0_step(value);
|
*data = pmc_core_adjust_slp_s0_step(value);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -172,9 +180,10 @@ EXPORT_SYMBOL_GPL(intel_pmc_slp_s0_counter_read);
|
||||||
static int pmc_core_dev_state_get(void *data, u64 *val)
|
static int pmc_core_dev_state_get(void *data, u64 *val)
|
||||||
{
|
{
|
||||||
struct pmc_dev *pmcdev = data;
|
struct pmc_dev *pmcdev = data;
|
||||||
|
const struct pmc_reg_map *map = pmcdev->map;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
value = pmc_core_reg_read(pmcdev, SPT_PMC_SLP_S0_RES_COUNTER_OFFSET);
|
value = pmc_core_reg_read(pmcdev, map->slp_s0_offset);
|
||||||
*val = pmc_core_adjust_slp_s0_step(value);
|
*val = pmc_core_adjust_slp_s0_step(value);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -187,8 +196,8 @@ static int pmc_core_check_read_lock_bit(void)
|
||||||
struct pmc_dev *pmcdev = &pmc;
|
struct pmc_dev *pmcdev = &pmc;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
value = pmc_core_reg_read(pmcdev, SPT_PMC_PM_CFG_OFFSET);
|
value = pmc_core_reg_read(pmcdev, pmcdev->map->pm_cfg_offset);
|
||||||
return value & BIT(SPT_PMC_READ_DISABLE_BIT);
|
return value & BIT(pmcdev->map->pm_read_disable_bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||||
|
@ -204,12 +213,13 @@ static int pmc_core_ppfear_sts_show(struct seq_file *s, void *unused)
|
||||||
{
|
{
|
||||||
struct pmc_dev *pmcdev = s->private;
|
struct pmc_dev *pmcdev = s->private;
|
||||||
const struct pmc_bit_map *map = pmcdev->map->pfear_sts;
|
const struct pmc_bit_map *map = pmcdev->map->pfear_sts;
|
||||||
u8 pf_regs[NUM_ENTRIES];
|
u8 pf_regs[PPFEAR_MAX_NUM_ENTRIES];
|
||||||
int index, iter;
|
int index, iter;
|
||||||
|
|
||||||
iter = SPT_PMC_XRAM_PPFEAR0A;
|
iter = pmcdev->map->ppfear0_offset;
|
||||||
|
|
||||||
for (index = 0; index < NUM_ENTRIES; index++, iter++)
|
for (index = 0; index < pmcdev->map->ppfear_buckets &&
|
||||||
|
index < PPFEAR_MAX_NUM_ENTRIES; index++, iter++)
|
||||||
pf_regs[index] = pmc_core_reg_read_byte(pmcdev, iter);
|
pf_regs[index] = pmc_core_reg_read_byte(pmcdev, iter);
|
||||||
|
|
||||||
for (index = 0; map[index].name; index++)
|
for (index = 0; map[index].name; index++)
|
||||||
|
@ -376,6 +386,7 @@ static ssize_t pmc_core_ltr_ignore_write(struct file *file, const char __user
|
||||||
*userbuf, size_t count, loff_t *ppos)
|
*userbuf, size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
struct pmc_dev *pmcdev = &pmc;
|
struct pmc_dev *pmcdev = &pmc;
|
||||||
|
const struct pmc_reg_map *map = pmcdev->map;
|
||||||
u32 val, buf_size, fd;
|
u32 val, buf_size, fd;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
@ -392,9 +403,9 @@ static ssize_t pmc_core_ltr_ignore_write(struct file *file, const char __user
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = pmc_core_reg_read(pmcdev, SPT_PMC_LTR_IGNORE_OFFSET);
|
fd = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset);
|
||||||
fd |= (1U << val);
|
fd |= (1U << val);
|
||||||
pmc_core_reg_write(pmcdev, SPT_PMC_LTR_IGNORE_OFFSET, fd);
|
pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, fd);
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&pmcdev->lock);
|
mutex_unlock(&pmcdev->lock);
|
||||||
|
@ -530,8 +541,8 @@ static int pmc_core_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_init(&pmcdev->lock);
|
mutex_init(&pmcdev->lock);
|
||||||
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
|
|
||||||
pmcdev->map = map;
|
pmcdev->map = map;
|
||||||
|
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
|
||||||
|
|
||||||
err = pmc_core_dbgfs_register(pmcdev);
|
err = pmc_core_dbgfs_register(pmcdev);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
|
@ -38,7 +38,8 @@
|
||||||
#define SPT_PMC_SLP_S0_RES_COUNTER_STEP 0x64
|
#define SPT_PMC_SLP_S0_RES_COUNTER_STEP 0x64
|
||||||
#define PMC_BASE_ADDR_MASK ~(SPT_PMC_MMIO_REG_LEN - 1)
|
#define PMC_BASE_ADDR_MASK ~(SPT_PMC_MMIO_REG_LEN - 1)
|
||||||
#define MTPMC_MASK 0xffff0000
|
#define MTPMC_MASK 0xffff0000
|
||||||
#define NUM_ENTRIES 5
|
#define PPFEAR_MAX_NUM_ENTRIES 5
|
||||||
|
#define SPT_PPFEAR_NUM_ENTRIES 5
|
||||||
#define SPT_PMC_READ_DISABLE_BIT 0x16
|
#define SPT_PMC_READ_DISABLE_BIT 0x16
|
||||||
#define SPT_PMC_MSG_FULL_STS_BIT 0x18
|
#define SPT_PMC_MSG_FULL_STS_BIT 0x18
|
||||||
#define NUM_RETRIES 100
|
#define NUM_RETRIES 100
|
||||||
|
@ -126,10 +127,37 @@ struct pmc_bit_map {
|
||||||
u32 bit_mask;
|
u32 bit_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct pmc_reg_map - Structure used to define parameter unique to a
|
||||||
|
PCH family
|
||||||
|
* @pfear_sts: Maps name of IP block to PPFEAR* bit
|
||||||
|
* @mphy_sts: Maps name of MPHY lane to MPHY status lane status bit
|
||||||
|
* @pll_sts: Maps name of PLL to corresponding bit status
|
||||||
|
* @slp_s0_offset: PWRMBASE offset to read SLP_S0 residency
|
||||||
|
* @ltr_ignore_offset: PWRMBASE offset to read/write LTR ignore bit
|
||||||
|
* @base_address: Base address of PWRMBASE defined in BIOS writer guide
|
||||||
|
* @regmap_length: Length of memory to map from PWRMBASE address to access
|
||||||
|
* @ppfear0_offset: PWRMBASE offset to to read PPFEAR*
|
||||||
|
* @ppfear_buckets: Number of 8 bits blocks to read all IP blocks from
|
||||||
|
* PPFEAR
|
||||||
|
* @pm_cfg_offset: PWRMBASE offset to PM_CFG register
|
||||||
|
* @pm_read_disable_bit: Bit index to read PMC_READ_DISABLE
|
||||||
|
*
|
||||||
|
* Each PCH has unique set of register offsets and bit indexes. This structure
|
||||||
|
* captures them to have a common implementation.
|
||||||
|
*/
|
||||||
struct pmc_reg_map {
|
struct pmc_reg_map {
|
||||||
const struct pmc_bit_map *pfear_sts;
|
const struct pmc_bit_map *pfear_sts;
|
||||||
const struct pmc_bit_map *mphy_sts;
|
const struct pmc_bit_map *mphy_sts;
|
||||||
const struct pmc_bit_map *pll_sts;
|
const struct pmc_bit_map *pll_sts;
|
||||||
|
const u32 slp_s0_offset;
|
||||||
|
const u32 ltr_ignore_offset;
|
||||||
|
const u32 base_address;
|
||||||
|
const int regmap_length;
|
||||||
|
const u32 ppfear0_offset;
|
||||||
|
const int ppfear_buckets;
|
||||||
|
const u32 pm_cfg_offset;
|
||||||
|
const int pm_read_disable_bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -72,20 +72,20 @@ struct intel_scu_ipc_pdata_t {
|
||||||
u8 irq_mode;
|
u8 irq_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = {
|
static const struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = {
|
||||||
.i2c_base = 0xff12b000,
|
.i2c_base = 0xff12b000,
|
||||||
.i2c_len = 0x10,
|
.i2c_len = 0x10,
|
||||||
.irq_mode = 0,
|
.irq_mode = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Penwell and Cloverview */
|
/* Penwell and Cloverview */
|
||||||
static struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
|
static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
|
||||||
.i2c_base = 0xff12b000,
|
.i2c_base = 0xff12b000,
|
||||||
.i2c_len = 0x10,
|
.i2c_len = 0x10,
|
||||||
.irq_mode = 1,
|
.irq_mode = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
|
static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
|
||||||
.i2c_base = 0xff00d000,
|
.i2c_base = 0xff00d000,
|
||||||
.i2c_len = 0x10,
|
.i2c_len = 0x10,
|
||||||
.irq_mode = 0,
|
.irq_mode = 0,
|
||||||
|
|
|
@ -331,6 +331,7 @@ static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
|
||||||
|
|
||||||
static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
|
static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
|
||||||
TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_debugfs_conf),
|
TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_debugfs_conf),
|
||||||
|
TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GEMINI_LAKE, telem_apl_debugfs_conf),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
#define TELEM_SAMPLING_DEFAULT_PERIOD 0xD
|
#define TELEM_SAMPLING_DEFAULT_PERIOD 0xD
|
||||||
|
|
||||||
#define TELEM_MAX_EVENTS_SRAM 28
|
#define TELEM_MAX_EVENTS_SRAM 28
|
||||||
#define TELEM_MAX_OS_ALLOCATED_EVENTS 20
|
|
||||||
#define TELEM_SSRAM_STARTTIME_OFFSET 8
|
#define TELEM_SSRAM_STARTTIME_OFFSET 8
|
||||||
#define TELEM_SSRAM_EVTLOG_OFFSET 16
|
#define TELEM_SSRAM_EVTLOG_OFFSET 16
|
||||||
|
|
||||||
|
@ -153,6 +152,30 @@ static struct telemetry_evtmap
|
||||||
{"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40},
|
{"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct telemetry_evtmap
|
||||||
|
telemetry_glk_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
|
||||||
|
{"IA_CORE0_C6_RES", 0x0400},
|
||||||
|
{"IA_CORE0_C6_CTR", 0x0000},
|
||||||
|
{"IA_MODULE0_C7_RES", 0x0410},
|
||||||
|
{"IA_MODULE0_C7_CTR", 0x000C},
|
||||||
|
{"IA_C0_RES", 0x0805},
|
||||||
|
{"PCS_LTR", 0x2801},
|
||||||
|
{"PSTATES", 0x2802},
|
||||||
|
{"SOC_S0I3_RES", 0x0407},
|
||||||
|
{"SOC_S0I3_CTR", 0x0008},
|
||||||
|
{"PCS_S0I3_CTR", 0x0007},
|
||||||
|
{"PCS_C1E_RES", 0x0414},
|
||||||
|
{"PCS_IDLE_STATUS", 0x2806},
|
||||||
|
{"IA_PERF_LIMITS", 0x280B},
|
||||||
|
{"GT_PERF_LIMITS", 0x280C},
|
||||||
|
{"PCS_WAKEUP_S0IX_CTR", 0x0025},
|
||||||
|
{"PCS_IDLE_BLOCKED", 0x2C00},
|
||||||
|
{"PCS_S0IX_BLOCKED", 0x2C01},
|
||||||
|
{"PCS_S0IX_WAKE_REASONS", 0x2C02},
|
||||||
|
{"PCS_LTR_BLOCKING", 0x2C03},
|
||||||
|
{"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40},
|
||||||
|
};
|
||||||
|
|
||||||
/* APL specific Data */
|
/* APL specific Data */
|
||||||
static struct telemetry_plt_config telem_apl_config = {
|
static struct telemetry_plt_config telem_apl_config = {
|
||||||
.pss_config = {
|
.pss_config = {
|
||||||
|
@ -163,8 +186,19 @@ static struct telemetry_plt_config telem_apl_config = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* GLK specific Data */
|
||||||
|
static struct telemetry_plt_config telem_glk_config = {
|
||||||
|
.pss_config = {
|
||||||
|
.telem_evts = telemetry_glk_pss_default_events,
|
||||||
|
},
|
||||||
|
.ioss_config = {
|
||||||
|
.telem_evts = telemetry_apl_ioss_default_events,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static const struct x86_cpu_id telemetry_cpu_ids[] = {
|
static const struct x86_cpu_id telemetry_cpu_ids[] = {
|
||||||
TELEM_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_config),
|
TELEM_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_config),
|
||||||
|
TELEM_CPU(INTEL_FAM6_ATOM_GEMINI_LAKE, telem_glk_config),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ static const struct backlight_ops msi_backlight_ops = {
|
||||||
static void msi_wmi_notify(u32 value, void *context)
|
static void msi_wmi_notify(u32 value, void *context)
|
||||||
{
|
{
|
||||||
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
|
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
static struct key_entry *key;
|
struct key_entry *key;
|
||||||
union acpi_object *obj;
|
union acpi_object *obj;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ int mxm_wmi_call_mxds(int adapter)
|
||||||
|
|
||||||
printk("calling mux switch %d\n", adapter);
|
printk("calling mux switch %d\n", adapter);
|
||||||
|
|
||||||
status = wmi_evaluate_method(MXM_WMMX_GUID, 0x1, adapter, &input,
|
status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
|
||||||
&output);
|
&output);
|
||||||
|
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
|
@ -78,7 +78,7 @@ int mxm_wmi_call_mxmx(int adapter)
|
||||||
|
|
||||||
printk("calling mux switch %d\n", adapter);
|
printk("calling mux switch %d\n", adapter);
|
||||||
|
|
||||||
status = wmi_evaluate_method(MXM_WMMX_GUID, 0x1, adapter, &input,
|
status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
|
||||||
&output);
|
&output);
|
||||||
|
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
|
|
|
@ -39,7 +39,7 @@ static void peaq_wmi_poll(struct input_polled_dev *dev)
|
||||||
struct acpi_buffer input = { sizeof(dummy), &dummy };
|
struct acpi_buffer input = { sizeof(dummy), &dummy };
|
||||||
struct acpi_buffer output = { sizeof(obj), &obj };
|
struct acpi_buffer output = { sizeof(obj), &obj };
|
||||||
|
|
||||||
status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 1,
|
status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 0,
|
||||||
PEAQ_DOLBY_BUTTON_METHOD_ID,
|
PEAQ_DOLBY_BUTTON_METHOD_ID,
|
||||||
&input, &output);
|
&input, &output);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
|
@ -51,7 +51,7 @@ static void peaq_wmi_poll(struct input_polled_dev *dev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peaq_ignore_events_counter && --peaq_ignore_events_counter >= 0)
|
if (peaq_ignore_events_counter && peaq_ignore_events_counter--)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (obj.integer.value) {
|
if (obj.integer.value) {
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#define TPACPI_VERSION "0.25"
|
#define TPACPI_VERSION "0.25"
|
||||||
#define TPACPI_SYSFS_VERSION 0x020700
|
#define TPACPI_SYSFS_VERSION 0x030000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changelog:
|
* Changelog:
|
||||||
|
@ -6342,7 +6342,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
|
||||||
|
|
||||||
switch (thermal_read_mode) {
|
switch (thermal_read_mode) {
|
||||||
case TPACPI_THERMAL_TPEC_16:
|
case TPACPI_THERMAL_TPEC_16:
|
||||||
res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
|
res = sysfs_create_group(&tpacpi_hwmon->kobj,
|
||||||
&thermal_temp_input16_group);
|
&thermal_temp_input16_group);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
@ -6350,7 +6350,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
|
||||||
case TPACPI_THERMAL_TPEC_8:
|
case TPACPI_THERMAL_TPEC_8:
|
||||||
case TPACPI_THERMAL_ACPI_TMP07:
|
case TPACPI_THERMAL_ACPI_TMP07:
|
||||||
case TPACPI_THERMAL_ACPI_UPDT:
|
case TPACPI_THERMAL_ACPI_UPDT:
|
||||||
res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
|
res = sysfs_create_group(&tpacpi_hwmon->kobj,
|
||||||
&thermal_temp_input8_group);
|
&thermal_temp_input8_group);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
@ -6367,13 +6367,13 @@ static void thermal_exit(void)
|
||||||
{
|
{
|
||||||
switch (thermal_read_mode) {
|
switch (thermal_read_mode) {
|
||||||
case TPACPI_THERMAL_TPEC_16:
|
case TPACPI_THERMAL_TPEC_16:
|
||||||
sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
|
sysfs_remove_group(&tpacpi_hwmon->kobj,
|
||||||
&thermal_temp_input16_group);
|
&thermal_temp_input16_group);
|
||||||
break;
|
break;
|
||||||
case TPACPI_THERMAL_TPEC_8:
|
case TPACPI_THERMAL_TPEC_8:
|
||||||
case TPACPI_THERMAL_ACPI_TMP07:
|
case TPACPI_THERMAL_ACPI_TMP07:
|
||||||
case TPACPI_THERMAL_ACPI_UPDT:
|
case TPACPI_THERMAL_ACPI_UPDT:
|
||||||
sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
|
sysfs_remove_group(&tpacpi_hwmon->kobj,
|
||||||
&thermal_temp_input8_group);
|
&thermal_temp_input8_group);
|
||||||
break;
|
break;
|
||||||
case TPACPI_THERMAL_NONE:
|
case TPACPI_THERMAL_NONE:
|
||||||
|
@ -8696,7 +8696,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
|
||||||
fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
|
fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
|
||||||
&dev_attr_fan2_input.attr;
|
&dev_attr_fan2_input.attr;
|
||||||
}
|
}
|
||||||
rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
|
rc = sysfs_create_group(&tpacpi_hwmon->kobj,
|
||||||
&fan_attr_group);
|
&fan_attr_group);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -8704,7 +8704,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
|
||||||
rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
|
rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
|
||||||
&driver_attr_fan_watchdog);
|
&driver_attr_fan_watchdog);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
|
sysfs_remove_group(&tpacpi_hwmon->kobj,
|
||||||
&fan_attr_group);
|
&fan_attr_group);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -8719,7 +8719,7 @@ static void fan_exit(void)
|
||||||
"cancelling any pending fan watchdog tasks\n");
|
"cancelling any pending fan watchdog tasks\n");
|
||||||
|
|
||||||
/* FIXME: can we really do this unconditionally? */
|
/* FIXME: can we really do this unconditionally? */
|
||||||
sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
|
sysfs_remove_group(&tpacpi_hwmon->kobj, &fan_attr_group);
|
||||||
driver_remove_file(&tpacpi_hwmon_pdriver.driver,
|
driver_remove_file(&tpacpi_hwmon_pdriver.driver,
|
||||||
&driver_attr_fan_watchdog);
|
&driver_attr_fan_watchdog);
|
||||||
|
|
||||||
|
@ -9149,16 +9149,6 @@ static void hotkey_driver_event(const unsigned int scancode)
|
||||||
tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
|
tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sysfs name ---------------------------------------------------------- */
|
|
||||||
static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
|
|
||||||
struct device_attribute *attr,
|
|
||||||
char *buf)
|
|
||||||
{
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
static DEVICE_ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* /proc support */
|
/* /proc support */
|
||||||
|
@ -9696,8 +9686,6 @@ static void thinkpad_acpi_module_exit(void)
|
||||||
if (tpacpi_hwmon)
|
if (tpacpi_hwmon)
|
||||||
hwmon_device_unregister(tpacpi_hwmon);
|
hwmon_device_unregister(tpacpi_hwmon);
|
||||||
|
|
||||||
if (tp_features.sensors_pdev_attrs_registered)
|
|
||||||
device_remove_file(&tpacpi_sensors_pdev->dev, &dev_attr_name);
|
|
||||||
if (tpacpi_sensors_pdev)
|
if (tpacpi_sensors_pdev)
|
||||||
platform_device_unregister(tpacpi_sensors_pdev);
|
platform_device_unregister(tpacpi_sensors_pdev);
|
||||||
if (tpacpi_pdev)
|
if (tpacpi_pdev)
|
||||||
|
@ -9818,14 +9806,10 @@ static int __init thinkpad_acpi_module_init(void)
|
||||||
thinkpad_acpi_module_exit();
|
thinkpad_acpi_module_exit();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = device_create_file(&tpacpi_sensors_pdev->dev, &dev_attr_name);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("unable to create sysfs hwmon device attributes\n");
|
|
||||||
thinkpad_acpi_module_exit();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
tp_features.sensors_pdev_attrs_registered = 1;
|
tp_features.sensors_pdev_attrs_registered = 1;
|
||||||
tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
|
tpacpi_hwmon = hwmon_device_register_with_groups(
|
||||||
|
&tpacpi_sensors_pdev->dev, TPACPI_NAME, NULL, NULL);
|
||||||
|
|
||||||
if (IS_ERR(tpacpi_hwmon)) {
|
if (IS_ERR(tpacpi_hwmon)) {
|
||||||
ret = PTR_ERR(tpacpi_hwmon);
|
ret = PTR_ERR(tpacpi_hwmon);
|
||||||
tpacpi_hwmon = NULL;
|
tpacpi_hwmon = NULL;
|
||||||
|
|
|
@ -218,7 +218,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
|
||||||
if (!(block->flags & ACPI_WMI_METHOD))
|
if (!(block->flags & ACPI_WMI_METHOD))
|
||||||
return AE_BAD_DATA;
|
return AE_BAD_DATA;
|
||||||
|
|
||||||
if (block->instance_count < instance)
|
if (block->instance_count <= instance)
|
||||||
return AE_BAD_PARAMETER;
|
return AE_BAD_PARAMETER;
|
||||||
|
|
||||||
input.count = 2;
|
input.count = 2;
|
||||||
|
@ -265,7 +265,7 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
|
||||||
block = &wblock->gblock;
|
block = &wblock->gblock;
|
||||||
handle = wblock->acpi_device->handle;
|
handle = wblock->acpi_device->handle;
|
||||||
|
|
||||||
if (block->instance_count < instance)
|
if (block->instance_count <= instance)
|
||||||
return AE_BAD_PARAMETER;
|
return AE_BAD_PARAMETER;
|
||||||
|
|
||||||
/* Check GUID is a data block */
|
/* Check GUID is a data block */
|
||||||
|
@ -392,7 +392,7 @@ acpi_status wmi_set_block(const char *guid_string, u8 instance,
|
||||||
block = &wblock->gblock;
|
block = &wblock->gblock;
|
||||||
handle = wblock->acpi_device->handle;
|
handle = wblock->acpi_device->handle;
|
||||||
|
|
||||||
if (block->instance_count < instance)
|
if (block->instance_count <= instance)
|
||||||
return AE_BAD_PARAMETER;
|
return AE_BAD_PARAMETER;
|
||||||
|
|
||||||
/* Check GUID is a data block */
|
/* Check GUID is a data block */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче