Bug 202139

Summary: i2c-designware stops working after S4 on CHT platforms
Product: Drivers Reporter: Jesse Sung (jesse)
Component: I2CAssignee: Rafael J. Wysocki (rjw)
Status: NEEDINFO ---    
Severity: normal CC: jesse, kai.heng.feng, rhowell, rjw
Priority: P1    
Hardware: x86-64   
OS: Linux   
Kernel Version: 4.18 Subsystem:
Regression: Yes Bisected commit-id:
Attachments: Reverting 02e45646d53b for 5.0-rc2 to fix Baytrail i2c-designware timeouts after S4

Description Jesse Sung 2019-01-04 15:57:22 UTC
We've noticed that i2c-designware stops working after waking up from S4
on a CHT platform we have. After searching it is found that this issue happens
after these two commits:

02e45646d53b - PM: i2c-designware-platdrv: Optimize power management
422cb781e0d0 - PM: i2c-designware-platdrv: Use DPM_FLAG_SMART_PREPARE

Both of them need to be reverted in order to make it work again.

So far I've tried up to 4.18. S4 stops working on 4.19 and 4.20 so I'm unable to
verify with these two versions until I can figure out why S4 doesn't work.

After waking up from S4:
[ 272.628526] PM: Timekeeping suspended for 115.313 seconds
[ 272.633110] ACPI: Waking up from system sleep state S4
[ 272.655524] PM: noirq restore of devices complete after 19.377 msecs
[ 272.775692] i2c_designware 80860F41:00: Unknown Synopsys component
type: 0xffffffff
[ 272.876322] PM: early restore of devices complete after 219.859 msecs
...
[ 273.060760] i2c_designware 80860F41:00: timeout waiting for bus ready
[ 274.214314] i2c_designware 80860F41:00: timeout in disabling adapter
Comment 1 Jesse Sung 2019-01-04 16:01:13 UTC
$ cat /proc/cpuinfo 
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 55
model name	: Intel(R) Atom(TM) CPU  E3815  @ 1.46GHz
stepping	: 9
microcode	: 0x90a
cpu MHz		: 1466.300
cache size	: 512 KB
physical id	: 0
siblings	: 1
core id		: 0
cpu cores	: 1
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 11
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes rdrand lahf_lm 3dnowprefetch epb pti ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid tsc_adjust smep erms dtherm arat
bugs		: cpu_meltdown spectre_v1 spectre_v2
bogomips	: 2932.60
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
power management:
Comment 2 Rafael J. Wysocki 2019-01-10 21:12:42 UTC
You said that you needed to revert both 422cb781e0d0 and 02e45646d53b in order to make the device work after resume from S4, but it really should be sufficient to revert 02e45646d53b for that, as 422cb781e0d0 should not affect hibernation (S4) at all.

Can you please double check if reverting 422cb781e0d0 was really necessary?

Also, have you tested suspend-to-RAM (S3) or suspend-to-idle on the affected system?
Comment 3 Rafael J. Wysocki 2019-01-10 21:15:07 UTC
Also please make sure that the i2c-designware-platdrv driver is loaded by the restore kernel before the hibernation image is read.
Comment 4 Jesse Sung 2019-01-18 06:34:11 UTC
Re-tested with 4.18 and, yes, you're right. 02e45646d53b is the only one that matters.

I only briefly tested S3 for several cycles and didn't find the problem.
Comment 5 Robert R. Howell 2019-01-18 20:54:33 UTC
Created attachment 280595 [details]
Reverting 02e45646d53b for 5.0-rc2 to fix Baytrail i2c-designware timeouts after S4

I've seen similar i2c-designware timeouts after S4 on several Baytrail based devices (the ASUS T100-TA, T100-TAM, and Toshiba Encore).  The problem breaks sound output after resume from S4.  Based on your comments above I tried reverting 02e45646d53b but not 422cb781e0d0 on the 5.0-rc2 (and -rc1) kernels and that does fix the problem -- eliminating all the i2c-designware timeout messages and allowing sound to work properly after resume.

For the 5.0 kernel there have been some changes in adjacent code in the i2c-designware-platdrv.c file so a simple attempt to revert 02e45646d53b fails and I've had to manually edit the file to reverse the changes from that commit.  Since I don't understand the details of some of that code I'm not sure I've really merged the 5.0 changes and the revert properly, but it seems to work for the above devices.  I've attached a 5.0 patch file in case you do want to see what I did.

In my system the i2c-designware driver is built into the kernel rather than being loaded as a module, so load order by the restore kernel shouldn't be relevant.

Let me know if I can help with any additional testing.