On Sat, Feb 25, 2012 at 6:34 PM, Russell King - ARM Linux
<[email protected]> wrote:
> Can someone explain to me this:
>
> #define GPIO_INDEX(bank, gpio) (gpio % bank->width)
> #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
>
> static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
> {
> void __iomem *reg = bank->base + bank->regs->datain;
>
> return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
> }
>
> static int gpio_get(struct gpio_chip *chip, unsigned offset)
> {
> struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
> void __iomem *reg = bank->base;
> int gpio = chip->base + offset;
> u32 mask = GPIO_BIT(bank, gpio);
>
> if (gpio_is_input(bank, mask))
> return _get_gpio_datain(bank, gpio);
> else
> return _get_gpio_dataout(bank, gpio);
> }
>
> Given that bank->width on OMAP is either 32 or 16, and GPIO numbers for
> any GPIO chip are always aligned to 32 or 16, why does this code bother
> adding the chips base gpio number and then modulo the width?
As far as I understand we could very well use offset directly.
The macro is used to derive the same offset value in this case.
Therefore, _get_gpio_datain(bank, gpio) and _get_gpio_dataout(bank, gpio)
can be passed offset instead of (bank->base + offset) as suggested by you below.
And of course, offset can be used to derive mask both here and in the
called functions.
>
> Surely this means if - for argument sake - you registered a GPIO chip
> with 8 lines followed by one with 16 lines, GPIO0..7 would be chip 0
> bit 0..7, GPIO8..15 would be chip 1 bit 8..15, GPIO16..23 would be
> chip 1 bit 0..7.
>
> However, if you registered a GPIO chip with 16 lines first, it would
> mean GPIO0..15 would be chip 0 bit 0..15, and GPIO16..31 would be
> chip 1 bit 0..15.
>
> Surely this kind of behaviour is not intended?
>
> Is there a reason why the bitmask can't just be (1 << offset) where
> offset is passed into these functions as GPIO number - chip->base ?
Yes, I have made the following changes and tested on OMAP4 and OMAP1(bootup).
[PATCH] gpio/omap: remove redundant decoding of gpio offset
---
drivers/gpio/gpio-omap.c | 18 +++++++-----------
1 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 5953ece..2196747 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -133,18 +133,18 @@ static void _set_gpio_dataout_mask(struct
gpio_bank *bank, int gpio, int enable)
bank->context.dataout = l;
}
-static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
+static int _get_gpio_datain(struct gpio_bank *bank, int offset)
{
void __iomem *reg = bank->base + bank->regs->datain;
- return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
+ return (__raw_readl(reg) & (1 << offset)) != 0;
}
-static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
+static int _get_gpio_dataout(struct gpio_bank *bank, int offset)
{
void __iomem *reg = bank->base + bank->regs->dataout;
- return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
+ return (__raw_readl(reg) & (1 << offset)) != 0;
}
static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
@@ -849,19 +849,15 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
static int gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct gpio_bank *bank;
- void __iomem *reg;
- int gpio;
u32 mask;
- gpio = chip->base + offset;
bank = container_of(chip, struct gpio_bank, chip);
- reg = bank->base;
- mask = GPIO_BIT(bank, gpio);
+ mask = (1 << offset);
if (gpio_is_input(bank, mask))
- return _get_gpio_datain(bank, gpio);
+ return _get_gpio_datain(bank, offset);
else
- return _get_gpio_dataout(bank, gpio);
+ return _get_gpio_dataout(bank, offset);
}
static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
--
1.7.0.4
--
Tarun
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html