diff mbox

ACPI/Battery: Retry to get Battery information if failed during probing

Message ID 1402552946-14704-1-git-send-email-tianyu.lan@intel.com (mailing list archive)
State Superseded, archived
Headers show

Commit Message

lan,Tianyu June 12, 2014, 6:02 a.m. UTC
Some machines'(E,G Lenovo Z480) ECs are not stable during boot up
and causes battery driver fails to be probed due to failure of getting
battery information from EC sometimes. After several retries, the
operation will work. This patch is to retry to get battery information 5
times if the first try fails.

Reported-and-tested-by: naszar <naszar@ya.ru>
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=75581
Cc: stable@vger.kernel.org
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
---
 drivers/acpi/battery.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

David Rientjes June 12, 2014, 6:55 a.m. UTC | #1
On Thu, 12 Jun 2014, Lan Tianyu wrote:

> Some machines'(E,G Lenovo Z480) ECs are not stable during boot up
> and causes battery driver fails to be probed due to failure of getting
> battery information from EC sometimes. After several retries, the
> operation will work. This patch is to retry to get battery information 5
> times if the first try fails.
> 
> Reported-and-tested-by: naszar <naszar@ya.ru>
> Reference: https://bugzilla.kernel.org/show_bug.cgi?id=75581
> Cc: stable@vger.kernel.org
> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
> ---
>  drivers/acpi/battery.c | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
> index e48fc98..485009d 100644
> --- a/drivers/acpi/battery.c
> +++ b/drivers/acpi/battery.c
> @@ -34,6 +34,7 @@
>  #include <linux/dmi.h>
>  #include <linux/slab.h>
>  #include <linux/suspend.h>
> +#include <linux/delay.h>
>  #include <asm/unaligned.h>
>  
>  #ifdef CONFIG_ACPI_PROCFS_POWER
> @@ -1119,7 +1120,7 @@ static struct dmi_system_id bat_dmi_table[] = {
>  
>  static int acpi_battery_add(struct acpi_device *device)
>  {
> -	int result = 0;
> +	int result = 0, retry = 5;
>  	struct acpi_battery *battery = NULL;
>  
>  	if (!device)
> @@ -1135,7 +1136,16 @@ static int acpi_battery_add(struct acpi_device *device)
>  	mutex_init(&battery->sysfs_lock);
>  	if (acpi_has_method(battery->device->handle, "_BIX"))
>  		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
> +
> +retry_get_info:
>  	result = acpi_battery_update(battery, false);
> +
> +	if (result && retry) {
> +		msleep(20);

We're really going to wait up to 20 * 5 = 100ms for acpi_battery_update() 
to succeed?  How are these the numbers that are determined to be optimal 
for probing?

> +		retry--;
> +		goto retry_get_info;
> +	}

This most certainly could be rewritten as a for-loop and remove the ugly 
goto.

> +
>  	if (result)
>  		goto fail;
>  #ifdef CONFIG_ACPI_PROCFS_POWER
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lan,Tianyu June 12, 2014, 7:19 a.m. UTC | #2
On 2014?06?12? 14:55, David Rientjes wrote:
> On Thu, 12 Jun 2014, Lan Tianyu wrote:
> 
>> Some machines'(E,G Lenovo Z480) ECs are not stable during boot up
>> and causes battery driver fails to be probed due to failure of getting
>> battery information from EC sometimes. After several retries, the
>> operation will work. This patch is to retry to get battery information 5
>> times if the first try fails.
>>
>> Reported-and-tested-by: naszar <naszar@ya.ru>
>> Reference: https://bugzilla.kernel.org/show_bug.cgi?id=75581
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
>> ---
>>  drivers/acpi/battery.c | 12 +++++++++++-
>>  1 file changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
>> index e48fc98..485009d 100644
>> --- a/drivers/acpi/battery.c
>> +++ b/drivers/acpi/battery.c
>> @@ -34,6 +34,7 @@
>>  #include <linux/dmi.h>
>>  #include <linux/slab.h>
>>  #include <linux/suspend.h>
>> +#include <linux/delay.h>
>>  #include <asm/unaligned.h>
>>  
>>  #ifdef CONFIG_ACPI_PROCFS_POWER
>> @@ -1119,7 +1120,7 @@ static struct dmi_system_id bat_dmi_table[] = {
>>  
>>  static int acpi_battery_add(struct acpi_device *device)
>>  {
>> -	int result = 0;
>> +	int result = 0, retry = 5;
>>  	struct acpi_battery *battery = NULL;
>>  
>>  	if (!device)
>> @@ -1135,7 +1136,16 @@ static int acpi_battery_add(struct acpi_device *device)
>>  	mutex_init(&battery->sysfs_lock);
>>  	if (acpi_has_method(battery->device->handle, "_BIX"))
>>  		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
>> +
>> +retry_get_info:
>>  	result = acpi_battery_update(battery, false);
>> +
>> +	if (result && retry) {
>> +		msleep(20);
> 

Hi David:
	Thanks for review.

> We're really going to wait up to 20 * 5 = 100ms for acpi_battery_update() 
> to succeed?

No, this depends which retry acpi_battery_update() will succeed. For
most machines, there will be no delay.

> How are these the numbers that are determined to be optimal 
> for probing?

So far, it depends the return values of executing ACPI methods. If they
were failed, the probing would not go further.

> 
>> +		retry--;
>> +		goto retry_get_info;
>> +	}
> 
> This most certainly could be rewritten as a for-loop and remove the ugly 
> goto.

Ok. I will update.

> 
>> +
>>  	if (result)
>>  		goto fail;
>>  #ifdef CONFIG_ACPI_PROCFS_POWER
David Rientjes June 12, 2014, 7:26 a.m. UTC | #3
On Thu, 12 Jun 2014, Lan Tianyu wrote:

> >> Some machines'(E,G Lenovo Z480) ECs are not stable during boot up
> >> and causes battery driver fails to be probed due to failure of getting
> >> battery information from EC sometimes. After several retries, the
> >> operation will work. This patch is to retry to get battery information 5
> >> times if the first try fails.
> >>
> >> Reported-and-tested-by: naszar <naszar@ya.ru>
> >> Reference: https://bugzilla.kernel.org/show_bug.cgi?id=75581
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
> >> ---
> >>  drivers/acpi/battery.c | 12 +++++++++++-
> >>  1 file changed, 11 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
> >> index e48fc98..485009d 100644
> >> --- a/drivers/acpi/battery.c
> >> +++ b/drivers/acpi/battery.c
> >> @@ -34,6 +34,7 @@
> >>  #include <linux/dmi.h>
> >>  #include <linux/slab.h>
> >>  #include <linux/suspend.h>
> >> +#include <linux/delay.h>
> >>  #include <asm/unaligned.h>
> >>  
> >>  #ifdef CONFIG_ACPI_PROCFS_POWER
> >> @@ -1119,7 +1120,7 @@ static struct dmi_system_id bat_dmi_table[] = {
> >>  
> >>  static int acpi_battery_add(struct acpi_device *device)
> >>  {
> >> -	int result = 0;
> >> +	int result = 0, retry = 5;
> >>  	struct acpi_battery *battery = NULL;
> >>  
> >>  	if (!device)
> >> @@ -1135,7 +1136,16 @@ static int acpi_battery_add(struct acpi_device *device)
> >>  	mutex_init(&battery->sysfs_lock);
> >>  	if (acpi_has_method(battery->device->handle, "_BIX"))
> >>  		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
> >> +
> >> +retry_get_info:
> >>  	result = acpi_battery_update(battery, false);
> >> +
> >> +	if (result && retry) {
> >> +		msleep(20);
> > 
> 
> Hi David:
> 	Thanks for review.
> 
> > We're really going to wait up to 20 * 5 = 100ms for acpi_battery_update() 
> > to succeed?
> 
> No, this depends which retry acpi_battery_update() will succeed. For
> most machines, there will be no delay.
> 

Right, but you're willing to wait up to 100ms for it to succeed?  You're 
implementing x retries with y ms sleep in between, I'm asking how it is 
determined that the optimal values are x = 5 and y = 20.  More directly: 
is it possible to succeed at 101ms?  Is it really likely to succeed after 
the first 20ms?
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lan,Tianyu June 12, 2014, 8:14 a.m. UTC | #4
On 2014?06?12? 15:26, David Rientjes wrote:
> On Thu, 12 Jun 2014, Lan Tianyu wrote:
> 
>>>> Some machines'(E,G Lenovo Z480) ECs are not stable during boot up
>>>> and causes battery driver fails to be probed due to failure of getting
>>>> battery information from EC sometimes. After several retries, the
>>>> operation will work. This patch is to retry to get battery information 5
>>>> times if the first try fails.
>>>>
>>>> Reported-and-tested-by: naszar <naszar@ya.ru>
>>>> Reference: https://bugzilla.kernel.org/show_bug.cgi?id=75581
>>>> Cc: stable@vger.kernel.org
>>>> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
>>>> ---
>>>>  drivers/acpi/battery.c | 12 +++++++++++-
>>>>  1 file changed, 11 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
>>>> index e48fc98..485009d 100644
>>>> --- a/drivers/acpi/battery.c
>>>> +++ b/drivers/acpi/battery.c
>>>> @@ -34,6 +34,7 @@
>>>>  #include <linux/dmi.h>
>>>>  #include <linux/slab.h>
>>>>  #include <linux/suspend.h>
>>>> +#include <linux/delay.h>
>>>>  #include <asm/unaligned.h>
>>>>  
>>>>  #ifdef CONFIG_ACPI_PROCFS_POWER
>>>> @@ -1119,7 +1120,7 @@ static struct dmi_system_id bat_dmi_table[] = {
>>>>  
>>>>  static int acpi_battery_add(struct acpi_device *device)
>>>>  {
>>>> -	int result = 0;
>>>> +	int result = 0, retry = 5;
>>>>  	struct acpi_battery *battery = NULL;
>>>>  
>>>>  	if (!device)
>>>> @@ -1135,7 +1136,16 @@ static int acpi_battery_add(struct acpi_device *device)
>>>>  	mutex_init(&battery->sysfs_lock);
>>>>  	if (acpi_has_method(battery->device->handle, "_BIX"))
>>>>  		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
>>>> +
>>>> +retry_get_info:
>>>>  	result = acpi_battery_update(battery, false);
>>>> +
>>>> +	if (result && retry) {
>>>> +		msleep(20);
>>>
>>
>> Hi David:
>> 	Thanks for review.
>>
>>> We're really going to wait up to 20 * 5 = 100ms for acpi_battery_update() 
>>> to succeed?
>>
>> No, this depends which retry acpi_battery_update() will succeed. For
>> most machines, there will be no delay.
>>
> 
> Right, but you're willing to wait up to 100ms for it to succeed?  You're 
> implementing x retries with y ms sleep in between, I'm asking how it is 
> determined that the optimal values are x = 5 and y = 20. More directly:
> is it possible to succeed at 101ms?

The retry time is set by randomly and not accurate because don't know
when EC will work normally. Set the retry time to 5 just in order to
make sure battery driver probing sucessfully every time,

>  Is it really likely to succeed after 
> the first 20ms?
> 

Yes, it's possible.
From naszar's test log, acpi_battery_update() failed only once. But not
sure that this happens every time, treat it conservatively and set the
retry time to 5.
https://bugzilla.kernel.org/attachment.cgi?id=139081&action=edit
David Rientjes June 12, 2014, 9:17 p.m. UTC | #5
On Thu, 12 Jun 2014, Lan Tianyu wrote:

> The retry time is set by randomly and not accurate because don't know
> when EC will work normally. Set the retry time to 5 just in order to
> make sure battery driver probing sucessfully every time,
> 

Ok, I was hoping to avoid the excessive wait if it will never actually 
succeed but I assume there's some evidence that it can succeed after 40ms, 
60ms, etc.  Please consider the following instead:

	for (i = 0; i < 5; i++) {
		/* Comment on why we need a delay in between retries */
		if (i)
			msleep(20);
		result = acpi_battery_update(battery, false);
		if (!result)
			break;
	}
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lan,Tianyu June 13, 2014, 2:25 a.m. UTC | #6
On 2014?06?13? 05:17, David Rientjes wrote:
> On Thu, 12 Jun 2014, Lan Tianyu wrote:
> 
>> The retry time is set by randomly and not accurate because don't know
>> when EC will work normally. Set the retry time to 5 just in order to
>> make sure battery driver probing sucessfully every time,
>>
> 
> Ok, I was hoping to avoid the excessive wait if it will never actually 
> succeed

Ok. The battery driver has used async init and so this will not affect
the speed of boot up.

> but I assume there's some evidence that it can succeed after 40ms, 
> 60ms, etc.  Please consider the following instead:
> 
> 	for (i = 0; i < 5; i++) {
> 		/* Comment on why we need a delay in between retries */
> 		if (i)
> 			msleep(20);
> 		result = acpi_battery_update(battery, false);
> 		if (!result)
> 			break;
> 	}
> 

How about this?

-       result = acpi_battery_update(battery, false);
-       if (result)
+
+       /*
+        * Some machines'(E,G Lenovo Z480) ECs are not stable
+        * during boot up and this causes battery driver fails to be
+        * probed due to failure of getting battery information
+        * from EC sometimes. After several retries, the operation
+        * may work. So add retry code here and 20ms sleep between
+        * every retries.
+        */
+       while (acpi_battery_update(battery, false) && retry--)
+               msleep(20);
+       if (!retry) {
+               result = -ENODEV;
                goto fail;
+       }
+
David Rientjes June 13, 2014, 9:46 p.m. UTC | #7
On Fri, 13 Jun 2014, Lan Tianyu wrote:

> How about this?
> 
> -       result = acpi_battery_update(battery, false);
> -       if (result)
> +
> +       /*
> +        * Some machines'(E,G Lenovo Z480) ECs are not stable
> +        * during boot up and this causes battery driver fails to be
> +        * probed due to failure of getting battery information
> +        * from EC sometimes. After several retries, the operation
> +        * may work. So add retry code here and 20ms sleep between
> +        * every retries.
> +        */
> +       while (acpi_battery_update(battery, false) && retry--)
> +               msleep(20);
> +       if (!retry) {
> +               result = -ENODEV;
>                 goto fail;
> +       }
> +

I think you want --retry and not retry--.  Otherwise it's possible for the 
final call to acpi_battery_update() to succeed and now it's returning 
-ENODEV.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lan,Tianyu June 16, 2014, 2:12 a.m. UTC | #8
On 2014?06?14? 05:46, David Rientjes wrote:
> On Fri, 13 Jun 2014, Lan Tianyu wrote:
> 
>> How about this?
>>
>> -       result = acpi_battery_update(battery, false);
>> -       if (result)
>> +
>> +       /*
>> +        * Some machines'(E,G Lenovo Z480) ECs are not stable
>> +        * during boot up and this causes battery driver fails to be
>> +        * probed due to failure of getting battery information
>> +        * from EC sometimes. After several retries, the operation
>> +        * may work. So add retry code here and 20ms sleep between
>> +        * every retries.
>> +        */
>> +       while (acpi_battery_update(battery, false) && retry--)
>> +               msleep(20);
>> +       if (!retry) {
>> +               result = -ENODEV;
>>                 goto fail;
>> +       }
>> +
> 
> I think you want --retry and not retry--.

My original purpose is to retry 5 times after the first try fails.
If use "--retry" here, it just retries 4 times.

>  Otherwise it's possible for the 
> final call to acpi_battery_update() to succeed and now it's returning 
> -ENODEV.
> 

Yes, it maybe and I will change code like the following.

while ((result = acpi_battery_update(battery, false)) && retry--)
       msleep(20);
if (result)
       goto fail;
Lv Zheng June 16, 2014, 2:35 a.m. UTC | #9
Hi,

> From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-owner@vger.kernel.org] On Behalf Of Lan Tianyu

> Sent: Monday, June 16, 2014 10:12 AM

> To: David Rientjes

> Cc: rjw@rjwysocki.net; lenb@kernel.org; naszar@ya.ru; linux-acpi@vger.kernel.org; linux-kernel@vger.kernel.org

> Subject: Re: [PATCH] ACPI/Battery: Retry to get Battery information if failed during probing

> 

> On 2014?06?14? 05:46, David Rientjes wrote:

> > On Fri, 13 Jun 2014, Lan Tianyu wrote:

> >

> >> How about this?

> >>

> >> -       result = acpi_battery_update(battery, false);

> >> -       if (result)

> >> +

> >> +       /*

> >> +        * Some machines'(E,G Lenovo Z480) ECs are not stable


Just a reminder.

This statement may not be true.
The issue may be caused by the EC driver itself.
So we need to investigate.

> >> +        * during boot up and this causes battery driver fails to be

> >> +        * probed due to failure of getting battery information

> >> +        * from EC sometimes. After several retries, the operation

> >> +        * may work. So add retry code here and 20ms sleep between

> >> +        * every retries.

> >> +        */

> >> +       while (acpi_battery_update(battery, false) && retry--)


If EC hardware is stable, why we need to do retry here?

Thanks and best regards
-Lv

> >> +               msleep(20);

> >> +       if (!retry) {

> >> +               result = -ENODEV;

> >>                 goto fail;

> >> +       }

> >> +

> >

> > I think you want --retry and not retry--.

> 

> My original purpose is to retry 5 times after the first try fails.

> If use "--retry" here, it just retries 4 times.

> 

> >  Otherwise it's possible for the

> > final call to acpi_battery_update() to succeed and now it's returning

> > -ENODEV.

> >

> 

> Yes, it maybe and I will change code like the following.

> 

> while ((result = acpi_battery_update(battery, false)) && retry--)

>        msleep(20);

> if (result)

>        goto fail;

> 

> 

> --

> Best regards

> Tianyu Lan

> --

> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in

> the body of a message to majordomo@vger.kernel.org

> More majordomo info at  http://vger.kernel.org/majordomo-info.html
lan,Tianyu June 16, 2014, 2:43 a.m. UTC | #10
On 2014?06?16? 10:35, Zheng, Lv wrote:
> Hi,
> 
>> From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-owner@vger.kernel.org] On Behalf Of Lan Tianyu
>> Sent: Monday, June 16, 2014 10:12 AM
>> To: David Rientjes
>> Cc: rjw@rjwysocki.net; lenb@kernel.org; naszar@ya.ru; linux-acpi@vger.kernel.org; linux-kernel@vger.kernel.org
>> Subject: Re: [PATCH] ACPI/Battery: Retry to get Battery information if failed during probing
>>
>> On 2014?06?14? 05:46, David Rientjes wrote:
>>> On Fri, 13 Jun 2014, Lan Tianyu wrote:
>>>
>>>> How about this?
>>>>
>>>> -       result = acpi_battery_update(battery, false);
>>>> -       if (result)
>>>> +
>>>> +       /*
>>>> +        * Some machines'(E,G Lenovo Z480) ECs are not stable
> 
> Just a reminder.
> 
> This statement may not be true.
> The issue may be caused by the EC driver itself.
> So we need to investigate.

Not sure. The bug doesn't happen every time. 5-10% during boot up.

> 
>>>> +        * during boot up and this causes battery driver fails to be
>>>> +        * probed due to failure of getting battery information
>>>> +        * from EC sometimes. After several retries, the operation
>>>> +        * may work. So add retry code here and 20ms sleep between
>>>> +        * every retries.
>>>> +        */
>>>> +       while (acpi_battery_update(battery, false) && retry--)
> 
> If EC hardware is stable, why we need to do retry here?
> 

Yes, if it can work normally every time, we don't need retry here.


> Thanks and best regards
> -Lv
> 
>>>> +               msleep(20);
>>>> +       if (!retry) {
>>>> +               result = -ENODEV;
>>>>                 goto fail;
>>>> +       }
>>>> +
>>>
>>> I think you want --retry and not retry--.
>>
>> My original purpose is to retry 5 times after the first try fails.
>> If use "--retry" here, it just retries 4 times.
>>
>>>  Otherwise it's possible for the
>>> final call to acpi_battery_update() to succeed and now it's returning
>>> -ENODEV.
>>>
>>
>> Yes, it maybe and I will change code like the following.
>>
>> while ((result = acpi_battery_update(battery, false)) && retry--)
>>        msleep(20);
>> if (result)
>>        goto fail;
>>
>>
>> --
>> Best regards
>> Tianyu Lan
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Rientjes June 17, 2014, 1:27 a.m. UTC | #11
On Mon, 16 Jun 2014, Lan Tianyu wrote:

> >> How about this?
> >>
> >> -       result = acpi_battery_update(battery, false);
> >> -       if (result)
> >> +
> >> +       /*
> >> +        * Some machines'(E,G Lenovo Z480) ECs are not stable
> >> +        * during boot up and this causes battery driver fails to be
> >> +        * probed due to failure of getting battery information
> >> +        * from EC sometimes. After several retries, the operation
> >> +        * may work. So add retry code here and 20ms sleep between
> >> +        * every retries.
> >> +        */
> >> +       while (acpi_battery_update(battery, false) && retry--)
> >> +               msleep(20);
> >> +       if (!retry) {
> >> +               result = -ENODEV;
> >>                 goto fail;
> >> +       }
> >> +
> > 
> > I think you want --retry and not retry--.
> 
> My original purpose is to retry 5 times after the first try fails.
> If use "--retry" here, it just retries 4 times.
> 
> >  Otherwise it's possible for the 
> > final call to acpi_battery_update() to succeed and now it's returning 
> > -ENODEV.
> > 
> 
> Yes, it maybe and I will change code like the following.
> 
> while ((result = acpi_battery_update(battery, false)) && retry--)
>        msleep(20);
> if (result)
>        goto fail;
> 

Looks good.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lan,Tianyu June 17, 2014, 1:27 a.m. UTC | #12
On 2014?06?17? 09:27, David Rientjes wrote:
> On Mon, 16 Jun 2014, Lan Tianyu wrote:
> 
>>>> How about this?
>>>>
>>>> -       result = acpi_battery_update(battery, false);
>>>> -       if (result)
>>>> +
>>>> +       /*
>>>> +        * Some machines'(E,G Lenovo Z480) ECs are not stable
>>>> +        * during boot up and this causes battery driver fails to be
>>>> +        * probed due to failure of getting battery information
>>>> +        * from EC sometimes. After several retries, the operation
>>>> +        * may work. So add retry code here and 20ms sleep between
>>>> +        * every retries.
>>>> +        */
>>>> +       while (acpi_battery_update(battery, false) && retry--)
>>>> +               msleep(20);
>>>> +       if (!retry) {
>>>> +               result = -ENODEV;
>>>>                 goto fail;
>>>> +       }
>>>> +
>>>
>>> I think you want --retry and not retry--.
>>
>> My original purpose is to retry 5 times after the first try fails.
>> If use "--retry" here, it just retries 4 times.
>>
>>>  Otherwise it's possible for the 
>>> final call to acpi_battery_update() to succeed and now it's returning 
>>> -ENODEV.
>>>
>>
>> Yes, it maybe and I will change code like the following.
>>
>> while ((result = acpi_battery_update(battery, false)) && retry--)
>>        msleep(20);
>> if (result)
>>        goto fail;
>>
> 
> Looks good.
> 

Great. Thanks for review. :)
diff mbox

Patch

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index e48fc98..485009d 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -34,6 +34,7 @@ 
 #include <linux/dmi.h>
 #include <linux/slab.h>
 #include <linux/suspend.h>
+#include <linux/delay.h>
 #include <asm/unaligned.h>
 
 #ifdef CONFIG_ACPI_PROCFS_POWER
@@ -1119,7 +1120,7 @@  static struct dmi_system_id bat_dmi_table[] = {
 
 static int acpi_battery_add(struct acpi_device *device)
 {
-	int result = 0;
+	int result = 0, retry = 5;
 	struct acpi_battery *battery = NULL;
 
 	if (!device)
@@ -1135,7 +1136,16 @@  static int acpi_battery_add(struct acpi_device *device)
 	mutex_init(&battery->sysfs_lock);
 	if (acpi_has_method(battery->device->handle, "_BIX"))
 		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
+
+retry_get_info:
 	result = acpi_battery_update(battery, false);
+
+	if (result && retry) {
+		msleep(20);
+		retry--;
+		goto retry_get_info;
+	}
+
 	if (result)
 		goto fail;
 #ifdef CONFIG_ACPI_PROCFS_POWER