Syniurge / i2c-amd-mp2

DKMS-ready driver for AMD PCI-E MP2 I2C controllers
22 stars 4 forks source link

HID over i2c has not been provided an Int IRQ if pinctrl_amd is not loaded first #3

Closed chithanh closed 5 years ago

chithanh commented 5 years ago

This has been observed on a Dell Latitude 5495, Gentoo kernel 4.19.2, patch v10:

If CONFIG_PINCTRL_AMD=n or the pinctrl-amd module is not loaded before i2c-amd-mp2, then i2c-hid will fail to initialize with the following message:

[ 29.866608] i2c_amd_mp2: AMD(R) PCI-E MP2 I2C Controller Driver Version: 1.0
[ 29.866611] i2c_amd_mp2 0000:04:00.7: MP2 device found [1022:15e6] (rev 0)
[ 29.866623] i2c_amd_mp2 0000:04:00.7: enabling device (0000 -> 0002)
[ 29.866753] i2c_amd_mp2 0000:04:00.7: MP2 device registered.
[ 29.869498] smo8800 SMO8810:00: failed to obtain IRQ
[ 29.869560] smo8800: probe of SMO8810:00 failed with error -22
[ 29.876200] i2c_hid i2c-DELL0814:00: HID over i2c has not been provided an Int IRQ
[ 29.876754] i2c_hid: probe of i2c-DELL0814:00 failed with error -22

If pinctrl-amd initializes first, then all is fine. So it may be necessary to put a dependency in Kconfig.

Also note that if i2c-hid gets probed before i2c-amd-mp2 then things may fail to work too. Ubuntu made this driver built-in in order to work around this issue (cf. https://patchwork.ozlabs.org/patch/946169/ comment 3).

My current workaround is adding softdep statements to /etc/modprobe.d/.

Syniurge commented 5 years ago

Thanks for noticing this, however if it was the MP2 I2C controller that relied on an interrupt managed by pinctrl-amd probing the MP2 would have failed (no "MP2 device registered." message).

It's actually the I2C HID device itself which depends on pinctrl-amd. It roughtly works this way: touchpad detects input and asserts an interrupt on the amd-gpio chip -> i2c-hid services the amd-gpio IRQ -> i2c-hid sends read message to the i2c controller driver -> i2c_amd_mp2 which receives the message sends read command to MP2 and waits for MP2's response/interrupt -> once i2c_amd_mp2 receives the interrupt it fills the i2c message buffer which is then returned to i2c-hid

For the Yoga 530 and Ideapad 530s at least the MP2 interrupt line goes to an APIC.

Ubuntu made this driver built-in in order to work around this issue (cf. https://patchwork.ozlabs.org/patch/946169/ comment 3).

Actually it was because of a missing MODULE_DEVICE_TABLE in the ACPI driver so the platform module wouldn't get loaded automatically.

The MP2 driver itself as module does work, but if we want the i2c touchpad uses it as transport, the MP2 driver has to be loaded before i2c-hid gets probed.

I don't think that comment is correct, at least for the Yoga 530 in the DSDT the I2C HID devices are listed as children of the MP2 I2C adapters, so if I understood the code properly Linux is probing the parent MP2 I2C controller and loading the appropriate module before probing the children.

Syniurge commented 5 years ago

My current workaround is adding softdep statements to /etc/modprobe.d/.

You mean it still doesn't work for you? Could you paste the DSDT of the Latitude 5495 somewhere?

chithanh commented 5 years ago

It works for me as long as pinctrl-amd is loaded. Further testing seems to suggest that CONFIG_PINCTRL_AMD=n causes the "HID over i2c has not been provided an Int IRQ" error above. So feel free to mark this issue as resolved.

If it is still of interest, here is the DSDT (gzip compressed because github will not allow upload otherwise):

DSDT.dat.gz

Syniurge commented 5 years ago

The DSDT is very similar to the Yoga 530's, the description of the MP2 I2C adapters is the same and the passage of interest for the I2C HID touchpad is:

    Scope (_SB.I2CB)
    {
        Device (TPNL)
        {
            Name (_HID, EisaId ("PNP0C50") /* HID Protocol Device (I2C bus) */)  // _HID: Hardware ID
            Name (_CID, "PNP0C50" /* HID Protocol Device (I2C bus) */)  // _CID: Compatible ID
            Name (_UID, 0x02)  // _UID: Unique ID
            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
            {
                Name (RBUF, ResourceTemplate ()
                {
                    I2cSerialBusV2 (0x004A, ControllerInitiated, 0x000F4240,
                        AddressingMode7Bit, "\\_SB.I2CB",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    GpioInt (Level, ActiveLow, Shared, PullUp, 0x0000,
                        "\\_SB.GPIO", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x000C
                        }
                })
                Return (RBUF) /* \_SB_.I2CB.TPNL._CRS.RBUF */
            }

From a quick look at the code handling GpioInt it seems that probing the HID I2C touchpad gets deferred until the GPIO chip gets probed by pinctrl-amd.

But if you set CONFIG_PINCTRL_AMD=n then the CONFIG_GPIOLIB dependency may also be n and it simply returns that there is no IRQ:

#if !defined(CONFIG_GPIOLIB)
static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
{
    return -ENXIO;
}
#endif

So although neither i2c-hid or i2c-amd-mp2 should depend on a particular GPIO driver, perhaps the GpioInt handling code should warn that there's no GPIO driver instead of silently returning no irq, but that's not directly related to i2c-amd-mp2 so I'm closing.

Syniurge commented 5 years ago

Btw the AMD GPIO chip is properly listed in the DSDT so the pinctrl-amd module (if built as such) should automatically get loaded at some point during boot. However if you for example blacklisted it, then the probing of the I2C HID touchpad gets deferred until you manually load pinctrl-amd.

markubiak commented 3 years ago

For those coming across this issue trying to resolve trackpad issues, this Reddit thread is probably what you're looking for.

In summary, some modules seem to be loading out-of-order. To fix this, make a new file, /etc/modprobe.d/elan-touchpad.conf:

softdep elan_i2c pre: pinctrl_amd
softdep hid_elan pre: pinctrl_amd

Working on an ASUS Zephyrus G14.

kvaps commented 3 years ago

I also have this problem with touchpad on my 81BR Lenovo ideapad 720S-13ARR, randomly it is not working after a boot, dmesg shows:

[    4.679608] drivers/hid/i2c-hid/i2c-hid-core.c: HID probe called for i2c 0x2c
[    4.679612] i2c_hid i2c-MSFT0001:00: HID over i2c has not been provided an Int IRQ
[    4.679659] i2c_hid: probe of i2c-MSFT0001:00 failed with error -22

Fixed by adding this line:

# cat /etc/modprobe.d/i2c-touchpad.conf
softdep i2c_hid pre: pinctrl_amd

Thanks for a hint!