1 | This series updates syscon-reboot to support warm/soft and soft/hard | 1 | This series updates syscon-reboot to support warm/soft and cold/hard |
---|---|---|---|
2 | reboot on gs101-based boards (Google Pixel 6 and Pixel 6 Pro). | 2 | reboot on gs101-based boards (Google Pixel 6 and Pixel 6 Pro). |
3 | 3 | ||
4 | Linux supports a couple different reboot modes, but syscon-reboot | 4 | Linux supports a couple different reboot modes, but syscon-reboot |
5 | doesn't distinguish between them and issues the same syscon register | 5 | doesn't distinguish between them and issues the same syscon register |
6 | write irrespective of the reboot mode requested by the kernel. | 6 | write irrespective of the reboot mode requested by the kernel. |
... | ... | ||
15 | As Rob pointed out in [1], register access shouldn't be encoded into | 15 | As Rob pointed out in [1], register access shouldn't be encoded into |
16 | DT, though. At the same time, at least on gs101, the difference is just | 16 | DT, though. At the same time, at least on gs101, the difference is just |
17 | different register values in different registers. Therefore these | 17 | different register values in different registers. Therefore these |
18 | patches: | 18 | patches: |
19 | 19 | ||
20 | * add a specific binding for gs101 reset | 20 | * add a new compatible for gs101 reset. In [2], Krzysztof suggested |
21 | to simply add that to the existing generic binding | ||
21 | * update the generic syscon reset driver to support this new | 22 | * update the generic syscon reset driver to support this new |
22 | compatible 'google,gs101-reboot'. In this case, and as suggested | 23 | compatible 'google,gs101-reboot'. In this case, and as suggested |
23 | in [1], the syscon writes are then deducted from the compatible, | 24 | in [1], the syscon writes are then deducted from the compatible, |
24 | rather than parsing them from DT. | 25 | rather than parsing them from DT. |
25 | 26 | ||
... | ... | ||
31 | 32 | ||
32 | Link: https://lore.kernel.org/all/20250227132644.GA1924628-robh@kernel.org/ [1] | 33 | Link: https://lore.kernel.org/all/20250227132644.GA1924628-robh@kernel.org/ [1] |
33 | 34 | ||
34 | Signed-off-by: André Draszik <andre.draszik@linaro.org> | 35 | Signed-off-by: André Draszik <andre.draszik@linaro.org> |
35 | --- | 36 | --- |
37 | Changes in v5: | ||
38 | - Krzysztof: | ||
39 | - drop gs101-specific schema and add the new compatible to the | ||
40 | generic syscon-reboot schema, with all appropriate follow-up | ||
41 | changes to it | ||
42 | - reuse existing syscon-reboot node for gs101 in exynos-pmu schema, | ||
43 | don't introduce a new one | ||
44 | - Link to v4: https://lore.kernel.org/r/20250328-syscon-reboot-reset-mode-v4-0-77ba57703ace@linaro.org | ||
45 | |||
36 | Changes in v4: | 46 | Changes in v4: |
37 | - Rob: | 47 | - Rob: |
38 | - don't add more properties to existing 'syscon-reboot' compatible / | 48 | - don't add more properties to existing 'syscon-reboot' compatible / |
39 | binding | 49 | binding |
40 | - add specific binding for 'google,gs101-reboot' compatible and | 50 | - add specific binding for 'google,gs101-reboot' compatible and |
... | ... | ||
50 | Changes in v2: | 60 | Changes in v2: |
51 | - fix whitespace issues in binding | 61 | - fix whitespace issues in binding |
52 | - Link to v1: https://lore.kernel.org/r/20250226-syscon-reboot-reset-mode-v1-0-91c1b62166ae@linaro.org | 62 | - Link to v1: https://lore.kernel.org/r/20250226-syscon-reboot-reset-mode-v1-0-91c1b62166ae@linaro.org |
53 | 63 | ||
54 | --- | 64 | --- |
55 | André Draszik (3): | 65 | André Draszik (2): |
56 | dt-bindings: power: reset: google,gs101-reboot: add Google GS101 specific reset | 66 | dt-bindings: reset: syscon-reboot: add google,gs101-reboot |
57 | dt-bindings: soc: samsung: exynos-pmu: update reset for gs101 | ||
58 | power: reset: syscon-reboot: add gs101-specific reset | 67 | power: reset: syscon-reboot: add gs101-specific reset |
59 | 68 | ||
60 | .../bindings/power/reset/google,gs101-reboot.yaml | 32 +++++++ | 69 | .../bindings/power/reset/syscon-reboot.yaml | 42 +++++++--- |
61 | .../bindings/soc/samsung/exynos-pmu.yaml | 21 +++++ | ||
62 | MAINTAINERS | 1 + | ||
63 | drivers/power/reset/syscon-reboot.c | 98 +++++++++++++++++----- | 70 | drivers/power/reset/syscon-reboot.c | 98 +++++++++++++++++----- |
64 | 4 files changed, 131 insertions(+), 21 deletions(-) | 71 | 2 files changed, 107 insertions(+), 33 deletions(-) |
65 | --- | 72 | --- |
66 | base-commit: db8da9da41bced445077925f8a886c776a47440c | 73 | base-commit: db8da9da41bced445077925f8a886c776a47440c |
67 | change-id: 20250226-syscon-reboot-reset-mode-566588b847e1 | 74 | change-id: 20250226-syscon-reboot-reset-mode-566588b847e1 |
68 | 75 | ||
69 | Best regards, | 76 | Best regards, |
70 | -- | 77 | -- |
71 | André Draszik <andre.draszik@linaro.org> | 78 | André Draszik <andre.draszik@linaro.org> |
72 | 79 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | GS101 supports a couple different reset types via certain registers in | ||
2 | the SYSCON register map. | ||
3 | 1 | ||
4 | Add a binding for this. | ||
5 | |||
6 | Signed-off-by: André Draszik <andre.draszik@linaro.org> | ||
7 | --- | ||
8 | .../bindings/power/reset/google,gs101-reboot.yaml | 32 ++++++++++++++++++++++ | ||
9 | MAINTAINERS | 1 + | ||
10 | 2 files changed, 33 insertions(+) | ||
11 | |||
12 | diff --git a/Documentation/devicetree/bindings/power/reset/google,gs101-reboot.yaml b/Documentation/devicetree/bindings/power/reset/google,gs101-reboot.yaml | ||
13 | new file mode 100644 | ||
14 | index XXXXXXX..XXXXXXX | ||
15 | --- /dev/null | ||
16 | +++ b/Documentation/devicetree/bindings/power/reset/google,gs101-reboot.yaml | ||
17 | @@ -XXX,XX +XXX,XX @@ | ||
18 | +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||
19 | +%YAML 1.2 | ||
20 | +--- | ||
21 | +$id: http://devicetree.org/schemas/power/reset/google,gs101-reboot.yaml# | ||
22 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | ||
23 | + | ||
24 | +title: Google GS101 syscon-mapped reset | ||
25 | + | ||
26 | +maintainers: | ||
27 | + - André Draszik <andre.draszik@linaro.org> | ||
28 | + | ||
29 | +description: | ||
30 | + GS101 supports a couple different reset types via certain registers in the | ||
31 | + SYSCON register map. This map is retrieved from the parental dt-node. So the | ||
32 | + gs101-reboot node should be represented as a sub-node of such a node. | ||
33 | + | ||
34 | +properties: | ||
35 | + compatible: | ||
36 | + oneOf: | ||
37 | + - items: | ||
38 | + - const: google,gs101-reboot | ||
39 | + | ||
40 | + priority: | ||
41 | + default: 192 | ||
42 | + | ||
43 | +required: | ||
44 | + - compatible | ||
45 | + | ||
46 | +additionalProperties: false | ||
47 | + | ||
48 | +allOf: | ||
49 | + - $ref: restart-handler.yaml# | ||
50 | diff --git a/MAINTAINERS b/MAINTAINERS | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/MAINTAINERS | ||
53 | +++ b/MAINTAINERS | ||
54 | @@ -XXX,XX +XXX,XX @@ L: linux-samsung-soc@vger.kernel.org | ||
55 | S: Maintained | ||
56 | C: irc://irc.oftc.net/pixel6-kernel-dev | ||
57 | F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml | ||
58 | +F: Documentation/devicetree/bindings/power/reset/google,gs101-reboot.yaml | ||
59 | F: arch/arm64/boot/dts/exynos/google/ | ||
60 | F: drivers/clk/samsung/clk-gs101.c | ||
61 | F: drivers/phy/samsung/phy-gs101-ufs.c | ||
62 | |||
63 | -- | ||
64 | 2.49.0.472.ge94155a9ec-goog | ||
65 | diff view generated by jsdifflib |
1 | Add the gs101-specific reset node, allow it on gs101, and disallow it | 1 | GS101 supports a couple different reset types via certain registers in |
---|---|---|---|
2 | on !gs101. Similarly, disallow the generic 'syscon-reboot' on gs101, as | 2 | the SYSCON register map. |
3 | we want the specific one in that case. | 3 | |
4 | Add a compatible for it. When in effect, all register values and offsets | ||
5 | are implied, hence they shall not be specified in that case. | ||
4 | 6 | ||
5 | Signed-off-by: André Draszik <andre.draszik@linaro.org> | 7 | Signed-off-by: André Draszik <andre.draszik@linaro.org> |
6 | --- | 8 | --- |
7 | .../devicetree/bindings/soc/samsung/exynos-pmu.yaml | 21 +++++++++++++++++++++ | 9 | .../bindings/power/reset/syscon-reboot.yaml | 42 +++++++++++++++------- |
8 | 1 file changed, 21 insertions(+) | 10 | 1 file changed, 30 insertions(+), 12 deletions(-) |
9 | 11 | ||
10 | diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml | 12 | diff --git a/Documentation/devicetree/bindings/power/reset/syscon-reboot.yaml b/Documentation/devicetree/bindings/power/reset/syscon-reboot.yaml |
11 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml | 14 | --- a/Documentation/devicetree/bindings/power/reset/syscon-reboot.yaml |
13 | +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml | 15 | +++ b/Documentation/devicetree/bindings/power/reset/syscon-reboot.yaml |
16 | @@ -XXX,XX +XXX,XX @@ description: |+ | ||
17 | |||
18 | properties: | ||
19 | compatible: | ||
20 | - const: syscon-reboot | ||
21 | + enum: | ||
22 | + - syscon-reboot | ||
23 | + - google,gs101-reboot | ||
24 | |||
25 | mask: | ||
26 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
14 | @@ -XXX,XX +XXX,XX @@ properties: | 27 | @@ -XXX,XX +XXX,XX @@ properties: |
15 | $ref: /schemas/phy/samsung,dp-video-phy.yaml | 28 | priority: |
16 | unevaluatedProperties: false | 29 | default: 192 |
17 | 30 | ||
18 | + gs101-reboot: | 31 | -oneOf: |
19 | + $ref: /schemas/power/reset/google,gs101-reboot.yaml# | 32 | - - required: |
20 | + type: object | 33 | - - offset |
21 | + description: | 34 | - - required: |
22 | + Node for gs101-specific reboot method | 35 | - - reg |
23 | + | 36 | - |
24 | interrupt-controller: | 37 | required: |
25 | description: | 38 | - compatible |
26 | Some PMUs are capable of behaving as an interrupt controller (mostly | 39 | |
27 | @@ -XXX,XX +XXX,XX @@ required: | 40 | @@ -XXX,XX +XXX,XX @@ additionalProperties: false |
28 | additionalProperties: false | ||
29 | |||
30 | allOf: | 41 | allOf: |
31 | + - if: | 42 | - $ref: restart-handler.yaml# |
43 | - if: | ||
44 | - not: | ||
45 | - required: | ||
46 | - - mask | ||
32 | + properties: | 47 | + properties: |
33 | + compatible: | 48 | + compatible: |
34 | + contains: | 49 | + contains: |
35 | + const: google,gs101-pmu | 50 | + const: google,gs101-reboot |
36 | + then: | 51 | then: |
52 | - required: | ||
53 | - - value | ||
37 | + properties: | 54 | + properties: |
38 | + gs101-reboot: true | 55 | + mask: false |
39 | + syscon-reboot: false | 56 | + offset: false |
57 | + reg: false | ||
58 | + value: false | ||
40 | + | 59 | + |
41 | + else: | 60 | + else: |
42 | + properties: | 61 | + if: |
43 | + gs101-reboot: false | 62 | + not: |
44 | + syscon-reboot: true | 63 | + required: |
64 | + - mask | ||
65 | + then: | ||
66 | + required: | ||
67 | + - value | ||
45 | + | 68 | + |
46 | - if: | 69 | + oneOf: |
47 | properties: | 70 | + - required: [offset] |
48 | compatible: | 71 | + - required: [reg] |
72 | |||
73 | examples: | ||
74 | - | | ||
75 | @@ -XXX,XX +XXX,XX @@ examples: | ||
76 | offset = <0x0>; | ||
77 | mask = <0x1>; | ||
78 | }; | ||
79 | + | ||
80 | + - | | ||
81 | + reboot { | ||
82 | + compatible = "google,gs101-reboot"; | ||
83 | + }; | ||
49 | 84 | ||
50 | -- | 85 | -- |
51 | 2.49.0.472.ge94155a9ec-goog | 86 | 2.49.0.472.ge94155a9ec-goog |
52 | 87 | diff view generated by jsdifflib |
1 | Linux supports a couple different reset modes, but this driver here | 1 | Linux supports a couple different reset modes, but this driver here |
---|---|---|---|
2 | doesn't distinguish between them and issues the same syscon register | 2 | doesn't distinguish between them and issues the same syscon register |
3 | write irrespective of the reset mode requested by the kernel. | 3 | write irrespective of the reset mode requested by the kernel. |
4 | 4 | ||
5 | Since DTs should not encode register writes (see e.g. [1]), update this | 5 | Since DTs should not encode register writes (see e.g. [1]), update this |
6 | driver to support different reset modes based on DT compatible match. | 6 | driver to support different reset modes based on DT compatible match. |
7 | 7 | ||
8 | At the same time, add support for Google GS101, which does support | 8 | At the same time, add support for Google GS101, which does support |
9 | cold, hard, warm, and soft. | 9 | cold, hard, warm, and soft. |
10 | 10 | ||
11 | As an example why this is useful, other than properly supporting the | 11 | As an example why this is useful, other than properly supporting the |
12 | Linux reboot= kernel command line option or sysfs entry, this change | 12 | Linux reboot= kernel command line option or sysfs entry, this change |
13 | allows gs101-platforms to default to a more secure cold-reset, but also | 13 | allows gs101-platforms to default to a more secure cold-reset, but also |
14 | to warm-reset in case RAM contents needs to be retained across the | 14 | to warm-reset in case RAM contents needs to be retained across the |
15 | reset. | 15 | reset. |
16 | 16 | ||
17 | Link: https://lore.kernel.org/all/20250227132644.GA1924628-robh@kernel.org/ [1] | 17 | Link: https://lore.kernel.org/all/20250227132644.GA1924628-robh@kernel.org/ [1] |
18 | Signed-off-by: André Draszik <andre.draszik@linaro.org> | 18 | Signed-off-by: André Draszik <andre.draszik@linaro.org> |
19 | --- | 19 | --- |
20 | drivers/power/reset/syscon-reboot.c | 98 +++++++++++++++++++++++++++++-------- | 20 | drivers/power/reset/syscon-reboot.c | 98 +++++++++++++++++++++++++++++-------- |
21 | 1 file changed, 77 insertions(+), 21 deletions(-) | 21 | 1 file changed, 77 insertions(+), 21 deletions(-) |
22 | 22 | ||
23 | diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c | 23 | diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c |
24 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/drivers/power/reset/syscon-reboot.c | 25 | --- a/drivers/power/reset/syscon-reboot.c |
26 | +++ b/drivers/power/reset/syscon-reboot.c | 26 | +++ b/drivers/power/reset/syscon-reboot.c |
27 | @@ -XXX,XX +XXX,XX @@ | 27 | @@ -XXX,XX +XXX,XX @@ |
28 | #include <linux/reboot.h> | 28 | #include <linux/reboot.h> |
29 | #include <linux/regmap.h> | 29 | #include <linux/regmap.h> |
30 | 30 | ||
31 | -struct syscon_reboot_context { | 31 | -struct syscon_reboot_context { |
32 | - struct regmap *map; | 32 | - struct regmap *map; |
33 | +struct reboot_mode_bits { | 33 | +struct reboot_mode_bits { |
34 | u32 offset; | 34 | u32 offset; |
35 | - u32 value; | 35 | - u32 value; |
36 | u32 mask; | 36 | u32 mask; |
37 | + u32 value; | 37 | + u32 value; |
38 | + bool valid; | 38 | + bool valid; |
39 | +}; | 39 | +}; |
40 | + | 40 | + |
41 | +struct reboot_data { | 41 | +struct reboot_data { |
42 | + struct reboot_mode_bits mode_bits[REBOOT_SOFT + 1]; | 42 | + struct reboot_mode_bits mode_bits[REBOOT_SOFT + 1]; |
43 | + struct reboot_mode_bits catchall; | 43 | + struct reboot_mode_bits catchall; |
44 | +}; | 44 | +}; |
45 | + | 45 | + |
46 | +struct syscon_reboot_context { | 46 | +struct syscon_reboot_context { |
47 | + struct regmap *map; | 47 | + struct regmap *map; |
48 | + | 48 | + |
49 | + const struct reboot_data *rd; /* from of match data, if any */ | 49 | + const struct reboot_data *rd; /* from of match data, if any */ |
50 | + struct reboot_mode_bits catchall; /* from DT */ | 50 | + struct reboot_mode_bits catchall; /* from DT */ |
51 | + | 51 | + |
52 | struct notifier_block restart_handler; | 52 | struct notifier_block restart_handler; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | @@ -XXX,XX +XXX,XX @@ static int syscon_restart_handle(struct notifier_block *this, | 55 | @@ -XXX,XX +XXX,XX @@ static int syscon_restart_handle(struct notifier_block *this, |
56 | struct syscon_reboot_context *ctx = | 56 | struct syscon_reboot_context *ctx = |
57 | container_of(this, struct syscon_reboot_context, | 57 | container_of(this, struct syscon_reboot_context, |
58 | restart_handler); | 58 | restart_handler); |
59 | + const struct reboot_mode_bits *mode_bits; | 59 | + const struct reboot_mode_bits *mode_bits; |
60 | + | 60 | + |
61 | + if (ctx->rd) { | 61 | + if (ctx->rd) { |
62 | + if (mode < ARRAY_SIZE(ctx->rd->mode_bits) && | 62 | + if (mode < ARRAY_SIZE(ctx->rd->mode_bits) && |
63 | + ctx->rd->mode_bits[mode].valid) | 63 | + ctx->rd->mode_bits[mode].valid) |
64 | + mode_bits = &ctx->rd->mode_bits[mode]; | 64 | + mode_bits = &ctx->rd->mode_bits[mode]; |
65 | + else | 65 | + else |
66 | + mode_bits = &ctx->rd->catchall; | 66 | + mode_bits = &ctx->rd->catchall; |
67 | + } else { | 67 | + } else { |
68 | + mode_bits = &ctx->catchall; | 68 | + mode_bits = &ctx->catchall; |
69 | + } | 69 | + } |
70 | 70 | ||
71 | /* Issue the reboot */ | 71 | /* Issue the reboot */ |
72 | - regmap_update_bits(ctx->map, ctx->offset, ctx->mask, ctx->value); | 72 | - regmap_update_bits(ctx->map, ctx->offset, ctx->mask, ctx->value); |
73 | + regmap_update_bits(ctx->map, mode_bits->offset, mode_bits->mask, | 73 | + regmap_update_bits(ctx->map, mode_bits->offset, mode_bits->mask, |
74 | + mode_bits->value); | 74 | + mode_bits->value); |
75 | 75 | ||
76 | mdelay(1000); | 76 | mdelay(1000); |
77 | 77 | ||
78 | @@ -XXX,XX +XXX,XX @@ static int syscon_reboot_probe(struct platform_device *pdev) | 78 | @@ -XXX,XX +XXX,XX @@ static int syscon_reboot_probe(struct platform_device *pdev) |
79 | { | 79 | { |
80 | struct syscon_reboot_context *ctx; | 80 | struct syscon_reboot_context *ctx; |
81 | struct device *dev = &pdev->dev; | 81 | struct device *dev = &pdev->dev; |
82 | - int mask_err, value_err; | 82 | - int mask_err, value_err; |
83 | int priority; | 83 | int priority; |
84 | int err; | 84 | int err; |
85 | 85 | ||
86 | @@ -XXX,XX +XXX,XX @@ static int syscon_reboot_probe(struct platform_device *pdev) | 86 | @@ -XXX,XX +XXX,XX @@ static int syscon_reboot_probe(struct platform_device *pdev) |
87 | if (of_property_read_s32(pdev->dev.of_node, "priority", &priority)) | 87 | if (of_property_read_s32(pdev->dev.of_node, "priority", &priority)) |
88 | priority = 192; | 88 | priority = 192; |
89 | 89 | ||
90 | - if (of_property_read_u32(pdev->dev.of_node, "offset", &ctx->offset)) | 90 | - if (of_property_read_u32(pdev->dev.of_node, "offset", &ctx->offset)) |
91 | - if (of_property_read_u32(pdev->dev.of_node, "reg", &ctx->offset)) | 91 | - if (of_property_read_u32(pdev->dev.of_node, "reg", &ctx->offset)) |
92 | - return -EINVAL; | 92 | - return -EINVAL; |
93 | + ctx->rd = of_device_get_match_data(dev); | 93 | + ctx->rd = of_device_get_match_data(dev); |
94 | + if (!ctx->rd) { | 94 | + if (!ctx->rd) { |
95 | + int mask_err, value_err; | 95 | + int mask_err, value_err; |
96 | 96 | ||
97 | - value_err = of_property_read_u32(pdev->dev.of_node, "value", &ctx->value); | 97 | - value_err = of_property_read_u32(pdev->dev.of_node, "value", &ctx->value); |
98 | - mask_err = of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask); | 98 | - mask_err = of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask); |
99 | - if (value_err && mask_err) { | 99 | - if (value_err && mask_err) { |
100 | - dev_err(dev, "unable to read 'value' and 'mask'"); | 100 | - dev_err(dev, "unable to read 'value' and 'mask'"); |
101 | - return -EINVAL; | 101 | - return -EINVAL; |
102 | - } | 102 | - } |
103 | + if (of_property_read_u32(pdev->dev.of_node, "offset", | 103 | + if (of_property_read_u32(pdev->dev.of_node, "offset", |
104 | + &ctx->catchall.offset) && | 104 | + &ctx->catchall.offset) && |
105 | + of_property_read_u32(pdev->dev.of_node, "reg", | 105 | + of_property_read_u32(pdev->dev.of_node, "reg", |
106 | + &ctx->catchall.offset)) | 106 | + &ctx->catchall.offset)) |
107 | + return -EINVAL; | 107 | + return -EINVAL; |
108 | 108 | ||
109 | - if (value_err) { | 109 | - if (value_err) { |
110 | - /* support old binding */ | 110 | - /* support old binding */ |
111 | - ctx->value = ctx->mask; | 111 | - ctx->value = ctx->mask; |
112 | - ctx->mask = 0xFFFFFFFF; | 112 | - ctx->mask = 0xFFFFFFFF; |
113 | - } else if (mask_err) { | 113 | - } else if (mask_err) { |
114 | - /* support value without mask*/ | 114 | - /* support value without mask*/ |
115 | - ctx->mask = 0xFFFFFFFF; | 115 | - ctx->mask = 0xFFFFFFFF; |
116 | + value_err = of_property_read_u32(pdev->dev.of_node, "value", | 116 | + value_err = of_property_read_u32(pdev->dev.of_node, "value", |
117 | + &ctx->catchall.value); | 117 | + &ctx->catchall.value); |
118 | + mask_err = of_property_read_u32(pdev->dev.of_node, "mask", | 118 | + mask_err = of_property_read_u32(pdev->dev.of_node, "mask", |
119 | + &ctx->catchall.mask); | 119 | + &ctx->catchall.mask); |
120 | + if (value_err && mask_err) { | 120 | + if (value_err && mask_err) { |
121 | + dev_err(dev, "unable to read 'value' and 'mask'"); | 121 | + dev_err(dev, "unable to read 'value' and 'mask'"); |
122 | + return -EINVAL; | 122 | + return -EINVAL; |
123 | + } | 123 | + } |
124 | + | 124 | + |
125 | + if (value_err) { | 125 | + if (value_err) { |
126 | + /* support old binding */ | 126 | + /* support old binding */ |
127 | + ctx->catchall.value = ctx->catchall.mask; | 127 | + ctx->catchall.value = ctx->catchall.mask; |
128 | + ctx->catchall.mask = 0xFFFFFFFF; | 128 | + ctx->catchall.mask = 0xFFFFFFFF; |
129 | + } else if (mask_err) { | 129 | + } else if (mask_err) { |
130 | + /* support value without mask */ | 130 | + /* support value without mask */ |
131 | + ctx->catchall.mask = 0xFFFFFFFF; | 131 | + ctx->catchall.mask = 0xFFFFFFFF; |
132 | + } | 132 | + } |
133 | } | 133 | } |
134 | 134 | ||
135 | ctx->restart_handler.notifier_call = syscon_restart_handle; | 135 | ctx->restart_handler.notifier_call = syscon_restart_handle; |
136 | @@ -XXX,XX +XXX,XX @@ static int syscon_reboot_probe(struct platform_device *pdev) | 136 | @@ -XXX,XX +XXX,XX @@ static int syscon_reboot_probe(struct platform_device *pdev) |
137 | return err; | 137 | return err; |
138 | } | 138 | } |
139 | 139 | ||
140 | +static const struct reboot_data gs101_reboot_data = { | 140 | +static const struct reboot_data gs101_reboot_data = { |
141 | + .mode_bits = { | 141 | + .mode_bits = { |
142 | + [REBOOT_WARM] = { | 142 | + [REBOOT_WARM] = { |
143 | + .offset = 0x3a00, /* SYSTEM_CONFIGURATION */ | 143 | + .offset = 0x3a00, /* SYSTEM_CONFIGURATION */ |
144 | + .mask = 0x00000002, /* SWRESET_SYSTEM */ | 144 | + .mask = 0x00000002, /* SWRESET_SYSTEM */ |
145 | + .value = 0x00000002, | 145 | + .value = 0x00000002, |
146 | + .valid = true, | 146 | + .valid = true, |
147 | + }, | 147 | + }, |
148 | + [REBOOT_SOFT] = { | 148 | + [REBOOT_SOFT] = { |
149 | + .offset = 0x3a00, /* SYSTEM_CONFIGURATION */ | 149 | + .offset = 0x3a00, /* SYSTEM_CONFIGURATION */ |
150 | + .mask = 0x00000002, /* SWRESET_SYSTEM */ | 150 | + .mask = 0x00000002, /* SWRESET_SYSTEM */ |
151 | + .value = 0x00000002, | 151 | + .value = 0x00000002, |
152 | + .valid = true, | 152 | + .valid = true, |
153 | + }, | 153 | + }, |
154 | + }, | 154 | + }, |
155 | + .catchall = { | 155 | + .catchall = { |
156 | + .offset = 0x3e9c, /* PAD_CTRL_PWR_HOLD */ | 156 | + .offset = 0x3e9c, /* PAD_CTRL_PWR_HOLD */ |
157 | + .mask = 0x00000100, | 157 | + .mask = 0x00000100, |
158 | + .value = 0x00000000, | 158 | + .value = 0x00000000, |
159 | + }, | 159 | + }, |
160 | +}; | 160 | +}; |
161 | + | 161 | + |
162 | static const struct of_device_id syscon_reboot_of_match[] = { | 162 | static const struct of_device_id syscon_reboot_of_match[] = { |
163 | + { .compatible = "google,gs101-reboot", .data = &gs101_reboot_data }, | 163 | + { .compatible = "google,gs101-reboot", .data = &gs101_reboot_data }, |
164 | { .compatible = "syscon-reboot" }, | 164 | { .compatible = "syscon-reboot" }, |
165 | {} | 165 | {} |
166 | }; | 166 | }; |
167 | 167 | ||
168 | -- | 168 | -- |
169 | 2.49.0.472.ge94155a9ec-goog | 169 | 2.49.0.472.ge94155a9ec-goog |
170 | 170 | diff view generated by jsdifflib |