Commit 870bb765 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'platform-drivers-x86-v6.2-4' of...

Merge tag 'platform-drivers-x86-v6.2-4' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform driver fixes from Hans de Goede:
 "A set of AMD PMF fixes + a few other small fixes"

* tag 'platform-drivers-x86-v6.2-4' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86:
  platform/x86: touchscreen_dmi: Add Chuwi Vi8 (CWI501) DMI match
  platform/x86: thinkpad_acpi: Fix thinklight LED brightness returning 255
  platform/x86/amd: pmc: add CONFIG_SERIO dependency
  platform/x86/amd/pmf: Ensure mutexes are initialized before use
  platform/x86/amd/pmf: Fix to update SPS thermals when power supply change
  platform/x86/amd/pmf: Fix to update SPS default pprof thermals
  platform/x86/amd/pmf: update to auto-mode limits only after AMT event
  platform/x86/amd/pmf: Add helper routine to check pprof is balanced
  platform/x86/amd/pmf: Add helper routine to update SPS thermals
parents 9f266cca eecf2acd
...@@ -8,6 +8,7 @@ source "drivers/platform/x86/amd/pmf/Kconfig" ...@@ -8,6 +8,7 @@ source "drivers/platform/x86/amd/pmf/Kconfig"
config AMD_PMC config AMD_PMC
tristate "AMD SoC PMC driver" tristate "AMD SoC PMC driver"
depends on ACPI && PCI && RTC_CLASS depends on ACPI && PCI && RTC_CLASS
select SERIO
help help
The driver provides support for AMD Power Management Controller The driver provides support for AMD Power Management Controller
primarily responsible for S2Idle transactions that are driven from primarily responsible for S2Idle transactions that are driven from
......
...@@ -275,13 +275,8 @@ int amd_pmf_reset_amt(struct amd_pmf_dev *dev) ...@@ -275,13 +275,8 @@ int amd_pmf_reset_amt(struct amd_pmf_dev *dev)
*/ */
if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) {
int mode = amd_pmf_get_pprof_modes(dev);
if (mode < 0)
return mode;
dev_dbg(dev->dev, "resetting AMT thermals\n"); dev_dbg(dev->dev, "resetting AMT thermals\n");
amd_pmf_update_slider(dev, SLIDER_OP_SET, mode, NULL); amd_pmf_set_sps_power_limits(dev);
} }
return 0; return 0;
} }
...@@ -299,7 +294,5 @@ void amd_pmf_deinit_auto_mode(struct amd_pmf_dev *dev) ...@@ -299,7 +294,5 @@ void amd_pmf_deinit_auto_mode(struct amd_pmf_dev *dev)
void amd_pmf_init_auto_mode(struct amd_pmf_dev *dev) void amd_pmf_init_auto_mode(struct amd_pmf_dev *dev)
{ {
amd_pmf_load_defaults_auto_mode(dev); amd_pmf_load_defaults_auto_mode(dev);
/* update the thermal limits for Automode */
amd_pmf_set_automode(dev, config_store.current_mode, NULL);
amd_pmf_init_metrics_table(dev); amd_pmf_init_metrics_table(dev);
} }
...@@ -103,7 +103,7 @@ int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t time_l ...@@ -103,7 +103,7 @@ int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t time_l
src = amd_pmf_cnqf_get_power_source(dev); src = amd_pmf_cnqf_get_power_source(dev);
if (dev->current_profile == PLATFORM_PROFILE_BALANCED) { if (is_pprof_balanced(dev)) {
amd_pmf_set_cnqf(dev, src, config_store.current_mode, NULL); amd_pmf_set_cnqf(dev, src, config_store.current_mode, NULL);
} else { } else {
/* /*
...@@ -307,13 +307,9 @@ static ssize_t cnqf_enable_store(struct device *dev, ...@@ -307,13 +307,9 @@ static ssize_t cnqf_enable_store(struct device *dev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct amd_pmf_dev *pdev = dev_get_drvdata(dev); struct amd_pmf_dev *pdev = dev_get_drvdata(dev);
int mode, result, src; int result, src;
bool input; bool input;
mode = amd_pmf_get_pprof_modes(pdev);
if (mode < 0)
return mode;
result = kstrtobool(buf, &input); result = kstrtobool(buf, &input);
if (result) if (result)
return result; return result;
...@@ -321,11 +317,11 @@ static ssize_t cnqf_enable_store(struct device *dev, ...@@ -321,11 +317,11 @@ static ssize_t cnqf_enable_store(struct device *dev,
src = amd_pmf_cnqf_get_power_source(pdev); src = amd_pmf_cnqf_get_power_source(pdev);
pdev->cnqf_enabled = input; pdev->cnqf_enabled = input;
if (pdev->cnqf_enabled && pdev->current_profile == PLATFORM_PROFILE_BALANCED) { if (pdev->cnqf_enabled && is_pprof_balanced(pdev)) {
amd_pmf_set_cnqf(pdev, src, config_store.current_mode, NULL); amd_pmf_set_cnqf(pdev, src, config_store.current_mode, NULL);
} else { } else {
if (is_apmf_func_supported(pdev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) if (is_apmf_func_supported(pdev, APMF_FUNC_STATIC_SLIDER_GRANULAR))
amd_pmf_update_slider(pdev, SLIDER_OP_SET, mode, NULL); amd_pmf_set_sps_power_limits(pdev);
} }
dev_dbg(pdev->dev, "Received CnQF %s\n", input ? "on" : "off"); dev_dbg(pdev->dev, "Received CnQF %s\n", input ? "on" : "off");
...@@ -386,7 +382,7 @@ int amd_pmf_init_cnqf(struct amd_pmf_dev *dev) ...@@ -386,7 +382,7 @@ int amd_pmf_init_cnqf(struct amd_pmf_dev *dev)
dev->cnqf_enabled = amd_pmf_check_flags(dev); dev->cnqf_enabled = amd_pmf_check_flags(dev);
/* update the thermal for CnQF */ /* update the thermal for CnQF */
if (dev->cnqf_enabled && dev->current_profile == PLATFORM_PROFILE_BALANCED) { if (dev->cnqf_enabled && is_pprof_balanced(dev)) {
src = amd_pmf_cnqf_get_power_source(dev); src = amd_pmf_cnqf_get_power_source(dev);
amd_pmf_set_cnqf(dev, src, config_store.current_mode, NULL); amd_pmf_set_cnqf(dev, src, config_store.current_mode, NULL);
} }
......
...@@ -58,6 +58,25 @@ static bool force_load; ...@@ -58,6 +58,25 @@ static bool force_load;
module_param(force_load, bool, 0444); module_param(force_load, bool, 0444);
MODULE_PARM_DESC(force_load, "Force load this driver on supported older platforms (experimental)"); MODULE_PARM_DESC(force_load, "Force load this driver on supported older platforms (experimental)");
static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long event, void *data)
{
struct amd_pmf_dev *pmf = container_of(nb, struct amd_pmf_dev, pwr_src_notifier);
if (event != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
if (is_apmf_func_supported(pmf, APMF_FUNC_AUTO_MODE) ||
is_apmf_func_supported(pmf, APMF_FUNC_DYN_SLIDER_DC) ||
is_apmf_func_supported(pmf, APMF_FUNC_DYN_SLIDER_AC)) {
if ((pmf->amt_enabled || pmf->cnqf_enabled) && is_pprof_balanced(pmf))
return NOTIFY_DONE;
}
amd_pmf_set_sps_power_limits(pmf);
return NOTIFY_OK;
}
static int current_power_limits_show(struct seq_file *seq, void *unused) static int current_power_limits_show(struct seq_file *seq, void *unused)
{ {
struct amd_pmf_dev *dev = seq->private; struct amd_pmf_dev *dev = seq->private;
...@@ -366,14 +385,18 @@ static int amd_pmf_probe(struct platform_device *pdev) ...@@ -366,14 +385,18 @@ static int amd_pmf_probe(struct platform_device *pdev)
if (!dev->regbase) if (!dev->regbase)
return -ENOMEM; return -ENOMEM;
mutex_init(&dev->lock);
mutex_init(&dev->update_mutex);
apmf_acpi_init(dev); apmf_acpi_init(dev);
platform_set_drvdata(pdev, dev); platform_set_drvdata(pdev, dev);
amd_pmf_init_features(dev); amd_pmf_init_features(dev);
apmf_install_handler(dev); apmf_install_handler(dev);
amd_pmf_dbgfs_register(dev); amd_pmf_dbgfs_register(dev);
mutex_init(&dev->lock); dev->pwr_src_notifier.notifier_call = amd_pmf_pwr_src_notify_call;
mutex_init(&dev->update_mutex); power_supply_reg_notifier(&dev->pwr_src_notifier);
dev_info(dev->dev, "registered PMF device successfully\n"); dev_info(dev->dev, "registered PMF device successfully\n");
return 0; return 0;
...@@ -383,11 +406,12 @@ static int amd_pmf_remove(struct platform_device *pdev) ...@@ -383,11 +406,12 @@ static int amd_pmf_remove(struct platform_device *pdev)
{ {
struct amd_pmf_dev *dev = platform_get_drvdata(pdev); struct amd_pmf_dev *dev = platform_get_drvdata(pdev);
mutex_destroy(&dev->lock); power_supply_unreg_notifier(&dev->pwr_src_notifier);
mutex_destroy(&dev->update_mutex);
amd_pmf_deinit_features(dev); amd_pmf_deinit_features(dev);
apmf_acpi_deinit(dev); apmf_acpi_deinit(dev);
amd_pmf_dbgfs_unregister(dev); amd_pmf_dbgfs_unregister(dev);
mutex_destroy(&dev->lock);
mutex_destroy(&dev->update_mutex);
kfree(dev->buf); kfree(dev->buf);
return 0; return 0;
} }
......
...@@ -169,6 +169,7 @@ struct amd_pmf_dev { ...@@ -169,6 +169,7 @@ struct amd_pmf_dev {
struct mutex update_mutex; /* protects race between ACPI handler and metrics thread */ struct mutex update_mutex; /* protects race between ACPI handler and metrics thread */
bool cnqf_enabled; bool cnqf_enabled;
bool cnqf_supported; bool cnqf_supported;
struct notifier_block pwr_src_notifier;
}; };
struct apmf_sps_prop_granular { struct apmf_sps_prop_granular {
...@@ -391,9 +392,11 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev); ...@@ -391,9 +392,11 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev);
void amd_pmf_deinit_sps(struct amd_pmf_dev *dev); void amd_pmf_deinit_sps(struct amd_pmf_dev *dev);
int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev,
struct apmf_static_slider_granular_output *output); struct apmf_static_slider_granular_output *output);
bool is_pprof_balanced(struct amd_pmf_dev *pmf);
int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx); int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx);
int amd_pmf_set_sps_power_limits(struct amd_pmf_dev *pmf);
/* Auto Mode Layer */ /* Auto Mode Layer */
int apmf_get_auto_mode_def(struct amd_pmf_dev *pdev, struct apmf_auto_mode *data); int apmf_get_auto_mode_def(struct amd_pmf_dev *pdev, struct apmf_auto_mode *data);
......
...@@ -70,6 +70,24 @@ void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx, ...@@ -70,6 +70,24 @@ void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx,
} }
} }
int amd_pmf_set_sps_power_limits(struct amd_pmf_dev *pmf)
{
int mode;
mode = amd_pmf_get_pprof_modes(pmf);
if (mode < 0)
return mode;
amd_pmf_update_slider(pmf, SLIDER_OP_SET, mode, NULL);
return 0;
}
bool is_pprof_balanced(struct amd_pmf_dev *pmf)
{
return (pmf->current_profile == PLATFORM_PROFILE_BALANCED) ? true : false;
}
static int amd_pmf_profile_get(struct platform_profile_handler *pprof, static int amd_pmf_profile_get(struct platform_profile_handler *pprof,
enum platform_profile_option *profile) enum platform_profile_option *profile)
{ {
...@@ -105,15 +123,10 @@ static int amd_pmf_profile_set(struct platform_profile_handler *pprof, ...@@ -105,15 +123,10 @@ static int amd_pmf_profile_set(struct platform_profile_handler *pprof,
enum platform_profile_option profile) enum platform_profile_option profile)
{ {
struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof);
int mode;
pmf->current_profile = profile; pmf->current_profile = profile;
mode = amd_pmf_get_pprof_modes(pmf);
if (mode < 0)
return mode;
amd_pmf_update_slider(pmf, SLIDER_OP_SET, mode, NULL); return amd_pmf_set_sps_power_limits(pmf);
return 0;
} }
int amd_pmf_init_sps(struct amd_pmf_dev *dev) int amd_pmf_init_sps(struct amd_pmf_dev *dev)
...@@ -123,6 +136,9 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev) ...@@ -123,6 +136,9 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev)
dev->current_profile = PLATFORM_PROFILE_BALANCED; dev->current_profile = PLATFORM_PROFILE_BALANCED;
amd_pmf_load_defaults_sps(dev); amd_pmf_load_defaults_sps(dev);
/* update SPS balanced power mode thermals */
amd_pmf_set_sps_power_limits(dev);
dev->pprof.profile_get = amd_pmf_profile_get; dev->pprof.profile_get = amd_pmf_profile_get;
dev->pprof.profile_set = amd_pmf_profile_set; dev->pprof.profile_set = amd_pmf_profile_set;
......
...@@ -5563,7 +5563,7 @@ static int light_sysfs_set(struct led_classdev *led_cdev, ...@@ -5563,7 +5563,7 @@ static int light_sysfs_set(struct led_classdev *led_cdev,
static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev) static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
{ {
return (light_get_status() == 1) ? LED_FULL : LED_OFF; return (light_get_status() == 1) ? LED_ON : LED_OFF;
} }
static struct tpacpi_led_classdev tpacpi_led_thinklight = { static struct tpacpi_led_classdev tpacpi_led_thinklight = {
......
...@@ -1097,6 +1097,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = { ...@@ -1097,6 +1097,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_BIOS_DATE, "05/07/2016"), DMI_MATCH(DMI_BIOS_DATE, "05/07/2016"),
}, },
}, },
{
/* Chuwi Vi8 (CWI501) */
.driver_data = (void *)&chuwi_vi8_data,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
DMI_MATCH(DMI_PRODUCT_NAME, "i86"),
DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.W86JLBNR01"),
},
},
{ {
/* Chuwi Vi8 (CWI506) */ /* Chuwi Vi8 (CWI506) */
.driver_data = (void *)&chuwi_vi8_data, .driver_data = (void *)&chuwi_vi8_data,
......
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