2

我正在使用飞思卡尔 MX6 和飞思卡尔 3.10.31 修改内核。我有一个用作 IO 扩展器的 Maxim MAX7325,它的按钮连接到 P0-P2。7325的中断线连接到GPIO_3焊盘(我相信是GPIO1_3 ...)

我在设备树中设置了 7325 和 gpio-keys,如下所示:

max7325_reset: max7325-reset {
  compatible = "gpio-reset";
  reset-gpios = <&gpio5 16 GPIO_ACTIVE_LOW>;
  reset-delay-us = <1>;
  #reset-cells = <0>;
};


gpio-keys {
  compatible = "gpio-keys";

  sw2 {
     gpios = <&max7325 2 GPIO_ACTIVE_LOW>;
     linux,code = <30>;    //a
     gpio-key,wakeup;
  };
};

&i2c1 {
   clock-frequency = <100000>;
   pinctrl-names = "default";
   pinctrl-0 = <&pinctrl_i2c1_2>;
   status = "okay";

   max7325: gpio@68 {
      compatible = "maxim,max7325";
      reg = <0x68>;
      gpio-controller;
      #gpio-cells = <2>;
      resets = <&max7325_reset>;

      gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
      interrupt-parent = <&gpio1>;
      interrupts = <3 2>;
   };
};

似乎发生的是当调用 MAX7325 驱动程序的探针时,client->dev.platform_data 为 NULL。正因为如此,当稍后调用 max732x_irq_setup 时,它并没有设置 chip->gpio_chip.to_irq 指针指向 max732x_gpio_to_irq 函数(可能是因为它没有正确的信息来使其工作。)后来,当 gpio_keys尝试配置第一个输入,当它尝试设置中断并且没有设置其他键时失败。

gpio-keys gpio-keys.20: Unable to get irq number for GPIO 242, error -6

我确实确定使用 P0 映射到 GPIO 240 的 /sys 接口,所以是的,GPIO 242 是我试图设置的 sw2 GPIO-KEY。

我想知道,这个驱动程序不能与设备树一起使用吗?我没有看到它试图获取任何设备树属性,但我查看的其他 IO 扩展器驱动程序也没有,所以我认为 I2C 内核可能正在读取设备树并应该以某种方式从那里填写 platform_data它调用驱动程序的探测函数(?)

我在这方面相当新,所以任何帮助将不胜感激。=)我确实在网上阅读了一些设备树文档,但我认为这是相当具体的事情,我没有正确地做,他们没有涵盖......(?)

我确实在内核中配置了 CONFIG_GPIO_MAX732X_IRQ ......我曾经尝试为 max7325 I2c1 节点设置中断控制器属性,但我不确定是否需要(?)

4

1 回答 1

5

MAX732x 设备树支持

您正在使用的驱动程序不适用于设备树中的数据。我已向此驱动程序添加了设备树支持并将其发送到内核邮件列表以供审查,但它们尚未合并。请参阅此线程(共 4 个补丁):

您可以将这些补丁应用到您的分支,或者等待它们进入上游内核,然后从那里挑选它们(进入您的分支)。

绑定文档(参见上面的补丁)显示了如何为 MAX732x 创建设备树声明。在您的情况下,它可能如下所示:

&i2c1 {
    expander: max7325@68 {
        compatible = "maxim,max7325";
        reg = <0x68>;
        gpio-controller;
        #gpio-cells = <2>;
        interrupt-controller;
        #interrupt-cells = <2>;
        interrupt-parent = <&gpio1>;
        interrupts = <3 2>;
    };
};

您使用此驱动程序的另一种方法(没有上面的补丁)是在板文件中为您的板指定平台数据。我相信它应该是下一个文件之一:

  • 拱/臂/mach-imx/mach-imx6q.c
  • 拱/臂/mach-imx/mach-imx6sl.c
  • 拱/臂/mach-imx/mach-imx6sx.c

您可以在此处找到如何执行此操作的示例:arch/arm/mach-pxa/littleton.c,第 394 行。

但这可能不是可靠的方法:我尝试这样做并且在 i2c 总线编号方面遇到了一些问题(尽管那样看起来并不算多)。在板文件和 dts 文件之间分散设备定义看起来也很糟糕。所以我强烈推荐你使用上面的补丁。

问题的答案

似乎发生的是当调用 MAX7325 驱动程序的探针时,client->dev.platform_data 为 NULL。

发生这种情况是因为驱动程序与设备树文件而不是板文件中的设备声明绑定。在这种情况下,驱动程序应该使用client->dev.of_node而不是client->dev.platform_data。只需在上面的补丁中查看它是如何完成的。

您可以在此处阅读内核文档中有关绑定/匹配/实例化如何发生的更多信息:

  • 文档/i2c/instantiating-devices
  • 文档/devicetree/usage-model.txt

我想也许 I2C 内核正在读取设备树,并且应该在调用驱动程序的探测函数之前以某种方式从那里填充 platform_data(?)

不会。当绑定发生时,client->irq会自动填充到 I2C 核心中(在调用驱动程序的探测函数之前)。gpio_baseirq_base 之类的属性——如果数据来自设备树,则不需要它们。

我曾经尝试为 max7325 I2c1 节点设置中断控制器属性,但我不确定是否需要(?)

当 MAX7325 检测到输入线路上的变化时(更具体地说,在配置为输入的开漏 I/O 端口上),它会向您的 SoC 发出中断。因此,如果您希望您的驱动程序为每个输入 I/O 线生成单独的中断(以便其他驱动程序可以使用它们),您应该指定“interrupt-controller”和“#interrupt-cells”属性。但为此,您需要应用上述所有补丁。

补丁状态

现在所有提到的补丁都被合并到上游内核(v4.0 及更高版本):

  1. gpio: max732x: 添加设备树支持
  2. gpio: max732x: 重写 IRQ 代码以使用 irq_domain API
  3. gpio: max732x: 修复可能的死锁
  4. gpio: max732x: 添加 DT 绑定文档

另请注意,在我的补丁之上制作了一些新补丁。你可以在这里观看。

于 2015-01-14T00:24:50.237 回答