Re: [RFC] wait for VX855 RTC to become ready during resume

From: Daniel Drake
Date: Tue Oct 18 2011 - 03:24:38 EST


Hi Andrew,

On Mon, Sep 19, 2011 at 10:28 PM, Andrew Morton <akpm@xxxxxxxxxx> wrote:
>> As diagnosed at http://dev.laptop.org/ticket/10757 we are finding that
>> the RTC on the VIA VX855 frequently is not 'ready' during system resume.
>>
>> Reading from it produces zero. This causes the resume code to fail to
>> increment the system clock for the amount of time that was spent sleeping,
>> so the time is then wrong.
>>
>> We have found that if we wait for the RTC_REF_CLCK_32KHZ signal, the RTC
>> does soon start returning 'good' values.
>>
>> The patch below demonstrates the solution we have found, but will probably
>> make x86 maintainers cry. What would be a good approach to get this
>> appropriately quirked and worked around? Detect VX855 southbridge on PCI bus
>> and apply the quirk in this case? Do it from OLPC platform code?
>>
>> Thanks,
>> Daniel
>>
>>
>> ---
>>  arch/x86/kernel/rtc.c |   15 +++++++++++++++
>>  1 files changed, 15 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
>> index 88ee70d..3ad2e47 100644
>> --- a/arch/x86/kernel/rtc.c
>> +++ b/arch/x86/kernel/rtc.c
>> @@ -100,6 +100,21 @@ unsigned long mach_get_cmos_time(void)
>>       unsigned int status, year, mon, day, hour, min, sec, century = 0;
>>
>>       /*
>> +      * dev.laptop.org #10757, sometimes the RTC returns zero data
>> +      * immediately after a resume, so this code will give it some
>> +      * more time by waiting for the 32KHz clock bit to be set, in the
>> +      * hope that this means it is ready to be used.
>> +      */
>> +     if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_REF_CLCK_32KHZ)) {
>> +             int n = 0;
>> +             printk(KERN_INFO "rtc is insane, waiting for it\n");
>> +             while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_REF_CLCK_32KHZ)) {
>> +                     cpu_relax();
>> +                     n++;
>> +             }
>> +             printk(KERN_INFO "rtc was insane for %d counts\n", n);
>> +     }
>
> If the rtc is permanently insane, the kernel locks up.  I'd suggest
> adding a timeout.
>
> Perhaps also replace the cpu_relax() with a udelay(1), so the timeout
> can be properly implemented and so that the information in that printk
> has some useful meaning: "102 microseconds" is better than "11,434 counts".

Thanks for looking at this. We'll make the changes you've suggested,
test and resubmit.

Do you have any comments on the general approach? Is it OK to run such
code on all systems or should we look for a way to limit this to only
VX855/OLPC systems?

Thanks,
Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/