initial commit
This commit is contained in:
parent
f228835581
commit
727b576154
1
.github/ build-canary-v3
vendored
Normal file
1
.github/ build-canary-v3
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
1
|
1
.github/build-nest-v3
vendored
Normal file
1
.github/build-nest-v3
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
1
|
1
.github/release-canary-v3
vendored
Normal file
1
.github/release-canary-v3
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
4
|
1
.github/release-nest-v3
vendored
Normal file
1
.github/release-nest-v3
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
1
|
34
.github/workflows/build-canaryv3.yml
vendored
Normal file
34
.github/workflows/build-canaryv3.yml
vendored
Normal 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
34
.github/workflows/build-nestv3.yml
vendored
Normal 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
|
24
.github/workflows/build.yml
vendored
24
.github/workflows/build.yml
vendored
@ -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
37
.github/workflows/release-canaryv3.yml
vendored
Normal 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
37
.github/workflows/release-nestv3.yml
vendored
Normal 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
|
37
.github/workflows/release.yml
vendored
37
.github/workflows/release.yml
vendored
@ -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
|
|
7
main.sh
7
main.sh
@ -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
12
mainv3.sh
Executable 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
|
@ -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-----
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
@ -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(¶mCopy, 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(¶mCopy) != 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)
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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)
|
|
||||||
{
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
@ -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
@ -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[] = {
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
@ -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) {
|
|
@ -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
@ -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 |
|
|
@ -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
@ -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)
|
|
@ -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
|
|
@ -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
49
scripts-v3/config.sh
Executable 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
8
scripts-v3/patch.sh
Executable 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
|
@ -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
|
|
@ -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
|
|
Loading…
Reference in New Issue
Block a user