Hi, On Mon, Nov 03, 2008 at 12:56:16AM +0300, Sergei Shtylyov wrote: > >+ val &= ~( ~bitval << offset ); /* unset bit if bitval == 0 */ > > > > If bitval == 0, ~bitval evaluates to all ones, and the final AND mask > ~(0xffffffff << offset) clears 32-offset MSBs. What you want is simply > ~(1 << offset). Right, I messed up boolean and bitwise inverting. The correct line is: | val &= ~(!bitval << offset); /* unset bit if bitval == 0 */ That's the same as ~(1 << offset) when bitval is zero, but turns into a no op when it's one. That's what I want here, successfully removing the need for the if-else case. > >@@ -176,117 +184,60 @@ static int rb532_gpio_direction_input(struct > >gpio_chip *chip, unsigned offset) > > static int rb532_gpio_direction_output(struct gpio_chip *chip, > > unsigned offset, int value) > > { > >- unsigned long flags; > >- u32 mask = 1 << offset; > >- u32 tmp; > > struct rb532_gpio_chip *gpch; > >- void __iomem *gpdr; > > > > gpch = container_of(chip, struct rb532_gpio_chip, chip); > >- writel(mask, gpch->regbase + GPIOD); > > > > Hm, the old code seems really borked here... It's not as bad as this may look like. In fact I could just simplify lots of the functions by having them call rb532_set_bit(). A patch fixing the above mentioned issue follows, thanks for your help! Greetings, Phil