9

I want to define a SPI device with usermode access, as explained for example in http://linux-sunxi.org/SPIdev

Following these examples, I added in the devicetree this :

&ecspi1 {
     .... other stuff ...
    mydev@0 {
       compatible = "spidev";
       spi-max-frequency = <5000000>;
       reg = <2>; /*chipselect*/
    };
};

The platform is i.MX6. ecspi1 seems to be their SPI controller. Then I indeed get /dev/spi0.2 and /sys/class/spidev/spidev0.2

But in kernel trace there's a WARNING saying this:

spidev spi0.2: buggy DT: spidev listed directly in DT

So how else the spidev should be described? What is the right syntax?

ddbug
  • 1,392
  • 1
  • 11
  • 25

2 Answers2

14

spidev: why it shouldn't be directly in devicetree?

The Device Tree should describe the board's hardware, but spidev does not describe/identify any hardware.

Mark Brown wrote:

Since spidev is a detail of how Linux controls a device rather than a description of the hardware in the system we should never have a node described as "spidev" in DT, any SPI device could be a spidev so this is just not a useful description.

The rationale and workaround for this kernel patch is https://patchwork.kernel.org/patch/6113191/


So how else the spidev should be described? What is the right syntax?

Instead of explicit use of spidev in your Device Tree source, you instead need to identify the actual device that you're controlling, e.g.

     mydev@0 {
-       compatible = "spidev";
+       compatible = "my_spi_device"; 
        spi-max-frequency = <5000000>;

Then (as Geert Uytterhoeven explains), modify drivers/spi/spidev.c in the kernel source code by adding the compatible value for your device to the spidev_dt_ids[] array

 static const struct of_device_id spidev_dt_ids[] = {
     { .compatible = "rohm,dh2228fv" },
     { .compatible = "lineartechnology,ltc2488" },
     { .compatible = "ge,achc" },
     { .compatible = "semtech,sx1301" },
+    { .compatible = "my_spi_device" },
     {},
 }

An alternate solution, which involves a quick-n-dirty change to just the Device Tree, is suggested by this article.
Simply replace the "spidev" compatible string with a proper string that already does exist:

     mydev@0 {
-       compatible = "spidev";
+       compatible = "rohm,dh2228fv";  /* actually spidev for my_spi_dev */
        spi-max-frequency = <5000000>;

Since "rohm,dh2228fv" is already in the spidev_dt_ids[] list, no edit to drivers/spi/spidev.c is needed.

sawdust
  • 16,103
  • 3
  • 40
  • 50
  • 9
    I personally disagree with the kernel maintainer's rationale. There is a use case for having an uncommitted SPI port on a board rather than a specific SPI device. It would be nice to have a specific `compatible` string for such a port, rather than having to "borrow" the `"rohm,dh2228fv"` string which might disappear someday. – Ian Abbott Dec 06 '18 at 14:53
  • Thanks sawdust for the explanation. Thank you @Ian Abbott. Will see what I can do about this. The simplest thing is just ignore the warning... – ddbug Dec 06 '18 at 19:14
  • 3
    @IanAbbott You can use `"linux,spidev"` (rather than just `"spidev"`) for this use case. – Compholio Aug 23 '21 at 14:38
4

To avoid this issue just use linux,spidev instead of spidev:

&spi0 {
    mydev@0 {
       compatible = "linux,spidev";
    };
};
Compholio
  • 733
  • 1
  • 9
  • 17
  • That requires a code patch in "drivers/spi/spidev.c" to add the compatible string to the device ID table. – Ian Abbott Aug 23 '21 at 14:55
  • I'm using the Xilinx kernel tree and that string does not appear in the compatible list and it still works ( list at exact commit: https://github.com/Xilinx/linux-xlnx/blob/93dc4dbd16d091a25e0200d375120ebd231246cc/drivers/spi/spidev.c#L660 ). – Compholio Aug 23 '21 at 16:32
  • Interesting. So it is selecting the driver by "modalias" value? – Ian Abbott Aug 23 '21 at 16:57
  • 1
    Yup, and if you do that with just "spidev" you get the awful warning in your boot log. I noticed that "linux,spidev" behaves differently because I set up a device tree according to these instructions: https://www.emcraft.com/stm32f769i-discovery-board/accessing-spi-devices-in-linux and I _didn't_ get the warning. I've configured SPI before, so I was expecting to have to patch the kernel to make it go away - when that wasn't necessary I tracked the difference down to the compatible string. – Compholio Aug 23 '21 at 17:47
  • 1
    FYI, it looks like what happens here is that spidev's call to of_device_is_compatible() does an exact match on "spidev" whereas the device tree modalias code strips the manufacturer: https://github.com/Xilinx/linux-xlnx/blob/93dc4dbd16d091a25e0200d375120ebd231246cc/drivers/of/base.c#L1194 – Compholio Aug 23 '21 at 19:27
  • I don't think `compatible = "linux,spidev";` works for Linux kernel 5.15 onwards since [commit 6840615f85f60](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6840615f85f60). At least, I cannot get it to work in v6.0 and this seems the most likely reason. – Ian Abbott Oct 24 '22 at 13:32