diff options
author | Jan200101 <sentrycraft123@gmail.com> | 2024-07-09 20:44:55 +0200 |
---|---|---|
committer | Jan200101 <sentrycraft123@gmail.com> | 2024-07-09 20:44:55 +0200 |
commit | b3bf69e0b6d610746c995da45a6751134461b6a7 (patch) | |
tree | fa0d40f9c800fedbcfab52bd86c76e731465b0e8 /SOURCES | |
parent | af581927ea286aadd5c1bd5224ad7d22536210e9 (diff) | |
download | kernel-fsync-b3bf69e0b6d610746c995da45a6751134461b6a7.tar.gz kernel-fsync-b3bf69e0b6d610746c995da45a6751134461b6a7.zip |
kernel 6.9.8
Diffstat (limited to 'SOURCES')
-rw-r--r-- | SOURCES/0001-Revert-drm-i915-mtl-Add-fake-PCH-for-Meteor-Lake.patch | 221 | ||||
-rw-r--r-- | SOURCES/0001-add-support-for-ally-x-mcu-switch.patch | 29 | ||||
-rw-r--r-- | SOURCES/asus-linux.patch | 3433 | ||||
-rw-r--r-- | SOURCES/kernel-aarch64-16k-debug-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel-aarch64-16k-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel-aarch64-debug-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel-aarch64-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel-ppc64le-debug-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel-ppc64le-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel-s390x-debug-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel-s390x-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel-x86_64-debug-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel-x86_64-fedora.config | 2 | ||||
-rw-r--r-- | SOURCES/kernel.changelog | 6 | ||||
-rw-r--r-- | SOURCES/patch-6.9-redhat.patch | 76 | ||||
-rw-r--r-- | SOURCES/v14.8-0004-HID-asus-add-ROG-Ally-xpad-settings.patch | 9 |
16 files changed, 3569 insertions, 225 deletions
diff --git a/SOURCES/0001-Revert-drm-i915-mtl-Add-fake-PCH-for-Meteor-Lake.patch b/SOURCES/0001-Revert-drm-i915-mtl-Add-fake-PCH-for-Meteor-Lake.patch new file mode 100644 index 0000000..c01e878 --- /dev/null +++ b/SOURCES/0001-Revert-drm-i915-mtl-Add-fake-PCH-for-Meteor-Lake.patch @@ -0,0 +1,221 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jan200101 <sentrycraft123@gmail.com> +Date: Tue, 9 Jul 2024 19:51:54 +0200 +Subject: [PATCH] Revert "drm/i915/mtl: Add fake PCH for Meteor Lake" + +This reverts commit 93cbc1accbcec2740231755774420934658e2b18. + +Signed-off-by: Jan200101 <sentrycraft123@gmail.com> +--- + drivers/gpu/drm/i915/display/intel_backlight.c | 2 +- + drivers/gpu/drm/i915/display/intel_bios.c | 3 ++- + drivers/gpu/drm/i915/display/intel_cdclk.c | 6 +++--- + drivers/gpu/drm/i915/display/intel_display_irq.c | 2 +- + drivers/gpu/drm/i915/display/intel_gmbus.c | 5 ++++- + drivers/gpu/drm/i915/display/intel_hotplug_irq.c | 6 ++++-- + drivers/gpu/drm/i915/display/intel_pps.c | 2 +- + drivers/gpu/drm/i915/soc/intel_pch.c | 16 ++++++++-------- + drivers/gpu/drm/i915/soc/intel_pch.h | 6 +++++- + 9 files changed, 29 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c +index 1946d7fb3c2e..3f3cd944a1c5 100644 +--- a/drivers/gpu/drm/i915/display/intel_backlight.c ++++ b/drivers/gpu/drm/i915/display/intel_backlight.c +@@ -1465,7 +1465,7 @@ static bool cnp_backlight_controller_is_valid(struct drm_i915_private *i915, int + + if (controller == 1 && + INTEL_PCH_TYPE(i915) >= PCH_ICP && +- INTEL_PCH_TYPE(i915) <= PCH_ADP) ++ INTEL_PCH_TYPE(i915) < PCH_MTP) + return intel_de_read(i915, SOUTH_CHICKEN1) & ICP_SECOND_PPS_IO_SELECT; + + return true; +diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c +index 7d1e443f97b9..02ec8e52dd7d 100644 +--- a/drivers/gpu/drm/i915/display/intel_bios.c ++++ b/drivers/gpu/drm/i915/display/intel_bios.c +@@ -2228,7 +2228,8 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin) + if (IS_DGFX(i915)) + return vbt_pin; + +- if (INTEL_PCH_TYPE(i915) >= PCH_MTL || IS_ALDERLAKE_P(i915)) { ++ if (INTEL_PCH_TYPE(i915) >= PCH_LNL || HAS_PCH_MTP(i915) || ++ IS_ALDERLAKE_P(i915)) { + ddc_pin_map = adlp_ddc_pin_map; + n_entries = ARRAY_SIZE(adlp_ddc_pin_map); + } else if (IS_ALDERLAKE_S(i915)) { +diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c +index f672bfd70d45..789b3a379363 100644 +--- a/drivers/gpu/drm/i915/display/intel_cdclk.c ++++ b/drivers/gpu/drm/i915/display/intel_cdclk.c +@@ -3509,15 +3509,15 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) + { + u32 freq; + +- if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTL) ++ if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) ++ freq = dg1_rawclk(dev_priv); ++ else if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTP) + /* + * MTL always uses a 38.4 MHz rawclk. The bspec tells us + * "RAWCLK_FREQ defaults to the values for 38.4 and does + * not need to be programmed." + */ + freq = 38400; +- else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) +- freq = dg1_rawclk(dev_priv); + else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) + freq = cnp_rawclk(dev_priv); + else if (HAS_PCH_SPLIT(dev_priv)) +diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c +index f846c5b108b5..f950a87392cf 100644 +--- a/drivers/gpu/drm/i915/display/intel_display_irq.c ++++ b/drivers/gpu/drm/i915/display/intel_display_irq.c +@@ -986,7 +986,7 @@ static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_i + * their flags both in the PICA and SDE IIR. + */ + if (*pch_iir & SDE_PICAINTERRUPT) { +- drm_WARN_ON(&i915->drm, INTEL_PCH_TYPE(i915) < PCH_MTL); ++ drm_WARN_ON(&i915->drm, INTEL_PCH_TYPE(i915) < PCH_MTP); + + pica_ier = intel_de_rmw(i915, PICAINTERRUPT_IER, ~0, 0); + *pica_iir = intel_de_read(i915, PICAINTERRUPT_IIR); +diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c +index d3e03ed5b79c..e9e4dcf345f9 100644 +--- a/drivers/gpu/drm/i915/display/intel_gmbus.c ++++ b/drivers/gpu/drm/i915/display/intel_gmbus.c +@@ -155,7 +155,7 @@ static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *i915, + const struct gmbus_pin *pins; + size_t size; + +- if (INTEL_PCH_TYPE(i915) >= PCH_MTL) { ++ if (INTEL_PCH_TYPE(i915) >= PCH_LNL) { + pins = gmbus_pins_mtp; + size = ARRAY_SIZE(gmbus_pins_mtp); + } else if (INTEL_PCH_TYPE(i915) >= PCH_DG2) { +@@ -164,6 +164,9 @@ static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *i915, + } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) { + pins = gmbus_pins_dg1; + size = ARRAY_SIZE(gmbus_pins_dg1); ++ } else if (INTEL_PCH_TYPE(i915) >= PCH_MTP) { ++ pins = gmbus_pins_mtp; ++ size = ARRAY_SIZE(gmbus_pins_mtp); + } else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) { + pins = gmbus_pins_icp; + size = ARRAY_SIZE(gmbus_pins_icp); +diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c +index 76076509f771..04f62f27ad74 100644 +--- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c ++++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c +@@ -163,10 +163,12 @@ static void intel_hpd_init_pins(struct drm_i915_private *dev_priv) + (!HAS_PCH_SPLIT(dev_priv) || HAS_PCH_NOP(dev_priv))) + return; + +- if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTL) ++ if (INTEL_PCH_TYPE(dev_priv) >= PCH_LNL) + hpd->pch_hpd = hpd_mtp; + else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) + hpd->pch_hpd = hpd_sde_dg1; ++ else if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTP) ++ hpd->pch_hpd = hpd_mtp; + else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) + hpd->pch_hpd = hpd_icp; + else if (HAS_PCH_CNP(dev_priv) || HAS_PCH_SPT(dev_priv)) +@@ -1137,7 +1139,7 @@ static void xelpdp_hpd_irq_setup(struct drm_i915_private *i915) + + if (INTEL_PCH_TYPE(i915) >= PCH_LNL) + xe2lpd_sde_hpd_irq_setup(i915); +- else if (INTEL_PCH_TYPE(i915) >= PCH_MTL) ++ else if (INTEL_PCH_TYPE(i915) >= PCH_MTP) + mtp_hpd_irq_setup(i915); + } + +diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c +index 2d65a538f83e..a8fa3a20990e 100644 +--- a/drivers/gpu/drm/i915/display/intel_pps.c ++++ b/drivers/gpu/drm/i915/display/intel_pps.c +@@ -366,7 +366,7 @@ static bool intel_pps_is_valid(struct intel_dp *intel_dp) + + if (intel_dp->pps.pps_idx == 1 && + INTEL_PCH_TYPE(i915) >= PCH_ICP && +- INTEL_PCH_TYPE(i915) <= PCH_ADP) ++ INTEL_PCH_TYPE(i915) < PCH_MTP) + return intel_de_read(i915, SOUTH_CHICKEN1) & ICP_SECOND_PPS_IO_SELECT; + + return true; +diff --git a/drivers/gpu/drm/i915/soc/intel_pch.c b/drivers/gpu/drm/i915/soc/intel_pch.c +index 3cad6dac06b0..240beafb38ed 100644 +--- a/drivers/gpu/drm/i915/soc/intel_pch.c ++++ b/drivers/gpu/drm/i915/soc/intel_pch.c +@@ -140,6 +140,11 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id) + drm_WARN_ON(&dev_priv->drm, !IS_ALDERLAKE_S(dev_priv) && + !IS_ALDERLAKE_P(dev_priv)); + return PCH_ADP; ++ case INTEL_PCH_MTP_DEVICE_ID_TYPE: ++ case INTEL_PCH_MTP2_DEVICE_ID_TYPE: ++ drm_dbg_kms(&dev_priv->drm, "Found Meteor Lake PCH\n"); ++ drm_WARN_ON(&dev_priv->drm, !IS_METEORLAKE(dev_priv)); ++ return PCH_MTP; + default: + return PCH_NONE; + } +@@ -168,7 +173,9 @@ intel_virt_detect_pch(const struct drm_i915_private *dev_priv, + * make an educated guess as to which PCH is really there. + */ + +- if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) ++ if (IS_METEORLAKE(dev_priv)) ++ id = INTEL_PCH_MTP_DEVICE_ID_TYPE; ++ else if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) + id = INTEL_PCH_ADP_DEVICE_ID_TYPE; + else if (IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) + id = INTEL_PCH_TGP_DEVICE_ID_TYPE; +@@ -218,13 +225,6 @@ void intel_detect_pch(struct drm_i915_private *dev_priv) + if (DISPLAY_VER(dev_priv) >= 20) { + dev_priv->pch_type = PCH_LNL; + return; +- } else if (IS_METEORLAKE(dev_priv)) { +- /* +- * Both north display and south display are on the SoC die. +- * The real PCH is uninvolved in display. +- */ +- dev_priv->pch_type = PCH_MTL; +- return; + } else if (IS_DG2(dev_priv)) { + dev_priv->pch_type = PCH_DG2; + return; +diff --git a/drivers/gpu/drm/i915/soc/intel_pch.h b/drivers/gpu/drm/i915/soc/intel_pch.h +index 89e89ede265d..1b03ea60a7a8 100644 +--- a/drivers/gpu/drm/i915/soc/intel_pch.h ++++ b/drivers/gpu/drm/i915/soc/intel_pch.h +@@ -25,11 +25,11 @@ enum intel_pch { + PCH_ICP, /* Ice Lake/Jasper Lake PCH */ + PCH_TGP, /* Tiger Lake/Mule Creek Canyon PCH */ + PCH_ADP, /* Alder Lake PCH */ ++ PCH_MTP, /* Meteor Lake PCH */ + + /* Fake PCHs, functionality handled on the same PCI dev */ + PCH_DG1 = 1024, + PCH_DG2, +- PCH_MTL, + PCH_LNL, + }; + +@@ -59,12 +59,16 @@ enum intel_pch { + #define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180 + #define INTEL_PCH_ADP3_DEVICE_ID_TYPE 0x7A00 + #define INTEL_PCH_ADP4_DEVICE_ID_TYPE 0x5480 ++#define INTEL_PCH_MTP_DEVICE_ID_TYPE 0x7E00 ++#define INTEL_PCH_MTP2_DEVICE_ID_TYPE 0xAE00 + #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 + #define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 + #define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ + + #define INTEL_PCH_TYPE(dev_priv) ((dev_priv)->pch_type) + #define INTEL_PCH_ID(dev_priv) ((dev_priv)->pch_id) ++#define HAS_PCH_LNL(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LNL) ++#define HAS_PCH_MTP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_MTP) + #define HAS_PCH_DG2(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_DG2) + #define HAS_PCH_ADP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_ADP) + #define HAS_PCH_DG1(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_DG1) diff --git a/SOURCES/0001-add-support-for-ally-x-mcu-switch.patch b/SOURCES/0001-add-support-for-ally-x-mcu-switch.patch new file mode 100644 index 0000000..266d639 --- /dev/null +++ b/SOURCES/0001-add-support-for-ally-x-mcu-switch.patch @@ -0,0 +1,29 @@ +From d821616f57bc2d47bdef54edf43a6bd63249c4ef Mon Sep 17 00:00:00 2001 +From: antheas <antheas@users.noreply.github.com> +Date: Tue, 9 Jul 2024 13:10:31 +0300 +Subject: [PATCH 1/2] add support for ally x mcu switch + +--- + drivers/platform/x86/asus-wmi.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 3f9b6285c..16c8745e1 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -4645,8 +4645,10 @@ static int asus_wmi_add(struct platform_device *pdev) + asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU); + asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU); + asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE); +- asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE) +- && dmi_match(DMI_BOARD_NAME, "RC71L"); ++ asus->ally_mcu_usb_switch = ++ acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE) && ++ (dmi_match(DMI_BOARD_NAME, "RC71L") || ++ dmi_match(DMI_BOARD_NAME, "RC72L")); + + if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE)) + asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE; +-- +2.45.2 + diff --git a/SOURCES/asus-linux.patch b/SOURCES/asus-linux.patch index 569a7b7..461ab82 100644 --- a/SOURCES/asus-linux.patch +++ b/SOURCES/asus-linux.patch @@ -1,19 +1,23 @@ -From 0616986582dd55686774bf7b60c61f3c36db9896 Mon Sep 17 00:00:00 2001 +From a120838990cea1397e9bacb303b41ab83fa76d8c Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Sun, 10 Mar 2024 15:14:37 +1300 -Subject: [PATCH v1 1/9] platform/x86: asus-wmi: add support for 2024 ROG +Subject: [PATCH v4 1/9] platform/x86: asus-wmi: add support for 2024 ROG Mini-LED +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Support the 2024 mini-led backlight and adjust the related functions to select the relevant dev-id. Also add `available_mini_led_mode` to the platform sysfs since the available mini-led levels can be different. -Signed-off-by: Luke D. Jones <luke@ljones.dev> +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +signed-off-by: Luke D. Jones <luke@ljones.dev> --- .../ABI/testing/sysfs-platform-asus-wmi | 8 ++ - drivers/platform/x86/asus-wmi.c | 81 ++++++++++++++++--- + drivers/platform/x86/asus-wmi.c | 96 +++++++++++++++++-- include/linux/platform_data/x86/asus-wmi.h | 1 + - 3 files changed, 79 insertions(+), 11 deletions(-) + 3 files changed, 95 insertions(+), 10 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi index 8a7e25bde085..ef1ac1a20a71 100644 @@ -35,10 +39,28 @@ index 8a7e25bde085..ef1ac1a20a71 100644 What: /sys/devices/platform/<platform>/ppt_pl1_spl Date: Jun 2023 diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 3f07bbf809ef..646f70c65097 100644 +index 3f07bbf809ef..aa2a3b402e33 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -288,7 +288,7 @@ struct asus_wmi { +@@ -126,6 +126,17 @@ module_param(fnlock_default, bool, 0444); + #define ASUS_SCREENPAD_BRIGHT_MAX 255 + #define ASUS_SCREENPAD_BRIGHT_DEFAULT 60 + ++#define ASUS_MINI_LED_MODE_MASK 0x03 ++/* Standard modes for devices with only on/off */ ++#define ASUS_MINI_LED_OFF 0x00 ++#define ASUS_MINI_LED_ON 0x01 ++/* New mode on some devices, define here to clarify remapping later */ ++#define ASUS_MINI_LED_STRONG_MODE 0x02 ++/* New modes for devices with 3 mini-led mode types */ ++#define ASUS_MINI_LED_2024_WEAK 0x00 ++#define ASUS_MINI_LED_2024_STRONG 0x01 ++#define ASUS_MINI_LED_2024_OFF 0x02 ++ + /* Controls the power state of the USB0 hub on ROG Ally which input is on */ + #define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE" + /* 300ms so far seems to produce a reliable result on AC and battery */ +@@ -288,7 +299,7 @@ struct asus_wmi { bool battery_rsoc_available; bool panel_overdrive_available; @@ -47,75 +69,81 @@ index 3f07bbf809ef..646f70c65097 100644 struct hotplug_slot hotplug_slot; struct mutex hotplug_lock; -@@ -2108,13 +2108,30 @@ static ssize_t mini_led_mode_show(struct device *dev, +@@ -2108,13 +2119,33 @@ static ssize_t mini_led_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct asus_wmi *asus = dev_get_drvdata(dev); - int result; + u32 value; ++ int err; - result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MINI_LED_MODE); - if (result < 0) - return result; -+ asus_wmi_get_devstate(asus, asus->mini_led_dev_id, &value); -+ value = value & 0x03; // only 3 modes on 2024 version ++ err = asus_wmi_get_devstate(asus, asus->mini_led_dev_id, &value); ++ if (err < 0) ++ return err; ++ value = value & ASUS_MINI_LED_MODE_MASK; - return sysfs_emit(buf, "%d\n", result); -+ /* Remap the mode values to match previous generation mini-led. -+ * Some BIOSes return -19 instead of 2, which is "mini-LED off", this -+ * appears to be a BIOS bug. ++ /* ++ * Remap the mode values to match previous generation mini-led. The last gen ++ * WMI 0 == off, while on this version WMI 2 ==off (flipped). + */ + if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) { + switch (value) { -+ case 0: -+ value = 1; ++ case ASUS_MINI_LED_2024_WEAK: ++ value = ASUS_MINI_LED_ON; ++ break; ++ case ASUS_MINI_LED_2024_STRONG: ++ value = ASUS_MINI_LED_STRONG_MODE; + break; -+ case 1: -+ value = 2; ++ case ASUS_MINI_LED_2024_OFF: ++ value = ASUS_MINI_LED_OFF; + break; -+ case 2: -+ value = 0; + } -+ } else if (value < 0) { -+ return value; + } ++ + return sysfs_emit(buf, "%d\n", value); } static ssize_t mini_led_mode_store(struct device *dev, -@@ -2130,11 +2147,28 @@ static ssize_t mini_led_mode_store(struct device *dev, +@@ -2130,11 +2161,32 @@ static ssize_t mini_led_mode_store(struct device *dev, if (result) return result; - if (mode > 1) -+ if (mode > 1 && asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE) - return -EINVAL; -+ if (mode > 2 && asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) ++ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE && ++ mode > ASUS_MINI_LED_ON) + return -EINVAL; ++ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2 && ++ mode > ASUS_MINI_LED_STRONG_MODE) + return -EINVAL; + +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MINI_LED_MODE, mode, &result); + /* + * Remap the mode values so expected behaviour is the same as the last -+ * generation of mini-LED ++ * generation of mini-LED with 0 == off, 1 == on. + */ + if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) { + switch (mode) { -+ case 0: -+ mode = 2; ++ case ASUS_MINI_LED_OFF: ++ mode = ASUS_MINI_LED_2024_OFF; ++ break; ++ case ASUS_MINI_LED_ON: ++ mode = ASUS_MINI_LED_2024_WEAK; + break; -+ case 1: -+ mode = 0; ++ case ASUS_MINI_LED_STRONG_MODE: ++ mode = ASUS_MINI_LED_2024_STRONG; + break; -+ case 2: -+ mode = 1; + } + } -- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MINI_LED_MODE, mode, &result); -- + err = asus_wmi_set_devstate(asus->mini_led_dev_id, mode, &result); if (err) { pr_warn("Failed to set mini-LED: %d\n", err); return err; -@@ -2151,6 +2185,23 @@ static ssize_t mini_led_mode_store(struct device *dev, +@@ -2151,6 +2203,23 @@ static ssize_t mini_led_mode_store(struct device *dev, } static DEVICE_ATTR_RW(mini_led_mode); @@ -139,7 +167,7 @@ index 3f07bbf809ef..646f70c65097 100644 /* Quirks *********************************************************************/ static void asus_wmi_set_xusb2pr(struct asus_wmi *asus) -@@ -4139,6 +4190,7 @@ static struct attribute *platform_attributes[] = { +@@ -4139,6 +4208,7 @@ static struct attribute *platform_attributes[] = { &dev_attr_nv_temp_target.attr, &dev_attr_panel_od.attr, &dev_attr_mini_led_mode.attr, @@ -147,7 +175,7 @@ index 3f07bbf809ef..646f70c65097 100644 NULL }; -@@ -4191,7 +4243,9 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, +@@ -4191,7 +4261,9 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, else if (attr == &dev_attr_panel_od.attr) ok = asus->panel_overdrive_available; else if (attr == &dev_attr_mini_led_mode.attr) @@ -158,7 +186,7 @@ index 3f07bbf809ef..646f70c65097 100644 if (devid != -1) ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); -@@ -4444,10 +4498,15 @@ static int asus_wmi_add(struct platform_device *pdev) +@@ -4444,10 +4516,14 @@ static int asus_wmi_add(struct platform_device *pdev) asus->nv_dyn_boost_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_DYN_BOOST); asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET); asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD); @@ -166,11 +194,10 @@ index 3f07bbf809ef..646f70c65097 100644 asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE) && dmi_match(DMI_BOARD_NAME, "RC71L"); -+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE)) { ++ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE)) + asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE; -+ } else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE2)) { ++ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE2)) + asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2; -+ } + err = fan_boost_mode_check_present(asus); if (err) @@ -190,11 +217,14 @@ index ab1c7deff118..9cadce10ad9a 100644 -- 2.44.0 -From b3b581a08241bd10b81dddcca9ee43e2fc8bc79d Mon Sep 17 00:00:00 2001 +From b54d273cb1fddcf9ae2618447e23b9f62730e15f Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Sun, 10 Mar 2024 17:10:05 +1300 -Subject: [PATCH v1 2/9] platform/x86: asus-wmi: add support for Vivobook GPU +Subject: [PATCH v4 2/9] platform/x86: asus-wmi: add support for Vivobook GPU MUX +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Add support for the Vivobook dgpu MUX available on the ASUS Viviobook and some of the other ranges (Zen). @@ -203,17 +233,18 @@ This MUX functions exactly the same as the existing ROG MUX support so the existing functionality now detects which MUX is available and uses that for control. +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Luke D. Jones <luke@ljones.dev> --- - drivers/platform/x86/asus-wmi.c | 23 +++++++++++++--------- + drivers/platform/x86/asus-wmi.c | 22 +++++++++++++--------- include/linux/platform_data/x86/asus-wmi.h | 1 + - 2 files changed, 15 insertions(+), 9 deletions(-) + 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 646f70c65097..7d7a9c8ee529 100644 +index aa2a3b402e33..1ab4380e9771 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -259,7 +259,7 @@ struct asus_wmi { +@@ -270,7 +270,7 @@ struct asus_wmi { bool egpu_enable_available; bool egpu_connect_available; bool dgpu_disable_available; @@ -222,7 +253,7 @@ index 646f70c65097..7d7a9c8ee529 100644 /* Tunables provided by ASUS for gaming laptops */ bool ppt_pl2_sppt_available; -@@ -682,8 +682,8 @@ static ssize_t dgpu_disable_store(struct device *dev, +@@ -693,8 +693,8 @@ static ssize_t dgpu_disable_store(struct device *dev, if (disable > 1) return -EINVAL; @@ -233,7 +264,7 @@ index 646f70c65097..7d7a9c8ee529 100644 if (result < 0) /* An error here may signal greater failure of GPU handling */ return result; -@@ -748,8 +748,8 @@ static ssize_t egpu_enable_store(struct device *dev, +@@ -759,8 +759,8 @@ static ssize_t egpu_enable_store(struct device *dev, return err; } @@ -244,7 +275,7 @@ index 646f70c65097..7d7a9c8ee529 100644 if (result < 0) { /* An error here may signal greater failure of GPU handling */ pr_warn("Failed to get gpu mux status: %d\n", result); -@@ -802,7 +802,7 @@ static ssize_t gpu_mux_mode_show(struct device *dev, +@@ -813,7 +813,7 @@ static ssize_t gpu_mux_mode_show(struct device *dev, struct asus_wmi *asus = dev_get_drvdata(dev); int result; @@ -253,7 +284,7 @@ index 646f70c65097..7d7a9c8ee529 100644 if (result < 0) return result; -@@ -848,7 +848,7 @@ static ssize_t gpu_mux_mode_store(struct device *dev, +@@ -859,7 +859,7 @@ static ssize_t gpu_mux_mode_store(struct device *dev, } } @@ -262,7 +293,7 @@ index 646f70c65097..7d7a9c8ee529 100644 if (err) { dev_err(dev, "Failed to set GPU MUX mode: %d\n", err); return err; -@@ -4221,7 +4221,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, +@@ -4239,7 +4239,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, else if (attr == &dev_attr_dgpu_disable.attr) ok = asus->dgpu_disable_available; else if (attr == &dev_attr_gpu_mux_mode.attr) @@ -271,7 +302,7 @@ index 646f70c65097..7d7a9c8ee529 100644 else if (attr == &dev_attr_fan_boost_mode.attr) ok = asus->fan_boost_mode_available; else if (attr == &dev_attr_throttle_thermal_policy.attr) -@@ -4487,7 +4487,6 @@ static int asus_wmi_add(struct platform_device *pdev) +@@ -4505,7 +4505,6 @@ static int asus_wmi_add(struct platform_device *pdev) asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU); asus->egpu_connect_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU_CONNECTED); asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU); @@ -279,15 +310,14 @@ index 646f70c65097..7d7a9c8ee529 100644 asus->kbd_rgb_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE); asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE); asus->ppt_pl2_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL2_SPPT); -@@ -4507,6 +4506,12 @@ static int asus_wmi_add(struct platform_device *pdev) +@@ -4524,6 +4523,11 @@ static int asus_wmi_add(struct platform_device *pdev) + else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE2)) asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2; - } -+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX)) { ++ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX)) + asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX; -+ } else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX_VIVO)) { ++ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX_VIVO)) + asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX_VIVO; -+ } + err = fan_boost_mode_check_present(asus); if (err) @@ -307,26 +337,30 @@ index 9cadce10ad9a..b48b024dd844 100644 -- 2.44.0 -From b2e77f69e0f8cabd5e90f80aea2a441800c19923 Mon Sep 17 00:00:00 2001 +From 3baa8b981e24bb1ae4e468085e89241a0439d259 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Sun, 10 Mar 2024 17:20:02 +1300 -Subject: [PATCH v1 3/9] platform/x86: asus-wmi: add support variant of TUF RGB +Subject: [PATCH v4 3/9] platform/x86: asus-wmi: add support variant of TUF RGB +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Adds support for a second TUF RGB wmi call that some versions of the TUF laptop come with. Also adjusts existing support to select whichever is available. +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Luke D. Jones <luke@ljones.dev> --- - drivers/platform/x86/asus-wmi.c | 14 ++++++++++---- + drivers/platform/x86/asus-wmi.c | 13 +++++++++---- include/linux/platform_data/x86/asus-wmi.h | 1 + - 2 files changed, 11 insertions(+), 4 deletions(-) + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 7d7a9c8ee529..fa5735af7675 100644 +index 1ab4380e9771..6896d056d227 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -270,7 +270,7 @@ struct asus_wmi { +@@ -281,7 +281,7 @@ struct asus_wmi { bool nv_dyn_boost_available; bool nv_temp_tgt_available; @@ -335,7 +369,7 @@ index 7d7a9c8ee529..fa5735af7675 100644 bool kbd_rgb_state_available; bool throttle_thermal_policy_available; -@@ -870,6 +870,7 @@ static ssize_t kbd_rgb_mode_store(struct device *dev, +@@ -881,6 +881,7 @@ static ssize_t kbd_rgb_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -343,7 +377,7 @@ index 7d7a9c8ee529..fa5735af7675 100644 u32 cmd, mode, r, g, b, speed; int err; -@@ -906,7 +907,7 @@ static ssize_t kbd_rgb_mode_store(struct device *dev, +@@ -917,7 +918,7 @@ static ssize_t kbd_rgb_mode_store(struct device *dev, speed = 0xeb; } @@ -352,7 +386,7 @@ index 7d7a9c8ee529..fa5735af7675 100644 cmd | (mode << 8) | (r << 16) | (g << 24), b | (speed << 8), NULL); if (err) return err; -@@ -1549,7 +1550,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus) +@@ -1560,7 +1561,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus) { int rv = 0, num_rgb_groups = 0, led_val; @@ -361,7 +395,7 @@ index 7d7a9c8ee529..fa5735af7675 100644 kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_mode_group; if (asus->kbd_rgb_state_available) kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_state_group; -@@ -4487,7 +4488,6 @@ static int asus_wmi_add(struct platform_device *pdev) +@@ -4505,7 +4506,6 @@ static int asus_wmi_add(struct platform_device *pdev) asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU); asus->egpu_connect_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU_CONNECTED); asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU); @@ -369,15 +403,14 @@ index 7d7a9c8ee529..fa5735af7675 100644 asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE); asus->ppt_pl2_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL2_SPPT); asus->ppt_pl1_spl_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL1_SPL); -@@ -4512,6 +4512,12 @@ static int asus_wmi_add(struct platform_device *pdev) +@@ -4528,6 +4528,11 @@ static int asus_wmi_add(struct platform_device *pdev) + else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX_VIVO)) asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX_VIVO; - } -+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE)) { ++ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE)) + asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE; -+ } else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2)) { ++ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2)) + asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE2; -+ } + err = fan_boost_mode_check_present(asus); if (err) @@ -397,13 +430,17 @@ index b48b024dd844..3e9a01467c67 100644 -- 2.44.0 -From 9926e49f27d0e3059a35b5baaa90a0eec611dc38 Mon Sep 17 00:00:00 2001 +From 37f3b097a3f245ab8a12befd37e2d76ed6ebf85f Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Sun, 10 Mar 2024 19:03:11 +1300 -Subject: [PATCH v1 4/9] platform/x86: asus-wmi: support toggling POST sound +Subject: [PATCH v4 4/9] platform/x86: asus-wmi: support toggling POST sound +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Add support for toggling the BIOS POST sound on some ASUS laptops. +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Luke D. Jones <luke@ljones.dev> --- .../ABI/testing/sysfs-platform-asus-wmi | 9 ++++ @@ -412,7 +449,7 @@ Signed-off-by: Luke D. Jones <luke@ljones.dev> 3 files changed, 63 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi -index ef1ac1a20a71..41b92e53e88a 100644 +index ef1ac1a20a71..72933527d2e4 100644 --- a/Documentation/ABI/testing/sysfs-platform-asus-wmi +++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi @@ -194,3 +194,12 @@ Contact: "Luke Jones" <luke@ljones.dev> @@ -428,12 +465,11 @@ index ef1ac1a20a71..41b92e53e88a 100644 + Set if the BIOS POST sound is played on boot. + * 0 - False, + * 1 - True -\ No newline at end of file diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index fa5735af7675..fcf976967325 100644 +index 6896d056d227..6c353b8e8da9 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -2104,6 +2104,54 @@ static ssize_t panel_od_store(struct device *dev, +@@ -2115,6 +2115,54 @@ static ssize_t panel_od_store(struct device *dev, } static DEVICE_ATTR_RW(panel_od); @@ -488,7 +524,7 @@ index fa5735af7675..fcf976967325 100644 /* Mini-LED mode **************************************************************/ static ssize_t mini_led_mode_show(struct device *dev, struct device_attribute *attr, char *buf) -@@ -4189,6 +4237,7 @@ static struct attribute *platform_attributes[] = { +@@ -4207,6 +4255,7 @@ static struct attribute *platform_attributes[] = { &dev_attr_ppt_platform_sppt.attr, &dev_attr_nv_dynamic_boost.attr, &dev_attr_nv_temp_target.attr, @@ -496,7 +532,7 @@ index fa5735af7675..fcf976967325 100644 &dev_attr_panel_od.attr, &dev_attr_mini_led_mode.attr, &dev_attr_available_mini_led_mode.attr, -@@ -4241,6 +4290,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, +@@ -4259,6 +4308,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, ok = asus->nv_dyn_boost_available; else if (attr == &dev_attr_nv_temp_target.attr) ok = asus->nv_temp_tgt_available; @@ -522,11 +558,14 @@ index 3e9a01467c67..3eb5cd6773ad 100644 -- 2.44.0 -From 3ab4c3241324bb294f5d94b9a07977d7e18c1330 Mon Sep 17 00:00:00 2001 +From eea03ef05c38fe9bfd8653b13b870bb8f96fe41d Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Mon, 11 Mar 2024 12:15:46 +1300 -Subject: [PATCH v1 5/9] platform/x86: asus-wmi: store a min default for ppt +Subject: [PATCH v4 5/9] platform/x86: asus-wmi: store a min default for ppt options +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Laptops with any of the ppt or nv tunables default to the minimum setting on boot so we can safely assume a stored value is correct. @@ -536,16 +575,17 @@ reading of those values back. To prevent creating a series of byte holes in the struct the "<name>_available" bool is removed and `asus_sysfs_is_visible()` uses the `ASUS_WMI_DEVID_<name>` directly. +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Luke D. Jones <luke@ljones.dev> --- drivers/platform/x86/asus-wmi.c | 127 +++++++++++++++++++++++++------- 1 file changed, 99 insertions(+), 28 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index fcf976967325..0d304a04e7de 100644 +index 6c353b8e8da9..f13606fc62e6 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -262,13 +262,13 @@ struct asus_wmi { +@@ -273,13 +273,13 @@ struct asus_wmi { u32 gpu_mux_dev; /* Tunables provided by ASUS for gaming laptops */ @@ -566,7 +606,7 @@ index fcf976967325..0d304a04e7de 100644 u32 kbd_rgb_dev; bool kbd_rgb_state_available; -@@ -1020,11 +1020,21 @@ static ssize_t ppt_pl2_sppt_store(struct device *dev, +@@ -1031,11 +1031,21 @@ static ssize_t ppt_pl2_sppt_store(struct device *dev, return -EIO; } @@ -583,13 +623,13 @@ index fcf976967325..0d304a04e7de 100644 +{ + struct asus_wmi *asus = dev_get_drvdata(dev); + -+ return sysfs_emit(buf, "%d\n", asus->ppt_pl2_sppt); ++ return sysfs_emit(buf, "%u\n", asus->ppt_pl2_sppt); +} +static DEVICE_ATTR_RW(ppt_pl2_sppt); /* Tunable: PPT, Intel=PL1, AMD=SPL ******************************************/ static ssize_t ppt_pl1_spl_store(struct device *dev, -@@ -1054,11 +1064,20 @@ static ssize_t ppt_pl1_spl_store(struct device *dev, +@@ -1065,11 +1075,20 @@ static ssize_t ppt_pl1_spl_store(struct device *dev, return -EIO; } @@ -605,13 +645,13 @@ index fcf976967325..0d304a04e7de 100644 +{ + struct asus_wmi *asus = dev_get_drvdata(dev); + -+ return sysfs_emit(buf, "%d\n", asus->ppt_pl1_spl); ++ return sysfs_emit(buf, "%u\n", asus->ppt_pl1_spl); +} +static DEVICE_ATTR_RW(ppt_pl1_spl); /* Tunable: PPT APU FPPT ******************************************************/ static ssize_t ppt_fppt_store(struct device *dev, -@@ -1088,11 +1107,21 @@ static ssize_t ppt_fppt_store(struct device *dev, +@@ -1099,11 +1118,21 @@ static ssize_t ppt_fppt_store(struct device *dev, return -EIO; } @@ -628,13 +668,13 @@ index fcf976967325..0d304a04e7de 100644 +{ + struct asus_wmi *asus = dev_get_drvdata(dev); + -+ return sysfs_emit(buf, "%d\n", asus->ppt_fppt); ++ return sysfs_emit(buf, "%u\n", asus->ppt_fppt); +} +static DEVICE_ATTR_RW(ppt_fppt); /* Tunable: PPT APU SPPT *****************************************************/ static ssize_t ppt_apu_sppt_store(struct device *dev, -@@ -1122,11 +1151,21 @@ static ssize_t ppt_apu_sppt_store(struct device *dev, +@@ -1133,11 +1162,21 @@ static ssize_t ppt_apu_sppt_store(struct device *dev, return -EIO; } @@ -651,13 +691,13 @@ index fcf976967325..0d304a04e7de 100644 +{ + struct asus_wmi *asus = dev_get_drvdata(dev); + -+ return sysfs_emit(buf, "%d\n", asus->ppt_apu_sppt); ++ return sysfs_emit(buf, "%u\n", asus->ppt_apu_sppt); +} +static DEVICE_ATTR_RW(ppt_apu_sppt); /* Tunable: PPT platform SPPT ************************************************/ static ssize_t ppt_platform_sppt_store(struct device *dev, -@@ -1156,11 +1195,21 @@ static ssize_t ppt_platform_sppt_store(struct device *dev, +@@ -1167,11 +1206,21 @@ static ssize_t ppt_platform_sppt_store(struct device *dev, return -EIO; } @@ -674,13 +714,13 @@ index fcf976967325..0d304a04e7de 100644 +{ + struct asus_wmi *asus = dev_get_drvdata(dev); + -+ return sysfs_emit(buf, "%d\n", asus->ppt_platform_sppt); ++ return sysfs_emit(buf, "%u\n", asus->ppt_platform_sppt); +} +static DEVICE_ATTR_RW(ppt_platform_sppt); /* Tunable: NVIDIA dynamic boost *********************************************/ static ssize_t nv_dynamic_boost_store(struct device *dev, -@@ -1190,11 +1239,21 @@ static ssize_t nv_dynamic_boost_store(struct device *dev, +@@ -1201,11 +1250,21 @@ static ssize_t nv_dynamic_boost_store(struct device *dev, return -EIO; } @@ -697,13 +737,13 @@ index fcf976967325..0d304a04e7de 100644 +{ + struct asus_wmi *asus = dev_get_drvdata(dev); + -+ return sysfs_emit(buf, "%d\n", asus->nv_dynamic_boost); ++ return sysfs_emit(buf, "%u\n", asus->nv_dynamic_boost); +} +static DEVICE_ATTR_RW(nv_dynamic_boost); /* Tunable: NVIDIA temperature target ****************************************/ static ssize_t nv_temp_target_store(struct device *dev, -@@ -1224,11 +1283,21 @@ static ssize_t nv_temp_target_store(struct device *dev, +@@ -1235,11 +1294,21 @@ static ssize_t nv_temp_target_store(struct device *dev, return -EIO; } @@ -720,13 +760,13 @@ index fcf976967325..0d304a04e7de 100644 +{ + struct asus_wmi *asus = dev_get_drvdata(dev); + -+ return sysfs_emit(buf, "%d\n", asus->nv_temp_target); ++ return sysfs_emit(buf, "%u\n", asus->nv_temp_target); +} +static DEVICE_ATTR_RW(nv_temp_target); /* Battery ********************************************************************/ -@@ -4277,19 +4346,19 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, +@@ -4295,19 +4364,19 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, else if (attr == &dev_attr_throttle_thermal_policy.attr) ok = asus->throttle_thermal_policy_available; else if (attr == &dev_attr_ppt_pl2_sppt.attr) @@ -753,7 +793,7 @@ index fcf976967325..0d304a04e7de 100644 else if (attr == &dev_attr_boot_sound.attr) devid = ASUS_WMI_DEVID_BOOT_SOUND; else if (attr == &dev_attr_panel_od.attr) -@@ -4535,18 +4604,20 @@ static int asus_wmi_add(struct platform_device *pdev) +@@ -4553,18 +4622,20 @@ static int asus_wmi_add(struct platform_device *pdev) if (err) goto fail_platform; @@ -784,25 +824,29 @@ index fcf976967325..0d304a04e7de 100644 -- 2.44.0 -From 15f1cf62ebc12203aa707513e14f6a0bc2af2999 Mon Sep 17 00:00:00 2001 +From 43355f0d9ba2d6e9ef791c0fe5efbbff872d05ac Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Mon, 25 Mar 2024 16:20:57 +1300 -Subject: [PATCH v1 6/9] platform/x86: asus-wmi: adjust formatting of +Subject: [PATCH v4 6/9] platform/x86: asus-wmi: adjust formatting of ppt-<name>() functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Shift the call to dev_get_drvdata() up to top of the function block in all of the ppt_<name>() functions as part of a minor cleanup. +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Luke D. Jones <luke@ljones.dev> --- drivers/platform/x86/asus-wmi.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 0d304a04e7de..2ff78e194801 100644 +index f13606fc62e6..976e26c82f80 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -997,11 +997,10 @@ static ssize_t ppt_pl2_sppt_store(struct device *dev, +@@ -1008,11 +1008,10 @@ static ssize_t ppt_pl2_sppt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -815,7 +859,7 @@ index 0d304a04e7de..2ff78e194801 100644 result = kstrtou32(buf, 10, &value); if (result) return result; -@@ -1041,11 +1040,10 @@ static ssize_t ppt_pl1_spl_store(struct device *dev, +@@ -1052,11 +1051,10 @@ static ssize_t ppt_pl1_spl_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -828,7 +872,7 @@ index 0d304a04e7de..2ff78e194801 100644 result = kstrtou32(buf, 10, &value); if (result) return result; -@@ -1084,11 +1082,10 @@ static ssize_t ppt_fppt_store(struct device *dev, +@@ -1095,11 +1093,10 @@ static ssize_t ppt_fppt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -841,7 +885,7 @@ index 0d304a04e7de..2ff78e194801 100644 result = kstrtou32(buf, 10, &value); if (result) return result; -@@ -1128,11 +1125,10 @@ static ssize_t ppt_apu_sppt_store(struct device *dev, +@@ -1139,11 +1136,10 @@ static ssize_t ppt_apu_sppt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -854,7 +898,7 @@ index 0d304a04e7de..2ff78e194801 100644 result = kstrtou32(buf, 10, &value); if (result) return result; -@@ -1172,11 +1168,10 @@ static ssize_t ppt_platform_sppt_store(struct device *dev, +@@ -1183,11 +1179,10 @@ static ssize_t ppt_platform_sppt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -867,7 +911,7 @@ index 0d304a04e7de..2ff78e194801 100644 result = kstrtou32(buf, 10, &value); if (result) return result; -@@ -1216,11 +1211,10 @@ static ssize_t nv_dynamic_boost_store(struct device *dev, +@@ -1227,11 +1222,10 @@ static ssize_t nv_dynamic_boost_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -880,7 +924,7 @@ index 0d304a04e7de..2ff78e194801 100644 result = kstrtou32(buf, 10, &value); if (result) return result; -@@ -1260,11 +1254,10 @@ static ssize_t nv_temp_target_store(struct device *dev, +@@ -1271,11 +1265,10 @@ static ssize_t nv_temp_target_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -896,11 +940,14 @@ index 0d304a04e7de..2ff78e194801 100644 -- 2.44.0 -From 6597ecfcc2836fbcce530c2e146965457abacabd Mon Sep 17 00:00:00 2001 +From 4f772c2affe17d50c791d61c72662df81b18884a Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Mon, 25 Mar 2024 11:14:28 +1300 -Subject: [PATCH v1 7/9] platform/x86: asus-wmi: ROG Ally increase wait time, +Subject: [PATCH v4 7/9] platform/x86: asus-wmi: ROG Ally increase wait time, allow MCU powersave +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit The previous work to allow the MCU to be resumed correctly after sleep and resume tried to take the shortest possible time. However as work @@ -918,16 +965,17 @@ to allow a proper disconnect and disable, and the same amount of time on resume is required to prevent a rapid disconnect/reconnect happening on seemingly random occasions. To be safe the time is now 1500ms for msleep. +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Luke D. Jones <luke@ljones.dev> --- drivers/platform/x86/asus-wmi.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 2ff78e194801..ec249eca0d94 100644 +index 976e26c82f80..ab98f91e573c 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -129,7 +129,7 @@ module_param(fnlock_default, bool, 0444); +@@ -140,7 +140,7 @@ module_param(fnlock_default, bool, 0444); /* Controls the power state of the USB0 hub on ROG Ally which input is on */ #define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE" /* 300ms so far seems to produce a reliable result on AC and battery */ @@ -936,7 +984,7 @@ index 2ff78e194801..ec249eca0d94 100644 static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; -@@ -4814,6 +4814,7 @@ static int asus_hotk_resume_early(struct device *device) +@@ -4829,6 +4829,7 @@ static int asus_hotk_resume_early(struct device *device) struct asus_wmi *asus = dev_get_drvdata(device); if (asus->ally_mcu_usb_switch) { @@ -944,7 +992,7 @@ index 2ff78e194801..ec249eca0d94 100644 if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB8))) dev_err(device, "ROG Ally MCU failed to connect USB dev\n"); else -@@ -4825,17 +4826,8 @@ static int asus_hotk_resume_early(struct device *device) +@@ -4840,17 +4841,8 @@ static int asus_hotk_resume_early(struct device *device) static int asus_hotk_prepare(struct device *device) { struct asus_wmi *asus = dev_get_drvdata(device); @@ -965,32 +1013,33 @@ index 2ff78e194801..ec249eca0d94 100644 -- 2.44.0 -From 34efcd3998a3af0adbf758a21868c58ff95991fc Mon Sep 17 00:00:00 2001 +From 67529648f99081e63e66c831d2644181ca314c86 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Mon, 25 Mar 2024 16:43:12 +1300 -Subject: [PATCH v1 8/9] platform/x86: asus-wmi: Add support for MCU powersave +Subject: [PATCH v4 8/9] platform/x86: asus-wmi: Add support for MCU powersave +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Add support for an MCU powersave WMI call. This is intended to set the MCU in to a low-power mode when sleeping. This mode can cut sleep power use by around half. +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Luke D. Jones <luke@ljones.dev> --- - .../ABI/testing/sysfs-platform-asus-wmi | 11 +++- + .../ABI/testing/sysfs-platform-asus-wmi | 9 ++++ drivers/platform/x86/asus-wmi.c | 50 +++++++++++++++++++ - 2 files changed, 60 insertions(+), 1 deletion(-) + 2 files changed, 59 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi -index 41b92e53e88a..28144371a0f1 100644 +index 72933527d2e4..28144371a0f1 100644 --- a/Documentation/ABI/testing/sysfs-platform-asus-wmi +++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi -@@ -202,4 +202,13 @@ Contact: "Luke Jones" <luke@ljones.dev> - Description: +@@ -203,3 +203,12 @@ Description: Set if the BIOS POST sound is played on boot. * 0 - False, -- * 1 - True -\ No newline at end of file -+ * 1 - True + * 1 - True + +What: /sys/devices/platform/<platform>/mcu_powersave +Date: Apr 2024 @@ -1001,10 +1050,10 @@ index 41b92e53e88a..28144371a0f1 100644 + * 0 - False, + * 1 - True diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index ec249eca0d94..a6b648457908 100644 +index ab98f91e573c..d06d9e0c498c 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -1292,6 +1292,53 @@ static ssize_t nv_temp_target_show(struct device *dev, +@@ -1303,6 +1303,53 @@ static ssize_t nv_temp_target_show(struct device *dev, } static DEVICE_ATTR_RW(nv_temp_target); @@ -1058,7 +1107,7 @@ index ec249eca0d94..a6b648457908 100644 /* Battery ********************************************************************/ /* The battery maximum charging percentage */ -@@ -4299,6 +4346,7 @@ static struct attribute *platform_attributes[] = { +@@ -4317,6 +4364,7 @@ static struct attribute *platform_attributes[] = { &dev_attr_ppt_platform_sppt.attr, &dev_attr_nv_dynamic_boost.attr, &dev_attr_nv_temp_target.attr, @@ -1066,7 +1115,7 @@ index ec249eca0d94..a6b648457908 100644 &dev_attr_boot_sound.attr, &dev_attr_panel_od.attr, &dev_attr_mini_led_mode.attr, -@@ -4352,6 +4400,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, +@@ -4370,6 +4418,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, devid = ASUS_WMI_DEVID_NV_DYN_BOOST; else if (attr == &dev_attr_nv_temp_target.attr) devid = ASUS_WMI_DEVID_NV_THERM_TARGET; @@ -1078,26 +1127,30 @@ index ec249eca0d94..a6b648457908 100644 -- 2.44.0 -From a8820c0337313f9f9dc41d2ce43fe20b9b53cf98 Mon Sep 17 00:00:00 2001 +From fb8027a2ca91fff199a21300ca2d2afaf264e1d3 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Mon, 25 Mar 2024 17:14:00 +1300 -Subject: [PATCH v1 9/9] platform/x86: asus-wmi: cleanup main struct to avoid +Subject: [PATCH v4 9/9] platform/x86: asus-wmi: cleanup main struct to avoid some holes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Reorganises some attr-available calls to remove a few unrequired booleans in the main driver struct which combined with some reorganisation prevents a series of large holes seen with pahole. +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Luke D. Jones <luke@ljones.dev> --- drivers/platform/x86/asus-wmi.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index a6b648457908..7163cce7079c 100644 +index d06d9e0c498c..2d2b4eca7fd8 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -243,6 +243,9 @@ struct asus_wmi { +@@ -254,6 +254,9 @@ struct asus_wmi { u32 tablet_switch_dev_id; bool tablet_switch_inverted; @@ -1107,7 +1160,7 @@ index a6b648457908..7163cce7079c 100644 enum fan_type fan_type; enum fan_type gpu_fan_type; enum fan_type mid_fan_type; -@@ -255,9 +258,7 @@ struct asus_wmi { +@@ -266,9 +269,7 @@ struct asus_wmi { u8 fan_boost_mode_mask; u8 fan_boost_mode; @@ -1117,7 +1170,7 @@ index a6b648457908..7163cce7079c 100644 bool dgpu_disable_available; u32 gpu_mux_dev; -@@ -298,9 +299,6 @@ struct asus_wmi { +@@ -309,9 +310,6 @@ struct asus_wmi { bool fnlock_locked; @@ -1127,7 +1180,7 @@ index a6b648457908..7163cce7079c 100644 struct asus_wmi_debug debug; struct asus_wmi_driver *driver; -@@ -4373,11 +4371,11 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, +@@ -4391,11 +4389,11 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, else if (attr == &dev_attr_als_enable.attr) devid = ASUS_WMI_DEVID_ALS_ENABLE; else if (attr == &dev_attr_charge_mode.attr) @@ -1141,7 +1194,7 @@ index a6b648457908..7163cce7079c 100644 else if (attr == &dev_attr_dgpu_disable.attr) ok = asus->dgpu_disable_available; else if (attr == &dev_attr_gpu_mux_mode.attr) -@@ -4405,7 +4403,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, +@@ -4423,7 +4421,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, else if (attr == &dev_attr_boot_sound.attr) devid = ASUS_WMI_DEVID_BOOT_SOUND; else if (attr == &dev_attr_panel_od.attr) @@ -1150,7 +1203,7 @@ index a6b648457908..7163cce7079c 100644 else if (attr == &dev_attr_mini_led_mode.attr) ok = asus->mini_led_dev_id != 0; else if (attr == &dev_attr_available_mini_led_mode.attr) -@@ -4656,12 +4654,9 @@ static int asus_wmi_add(struct platform_device *pdev) +@@ -4674,12 +4672,9 @@ static int asus_wmi_add(struct platform_device *pdev) asus->nv_dynamic_boost = 5; asus->nv_temp_target = 75; @@ -1166,6 +1219,272 @@ index a6b648457908..7163cce7079c 100644 -- 2.44.0 +From 8cab59d3fb33f17e3b3fa4937c5d4bf0b59e6b12 Mon Sep 17 00:00:00 2001 +From: Mohamed Ghanmi <mohamed.ghanmi@supcom.tn> +Date: Fri, 12 Apr 2024 00:56:39 +0100 +Subject: [PATCH] platform/x86: asus-wmi: add support for vivobook fan profiles + +Add support for vivobook fan profiles wmi call on the ASUS VIVOBOOK +to adjust power limits. + +These fan profiles have a different device id than the ROG series. +and different order. This reorders the existing modes and adds a new +full speed mode available on these laptops. + +As part of keeping the patch clean the throttle_thermal_policy_available +boolean stored in the driver struct is removed and +throttle_thermal_policy_dev is used in place (as on init it is zeroed). + +Signed-off-by: Mohamed Ghanmi <mohamed.ghanmi@supcom.tn> +Co-developed-by: Luke D. Jones <luke@ljones.dev> +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/platform/x86/asus-wmi.c | 100 +++++++++++---------- + include/linux/platform_data/x86/asus-wmi.h | 1 + + 2 files changed, 55 insertions(+), 46 deletions(-) + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 2d2b4eca7fd8..439d330fb80b 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -97,6 +97,11 @@ module_param(fnlock_default, bool, 0444); + #define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST 1 + #define ASUS_THROTTLE_THERMAL_POLICY_SILENT 2 + ++#define ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO 0 ++#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO 2 ++#define ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO 1 ++#define ASUS_THROTTLE_THERMAL_POLICY_FULLSPEED 3 ++ + #define USB_INTEL_XUSB2PR 0xD0 + #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 + +@@ -285,8 +290,8 @@ struct asus_wmi { + u32 kbd_rgb_dev; + bool kbd_rgb_state_available; + +- bool throttle_thermal_policy_available; + u8 throttle_thermal_policy_mode; ++ u32 throttle_thermal_policy_dev; + + bool cpu_fan_curve_available; + bool gpu_fan_curve_available; +@@ -3153,7 +3158,7 @@ static int fan_curve_get_factory_default(struct asus_wmi *asus, u32 fan_dev) + int err, fan_idx; + u8 mode = 0; + +- if (asus->throttle_thermal_policy_available) ++ if (asus->throttle_thermal_policy_dev) + mode = asus->throttle_thermal_policy_mode; + /* DEVID_<C/G>PU_FAN_CURVE is switched for OVERBOOST vs SILENT */ + if (mode == 2) +@@ -3360,7 +3365,7 @@ static ssize_t fan_curve_enable_store(struct device *dev, + * For machines with throttle this is the only way to reset fans + * to default mode of operation (does not erase curve data). + */ +- if (asus->throttle_thermal_policy_available) { ++ if (asus->throttle_thermal_policy_dev) { + err = throttle_thermal_policy_write(asus); + if (err) + return err; +@@ -3577,8 +3582,8 @@ static const struct attribute_group asus_fan_curve_attr_group = { + __ATTRIBUTE_GROUPS(asus_fan_curve_attr); + + /* +- * Must be initialised after throttle_thermal_policy_check_present() as +- * we check the status of throttle_thermal_policy_available during init. ++ * Must be initialised after throttle_thermal_policy_dev is set as ++ * we check the status of throttle_thermal_policy_dev during init. + */ + static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus) + { +@@ -3619,38 +3624,31 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus) + } + + /* Throttle thermal policy ****************************************************/ +- +-static int throttle_thermal_policy_check_present(struct asus_wmi *asus) +-{ +- u32 result; +- int err; +- +- asus->throttle_thermal_policy_available = false; +- +- err = asus_wmi_get_devstate(asus, +- ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, +- &result); +- if (err) { +- if (err == -ENODEV) +- return 0; +- return err; +- } +- +- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) +- asus->throttle_thermal_policy_available = true; +- +- return 0; +-} +- + static int throttle_thermal_policy_write(struct asus_wmi *asus) + { +- int err; +- u8 value; ++ u8 value = asus->throttle_thermal_policy_mode; + u32 retval; ++ bool vivo; ++ int err; + +- value = asus->throttle_thermal_policy_mode; ++ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO; ++ if (vivo) { ++ switch (value) { ++ case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT: ++ value = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO; ++ break; ++ case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST: ++ value = ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO; ++ break; ++ case ASUS_THROTTLE_THERMAL_POLICY_SILENT: ++ value = ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO; ++ break; ++ default: ++ break; ++ } ++ } + +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, ++ err = asus_wmi_set_devstate(asus->throttle_thermal_policy_dev, + value, &retval); + + sysfs_notify(&asus->platform_device->dev.kobj, NULL, +@@ -3680,7 +3678,7 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus) + + static int throttle_thermal_policy_set_default(struct asus_wmi *asus) + { +- if (!asus->throttle_thermal_policy_available) ++ if (!asus->throttle_thermal_policy_dev) + return 0; + + asus->throttle_thermal_policy_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT; +@@ -3690,9 +3688,14 @@ static int throttle_thermal_policy_set_default(struct asus_wmi *asus) + static int throttle_thermal_policy_switch_next(struct asus_wmi *asus) + { + u8 new_mode = asus->throttle_thermal_policy_mode + 1; ++ bool vivo; + int err; + +- if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT) ++ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO; ++ if (!vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT) ++ new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT; ++ ++ if (vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_FULLSPEED) + new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT; + + asus->throttle_thermal_policy_mode = new_mode; +@@ -3725,13 +3728,17 @@ static ssize_t throttle_thermal_policy_store(struct device *dev, + struct asus_wmi *asus = dev_get_drvdata(dev); + u8 new_mode; + int result; ++ bool vivo; + int err; + + result = kstrtou8(buf, 10, &new_mode); + if (result < 0) + return result; + +- if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT) ++ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO; ++ if (vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_FULLSPEED) ++ return -EINVAL; ++ else if (!vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT) + return -EINVAL; + + asus->throttle_thermal_policy_mode = new_mode; +@@ -3748,7 +3755,10 @@ static ssize_t throttle_thermal_policy_store(struct device *dev, + return count; + } + +-// Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent ++/* ++ * Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent ++ * VIVOBOOK: 3 - fans full speed ++ */ + static DEVICE_ATTR_RW(throttle_thermal_policy); + + /* Platform profile ***********************************************************/ +@@ -3814,7 +3824,7 @@ static int platform_profile_setup(struct asus_wmi *asus) + * Not an error if a component platform_profile relies on is unavailable + * so early return, skipping the setup of platform_profile. + */ +- if (!asus->throttle_thermal_policy_available) ++ if (!asus->throttle_thermal_policy_dev) + return 0; + + dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n"); +@@ -4229,7 +4239,7 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus) + if (code == NOTIFY_KBD_FBM || code == NOTIFY_KBD_TTP) { + if (asus->fan_boost_mode_available) + fan_boost_mode_switch_next(asus); +- if (asus->throttle_thermal_policy_available) ++ if (asus->throttle_thermal_policy_dev) + throttle_thermal_policy_switch_next(asus); + return; + +@@ -4401,7 +4411,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, + else if (attr == &dev_attr_fan_boost_mode.attr) + ok = asus->fan_boost_mode_available; + else if (attr == &dev_attr_throttle_thermal_policy.attr) +- ok = asus->throttle_thermal_policy_available; ++ ok = asus->throttle_thermal_policy_dev != 0; + else if (attr == &dev_attr_ppt_pl2_sppt.attr) + devid = ASUS_WMI_DEVID_PPT_PL2_SPPT; + else if (attr == &dev_attr_ppt_pl1_spl.attr) +@@ -4693,16 +4703,15 @@ static int asus_wmi_add(struct platform_device *pdev) + else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2)) + asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE2; + ++ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY)) ++ asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY; ++ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO)) ++ asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO; ++ + err = fan_boost_mode_check_present(asus); + if (err) + goto fail_fan_boost_mode; + +- err = throttle_thermal_policy_check_present(asus); +- if (err) +- goto fail_throttle_thermal_policy; +- else +- throttle_thermal_policy_set_default(asus); +- + err = platform_profile_setup(asus); + if (err) + goto fail_platform_profile_setup; +@@ -4797,7 +4806,6 @@ static int asus_wmi_add(struct platform_device *pdev) + fail_input: + asus_wmi_sysfs_exit(asus->platform_device); + fail_sysfs: +-fail_throttle_thermal_policy: + fail_custom_fan_curve: + fail_platform_profile_setup: + if (asus->platform_profile_support) +diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h +index 3eb5cd6773ad..982a637744ec 100644 +--- a/include/linux/platform_data/x86/asus-wmi.h ++++ b/include/linux/platform_data/x86/asus-wmi.h +@@ -64,6 +64,7 @@ + #define ASUS_WMI_DEVID_SCREENPAD_LIGHT 0x00050032 + #define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018 + #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075 ++#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO 0x00110019 + + /* Misc */ + #define ASUS_WMI_DEVID_PANEL_OD 0x00050019 +-- +2.44.0 + From de9b01c3b8869451d4cf44ab0baf55440e804fc6 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> Date: Sat, 2 Dec 2023 17:47:59 +1300 @@ -1321,28 +1640,6 @@ index cdd998a761fe..3a1a6024d299 100644 default: -@@ -1239,6 +1243,9 @@ static const struct hid_device_id asus_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, - USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, -+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, -+ USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY), -+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, - USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), - QUIRK_ROG_CLAYMORE_II_KEYBOARD }, -diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h -index 8376fb5e2d0b..f1e508a7ef06 100644 ---- a/drivers/hid/hid-ids.h -+++ b/drivers/hid/hid-ids.h -@@ -208,6 +208,7 @@ - #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866 - #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6 - #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30 -+#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe - #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b - #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 - -- 2.44.0 @@ -1364,16 +1661,16 @@ diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 3a1a6024d299..de0c13babc03 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c -@@ -1243,6 +1243,9 @@ static const struct hid_device_id asus_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, +@@ -1274,6 +1274,9 @@ USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3), QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, -+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR), + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), + QUIRK_ROG_CLAYMORE_II_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, - USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f1e508a7ef06..94501dbdd463 100644 --- a/drivers/hid/hid-ids.h @@ -1383,9 +1680,2809 @@ index f1e508a7ef06..94501dbdd463 100644 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30 +#define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6 - #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 + -- 2.44.0 +From f6690cfd476029bc67f3161705587497dabb6b8e Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Tue, 21 May 2024 18:17:17 +1200 +Subject: [PATCH 1/8] platform/x86: asus-wmi: add debug print in more key + places + +Add more verbose debug print in the WMI method calls. This helps a lot +with debugging various issues working with regular users as the WMI +methods can be traced now. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/platform/x86/asus-wmi.c | 58 +++++++++++++++++++++++++++------ + 1 file changed, 48 insertions(+), 10 deletions(-) + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 799d928c7d3d..4c129881ce28 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -334,20 +334,29 @@ static int asus_wmi_evaluate_method3(u32 method_id, + status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id, + &input, &output); + +- if (ACPI_FAILURE(status)) ++ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x\n", ++ __func__, method_id, arg0, arg1, arg2); ++ if (ACPI_FAILURE(status)) { ++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n", ++ __func__, method_id, arg0, -EIO); + return -EIO; ++ } + + obj = (union acpi_object *)output.pointer; + if (obj && obj->type == ACPI_TYPE_INTEGER) + tmp = (u32) obj->integer.value; + ++ pr_debug("Result: 0x%08x\n", tmp); + if (retval) + *retval = tmp; + + kfree(obj); + +- if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) ++ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) { ++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n", ++ __func__, method_id, arg0, -ENODEV); + return -ENODEV; ++ } + + return 0; + } +@@ -377,20 +386,29 @@ static int asus_wmi_evaluate_method5(u32 method_id, + status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id, + &input, &output); + +- if (ACPI_FAILURE(status)) ++ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", ++ __func__, method_id, arg0, arg1, arg2, arg3, arg4); ++ if (ACPI_FAILURE(status)) { ++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n", ++ __func__, method_id, arg0, -EIO); + return -EIO; ++ } + + obj = (union acpi_object *)output.pointer; + if (obj && obj->type == ACPI_TYPE_INTEGER) + tmp = (u32) obj->integer.value; + ++ pr_debug("Result: %x\n", tmp); + if (retval) + *retval = tmp; + + kfree(obj); + +- if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) ++ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) { ++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n", ++ __func__, method_id, arg0, -ENODEV); + return -ENODEV; ++ } + + return 0; + } +@@ -416,8 +434,13 @@ static int asus_wmi_evaluate_method_buf(u32 method_id, + status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id, + &input, &output); + +- if (ACPI_FAILURE(status)) ++ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x\n", ++ __func__, method_id, arg0, arg1); ++ if (ACPI_FAILURE(status)) { ++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n", ++ __func__, method_id, arg0, -EIO); + return -EIO; ++ } + + obj = (union acpi_object *)output.pointer; + +@@ -453,8 +476,11 @@ static int asus_wmi_evaluate_method_buf(u32 method_id, + + kfree(obj); + +- if (err) ++ if (err) { ++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n", ++ __func__, method_id, arg0, err); + return err; ++ } + + return 0; + } +@@ -542,6 +568,7 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id) + { + u32 retval; + int status = asus_wmi_get_devstate(asus, dev_id, &retval); ++ pr_debug("%s called (0x%08x), retval: 0x%08x\n", __func__, dev_id, retval); + + return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT); + } +@@ -3559,18 +3586,27 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus) + + err = fan_curve_check_present(asus, &asus->cpu_fan_curve_available, + ASUS_WMI_DEVID_CPU_FAN_CURVE); +- if (err) ++ if (err) { ++ pr_err("%s, checked 0x%08x, failed: %d\n", ++ __func__, ASUS_WMI_DEVID_CPU_FAN_CURVE, err); + return err; ++ } + + err = fan_curve_check_present(asus, &asus->gpu_fan_curve_available, + ASUS_WMI_DEVID_GPU_FAN_CURVE); +- if (err) ++ if (err) { ++ pr_err("%s, checked 0x%08x, failed: %d\n", ++ __func__, ASUS_WMI_DEVID_GPU_FAN_CURVE, err); + return err; ++ } + + err = fan_curve_check_present(asus, &asus->mid_fan_curve_available, + ASUS_WMI_DEVID_MID_FAN_CURVE); +- if (err) ++ if (err) { ++ pr_err("%s, checked 0x%08x, failed: %d\n", ++ __func__, ASUS_WMI_DEVID_MID_FAN_CURVE, err); + return err; ++ } + + if (!asus->cpu_fan_curve_available + && !asus->gpu_fan_curve_available +@@ -4398,8 +4434,10 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, + else if (attr == &dev_attr_available_mini_led_mode.attr) + ok = asus->mini_led_dev_id != 0; + +- if (devid != -1) ++ if (devid != -1) { + ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); ++ pr_debug("%s called 0x%08x, ok: %x\n", __func__, devid, ok); ++ } + + return ok ? attr->mode : 0; + } +-- +2.45.1 + +From 7a08b0a6a1b47ad7c3e84a14f433c5909ec13679 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Fri, 24 May 2024 10:54:36 +1200 +Subject: [PATCH 2/8] platform/x86: asus-wmi: don't fail if platform_profile + already registered + +On some newer laptops it appears that an AMD driver can register a +platform_profile handler. If this happens then the asus_wmi driver would +error with -EEXIST when trying to register its own handler. + +We can safely continue loading the driver instead of bombing out. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/platform/x86/asus-wmi.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 4c129881ce28..7d87ff68f418 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -3836,8 +3836,13 @@ static int platform_profile_setup(struct asus_wmi *asus) + asus->platform_profile_handler.choices); + + err = platform_profile_register(&asus->platform_profile_handler); +- if (err) ++ if (err == -EEXIST) { ++ pr_warn("%s, a platform_profile handler is already registered\n", __func__); ++ return 0; ++ } else if (err) { ++ pr_err("%s, failed at platform_profile_register: %d\n", __func__, err); + return err; ++ } + + asus->platform_profile_support = true; + return 0; +@@ -4662,7 +4662,7 @@ + goto fail_fan_boost_mode; + + err = platform_profile_setup(asus); +- if (err) ++ if (err && err != -EEXIST) + goto fail_platform_profile_setup; + + err = asus_wmi_sysfs_init(asus->platform_device); +-- +2.45.1 + +From 2ebd194c3d390abdb67e61941f3b71fe149620eb Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Thu, 30 May 2024 13:20:11 +1200 +Subject: [PATCH 3/8] asus-bios: refactor existing tunings in to asus-bios + module + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/platform/x86/Kconfig | 14 + + drivers/platform/x86/Makefile | 1 + + drivers/platform/x86/asus-bios.c | 654 +++++++++++++++++++++ + drivers/platform/x86/asus-bios.h | 234 ++++++++ + drivers/platform/x86/asus-wmi.c | 18 +- + include/linux/platform_data/x86/asus-wmi.h | 10 + + 6 files changed, 930 insertions(+), 1 deletion(-) + create mode 100644 drivers/platform/x86/asus-bios.c + create mode 100644 drivers/platform/x86/asus-bios.h + +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index 0ec952b5d03e..296b5c9bfbb0 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -264,6 +264,18 @@ config ASUS_WIRELESS + If you choose to compile this driver as a module the module will be + called asus-wireless. + ++config ASUS_BIOS ++ tristate "ASUS BIOS Driver" ++ depends on ACPI_WMI ++ depends on ASUS_WMI ++ select FW_ATTR_CLASS ++ help ++ Say Y here if you have a WMI aware Asus laptop and would like to use the ++ firmware_attributes API. ++ ++ To compile this driver as a module, choose M here: the module will ++ be called asus-bios. ++ + config ASUS_WMI + tristate "ASUS WMI Driver" + depends on ACPI_WMI +@@ -275,6 +287,8 @@ config ASUS_WMI + depends on HOTPLUG_PCI + depends on ACPI_VIDEO || ACPI_VIDEO = n + depends on SERIO_I8042 || SERIO_I8042 = n ++ select ASUS_BIOS ++ select ASUS_WMI_BIOS + select INPUT_SPARSEKMAP + select LEDS_CLASS + select NEW_LEDS +diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile +index e1b142947067..d9b5b3f3b241 100644 +--- a/drivers/platform/x86/Makefile ++++ b/drivers/platform/x86/Makefile +@@ -32,6 +32,7 @@ obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o + # ASUS + obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o + obj-$(CONFIG_ASUS_WIRELESS) += asus-wireless.o ++obj-$(CONFIG_ASUS_BIOS) += asus-bios.o + obj-$(CONFIG_ASUS_WMI) += asus-wmi.o + obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o + obj-$(CONFIG_ASUS_TF103C_DOCK) += asus-tf103c-dock.o +diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c +new file mode 100644 +index 000000000000..c245a48c4072 +--- /dev/null ++++ b/drivers/platform/x86/asus-bios.c +@@ -0,0 +1,654 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Asus BIOS attributes driver ++ * ++ * Copyright(C) 2010 Intel Corporation. ++ * Copyright(C) 2024-2024 Luke Jones <luke@ljones.dev> ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include <linux/platform_data/x86/asus-wmi.h> ++#include <linux/errno.h> ++#include <linux/fs.h> ++#include <linux/types.h> ++#include <linux/dmi.h> ++#include <linux/device.h> ++#include <linux/kmod.h> ++#include <linux/kobject.h> ++#include <linux/module.h> ++#include <linux/mutex.h> ++#include <linux/kernel.h> ++#include "asus-bios.h" ++#include "asus-wmi.h" ++#include "firmware_attributes_class.h" ++ ++MODULE_AUTHOR("Luke Jones <luke@ljones.dev>"); ++MODULE_DESCRIPTION("ASUS BIOS Configuration Driver"); ++MODULE_LICENSE("GPL"); ++ ++#define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C" ++ ++MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); ++ ++#define ASUS_MINI_LED_MODE_MASK 0x03 ++/* Standard modes for devices with only on/off */ ++#define ASUS_MINI_LED_OFF 0x00 ++#define ASUS_MINI_LED_ON 0x01 ++/* New mode on some devices, define here to clarify remapping later */ ++#define ASUS_MINI_LED_STRONG_MODE 0x02 ++/* New modes for devices with 3 mini-led mode types */ ++#define ASUS_MINI_LED_2024_WEAK 0x00 ++#define ASUS_MINI_LED_2024_STRONG 0x01 ++#define ASUS_MINI_LED_2024_OFF 0x02 ++ ++/* Default limits for tunables available on ASUS ROG laptops */ ++#define PPT_CPU_LIMIT_MIN 5 ++#define PPT_CPU_LIMIT_MAX 150 ++#define PPT_CPU_LIMIT_DEFAULT 80 ++#define PPT_PLATFORM_MIN 5 ++#define PPT_PLATFORM_MAX 100 ++#define PPT_PLATFORM_DEFAULT 80 ++#define NVIDIA_BOOST_MIN 5 ++#define NVIDIA_BOOST_MAX 25 ++#define NVIDIA_TEMP_MIN 75 ++#define NVIDIA_TEMP_MAX 87 ++ ++/* Tunables provided by ASUS for gaming laptops */ ++struct rog_tunables { ++ u32 cpu_default; ++ u32 cpu_max; ++ ++ u32 platform_default; ++ u32 platform_max; ++ ++ u32 ppt_pl1_spl; // cpu ++ u32 ppt_pl2_sppt; // cpu ++ u32 ppt_apu_sppt; // plat ++ u32 ppt_platform_sppt; // plat ++ u32 ppt_fppt; // cpu ++ ++ u32 nv_boost_default; ++ u32 nv_boost_max; ++ u32 nv_dynamic_boost; ++ ++ u32 nv_temp_default; ++ u32 nv_temp_max; ++ u32 nv_temp_target; ++}; ++ ++static const struct class *fw_attr_class; ++ ++struct asus_bios_priv { ++ struct device *fw_attr_dev; ++ struct kset *fw_attr_kset; ++ ++ struct rog_tunables *rog_tunables; ++ u32 mini_led_dev_id; ++ u32 gpu_mux_dev_id; ++ bool dgpu_disable_available; ++ bool egpu_enable_available; ++ ++ struct mutex mutex; ++} asus_bios = { ++ .mutex = __MUTEX_INITIALIZER(asus_bios.mutex), ++}; ++ ++static struct fw_attrs_group { ++ u32 pending_reboot; ++} fw_attrs = { ++ .pending_reboot = 0, ++}; ++ ++/* WMI helper methods */ ++static bool asus_wmi_is_present(u32 dev_id) ++{ ++ u32 retval; ++ int status = asus_wmi_get_devstate_dsts(dev_id, &retval); ++ pr_debug("%s called (0x%08x), retval: 0x%08x\n", __func__, dev_id, retval); ++ ++ return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT); ++} ++ ++static void asus_set_reboot_and_signal_event(void) ++{ ++ fw_attrs.pending_reboot = 1; ++ kobject_uevent(&asus_bios.fw_attr_dev->kobj, KOBJ_CHANGE); ++} ++ ++static ssize_t pending_reboot_show(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ char *buf) ++{ ++ return sysfs_emit(buf, "%d\n", fw_attrs.pending_reboot); ++} ++ ++static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot); ++ ++static bool asus_bios_requires_reboot(struct kobj_attribute *attr) { ++ return !strcmp(attr->attr.name, "gpu_mux_mode"); ++} ++ ++/* ++ * Generic store function for use with many ROG tunables ++ */ ++static ssize_t attr_int_store(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ const char *buf, size_t count, ++ u32 min, u32 max, u32 *store_value, u32 wmi_dev) ++{ ++ int result, value; ++ ++ result = kstrtoint(buf, 10, &value); ++ if (result) ++ return result; ++ ++ if (value < min || value > max) ++ return -EINVAL; ++ ++ asus_wmi_set_devstate(wmi_dev, value, &result); ++ if (result) { ++ pr_err("Failed to set %s: %d\n", attr->attr.name, result); ++ return result; ++ } ++ ++ if (result > 1) { ++ pr_err("Failed to set %s (result): 0x%x\n", attr->attr.name, result); ++ return -EIO; ++ } ++ ++ if (store_value != NULL) ++ *store_value = value; ++ sysfs_notify(kobj, NULL, attr->attr.name); ++ ++ if (asus_bios_requires_reboot(attr)) ++ asus_set_reboot_and_signal_event(); ++ ++ return count; ++} ++ ++/* Mini-LED mode **************************************************************/ ++static ssize_t mini_led_mode_current_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ u32 value; ++ int err; ++ ++ err = asus_wmi_get_devstate_dsts(asus_bios.mini_led_dev_id, &value); ++ if (err) ++ return err; ++ ++ value = value & ASUS_MINI_LED_MODE_MASK; ++ ++ /* ++ * Remap the mode values to match previous generation mini-led. The last gen ++ * WMI 0 == off, while on this version WMI 2 ==off (flipped). ++ */ ++ if (asus_bios.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) { ++ switch (value) { ++ case ASUS_MINI_LED_2024_WEAK: ++ value = ASUS_MINI_LED_ON; ++ break; ++ case ASUS_MINI_LED_2024_STRONG: ++ value = ASUS_MINI_LED_STRONG_MODE; ++ break; ++ case ASUS_MINI_LED_2024_OFF: ++ value = ASUS_MINI_LED_OFF; ++ break; ++ } ++ } ++ ++ return sysfs_emit(buf, "%d\n", value); ++} ++ ++static ssize_t mini_led_mode_current_value_store(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int result, err; ++ u32 mode; ++ ++ result = kstrtou32(buf, 10, &mode); ++ if (result) ++ return result; ++ ++ if (asus_bios.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE && ++ mode > ASUS_MINI_LED_ON) ++ return -EINVAL; ++ if (asus_bios.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2 && ++ mode > ASUS_MINI_LED_STRONG_MODE) ++ return -EINVAL; ++ ++ /* ++ * Remap the mode values so expected behaviour is the same as the last ++ * generation of mini-LED with 0 == off, 1 == on. ++ */ ++ if (asus_bios.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) { ++ switch (mode) { ++ case ASUS_MINI_LED_OFF: ++ mode = ASUS_MINI_LED_2024_OFF; ++ break; ++ case ASUS_MINI_LED_ON: ++ mode = ASUS_MINI_LED_2024_WEAK; ++ break; ++ case ASUS_MINI_LED_STRONG_MODE: ++ mode = ASUS_MINI_LED_2024_STRONG; ++ break; ++ } ++ } ++ ++ err = asus_wmi_set_devstate(asus_bios.mini_led_dev_id, mode, &result); ++ if (err) { ++ pr_warn("Failed to set mini-LED: %d\n", err); ++ return err; ++ } ++ ++ if (result > 1) { ++ pr_warn("Failed to set mini-LED mode (result): 0x%x\n", result); ++ return -EIO; ++ } ++ ++ sysfs_notify(kobj, NULL, attr->attr.name); ++ ++ return count; ++} ++ ++static ssize_t mini_led_mode_possible_values_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ switch (asus_bios.mini_led_dev_id) { ++ case ASUS_WMI_DEVID_MINI_LED_MODE: ++ return sysfs_emit(buf, "0;1\n"); ++ case ASUS_WMI_DEVID_MINI_LED_MODE2: ++ return sysfs_emit(buf, "0;1;2\n"); ++ } ++ ++ return sysfs_emit(buf, "0\n"); ++} ++ ++ATTR_GROUP_ENUM_CUSTOM(mini_led_mode, "mini_led_mode", "Set the mini-LED backlight mode"); ++ ++static ssize_t gpu_mux_mode_current_value_store(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int result, err; ++ u32 optimus; ++ ++ err = kstrtou32(buf, 10, &optimus); ++ if (err) ++ return err; ++ ++ if (optimus > 1) ++ return -EINVAL; ++ ++ if (asus_bios.dgpu_disable_available) { ++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_DGPU, &result); ++ if (err) ++ return err; ++ if (err && !optimus) { ++ err = -ENODEV; ++ pr_warn("Can not switch MUX to dGPU mode when dGPU is disabled: %d\n", err); ++ return err; ++ } ++ } ++ ++ if (asus_bios.egpu_enable_available) { ++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_EGPU, &result); ++ if (err) ++ return err; ++ if (result && !optimus) { ++ err = -ENODEV; ++ pr_warn("Can not switch MUX to dGPU mode when eGPU is enabled: %d\n", err); ++ return err; ++ } ++ } ++ ++ err = asus_wmi_set_devstate(asus_bios.gpu_mux_dev_id, optimus, &result); ++ if (err) { ++ pr_err("%s Failed to set GPU MUX mode: %d\nn", __func__, err); ++ return err; ++ } ++ /* !1 is considered a fail by ASUS */ ++ if (result != 1) { ++ pr_warn("%s Failed to set GPU MUX mode (result): 0x%x\n", __func__, result); ++ return -EIO; ++ } ++ ++ sysfs_notify(kobj, NULL, attr->attr.name); ++ ++ return count; ++} ++WMI_SHOW_INT(gpu_mux_mode_current_value, "%d\n", asus_bios.gpu_mux_dev_id); ++ATTR_GROUP_BOOL_CUSTOM(gpu_mux_mode, "gpu_mux_mode", "Set the GPU display MUX mode"); ++ ++/* ++ * A user may be required to store the value twice, typcial store first, then ++ * rescan PCI bus to activate power, then store a second time to save correctly. ++ * The reason for this is that an extra code path in the ACPI is enabled when ++ * the device and bus are powered. ++ */ ++static ssize_t dgpu_disable_current_value_store(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int result, err; ++ u32 disable; ++ ++ result = kstrtou32(buf, 10, &disable); ++ if (result) ++ return result; ++ ++ if (disable > 1) ++ return -EINVAL; ++ ++ if (asus_bios.gpu_mux_dev_id) { ++ err = asus_wmi_get_devstate_dsts(asus_bios.gpu_mux_dev_id, &result); ++ if (err) ++ return err; ++ if (!result && disable) { ++ err = -ENODEV; ++ pr_warn("Can not disable dGPU when the MUX is in dGPU mode: %d\n", err); ++ return err; ++ } ++ } ++ ++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, disable, &result); ++ if (err) { ++ pr_warn("Failed to set dgpu disable: %d\n", err); ++ return err; ++ } ++ ++ if (result > 1) { ++ pr_warn("Failed to set dgpu disable (result): 0x%x\n", result); ++ return -EIO; ++ } ++ ++ sysfs_notify(kobj, NULL, attr->attr.name); ++ ++ return count; ++} ++WMI_SHOW_INT(dgpu_disable_current_value, "%d\n", ASUS_WMI_DEVID_DGPU); ++ATTR_GROUP_BOOL_CUSTOM(dgpu_disable, "dgpu_disable", "Disable the dGPU"); ++ ++/* The ACPI call to enable the eGPU also disables the internal dGPU */ ++static ssize_t egpu_enable_current_value_store(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int result, err; ++ u32 enable; ++ ++ err = kstrtou32(buf, 10, &enable); ++ if (err) ++ return err; ++ ++ if (enable > 1) ++ return -EINVAL; ++ ++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_EGPU_CONNECTED, &result); ++ if (err) { ++ pr_warn("Failed to get egpu connection status: %d\n", err); ++ return err; ++ } ++ ++ if (asus_bios.gpu_mux_dev_id) { ++ err = asus_wmi_get_devstate_dsts(asus_bios.gpu_mux_dev_id, &result); ++ if (err) { ++ pr_warn("Failed to get gpu mux status: %d\n", result); ++ return result; ++ } ++ if (!result && enable) { ++ err = -ENODEV; ++ pr_warn("Can not enable eGPU when the MUX is in dGPU mode: %d\n", err); ++ return err; ++ } ++ } ++ ++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, enable, &result); ++ if (err) { ++ pr_warn("Failed to set egpu state: %d\n", err); ++ return err; ++ } ++ ++ if (result > 1) { ++ pr_warn("Failed to set egpu state (retval): 0x%x\n", result); ++ return -EIO; ++ } ++ ++ sysfs_notify(kobj, NULL, attr->attr.name); ++ ++ return count; ++} ++WMI_SHOW_INT(egpu_enable_current_value, "%d\n", ASUS_WMI_DEVID_EGPU); ++ATTR_GROUP_BOOL_CUSTOM(egpu_enable, "egpu_enable", "Enable the eGPU (also disables dGPU)"); ++ ++/* Simple attribute creation */ ++ATTR_GROUP_ENUM_INT_RW(thermal_policy, "thermal_policy", ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, 0, 3, "0;1;2", "Fan stuff todo"); ++ATTR_GROUP_PPT_RW(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL, ++ cpu_default, 5, cpu_max, 1, "Set the CPU slow package limit"); ++ATTR_GROUP_PPT_RW(ppt_pl2_sppt, "ppt_pl2_sppt", ASUS_WMI_DEVID_PPT_PL2_SPPT, ++ cpu_default, 5, cpu_max, 1, "Set the CPU fast package limit"); ++ATTR_GROUP_PPT_RW(ppt_apu_sppt, "ppt_apu_sppt", ASUS_WMI_DEVID_PPT_APU_SPPT, ++ platform_default, 5, platform_max, 1, "Set the CPU slow package limit"); ++ATTR_GROUP_PPT_RW(ppt_platform_sppt, "ppt_platform_sppt", ASUS_WMI_DEVID_PPT_PLAT_SPPT, ++ platform_default, 5, platform_max, 1, "Set the CPU slow package limit"); ++ATTR_GROUP_PPT_RW(ppt_fppt, "ppt_fppt", ASUS_WMI_DEVID_PPT_FPPT, ++ cpu_default, 5, cpu_max, 1, "Set the CPU slow package limit"); ++ ++ATTR_GROUP_PPT_RW(nv_dynamic_boost, "nv_dynamic_boost", ASUS_WMI_DEVID_NV_DYN_BOOST, ++ nv_boost_default, 5, nv_boost_max, 1, "Set the Nvidia dynamic boost limit"); ++ATTR_GROUP_PPT_RW(nv_temp_target, "nv_temp_target", ASUS_WMI_DEVID_NV_THERM_TARGET, ++ nv_temp_default, 75, nv_temp_max, 1, "Set the Nvidia max thermal limit"); ++ ++ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, 0, 0, "0;1;2", "Show the current mode of charging"); ++ATTR_GROUP_BOOL_RW(boot_sound, "boot_sound", ASUS_WMI_DEVID_BOOT_SOUND, "Set the boot POST sound"); ++ATTR_GROUP_BOOL_RW(mcu_powersave, "mcu_powersave", ASUS_WMI_DEVID_MCU_POWERSAVE, "Set MCU powersaving mode"); ++ATTR_GROUP_BOOL_RW(panel_od, "panel_overdrive", ASUS_WMI_DEVID_PANEL_OD, "Set the panel refresh overdrive"); ++ATTR_GROUP_BOOL_RO(egpu_connected, "egpu_connected", ASUS_WMI_DEVID_EGPU_CONNECTED, "Show the eGPU connection status"); ++ ++static int asus_fw_attr_add(void) ++{ ++ int ret; ++ ret = fw_attributes_class_get(&fw_attr_class); ++ if (ret) ++ goto fail_class_created; ++ else ++ asus_bios.fw_attr_dev = device_create(fw_attr_class, NULL, ++ MKDEV(0, 0), NULL, "%s", DRIVER_NAME); ++ ++ if (IS_ERR(asus_bios.fw_attr_dev)) { ++ ret = PTR_ERR(asus_bios.fw_attr_dev); ++ goto fail_class_created; ++ } ++ ++ asus_bios.fw_attr_kset = kset_create_and_add("attributes", NULL, ++ &asus_bios.fw_attr_dev->kobj); ++ if (!asus_bios.fw_attr_dev) { ++ ret = -ENOMEM; ++ pr_debug("Failed to create and add attributes\n"); ++ goto err_destroy_classdev; ++ } ++ ++ /* Add any firmware_attributes required */ ++ ret = sysfs_create_file(&asus_bios.fw_attr_kset->kobj, &pending_reboot.attr); ++ if (ret) { ++ pr_warn("Failed to create sysfs level attributes\n"); ++ goto fail_class_created; ++ } ++ ++ // TODO: logging ++ asus_bios.mini_led_dev_id = 0; ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_MINI_LED_MODE)) { ++ asus_bios.mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE; ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &mini_led_mode_attr_group); ++ } ++ else if (asus_wmi_is_present(ASUS_WMI_DEVID_MINI_LED_MODE2)) { ++ asus_bios.mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2; ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &mini_led_mode_attr_group); ++ } ++ ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_GPU_MUX)) { ++ asus_bios.gpu_mux_dev_id = ASUS_WMI_DEVID_GPU_MUX; ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &gpu_mux_mode_attr_group); ++ } else if (asus_wmi_is_present(ASUS_WMI_DEVID_GPU_MUX_VIVO)) { ++ asus_bios.gpu_mux_dev_id = ASUS_WMI_DEVID_GPU_MUX_VIVO; ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &gpu_mux_mode_attr_group); ++ } ++ ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU)) { ++ asus_bios.dgpu_disable_available = true; ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_disable_attr_group); ++ } ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_EGPU)) { ++ asus_bios.egpu_enable_available = true; ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &egpu_enable_attr_group); ++ } ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_EGPU_CONNECTED)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &egpu_connected_attr_group); ++ ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &thermal_policy_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_PL1_SPL)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &ppt_pl1_spl_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_PL2_SPPT)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &ppt_pl2_sppt_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_APU_SPPT)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &ppt_apu_sppt_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_PLAT_SPPT)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &ppt_platform_sppt_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_FPPT)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &ppt_fppt_attr_group); ++ ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_NV_DYN_BOOST)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &nv_dynamic_boost_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_NV_THERM_TARGET)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &nv_temp_target_attr_group); ++ ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_CHARGE_MODE)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &charge_mode_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_BOOT_SOUND)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &boot_sound_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_MCU_POWERSAVE)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &mcu_powersave_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_PANEL_OD)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &panel_od_attr_group); ++ ++ return 0; ++ ++err_destroy_classdev: ++ device_destroy(fw_attr_class, MKDEV(0, 0)); ++ ++fail_class_created: ++ fw_attributes_class_put(); ++ return ret; ++} ++ ++/* Init / exit ****************************************************************/ ++ ++/* Set up the min/max and defaults for ROG tunables */ ++static void init_rog_tunables(struct rog_tunables *rog) ++{ ++ const char *product; ++ u32 max_boost = NVIDIA_BOOST_MAX; ++ u32 cpu_default = PPT_CPU_LIMIT_DEFAULT; ++ u32 cpu_max = PPT_CPU_LIMIT_MAX; ++ u32 platform_default = PPT_PLATFORM_DEFAULT; ++ u32 platform_max = PPT_PLATFORM_MAX; ++ ++ /* ++ * ASUS product_name contains everything required, e.g, ++ * "ROG Flow X16 GV601VV_GV601VV_00185149B" ++ */ ++ product = dmi_get_system_info(DMI_PRODUCT_NAME); ++ ++ if (strstr(product, "GA402R")) { ++ cpu_default = 125; ++ } else if (strstr(product, "13QY")) { ++ cpu_max = 250; ++ } else if (strstr(product, "X13")) { ++ cpu_max = 75; ++ cpu_default = 50; ++ } else if (strstr(product, "RC71")) { ++ cpu_max = 50; ++ cpu_default = 30; ++ } else if (strstr(product, "G814") ++ || strstr(product, "G614") ++ || strstr(product, "G834") ++ || strstr(product, "G634")) { ++ cpu_max = 175; ++ } else if (strstr(product, "GA402X") ++ || strstr(product, "GA403") ++ || strstr(product, "FA507N") ++ || strstr(product, "FA507X") ++ || strstr(product, "FA707N") ++ || strstr(product, "FA707X")) { ++ cpu_max = 90; ++ } ++ ++ if (strstr(product, "GZ301ZE")) ++ max_boost = 5; ++ else if (strstr(product, "FX507ZC4")) ++ max_boost = 15; ++ else if (strstr(product, "GU605")) ++ max_boost = 20; ++ ++ /* ensure defaults for tunables */ ++ rog->cpu_default = cpu_default; ++ rog->cpu_max = cpu_max; ++ ++ rog->platform_default = platform_default; ++ rog->platform_max = platform_max; ++ ++ rog->ppt_pl1_spl = cpu_default; ++ rog->ppt_pl2_sppt = cpu_default; ++ rog->ppt_apu_sppt = cpu_default; ++ ++ rog->ppt_platform_sppt = platform_default; ++ rog->ppt_fppt = platform_default; ++ ++ rog->nv_boost_default = NVIDIA_BOOST_MAX; ++ rog->nv_boost_max = max_boost; ++ rog->nv_dynamic_boost = NVIDIA_BOOST_MIN; ++ ++ rog->nv_temp_default = NVIDIA_TEMP_MAX; ++ rog->nv_temp_max = NVIDIA_TEMP_MAX; ++ rog->nv_temp_target = NVIDIA_TEMP_MIN; ++ ++} ++ ++static int __init asus_fw_init(void) ++{ ++ int err; ++ ++ mutex_lock(&asus_bios.mutex); ++ ++ asus_bios.rog_tunables = kzalloc(sizeof(struct rog_tunables), GFP_KERNEL); ++ if (!asus_bios.rog_tunables) { ++ mutex_unlock(&asus_bios.mutex); ++ return -ENOMEM; ++ } ++ init_rog_tunables(asus_bios.rog_tunables); ++ ++ err = asus_fw_attr_add(); ++ mutex_unlock(&asus_bios.mutex); ++ if (err) ++ return err; ++ ++ return 0; ++} ++ ++static void __exit asus_fw_exit(void) ++{ ++ mutex_lock(&asus_bios.mutex); ++ ++ sysfs_remove_file(&asus_bios.fw_attr_kset->kobj, &pending_reboot.attr); ++ kset_unregister(asus_bios.fw_attr_kset); ++ device_destroy(fw_attr_class, MKDEV(0, 0)); ++ fw_attributes_class_put(); ++ ++ mutex_unlock(&asus_bios.mutex); ++} ++ ++module_init(asus_fw_init); ++module_exit(asus_fw_exit); +diff --git a/drivers/platform/x86/asus-bios.h b/drivers/platform/x86/asus-bios.h +new file mode 100644 +index 000000000000..acae11698a07 +--- /dev/null ++++ b/drivers/platform/x86/asus-bios.h +@@ -0,0 +1,234 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Definitions for kernel modules using asus-bios driver ++ * ++ * Copyright (c) 2024 Luke Jones <luke@ljones.dev> ++ */ ++ ++#ifndef _ASUS_BIOSCFG_H_ ++#define _ASUS_BIOSCFG_H_ ++ ++#include "firmware_attributes_class.h" ++#include <linux/types.h> ++ ++#define DRIVER_NAME "asus-bioscfg" ++ ++static ssize_t attr_int_store(struct kobject *kobj, struct kobj_attribute *attr, ++ const char *buf, size_t count, ++ u32 min, u32 max, u32 *store_value, u32 wmi_dev); ++ ++ ++static ssize_t int_type_show(struct kobject *kobj, struct kobj_attribute *attr, ++ char *buf) ++{ ++ return sysfs_emit(buf, "integer\n"); ++} ++ ++static ssize_t enum_type_show(struct kobject *kobj, struct kobj_attribute *attr, ++ char *buf) ++{ ++ return sysfs_emit(buf, "enumeration\n"); ++} ++ ++#define __ASUS_ATTR_RO(_func, _name) { \ ++ .attr = { .name = __stringify(_name), .mode = 0444 }, \ ++ .show = _func##_##_name##_show, \ ++} ++ ++#define __ASUS_ATTR_RO_AS(_name, _show) { \ ++ .attr = { .name = __stringify(_name), .mode = 0444 }, \ ++ .show = _show, \ ++} ++ ++#define __ASUS_ATTR_RW(_func, _name) __ATTR(_name, 0644, _func##_##_name##_show, _func##_##_name##_store) ++ ++#define __WMI_STORE_INT(_attr, _min, _max, _wmi) \ ++static ssize_t _attr##_store(struct kobject *kobj, \ ++ struct kobj_attribute *attr, \ ++ const char *buf, size_t count) \ ++{ \ ++ return attr_int_store(kobj, attr, buf, count, _min, _max, NULL, _wmi); \ ++} ++ ++#define WMI_SHOW_INT(_attr, _fmt, _wmi) \ ++static ssize_t _attr##_show(struct kobject *kobj, \ ++ struct kobj_attribute *attr, char *buf) \ ++{ \ ++ u32 result; \ ++ int err; \ ++ err = asus_wmi_get_devstate_dsts(_wmi, &result); \ ++ if (err) \ ++ return err; \ ++ return sysfs_emit(buf, _fmt, \ ++ result & ~ASUS_WMI_DSTS_PRESENCE_BIT); \ ++} ++ ++/* Create functions and attributes for use in other macros or on their own */ ++ ++#define __ROG_TUNABLE_RW(_attr, _min, _max, _wmi) \ ++static ssize_t _attr##_current_value_store(struct kobject *kobj, \ ++ struct kobj_attribute *attr, \ ++ const char *buf, size_t count) \ ++{ \ ++ return attr_int_store(kobj, attr, buf, count, \ ++ _min, asus_bios.rog_tunables->_max, \ ++ &asus_bios.rog_tunables->_attr, _wmi); \ ++} \ ++static ssize_t _attr##_current_value_show(struct kobject *kobj, \ ++ struct kobj_attribute *attr, char *buf) \ ++{ \ ++ return sysfs_emit(buf, "%u\n", asus_bios.rog_tunables->_attr); \ ++} \ ++static struct kobj_attribute attr_##_attr##_current_value = \ ++ __ASUS_ATTR_RW(_attr, current_value); ++ ++#define __ROG_TUNABLE_SHOW(_prop, _attrname, _val) \ ++static ssize_t _attrname##_##_prop##_show(struct kobject *kobj, \ ++ struct kobj_attribute *attr, char *buf) \ ++{ \ ++ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->_val); \ ++} \ ++static struct kobj_attribute attr_##_attrname##_##_prop = \ ++ __ASUS_ATTR_RO(_attrname, _prop); ++ ++#define __ATTR_CURRENT_INT_RO(_attr, _wmi) \ ++WMI_SHOW_INT(_attr##_current_value, "%d\n", _wmi); \ ++static struct kobj_attribute attr_##_attr##_current_value = \ ++ __ASUS_ATTR_RO(_attr, current_value); ++ ++#define __ATTR_CURRENT_INT_RW(_attr, _minv, _maxv, _wmi) \ ++__WMI_STORE_INT(_attr##_current_value, _minv, _maxv, _wmi); \ ++WMI_SHOW_INT(_attr##_current_value, "%d\n", _wmi); \ ++static struct kobj_attribute attr_##_attr##_current_value = \ ++ __ASUS_ATTR_RW(_attr, current_value); ++ ++/* Shows a formatted static variable */ ++#define __ATTR_SHOW_FMT(_prop, _attrname, _fmt, _val) \ ++static ssize_t _attrname##_##_prop##_show(struct kobject *kobj, \ ++ struct kobj_attribute *attr, char *buf) \ ++{ \ ++ return sysfs_emit(buf, _fmt, _val); \ ++} \ ++static struct kobj_attribute attr_##_attrname##_##_prop = \ ++ __ASUS_ATTR_RO(_attrname, _prop); ++ ++/* Int style min/max range, base macro. Requires current_value show&|store */ ++#define __ATTR_GROUP_INT(_attrname, _fsname, _default, \ ++ _min, _max, _incstep, _dispname)\ ++__ATTR_SHOW_FMT(default_value, _attrname, "%d\n", _default); \ ++__ATTR_SHOW_FMT(min_value, _attrname, "%d\n", _min); \ ++__ATTR_SHOW_FMT(max_value, _attrname, "%d\n", _max); \ ++__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", _incstep); \ ++__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \ ++static struct kobj_attribute attr_##_attrname##_type = \ ++ __ASUS_ATTR_RO_AS(type, int_type_show); \ ++static struct attribute *_attrname##_attrs[] = { \ ++ &attr_##_attrname##_current_value.attr, \ ++ &attr_##_attrname##_default_value.attr, \ ++ &attr_##_attrname##_min_value.attr, \ ++ &attr_##_attrname##_max_value.attr, \ ++ &attr_##_attrname##_scalar_increment.attr, \ ++ &attr_##_attrname##_display_name.attr, \ ++ &attr_##_attrname##_type.attr, \ ++ NULL \ ++}; \ ++static const struct attribute_group _attrname##_attr_group = { \ ++ .name = _fsname, \ ++ .attrs = _attrname##_attrs \ ++}; ++ ++/* Boolean style enumeration, base macro. Requires adding show/store */ ++#define __ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname) \ ++__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \ ++__ATTR_SHOW_FMT(possible_values, _attrname, "%s\n", _possible); \ ++static struct kobj_attribute attr_##_attrname##_type = \ ++ __ASUS_ATTR_RO_AS(type, enum_type_show); \ ++static struct attribute *_attrname##_attrs[] = { \ ++ &attr_##_attrname##_current_value.attr, \ ++ &attr_##_attrname##_display_name.attr, \ ++ &attr_##_attrname##_possible_values.attr, \ ++ &attr_##_attrname##_type.attr, \ ++ NULL \ ++}; \ ++static const struct attribute_group _attrname##_attr_group = { \ ++ .name = _fsname, \ ++ .attrs = _attrname##_attrs \ ++}; ++ ++#define ATTR_GROUP_BOOL_RO(_attrname, _fsname, _wmi, _dispname) \ ++__ATTR_CURRENT_INT_RO(_attrname, _wmi); \ ++__ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname); ++ ++#define ATTR_GROUP_BOOL_RW(_attrname, _fsname, _wmi, _dispname) \ ++__ATTR_CURRENT_INT_RW(_attrname, 0, 1, _wmi); \ ++__ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname); ++ ++/* ++ * Requires <name>_current_value_show(), <name>_current_value_show() ++ */ ++#define ATTR_GROUP_BOOL_CUSTOM(_attrname, _fsname, _dispname) \ ++static struct kobj_attribute attr_##_attrname##_current_value = \ ++ __ASUS_ATTR_RW(_attrname, current_value); \ ++__ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname); ++ ++#define ATTR_GROUP_ENUM_INT_RO(_attrname, _fsname, _wmi, _min, \ ++ _max, _possible, _dispname) \ ++__ATTR_CURRENT_INT_RO(_attrname, _wmi); \ ++__ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname); ++ ++#define ATTR_GROUP_ENUM_INT_RW(_attrname, _fsname, _wmi, _min, \ ++ _max, _possible, _dispname) \ ++__ATTR_CURRENT_INT_RW(_attrname, _min, _max, _wmi); \ ++__ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname); ++ ++/* ++ * Requires <name>_current_value_show(), <name>_current_value_show() ++ * and <name>_possible_values_show() ++ */ ++#define ATTR_GROUP_ENUM_CUSTOM(_attrname, _fsname, _dispname) \ ++__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \ ++static struct kobj_attribute attr_##_attrname##_current_value = \ ++ __ASUS_ATTR_RW(_attrname, current_value); \ ++static struct kobj_attribute attr_##_attrname##_possible_values = \ ++ __ASUS_ATTR_RO(_attrname, possible_values); \ ++static struct kobj_attribute attr_##_attrname##_type = \ ++ __ASUS_ATTR_RO_AS(type, enum_type_show); \ ++static struct attribute *_attrname##_attrs[] = { \ ++ &attr_##_attrname##_current_value.attr, \ ++ &attr_##_attrname##_display_name.attr, \ ++ &attr_##_attrname##_possible_values.attr, \ ++ &attr_##_attrname##_type.attr, \ ++ NULL \ ++}; \ ++static const struct attribute_group _attrname##_attr_group = { \ ++ .name = _fsname, \ ++ .attrs = _attrname##_attrs \ ++}; ++ ++/* ROG PPT attributes need a little different in setup */ ++#define ATTR_GROUP_PPT_RW(_attrname, _fsname, _wmi, _default, \ ++ _min, _max, _incstep, _dispname) \ ++__ROG_TUNABLE_RW(_attrname, _min, _max, _wmi); \ ++__ROG_TUNABLE_SHOW(default_value, _attrname, _default); \ ++__ATTR_SHOW_FMT(min_value, _attrname, "%d\n", _min); \ ++__ROG_TUNABLE_SHOW(max_value, _attrname, _max); \ ++__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", _incstep); \ ++__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \ ++static struct kobj_attribute attr_##_attrname##_type = \ ++ __ASUS_ATTR_RO_AS(type, int_type_show); \ ++static struct attribute *_attrname##_attrs[] = { \ ++ &attr_##_attrname##_current_value.attr, \ ++ &attr_##_attrname##_default_value.attr, \ ++ &attr_##_attrname##_min_value.attr, \ ++ &attr_##_attrname##_max_value.attr, \ ++ &attr_##_attrname##_scalar_increment.attr, \ ++ &attr_##_attrname##_display_name.attr, \ ++ &attr_##_attrname##_type.attr, \ ++ NULL \ ++}; \ ++static const struct attribute_group _attrname##_attr_group = { \ ++ .name = _fsname, \ ++ .attrs = _attrname##_attrs \ ++}; ++ ++#endif /* _ASUS_BIOSCFG_H_ */ +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 7d87ff68f418..a6f2e5325a60 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -529,12 +529,28 @@ static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval) + return 0; + } + +-static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, ++int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval) ++{ ++ int err; ++ ++ err = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, dev_id, 0, retval); ++ if (err) ++ return err; ++ ++ if (*retval == ~0) ++ return -ENODEV; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(asus_wmi_get_devstate_dsts); ++ ++int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, + u32 *retval) + { + return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id, + ctrl_param, retval); + } ++EXPORT_SYMBOL_GPL(asus_wmi_set_devstate); + + /* Helper for special devices with magic return codes */ + static int asus_wmi_get_devstate_bits(struct asus_wmi *asus, +diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h +index 6ba0015e4386..525cb7c803fe 100644 +--- a/include/linux/platform_data/x86/asus-wmi.h ++++ b/include/linux/platform_data/x86/asus-wmi.h +@@ -152,8 +152,18 @@ + #define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F + + #if IS_REACHABLE(CONFIG_ASUS_WMI) ++int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval); ++int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval); + int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval); + #else ++static int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval) ++{ ++ return -ENODEV; ++} ++static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval) ++{ ++ return -ENODEV; ++} + static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, + u32 *retval) + { +-- +2.45.1 + +From 4a50aed36c4c202688226653511af52f5a4915e1 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Sun, 2 Jun 2024 13:44:22 +1200 +Subject: [PATCH 4/8] asus-bios: add panel-hd control + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/platform/x86/asus-bios.c | 6 +++++- + include/linux/platform_data/x86/asus-wmi.h | 1 + + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c +index c245a48c4072..9af7a8da9c05 100644 +--- a/drivers/platform/x86/asus-bios.c ++++ b/drivers/platform/x86/asus-bios.c +@@ -126,7 +126,8 @@ static ssize_t pending_reboot_show(struct kobject *kobj, + static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot); + + static bool asus_bios_requires_reboot(struct kobj_attribute *attr) { +- return !strcmp(attr->attr.name, "gpu_mux_mode"); ++ return !strcmp(attr->attr.name, "gpu_mux_mode") || ++ !strcmp(attr->attr.name, "panel_hd_mode"); + } + + /* +@@ -445,6 +446,7 @@ ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, 0 + ATTR_GROUP_BOOL_RW(boot_sound, "boot_sound", ASUS_WMI_DEVID_BOOT_SOUND, "Set the boot POST sound"); + ATTR_GROUP_BOOL_RW(mcu_powersave, "mcu_powersave", ASUS_WMI_DEVID_MCU_POWERSAVE, "Set MCU powersaving mode"); + ATTR_GROUP_BOOL_RW(panel_od, "panel_overdrive", ASUS_WMI_DEVID_PANEL_OD, "Set the panel refresh overdrive"); ++ATTR_GROUP_BOOL_RW(panel_hd_mode, "panel_hd_mode", ASUS_WMI_DEVID_PANEL_HD, "Set the panel HD mode to UHD<0> or FHD<1>"); + ATTR_GROUP_BOOL_RO(egpu_connected, "egpu_connected", ASUS_WMI_DEVID_EGPU_CONNECTED, "Show the eGPU connection status"); + + static int asus_fw_attr_add(void) +@@ -533,6 +535,8 @@ static int asus_fw_attr_add(void) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &mcu_powersave_attr_group); + if (asus_wmi_is_present(ASUS_WMI_DEVID_PANEL_OD)) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &panel_od_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_PANEL_HD)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &panel_hd_mode_attr_group); + + return 0; + +diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h +index 525cb7c803fe..c93068afc2b6 100644 +--- a/include/linux/platform_data/x86/asus-wmi.h ++++ b/include/linux/platform_data/x86/asus-wmi.h +@@ -68,6 +68,7 @@ + #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO 0x00110019 + + /* Misc */ ++#define ASUS_WMI_DEVID_PANEL_HD 0x0005001C + #define ASUS_WMI_DEVID_PANEL_OD 0x00050019 + #define ASUS_WMI_DEVID_CAMERA 0x00060013 + #define ASUS_WMI_DEVID_LID_FLIP 0x00060062 +-- +2.45.1 + +From 59d69aba37bc9ca2a22a2c44d8a5dd8600d2a35c Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Sun, 2 Jun 2024 14:32:15 +1200 +Subject: [PATCH 5/8] asus-bios: add dgpu tgp control + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/platform/x86/asus-bios.c | 8 +++++++ + drivers/platform/x86/asus-bios.h | 25 ++++++++++++++++++++++ + include/linux/platform_data/x86/asus-wmi.h | 3 +++ + 3 files changed, 36 insertions(+) + +diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c +index 9af7a8da9c05..d453f02a22fd 100644 +--- a/drivers/platform/x86/asus-bios.c ++++ b/drivers/platform/x86/asus-bios.c +@@ -53,6 +53,7 @@ MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); + #define NVIDIA_BOOST_MAX 25 + #define NVIDIA_TEMP_MIN 75 + #define NVIDIA_TEMP_MAX 87 ++#define NVIDIA_GPU_POWER_MAX 70 + + /* Tunables provided by ASUS for gaming laptops */ + struct rog_tunables { +@@ -441,6 +442,9 @@ ATTR_GROUP_PPT_RW(nv_dynamic_boost, "nv_dynamic_boost", ASUS_WMI_DEVID_NV_DYN_BO + nv_boost_default, 5, nv_boost_max, 1, "Set the Nvidia dynamic boost limit"); + ATTR_GROUP_PPT_RW(nv_temp_target, "nv_temp_target", ASUS_WMI_DEVID_NV_THERM_TARGET, + nv_temp_default, 75, nv_temp_max, 1, "Set the Nvidia max thermal limit"); ++ATTR_GROUP_INT_VALUE_ONLY_RO(dgpu_base_tgp, "dgpu_base_tgp", ASUS_WMI_DEVID_DGPU_BASE_TGP, "Read the base TGP value") ++ATTR_GROUP_INT_RW(dgpu_tgp, "dgpu_tgp", ASUS_WMI_DEVID_DGPU_SET_TGP, ++ 70, 0, NVIDIA_GPU_POWER_MAX, 1, "Set the additional TGP on top of the base TGP"); + + ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, 0, 0, "0;1;2", "Show the current mode of charging"); + ATTR_GROUP_BOOL_RW(boot_sound, "boot_sound", ASUS_WMI_DEVID_BOOT_SOUND, "Set the boot POST sound"); +@@ -526,6 +530,10 @@ static int asus_fw_attr_add(void) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &nv_dynamic_boost_attr_group); + if (asus_wmi_is_present(ASUS_WMI_DEVID_NV_THERM_TARGET)) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &nv_temp_target_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU_BASE_TGP)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_base_tgp_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU_SET_TGP)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_tgp_attr_group); + + if (asus_wmi_is_present(ASUS_WMI_DEVID_CHARGE_MODE)) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &charge_mode_attr_group); +diff --git a/drivers/platform/x86/asus-bios.h b/drivers/platform/x86/asus-bios.h +index acae11698a07..7c4176ab757a 100644 +--- a/drivers/platform/x86/asus-bios.h ++++ b/drivers/platform/x86/asus-bios.h +@@ -112,6 +112,22 @@ static ssize_t _attrname##_##_prop##_show(struct kobject *kobj, \ + static struct kobj_attribute attr_##_attrname##_##_prop = \ + __ASUS_ATTR_RO(_attrname, _prop); + ++/* Requires current_value show&|store */ ++#define __ATTR_GROUP_INT_VALUE_ONLY(_attrname, _fsname, _dispname) \ ++__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \ ++static struct kobj_attribute attr_##_attrname##_type = \ ++ __ASUS_ATTR_RO_AS(type, int_type_show); \ ++static struct attribute *_attrname##_attrs[] = { \ ++ &attr_##_attrname##_current_value.attr, \ ++ &attr_##_attrname##_display_name.attr, \ ++ &attr_##_attrname##_type.attr, \ ++ NULL \ ++}; \ ++static const struct attribute_group _attrname##_attr_group = { \ ++ .name = _fsname, \ ++ .attrs = _attrname##_attrs \ ++}; ++ + /* Int style min/max range, base macro. Requires current_value show&|store */ + #define __ATTR_GROUP_INT(_attrname, _fsname, _default, \ + _min, _max, _incstep, _dispname)\ +@@ -155,6 +171,15 @@ static const struct attribute_group _attrname##_attr_group = { \ + .attrs = _attrname##_attrs \ + }; + ++#define ATTR_GROUP_INT_VALUE_ONLY_RO(_attrname, _fsname, _wmi, _dispname) \ ++__ATTR_CURRENT_INT_RO(_attrname, _wmi); \ ++__ATTR_GROUP_INT_VALUE_ONLY(_attrname, _fsname, _dispname); ++ ++#define ATTR_GROUP_INT_RW(_attrname, _fsname, _wmi, _default, _min, \ ++ _max, _incstep, _dispname) \ ++__ATTR_CURRENT_INT_RW(_attrname, _min, _max, _wmi); \ ++__ATTR_GROUP_INT(_attrname, _fsname, _default, _min, _max, _incstep, _dispname); ++ + #define ATTR_GROUP_BOOL_RO(_attrname, _fsname, _wmi, _dispname) \ + __ATTR_CURRENT_INT_RO(_attrname, _wmi); \ + __ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname); +diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h +index c93068afc2b6..71f3f1d67479 100644 +--- a/include/linux/platform_data/x86/asus-wmi.h ++++ b/include/linux/platform_data/x86/asus-wmi.h +@@ -128,6 +128,9 @@ + /* dgpu on/off */ + #define ASUS_WMI_DEVID_DGPU 0x00090020 + ++#define ASUS_WMI_DEVID_DGPU_BASE_TGP 0x00120099 ++#define ASUS_WMI_DEVID_DGPU_SET_TGP 0x00120098 ++ + /* gpu mux switch, 0 = dGPU, 1 = Optimus */ + #define ASUS_WMI_DEVID_GPU_MUX 0x00090016 + #define ASUS_WMI_DEVID_GPU_MUX_VIVO 0x00090026 +-- +2.45.1 + +From ae58c8b2e60a5feff3cf833d7f572414758d06c2 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Sun, 2 Jun 2024 14:44:31 +1200 +Subject: [PATCH 6/8] asus-bios: add apu-mem + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/platform/x86/asus-bios.c | 116 +++++++++++++++++++++ + include/linux/platform_data/x86/asus-wmi.h | 1 + + 2 files changed, 117 insertions(+) + +diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c +index d453f02a22fd..bcb053b57102 100644 +--- a/drivers/platform/x86/asus-bios.c ++++ b/drivers/platform/x86/asus-bios.c +@@ -425,6 +425,120 @@ static ssize_t egpu_enable_current_value_store(struct kobject *kobj, + WMI_SHOW_INT(egpu_enable_current_value, "%d\n", ASUS_WMI_DEVID_EGPU); + ATTR_GROUP_BOOL_CUSTOM(egpu_enable, "egpu_enable", "Enable the eGPU (also disables dGPU)"); + ++/* Device memory available to APU */ ++ ++static ssize_t apu_mem_current_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ int err; ++ u32 mem; ++ ++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_APU_MEM, &mem); ++ if (err) ++ return err; ++ ++ switch (mem) { ++ case 256: ++ mem = 0; ++ break; ++ case 258: ++ mem = 1; ++ break; ++ case 259: ++ mem = 2; ++ break; ++ case 260: ++ mem = 3; ++ break; ++ case 261: ++ mem = 4; ++ break; ++ case 262: ++ /* This is out of order and looks wrong but is correct */ ++ mem = 8; ++ break; ++ case 263: ++ mem = 5; ++ break; ++ case 264: ++ mem = 6; ++ break; ++ case 265: ++ mem = 7; ++ break; ++ default: ++ mem = 4; ++ break; ++ } ++ ++ return sysfs_emit(buf, "%d\n", mem); ++} ++ ++static ssize_t apu_mem_current_value_store(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int result, err; ++ u32 requested, mem; ++ ++ result = kstrtou32(buf, 10, &requested); ++ if (result) ++ return result; ++ ++ switch (requested) { ++ case 0: ++ mem = 0; ++ break; ++ case 1: ++ mem = 258; ++ break; ++ case 2: ++ mem = 259; ++ break; ++ case 3: ++ mem = 260; ++ break; ++ case 4: ++ mem = 261; ++ break; ++ case 5: ++ mem = 263; ++ break; ++ case 6: ++ mem = 264; ++ break; ++ case 7: ++ mem = 265; ++ break; ++ case 8: ++ /* This is outof order and looks wrong but is correct */ ++ mem = 262; ++ break; ++ default: ++ return -EIO; ++ } ++ ++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_APU_MEM, mem, &result); ++ if (err) { ++ pr_warn("Failed to set apu_mem: %d\n", err); ++ return err; ++ } ++ ++ pr_info("APU memory changed to %dGB, reboot required\n", requested); ++ sysfs_notify(kobj, NULL, attr->attr.name); ++ ++ asus_set_reboot_and_signal_event(); ++ ++ return count; ++} ++ ++static ssize_t apu_mem_possible_values_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return sysfs_emit(buf, "0;1;2;3;4;5;6;7;8\n"); ++} ++ATTR_GROUP_ENUM_CUSTOM(apu_mem, "apu_mem", "Set the available system memory for the APU to use"); ++ + /* Simple attribute creation */ + ATTR_GROUP_ENUM_INT_RW(thermal_policy, "thermal_policy", ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, 0, 3, "0;1;2", "Fan stuff todo"); + ATTR_GROUP_PPT_RW(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL, +@@ -534,6 +648,8 @@ static int asus_fw_attr_add(void) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_base_tgp_attr_group); + if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU_SET_TGP)) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_tgp_attr_group); ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_APU_MEM)) ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &apu_mem_attr_group); + + if (asus_wmi_is_present(ASUS_WMI_DEVID_CHARGE_MODE)) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &charge_mode_attr_group); +diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h +index 71f3f1d67479..da0e423ecb06 100644 +--- a/include/linux/platform_data/x86/asus-wmi.h ++++ b/include/linux/platform_data/x86/asus-wmi.h +@@ -130,6 +130,7 @@ + + #define ASUS_WMI_DEVID_DGPU_BASE_TGP 0x00120099 + #define ASUS_WMI_DEVID_DGPU_SET_TGP 0x00120098 ++#define ASUS_WMI_DEVID_APU_MEM 0x000600C1 + + /* gpu mux switch, 0 = dGPU, 1 = Optimus */ + #define ASUS_WMI_DEVID_GPU_MUX 0x00090016 +-- +2.45.1 + +From f7e8fe2458a3f8aa091e5e282b67f2a78f5cc1c4 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Sun, 2 Jun 2024 16:21:32 +1200 +Subject: [PATCH 7/8] asus-bios: add core count control + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/platform/x86/asus-bios.c | 201 +++++++++++++++++++++ + drivers/platform/x86/asus-bios.h | 29 +++ + include/linux/platform_data/x86/asus-wmi.h | 4 + + 3 files changed, 234 insertions(+) + +diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c +index bcb053b57102..bd4c408fd062 100644 +--- a/drivers/platform/x86/asus-bios.c ++++ b/drivers/platform/x86/asus-bios.c +@@ -42,6 +42,18 @@ MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); + #define ASUS_MINI_LED_2024_STRONG 0x01 + #define ASUS_MINI_LED_2024_OFF 0x02 + ++enum cpu_core_type { ++ CPU_CORE_PERF = 0, ++ CPU_CORE_POWER, ++}; ++ ++enum cpu_core_value { ++ CPU_CORE_DEFAULT = 0, ++ CPU_CORE_MIN, ++ CPU_CORE_MAX, ++ CPU_CORE_CURRENT, ++}; ++ + /* Default limits for tunables available on ASUS ROG laptops */ + #define PPT_CPU_LIMIT_MIN 5 + #define PPT_CPU_LIMIT_MAX 150 +@@ -76,6 +88,10 @@ struct rog_tunables { + u32 nv_temp_default; + u32 nv_temp_max; + u32 nv_temp_target; ++ ++ u32 min_perf_cores; ++ u32 max_perf_cores; ++ u32 max_power_cores; + }; + + static const struct class *fw_attr_class; +@@ -539,6 +555,185 @@ static ssize_t apu_mem_possible_values_show(struct kobject *kobj, + } + ATTR_GROUP_ENUM_CUSTOM(apu_mem, "apu_mem", "Set the available system memory for the APU to use"); + ++static int asus_bios_set_max_cores(void) ++{ ++ u32 cores; ++ int err; ++ ++ asus_bios.rog_tunables->min_perf_cores = 4; ++ asus_bios.rog_tunables->max_perf_cores = 4; ++ asus_bios.rog_tunables->max_power_cores = 8; ++ ++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES_MAX, &cores); ++ if (err) ++ return err; ++ ++ cores &= ~ASUS_WMI_DSTS_PRESENCE_BIT; ++ asus_bios.rog_tunables->max_power_cores = (cores & 0xff00) >> 8; ++ asus_bios.rog_tunables->max_perf_cores = cores & 0xff; ++ ++ return 0; ++} ++ ++static ssize_t cores_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf, ++ enum cpu_core_type core_type, ++ enum cpu_core_value core_value) ++{ ++ u32 cores; ++ int err; ++ ++ switch (core_value) { ++ case CPU_CORE_DEFAULT: ++ case CPU_CORE_MAX: ++ if (core_type == CPU_CORE_PERF) ++ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->max_perf_cores); ++ else ++ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->max_power_cores); ++ case CPU_CORE_MIN: ++ if (core_type == CPU_CORE_PERF) ++ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->min_perf_cores); ++ else ++ return sysfs_emit(buf, "%d\n", 0); ++ default: ++ break; ++ } ++ ++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES, &cores); ++ if (err) ++ return err; ++ ++ cores &= ~ASUS_WMI_DSTS_PRESENCE_BIT; ++ if (core_type == CPU_CORE_PERF) ++ cores &= 0xff; ++ else ++ cores = (cores & 0xff00) >> 8; ++ return sysfs_emit(buf, "%d\n", cores); ++} ++ ++static ssize_t cores_current_value_store(struct kobject *kobj, ++ struct kobj_attribute *attr, const char *buf, ++ enum cpu_core_type core_type) ++{ ++ int result, err; ++ u32 cores, currentv, min, max; ++ ++ result = kstrtou32(buf, 10, &cores); ++ if (result) ++ return result; ++ ++ if (core_type == CPU_CORE_PERF) { ++ min = asus_bios.rog_tunables->min_perf_cores; ++ max = asus_bios.rog_tunables->max_perf_cores; ++ } else { ++ min = 0; ++ max = asus_bios.rog_tunables->max_power_cores; ++ } ++ if (cores < min || cores > max) ++ return -EINVAL; ++ ++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES, ¤tv); ++ if (err) ++ return err; ++ ++ if (core_type == CPU_CORE_PERF) ++ cores |= (currentv & 0xff00); ++ else ++ cores |= currentv & 0xff; ++ ++ if (cores == currentv) ++ return 0; ++ ++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_CORES, cores, &result); ++ if (err) { ++ pr_warn("Failed to set perfromance core count: %d\n", err); ++ return err; ++ } ++ ++ if (result > 1) { ++ pr_warn("Failed to set performance core count (result): 0x%x\n", result); ++ return -EIO; ++ } ++ ++ pr_info("CPU core count changed, reboot required\n"); ++ sysfs_notify(kobj, NULL, attr->attr.name); ++ asus_set_reboot_and_signal_event(); ++ ++ return 0; ++} ++ ++static ssize_t cores_performance_min_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_MIN); ++} ++ ++static ssize_t cores_performance_max_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_MAX); ++} ++ ++static ssize_t cores_performance_default_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_DEFAULT); ++} ++ ++static ssize_t cores_performance_current_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_CURRENT); ++} ++ ++static ssize_t cores_performance_current_value_store(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int err = cores_current_value_store(kobj, attr, buf, CPU_CORE_PERF); ++ if (err) ++ return err; ++ ++ return count; ++} ++ATTR_GROUP_CORES_RW(cores_performance, "cores_performance", ASUS_WMI_DEVID_CORES, "Set the max available performance cores"); ++ ++static ssize_t cores_efficiency_min_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_MIN); ++} ++ ++static ssize_t cores_efficiency_max_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_MAX); ++} ++ ++static ssize_t cores_efficiency_default_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_DEFAULT); ++} ++ ++static ssize_t cores_efficiency_current_value_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_CURRENT); ++} ++ ++static ssize_t cores_efficiency_current_value_store(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int err = cores_current_value_store(kobj, attr, buf, CPU_CORE_POWER); ++ if (err) ++ return err; ++ ++ return count; ++} ++ATTR_GROUP_CORES_RW(cores_efficiency, "cores_efficiency", ASUS_WMI_DEVID_CORES, "Set the max available efficiency cores"); ++ + /* Simple attribute creation */ + ATTR_GROUP_ENUM_INT_RW(thermal_policy, "thermal_policy", ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, 0, 3, "0;1;2", "Fan stuff todo"); + ATTR_GROUP_PPT_RW(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL, +@@ -627,8 +822,14 @@ static int asus_fw_attr_add(void) + if (asus_wmi_is_present(ASUS_WMI_DEVID_EGPU_CONNECTED)) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &egpu_connected_attr_group); + ++ if (asus_wmi_is_present(ASUS_WMI_DEVID_CORES_MAX) && !asus_bios_set_max_cores()){ ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &cores_performance_attr_group); ++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &cores_efficiency_attr_group); ++ } ++ + if (asus_wmi_is_present(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY)) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &thermal_policy_attr_group); ++ + if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_PL1_SPL)) + sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &ppt_pl1_spl_attr_group); + if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_PL2_SPPT)) +diff --git a/drivers/platform/x86/asus-bios.h b/drivers/platform/x86/asus-bios.h +index 7c4176ab757a..7016ec14efc1 100644 +--- a/drivers/platform/x86/asus-bios.h ++++ b/drivers/platform/x86/asus-bios.h +@@ -230,6 +230,35 @@ static const struct attribute_group _attrname##_attr_group = { \ + .attrs = _attrname##_attrs \ + }; + ++/* CPU core attributes need a little different in setup */ ++#define ATTR_GROUP_CORES_RW(_attrname, _fsname, _wmi, _dispname)\ ++__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", 1); \ ++__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \ ++static struct kobj_attribute attr_##_attrname##_current_value = \ ++ __ASUS_ATTR_RW(_attrname, current_value); \ ++static struct kobj_attribute attr_##_attrname##_default_value = \ ++ __ASUS_ATTR_RO(_attrname, default_value); \ ++static struct kobj_attribute attr_##_attrname##_min_value = \ ++ __ASUS_ATTR_RO(_attrname, min_value); \ ++static struct kobj_attribute attr_##_attrname##_max_value = \ ++ __ASUS_ATTR_RO(_attrname, max_value); \ ++static struct kobj_attribute attr_##_attrname##_type = \ ++ __ASUS_ATTR_RO_AS(type, int_type_show); \ ++static struct attribute *_attrname##_attrs[] = { \ ++ &attr_##_attrname##_current_value.attr, \ ++ &attr_##_attrname##_default_value.attr, \ ++ &attr_##_attrname##_min_value.attr, \ ++ &attr_##_attrname##_max_value.attr, \ ++ &attr_##_attrname##_scalar_increment.attr, \ ++ &attr_##_attrname##_display_name.attr, \ ++ &attr_##_attrname##_type.attr, \ ++ NULL \ ++}; \ ++static const struct attribute_group _attrname##_attr_group = { \ ++ .name = _fsname, \ ++ .attrs = _attrname##_attrs \ ++}; ++ + /* ROG PPT attributes need a little different in setup */ + #define ATTR_GROUP_PPT_RW(_attrname, _fsname, _wmi, _default, \ + _min, _max, _incstep, _dispname) \ +diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h +index da0e423ecb06..9756e595d2cd 100644 +--- a/include/linux/platform_data/x86/asus-wmi.h ++++ b/include/linux/platform_data/x86/asus-wmi.h +@@ -128,6 +128,10 @@ + /* dgpu on/off */ + #define ASUS_WMI_DEVID_DGPU 0x00090020 + ++/* Intel E-core and P-core configuration in a format 0x0[E]0[P] */ ++#define ASUS_WMI_DEVID_CORES 0x001200D2 ++ /* Maximum Intel E-core and P-core availability */ ++#define ASUS_WMI_DEVID_CORES_MAX 0x001200D3 + #define ASUS_WMI_DEVID_DGPU_BASE_TGP 0x00120099 + #define ASUS_WMI_DEVID_DGPU_SET_TGP 0x00120098 + #define ASUS_WMI_DEVID_APU_MEM 0x000600C1 +-- +2.45.1 + +From 59cb165cde465df5380b809ecea6737d85405dac Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Mon, 13 May 2024 19:20:04 +1200 +Subject: [PATCH v2 1/3] hid-asus: use hid for brightness control on keyboard + +On almost all ASUS ROG series laptops the MCU used for the USB keyboard +also has a HID packet used for setting the brightness. This is usually +the same as the WMI method. But in some laptops the WMI method either +is missing or doesn't work, so we should default to the HID control. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/hid/hid-asus.c | 7 ++++ + drivers/platform/x86/asus-wmi.c | 3 +- + include/linux/platform_data/x86/asus-wmi.h | 45 ++++++++++++++++++++++ + 3 files changed, 54 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 02de2bf4f790..0ed3708ef7e2 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -492,12 +492,19 @@ static void asus_kbd_backlight_work(struct work_struct *work) + */ + static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev) + { ++ struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + u32 value; + int ret; + + if (!IS_ENABLED(CONFIG_ASUS_WMI)) + return false; + ++ if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && ++ dmi_check_system(asus_use_hid_led_dmi_ids)) { ++ hid_info(hdev, "using HID for asus::kbd_backlight\n"); ++ return false; ++ } ++ + ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, + ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value); + hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value); +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 3f9b6285c9a6..799d928c7d3d 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -1681,7 +1681,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus) + goto error; + } + +- if (!kbd_led_read(asus, &led_val, NULL)) { ++ if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) { ++ pr_info("using asus-wmi for asus::kbd_backlight\n"); + asus->kbd_led_wk = led_val; + asus->kbd_led.name = "asus::kbd_backlight"; + asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED; +diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h +index 3eb5cd6773ad..96c780efa0d7 100644 +--- a/include/linux/platform_data/x86/asus-wmi.h ++++ b/include/linux/platform_data/x86/asus-wmi.h +@@ -4,6 +4,7 @@ + + #include <linux/errno.h> + #include <linux/types.h> ++#include <linux/dmi.h> + + /* WMI Methods */ + #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */ +@@ -160,4 +161,48 @@ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, + } + #endif + ++/* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */ ++#if IS_ENABLED(CONFIG_ASUS_WMI) ++bool asus_use_hid_led(void); ++#else ++static inline bool asus_use_hid_led(void) ++{ ++ return true; ++} ++#endif ++ ++static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Zephyrus"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Strix"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "GA403U"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "GU605M"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "RC71L"), ++ }, ++ }, ++ NULL, ++}; ++ + #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */ +-- +2.45.2 + +From 671da604738dd6dd01903585e8e8a55d49ab06e9 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Fri, 7 Jun 2024 15:58:01 +1200 +Subject: [PATCH v2 3/3] Input: xpad - add support for ASUS ROG RAIKIRI PRO + +Add the VID/PID for ASUS ROG RAIKIRI PRO to +xpad_device and the VID to xpad_table. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/hid/hid-ids.h | 1 + + drivers/input/joystick/xpad.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 61d2a21affa2..31c522fa4e87 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -209,6 +209,7 @@ + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6 + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30 + #define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6 ++#define USB_DEVICE_ID_ASUSTEK_ROG_RAIKIRI_PAD 0x1abb + #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b + #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 + +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 6fadaddb2b90..3a5af0909233 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -209,6 +209,7 @@ static const struct xpad_device { + { 0x0738, 0xf738, "Super SFIV FightStick TE S", 0, XTYPE_XBOX360 }, + { 0x07ff, 0xffff, "Mad Catz GamePad", 0, XTYPE_XBOX360 }, + { 0x0b05, 0x1a38, "ASUS ROG RAIKIRI", 0, XTYPE_XBOXONE }, ++ { 0x0b05, 0x1abb, "ASUS ROG RAIKIRI PRO", 0, XTYPE_XBOXONE }, + { 0x0c12, 0x0005, "Intec wireless", 0, XTYPE_XBOX }, + { 0x0c12, 0x8801, "Nyko Xbox Controller", 0, XTYPE_XBOX }, + { 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, +-- +2.45.2 + +/* Default limits for tunables available on ASUS ROG laptops */ +#define PPT_CPU_LIMIT_MIN 5 +#define PPT_CPU_LIMIT_MAX 150 +#define PPT_CPU_LIMIT_DEFAULT 80 +#define PPT_PLATFORM_MIN 5 +#define PPT_PLATFORM_MAX 100 +#define PPT_PLATFORM_DEFAULT 80 +#define NVIDIA_BOOST_MIN 5 +#define NVIDIA_BOOST_MAX 25 +#define NVIDIA_TEMP_MIN 75 + +/* Tunables provided by ASUS for gaming laptops */ +struct rog_tunables { + u32 cpu_default; + u32 cpu_max; + + u32 platform_default; + u32 platform_max; + + u32 ppt_pl1_spl; // total + u32 ppt_pl2_sppt; // total + u32 ppt_apu_sppt; // cpu + u32 ppt_platform_sppt; // cpu + u32 ppt_fppt; // total + + u32 nv_boost_default; + u32 nv_boost_max; + u32 nv_dynamic_boost; + + u32 nv_temp_default; + u32 nv_temp_max; + u32 nv_temp_target; +}; + + +From 74b729c160f95f0bec8d7af3efc94514195b23e3 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Sat, 25 May 2024 17:31:07 +1200 +Subject: [PATCH 3/9] platform/x86: asus-wmi: add macros and expose min/max + sysfs for ppt tunables + +In most cases the safe min and max values of the various PPT tunables are +known for various ASUS ROG (and other) laptop models. We can match the +DMI string for these and expose min/max sysfs points, plus set some sane +default values. + +As part of the addition of the min/max and defaults, to reduce the amount +of code copy/paste and introduce some sanity a group of macros were added +specific to the PPT and NV tunables. The code becomes much cleaner and +easier to read. + +This makes the PPT functions much more usable and safe. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + .../ABI/testing/sysfs-platform-asus-wmi | 23 +- + drivers/platform/x86/asus-wmi.c | 561 ++++++++---------- + 2 files changed, 245 insertions(+), 339 deletions(-) + +diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi +index 28144371a0f1..984a04f32fd0 100644 +--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi ++++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi +@@ -142,8 +142,8 @@ Contact: "Luke Jones" <luke@ljones.dev> + Description: + Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD. + Shown on Intel+Nvidia or AMD+Nvidia based systems: +- +- * min=5, max=250 ++ * min/max varies, read *_min/*_max sysfs entries ++ * -1 resets to default + + What: /sys/devices/platform/<platform>/ppt_pl2_sppt + Date: Jun 2023 +@@ -152,8 +152,8 @@ Contact: "Luke Jones" <luke@ljones.dev> + Description: + Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT, + on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems: +- +- * min=5, max=250 ++ * min/max varies, read *_min/*_max sysfs entries ++ * -1 resets to default + + What: /sys/devices/platform/<platform>/ppt_fppt + Date: Jun 2023 +@@ -161,7 +161,8 @@ KernelVersion: 6.5 + Contact: "Luke Jones" <luke@ljones.dev> + Description: + Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only: +- * min=5, max=250 ++ * min/max varies, read *_min/*_max sysfs entries ++ * -1 resets to default + + What: /sys/devices/platform/<platform>/ppt_apu_sppt + Date: Jun 2023 +@@ -169,7 +170,8 @@ KernelVersion: 6.5 + Contact: "Luke Jones" <luke@ljones.dev> + Description: + Set the APU SPPT limit. Shown on full AMD systems only: +- * min=5, max=130 ++ * min/max varies, read *_min/*_max sysfs entries ++ * -1 resets to default + + What: /sys/devices/platform/<platform>/ppt_platform_sppt + Date: Jun 2023 +@@ -177,7 +179,8 @@ KernelVersion: 6.5 + Contact: "Luke Jones" <luke@ljones.dev> + Description: + Set the platform SPPT limit. Shown on full AMD systems only: +- * min=5, max=130 ++ * min/max varies, read *_min/*_max sysfs entries ++ * -1 resets to default + + What: /sys/devices/platform/<platform>/nv_dynamic_boost + Date: Jun 2023 +@@ -185,7 +188,8 @@ KernelVersion: 6.5 + Contact: "Luke Jones" <luke@ljones.dev> + Description: + Set the dynamic boost limit of the Nvidia dGPU: +- * min=5, max=25 ++ * min/max varies, read *_min/*_max sysfs entries ++ * -1 resets to default + + What: /sys/devices/platform/<platform>/nv_temp_target + Date: Jun 2023 +@@ -193,7 +197,8 @@ KernelVersion: 6.5 + Contact: "Luke Jones" <luke@ljones.dev> + Description: + Set the target temperature limit of the Nvidia dGPU: +- * min=75, max=87 ++ * min/max varies, read *_min/*_max sysfs entries ++ * -1 resets to default + + What: /sys/devices/platform/<platform>/boot_sound + Date: Apr 2024 +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 999cd658ec8b..d016acb23789 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -112,11 +112,13 @@ module_param(fnlock_default, bool, 0444); + /* Mask to determine if setting temperature or percentage */ + #define FAN_CURVE_PWM_MASK 0x04 + +-/* Limits for tunables available on ASUS ROG laptops */ +-#define PPT_TOTAL_MIN 5 +-#define PPT_TOTAL_MAX 250 +-#define PPT_CPU_MIN 5 +-#define PPT_CPU_MAX 130 ++/* Default limits for tunables available on ASUS ROG laptops */ ++#define PPT_CPU_LIMIT_MIN 5 ++#define PPT_CPU_LIMIT_MAX 150 ++#define PPT_CPU_LIMIT_DEFAULT 80 ++#define PPT_PLATFORM_MIN 5 ++#define PPT_PLATFORM_MAX 100 ++#define PPT_PLATFORM_DEFAULT 80 + #define NVIDIA_BOOST_MIN 5 + #define NVIDIA_BOOST_MAX 25 + #define NVIDIA_TEMP_MIN 75 +@@ -219,6 +221,29 @@ struct fan_curve_data { + u8 percents[FAN_CURVE_POINTS]; + }; + ++/* Tunables provided by ASUS for gaming laptops */ ++struct rog_tunables { ++ u32 cpu_default; ++ u32 cpu_max; ++ ++ u32 platform_default; ++ u32 platform_max; ++ ++ u32 ppt_pl1_spl; // total ++ u32 ppt_pl2_sppt; // total ++ u32 ppt_apu_sppt; // cpu ++ u32 ppt_platform_sppt; // cpu ++ u32 ppt_fppt; // total ++ ++ u32 nv_boost_default; ++ u32 nv_boost_max; ++ u32 nv_dynamic_boost; ++ ++ u32 nv_temp_default; ++ u32 nv_temp_max; ++ u32 nv_temp_target; ++}; ++ + struct asus_wmi { + int dsts_id; + int spec; +@@ -273,14 +298,7 @@ struct asus_wmi { + bool dgpu_disable_available; + u32 gpu_mux_dev; + +- /* Tunables provided by ASUS for gaming laptops */ +- u32 ppt_pl2_sppt; +- u32 ppt_pl1_spl; +- u32 ppt_apu_sppt; +- u32 ppt_platform_sppt; +- u32 ppt_fppt; +- u32 nv_dynamic_boost; +- u32 nv_temp_target; ++ struct rog_tunables rog_tunables; + + u32 kbd_rgb_dev; + bool kbd_rgb_state_available; +@@ -652,6 +670,98 @@ static void asus_wmi_input_exit(struct asus_wmi *asus) + asus->inputdev = NULL; + } + ++/* Helper macros for generalised WMI calls */ ++ ++/* Generic store function for use with many ROG tunables */ ++static ssize_t rog_tunable_store(struct asus_wmi *asus, ++ struct attribute *attr, ++ const char *buf, size_t count, ++ u32 min, u32 max, u32 defaultv, ++ u32 *store_value, u32 wmi_dev) ++{ ++ int result, err, value; ++ ++ result = kstrtoint(buf, 10, &value); ++ if (result) ++ return result; ++ ++ if (value == -1 ) ++ value = defaultv; ++ if (value < min || value > max) ++ return -EINVAL; ++ ++ err = asus_wmi_set_devstate(wmi_dev, value, &result); ++ if (err) { ++ pr_err("Failed to set %s: %d\n", attr->name, err); ++ return err; ++ } ++ ++ if (result > 1) { ++ pr_err("Failed to set %s (result): 0x%x\n", attr->name, result); ++ return -EIO; ++ } ++ ++ if (store_value != NULL) ++ *store_value = value; ++ sysfs_notify(&asus->platform_device->dev.kobj, NULL, attr->name); ++ ++ return count; ++} ++ ++#define ROG_TUNABLE_STORE(_fname, _min, _max, _default, _wmi) \ ++static ssize_t _fname##_store(struct device *dev, \ ++ struct device_attribute *attr, const char *buf, size_t count) \ ++{ \ ++ struct asus_wmi *asus = dev_get_drvdata(dev); \ ++ return rog_tunable_store(asus, &attr->attr, buf, count, \ ++ _min, asus->rog_tunables._max, asus->rog_tunables._default, \ ++ &asus->rog_tunables._fname, _wmi); \ ++} ++ ++#define ROG_TUNABLE_SHOW(_fname) \ ++static ssize_t _fname##_show(struct device *dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ struct asus_wmi *asus = dev_get_drvdata(dev); \ ++ return sysfs_emit(buf, "%u\n", asus->rog_tunables._fname); \ ++} ++ ++#define ROG_TUNABLE_MIN_SHOW(_fname, _minv) \ ++static ssize_t _fname##_min_show(struct device *dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ return sysfs_emit(buf, "%u\n", _minv); \ ++} ++ ++#define ROG_TUNABLE_MAX_SHOW(_fname, _maxv) \ ++static ssize_t _fname##_max_show(struct device *dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ struct asus_wmi *asus = dev_get_drvdata(dev); \ ++ return sysfs_emit(buf, "%u\n", asus->rog_tunables._maxv); \ ++} ++ ++#define ROG_ATTR_RW(_fname, _minv, _maxv, _defaultv, _wmi) \ ++ROG_TUNABLE_MIN_SHOW(_fname, _minv); \ ++ROG_TUNABLE_MAX_SHOW(_fname, _maxv); \ ++ROG_TUNABLE_STORE(_fname, _minv, _maxv, _defaultv, _wmi);\ ++ROG_TUNABLE_SHOW(_fname); \ ++static DEVICE_ATTR_RO(_fname##_min); \ ++static DEVICE_ATTR_RO(_fname##_max); \ ++static DEVICE_ATTR_RW(_fname) ++ ++ROG_ATTR_RW(ppt_platform_sppt, ++ PPT_PLATFORM_MIN, platform_max, platform_default, ASUS_WMI_DEVID_PPT_PLAT_SPPT); ++ROG_ATTR_RW(ppt_pl2_sppt, ++ PPT_CPU_LIMIT_MIN, cpu_max, cpu_default, ASUS_WMI_DEVID_PPT_PL2_SPPT); ++ROG_ATTR_RW(ppt_apu_sppt, ++ PPT_PLATFORM_MIN, platform_max, platform_default, ASUS_WMI_DEVID_PPT_APU_SPPT); ++ROG_ATTR_RW(ppt_pl1_spl, ++ PPT_CPU_LIMIT_MIN, cpu_max, cpu_default, ASUS_WMI_DEVID_PPT_PL1_SPL); ++ROG_ATTR_RW(ppt_fppt, ++ PPT_CPU_LIMIT_MIN, cpu_max, cpu_default, ASUS_WMI_DEVID_PPT_FPPT); ++ROG_ATTR_RW(nv_dynamic_boost, ++ NVIDIA_BOOST_MIN, nv_boost_max, nv_boost_default, ASUS_WMI_DEVID_NV_DYN_BOOST); ++ROG_ATTR_RW(nv_temp_target, ++ NVIDIA_TEMP_MIN, nv_temp_max, nv_temp_default, ASUS_WMI_DEVID_NV_THERM_TARGET); ++ + /* Tablet mode ****************************************************************/ + + static void asus_wmi_tablet_mode_get_state(struct asus_wmi *asus) +@@ -1018,306 +1128,6 @@ static const struct attribute_group *kbd_rgb_mode_groups[] = { + NULL, + }; + +-/* Tunable: PPT: Intel=PL1, AMD=SPPT *****************************************/ +-static ssize_t ppt_pl2_sppt_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- int result, err; +- u32 value; +- +- result = kstrtou32(buf, 10, &value); +- if (result) +- return result; +- +- if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX) +- return -EINVAL; +- +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PL2_SPPT, value, &result); +- if (err) { +- pr_warn("Failed to set ppt_pl2_sppt: %d\n", err); +- return err; +- } +- +- if (result > 1) { +- pr_warn("Failed to set ppt_pl2_sppt (result): 0x%x\n", result); +- return -EIO; +- } +- +- asus->ppt_pl2_sppt = value; +- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl2_sppt"); +- +- return count; +-} +- +-static ssize_t ppt_pl2_sppt_show(struct device *dev, +- struct device_attribute *attr, +- char *buf) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%u\n", asus->ppt_pl2_sppt); +-} +-static DEVICE_ATTR_RW(ppt_pl2_sppt); +- +-/* Tunable: PPT, Intel=PL1, AMD=SPL ******************************************/ +-static ssize_t ppt_pl1_spl_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- int result, err; +- u32 value; +- +- result = kstrtou32(buf, 10, &value); +- if (result) +- return result; +- +- if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX) +- return -EINVAL; +- +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PL1_SPL, value, &result); +- if (err) { +- pr_warn("Failed to set ppt_pl1_spl: %d\n", err); +- return err; +- } +- +- if (result > 1) { +- pr_warn("Failed to set ppt_pl1_spl (result): 0x%x\n", result); +- return -EIO; +- } +- +- asus->ppt_pl1_spl = value; +- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl1_spl"); +- +- return count; +-} +-static ssize_t ppt_pl1_spl_show(struct device *dev, +- struct device_attribute *attr, +- char *buf) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%u\n", asus->ppt_pl1_spl); +-} +-static DEVICE_ATTR_RW(ppt_pl1_spl); +- +-/* Tunable: PPT APU FPPT ******************************************************/ +-static ssize_t ppt_fppt_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- int result, err; +- u32 value; +- +- result = kstrtou32(buf, 10, &value); +- if (result) +- return result; +- +- if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX) +- return -EINVAL; +- +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_FPPT, value, &result); +- if (err) { +- pr_warn("Failed to set ppt_fppt: %d\n", err); +- return err; +- } +- +- if (result > 1) { +- pr_warn("Failed to set ppt_fppt (result): 0x%x\n", result); +- return -EIO; +- } +- +- asus->ppt_fppt = value; +- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_fpu_sppt"); +- +- return count; +-} +- +-static ssize_t ppt_fppt_show(struct device *dev, +- struct device_attribute *attr, +- char *buf) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%u\n", asus->ppt_fppt); +-} +-static DEVICE_ATTR_RW(ppt_fppt); +- +-/* Tunable: PPT APU SPPT *****************************************************/ +-static ssize_t ppt_apu_sppt_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- int result, err; +- u32 value; +- +- result = kstrtou32(buf, 10, &value); +- if (result) +- return result; +- +- if (value < PPT_CPU_MIN || value > PPT_CPU_MAX) +- return -EINVAL; +- +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_APU_SPPT, value, &result); +- if (err) { +- pr_warn("Failed to set ppt_apu_sppt: %d\n", err); +- return err; +- } +- +- if (result > 1) { +- pr_warn("Failed to set ppt_apu_sppt (result): 0x%x\n", result); +- return -EIO; +- } +- +- asus->ppt_apu_sppt = value; +- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_apu_sppt"); +- +- return count; +-} +- +-static ssize_t ppt_apu_sppt_show(struct device *dev, +- struct device_attribute *attr, +- char *buf) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%u\n", asus->ppt_apu_sppt); +-} +-static DEVICE_ATTR_RW(ppt_apu_sppt); +- +-/* Tunable: PPT platform SPPT ************************************************/ +-static ssize_t ppt_platform_sppt_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- int result, err; +- u32 value; +- +- result = kstrtou32(buf, 10, &value); +- if (result) +- return result; +- +- if (value < PPT_CPU_MIN || value > PPT_CPU_MAX) +- return -EINVAL; +- +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PLAT_SPPT, value, &result); +- if (err) { +- pr_warn("Failed to set ppt_platform_sppt: %d\n", err); +- return err; +- } +- +- if (result > 1) { +- pr_warn("Failed to set ppt_platform_sppt (result): 0x%x\n", result); +- return -EIO; +- } +- +- asus->ppt_platform_sppt = value; +- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_platform_sppt"); +- +- return count; +-} +- +-static ssize_t ppt_platform_sppt_show(struct device *dev, +- struct device_attribute *attr, +- char *buf) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%u\n", asus->ppt_platform_sppt); +-} +-static DEVICE_ATTR_RW(ppt_platform_sppt); +- +-/* Tunable: NVIDIA dynamic boost *********************************************/ +-static ssize_t nv_dynamic_boost_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- int result, err; +- u32 value; +- +- result = kstrtou32(buf, 10, &value); +- if (result) +- return result; +- +- if (value < NVIDIA_BOOST_MIN || value > NVIDIA_BOOST_MAX) +- return -EINVAL; +- +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_DYN_BOOST, value, &result); +- if (err) { +- pr_warn("Failed to set nv_dynamic_boost: %d\n", err); +- return err; +- } +- +- if (result > 1) { +- pr_warn("Failed to set nv_dynamic_boost (result): 0x%x\n", result); +- return -EIO; +- } +- +- asus->nv_dynamic_boost = value; +- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_dynamic_boost"); +- +- return count; +-} +- +-static ssize_t nv_dynamic_boost_show(struct device *dev, +- struct device_attribute *attr, +- char *buf) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%u\n", asus->nv_dynamic_boost); +-} +-static DEVICE_ATTR_RW(nv_dynamic_boost); +- +-/* Tunable: NVIDIA temperature target ****************************************/ +-static ssize_t nv_temp_target_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- int result, err; +- u32 value; +- +- result = kstrtou32(buf, 10, &value); +- if (result) +- return result; +- +- if (value < NVIDIA_TEMP_MIN || value > NVIDIA_TEMP_MAX) +- return -EINVAL; +- +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_THERM_TARGET, value, &result); +- if (err) { +- pr_warn("Failed to set nv_temp_target: %d\n", err); +- return err; +- } +- +- if (result > 1) { +- pr_warn("Failed to set nv_temp_target (result): 0x%x\n", result); +- return -EIO; +- } +- +- asus->nv_temp_target = value; +- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_temp_target"); +- +- return count; +-} +- +-static ssize_t nv_temp_target_show(struct device *dev, +- struct device_attribute *attr, +- char *buf) +-{ +- struct asus_wmi *asus = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%u\n", asus->nv_temp_target); +-} +-static DEVICE_ATTR_RW(nv_temp_target); +- + /* Ally MCU Powersave ********************************************************/ + static ssize_t mcu_powersave_show(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -4367,13 +4177,27 @@ static struct attribute *platform_attributes[] = { + &dev_attr_als_enable.attr, + &dev_attr_fan_boost_mode.attr, + &dev_attr_throttle_thermal_policy.attr, +- &dev_attr_ppt_pl2_sppt.attr, + &dev_attr_ppt_pl1_spl.attr, ++ &dev_attr_ppt_pl1_spl_min.attr, ++ &dev_attr_ppt_pl1_spl_max.attr, ++ &dev_attr_ppt_pl2_sppt.attr, ++ &dev_attr_ppt_pl2_sppt_min.attr, ++ &dev_attr_ppt_pl2_sppt_max.attr, + &dev_attr_ppt_fppt.attr, ++ &dev_attr_ppt_fppt_min.attr, ++ &dev_attr_ppt_fppt_max.attr, + &dev_attr_ppt_apu_sppt.attr, ++ &dev_attr_ppt_apu_sppt_min.attr, ++ &dev_attr_ppt_apu_sppt_max.attr, + &dev_attr_ppt_platform_sppt.attr, ++ &dev_attr_ppt_platform_sppt_min.attr, ++ &dev_attr_ppt_platform_sppt_max.attr, + &dev_attr_nv_dynamic_boost.attr, ++ &dev_attr_nv_dynamic_boost_min.attr, ++ &dev_attr_nv_dynamic_boost_max.attr, + &dev_attr_nv_temp_target.attr, ++ &dev_attr_nv_temp_target_min.attr, ++ &dev_attr_nv_temp_target_max.attr, + &dev_attr_mcu_powersave.attr, + &dev_attr_boot_sound.attr, + &dev_attr_panel_od.attr, +@@ -4294,19 +4294,33 @@ + ok = asus->fan_boost_mode_available; + else if (attr == &dev_attr_throttle_thermal_policy.attr) + ok = asus->throttle_thermal_policy_dev != 0; +- else if (attr == &dev_attr_ppt_pl2_sppt.attr) ++ else if (attr == &dev_attr_ppt_pl2_sppt.attr ++ || attr == &dev_attr_ppt_pl2_sppt_min.attr ++ || attr == &dev_attr_ppt_pl2_sppt_max.attr) + devid = ASUS_WMI_DEVID_PPT_PL2_SPPT; +- else if (attr == &dev_attr_ppt_pl1_spl.attr) ++ else if (attr == &dev_attr_ppt_pl1_spl.attr ++ || attr == &dev_attr_ppt_pl1_spl_min.attr ++ || attr == &dev_attr_ppt_pl1_spl_max.attr) + devid = ASUS_WMI_DEVID_PPT_PL1_SPL; +- else if (attr == &dev_attr_ppt_fppt.attr) ++ else if (attr == &dev_attr_ppt_fppt.attr ++ || attr == &dev_attr_ppt_fppt_min.attr ++ || attr == &dev_attr_ppt_fppt_max.attr) + devid = ASUS_WMI_DEVID_PPT_FPPT; +- else if (attr == &dev_attr_ppt_apu_sppt.attr) ++ else if (attr == &dev_attr_ppt_apu_sppt.attr ++ || attr == &dev_attr_ppt_apu_sppt_min.attr ++ || attr == &dev_attr_ppt_apu_sppt_max.attr) + devid = ASUS_WMI_DEVID_PPT_APU_SPPT; +- else if (attr == &dev_attr_ppt_platform_sppt.attr) ++ else if (attr == &dev_attr_ppt_platform_sppt.attr ++ || attr == &dev_attr_ppt_platform_sppt_min.attr ++ || attr == &dev_attr_ppt_platform_sppt_max.attr) + devid = ASUS_WMI_DEVID_PPT_PLAT_SPPT; +- else if (attr == &dev_attr_nv_dynamic_boost.attr) ++ else if (attr == &dev_attr_nv_dynamic_boost.attr ++ || attr == &dev_attr_nv_dynamic_boost_min.attr ++ || attr == &dev_attr_nv_dynamic_boost_max.attr) + devid = ASUS_WMI_DEVID_NV_DYN_BOOST; +- else if (attr == &dev_attr_nv_temp_target.attr) ++ else if (attr == &dev_attr_nv_temp_target.attr ++ || attr == &dev_attr_nv_temp_target_min.attr ++ || attr == &dev_attr_nv_temp_target_max.attr) + devid = ASUS_WMI_DEVID_NV_THERM_TARGET; + else if (attr == &dev_attr_mcu_powersave.attr) + devid = ASUS_WMI_DEVID_MCU_POWERSAVE; +@@ -4652,6 +4490,77 @@ static void asus_wmi_debugfs_init(struct asus_wmi *asus) + + /* Init / exit ****************************************************************/ + ++/* Set up the min/max and defaults for ROG tunables */ ++static void init_rog_tunables(struct asus_wmi *asus) ++{ ++ const char *product; ++ u32 max_boost = NVIDIA_BOOST_MAX; ++ u32 cpu_default = PPT_CPU_LIMIT_DEFAULT; ++ u32 cpu_max = PPT_CPU_LIMIT_MAX; ++ u32 platform_default = PPT_PLATFORM_DEFAULT; ++ u32 platform_max = PPT_PLATFORM_MAX; ++ ++ /* ++ * ASUS product_name contains everything required, e.g, ++ * "ROG Flow X16 GV601VV_GV601VV_00185149B" ++ */ ++ product = dmi_get_system_info(DMI_PRODUCT_NAME); ++ ++ if (strstr(product, "GA402R")) { ++ cpu_default = 125; ++ } else if (strstr(product, "13QY")) { ++ cpu_max = 250; ++ } else if (strstr(product, "X13")) { ++ cpu_max = 75; ++ cpu_default = 50; ++ } else if (strstr(product, "RC71")) { ++ cpu_max = 50; ++ cpu_default = 30; ++ } else if (strstr(product, "G814") ++ || strstr(product, "G614") ++ || strstr(product, "G834") ++ || strstr(product, "G634")) { ++ cpu_max = 175; ++ } else if (strstr(product, "GA402X") ++ || strstr(product, "GA403") ++ || strstr(product, "FA507N") ++ || strstr(product, "FA507X") ++ || strstr(product, "FA707N") ++ || strstr(product, "FA707X")) { ++ cpu_max = 90; ++ } ++ ++ if (strstr(product, "GZ301ZE")) ++ max_boost = 5; ++ else if (strstr(product, "FX507ZC4")) ++ max_boost = 15; ++ else if (strstr(product, "GU605")) ++ max_boost = 20; ++ ++ /* ensure defaults for tunables */ ++ asus->rog_tunables.cpu_default = cpu_default; ++ asus->rog_tunables.cpu_max = cpu_max; ++ ++ asus->rog_tunables.platform_default = platform_default; ++ asus->rog_tunables.platform_max = platform_max; ++ ++ asus->rog_tunables.ppt_pl1_spl = cpu_default; ++ asus->rog_tunables.ppt_pl2_sppt = cpu_default; ++ asus->rog_tunables.ppt_apu_sppt = cpu_default; ++ ++ asus->rog_tunables.ppt_platform_sppt = platform_default; ++ asus->rog_tunables.ppt_fppt = platform_default; ++ ++ asus->rog_tunables.nv_boost_default = NVIDIA_BOOST_MAX; ++ asus->rog_tunables.nv_boost_max = max_boost; ++ asus->rog_tunables.nv_dynamic_boost = NVIDIA_BOOST_MIN; ++ ++ asus->rog_tunables.nv_temp_default = NVIDIA_TEMP_MAX; ++ asus->rog_tunables.nv_temp_max = NVIDIA_TEMP_MAX; ++ asus->rog_tunables.nv_temp_target = NVIDIA_TEMP_MIN; ++ ++} ++ + static int asus_wmi_add(struct platform_device *pdev) + { + struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver); +@@ -4677,15 +4586,7 @@ static int asus_wmi_add(struct platform_device *pdev) + if (err) + goto fail_platform; + +- /* ensure defaults for tunables */ +- asus->ppt_pl2_sppt = 5; +- asus->ppt_pl1_spl = 5; +- asus->ppt_apu_sppt = 5; +- asus->ppt_platform_sppt = 5; +- asus->ppt_fppt = 5; +- asus->nv_dynamic_boost = 5; +- asus->nv_temp_target = 75; +- ++ init_rog_tunables(asus); + asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU); + asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU); + asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE); +-- +2.45.1 + diff --git a/SOURCES/kernel-aarch64-16k-debug-fedora.config b/SOURCES/kernel-aarch64-16k-debug-fedora.config index 7d6340f..0604ee6 100644 --- a/SOURCES/kernel-aarch64-16k-debug-fedora.config +++ b/SOURCES/kernel-aarch64-16k-debug-fedora.config @@ -9350,7 +9350,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel-aarch64-16k-fedora.config b/SOURCES/kernel-aarch64-16k-fedora.config index a8ebba8..42fd197 100644 --- a/SOURCES/kernel-aarch64-16k-fedora.config +++ b/SOURCES/kernel-aarch64-16k-fedora.config @@ -9321,7 +9321,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel-aarch64-debug-fedora.config b/SOURCES/kernel-aarch64-debug-fedora.config index c0b2c84..39ea91b 100644 --- a/SOURCES/kernel-aarch64-debug-fedora.config +++ b/SOURCES/kernel-aarch64-debug-fedora.config @@ -9349,7 +9349,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel-aarch64-fedora.config b/SOURCES/kernel-aarch64-fedora.config index f46c5f6..4db5583 100644 --- a/SOURCES/kernel-aarch64-fedora.config +++ b/SOURCES/kernel-aarch64-fedora.config @@ -9320,7 +9320,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel-ppc64le-debug-fedora.config b/SOURCES/kernel-ppc64le-debug-fedora.config index 11d7eae..71e353f 100644 --- a/SOURCES/kernel-ppc64le-debug-fedora.config +++ b/SOURCES/kernel-ppc64le-debug-fedora.config @@ -7676,7 +7676,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel-ppc64le-fedora.config b/SOURCES/kernel-ppc64le-fedora.config index 05dfe02..c4d4b39 100644 --- a/SOURCES/kernel-ppc64le-fedora.config +++ b/SOURCES/kernel-ppc64le-fedora.config @@ -7645,7 +7645,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel-s390x-debug-fedora.config b/SOURCES/kernel-s390x-debug-fedora.config index 1a3b3a2..2b0e9c9 100644 --- a/SOURCES/kernel-s390x-debug-fedora.config +++ b/SOURCES/kernel-s390x-debug-fedora.config @@ -7609,7 +7609,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel-s390x-fedora.config b/SOURCES/kernel-s390x-fedora.config index 6bc8770..62d88b8 100644 --- a/SOURCES/kernel-s390x-fedora.config +++ b/SOURCES/kernel-s390x-fedora.config @@ -7578,7 +7578,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel-x86_64-debug-fedora.config b/SOURCES/kernel-x86_64-debug-fedora.config index 6448298..cc2952e 100644 --- a/SOURCES/kernel-x86_64-debug-fedora.config +++ b/SOURCES/kernel-x86_64-debug-fedora.config @@ -8208,7 +8208,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel-x86_64-fedora.config b/SOURCES/kernel-x86_64-fedora.config index c0749e7..91bf4f5 100644 --- a/SOURCES/kernel-x86_64-fedora.config +++ b/SOURCES/kernel-x86_64-fedora.config @@ -8178,7 +8178,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m -# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_F81232=m CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_GARMIN=m diff --git a/SOURCES/kernel.changelog b/SOURCES/kernel.changelog index 4183d93..d8e3274 100644 --- a/SOURCES/kernel.changelog +++ b/SOURCES/kernel.changelog @@ -1,3 +1,9 @@ +* Fri Jul 05 2024 Augusto Caringi <acaringi@redhat.com> [6.9.8-0] +- Add BugsFixed for 6.9 (Justin M. Forbes) +- Turn on USB_SERIAL_F81232 for Fedora (Justin M. Forbes) +- Linux v6.9.8 +Resolves: + * Thu Jun 27 2024 Augusto Caringi <acaringi@redhat.com> [6.9.7-0] - ACPI: scan: Ignore camera graph port nodes on all Dell Tiger, Alder and Raptor Lake models (Hans de Goede) - Linux v6.9.7 diff --git a/SOURCES/patch-6.9-redhat.patch b/SOURCES/patch-6.9-redhat.patch index 3de77a3..6503803 100644 --- a/SOURCES/patch-6.9-redhat.patch +++ b/SOURCES/patch-6.9-redhat.patch @@ -39,7 +39,7 @@ 38 files changed, 762 insertions(+), 192 deletions(-) diff --git a/Kconfig b/Kconfig -index 745bc773f5670..f57ff40109d71 100644 +index 745bc773f567..f57ff40109d7 100644 --- a/Kconfig +++ b/Kconfig @@ -30,3 +30,5 @@ source "lib/Kconfig" @@ -50,7 +50,7 @@ index 745bc773f5670..f57ff40109d71 100644 +source "Kconfig.redhat" diff --git a/Kconfig.redhat b/Kconfig.redhat new file mode 100644 -index 0000000000000..733a26bd887a2 +index 000000000000..733a26bd887a --- /dev/null +++ b/Kconfig.redhat @@ -0,0 +1,17 @@ @@ -72,7 +72,7 @@ index 0000000000000..733a26bd887a2 + +endmenu diff --git a/Makefile b/Makefile -index 17dc3e55323e7..205a0114f9351 100644 +index 060e20dba35e..58478aa0cc73 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,18 @@ $(if $(filter __%, $(MAKECMDGOALS)), \ @@ -95,7 +95,7 @@ index 17dc3e55323e7..205a0114f9351 100644 # to get the ordering right. # diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h -index b0d00032479d6..afb9544fb0074 100644 +index b0d00032479d..afb9544fb007 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -139,6 +139,7 @@ int ipl_report_add_component(struct ipl_report *report, struct kexec_buf *kbuf, @@ -107,7 +107,7 @@ index b0d00032479d6..afb9544fb0074 100644 /* * DIAG 308 support diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c -index 469e8d3fbfbf3..3ce742cd61c3b 100644 +index 469e8d3fbfbf..3ce742cd61c3 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -2519,3 +2519,8 @@ int ipl_report_free(struct ipl_report *report) @@ -120,7 +120,7 @@ index 469e8d3fbfbf3..3ce742cd61c3b 100644 + return !!ipl_secure_flag; +} diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c -index 7ecd27c62d564..cad68dfba646c 100644 +index 7ecd27c62d56..cad68dfba646 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -49,6 +49,7 @@ @@ -142,7 +142,7 @@ index 7ecd27c62d564..cad68dfba646c 100644 /* boot_command_line has been already set up in early.c */ *cmdline_p = boot_command_line; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index e125e059e2c45..9cfd28e580e0a 100644 +index e125e059e2c4..9cfd28e580e0 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -20,6 +20,7 @@ @@ -189,7 +189,7 @@ index e125e059e2c45..9cfd28e580e0a 100644 reserve_initrd(); diff --git a/crypto/drbg.c b/crypto/drbg.c -index 3addce90930c3..730b03de596a3 100644 +index 3addce90930c..730b03de596a 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1494,13 +1494,14 @@ static int drbg_generate(struct drbg_state *drbg, @@ -244,7 +244,7 @@ index 3addce90930c3..730b03de596a3 100644 /* diff --git a/crypto/rng.c b/crypto/rng.c -index 279dffdebf598..d24dd37205cd7 100644 +index 279dffdebf59..d24dd37205cd 100644 --- a/crypto/rng.c +++ b/crypto/rng.c @@ -12,10 +12,13 @@ @@ -463,7 +463,7 @@ index 279dffdebf598..d24dd37205cd7 100644 MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Random Number Generator"); diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c -index 20d757687e3d9..90a13f20f052b 100644 +index 20d757687e3d..90a13f20f052 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -142,6 +142,14 @@ static int apei_hest_parse(apei_hest_func_t func, void *data) @@ -482,7 +482,7 @@ index 20d757687e3d9..90a13f20f052b 100644 for (i = 0; i < hest_tab->error_source_count; i++) { len = hest_esrc_len(hest_hdr); diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c -index 1687483ff319e..390b67f19181a 100644 +index 1687483ff319..390b67f19181 100644 --- a/drivers/acpi/irq.c +++ b/drivers/acpi/irq.c @@ -143,6 +143,7 @@ struct acpi_irq_parse_one_ctx { @@ -525,7 +525,7 @@ index 1687483ff319e..390b67f19181a 100644 return ctx.rc; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index d1464324de951..a3b2f99a2d785 100644 +index d1464324de95..a3b2f99a2d78 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1798,6 +1798,15 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) @@ -545,7 +545,7 @@ index d1464324de951..a3b2f99a2d785 100644 acpi_dev_get_resources(device, &resource_list, acpi_check_serial_bus_slave, diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c -index 83431aae74d8b..f2a9c0d644af2 100644 +index 83431aae74d8..f2a9c0d644af 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -729,6 +729,24 @@ int ahci_stop_engine(struct ata_port *ap) @@ -574,7 +574,7 @@ index 83431aae74d8b..f2a9c0d644af2 100644 tmp = ata_wait_register(ap, port_mmio + PORT_CMD, PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c -index bbf7029e224be..cf7faa970dd65 100644 +index bbf7029e224b..cf7faa970dd6 100644 --- a/drivers/char/ipmi/ipmi_dmi.c +++ b/drivers/char/ipmi/ipmi_dmi.c @@ -215,6 +215,21 @@ static int __init scan_for_dmi_ipmi(void) @@ -600,7 +600,7 @@ index bbf7029e224be..cf7faa970dd65 100644 dmi_decode_ipmi((const struct dmi_header *) dev->device_data); diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c -index b0eedc4595b37..a9024c1dd68ab 100644 +index b0eedc4595b3..a9024c1dd68a 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -35,6 +35,7 @@ @@ -635,7 +635,7 @@ index b0eedc4595b37..a9024c1dd68ab 100644 rv = ipmi_register_driver(); mutex_unlock(&ipmi_interfaces_mutex); diff --git a/drivers/char/random.c b/drivers/char/random.c -index 2597cb43f4387..d860f4f6ba2c7 100644 +index 2597cb43f438..d860f4f6ba2c 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -51,6 +51,7 @@ @@ -832,7 +832,7 @@ index 2597cb43f4387..d860f4f6ba2c7 100644 /******************************************************************** * diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile -index a2d0009560d0f..4f3486e6a84b2 100644 +index a2d0009560d0..4f3486e6a84b 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -25,6 +25,7 @@ subdir-$(CONFIG_EFI_STUB) += libstub @@ -844,7 +844,7 @@ index a2d0009560d0f..4f3486e6a84b2 100644 obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index fdf07dd6f4591..cfd2b58a34940 100644 +index fdf07dd6f459..cfd2b58a3494 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -33,6 +33,7 @@ @@ -990,7 +990,7 @@ index fdf07dd6f4591..cfd2b58a34940 100644 diff --git a/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c new file mode 100644 -index 0000000000000..de0a3714a5d44 +index 000000000000..de0a3714a5d4 --- /dev/null +++ b/drivers/firmware/efi/secureboot.c @@ -0,0 +1,38 @@ @@ -1033,7 +1033,7 @@ index 0000000000000..de0a3714a5d44 + } +} diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c -index d4af17fdba467..154f0403cbf4c 100644 +index d4af17fdba46..154f0403cbf4 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c @@ -321,21 +321,12 @@ static int rmi_input_event(struct hid_device *hdev, u8 *data, int size) @@ -1135,7 +1135,7 @@ index d4af17fdba467..154f0403cbf4c 100644 data->xport.ops = &hid_rmi_ops; diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c -index a0bdfabddbc68..cd824ceebd0fe 100644 +index a0bdfabddbc6..cd824ceebd0f 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -10,6 +10,7 @@ @@ -1186,7 +1186,7 @@ index a0bdfabddbc68..cd824ceebd0fe 100644 platform_driver_unregister(&etm4_platform_driver); etm4_pm_clear(); diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c -index ef9ea295f9e03..0103334e8f32c 100644 +index ef9ea295f9e0..0103334e8f32 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -182,34 +182,47 @@ void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status, @@ -1378,7 +1378,7 @@ index ef9ea295f9e03..0103334e8f32c 100644 if (data->f01_container->dev.driver) { /* Driver already bound, so enable ATTN now. */ diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c -index 659a77f7bb833..e8dc1fd50e21d 100644 +index 659a77f7bb83..e8dc1fd50e21 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -8,6 +8,7 @@ @@ -1418,7 +1418,7 @@ index 659a77f7bb833..e8dc1fd50e21d 100644 * iommu_setup_default_domain - Set the default_domain for the group * @group: Group to change diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index eff7f5df08e27..b58145ce7775c 100644 +index eff7f5df08e2..b58145ce7775 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4433,6 +4433,30 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9000, @@ -1453,7 +1453,7 @@ index eff7f5df08e27..b58145ce7775c 100644 * Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero) * class code. Fix it. diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index a4638ea92571d..aff13cdce0156 100644 +index a4638ea92571..aff13cdce015 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -120,6 +120,14 @@ static const char *sd_cache_types[] = { @@ -1481,7 +1481,7 @@ index a4638ea92571d..aff13cdce0156 100644 if (err) goto err_out_driver; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 008053039875a..f948a5c96006b 100644 +index 008053039875..f948a5c96006 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -5845,6 +5845,13 @@ static void hub_event(struct work_struct *work) @@ -1499,7 +1499,7 @@ index 008053039875a..f948a5c96006b 100644 * disconnected while waiting for the lock to succeed. */ usb_lock_device(hdev); diff --git a/include/linux/crypto.h b/include/linux/crypto.h -index b164da5e129e8..59021b8609a70 100644 +index b164da5e129e..59021b8609a7 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -133,6 +133,7 @@ @@ -1511,7 +1511,7 @@ index b164da5e129e8..59021b8609a70 100644 /* * Miscellaneous stuff. diff --git a/include/linux/efi.h b/include/linux/efi.h -index d59b0947fba08..8b1e2e71d4858 100644 +index d59b0947fba0..8b1e2e71d485 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -45,6 +45,8 @@ struct screen_info; @@ -1579,7 +1579,7 @@ index d59b0947fba08..8b1e2e71d4858 100644 enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var) { diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h -index 7e539f6f8c674..3c3e56566457a 100644 +index 7e539f6f8c67..3c3e56566457 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -436,6 +436,8 @@ LSM_HOOK(int, 0, bpf_token_capable, const struct bpf_token *token, int cap) @@ -1592,7 +1592,7 @@ index 7e539f6f8c674..3c3e56566457a 100644 #ifdef CONFIG_PERF_EVENTS LSM_HOOK(int, 0, perf_event_open, struct perf_event_attr *attr, int type) diff --git a/include/linux/random.h b/include/linux/random.h -index b0a940af4fff5..8a52424fd0d50 100644 +index b0a940af4fff..8a52424fd0d5 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -9,6 +9,13 @@ @@ -1620,7 +1620,7 @@ index b0a940af4fff5..8a52424fd0d50 100644 extern const struct file_operations random_fops, urandom_fops; #endif diff --git a/include/linux/rmi.h b/include/linux/rmi.h -index ab7eea01ab427..fff7c5f737fc8 100644 +index ab7eea01ab42..fff7c5f737fc 100644 --- a/include/linux/rmi.h +++ b/include/linux/rmi.h @@ -364,6 +364,7 @@ struct rmi_driver_data { @@ -1632,7 +1632,7 @@ index ab7eea01ab427..fff7c5f737fc8 100644 int rmi_register_transport_device(struct rmi_transport_dev *xport); diff --git a/include/linux/security.h b/include/linux/security.h -index 5122e3ad83b19..b5f0081bc894d 100644 +index 5122e3ad83b1..b5f0081bc894 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -507,6 +507,7 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); @@ -1655,7 +1655,7 @@ index 5122e3ad83b19..b5f0081bc894d 100644 u32 *uctx_len, void *val, size_t val_len, u64 id, u64 flags) diff --git a/kernel/module/signing.c b/kernel/module/signing.c -index a2ff4242e623d..f0d2be1ee4f1c 100644 +index a2ff4242e623..f0d2be1ee4f1 100644 --- a/kernel/module/signing.c +++ b/kernel/module/signing.c @@ -61,10 +61,17 @@ int mod_verify_sig(const void *mod, struct load_info *info) @@ -1678,7 +1678,7 @@ index a2ff4242e623d..f0d2be1ee4f1c 100644 int module_sig_check(struct load_info *info, int flags) diff --git a/scripts/tags.sh b/scripts/tags.sh -index 191e0461d6d5b..e6f418b3e948b 100755 +index 191e0461d6d5..e6f418b3e948 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -16,6 +16,8 @@ fi @@ -1691,7 +1691,7 @@ index 191e0461d6d5b..e6f418b3e948b 100755 # ignore arbitrary directories if [ -n "${IGNORE_DIRS}" ]; then diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c -index d1fdd113450a6..182e8090cfe85 100644 +index d1fdd113450a..182e8090cfe8 100644 --- a/security/integrity/platform_certs/load_uefi.c +++ b/security/integrity/platform_certs/load_uefi.c @@ -74,7 +74,8 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, @@ -1715,7 +1715,7 @@ index d1fdd113450a6..182e8090cfe85 100644 } diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig -index e84ddf4840101..d0501353a4b95 100644 +index e84ddf484010..d0501353a4b9 100644 --- a/security/lockdown/Kconfig +++ b/security/lockdown/Kconfig @@ -16,6 +16,19 @@ config SECURITY_LOCKDOWN_LSM_EARLY @@ -1739,7 +1739,7 @@ index e84ddf4840101..d0501353a4b95 100644 prompt "Kernel default lockdown mode" default LOCK_DOWN_KERNEL_FORCE_NONE diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c -index cd84d8ea1dfbf..e4c70a0312bc8 100644 +index cd84d8ea1dfb..e4c70a0312bc 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -74,6 +74,7 @@ static int lockdown_is_locked_down(enum lockdown_reason what) @@ -1751,7 +1751,7 @@ index cd84d8ea1dfbf..e4c70a0312bc8 100644 const struct lsm_id lockdown_lsmid = { diff --git a/security/security.c b/security/security.c -index 4fd3c839353ec..d52cb3bb720dd 100644 +index 4fd3c839353e..d52cb3bb720d 100644 --- a/security/security.c +++ b/security/security.c @@ -5569,6 +5569,18 @@ int security_locked_down(enum lockdown_reason what) diff --git a/SOURCES/v14.8-0004-HID-asus-add-ROG-Ally-xpad-settings.patch b/SOURCES/v14.8-0004-HID-asus-add-ROG-Ally-xpad-settings.patch index 0d4d43d..2a21e86 100644 --- a/SOURCES/v14.8-0004-HID-asus-add-ROG-Ally-xpad-settings.patch +++ b/SOURCES/v14.8-0004-HID-asus-add-ROG-Ally-xpad-settings.patch @@ -286,15 +286,6 @@ index 3a1a6024d299..026705c43ee1 100644 hid_hw_stop(hdev); } -@@ -1245,7 +1234,7 @@ static const struct hid_device_id asus_devices[] = { - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, - USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY), -- QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, -+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, - USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), - QUIRK_ROG_CLAYMORE_II_KEYBOARD }, diff --git a/drivers/hid/hid-asus-rog.c b/drivers/hid/hid-asus-rog.c new file mode 100644 index 000000000000..94b7c986576c |