外接的模块是一个mcp2515的can芯片,在它驱动里的probe里需要获取clk,但我调试看了下,一直获取不到。
它调用的函数是clk = devm_clk_get(&spi->dev, NULL)
我代码跟踪感觉这个函数最终会调用
    clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
这个函数,dev_id 是从spi->dev.init_name中获取的,我打印了下为NULL, con_id 也为NULL(第一个函数传进去的)
所以我用了"spi","mod","ahb"作为devm_clk_get()这个函数的第二个参数来调试,依然获取不到。
这是设备树里的配置
官方的那个头里的配置
spi0: spi@1c68000 {
    compatible = "allwinner,sun8i-h3-spi";
    reg = <0x01c68000 0x1000>;
    interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
    clock-names = "ahb", "mod";
    pinctrl-names = "default";
    pinctrl-0 = <&spi0_pins>;
    resets = <&ccu RST_BUS_SPI0>;
    status = "disabled";
    #address-cells = <1>;
    #size-cells = <0>;
};
我自己的配置
&spi0{
   status = "okay";
   can@0{
        status = "okay";
        compatible = "microchip,mcp2515";
        reg = <0>;
        spi-max-frequency = <5000000>;
        interrupt-parent = <&pio>;
        interrupts = < 4 21  IRQ_TYPE_EDGE_FALLING>;
   };
};
最近编辑记录 Helloafer (2019-11-12 11:19:10)
离线
芯片下面的那个spi flash吗?没有接的。
spi外设我确定驱动已经可以了,我之前用系统带的那个spidev驱动试过,又用spi_test测试过,短接miso和mosi,是可以发送和接收数据的。
离线
而且我在spidev这个驱动里调用clk = devm_clk_get(&spi->dev, NULL);也是获取不到的。
但就算获取不到,也不耽误测试程序的正常收发。
最近编辑记录 Helloafer (2019-11-12 11:33:07)
离线
有点诡异,改天我也试一试,淘宝有没有模块卖啊?
离线
终于有进展了。
我跟踪到这个函数内部:(位于drivers/clk/clkdev.c)
static struct clk *__of_clk_get_by_name(struct device_node *np,
                    const char *dev_id,
                    const char *name)
{
    struct clk *clk = ERR_PTR(-ENOENT);
    /* Walk up the tree of devices looking for a clock that matches */
    while (np) {
        int index = 0;
        /*
         * For named clocks, first look up the name in the
         * "clock-names" property.  If it cannot be found, then
         * index will be an error code, and of_clk_get() will fail.
         */
        if (name)
            index = of_property_match_string(np, "clock-names", name);
        clk = __of_clk_get(np, index, dev_id, name);
        if (!IS_ERR(clk)) {
            break;
        } else if (name && index >= 0) {
            if (PTR_ERR(clk) != -EPROBE_DEFER)
                pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
                    np, name ? name : "", index);
            return clk;
        }
        /*
         * No matching clock found on this node.  If the parent node
         * has a "clock-ranges" property, then we can try one of its
         * clocks.
         */
        np = np->parent;
        if (np && !of_get_property(np, "clock-ranges", NULL))
            break;
    }
    return clk;
}
发现while循环的末尾有个判断可能写错了。
        np = np->parent;
        if (np && !of_get_property(np, "clock-ranges", NULL))
            break;
应该是
               np = np->parent;
        if (!np && !of_get_property(np, "clock-ranges", NULL))
            break;
改了后,我的can设备就出现了。
[  181.937474] mcp251x spi0.0 can0: MCP2515 successfully initialized.
# ifconfig -a
can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          NOARP  MTU:16  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
好开心啊!!!
离线
感觉不应该是 !np 这个地方问题, 如果是这里问题, 应该早发现了。
离线
感觉不应该是 !np 这个地方问题, 如果是这里问题, 应该早发现了。
同感, 这里是 Linux 驱动部分的核心代码, 按理不应该会这里出错。
https://github.com/torvalds/linux/blob/v4.13/drivers/clk/clkdev.c
https://github.com/torvalds/linux/blob/v4.14/drivers/clk/clkdev.c
https://github.com/torvalds/linux/blob/v4.15/drivers/clk/clkdev.c
https://github.com/torvalds/linux/blob/v4.16/drivers/clk/clkdev.c
https://github.com/torvalds/linux/blob/v4.17/drivers/clk/clkdev.c
https://github.com/torvalds/linux/blob/v4.18/drivers/clk/clkdev.c
https://github.com/torvalds/linux/blob/v4.19/drivers/clk/clkdev.c
https://github.com/torvalds/linux/blob/v4.20/drivers/clk/clkdev.c
这里全部都一样。
离线
Example:
can0: can@1 {
compatible = "microchip,mcp2515";
reg = <1>;
clocks = <&clk24m>;
interrupt-parent = <&gpio4>;
interrupts = <13 0x2>;
vdd-supply = <®5v0>;
xceiver-supply = <®5v0>;
};
貌似你的设备树缺时钟源。
离线
也可以参考这个,刚好也是全志的
https://github.com/armbian/sunxi-DT-overlays/blob/master/examples/spi-mcp251x.dts
			can0_osc_fixed: can0_osc_fixed {
				compatible = "fixed-clock";
				#clock-cells = <0>;
				clock-frequency  = <8000000>;
			};			mcp2515 {
				reg = <0>;
				compatible = "microchip,mcp2515";
				pinctrl-names = "default";
				pinctrl-0 = <&can0_pin_irq>;
				spi-max-frequency = <10000000>;
				interrupt-parent = <&pio>;
				interrupts = <0 7 2>; /* PA7 IRQ_TYPE_EDGE_FALLING */
				clocks = <&can0_osc_fixed>;
				status = "okay";
			};离线
https://lkml.org/lkml/2019/4/18/554
Oceanic 5205 5inMFD has MCP2515 CAN device connected via SPI1.
- via SPI1 bus
- vdd supplied by 5V supply along with PL2 enable pin
- xceiver supply same as vdd
- can oscillator connected at 20MHz
- PB2 gpio as interrupt pin
- PD6 gpio as RX_BUF1_CAN0
- PD7 gpio as RX_BUF0_CAN0
Tested-by: Tamas Papp <tamas@osukl.com>
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
 .../sun50i-a64-oceanic-5205-5inmfd.dts        | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-oceanic-5205-5inmfd.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-oceanic-5205-5inmfd.dts
index f0cd6587f619..22535a297f51 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-oceanic-5205-5inmfd.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-oceanic-5205-5inmfd.dts
@@ -21,6 +21,24 @@
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
+
+	can_osc: can-osc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <20000000>;
+	};
+
+	reg_can_v5v: reg-can-v5v {
+		compatible = "regulator-fixed";
+		regulator-name = "reg-can-v5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-boot-on;
+		enable-active-high;
+		gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* CAN_3V3_EN: PL2 */
+		status = "okay";
+	};
+
 };
 
 &ehci0 {
@@ -77,6 +95,31 @@
 	status = "okay";
 };
 
+&pio {
+	can_pins: can-pins {
+		pins = "PD6",			/* RX_BUF1_CAN0 */
+		       "PD7";			/* RX_BUF0_CAN0 */
+		function = "gpio_in";
+	};
+};
+
+&spi1 {
+	status = "okay";
+
+	can@0 {
+		compatible = "microchip,mcp2515";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&can_pins>;
+		interrupt-parent = <&pio>;
+		interrupts = <1 2 IRQ_TYPE_EDGE_FALLING>;	/* INT_CAN0: PB2 */
+		clocks = <&can_osc>;
+		vdd-supply = <®_can_v5v>;
+		xceiver-supply = <®_can_v5v>;
+	};
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pb_pins>;
-- 
2.18.0.321.gffc6fa0e3离线
谢谢各位了!晕哥说这代码是核心代码,那基本上是不可能出错的,看了那个语句的后半断,会查找父设备里的有没一个"clock-ranges"这样的属性,如果有就会使用父设备返回父设备的clk,我就给加上了,现在不改代码,can设备也出现了。水平有限,我主要搞单片机的,这个设备树还不理解,楼上给的,我不知道在荔枝上怎么配置,我就不试了。先看看这个can设备是不是能用了,如果可以我就先这样吧,再次谢谢各位!@ALL
dock这个设备树文件里这样写,就可以了。
&spi0{
   status = "okay";
   clock-ranges;
   can@0{
        status = "okay";
        compatible = "microchip,mcp2515";
        reg = <0>;
        spi-max-frequency = <5000000>;
        interrupt-parent = <&pio>;
        interrupts = < 4 21  IRQ_TYPE_EDGE_FALLING>;
   };
};最近编辑记录 Helloafer (2019-11-12 15:46:19)
离线
哈, 你这样改只是让 mp2515 有了时钟, 暂时跑起来了,后面可能会有未知的坑,目前调试 can 的时候可以这么做,后面量产的时候一定记得改回来。
离线
哈, 你这样改只是让 mp2515 有了时钟, 暂时跑起来了,后面可能会有未知的坑,目前调试 can 的时候可以这么做,后面量产的时候一定记得改回来。
看你说的会有坑,有点怕,我又查了些资料。
https://searchcode.com/codesearch/view/47347027/
linux /Documentation/devicetree/bindings/clock/clock-bindings.txt
76:     clock-ranges:         Empty property indicating that child nodes can inherit named
                             clocks from this node. Useful for bus nodes to provide a
                             clock to their children.
这意思是不是刚好符合我这情况?
离线
按10楼方法修改dts能挂载can设备,谢谢大家分享~!
离线
按照楼主的帖子,我用的licheepi zero 成功挂载了mcp2515,设置波特率,up等操作都是正常的,但是,用cansend数据后,用ifconfig 查看 can0的tx没有增加,不知道楼主有碰到类似的情况吗
离线
按照楼主的帖子,我用的licheepi zero 成功挂载了mcp2515,设置波特率,up等操作都是正常的,但是,用cansend数据后,用ifconfig 查看 can0的tx没有增加,不知道楼主有碰到类似的情况吗
我是这种情况,就离谱
离线