summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Eichenberger <stefan.eichenberger@toradex.com>2023-10-13 15:15:18 +0200
committerStefan Eichenberger <eichest@gmail.com>2023-10-13 15:20:19 +0200
commitc41e9b77a451693df5755fca03e8db1956e8b2be (patch)
tree3fae1dbc62b43b3da6004c13872f26b13c003e26
parent16e5f73b2b294855fe579e8252b149154bdb7322 (diff)
linux-toradex-mainline: Add patches to support gpio poweroff priority
This commit adds a patch series which allows to set a higher priority for gpio-poweroff. This allows to execute the gpio-poweroff before a default poweroff handler. The patch series has been submitted upstream [1]. [1] https://lore.kernel.org/all/20231006130428.11259-1-francesco@dolcini.it/ Related-to: ELB-5383 Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
-rw-r--r--recipes-kernel/linux/linux-toradex-mainline-git/0001-power-reset-gpio-poweroff-use-a-struct-to-store-the-.patch108
-rw-r--r--recipes-kernel/linux/linux-toradex-mainline-git/0002-power-reset-gpio-poweroff-use-sys-off-handler-API.patch101
-rw-r--r--recipes-kernel/linux/linux-toradex-mainline-git/0003-dt-bindings-power-reset-gpio-poweroff-Add-priority-p.patch43
-rw-r--r--recipes-kernel/linux/linux-toradex-mainline-git/0004-power-reset-gpio-poweroff-make-sys-handler-priority-.patch52
-rw-r--r--recipes-kernel/linux/linux-toradex-mainline_git.bb4
5 files changed, 308 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-toradex-mainline-git/0001-power-reset-gpio-poweroff-use-a-struct-to-store-the-.patch b/recipes-kernel/linux/linux-toradex-mainline-git/0001-power-reset-gpio-poweroff-use-a-struct-to-store-the-.patch
new file mode 100644
index 0000000..1632b53
--- /dev/null
+++ b/recipes-kernel/linux/linux-toradex-mainline-git/0001-power-reset-gpio-poweroff-use-a-struct-to-store-the-.patch
@@ -0,0 +1,108 @@
+From 9b5f4266b75827bdc63f41aac93ee585c8feee49 Mon Sep 17 00:00:00 2001
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Date: Wed, 20 Sep 2023 10:45:54 +0200
+Subject: [PATCH 1/4] power: reset: gpio-poweroff: use a struct to store the
+ module variables
+
+Use a struct to store the module variables. This is required to later
+move to notifier_blocks where we can have several instances.
+
+Upstream-Status: Submitted [https://lore.kernel.org/all/20231006130428.11259-1-francesco@dolcini.it/]
+
+Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+---
+ drivers/power/reset/gpio-poweroff.c | 48 +++++++++++++++++++----------
+ 1 file changed, 31 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
+index 1c5af2fef1423..8b99f6ebb2fcf 100644
+--- a/drivers/power/reset/gpio-poweroff.c
++++ b/drivers/power/reset/gpio-poweroff.c
+@@ -16,32 +16,37 @@
+ #include <linux/module.h>
+
+ #define DEFAULT_TIMEOUT_MS 3000
++
++struct gpio_poweroff {
++ struct gpio_desc *reset_gpio;
++ u32 timeout_ms;
++ u32 active_delay_ms;
++ u32 inactive_delay_ms;
++};
++
+ /*
+ * Hold configuration here, cannot be more than one instance of the driver
+ * since pm_power_off itself is global.
+ */
+-static struct gpio_desc *reset_gpio;
+-static u32 timeout = DEFAULT_TIMEOUT_MS;
+-static u32 active_delay = 100;
+-static u32 inactive_delay = 100;
++static struct gpio_poweroff *gpio_poweroff;
+
+ static void gpio_poweroff_do_poweroff(void)
+ {
+- BUG_ON(!reset_gpio);
++ BUG_ON(!gpio_poweroff);
+
+ /* drive it active, also inactive->active edge */
+- gpiod_direction_output(reset_gpio, 1);
+- mdelay(active_delay);
++ gpiod_direction_output(gpio_poweroff->reset_gpio, 1);
++ mdelay(gpio_poweroff->active_delay_ms);
+
+ /* drive inactive, also active->inactive edge */
+- gpiod_set_value_cansleep(reset_gpio, 0);
+- mdelay(inactive_delay);
++ gpiod_set_value_cansleep(gpio_poweroff->reset_gpio, 0);
++ mdelay(gpio_poweroff->inactive_delay_ms);
+
+ /* drive it active, also inactive->active edge */
+- gpiod_set_value_cansleep(reset_gpio, 1);
++ gpiod_set_value_cansleep(gpio_poweroff->reset_gpio, 1);
+
+ /* give it some time */
+- mdelay(timeout);
++ mdelay(gpio_poweroff->timeout_ms);
+
+ WARN_ON(1);
+ }
+@@ -59,20 +64,29 @@ static int gpio_poweroff_probe(struct platform_device *pdev)
+ return -EBUSY;
+ }
+
++ gpio_poweroff = devm_kzalloc(&pdev->dev, sizeof(*gpio_poweroff), GFP_KERNEL);
++ if (!gpio_poweroff)
++ return -ENOMEM;
++
+ input = device_property_read_bool(&pdev->dev, "input");
+ if (input)
+ flags = GPIOD_IN;
+ else
+ flags = GPIOD_OUT_LOW;
+
+- device_property_read_u32(&pdev->dev, "active-delay-ms", &active_delay);
++
++ gpio_poweroff->active_delay_ms = 100;
++ gpio_poweroff->inactive_delay_ms = 100;
++ gpio_poweroff->timeout_ms = DEFAULT_TIMEOUT_MS;
++
++ device_property_read_u32(&pdev->dev, "active-delay-ms", &gpio_poweroff->active_delay_ms);
+ device_property_read_u32(&pdev->dev, "inactive-delay-ms",
+- &inactive_delay);
+- device_property_read_u32(&pdev->dev, "timeout-ms", &timeout);
++ &gpio_poweroff->inactive_delay_ms);
++ device_property_read_u32(&pdev->dev, "timeout-ms", &gpio_poweroff->timeout_ms);
+
+- reset_gpio = devm_gpiod_get(&pdev->dev, NULL, flags);
+- if (IS_ERR(reset_gpio))
+- return PTR_ERR(reset_gpio);
++ gpio_poweroff->reset_gpio = devm_gpiod_get(&pdev->dev, NULL, flags);
++ if (IS_ERR(gpio_poweroff->reset_gpio))
++ return PTR_ERR(gpio_poweroff->reset_gpio);
+
+ pm_power_off = &gpio_poweroff_do_poweroff;
+ return 0;
+--
+2.39.2
+
diff --git a/recipes-kernel/linux/linux-toradex-mainline-git/0002-power-reset-gpio-poweroff-use-sys-off-handler-API.patch b/recipes-kernel/linux/linux-toradex-mainline-git/0002-power-reset-gpio-poweroff-use-sys-off-handler-API.patch
new file mode 100644
index 0000000..bdf8364
--- /dev/null
+++ b/recipes-kernel/linux/linux-toradex-mainline-git/0002-power-reset-gpio-poweroff-use-sys-off-handler-API.patch
@@ -0,0 +1,101 @@
+From e762528fae6393686f4ff2bd3c2ca89ec0b8f5c5 Mon Sep 17 00:00:00 2001
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Date: Wed, 20 Sep 2023 17:49:09 +0200
+Subject: [PATCH 2/4] power: reset: gpio-poweroff: use sys-off handler API
+
+Use the new sys-off handler API for gpio-poweroff. This allows us to
+have more than one poweroff handler and prioritise them.
+
+Upstream-Status: Submitted [https://lore.kernel.org/all/20231006130428.11259-1-francesco@dolcini.it/]
+
+Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+---
+ drivers/power/reset/gpio-poweroff.c | 37 ++++++++++-------------------
+ 1 file changed, 12 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
+index 8b99f6ebb2fcf..d2548010369b0 100644
+--- a/drivers/power/reset/gpio-poweroff.c
++++ b/drivers/power/reset/gpio-poweroff.c
+@@ -14,6 +14,7 @@
+ #include <linux/gpio/consumer.h>
+ #include <linux/of_platform.h>
+ #include <linux/module.h>
++#include <linux/reboot.h>
+
+ #define DEFAULT_TIMEOUT_MS 3000
+
+@@ -24,15 +25,9 @@ struct gpio_poweroff {
+ u32 inactive_delay_ms;
+ };
+
+-/*
+- * Hold configuration here, cannot be more than one instance of the driver
+- * since pm_power_off itself is global.
+- */
+-static struct gpio_poweroff *gpio_poweroff;
+-
+-static void gpio_poweroff_do_poweroff(void)
++static int gpio_poweroff_do_poweroff(struct sys_off_data *data)
+ {
+- BUG_ON(!gpio_poweroff);
++ struct gpio_poweroff *gpio_poweroff = data->cb_data;
+
+ /* drive it active, also inactive->active edge */
+ gpiod_direction_output(gpio_poweroff->reset_gpio, 1);
+@@ -49,20 +44,16 @@ static void gpio_poweroff_do_poweroff(void)
+ mdelay(gpio_poweroff->timeout_ms);
+
+ WARN_ON(1);
++
++ return NOTIFY_DONE;
+ }
+
+ static int gpio_poweroff_probe(struct platform_device *pdev)
+ {
++ struct gpio_poweroff *gpio_poweroff;
+ bool input = false;
+ enum gpiod_flags flags;
+-
+- /* If a pm_power_off function has already been added, leave it alone */
+- if (pm_power_off != NULL) {
+- dev_err(&pdev->dev,
+- "%s: pm_power_off function already registered\n",
+- __func__);
+- return -EBUSY;
+- }
++ int ret;
+
+ gpio_poweroff = devm_kzalloc(&pdev->dev, sizeof(*gpio_poweroff), GFP_KERNEL);
+ if (!gpio_poweroff)
+@@ -88,14 +79,11 @@ static int gpio_poweroff_probe(struct platform_device *pdev)
+ if (IS_ERR(gpio_poweroff->reset_gpio))
+ return PTR_ERR(gpio_poweroff->reset_gpio);
+
+- pm_power_off = &gpio_poweroff_do_poweroff;
+- return 0;
+-}
+-
+-static int gpio_poweroff_remove(struct platform_device *pdev)
+-{
+- if (pm_power_off == &gpio_poweroff_do_poweroff)
+- pm_power_off = NULL;
++ ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
++ SYS_OFF_PRIO_DEFAULT, gpio_poweroff_do_poweroff,
++ gpio_poweroff);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "Cannot register poweroff handler\n");
+
+ return 0;
+ }
+@@ -108,7 +96,6 @@ MODULE_DEVICE_TABLE(of, of_gpio_poweroff_match);
+
+ static struct platform_driver gpio_poweroff_driver = {
+ .probe = gpio_poweroff_probe,
+- .remove = gpio_poweroff_remove,
+ .driver = {
+ .name = "poweroff-gpio",
+ .of_match_table = of_gpio_poweroff_match,
+--
+2.39.2
+
diff --git a/recipes-kernel/linux/linux-toradex-mainline-git/0003-dt-bindings-power-reset-gpio-poweroff-Add-priority-p.patch b/recipes-kernel/linux/linux-toradex-mainline-git/0003-dt-bindings-power-reset-gpio-poweroff-Add-priority-p.patch
new file mode 100644
index 0000000..a886b58
--- /dev/null
+++ b/recipes-kernel/linux/linux-toradex-mainline-git/0003-dt-bindings-power-reset-gpio-poweroff-Add-priority-p.patch
@@ -0,0 +1,43 @@
+From de109153fbdc722a63a880101bc0f2065ac029b2 Mon Sep 17 00:00:00 2001
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Date: Wed, 20 Sep 2023 18:14:49 +0200
+Subject: [PATCH 3/4] dt-bindings: power: reset: gpio-poweroff: Add priority
+ property
+
+Add the priority property to the gpio-poweroff bindings description.
+
+Upstream-Status: Submitted [https://lore.kernel.org/all/20231006130428.11259-1-francesco@dolcini.it/]
+
+Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+---
+ .../devicetree/bindings/power/reset/gpio-poweroff.yaml | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/power/reset/gpio-poweroff.yaml b/Documentation/devicetree/bindings/power/reset/gpio-poweroff.yaml
+index 45d66c7751156..0d1d8d28ccdbb 100644
+--- a/Documentation/devicetree/bindings/power/reset/gpio-poweroff.yaml
++++ b/Documentation/devicetree/bindings/power/reset/gpio-poweroff.yaml
+@@ -18,6 +18,9 @@ description: >
+ Finally the operating system assumes the power off failed if
+ the system is still running after waiting some time (timeout-ms).
+
++allOf:
++ - $ref: restart-handler.yaml#
++
+ properties:
+ compatible:
+ const: gpio-poweroff
+@@ -40,6 +43,10 @@ properties:
+ default: 100
+ description: Delay to wait after driving gpio inactive
+
++ priority:
++ default: 0
++ description: Priority of the power off handler
++
+ timeout-ms:
+ default: 3000
+ description: Time to wait before assuming the power off sequence failed.
+--
+2.39.2
+
diff --git a/recipes-kernel/linux/linux-toradex-mainline-git/0004-power-reset-gpio-poweroff-make-sys-handler-priority-.patch b/recipes-kernel/linux/linux-toradex-mainline-git/0004-power-reset-gpio-poweroff-make-sys-handler-priority-.patch
new file mode 100644
index 0000000..44d037c
--- /dev/null
+++ b/recipes-kernel/linux/linux-toradex-mainline-git/0004-power-reset-gpio-poweroff-make-sys-handler-priority-.patch
@@ -0,0 +1,52 @@
+From 36991ce6ffece72d961a474f994ed5a05efaaca8 Mon Sep 17 00:00:00 2001
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Date: Wed, 20 Sep 2023 18:07:19 +0200
+Subject: [PATCH 4/4] power: reset: gpio-poweroff: make sys handler priority
+ configurable
+
+Add a priority property equal to gpio-restart to allow increasing the
+priority of the gpio-poweroff handler.
+
+Upstream-Status: Submitted [https://lore.kernel.org/all/20231006130428.11259-1-francesco@dolcini.it/]
+
+Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+---
+ drivers/power/reset/gpio-poweroff.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
+index d2548010369b0..46d94f660f87d 100644
+--- a/drivers/power/reset/gpio-poweroff.c
++++ b/drivers/power/reset/gpio-poweroff.c
+@@ -53,6 +53,7 @@ static int gpio_poweroff_probe(struct platform_device *pdev)
+ struct gpio_poweroff *gpio_poweroff;
+ bool input = false;
+ enum gpiod_flags flags;
++ int priority = SYS_OFF_PRIO_DEFAULT;
+ int ret;
+
+ gpio_poweroff = devm_kzalloc(&pdev->dev, sizeof(*gpio_poweroff), GFP_KERNEL);
+@@ -74,14 +75,18 @@ static int gpio_poweroff_probe(struct platform_device *pdev)
+ device_property_read_u32(&pdev->dev, "inactive-delay-ms",
+ &gpio_poweroff->inactive_delay_ms);
+ device_property_read_u32(&pdev->dev, "timeout-ms", &gpio_poweroff->timeout_ms);
++ device_property_read_u32(&pdev->dev, "priority", &priority);
++ if (priority > 255) {
++ dev_err(&pdev->dev, "Invalid priority property: %u\n", priority);
++ return -EINVAL;
++ }
+
+ gpio_poweroff->reset_gpio = devm_gpiod_get(&pdev->dev, NULL, flags);
+ if (IS_ERR(gpio_poweroff->reset_gpio))
+ return PTR_ERR(gpio_poweroff->reset_gpio);
+
+ ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
+- SYS_OFF_PRIO_DEFAULT, gpio_poweroff_do_poweroff,
+- gpio_poweroff);
++ priority, gpio_poweroff_do_poweroff, gpio_poweroff);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "Cannot register poweroff handler\n");
+
+--
+2.39.2
+
diff --git a/recipes-kernel/linux/linux-toradex-mainline_git.bb b/recipes-kernel/linux/linux-toradex-mainline_git.bb
index 9c95b95..2ab8ffc 100644
--- a/recipes-kernel/linux/linux-toradex-mainline_git.bb
+++ b/recipes-kernel/linux/linux-toradex-mainline_git.bb
@@ -44,6 +44,10 @@ SRC_URI:append = " \
file://0001-media-v4l2-async-fix-binding-async-subdevs-with-mult.patch \
file://0002-media-i2c-ov5640-Implement-get_mbus_config.patch \
file://0001-Revert-media-v4l2-async-Use-endpoints-in-__v4l2_asyn.patch \
+ file://0001-power-reset-gpio-poweroff-use-a-struct-to-store-the-.patch \
+ file://0002-power-reset-gpio-poweroff-use-sys-off-handler-API.patch \
+ file://0003-dt-bindings-power-reset-gpio-poweroff-Add-priority-p.patch \
+ file://0004-power-reset-gpio-poweroff-make-sys-handler-priority-.patch \
"
LINUX_VERSION ?= "6.1.55"