[U-Boot] [PATCH V3 2/6] power: Explicitly select pmic device's bus

Leela Krishna Amudala l.krishna at samsung.com
Fri Jan 3 00:37:06 CET 2014


Hi Minkyu Kang,

On Thu, Dec 5, 2013 at 2:50 PM, Minkyu Kang <mk7.kang at samsung.com> wrote:
> Dear Leela Krishna Amudala,
>
> On 12/11/13 19:04, Leela Krishna Amudala wrote:
>> The current pmic i2c code assumes the current i2c bus is
>> the same as the pmic device's bus. There is nothing ensuring
>> that to be true. Therefore, select the proper bus before performing
>> a transaction.
>>
>> Signed-off-by: Aaron Durbin <adurbin at chromium.org>
>> Signed-off-by: Simon Glass <sjg at chromium.org>
>> Signed-off-by: Leela Krishna Amudala <l.krishna at samsung.com>
>> Reviewed-by: Doug Anderson <dianders at google.com>
>> Acked-by: Simon Glass <sjg at chromium.org>
>> ---
>>  drivers/power/power_i2c.c |   62 +++++++++++++++++++++++++++++++++++++++++----
>>  1 file changed, 57 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/power/power_i2c.c b/drivers/power/power_i2c.c
>> index ac76870..3cafa4d 100644
>> --- a/drivers/power/power_i2c.c
>> +++ b/drivers/power/power_i2c.c
>> @@ -16,9 +16,45 @@
>>  #include <i2c.h>
>>  #include <compiler.h>
>>
>> +static int pmic_select(struct pmic *p)
>> +{
>> +     int ret, old_bus;
>
> I think, old prefix is meaningless.
> please fix it globally.
>

I think, it is necessary to differentiate with the current bus.
Please see my below commets for clear picture.

>> +
>> +     old_bus = i2c_get_bus_num();
>> +     if (old_bus != p->bus) {
>
> How about return immediately if get a bus.
>
> if (old_bus == p->bus)
>         return old_bus;
>

The current code is also doing the same but in other way.
If old_bus != p->bus then set the new bus otherwise no code to execute
and return old_bus.
This is same as what you suggested.

>> +             debug("%s: Select bus %d\n", __func__, p->bus);
>> +             ret = i2c_set_bus_num(p->bus);
>> +             if (ret) {
>> +                     debug("%s: Cannot select pmic %s, err %d\n",
>> +                           __func__, p->name, ret);
>> +                     return -1;
>> +             }
>> +     }
>> +
>> +     return old_bus;
>> +}
>> +
>> +static int pmic_deselect(int old_bus)
>
> in your patch, you never check a return value.
> then is it void function or wrong usage?
>

Okay, I'll change the function return type.

> And I think pmic_deselect function is almost same with pmic_select.
> If you change the parameter for pmic_select to "int bus" then,
> What is different with pmic_select?
>
> for example.
>
> bus = pmic_select(p->bus);
> /* do something */
> pmic_deselect(bus);
>
> is same with.
>
> bus = pmic_select(p->bus);
> /* do something */
> pmic_select(bus);
>
> How do you think?
>

Yes, pmic_deselect is almost same as pmic_select but there is a minor
difference.

pmic_select() is used to set new bus and this function returns the old
bus number. we will hold this old_bus number and once we are done with
our work we have to restore the old_bus so we are passing old_bus to
pmic_deselect()

Now, pmic_deselect() takes old_bus as argument and trying to set it.
This function won't return any bus number.

Hope this explanation helps.

>> +{
>> +     int ret;
>> +
>> +     if (old_bus != i2c_get_bus_num()) {
>> +             ret = i2c_set_bus_num(old_bus);
>> +             debug("%s: Select bus %d\n", __func__, old_bus);
>> +             if (ret) {
>> +                     debug("%s: Cannot restore i2c bus, err %d\n",
>> +                           __func__, ret);
>> +                     return -1;
>> +             }
>> +     }
>> +
>> +     return 0;
>> +}
>> +
>>  int pmic_reg_write(struct pmic *p, u32 reg, u32 val)
>>  {
>>       unsigned char buf[4] = { 0 };
>> +     int ret, old_bus;
>>
>>       if (check_reg(p, reg))
>>               return -1;
>> @@ -52,23 +88,33 @@ int pmic_reg_write(struct pmic *p, u32 reg, u32 val)
>>               return -1;
>>       }
>>
>> -     if (i2c_write(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num))
>> +     old_bus = pmic_select(p);
>> +     if (old_bus < 0)
>>               return -1;
>>
>> -     return 0;
>> +     ret = i2c_write(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num);
>> +     pmic_deselect(old_bus);
>
> please add blank line.
>

Okay, will do it.

>> +     return ret;
>>  }
>>
>>  int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
>>  {
>>       unsigned char buf[4] = { 0 };
>>       u32 ret_val = 0;
>> +     int ret, old_bus;
>>
>>       if (check_reg(p, reg))
>>               return -1;
>>
>> -     if (i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num))
>> +     old_bus = pmic_select(p);
>> +     if (old_bus < 0)
>>               return -1;
>>
>> +     ret = i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num);
>> +     pmic_deselect(old_bus);
>> +     if (ret)
>> +             return ret;
>> +
>>       switch (pmic_i2c_tx_num) {
>>       case 3:
>>               if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG)
>> @@ -98,9 +144,15 @@ int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
>>
>>  int pmic_probe(struct pmic *p)
>>  {
>> -     i2c_set_bus_num(p->bus);
>> +     int ret, old_bus;
>> +
>> +     old_bus = pmic_select(p);
>> +     if (old_bus < 0)
>> +             return -1;
>
> please add blank line.
>

Okay, will do it.

Best Wishes,
Leela Krishna.

>>       debug("Bus: %d PMIC:%s probed!\n", p->bus, p->name);
>> -     if (i2c_probe(pmic_i2c_addr)) {
>> +     ret = i2c_probe(pmic_i2c_addr);
>> +     pmic_deselect(old_bus);
>> +     if (ret) {
>>               printf("Can't find PMIC:%s\n", p->name);
>>               return -1;
>>       }
>>
>
> Thanks,
> Minkyu Kang.
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot


More information about the U-Boot mailing list