0

I have SBC: mango pi mq-pro

Processor: Allwinner D1

Distribution: Linux Ubuntu 5.17.0-1003-allwinner riscv64

Link at distro: https://wiki.sipeed.com/hardware/en/lichee/RV/ubuntu.html

I need to enable the i2c interface on the board. There are specific legs to which the SDA and SCL functions are attached (i2c function in general). Activation and binding of legs are done through the Device Tree. After reboot i2c is activated:

$ cat /sys/firmware/devicetree/base/soc/i2c@2502000/status 
okay
$ cat /sys/kernel/debug/pinctrl/2000000.pinctrl/pinmux-pins | grep i2c   
pin 144 (PE16): device 2502000.i2c function i2c3 group PE16
pin 145 (PE17): device 2502000.i2c function i2c3 group PE17

That is, everything is correctly indicated in the settings for enabling and linking pins.

Next, the command for the presence of i2c:

$ i2cdetect -l
i2c-0 i2c mv64xxx_i2c adapter I2C adapter
i2c-1 i2c DesignWare  HDMI    I2C adapter

The i2cdetect -y 1 command shows device addresses, something like:

    0  1  2  3...                      ...f
00:                     -- -- -- --
10: -- -- -- -- --...
...
30: 30 -- -- -- --...
...
70: -- -- -- -- --...

But this is not the chip that I need, I need 0, which is associated with the mv64xxx driver, because it is he who appears when i2c is activated in the device tree.

Command i2cdetect -y 0 output:

[время] i2c i2c-0: mv64xxx: I2C bus locked, block: 1, time_left: 0

I found the source code for fixing this driver in kernel version 6.4:

static irqreturn_t
mv64xxx_i2c_intr(int irq, void *dev_id)
{
    struct mv64xxx_i2c_data *drv_data = dev_id;
    u32     status;
    irqreturn_t rc = IRQ_NONE;

    spin_lock(&drv_data->lock);

    if (drv_data->offload_enabled)
        rc = mv64xxx_i2c_intr_offload(drv_data);

    while (readl(drv_data->reg_base + drv_data->reg_offsets.control) &
                        MV64XXX_I2C_REG_CONTROL_IFLG) {
        /*
         * It seems that sometime the controller updates the status
         * register only after it asserts IFLG in control register.
         * This may result in weird bugs when in atomic mode. A delay
         * of 100 ns before reading the status register solves this
         * issue. This bug does not seem to appear when using
         * interrupts.
         */
        if (drv_data->atomic) // The new in 6.4
            ndelay(100);      // And this

        status = readl(drv_data->reg_base + drv_data->reg_offsets.status);
        mv64xxx_i2c_fsm(drv_data, status);
        mv64xxx_i2c_do_action(drv_data);

        if (drv_data->irq_clear_inverted)
            writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_IFLG,
                   drv_data->reg_base + drv_data->reg_offsets.control);

        rc = IRQ_HANDLED;
    }
    spin_unlock(&drv_data->lock);

    return rc;
}

It seems to me that this is precisely the point.

Questions (apologies, but there are several):

  • I can't figure out where the mv64xxx.ko file is located. The /lib/modules/.../kernel/drivers/i2c/busses directory contains all the other drivers, but the mv64xxx.ko file is missing. I do not understand how it is loaded into the kernel or how it is activated. It cannot be added or removed in modprobe, it is not in lsmod either, but it is activated, because error messages come from this file. Where does this file come from?

  • I want to replace my current mv64xxx driver on linux 5.17 with the mv64xxx driver from linux >= 6.4. I read about make inside /usr/src/kernel/, you can install a separate driver, but I can not fully understand how to do it. make oldconfig already done. If my theory is correct, then that driver-specific .ko file (from question 1) is linked to the kernel and removed, and the rest of the .ko files are there to do it with if needed. How can I recompile this file and include it in the kernel?

  • Well, the third question. How exactly can this problem be solved? Maybe someone else has come across this.

Thank you for your attention. I tried to describe the problem in detail.

UPD: I did it, I recompiled new module. There was several easy changes, one function with another return type and one struct with one another name of field that takes this function pointer (return VOID, instead INT 0). I have new i2c-mv64xxx.ko file and other files within directory with this module. I did depmode and then modprobe i2c-mv64xxx, no errors, nothing is going on. lsmod | grep i2c : empty, dmesg | grep mv64 : empty, dmesg | grep i2c : i2c_dev: i2c /dev entries driver, BUT, it was already before I recompiled module. May be old module dont give me load new module? :(

7
  • "I can't figure out where the mv64xxx.ko file is located" -- That's because you're careless with names. The Kconfig entry states: This driver (i2c_mv64xxx.c) can also be built as a module. If so, the module will be called i2c-mv64xxx. "I want to replace my current mv64xxx driver on linux 5.17 with the mv64xxx driver from linux >= 6.4." -- Not feasible. The internal interfaces of the kernel can change between kernel versions. Instead you would have to back-port the salient patch.
    – sawdust
    Commented Aug 17, 2023 at 21:34
  • @sawdust, I did it, I recompiled new module! There was several easy changes, one function with another return type and one struct with one another name of field that takes this function pointer. I have new i2c-mv64xxx.ko file and other files within directory with this module. But how to enable him now? I try modprobe, but no this driver in lsmod and after modprobe no errors, just new prompt :(
    – nx4n
    Commented Aug 18, 2023 at 6:27
  • @sawdust new function void return, old int and return 0, bruh. I did depmode and then modprobe i2c-mv64xxx, no errors, nothing is going on. lsmod | grep i2c : empty, dmesg | grep mv64 : empty, dmesg | grep i2c : i2c_dev: i2c /dev entries driver, BUT, it was already before I recompile module. May be old module dont give me load new module?
    – nx4n
    Commented Aug 18, 2023 at 6:33
  • And about "careless with names": I tried to find / -type f -name "mv64xxx" before compiling module and result was empty => also there is not i2c-mv64xxx.ko and other files in my fs
    – nx4n
    Commented Aug 18, 2023 at 6:41
  • Did you review the boot log of the original kernel? What messages (if any) did the original i2c_mv64xxx driver generate? Where in the boot sequence do they occur? Did you review the boot log of the new kernel? What messages (if any) did the modified i2c_mv64xxx driver generate?
    – sawdust
    Commented Aug 18, 2023 at 7:21

1 Answer 1

1

I can't figure out where the mv64xxx.ko file is located. The /lib/modules/.../kernel/drivers/i2c/busses directory contains all the other drivers, but the mv64xxx.ko file is missing. I do not understand how it is loaded into the kernel or how it is activated. It cannot be added or removed in modprobe, it is not in lsmod either, but it is activated, because error messages come from this file. Where does this file come from?

At compile time, it was selected to be built-in – it's literally part of the main vmlinuz image. (It's commonly done for drivers that need to be available during early boot, in case the builder does not want to use an initramfs or if the platform makes initramfs usage difficult.)

This usually means that the driver cannot be overridden by loading a module, either. You'll need to rebuild the whole kernel.

4
  • 1
    "This usually means that the driver cannot be overridden by loading a module" -- Since this kernel boots with a Device Tree, a built-in driver can be ignored by changing the compatible property in the DT to refer instead to a new loadable module. See stackoverflow.com/questions/26840267/…
    – sawdust
    Commented Aug 20, 2023 at 0:24
  • @sawdust, but in my case there is no any words like 'mv64xxx' in my dts for i2c nodes, there is 'compatible = "allwinner,sun20i-d1-i2c\0allwinner,sun6i-a31-i2c"'...
    – nx4n
    Commented Aug 24, 2023 at 12:15
  • @nx4n - Since you persist in only providing only the minimal amount of information, I vote to close this question
    – sawdust
    Commented Aug 24, 2023 at 18:29
  • @sawdust what? I have only one .dtb file in the /boot directory, there is i2c@xxxxxxxx node that has compatible field looks like I wrote above, that's all, I can't get and give you more information :(
    – nx4n
    Commented Aug 24, 2023 at 19:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .