Bug 213353 - IRQs for onboard UARTs are not level-triggered with IRQNoFlags even if the parent section has the defaults in PRS
Summary: IRQs for onboard UARTs are not level-triggered with IRQNoFlags even if the pa...
Status: CLOSED INSUFFICIENT_DATA
Alias: None
Product: ACPI
Classification: Unclassified
Component: Config-Interrupts (show other bugs)
Hardware: All Linux
: P1 enhancement
Assignee: acpi_config-interrupts
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-06-07 09:56 UTC by Zoltan Boszormenyi
Modified: 2022-06-21 08:01 UTC (History)
2 users (show)

See Also:
Kernel Version: 5.12.8
Subsystem:
Regression: No
Bisected commit-id:


Attachments
dmesg (49.96 KB, text/plain)
2021-06-07 14:15 UTC, Zoltan Boszormenyi
Details
acpidump output (483.91 KB, text/plain)
2021-06-07 14:15 UTC, Zoltan Boszormenyi
Details
ACPI PCI Interrupt Device IRQ discovery (3.85 KB, patch)
2021-06-16 08:32 UTC, Zoltan Boszormenyi
Details | Diff

Description Zoltan Boszormenyi 2021-06-07 09:56:32 UTC
I have tablet with that supposedly has a serial-attached EETI touchscreen device.

# dmesg | grep ttyS0   
[    3.896102] 00:01: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A

When trying to use it via inputattach, it fails:

# inputattach -eeti /dev/ttyS0
inputattach: device initialization failed

The IRQ set up for the UART is edge-triggered, while it's attached to the LPC bus and should be level-trigered:

# grep " 4:" /proc/interrupts 
   4:          0          1          0          0   IO-APIC    4-edge    

Disassembling the DSDT, I can see this:

    Scope (_SB)
    {
       ...
       /* IRQ defaults for (E)ISA/LPC IRQs? */
       Name (PRSA, ResourceTemplate ()
        {
            IRQ (Level, ActiveLow, Shared, )
                {3,4,5,6,10,11,12,14,15}
        })
        Alias (PRSA, PRSB)
        Alias (PRSA, PRSC)
        Alias (PRSA, PRSD)
        Alias (PRSA, PRSE)
        Alias (PRSA, PRSF)
        Alias (PRSA, PRSG)
        Alias (PRSA, PRSH)


The serial device is in the above parent scope:

                Device (IURT)
                {
                    Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */)  // _HID: Hardware ID
                    Name (_UID, One)  // _UID: Unique ID
                    Method (_STA, 0, Serialized)  // _STA: Status
                    {
                        If ((USEL == Zero))
                        {
                            UI4E = One
                            C1EN = One
                            Return (0x0F)
                        }

                        Return (Zero)
                    }

                    Method (_DIS, 0, Serialized)  // _DIS: Disable Device
                    {
                        If (((BDID != One) && ((BDID != 0x0A) && 
                            (BDID != 0x09))))
                        {
                            UI4E = Zero
                            C1EN = Zero
                        }
                    }

                    Method (_CRS, 0, Serialized)  // _CRS: Current Resource Settings
                    {
                        Name (BUF0, ResourceTemplate ()
                        {
                            IO (Decode16,
                                0x03F8,             // Range Minimum
                                0x03F8,             // Range Maximum
                                0x01,               // Alignment
                                0x08,               // Length
                                )
                            IRQNoFlags ()
                                {4}
                        })
                        Return (BUF0) /* \_SB_.PCI0.LPCB.IURT._CRS.BUF0 */
                    }
                }

It seems to me that the IRQ default parameters from PRS are not applied to the PNP0501 device and as such, the serial device doesn't work.
Comment 1 Zhang Rui 2021-06-07 13:47:02 UTC
Please attach the full acpidump output and dmesg output after boot.
Comment 2 Zhang Rui 2021-06-07 13:52:14 UTC
and what if you change the BUF0 ASL code to
            IRQ (Level, ActiveLow, Shared, )
                {4}
and build the kernel with the customized DSDT?
Comment 3 Zoltan Boszormenyi 2021-06-07 14:15:31 UTC
Created attachment 297201 [details]
dmesg
Comment 4 Zoltan Boszormenyi 2021-06-07 14:15:56 UTC
Created attachment 297203 [details]
acpidump output
Comment 5 Zoltan Boszormenyi 2021-06-07 14:17:37 UTC
I was unable to recompile the DSDT because of this error printed by iasl -tc:

...
DSDT.dsl  23617:                     Local1 = WIDR /* \_SB_.PCI0.I2C7.WIDR */
Error    6058 -                      Invalid type ^  ([Device] found, Store operator requires [Integer|String|Buffer|Package|DdbHandle|Reference])
...
Compilation failed. 1 Errors, 100 Warnings, 186 Remarks
No AML files were generated due to compiler error(s)
Comment 6 Zoltan Boszormenyi 2021-06-10 06:16:11 UTC
(In reply to Zhang Rui from comment #1)
> Please attach the full acpidump output and dmesg output after boot.

I provided the necessary information.
Comment 7 Zhang Rui 2021-06-10 06:50:19 UTC
just remove the PSOC method that contains the bogus line and rebuild your DSDT. I tried this and it works.
I think it is okay to delete this PSOC because it is not used anywhere.
Comment 8 Zhang Rui 2021-06-16 06:59:39 UTC
Hi, Zoltan, any updates?
Comment 10 Zoltan Boszormenyi 2021-06-16 08:31:42 UTC
(In reply to Zhang Rui from comment #8)
> Hi, Zoltan, any updates?

Regarding the tablet in question, it turned out that the touchscreen is actually I2C and is correctly handled by the i2c-hid-acpi driver. We didn't have this driver enabled before.

FWIW, I also found https://bugzilla.kernel.org/show_bug.cgi?id=213031 and have been testing previous incarnations of the patch. It didn't help. I even had something like the attached patch which have built on the test patch from this other ticket and tried discovering the IRQ parameteres from the ACPI PCI Interrupt Link Device found in DSDT. And that also didn't help.
Comment 11 Zoltan Boszormenyi 2021-06-16 08:32:26 UTC
Created attachment 297387 [details]
ACPI PCI Interrupt Device IRQ discovery
Comment 12 Zoltan Boszormenyi 2021-06-16 08:34:24 UTC
(In reply to Zoltan Boszormenyi from comment #10)
> ... that also didn't help.

Obviously, the touchscreen now works, but I have been testing by opening the ttyS0 device and observing /proc/interrupts for IRQ 4.
Comment 13 Zhang Rui 2021-06-17 06:20:40 UTC
Sorry, I'm a little confused.

(In reply to Zoltan Boszormenyi from comment #10)
> (In reply to Zhang Rui from comment #8)
> > Hi, Zoltan, any updates?
> 
> Regarding the tablet in question, it turned out that the touchscreen is
> actually I2C and is correctly handled by the i2c-hid-acpi driver. We didn't
> have this driver enabled before.

Does the problem go away after you enabling this driver?
If yes, is there any other problem that blocks us from closing this bug report?
If no, do you mean it is still the IRQ problem still exists after enabling the i2c-hid-acpi driver? And can you try custom DSDT as I suggested?
Comment 14 Zoltan Boszormenyi 2021-06-19 04:58:02 UTC
(In reply to Zhang Rui from comment #13)
> Sorry, I'm a little confused.
> 
> (In reply to Zoltan Boszormenyi from comment #10)
> > (In reply to Zhang Rui from comment #8)
> > > Hi, Zoltan, any updates?
> > 
> > Regarding the tablet in question, it turned out that the touchscreen is
> > actually I2C and is correctly handled by the i2c-hid-acpi driver. We didn't
> > have this driver enabled before.
> 
> Does the problem go away after you enabling this driver?
> If yes, is there any other problem that blocks us from closing this bug
> report?
> If no, do you mean it is still the IRQ problem still exists after enabling
> the i2c-hid-acpi driver? And can you try custom DSDT as I suggested?

There were two orthogonal issues here.

1. the touchscreen didn't work, believed to be UART based but actually I2C and fixed by i2c-hid-acpi

2. the ttyS0 UART IRQ is wrong if the IRQ subsection for the specific device contains an empty IRQ () or IRQNoFlags () subsection.

This ticket is about the latter.

Possibly the Linux kernel's default IRQ parameters are wrong and the IOAPIC is programmed wrongly.

My patch that I attached here tries to collect the default legacy IRQ parameters from the PCI Interrupt Link device, but the kernel fails to use it.

Without irq_set_irq_type() in the patch, the IRQ stays edge triggered with extra messages in dmesg telling the IRQ is overridden to edge triggered.

With  irq_set_irq_type() in the patch, the IRQ becomes fasteoi instead of level triggered, resulting in the IRQ being disabled very quickly.

Possibly a small change may make the patch work but I don't know enough to make it work. It is also possible that by the time this code is reached, it's too late for IRQ setup in the APIC/IOAPIC.
Comment 15 Zhang Rui 2021-07-01 02:13:26 UTC
so let's focus on the second issue only.
Do you have a pattern that can fix it?
if no, can you please check if the problem is gone with DSDT fixed as I suggested in comment #2? the bogus piece of ASL code can be removed as I mentioned in comment #7.
Only if we have a pattern that works, we can think about how to fix it in Linux kernel.
Comment 16 Zhang Rui 2022-06-21 08:01:13 UTC
Bug closed as there is no response from the bug reporter.
Please feel free to reopen it if you can provide the info required.

Note You need to log in before you can comment on or make changes to this bug.