Patchwork [v2] qe_lib: Set gpio data before changing the direction to output

login
register
mail settings
Submitter Michael Barkowski
Date Aug. 18, 2009, 9:20 p.m.
Message ID <4A8B1B2C.5090606@ruggedcom.com>
Download mbox | patch
Permalink /patch/31590/
State Accepted, archived
Commit 1dcd8ffc81e80a170625883f63f6a5db3cd0428d
Delegated to: Kumar Gala
Headers show

Comments

Michael Barkowski - Aug. 18, 2009, 9:20 p.m.
This avoids having a short glitch if the desired initial value is not
the same as what was previously in the data register.

Signed-off-by: Michael Barkowski <michaelbarkowski@ruggedcom.com>
---
Anton Vorontsov wrote:
> There is a recursive locking bug: _set() takes the same spinlock.
> So you'd better move this call two lines upper. Otherwise the
> patch looks OK.
> 
> Thanks!

Thanks - here is v2.

 arch/powerpc/sysdev/qe_lib/gpio.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
Anton Vorontsov - Aug. 18, 2009, 9:33 p.m.
On Tue, Aug 18, 2009 at 05:20:44PM -0400, Michael Barkowski wrote:
> This avoids having a short glitch if the desired initial value is not
> the same as what was previously in the data register.
> 
> Signed-off-by: Michael Barkowski <michaelbarkowski@ruggedcom.com>

Acked-by: Anton Vorontsov <avorontsov@ru.mvista.com>

Thanks!

> ---
> Anton Vorontsov wrote:
> > There is a recursive locking bug: _set() takes the same spinlock.
> > So you'd better move this call two lines upper. Otherwise the
> > patch looks OK.
> > 
> > Thanks!
> 
> Thanks - here is v2.
> 
>  arch/powerpc/sysdev/qe_lib/gpio.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c
> index 3485288..8e7a776 100644
> --- a/arch/powerpc/sysdev/qe_lib/gpio.c
> +++ b/arch/powerpc/sysdev/qe_lib/gpio.c
> @@ -105,14 +105,14 @@ static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>  	struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
>  	unsigned long flags;
>  
> +	qe_gpio_set(gc, gpio, val);
> +
>  	spin_lock_irqsave(&qe_gc->lock, flags);
>  
>  	__par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0);
>  
>  	spin_unlock_irqrestore(&qe_gc->lock, flags);
>  
> -	qe_gpio_set(gc, gpio, val);
> -
>  	return 0;
>  }
>  
> -- 
> 1.6.3.3
>
Timur Tabi - Aug. 18, 2009, 10:33 p.m.
Anton Vorontsov wrote:
> On Tue, Aug 18, 2009 at 05:20:44PM -0400, Michael Barkowski wrote:
>> This avoids having a short glitch if the desired initial value is not
>> the same as what was previously in the data register.
>>
>> Signed-off-by: Michael Barkowski <michaelbarkowski@ruggedcom.com>
> 
> Acked-by: Anton Vorontsov <avorontsov@ru.mvista.com>

I don't have the time to test this patch, so I abstain from acking. :-)  If Anton likes it, that's good enough for me.
Anton Vorontsov - Aug. 18, 2009, 10:56 p.m.
On Tue, Aug 18, 2009 at 05:33:00PM -0500, Timur Tabi wrote:
> Anton Vorontsov wrote:
> > On Tue, Aug 18, 2009 at 05:20:44PM -0400, Michael Barkowski wrote:
> >> This avoids having a short glitch if the desired initial value is not
> >> the same as what was previously in the data register.
> >>
> >> Signed-off-by: Michael Barkowski <michaelbarkowski@ruggedcom.com>
> > 
> > Acked-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> 
> I don't have the time to test this patch, so I abstain from acking. :-)
> If Anton likes it, that's good enough for me.

You made me doubt for a moment. :-) Thanks for the suspiciousness.

What happens if a pin was previously configured as input? Does our
write to the data register survive? For MPC8xxx GPIO controllers
it does. And randomly taken QE spec says:

  A write to CPDAT is latched, and if the corresponding CPDIR
  bits have configured the port pin as an output, the latched
  value is driven onto the respective pin. However, if the
  corresponding CPDIR bits have configured the port pin as an
  input, the latched value is prevented from reaching the pin.

I guess we're safe, but Michael, could you actually test it
(if not already)?

Thanks!
Michael Barkowski - Aug. 19, 2009, 1:30 p.m.
Anton Vorontsov wrote:
> On Tue, Aug 18, 2009 at 05:33:00PM -0500, Timur Tabi wrote:
>> Anton Vorontsov wrote:
>>> On Tue, Aug 18, 2009 at 05:20:44PM -0400, Michael Barkowski wrote:
>>>> This avoids having a short glitch if the desired initial value is not
>>>> the same as what was previously in the data register.
>>>>
>>>> Signed-off-by: Michael Barkowski <michaelbarkowski@ruggedcom.com>
>>> Acked-by: Anton Vorontsov <avorontsov@ru.mvista.com>
>> I don't have the time to test this patch, so I abstain from acking. :-)
>> If Anton likes it, that's good enough for me.
> 
> You made me doubt for a moment. :-) Thanks for the suspiciousness.
> 
> What happens if a pin was previously configured as input? Does our
> write to the data register survive? For MPC8xxx GPIO controllers
> it does. And randomly taken QE spec says:
> 
>   A write to CPDAT is latched, and if the corresponding CPDIR
>   bits have configured the port pin as an output, the latched
>   value is driven onto the respective pin. However, if the
>   corresponding CPDIR bits have configured the port pin as an
>   input, the latched value is prevented from reaching the pin.
> 
> I guess we're safe, but Michael, could you actually test it
> (if not already)?
> 

I had tested it before with the pin initially configured as "disabled".

I have now also tested it with the pin initially configured as "input".

The value written to CPDAT seems to survive and is driven onto the pin
once CPDIR is changed to 1, just as noted in the spec.

Tested on 8360, by probing with a logic analyzer.

There are lots of users of this code.  I understand if you'd like it to
stay open for testing by others.
Anton Vorontsov - Aug. 19, 2009, 1:32 p.m.
On Wed, Aug 19, 2009 at 09:30:20AM -0400, Michael Barkowski wrote:
> Anton Vorontsov wrote:
> > On Tue, Aug 18, 2009 at 05:33:00PM -0500, Timur Tabi wrote:
> >> Anton Vorontsov wrote:
> >>> On Tue, Aug 18, 2009 at 05:20:44PM -0400, Michael Barkowski wrote:
> >>>> This avoids having a short glitch if the desired initial value is not
> >>>> the same as what was previously in the data register.
> >>>>
> >>>> Signed-off-by: Michael Barkowski <michaelbarkowski@ruggedcom.com>
> >>> Acked-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> >> I don't have the time to test this patch, so I abstain from acking. :-)
> >> If Anton likes it, that's good enough for me.
> > 
> > You made me doubt for a moment. :-) Thanks for the suspiciousness.
> > 
> > What happens if a pin was previously configured as input? Does our
> > write to the data register survive? For MPC8xxx GPIO controllers
> > it does. And randomly taken QE spec says:
> > 
> >   A write to CPDAT is latched, and if the corresponding CPDIR
> >   bits have configured the port pin as an output, the latched
> >   value is driven onto the respective pin. However, if the
> >   corresponding CPDIR bits have configured the port pin as an
> >   input, the latched value is prevented from reaching the pin.
> > 
> > I guess we're safe, but Michael, could you actually test it
> > (if not already)?
> > 
> 
> I had tested it before with the pin initially configured as "disabled".
> 
> I have now also tested it with the pin initially configured as "input".
> 
> The value written to CPDAT seems to survive and is driven onto the pin
> once CPDIR is changed to 1, just as noted in the spec.
> 
> Tested on 8360, by probing with a logic analyzer.

Great, thanks a lot! I think the patch is perfect.
Kumar Gala - Aug. 25, 2009, 2:44 p.m.
On Aug 18, 2009, at 4:20 PM, Michael Barkowski wrote:

> This avoids having a short glitch if the desired initial value is not
> the same as what was previously in the data register.
>
> Signed-off-by: Michael Barkowski <michaelbarkowski@ruggedcom.com>
> ---
> Anton Vorontsov wrote:
>> There is a recursive locking bug: _set() takes the same spinlock.
>> So you'd better move this call two lines upper. Otherwise the
>> patch looks OK.
>>
>> Thanks!
>
> Thanks - here is v2.
>
> arch/powerpc/sysdev/qe_lib/gpio.c |    4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)


applied to next.

- k

Patch

diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c
index 3485288..8e7a776 100644
--- a/arch/powerpc/sysdev/qe_lib/gpio.c
+++ b/arch/powerpc/sysdev/qe_lib/gpio.c
@@ -105,14 +105,14 @@  static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 	struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
 	unsigned long flags;
 
+	qe_gpio_set(gc, gpio, val);
+
 	spin_lock_irqsave(&qe_gc->lock, flags);
 
 	__par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0);
 
 	spin_unlock_irqrestore(&qe_gc->lock, flags);
 
-	qe_gpio_set(gc, gpio, val);
-
 	return 0;
 }