IMX91&IMX93的gpio号配置从0开始

说明

NXP的IMX93、91的sdk从6.1换到6.6之后gpio号就会从512开始,实在是难受,之前写的sysfs的脚本都不能用了。解决下这个问题。

步骤

看patch即可。

yangx@u20:~/linux2/yangx/IMX91/ xxx-IMX91-MB/kernel$ git show 473c96d22ddf9b7ba5eb3626daa4097e63fbae60
commit 473c96d22ddf9b7ba5eb3626daa4097e63fbae60
Author: yangx <yangx@ .com>
Date:   Wed Aug 26 17:53:25 2026 +0800

    gpio: vf610: 按设备树 gpioN alias 固定 GPIO base 顺序

diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
index 13cbde8c9361..16f046debcd9 100644
--- a/drivers/gpio/gpio-vf610.c
+++ b/drivers/gpio/gpio-vf610.c
@@ -357,6 +357,14 @@ static int vf610_gpio_probe(struct platform_device *pdev)
        gc->ngpio = VF610_GPIO_PER_PORT;
        gc->base = -1;

+       /* If DT aliases exist, use gpioN to keep a stable base order. */
+       if (dev->of_node) {
+               int alias_id = of_alias_get_id(dev->of_node, "gpio");
+
+               if (alias_id >= 0)
+                       gc->base = alias_id * 32;
+       }
+
        gc->request = gpiochip_generic_request;
        gc->free = gpiochip_generic_free;
        gc->direction_input = vf610_gpio_direction_input;
yangx@u20:~/linux2/yangx/IMX91/ xxx-IMX91-MB/kernel$ git show 13884146021716926b3765caf78f32a66ea1c0c1
commit 13884146021716926b3765caf78f32a66ea1c0c1
Author: yangx <yangx@ .com>
Date:   Wed Aug 26 17:08:34 2026 +0800

    gpio: GPIO_DYNAMIC_BASE 改为 0,动态 GPIO 从 0 开始分配

diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index 7ecc25c543ce..cd4f91337257 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -69,11 +69,9 @@ static inline bool gpio_is_valid(int number)
  */

 /*
- * At the end we want all GPIOs to be dynamically allocated from 0.
- * However, some legacy drivers still perform fixed allocation.
- * Until they are all fixed, leave 0-512 space for them.
+ * All GPIOs are dynamically allocated from 0.
  */
-#define GPIO_DYNAMIC_BASE      512
+#define GPIO_DYNAMIC_BASE      0

 /* Always use the library code for GPIO management calls,
  * or when sleeping may be involved.
yangx@u20:~/linux2/yangx/IMX91/ xxx-IMX91-MB/kernel$ git show eae3a624c40300b2f71cbd4ed433dd2dc6f59b9b
commit eae3a624c40300b2f71cbd4ed433dd2dc6f59b9b (HEAD -> ENERGY-IMX93-MB)
Author: yangx <yangx@ .com>
Date:   Wed Aug 26 18:00:33 2026 +0800

    arm64: dts: imx93: 调整 GPIO1 节点顺序使 47400000 先注册

diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
index 28d10680cae5..7aab7b168714 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -1324,6 +1324,21 @@ parallel_csi: pcsi@4ac10070 {
                        };
                };

+               gpio1: gpio@47400000 {
+                       compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
+                       reg = <0x47400000 0x1000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       clocks = <&clk IMX93_CLK_GPIO1_GATE>,
+                                <&clk IMX93_CLK_GPIO1_GATE>;
+                       clock-names = "gpio", "port";
+                       gpio-ranges = <&iomuxc 0 92 16>;
+               };
+
                gpio2: gpio@43810000 {
                        compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
                        reg = <0x43810000 0x1000>;
@@ -1370,21 +1385,6 @@ gpio4: gpio@43830000 {
                        gpio-ranges = <&iomuxc 0 38 28>, <&iomuxc 28 36 2>;
                };

-               gpio1: gpio@47400000 {
-                       compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
-                       reg = <0x47400000 0x1000>;
-                       gpio-controller;
-                       #gpio-cells = <2>;
-                       interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-                       clocks = <&clk IMX93_CLK_GPIO1_GATE>,
-                                <&clk IMX93_CLK_GPIO1_GATE>;
-                       clock-names = "gpio", "port";
-                       gpio-ranges = <&iomuxc 0 92 16>;
-               };
-
                ocotp: efuse@47510000 {
                        compatible = "fsl,imx93-ocotp", "syscon", "simple-mfd";
                        reg = <0x47510000 0x10000>;

原因

GPIO_DYNAMIC_BASE这个宏定义是配置GPIO起始号的,被NXP的人配置为512。
然后注释是

- * At the end we want all GPIOs to be dynamically allocated from 0.
- * However, some legacy drivers still perform fixed allocation.
- * Until they are all fixed, leave 0-512 space for them.

最后,我们希望所有 GPIO 都能从 0 开始动态分配。
然而,一些传统驱动程序仍然执行固定分配。
直到它们都修好,给它们留出 0-512 的空间。

改为0即可。

然后gpio1: gpio@47400000节点一定要是gpiochip0

#预期
gpiochip0: 0-31    parent 47400000
gpiochip1: 32-63   parent 43810000
gpiochip2: 64-95   parent 43820000
gpiochip3: 96-127  parent 43830000

把gpio1的节点往前提即可。

代码解析

gpio的节点是compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";,使用的是drivers/gpio/gpio-vf610.c驱动。

{ .compatible = "fsl,imx8ulp-gpio", .data = &imx8ulp_data },

-> probe 时注册 gpiochip

vf610_gpio_probe() 初始化 struct gpio_chip:

gc->ngpio = VF610_GPIO_PER_PORT;  // 32
gc->base  = -1;                   // 动态分配

然后调用:

devm_gpiochip_add_data(dev, gc, port);

-> gpiolib 分配全局 GPIO 编号

gpiochip_add_data() 发现 gc->base == -1 后,会调用gpiochip_find_base(gc->ngpio).

这个函数从 GPIO_DYNAMIC_BASE 开始找第一个能容纳 32 个 GPIO 的空闲区间。GPIO_DYNAMIC_BASE就是改的宏定义。

-> 使用方拿到 GPIO 号

设备树里如:

gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
#表示 gpio2 控制器的第 10 脚。

内核通过 phandle 找到对应 gpiochip,再算出全局编号:

全局 GPIO 号 = gpiochip.base + offset

例如 gpiochip0 base 为 0,<&gpio2 10> 就是 0 + 10 = 10。

aliases 里的 gpio0~gpio3 只影响像 gpio-mxc 那样使用固定 base 的驱动;

gpio-vf610 使用 base = -1 动态分配,真正决定编号的是 GPIO_DYNAMIC_BASE

posted @ 2026-08-26 18:40  杨旭0324  阅读(10)  评论(0)    收藏  举报