* [RFC] wait for VX855 RTC to become ready during resume
@ 2011-09-19 10:36 Daniel Drake
2011-09-19 21:28 ` Andrew Morton
0 siblings, 1 reply; 3+ messages in thread
From: Daniel Drake @ 2011-09-19 10:36 UTC (permalink / raw)
To: linux-kernel, tglx, mingo, hpa, rjw
Hi,
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 UIP is clear, then we have >= 244 microseconds before
* RTC registers will be updated. Spec sheet says that this
* is the reliable way to read RTC - registers. If UIP is set
--
1.7.6.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [RFC] wait for VX855 RTC to become ready during resume
2011-09-19 10:36 [RFC] wait for VX855 RTC to become ready during resume Daniel Drake
@ 2011-09-19 21:28 ` Andrew Morton
2011-10-18 7:24 ` Daniel Drake
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2011-09-19 21:28 UTC (permalink / raw)
To: Daniel Drake; +Cc: linux-kernel, tglx, mingo, hpa, rjw, Andrew Morton
On Mon, 19 Sep 2011 11:36:37 +0100 (BST)
Daniel Drake <dsd@laptop.org> wrote:
> Hi,
>
> 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".
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFC] wait for VX855 RTC to become ready during resume
2011-09-19 21:28 ` Andrew Morton
@ 2011-10-18 7:24 ` Daniel Drake
0 siblings, 0 replies; 3+ messages in thread
From: Daniel Drake @ 2011-10-18 7:24 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, tglx, mingo, hpa, rjw, Andrew Morton
Hi Andrew,
On Mon, Sep 19, 2011 at 10:28 PM, Andrew Morton <akpm@google.com> 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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-10-18 7:24 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-19 10:36 [RFC] wait for VX855 RTC to become ready during resume Daniel Drake
2011-09-19 21:28 ` Andrew Morton
2011-10-18 7:24 ` Daniel Drake
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox