linux-valve-jupiter: new aport (MR 4885)

There are some important platform drivers that Valve has not upstreamed,
that are basically required for this device to operate well. I picked
those patches from the kernel tree they released for 6.5, and rebased
them onto 6.8.
This commit is contained in:
Clayton Craft 2024-03-04 11:01:07 -08:00
parent a2fef82d62
commit 46bf4695d7
No known key found for this signature in database
GPG key ID: 4A4CED6D7EDF950A
23 changed files with 10507 additions and 0 deletions

View file

@ -0,0 +1,117 @@
From 103895dd0c1106595c46e8cd61f5edea349e6f4c Mon Sep 17 00:00:00 2001
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Date: Fri, 4 Mar 2022 21:20:39 +0000
Subject: [PATCH 01/21] ACPICA: Limit error message flood caused by firmware
bug
The following error messages are generated because of an infinite
recursion in the latest production BIOS:
ACPI Error: Method reached maximum reentrancy limit (255) (20210331/dsmethod-309)
ACPI Error: Aborting method \_SB.PCI0.LPC0.EC0.VFCD.PDVL due to previous error (AE_AML_METHOD_LIMIT) (20210331/psparse-529)
[...]
ACPI Error: Aborting method \_SB.PCI0.LPC0.EC0.VFCD.PDVL due to previous error (AE_AML_METHOD_LIMIT) (20210331/psparse-529)
Let's detect this and limit the amount of errors generated.
Additionally, add a kernel parameter 'acpi_no_msg_flood_detect' to
disable the detection for debugging purposes.
https://gitlab.steamos.cloud/jupiter/linux-integration/-/issues/11
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/acpi/acpica/dsmethod.c | 5 ++--
drivers/acpi/acpica/uterror.c | 53 ++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
index e809c2aed78a..66267b1a3170 100644
--- a/drivers/acpi/acpica/dsmethod.c
+++ b/drivers/acpi/acpica/dsmethod.c
@@ -306,8 +306,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
/* Prevent wraparound of thread count */
if (obj_desc->method.thread_count == ACPI_UINT8_MAX) {
- ACPI_ERROR((AE_INFO,
- "Method reached maximum reentrancy limit (255)"));
+ /* Suppressing this due to firmware bug flooding the logs */
+ /*ACPI_ERROR((AE_INFO,
+ "Method reached maximum reentrancy limit (255)"));*/
return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
}
diff --git a/drivers/acpi/acpica/uterror.c b/drivers/acpi/acpica/uterror.c
index 918aca7c4db4..4a482de2e55d 100644
--- a/drivers/acpi/acpica/uterror.c
+++ b/drivers/acpi/acpica/uterror.c
@@ -278,6 +278,56 @@ acpi_ut_namespace_error(const char *module_name,
}
#endif
+/*******************************************************************************
+ *
+ * Limit the error message flood caused by a firmware bug:
+ *
+ * ACPI Error: Method reached maximum reentrancy limit (255) (20210331/dsmethod-309)
+ * ACPI Error: Aborting method \_SB.PCI0.LPC0.EC0.VFCD.PDVL due to previous error (AE_AML_METHOD_LIMIT) (20210331/psparse-529)
+ * [...]
+ * ACPI Error: Aborting method \_SB.PCI0.LPC0.EC0.VFCD.PDVL due to previous error (AE_AML_METHOD_LIMIT) (20210331/psparse-529)
+ *
+ ******************************************************************************/
+
+static bool acpi_disable_msg_flood_detect;
+
+static int __init acpi_no_msg_flood_detect_setup(char *s)
+{
+ acpi_disable_msg_flood_detect = true;
+ pr_info("ACPI error message flood detection disabled\n");
+
+ return 0;
+}
+
+early_param("acpi_no_msg_flood_detect", acpi_no_msg_flood_detect_setup);
+
+static bool acpi_skip_print_node(struct acpi_namespace_node *node)
+{
+ static bool skip_print = false;
+ struct acpi_buffer buffer;
+ acpi_status status;
+
+ if (acpi_disable_msg_flood_detect || !node)
+ return false;
+
+ if (!skip_print) {
+ /* Convert handle to full pathname */
+ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+ status = acpi_ns_handle_to_pathname(node, &buffer, TRUE);
+ if (ACPI_SUCCESS(status)) {
+ skip_print = !strcmp((const char *)buffer.pointer,
+ "\\_SB.PCI0.LPC0.EC0.VFCD.PDVL");
+ ACPI_FREE(buffer.pointer);
+
+ if (skip_print)
+ return false; /* print once */
+ }
+ }
+
+ return skip_print;
+}
+
/*******************************************************************************
*
* FUNCTION: acpi_ut_method_error
@@ -305,6 +355,9 @@ acpi_ut_method_error(const char *module_name,
acpi_status status;
struct acpi_namespace_node *node = prefix_node;
+ if (acpi_skip_print_node(node))
+ return;
+
ACPI_MSG_REDIRECT_BEGIN;
acpi_os_printf(ACPI_MSG_ERROR);
--
2.44.0

View file

@ -0,0 +1,41 @@
From 6122171153699e140375a99ad2b0cca7668617aa Mon Sep 17 00:00:00 2001
From: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com>
Date: Tue, 14 Jun 2022 14:31:18 -0700
Subject: [PATCH 02/21] drivers: video: backlight: Disable backlight
notification events.
We don't want to generate udev events for brightness changes on Steam Deck,
as some games like Celeste will re-enumerate controller devices in response
to this event.
Patch from Sam Lantinga.
(cherry picked from commit 85da5a5f7b69f22f960776cde3bf5862f3613363)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/video/backlight/backlight.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 86e1cdc8e369..06641d99c209 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -160,6 +160,7 @@ static inline void backlight_unregister_fb(struct backlight_device *bd)
static void backlight_generate_event(struct backlight_device *bd,
enum backlight_update_reason reason)
{
+#if 0 // We don't want to generate udev events for brightness changes on Steam Deck, as some games like Celeste will re-enumerate controller devices in response to this event.
char *envp[2];
switch (reason) {
@@ -175,6 +176,7 @@ static void backlight_generate_event(struct backlight_device *bd,
}
envp[1] = NULL;
kobject_uevent_env(&bd->dev.kobj, KOBJ_CHANGE, envp);
+#endif // 0
sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness");
}
--
2.44.0

View file

@ -0,0 +1,81 @@
From 046bbbde9257dd08a4433ebce76132a71b397294 Mon Sep 17 00:00:00 2001
From: Shreeya Patel <shreeya.patel@collabora.com>
Date: Mon, 17 Jul 2023 14:02:21 +0530
Subject: [PATCH 03/21] iio: light: ltrf216a: Return floating point values
For better precision of input light intesity, return floating point
values through sysfs instead of integer.
Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com>
(cherry picked from commit 13b313070846439805525ddb9f76dbf2b8de4300)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/iio/light/ltrf216a.c | 39 ++++++++++++------------------------
1 file changed, 13 insertions(+), 26 deletions(-)
diff --git a/drivers/iio/light/ltrf216a.c b/drivers/iio/light/ltrf216a.c
index 68dc48420a88..d2914252b99f 100644
--- a/drivers/iio/light/ltrf216a.c
+++ b/drivers/iio/light/ltrf216a.c
@@ -231,32 +231,13 @@ static int ltrf216a_read_data(struct ltrf216a_data *data, u8 addr)
return get_unaligned_le24(&buf[0]);
}
-static int ltrf216a_get_lux(struct ltrf216a_data *data)
-{
- int ret, greendata;
- u64 lux;
-
- ret = ltrf216a_set_power_state(data, true);
- if (ret)
- return ret;
-
- greendata = ltrf216a_read_data(data, LTRF216A_ALS_DATA_0);
- if (greendata < 0)
- return greendata;
-
- ltrf216a_set_power_state(data, false);
-
- lux = greendata * 45 * LTRF216A_WIN_FAC;
-
- return lux;
-}
-
static int ltrf216a_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
{
struct ltrf216a_data *data = iio_priv(indio_dev);
- int ret;
+ int ret, greendata;
+ u64 lux, div;
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -273,12 +254,18 @@ static int ltrf216a_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_PROCESSED:
mutex_lock(&data->lock);
- ret = ltrf216a_get_lux(data);
- mutex_unlock(&data->lock);
- if (ret < 0)
+ ret = ltrf216a_set_power_state(data, true);
+ if (ret)
return ret;
- *val = ret;
- *val2 = data->als_gain_fac * data->int_time_fac;
+ greendata = ltrf216a_read_data(data, LTRF216A_ALS_DATA_0);
+ if (greendata < 0)
+ return greendata;
+ ltrf216a_set_power_state(data, false);
+ lux = greendata * 45 * LTRF216A_WIN_FAC;
+ div = data->als_gain_fac * data->int_time_fac;
+ mutex_unlock(&data->lock);
+ *val = lux;
+ *val2 = div;
return IIO_VAL_FRACTIONAL;
case IIO_CHAN_INFO_INT_TIME:
mutex_lock(&data->lock);
--
2.44.0

View file

@ -0,0 +1,185 @@
From 4cc7f39b393b2a9531951bb6ac544a72ae2a3edf Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Sat, 19 Feb 2022 16:08:36 -0800
Subject: [PATCH 04/21] mfd: Add MFD core driver for Steam Deck
Add MFD core driver for Steam Deck. Doesn't really do much so far
besides instantiating a number of MFD cells that implement all the
interesting functionality.
(cherry picked from commit 5f534c2d6ebdefccb9c024eb0f013bc1c0c622d9)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/mfd/Kconfig | 11 ++++
drivers/mfd/Makefile | 2 +
drivers/mfd/steamdeck.c | 127 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 140 insertions(+)
create mode 100644 drivers/mfd/steamdeck.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index e7a6e45b9fac..31e2c95eca02 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2333,5 +2333,16 @@ config MFD_RSMU_SPI
Additional drivers must be enabled in order to use the functionality
of the device.
+config MFD_STEAMDECK
+ tristate "Valve Steam Deck"
+ select MFD_CORE
+ depends on ACPI
+ depends on X86_64 || COMPILE_TEST
+ help
+ This driver registers various MFD cells that expose aspects
+ of Steam Deck specific ACPI functionality.
+
+ Say N here, unless you are running on Steam Deck hardware.
+
endmenu
endif
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c66f07edcd0e..2bbdf4127232 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -284,3 +284,5 @@ rsmu-i2c-objs := rsmu_core.o rsmu_i2c.o
rsmu-spi-objs := rsmu_core.o rsmu_spi.o
obj-$(CONFIG_MFD_RSMU_I2C) += rsmu-i2c.o
obj-$(CONFIG_MFD_RSMU_SPI) += rsmu-spi.o
+
+obj-$(CONFIG_MFD_STEAMDECK) += steamdeck.o
diff --git a/drivers/mfd/steamdeck.c b/drivers/mfd/steamdeck.c
new file mode 100644
index 000000000000..0e504b3c2796
--- /dev/null
+++ b/drivers/mfd/steamdeck.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Steam Deck EC MFD core driver
+ *
+ * Copyright (C) 2021-2022 Valve Corporation
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+
+#define STEAMDECK_STA_OK \
+ (ACPI_STA_DEVICE_ENABLED | \
+ ACPI_STA_DEVICE_PRESENT | \
+ ACPI_STA_DEVICE_FUNCTIONING)
+
+struct steamdeck {
+ struct acpi_device *adev;
+ struct device *dev;
+};
+
+#define STEAMDECK_ATTR_RO(_name, _method) \
+ static ssize_t _name##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ struct steamdeck *sd = dev_get_drvdata(dev); \
+ unsigned long long val; \
+ \
+ if (ACPI_FAILURE(acpi_evaluate_integer( \
+ sd->adev->handle, \
+ _method, NULL, &val))) \
+ return -EIO; \
+ \
+ return sysfs_emit(buf, "%llu\n", val); \
+ } \
+ static DEVICE_ATTR_RO(_name)
+
+STEAMDECK_ATTR_RO(firmware_version, "PDFW");
+STEAMDECK_ATTR_RO(board_id, "BOID");
+
+static struct attribute *steamdeck_attrs[] = {
+ &dev_attr_firmware_version.attr,
+ &dev_attr_board_id.attr,
+ NULL
+};
+
+ATTRIBUTE_GROUPS(steamdeck);
+
+static const struct mfd_cell steamdeck_cells[] = {
+ { .name = "steamdeck-hwmon" },
+ { .name = "steamdeck-leds" },
+ { .name = "steamdeck-extcon" },
+};
+
+static void steamdeck_remove_sysfs_groups(void *data)
+{
+ struct steamdeck *sd = data;
+
+ sysfs_remove_groups(&sd->dev->kobj, steamdeck_groups);
+}
+
+static int steamdeck_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ unsigned long long sta;
+ struct steamdeck *sd;
+ acpi_status status;
+ int ret;
+
+ sd = devm_kzalloc(dev, sizeof(*sd), GFP_KERNEL);
+ if (!sd)
+ return -ENOMEM;
+ sd->adev = ACPI_COMPANION(dev);
+ sd->dev = dev;
+ platform_set_drvdata(pdev, sd);
+
+ status = acpi_evaluate_integer(sd->adev->handle, "_STA",
+ NULL, &sta);
+ if (ACPI_FAILURE(status)) {
+ dev_err(dev, "Status check failed (0x%x)\n", status);
+ return -EINVAL;
+ }
+
+ if ((sta & STEAMDECK_STA_OK) != STEAMDECK_STA_OK) {
+ dev_err(dev, "Device is not ready\n");
+ return -EINVAL;
+ }
+
+ ret = sysfs_create_groups(&dev->kobj, steamdeck_groups);
+ if (ret) {
+ dev_err(dev, "Failed to create sysfs group\n");
+ return ret;
+ }
+
+ ret = devm_add_action_or_reset(dev, steamdeck_remove_sysfs_groups,
+ sd);
+ if (ret) {
+ dev_err(dev, "Failed to register devres action\n");
+ return ret;
+ }
+
+ return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
+ steamdeck_cells, ARRAY_SIZE(steamdeck_cells),
+ NULL, 0, NULL);
+}
+
+static const struct acpi_device_id steamdeck_device_ids[] = {
+ { "VLV0100", 0 },
+ { "", 0 },
+};
+MODULE_DEVICE_TABLE(acpi, steamdeck_device_ids);
+
+static struct platform_driver steamdeck_driver = {
+ .probe = steamdeck_probe,
+ .driver = {
+ .name = "steamdeck",
+ .acpi_match_table = steamdeck_device_ids,
+ },
+};
+module_platform_driver(steamdeck_driver);
+
+MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
+MODULE_DESCRIPTION("Steam Deck EC MFD core driver");
+MODULE_LICENSE("GPL");
--
2.44.0

View file

@ -0,0 +1,283 @@
From 498c8379bae238aca5707308652e0834e1f6de7a Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Sat, 19 Feb 2022 16:09:45 -0800
Subject: [PATCH 05/21] hwmon: Add driver for Steam Deck's EC sensors
Add driver for sensors exposed by EC firmware on Steam Deck hardware.
(cherry picked from commit 6917aac77bee6185ae3920b936cdbe7876118c0b)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/hwmon/Kconfig | 11 ++
drivers/hwmon/Makefile | 1 +
drivers/hwmon/steamdeck-hwmon.c | 224 ++++++++++++++++++++++++++++++++
3 files changed, 236 insertions(+)
create mode 100644 drivers/hwmon/steamdeck-hwmon.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index a608264da87d..cf0fc2ce1017 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1974,6 +1974,17 @@ config SENSORS_SCH5636
This driver can also be built as a module. If so, the module
will be called sch5636.
+config SENSORS_STEAMDECK
+ tristate "Steam Deck EC sensors"
+ depends on MFD_STEAMDECK
+ help
+ If you say yes here you get support for the hardware
+ monitoring features exposed by EC firmware on Steam Deck
+ devices
+
+ This driver can also be built as a module. If so, the module
+ will be called steamdeck-hwmon.
+
config SENSORS_STTS751
tristate "ST Microelectronics STTS751"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 47be39af5c03..b1cc9112a0a6 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -200,6 +200,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o
+obj-$(CONFIG_SENSORS_STEAMDECK) += steamdeck-hwmon.o
obj-$(CONFIG_SENSORS_STTS751) += stts751.o
obj-$(CONFIG_SENSORS_SY7636A) += sy7636a-hwmon.o
obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o
diff --git a/drivers/hwmon/steamdeck-hwmon.c b/drivers/hwmon/steamdeck-hwmon.c
new file mode 100644
index 000000000000..fab9e9460bd4
--- /dev/null
+++ b/drivers/hwmon/steamdeck-hwmon.c
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Steam Deck EC sensors driver
+ *
+ * Copyright (C) 2021-2022 Valve Corporation
+ */
+
+#include <linux/acpi.h>
+#include <linux/hwmon.h>
+#include <linux/platform_device.h>
+
+#define STEAMDECK_HWMON_NAME "steamdeck-hwmon"
+
+struct steamdeck_hwmon {
+ struct acpi_device *adev;
+};
+
+static long
+steamdeck_hwmon_get(struct steamdeck_hwmon *sd, const char *method)
+{
+ unsigned long long val;
+ if (ACPI_FAILURE(acpi_evaluate_integer(sd->adev->handle,
+ (char *)method, NULL, &val)))
+ return -EIO;
+
+ return val;
+}
+
+static int
+steamdeck_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *out)
+{
+ struct steamdeck_hwmon *sd = dev_get_drvdata(dev);
+
+ switch (type) {
+ case hwmon_curr:
+ if (attr != hwmon_curr_input)
+ return -EOPNOTSUPP;
+
+ *out = steamdeck_hwmon_get(sd, "PDAM");
+ if (*out < 0)
+ return *out;
+ break;
+ case hwmon_in:
+ if (attr != hwmon_in_input)
+ return -EOPNOTSUPP;
+
+ *out = steamdeck_hwmon_get(sd, "PDVL");
+ if (*out < 0)
+ return *out;
+ break;
+ case hwmon_temp:
+ if (attr != hwmon_temp_input)
+ return -EOPNOTSUPP;
+
+ *out = steamdeck_hwmon_get(sd, "BATT");
+ if (*out < 0)
+ return *out;
+ /*
+ * Assuming BATT returns deg C we need to mutiply it
+ * by 1000 to convert to mC
+ */
+ *out *= 1000;
+ break;
+ case hwmon_fan:
+ switch (attr) {
+ case hwmon_fan_input:
+ *out = steamdeck_hwmon_get(sd, "FANR");
+ if (*out < 0)
+ return *out;
+ break;
+ case hwmon_fan_target:
+ *out = steamdeck_hwmon_get(sd, "FSSR");
+ if (*out < 0)
+ return *out;
+ break;
+ case hwmon_fan_fault:
+ *out = steamdeck_hwmon_get(sd, "FANC");
+ if (*out < 0)
+ return *out;
+ /*
+ * FANC (Fan check):
+ * 0: Abnormal
+ * 1: Normal
+ */
+ *out = !*out;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int
+steamdeck_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, const char **str)
+{
+ switch (type) {
+ /*
+ * These two aren't, strictly speaking, measured. EC
+ * firmware just reports what PD negotiation resulted
+ * in.
+ */
+ case hwmon_curr:
+ *str = "PD Contract Current";
+ break;
+ case hwmon_in:
+ *str = "PD Contract Voltage";
+ break;
+ case hwmon_temp:
+ *str = "Battery Temp";
+ break;
+ case hwmon_fan:
+ *str = "System Fan";
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int
+steamdeck_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long val)
+{
+ struct steamdeck_hwmon *sd = dev_get_drvdata(dev);
+
+ if (type != hwmon_fan ||
+ attr != hwmon_fan_target)
+ return -EOPNOTSUPP;
+
+ val = clamp_val(val, 0, 7300);
+
+ if (ACPI_FAILURE(acpi_execute_simple_method(sd->adev->handle,
+ "FANS", val)))
+ return -EIO;
+
+ return 0;
+}
+
+static umode_t
+steamdeck_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ if (type == hwmon_fan &&
+ attr == hwmon_fan_target)
+ return 0644;
+
+ return 0444;
+}
+
+static const struct hwmon_channel_info *steamdeck_hwmon_info[] = {
+ HWMON_CHANNEL_INFO(in,
+ HWMON_I_INPUT | HWMON_I_LABEL),
+ HWMON_CHANNEL_INFO(curr,
+ HWMON_C_INPUT | HWMON_C_LABEL),
+ HWMON_CHANNEL_INFO(temp,
+ HWMON_T_INPUT | HWMON_T_LABEL),
+ HWMON_CHANNEL_INFO(fan,
+ HWMON_F_INPUT | HWMON_F_LABEL |
+ HWMON_F_TARGET | HWMON_F_FAULT),
+ NULL
+};
+
+static const struct hwmon_ops steamdeck_hwmon_ops = {
+ .is_visible = steamdeck_hwmon_is_visible,
+ .read = steamdeck_hwmon_read,
+ .read_string = steamdeck_hwmon_read_string,
+ .write = steamdeck_hwmon_write,
+};
+
+static const struct hwmon_chip_info steamdeck_hwmon_chip_info = {
+ .ops = &steamdeck_hwmon_ops,
+ .info = steamdeck_hwmon_info,
+};
+
+static int steamdeck_hwmon_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct steamdeck_hwmon *sd;
+ struct device *hwmon;
+
+ sd = devm_kzalloc(dev, sizeof(*sd), GFP_KERNEL);
+ if (!sd)
+ return -ENOMEM;
+
+ sd->adev = ACPI_COMPANION(dev->parent);
+ hwmon = devm_hwmon_device_register_with_info(dev,
+ "steamdeck_hwmon",
+ sd,
+ &steamdeck_hwmon_chip_info,
+ NULL);
+ if (IS_ERR(hwmon)) {
+ dev_err(dev, "Failed to register HWMON device");
+ return PTR_ERR(hwmon);
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id steamdeck_hwmon_id_table[] = {
+ { .name = STEAMDECK_HWMON_NAME },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, steamdeck_hwmon_id_table);
+
+static struct platform_driver steamdeck_hwmon_driver = {
+ .probe = steamdeck_hwmon_probe,
+ .driver = {
+ .name = STEAMDECK_HWMON_NAME,
+ },
+ .id_table = steamdeck_hwmon_id_table,
+};
+module_platform_driver(steamdeck_hwmon_driver);
+
+MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
+MODULE_DESCRIPTION("Steam Deck EC sensors driver");
+MODULE_LICENSE("GPL");
--
2.44.0

View file

@ -0,0 +1,127 @@
From 497ad3272c2d94687d1300517aff7da599d98232 Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Sun, 27 Feb 2022 12:58:05 -0800
Subject: [PATCH 06/21] leds: steamdeck: Add support for Steam Deck LED
(cherry picked from commit 85a86d19aa7022ff0555023d53aef78323a42d0c)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/leds/Kconfig | 7 ++++
drivers/leds/Makefile | 1 +
drivers/leds/leds-steamdeck.c | 74 +++++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+)
create mode 100644 drivers/leds/leds-steamdeck.c
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index d721b254e1e4..673b751f625b 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -917,6 +917,13 @@ config LEDS_ACER_A500
This option enables support for the Power Button LED of
Acer Iconia Tab A500.
+config LEDS_STEAMDECK
+ tristate "LED support for Steam Deck"
+ depends on LEDS_CLASS && MFD_STEAMDECK
+ help
+ This option enabled support for the status LED (next to the
+ power button) on Steam Deck
+
source "drivers/leds/blink/Kconfig"
comment "Flash and Torch LED drivers"
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index ce07dc295ff0..8b1be8945a57 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -79,6 +79,7 @@ obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o
obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o
+obj-$(CONFIG_LEDS_STEAMDECK) += leds-steamdeck.o
obj-$(CONFIG_LEDS_SUN50I_A100) += leds-sun50i-a100.o
obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o
obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o
diff --git a/drivers/leds/leds-steamdeck.c b/drivers/leds/leds-steamdeck.c
new file mode 100644
index 000000000000..686500b8de73
--- /dev/null
+++ b/drivers/leds/leds-steamdeck.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Steam Deck EC MFD LED cell driver
+ *
+ * Copyright (C) 2021-2022 Valve Corporation
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+struct steamdeck_led {
+ struct acpi_device *adev;
+ struct led_classdev cdev;
+};
+
+static int steamdeck_leds_brightness_set(struct led_classdev *cdev,
+ enum led_brightness value)
+{
+ struct steamdeck_led *sd = container_of(cdev, struct steamdeck_led,
+ cdev);
+
+ if (ACPI_FAILURE(acpi_execute_simple_method(sd->adev->handle,
+ "CHBV", value)))
+ return -EIO;
+
+ return 0;
+}
+
+static int steamdeck_leds_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct steamdeck_led *sd;
+ int ret;
+
+ sd = devm_kzalloc(dev, sizeof(*sd), GFP_KERNEL);
+ if (!sd)
+ return -ENOMEM;
+
+ sd->adev = ACPI_COMPANION(dev->parent);
+
+ sd->cdev.name = "status:white";
+ sd->cdev.brightness_set_blocking = steamdeck_leds_brightness_set;
+ sd->cdev.max_brightness = 100;
+
+ ret = devm_led_classdev_register(dev, &sd->cdev);
+ if (ret) {
+ dev_err(dev, "Failed to register LEDs device: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id steamdeck_leds_id_table[] = {
+ { .name = "steamdeck-leds" },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, steamdeck_leds_id_table);
+
+static struct platform_driver steamdeck_leds_driver = {
+ .probe = steamdeck_leds_probe,
+ .driver = {
+ .name = "steamdeck-leds",
+ },
+ .id_table = steamdeck_leds_id_table,
+};
+module_platform_driver(steamdeck_leds_driver);
+
+MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
+MODULE_DESCRIPTION("Steam Deck LEDs driver");
+MODULE_LICENSE("GPL");
--
2.44.0

View file

@ -0,0 +1,229 @@
From d29a5ac61f85c4dbdb553b0aae6c0700ccb46872 Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Sun, 27 Feb 2022 14:46:08 -0800
Subject: [PATCH 07/21] extcon: Add driver for Steam Deck
(cherry picked from commit f9f2eddae582ae39d5f89c1218448fc259b90aa8)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/extcon/Kconfig | 7 ++
drivers/extcon/Makefile | 1 +
drivers/extcon/extcon-steamdeck.c | 180 ++++++++++++++++++++++++++++++
3 files changed, 188 insertions(+)
create mode 100644 drivers/extcon/extcon-steamdeck.c
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index 5f869eacd19a..90f51661a489 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -202,4 +202,11 @@ config EXTCON_RTK_TYPE_C
The DHC (Digital Home Hub) RTD series SoC contains a type c module.
This driver will detect the status of the type-c port.
+config EXTCON_STEAMDECK
+ tristate "Steam Deck extcon support"
+ depends on MFD_STEAMDECK
+ help
+ Say Y here to enable support of USB Type C cable detection extcon
+ support on Steam Deck devices
+
endif
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile
index f779adb5e4c7..c7f3c908b329 100644
--- a/drivers/extcon/Makefile
+++ b/drivers/extcon/Makefile
@@ -25,4 +25,5 @@ obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o
obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o
obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o
obj-$(CONFIG_EXTCON_USBC_TUSB320) += extcon-usbc-tusb320.o
+obj-$(CONFIG_EXTCON_STEAMDECK) += extcon-steamdeck.o
obj-$(CONFIG_EXTCON_RTK_TYPE_C) += extcon-rtk-type-c.o
diff --git a/drivers/extcon/extcon-steamdeck.c b/drivers/extcon/extcon-steamdeck.c
new file mode 100644
index 000000000000..74f190adc8ea
--- /dev/null
+++ b/drivers/extcon/extcon-steamdeck.c
@@ -0,0 +1,180 @@
+
+#include <linux/acpi.h>
+#include <linux/platform_device.h>
+#include <linux/extcon-provider.h>
+
+#define ACPI_STEAMDECK_NOTIFY_STATUS 0x80
+
+/* 0 - port connected, 1 -port disconnected */
+#define ACPI_STEAMDECK_PORT_CONNECT BIT(0)
+/* 0 - Upstream Facing Port, 1 - Downdstream Facing Port */
+#define ACPI_STEAMDECK_CUR_DATA_ROLE BIT(3)
+/*
+ * Debouncing delay to allow negotiation process to settle. 2s value
+ * was arrived at via trial and error.
+ */
+#define STEAMDECK_ROLE_SWITCH_DELAY (msecs_to_jiffies(2000))
+
+struct steamdeck_extcon {
+ struct acpi_device *adev;
+ struct delayed_work role_work;
+ struct extcon_dev *edev;
+ struct device *dev;
+};
+
+static int steamdeck_read_pdcs(struct steamdeck_extcon *sd, unsigned long long *pdcs)
+{
+ acpi_status status;
+
+ status = acpi_evaluate_integer(sd->adev->handle, "PDCS", NULL, pdcs);
+ if (ACPI_FAILURE(status)) {
+ dev_err(sd->dev, "PDCS evaluation failed: %s\n",
+ acpi_format_exception(status));
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void steamdeck_usb_role_work(struct work_struct *work)
+{
+ struct steamdeck_extcon *sd =
+ container_of(work, struct steamdeck_extcon, role_work.work);
+ unsigned long long pdcs;
+ bool usb_host;
+
+ if (steamdeck_read_pdcs(sd, &pdcs))
+ return;
+
+ /*
+ * We only care about these two
+ */
+ pdcs &= ACPI_STEAMDECK_PORT_CONNECT | ACPI_STEAMDECK_CUR_DATA_ROLE;
+
+ /*
+ * For "connect" events our role is determined by a bit in
+ * PDCS, for "disconnect" we switch to being a gadget
+ * unconditionally. The thinking for the latter is we don't
+ * want to start acting as a USB host until we get
+ * confirmation from the firmware that we are a USB host
+ */
+ usb_host = (pdcs & ACPI_STEAMDECK_PORT_CONNECT) ?
+ pdcs & ACPI_STEAMDECK_CUR_DATA_ROLE : false;
+
+ dev_dbg(sd->dev, "USB role is %s\n", usb_host ? "host" : "device");
+ WARN_ON(extcon_set_state_sync(sd->edev, EXTCON_USB_HOST,
+ usb_host));
+
+}
+
+static void steamdeck_notify(acpi_handle handle, u32 event, void *context)
+{
+ struct device *dev = context;
+ struct steamdeck_extcon *sd = dev_get_drvdata(dev);
+ unsigned long long pdcs;
+ unsigned long delay;
+
+ switch (event) {
+ case ACPI_STEAMDECK_NOTIFY_STATUS:
+ if (steamdeck_read_pdcs(sd, &pdcs))
+ return;
+ /*
+ * We process "disconnect" events immediately and
+ * "connect" events with a delay to give the HW time
+ * to settle. For example attaching USB hub (at least
+ * for HW used for testing) will generate intermediary
+ * event with "host" bit not set, followed by the one
+ * that does have it set.
+ */
+ delay = (pdcs & ACPI_STEAMDECK_PORT_CONNECT) ?
+ STEAMDECK_ROLE_SWITCH_DELAY : 0;
+
+ queue_delayed_work(system_long_wq, &sd->role_work, delay);
+ break;
+ default:
+ dev_warn(dev, "Unsupported event [0x%x]\n", event);
+ }
+}
+
+static void steamdeck_remove_notify_handler(void *data)
+{
+ struct steamdeck_extcon *sd = data;
+
+ acpi_remove_notify_handler(sd->adev->handle, ACPI_DEVICE_NOTIFY,
+ steamdeck_notify);
+ cancel_delayed_work_sync(&sd->role_work);
+}
+
+static const unsigned int steamdeck_extcon_cable[] = {
+ EXTCON_USB,
+ EXTCON_USB_HOST,
+ EXTCON_CHG_USB_SDP,
+ EXTCON_CHG_USB_CDP,
+ EXTCON_CHG_USB_DCP,
+ EXTCON_CHG_USB_ACA,
+ EXTCON_NONE,
+};
+
+static int steamdeck_extcon_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct steamdeck_extcon *sd;
+ acpi_status status;
+ int ret;
+
+ sd = devm_kzalloc(dev, sizeof(*sd), GFP_KERNEL);
+ if (!sd)
+ return -ENOMEM;
+
+ INIT_DELAYED_WORK(&sd->role_work, steamdeck_usb_role_work);
+ platform_set_drvdata(pdev, sd);
+ sd->adev = ACPI_COMPANION(dev->parent);
+ sd->dev = dev;
+ sd->edev = devm_extcon_dev_allocate(dev, steamdeck_extcon_cable);
+ if (IS_ERR(sd->edev))
+ return PTR_ERR(sd->edev);
+
+ ret = devm_extcon_dev_register(dev, sd->edev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to register extcon device: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * Set initial role value
+ */
+ queue_delayed_work(system_long_wq, &sd->role_work, 0);
+ flush_delayed_work(&sd->role_work);
+
+ status = acpi_install_notify_handler(sd->adev->handle,
+ ACPI_DEVICE_NOTIFY,
+ steamdeck_notify,
+ dev);
+ if (ACPI_FAILURE(status)) {
+ dev_err(dev, "Error installing ACPI notify handler\n");
+ return -EIO;
+ }
+
+ ret = devm_add_action_or_reset(dev, steamdeck_remove_notify_handler,
+ sd);
+ return ret;
+}
+
+static const struct platform_device_id steamdeck_extcon_id_table[] = {
+ { .name = "steamdeck-extcon" },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, steamdeck_extcon_id_table);
+
+static struct platform_driver steamdeck_extcon_driver = {
+ .probe = steamdeck_extcon_probe,
+ .driver = {
+ .name = "steamdeck-extcon",
+ },
+ .id_table = steamdeck_extcon_id_table,
+};
+module_platform_driver(steamdeck_extcon_driver);
+
+MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
+MODULE_DESCRIPTION("Steam Deck extcon driver");
+MODULE_LICENSE("GPL");
--
2.44.0

View file

@ -0,0 +1,108 @@
From 666399155bd11608017e09f0bbda0181119d6206 Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Sat, 15 Jul 2023 12:58:54 -0700
Subject: [PATCH 08/21] hwmon: steamdeck-hwmon: Add support for max battery
level/rate
Add support for max battery level/charge rate attributes.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
(cherry picked from commit 50af83e8fd75dc52221edd3fb6fd7a7f70c4d8a4)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/hwmon/steamdeck-hwmon.c | 72 ++++++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/steamdeck-hwmon.c b/drivers/hwmon/steamdeck-hwmon.c
index fab9e9460bd4..9d0a5471b181 100644
--- a/drivers/hwmon/steamdeck-hwmon.c
+++ b/drivers/hwmon/steamdeck-hwmon.c
@@ -180,6 +180,76 @@ static const struct hwmon_chip_info steamdeck_hwmon_chip_info = {
.info = steamdeck_hwmon_info,
};
+
+static ssize_t
+steamdeck_hwmon_simple_store(struct device *dev, const char *buf, size_t count,
+ const char *method,
+ unsigned long upper_limit)
+{
+ struct steamdeck_hwmon *sd = dev_get_drvdata(dev);
+ unsigned long value;
+
+ if (kstrtoul(buf, 10, &value) || value >= upper_limit)
+ return -EINVAL;
+
+ if (ACPI_FAILURE(acpi_execute_simple_method(sd->adev->handle,
+ (char *)method, value)))
+ return -EIO;
+
+ return count;
+}
+
+static ssize_t
+steamdeck_hwmon_simple_show(struct device *dev, char *buf,
+ const char *method)
+{
+ struct steamdeck_hwmon *sd = dev_get_drvdata(dev);
+ unsigned long value;
+
+ value = steamdeck_hwmon_get(sd, method);
+ if (value < 0)
+ return value;
+
+ return sprintf(buf, "%ld\n", value);
+}
+
+#define STEAMDECK_HWMON_ATTR_RW(_name, _set_method, _get_method, \
+ _upper_limit) \
+ static ssize_t _name##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ return steamdeck_hwmon_simple_show(dev, buf, \
+ _get_method); \
+ } \
+ static ssize_t _name##_store(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+ { \
+ return steamdeck_hwmon_simple_store(dev, buf, count, \
+ _set_method, \
+ _upper_limit); \
+ } \
+ static DEVICE_ATTR_RW(_name)
+
+STEAMDECK_HWMON_ATTR_RW(max_battery_charge_level, "FCBL", "SFBL", 101);
+STEAMDECK_HWMON_ATTR_RW(max_battery_charge_rate, "CHGR", "GCHR", 101);
+
+static struct attribute *steamdeck_hwmon_attributes[] = {
+ &dev_attr_max_battery_charge_level.attr,
+ &dev_attr_max_battery_charge_rate.attr,
+ NULL
+};
+
+static const struct attribute_group steamdeck_hwmon_group = {
+ .attrs = steamdeck_hwmon_attributes,
+};
+
+static const struct attribute_group *steamdeck_hwmon_groups[] = {
+ &steamdeck_hwmon_group,
+ NULL
+};
+
static int steamdeck_hwmon_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -195,7 +265,7 @@ static int steamdeck_hwmon_probe(struct platform_device *pdev)
"steamdeck_hwmon",
sd,
&steamdeck_hwmon_chip_info,
- NULL);
+ steamdeck_hwmon_groups);
if (IS_ERR(hwmon)) {
dev_err(dev, "Failed to register HWMON device");
return PTR_ERR(hwmon);
--
2.44.0

View file

@ -0,0 +1,53 @@
From 7b9a162071ee2bf519336b70dccdf2954d881892 Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Sun, 24 Sep 2023 15:02:33 -0700
Subject: [PATCH 09/21] mfd: steamdeck: Expose controller board power in sysfs
As of version 118 Deck's BIOS implements "SCBP" method that allows
gating power of the controller board (VBUS). Add a basic WO method to
our root MFD device to allow toggling that.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
(cherry picked from commit f97f32718acc10cbb51fef925842392e80904d74)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/mfd/steamdeck.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/mfd/steamdeck.c b/drivers/mfd/steamdeck.c
index 0e504b3c2796..a60fa7db9141 100644
--- a/drivers/mfd/steamdeck.c
+++ b/drivers/mfd/steamdeck.c
@@ -41,9 +41,29 @@ struct steamdeck {
STEAMDECK_ATTR_RO(firmware_version, "PDFW");
STEAMDECK_ATTR_RO(board_id, "BOID");
+static ssize_t controller_board_power_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct steamdeck *sd = dev_get_drvdata(dev);
+ bool enabled;
+ ssize_t ret = kstrtobool(buf, &enabled);
+
+ if (ret)
+ return ret;
+
+ if (ACPI_FAILURE(acpi_execute_simple_method(sd->adev->handle,
+ "SCBP", enabled)))
+ return -EIO;
+
+ return count;
+}
+static DEVICE_ATTR_WO(controller_board_power);
+
static struct attribute *steamdeck_attrs[] = {
&dev_attr_firmware_version.attr,
&dev_attr_board_id.attr,
+ &dev_attr_controller_board_power.attr,
NULL
};
--
2.44.0

View file

@ -0,0 +1,163 @@
From 1fba949e975caea1a568124ad9f417daa989dc80 Mon Sep 17 00:00:00 2001
From: Steven Noonan <steven@uplinklabs.net>
Date: Wed, 17 Nov 2021 00:25:26 -0800
Subject: [PATCH 10/21] x86: implement tsc=directsync for systems without
IA32_TSC_ADJUST
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
[fwd-port to v6.5]
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
.../admin-guide/kernel-parameters.txt | 2 +
arch/x86/include/asm/tsc.h | 1 +
arch/x86/kernel/tsc.c | 3 ++
arch/x86/kernel/tsc_sync.c | 48 +++++++++++++++----
4 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 31b3a25680d0..8243a9c96031 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -6727,6 +6727,8 @@
This will be suppressed by an earlier tsc=nowatchdog and
can be overridden by a later tsc=nowatchdog. A console
message will flag any such suppression or overriding.
+ [x86] directsync: attempt to sync the tsc via direct
+ writes if MSR_IA32_TSC_ADJUST isn't available
tsc_early_khz= [X86] Skip early TSC calibration and use the given
value instead. Useful when the early TSC frequency discovery
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index 594fce0ca744..529dc6d4a426 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -41,6 +41,7 @@ extern unsigned long native_calibrate_tsc(void);
extern unsigned long long native_sched_clock_from_tsc(u64 tsc);
extern int tsc_clocksource_reliable;
+extern int tsc_allow_direct_sync;
#ifdef CONFIG_X86_TSC
extern bool tsc_async_resets;
#else
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 15f97c0abc9d..9cf8f85c5638 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -47,6 +47,7 @@ static unsigned int __initdata tsc_early_khz;
static DEFINE_STATIC_KEY_FALSE(__use_tsc);
int tsc_clocksource_reliable;
+int tsc_allow_direct_sync;
static int __read_mostly tsc_force_recalibrate;
@@ -339,6 +340,8 @@ static int __init tsc_setup(char *str)
else
tsc_as_watchdog = 1;
}
+ if (!strcmp(str, "directsync"))
+ tsc_allow_direct_sync = 1;
return 1;
}
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index 1123ef3ccf90..5a553feaef76 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -33,6 +33,8 @@ struct tsc_adjust {
static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust);
static struct timer_list tsc_sync_check_timer;
+extern int tsc_allow_direct_sync;
+
/*
* TSC's on different sockets may be reset asynchronously.
* This may cause the TSC ADJUST value on socket 0 to be NOT 0.
@@ -340,6 +342,8 @@ static cycles_t check_tsc_warp(unsigned int timeout)
*/
static inline unsigned int loop_timeout(int cpu)
{
+ if (!boot_cpu_has(X86_FEATURE_TSC_ADJUST))
+ return 30;
return (cpumask_weight(topology_core_cpumask(cpu)) > 1) ? 2 : 20;
}
@@ -360,13 +364,16 @@ static void check_tsc_sync_source(void *__cpu)
/*
* Set the maximum number of test runs to
- * 1 if the CPU does not provide the TSC_ADJUST MSR
- * 3 if the MSR is available, so the target can try to adjust
+ * 5 if we can write TSC_ADJUST to compensate
+ * 1000 if we are allowed to write to the TSC MSR to compensate
+ * 1 if we cannot write MSRs to synchronize TSCs
*/
- if (!boot_cpu_has(X86_FEATURE_TSC_ADJUST))
- atomic_set(&test_runs, 1);
- else
+ if (boot_cpu_has(X86_FEATURE_TSC_ADJUST))
atomic_set(&test_runs, 3);
+ else if (tsc_allow_direct_sync)
+ atomic_set(&test_runs, 1000);
+ else
+ atomic_set(&test_runs, 1);
retry:
/* Wait for the target to start. */
while (atomic_read(&start_count) != cpus - 1)
@@ -427,6 +434,21 @@ static void check_tsc_sync_source(void *__cpu)
goto retry;
}
+static inline cycles_t write_tsc_adjustment(s64 adjustment)
+{
+ cycles_t adjval, nextval;
+
+ rdmsrl(MSR_IA32_TSC, adjval);
+ adjval += adjustment;
+ wrmsrl(MSR_IA32_TSC, adjval);
+ rdmsrl(MSR_IA32_TSC, nextval);
+
+ /*
+ * Estimated clock cycle overhead for wrmsr + rdmsr
+ */
+ return nextval - adjval;
+}
+
/*
* Freshly booted CPUs call into this:
*/
@@ -434,7 +456,7 @@ void check_tsc_sync_target(void)
{
struct tsc_adjust *cur = this_cpu_ptr(&tsc_adjust);
unsigned int cpu = smp_processor_id();
- cycles_t cur_max_warp, gbl_max_warp;
+ cycles_t cur_max_warp, gbl_max_warp, est_overhead = 0;
int cpus = 2;
/* Also aborts if there is no TSC. */
@@ -515,12 +537,18 @@ void check_tsc_sync_target(void)
* value is used. In the worst case the adjustment needs to go
* through a 3rd run for fine tuning.
*/
- cur->adjusted += cur_max_warp;
+ if (boot_cpu_has(X86_FEATURE_TSC_ADJUST)) {
+ cur->adjusted += cur_max_warp + est_overhead;
- pr_warn("TSC ADJUST compensate: CPU%u observed %lld warp. Adjust: %lld\n",
- cpu, cur_max_warp, cur->adjusted);
+ pr_warn("TSC ADJUST compensate: CPU%u observed %lld warp. Adjust: %lld\n",
+ cpu, cur_max_warp, cur->adjusted);
- wrmsrl(MSR_IA32_TSC_ADJUST, cur->adjusted);
+ wrmsrl(MSR_IA32_TSC_ADJUST, cur->adjusted);
+ } else {
+ pr_debug("TSC direct sync: CPU%u observed %lld warp. Overhead: %lld\n",
+ cpu, cur_max_warp, est_overhead);
+ est_overhead = write_tsc_adjustment(cur_max_warp + est_overhead);
+ }
goto retry;
}
--
2.44.0

View file

@ -0,0 +1,44 @@
From c40db6ea8e9a1c9d7d136de44108fbacd659fd45 Mon Sep 17 00:00:00 2001
From: Steven Noonan <steven@uplinklabs.net>
Date: Wed, 17 Nov 2021 11:55:18 -0800
Subject: [PATCH 11/21] x86: touch clocksource watchdog after syncing TSCs
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
[Forward port to 6.5]
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
arch/x86/kernel/smpboot.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3f57ce68a3f1..f13ddbbb5d79 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -60,6 +60,7 @@
#include <linux/stackprotector.h>
#include <linux/cpuhotplug.h>
#include <linux/mc146818rtc.h>
+#include <linux/clocksource.h>
#include <asm/acpi.h>
#include <asm/cacheinfo.h>
@@ -1248,6 +1249,7 @@ void arch_thaw_secondary_cpus_begin(void)
void arch_thaw_secondary_cpus_end(void)
{
+ clocksource_touch_watchdog();
cache_aps_init();
}
@@ -1282,6 +1284,8 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
{
pr_debug("Boot done\n");
+ clocksource_touch_watchdog();
+
calculate_max_logical_packages();
build_sched_topology();
nmi_selftest();
--
2.44.0

View file

@ -0,0 +1,82 @@
From 426f372abc181230275dba722a2d17377d4050d7 Mon Sep 17 00:00:00 2001
From: Steven Noonan <steven@uplinklabs.net>
Date: Wed, 17 Nov 2021 00:26:20 -0800
Subject: [PATCH 12/21] x86: save/restore TSC counter value during sleep/wake
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
arch/x86/kernel/acpi/sleep.c | 5 +++++
arch/x86/realmode/rm/wakeup.h | 3 +++
arch/x86/realmode/rm/wakeup_asm.S | 12 ++++++++++++
3 files changed, 20 insertions(+)
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 6dfecb27b846..07b7f6e578e8 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -103,6 +103,11 @@ int x86_acpi_suspend_lowlevel(void)
header->pmode_misc_en_high))
header->pmode_behavior |=
(1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE);
+ if (!rdmsr_safe(MSR_IA32_TSC,
+ &header->pmode_tsc_low,
+ &header->pmode_tsc_high))
+ header->pmode_behavior |=
+ (1 << WAKEUP_BEHAVIOR_RESTORE_TSC);
header->realmode_flags = acpi_realmode_flags;
header->real_magic = 0x12345678;
diff --git a/arch/x86/realmode/rm/wakeup.h b/arch/x86/realmode/rm/wakeup.h
index 0e4fd08ae447..c728d8563de1 100644
--- a/arch/x86/realmode/rm/wakeup.h
+++ b/arch/x86/realmode/rm/wakeup.h
@@ -23,6 +23,8 @@ struct wakeup_header {
u64 pmode_gdt;
u32 pmode_misc_en_low; /* Protected mode MISC_ENABLE */
u32 pmode_misc_en_high;
+ u32 pmode_tsc_low;
+ u32 pmode_tsc_high;
u32 pmode_behavior; /* Wakeup routine behavior flags */
u32 realmode_flags;
u32 real_magic;
@@ -39,5 +41,6 @@ extern struct wakeup_header wakeup_header;
#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0
#define WAKEUP_BEHAVIOR_RESTORE_CR4 1
#define WAKEUP_BEHAVIOR_RESTORE_EFER 2
+#define WAKEUP_BEHAVIOR_RESTORE_TSC 3
#endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */
diff --git a/arch/x86/realmode/rm/wakeup_asm.S b/arch/x86/realmode/rm/wakeup_asm.S
index 02d0ba16ae33..0154ef895960 100644
--- a/arch/x86/realmode/rm/wakeup_asm.S
+++ b/arch/x86/realmode/rm/wakeup_asm.S
@@ -27,6 +27,7 @@ SYM_DATA_START(wakeup_header)
pmode_efer: .quad 0 /* Saved EFER */
pmode_gdt: .quad 0
pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */
+ pmode_tsc: .quad 0 /* Saved TSC MSR */
pmode_behavior: .long 0 /* Wakeup behavior flags */
realmode_flags: .long 0
real_magic: .long 0
@@ -104,6 +105,17 @@ SYM_CODE_START(wakeup_start)
wrmsr
1:
+ /* Restore TSC */
+ movl pmode_behavior, %edi
+ btl $WAKEUP_BEHAVIOR_RESTORE_TSC, %edi
+ jnc 1f
+
+ movl pmode_tsc, %eax
+ movl pmode_tsc + 4, %edx
+ movl $MSR_IA32_TSC, %ecx
+ wrmsr
+1:
+
/* Do any other stuff... */
#ifndef CONFIG_64BIT
--
2.44.0

View file

@ -0,0 +1,39 @@
From 2673c6532e52380e8fd7b1ebff966bc7b07755fa Mon Sep 17 00:00:00 2001
From: Steven Noonan <steven@uplinklabs.net>
Date: Wed, 17 Nov 2021 11:58:46 -0800
Subject: [PATCH 13/21] x86: only restore TSC if we have IA32_TSC_ADJUST or
directsync enabled
Otherwise we'd only be restoring the TSC for CPU0 on resume, which would
necessitate a TSC adjustment on other CPUs.
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
arch/x86/kernel/acpi/sleep.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 07b7f6e578e8..48a7a0341b81 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -103,11 +103,15 @@ int x86_acpi_suspend_lowlevel(void)
header->pmode_misc_en_high))
header->pmode_behavior |=
(1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE);
- if (!rdmsr_safe(MSR_IA32_TSC,
+
+ if ((boot_cpu_has(X86_FEATURE_TSC_ADJUST) ||
+ tsc_allow_direct_sync) &&
+ !rdmsr_safe(MSR_IA32_TSC,
&header->pmode_tsc_low,
&header->pmode_tsc_high))
header->pmode_behavior |=
(1 << WAKEUP_BEHAVIOR_RESTORE_TSC);
+
header->realmode_flags = acpi_realmode_flags;
header->real_magic = 0x12345678;
--
2.44.0

View file

@ -0,0 +1,31 @@
From 609d68f2225d5e394a573ffe9c77c82b30ea8e9d Mon Sep 17 00:00:00 2001
From: Steven Noonan <steven@uplinklabs.net>
Date: Wed, 17 Nov 2021 19:42:32 -0800
Subject: [PATCH 14/21] x86: don't check for random warps if using direct sync
There's some overhead in writing/reading MSR_IA32_TSC. We try to account
for it, but sometimes it under or over estimates the overhead, and we retry
syncing, and it sees the clock "go backwards".
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
arch/x86/kernel/tsc_sync.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index 5a553feaef76..2a09a55136f4 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -400,7 +400,7 @@ static void check_tsc_sync_source(void *__cpu)
pr_debug("TSC synchronization [CPU#%d -> CPU#%u]: passed\n",
smp_processor_id(), cpu);
- } else if (atomic_dec_and_test(&test_runs) || random_warps) {
+ } else if (atomic_dec_and_test(&test_runs) || (random_warps && !tsc_allow_direct_sync)) {
/* Force it to 0 if random warps brought us here */
atomic_set(&test_runs, 0);
--
2.44.0

View file

@ -0,0 +1,33 @@
From 58758906879db1450ac2dfdedf08fe68f018c5f5 Mon Sep 17 00:00:00 2001
From: Muhammad Usama Anjum <usama.anjum@collabora.com>
Date: Tue, 6 Jun 2023 16:12:06 +0500
Subject: [PATCH 15/21] x86: revert extra time added to check for tsc wraps
Reverts extra time duration added to test tsc wraps in
"x86: implement tsc=directsync for systems without IA32_TSC_ADJUST".
This duration makes the sanity checking longer in case tsc wraps. Revert
this to decrease average resume time.
Signed-off-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
(cherry picked from commit 458039cfa58ef8b1c4538a75487b67bf489374c4)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
arch/x86/kernel/tsc_sync.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index 2a09a55136f4..429109f02b27 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -342,8 +342,6 @@ static cycles_t check_tsc_warp(unsigned int timeout)
*/
static inline unsigned int loop_timeout(int cpu)
{
- if (!boot_cpu_has(X86_FEATURE_TSC_ADJUST))
- return 30;
return (cpumask_weight(topology_core_cpumask(cpu)) > 1) ? 2 : 20;
}
--
2.44.0

View file

@ -0,0 +1,33 @@
From 4bda77716e5b8c3716917fa85ff9f4f745bba88f Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Fri, 2 Sep 2022 19:13:12 +0300
Subject: [PATCH 16/21] usb: dwc3: Hardcode jupiter ACPI device as extcon name
Hardcode jupiter ACPI device as extcon name in order to connect the
two together. This is really a hack and should really be coming from
our ACPI tables.
(cherry picked from commit 190ce1057f9bafd3ca4e11e7cda286c234666196)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
[Fwd port to 6.0]
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/usb/dwc3/dwc3-pci.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 39564e17f3b0..393a2efac0c7 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -179,6 +179,7 @@ static const struct property_entry dwc3_pci_mr_properties[] = {
PROPERTY_ENTRY_BOOL("usb-role-switch"),
PROPERTY_ENTRY_STRING("role-switch-default-mode", "host"),
PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
+ PROPERTY_ENTRY_STRING("linux,extcon-name", "VLV0100:00"),
{}
};
--
2.44.0

View file

@ -0,0 +1,30 @@
From 770e26e1816b0a1a3013c26d1dc1b1da7cff9dbc Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Tue, 18 Jan 2022 08:44:34 -0800
Subject: [PATCH 17/21] usb: dwc3: Bump USB gadget wakeup timeout
Seems to be necessary to avoid timouts when switching host/gadged on
Steam Deck.
(cherry picked from commit b69aafb85c7794a729e68e92214e539e7e820192)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/usb/dwc3/gadget.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 28f49400f3e8..93f7d0290037 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2382,7 +2382,7 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc, bool async)
return 0;
/* poll until Link State changes to ON */
- retries = 20000;
+ retries = 2000000;
while (retries--) {
reg = dwc3_readl(dwc->regs, DWC3_DSTS);
--
2.44.0

View file

@ -0,0 +1,37 @@
From e61238022c903aaec88609454f602e3fda0cd623 Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Sat, 29 Oct 2022 15:25:21 -0700
Subject: [PATCH 18/21] usb: dwc3: Drop "usb-role-swtich" from
dwc3_pci_mr_properties
Having both "usb-role-swtich" and "linux,extcon-name" is a conflicting
configuration since the two are mutually exclusive. This wasn't a
problem before since "linux,extcon-name" had a priority, but recent
change in the kernel changed that, breaking Deck's role detection
integration.
Fix this by dropping "usb-role-switch" (and "role-switch-default-mode"
with it), to allow dwc3 driver to use extcon as it should.
(cherry picked from commit 498d5dccfac3e71b95fe3b9d6a156f15b6028aec)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/usb/dwc3/dwc3-pci.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 393a2efac0c7..21a764d30bff 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -176,8 +176,6 @@ static const struct property_entry dwc3_pci_amd_properties[] = {
static const struct property_entry dwc3_pci_mr_properties[] = {
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
- PROPERTY_ENTRY_BOOL("usb-role-switch"),
- PROPERTY_ENTRY_STRING("role-switch-default-mode", "host"),
PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
PROPERTY_ENTRY_STRING("linux,extcon-name", "VLV0100:00"),
{}
--
2.44.0

View file

@ -0,0 +1,27 @@
From 1ab4a0fb0e9436f72b668778ee27a036042de6e9 Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Sun, 27 Feb 2022 16:34:23 -0800
Subject: [PATCH 19/21] usb: dwc3: Fix "linux,extcon-name"
(cherry picked from commit 601ff3cebe00d1d5e4f165f4ac69a8ec0a57549e)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/usb/dwc3/dwc3-pci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 21a764d30bff..cf805293a933 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -177,7 +177,7 @@ static const struct property_entry dwc3_pci_amd_properties[] = {
static const struct property_entry dwc3_pci_mr_properties[] = {
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
- PROPERTY_ENTRY_STRING("linux,extcon-name", "VLV0100:00"),
+ PROPERTY_ENTRY_STRING("linux,extcon-name", "steamdeck-extcon"),
{}
};
--
2.44.0

View file

@ -0,0 +1,70 @@
From 23305d0eaad752788bae70db64f933febcbced82 Mon Sep 17 00:00:00 2001
From: Gabriel Krisman Bertazi <krisman@collabora.com>
Date: Wed, 5 May 2021 22:12:17 -0400
Subject: [PATCH 20/21] pinctrl-amd: Add quirk to timeout irq pin
reconfiguration
Since commit 37b635b47124 ("Add support for AMD SPI controller-1 (v2)"),
which enabled the SPI bus on jupiter, the probe of cs35l41 hangs the
entire kernel, because pinctrl-amd spins forever when attempting to
reconfigure the cs35l41 irq pin with interrupts disabled and holding the
spinlock of the irq controller. The infinite loop happens because of a
board design issue (according to AMD), that tries to use a pin that
can't even trigger the interruption that would otherwise signal the
reconfiguratiion completion.
This patch detects the condition and aborts the reconfiguration when the
problem occurs, failing the probe of the device, but allowing the kernel
to recover.
With this patch, it should be safe to reenable CONFIG_SPI_AMD.
Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com>
[Fwd-ported to v6.5]
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/pinctrl/pinctrl-amd.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index 49f89b70dcec..16d544bb0626 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -31,6 +31,7 @@
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/suspend.h>
+#include <linux/delay.h>
#include "core.h"
#include "pinctrl-utils.h"
@@ -484,6 +485,7 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
unsigned long flags;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+ int timeout = 100;
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
@@ -553,11 +555,16 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
pin_reg_irq_en |= mask;
pin_reg_irq_en &= ~BIT(INTERRUPT_MASK_OFF);
writel(pin_reg_irq_en, gpio_dev->base + (d->hwirq)*4);
- while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask)
- continue;
+ while (((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask) && timeout--)
+ udelay(100);
+
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ if (timeout <= 0)
+ printk("%s: applying Cirrus quirk after timeout when setting irq pin\n",
+ __func__);
+
return ret;
}
--
2.44.0

View file

@ -0,0 +1,87 @@
From 1ae0920b6e301eb38879d865f6feb3aac49ae76b Mon Sep 17 00:00:00 2001
From: Andres Rodriguez <andresx7@gmail.com>
Date: Tue, 8 Nov 2022 17:32:25 -0500
Subject: [PATCH 21/21] mmc: core: add safe_trim_quirk attribute
This attribute is intended to be used by userspace tools to identify
if trimming a device is safe or not. It helps in cases where a
userspace tool is aware of the necessity of the quirk and a user
accidentally downgrades their kernel to a one that doesn't have
support for the quirk.
Signed-off-by: Andres Rodriguez <andresx7@gmail.com>
(cherry picked from commit dfc5952c55f58d0e0863ccba0aa598fdae16ed14)
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/mmc/core/mmc.c | 2 ++
drivers/mmc/core/quirks.h | 2 ++
drivers/mmc/core/sd.c | 2 ++
include/linux/mmc/card.h | 1 +
4 files changed, 7 insertions(+)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index f410bee50132..aee1e0cbbd11 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -820,6 +820,7 @@ MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
MMC_DEV_ATTR(cmdq_en, "%d\n", card->ext_csd.cmdq_en);
+MMC_DEV_ATTR(safe_trim_quirk, "%d\n", card->safe_trim_quirk_version);
static ssize_t mmc_fwrev_show(struct device *dev,
struct device_attribute *attr,
@@ -879,6 +880,7 @@ static struct attribute *mmc_std_attrs[] = {
&dev_attr_rca.attr,
&dev_attr_dsr.attr,
&dev_attr_cmdq_en.attr,
+ &dev_attr_safe_trim_quirk.attr,
NULL,
};
ATTRIBUTE_GROUPS(mmc_std);
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
index cca71867bc4a..6418bfdf849e 100644
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
@@ -241,4 +241,6 @@ static inline void mmc_fixup_device(struct mmc_card *card,
dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup);
f->vendor_fixup(card, f->data);
}
+
+ card->safe_trim_quirk_version = 1;
}
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index c3e554344c99..b64b8462bb66 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -714,6 +714,7 @@ MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
+MMC_DEV_ATTR(safe_trim_quirk, "%d\n", card->safe_trim_quirk_version);
static ssize_t mmc_dsr_show(struct device *dev, struct device_attribute *attr,
@@ -776,6 +777,7 @@ static struct attribute *sd_std_attrs[] = {
&dev_attr_ocr.attr,
&dev_attr_rca.attr,
&dev_attr_dsr.attr,
+ &dev_attr_safe_trim_quirk.attr,
NULL,
};
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index f34407cc2788..12fdace380f0 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -275,6 +275,7 @@ struct mmc_card {
unsigned int state; /* (our) card state */
unsigned int quirks; /* card quirks */
unsigned int quirk_max_rate; /* max rate set by quirks */
+ unsigned int safe_trim_quirk_version; /* advertise if we have protection for cards which misbehave with trim */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
/* for byte mode */
--
2.44.0

View file

@ -0,0 +1,111 @@
# Maintainer: Clayton Craft <clayton@craftyguy.net>
pkgname=linux-valve-jupiter
pkgver=6.8_rc7
pkgrel=0
pkgdesc="Valve Steam Deck kernel fork"
arch="x86_64"
_flavor="valve-jupiter"
_carch="x86"
url="https://kernel.org"
license="GPL-2.0-only"
options="!strip !check !tracedeps
pmb:cross-native
pmb:kconfigcheck-community
pmb:kconfigcheck-uefi
"
makedepends="
bash
bison
elfutils-dev
findutils
flex
linux-headers
openssl-dev
perl
postmarketos-installkernel
"
# Source
_config="config-$_flavor.$arch"
case $pkgver in
*.*.*) _kernver=${pkgver%.0};;
*.*) _kernver=$pkgver;;
esac
source="
https://git.kernel.org/torvalds/t/linux-${_kernver//_/-}.tar.gz
$_config
0001-ACPICA-Limit-error-message-flood-caused-by-firmware-.patch
0002-drivers-video-backlight-Disable-backlight-notificati.patch
0003-iio-light-ltrf216a-Return-floating-point-values.patch
0004-mfd-Add-MFD-core-driver-for-Steam-Deck.patch
0005-hwmon-Add-driver-for-Steam-Deck-s-EC-sensors.patch
0006-leds-steamdeck-Add-support-for-Steam-Deck-LED.patch
0007-extcon-Add-driver-for-Steam-Deck.patch
0008-hwmon-steamdeck-hwmon-Add-support-for-max-battery-le.patch
0009-mfd-steamdeck-Expose-controller-board-power-in-sysfs.patch
0010-x86-implement-tsc-directsync-for-systems-without-IA3.patch
0011-x86-touch-clocksource-watchdog-after-syncing-TSCs.patch
0012-x86-save-restore-TSC-counter-value-during-sleep-wake.patch
0013-x86-only-restore-TSC-if-we-have-IA32_TSC_ADJUST-or-d.patch
0014-x86-don-t-check-for-random-warps-if-using-direct-syn.patch
0015-x86-revert-extra-time-added-to-check-for-tsc-wraps.patch
0016-usb-dwc3-Hardcode-jupiter-ACPI-device-as-extcon-name.patch
0017-usb-dwc3-Bump-USB-gadget-wakeup-timeout.patch
0018-usb-dwc3-Drop-usb-role-swtich-from-dwc3_pci_mr_prope.patch
0019-usb-dwc3-Fix-linux-extcon-name.patch
0020-pinctrl-amd-Add-quirk-to-timeout-irq-pin-reconfigura.patch
0021-mmc-core-add-safe_trim_quirk-attribute.patch
"
builddir="$srcdir/linux-${_kernver//_/-}"
prepare() {
default_prepare
cp "$srcdir/$_config" .config
}
build() {
unset LDFLAGS
make ARCH="$_carch" CC="${CC:-gcc}" \
KBUILD_BUILD_VERSION="$((pkgrel + 1 ))-$_flavor"
}
package() {
mkdir -p "$pkgdir"/boot
make install modules_install \
ARCH="$_carch" \
INSTALL_PATH="$pkgdir"/boot \
INSTALL_MOD_PATH="$pkgdir" \
INSTALL_MOD_STRIP=1
rm -f "$pkgdir"/lib/modules/*/build "$pkgdir"/lib/modules/*/source
install -D "$builddir"/include/config/kernel.release \
"$pkgdir"/usr/share/kernel/$_flavor/kernel.release
}
sha512sums="
14dfe21da64bd625548f3439a878b46010c7c9c0569ca320dacc2219c297e2c1a8e3cb95c7c497b1177d3e4f6f6ea94b2a622cf75db86fd4a8edeccdfdeed42a linux-6.8-rc7.tar.gz
23e8144e337e1ec25ffdd90458e0f55760913ff3489bd4e019df9c5e39fdc80c87c23ee192aef52d3f7301b759a77b383e09fce75cf281149512fc8370fb6faf config-valve-jupiter.x86_64
fe6d4f0b8b86134b62a1f040ef7e8090702b1933b909a095217180160b4dd87d1d2cd7da41b1578f4577dd423e6dbca40d74f8f2d21c274074b19f612de3f343 0001-ACPICA-Limit-error-message-flood-caused-by-firmware-.patch
ff6e833025d8df063d5de4db08376bc70892a5a07f98cfcec665e75e85862b4a583ad3685b056af9e623cd45458921d102c8fe94d2cad58385129e1f01308da1 0002-drivers-video-backlight-Disable-backlight-notificati.patch
35fed97f0bae352f2cfb53fe301c24e893c5d04120fdcd8b1390582c489517f8f11d01f98cacbe3f4a51ee7156e8eab6197a1cdd96be3d70d5ad40d5e0992494 0003-iio-light-ltrf216a-Return-floating-point-values.patch
538acf33701914f9fd894db4655390ebdbf4e7902e1f44adeb145e2d9c0e6e326e7331d5e5da55a0115c5b9079abb1358232424dd543b1ab8961da0a536d9b5b 0004-mfd-Add-MFD-core-driver-for-Steam-Deck.patch
86a93d8872986e4ad67f6a83031286bcb2ba59939dceff4af720be0a960c011c59cf7857c9e0a6c2aff1b61c75f9a2245c8d9489693e6c36833ebd143d76734d 0005-hwmon-Add-driver-for-Steam-Deck-s-EC-sensors.patch
985dc1f7cf67de127f1d270553f78783086f0e4cebd3e30ae4c577aed22c7b2ff99aa5dfd2d42c626c93b942ac657417f79c45308949862107c4e30169fed694 0006-leds-steamdeck-Add-support-for-Steam-Deck-LED.patch
e0a753212d225552f1c87eabe37c0a64bd345314ac14d09361bc0f8046f4bf33c8d290b6d85b7d2ac8a6e1bbb9aa1d24403ca34068165d558bead33d375a4467 0007-extcon-Add-driver-for-Steam-Deck.patch
2431d4bedc5a916a16cf597f7ca3518cc51bd4951b1789383bbdad59a031f1863508073e5afe9174be527b5398606aa189ad1a8e0833b29394c6e5e561b1cb09 0008-hwmon-steamdeck-hwmon-Add-support-for-max-battery-le.patch
a2f387ebebe84f41a75b64f1cddf33fb56dbaf8388ae10d7f873f5b26eaa82055413d35cccebd1c9011342e722aa07dbf8537c47f34d05deb6296738a3553b7f 0009-mfd-steamdeck-Expose-controller-board-power-in-sysfs.patch
057e188e9eb3a838ce3a1f43bc3ed712f936e37f022a3655691ea2b152e99c8d41c264e5ef11a7a27a020a57558d53afb72fb81cef9fb280a60e9d302fc50159 0010-x86-implement-tsc-directsync-for-systems-without-IA3.patch
71164e34b08d4d364c1cc859debb109f65b736727e4d7c42644eb61edcb457b5fcbe71c5a3724fe15a12819a4838d3eb3010fcb91571074a2707ddc3f945f0a5 0011-x86-touch-clocksource-watchdog-after-syncing-TSCs.patch
ad4b783bae034ba2e79b87854a552acda800f8e743d74f97ee594eaf8da3ec25729086fadbcfeeca06f05734b6be5382d784b6e8e1b0bd5041c3472da8b8a508 0012-x86-save-restore-TSC-counter-value-during-sleep-wake.patch
7b57f48ab74645e2530371a99040e88b5aab7addbddfec900089100aec89e0f992a8b298819d99347e8306a9ff65f2d112de921772866fefde27483e7b236562 0013-x86-only-restore-TSC-if-we-have-IA32_TSC_ADJUST-or-d.patch
1b1f88ddc32539a81c645de6fb1f13d2070df01570e5b29300a6ecf7b626a9e97c8581198c5b47cdc93c6dc1301c6737de9147919e3b9a134e9e6e0a39dd86d0 0014-x86-don-t-check-for-random-warps-if-using-direct-syn.patch
e914ce3e2ac406a8c280bd88fdb6908161d6fbccccd0c2e6a2c2c3814917271230cb1f8fa2a3111f9057d8fd36bd18753b5306f4596889f27656415239c92f95 0015-x86-revert-extra-time-added-to-check-for-tsc-wraps.patch
3e71e8a96934113b53b31e153addf498a8bc52e80fc874d66e34210945f0c8e85f201143f1303e51cf05a1b43109cbfb3da31c071ab7cf1cadd07a226c1b0861 0016-usb-dwc3-Hardcode-jupiter-ACPI-device-as-extcon-name.patch
738a46214f80e3e5d9878f74e90c3532ddcff0706cc381662c643b1954fbc94fcb47bf3e79d8f892671002c4683a872bcd73bddbff89724c416631cb2da212b5 0017-usb-dwc3-Bump-USB-gadget-wakeup-timeout.patch
fac38c82ddd1a099925452c0ac205f8b8cc02ab846c1c71f69d51aea79b52a985e3175371c2a854b4cf7569d0100e599b961dd6d919c96a0582fd640871c9c13 0018-usb-dwc3-Drop-usb-role-swtich-from-dwc3_pci_mr_prope.patch
212567512f28b4400f82117d90a1e5fa03ab9ba59f3e70c58d5854a3a201751e70bce2437d19d706c2a495ec951dd77f599d2700f42fb87a820f15cfd3e2c50b 0019-usb-dwc3-Fix-linux-extcon-name.patch
f37c466b18d97233511193d8512d311acd4bb4f95bbc9b08893ce2f2d80bfe75c92f0e5979e2577c2be560eaa3d7001cf2bae32b9c37730fdce9eaa402320745 0020-pinctrl-amd-Add-quirk-to-timeout-irq-pin-reconfigura.patch
4c3454dcb3eac580edfcb34d85cfed2bfcc3df1a77c9d88344b5936ae1210b66c8c7eb778f3317085368c82348f7f6860591e367715ef879641d32ed4d266953 0021-mmc-core-add-safe_trim_quirk-attribute.patch
"

File diff suppressed because it is too large Load diff