initial commit
Some checks failed
PikaOS Package Build Only (amd64-v3) / build (push) Failing after 1s
PikaOS Package Build & Release (Canary) (amd64-v3) / build (push) Failing after 5s
PikaOS Package Build & Release (amd64-v3) / build (push) Failing after 1s

This commit is contained in:
Ward from fusion-voyager-3 2024-07-24 05:09:14 +03:00
parent f228835581
commit 727b576154
50 changed files with 217 additions and 79331 deletions

1
.github/ build-canary-v3 vendored Normal file
View File

@ -0,0 +1 @@
1

1
.github/build-nest-v3 vendored Normal file
View File

@ -0,0 +1 @@
1

1
.github/release-canary-v3 vendored Normal file
View File

@ -0,0 +1 @@
4

1
.github/release-nest-v3 vendored Normal file
View File

@ -0,0 +1 @@
1

34
.github/workflows/build-canaryv3.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: PikaOS Package Build Only (Canary) (amd64-v3)
on:
push:
branches:
- main
paths:
- '.github/build-canary-v3'
jobs:
build:
runs-on: ubuntu-latest
container:
image: ghcr.io/pikaos-linux/pikaos-builder:canaryv3
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ vars.SSH_KEY }}
name: id_rsa
known_hosts: ${{ vars.KNOWN_HOSTS }}
if_key_exists: replace
- name: Update APT Cache
run: apt-get update -y
- name: Build Package
run: ./mainv3.sh

34
.github/workflows/build-nestv3.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: PikaOS Package Build Only (amd64-v3)
on:
push:
branches:
- main
paths:
- '.github/build-nest-v3'
jobs:
build:
runs-on: ubuntu-latest
container:
image: ghcr.io/pikaos-linux/pikaos-builder:nestv3
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ vars.SSH_KEY }}
name: id_rsa
known_hosts: ${{ vars.KNOWN_HOSTS }}
if_key_exists: replace
- name: Update APT Cache
run: apt-get update -y
- name: Build Package
run: ./mainv3.sh

View File

@ -1,24 +0,0 @@
name: PikaOS Kernel Build Only
on:
workflow_dispatch
jobs:
build:
runs-on: self-hosted
container:
image: ghcr.io/pikaos-linux/pikaos-builder:canary
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Build Kernel
run: ./main.sh
- uses: actions/upload-artifact@v3
with:
name: PikaOS Kernel
path: output/

37
.github/workflows/release-canaryv3.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: PikaOS Package Build & Release (Canary) (amd64-v3)
on:
push:
branches:
- main
paths:
- '.github/release-canary-v3'
jobs:
build:
runs-on: ubuntu-latest
container:
image: ghcr.io/pikaos-linux/pikaos-builder:canaryv3
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ vars.SSH_KEY }}
name: id_rsa
known_hosts: ${{ vars.KNOWN_HOSTS }}
if_key_exists: replace
- name: Update APT Cache
run: apt-get update -y
- name: Build Package
run: ./mainv3.sh
- name: Release Package
run: ./release.sh

37
.github/workflows/release-nestv3.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: PikaOS Package Build & Release (amd64-v3)
on:
push:
branches:
- main
paths:
- '.github/release-nest-v3'
jobs:
build:
runs-on: ubuntu-latest
container:
image: ghcr.io/pikaos-linux/pikaos-builder:nestv3
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ vars.SSH_KEY }}
name: id_rsa
known_hosts: ${{ vars.KNOWN_HOSTS }}
if_key_exists: replace
- name: Update APT Cache
run: apt-get update -y
- name: Build Package
run: ./mainv3.sh
- name: Release Package
run: ./release.sh

View File

@ -1,37 +0,0 @@
name: PikaOS Kernel Build And Release
on:
workflow_dispatch
jobs:
build:
runs-on: self-hosted
container:
image: ghcr.io/pikaos-linux/pikaos-builder:canary
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Import GPG key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v5
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
name: id_rsa
known_hosts: ${{ secrets.KNOWN_HOSTS }}
if_key_exists: replace
- name: Build Kernel
run: ./main.sh
- name: Release Kernel
run: ./release.sh

View File

@ -1 +1 @@
6.10 #PUT LINUX UPSTREAM VERSION HERE#

View File

@ -1,7 +0,0 @@
#!/bin/bash
. ./scripts/source.sh
. ../scripts/patch.sh
. ../scripts/config.sh
. ../scripts/build.sh
. ../scripts/output.sh

12
mainv3.sh Executable file
View File

@ -0,0 +1,12 @@
#! /bin/bash
set -e
# Move the debs to output
mkdir -p ./output
. ./scripts-v3/source.sh
. ../scripts-v3/patch.sh
. ../scripts-v3/config.sh
. ../scripts-v3/build.sh
. ../scripts-v3/output.sh

View File

@ -1,30 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBGPJoigBCADZ8tDzkO2LlWIzXZLLyRLIaRnaNHG6P9xx0ABSFsqU+X+p9qDS
eQW6SmeCN+PauqAHlzrJ7p3XZi07E+h69PEk5R5n7qhVECW35Y1sB9EfC2nqVRxd
RcWtwQsipEHQmjvWIsD4hR5uhq62p7grSkQxv13SGLqyJkKIpkic2vZEgqubfZd4
KLPFvaQZar6QWa3urfYnUZzc1TNkEYxghr/dQuCFSfYPM+yHT70MXrlPOgfslGgL
YtoN1YauF04wzAg1RFfrWX2AdHE792fVHrkHRsvQg1Pvw4KjPnM6jX2V8W8n7C++
yxpiMUU2h9FqBWfHrqNLWtKdn6+lgHUq2Oj3ABEBAAG0IWZlcnJlbyA8aGFyZGVy
dGhhbmZpcmVAZ21haWwuY29tPokBTgQTAQoAOBYhBIvETfAmQkhf8fPMBKt4xg37
WBYDBQJjyaIoAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEKt4xg37WBYD
4/oH/2LRW4FwLHCsWeJfRx5Z7BwKrGqWIF2VujkvEjlFOGYO7aN5HxeX/QKeN+Wy
901hv4CO7T7aSye0qjaYz0I6ZUmr9CaINdXTH7fok3CXQYBfluaLiyxMPSm+Fe5o
vfiUiSMZ488uaUkFSww/TEP8wi5H02yqGJcx3yB54OTsVb8eUHLPXno0T4tooWvX
EOMUKkpj3tEylJoqL5d2iz2ZrkMdX9tVXOkKY3iJD2El0TPITrTIuRuurqzc4CWU
laV7bmZ1Mq5r21S7ISOhhzvEMwsiWylIFXmXNPvbU7DC43uT3+nKhBca8VESzvmu
r7zC6CcQAR5IVHMjd8weFfrnGXm5AQ0EY8miKAEIALnnC+U4gx0m0yLEVOHBoccb
T7CvhmBYer2shxe5o7zUZ5V4y1iJdzSSJksbQkZH4+JDwi7Hp3/lqI2EsxQ9TR+A
OdRvETfz88aK/e2vJ0j7Bt3Dr0u0mgoo9kSx6rLq1oH9Nha9ReOljmEfDtuINR86
QGEd8PyvNDcUap+6QQa6/RBEDiH1zYBYtxv4rbuciKsh+e6r6C8TJb43nKr3YBGu
/GE1aDlGaKvFgUOZmaapgoQVdpXcg7ZtTpI8sNKdnLVEChIKk35n52XfQDZPVvAt
bsUIr77B4hi+GsjGli7ihr+JJEiHwOyCMZvV95ZWq2ThrXxRWA8mHqCLhz7oTV8A
EQEAAYkBNgQYAQoAIBYhBIvETfAmQkhf8fPMBKt4xg37WBYDBQJjyaIoAhsMAAoJ
EKt4xg37WBYDdwAIAI3yJwOa6P6wz3ddLt/4FTlCSnlJ8C904RDwtJEO/C/y9qZv
yE0qitUi7mntzYE6G7SES3Zn6b9HhdTS9kQv6VUg75TjD/WGPVju5cB11mte95Z9
6iW5u65kxpawxiTUhaO+O4RO6fZ29rZyCQDfa7ESudkVE/yktAA5umnAbGpgxGa6
8egCGiZ0LKUqcHxMAsoUUhlOTk3LR4yS6nKE1Q8Dr6E7NYlrWcoGDSQzKvXLqf8e
9eJLGckePwHDzhgO9LKGW3meTV6ldLehTsxm/ycHqXL7/wYjYy6ZXj/5Px3CGLPg
DH9mVj8ERsz096eQA+53gmcTsNtq/FLWS2MhtCc=
=+26V
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -1,151 +0,0 @@
From 55426abb60d99efed912d8309498c0c365e8dcec 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 1/5] platform/x86: asus-wmi: add support for 2024 ROG Mini-LED
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>
---
.../ABI/testing/sysfs-platform-asus-wmi | 8 ++++
drivers/platform/x86/asus-wmi.c | 48 ++++++++++++++++---
include/linux/platform_data/x86/asus-wmi.h | 1 +
3 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
index 8a7e25bde085..e32b4f0ae15f 100644
--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
@@ -126,6 +126,14 @@ Description:
Change the mini-LED mode:
* 0 - Single-zone,
* 1 - Multi-zone
+ * 2 - Multi-zone strong (available on newer generation mini-led)
+
+What: /sys/devices/platform/<platform>/avilable_mini_led_mode
+Date: Jun 2023
+KernelVersion: 6.9
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ List the available mini-led modes.
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 18be35fdb381..a56152ccfbe7 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -297,6 +297,7 @@ struct asus_wmi {
bool panel_overdrive_available;
bool mini_led_mode_available;
+ u32 mini_led_dev_id;
struct hotplug_slot hotplug_slot;
struct mutex hotplug_lock;
@@ -2109,10 +2110,17 @@ static ssize_t mini_led_mode_show(struct device *dev,
struct asus_wmi *asus = dev_get_drvdata(dev);
int result;
- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MINI_LED_MODE);
- if (result < 0)
- return result;
+ result = asus_wmi_get_devstate_simple(asus, asus->mini_led_dev_id);
+ // Remap the mode values to match previous generation mini-led including
+ // if errored -19 since some of these bios return a bad result if set to "2"
+ // which is mini-led off
+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) {
+ if (result >= 0 || result == -19)
+ result = result == 1 ? 2 : result == 0 ? 1 : 0;
+ } else if (result < 0) {
+ return result;
+ }
return sysfs_emit(buf, "%d\n", result);
}
@@ -2129,10 +2137,15 @@ 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)
+ return -EINVAL;
+ // Remap the mode values to match previous generation mini-led
+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2)
+ mode = mode == 2 ? 1 : mode == 0 ? 2 : 0;
- 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);
@@ -2150,6 +2163,21 @@ static ssize_t mini_led_mode_store(struct device *dev,
}
static DEVICE_ATTR_RW(mini_led_mode);
+static ssize_t available_mini_led_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE)
+ return sysfs_emit(buf, "0 1\n");
+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2)
+ return sysfs_emit(buf, "0 1 2\n");
+
+ return sysfs_emit(buf, "0\n");
+}
+
+static DEVICE_ATTR_RO(available_mini_led_mode);
+
/* Quirks *********************************************************************/
static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
@@ -4174,6 +4202,7 @@ static struct attribute *platform_attributes[] = {
&dev_attr_nv_temp_target.attr,
&dev_attr_panel_od.attr,
&dev_attr_mini_led_mode.attr,
+ &dev_attr_available_mini_led_mode.attr,
NULL
};
@@ -4496,10 +4525,17 @@ 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);
- asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE);
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)) {
+ asus->mini_led_mode_available = true;
+ 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)) {
+ asus->mini_led_mode_available = true;
+ asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2;
+ }
+
err = fan_boost_mode_check_present(asus);
if (err)
goto fail_fan_boost_mode;
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index ab1c7deff118..9cadce10ad9a 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -71,6 +71,7 @@
#define ASUS_WMI_DEVID_LID_FLIP 0x00060062
#define ASUS_WMI_DEVID_LID_FLIP_ROG 0x00060077
#define ASUS_WMI_DEVID_MINI_LED_MODE 0x0005001E
+#define ASUS_WMI_DEVID_MINI_LED_MODE2 0x0005002E
/* Storage */
#define ASUS_WMI_DEVID_CARDREADER 0x00080013
--
2.44.0

View File

@ -1,100 +0,0 @@
From 06d5a9b83548d99b70764166d723489cc8336b1d 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 2/5] platform/x86: asus-wmi: add support for Vivobook GPU MUX
Adjust existing MUX support to select whichever MUX support is available
so that ASUS Vivobook MUX can also be used if detected.
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
drivers/platform/x86/asus-wmi.c | 18 +++++++++++++-----
include/linux/platform_data/x86/asus-wmi.h | 1 +
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index a56152ccfbe7..b9a2fb8007c0 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -268,6 +268,7 @@ struct asus_wmi {
bool egpu_connect_available;
bool dgpu_disable_available;
bool gpu_mux_mode_available;
+ u32 gpu_mux_dev;
/* Tunables provided by ASUS for gaming laptops */
bool ppt_pl2_sppt_available;
@@ -682,7 +683,7 @@ static ssize_t dgpu_disable_store(struct device *dev,
return -EINVAL;
if (asus->gpu_mux_mode_available) {
- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX);
+ result = asus_wmi_get_devstate_simple(asus, asus->gpu_mux_dev);
if (result < 0)
/* An error here may signal greater failure of GPU handling */
return result;
@@ -748,7 +749,7 @@ static ssize_t egpu_enable_store(struct device *dev,
}
if (asus->gpu_mux_mode_available) {
- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX);
+ result = asus_wmi_get_devstate_simple(asus, asus->gpu_mux_dev);
if (result < 0) {
/* An error here may signal greater failure of GPU handling */
pr_warn("Failed to get gpu mux status: %d\n", result);
@@ -801,7 +802,7 @@ static ssize_t gpu_mux_mode_show(struct device *dev,
struct asus_wmi *asus = dev_get_drvdata(dev);
int result;
- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX);
+ result = asus_wmi_get_devstate_simple(asus, asus->gpu_mux_dev);
if (result < 0)
return result;
@@ -847,7 +848,7 @@ static ssize_t gpu_mux_mode_store(struct device *dev,
}
}
- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_MUX, optimus, &result);
+ err = asus_wmi_set_devstate(asus->gpu_mux_dev, optimus, &result);
if (err) {
dev_err(dev, "Failed to set GPU MUX mode: %d\n", err);
return err;
@@ -4514,7 +4515,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);
- asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX);
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);
@@ -4536,6 +4536,14 @@ static int asus_wmi_add(struct platform_device *pdev)
asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2;
}
+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX)) {
+ asus->gpu_mux_mode_available = true;
+ asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX;
+ } else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX_VIVO)) {
+ asus->gpu_mux_mode_available = true;
+ asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX_VIVO;
+ }
+
err = fan_boost_mode_check_present(asus);
if (err)
goto fail_fan_boost_mode;
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index 9cadce10ad9a..b48b024dd844 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -128,6 +128,7 @@
/* gpu mux switch, 0 = dGPU, 1 = Optimus */
#define ASUS_WMI_DEVID_GPU_MUX 0x00090016
+#define ASUS_WMI_DEVID_GPU_MUX_VIVO 0x00090026
/* TUF laptop RGB modes/colours */
#define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056
--
2.44.0

View File

@ -1,74 +0,0 @@
From 9b038d6db81b457738cf65e43f401ccb8bf505e6 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 3/5] platform/x86: asus-wmi: add support variant of TUF RGB
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.
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
drivers/platform/x86/asus-wmi.c | 12 +++++++++++-
include/linux/platform_data/x86/asus-wmi.h | 1 +
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index b9a2fb8007c0..e1100726de53 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -280,6 +280,7 @@ struct asus_wmi {
bool nv_temp_tgt_available;
bool kbd_rgb_mode_available;
+ u32 kbd_rgb_dev;
bool kbd_rgb_state_available;
bool throttle_thermal_policy_available;
@@ -870,6 +871,7 @@ static ssize_t kbd_rgb_mode_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct asus_wmi *asus = dev_get_drvdata(dev);
u32 cmd, mode, r, g, b, speed;
int err;
@@ -906,7 +908,7 @@ static ssize_t kbd_rgb_mode_store(struct device *dev,
speed = 0xeb;
}
- err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, ASUS_WMI_DEVID_TUF_RGB_MODE,
+ err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, asus->kbd_rgb_dev,
cmd | (mode << 8) | (r << 16) | (g << 24), b | (speed << 8), NULL);
if (err)
return err;
@@ -4544,6 +4546,14 @@ static int asus_wmi_add(struct platform_device *pdev)
asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX_VIVO;
}
+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE)) {
+ asus->kbd_rgb_mode_available = true;
+ asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE;
+ } else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2)) {
+ asus->kbd_rgb_mode_available = true;
+ asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE2;
+ }
+
err = fan_boost_mode_check_present(asus);
if (err)
goto fail_fan_boost_mode;
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index b48b024dd844..3e9a01467c67 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -132,6 +132,7 @@
/* TUF laptop RGB modes/colours */
#define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056
+#define ASUS_WMI_DEVID_TUF_RGB_MODE2 0x0010005A
/* TUF laptop RGB power/state */
#define ASUS_WMI_DEVID_TUF_RGB_STATE 0x00100057
--
2.44.0

View File

@ -1,139 +0,0 @@
From 1c0f375634b3ddbcf479c4ddb81639e397795802 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 4/5] platform/x86: asus-wmi: support toggling POST sound
Add support for toggling the BIOS POST sound on some ASUS laptops.
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
.../ABI/testing/sysfs-platform-asus-wmi | 7 +++
drivers/platform/x86/asus-wmi.c | 54 +++++++++++++++++++
include/linux/platform_data/x86/asus-wmi.h | 3 ++
3 files changed, 64 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
index e32b4f0ae15f..f3c53b7453f0 100644
--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
@@ -194,3 +194,10 @@ Contact: "Luke Jones" <luke@ljones.dev>
Description:
Set the target temperature limit of the Nvidia dGPU:
* min=75, max=87
+
+What: /sys/devices/platform/<platform>/boot_sound
+Date: Jun 2023
+KernelVersion: 6.9
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set if the BIOS POST sound is played on boot.
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index e1100726de53..e4341abb71e0 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -297,6 +297,7 @@ struct asus_wmi {
// The RSOC controls the maximum charging percentage.
bool battery_rsoc_available;
+ bool boot_sound_available;
bool panel_overdrive_available;
bool mini_led_mode_available;
u32 mini_led_dev_id;
@@ -2106,6 +2107,55 @@ static ssize_t panel_od_store(struct device *dev,
}
static DEVICE_ATTR_RW(panel_od);
+/* Bootup sound ***************************************************************/
+
+static ssize_t boot_sound_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+ int result;
+
+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BOOT_SOUND);
+ if (result < 0)
+ return result;
+
+ return sysfs_emit(buf, "%d\n", result);
+}
+
+static ssize_t boot_sound_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 snd;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &snd);
+ if (result)
+ return result;
+
+ if (snd > 1)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BOOT_SOUND, snd, &result);
+
+ if (err) {
+ pr_warn("Failed to set boot sound: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set panel boot sound (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "boot_sound");
+
+ return count;
+}
+static DEVICE_ATTR_RW(boot_sound);
+
/* Mini-LED mode **************************************************************/
static ssize_t mini_led_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -4203,6 +4253,7 @@ static struct attribute *platform_attributes[] = {
&dev_attr_ppt_platform_sppt.attr,
&dev_attr_nv_dynamic_boost.attr,
&dev_attr_nv_temp_target.attr,
+ &dev_attr_boot_sound.attr,
&dev_attr_panel_od.attr,
&dev_attr_mini_led_mode.attr,
&dev_attr_available_mini_led_mode.attr,
@@ -4255,6 +4306,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;
+ else if (attr == &dev_attr_boot_sound.attr)
+ ok = asus->boot_sound_available;
else if (attr == &dev_attr_panel_od.attr)
ok = asus->panel_overdrive_available;
else if (attr == &dev_attr_mini_led_mode.attr)
@@ -4526,6 +4579,7 @@ static int asus_wmi_add(struct platform_device *pdev)
asus->ppt_plat_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PLAT_SPPT);
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->boot_sound_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_BOOT_SOUND);
asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
&& dmi_match(DMI_BOARD_NAME, "RC71L");
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index 3e9a01467c67..3eb5cd6773ad 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -137,6 +137,9 @@
/* TUF laptop RGB power/state */
#define ASUS_WMI_DEVID_TUF_RGB_STATE 0x00100057
+/* Bootup sound control */
+#define ASUS_WMI_DEVID_BOOT_SOUND 0x00130022
+
/* DSTS masks */
#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
--
2.44.0

View File

@ -1,342 +0,0 @@
From 6045f385154a2c0a4aaa692d13bb0fa14bbe1d12 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 5/5] platform/x86: asus-wmi: store a min default for ppt
options
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.
This patch adds storing of those values in the local struct, and enables
reading of those values back.
Secondary to the above it renames some internal variables to be more
consistent (which makes code grepping show all related parts)
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
drivers/platform/x86/asus-wmi.c | 141 +++++++++++++++++++++++++-------
1 file changed, 111 insertions(+), 30 deletions(-)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index e4341abb71e0..482e23b55e1e 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -272,12 +272,19 @@ struct asus_wmi {
/* Tunables provided by ASUS for gaming laptops */
bool ppt_pl2_sppt_available;
+ u32 ppt_pl2_sppt;
bool ppt_pl1_spl_available;
+ u32 ppt_pl1_spl;
bool ppt_apu_sppt_available;
- bool ppt_plat_sppt_available;
+ u32 ppt_apu_sppt;
+ bool ppt_platform_sppt_available;
+ u32 ppt_platform_sppt;
bool ppt_fppt_available;
- bool nv_dyn_boost_available;
- bool nv_temp_tgt_available;
+ u32 ppt_fppt;
+ bool nv_dynamic_boost_available;
+ u32 nv_dynamic_boost;
+ bool nv_temp_target_available;
+ u32 nv_temp_target;
bool kbd_rgb_mode_available;
u32 kbd_rgb_dev;
@@ -999,11 +1006,10 @@ 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;
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
result = kstrtou32(buf, 10, &value);
if (result)
return result;
@@ -1022,22 +1028,31 @@ static ssize_t ppt_pl2_sppt_store(struct device *dev,
return -EIO;
}
+ asus->ppt_pl2_sppt = value;
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl2_sppt");
return count;
}
-static DEVICE_ATTR_WO(ppt_pl2_sppt);
+
+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, "%d\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;
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
result = kstrtou32(buf, 10, &value);
if (result)
return result;
@@ -1056,22 +1071,30 @@ static ssize_t ppt_pl1_spl_store(struct device *dev,
return -EIO;
}
+ asus->ppt_pl1_spl = value;
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl1_spl");
return count;
}
-static DEVICE_ATTR_WO(ppt_pl1_spl);
+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, "%d\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;
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
result = kstrtou32(buf, 10, &value);
if (result)
return result;
@@ -1090,22 +1113,31 @@ static ssize_t ppt_fppt_store(struct device *dev,
return -EIO;
}
+ asus->ppt_fppt = value;
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_fpu_sppt");
return count;
}
-static DEVICE_ATTR_WO(ppt_fppt);
+
+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, "%d\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;
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
result = kstrtou32(buf, 10, &value);
if (result)
return result;
@@ -1124,22 +1156,31 @@ static ssize_t ppt_apu_sppt_store(struct device *dev,
return -EIO;
}
+ asus->ppt_apu_sppt = value;
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_apu_sppt");
return count;
}
-static DEVICE_ATTR_WO(ppt_apu_sppt);
+
+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, "%d\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;
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
result = kstrtou32(buf, 10, &value);
if (result)
return result;
@@ -1158,22 +1199,31 @@ static ssize_t ppt_platform_sppt_store(struct device *dev,
return -EIO;
}
+ asus->ppt_platform_sppt = value;
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_platform_sppt");
return count;
}
-static DEVICE_ATTR_WO(ppt_platform_sppt);
+
+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, "%d\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;
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
result = kstrtou32(buf, 10, &value);
if (result)
return result;
@@ -1192,22 +1242,31 @@ static ssize_t nv_dynamic_boost_store(struct device *dev,
return -EIO;
}
+ asus->nv_dynamic_boost = value;
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_dynamic_boost");
return count;
}
-static DEVICE_ATTR_WO(nv_dynamic_boost);
+
+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, "%d\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;
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
result = kstrtou32(buf, 10, &value);
if (result)
return result;
@@ -1226,11 +1285,21 @@ static ssize_t nv_temp_target_store(struct device *dev,
return -EIO;
}
+ asus->nv_temp_target = value;
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_temp_target");
return count;
}
-static DEVICE_ATTR_WO(nv_temp_target);
+
+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, "%d\n", asus->nv_temp_target);
+}
+static DEVICE_ATTR_RW(nv_temp_target);
/* Battery ********************************************************************/
@@ -4301,11 +4370,11 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
else if (attr == &dev_attr_ppt_apu_sppt.attr)
ok = asus->ppt_apu_sppt_available;
else if (attr == &dev_attr_ppt_platform_sppt.attr)
- ok = asus->ppt_plat_sppt_available;
+ ok = asus->ppt_platform_sppt_available;
else if (attr == &dev_attr_nv_dynamic_boost.attr)
- ok = asus->nv_dyn_boost_available;
+ ok = asus->nv_dynamic_boost_available;
else if (attr == &dev_attr_nv_temp_target.attr)
- ok = asus->nv_temp_tgt_available;
+ ok = asus->nv_temp_target_available;
else if (attr == &dev_attr_boot_sound.attr)
ok = asus->boot_sound_available;
else if (attr == &dev_attr_panel_od.attr)
@@ -4566,6 +4635,15 @@ 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;
+
asus->charge_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CHARGE_MODE);
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);
@@ -4576,9 +4654,12 @@ static int asus_wmi_add(struct platform_device *pdev)
asus->ppt_pl1_spl_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL1_SPL);
asus->ppt_fppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_FPPT);
asus->ppt_apu_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_APU_SPPT);
- asus->ppt_plat_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PLAT_SPPT);
- 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->ppt_platform_sppt_available = asus_wmi_dev_is_present(asus,
+ ASUS_WMI_DEVID_PPT_PLAT_SPPT);
+ asus->nv_dynamic_boost_available = asus_wmi_dev_is_present(asus,
+ ASUS_WMI_DEVID_NV_DYN_BOOST);
+ asus->nv_temp_target_available = asus_wmi_dev_is_present(asus,
+ ASUS_WMI_DEVID_NV_THERM_TARGET);
asus->boot_sound_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_BOOT_SOUND);
asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
--
2.44.0

View File

@ -1,929 +0,0 @@
From fea4a499d6783faff756fe852c645f90aa73ccf7 Mon Sep 17 00:00:00 2001
From: Peter Jung <admin@ptr1337.dev>
Date: Mon, 15 Jul 2024 13:57:19 +0200
Subject: [PATCH] bore-cachy
Signed-off-by: Peter Jung <admin@ptr1337.dev>
---
include/linux/sched.h | 10 ++
init/Kconfig | 17 +++
kernel/Kconfig.hz | 16 +++
kernel/sched/core.c | 143 ++++++++++++++++++
kernel/sched/debug.c | 60 +++++++-
kernel/sched/fair.c | 310 ++++++++++++++++++++++++++++++++++++----
kernel/sched/features.h | 22 ++-
kernel/sched/sched.h | 7 +
8 files changed, 555 insertions(+), 30 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a5f4b48fca18..df62c56b13ae 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -547,6 +547,16 @@ struct sched_entity {
u64 sum_exec_runtime;
u64 prev_sum_exec_runtime;
u64 vruntime;
+#ifdef CONFIG_SCHED_BORE
+ u64 burst_time;
+ u8 prev_burst_penalty;
+ u8 curr_burst_penalty;
+ u8 burst_penalty;
+ u8 burst_score;
+ u8 child_burst;
+ u32 child_burst_cnt;
+ u64 child_burst_last_cached;
+#endif // CONFIG_SCHED_BORE
s64 vlag;
u64 slice;
diff --git a/init/Kconfig b/init/Kconfig
index 3ba6142f2f42..2966dec64df7 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1303,6 +1303,23 @@ config CHECKPOINT_RESTORE
If unsure, say N here.
+config SCHED_BORE
+ bool "Burst-Oriented Response Enhancer"
+ default y
+ help
+ In Desktop and Mobile computing, one might prefer interactive
+ tasks to keep responsive no matter what they run in the background.
+
+ Enabling this kernel feature modifies the scheduler to discriminate
+ tasks by their burst time (runtime since it last went sleeping or
+ yielding state) and prioritize those that run less bursty.
+ Such tasks usually include window compositor, widgets backend,
+ terminal emulator, video playback, games and so on.
+ With a little impact to scheduling fairness, it may improve
+ responsiveness especially under heavy background workload.
+
+ If unsure, say Y here.
+
config SCHED_AUTOGROUP
bool "Automatic process group scheduling"
select CGROUPS
diff --git a/kernel/Kconfig.hz b/kernel/Kconfig.hz
index 0f78364efd4f..b50189ee5b93 100644
--- a/kernel/Kconfig.hz
+++ b/kernel/Kconfig.hz
@@ -79,5 +79,21 @@ config HZ
default 750 if HZ_750
default 1000 if HZ_1000
+config MIN_BASE_SLICE_NS
+ int "Default value for min_base_slice_ns"
+ default 2000000
+ help
+ The BORE Scheduler automatically calculates the optimal base
+ slice for the configured HZ using the following equation:
+
+ base_slice_ns = max(min_base_slice_ns, 1000000000/HZ)
+
+ This option sets the default lower bound limit of the base slice
+ to prevent the loss of task throughput due to overscheduling.
+
+ Setting this value too high can cause the system to boot with
+ an unnecessarily large base slice, resulting in high scheduling
+ latency and poor system responsiveness.
+
config SCHED_HRTICK
def_bool HIGH_RES_TIMERS
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 59ce0841eb1f..c5d10b464779 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4515,6 +4515,138 @@ int wake_up_state(struct task_struct *p, unsigned int state)
return try_to_wake_up(p, state, 0);
}
+#ifdef CONFIG_SCHED_BORE
+extern u8 sched_burst_fork_atavistic;
+extern uint sched_burst_cache_lifetime;
+
+static void __init sched_init_bore(void) {
+ init_task.se.burst_time = 0;
+ init_task.se.prev_burst_penalty = 0;
+ init_task.se.curr_burst_penalty = 0;
+ init_task.se.burst_penalty = 0;
+ init_task.se.burst_score = 0;
+ init_task.se.child_burst_last_cached = 0;
+}
+
+inline void sched_fork_bore(struct task_struct *p) {
+ p->se.burst_time = 0;
+ p->se.curr_burst_penalty = 0;
+ p->se.burst_score = 0;
+ p->se.child_burst_last_cached = 0;
+}
+
+static u32 count_child_tasks(struct task_struct *p) {
+ struct task_struct *child;
+ u32 cnt = 0;
+ list_for_each_entry(child, &p->children, sibling) {cnt++;}
+ return cnt;
+}
+
+static inline bool task_is_inheritable(struct task_struct *p) {
+ return (p->sched_class == &fair_sched_class);
+}
+
+static inline bool child_burst_cache_expired(struct task_struct *p, u64 now) {
+ u64 expiration_time =
+ p->se.child_burst_last_cached + sched_burst_cache_lifetime;
+ return ((s64)(expiration_time - now) < 0);
+}
+
+static void __update_child_burst_cache(
+ struct task_struct *p, u32 cnt, u32 sum, u64 now) {
+ u8 avg = 0;
+ if (cnt) avg = sum / cnt;
+ p->se.child_burst = max(avg, p->se.burst_penalty);
+ p->se.child_burst_cnt = cnt;
+ p->se.child_burst_last_cached = now;
+}
+
+static inline void update_child_burst_direct(struct task_struct *p, u64 now) {
+ struct task_struct *child;
+ u32 cnt = 0;
+ u32 sum = 0;
+
+ list_for_each_entry(child, &p->children, sibling) {
+ if (!task_is_inheritable(child)) continue;
+ cnt++;
+ sum += child->se.burst_penalty;
+ }
+
+ __update_child_burst_cache(p, cnt, sum, now);
+}
+
+static inline u8 __inherit_burst_direct(struct task_struct *p, u64 now) {
+ struct task_struct *parent = p->real_parent;
+ if (child_burst_cache_expired(parent, now))
+ update_child_burst_direct(parent, now);
+
+ return parent->se.child_burst;
+}
+
+static void update_child_burst_topological(
+ struct task_struct *p, u64 now, u32 depth, u32 *acnt, u32 *asum) {
+ struct task_struct *child, *dec;
+ u32 cnt = 0, dcnt = 0;
+ u32 sum = 0;
+
+ list_for_each_entry(child, &p->children, sibling) {
+ dec = child;
+ while ((dcnt = count_child_tasks(dec)) == 1)
+ dec = list_first_entry(&dec->children, struct task_struct, sibling);
+
+ if (!dcnt || !depth) {
+ if (!task_is_inheritable(dec)) continue;
+ cnt++;
+ sum += dec->se.burst_penalty;
+ continue;
+ }
+ if (!child_burst_cache_expired(dec, now)) {
+ cnt += dec->se.child_burst_cnt;
+ sum += (u32)dec->se.child_burst * dec->se.child_burst_cnt;
+ continue;
+ }
+ update_child_burst_topological(dec, now, depth - 1, &cnt, &sum);
+ }
+
+ __update_child_burst_cache(p, cnt, sum, now);
+ *acnt += cnt;
+ *asum += sum;
+}
+
+static inline u8 __inherit_burst_topological(struct task_struct *p, u64 now) {
+ struct task_struct *anc = p->real_parent;
+ u32 cnt = 0, sum = 0;
+
+ while (anc->real_parent != anc && count_child_tasks(anc) == 1)
+ anc = anc->real_parent;
+
+ if (child_burst_cache_expired(anc, now))
+ update_child_burst_topological(
+ anc, now, sched_burst_fork_atavistic - 1, &cnt, &sum);
+
+ return anc->se.child_burst;
+}
+
+static inline void inherit_burst(struct task_struct *p) {
+ u8 burst_cache;
+ u64 now = ktime_get_ns();
+
+ read_lock(&tasklist_lock);
+ burst_cache = likely(sched_burst_fork_atavistic)?
+ __inherit_burst_topological(p, now):
+ __inherit_burst_direct(p, now);
+ read_unlock(&tasklist_lock);
+
+ p->se.prev_burst_penalty = max(p->se.prev_burst_penalty, burst_cache);
+}
+
+static void sched_post_fork_bore(struct task_struct *p) {
+ if (p->sched_class == &fair_sched_class)
+ inherit_burst(p);
+ p->se.burst_penalty = p->se.prev_burst_penalty;
+}
+#endif // CONFIG_SCHED_BORE
+
/*
* Perform scheduler related setup for a newly forked process p.
* p is forked by current.
@@ -4531,6 +4663,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
p->se.prev_sum_exec_runtime = 0;
p->se.nr_migrations = 0;
p->se.vruntime = 0;
+#ifdef CONFIG_SCHED_BORE
+ sched_fork_bore(p);
+#endif // CONFIG_SCHED_BORE
p->se.vlag = 0;
p->se.slice = sysctl_sched_base_slice;
INIT_LIST_HEAD(&p->se.group_node);
@@ -4846,6 +4981,9 @@ void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs)
void sched_post_fork(struct task_struct *p)
{
+#ifdef CONFIG_SCHED_BORE
+ sched_post_fork_bore(p);
+#endif // CONFIG_SCHED_BORE
uclamp_post_fork(p);
}
@@ -9933,6 +10071,11 @@ void __init sched_init(void)
BUG_ON(&dl_sched_class != &stop_sched_class + 1);
#endif
+#ifdef CONFIG_SCHED_BORE
+ sched_init_bore();
+ printk(KERN_INFO "BORE (Burst-Oriented Response Enhancer) CPU Scheduler modification 5.2.5 by Masahito Suzuki");
+#endif // CONFIG_SCHED_BORE
+
wait_bit_init();
#ifdef CONFIG_FAIR_GROUP_SCHED
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index c1eb9a1afd13..e2da8d773877 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -167,7 +167,52 @@ static const struct file_operations sched_feat_fops = {
};
#ifdef CONFIG_SMP
+#ifdef CONFIG_SCHED_BORE
+static ssize_t sched_min_base_slice_write(struct file *filp, const char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char buf[16];
+ unsigned int value;
+
+ if (cnt > 15)
+ cnt = 15;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+ buf[cnt] = '\0';
+
+ if (kstrtouint(buf, 10, &value))
+ return -EINVAL;
+ if (!value)
+ return -EINVAL;
+
+ sysctl_sched_min_base_slice = value;
+ sched_update_min_base_slice();
+
+ *ppos += cnt;
+ return cnt;
+}
+
+static int sched_min_base_slice_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "%d\n", sysctl_sched_min_base_slice);
+ return 0;
+}
+
+static int sched_min_base_slice_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, sched_min_base_slice_show, NULL);
+}
+
+static const struct file_operations sched_min_base_slice_fops = {
+ .open = sched_min_base_slice_open,
+ .write = sched_min_base_slice_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#else // !CONFIG_SCHED_BORE
static ssize_t sched_scaling_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
@@ -213,7 +258,7 @@ static const struct file_operations sched_scaling_fops = {
.llseek = seq_lseek,
.release = single_release,
};
-
+#endif // CONFIG_SCHED_BORE
#endif /* SMP */
#ifdef CONFIG_PREEMPT_DYNAMIC
@@ -347,13 +392,20 @@ static __init int sched_init_debug(void)
debugfs_create_file("preempt", 0644, debugfs_sched, NULL, &sched_dynamic_fops);
#endif
+#ifdef CONFIG_SCHED_BORE
+ debugfs_create_file("min_base_slice_ns", 0644, debugfs_sched, NULL, &sched_min_base_slice_fops);
+ debugfs_create_u32("base_slice_ns", 0400, debugfs_sched, &sysctl_sched_base_slice);
+#else // !CONFIG_SCHED_BORE
debugfs_create_u32("base_slice_ns", 0644, debugfs_sched, &sysctl_sched_base_slice);
+#endif // CONFIG_SCHED_BORE
debugfs_create_u32("latency_warn_ms", 0644, debugfs_sched, &sysctl_resched_latency_warn_ms);
debugfs_create_u32("latency_warn_once", 0644, debugfs_sched, &sysctl_resched_latency_warn_once);
#ifdef CONFIG_SMP
+#if !defined(CONFIG_SCHED_BORE)
debugfs_create_file("tunable_scaling", 0644, debugfs_sched, NULL, &sched_scaling_fops);
+#endif // CONFIG_SCHED_BORE
debugfs_create_u32("migration_cost_ns", 0644, debugfs_sched, &sysctl_sched_migration_cost);
debugfs_create_u32("nr_migrate", 0644, debugfs_sched, &sysctl_sched_nr_migrate);
@@ -596,6 +648,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
SPLIT_NS(schedstat_val_or_zero(p->stats.sum_sleep_runtime)),
SPLIT_NS(schedstat_val_or_zero(p->stats.sum_block_runtime)));
+#ifdef CONFIG_SCHED_BORE
+ SEQ_printf(m, " %2d", p->se.burst_score);
+#endif // CONFIG_SCHED_BORE
#ifdef CONFIG_NUMA_BALANCING
SEQ_printf(m, " %d %d", task_node(p), task_numa_group_id(p));
#endif
@@ -1069,6 +1124,9 @@ void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns,
P(se.load.weight);
#ifdef CONFIG_SMP
+#ifdef CONFIG_SCHED_BORE
+ P(se.burst_score);
+#endif // CONFIG_SCHED_BORE
P(se.avg.load_sum);
P(se.avg.runnable_sum);
P(se.avg.util_sum);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index c2bb8eb1d6ba..9e8b220f27e6 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -19,6 +19,9 @@
*
* Adaptive scheduling granularity, math enhancements by Peter Zijlstra
* Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra
+ *
+ * Burst-Oriented Response Enhancer (BORE) CPU Scheduler
+ * Copyright (C) 2021-2024 Masahito Suzuki <firelzrd@gmail.com>
*/
#include <linux/energy_model.h>
#include <linux/mmap_lock.h>
@@ -64,28 +67,126 @@
* SCHED_TUNABLESCALING_LOG - scaled logarithmical, *1+ilog(ncpus)
* SCHED_TUNABLESCALING_LINEAR - scaled linear, *ncpus
*
- * (default SCHED_TUNABLESCALING_LOG = *(1+ilog(ncpus))
+ * (BORE default SCHED_TUNABLESCALING_NONE = *1 constant)
+ * (EEVDF default SCHED_TUNABLESCALING_LOG = *(1+ilog(ncpus))
*/
+#ifdef CONFIG_SCHED_BORE
+unsigned int sysctl_sched_tunable_scaling = SCHED_TUNABLESCALING_NONE;
+#else // !CONFIG_SCHED_BORE
unsigned int sysctl_sched_tunable_scaling = SCHED_TUNABLESCALING_LOG;
+#endif // CONFIG_SCHED_BORE
/*
* Minimal preemption granularity for CPU-bound tasks:
*
- * (default: 0.75 msec * (1 + ilog(ncpus)), units: nanoseconds)
+ * (BORE default: max(1 sec / HZ, min_base_slice) constant, units: nanoseconds)
+ * (EEVDF default: 0.75 msec * (1 + ilog(ncpus)), units: nanoseconds)
*/
-#ifdef CONFIG_CACHY
-unsigned int sysctl_sched_base_slice = 350000ULL;
-static unsigned int normalized_sysctl_sched_base_slice = 350000ULL;
-#else
+#ifdef CONFIG_SCHED_BORE
+unsigned int sysctl_sched_base_slice = 1000000000ULL / HZ;
+static unsigned int configured_sched_base_slice = 1000000000ULL / HZ;
+unsigned int sysctl_sched_min_base_slice = CONFIG_MIN_BASE_SLICE_NS;
+#else // !CONFIG_SCHED_BORE
unsigned int sysctl_sched_base_slice = 750000ULL;
static unsigned int normalized_sysctl_sched_base_slice = 750000ULL;
-#endif
+#endif // CONFIG_SCHED_BORE
-#ifdef CONFIG_CACHY
-const_debug unsigned int sysctl_sched_migration_cost = 300000UL;
-#else
const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
-#endif
+
+#ifdef CONFIG_SCHED_BORE
+u8 __read_mostly sched_bore = 1;
+u8 __read_mostly sched_burst_smoothness_long = 1;
+u8 __read_mostly sched_burst_smoothness_short = 0;
+u8 __read_mostly sched_burst_fork_atavistic = 2;
+u8 __read_mostly sched_burst_penalty_offset = 22;
+uint __read_mostly sched_burst_penalty_scale = 1280;
+uint __read_mostly sched_burst_cache_lifetime = 60000000;
+uint __read_mostly sched_deadline_boost_mask = 0x81; // ENQUEUE_INITIAL | ENQUEUE_WAKEUP
+uint __read_mostly sched_deadline_preserve_mask = 0x42; // ENQUEUE_RESTORE | ENQUEUE_MIGRATED
+static int __maybe_unused sixty_four = 64;
+static int __maybe_unused maxval_12_bits = 4095;
+
+#define MAX_BURST_PENALTY (39U <<2)
+
+static inline u32 log2plus1_u64_u32f8(u64 v) {
+ u32 msb = fls64(v);
+ s32 excess_bits = msb - 9;
+ u8 fractional = (0 <= excess_bits)? v >> excess_bits: v << -excess_bits;
+ return msb << 8 | fractional;
+}
+
+static inline u32 calc_burst_penalty(u64 burst_time) {
+ u32 greed, tolerance, penalty, scaled_penalty;
+
+ greed = log2plus1_u64_u32f8(burst_time);
+ tolerance = sched_burst_penalty_offset << 8;
+ penalty = max(0, (s32)greed - (s32)tolerance);
+ scaled_penalty = penalty * sched_burst_penalty_scale >> 16;
+
+ return min(MAX_BURST_PENALTY, scaled_penalty);
+}
+
+static inline u64 scale_slice(u64 delta, struct sched_entity *se) {
+ return mul_u64_u32_shr(delta, sched_prio_to_wmult[se->burst_score], 22);
+}
+
+static inline u64 __unscale_slice(u64 delta, u8 score) {
+ return mul_u64_u32_shr(delta, sched_prio_to_weight[score], 10);
+}
+
+static inline u64 unscale_slice(u64 delta, struct sched_entity *se) {
+ return __unscale_slice(delta, se->burst_score);
+}
+
+void reweight_task(struct task_struct *p, int prio);
+
+static void update_burst_score(struct sched_entity *se) {
+ if (!entity_is_task(se)) return;
+ struct task_struct *p = task_of(se);
+ u8 prio = p->static_prio - MAX_RT_PRIO;
+ u8 prev_prio = min(39, prio + se->burst_score);
+
+ se->burst_score = se->burst_penalty >> 2;
+
+ u8 new_prio = min(39, prio + se->burst_score);
+ if (new_prio != prev_prio)
+ reweight_task(p, new_prio);
+}
+
+static void update_burst_penalty(struct sched_entity *se) {
+ se->curr_burst_penalty = calc_burst_penalty(se->burst_time);
+ se->burst_penalty = max(se->prev_burst_penalty, se->curr_burst_penalty);
+ update_burst_score(se);
+}
+
+static inline u32 binary_smooth(u32 new, u32 old) {
+ int increment = new - old;
+ return (0 <= increment)?
+ old + ( increment >> (int)sched_burst_smoothness_long):
+ old - (-increment >> (int)sched_burst_smoothness_short);
+}
+
+static void restart_burst(struct sched_entity *se) {
+ se->burst_penalty = se->prev_burst_penalty =
+ binary_smooth(se->curr_burst_penalty, se->prev_burst_penalty);
+ se->curr_burst_penalty = 0;
+ se->burst_time = 0;
+ update_burst_score(se);
+}
+
+static void restart_burst_rescale_deadline(struct sched_entity *se) {
+ s64 vscaled, wremain, vremain = se->deadline - se->vruntime;
+ u8 prev_score = se->burst_score;
+ restart_burst(se);
+ if (prev_score > se->burst_score) {
+ wremain = __unscale_slice(abs(vremain), prev_score);
+ vscaled = scale_slice(wremain, se);
+ if (unlikely(vremain < 0))
+ vscaled = -vscaled;
+ se->deadline = se->vruntime + vscaled;
+ }
+}
+#endif // CONFIG_SCHED_BORE
static int __init setup_sched_thermal_decay_shift(char *str)
{
@@ -130,12 +231,8 @@ int __weak arch_asym_cpu_priority(int cpu)
*
* (default: 5 msec, units: microseconds)
*/
-#ifdef CONFIG_CACHY
-static unsigned int sysctl_sched_cfs_bandwidth_slice = 3000UL;
-#else
static unsigned int sysctl_sched_cfs_bandwidth_slice = 5000UL;
#endif
-#endif
#ifdef CONFIG_NUMA_BALANCING
/* Restrict the NUMA promotion throughput (MB/s) for each target node. */
@@ -144,6 +241,83 @@ static unsigned int sysctl_numa_balancing_promote_rate_limit = 65536;
#ifdef CONFIG_SYSCTL
static struct ctl_table sched_fair_sysctls[] = {
+#ifdef CONFIG_SCHED_BORE
+ {
+ .procname = "sched_bore",
+ .data = &sched_bore,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+ .proc_handler = proc_dou8vec_minmax,
+ .extra1 = SYSCTL_ONE,
+ .extra2 = SYSCTL_ONE,
+ },
+ {
+ .procname = "sched_burst_smoothness_long",
+ .data = &sched_burst_smoothness_long,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+ .proc_handler = proc_dou8vec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE,
+ },
+ {
+ .procname = "sched_burst_smoothness_short",
+ .data = &sched_burst_smoothness_short,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+ .proc_handler = proc_dou8vec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE,
+ },
+ {
+ .procname = "sched_burst_fork_atavistic",
+ .data = &sched_burst_fork_atavistic,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+ .proc_handler = proc_dou8vec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_THREE,
+ },
+ {
+ .procname = "sched_burst_penalty_offset",
+ .data = &sched_burst_penalty_offset,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+ .proc_handler = proc_dou8vec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = &sixty_four,
+ },
+ {
+ .procname = "sched_burst_penalty_scale",
+ .data = &sched_burst_penalty_scale,
+ .maxlen = sizeof(uint),
+ .mode = 0644,
+ .proc_handler = proc_douintvec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = &maxval_12_bits,
+ },
+ {
+ .procname = "sched_burst_cache_lifetime",
+ .data = &sched_burst_cache_lifetime,
+ .maxlen = sizeof(uint),
+ .mode = 0644,
+ .proc_handler = proc_douintvec,
+ },
+ {
+ .procname = "sched_deadline_boost_mask",
+ .data = &sched_deadline_boost_mask,
+ .maxlen = sizeof(uint),
+ .mode = 0644,
+ .proc_handler = proc_douintvec,
+ },
+ {
+ .procname = "sched_deadline_preserve_mask",
+ .data = &sched_deadline_preserve_mask,
+ .maxlen = sizeof(uint),
+ .mode = 0644,
+ .proc_handler = proc_douintvec,
+ },
+#endif // CONFIG_SCHED_BORE
#ifdef CONFIG_CFS_BANDWIDTH
{
.procname = "sched_cfs_bandwidth_slice_us",
@@ -201,6 +375,13 @@ static inline void update_load_set(struct load_weight *lw, unsigned long w)
*
* This idea comes from the SD scheduler of Con Kolivas:
*/
+#ifdef CONFIG_SCHED_BORE
+static void update_sysctl(void) {
+ sysctl_sched_base_slice =
+ max(sysctl_sched_min_base_slice, configured_sched_base_slice);
+}
+void sched_update_min_base_slice(void) { update_sysctl(); }
+#else // !CONFIG_SCHED_BORE
static unsigned int get_update_sysctl_factor(void)
{
unsigned int cpus = min_t(unsigned int, num_online_cpus(), 8);
@@ -231,6 +412,7 @@ static void update_sysctl(void)
SET_SYSCTL(sched_base_slice);
#undef SET_SYSCTL
}
+#endif // CONFIG_SCHED_BORE
void __init sched_init_granularity(void)
{
@@ -708,6 +890,9 @@ static s64 entity_lag(u64 avruntime, struct sched_entity *se)
vlag = avruntime - se->vruntime;
limit = calc_delta_fair(max_t(u64, 2*se->slice, TICK_NSEC), se);
+#ifdef CONFIG_SCHED_BORE
+ limit >>= 1;
+#endif // CONFIG_SCHED_BORE
return clamp(vlag, -limit, limit);
}
@@ -868,6 +1053,39 @@ struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq)
return __node_2_se(left);
}
+static inline bool pick_curr(struct cfs_rq *cfs_rq,
+ struct sched_entity *curr, struct sched_entity *wakee)
+{
+ /*
+ * Nothing to preserve...
+ */
+ if (!curr || !sched_feat(RESPECT_SLICE))
+ return false;
+
+ /*
+ * Allow preemption at the 0-lag point -- even if not all of the slice
+ * is consumed. Note: placement of positive lag can push V left and render
+ * @curr instantly ineligible irrespective the time on-cpu.
+ */
+ if (sched_feat(RUN_TO_PARITY) && !entity_eligible(cfs_rq, curr))
+ return false;
+
+ /*
+ * Don't preserve @curr when the @wakee has a shorter slice and earlier
+ * deadline. IOW, explicitly allow preemption.
+ */
+ if (sched_feat(PREEMPT_SHORT) && wakee &&
+ wakee->slice < curr->slice &&
+ (s64)(wakee->deadline - curr->deadline) < 0)
+ return false;
+
+ /*
+ * Preserve @curr to allow it to finish its first slice.
+ * See the HACK in set_next_entity().
+ */
+ return curr->vlag == curr->deadline;
+}
+
/*
* Earliest Eligible Virtual Deadline First
*
@@ -887,28 +1105,27 @@ struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq)
*
* Which allows tree pruning through eligibility.
*/
-static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq)
+static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *wakee)
{
struct rb_node *node = cfs_rq->tasks_timeline.rb_root.rb_node;
struct sched_entity *se = __pick_first_entity(cfs_rq);
struct sched_entity *curr = cfs_rq->curr;
struct sched_entity *best = NULL;
+ if (curr && !curr->on_rq)
+ curr = NULL;
+
/*
* We can safely skip eligibility check if there is only one entity
* in this cfs_rq, saving some cycles.
*/
if (cfs_rq->nr_running == 1)
- return curr && curr->on_rq ? curr : se;
-
- if (curr && (!curr->on_rq || !entity_eligible(cfs_rq, curr)))
- curr = NULL;
+ return curr ?: se;
/*
- * Once selected, run a task until it either becomes non-eligible or
- * until it gets a new slice. See the HACK in set_next_entity().
+ * Preserve @curr to let it finish its slice.
*/
- if (sched_feat(RUN_TO_PARITY) && curr && curr->vlag == curr->deadline)
+ if (pick_curr(cfs_rq, curr, wakee))
return curr;
/* Pick the leftmost entity if it's eligible */
@@ -967,6 +1184,7 @@ struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
* Scheduling class statistics methods:
*/
#ifdef CONFIG_SMP
+#if !defined(CONFIG_SCHED_BORE)
int sched_update_scaling(void)
{
unsigned int factor = get_update_sysctl_factor();
@@ -978,6 +1196,7 @@ int sched_update_scaling(void)
return 0;
}
+#endif // CONFIG_SCHED_BORE
#endif
#endif
@@ -1178,7 +1397,13 @@ static void update_curr(struct cfs_rq *cfs_rq)
if (unlikely(delta_exec <= 0))
return;
+#ifdef CONFIG_SCHED_BORE
+ curr->burst_time += delta_exec;
+ update_burst_penalty(curr);
+ curr->vruntime += max(1ULL, calc_delta_fair(delta_exec, curr));
+#else // !CONFIG_SCHED_BORE
curr->vruntime += calc_delta_fair(delta_exec, curr);
+#endif // CONFIG_SCHED_BORE
update_deadline(cfs_rq, curr);
update_min_vruntime(cfs_rq);
@@ -5193,6 +5418,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
s64 lag = 0;
se->slice = sysctl_sched_base_slice;
+#ifdef CONFIG_SCHED_BORE
+ if (flags & ~sched_deadline_boost_mask & sched_deadline_preserve_mask)
+ vslice = se->deadline - se->vruntime;
+ else
+#endif // CONFIG_SCHED_BORE
vslice = calc_delta_fair(se->slice, se);
/*
@@ -5203,6 +5433,9 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
*
* EEVDF: placement strategy #1 / #2
*/
+#ifdef CONFIG_SCHED_BORE
+ if (se->vlag)
+#endif // CONFIG_SCHED_BORE
if (sched_feat(PLACE_LAG) && cfs_rq->nr_running) {
struct sched_entity *curr = cfs_rq->curr;
unsigned long load;
@@ -5278,7 +5511,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
* on average, halfway through their slice, as such start tasks
* off with half a slice to ease into the competition.
*/
+#if !defined(CONFIG_SCHED_BORE)
if (sched_feat(PLACE_DEADLINE_INITIAL) && (flags & ENQUEUE_INITIAL))
+#else // CONFIG_SCHED_BORE
+ if (flags & sched_deadline_boost_mask)
+#endif // CONFIG_SCHED_BORE
vslice /= 2;
/*
@@ -5492,7 +5729,7 @@ pick_next_entity(struct cfs_rq *cfs_rq)
cfs_rq->next && entity_eligible(cfs_rq, cfs_rq->next))
return cfs_rq->next;
- return pick_eevdf(cfs_rq);
+ return pick_eevdf(cfs_rq, NULL);
}
static bool check_cfs_rq_runtime(struct cfs_rq *cfs_rq);
@@ -6860,6 +7097,14 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
bool was_sched_idle = sched_idle_rq(rq);
util_est_dequeue(&rq->cfs, p);
+#ifdef CONFIG_SCHED_BORE
+ if (task_sleep) {
+ cfs_rq = cfs_rq_of(se);
+ if (cfs_rq->curr == se)
+ update_curr(cfs_rq);
+ restart_burst(se);
+ }
+#endif // CONFIG_SCHED_BORE
for_each_sched_entity(se) {
cfs_rq = cfs_rq_of(se);
@@ -8425,10 +8670,7 @@ static void check_preempt_wakeup_fair(struct rq *rq, struct task_struct *p, int
cfs_rq = cfs_rq_of(se);
update_curr(cfs_rq);
- /*
- * XXX pick_eevdf(cfs_rq) != se ?
- */
- if (pick_eevdf(cfs_rq) == pse)
+ if (pick_eevdf(cfs_rq, pse) == pse)
goto preempt;
return;
@@ -8646,16 +8888,25 @@ static void yield_task_fair(struct rq *rq)
/*
* Are we the only task in the tree?
*/
+#if !defined(CONFIG_SCHED_BORE)
if (unlikely(rq->nr_running == 1))
return;
clear_buddies(cfs_rq, se);
+#endif // CONFIG_SCHED_BORE
update_rq_clock(rq);
/*
* Update run-time statistics of the 'current'.
*/
update_curr(cfs_rq);
+#ifdef CONFIG_SCHED_BORE
+ restart_burst_rescale_deadline(se);
+ if (unlikely(rq->nr_running == 1))
+ return;
+
+ clear_buddies(cfs_rq, se);
+#endif // CONFIG_SCHED_BORE
/*
* Tell update_rq_clock() that we've just updated,
* so we don't do microscopic update in schedule()
@@ -12723,6 +12974,9 @@ static void task_fork_fair(struct task_struct *p)
curr = cfs_rq->curr;
if (curr)
update_curr(cfs_rq);
+#ifdef CONFIG_SCHED_BORE
+ update_burst_score(se);
+#endif // CONFIG_SCHED_BORE
place_entity(cfs_rq, se, ENQUEUE_INITIAL);
rq_unlock(rq, &rf);
}
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
index 143f55df890b..3aad8900c35e 100644
--- a/kernel/sched/features.h
+++ b/kernel/sched/features.h
@@ -5,8 +5,28 @@
* sleep+wake cycles. EEVDF placement strategy #1, #2 if disabled.
*/
SCHED_FEAT(PLACE_LAG, true)
+/*
+ * Give new tasks half a slice to ease into the competition.
+ */
+#if !defined(CONFIG_SCHED_BORE)
SCHED_FEAT(PLACE_DEADLINE_INITIAL, true)
-SCHED_FEAT(RUN_TO_PARITY, true)
+#endif // CONFIG_SCHED_BORE
+/*
+ * Inhibit (wakeup) preemption until the current task has exhausted its slice.
+ */
+#ifdef CONFIG_SCHED_BORE
+SCHED_FEAT(RESPECT_SLICE, false)
+#else // !CONFIG_SCHED_BORE
+SCHED_FEAT(RESPECT_SLICE, true)
+#endif // CONFIG_SCHED_BORE
+/*
+ * Relax RESPECT_SLICE to allow preemption once current has reached 0-lag.
+ */
+SCHED_FEAT(RUN_TO_PARITY, false)
+/*
+ * Allow tasks with a shorter slice to disregard RESPECT_SLICE
+ */
+SCHED_FEAT(PREEMPT_SHORT, true)
/*
* Prefer to schedule the task we woke last (assuming it failed
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 10c1caff5e06..5d845dbd0cf9 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1969,7 +1969,11 @@ static inline void dirty_sched_domain_sysctl(int cpu)
}
#endif
+#ifdef CONFIG_SCHED_BORE
+extern void sched_update_min_base_slice(void);
+#else // !CONFIG_SCHED_BORE
extern int sched_update_scaling(void);
+#endif // CONFIG_SCHED_BORE
static inline const struct cpumask *task_user_cpus(struct task_struct *p)
{
@@ -2554,6 +2558,9 @@ extern const_debug unsigned int sysctl_sched_nr_migrate;
extern const_debug unsigned int sysctl_sched_migration_cost;
extern unsigned int sysctl_sched_base_slice;
+#ifdef CONFIG_SCHED_BORE
+extern unsigned int sysctl_sched_min_base_slice;
+#endif // CONFIG_SCHED_BORE
#ifdef CONFIG_SCHED_DEBUG
extern int sysctl_resched_latency_warn_ms;
--
2.46.0.rc0

File diff suppressed because it is too large Load Diff

View File

@ -1,761 +0,0 @@
From eb7e13baaf58cdede50c060633bdb14bf9603a54 Mon Sep 17 00:00:00 2001
From: Peter Jung <admin@ptr1337.dev>
Date: Mon, 3 Jun 2024 15:33:26 +0200
Subject: [PATCH] Fix 6.10 NVIDIA
Co Authord by Laio Oriel Seman <laioseman@gmail.com>
Signed-off-by: Peter Jung <admin@ptr1337.dev>
---
include/linux/mm.h | 4 ++++
mm/memory.c | 37 ++++++++++++++++++++++++++++++++++++-
mm/nommu.c | 21 +++++++++++++++++++++
3 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9849dfda44d43..adc5a252da02e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2438,6 +2438,10 @@ int
copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma);
int follow_pte(struct vm_area_struct *vma, unsigned long address,
pte_t **ptepp, spinlock_t **ptlp);
+int follow_pfn(struct vm_area_struct *vma, unsigned long address,
+ unsigned long *pfn);
+//int follow_phys(struct vm_area_struct *vma, unsigned long address,
+// unsigned int flags, unsigned long *prot, resource_size_t *phys);
int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
void *buf, int len, int write);
diff --git a/mm/memory.c b/mm/memory.c
index 0f47a533014e4..0401d10b3d824 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -5962,7 +5962,8 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
* Only IO mappings and raw PFN mappings are allowed. The mmap semaphore
* should be taken for read.
*
- * This function must not be used to modify PTE content.
+ * KVM uses this function. While it is arguably less bad than ``follow_pfn``,
+ * it is not a good general-purpose API.
*
* Return: zero on success, -ve otherwise.
*/
@@ -6012,6 +6013,40 @@ int follow_pte(struct vm_area_struct *vma, unsigned long address,
}
EXPORT_SYMBOL_GPL(follow_pte);
+/**
+ * follow_pfn - look up PFN at a user virtual address
+ * @vma: memory mapping
+ * @address: user virtual address
+ * @pfn: location to store found PFN
+ *
+ * Only IO mappings and raw PFN mappings are allowed.
+ *
+ * This function does not allow the caller to read the permissions
+ * of the PTE. Do not use it.
+ *
+ * Return: zero and the pfn at @pfn on success, -ve otherwise.
+ */
+int follow_pfn(struct vm_area_struct *vma, unsigned long address,
+ unsigned long *pfn)
+{
+ int ret = -EINVAL;
+ spinlock_t *ptl;
+ pte_t *ptep;
+
+ if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
+ return ret;
+
+ //ret = follow_pte(vma->vm_mm, address, &ptep, &ptl);
+ ret = follow_pte(vma, address, &ptep, &ptl);
+
+ if (ret)
+ return ret;
+ *pfn = pte_pfn(ptep_get(ptep));
+ pte_unmap_unlock(ptep, ptl);
+ return 0;
+}
+EXPORT_SYMBOL(follow_pfn);
+
#ifdef CONFIG_HAVE_IOREMAP_PROT
/**
* generic_access_phys - generic implementation for iomem mmap access
diff --git a/mm/nommu.c b/mm/nommu.c
index 7296e775e04e2..8e0deb733bfef 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -110,6 +110,27 @@ unsigned int kobjsize(const void *objp)
return page_size(page);
}
+/**
+ * follow_pfn - look up PFN at a user virtual address
+ * @vma: memory mapping
+ * @address: user virtual address
+ * @pfn: location to store found PFN
+ *
+ * Only IO mappings and raw PFN mappings are allowed.
+ *
+ * Returns zero and the pfn at @pfn on success, -ve otherwise.
+ */
+int follow_pfn(struct vm_area_struct *vma, unsigned long address,
+ unsigned long *pfn)
+{
+ if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
+ return -EINVAL;
+
+ *pfn = address >> PAGE_SHIFT;
+ return 0;
+}
+EXPORT_SYMBOL(follow_pfn);
+
void vfree(const void *addr)
{
kfree(addr);
--
2.45.1
--- a/kernel/nvidia-drm/nvidia-drm-drv.c
+++ b/kernel/nvidia-drm/nvidia-drm-drv.c
@@ -480,6 +480,22 @@ static int nv_drm_load(struct drm_device *dev, unsigned long flags)
return -ENODEV;
}
+#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
+ /*
+ * If fbdev is enabled, take modeset ownership now before other DRM clients
+ * can take master (and thus NVKMS ownership).
+ */
+ if (nv_drm_fbdev_module_param) {
+ if (!nvKms->grabOwnership(pDevice)) {
+ nvKms->freeDevice(pDevice);
+ NV_DRM_DEV_LOG_ERR(nv_dev, "Failed to grab NVKMS modeset ownership");
+ return -EBUSY;
+ }
+
+ nv_dev->hasFramebufferConsole = NV_TRUE;
+ }
+#endif
+
mutex_lock(&nv_dev->lock);
/* Set NvKmsKapiDevice */
@@ -590,6 +606,15 @@ static void __nv_drm_unload(struct drm_device *dev)
return;
}
+ /* Release modeset ownership if fbdev is enabled */
+
+#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
+ if (nv_dev->hasFramebufferConsole) {
+ drm_atomic_helper_shutdown(dev);
+ nvKms->releaseOwnership(nv_dev->pDevice);
+ }
+#endif
+
cancel_delayed_work_sync(&nv_dev->hotplug_event_work);
mutex_lock(&nv_dev->lock);
@@ -1768,14 +1793,7 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
}
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
- if (nv_drm_fbdev_module_param &&
- drm_core_check_feature(dev, DRIVER_MODESET)) {
-
- if (!nvKms->grabOwnership(nv_dev->pDevice)) {
- NV_DRM_DEV_LOG_ERR(nv_dev, "Failed to grab NVKMS modeset ownership");
- goto failed_grab_ownership;
- }
-
+ if (nv_dev->hasFramebufferConsole) {
if (bus_is_pci) {
struct pci_dev *pdev = to_pci_dev(device);
@@ -1786,8 +1804,6 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
#endif
}
drm_fbdev_generic_setup(dev, 32);
-
- nv_dev->hasFramebufferConsole = NV_TRUE;
}
#endif /* defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) */
@@ -1798,12 +1814,6 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
return; /* Success */
-#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
-failed_grab_ownership:
-
- drm_dev_unregister(dev);
-#endif
-
failed_drm_register:
nv_drm_dev_free(dev);
@@ -1870,12 +1880,6 @@ void nv_drm_remove_devices(void)
struct nv_drm_device *next = dev_list->next;
struct drm_device *dev = dev_list->dev;
-#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
- if (dev_list->hasFramebufferConsole) {
- drm_atomic_helper_shutdown(dev);
- nvKms->releaseOwnership(dev_list->pDevice);
- }
-#endif
drm_dev_unregister(dev);
nv_drm_dev_free(dev);
From 612740b11c9645e0f0240b3ca5908ef225763bc8 Mon Sep 17 00:00:00 2001
From: Peter Jung <admin@ptr1337.dev>
Date: Thu, 27 Jun 2024 19:46:51 +0200
Subject: [PATCH] gsp-stutter-fix
We've been having reports of stutter issues in 555 releases related to GSP enablement. On the proprietary driver, NVreg_EnableGpuFirmware=0 makes them go away; on the open driver that's not an option.
So far, we've identified two possible causes here. One is fixed by commit 674c009 below. The other we can't fix/workaround in the kernel modules and requires usermode changes, but commit 8c1c49b should tell us if that path is actually being hit or not.
I've also augmented the logs captured by nvidia-bug-report.sh with some of the info that we found severely lacking in the bug reports so far.
My hope is that folks that have experienced these stutter issues can take these patches, try to reproduce the issue and report back with their findings (and their nvidia-bug-report logs). Many thanks in advance to anyone willing to go the extra mile(s) for us here!
We've unfortunately missed beta2 / 555.52 with this stuff (security fixes can't wait), but here it is early so we don't have to wait on the next release.
---
kernel-open/nvidia/nv.c | 10 +
src/nvidia/arch/nvalloc/unix/include/osapi.h | 6 -
src/nvidia/arch/nvalloc/unix/src/escape.c | 46 ----
src/nvidia/arch/nvalloc/unix/src/osapi.c | 230 ++++++++-----------
src/nvidia/exports_link_command.txt | 1 -
src/nvidia/src/kernel/disp/disp_sw.c | 23 ++
6 files changed, 132 insertions(+), 184 deletions(-)
diff --git a/kernel-open/nvidia/nv.c b/kernel-open/nvidia/nv.c
index 99792de9..ccef3f29 100644
--- a/kernel-open/nvidia/nv.c
+++ b/kernel-open/nvidia/nv.c
@@ -4042,6 +4042,16 @@ int NV_API_CALL nv_get_event(
nvidia_event_t *nvet;
unsigned long eflags;
+ //
+ // Note that the head read/write is not atomic when done outside of the
+ // spinlock, so this might not be a valid pointer at all. But if we read
+ // NULL here that means that the value indeed was NULL and we can bail
+ // early since there's no events. Otherwise, we have to do a proper read
+ // under a spinlock.
+ //
+ if (nvlfp->event_data_head == NULL)
+ return NV_ERR_GENERIC;
+
NV_SPIN_LOCK_IRQSAVE(&nvlfp->fp_lock, eflags);
nvet = nvlfp->event_data_head;
diff --git a/src/nvidia/arch/nvalloc/unix/include/osapi.h b/src/nvidia/arch/nvalloc/unix/include/osapi.h
index f91e3aa5..640155e9 100644
--- a/src/nvidia/arch/nvalloc/unix/include/osapi.h
+++ b/src/nvidia/arch/nvalloc/unix/include/osapi.h
@@ -121,9 +121,6 @@ NvBool RmGpuHasIOSpaceEnabled (nv_state_t *);
void RmFreeUnusedClients (nv_state_t *, nv_file_private_t *);
NV_STATUS RmIoctl (nv_state_t *, nv_file_private_t *, NvU32, void *, NvU32);
-NV_STATUS RmAllocOsEvent (NvHandle, nv_file_private_t *, NvU32);
-NV_STATUS RmFreeOsEvent (NvHandle, NvU32);
-
void RmI2cAddGpuPorts(nv_state_t *);
NV_STATUS RmInitX86EmuState(OBJGPU *);
@@ -141,9 +138,6 @@ int amd_msr_c0011022_incompatible(OBJOS *);
NV_STATUS rm_get_adapter_status (nv_state_t *, NvU32 *);
-NV_STATUS rm_alloc_os_event (NvHandle, nv_file_private_t *, NvU32);
-NV_STATUS rm_free_os_event (NvHandle, NvU32);
-NV_STATUS rm_get_event_data (nv_file_private_t *, NvP64, NvU32 *);
void rm_client_free_os_events (NvHandle);
NV_STATUS rm_create_mmap_context (NvHandle, NvHandle, NvHandle, NvP64, NvU64, NvU64, NvU32, NvU32);
diff --git a/src/nvidia/arch/nvalloc/unix/src/escape.c b/src/nvidia/arch/nvalloc/unix/src/escape.c
index de099513..1046b19f 100644
--- a/src/nvidia/arch/nvalloc/unix/src/escape.c
+++ b/src/nvidia/arch/nvalloc/unix/src/escape.c
@@ -677,52 +677,6 @@ NV_STATUS RmIoctl(
break;
}
- case NV_ESC_ALLOC_OS_EVENT:
- {
- nv_ioctl_alloc_os_event_t *pApi = data;
-
- if (dataSize != sizeof(nv_ioctl_alloc_os_event_t))
- {
- rmStatus = NV_ERR_INVALID_ARGUMENT;
- goto done;
- }
-
- pApi->Status = rm_alloc_os_event(pApi->hClient,
- nvfp,
- pApi->fd);
- break;
- }
-
- case NV_ESC_FREE_OS_EVENT:
- {
- nv_ioctl_free_os_event_t *pApi = data;
-
- if (dataSize != sizeof(nv_ioctl_free_os_event_t))
- {
- rmStatus = NV_ERR_INVALID_ARGUMENT;
- goto done;
- }
-
- pApi->Status = rm_free_os_event(pApi->hClient, pApi->fd);
- break;
- }
-
- case NV_ESC_RM_GET_EVENT_DATA:
- {
- NVOS41_PARAMETERS *pApi = data;
-
- if (dataSize != sizeof(NVOS41_PARAMETERS))
- {
- rmStatus = NV_ERR_INVALID_ARGUMENT;
- goto done;
- }
-
- pApi->status = rm_get_event_data(nvfp,
- pApi->pEvent,
- &pApi->MoreEvents);
- break;
- }
-
case NV_ESC_STATUS_CODE:
{
nv_state_t *pNv;
diff --git a/src/nvidia/arch/nvalloc/unix/src/osapi.c b/src/nvidia/arch/nvalloc/unix/src/osapi.c
index fd312466..51249750 100644
--- a/src/nvidia/arch/nvalloc/unix/src/osapi.c
+++ b/src/nvidia/arch/nvalloc/unix/src/osapi.c
@@ -25,6 +25,7 @@
#include <nv_ref.h>
#include <nv.h>
+#include <nv_escape.h>
#include <nv-priv.h>
#include <os/os.h>
#include <osapi.h>
@@ -406,6 +407,39 @@ static void free_os_events(
portSyncSpinlockRelease(nv->event_spinlock);
}
+static NV_STATUS get_os_event_data(
+ nv_file_private_t *nvfp,
+ NvP64 pEvent,
+ NvU32 *MoreEvents
+)
+{
+ nv_event_t nv_event;
+ NvUnixEvent *nv_unix_event;
+ NV_STATUS status;
+
+ status = os_alloc_mem((void**)&nv_unix_event, sizeof(NvUnixEvent));
+ if (status != NV_OK)
+ return status;
+
+ status = nv_get_event(nvfp, &nv_event, MoreEvents);
+ if (status != NV_OK)
+ {
+ status = NV_ERR_OPERATING_SYSTEM;
+ goto done;
+ }
+
+ os_mem_set(nv_unix_event, 0, sizeof(NvUnixEvent));
+ nv_unix_event->hObject = nv_event.hObject;
+ nv_unix_event->NotifyIndex = nv_event.index;
+ nv_unix_event->info32 = nv_event.info32;
+ nv_unix_event->info16 = nv_event.info16;
+
+ status = os_memcpy_to_user(NvP64_VALUE(pEvent), nv_unix_event, sizeof(NvUnixEvent));
+done:
+ os_free_mem(nv_unix_event);
+ return status;
+}
+
void rm_client_free_os_events(
NvHandle client
)
@@ -482,6 +516,12 @@ static NV_STATUS allocate_os_event(
goto done;
}
+ new_event->hParent = hParent;
+ new_event->nvfp = nvfp;
+ new_event->fd = fd;
+ new_event->active = NV_TRUE;
+ new_event->refcount = 0;
+
portSyncSpinlockAcquire(nv->event_spinlock);
for (event = nv->event_list; event; event = event->next)
{
@@ -496,45 +536,26 @@ static NV_STATUS allocate_os_event(
new_event->next = nv->event_list;
nv->event_list = new_event;
+ nvfp->bCleanupRmapi = NV_TRUE;
portSyncSpinlockRelease(nv->event_spinlock);
done:
if (status == NV_OK)
{
- new_event->hParent = hParent;
- new_event->nvfp = nvfp;
- new_event->fd = fd;
- new_event->active = NV_TRUE;
- new_event->refcount = 0;
-
- nvfp->bCleanupRmapi = NV_TRUE;
-
NV_PRINTF(LEVEL_INFO, "allocated OS event:\n");
NV_PRINTF(LEVEL_INFO, " hParent: 0x%x\n", hParent);
NV_PRINTF(LEVEL_INFO, " fd: %d\n", fd);
}
else
{
+ NV_PRINTF(LEVEL_ERROR, "failed to allocate OS event: 0x%08x\n", status);
+ status = NV_ERR_INSUFFICIENT_RESOURCES;
portMemFree(new_event);
}
return status;
}
-NV_STATUS RmAllocOsEvent(
- NvHandle hParent,
- nv_file_private_t *nvfp,
- NvU32 fd
-)
-{
- if (NV_OK != allocate_os_event(hParent, nvfp, fd))
- {
- NV_PRINTF(LEVEL_ERROR, "failed to allocate OS event\n");
- return NV_ERR_INSUFFICIENT_RESOURCES;
- }
- return NV_OK;
-}
-
static NV_STATUS free_os_event(
NvHandle hParent,
NvU32 fd
@@ -585,18 +606,6 @@ static NV_STATUS free_os_event(
return result;
}
-NV_STATUS RmFreeOsEvent(
- NvHandle hParent,
- NvU32 fd
-)
-{
- if (NV_OK != free_os_event(hParent, fd))
- {
- return NV_ERR_INVALID_EVENT;
- }
- return NV_OK;
-}
-
static void RmExecuteWorkItem(
void *pWorkItem
)
@@ -656,40 +665,6 @@ done:
portMemFree((void *)pWi);
}
-static NV_STATUS RmGetEventData(
- nv_file_private_t *nvfp,
- NvP64 pEvent,
- NvU32 *MoreEvents,
- NvBool bUserModeArgs
-)
-{
- NV_STATUS RmStatus;
- NvUnixEvent *pKernelEvent = NULL;
- nv_event_t nv_event;
- RMAPI_PARAM_COPY paramCopy;
-
- RmStatus = nv_get_event(nvfp, &nv_event, MoreEvents);
- if (RmStatus != NV_OK)
- return NV_ERR_OPERATING_SYSTEM;
-
- // setup for access to client's parameters
- RMAPI_PARAM_COPY_INIT(paramCopy, pKernelEvent, pEvent, 1, sizeof(NvUnixEvent));
- RmStatus = rmapiParamsAcquire(&paramCopy, bUserModeArgs);
- if (RmStatus != NV_OK)
- return NV_ERR_OPERATING_SYSTEM;
-
- pKernelEvent->hObject = nv_event.hObject;
- pKernelEvent->NotifyIndex = nv_event.index;
- pKernelEvent->info32 = nv_event.info32;
- pKernelEvent->info16 = nv_event.info16;
-
- // release client buffer access, with copyout as needed
- if (rmapiParamsRelease(&paramCopy) != NV_OK)
- return NV_ERR_OPERATING_SYSTEM;
-
- return NV_OK;
-}
-
static NV_STATUS RmAccessRegistry(
NvHandle hClient,
NvHandle hObject,
@@ -2738,16 +2713,68 @@ NV_STATUS NV_API_CALL rm_ioctl(
NvU32 dataSize
)
{
- NV_STATUS rmStatus;
+ NV_STATUS rmStatus = NV_OK;
THREAD_STATE_NODE threadState;
void *fp;
NV_ENTER_RM_RUNTIME(sp,fp);
- threadStateInit(&threadState, THREAD_STATE_FLAGS_NONE);
- rmStatus = RmIoctl(pNv, nvfp, Command, pData, dataSize);
+ //
+ // Some ioctls are handled entirely inside the OS layer and don't need to
+ // suffer the overhead of calling into RM core.
+ //
+ switch (Command)
+ {
+ case NV_ESC_ALLOC_OS_EVENT:
+ {
+ nv_ioctl_alloc_os_event_t *pApi = pData;
+
+ if (dataSize != sizeof(nv_ioctl_alloc_os_event_t))
+ {
+ rmStatus = NV_ERR_INVALID_ARGUMENT;
+ break;
+ }
+
+ pApi->Status = allocate_os_event(pApi->hClient, nvfp, pApi->fd);
+ break;
+ }
+ case NV_ESC_FREE_OS_EVENT:
+ {
+ nv_ioctl_free_os_event_t *pApi = pData;
+
+ if (dataSize != sizeof(nv_ioctl_free_os_event_t))
+ {
+ rmStatus = NV_ERR_INVALID_ARGUMENT;
+ break;
+ }
+
+ pApi->Status = free_os_event(pApi->hClient, pApi->fd);
+ break;
+ }
+ case NV_ESC_RM_GET_EVENT_DATA:
+ {
+ NVOS41_PARAMETERS *pApi = pData;
+
+ if (dataSize != sizeof(NVOS41_PARAMETERS))
+ {
+ rmStatus = NV_ERR_INVALID_ARGUMENT;
+ break;
+ }
+
+ pApi->status = get_os_event_data(nvfp,
+ pApi->pEvent,
+ &pApi->MoreEvents);
+ break;
+ }
+ default:
+ {
+ threadStateInit(&threadState, THREAD_STATE_FLAGS_NONE);
+ rmStatus = RmIoctl(pNv, nvfp, Command, pData, dataSize);
+ threadStateFree(&threadState, THREAD_STATE_FLAGS_NONE);
+ break;
+ }
+ }
- threadStateFree(&threadState, THREAD_STATE_FLAGS_NONE);
NV_EXIT_RM_RUNTIME(sp,fp);
return rmStatus;
@@ -2882,65 +2909,6 @@ void NV_API_CALL rm_unbind_lock(
NV_EXIT_RM_RUNTIME(sp,fp);
}
-NV_STATUS rm_alloc_os_event(
- NvHandle hClient,
- nv_file_private_t *nvfp,
- NvU32 fd
-)
-{
- NV_STATUS RmStatus;
-
- // LOCK: acquire API lock
- if ((RmStatus = rmapiLockAcquire(RMAPI_LOCK_FLAGS_READ, RM_LOCK_MODULES_EVENT)) == NV_OK)
- {
- RmStatus = RmAllocOsEvent(hClient, nvfp, fd);
-
- // UNLOCK: release API lock
- rmapiLockRelease();
- }
-
- return RmStatus;
-}
-
-NV_STATUS rm_free_os_event(
- NvHandle hClient,
- NvU32 fd
-)
-{
- NV_STATUS RmStatus;
-
- // LOCK: acquire API lock
- if ((RmStatus = rmapiLockAcquire(RMAPI_LOCK_FLAGS_READ, RM_LOCK_MODULES_EVENT)) == NV_OK)
- {
- RmStatus = RmFreeOsEvent(hClient, fd);
-
- // UNLOCK: release API lock
- rmapiLockRelease();
- }
-
- return RmStatus;
-}
-
-NV_STATUS rm_get_event_data(
- nv_file_private_t *nvfp,
- NvP64 pEvent,
- NvU32 *MoreEvents
-)
-{
- NV_STATUS RmStatus;
-
- // LOCK: acquire API lock
- if ((RmStatus = rmapiLockAcquire(RMAPI_LOCK_FLAGS_READ, RM_LOCK_MODULES_EVENT)) == NV_OK)
- {
- RmStatus = RmGetEventData(nvfp, pEvent, MoreEvents, NV_TRUE);
-
- // UNLOCK: release API lock
- rmapiLockRelease();
- }
-
- return RmStatus;
-}
-
NV_STATUS NV_API_CALL rm_read_registry_dword(
nvidia_stack_t *sp,
nv_state_t *nv,
diff --git a/src/nvidia/exports_link_command.txt b/src/nvidia/exports_link_command.txt
index de3cf86d..b92185de 100644
--- a/src/nvidia/exports_link_command.txt
+++ b/src/nvidia/exports_link_command.txt
@@ -1,6 +1,5 @@
--undefined=rm_disable_adapter
--undefined=rm_execute_work_item
---undefined=rm_free_os_event
--undefined=rm_free_private_state
--undefined=rm_cleanup_file_private
--undefined=rm_unbind_lock
diff --git a/src/nvidia/src/kernel/disp/disp_sw.c b/src/nvidia/src/kernel/disp/disp_sw.c
index 03ce58f7..bb7396b6 100644
--- a/src/nvidia/src/kernel/disp/disp_sw.c
+++ b/src/nvidia/src/kernel/disp/disp_sw.c
@@ -141,8 +141,15 @@ NV_STATUS dispswReleaseSemaphoreAndNotifierFill
NvBool bFound = NV_FALSE;
NV_STATUS status;
+#define PRINT_INTERVAL 3600 // At 60Hz, this will emit about once per minute.
+
if (flags & F_SEMAPHORE_ADDR_VALID)
{
+ static NvU64 counter;
+ if ((++counter % PRINT_INTERVAL) == 0) {
+ NV_PRINTF(LEVEL_ERROR, "XXXMT: NVRM debugging - F_SEMAPHORE_ADDR_VALID = %llu\n", counter);
+ }
+
bFound = CliGetDmaMappingInfo(RES_GET_CLIENT(pDevice),
RES_GET_HANDLE(pDevice),
vaSpace,
@@ -154,6 +161,11 @@ NV_STATUS dispswReleaseSemaphoreAndNotifierFill
}
else if (flags & F_SEMAPHORE_RELEASE)
{
+ static NvU64 counter;
+ if ((++counter % PRINT_INTERVAL) == 0) {
+ NV_PRINTF(LEVEL_ERROR, "XXXMT: NVRM debugging - F_SEMAPHORE_RELEASE = %llu\n", counter);
+ }
+
status = semaphoreFillGPUVA(pGpu,
pDevice,
vaSpace,
@@ -165,6 +177,11 @@ NV_STATUS dispswReleaseSemaphoreAndNotifierFill
}
else if (flags & F_NOTIFIER_FILL)
{
+ static NvU64 counter;
+ if ((++counter % PRINT_INTERVAL) == 0) {
+ NV_PRINTF(LEVEL_ERROR, "XXXMT: NVRM debugging - F_NOTIFIER_FILL = %llu\n", counter);
+ }
+
status = notifyFillNotifierGPUVA(pGpu,
pDevice,
vaSpace,
@@ -175,5 +192,11 @@ NV_STATUS dispswReleaseSemaphoreAndNotifierFill
NV9072_NOTIFIERS_NOTIFY_ON_VBLANK /* Index */);
return status;
}
+ else {
+ static NvU64 counter;
+ if ((++counter % PRINT_INTERVAL) == 0) {
+ NV_PRINTF(LEVEL_ERROR, "XXXMT: NVRM debugging - ??? 0x%08x = %llu\n", flags, counter);
+ }
+ }
return NV9072_NOTIFICATION_STATUS_DONE_SUCCESS;
}
--
2.45.2
--- a/nvidia-drm/nvidia-drm-linux.c
+++ b/nvidia-drm/nvidia-drm-linux.c
@@ -31,13 +31,13 @@
MODULE_PARM_DESC(
modeset,
- "Enable atomic kernel modesetting (1 = enable, 0 = disable (default))");
+ "Enable atomic kernel modesetting (1 = enable (default), 0 = disable)");
module_param_named(modeset, nv_drm_modeset_module_param, bool, 0400);
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
MODULE_PARM_DESC(
fbdev,
- "Create a framebuffer device (1 = enable, 0 = disable (default)) (EXPERIMENTAL)");
+ "Create a framebuffer device (1 = enable (default), 0 = disable) (EXPERIMENTAL)");
module_param_named(fbdev, nv_drm_fbdev_module_param, bool, 0400);
#endif
--- a/nvidia-drm/nvidia-drm-os-interface.c
+++ b/nvidia-drm/nvidia-drm-os-interface.c
@@ -41,8 +41,8 @@
#include <drm/drmP.h>
#endif
-bool nv_drm_modeset_module_param = false;
-bool nv_drm_fbdev_module_param = false;
+bool nv_drm_modeset_module_param = true;
+bool nv_drm_fbdev_module_param = true;
void *nv_drm_calloc(size_t nmemb, size_t size)
{
--- a/src/nvidia-modeset/Makefile
+++ b/src/nvidia-modeset/Makefile
@@ -142,6 +142,7 @@ ifeq ($(TARGET_ARCH),x86_64)
CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -fno-jump-tables)
CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -mindirect-branch=thunk-extern)
CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -mindirect-branch-register)
+ CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -mharden-sls=all)
endif
CFLAGS += $(CONDITIONAL_CFLAGS)

View File

@ -1,258 +0,0 @@
From 498e88ae626be4f523063c8a7027b4b02eca31d2 Mon Sep 17 00:00:00 2001
From: GloriousEggroll <gloriouseggroll@gmail.com>
Date: Tue, 17 Jan 2023 12:08:46 -0700
Subject: [PATCH] Allow to set custom USB pollrate for specific devices like
so: usbcore.interrupt_interval_override=045e:00db:16,1bcf:0005:1
---
.../admin-guide/kernel-parameters.txt | 8 +
drivers/usb/core/config.c | 170 +++++++++++++++++-
drivers/usb/core/usb.c | 1 +
drivers/usb/core/usb.h | 1 +
4 files changed, 179 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index dbd26fde4..c9b8b80af 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -6552,6 +6552,14 @@
delay after resetting its port);
Example: quirks=0781:5580:bk,0a5c:5834:gij
+ usbcore.interrupt_interval_override=
+ [USB] A list of USB devices for which a different polling
+ interval than the default shall be used on all interrupt-type
+ endpoints. The format is VendorID:ProductID:interval, with
+ the vendor and product ids specified hexadecimally, and the
+ interval decimally in milliseconds.
+ Example: interrupt_interval_override=045e:00db:16,1bcf:0005:2
+
usbhid.mousepoll=
[USBHID] The interval which mice are to be polled at.
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 48bc8a481..84bd550ad 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -19,6 +19,149 @@
#define USB_MAXCONFIG 8 /* Arbitrary limit */
+/* A struct associated with the interrupt_interval_override module parameter, representing
+ an user's choice to force a specific interrupt interval upon all interrupt endpoints of
+ a certain device. */
+struct interrupt_interval_override {
+ /* The vendor ID of the device of which the interrupt interval shall be overridden */
+ u16 vendor;
+ /* The product ID of the device of which the interrupt interval shall be overridden */
+ u16 product;
+ /* The new interval measured in milliseconds that shall be given to all endpoints of type interrupt on said device */
+ unsigned int interval;
+};
+
+static DEFINE_MUTEX(interrupt_interval_override_mutex);
+static char interrupt_interval_override_param[128];
+static struct interrupt_interval_override *interrupt_interval_override_list = NULL;
+static size_t interrupt_interval_override_count = 0;
+
+static int interrupt_interval_override_param_set(const char *value, const struct kernel_param *kp)
+{
+ const char *p;
+ unsigned short vendor, product;
+ unsigned int interval;
+ struct interrupt_interval_override* list;
+ struct interrupt_interval_override param;
+ size_t count, max_count, i, len;
+ int err, res;
+
+ mutex_lock(&interrupt_interval_override_mutex);
+
+ if (!value || !*value) {
+ /* Unset the current variable. */
+ kfree(interrupt_interval_override_list);
+ interrupt_interval_override_list = NULL;
+ interrupt_interval_override_count = 0;
+ param_set_copystring(value, kp); /* Does not fail: the empty string is short enough to fit. */
+ mutex_unlock(&interrupt_interval_override_mutex);
+ return 0;
+ }
+
+ /* Compute an upper bound on the amount of entries we need. */
+ for (max_count = 1, i = 0; value[i]; i++) {
+ if (value[i] == ',')
+ max_count++;
+ }
+
+ /* Ensure we can allocate enough memory before overwriting the global variables. */
+ list = kcalloc(max_count,
+ sizeof(struct interrupt_interval_override),
+ GFP_KERNEL);
+
+ if (!list) {
+ mutex_unlock(&interrupt_interval_override_mutex);
+ return -ENOMEM;
+ }
+
+ err = param_set_copystring(value, kp);
+ if (err) {
+ kfree(list);
+ mutex_unlock(&interrupt_interval_override_mutex);
+ return err;
+ }
+
+ /* Parse the parameter. Example of a valid parameter: 045e:00db:16,1bcf:0005:2 */
+ for (count = 0, p = (const char*)value; p && *p;) {
+ res = sscanf(p, "%hx:%hx:%d%zn", &vendor, &product, &interval, &len);
+
+ /* Check whether all variables (vendor, product, interval, len) were assigned.
+ %zn does not increase the assignment count, so we need to check for value 3 instead of 4.
+ %zn does not consume input either, so setting len shouldn't fail if interval has been properly set. */
+ if (res != 3) {
+ pr_warn("Error while parsing USB interrupt interval override parameter %s.\n", value);
+ break;
+ }
+
+ param.vendor = (u16)vendor;
+ param.product = (u16)product;
+ param.interval = interval;
+ list[count++] = param;
+
+ p += len;
+ if (*p == ',' && *(p+1) != '\0') {
+ p++;
+ continue;
+ } else if(*p == '\0' || (*p == '\n' && *(p+1) == '\0')) {
+ break;
+ } else {
+ pr_warn("Error while parsing USB interrupt interval override parameter %s.\n", value);
+ break;
+ }
+ }
+
+ /* Overwrite the global variables with the local ones. */
+ kfree(interrupt_interval_override_list);
+ interrupt_interval_override_list = list;
+ interrupt_interval_override_count = count;
+ mutex_unlock(&interrupt_interval_override_mutex);
+ return 0;
+}
+
+static const struct kernel_param_ops interrupt_interval_override_param_ops = {
+ .set = interrupt_interval_override_param_set,
+ .get = param_get_string,
+};
+
+static struct kparam_string interrupt_interval_override_param_string = {
+ .maxlen = sizeof(interrupt_interval_override_param),
+ .string = interrupt_interval_override_param,
+};
+
+device_param_cb(interrupt_interval_override,
+ &interrupt_interval_override_param_ops,
+ &interrupt_interval_override_param_string,
+ 0644);
+MODULE_PARM_DESC(interrupt_interval_override,
+ "Override the polling interval of all interrupt-type endpoints of a specific USB"
+ " device by specifying interrupt_interval_override=vendorID:productID:interval.");
+
+/* Given an USB device, this checks whether the user has specified they want to override the interrupt
+ polling interval on all interrupt-type endpoints of said device.
+
+ This function returns the user-desired amount of milliseconds between interrupts on said endpoint.
+ If this function returns zero, the device-requested interrupt interval should be used. */
+static unsigned int usb_check_interrupt_interval_override(struct usb_device* udev)
+{
+ size_t i;
+ unsigned int res;
+ u16 vendor = le16_to_cpu(udev->descriptor.idVendor);
+ u16 product = le16_to_cpu(udev->descriptor.idProduct);
+
+ mutex_lock(&interrupt_interval_override_mutex);
+ for (i = 0; i < interrupt_interval_override_count; i++) {
+ if (interrupt_interval_override_list[i].vendor == vendor
+ && interrupt_interval_override_list[i].product == product) {
+
+ res = interrupt_interval_override_list[i].interval;
+ mutex_unlock(&interrupt_interval_override_mutex);
+ return res;
+ }
+ }
+ mutex_unlock(&interrupt_interval_override_mutex);
+ return 0;
+}
+
static inline const char *plural(int n)
{
return (n == 1 ? "" : "s");
@@ -261,7 +404,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
struct usb_endpoint_descriptor *d;
struct usb_host_endpoint *endpoint;
int n, i, j, retval;
- unsigned int maxp;
+ unsigned int maxp, ival;
const unsigned short *maxpacket_maxes;
d = (struct usb_endpoint_descriptor *) buffer;
@@ -386,6 +529,23 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
endpoint->desc.bInterval = n;
}
+ /* Override the interrupt polling interval if a module parameter tells us to do so. */
+ if (usb_endpoint_xfer_int(d)) {
+ ival = usb_check_interrupt_interval_override(udev);
+ if (ival > 0) {
+ switch (udev->speed) {
+ case USB_SPEED_SUPER_PLUS:
+ case USB_SPEED_SUPER:
+ case USB_SPEED_HIGH:
+ endpoint->desc.bInterval = fls(ival) + 3;
+ break;
+ default: /* USB_SPEED_FULL or _LOW */
+ endpoint->desc.bInterval = ival;
+ break;
+ }
+ }
+ }
+
/* Some buggy low-speed devices have Bulk endpoints, which is
* explicitly forbidden by the USB spec. In an attempt to make
* them usable, we will try treating them as Interrupt endpoints.
@@ -1092,3 +1252,11 @@ int usb_get_bos_descriptor(struct usb_device *dev)
usb_release_bos_descriptor(dev);
return ret;
}
+
+void usb_release_interrupt_interval_override_list(void)
+{
+ mutex_lock(&interrupt_interval_override_mutex);
+ kfree(interrupt_interval_override_list);
+ interrupt_interval_override_list = NULL;
+ mutex_unlock(&interrupt_interval_override_mutex);
+}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 11b15d7b3..ec52c6322 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1066,6 +1066,7 @@ static void __exit usb_exit(void)
return;
usb_release_quirk_list();
+ usb_release_interrupt_interval_override_list();
usb_deregister_device_driver(&usb_generic_driver);
usb_major_cleanup();
usb_deregister(&usbfs_driver);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 82538daac..b6faa897c 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -37,6 +37,7 @@ extern void usb_authorize_interface(struct usb_interface *);
extern void usb_detect_quirks(struct usb_device *udev);
extern void usb_detect_interface_quirks(struct usb_device *udev);
extern void usb_release_quirk_list(void);
+extern void usb_release_interrupt_interval_override_list(void);
extern bool usb_endpoint_is_ignored(struct usb_device *udev,
struct usb_host_interface *intf,
struct usb_endpoint_descriptor *epd);
--
2.39.0

View File

@ -1,34 +0,0 @@
From 4b4ce124699c160925e5fdeb147a78f79d38351f Mon Sep 17 00:00:00 2001
From: Simon May <simon.may@protonmail.ch>
Date: Sun, 19 Sep 2021 23:45:59 +0200
Subject: [PATCH] Revert "PCI: Add a REBAR size quirk for Sapphire RX 5600 XT
Pulse"
This reverts commit 907830b0fc9e374d00f3c83de5e426157b482c01.
---
drivers/pci/pci.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index a607f277c..3174fa871 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3755,14 +3755,8 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
return 0;
pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap);
- cap = FIELD_GET(PCI_REBAR_CAP_SIZES, cap);
- /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */
- if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f &&
- bar == 0 && cap == 0x700)
- return 0x3f00;
-
- return cap;
+ return (cap & PCI_REBAR_CAP_SIZES) >> 4;
}
EXPORT_SYMBOL(pci_rebar_get_possible_sizes);
--
2.30.2

View File

@ -1,108 +0,0 @@
From 7d86ca8db51f6b75b5c1470d6294c6f24221f560 Mon Sep 17 00:00:00 2001
From: GloriousEggroll <gloriouseggroll@gmail.com>
Date: Mon, 30 Oct 2023 22:36:19 -0600
Subject: [PATCH] Revert "nvme-pci: drop redundant
pci_enable_pcie_error_reporting()"
This reverts commits:
1ad11eafc63ac16e667853bee4273879226d2d1b
7ec4b34be4234599cf1241ef807cdb7c3636f6fe
69b264df8a412820e98867dbab871c6526c5e5aa
---
drivers/nvme/host/pci.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 3f0c9ee09a12..bc11bfe6f87a 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -5,6 +5,7 @@
*/
#include <linux/acpi.h>
+#include <linux/aer.h>
#include <linux/async.h>
#include <linux/blkdev.h>
#include <linux/blk-mq.h>
@@ -2537,6 +2538,7 @@ static int nvme_pci_enable(struct nvme_dev *dev)
nvme_map_cmb(dev);
+ pci_enable_pcie_error_reporting(pdev);
pci_save_state(pdev);
result = nvme_pci_configure_admin_queue(dev);
@@ -2601,8 +2603,10 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
nvme_suspend_io_queues(dev);
nvme_suspend_queue(dev, 0);
pci_free_irq_vectors(pdev);
- if (pci_is_enabled(pdev))
+ if (pci_is_enabled(pdev)) {
+ pci_disable_pcie_error_reporting(pdev);
pci_disable_device(pdev);
+ }
nvme_reap_pending_cqes(dev);
nvme_cancel_tagset(&dev->ctrl);
--
2.41.0
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 29cc10220..94ce49a5f 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -41,9 +41,20 @@ struct aer_capability_regs {
};
#if defined(CONFIG_PCIEAER)
+/* PCIe port driver needs this function to enable AER */
+int pci_enable_pcie_error_reporting(struct pci_dev *dev);
+int pci_disable_pcie_error_reporting(struct pci_dev *dev);
int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
int pcie_aer_is_native(struct pci_dev *dev);
#else
+static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
+{
+ return -EINVAL;
+}
+static inline int pci_disable_pcie_error_reporting(struct pci_dev *dev)
+{
+ return -EINVAL;
+}
static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
{
return -EINVAL;
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index 9c8fd69ae..0dc7be481 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -231,7 +231,7 @@ int pcie_aer_is_native(struct pci_dev *dev)
}
EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, CXL);
-static int pci_enable_pcie_error_reporting(struct pci_dev *dev)
+int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
int rc;
@@ -241,6 +241,19 @@ static int pci_enable_pcie_error_reporting(struct pci_dev *dev)
rc = pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
return pcibios_err_to_errno(rc);
}
+EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
+
+int pci_disable_pcie_error_reporting(struct pci_dev *dev)
+{
+ int rc;
+
+ if (!pcie_aer_is_native(dev))
+ return -EIO;
+
+ rc = pcie_capability_clear_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
+ return pcibios_err_to_errno(rc);
+}
+EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
{

View File

@ -1,25 +0,0 @@
From 9179080ffaaf1d438db6e0a5a37bdf8dafe233a6 Mon Sep 17 00:00:00 2001
From: Thomas Crider <gloriouseggroll@gmail.com>
Date: Mon, 27 Nov 2023 16:13:13 -0500
Subject: [PATCH] Set amdgpu.ppfeaturemask=0xffffffff as default
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index e06009966..4e791eb8f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -158,7 +158,7 @@ bool enforce_isolation;
* OverDrive(bit 14) disabled by default
* GFX DCS(bit 19) disabled by default
*/
-uint amdgpu_pp_feature_mask = 0xfff7bfff;
+uint amdgpu_pp_feature_mask = 0xffffffff;
uint amdgpu_force_long_training;
int amdgpu_lbpw = -1;
int amdgpu_compute_multipipe = -1;
--
2.43.0

View File

@ -1,125 +0,0 @@
Processors based on the Zen microarchitecture support IOPORT based deeper
C-states. The idle driver reads the acpi_gbl_FADT.xpm_timer_block.address
in the IOPORT based C-state exit path which is claimed to be a
"Dummy wait op" and has been around since ACPI introduction to Linux
dating back to Andy Grover's Mar 14, 2002 posting [1].
The comment above the dummy operation was elaborated by Andreas Mohr back
in 2006 in commit b488f02156d3d ("ACPI: restore comment justifying 'extra'
P_LVLx access") [2] where the commit log claims:
"this dummy read was about: STPCLK# doesn't get asserted in time on
(some) chipsets, which is why we need to have a dummy I/O read to delay
further instruction processing until the CPU is fully stopped."
However, sampling certain workloads with IBS on AMD Zen3 system shows
that a significant amount of time is spent in the dummy op, which
incorrectly gets accounted as C-State residency. A large C-State
residency value can prime the cpuidle governor to recommend a deeper
C-State during the subsequent idle instances, starting a vicious cycle,
leading to performance degradation on workloads that rapidly switch
between busy and idle phases.
One such workload is tbench where a massive performance degradation can
be observed during certain runs. Following are some statistics gathered
by running tbench with 128 clients, on a dual socket (2 x 64C/128T) Zen3
system with the baseline kernel, baseline kernel keeping C2 disabled,
and baseline kernel with this patch applied keeping C2 enabled:
baseline kernel was tip:sched/core at
commit f3dd3f674555 ("sched: Remove the limitation of WF_ON_CPU on
wakelist if wakee cpu is idle")
Kernel : baseline baseline + C2 disabled baseline + patch
Min (MB/s) : 2215.06 33072.10 (+1393.05%) 33016.10 (+1390.52%)
Max (MB/s) : 32938.80 34399.10 34774.50
Median (MB/s) : 32191.80 33476.60 33805.70
AMean (MB/s) : 22448.55 33649.27 (+49.89%) 33865.43 (+50.85%)
AMean Stddev : 17526.70 680.14 880.72
AMean CoefVar : 78.07% 2.02% 2.60%
The data shows there are edge cases that can cause massive regressions
in case of tbench. Profiling the bad runs with IBS shows a significant
amount of time being spent in acpi_idle_do_entry method:
Overhead Command Shared Object Symbol
74.76% swapper [kernel.kallsyms] [k] acpi_idle_do_entry
0.71% tbench [kernel.kallsyms] [k] update_sd_lb_stats.constprop.0
0.69% tbench_srv [kernel.kallsyms] [k] update_sd_lb_stats.constprop.0
0.49% swapper [kernel.kallsyms] [k] psi_group_change
...
Annotation of acpi_idle_do_entry method reveals almost all the time in
acpi_idle_do_entry is spent on the port I/O in wait_for_freeze():
0.14 │ in (%dx),%al # <------ First "in" corresponding to inb(cx->address)
0.51 │ mov 0x144d64d(%rip),%rax
0.00 │ test $0x80000000,%eax
│ ↓ jne 62 # <------ Skip if running in guest
0.00 │ mov 0x19800c3(%rip),%rdx
99.33 │ in (%dx),%eax # <------ Second "in" corresponding to inl(acpi_gbl_FADT.xpm_timer_block.address)
0.00 │62: mov -0x8(%rbp),%r12
0.00 │ leave
0.00 │ ← ret
This overhead is reflected in the C2 residency on the test system where
C2 is an IOPORT based C-State. The total C-state residency reported by
"cpupower idle-info" on CPU0 for good and bad case over the 80s tbench
run is as follows (all numbers are in microseconds):
Good Run Bad Run
(Baseline)
POLL: 43338 6231 (-85.62%)
C1 (MWAIT Based): 23576156 363861 (-98.45%)
C2 (IOPORT Based): 10781218 77027280 (+614.45%)
The larger residency value in bad case leads to the system recommending
C2 state again for subsequent idle instances. The pattern lasts till the
end of the tbench run. Following is the breakdown of "entry_method"
passed to acpi_idle_do_entry during good run and bad run:
Good Run Bad Run
(Baseline)
Number of times acpi_idle_do_entry was called: 6149573 6149050 (-0.01%)
|-> Number of times entry_method was "ACPI_CSTATE_FFH": 6141494 88144 (-98.56%)
|-> Number of times entry_method was "ACPI_CSTATE_HALT": 0 0 (+0.00%)
|-> Number of times entry_method was "ACPI_CSTATE_SYSTEMIO": 8079 6060906 (+74920.49%)
For processors based on the Zen microarchitecture, this dummy wait op is
unnecessary and can be skipped when choosing IOPORT based C-States to
avoid polluting the C-state residency information.
Link: https://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux-fullhistory.git/commit/?id=972c16130d9dc182cedcdd408408d9eacc7d6a2d [1]
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b488f02156d3deb08f5ad7816d565c370a8cc6f1 [2]
Suggested-by: Calvin Ong <calvin.ong@amd.com>
Cc: stable@vger.kernel.org
Cc: regressions@lists.linux.dev
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
drivers/acpi/processor_idle.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 16a1663d02d4..18850aa2b79b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -529,9 +529,11 @@ static __cpuidle void io_idle(unsigned long addr)
inb(addr);
#ifdef CONFIG_X86
- /* No delay is needed if we are in guest */
- if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
- return;
+ /*
+ * No delay is needed if we are in guest or on a processor
+ * based on the Zen microarchitecture.
+ */
+ if (boot_cpu_has(X86_FEATURE_HYPERVISOR) || boot_cpu_has(X86_FEATURE_ZEN))
/*
* Modern (>=Nehalem) Intel systems use ACPI via intel_idle,
* not this code. Assume that any Intel systems using this
--
2.25.1

View File

@ -1,506 +0,0 @@
From 3f14226e2e90dba5d72c106da29e1876eb7b88ff Mon Sep 17 00:00:00 2001
From: Denis <benato.denis96@gmail.com>
Date: Thu, 28 Sep 2023 03:40:53 +0200
Subject: [PATCH] add acpi_call
---
drivers/platform/x86/Kconfig | 5 +
drivers/platform/x86/Makefile | 4 +
drivers/platform/x86/acpi_call.c | 449 +++++++++++++++++++++++++++++++
3 files changed, 458 insertions(+)
create mode 100644 drivers/platform/x86/acpi_call.c
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 49c2c4cd8d00..fde791e51261 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -170,6 +170,11 @@ config ACER_WIRELESS
If you choose to compile this driver as a module the module will be
called acer-wireless.
+config ACPI_CALL
+ tristate "acpi_call module"
+ help
+ This embeds acpi_call module into the kernel
+
config ACER_WMI
tristate "Acer WMI Laptop Extras"
depends on BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 52dfdf574ac2..1e434fcb8273 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -4,10 +4,14 @@
# x86 Platform-Specific Drivers
#
+# ACPI calls
+
# Windows Management Interface
obj-$(CONFIG_ACPI_WMI) += wmi.o
obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o
+obj-$(CONFIG_ACPI_CALL) += acpi_call.o
+
# WMI drivers
obj-$(CONFIG_HUAWEI_WMI) += huawei-wmi.o
obj-$(CONFIG_MXM_WMI) += mxm-wmi.o
diff --git a/drivers/platform/x86/acpi_call.c b/drivers/platform/x86/acpi_call.c
new file mode 100644
index 000000000000..d7bc238e16da
--- /dev/null
+++ b/drivers/platform/x86/acpi_call.c
@@ -0,0 +1,449 @@
+/* Copyright (c) 2010: Michal Kottman */
+
+#define BUILDING_ACPICA
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
+#include <asm/uaccess.h>
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+#include <linux/acpi.h>
+#else
+#include <acpi/acpi.h>
+#endif
+
+MODULE_LICENSE("GPL");
+
+/* Uncomment the following line to enable debug messages */
+/*
+#define DEBUG
+*/
+
+#define BUFFER_SIZE 4096
+#define INPUT_BUFFER_SIZE (2 * BUFFER_SIZE)
+#define MAX_ACPI_ARGS 16
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+#define HAVE_PROC_CREATE
+#endif
+
+extern struct proc_dir_entry *acpi_root_dir;
+
+static char input_buffer[INPUT_BUFFER_SIZE];
+static char result_buffer[BUFFER_SIZE];
+static char not_called_message[11] = "not called";
+
+static u8 temporary_buffer[BUFFER_SIZE];
+
+static size_t get_avail_bytes(void) {
+ return BUFFER_SIZE - strlen(result_buffer);
+}
+static char *get_buffer_end(void) {
+ return result_buffer + strlen(result_buffer);
+}
+
+/** Appends the contents of an acpi_object to the result buffer
+@param result An acpi object holding result data
+@returns 0 if the result could fully be saved, a higher value otherwise
+*/
+static int acpi_result_to_string(union acpi_object *result) {
+ if (result->type == ACPI_TYPE_INTEGER) {
+ snprintf(get_buffer_end(), get_avail_bytes(),
+ "0x%x", (int)result->integer.value);
+ } else if (result->type == ACPI_TYPE_STRING) {
+ snprintf(get_buffer_end(), get_avail_bytes(),
+ "\"%*s\"", result->string.length, result->string.pointer);
+ } else if (result->type == ACPI_TYPE_BUFFER) {
+ int i;
+ // do not store more than data if it does not fit. The first element is
+ // just 4 chars, but there is also two bytes from the curly brackets
+ int show_values = min((size_t)result->buffer.length, get_avail_bytes() / 6);
+
+ snprintf(get_buffer_end(), get_avail_bytes(), "{");
+ for (i = 0; i < show_values; i++)
+ sprintf(get_buffer_end(),
+ i == 0 ? "0x%02x" : ", 0x%02x", result->buffer.pointer[i]);
+
+ if (result->buffer.length > show_values) {
+ // if data was truncated, show a trailing comma if there is space
+ snprintf(get_buffer_end(), get_avail_bytes(), ",");
+ return 1;
+ } else {
+ // in case show_values == 0, but the buffer is too small to hold
+ // more values (i.e. the buffer cannot have anything more than "{")
+ snprintf(get_buffer_end(), get_avail_bytes(), "}");
+ }
+ } else if (result->type == ACPI_TYPE_PACKAGE) {
+ int i;
+ snprintf(get_buffer_end(), get_avail_bytes(), "[");
+ for (i=0; i<result->package.count; i++) {
+ if (i > 0)
+ snprintf(get_buffer_end(), get_avail_bytes(), ", ");
+
+ // abort if there is no more space available
+ if (!get_avail_bytes() || acpi_result_to_string(&result->package.elements[i]))
+ return 1;
+ }
+ snprintf(get_buffer_end(), get_avail_bytes(), "]");
+ } else {
+ snprintf(get_buffer_end(), get_avail_bytes(),
+ "Object type 0x%x\n", result->type);
+ }
+
+ // return 0 if there are still bytes available, 1 otherwise
+ return !get_avail_bytes();
+}
+
+/**
+@param method The full name of ACPI method to call
+@param argc The number of parameters
+@param argv A pre-allocated array of arguments of type acpi_object
+*/
+static void do_acpi_call(const char * method, int argc, union acpi_object *argv)
+{
+ acpi_status status;
+ acpi_handle handle;
+ struct acpi_object_list arg;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+#ifdef DEBUG
+ printk(KERN_INFO "acpi_call: Calling %s\n", method);
+#endif
+
+ // get the handle of the method, must be a fully qualified path
+ status = acpi_get_handle(NULL, (acpi_string) method, &handle);
+
+ if (ACPI_FAILURE(status))
+ {
+ snprintf(result_buffer, BUFFER_SIZE, "Error: %s", acpi_format_exception(status));
+ printk(KERN_ERR "acpi_call: Cannot get handle: %s\n", result_buffer);
+ return;
+ }
+
+ // prepare parameters
+ arg.count = argc;
+ arg.pointer = argv;
+
+ // call the method
+ status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
+ if (ACPI_FAILURE(status))
+ {
+ snprintf(result_buffer, BUFFER_SIZE, "Error: %s", acpi_format_exception(status));
+ printk(KERN_ERR "acpi_call: Method call failed: %s\n", result_buffer);
+ return;
+ }
+
+ // reset the result buffer
+ *result_buffer = '\0';
+ acpi_result_to_string(buffer.pointer);
+ kfree(buffer.pointer);
+
+#ifdef DEBUG
+ printk(KERN_INFO "acpi_call: Call successful: %s\n", result_buffer);
+#endif
+}
+
+/** Decodes 2 hex characters to an u8 int
+*/
+u8 decodeHex(char *hex) {
+ char buf[3] = { hex[0], hex[1], 0};
+ return (u8) simple_strtoul(buf, NULL, 16);
+}
+
+/** Parses method name and arguments
+@param input Input string to be parsed. Modified in the process.
+@param nargs Set to number of arguments parsed (output)
+@param args
+*/
+static char *parse_acpi_args(char *input, int *nargs, union acpi_object **args)
+{
+ char *s = input;
+ int i;
+
+ *nargs = 0;
+ *args = NULL;
+
+ // the method name is separated from the arguments by a space
+ while (*s && *s != ' ')
+ s++;
+ // if no space is found, return 0 arguments
+ if (*s == 0)
+ return input;
+
+ *args = (union acpi_object *) kmalloc(MAX_ACPI_ARGS * sizeof(union acpi_object), GFP_KERNEL);
+ if (!*args) {
+ printk(KERN_ERR "acpi_call: unable to allocate buffer\n");
+ return NULL;
+ }
+
+ while (*s) {
+ if (*s == ' ') {
+ if (*nargs == 0)
+ *s = 0; // change first space to nul
+ ++ *nargs;
+ ++ s;
+ } else {
+ union acpi_object *arg = (*args) + (*nargs - 1);
+ if (*s == '"') {
+ // decode string
+ arg->type = ACPI_TYPE_STRING;
+ arg->string.pointer = ++s;
+ arg->string.length = 0;
+ while (*s && *s++ != '"')
+ arg->string.length ++;
+ // skip the last "
+ if (*s == '"')
+ ++s;
+ } else if (*s == 'b') {
+ // decode buffer - bXXXX
+ char *p = ++s;
+ int len = 0, i;
+ u8 *buf = NULL;
+
+ while (*p && *p!=' ')
+ p++;
+
+ len = p - s;
+ if (len % 2 == 1) {
+ printk(KERN_ERR "acpi_call: buffer arg%d is not multiple of 8 bits\n", *nargs);
+ --*nargs;
+ goto err;
+ }
+ len /= 2;
+
+ buf = (u8*) kmalloc(len, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "acpi_call: unable to allocate buffer\n");
+ --*nargs;
+ goto err;
+ }
+ for (i=0; i<len; i++) {
+ buf[i] = decodeHex(s + i*2);
+ }
+ s = p;
+
+ arg->type = ACPI_TYPE_BUFFER;
+ arg->buffer.pointer = buf;
+ arg->buffer.length = len;
+ } else if (*s == '{') {
+ // decode buffer - { b1, b2 ...}
+ u8 *buf = temporary_buffer;
+ arg->type = ACPI_TYPE_BUFFER;
+ arg->buffer.pointer = buf;
+ arg->buffer.length = 0;
+ while (*s && *s++ != '}') {
+ if (buf >= temporary_buffer + sizeof(temporary_buffer)) {
+ printk(KERN_ERR "acpi_call: buffer arg%d is truncated because the buffer is full\n", *nargs);
+ // clear remaining arguments
+ while (*s && *s != '}')
+ ++s;
+ break;
+ }
+ else if (*s >= '0' && *s <= '9') {
+ // decode integer into buffer
+ arg->buffer.length ++;
+ if (s[0] == '0' && s[1] == 'x')
+ *buf++ = simple_strtol(s+2, 0, 16);
+ else
+ *buf++ = simple_strtol(s, 0, 10);
+ }
+ // skip until space or comma or '}'
+ while (*s && *s != ' ' && *s != ',' && *s != '}')
+ ++s;
+ }
+ // store the result in new allocated buffer
+ buf = (u8*) kmalloc(arg->buffer.length, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "acpi_call: unable to allocate buffer\n");
+ --*nargs;
+ goto err;
+ }
+ memcpy(buf, temporary_buffer, arg->buffer.length);
+ arg->buffer.pointer = buf;
+ } else {
+ // decode integer, N or 0xN
+ arg->type = ACPI_TYPE_INTEGER;
+ if (s[0] == '0' && s[1] == 'x') {
+ arg->integer.value = simple_strtol(s+2, 0, 16);
+ } else {
+ arg->integer.value = simple_strtol(s, 0, 10);
+ }
+ while (*s && *s != ' ') {
+ ++s;
+ }
+ }
+ }
+ }
+
+ return input;
+
+err:
+ for (i=0; i<*nargs; i++)
+ if ((*args)[i].type == ACPI_TYPE_BUFFER && (*args)[i].buffer.pointer)
+ kfree((*args)[i].buffer.pointer);
+ kfree(*args);
+ return NULL;
+}
+
+/** procfs write callback. Called when writing into /proc/acpi/call.
+*/
+#ifdef HAVE_PROC_CREATE
+static ssize_t acpi_proc_write( struct file *filp, const char __user *buff,
+ size_t len, loff_t *data )
+#else
+static int acpi_proc_write( struct file *filp, const char __user *buff,
+ unsigned long len, void *data )
+#endif
+{
+ union acpi_object *args;
+ int nargs, i;
+ char *method;
+
+ memset(input_buffer, 0, INPUT_BUFFER_SIZE);
+ if (len > sizeof(input_buffer) - 1) {
+#ifdef HAVE_PROC_CREATE
+ printk(KERN_ERR "acpi_call: Input too long! (%zu)\n", len);
+#else
+ printk(KERN_ERR "acpi_call: Input too long! (%lu)\n", len);
+#endif
+ return -ENOSPC;
+ }
+
+ if (copy_from_user( input_buffer, buff, len )) {
+ return -EFAULT;
+ }
+ input_buffer[len] = '\0';
+ if (input_buffer[len-1] == '\n')
+ input_buffer[len-1] = '\0';
+
+ method = parse_acpi_args(input_buffer, &nargs, &args);
+ if (method) {
+ do_acpi_call(method, nargs, args);
+ if (args) {
+ for (i=0; i<nargs; i++)
+ if (args[i].type == ACPI_TYPE_BUFFER)
+ kfree(args[i].buffer.pointer);
+ }
+ }
+ if (args)
+ kfree(args);
+
+ return len;
+}
+
+/** procfs 'call' read callback. Called when reading the content of /proc/acpi/call.
+Returns the last call status:
+- "not called" when no call was previously issued
+- "failed" if the call failed
+- "ok" if the call succeeded
+*/
+#ifdef HAVE_PROC_CREATE
+static ssize_t acpi_proc_read( struct file *filp, char __user *buff,
+ size_t count, loff_t *off )
+{
+ ssize_t ret;
+ int len = strlen(result_buffer);
+
+ if(len == 0) {
+ ret = simple_read_from_buffer(buff, count, off, not_called_message, strlen(not_called_message) + 1);
+ } else if(len + 1 > count) {
+ // user buffer is too small
+ ret = 0;
+ } else if(*off == len + 1) {
+ // we're done
+ ret = 0;
+ result_buffer[0] = '\0';
+ } else {
+ // output the current result buffer
+ ret = simple_read_from_buffer(buff, count, off, result_buffer, len + 1);
+ *off = ret;
+ }
+
+ return ret;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
+static struct proc_ops proc_acpi_operations = {
+ .proc_read = acpi_proc_read,
+ .proc_write = acpi_proc_write,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
+ .proc_lseek = default_llseek,
+#endif
+};
+#else
+static struct file_operations proc_acpi_operations = {
+ .owner = THIS_MODULE,
+ .read = acpi_proc_read,
+ .write = acpi_proc_write,
+};
+#endif
+
+#else
+static int acpi_proc_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ if (off > 0) {
+ *eof = 1;
+ return 0;
+ }
+
+ // output the current result buffer
+ len = strlen(result_buffer);
+ memcpy(page, result_buffer, len + 1);
+
+ // initialize the result buffer for later
+ strcpy(result_buffer, "not called");
+
+ return len;
+}
+#endif
+
+/** module initialization function */
+static int __init init_acpi_call(void)
+{
+#ifdef HAVE_PROC_CREATE
+ struct proc_dir_entry *acpi_entry = proc_create("call",
+ 0660,
+ acpi_root_dir,
+ &proc_acpi_operations);
+#else
+ struct proc_dir_entry *acpi_entry = create_proc_entry("call", 0660, acpi_root_dir);
+#endif
+
+ strcpy(result_buffer, "not called");
+
+ if (acpi_entry == NULL) {
+ printk(KERN_ERR "acpi_call: Couldn't create proc entry\n");
+ return -ENOMEM;
+ }
+
+#ifndef HAVE_PROC_CREATE
+ acpi_entry->write_proc = acpi_proc_write;
+ acpi_entry->read_proc = acpi_proc_read;
+#endif
+
+#ifdef DEBUG
+ printk(KERN_INFO "acpi_call: Module loaded successfully\n");
+#endif
+
+ return 0;
+}
+
+static void __exit unload_acpi_call(void)
+{
+ remove_proc_entry("call", acpi_root_dir);
+
+#ifdef DEBUG
+ printk(KERN_INFO "acpi_call: Module unloaded successfully\n");
+#endif
+}
+
+module_init(init_acpi_call);
+module_exit(unload_acpi_call);
\ No newline at end of file
--
2.42.0

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan200101 <sentrycraft123@gmail.com>
Date: Mon, 14 Nov 2022 20:13:53 +0100
Subject: [PATCH] drm/i915/quirks: disable async flipping on specific devices
Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
---
drivers/gpu/drm/i915/display/intel_quirks.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c
index a280448df771..1596114dd9ae 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -14,6 +14,12 @@ static void intel_set_quirk(struct drm_i915_private *i915, enum intel_quirk_id q
i915->display.quirks.mask |= BIT(quirk);
}
+static void quirk_async_page_flips_force_disable(struct drm_i915_private *i915)
+{
+ i915->drm.mode_config.async_page_flip = false;
+ drm_info(&i915->drm, "applying async flip disable quirk\n");
+}
+
/*
* Some machines (Lenovo U160) do not work with SSC on LVDS for some reason
*/
@@ -136,6 +142,20 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = {
},
.hook = quirk_no_pps_backlight_power_hook,
},
+ {
+ .dmi_id_list = &(const struct dmi_system_id[]) {
+ {
+ .callback = NULL,
+ .ident = "ASUS TUF DASH F15",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ASUS TUF Dash F15 FX516PC_FX516PC"),
+ },
+ },
+ { }
+ },
+ .hook = quirk_async_page_flips_force_disable,
+ },
};
static struct intel_quirk intel_quirks[] = {

View File

@ -1,972 +0,0 @@
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index fd61dba88..3220d96fc 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -26,7 +26,9 @@
#include <linux/dmi.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/sysfs.h>
#include <linux/platform_data/x86/asus-wmi.h>
+#include <linux/platform_device.h>
#include <linux/input/mt.h>
#include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */
#include <linux/power_supply.h>
@@ -94,6 +96,435 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
+/*
+ * USB buffers to be used in a control transfer to make the joystick change buttons mode and scancodes
+ * 0 is default (game_mode with back buttons sending F17 and F18 instead of F15 for both as when unconfigured)
+ * 1 is mouse mode: back buttons still are F17 and F18
+ * 2 is macro mode
+ */
+static const u8 rc71l_mode_switch_commands[][23][64] = {
+ {
+ {
+ 0x5A, 0xD1, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x01, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+ },
+ {
+ {
+ 0x5A, 0xD1, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x02, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x99, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x02, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x9B, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x02, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x02, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x02, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x96, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x0D, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+ },
+ {
+ {
+ 0x5A, 0xD1, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x01, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8F, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+ }
+};
+
struct asus_kbd_leds {
struct led_classdev cdev;
struct hid_device *hdev;
@@ -103,6 +534,25 @@ struct asus_kbd_leds {
bool removed;
};
+enum rc71l_controller_mode {
+ rc71l_gamepad_mode,
+ rc71l_mouse_mode,
+ rc71l_macro_mode,
+};
+
+struct asus_rc71l {
+ unsigned int usb_pipe;
+
+ struct platform_device *mcu_dev;
+
+ struct mutex mutex; /* Mutex that protects everything below it */
+
+ enum rc71l_controller_mode mode;
+
+ u8 usb_in_buf[32];
+ u8 usb_out_buf[64]; /* A temporary buffer to hold data that gets sent over USB (must be accessed upon locking the appropriate mutex) */
+};
+
struct asus_touchpad_info {
int max_x;
int max_y;
@@ -127,6 +577,7 @@ struct asus_drvdata {
int battery_stat;
bool battery_in_query;
unsigned long battery_next_query;
+ struct asus_rc71l *rc71l_data;
};
static int asus_report_battery(struct asus_drvdata *, u8 *, int);
@@ -189,6 +640,245 @@ static const struct asus_touchpad_info medion_e1239t_tp = {
.report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */,
};
+/**
+ * This function reads data over the USB device on the ROG Ally.
+ * Unlike outgoing traffic the inbound always performs 32-bytes transfers.
+ *
+ * PRE:
+ * - rc71l internal mutex MUST be locked
+ */
+static int rc71l_usb_read(struct hid_device * hdev) {
+ struct asus_drvdata *drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ const int retval = usb_control_msg_recv(dev, 0x80, 0x01, 0xa1, 0x035A, 0x0002, (void*)&rc71l_drvdata->usb_in_buf[0], 32, 250, GFP_KERNEL);
+
+ if (retval < 0) {
+ hid_err(hdev, "Ally read failed performing control read, error %d\n", retval);
+ goto rc71l_usb_read_err;
+ }
+
+ const char* b = (const u8*)&rc71l_drvdata->usb_in_buf[0];
+ hid_info(hdev, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9],
+ b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19],
+ b[20], b[21], b[22], b[23], b[24], b[25], b[26], b[27], b[28], b[29],
+ b[30], b[31]
+ );
+
+rc71l_usb_read_err:
+ return retval;
+}
+
+/**
+ * This function writes a command over the USB device on the ROG Ally.
+ * The ROG Ally accepts 64-bytes long messages as commands: as such at most 64-bytes will be sent
+ * and unused bytes will be zeroed out.
+ *
+ * PRE:
+ * - rc71l internal mutex MUST be locked
+ */
+static int rc71l_usb_write(struct hid_device * hdev, const void* buf, size_t buf_sz) {
+ struct asus_drvdata *drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ if (buf_sz > 64) {
+ hid_err(hdev, "Bug in the kernel: cannot write more than 64-bytes\n");
+
+ return -EINVAL;
+ }
+
+ // make sure bytes in excess will be zeroes and copy the user-provided buffer
+ memset((void*)&rc71l_drvdata->usb_out_buf[0], 0, 64);
+ memcpy((void*)&rc71l_drvdata->usb_out_buf[0], buf, buf_sz);
+
+ /* send the data out the bulk port */
+ const int retval = usb_control_msg(dev, rc71l_drvdata->usb_pipe, 0x09, 0x21, 0x035A, 0x0002, (void*)&rc71l_drvdata->usb_out_buf[0], 64, 250);
+ if (retval < 0) {
+ hid_err(hdev,
+ "Failed submitting control write error %d\n", retval);
+
+ goto rc71l_usb_write_err;
+ }
+
+rc71l_usb_write_err:
+ return retval < 0 ? retval : 0;
+}
+
+static int rc71l_mode_change(struct hid_device * hdev, enum rc71l_controller_mode new_mode) {
+ struct asus_drvdata *drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ int ret = 0;
+
+ size_t packets_group = 0;
+ switch (new_mode) {
+ case rc71l_gamepad_mode:
+ packets_group = 0;
+ break;
+
+ case rc71l_mouse_mode:
+ packets_group = 1;
+ break;
+
+ case rc71l_macro_mode:
+ packets_group = 2;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ for (int i = 0; (i < 23) && (ret == 0); ++i) {
+ ret = rc71l_usb_write(hdev, (const void*)&rc71l_mode_switch_commands[packets_group][i][0], 64);
+ if (ret > 0) {
+ hid_err(hdev, "Ally controller mode switch %d/23 error %d\n", i, ret);
+ goto rc71l_mode_change_err;
+ }
+ }
+
+ // controller mode has been switched successfully: change that in driver data
+ if (ret == 0) {
+ hid_info(hdev, "ROG Ally [RC71L] controller mode switch succeeded\n");
+ rc71l_drvdata->mode = new_mode;
+ }
+
+rc71l_mode_change_err:
+ return ret;
+}
+
+static ssize_t __maybe_unused mode_show(struct device *raw_dev, struct device_attribute *attr, char *buf) {
+ struct platform_device *const pdev = to_platform_device(raw_dev);
+ struct hid_device *const hdev = platform_get_drvdata(pdev);
+ if (hdev == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_drvdata *const drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *const rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ mutex_lock(&rc71l_drvdata->mutex);
+ int current_mode = 0;
+ switch (rc71l_drvdata->mode) {
+ case rc71l_gamepad_mode:
+ current_mode = 0;
+ break;
+
+ case rc71l_mouse_mode:
+ current_mode = 1;
+ break;
+
+ case rc71l_macro_mode:
+ current_mode = 2;
+ break;
+
+ default:
+ mutex_unlock(&rc71l_drvdata->mutex);
+ return -EINVAL;
+ }
+ mutex_unlock(&rc71l_drvdata->mutex);
+
+ return sysfs_emit(buf, "%d\n", (int)current_mode);
+}
+
+static ssize_t __maybe_unused mode_store(struct device *raw_dev, struct device_attribute *attr, const char *buf, size_t count) {
+ struct platform_device *const pdev = to_platform_device(raw_dev);
+ struct hid_device *const hdev = platform_get_drvdata(pdev);
+ if (hdev == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_drvdata *const drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *const rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ int res = -EINVAL;
+ int val = -EINVAL;
+ res = kstrtoint(buf, 0, &val);
+ if (res)
+ return res;
+
+ switch (val) {
+ case 0:
+ mutex_lock(&rc71l_drvdata->mutex);
+ res = rc71l_mode_change(hdev, rc71l_gamepad_mode);
+ mutex_unlock(&rc71l_drvdata->mutex);
+ break;
+
+ case 1:
+ mutex_lock(&rc71l_drvdata->mutex);
+ res = rc71l_mode_change(hdev, rc71l_mouse_mode);
+ mutex_unlock(&rc71l_drvdata->mutex);
+ break;
+
+ case 2:
+ mutex_lock(&rc71l_drvdata->mutex);
+ res = rc71l_mode_change(hdev, rc71l_macro_mode);
+ mutex_unlock(&rc71l_drvdata->mutex);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ hid_err(hdev, "Ally controller mode switch to %d mode op result: %d\n", val, res);
+
+ return count;
+}
+
+DEVICE_ATTR_RW(mode);
+
+static struct attribute *rc71l_input_attrs[] = {
+ &dev_attr_mode.attr,
+ NULL
+};
+
+static const struct attribute_group mcu_attr_group = {
+ .name = "input",
+ .attrs = rc71l_input_attrs,
+};
+
static void asus_report_contact_down(struct asus_drvdata *drvdat,
int toolType, u8 *data)
{
@@ -386,7 +1076,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size
unsigned char *dmabuf;
int ret;
- dmabuf = kmemdup(buf, buf_size, GFP_KERNEL);
+ dmabuf = kmemdup((const void*)buf, buf_size, GFP_KERNEL);
if (!dmabuf)
return -ENOMEM;
@@ -897,6 +1587,10 @@ static int asus_input_mapping(struct hid_device *hdev,
case 0xb3: asus_map_key_clear(KEY_PROG3); break; /* Fn+Left next aura */
case 0x6a: asus_map_key_clear(KEY_F13); break; /* Screenpad toggle */
case 0x4b: asus_map_key_clear(KEY_F14); break; /* Arrows/Pg-Up/Dn toggle */
+ case 0xa5: asus_map_key_clear(KEY_F15); break; /* ROG Ally left back */
+ case 0xa6: asus_map_key_clear(KEY_F16); break; /* ROG Ally QAM button */
+ case 0xa7: asus_map_key_clear(KEY_F17); break; /* ROG Ally ROG long-press */
+ case 0xa8: asus_map_key_clear(KEY_F18); break; /* ROG Ally ROG long-press-release */
default:
@@ -1000,16 +1694,108 @@ static int asus_start_multitouch(struct hid_device *hdev)
return 0;
}
+#ifdef CONFIG_PM
static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
{
+ int ret = 0;
+
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+ if (drvdata != NULL) {
+ return -EINVAL;
+ }
if (drvdata->tp)
return asus_start_multitouch(hdev);
- return 0;
+ return ret;
}
+static int __maybe_unused asus_resume(struct hid_device *hdev)
+{
+ int ret = 0;
+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+/*
+ // Controller mode is kept on device sleep
+ if (dmi_match(DMI_PRODUCT_NAME, "ROG Ally RC71L_RC71L"))
+ {
+ // Apply the joystick mode switch
+ ret = rog_ally_controller_mode_change(hdev, game_mode);
+
+ hid_err(hdev, "Asus wake, restore controller %d\n", ret);
+ }
+*/
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata != NULL) {
+ mutex_lock(&rc71l_drvdata->mutex);
+ ret = rc71l_mode_change(hdev, rc71l_drvdata->mode);
+ mutex_unlock(&rc71l_drvdata->mutex);
+
+ if (ret < 0) {
+ hid_err(hdev, "ROG Ally [RC71L] failed to reset controller mode: %d\n", ret);
+ goto asus_resume_err;
+ }
+ }
+
+
+ /*
+ * On some devices such as the Asus RC71L leds are reset to default after sleep and sysfs attribute will report
+ * something that won't be true: resetting the user-provided value is necessary to maintain coherency and avoid
+ * flashing full brightness leds in face of the user.
+ */
+ if (drvdata->kbd_backlight) {
+ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, drvdata->kbd_backlight->cdev.brightness };
+ ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
+ if (ret < 0) {
+ hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret);
+ goto asus_resume_err;
+ }
+
+ hid_err(hdev, "Asus ROG Ally asus_reset_resume, leds reset: %d at brightness %d\n", ret, (int)drvdata->kbd_backlight->cdev.brightness);
+ }
+
+ asus_resume_err:
+ return ret;
+}
+
+static int __maybe_unused asus_suspend(struct hid_device *hdev, struct pm_message)
+ {
+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+
+ if (drvdata == NULL) {
+ return 0;
+ }
+
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ int ret = 0;
+
+ if (dmi_match(DMI_PRODUCT_NAME, "ROG Ally RC71L_RC71L")) {
+ // Send the USB ABORT_PIPE command
+ int result = usb_control_msg(
+ dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE,
+ USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT,
+ USB_ENDPOINT_HALT, 0x02, NULL, 0, 1000);
+
+ if (result < 0) {
+ printk("USB ABORT_PIPE failed: %d\n", result);
+ } else {
+ printk("USB ABORT_PIPE succeeded\n");
+ }
+ }
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata != NULL) {
+ mutex_lock(&rc71l_drvdata->mutex);
+ // TODO: send ABORT_PIPE here
+ mutex_unlock(&rc71l_drvdata->mutex);
+ }
+
+ return ret;
+}
+#endif
+
static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret;
@@ -1021,6 +1807,8 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
return -ENOMEM;
}
+ drvdata->rc71l_data = NULL;
+
hid_set_drvdata(hdev, drvdata);
drvdata->quirks = id->driver_data;
@@ -1109,6 +1897,51 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_stop_hw;
}
+ if ((dmi_match(DMI_PRODUCT_NAME, "ROG Ally RC71L_RC71L")) && (hdev->rsize > 9) && (hdev->rdesc[7] == 0x85) && (hdev->rdesc[8] == 0x5a))
+ {
+ drvdata->rc71l_data = devm_kzalloc(&hdev->dev, sizeof(*drvdata->rc71l_data), GFP_KERNEL);
+ if (drvdata->rc71l_data == NULL) {
+ hid_err(hdev, "Can't alloc Asus ROG Ally [RC71L] descriptor\n");
+ ret = -ENOMEM;
+ goto err_stop_hw;
+ }
+
+ mutex_init(&drvdata->rc71l_data->mutex);
+
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ // default controller mode
+ drvdata->rc71l_data->mode = rc71l_gamepad_mode;
+
+ // usb_device and endpoint
+ drvdata->rc71l_data->usb_pipe = usb_sndctrlpipe(dev, 0);
+
+ // apply the default controller mode
+ mutex_lock(&drvdata->rc71l_data->mutex);
+ ret = rc71l_mode_change(hdev, drvdata->rc71l_data->mode);
+ mutex_unlock(&drvdata->rc71l_data->mutex);
+
+ if (ret < 0) {
+ hid_err(hdev, "Asus ROG Ally [RC71L] error setting the default controller mode: %d\n", ret);
+ goto err_stop_hw;
+ }
+
+ drvdata->rc71l_data->mcu_dev = platform_device_register_simple("asus-mcu", 0, NULL, 0);
+ if (IS_ERR(drvdata->rc71l_data->mcu_dev)) {
+ hid_err(hdev, "Error registering MCU platform device: %ld\n", PTR_ERR(drvdata->rc71l_data->mcu_dev));
+ goto err_stop_hw;
+ }
+
+ platform_set_drvdata(drvdata->rc71l_data->mcu_dev, hdev);
+
+ ret = devm_device_add_group(&drvdata->rc71l_data->mcu_dev->dev, &mcu_attr_group);
+ if (ret != 0) {
+ platform_device_unregister(drvdata->rc71l_data->mcu_dev);
+ goto err_stop_hw;
+ }
+ }
+
if (drvdata->tp) {
drvdata->input->name = "Asus TouchPad";
} else {
@@ -1140,6 +1973,16 @@ static void asus_remove(struct hid_device *hdev)
cancel_work_sync(&drvdata->kbd_backlight->work);
}
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata != NULL) {
+ platform_device_unregister(rc71l_drvdata->mcu_dev);
+
+ mutex_lock(&rc71l_drvdata->mutex);
+ platform_device_unregister(rc71l_drvdata->mcu_dev);
+ // TODO: perform cleanup operations
+ mutex_unlock(&rc71l_drvdata->mutex);
+ }
+
hid_hw_stop(hdev);
}
@@ -1258,6 +2101,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 },
@@ -1294,6 +2140,8 @@ static struct hid_driver asus_driver = {
.input_configured = asus_input_configured,
#ifdef CONFIG_PM
.reset_resume = asus_reset_resume,
+ .resume = asus_resume,
+ .suspend = asus_suspend,
#endif
.event = asus_event,
.raw_event = asus_raw_event
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index d10ccfa17..213492ee8 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.43.0

View File

@ -1,54 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan200101 <sentrycraft123@gmail.com>
Date: Wed, 8 Mar 2023 20:51:16 +0100
Subject: [PATCH] drm/i915: add kernel parameter to disable async page flipping
Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
---
drivers/gpu/drm/i915/display/intel_display_driver.c | 2 +-
drivers/gpu/drm/i915/i915_params.c | 4 ++++
drivers/gpu/drm/i915/i915_params.h | 3 ++-
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index ade744cccfea..119be26b5641 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -222,6 +222,10 @@ i915_param_named_unsafe(lmem_size, uint, 0400,
i915_param_named_unsafe(lmem_bar_size, uint, 0400,
"Set the lmem bar size(in MiB).");
+i915_param_named_unsafe(disable_async_page_flip, bool, 0400,
+ "Disable async page flipping"
+ "(0=disabled [default], 1=enabled)");
+
static void _param_print_bool(struct drm_printer *p, const char *name,
bool val)
{
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index 3f51f90145b6..37f25ec1b874 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -85,7 +85,8 @@ struct drm_printer;
param(bool, verbose_state_checks, true, 0) \
param(bool, nuclear_pageflip, false, 0400) \
param(bool, enable_dp_mst, true, 0600) \
- param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0)
+ param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0) \
+ param(bool, disable_async_page_flip, false, 0400)
#define MEMBER(T, member, ...) T member;
struct i915_params {
diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c
index b909814ae..918b8b589 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -121,7 +121,7 @@ static void intel_mode_config_init(struct drm_i915_private *i915)
mode_config->funcs = &intel_mode_funcs;
mode_config->helper_private = &intel_mode_config_funcs;
- mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915);
+ mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915) && !i915->params.disable_async_page_flip;
/*
* Maximum framebuffer dimensions, chosen to match

View File

@ -1,703 +0,0 @@
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2ddca08f8a76..72647850f08e 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -217,6 +217,15 @@ config I2C_CHT_WC
combined with a FUSB302 Type-C port-controller as such it is advised
to also select CONFIG_TYPEC_FUSB302=m.
+config I2C_NCT6775
+ tristate "Nuvoton NCT6775 and compatible SMBus controller"
+ help
+ If you say yes to this option, support will be included for the
+ Nuvoton NCT6775 and compatible SMBus controllers.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-nct6775.
+
config I2C_NFORCE2
tristate "Nvidia nForce2, nForce3 and nForce4"
depends on PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 25d60889713c..3c2a9b237ac6 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_I2C_CHT_WC) += i2c-cht-wc.o
obj-$(CONFIG_I2C_I801) += i2c-i801.o
obj-$(CONFIG_I2C_ISCH) += i2c-isch.o
obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o
+obj-$(CONFIG_I2C_NCT6775) += i2c-nct6775.o
obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o
obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o
obj-$(CONFIG_I2C_NVIDIA_GPU) += i2c-nvidia-gpu.o
diff --git a/drivers/i2c/busses/i2c-nct6775.c b/drivers/i2c/busses/i2c-nct6775.c
new file mode 100644
index 000000000000..0462f0952043
--- /dev/null
+++ b/drivers/i2c/busses/i2c-nct6775.c
@@ -0,0 +1,647 @@
+/*
+ * i2c-nct6775 - Driver for the SMBus master functionality of
+ * Nuvoton NCT677x Super-I/O chips
+ *
+ * Copyright (C) 2019 Adam Honse <calcprogrammer1@gmail.com>
+ *
+ * Derived from nct6775 hwmon driver
+ * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon-vid.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+#include <linux/bitops.h>
+#include <linux/dmi.h>
+#include <linux/io.h>
+#include <linux/nospec.h>
+
+#define DRVNAME "i2c-nct6775"
+
+/* Nuvoton SMBus address offsets */
+#define SMBHSTDAT (0 + nuvoton_nct6793d_smba)
+#define SMBBLKSZ (1 + nuvoton_nct6793d_smba)
+#define SMBHSTCMD (2 + nuvoton_nct6793d_smba)
+#define SMBHSTIDX (3 + nuvoton_nct6793d_smba) //Index field is the Command field on other controllers
+#define SMBHSTCTL (4 + nuvoton_nct6793d_smba)
+#define SMBHSTADD (5 + nuvoton_nct6793d_smba)
+#define SMBHSTERR (9 + nuvoton_nct6793d_smba)
+#define SMBHSTSTS (0xE + nuvoton_nct6793d_smba)
+
+/* Command register */
+#define NCT6793D_READ_BYTE 0
+#define NCT6793D_READ_WORD 1
+#define NCT6793D_READ_BLOCK 2
+#define NCT6793D_BLOCK_WRITE_READ_PROC_CALL 3
+#define NCT6793D_PROC_CALL 4
+#define NCT6793D_WRITE_BYTE 8
+#define NCT6793D_WRITE_WORD 9
+#define NCT6793D_WRITE_BLOCK 10
+
+/* Control register */
+#define NCT6793D_MANUAL_START 128
+#define NCT6793D_SOFT_RESET 64
+
+/* Error register */
+#define NCT6793D_NO_ACK 32
+
+/* Status register */
+#define NCT6793D_FIFO_EMPTY 1
+#define NCT6793D_FIFO_FULL 2
+#define NCT6793D_MANUAL_ACTIVE 4
+
+#define NCT6775_LD_SMBUS 0x0B
+
+/* Other settings */
+#define MAX_RETRIES 400
+
+enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793,
+ nct6795, nct6796, nct6798 };
+
+struct nct6775_sio_data {
+ int sioreg;
+ enum kinds kind;
+};
+
+/* used to set data->name = nct6775_device_names[data->sio_kind] */
+static const char * const nct6775_device_names[] = {
+ "nct6106",
+ "nct6775",
+ "nct6776",
+ "nct6779",
+ "nct6791",
+ "nct6792",
+ "nct6793",
+ "nct6795",
+ "nct6796",
+ "nct6798",
+};
+
+static const char * const nct6775_sio_names[] __initconst = {
+ "NCT6106D",
+ "NCT6775F",
+ "NCT6776D/F",
+ "NCT6779D",
+ "NCT6791D",
+ "NCT6792D",
+ "NCT6793D",
+ "NCT6795D",
+ "NCT6796D",
+ "NCT6798D",
+};
+
+#define SIO_REG_LDSEL 0x07 /* Logical device select */
+#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
+#define SIO_REG_SMBA 0x62 /* SMBus base address register */
+
+#define SIO_NCT6106_ID 0xc450
+#define SIO_NCT6775_ID 0xb470
+#define SIO_NCT6776_ID 0xc330
+#define SIO_NCT6779_ID 0xc560
+#define SIO_NCT6791_ID 0xc800
+#define SIO_NCT6792_ID 0xc910
+#define SIO_NCT6793_ID 0xd120
+#define SIO_NCT6795_ID 0xd350
+#define SIO_NCT6796_ID 0xd420
+#define SIO_NCT6798_ID 0xd428
+#define SIO_ID_MASK 0xFFF0
+
+static inline void
+superio_outb(int ioreg, int reg, int val)
+{
+ outb(reg, ioreg);
+ outb(val, ioreg + 1);
+}
+
+static inline int
+superio_inb(int ioreg, int reg)
+{
+ outb(reg, ioreg);
+ return inb(ioreg + 1);
+}
+
+static inline void
+superio_select(int ioreg, int ld)
+{
+ outb(SIO_REG_LDSEL, ioreg);
+ outb(ld, ioreg + 1);
+}
+
+static inline int
+superio_enter(int ioreg)
+{
+ /*
+ * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
+ */
+ if (!request_muxed_region(ioreg, 2, DRVNAME))
+ return -EBUSY;
+
+ outb(0x87, ioreg);
+ outb(0x87, ioreg);
+
+ return 0;
+}
+
+static inline void
+superio_exit(int ioreg)
+{
+ outb(0xaa, ioreg);
+ outb(0x02, ioreg);
+ outb(0x02, ioreg + 1);
+ release_region(ioreg, 2);
+}
+
+/*
+ * ISA constants
+ */
+
+#define IOREGION_ALIGNMENT (~7)
+#define IOREGION_LENGTH 2
+#define ADDR_REG_OFFSET 0
+#define DATA_REG_OFFSET 1
+
+#define NCT6775_REG_BANK 0x4E
+#define NCT6775_REG_CONFIG 0x40
+
+static struct i2c_adapter *nct6775_adapter;
+
+struct i2c_nct6775_adapdata {
+ unsigned short smba;
+};
+
+/* Return negative errno on error. */
+static s32 nct6775_access(struct i2c_adapter * adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data * data)
+{
+ struct i2c_nct6775_adapdata *adapdata = i2c_get_adapdata(adap);
+ unsigned short nuvoton_nct6793d_smba = adapdata->smba;
+ int i, len, cnt;
+ union i2c_smbus_data tmp_data;
+ int timeout = 0;
+
+ tmp_data.word = 0;
+ cnt = 0;
+ len = 0;
+
+ outb_p(NCT6793D_SOFT_RESET, SMBHSTCTL);
+
+ switch (size) {
+ case I2C_SMBUS_QUICK:
+ outb_p((addr << 1) | read_write,
+ SMBHSTADD);
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ tmp_data.byte = data->byte;
+ case I2C_SMBUS_BYTE:
+ outb_p((addr << 1) | read_write,
+ SMBHSTADD);
+ outb_p(command, SMBHSTIDX);
+ if (read_write == I2C_SMBUS_WRITE) {
+ outb_p(tmp_data.byte, SMBHSTDAT);
+ outb_p(NCT6793D_WRITE_BYTE, SMBHSTCMD);
+ }
+ else {
+ outb_p(NCT6793D_READ_BYTE, SMBHSTCMD);
+ }
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ outb_p((addr << 1) | read_write,
+ SMBHSTADD);
+ outb_p(command, SMBHSTIDX);
+ if (read_write == I2C_SMBUS_WRITE) {
+ outb_p(data->word & 0xff, SMBHSTDAT);
+ outb_p((data->word & 0xff00) >> 8, SMBHSTDAT);
+ outb_p(NCT6793D_WRITE_WORD, SMBHSTCMD);
+ }
+ else {
+ outb_p(NCT6793D_READ_WORD, SMBHSTCMD);
+ }
+ break;
+ case I2C_SMBUS_BLOCK_DATA:
+ outb_p((addr << 1) | read_write,
+ SMBHSTADD);
+ outb_p(command, SMBHSTIDX);
+ if (read_write == I2C_SMBUS_WRITE) {
+ len = data->block[0];
+ if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
+ return -EINVAL;
+ outb_p(len, SMBBLKSZ);
+
+ cnt = 1;
+ if (len >= 4) {
+ for (i = cnt; i <= 4; i++) {
+ outb_p(data->block[i], SMBHSTDAT);
+ }
+
+ len -= 4;
+ cnt += 4;
+ }
+ else {
+ for (i = cnt; i <= len; i++ ) {
+ outb_p(data->block[i], SMBHSTDAT);
+ }
+
+ len = 0;
+ }
+
+ outb_p(NCT6793D_WRITE_BLOCK, SMBHSTCMD);
+ }
+ else {
+ return -ENOTSUPP;
+ }
+ break;
+ default:
+ dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+ return -EOPNOTSUPP;
+ }
+
+ outb_p(NCT6793D_MANUAL_START, SMBHSTCTL);
+
+ while ((size == I2C_SMBUS_BLOCK_DATA) && (len > 0)) {
+ if (read_write == I2C_SMBUS_WRITE) {
+ timeout = 0;
+ while ((inb_p(SMBHSTSTS) & NCT6793D_FIFO_EMPTY) == 0)
+ {
+ if(timeout > MAX_RETRIES)
+ {
+ return -ETIMEDOUT;
+ }
+ usleep_range(250, 500);
+ timeout++;
+ }
+
+ //Load more bytes into FIFO
+ if (len >= 4) {
+ for (i = cnt; i <= (cnt + 4); i++) {
+ outb_p(data->block[i], SMBHSTDAT);
+ }
+
+ len -= 4;
+ cnt += 4;
+ }
+ else {
+ for (i = cnt; i <= (cnt + len); i++) {
+ outb_p(data->block[i], SMBHSTDAT);
+ }
+
+ len = 0;
+ }
+ }
+ else {
+ return -ENOTSUPP;
+ }
+
+ }
+
+ //wait for manual mode to complete
+ timeout = 0;
+ while ((inb_p(SMBHSTSTS) & NCT6793D_MANUAL_ACTIVE) != 0)
+ {
+ if(timeout > MAX_RETRIES)
+ {
+ return -ETIMEDOUT;
+ }
+ usleep_range(250, 500);
+ timeout++;
+ }
+
+ if ((inb_p(SMBHSTERR) & NCT6793D_NO_ACK) != 0) {
+ return -ENXIO;
+ }
+ else if ((read_write == I2C_SMBUS_WRITE) || (size == I2C_SMBUS_QUICK)) {
+ return 0;
+ }
+
+ switch (size) {
+ case I2C_SMBUS_QUICK:
+ case I2C_SMBUS_BYTE_DATA:
+ data->byte = inb_p(SMBHSTDAT);
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ data->word = inb_p(SMBHSTDAT) + (inb_p(SMBHSTDAT) << 8);
+ break;
+ }
+ return 0;
+}
+
+static u32 nct6775_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+ I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+static const struct i2c_algorithm smbus_algorithm = {
+ .smbus_xfer = nct6775_access,
+ .functionality = nct6775_func,
+};
+
+static int nct6775_add_adapter(unsigned short smba, const char *name, struct i2c_adapter **padap)
+{
+ struct i2c_adapter *adap;
+ struct i2c_nct6775_adapdata *adapdata;
+ int retval;
+
+ adap = kzalloc(sizeof(*adap), GFP_KERNEL);
+ if (adap == NULL) {
+ return -ENOMEM;
+ }
+
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ adap->algo = &smbus_algorithm;
+
+ adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL);
+ if (adapdata == NULL) {
+ kfree(adap);
+ return -ENOMEM;
+ }
+
+ adapdata->smba = smba;
+
+ snprintf(adap->name, sizeof(adap->name),
+ "SMBus NCT67xx adapter%s at %04x", name, smba);
+
+ i2c_set_adapdata(adap, adapdata);
+
+ retval = i2c_add_adapter(adap);
+ if (retval) {
+ kfree(adapdata);
+ kfree(adap);
+ return retval;
+ }
+
+ *padap = adap;
+ return 0;
+}
+
+static void nct6775_remove_adapter(struct i2c_adapter *adap)
+{
+ struct i2c_nct6775_adapdata *adapdata = i2c_get_adapdata(adap);
+
+ if (adapdata->smba) {
+ i2c_del_adapter(adap);
+ kfree(adapdata);
+ kfree(adap);
+ }
+}
+
+//static SIMPLE_DEV_PM_OPS(nct6775_dev_pm_ops, nct6775_suspend, nct6775_resume);
+
+/*
+ * when Super-I/O functions move to a separate file, the Super-I/O
+ * bus will manage the lifetime of the device and this module will only keep
+ * track of the nct6775 driver. But since we use platform_device_alloc(), we
+ * must keep track of the device
+ */
+static struct platform_device *pdev[2];
+
+static int nct6775_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
+ DRVNAME))
+ return -EBUSY;
+
+ switch (sio_data->kind) {
+ case nct6791:
+ case nct6792:
+ case nct6793:
+ case nct6795:
+ case nct6796:
+ case nct6798:
+ nct6775_add_adapter(res->start, "", &nct6775_adapter);
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ return 0;
+}
+/*
+static void nct6791_enable_io_mapping(int sioaddr)
+{
+ int val;
+
+ val = superio_inb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
+ if (val & 0x10) {
+ pr_info("Enabling hardware monitor logical device mappings.\n");
+ superio_outb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
+ val & ~0x10);
+ }
+}*/
+
+static struct platform_driver i2c_nct6775_driver = {
+ .driver = {
+ .name = DRVNAME,
+// .pm = &nct6775_dev_pm_ops,
+ },
+ .probe = nct6775_probe,
+};
+
+static void __exit i2c_nct6775_exit(void)
+{
+ int i;
+
+ if(nct6775_adapter)
+ nct6775_remove_adapter(nct6775_adapter);
+
+ for (i = 0; i < ARRAY_SIZE(pdev); i++) {
+ if (pdev[i])
+ platform_device_unregister(pdev[i]);
+ }
+ platform_driver_unregister(&i2c_nct6775_driver);
+}
+
+/* nct6775_find() looks for a '627 in the Super-I/O config space */
+static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
+{
+ u16 val;
+ int err;
+ int addr;
+
+ err = superio_enter(sioaddr);
+ if (err)
+ return err;
+
+ val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) |
+ superio_inb(sioaddr, SIO_REG_DEVID + 1);
+
+ switch (val & SIO_ID_MASK) {
+ case SIO_NCT6106_ID:
+ sio_data->kind = nct6106;
+ break;
+ case SIO_NCT6775_ID:
+ sio_data->kind = nct6775;
+ break;
+ case SIO_NCT6776_ID:
+ sio_data->kind = nct6776;
+ break;
+ case SIO_NCT6779_ID:
+ sio_data->kind = nct6779;
+ break;
+ case SIO_NCT6791_ID:
+ sio_data->kind = nct6791;
+ break;
+ case SIO_NCT6792_ID:
+ sio_data->kind = nct6792;
+ break;
+ case SIO_NCT6793_ID:
+ sio_data->kind = nct6793;
+ break;
+ case SIO_NCT6795_ID:
+ sio_data->kind = nct6795;
+ break;
+ case SIO_NCT6796_ID:
+ sio_data->kind = nct6796;
+ break;
+ case SIO_NCT6798_ID:
+ sio_data->kind = nct6798;
+ break;
+ default:
+ if (val != 0xffff)
+ pr_debug("unsupported chip ID: 0x%04x\n", val);
+ superio_exit(sioaddr);
+ return -ENODEV;
+ }
+
+ /* We have a known chip, find the SMBus I/O address */
+ superio_select(sioaddr, NCT6775_LD_SMBUS);
+ val = (superio_inb(sioaddr, SIO_REG_SMBA) << 8)
+ | superio_inb(sioaddr, SIO_REG_SMBA + 1);
+ addr = val & IOREGION_ALIGNMENT;
+ if (addr == 0) {
+ pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
+ superio_exit(sioaddr);
+ return -ENODEV;
+ }
+
+ //if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
+ // sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
+ // sio_data->kind == nct6796)
+ // nct6791_enable_io_mapping(sioaddr);
+
+ superio_exit(sioaddr);
+ pr_info("Found %s or compatible chip at %#x:%#x\n",
+ nct6775_sio_names[sio_data->kind], sioaddr, addr);
+ sio_data->sioreg = sioaddr;
+
+ return addr;
+}
+
+static int __init i2c_nct6775_init(void)
+{
+ int i, err;
+ bool found = false;
+ int address;
+ struct resource res;
+ struct nct6775_sio_data sio_data;
+ int sioaddr[2] = { 0x2e, 0x4e };
+
+ err = platform_driver_register(&i2c_nct6775_driver);
+ if (err)
+ return err;
+
+ /*
+ * initialize sio_data->kind and sio_data->sioreg.
+ *
+ * when Super-I/O functions move to a separate file, the Super-I/O
+ * driver will probe 0x2e and 0x4e and auto-detect the presence of a
+ * nct6775 hardware monitor, and call probe()
+ */
+ for (i = 0; i < ARRAY_SIZE(pdev); i++) {
+ address = nct6775_find(sioaddr[i], &sio_data);
+ if (address <= 0)
+ continue;
+
+ found = true;
+
+ pdev[i] = platform_device_alloc(DRVNAME, address);
+ if (!pdev[i]) {
+ err = -ENOMEM;
+ goto exit_device_unregister;
+ }
+
+ err = platform_device_add_data(pdev[i], &sio_data,
+ sizeof(struct nct6775_sio_data));
+ if (err)
+ goto exit_device_put;
+
+ memset(&res, 0, sizeof(res));
+ res.name = DRVNAME;
+ res.start = address;
+ res.end = address + IOREGION_LENGTH - 1;
+ res.flags = IORESOURCE_IO;
+
+ err = acpi_check_resource_conflict(&res);
+ if (err) {
+ platform_device_put(pdev[i]);
+ pdev[i] = NULL;
+ continue;
+ }
+
+ err = platform_device_add_resources(pdev[i], &res, 1);
+ if (err)
+ goto exit_device_put;
+
+ /* platform_device_add calls probe() */
+ err = platform_device_add(pdev[i]);
+ if (err)
+ goto exit_device_put;
+ }
+ if (!found) {
+ err = -ENODEV;
+ goto exit_unregister;
+ }
+
+ return 0;
+
+exit_device_put:
+ platform_device_put(pdev[i]);
+exit_device_unregister:
+ while (--i >= 0) {
+ if (pdev[i])
+ platform_device_unregister(pdev[i]);
+ }
+exit_unregister:
+ platform_driver_unregister(&i2c_nct6775_driver);
+ return err;
+}
+
+MODULE_AUTHOR("Adam Honse <calcprogrammer1@gmail.com>");
+MODULE_DESCRIPTION("SMBus driver for NCT6775F and compatible chips");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_nct6775_init);
+module_exit(i2c_nct6775_exit);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 30ded6422e7b..e25ce84c26af 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -467,11 +467,11 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter)
if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
usleep_range(2000, 2100);
else
- usleep_range(250, 500);
+ usleep_range(25, 50);
while ((++timeout < MAX_TIMEOUT) &&
((temp = inb_p(SMBHSTSTS)) & 0x01))
- usleep_range(250, 500);
+ usleep_range(25, 50);
/* If the SMBus is still busy, we give up */
if (timeout == MAX_TIMEOUT) {

View File

@ -1,70 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan200101 <sentrycraft123@gmail.com>
Date: Mon, 27 Nov 2023 09:53:59 +0100
Subject: [PATCH] drm/amdgpu: enable SI and CIK support by default
Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 10 ----------
drivers/gpu/drm/radeon/radeon_drv.c | 10 ++++++++++
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 81edf66dbea8..5021d03089ff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -582,13 +582,8 @@ module_param_named(timeout_period, amdgpu_watchdog_timer.period, uint, 0644);
*/
#ifdef CONFIG_DRM_AMDGPU_SI
-#if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE)
-int amdgpu_si_support = 0;
-MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))");
-#else
int amdgpu_si_support = 1;
MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)");
-#endif
module_param_named(si_support, amdgpu_si_support, int, 0444);
#endif
@@ -601,13 +596,8 @@ module_param_named(si_support, amdgpu_si_support, int, 0444);
*/
#ifdef CONFIG_DRM_AMDGPU_CIK
-#if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE)
-int amdgpu_cik_support = 0;
-MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))");
-#else
int amdgpu_cik_support = 1;
MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)");
-#endif
module_param_named(cik_support, amdgpu_cik_support, int, 0444);
#endif
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 7bf08164140e..865f186f48c4 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -239,12 +239,22 @@ module_param_named(uvd, radeon_uvd, int, 0444);
MODULE_PARM_DESC(vce, "vce enable/disable vce support (1 = enable, 0 = disable)");
module_param_named(vce, radeon_vce, int, 0444);
+#ifdef CONFIG_DRM_AMDGPU_SI
+int radeon_si_support = 0;
+MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))");
+#else
int radeon_si_support = 1;
MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)");
+#endif
module_param_named(si_support, radeon_si_support, int, 0444);
+#ifdef CONFIG_DRM_AMDGPU_CIK
+int radeon_cik_support = 0;
+MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))");
+#else
int radeon_cik_support = 1;
MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)");
+#endif
module_param_named(cik_support, radeon_cik_support, int, 0444);
static struct pci_device_id pciidlist[] = {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan200101 <sentrycraft123@gmail.com>
Date: Mon, 27 Nov 2023 15:25:48 +0100
Subject: [PATCH] mt76: mt7921: Disable powersave features by default
This brings WiFi latency down considerably and makes latency consistent by
disabling runtime PM and typical powersave features by default. The actual
power consumption difference is inconsequential on desktops and laptops,
while the performance difference is monumental. Latencies of 20+ ms are no
longer observed after this change, and the connection is much more stable.
Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
---
drivers/net/wireless/mediatek/mt76/mt7921/init.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
index ff63f37f67d9..840b4c606c83 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
@@ -220,12 +220,6 @@ int mt7921_register_device(struct mt792x_dev *dev)
dev->pm.idle_timeout = MT792x_PM_TIMEOUT;
dev->pm.stats.last_wake_event = jiffies;
dev->pm.stats.last_doze_event = jiffies;
- if (!mt76_is_usb(&dev->mt76)) {
- dev->pm.enable_user = true;
- dev->pm.enable = true;
- dev->pm.ds_enable_user = true;
- dev->pm.ds_enable = true;
- }
if (!mt76_is_mmio(&dev->mt76))
hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE;
@@ -240,6 +234,8 @@ int mt7921_register_device(struct mt792x_dev *dev)
if (ret)
return ret;
+ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
hw->wiphy->reg_notifier = mt7921_regd_notifier;
dev->mphy.sband_2g.sband.ht_cap.cap |=
IEEE80211_HT_CAP_LDPC_CODING |

View File

@ -1,27 +0,0 @@
From 0f2c07ab93dca496a1f34399ad2ff8a954690a72 Mon Sep 17 00:00:00 2001
From: GloriousEggroll <gloriouseggroll@gmail.com>
Date: Mon, 29 May 2023 17:15:14 -0600
Subject: [PATCH] set ds controller bluetooth pollrate to 1 ms
---
drivers/hid/hid-playstation.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
index 8ac8f7b8e..1130663c3 100644
--- a/drivers/hid/hid-playstation.c
+++ b/drivers/hid/hid-playstation.c
@@ -330,8 +330,8 @@ struct dualsense_output_report {
* 0x3F - disabled
*/
#define DS4_OUTPUT_HWCTL_BT_POLL_MASK 0x3F
-/* Default to 4ms poll interval, which is same as USB (not adjustable). */
-#define DS4_BT_DEFAULT_POLL_INTERVAL_MS 4
+/* Default to 1ms poll interval (1000Hz, lower latency). */
+#define DS4_BT_DEFAULT_POLL_INTERVAL_MS 1
#define DS4_OUTPUT_HWCTL_CRC32 0x40
#define DS4_OUTPUT_HWCTL_HID 0x80
--
2.40.1

File diff suppressed because it is too large Load Diff

View File

@ -1,133 +0,0 @@
---
drivers/input/misc/uinput.c | 48 +++++++++++++++++++++++++------------
include/uapi/linux/uinput.h | 5 ++++
2 files changed, 38 insertions(+), 15 deletions(-)
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 84051f20b18a..2c3180370a02 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -20,6 +20,7 @@
*/
#include <uapi/linux/uinput.h>
#include <linux/poll.h>
+#include <linux/printk.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/module.h>
@@ -280,7 +281,7 @@ static int uinput_dev_flush(struct input_dev *dev, struct file *file)
static void uinput_destroy_device(struct uinput_device *udev)
{
- const char *name, *phys;
+ const char *name, *phys, *uniq;
struct input_dev *dev = udev->dev;
enum uinput_state old_state = udev->state;
@@ -289,6 +290,7 @@ static void uinput_destroy_device(struct uinput_device *udev)
if (dev) {
name = dev->name;
phys = dev->phys;
+ uniq = dev->uniq;
if (old_state == UIST_CREATED) {
uinput_flush_requests(udev);
input_unregister_device(dev);
@@ -297,6 +299,7 @@ static void uinput_destroy_device(struct uinput_device *udev)
}
kfree(name);
kfree(phys);
+ kfree(uniq);
udev->dev = NULL;
}
}
@@ -831,6 +834,24 @@ static int uinput_str_to_user(void __user *dest, const char *str,
return ret ? -EFAULT : len;
}
+static int uinput_get_user_str(struct uinput_device *udev, const char **kptr,
+ const char *uptr, unsigned int size)
+{
+ char *tmp;
+
+ if (udev->state == UIST_CREATED)
+ return -EINVAL;
+
+ tmp = strndup_user(uptr, size);
+ if (IS_ERR(tmp))
+ return PTR_ERR(tmp);
+
+ kfree(*kptr);
+ *kptr = tmp;
+
+ return 0;
+}
+
static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
unsigned long arg, void __user *p)
{
@@ -839,7 +860,6 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
struct uinput_ff_upload ff_up;
struct uinput_ff_erase ff_erase;
struct uinput_request *req;
- char *phys;
const char *name;
unsigned int size;
@@ -916,19 +936,8 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
goto out;
case UI_SET_PHYS:
- if (udev->state == UIST_CREATED) {
- retval = -EINVAL;
- goto out;
- }
-
- phys = strndup_user(p, 1024);
- if (IS_ERR(phys)) {
- retval = PTR_ERR(phys);
- goto out;
- }
-
- kfree(udev->dev->phys);
- udev->dev->phys = phys;
+ pr_warn_once("uinput: UI_SET_PHYS is deprecated. Use UI_SET_PHYS_STR");
+ retval = uinput_get_user_str(udev, &udev->dev->phys, p, 1024);
goto out;
case UI_BEGIN_FF_UPLOAD:
@@ -1023,6 +1032,15 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
case UI_ABS_SETUP & ~IOCSIZE_MASK:
retval = uinput_abs_setup(udev, p, size);
goto out;
+
+ case UI_SET_PHYS_STR(0):
+ retval = uinput_get_user_str(udev, &udev->dev->phys, p, size);
+ goto out;
+
+ case UI_SET_UNIQ_STR(0):
+ retval = uinput_get_user_str(udev, &udev->dev->uniq, p, size);
+ goto out;
+
}
retval = -EINVAL;
diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h
index c9e677e3af1d..84d4fa142830 100644
--- a/include/uapi/linux/uinput.h
+++ b/include/uapi/linux/uinput.h
@@ -142,9 +142,14 @@ struct uinput_abs_setup {
#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
+
+/* DEPRECATED: Data size is ambiguous. Use UI_SET_PHYS_STR instead. */
#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
+
#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
+#define UI_SET_PHYS_STR(len) _IOC(_IOC_WRITE, UINPUT_IOCTL_BASE, 111, len)
+#define UI_SET_UNIQ_STR(len) _IOC(_IOC_WRITE, UINPUT_IOCTL_BASE, 112, len)
#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)

View File

@ -1,15 +0,0 @@
cachyos/0001-cachyos-base-all.patch
cachyos/0001-bore-cachy.patch
# nobara/0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch
# nobara/0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch
# nobara/0001-Revert-nvme-pci-drop-redundant-pci_enable_pcie_error.patch
# nobara/0001-Set-amdgpu.ppfeaturemask-0xffffffff-as-default.patch
# nobara/0001-acpi-proc-idle-skip-dummy-wait.patch
# nobara/0001-add-acpi_call.patch
# nobara/amdgpu-si-cik-default.patch
# nobara/lenovo-legion-laptop.patch
# asuslinux/0001-platform-x86-asus-wmi-add-support-for-2024-ROG-Mini-.patch
# asuslinux/0002-platform-x86-asus-wmi-add-support-for-Vivobook-GPU-M.patch
# asuslinux/0003-platform-x86-asus-wmi-add-support-variant-of-TUF-RGB.patch
# asuslinux/0004-platform-x86-asus-wmi-support-toggling-POST-sound.patch
# asuslinux/0005-platform-x86-asus-wmi-store-a-min-default-for-ppt-op.patch

View File

@ -1,2 +1,2 @@
# send debs to server # send debs to server
rsync -azP --include './' --include '*.deb' --exclude '*' ./output/ ferreo@direct.pika-os.com:/srv/www/cockatiel-incoming/ rsync -azP --include './' --include '*.deb' --exclude '*' ./output/ ferreo@direct.pika-os.com:/srv/www/cockatiel-incoming/

49
scripts-v3/config.sh Executable file
View File

@ -0,0 +1,49 @@
#!/bin/bash
echo "Pika Kernel - Applying configuration"
scripts-v3/config -k -d CONFIG_GENERIC_CPU
scripts-v3/config -k -e CONFIG_GENERIC_CPU3
scripts-v3/config -e CACHY
scripts-v3/config -e SCHED_BORE
scripts-v3/config -e HZ_300 --set-val HZ 750
scripts-v3/config -d HZ_PERIODIC -d NO_HZ_IDLE -d CONTEXT_TRACKING_FORCE -e NO_HZ_FULL_NODEF -e NO_HZ_FULL -e NO_HZ -e NO_HZ_COMMON -e CONTEXT_TRACKING
scripts-v3/config -e PREEMPT_BUILD -d PREEMPT_NONE -d PREEMPT_VOLUNTARY -e PREEMPT -e PREEMPT_COUNT -e PREEMPTION -e PREEMPT_DYNAMIC
scripts-v3/config -d CC_OPTIMIZE_FOR_PERFORMANCE \
-e CC_OPTIMIZE_FOR_PERFORMANCE_O3
scripts-v3/config -m TCP_CONG_CUBIC \
-d DEFAULT_CUBIC \
-e TCP_CONG_BBR \
-e DEFAULT_BBR \
--set-str DEFAULT_TCP_CONG bbr
scripts-v3/config -m NET_SCH_FQ_CODEL \
-e NET_SCH_FQ \
-d DEFAULT_FQ_CODEL \
-e DEFAULT_FQ \
--set-str DEFAULT_NET_SCH fq
scripts-v3/config -e LRU_GEN -e LRU_GEN_ENABLED -d LRU_GEN_STATS
scripts-v3/config -d TRANSPARENT_HUGEPAGE_MADVISE -e TRANSPARENT_HUGEPAGE_ALWAYS
scripts-v3/config -e PER_VMA_LOCK -d PER_VMA_LOCK_STATS
scripts-v3/config -e DAMON \
-e DAMON_VADDR \
-e DAMON_DBGFS \
-e DAMON_SYSFS \
-e DAMON_PADDR \
-e DAMON_RECLAIM \
-e DAMON_LRU_SORT
scripts-v3/config --set-val MODULE_COMPRESS_ZSTD_LEVEL 19 -e MODULE_COMPRESS_ZSTD_ULTRA --set-val MODULE_COMPRESS_ZSTD_LEVEL_ULTRA 22 --set-val ZSTD_COMP_VAL 22
scripts-v3/config -e EFI_HANDOVER_PROTOCOL
scripts-v3/config -e USER_NS
make prepare

8
scripts-v3/patch.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
echo "Pika Kernel - Applying patches"
if [ -f ../patches/series ]
then
for i in $(cat ../patches/series | grep -v '^#') ; do echo "Applying Patch: $i" && patch -Np1 -i ../patches/$i || bash -c "echo "Applying Patch $i Failed!" && exit 2"; done
fi

View File

@ -1,51 +0,0 @@
#!/bin/bash
echo "Pika Kernel - Applying configuration"
cp ../config .config
scripts/config -k -d CONFIG_GENERIC_CPU
scripts/config -k -e CONFIG_GENERIC_CPU3
scripts/config -e CACHY
scripts/config -e SCHED_BORE
scripts/config -e HZ_300 --set-val HZ 750
scripts/config -d HZ_PERIODIC -d NO_HZ_IDLE -d CONTEXT_TRACKING_FORCE -e NO_HZ_FULL_NODEF -e NO_HZ_FULL -e NO_HZ -e NO_HZ_COMMON -e CONTEXT_TRACKING
scripts/config -e PREEMPT_BUILD -d PREEMPT_NONE -d PREEMPT_VOLUNTARY -e PREEMPT -e PREEMPT_COUNT -e PREEMPTION -e PREEMPT_DYNAMIC
scripts/config -d CC_OPTIMIZE_FOR_PERFORMANCE \
-e CC_OPTIMIZE_FOR_PERFORMANCE_O3
scripts/config -m TCP_CONG_CUBIC \
-d DEFAULT_CUBIC \
-e TCP_CONG_BBR \
-e DEFAULT_BBR \
--set-str DEFAULT_TCP_CONG bbr
scripts/config -m NET_SCH_FQ_CODEL \
-e NET_SCH_FQ \
-d DEFAULT_FQ_CODEL \
-e DEFAULT_FQ \
--set-str DEFAULT_NET_SCH fq
scripts/config -e LRU_GEN -e LRU_GEN_ENABLED -d LRU_GEN_STATS
scripts/config -d TRANSPARENT_HUGEPAGE_MADVISE -e TRANSPARENT_HUGEPAGE_ALWAYS
scripts/config -e PER_VMA_LOCK -d PER_VMA_LOCK_STATS
scripts/config -e DAMON \
-e DAMON_VADDR \
-e DAMON_DBGFS \
-e DAMON_SYSFS \
-e DAMON_PADDR \
-e DAMON_RECLAIM \
-e DAMON_LRU_SORT
scripts/config --set-val MODULE_COMPRESS_ZSTD_LEVEL 19 -e MODULE_COMPRESS_ZSTD_ULTRA --set-val MODULE_COMPRESS_ZSTD_LEVEL_ULTRA 22 --set-val ZSTD_COMP_VAL 22
scripts/config -e EFI_HANDOVER_PROTOCOL
scripts/config -e USER_NS
make prepare

View File

@ -1,5 +0,0 @@
#!/bin/bash
echo "Pika Kernel - Applying patches"
for i in $(cat ../patches/series | grep -v '^#') ; do echo "Applying Patch: $i" && patch -Np1 -i ../patches/$i || bash -c "echo "Applying Patch $i Failed!" && exit 2"; done