Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

platform/x86: ideapad-laptop: Protect GBMD/SBMC calls with mutex

The upcoming changes for Rapid Charge support require two consecutive
SBMC calls to switch charge_types. Hence, a mutex is required.

No functional change intended.

Signed-off-by: Rong Zhang <i@rong.moe>
Acked-by: Ike Panhc <ikepanhc@gmail.com>
Link: https://patch.msgid.link/20251105182832.104946-3-i@rong.moe
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Rong Zhang and committed by
Ilpo Järvinen
85901a0d 06c129ca

+55 -34
+55 -34
drivers/platform/x86/lenovo/ideapad-laptop.c
··· 159 159 struct ideapad_private { 160 160 struct acpi_device *adev; 161 161 struct mutex vpc_mutex; /* protects the VPC calls */ 162 + struct mutex gbmd_sbmc_mutex; /* protects GBMD/SBMC calls */ 162 163 struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; 163 164 struct ideapad_rfk_priv rfk_priv[IDEAPAD_RFKILL_DEV_NUM]; 164 165 struct platform_device *platform_device; ··· 457 456 struct ideapad_private *priv = s->private; 458 457 unsigned long value; 459 458 460 - guard(mutex)(&priv->vpc_mutex); 459 + scoped_guard(mutex, &priv->vpc_mutex) { 460 + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &value)) 461 + seq_printf(s, "Backlight max: %lu\n", value); 462 + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL, &value)) 463 + seq_printf(s, "Backlight now: %lu\n", value); 464 + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &value)) 465 + seq_printf(s, "BL power value: %s (%lu)\n", str_on_off(value), value); 461 466 462 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &value)) 463 - seq_printf(s, "Backlight max: %lu\n", value); 464 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL, &value)) 465 - seq_printf(s, "Backlight now: %lu\n", value); 466 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &value)) 467 - seq_printf(s, "BL power value: %s (%lu)\n", str_on_off(value), value); 467 + seq_puts(s, "=====================\n"); 468 + 469 + if (!read_ec_data(priv->adev->handle, VPCCMD_R_RF, &value)) 470 + seq_printf(s, "Radio status: %s (%lu)\n", str_on_off(value), value); 471 + if (!read_ec_data(priv->adev->handle, VPCCMD_R_WIFI, &value)) 472 + seq_printf(s, "Wifi status: %s (%lu)\n", str_on_off(value), value); 473 + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BT, &value)) 474 + seq_printf(s, "BT status: %s (%lu)\n", str_on_off(value), value); 475 + if (!read_ec_data(priv->adev->handle, VPCCMD_R_3G, &value)) 476 + seq_printf(s, "3G status: %s (%lu)\n", str_on_off(value), value); 477 + 478 + seq_puts(s, "=====================\n"); 479 + 480 + if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) 481 + seq_printf(s, "Touchpad status: %s (%lu)\n", str_on_off(value), value); 482 + if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value)) 483 + seq_printf(s, "Camera status: %s (%lu)\n", str_on_off(value), value); 484 + } 468 485 469 486 seq_puts(s, "=====================\n"); 470 487 471 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_RF, &value)) 472 - seq_printf(s, "Radio status: %s (%lu)\n", str_on_off(value), value); 473 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_WIFI, &value)) 474 - seq_printf(s, "Wifi status: %s (%lu)\n", str_on_off(value), value); 475 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_BT, &value)) 476 - seq_printf(s, "BT status: %s (%lu)\n", str_on_off(value), value); 477 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_3G, &value)) 478 - seq_printf(s, "3G status: %s (%lu)\n", str_on_off(value), value); 488 + scoped_guard(mutex, &priv->gbmd_sbmc_mutex) { 489 + if (!eval_gbmd(priv->adev->handle, &value)) 490 + seq_printf(s, "GBMD: %#010lx\n", value); 491 + } 479 492 480 - seq_puts(s, "=====================\n"); 481 - 482 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) 483 - seq_printf(s, "Touchpad status: %s (%lu)\n", str_on_off(value), value); 484 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value)) 485 - seq_printf(s, "Camera status: %s (%lu)\n", str_on_off(value), value); 486 - 487 - seq_puts(s, "=====================\n"); 488 - 489 - if (!eval_gbmd(priv->adev->handle, &value)) 490 - seq_printf(s, "GBMD: %#010lx\n", value); 491 493 if (!eval_hals(priv->adev->handle, &value)) 492 494 seq_printf(s, "HALS: %#010lx\n", value); 493 495 ··· 627 623 628 624 show_conservation_mode_deprecation_warning(dev); 629 625 630 - err = eval_gbmd(priv->adev->handle, &result); 631 - if (err) 632 - return err; 626 + scoped_guard(mutex, &priv->gbmd_sbmc_mutex) { 627 + err = eval_gbmd(priv->adev->handle, &result); 628 + if (err) 629 + return err; 630 + } 633 631 634 632 return sysfs_emit(buf, "%d\n", !!test_bit(GBMD_CONSERVATION_STATE_BIT, &result)); 635 633 } ··· 649 643 err = kstrtobool(buf, &state); 650 644 if (err) 651 645 return err; 646 + 647 + guard(mutex)(&priv->gbmd_sbmc_mutex); 652 648 653 649 err = exec_sbmc(priv->adev->handle, state ? SBMC_CONSERVATION_ON : SBMC_CONSERVATION_OFF); 654 650 if (err) ··· 2016 2008 const union power_supply_propval *val) 2017 2009 { 2018 2010 struct ideapad_private *priv = ext_data; 2011 + unsigned long op; 2019 2012 2020 2013 switch (val->intval) { 2021 2014 case POWER_SUPPLY_CHARGE_TYPE_LONGLIFE: 2022 - return exec_sbmc(priv->adev->handle, SBMC_CONSERVATION_ON); 2015 + op = SBMC_CONSERVATION_ON; 2016 + break; 2023 2017 case POWER_SUPPLY_CHARGE_TYPE_STANDARD: 2024 - return exec_sbmc(priv->adev->handle, SBMC_CONSERVATION_OFF); 2018 + op = SBMC_CONSERVATION_OFF; 2019 + break; 2025 2020 default: 2026 2021 return -EINVAL; 2027 2022 } 2023 + 2024 + guard(mutex)(&priv->gbmd_sbmc_mutex); 2025 + 2026 + return exec_sbmc(priv->adev->handle, op); 2028 2027 } 2029 2028 2030 2029 static int ideapad_psy_ext_get_prop(struct power_supply *psy, ··· 2044 2029 unsigned long result; 2045 2030 int err; 2046 2031 2047 - err = eval_gbmd(priv->adev->handle, &result); 2048 - if (err) 2049 - return err; 2032 + scoped_guard(mutex, &priv->gbmd_sbmc_mutex) { 2033 + err = eval_gbmd(priv->adev->handle, &result); 2034 + if (err) 2035 + return err; 2036 + } 2050 2037 2051 2038 if (test_bit(GBMD_CONSERVATION_STATE_BIT, &result)) 2052 2039 val->intval = POWER_SUPPLY_CHARGE_TYPE_LONGLIFE; ··· 2307 2290 priv->platform_device = pdev; 2308 2291 2309 2292 err = devm_mutex_init(&pdev->dev, &priv->vpc_mutex); 2293 + if (err) 2294 + return err; 2295 + 2296 + err = devm_mutex_init(&pdev->dev, &priv->gbmd_sbmc_mutex); 2310 2297 if (err) 2311 2298 return err; 2312 2299