This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM3352: enabling spidev support

Part Number: AM3352


Tool/software: Linux

Hi

I am trying to enable spidev support on a board based on a BeagleBoneBlack.

I have inherited a project developed using SDK 8.00.00.00 (Linux/arm 3.14.26) that makes use of /dev/spidev2.0

I am in the process of porting this project to the newest TISDK and find that I am unable to see any spidev within /dev/.
I have enabled CONFIG_SPI_SPIDEV=y within my .config

I have copied the pinmux defintions from the original project:

spi1_pins: pinmux_spi1_pins {
pinctrl-single,pins = <
0x108 0x32 
0x194 0x33 
0x198 0x13 
0x19c 0x13 
>;
};

and confirmed that these agree with the schematics, datasheet and TRM (unsurprisingly as the old code worked!)

There are also the following nodes defined on spi1:

&spi1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins>;

spidev@0 {
spi-max-frequency = <24000000>;
reg = <0>;
compatible = "linux, spidev";
};

spidev@1 {
spi-max-frequency = <24000000>;
reg = <1>;
compatible = "linux, spidev";
};

};

- the syntax here has changed from the original by adding the "linux" term in the compatible field
- I notice that if I leave this out I get errors in the kernel start up serial as follows

[ 1.032904] spidev spi2.0: buggy DT: spidev listed directly in DT
[ 1.038679] ------------[ cut here ]------------
[ 1.042994] WARNING: CPU: 0 PID: 1 at drivers/spi/spidev.c:719 spidev_probe+0x1a0/0x1bc()
[ 1.050598] Modules linked in:
[ 1.053448] CPU: 0 PID: 1 Comm: swapper Not tainted 4.4.19-gdb0b54cdad #30
[ 1.059837] Hardware name: Generic AM33XX (Flattened Device Tree)
[ 1.065535] [<c0015c94>] (unwind_backtrace) from [<c0012e80>] (show_stack+0x10/0x14)
[ 1.072753] [<c0012e80>] (show_stack) from [<c00300cc>] (warn_slowpath_common+0x80/0xac)
[ 1.080281] [<c00300cc>] (warn_slowpath_common) from [<c0030194>] (warn_slowpath_null+0x1c/0x)
[ 1.088454] [<c0030194>] (warn_slowpath_null) from [<c040cfb0>] (spidev_probe+0x1a0/0x1bc)
[ 1.096128] [<c040cfb0>] (spidev_probe) from [<c040a260>] (spi_drv_probe+0x7c/0xa8)
[ 1.103252] [<c040a260>] (spi_drv_probe) from [<c03b5308>] (driver_probe_device+0x1fc/0x2f0)
[ 1.111110] [<c03b5308>] (driver_probe_device) from [<c03b36d4>] (bus_for_each_drv+0x60/0x94)
[ 1.119039] [<c03b36d4>] (bus_for_each_drv) from [<c03b5080>] (__device_attach+0xb0/0x114)
[ 1.126711] [<c03b5080>] (__device_attach) from [<c03b4634>] (bus_probe_device+0x84/0x8c)
[ 1.134317] [<c03b4634>] (bus_probe_device) from [<c03b291c>] (device_add+0x370/0x56c)
[ 1.141682] [<c03b291c>] (device_add) from [<c040ab58>] (spi_add_device+0x9c/0x134)
[ 1.148805] [<c040ab58>] (spi_add_device) from [<c040b01c>] (of_register_spi_device+0x224/0x2)
[ 1.156973] [<c040b01c>] (of_register_spi_device) from [<c040c81c>] (spi_register_master+0x25)
[ 1.165531] [<c040c81c>] (spi_register_master) from [<c040ca38>] (devm_spi_register_master+0x)
[ 1.174104] [<c040ca38>] (devm_spi_register_master) from [<c040f94c>] (omap2_mcspi_probe+0x2c)
[ 1.182680] [<c040f94c>] (omap2_mcspi_probe) from [<c03b6b6c>] (platform_drv_probe+0x4c/0xb0)
[ 1.190607] [<c03b6b6c>] (platform_drv_probe) from [<c03b5308>] (driver_probe_device+0x1fc/0x)
[ 1.198854] [<c03b5308>] (driver_probe_device) from [<c03b5488>] (__driver_attach+0x8c/0x90)
[ 1.206686] [<c03b5488>] (__driver_attach) from [<c03b362c>] (bus_for_each_dev+0x68/0x9c)
[ 1.214292] [<c03b362c>] (bus_for_each_dev) from [<c03b48e0>] (bus_add_driver+0x1a0/0x218)
[ 1.221977] [<c03b48e0>] (bus_add_driver) from [<c03b5be0>] (driver_register+0x78/0xf8)
[ 1.229420] [<c03b5be0>] (driver_register) from [<c000966c>] (do_one_initcall+0x90/0x1dc)
[ 1.237036] [<c000966c>] (do_one_initcall) from [<c089bdc8>] (kernel_init_freeable+0x12c/0x1b)
[ 1.245120] [<c089bdc8>] (kernel_init_freeable) from [<c0621b7c>] (kernel_init+0xc/0xec)
[ 1.252648] [<c0621b7c>] (kernel_init) from [<c000f598>] (ret_from_fork+0x14/0x3c)
[ 1.259724] ---[ end trace b4816ec3f58ddc0f ]---
[ 1.264822] spidev spi2.1: buggy DT: spidev listed directly in DT
[ 1.270539] ------------[ cut here ]------------

which appears to be calling spidev_probe

my confusion is that if I modify the DTS to include the needed "linux" term I appear to never call spidev probe on boot (I ahve inserted serial strings to check the codeflow for entry here)

If I inspect the DTB for these nodes I see:

62672: spi@481a0000 {
62695: compatible = "ti,omap4-mcspi";
62738- #address-cells = <0x00000001>;
62781- #size-cells = <0x00000000>;
62821- reg = <0x481a0000 0x000001c1>;
62864- interrupts = <0x0000007d>;
62903: ti,spi-num-cs = <0x00000002>;
62945: ti,hwmods = "spi1";
62977- dmas = <0x0000002d 0x0000002b 0x00000000 0x00000003 0x72783000 0x00000005 0x00000003 0x756c7400 0x00000044 0x00000000 0x016e3600 0x00000000>;
63131- dma-names = "tx0", "rx0", "tx1", "rx1";
63183- status = "okay";
63212- pinctrl-names = "default";
63251- pinctrl-0 = <0x00000044>;
63289: spidev@0 {
63312: spi-max-frequency = <0x016e3600>;
63362- reg = <0x00000000>;
63398: compatible = "spidev";
63437- };
63452: spidev@1 {
63475: spi-max-frequency = <0x016e3600>;
63525- reg = <0x00000001>;
63561: compatible = "spidev";
63600- };
63615- };

If I enable verbose debug at the printk level the following strings that appear relevant appear at boot:

[ 14.126735] device class 'spidev': registering
[ 14.130861] kobject: 'spidev' (ddbcb188): kobject_add_internal: parent: 'class', set: 'class'
[ 14.138792] kobject: 'spidev' (ddbcb188): kobject_uevent_env
[ 14.144045] kobject: 'spidev' (ddbcb188): fill_kobj_path: path = '/class/spidev'
[ 14.150925] bus: 'spi': add driver spidev
[ 14.154646] kobject: 'spidev' (ddbce800): kobject_add_internal: parent: 'drivers', set: 'drivers'
[ 14.162915] kobject: 'spidev' (ddbce800): kobject_uevent_env
[ 14.168185] kobject: 'spidev' (ddbce800): fill_kobj_path: path = '/bus/spi/drivers/spidev'

<---snip--->

[ 14.326125] bus: 'platform': driver_probe_device: matched device 481a0000.spi with driver omap2_mcspi
[ 14.334678] bus: 'platform': really_probe: probing driver omap2_mcspi with device 481a0000.spi
[ 14.342731] pinctrl core: add 1 pinctrl maps
[ 14.346768] devices_kset: Moving 481a0000.spi to end of list
[ 14.352057] omap_hwmod: spi1: enabling
[ 14.355537] powerdomain: completed transition in 0 loops
[ 14.360464] clockdomain: l4ls_clkdm: enabled
[ 14.364421] omap_hwmod: spi1: enabling clocks
[ 14.368462] omap_hwmod: spi1: _omap4_enable_module: 2
[ 14.373196] device: 'spi2': device_add
[ 14.376697] kobject: 'spi_master' (ddbe0780): kobject_add_internal: parent: '481a0000.spi', set: '(null)'
[ 14.385599] kobject: 'spi2' (ddbc5408): kobject_add_internal: parent: 'spi_master', set: 'devices'
[ 14.394160] PM: Adding info for No Bus:spi2
[ 14.398065] kobject: 'spi2' (ddbc5408): kobject_uevent_env
[ 14.403161] kobject: 'spi2' (ddbc5408): fill_kobj_path: path = '/devices/platform/ocp/481a0000.spi/spi_master/spi'
[ 14.413090] device: 'spi2.0': device_add
[ 14.416784] kobject: 'spi2.0' (ddbc5808): kobject_add_internal: parent: 'spi2', set: 'devices'
[ 14.424820] bus: 'spi': add device spi2.0
[ 14.428762] PM: Adding info for spi:spi2.0
[ 14.432562] kobject: 'spi2.0' (ddbc5808): kobject_uevent_env
[ 14.437839] kobject: 'spi2.0' (ddbc5808): fill_kobj_path: path = '/devices/platform/ocp/481a0000.spi/spi_master/s'
[ 14.448386] device: 'spi2.1': device_add
[ 14.452029] kobject: 'spi2.1' (ddbc5c08): kobject_add_internal: parent: 'spi2', set: 'devices'
[ 14.460061] bus: 'spi': add device spi2.1
[ 14.464011] PM: Adding info for spi:spi2.1
[ 14.467833] kobject: 'spi2.1' (ddbc5c08): kobject_uevent_env
[ 14.473090] kobject: 'spi2.1' (ddbc5c08): fill_kobj_path: path = '/devices/platform/ocp/481a0000.spi/spi_master/s'
[ 14.483536] driver: 'omap2_mcspi': driver_bound: bound to device '481a0000.spi'
[ 14.490337] bus: 'platform': really_probe: bound device 481a0000.spi to driver omap2_mcspi
[ 14.498127] kobject: 'omap2_mcspi' (ddbce880): kobject_uevent_env
[ 14.503788] kobject: 'omap2_mcspi' (ddbce880): fill_kobj_path: path = '/bus/platform/drivers/omap2_mcspi'

but again I cannot see anything attempting to call spidev_probe and the /dev/ entries I would expect never appear

I can find the entries under /sys/bus/spi/devices

lrwxrwxrwx 1 root root 0 Jan 1 00:12 spi1.0 -> ../../../devices/platform/ocp/48030000.spi/spi_master/spi1/spi1.0
lrwxrwxrwx 1 root root 0 Jan 1 00:12 spi2.0 -> ../../../devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.0
lrwxrwxrwx 1 root root 0 Jan 1 00:12 spi2.1 -> ../../../devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.1

any suggestions for where I can look next?

Thanks for the help.

All the best,
Richard

  • Hello,

    Please check these threads:
    e2e.ti.com/.../1300759
    e2e.ti.com/.../340805

    Hope this helps you.

    BR
    Margarita
  • Thanks Margarita

    I have read both those a few times
    - and have since tried specifying the clock for my spidev node 
    - I have all the enables mentioned set in my .config

    Still the code never calls the spidev_probe function.

    I wonder if those threads are a bit out of date as they include references to the form of the compatible string that does not mention "linux" (doing this with the latest kernel throws the errors I pasted in my original post.

    If I look in my sys folder:
    root@proto-board:~# find /sys -name spi*
    /sys/bus/spi
    /sys/bus/spi/devices/spi1.0
    /sys/bus/spi/devices/spi2.0
    /sys/bus/spi/devices/spi2.1
    /sys/bus/spi/drivers/spidev
    /sys/devices/platform/ocp/48030000.spi/spi_master
    /sys/devices/platform/ocp/48030000.spi/spi_master/spi1
    /sys/devices/platform/ocp/48030000.spi/spi_master/spi1/spi1.0
    /sys/devices/platform/ocp/48030000.spi/spi_master/spi1/spi1.0/statistics/spi_sync_immediate
    /sys/devices/platform/ocp/48030000.spi/spi_master/spi1/spi1.0/statistics/spi_sync
    /sys/devices/platform/ocp/48030000.spi/spi_master/spi1/spi1.0/statistics/spi_async
    /sys/devices/platform/ocp/48030000.spi/spi_master/spi1/statistics/spi_sync_immediate
    /sys/devices/platform/ocp/48030000.spi/spi_master/spi1/statistics/spi_sync
    /sys/devices/platform/ocp/48030000.spi/spi_master/spi1/statistics/spi_async
    /sys/devices/platform/ocp/481a0000.spi/spi_master
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.0
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.0/statistics/spi_sync_immediate
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.0/statistics/spi_sync
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.0/statistics/spi_async
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.1
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.1/statistics/spi_sync_immediate
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.1/statistics/spi_sync
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/spi2.1/statistics/spi_async
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/statistics/spi_sync_immediate
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/statistics/spi_sync
    /sys/devices/platform/ocp/481a0000.spi/spi_master/spi2/statistics/spi_async
    /sys/class/spi_master
    /sys/class/spi_master/spi1
    /sys/class/spi_master/spi2
    /sys/class/spidev
    /sys/firmware/devicetree/base/ocp/spi@48030000
    /sys/firmware/devicetree/base/ocp/spi@48030000/spi-flash@0
    /sys/firmware/devicetree/base/ocp/spi@48030000/spi-flash@0/spi-max-frequency
    /sys/firmware/devicetree/base/ocp/spi@481a0000
    /sys/firmware/devicetree/base/ocp/spi@481a0000/spidev@0
    /sys/firmware/devicetree/base/ocp/spi@481a0000/spidev@0/spi-max-frequency
    /sys/firmware/devicetree/base/ocp/spi@481a0000/spidev@1
    /sys/firmware/devicetree/base/ocp/spi@481a0000/spidev@1/spi-max-frequency
    /sys/firmware/devicetree/base/ocp/spinlock@480ca000
    /sys/module/spidev

    I appear to be missing the /dev/spidev#.# and /sys/class/spidev/spidev#.# that I would expect given the documentation.

    I get the impression that getting the spidev_probe called at boot in the right place is key to this: any idea how to convince my kernel to do this?

    Thanks for the help
    - Richard

  • OK 

    I've learned a few things since my last post:

    - avoid whitespace after a comma in the "compatible" property
    - you need to ensure there is a "compatible" of_device in the spidev driver for the definition of your node

    with both of these in place I find the necessary /dev/spidev#.# and boot  without warning

    Thanks for the suggestions
    - Richard

     

  • Hello,

    I am glad that this issue is solved. Please verify your answer so the thread could be closed.
    For the new issue you could open a new topic.

    Best Regards,
    Margarita