> Date: Tue, 14 Dec 2021 02:20:11 +0000
> From: Renato Aguiar <[email protected]>
>
> I did some investigation over the weekend and I was able to get more
> information about the problem and find a better workaround.
>
> There are 3 devices attaching to `dwiic* at pci0':
>
> dwiic0 at pci0 dev 21 function 0 "Intel 500 Series I2C" rev 0x20: apic 2 int
> 27
>
> I have no idea what this one is for, but it keeps sending interrupts
> after resume and that is what is causing the laptop to freeze.
> Disabling this device alone "fixes" suspend/resume for me.
>
> dwiic1 at pci0 dev 21 function 1 "Intel 500 Series I2C" rev 0x20: apic 2 int
> 40
>
> This is for some special keyboard keys, like brightness control.
>
> dwiic2 at pci0 dev 21 function 3 "Intel 500 Series I2C" rev 0x20: apic 2 int
> 30
>
> And this one is for touchpad.
>
> As a workaround for now, I'm changing `dwiic* at pci*` to attach only to
> touchpad, so I can have suspend/resume working without losing the touchpad.
>
> # config -ef /bsd
> ukc> find dwiic
> 226 dwiic* at pci* dev -1 function -1 flags 0x0
> 448 dwiic* at acpi0 flags 0x0
> ukc> change 226
> 226 dwiic* at pci* dev -1 function -1 flags 0x0
> change [n] y
> dev [-1] ? 21
> function [-1] ? 3
> flags [0] ?
> 226 dwiic* changed
> 226 dwiic* at pci* dev 0x15 function 3 flags 0x0
> ukc> quit
>
> Now it only configures dwiic0 for touchpad:
>
> "Intel 500 Series I2C" rev 0x20 at pci0 dev 21 function 0 not configured
> "Intel 500 Series I2C" rev 0x20 at pci0 dev 21 function 1 not configured
> dwiic0 at pci0 dev 21 function 3 "Intel 500 Series I2C" rev 0x20: apic 2
> int 30
>
> To make it survive reboots, I added the configuration to
> `/etc/bsd.re-config`. Be careful when using this one because of the
> hardcoded DevNo.
>
> $ cat /etc/bsd.re-config
> change 226
> y
> 21
> 3
> 0
>
> I hope this issue can be fixed soon, but at least I now have a fully
> functional OpenBSD on my Framework laptop :)
That is a good find. It seems we don't mask interrupts upon resume.
And the interrupt handler is written in a way such that it doesn't
necessarily acknowledge interrupts if the controller is currently
disabled, which will always be the case for controllers with no
attached devices.
Does the diff below help?
Index: dev/ic/dwiic.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/dwiic.c,v
retrieving revision 1.13
diff -u -p -r1.13 dwiic.c
--- dev/ic/dwiic.c 7 Nov 2021 14:07:43 -0000 1.13
+++ dev/ic/dwiic.c 14 Dec 2021 10:56:37 -0000
@@ -153,6 +153,10 @@ dwiic_init(struct dwiic_softc *sc)
/* disable the adapter */
dwiic_enable(sc, 0);
+ /* disable interrupts */
+ dwiic_write(sc, DW_IC_INTR_MASK, 0);
+ dwiic_read(sc, DW_IC_CLR_INTR);
+
/* write standard-mode SCL timing parameters */
dwiic_write(sc, DW_IC_SS_SCL_HCNT, sc->ss_hcnt);
dwiic_write(sc, DW_IC_SS_SCL_LCNT, sc->ss_lcnt);