Commit d9b2ba67 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'platform-drivers-x86-v5.19-3' of...

Merge tag 'platform-drivers-x86-v5.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform driver fixes from Hans de Goede:

 - thinkpad_acpi/ideapad-laptop: mem-leak and platform-profile fixes

 - panasonic-laptop: missing hotkey presses regression fix

 - some hardware-id additions

 - some other small fixes

* tag 'platform-drivers-x86-v5.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86:
  platform/x86: hp-wmi: Ignore Sanitization Mode event
  platform/x86: thinkpad_acpi: do not use PSC mode on Intel platforms
  platform/x86: thinkpad-acpi: profile capabilities as integer
  platform/x86: panasonic-laptop: filter out duplicate volume up/down/mute keypresses
  platform/x86: panasonic-laptop: don't report duplicate brightness key-presses
  platform/x86: panasonic-laptop: revert "Resolve hotkey double trigger bug"
  platform/x86: panasonic-laptop: sort includes alphabetically
  platform/x86: panasonic-laptop: de-obfuscate button codes
  ACPI: video: Change how we determine if brightness key-presses are handled
  platform/x86: ideapad-laptop: Add Ideapad 5 15ITL05 to ideapad_dytc_v4_allow_table[]
  platform/x86: ideapad-laptop: Add allow_v4_dytc module parameter
  platform/x86: thinkpad_acpi: Fix a memory leak of EFCH MMIO resource
  platform/mellanox: nvsw-sn2201: fix error code in nvsw_sn2201_create_static_devices()
  platform/x86: intel/pmc: Add Alder Lake N support to PMC core driver
parents 732f3069 9ab762a8
...@@ -73,6 +73,7 @@ module_param(device_id_scheme, bool, 0444); ...@@ -73,6 +73,7 @@ module_param(device_id_scheme, bool, 0444);
static int only_lcd = -1; static int only_lcd = -1;
module_param(only_lcd, int, 0444); module_param(only_lcd, int, 0444);
static bool has_backlight;
static int register_count; static int register_count;
static DEFINE_MUTEX(register_count_mutex); static DEFINE_MUTEX(register_count_mutex);
static DEFINE_MUTEX(video_list_lock); static DEFINE_MUTEX(video_list_lock);
...@@ -1222,6 +1223,9 @@ acpi_video_bus_get_one_device(struct acpi_device *device, ...@@ -1222,6 +1223,9 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
acpi_video_device_bind(video, data); acpi_video_device_bind(video, data);
acpi_video_device_find_cap(data); acpi_video_device_find_cap(data);
if (data->cap._BCM && data->cap._BCL)
has_backlight = true;
mutex_lock(&video->device_list_lock); mutex_lock(&video->device_list_lock);
list_add_tail(&data->entry, &video->video_device_list); list_add_tail(&data->entry, &video->video_device_list);
mutex_unlock(&video->device_list_lock); mutex_unlock(&video->device_list_lock);
...@@ -2249,6 +2253,7 @@ void acpi_video_unregister(void) ...@@ -2249,6 +2253,7 @@ void acpi_video_unregister(void)
if (register_count) { if (register_count) {
acpi_bus_unregister_driver(&acpi_video_bus); acpi_bus_unregister_driver(&acpi_video_bus);
register_count = 0; register_count = 0;
has_backlight = false;
} }
mutex_unlock(&register_count_mutex); mutex_unlock(&register_count_mutex);
} }
...@@ -2270,13 +2275,7 @@ void acpi_video_unregister_backlight(void) ...@@ -2270,13 +2275,7 @@ void acpi_video_unregister_backlight(void)
bool acpi_video_handles_brightness_key_presses(void) bool acpi_video_handles_brightness_key_presses(void)
{ {
bool have_video_busses; return has_backlight &&
mutex_lock(&video_list_lock);
have_video_busses = !list_empty(&video_bus_head);
mutex_unlock(&video_list_lock);
return have_video_busses &&
(report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS); (report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS);
} }
EXPORT_SYMBOL(acpi_video_handles_brightness_key_presses); EXPORT_SYMBOL(acpi_video_handles_brightness_key_presses);
......
...@@ -890,6 +890,7 @@ nvsw_sn2201_create_static_devices(struct nvsw_sn2201 *nvsw_sn2201, ...@@ -890,6 +890,7 @@ nvsw_sn2201_create_static_devices(struct nvsw_sn2201 *nvsw_sn2201,
int size) int size)
{ {
struct mlxreg_hotplug_device *dev = devs; struct mlxreg_hotplug_device *dev = devs;
int ret;
int i; int i;
/* Create I2C static devices. */ /* Create I2C static devices. */
...@@ -901,6 +902,7 @@ nvsw_sn2201_create_static_devices(struct nvsw_sn2201 *nvsw_sn2201, ...@@ -901,6 +902,7 @@ nvsw_sn2201_create_static_devices(struct nvsw_sn2201 *nvsw_sn2201,
dev->nr, dev->brdinfo->addr); dev->nr, dev->brdinfo->addr);
dev->adapter = NULL; dev->adapter = NULL;
ret = PTR_ERR(dev->client);
goto fail_create_static_devices; goto fail_create_static_devices;
} }
} }
...@@ -914,7 +916,7 @@ nvsw_sn2201_create_static_devices(struct nvsw_sn2201 *nvsw_sn2201, ...@@ -914,7 +916,7 @@ nvsw_sn2201_create_static_devices(struct nvsw_sn2201 *nvsw_sn2201,
dev->client = NULL; dev->client = NULL;
dev->adapter = NULL; dev->adapter = NULL;
} }
return IS_ERR(dev->client); return ret;
} }
static void nvsw_sn2201_destroy_static_devices(struct nvsw_sn2201 *nvsw_sn2201, static void nvsw_sn2201_destroy_static_devices(struct nvsw_sn2201 *nvsw_sn2201,
......
...@@ -945,6 +945,8 @@ config PANASONIC_LAPTOP ...@@ -945,6 +945,8 @@ config PANASONIC_LAPTOP
tristate "Panasonic Laptop Extras" tristate "Panasonic Laptop Extras"
depends on INPUT && ACPI depends on INPUT && ACPI
depends on BACKLIGHT_CLASS_DEVICE depends on BACKLIGHT_CLASS_DEVICE
depends on ACPI_VIDEO=n || ACPI_VIDEO
depends on SERIO_I8042 || SERIO_I8042 = n
select INPUT_SPARSEKMAP select INPUT_SPARSEKMAP
help help
This driver adds support for access to backlight control and hotkeys This driver adds support for access to backlight control and hotkeys
......
...@@ -89,6 +89,7 @@ enum hp_wmi_event_ids { ...@@ -89,6 +89,7 @@ enum hp_wmi_event_ids {
HPWMI_BACKLIT_KB_BRIGHTNESS = 0x0D, HPWMI_BACKLIT_KB_BRIGHTNESS = 0x0D,
HPWMI_PEAKSHIFT_PERIOD = 0x0F, HPWMI_PEAKSHIFT_PERIOD = 0x0F,
HPWMI_BATTERY_CHARGE_PERIOD = 0x10, HPWMI_BATTERY_CHARGE_PERIOD = 0x10,
HPWMI_SANITIZATION_MODE = 0x17,
}; };
/* /*
...@@ -853,6 +854,8 @@ static void hp_wmi_notify(u32 value, void *context) ...@@ -853,6 +854,8 @@ static void hp_wmi_notify(u32 value, void *context)
break; break;
case HPWMI_BATTERY_CHARGE_PERIOD: case HPWMI_BATTERY_CHARGE_PERIOD:
break; break;
case HPWMI_SANITIZATION_MODE:
break;
default: default:
pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data); pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
break; break;
......
...@@ -152,6 +152,10 @@ static bool no_bt_rfkill; ...@@ -152,6 +152,10 @@ static bool no_bt_rfkill;
module_param(no_bt_rfkill, bool, 0444); module_param(no_bt_rfkill, bool, 0444);
MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth."); MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth.");
static bool allow_v4_dytc;
module_param(allow_v4_dytc, bool, 0444);
MODULE_PARM_DESC(allow_v4_dytc, "Enable DYTC version 4 platform-profile support.");
/* /*
* ACPI Helpers * ACPI Helpers
*/ */
...@@ -871,12 +875,18 @@ static void dytc_profile_refresh(struct ideapad_private *priv) ...@@ -871,12 +875,18 @@ static void dytc_profile_refresh(struct ideapad_private *priv)
static const struct dmi_system_id ideapad_dytc_v4_allow_table[] = { static const struct dmi_system_id ideapad_dytc_v4_allow_table[] = {
{ {
/* Ideapad 5 Pro 16ACH6 */ /* Ideapad 5 Pro 16ACH6 */
.ident = "LENOVO 82L5",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "82L5") DMI_MATCH(DMI_PRODUCT_NAME, "82L5")
} }
}, },
{
/* Ideapad 5 15ITL05 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad 5 15ITL05")
}
},
{} {}
}; };
...@@ -901,13 +911,16 @@ static int ideapad_dytc_profile_init(struct ideapad_private *priv) ...@@ -901,13 +911,16 @@ static int ideapad_dytc_profile_init(struct ideapad_private *priv)
dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF; dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF;
if (dytc_version < 5) { if (dytc_version < 4) {
if (dytc_version < 4 || !dmi_check_system(ideapad_dytc_v4_allow_table)) { dev_info(&priv->platform_device->dev, "DYTC_VERSION < 4 is not supported\n");
dev_info(&priv->platform_device->dev, return -ENODEV;
"DYTC_VERSION is less than 4 or is not allowed: %d\n", }
dytc_version);
return -ENODEV; if (dytc_version < 5 &&
} !(allow_v4_dytc || dmi_check_system(ideapad_dytc_v4_allow_table))) {
dev_info(&priv->platform_device->dev,
"DYTC_VERSION 4 support may not work. Pass ideapad_laptop.allow_v4_dytc=Y on the kernel commandline to enable\n");
return -ENODEV;
} }
priv->dytc = kzalloc(sizeof(*priv->dytc), GFP_KERNEL); priv->dytc = kzalloc(sizeof(*priv->dytc), GFP_KERNEL);
......
...@@ -1911,6 +1911,7 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = { ...@@ -1911,6 +1911,7 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, &icl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, &icl_reg_map),
X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &tgl_reg_map),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &tgl_reg_map),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &tgl_reg_map),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_reg_map),
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &tgl_reg_map),
{} {}
......
...@@ -119,20 +119,22 @@ ...@@ -119,20 +119,22 @@
* - v0.1 start from toshiba_acpi driver written by John Belmonte * - v0.1 start from toshiba_acpi driver written by John Belmonte
*/ */
#include <linux/kernel.h> #include <linux/acpi.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/seq_file.h> #include <linux/i8042.h>
#include <linux/uaccess.h> #include <linux/init.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input/sparse-keymap.h> #include <linux/input/sparse-keymap.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/seq_file.h>
#include <linux/serio.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <acpi/video.h>
MODULE_AUTHOR("Hiroshi Miura <miura@da-cha.org>"); MODULE_AUTHOR("Hiroshi Miura <miura@da-cha.org>");
MODULE_AUTHOR("David Bronaugh <dbronaugh@linuxboxen.org>"); MODULE_AUTHOR("David Bronaugh <dbronaugh@linuxboxen.org>");
...@@ -241,6 +243,42 @@ struct pcc_acpi { ...@@ -241,6 +243,42 @@ struct pcc_acpi {
struct platform_device *platform; struct platform_device *platform;
}; };
/*
* On some Panasonic models the volume up / down / mute keys send duplicate
* keypress events over the PS/2 kbd interface, filter these out.
*/
static bool panasonic_i8042_filter(unsigned char data, unsigned char str,
struct serio *port)
{
static bool extended;
if (str & I8042_STR_AUXDATA)
return false;
if (data == 0xe0) {
extended = true;
return true;
} else if (extended) {
extended = false;
switch (data & 0x7f) {
case 0x20: /* e0 20 / e0 a0, Volume Mute press / release */
case 0x2e: /* e0 2e / e0 ae, Volume Down press / release */
case 0x30: /* e0 30 / e0 b0, Volume Up press / release */
return true;
default:
/*
* Report the previously filtered e0 before continuing
* with the next non-filtered byte.
*/
serio_interrupt(port, 0xe0, 0);
return false;
}
}
return false;
}
/* method access functions */ /* method access functions */
static int acpi_pcc_write_sset(struct pcc_acpi *pcc, int func, int val) static int acpi_pcc_write_sset(struct pcc_acpi *pcc, int func, int val)
{ {
...@@ -762,6 +800,8 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) ...@@ -762,6 +800,8 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
struct input_dev *hotk_input_dev = pcc->input_dev; struct input_dev *hotk_input_dev = pcc->input_dev;
int rc; int rc;
unsigned long long result; unsigned long long result;
unsigned int key;
unsigned int updown;
rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY, rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY,
NULL, &result); NULL, &result);
...@@ -770,20 +810,27 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) ...@@ -770,20 +810,27 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
return; return;
} }
key = result & 0xf;
updown = result & 0x80; /* 0x80 == key down; 0x00 = key up */
/* hack: some firmware sends no key down for sleep / hibernate */ /* hack: some firmware sends no key down for sleep / hibernate */
if ((result & 0xf) == 0x7 || (result & 0xf) == 0xa) { if (key == 7 || key == 10) {
if (result & 0x80) if (updown)
sleep_keydown_seen = 1; sleep_keydown_seen = 1;
if (!sleep_keydown_seen) if (!sleep_keydown_seen)
sparse_keymap_report_event(hotk_input_dev, sparse_keymap_report_event(hotk_input_dev,
result & 0xf, 0x80, false); key, 0x80, false);
} }
if ((result & 0xf) == 0x7 || (result & 0xf) == 0x9 || (result & 0xf) == 0xa) { /*
if (!sparse_keymap_report_event(hotk_input_dev, * Don't report brightness key-presses if they are also reported
result & 0xf, result & 0x80, false)) * by the ACPI video bus.
pr_err("Unknown hotkey event: 0x%04llx\n", result); */
} if ((key == 1 || key == 2) && acpi_video_handles_brightness_key_presses())
return;
if (!sparse_keymap_report_event(hotk_input_dev, key, updown, false))
pr_err("Unknown hotkey event: 0x%04llx\n", result);
} }
static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event) static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
...@@ -997,6 +1044,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) ...@@ -997,6 +1044,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
pcc->platform = NULL; pcc->platform = NULL;
} }
i8042_install_filter(panasonic_i8042_filter);
return 0; return 0;
out_platform: out_platform:
...@@ -1020,6 +1068,8 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device) ...@@ -1020,6 +1068,8 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device)
if (!device || !pcc) if (!device || !pcc)
return -EINVAL; return -EINVAL;
i8042_remove_filter(panasonic_i8042_filter);
if (pcc->platform) { if (pcc->platform) {
device_remove_file(&pcc->platform->dev, &dev_attr_cdpower); device_remove_file(&pcc->platform->dev, &dev_attr_cdpower);
platform_device_unregister(pcc->platform); platform_device_unregister(pcc->platform);
......
...@@ -4529,6 +4529,7 @@ static void thinkpad_acpi_amd_s2idle_restore(void) ...@@ -4529,6 +4529,7 @@ static void thinkpad_acpi_amd_s2idle_restore(void)
iounmap(addr); iounmap(addr);
cleanup_resource: cleanup_resource:
release_resource(res); release_resource(res);
kfree(res);
} }
static struct acpi_s2idle_dev_ops thinkpad_acpi_s2idle_dev_ops = { static struct acpi_s2idle_dev_ops thinkpad_acpi_s2idle_dev_ops = {
...@@ -10299,21 +10300,15 @@ static struct ibm_struct proxsensor_driver_data = { ...@@ -10299,21 +10300,15 @@ static struct ibm_struct proxsensor_driver_data = {
#define DYTC_DISABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_MMC_BALANCE, 0) #define DYTC_DISABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_MMC_BALANCE, 0)
#define DYTC_ENABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_MMC_BALANCE, 1) #define DYTC_ENABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_MMC_BALANCE, 1)
enum dytc_profile_funcmode {
DYTC_FUNCMODE_NONE = 0,
DYTC_FUNCMODE_MMC,
DYTC_FUNCMODE_PSC,
};
static enum dytc_profile_funcmode dytc_profile_available;
static enum platform_profile_option dytc_current_profile; static enum platform_profile_option dytc_current_profile;
static atomic_t dytc_ignore_event = ATOMIC_INIT(0); static atomic_t dytc_ignore_event = ATOMIC_INIT(0);
static DEFINE_MUTEX(dytc_mutex); static DEFINE_MUTEX(dytc_mutex);
static int dytc_capabilities;
static bool dytc_mmc_get_available; static bool dytc_mmc_get_available;
static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *profile) static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *profile)
{ {
if (dytc_profile_available == DYTC_FUNCMODE_MMC) { if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
switch (dytcmode) { switch (dytcmode) {
case DYTC_MODE_MMC_LOWPOWER: case DYTC_MODE_MMC_LOWPOWER:
*profile = PLATFORM_PROFILE_LOW_POWER; *profile = PLATFORM_PROFILE_LOW_POWER;
...@@ -10330,7 +10325,7 @@ static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p ...@@ -10330,7 +10325,7 @@ static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p
} }
return 0; return 0;
} }
if (dytc_profile_available == DYTC_FUNCMODE_PSC) { if (dytc_capabilities & BIT(DYTC_FC_PSC)) {
switch (dytcmode) { switch (dytcmode) {
case DYTC_MODE_PSC_LOWPOWER: case DYTC_MODE_PSC_LOWPOWER:
*profile = PLATFORM_PROFILE_LOW_POWER; *profile = PLATFORM_PROFILE_LOW_POWER;
...@@ -10352,21 +10347,21 @@ static int convert_profile_to_dytc(enum platform_profile_option profile, int *pe ...@@ -10352,21 +10347,21 @@ static int convert_profile_to_dytc(enum platform_profile_option profile, int *pe
{ {
switch (profile) { switch (profile) {
case PLATFORM_PROFILE_LOW_POWER: case PLATFORM_PROFILE_LOW_POWER:
if (dytc_profile_available == DYTC_FUNCMODE_MMC) if (dytc_capabilities & BIT(DYTC_FC_MMC))
*perfmode = DYTC_MODE_MMC_LOWPOWER; *perfmode = DYTC_MODE_MMC_LOWPOWER;
else if (dytc_profile_available == DYTC_FUNCMODE_PSC) else if (dytc_capabilities & BIT(DYTC_FC_PSC))
*perfmode = DYTC_MODE_PSC_LOWPOWER; *perfmode = DYTC_MODE_PSC_LOWPOWER;
break; break;
case PLATFORM_PROFILE_BALANCED: case PLATFORM_PROFILE_BALANCED:
if (dytc_profile_available == DYTC_FUNCMODE_MMC) if (dytc_capabilities & BIT(DYTC_FC_MMC))
*perfmode = DYTC_MODE_MMC_BALANCE; *perfmode = DYTC_MODE_MMC_BALANCE;
else if (dytc_profile_available == DYTC_FUNCMODE_PSC) else if (dytc_capabilities & BIT(DYTC_FC_PSC))
*perfmode = DYTC_MODE_PSC_BALANCE; *perfmode = DYTC_MODE_PSC_BALANCE;
break; break;
case PLATFORM_PROFILE_PERFORMANCE: case PLATFORM_PROFILE_PERFORMANCE:
if (dytc_profile_available == DYTC_FUNCMODE_MMC) if (dytc_capabilities & BIT(DYTC_FC_MMC))
*perfmode = DYTC_MODE_MMC_PERFORM; *perfmode = DYTC_MODE_MMC_PERFORM;
else if (dytc_profile_available == DYTC_FUNCMODE_PSC) else if (dytc_capabilities & BIT(DYTC_FC_PSC))
*perfmode = DYTC_MODE_PSC_PERFORM; *perfmode = DYTC_MODE_PSC_PERFORM;
break; break;
default: /* Unknown profile */ default: /* Unknown profile */
...@@ -10445,7 +10440,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof, ...@@ -10445,7 +10440,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
if (err) if (err)
goto unlock; goto unlock;
if (dytc_profile_available == DYTC_FUNCMODE_MMC) { if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
if (profile == PLATFORM_PROFILE_BALANCED) { if (profile == PLATFORM_PROFILE_BALANCED) {
/* /*
* To get back to balanced mode we need to issue a reset command. * To get back to balanced mode we need to issue a reset command.
...@@ -10464,7 +10459,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof, ...@@ -10464,7 +10459,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
goto unlock; goto unlock;
} }
} }
if (dytc_profile_available == DYTC_FUNCMODE_PSC) { if (dytc_capabilities & BIT(DYTC_FC_PSC)) {
err = dytc_command(DYTC_SET_COMMAND(DYTC_FUNCTION_PSC, perfmode, 1), &output); err = dytc_command(DYTC_SET_COMMAND(DYTC_FUNCTION_PSC, perfmode, 1), &output);
if (err) if (err)
goto unlock; goto unlock;
...@@ -10483,12 +10478,12 @@ static void dytc_profile_refresh(void) ...@@ -10483,12 +10478,12 @@ static void dytc_profile_refresh(void)
int perfmode; int perfmode;
mutex_lock(&dytc_mutex); mutex_lock(&dytc_mutex);
if (dytc_profile_available == DYTC_FUNCMODE_MMC) { if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
if (dytc_mmc_get_available) if (dytc_mmc_get_available)
err = dytc_command(DYTC_CMD_MMC_GET, &output); err = dytc_command(DYTC_CMD_MMC_GET, &output);
else else
err = dytc_cql_command(DYTC_CMD_GET, &output); err = dytc_cql_command(DYTC_CMD_GET, &output);
} else if (dytc_profile_available == DYTC_FUNCMODE_PSC) } else if (dytc_capabilities & BIT(DYTC_FC_PSC))
err = dytc_command(DYTC_CMD_GET, &output); err = dytc_command(DYTC_CMD_GET, &output);
mutex_unlock(&dytc_mutex); mutex_unlock(&dytc_mutex);
...@@ -10517,7 +10512,6 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) ...@@ -10517,7 +10512,6 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
set_bit(PLATFORM_PROFILE_BALANCED, dytc_profile.choices); set_bit(PLATFORM_PROFILE_BALANCED, dytc_profile.choices);
set_bit(PLATFORM_PROFILE_PERFORMANCE, dytc_profile.choices); set_bit(PLATFORM_PROFILE_PERFORMANCE, dytc_profile.choices);
dytc_profile_available = DYTC_FUNCMODE_NONE;
err = dytc_command(DYTC_CMD_QUERY, &output); err = dytc_command(DYTC_CMD_QUERY, &output);
if (err) if (err)
return err; return err;
...@@ -10530,13 +10524,12 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) ...@@ -10530,13 +10524,12 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
return -ENODEV; return -ENODEV;
/* Check what capabilities are supported */ /* Check what capabilities are supported */
err = dytc_command(DYTC_CMD_FUNC_CAP, &output); err = dytc_command(DYTC_CMD_FUNC_CAP, &dytc_capabilities);
if (err) if (err)
return err; return err;
if (output & BIT(DYTC_FC_MMC)) { /* MMC MODE */ if (dytc_capabilities & BIT(DYTC_FC_MMC)) { /* MMC MODE */
dytc_profile_available = DYTC_FUNCMODE_MMC; pr_debug("MMC is supported\n");
/* /*
* Check if MMC_GET functionality available * Check if MMC_GET functionality available
* Version > 6 and return success from MMC_GET command * Version > 6 and return success from MMC_GET command
...@@ -10547,8 +10540,13 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) ...@@ -10547,8 +10540,13 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
if (!err && ((output & DYTC_ERR_MASK) == DYTC_ERR_SUCCESS)) if (!err && ((output & DYTC_ERR_MASK) == DYTC_ERR_SUCCESS))
dytc_mmc_get_available = true; dytc_mmc_get_available = true;
} }
} else if (output & BIT(DYTC_FC_PSC)) { /* PSC MODE */ } else if (dytc_capabilities & BIT(DYTC_FC_PSC)) { /* PSC MODE */
dytc_profile_available = DYTC_FUNCMODE_PSC; /* Support for this only works on AMD platforms */
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
dbg_printk(TPACPI_DBG_INIT, "PSC not support on Intel platforms\n");
return -ENODEV;
}
pr_debug("PSC is supported\n");
} else { } else {
dbg_printk(TPACPI_DBG_INIT, "No DYTC support available\n"); dbg_printk(TPACPI_DBG_INIT, "No DYTC support available\n");
return -ENODEV; return -ENODEV;
...@@ -10574,7 +10572,6 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) ...@@ -10574,7 +10572,6 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
static void dytc_profile_exit(void) static void dytc_profile_exit(void)
{ {
dytc_profile_available = DYTC_FUNCMODE_NONE;
platform_profile_remove(); platform_profile_remove();
} }
......
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