All of lore.kernel.org
 help / color / mirror / Atom feed
From: grinberg@compulab.co.il (Igor Grinberg)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Date: Sun, 01 Apr 2012 15:23:58 +0300	[thread overview]
Message-ID: <4F7848DE.2080605@compulab.co.il> (raw)
In-Reply-To: <1333277787.12023.YahooMailClassic@web29010.mail.ird.yahoo.com>

On 04/01/12 13:56, Paul Parsons wrote:
> Hello Igor,
> 
> --- On Sun, 1/4/12, Igor Grinberg <grinberg@compulab.co.il> wrote:
>> Hi Paul,
>>
>> On 03/31/12 15:20, Paul Parsons wrote:
>>> Some MFP configurations specify MFP_LPM_KEEP_OUTPUT to
>> preserve the gpio output
>>> value (HIGH or LOW) during sleep mode. For example:
>>>
>>>      GPIO72_GPIO |
>> MFP_LPM_KEEP_OUTPUT,
>>>
>>> Unfortunately MFP_LPM_KEEP_OUTPUT makes no special
>> provision for setting the
>>> sleep mode gpio direction, unlike MFP_LPM_DRIVE_HIGH
>> and MFP_LPM_DRIVE_LOW.
>>> Consequently MFP configurations of the form:
>>>
>>>      GPIO<n>_GPIO |
>> MFP_LPM_KEEP_OUTPUT,
>>>
>>> will set the sleep mode gpio direction to INPUT.
>>>
>>> This patch forces the sleep mode gpio direction to
>> OUTPUT in cases where
>>> MFP_LPM_KEEP_OUTPUT was specified. This brings
>> MFP_LPM_KEEP_OUTPUT into line
>>> with MFP_LPM_DRIVE_HIGH and MFP_LPM_DRIVE_LOW.
>>>
>>> Signed-off-by: Paul Parsons <lost.distance@yahoo.com>
>>> ---
>>>
>>> diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c
>> b/arch/arm/mach-pxa/mfp-pxa2xx.c
>>> index b0a8428..3b443199 100644
>>> --- a/arch/arm/mach-pxa/mfp-pxa2xx.c
>>> +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
>>> @@ -96,6 +96,9 @@ static int __mfp_config_gpio(unsigned
>> gpio, unsigned long c)
>>>           break;
>>>       }
>>>   
>>> +    if (c & MFP_LPM_KEEP_OUTPUT)
>>> +        is_out = 1;
>>> +
>>
>> MFP_LPM_KEEP_OUTPUT does not meant to be used to setup the
>> mfp config,
> 
> As far as I can see, MFP_LPM_KEEP_OUTPUT is *only* used to setup the
> mfp config:
> 
> % xzcat linux-3.4-rc1.tar.xz | fgrep -a MFP_LPM_KEEP_OUTPUT
> 	GPIO13_GPIO | MFP_LPM_KEEP_OUTPUT,	/* CORGI_GPIO_LED_ORANGE */
> 	GPIO38_GPIO | MFP_LPM_KEEP_OUTPUT,	/* CORGI_GPIO_CHRG_ON */
> 	GPIO43_GPIO | MFP_LPM_KEEP_OUTPUT,	/* CORGI_GPIO_CHRG_UKN */
> #define MFP_LPM_KEEP_OUTPUT	(0x1 << 25)
> 	/* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */
> 		if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
> % 

How can you be certain that you don't break corgi, with the proposed patch?

> 
>> but for pins that have been configured for output by
>> gpio_direction_out().
>> (Hint: *_KEEP_*).
> 
> MFP_LPM_KEEP_OUTPUT only takes effect when the system enters sleep mode,
> at which point the GPIO directions (GPDR registers) are forced from the
> values privately stored in gpdr_lpm[].

Correct, but with your patch, the direction will be forced to output,
but the value will be undefined...

> As far as I can tell MFP_LPM_KEEP_OUTPUT has no direct connection to
> gpio_direction_output().

Well, it has... in the pxa2xx_mfp_suspend() function you've pasted below.

> 
>> Also, I don't think this is a good idea, because the patch
>> allows a pin
>> be configured as output, but does not forces a value
>> (high/low)
>> and this is not safe.
> 
> A value does not need to be provided until the system enters sleep mode,
> at which point the value is provided via the PGSR registers.

Yes, but you don't force the PGSR to be set...
and that is the problem.

> 
>    353	static int pxa2xx_mfp_suspend(void)
>    354	{
>    355		int i;
>    356	
>    357		/* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */
>    358		for (i = 0; i < pxa_last_gpio; i++) {
>    359			if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
>    360			    (GPDR(i) & GPIO_bit(i))) {

Look at the check above...
the PGSR only gets set for the GPIOs configured to output
(presumably by gpio_direction_output() function).

>    361				if (GPLR(i) & GPIO_bit(i))
>    362					PGSR(gpio_to_bank(i)) |= GPIO_bit(i);
>    363				else
>    364					PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
>    365			}
>    366		}
>    367	
>    368		for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
>    369	
>         ...
>    375			GPDR(i * 32) = gpdr_lpm[i];
>    376		}
>    377		return 0;
>    378	}
> 
> However looking at pxa2xx_mfp_suspend() more closely it is true that the
> GPDR registers are set before the PGSR values take effect (when the
> processor enters sleep mode).
> That is no different from MFP_LPM_DRIVE_HIGH or MFP_LPM_DRIVE_LOW though.

Well, it is different, because the in case of MFP_LPM_DRIVE_*,
the PGSR is set in the __mfp_config_gpio() function and has a _known value_.

> So the presumption must be that the GPIOs configured as DRIVE_HIGH,
> DRIVER_LOW and now KEEP_OUTPUT already have a valid direction and value
> set at the point the GPDR registers are forced.

Yes. That is exactly my point here.
MFP_LPM_DRIVE_* has the value determined and set.
MFP_LPM_KEEP_OUTPUT does not, but with your patch it will effectively
force the GPIO to be output in sleep mode, but with no value set!

> 
>> Why can't you use:
>> GPIO<n>_GPIO | MFP_LPM_DRIVE_<level>
>> ?
> 
> The hx4700 has a couple of charging GPIOs which we want to keep HIGH or
> LOW during sleep mode:
> 
> % fgrep MFP_LPM_KEEP_OUTPUT arch/arm/mach-pxa/hx4700.c
> 	GPIO72_GPIO | MFP_LPM_KEEP_OUTPUT,	/* BQ24022_nCHARGE_EN */
> 	GPIO96_GPIO | MFP_LPM_KEEP_OUTPUT,	/* BQ24022_ISET2 */
> % 

I still, can't understand, why MFP_LPM_DRIVE_* does not do the job for you...
What's the real problem with using MFP_LPM_DRIVE_*?
Can't you specify it for those GPIO72/96?


-- 
Regards,
Igor.

  reply	other threads:[~2012-04-01 12:23 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-31 12:20 [PATCH] ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT Paul Parsons
2012-04-01  9:15 ` Igor Grinberg
2012-04-01 10:56   ` Paul Parsons
2012-04-01 12:23     ` Igor Grinberg [this message]
2012-04-01 17:56       ` Paul Parsons
2012-04-02  8:39         ` Igor Grinberg
2012-04-02 11:30           ` Paul Parsons
2012-04-02 12:44             ` Igor Grinberg
2012-04-02 13:33               ` Paul Parsons
2012-04-02 14:58                 ` Haojian Zhuang
2012-04-02 15:34                   ` Paul Parsons
2012-04-03  8:48                     ` Igor Grinberg
2012-04-03  8:01                 ` Igor Grinberg
2012-04-03 12:30                   ` Paul Parsons
2012-04-03 14:42                     ` Igor Grinberg
2012-04-03 15:08                       ` Igor Grinberg
2012-04-03 16:26                         ` Paul Parsons
2012-04-12 10:59                           ` Igor Grinberg
2012-04-04  1:00                         ` Paul Parsons
2012-04-03 23:55                   ` Paul Parsons
2012-04-05  8:16                     ` Igor Grinberg
2012-04-05 11:15                       ` Paul Parsons

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F7848DE.2080605@compulab.co.il \
    --to=grinberg@compulab.co.il \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.