-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix GPIO framework to prevent glitch when requesting an output GPIO #7478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Align the OP-TEE GPIO driver on the Linux GPIO lib behavior for the gpio properties in device tree: search "gpios" or "gpio" when gpio_name is omitted and "foo-gpios" or "foo-gpio" when and if the gpio_name="foo". This patch allows use of the function gpio_dt_get_by_index() by GPIO consumers for all supported bindings. Signed-off-by: Patrick Delaunay <[email protected]> Signed-off-by: Thomas Bourgoin <[email protected]>
Use gpio_dt_get_by_index() to get the properties in device tree with all the possible variant name: "gpio" and "gpios". Signed-off-by: Patrick Delaunay <[email protected]> Signed-off-by: Thomas Bourgoin <[email protected]>
Align the OP-TEE GPIO driver with GPIO lib (devm_gpiod_get_index with enum gpiod_flags) and add a way to select the GPIO configuration directly during request with the new function, gpio_dt_cfg_by_index(). This patch remove assumption on GPIO direction (gpio input was assumed in GPIO driver) or output level when the GPIO is requested by consumer. with this patch it must be requested explicitly with: - GPIO_IN: configure the input GPIO - GPIO_ASIS: direction is managed by caller later with gpio_set_value() call. - GPIO_OUT_LOW / GPIO_OUT_HIGH: output GPIO at expected level, the sequence for GPIO have the correct order to avoid glitch by using the gpio function at the correct order. This patch is a preliminary step for the introduction of ops configure. The API gpio_dt_get_by_index() is keep for backward compatibility but should be used with gpio_configure() or replaced by gpio_dt_cfg_by_index(). Now gpio_configure() is only used in the 2 drivers, regulator_fixed and regulator_gpio, because in these drivers the flags gpio->dt_flags are modified after call of gpio_dt_get_by_index(). For get_voltage_level_gpio(), GPIO_OUT_HIGH is used by default as it is done in Linux function of_get_gpio_regulator_config(). Signed-off-by: Patrick Delaunay <[email protected]> Signed-off-by: Thomas Bourgoin <[email protected]>
Add the new ops configure to initialize the GPIO resource based on dt_flags. This new ops is require to support the modification of dt_flag done by caller after gpio_dt_init_by_index() and before call of gpio_configure(). It is done by example in driver of regulator fixed and gpio. The new ops is called only in gpio_dt_cfg_by_index() or in gpio_configure() so usage of one of this API is manadatory after this patch. Signed-off-by: Patrick Delaunay <[email protected]> Signed-off-by: Thomas Bourgoin <[email protected]>
Move the GPIO configuration based on dt_flags previously done in get_dt ops in the new gpio configure ops. To avoid glitch on GPIO line, the write in register GPIO_MODER is only kept in the ops stm32_gpio_set_direction(), called by gpio framework function gpio_configure() after the call of configure ops, so we have no more transient GPIO input configuration. Moreover, this patch allows to correctly apply the dt_flags when they are modify after the call of stm32_gpio_get_dt(), for example in drivers regulator fixed and gpio. Signed-off-by: Patrick Delaunay <[email protected]> Signed-off-by: Thomas Bourgoin <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some preliminary comments...
for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { | ||
if (gpio_name) | ||
snprintf(prop_name, sizeof(prop_name), "%s-%s", | ||
gpio_name, gpio_suffixes[i]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
snprintf()
return value to check? I could not find where in the DT spec property names shall be at most 32bytes (including terminal \0 char?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The limit of 32 bytes depends on the devicetree specifications :
https://devicetree-specification.readthedocs.io/en/v0.3/devicetree-basics.html#properties
2.2.4.1.
In linux the function of_find_gpio() has the following comment :
char propname[32]; /* 32 is max size of property name */
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, clear. Thanks.
For consistency and help maintenance, could you introduce a DT_PROP_NAME_SIZE_MAX
macro in core/kernel/dt.h through a dedicated commit (which commit message could refer to URL you pointed above)?
I still think snprintf()
return value should be checked, at least asserted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll search for a commit in Linux,
I cannot see why it's mandatory to check the error of snprintf()
, The function cannot overflow and if the property name is too long the search in the DT will fail. It seems to be overprotecting the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. Checking the return value is not needed.
Discard my comment. Sorry for the noise.
remove gpio_configure(); since it's always define independantyly of CFG_DT. Restore inline gpio_dt_get_by_index() stub definition. handle return code of gpio_configure() in gpio_dt_cfg_by_index(). Update comment of gpio_dt_cfg_by_index() to explicitly mention 'gpios', 'gpio', '-gpios' and '-gpio'. Signed-off-by: Thomas Bourgoin <[email protected]>
Do not accept to configure a NULL gpio. Signed-off-by: Thomas Bourgoin <[email protected]>
Update comment of gpio_dt_get_by_index() to explicitly mention 'gpios', 'gpio', '-gpios' and '-gpio'. Signed-off-by: Thomas Bourgoin <[email protected]>
Hello, I've update the series with the most of the comments. Mainly to fix the CI compiling error ASAP. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates. I'm fine you squash any fixup commits.
* gpio_configure() - Configure a GPIO controller | ||
* | ||
* @gpio: GPIO pin reference upon success | ||
* @flags: requester flags of GPIO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/flags/mode/
Or maybe the a more consistent change would be to rename the argument from mode
to flags
.
Ditto in gpio_dt_cfg_by_index()
inline description comment.
} | ||
} | ||
|
||
return TEE_SUCCESS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If always successful, return value is not needed.
That said, I think it would be better to allow configure
ops handler to return a status.
@@ -114,6 +108,10 @@ static TEE_Result get_enable_gpio(const void *fdt, int node, | |||
if (cuint) | |||
regu->off_on_delay = fdt32_to_cpu(*cuint); | |||
|
|||
/* Low level initialisation with updated dt_flags */ | |||
gpio_configure(gpio, GPIO_ASIS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If gpio_configure()
returns a status, it should be checked.
Hello,
During internal test I discovered that a voltage glitch appeared on boards with discrete regulators.
After further investigation I find out that when a GPIO is retrieved from the device tree it's configured as input and then the function gpio_set_direction() is called to configure the GPIO as output.
This intermediate configuration creates a glitch on the voltage line, we should only configure once a GPIO. Especially since the configuration might already be set by the previous bootloader.
When discussing the issue with @patrickdelaunay we found another bug in the
regulator_gpio
andregulator_fixed
drivers.The properties
enable-active-high
,gpio-open-drain
from the device tree are not taken into account. The device tree is parsed and variablegpio->dt_flags
is updated but the configuration of the GPIO with the device tree flags is done in functiongpio_dt_get_by_index()
which is called before parsing the custom options.So this PR does the following :
gpio_dt_get_by_index()
to search for properties with and without suffixes.configure()
ops in GPIO framework configure a GPIO after the parsing of custom properties.gpio_dt_cfg_by_index()
to request a GPIO from the DT and configure it.Thomas