* [PATCH v4 1/3] dt-bindings: power: reset: google,gs101-reboot: add Google GS101 specific reset
2025-03-28 15:15 [PATCH v4 0/3] support Linux reboot modes in syscon-reboot on gs101 (Google Pixel) André Draszik
@ 2025-03-28 15:15 ` André Draszik
2025-03-31 7:11 ` Krzysztof Kozlowski
2025-03-28 15:15 ` [PATCH v4 2/3] dt-bindings: soc: samsung: exynos-pmu: update reset for gs101 André Draszik
2025-03-28 15:15 ` [PATCH v4 3/3] power: reset: syscon-reboot: add gs101-specific reset André Draszik
2 siblings, 1 reply; 6+ messages in thread
From: André Draszik @ 2025-03-28 15:15 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Alim Akhtar
Cc: Peter Griffin, Tudor Ambarus, Will McVicker, kernel-team,
linux-pm, devicetree, linux-kernel, linux-arm-kernel,
linux-samsung-soc, André Draszik
GS101 supports a couple different reset types via certain registers in
the SYSCON register map.
Add a binding for this.
Signed-off-by: André Draszik <andre.draszik@linaro.org>
---
.../bindings/power/reset/google,gs101-reboot.yaml | 32 ++++++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 33 insertions(+)
diff --git a/Documentation/devicetree/bindings/power/reset/google,gs101-reboot.yaml b/Documentation/devicetree/bindings/power/reset/google,gs101-reboot.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cbd0a1d9b45af0cb994d616c56b96440c43ab971
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/google,gs101-reboot.yaml
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/reset/google,gs101-reboot.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Google GS101 syscon-mapped reset
+
+maintainers:
+ - André Draszik <andre.draszik@linaro.org>
+
+description:
+ GS101 supports a couple different reset types via certain registers in the
+ SYSCON register map. This map is retrieved from the parental dt-node. So the
+ gs101-reboot node should be represented as a sub-node of such a node.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: google,gs101-reboot
+
+ priority:
+ default: 192
+
+required:
+ - compatible
+
+additionalProperties: false
+
+allOf:
+ - $ref: restart-handler.yaml#
diff --git a/MAINTAINERS b/MAINTAINERS
index 322ee00547f6e494a96d2495092f72148da22bd0..e27f5e672bc5a04777afd098355898654654659d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10080,6 +10080,7 @@ L: linux-samsung-soc@vger.kernel.org
S: Maintained
C: irc://irc.oftc.net/pixel6-kernel-dev
F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
+F: Documentation/devicetree/bindings/power/reset/google,gs101-reboot.yaml
F: arch/arm64/boot/dts/exynos/google/
F: drivers/clk/samsung/clk-gs101.c
F: drivers/phy/samsung/phy-gs101-ufs.c
--
2.49.0.472.ge94155a9ec-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/3] dt-bindings: soc: samsung: exynos-pmu: update reset for gs101
2025-03-28 15:15 [PATCH v4 0/3] support Linux reboot modes in syscon-reboot on gs101 (Google Pixel) André Draszik
2025-03-28 15:15 ` [PATCH v4 1/3] dt-bindings: power: reset: google,gs101-reboot: add Google GS101 specific reset André Draszik
@ 2025-03-28 15:15 ` André Draszik
2025-03-31 7:15 ` Krzysztof Kozlowski
2025-03-28 15:15 ` [PATCH v4 3/3] power: reset: syscon-reboot: add gs101-specific reset André Draszik
2 siblings, 1 reply; 6+ messages in thread
From: André Draszik @ 2025-03-28 15:15 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Alim Akhtar
Cc: Peter Griffin, Tudor Ambarus, Will McVicker, kernel-team,
linux-pm, devicetree, linux-kernel, linux-arm-kernel,
linux-samsung-soc, André Draszik
Add the gs101-specific reset node, allow it on gs101, and disallow it
on !gs101. Similarly, disallow the generic 'syscon-reboot' on gs101, as
we want the specific one in that case.
Signed-off-by: André Draszik <andre.draszik@linaro.org>
---
.../devicetree/bindings/soc/samsung/exynos-pmu.yaml | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
index 204da6fe458d2d4bfeee1471ebc5c38247477ae2..8c7362cf3eeab11f6bb13a27eb295d5ee6721b71 100644
--- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
+++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
@@ -97,6 +97,12 @@ properties:
$ref: /schemas/phy/samsung,dp-video-phy.yaml
unevaluatedProperties: false
+ gs101-reboot:
+ $ref: /schemas/power/reset/google,gs101-reboot.yaml#
+ type: object
+ description:
+ Node for gs101-specific reboot method
+
interrupt-controller:
description:
Some PMUs are capable of behaving as an interrupt controller (mostly
@@ -136,6 +142,21 @@ required:
additionalProperties: false
allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: google,gs101-pmu
+ then:
+ properties:
+ gs101-reboot: true
+ syscon-reboot: false
+
+ else:
+ properties:
+ gs101-reboot: false
+ syscon-reboot: true
+
- if:
properties:
compatible:
--
2.49.0.472.ge94155a9ec-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v4 3/3] power: reset: syscon-reboot: add gs101-specific reset
2025-03-28 15:15 [PATCH v4 0/3] support Linux reboot modes in syscon-reboot on gs101 (Google Pixel) André Draszik
2025-03-28 15:15 ` [PATCH v4 1/3] dt-bindings: power: reset: google,gs101-reboot: add Google GS101 specific reset André Draszik
2025-03-28 15:15 ` [PATCH v4 2/3] dt-bindings: soc: samsung: exynos-pmu: update reset for gs101 André Draszik
@ 2025-03-28 15:15 ` André Draszik
2 siblings, 0 replies; 6+ messages in thread
From: André Draszik @ 2025-03-28 15:15 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Alim Akhtar
Cc: Peter Griffin, Tudor Ambarus, Will McVicker, kernel-team,
linux-pm, devicetree, linux-kernel, linux-arm-kernel,
linux-samsung-soc, André Draszik
Linux supports a couple different reset modes, but this driver here
doesn't distinguish between them and issues the same syscon register
write irrespective of the reset mode requested by the kernel.
Since DTs should not encode register writes (see e.g. [1]), update this
driver to support different reset modes based on DT compatible match.
At the same time, add support for Google GS101, which does support
cold, hard, warm, and soft.
As an example why this is useful, other than properly supporting the
Linux reboot= kernel command line option or sysfs entry, this change
allows gs101-platforms to default to a more secure cold-reset, but also
to warm-reset in case RAM contents needs to be retained across the
reset.
Link: https://lore.kernel.org/all/20250227132644.GA1924628-robh@kernel.org/ [1]
Signed-off-by: André Draszik <andre.draszik@linaro.org>
---
drivers/power/reset/syscon-reboot.c | 98 +++++++++++++++++++++++++++++--------
1 file changed, 77 insertions(+), 21 deletions(-)
diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c
index d623d77e657e4c233d8ae88bb099bee13c48a9ef..2e2cf5f62d733c7c07110f3052583607e25afd5d 100644
--- a/drivers/power/reset/syscon-reboot.c
+++ b/drivers/power/reset/syscon-reboot.c
@@ -14,11 +14,24 @@
#include <linux/reboot.h>
#include <linux/regmap.h>
-struct syscon_reboot_context {
- struct regmap *map;
+struct reboot_mode_bits {
u32 offset;
- u32 value;
u32 mask;
+ u32 value;
+ bool valid;
+};
+
+struct reboot_data {
+ struct reboot_mode_bits mode_bits[REBOOT_SOFT + 1];
+ struct reboot_mode_bits catchall;
+};
+
+struct syscon_reboot_context {
+ struct regmap *map;
+
+ const struct reboot_data *rd; /* from of match data, if any */
+ struct reboot_mode_bits catchall; /* from DT */
+
struct notifier_block restart_handler;
};
@@ -28,9 +41,21 @@ static int syscon_restart_handle(struct notifier_block *this,
struct syscon_reboot_context *ctx =
container_of(this, struct syscon_reboot_context,
restart_handler);
+ const struct reboot_mode_bits *mode_bits;
+
+ if (ctx->rd) {
+ if (mode < ARRAY_SIZE(ctx->rd->mode_bits) &&
+ ctx->rd->mode_bits[mode].valid)
+ mode_bits = &ctx->rd->mode_bits[mode];
+ else
+ mode_bits = &ctx->rd->catchall;
+ } else {
+ mode_bits = &ctx->catchall;
+ }
/* Issue the reboot */
- regmap_update_bits(ctx->map, ctx->offset, ctx->mask, ctx->value);
+ regmap_update_bits(ctx->map, mode_bits->offset, mode_bits->mask,
+ mode_bits->value);
mdelay(1000);
@@ -42,7 +67,6 @@ static int syscon_reboot_probe(struct platform_device *pdev)
{
struct syscon_reboot_context *ctx;
struct device *dev = &pdev->dev;
- int mask_err, value_err;
int priority;
int err;
@@ -60,24 +84,33 @@ static int syscon_reboot_probe(struct platform_device *pdev)
if (of_property_read_s32(pdev->dev.of_node, "priority", &priority))
priority = 192;
- if (of_property_read_u32(pdev->dev.of_node, "offset", &ctx->offset))
- if (of_property_read_u32(pdev->dev.of_node, "reg", &ctx->offset))
- return -EINVAL;
+ ctx->rd = of_device_get_match_data(dev);
+ if (!ctx->rd) {
+ int mask_err, value_err;
- value_err = of_property_read_u32(pdev->dev.of_node, "value", &ctx->value);
- mask_err = of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask);
- if (value_err && mask_err) {
- dev_err(dev, "unable to read 'value' and 'mask'");
- return -EINVAL;
- }
+ if (of_property_read_u32(pdev->dev.of_node, "offset",
+ &ctx->catchall.offset) &&
+ of_property_read_u32(pdev->dev.of_node, "reg",
+ &ctx->catchall.offset))
+ return -EINVAL;
- if (value_err) {
- /* support old binding */
- ctx->value = ctx->mask;
- ctx->mask = 0xFFFFFFFF;
- } else if (mask_err) {
- /* support value without mask*/
- ctx->mask = 0xFFFFFFFF;
+ value_err = of_property_read_u32(pdev->dev.of_node, "value",
+ &ctx->catchall.value);
+ mask_err = of_property_read_u32(pdev->dev.of_node, "mask",
+ &ctx->catchall.mask);
+ if (value_err && mask_err) {
+ dev_err(dev, "unable to read 'value' and 'mask'");
+ return -EINVAL;
+ }
+
+ if (value_err) {
+ /* support old binding */
+ ctx->catchall.value = ctx->catchall.mask;
+ ctx->catchall.mask = 0xFFFFFFFF;
+ } else if (mask_err) {
+ /* support value without mask */
+ ctx->catchall.mask = 0xFFFFFFFF;
+ }
}
ctx->restart_handler.notifier_call = syscon_restart_handle;
@@ -89,7 +122,30 @@ static int syscon_reboot_probe(struct platform_device *pdev)
return err;
}
+static const struct reboot_data gs101_reboot_data = {
+ .mode_bits = {
+ [REBOOT_WARM] = {
+ .offset = 0x3a00, /* SYSTEM_CONFIGURATION */
+ .mask = 0x00000002, /* SWRESET_SYSTEM */
+ .value = 0x00000002,
+ .valid = true,
+ },
+ [REBOOT_SOFT] = {
+ .offset = 0x3a00, /* SYSTEM_CONFIGURATION */
+ .mask = 0x00000002, /* SWRESET_SYSTEM */
+ .value = 0x00000002,
+ .valid = true,
+ },
+ },
+ .catchall = {
+ .offset = 0x3e9c, /* PAD_CTRL_PWR_HOLD */
+ .mask = 0x00000100,
+ .value = 0x00000000,
+ },
+};
+
static const struct of_device_id syscon_reboot_of_match[] = {
+ { .compatible = "google,gs101-reboot", .data = &gs101_reboot_data },
{ .compatible = "syscon-reboot" },
{}
};
--
2.49.0.472.ge94155a9ec-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread