On Di, 2024-01-23 at 15:13 +0100, Krzysztof Kozlowski wrote:
Devices sharing a reset GPIO could use the reset framework for coordinated handling of that shared GPIO line. We have several cases of such needs, at least for Devicetree-based platforms.
If Devicetree-based device requests a reset line, while "resets" Devicetree property is missing but there is a "reset-gpios" one, instantiate a new "reset-gpio" platform device which will handle such reset line. This allows seamless handling of such shared reset-gpios without need of changing Devicetree binding [1].
To avoid creating multiple "reset-gpio" platform devices, store the Devicetree "reset-gpios" GPIO specifiers used for new devices on a linked list. Later such Devicetree GPIO specifier (phandle to GPIO controller, GPIO number and GPIO flags) is used to check if reset controller for given GPIO was already registered.
If two devices have conflicting "reset-gpios" property, e.g. with different ACTIVE_xxx flags, this would allow to spawn two separate "reset-gpio" devices, where the second would fail probing on busy GPIO request.
Link: https://lore.kernel.org/all/YXi5CUCEi7YmNxXM@robh.at.kernel.org/ [1] Cc: Bartosz Golaszewski brgl@bgdev.pl Cc: Chris Packham chris.packham@alliedtelesis.co.nz Cc: Sean Anderson sean.anderson@seco.com Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
I'm nearly out of complaints, two tiny cosmetic issues remaining:
[...]
diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 4d5a78d3c085..6e81b8d35055 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c
[...]
@@ -813,12 +838,161 @@ static void __reset_control_put_internal(struct reset_control *rstc) kref_put(&rstc->refcnt, __reset_control_release); }
+static int __reset_add_reset_gpio_lookup(int id, struct device_node *np,
unsigned int gpio,
unsigned int of_flags)
+{
- unsigned int lookup_flags;
- const char *label_tmp;
- /*
* Later we map GPIO flags between OF and Linux, however not all
* constants from include/dt-bindings/gpio/gpio.h and
* include/linux/gpio/machine.h match each other.
*/
- if (of_flags > GPIO_ACTIVE_LOW) {
pr_err("reset-gpio code does not support GPIO flags %u for GPIO %u\n",
of_flags, gpio);
Alignment to parenthesis is slightly off.
return -EINVAL;
- }
- struct gpio_device *gdev __free(gpio_device_put) = gpio_device_find_by_fwnode(of_fwnode_handle(np));
Adding a local fwnode variable would make this fit in the 100 character limit again.
regards Philipp