我一直在尝试让 MCP2515 CAN 控制器在我的设备树中的 spi-gpio 总线上工作,但 MCP251x 驱动程序的探测函数似乎从未真正被调用。但奇怪的是,某处的某些探测函数正在被调用,因为它返回-EPROBE_DEFER
。
我修改了/drivers/base/dd.c
一堆 dev_dbg 打印调用来找出我实际从哪里返回。
https://github.com/torvalds/linux/blob/v4.14/drivers/base/dd.c
第 416 行是驱动程序探测被推迟的地方
else if (drv->probe) {
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}
如果我添加调试语句,我可以看到drv
变量的名称是 MCP251x,它与驱动程序匹配。
dev_dbg(dev, "%s line %d ret: %d\n", drv->name, __LINE__,ret);
所以我在MCP251x驱动程序的mcp251x_can_probe
函数 中添加了一些调试语句https://github.com/torvalds/linux/blob/v4.14/drivers/net/can/spi/mcp251x.c
我从未看到 MCP251x 探测功能的任何调试打印。为什么?我不明白为什么这个探测函数没有被调用,但有些东西正在设法返回-EPROBE_DEFER
。
我不知道是否调用了一些我不知道的中间 spi 探针函数,但它永远不会到达 MCP251x 的探针。
这是我的设备树的相关片段,以防万一。
spi1{
compatible = "spi-gpio";
status="okay";
#address-cells = <0x1>;
ranges;
gpio-sck = <&gpio0 4 0>;
gpio-miso = <&gpio0 5 0>;
gpio-mosi = <&gpio0 19 0>;
cs-gpios = <&gpio0 18 1>;
num-chipselects = <1>;
can0: mcp2515@0 {
compatible = "microchip,mcp2515";
reg = <0>;
status = "okay";
clocks = <&mcp2515_clk>;
interrupt-parent = <&gpio0>;
interrupts = <11 0x2>; //falling edge
spi-max-frequency = <10000000>;
mcp2515_clk: oscillator {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <8000000>; //8MHz
};
};
};
答案1
我一直在尝试让 MCP2515 在 Linux 下的 Xilinx Zynq 上运行。
我在遇到完全相同的问题时发现了您的帖子。
我走的是与你完全相同的路线,并在 mpc251x 驱动程序中散布了 printk,希望找到探针失败的位置,但它也没有被调用。
相反,驱动程序 spi.c 中的探测函数是从 dd.c 为我调用的。
延迟错误是从以下位置返回的:
https://github.com/torvalds/linux/blob/master/drivers/spi/spi.c#L397
就我而言,这是由于找不到我定义的中断。
对我来说,这很简单,因为未加载中断控制器驱动程序,因此无法找到中断。
构建了中断控制器驱动程序,并看到 mcp251x 驱动程序中的所有 printk 都活跃起来。
希望有帮助!
祝你好运,
菲尔