diff mbox

[5/7] ASoC: wm5100: remove bitwise operations involving GPIO level value

Message ID 1433200158-6890-5-git-send-email-vz@mleia.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vladimir Zapolskiy June 1, 2015, 11:09 p.m. UTC
The main intention of the change is to remove bitwise operations on
GPIO level value as a preceding change before updating gpiolib
callbacks to utilize bool type to represent GPIO level.

No functional change.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Cc: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Axel Lin <axel.lin@ingics.com>
Cc: patches@opensource.wolfsonmicro.com
---
 sound/soc/codecs/wm5100.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

Comments

Charles Keepax June 2, 2015, 8:40 a.m. UTC | #1
On Tue, Jun 02, 2015 at 02:09:16AM +0300, Vladimir Zapolskiy wrote:
> The main intention of the change is to remove bitwise operations on
> GPIO level value as a preceding change before updating gpiolib
> callbacks to utilize bool type to represent GPIO level.
> 
> No functional change.
> 
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> Cc: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Axel Lin <axel.lin@ingics.com>
> Cc: patches@opensource.wolfsonmicro.com
> ---

Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>

Thanks,
Charles
Mark Brown June 2, 2015, 7:45 p.m. UTC | #2
On Tue, Jun 02, 2015 at 02:09:16AM +0300, Vladimir Zapolskiy wrote:

> @@ -2244,26 +2244,27 @@ static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
>  static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
>  {
>  	struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
> +	unsigned int val = 0;
> +
> +	if (value)
> +		val = 0x1 << WM5100_GP1_LVL_SHIFT;

Write this as an if/else so the reader doesn't have to wonder why you've
missed the handling of the false case.
Vladimir Zapolskiy June 2, 2015, 8:23 p.m. UTC | #3
Hello Mark,

On 02.06.2015 22:45, Mark Brown wrote:
> On Tue, Jun 02, 2015 at 02:09:16AM +0300, Vladimir Zapolskiy wrote:
> 
>> @@ -2244,26 +2244,27 @@ static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
>>  static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
>>  {
>>  	struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
>> +	unsigned int val = 0;
>> +
>> +	if (value)
>> +		val = 0x1 << WM5100_GP1_LVL_SHIFT;
> 
> Write this as an if/else so the reader doesn't have to wonder why you've
> missed the handling of the false case.  
> 

the only objection I have is that the resulting code will be two lines
longer. If you think this code is not clear enough (is "val" vs. "value"
misleading?), I'll change the rest of my patches, which contain the same
logic structure, please let me know.

--
With best wishes,
Vladimir
Mark Brown June 2, 2015, 8:36 p.m. UTC | #4
On Tue, Jun 02, 2015 at 11:23:41PM +0300, Vladimir Zapolskiy wrote:
> On 02.06.2015 22:45, Mark Brown wrote:
> > On Tue, Jun 02, 2015 at 02:09:16AM +0300, Vladimir Zapolskiy wrote:

> >> +	unsigned int val = 0;
> >> +
> >> +	if (value)
> >> +		val = 0x1 << WM5100_GP1_LVL_SHIFT;

> > Write this as an if/else so the reader doesn't have to wonder why you've
> > missed the handling of the false case.  

> the only objection I have is that the resulting code will be two lines
> longer. If you think this code is not clear enough (is "val" vs. "value"
> misleading?), I'll change the rest of my patches, which contain the same
> logic structure, please let me know.

Especially after the unrelated style change thing earlier on (which
meant I was reading things more carefully than usual) it'd be good to
make things as clear as possible - you're right that the val vs value
thing isn't helping either.  

Like I say I am a bit surprised that the int/bool conversion doesn't do
the right thing without any code changes other than the type of the
parameter but ICBW, I didn't actually check.
Vladimir Zapolskiy June 2, 2015, 8:58 p.m. UTC | #5
Hello Mark,

On 02.06.2015 23:36, Mark Brown wrote:
> On Tue, Jun 02, 2015 at 11:23:41PM +0300, Vladimir Zapolskiy wrote:
>> On 02.06.2015 22:45, Mark Brown wrote:
>>> On Tue, Jun 02, 2015 at 02:09:16AM +0300, Vladimir Zapolskiy wrote:
> 
>>>> +	unsigned int val = 0;
>>>> +
>>>> +	if (value)
>>>> +		val = 0x1 << WM5100_GP1_LVL_SHIFT;
> 
>>> Write this as an if/else so the reader doesn't have to wonder why you've
>>> missed the handling of the false case.  
> 
>> the only objection I have is that the resulting code will be two lines
>> longer. If you think this code is not clear enough (is "val" vs. "value"
>> misleading?), I'll change the rest of my patches, which contain the same
>> logic structure, please let me know.
> 
> Especially after the unrelated style change thing earlier on (which
> meant I was reading things more carefully than usual) it'd be good to
> make things as clear as possible - you're right that the val vs value
> thing isn't helping either.  

got your concern, will send an update.

> Like I say I am a bit surprised that the int/bool conversion doesn't do
> the right thing without any code changes other than the type of the
> parameter but ICBW, I didn't actually check.
> 

My tested compilers do the work right, but I can not be sure about the
whole variety of compilers, well, probably I should just follow the
standard, which in turn is expected to be quite volatile in future
revisions regarding usage of "_Bool" or future "bool" type.

If we assume the preferred Linux kernel style to use true/false
constants for boolean variables only (see the reference to
bool{init,return}.cocci), then even if bitwise and arithmetic operations
on bool type are understandable to a compiler, but probably "false <<
true" (or whatever is hidden under a variable name) is not quite
aesthetic for a human eye. This is not a technical argument though, and
I'm not sure if any clear code style policy related to the case is agreed.

--
With best wishes,
Vladimir
Trent Piepho June 3, 2015, 10:50 a.m. UTC | #6
On Tue, Jun 2, 2015 at 1:23 PM, Vladimir Zapolskiy <vz@mleia.com> wrote:

> Hello Mark,
>
> On 02.06.2015 22:45, Mark Brown wrote:
> > On Tue, Jun 02, 2015 at 02:09:16AM +0300, Vladimir Zapolskiy wrote:
> >
> >> @@ -2244,26 +2244,27 @@ static inline struct wm5100_priv
> *gpio_to_wm5100(struct gpio_chip *chip)
> >>  static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset,
> int value)
> >>  {
> >>      struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
> >> +    unsigned int val = 0;
> >> +
> >> +    if (value)
> >> +            val = 0x1 << WM5100_GP1_LVL_SHIFT;
> >
> > Write this as an if/else so the reader doesn't have to wonder why you've
> > missed the handling of the false case.
> >
>
> the only objection I have is that the resulting code will be two lines
> longer. If you think this code is not clear enough (is "val" vs. "value"
> misleading?), I'll change the rest of my patches, which contain the same
> logic structure, please let me know.
>

const unsigned int val = value ?  (0x1 << WM5100_GP1_LVL_SHIFT) : 0;

Two lines shorter....

Have you measured the effect of going from int to bool on code size and
speed?  Clearly, the C code is getting longer as '!!' is transformed into
an if-then-else to set a new scratch variable.  But the compiler likely
converts both to a conditional branch or cmov type instruction.  What I
wonder is if converting gpiolib to use bools instead of ints is better just
because someone likes it more that way or if there are objective metrics
that show improvement.

BTW, with a little C algebra:
const unsigned int val = value ?  0x1 << WM5100_GP1_LVL_SHIFT : 0;
const unsigned int val = (value ?  0x1 : 0) << WM5100_GP1_LVL_SHIFT;
const unsigned int val = (!!value) << WM5100_GP1_LVL_SHIFT;  // definition
of ! operator

And now we're back to where we started, so I don't really see why this is
even necessary.  The semantics of the ! operator will be changed in a
future C version?
Mark Brown June 3, 2015, 11:07 a.m. UTC | #7
On Wed, Jun 03, 2015 at 03:50:04AM -0700, Trent Piepho wrote:

> BTW, with a little C algebra:
> const unsigned int val = value ?  0x1 << WM5100_GP1_LVL_SHIFT : 0;
> const unsigned int val = (value ?  0x1 : 0) << WM5100_GP1_LVL_SHIFT;
> const unsigned int val = (!!value) << WM5100_GP1_LVL_SHIFT;  // definition
> of ! operator

> And now we're back to where we started, so I don't really see why this is
> even necessary.  The semantics of the ! operator will be changed in a
> future C version?

Yes, this is exactly the point I was trying to make.
Vladimir Zapolskiy June 3, 2015, 7:13 p.m. UTC | #8
Hello Mark, Trent,

thank you for review.

On 03.06.2015 13:50, Trent Piepho wrote:
> On Tue, Jun 2, 2015 at 1:23 PM, Vladimir Zapolskiy <vz@mleia.com
> <mailto:vz@mleia.com>> wrote:
> 
>     Hello Mark,
> 
>     On 02.06.2015 22:45, Mark Brown wrote:
>     > On Tue, Jun 02, 2015 at 02:09:16AM +0300, Vladimir Zapolskiy wrote:
>     >
>     >> @@ -2244,26 +2244,27 @@ static inline struct wm5100_priv
>     *gpio_to_wm5100(struct gpio_chip *chip)
>     >>  static void wm5100_gpio_set(struct gpio_chip *chip, unsigned
>     offset, int value)
>     >>  {
>     >>      struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
>     >> +    unsigned int val = 0;
>     >> +
>     >> +    if (value)
>     >> +            val = 0x1 << WM5100_GP1_LVL_SHIFT;
>     >
>     > Write this as an if/else so the reader doesn't have to wonder why
>     you've
>     > missed the handling of the false case.
>     >
> 
>     the only objection I have is that the resulting code will be two lines
>     longer. If you think this code is not clear enough (is "val" vs. "value"
>     misleading?), I'll change the rest of my patches, which contain the same
>     logic structure, please let me know.
> 
> 
> const unsigned int val = value ?  (0x1 << WM5100_GP1_LVL_SHIFT) : 0;
> 
> Two lines shorter....
> 
> Have you measured the effect of going from int to bool on code size and
> speed?  Clearly, the C code is getting longer as '!!' is transformed
> into an if-then-else to set a new scratch variable.  But the compiler
> likely converts both to a conditional branch or cmov type instruction. 
> What I wonder is if converting gpiolib to use bools instead of ints is
> better just because someone likes it more that way or if there are
> objective metrics that show improvement.
> 
> BTW, with a little C algebra:
> const unsigned int val = value ?  0x1 << WM5100_GP1_LVL_SHIFT : 0;
> const unsigned int val = (value ?  0x1 : 0) << WM5100_GP1_LVL_SHIFT;
> const unsigned int val = (!!value) << WM5100_GP1_LVL_SHIFT;  //
> definition of ! operator
> 
> And now we're back to where we started, so I don't really see why this
> is even necessary.  The semantics of the ! operator will be changed in a
> future C version?

I don't think it makes sense to discuss technical aspects of the
proposed change, as I mentioned in the discussion yesterday I see no
technical issues at this point, and my changes are described as
nonfunctional.

The _nontechnical_ problem I see (well, may be I'm just blowing it up)
is a Linux kernel code style policy problem, to my knowledge the policy
of using bitwise and arithmetic operations on bool type variables and
constants is not defined, and since the policy is not yet defined I'm
glad to take part in its discussion now.

As an example of one related policy is change of 0/1 constants to
false/true, when they are attended by bool type, see c2b49ae678b ,
5c216cc3f37 , 7eef08554ca , bool{init,return}.cocci etc.

One may say that the changes above has no value (however it might be
related to ABI treatment of _Bool/bool), personally I agree with this
accepted code policy.

Another code policy question is to which degree arithmetic and bitwise
operations on bool variables and constants are acceptable. In my
personal opinion arithmetic and bitwise operations on bool variables are
quite undesired, that's why I attempt to replace them in advance in some
sound/soc/codecs/* functions before changing the type of input variable
representing GPIO level from int to bool. I guess in your personal
opinion this proposed change has no technical sense, I respect your
opinion and do not insist on my answer to the policy.

My little deal is to let you know that there is another opinion on the
subject and send you the changes for review and ack/nak verdict.

--
With best wishes,
Vladimir
Trent Piepho June 3, 2015, 9:51 p.m. UTC | #9
On Wed, Jun 3, 2015 at 12:13 PM, Vladimir Zapolskiy <vz@mleia.com> wrote:
>>
>> BTW, with a little C algebra:
>> const unsigned int val = value ?  0x1 << WM5100_GP1_LVL_SHIFT : 0;
>> const unsigned int val = (value ?  0x1 : 0) << WM5100_GP1_LVL_SHIFT;
>> const unsigned int val = (!!value) << WM5100_GP1_LVL_SHIFT;  //
>> definition of ! operator
>>
>> And now we're back to where we started, so I don't really see why this
>> is even necessary.  The semantics of the ! operator will be changed in a
>> future C version?
>
> I don't think it makes sense to discuss technical aspects of the
> proposed change, as I mentioned in the discussion yesterday I see no
> technical issues at this point, and my changes are described as
> nonfunctional.
>
> The _nontechnical_ problem I see (well, may be I'm just blowing it up)
> is a Linux kernel code style policy problem, to my knowledge the policy
> of using bitwise and arithmetic operations on bool type variables and
> constants is not defined, and since the policy is not yet defined I'm
> glad to take part in its discussion now.

I don't believe this is the case.  From C99, section 6.5.3.3, paragraph 5:

The result of the logical negation operator ! is 0 if the value of its
operand compares unequal to 0,  1 if the value of its operand compares
equal to 0. The result has type int.

Thus, it's defined that !!(bool_var) and !!(int_var) will return an
int that is either 0 or 1.  This has always been part of the C
standard and I have a very hard time believing that a future standard
will change that.  It would break so much code to do so and I don't
the case for what it will improve.

So I don't see the point in changing:
!!value << SHIFT;
into:
unsigned int temp_val;
if (value)
   temp_val = 1 << SHIFT;
else
   temp_val = 0;

The former is shorter and simpler and completely defined by the C standard.
Vladimir Zapolskiy June 3, 2015, 10:58 p.m. UTC | #10
Hello Trent,

On 04.06.2015 00:51, Trent Piepho wrote:
> On Wed, Jun 3, 2015 at 12:13 PM, Vladimir Zapolskiy <vz@mleia.com> wrote:
>>>
>>> BTW, with a little C algebra:
>>> const unsigned int val = value ?  0x1 << WM5100_GP1_LVL_SHIFT : 0;
>>> const unsigned int val = (value ?  0x1 : 0) << WM5100_GP1_LVL_SHIFT;
>>> const unsigned int val = (!!value) << WM5100_GP1_LVL_SHIFT;  //
>>> definition of ! operator
>>>
>>> And now we're back to where we started, so I don't really see why this
>>> is even necessary.  The semantics of the ! operator will be changed in a
>>> future C version?
>>
>> I don't think it makes sense to discuss technical aspects of the
>> proposed change, as I mentioned in the discussion yesterday I see no
>> technical issues at this point, and my changes are described as
>> nonfunctional.
>>
>> The _nontechnical_ problem I see (well, may be I'm just blowing it up)
>> is a Linux kernel code style policy problem, to my knowledge the policy
>> of using bitwise and arithmetic operations on bool type variables and
>> constants is not defined, and since the policy is not yet defined I'm
>> glad to take part in its discussion now.
> 
> I don't believe this is the case.

please excuse me for possible misunderstanding, you don't believe that
I'm interested in discussing a _nontechnical_ problem stated above?

>  From C99, section 6.5.3.3, paragraph 5:

C99 is a strict superset over Linux coding style (e.g. remember //
comments or "register" specifier), so let's forget about.

--
With best wishes,
Vladimir
diff mbox

Patch

diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 4c10cd8..fae9d13 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2244,26 +2244,27 @@  static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
 static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
 	struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
+	unsigned int val = 0;
+
+	if (value)
+		val = 0x1 << WM5100_GP1_LVL_SHIFT;
 
 	regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
-			   WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
+			   WM5100_GP1_LVL, val);
 }
 
 static int wm5100_gpio_direction_out(struct gpio_chip *chip,
 				     unsigned offset, int value)
 {
 	struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
-	int val, ret;
+	unsigned int val = 0x1 << WM5100_GP1_FN_SHIFT;
 
-	val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
+	if (value)
+		val |= 0x1 << WM5100_GP1_LVL_SHIFT;
 
-	ret = regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
-				 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
-				 WM5100_GP1_LVL, val);
-	if (ret < 0)
-		return ret;
-	else
-		return 0;
+	return regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
+				  WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
+				  WM5100_GP1_LVL, val);
 }
 
 static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)