Skip to content

Commit

Permalink
Galland: Bugfix sram_gpio_init for RK3066 when called for RK30_PIN6_*
Browse files Browse the repository at this point in the history
sram_gpio_init is called from mach-rk30/board-pmu-tps65910.c with
PMU_POWER_SLEEP (RK30_PIN6_PB1) as first argument. The return is -EINVAL
even though it's a valid pin.

This is caused, in rk3066, by the bad way in which sram_gpio_init checks
against the gpio_base array, taking into account that for RK3066 this
array is missing one element (RK30_GPIO5_BASE, which is ok). This makes
it give wrong results for any pin on GPIO6_BASE, because of this
comparison:
       if(index/NUM_GROUP >= ARRAY_SIZE(gpio_base))

For example:
PMU_POWER_SLEEP = RK30_PIN6_PB1 = 361

Taking the previous line's index calc: index = gpio - PIN_BASE;
Knowing that:
- #define PIN_BASE         NR_GIC_IRQS
- #define NR_GIC_IRQS      (5 * 32)

index = gpio - PIN_BASE = 361 - 5*32 = 201

and then in the if we have:
-  index/NUM_GROUP = 201 / 32 = 6.2 ... = 6
-  ARRAY_SIZE(gpio_base) = 6

which is == to ARRAY_SIZE so RK30_PIN6_* fail here
due to using array_size without a RK30_GPIO5_BASE

Solution entails failing on pins in GPIO5_BASE, but allowing them in
GPIO6, and then pressing the right base into data->base by using index 5
for GPIO6, as expected.

Signed-off-by: Omegamoon <[email protected]>
  • Loading branch information
omegamoon committed Sep 30, 2013
1 parent 3823699 commit 80096fc
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions arch/arm/plat-rk/sram.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,23 @@ int sram_gpio_init(int gpio, struct sram_gpio_data *data)
if(gpio == INVALID_GPIO)
return -EINVAL;
index = gpio - PIN_BASE;
if(index/NUM_GROUP >= ARRAY_SIZE(gpio_base))
return -EINVAL;

data->base = gpio_base[index/NUM_GROUP];
#if !defined(CONFIG_ARCH_RK30)
if(index/NUM_GROUP >= ARRAY_SIZE(gpio_base))
return -EINVAL;

data->base = gpio_base[index/NUM_GROUP];
#else
//Galland: RK30_GPIO5_BASE is missing from gpio_base array,
// so this fails on any pin on RK30_PIN6_* (like PMU_POWER_SLEEP)
if(index/NUM_GROUP > ARRAY_SIZE(gpio_base) && index/NUM_GROUP != 5)
return -EINVAL;

//Galland: RK30_GPIO6_BASE takes the place of GPIO5 in the gpio_base array
// (but index/NUM_GROUP=6, so adjust to point to index 5)
data->base = gpio_base[((index/NUM_GROUP)==6?5:(index/NUM_GROUP))];
#endif

if(data->base == 0)
return -EINVAL;

Expand Down

0 comments on commit 80096fc

Please sign in to comment.