[U-Boot] [PATCH v3 5/9] pinctrl: stm32: Add get_pins_count() ops
Patrice Chotard
patrice.chotard at st.com
Tue Oct 9 13:31:24 UTC 2018
Add get_pins_count ops to obtain the number of pins
owns by a pin-controller.
On STM32 SoCs bindings, each pin-controller owns
several gpio banks. Each GPIO bank can own up to 16 pins.
To obtain the total pins count, walk through each sub-nodes
(ie GPIO banks) and sum each GPIO banks pins number. For that
in probe() we build a list with each GPIO device reference found.
This list will also be used with future get_pin_muxing and get_pin_name
ops to speed up and optimize walk through all GPIO banks.
As this code is common to all STM32 SoCs, this code is put
under SPL_BUILD compilation flag to avoid to increase SPL code size
for STM32F7 which is limited to 32Ko.
Signed-off-by: Patrice Chotard <patrice.chotard at st.com>
---
Changes in v3: None
Changes in v2: None
drivers/pinctrl/pinctrl_stm32.c | 94 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 89 insertions(+), 5 deletions(-)
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c
index 31285cdd5784..82ac261dafea 100644
--- a/drivers/pinctrl/pinctrl_stm32.c
+++ b/drivers/pinctrl/pinctrl_stm32.c
@@ -14,6 +14,83 @@ DECLARE_GLOBAL_DATA_PTR;
#define OTYPE_MSK 1
#define AFR_MASK 0xF
+#ifndef CONFIG_SPL_BUILD
+struct stm32_pinctrl_priv {
+ int pinctrl_ngpios;
+ struct list_head gpio_dev;
+};
+
+struct stm32_gpio_bank {
+ struct udevice *gpio_dev;
+ struct list_head list;
+};
+
+static int stm32_pinctrl_get_pins_count(struct udevice *dev)
+{
+ struct stm32_pinctrl_priv *priv = dev_get_priv(dev);
+ struct gpio_dev_priv *uc_priv;
+ struct stm32_gpio_bank *gpio_bank;
+
+ /*
+ * if get_pins_count has already been executed once on this
+ * pin-controller, no need to run it again
+ */
+ if (priv->pinctrl_ngpios)
+ return priv->pinctrl_ngpios;
+
+ /*
+ * walk through all banks to retrieve the pin-controller
+ * pins number
+ */
+ list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
+ uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
+
+ priv->pinctrl_ngpios += uc_priv->gpio_count;
+ }
+
+ return priv->pinctrl_ngpios;
+}
+
+int stm32_pinctrl_probe(struct udevice *dev)
+{
+ struct stm32_pinctrl_priv *priv = dev_get_priv(dev);
+ struct udevice *gpio_dev;
+ struct udevice *child;
+ struct stm32_gpio_bank *gpio_bank;
+ int ret;
+
+ INIT_LIST_HEAD(&priv->gpio_dev);
+
+ /*
+ * parse pin-controller sub-nodes (ie gpio bank nodes) and fill
+ * a list with all gpio device reference which belongs to the
+ * current pin-controller. This list is used to find pin_name and
+ * pin muxing
+ */
+ list_for_each_entry(child, &dev->child_head, sibling_node) {
+ ret = uclass_get_device_by_name(UCLASS_GPIO, child->name,
+ &gpio_dev);
+
+ if (ret < 0 && ret != -ENODEV) {
+ dev_err(dev, "Failed to find %s device ret = %d\n",
+ child->name, ret);
+ return ret;
+ }
+
+ gpio_bank = malloc(sizeof(*gpio_bank));
+ if (!gpio_bank) {
+ dev_err(dev, "Not enough memory\n");
+ return -ENOMEM;
+ }
+
+ gpio_bank->gpio_dev = gpio_dev;
+ list_add_tail(&gpio_bank->list, &priv->gpio_dev);
+ }
+
+ return 0;
+}
+#endif
+
static int stm32_gpio_config(struct gpio_desc *desc,
const struct stm32_gpio_ctl *ctl)
{
@@ -182,6 +259,9 @@ static struct pinctrl_ops stm32_pinctrl_ops = {
#else /* PINCTRL_FULL */
.set_state_simple = stm32_pinctrl_set_state_simple,
#endif /* PINCTRL_FULL */
+#ifndef CONFIG_SPL_BUILD
+ .get_pins_count = stm32_pinctrl_get_pins_count,
+#endif
};
static const struct udevice_id stm32_pinctrl_ids[] = {
@@ -195,9 +275,13 @@ static const struct udevice_id stm32_pinctrl_ids[] = {
};
U_BOOT_DRIVER(pinctrl_stm32) = {
- .name = "pinctrl_stm32",
- .id = UCLASS_PINCTRL,
- .of_match = stm32_pinctrl_ids,
- .ops = &stm32_pinctrl_ops,
- .bind = dm_scan_fdt_dev,
+ .name = "pinctrl_stm32",
+ .id = UCLASS_PINCTRL,
+ .of_match = stm32_pinctrl_ids,
+ .ops = &stm32_pinctrl_ops,
+ .bind = dm_scan_fdt_dev,
+#ifndef CONFIG_SPL_BUILD
+ .probe = stm32_pinctrl_probe,
+ .priv_auto_alloc_size = sizeof(struct stm32_pinctrl_priv),
+#endif
};
--
1.9.1
More information about the U-Boot
mailing list