ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Subsystems (3)
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
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.
---
arch/arm/mach-pxa/mfp-pxa2xx.c +3 -0
@@ -96,6 +96,9 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)break ; } +if (c &MFP_LPM_KEEP_OUTPUT ) + is_out =1 ; +if (is_out ^ gpio_desc[gpio].dir_inverted) gpdr_lpm[bank] |= mask;else
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hi Paul,
Quoted 25 lines · Paul Parsons
Some MFP configurations specify
MFP_LPM_KEEP_OUTPUTto preserve the gpio output value (HIGH or LOW) during sleep mode. For example:
GPIO72_GPIO|MFP_LPM_KEEP_OUTPUT,Unfortunately
MFP_LPM_KEEP_OUTPUTmakes no special provision for setting the sleep mode gpio direction, unlikeMFP_LPM_DRIVE_HIGHandMFP_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_OUTPUTwas specified. This bringsMFP_LPM_KEEP_OUTPUTinto line withMFP_LPM_DRIVE_HIGHandMFP_LPM_DRIVE_LOW.Signed-off-by Paul Parsons <[email protected]>---
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0
arch/arm/mach-pxa/mfp-pxa2xx.c static int __mfp_config_gpio(unsigned gpio, unsigned long c) · line 101
Quoted 6 lines
arch/arm/mach-pxa/mfp-pxa2xx.c +3
-0@@ -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, but for pins that have been configured for output by gpio_direction_out(). (Hint: *_KEEP_*).
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.
Why can't you use:
GPIO<n>_GPIO | MFP_LPM_DRIVE_<level>
?
Quoted 3 lines
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0if (is_out ^ gpio_desc[gpio].dir_inverted) gpdr_lpm[bank] |= mask;else
Signature · 2 lines
Regards, Igor.
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hello Igor,
Quoted 44 lines · Igor Grinberg
Hi Paul,
Quoted 1 line · Paul Parsons
Some MFP configurations specify
MFP_LPM_KEEP_OUTPUTtopreserve the gpio output
Quoted 3 lines
value (HIGH or LOW) during sleep mode. For example:
? ???GPIO72_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
Unfortunately
MFP_LPM_KEEP_OUTPUTmakes no specialprovision for setting the
Quoted 1 line
sleep mode gpio direction, unlike
MFP_LPM_DRIVE_HIGHand
MFP_LPM_DRIVE_LOW.Quoted 3 lines
Consequently MFP configurations of the form:
? ???GPIO<n>_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 4 lines
will set the sleep mode gpio direction to INPUT.
This patch forces the sleep mode gpio direction to
OUTPUT in cases where
Quoted 1 line
MFP_LPM_KEEP_OUTPUTwas specified. This brings
MFP_LPM_KEEP_OUTPUTinto lineReview
Quoted 6 lines
with
MFP_LPM_DRIVE_HIGHandMFP_LPM_DRIVE_LOW.Signed-off-by Paul Parsons <[email protected]>---
(quoted diff) +0
-0
b/arch/arm/mach-pxa/mfp-pxa2xx.carch/arm/mach-pxa/mfp-pxa2xx.c static int __mfp_config_gpio(unsigned
Quoted 4 lines
index b0a8428..3b443199 100644
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0@@ -96,6 +96,9 @@ static int __mfp_config_gpio(unsignedgpio, unsigned long c)
Quoted 6 lines
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0? ??? ??? break; ? ??? }?
+??? if (c &MFP_LPM_KEEP_OUTPUT)
+??? ???is_out= 1;
+
Quoted 2 lines
MFP_LPM_KEEP_OUTPUTdoes 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) &&
%
Quoted 3 lines
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[].
As far as I can tell MFP_LPM_KEEP_OUTPUT has no direct connection to gpio_direction_output().
Quoted 5 lines
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.
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))) {
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. 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@the point the GPDR registers are forced.
Quoted 3 lines
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 */
%
Regards,
Paul
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Quoted 53 lines · Paul Parsons
Hello Igor,
Quoted 40 lines · Igor Grinberg
Hi Paul,
Quoted 1 line · Paul Parsons
Some MFP configurations specify
MFP_LPM_KEEP_OUTPUTtopreserve the gpio output
Quoted 3 lines
value (HIGH or LOW) during sleep mode. For example:
GPIO72_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
Unfortunately
MFP_LPM_KEEP_OUTPUTmakes no specialprovision for setting the
Quoted 1 line
sleep mode gpio direction, unlike
MFP_LPM_DRIVE_HIGHand
MFP_LPM_DRIVE_LOW.Quoted 3 lines
Consequently MFP configurations of the form:
GPIO<n>_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 4 lines
will set the sleep mode gpio direction to INPUT.
This patch forces the sleep mode gpio direction to
OUTPUT in cases where
Quoted 1 line
MFP_LPM_KEEP_OUTPUTwas specified. This brings
MFP_LPM_KEEP_OUTPUTinto lineReview
Quoted 6 lines
with
MFP_LPM_DRIVE_HIGHandMFP_LPM_DRIVE_LOW.Signed-off-by Paul Parsons <[email protected]>---
(quoted diff) +0
-0
b/arch/arm/mach-pxa/mfp-pxa2xx.carch/arm/mach-pxa/mfp-pxa2xx.c static int __mfp_config_gpio(unsigned
Quoted 4 lines
index b0a8428..3b443199 100644
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0@@ -96,6 +96,9 @@ static int __mfp_config_gpio(unsignedgpio, unsigned long c)
Quoted 3 lines
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0break ; }Quoted 6 lines
arch/arm/mach-pxa/mfp-pxa2xx.c static int __mfp_config_gpio(unsigned gpio, unsigned long c) · line 101
Quoted 3 lines
arch/arm/mach-pxa/mfp-pxa2xx.c +3
-0+if (c &MFP_LPM_KEEP_OUTPUT ) + is_out =1 ; +
MFP_LPM_KEEP_OUTPUTdoes not meant to be used to setup the mfp config,As far as I can see,
MFP_LPM_KEEP_OUTPUTis *only* used to setup the mfp config:
Quoted 8 lines
% xzcat linux-3.4-rc1.tar.xz | fgrep -a
MFP_LPM_KEEP_OUTPUTGPIO13_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?
Quoted 8 lines
Quoted 4 lines
but for pins that have been configured for output by
gpio_direction_out().
(Hint: *_KEEP_*).
MFP_LPM_KEEP_OUTPUTonly 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...
Quoted 2 lines
As far as I can tell
MFP_LPM_KEEP_OUTPUThas no direct connection togpio_direction_output().
Well, it has... in the pxa2xx_mfp_suspend() function you've pasted below.
Quoted 9 lines
Quoted 6 lines
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.
Quoted 9 lines
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).
Quoted 15 lines
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 }Quoted 4 lines
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 fromMFP_LPM_DRIVE_HIGHorMFP_LPM_DRIVE_LOWthough.
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_.
Quoted 3 lines
So the presumption must be that the GPIOs configured as
DRIVE_HIGH,DRIVER_LOWand nowKEEP_OUTPUTalready 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!
Quoted 5 lines
Quoted 4 lines
Why can't you use:
GPIO<n>_GPIO | MFP_LPM_DRIVE_<level>
?
Quoted 7 lines
The hx4700 has a couple of charging GPIOs which we want to keep HIGH or LOW during sleep mode:
% fgrep
MFP_LPM_KEEP_OUTPUTarch/arm/mach-pxa/hx4700.cGPIO72_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?
Signature · 2 lines
Regards, Igor.
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hello Igor,
Quoted 80 lines · Igor Grinberg
Quoted 3 lines · Paul Parsons
Hello Igor,
--- On Sun, 1/4/12, Igor Grinberg <[email protected]>
Quoted 4 lines · wrote:
Quoted 4 lines
Hi Paul,
Quoted 1 line · Paul Parsons
Some MFP configurations specify
MFP_LPM_KEEP_OUTPUTtoQuoted 2 lines
Quoted 2 lines
preserve the gpio output
Quoted 1 line
value (HIGH or LOW) during sleep mode. For
example:
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
? ? ?
GPIO72_GPIO|
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
Unfortunately
MFP_LPM_KEEP_OUTPUTmakes nospecial
Quoted 2 lines
Quoted 2 lines
provision for setting the
Quoted 1 line
sleep mode gpio direction, unlike
MFP_LPM_DRIVE_HIGHQuoted 7 lines
Quoted 7 lines
and
MFP_LPM_DRIVE_LOW.Quoted 3 lines
Consequently MFP configurations of the form:
? ? ? GPIO<n>_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
will set the sleep mode gpio direction to
INPUT.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
This patch forces the sleep mode gpio direction
to
Quoted 8 lines
Quoted 8 lines
OUTPUT in cases where
Quoted 1 line
MFP_LPM_KEEP_OUTPUTwas specified. This brings
MFP_LPM_KEEP_OUTPUTinto lineQuoted 5 lines
with
MFP_LPM_DRIVE_HIGHandMFP_LPM_DRIVE_LOW.Signed-off-by Paul Parsons <[email protected]>---
Quoted 6 lines
Quoted 6 lines
Review
Quoted 1 line
(quoted diff) +0
-0
b/arch/arm/mach-pxa/mfp-pxa2xx.carch/arm/mach-pxa/mfp-pxa2xx.c static int
Quoted 4 lines
index b0a8428..3b443199 100644
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0@@ -96,6 +96,9 @@ static int__mfp_config_gpio(unsigned
Quoted 2 lines
Quoted 2 lines
gpio, unsigned long c)
Quoted 1 line
? ? ? ?
???break;
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
? ? ???}
???
+? ? if (c &
MFP_LPM_KEEP_OUTPUT)Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
+? ? ? ?
is_out= 1;
+
MFP_LPM_KEEP_OUTPUTdoes not meant to be used tosetup the
Quoted 3 lines
Quoted 1 line
mfp config,
As far as I can see,
MFP_LPM_KEEP_OUTPUTis *only* usedto setup the
Quoted 3 lines
mfp config:
% xzcat linux-3.4-rc1.tar.xz | fgrep -a
MFP_LPM_KEEP_OUTPUTQuoted 1 line
???
GPIO13_GPIO|
MFP_LPM_KEEP_OUTPUT,??? /*CORGI_GPIO_LED_ORANGE*/Quoted 1 line
???
GPIO38_GPIO|
MFP_LPM_KEEP_OUTPUT,??? /*CORGI_GPIO_CHRG_ON
*/Quoted 1 line
???
GPIO43_GPIO|
MFP_LPM_KEEP_OUTPUT,??? /*CORGI_GPIO_CHRG_UKN*/Quoted 1 line
#define
MFP_LPM_KEEP_OUTPUT??? (0x1<< 25)
Quoted 8 lines
Quoted 1 line
??? /* set corresponding PGSR bit of
those marked
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
??? ??? if
((gpio_desc[i].config &
MFP_LPM_KEEP_OUTPUT) &&Quoted 1 line
%
How can you be certain that you don't break corgi, with the proposed patch?
On corgi, the three GPIOs configured as MFP_LPM_KEEP_OUTPUT:
CORGI_GPIO_LED_ORANGE
CORGI_GPIO_CHRG_ON
CORGI_GPIO_CHRG_UKN
are all used as outputs.
Quoted 6 lines
Quoted 1 line
Quoted 1 line
but for pins that have been configured for output
by
Quoted 4 lines
Quoted 2 lines
gpio_direction_out().
(Hint: *_KEEP_*).
MFP_LPM_KEEP_OUTPUTonly takes effect when the system
Quoted 8 lines
enters sleep mode,
Quoted 1 line
at which point the GPIO directions (GPDR registers) are
forced from the
Quoted 1 line
values privately stored in gpdr_lpm[].
Correct, but with your patch, the direction will be forced to output,
but the value will be undefined...
The values will be defined in pxa2xx_mfp_suspend() when it sets the PGSR registers. Or at least they will be on corgi and hx4700, but see below...
Quoted 16 lines
Quoted 1 line
As far as I can tell
MFP_LPM_KEEP_OUTPUThas no directconnection to
Quoted 1 line
gpio_direction_output().Well, it has... in the
pxa2xx_mfp_suspend()function you've pasted below.Quoted 2 lines
Quoted 2 lines
Also, I don't think this is a good idea, because
the patch
Quoted 2 lines
Quoted 2 lines
allows a pin
be configured as output, but does not forces avalue
Quoted 3 lines
Quoted 2 lines
(high/low)
and this is not safe.
Quoted 7 lines
Quoted 1 line
A value does not need to be provided until the system
enters sleep mode,
Quoted 1 line
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.
OK, see below...
Quoted 14 lines
Quoted 1 line
? ? 353??? static int
pxa2xx_mfp_suspend(void)Quoted 2 lines
? ? 354??? {
? ? 355??? ???int i;
Quoted 2 lines
? ? 356???
? ? 357??? ???/* set corresponding PGSR bit of those marked
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
? ? 358??? ???
for (i = 0; i <
pxa_last_gpio; i++) {Quoted 1 line
? ? 359??? ???
??? if ((gpio_desc[i].config &
MFP_LPM_KEEP_OUTPUT) &&
Quoted 7 lines
Quoted 1 line
? ? 360??? ???
??? ? ? (GPDR(i) &
GPIO_bit(i))) {Look at the check above...
the PGSR only gets set for the GPIOs configured to output (presumably bygpio_direction_output()function).
OK, I understand your objection here.
My feeling is that the (GPDR(i) & GPIO_bit(i)) test is unwanted because the current state of GPDR (via gpio_direction_output()) does not apply in sleep mode, yet for some reason it is being allowed to prevent the setting of PGSR in the case of GPIO inputs.
Consequently the (GPDR(i) & GPIO_bit(i)) test should be removed.
Quoted 32 lines
Quoted 1 line
? ? 361??? ???
??? ??? if (GPLR(i) &
GPIO_bit(i))Quoted 1 line
? ? 362??? ???
??? ??? ???
PGSR(gpio_to_bank(i)) |=GPIO_bit(i);Quoted 1 line
? ? 363??? ???
??? ??? else
Quoted 1 line
? ? 364??? ???
??? ??? ???
PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);Quoted 1 line
? ? 365??? ???
??? }
Quoted 1 line
? ? 366??? ???
}
Quoted 2 lines
? ? 367???
? ? 368??? ???for (i = 0; i <=
gpio_to_bank(pxa_last_gpio); i++) {Quoted 3 lines
? ? 369???
? ? ? ???...
? ? 375??? ??????
GPDR(i * 32)= gpdr_lpm[i];Quoted 1 line
? ? 376??? ???
}
Quoted 1 line
? ? 377??? ???
return 0;
Quoted 3 lines
? ? 378??? }
However looking at
pxa2xx_mfp_suspend()more closely itis true that the
Quoted 1 line
GPDR registers are set before the PGSR values take
effect (when the
Quoted 8 lines
Quoted 2 lines
processor enters sleep mode).
That is no different fromMFP_LPM_DRIVE_HIGHor
MFP_LPM_DRIVE_LOWthough.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_knownvalue_.
KEEP_OUTPUT does the same where GPIOs are configured as outputs, as is the case with corgi and hx4700.
Your valid objection is for cases where GPIOs are configured as inputs. So I presume that removing the (GPDR(i) & GPIO_bit(i)) test will satisfy your objection.
Quoted 4 lines
Quoted 1 line
So the presumption must be that the GPIOs configured as
DRIVE_HIGH,Quoted 1 line
DRIVER_LOWand nowKEEP_OUTPUTalready have a validdirection and value
Quoted 8 lines
Quoted 1 line
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_OUTPUTdoes not, but with your patch it will effectively
force the GPIO to be output in sleep mode, but with no value set!
Only in cases where the GPIO is used as an input in normal mode but configured to be an output in sleep mode.
Removing the (GPDR(i) & GPIO_bit(i)) test addresses that case.
Quoted 12 lines
Quoted 5 lines
Quoted 3 lines
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
Quoted 4 lines
LOW during sleep mode:
% fgrep
MFP_LPM_KEEP_OUTPUTarch/arm/mach-pxa/hx4700.c???GPIO72_GPIO|
MFP_LPM_KEEP_OUTPUT,??? /*BQ24022_nCHARGE_EN
*/
Quoted 8 lines
Quoted 1 line
???
GPIO96_GPIO|
MFP_LPM_KEEP_OUTPUT,??? /*BQ24022_ISET2*/Quoted 1 line
%
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?
The feeling was that if the unit was charging in normal mode then it should remain charging in sleep mode, and if it wasn't then it should remain not charging.
Actually that's an interim solution until the bootloader can take control of sleep mode charging, but we're not there yet.
Regards,
Paul
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hi Paul,
Can you, please, configure your mailer to _not_ wrap the text? It is rally hard to read it after a few replies...
Quoted 89 lines · Paul Parsons
Hello Igor,
Quoted 86 lines · Igor Grinberg
Quoted 3 lines · Paul Parsons
Hello Igor,
--- On Sun, 1/4/12, Igor Grinberg <[email protected]>
Quoted 4 lines · wrote:
Quoted 4 lines
Hi Paul,
Quoted 1 line · Paul Parsons
Some MFP configurations specify
MFP_LPM_KEEP_OUTPUTtoQuoted 2 lines
Quoted 2 lines
preserve the gpio output
Quoted 1 line
value (HIGH or LOW) during sleep mode. For
example:
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
GPIO72_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
Unfortunately
MFP_LPM_KEEP_OUTPUTmakes nospecial
Quoted 2 lines
Quoted 2 lines
provision for setting the
Quoted 1 line
sleep mode gpio direction, unlike
MFP_LPM_DRIVE_HIGHQuoted 7 lines
Quoted 7 lines
and
MFP_LPM_DRIVE_LOW.Quoted 3 lines
Consequently MFP configurations of the form:
GPIO<n>_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
will set the sleep mode gpio direction to
INPUT.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
This patch forces the sleep mode gpio direction
to
Quoted 8 lines
Quoted 8 lines
OUTPUT in cases where
Quoted 1 line
MFP_LPM_KEEP_OUTPUTwas specified. This brings
MFP_LPM_KEEP_OUTPUTinto lineQuoted 5 lines
with
MFP_LPM_DRIVE_HIGHandMFP_LPM_DRIVE_LOW.Signed-off-by Paul Parsons <[email protected]>---
Quoted 6 lines
Quoted 6 lines
Review
Quoted 1 line
(quoted diff) +0
-0
b/arch/arm/mach-pxa/mfp-pxa2xx.carch/arm/mach-pxa/mfp-pxa2xx.c static int
Quoted 4 lines
index b0a8428..3b443199 100644
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0@@ -96,6 +96,9 @@ static int__mfp_config_gpio(unsigned
Quoted 2 lines
Quoted 2 lines
gpio, unsigned long c)
Quoted 1 line
break;
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
}+ if (c &
MFP_LPM_KEEP_OUTPUT)Quoted 4 lines
Quoted 4 lines
arch/arm/mach-pxa/mfp-pxa2xx.c static int __mfp_config_gpio(unsigned gpio, unsigned long c) · line 101
Quoted 2 lines
arch/arm/mach-pxa/mfp-pxa2xx.c +2
-0+ is_out =1 ; +
MFP_LPM_KEEP_OUTPUTdoes not meant to be used tosetup the
Quoted 3 lines
Quoted 1 line
mfp config,
As far as I can see,
MFP_LPM_KEEP_OUTPUTis *only* usedto setup the
Quoted 3 lines
mfp config:
% xzcat linux-3.4-rc1.tar.xz | fgrep -a
MFP_LPM_KEEP_OUTPUTQuoted 1 line
GPIO13_GPIO |
MFP_LPM_KEEP_OUTPUT, /*CORGI_GPIO_LED_ORANGE*/Quoted 1 line
GPIO38_GPIO |
MFP_LPM_KEEP_OUTPUT, /*CORGI_GPIO_CHRG_ON
*/Quoted 1 line
GPIO43_GPIO |
MFP_LPM_KEEP_OUTPUT, /*CORGI_GPIO_CHRG_UKN*/Quoted 1 line
#define
MFP_LPM_KEEP_OUTPUT(0x1<< 25)
Quoted 1 line
/* set corresponding PGSR bit ofthose marked
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
if
((gpio_desc[i].config &
MFP_LPM_KEEP_OUTPUT) &&Quoted 1 line
%
Quoted 8 lines
Quoted 2 lines
How can you be certain that you don't break corgi, with the proposed patch?
On corgi, the three GPIOs configured as
MFP_LPM_KEEP_OUTPUT:
CORGI_GPIO_LED_ORANGE
CORGI_GPIO_CHRG_ON
CORGI_GPIO_CHRG_UKN
are all used as outputs.
Have you verified it, because currently MFP_LPM_KEEP_OUTPUT does not do a direction configuration... and IMO, it should not!
Quoted 10 lines
Quoted 10 lines
Quoted 2 lines
Quoted 2 lines
but for pins that have been configured for output
by
Quoted 4 lines
Quoted 2 lines
gpio_direction_out().
(Hint: *_KEEP_*).
MFP_LPM_KEEP_OUTPUTonly takes effect when the systementers sleep mode,
Quoted 1 line
at which point the GPIO directions (GPDR registers) are
forced from the
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
values privately stored in gpdr_lpm[].
Correct, but with your patch, the direction will be forced to output,
but the value will be undefined...The values will be defined in
pxa2xx_mfp_suspend()when it sets the PGSR registers. Or at least they will be on corgi and hx4700, but see below...
No, they will not, because the direction can be input...
Quoted 49 lines
Quoted 17 lines
Quoted 2 lines
As far as I can tell
MFP_LPM_KEEP_OUTPUThas no directconnection to
Quoted 1 line
gpio_direction_output().Well, it has... in the
pxa2xx_mfp_suspend()function you've pasted below.Quoted 2 lines
Quoted 2 lines
Also, I don't think this is a good idea, because
the patch
Quoted 2 lines
Quoted 2 lines
allows a pin
be configured as output, but does not forces avalue
Quoted 3 lines
Quoted 2 lines
(high/low)
and this is not safe.Quoted 7 lines
Quoted 1 line
A value does not need to be provided until the system
enters sleep mode,
Quoted 1 line
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.
OK, see below...
Quoted 13 lines
Quoted 1 line
353 static int
pxa2xx_mfp_suspend(void)Quoted 2 lines
354 { 355int i;
Quoted 2 lines
356 357/* set corresponding PGSR bit of those marked
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
358for (i = 0; i <
pxa_last_gpio; i++) {Quoted 1 line
359if ((gpio_desc[i].config &Quoted 8 lines
MFP_LPM_KEEP_OUTPUT) &&Quoted 1 line
360(GPDR(i) &
GPIO_bit(i))) {Look at the check above...
the PGSR only gets set for the GPIOs configured to output (presumably bygpio_direction_output()function).
Quoted 5 lines
OK, I understand your objection here.
My feeling is that the (GPDR(i) &
GPIO_bit(i)) test is unwanted because the current state of GPDR (viagpio_direction_output()) does not apply in sleep mode,
It gets copied to PGSR in the pxa2xx_mfp_suspend() and therefore it does apply! That is exactly the meaning of MFP_LPM_KEEP_OUTPUT:
_If_ the pin is output, then _keep_ it output with the _runtime_ value.
Quoted 2 lines
yet for some reason it is being allowed to prevent the setting of PGSR in the case of GPIO inputs.
Because, the PGSR is valid only for GPIO outputs!
and has nothing to do with inputs.
Quoted 2 lines
Consequently the (GPDR(i) &
GPIO_bit(i)) test should be removed.
No, absolutely not!
This will change the meaning of the MFP_LPM_KEEP_OUTPUT symbol! I have a feeling that you are trying to solve a problem that does not exist!
Quoted 42 lines
Quoted 33 lines
Quoted 2 lines
361if (GPLR(i) &
GPIO_bit(i))Quoted 1 line
362PGSR(gpio_to_bank(i)) |=
GPIO_bit(i);Quoted 1 line
363else
Quoted 1 line
364PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
Quoted 1 line
365}Quoted 1 line
366}
Quoted 2 lines
367 368for (i = 0; i <=
gpio_to_bank(pxa_last_gpio); i++) {Quoted 3 lines
369 ... 375GPDR(i * 32) = gpdr_lpm[i];Quoted 1 line
376}
Quoted 1 line
377return 0;
Quoted 3 lines
378 }However looking at
pxa2xx_mfp_suspend()more closely itis true that the
Quoted 1 line
GPDR registers are set before the PGSR values take
effect (when the
Quoted 8 lines
Quoted 2 lines
processor enters sleep mode).
That is no different fromMFP_LPM_DRIVE_HIGHor
MFP_LPM_DRIVE_LOWthough.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_knownvalue_.
Quoted 5 lines
KEEP_OUTPUTdoes the same where GPIOs are configured as outputs, as is the case with corgi and hx4700.
Your valid objection is for cases where GPIOs are configured as inputs. So I presume that removing the (GPDR(i) &GPIO_bit(i)) test will satisfy your objection.
again, no, because it will change the meaning of the MFP_LPM_KEEP_OUTPUT symbol!
Quoted 14 lines
Quoted 5 lines
Quoted 2 lines
So the presumption must be that the GPIOs configured as
DRIVE_HIGH,Quoted 1 line
DRIVER_LOWand nowKEEP_OUTPUTalready have a validdirection and value
Quoted 8 lines
Quoted 1 line
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_OUTPUTdoes not, but with your patch it will effectively
force the GPIO to be output in sleep mode, but with no value set!
Quoted 3 lines
Only in cases where the GPIO is used as an input in normal mode but configured to be an output in sleep mode.
Removing the (GPDR(i) &GPIO_bit(i)) test addresses that case.
No, because, if the GPIO is input, you will configure it for output and set some arbitrary value that is seen on the input! This is bad!
Quoted 17 lines
Quoted 17 lines
Quoted 6 lines
Quoted 4 lines
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
Quoted 4 lines
LOW during sleep mode:
% fgrep
MFP_LPM_KEEP_OUTPUTarch/arm/mach-pxa/hx4700.cGPIO72_GPIO |
MFP_LPM_KEEP_OUTPUT, /*BQ24022_nCHARGE_EN
*/Quoted 1 line
GPIO96_GPIO |
MFP_LPM_KEEP_OUTPUT, /*BQ24022_ISET2*/Quoted 1 line
%
Quoted 8 lines
Quoted 4 lines
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?The feeling was that if the unit was charging in normal mode then it should remain charging in sleep mode, and if it wasn't then it should remain not charging.
Ok, finally we are talking about a real problem...
I see...
IMO, the best solution will be to add a generic GPIOx_GPIO_OUT (as already proposed by Haojian) definition (where x is the required GPIO number)for your used GPIOs and use it in MFP config structure for hx4700 along with MFP_LPM_KEEP_OUTPUT.
Another solution would be (though a bit hackish):GPIOx_GPIO | MFP_LPM_DRIVE_LOW | MFP_LPM_KEEP_OUTPUT
The above should work for you as you would expect - will set the GPIO to be output low by default, then you will reconfigure it to the appropriate level from your charger driver and the new level will be used by the existing logic in pxa2xx_mfp_suspend().
Quoted 2 lines
Actually that's an interim solution until the bootloader can take control of sleep mode charging, but we're not there yet.
still you don't want the turn on/off of the charger in the suspend sequence, so IMO, it must also be fixed in Linux.
But, please, don't change the meaning of MFP_LPM_KEEP_OUTPUT! Because, currently it is safe to use it also with inputs
and we don't want to break this assumption.
Signature · 2 lines
Regards, Igor.
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hello Igor,
Quoted 119 lines · Igor Grinberg
Hi Paul,
Can you, please, configure your mailer to _not_ wrap the text?
It is rally hard to read it after a few replies...Quoted 3 lines · Paul Parsons
Hello Igor,
--- On Sun, 1/4/12, Igor Grinberg <[email protected]>
Quoted 5 lines · wrote:
Quoted 5 lines
Quoted 3 lines · Paul Parsons
Hello Igor,
--- On Sun, 1/4/12, Igor Grinberg <[email protected]>
Quoted 8 lines
Quoted 8 lines
Quoted 4 lines · wrote:
Quoted 4 lines
Hi Paul,
Quoted 1 line · Paul Parsons
Some MFP configurations specify
MFP_LPM_KEEP_OUTPUTtoQuoted 2 lines
Quoted 2 lines
preserve the gpio output
Quoted 1 line
value (HIGH or LOW) during sleep mode.
For
Quoted 3 lines
Quoted 3 lines
example:
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
? ?
???GPIO72_GPIO |
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
Unfortunately
MFP_LPM_KEEP_OUTPUTmakesno
Quoted 6 lines
Quoted 6 lines
special
Quoted 2 lines
Quoted 2 lines
provision for setting the
Quoted 1 line
sleep mode gpio direction, unlike
MFP_LPM_DRIVE_HIGHQuoted 2 lines
Quoted 2 lines
and
MFP_LPM_DRIVE_LOW.Quoted 1 line
Consequently MFP configurations of the
form:
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
? ?
???GPIO<n>_GPIO |
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
will set the sleep mode gpio direction
to
Quoted 3 lines
Quoted 3 lines
INPUT.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
This patch forces the sleep mode gpio
direction
Quoted 3 lines
Quoted 3 lines
to
Quoted 2 lines
Quoted 2 lines
OUTPUT in cases where
Quoted 1 line
MFP_LPM_KEEP_OUTPUTwas specified. Thisbrings
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
MFP_LPM_KEEP_OUTPUTinto lineQuoted 1 line
with
MFP_LPM_DRIVE_HIGHand
MFP_LPM_DRIVE_LOW.Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Signed-off-by Paul Parsons <[email protected]>---
diff --git
a/arch/arm/mach-pxa/mfp-pxa2xx.cQuoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 5 lines
b/arch/arm/mach-pxa/mfp-pxa2xx.carch/arm/mach-pxa/mfp-pxa2xx.c static int
Quoted 4 lines
index b0a8428..3b443199 100644
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0@@ -96,6 +96,9 @@ static int__mfp_config_gpio(unsigned
Quoted 8 lines
Quoted 8 lines
Quoted 2 lines
Quoted 2 lines
gpio, unsigned long c)
Quoted 1 line
? ? ? ?
? ? break;
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
? ? ? ? }
? ?
+? ? if (c &
MFP_LPM_KEEP_OUTPUT)Quoted 1 line
Quoted 1 line
Quoted 1 line
+? ? ? ?
is_out=1;
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
+
MFP_LPM_KEEP_OUTPUTdoes not meant to beused to
Quoted 4 lines
Quoted 4 lines
setup the
Quoted 3 lines
Quoted 1 line
mfp config,
As far as I can see,
MFP_LPM_KEEP_OUTPUTis*only* used
Quoted 10 lines
Quoted 10 lines
to setup the
Quoted 3 lines
mfp config:
% xzcat linux-3.4-rc1.tar.xz | fgrep -a
MFP_LPM_KEEP_OUTPUTQuoted 1 line
? ???GPIO13_GPIO |
MFP_LPM_KEEP_OUTPUT,? ? /*CORGI_GPIO_LED_ORANGE*/Quoted 1 line
? ???GPIO38_GPIO |
MFP_LPM_KEEP_OUTPUT,? ? /*
CORGI_GPIO_CHRG_ONQuoted 7 lines
Quoted 7 lines
*/
Quoted 1 line
? ???GPIO43_GPIO |
MFP_LPM_KEEP_OUTPUT,? ? /*CORGI_GPIO_CHRG_UKN*/Quoted 1 line
#define
MFP_LPM_KEEP_OUTPUT? ? (0x1<< 25)
Quoted 1 line
? ???/* set corresponding
PGSR bit of
Quoted 3 lines
Quoted 3 lines
those marked
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
? ? ? ???if
((gpio_desc[i].config &
MFP_LPM_KEEP_OUTPUT)&&
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
%
How can you be certain that you don't break corgi,
with the
Quoted 3 lines
Quoted 1 line
proposed patch?
On corgi, the three GPIOs configured as
MFP_LPM_KEEP_OUTPUT:
Quoted 8 lines
Quoted 4 lines
? ???CORGI_GPIO_LED_ORANGE
? ???CORGI_GPIO_CHRG_ON
? ???CORGI_GPIO_CHRG_UKN
are all used as outputs.Have you verified it, because currently
MFP_LPM_KEEP_OUTPUTdoes not do a direction configuration... and IMO, it should not!
Yes, all 3 GPIOs are configured as outputs:CORGI_GPIO_LED_ORANGE in drivers/leds/leds-gpio.c CORGI_GPIO_CHRG_ON in arch/arm/mach-pxa/corgi_pm.c CORGI_GPIO_CHRG_UKN in arch/arm/mach-pxa/corgi_pm.c
Quoted 97 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
but for pins that have been configured for
output
Quoted 5 lines
Quoted 5 lines
by
Quoted 4 lines
Quoted 2 lines
gpio_direction_out().
(Hint: *_KEEP_*).
MFP_LPM_KEEP_OUTPUTonly takes effect when thesystem
Quoted 2 lines
Quoted 2 lines
enters sleep mode,
Quoted 1 line
at which point the GPIO directions (GPDR
registers) are
Quoted 4 lines
Quoted 4 lines
forced from the
Quoted 1 line
values privately stored in gpdr_lpm[].
Correct, but with your patch, the direction will be
forced
Quoted 4 lines
Quoted 2 lines
to output,
but the value will be undefined...The values will be defined in
pxa2xx_mfp_suspend()whenit sets the PGSR
Quoted 1 line
registers. Or at least they will be on corgi and
hx4700, but see below...
No, they will not, because the direction can be input...
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
As far as I can tell
MFP_LPM_KEEP_OUTPUThas nodirect
Quoted 4 lines
Quoted 4 lines
connection to
Quoted 1 line
gpio_direction_output().Well, it has... in the
pxa2xx_mfp_suspend()function you've
Quoted 4 lines
Quoted 4 lines
pasted below.
Quoted 2 lines
Quoted 2 lines
Also, I don't think this is a good idea,
because
Quoted 3 lines
Quoted 3 lines
the patch
Quoted 2 lines
Quoted 2 lines
allows a pin
be configured as output, but does notforces a
Quoted 5 lines
Quoted 5 lines
value
Quoted 4 lines
Quoted 2 lines
(high/low)
and this is not safe.A value does not need to be provided until the
system
Quoted 2 lines
Quoted 2 lines
enters sleep mode,
Quoted 1 line
at which point the value is provided via the
PGSR
Quoted 8 lines
Quoted 4 lines
registers.
Yes, but you don't force the PGSR to be set...
and that is the problem.OK, see below...
Quoted 1 line
Quoted 1 line
? ???353? ? static
int
Quoted 3 lines
Quoted 3 lines
pxa2xx_mfp_suspend(void)Quoted 2 lines
? ???354? ? {
? ???355? ????
Quoted 3 lines
Quoted 3 lines
int i;
Quoted 2 lines
? ???356? ?
? ???357? ????
Quoted 3 lines
Quoted 3 lines
/* set corresponding PGSR bit of those marked
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
? ???358? ?
???
Quoted 2 lines
Quoted 2 lines
for (i = 0; i <
pxa_last_gpio; i++) {Quoted 1 line
? ???359? ?
???
Quoted 1 line
Quoted 1 line
? ???if ((gpio_desc[i].config
&
Quoted 2 lines
Quoted 2 lines
MFP_LPM_KEEP_OUTPUT) &&Quoted 1 line
? ???360? ?
???
Quoted 1 line
Quoted 1 line
? ? ? ???(GPDR(i)
&
Quoted 4 lines
Quoted 4 lines
GPIO_bit(i))) {Look at the check above...
the PGSR only gets set for the GPIOs configured tooutput
Quoted 5 lines
Quoted 1 line
(presumably by
gpio_direction_output()function).OK, I understand your objection here.
My feeling is that the (GPDR(i) &
GPIO_bit(i)) testis unwanted because
Quoted 1 line
the current state of GPDR (via
gpio_direction_output())
Quoted 8 lines
does not apply in
Quoted 1 line
sleep mode,
It gets copied to PGSR in the
pxa2xx_mfp_suspend()and therefore it does apply!
That is exactly the meaning ofMFP_LPM_KEEP_OUTPUT:
_If_ the pin is output, then _keep_ it output with the _runtime_ value.
OK, I see, your interpretation is that MFP_LPM_KEEP_OUTPUT is optional:
it should not apply if the pin is an input at the time pxa2xx_mfp_suspend() is called.
My interpretation was that MFP_LPM_KEEP_OUTPUT is mandatory: it always applies regardless of the current pin direction, exactly like MFP_LPM_DRIVE_HIGH and MFP_LPM_DRIVE_LOW.
If your interpretation is correct then DRIVE_HIGH and DRIVE_LOW will likewise need to check the state of GPDR at the time pxa2xx_mfp_suspend() is called.
If my interpretation is correct then having KEEP_OUTPUT ignore the state of GPDR in pxa2xx_mfp_suspend() is the correct thing to do.
Do you agree that KEEP_OUTPUT, DRIVE_HIGH and DRIVE_LOW should all be consistent in being either optional or mandatory sleep mode configurations?
Quoted 6 lines
Quoted 3 lines
yet for some reason it is being allowed to prevent the setting of PGSR in the case of GPIO inputs.
Because, the PGSR is valid only for GPIO outputs! and has nothing to do with inputs.
I know, it makes no sense to specify KEEP_OUTPUT, DRIVE_HIGH or DRIVE_LOW for GPIO inputs.
But since DRIVE_HIGH or DRIVE_LOW currently don't prevent that, the presumption must be that GPIOs configured as DRIVE_HIGH or DRIVE_LOW are being used as outputs. Likewise for KEEP_OUTPUT?
Quoted 8 lines
Quoted 3 lines
Consequently the (GPDR(i) &
GPIO_bit(i)) testshould be removed.
No, absolutely not!
This will change the meaning of theMFP_LPM_KEEP_OUTPUTsymbol!
Only if you interpret KEEP_OUTPUT as an optional sleep mode configuration.
Quoted 2 lines
I have a feeling that you are trying to solve a problem that does not exist!
The problem is that MFP configurations of the form:
GPIO<n>_GPIO | MFP_LPM_KEEP_OUTPUT,
will always set the sleep mode gpio direction to INPUT. That is the case with corgi and would also be the case with hx4700. That is the problem which needs to be solved.
Quoted 150 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
? ???361? ?
???
Quoted 1 line
Quoted 1 line
? ? ? ???if (GPLR(i)
&
Quoted 2 lines
Quoted 2 lines
GPIO_bit(i))Quoted 1 line
? ???362? ?
???
Quoted 3 lines
Quoted 3 lines
? ? ? ? ? ?
PGSR(gpio_to_bank(i)) |=GPIO_bit(i);Quoted 1 line
? ???363? ?
???
Quoted 2 lines
Quoted 2 lines
? ? ? ???else
Quoted 1 line
? ???364? ?
???
Quoted 3 lines
Quoted 3 lines
? ? ? ? ? ?
PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);Quoted 1 line
? ???365? ?
???
Quoted 2 lines
Quoted 2 lines
? ???}
Quoted 1 line
? ???366? ?
???
Quoted 3 lines
Quoted 3 lines
}
Quoted 2 lines
? ???367? ?
? ???368? ????
Quoted 1 line
Quoted 1 line
for (i = 0; i <=
gpio_to_bank(pxa_last_gpio);i++) {
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
? ???369? ?
? ? ? ? ? ...
? ???375? ????
Quoted 1 line
Quoted 1 line
? ???GPDR(i * 32) =
gpdr_lpm[i];
Quoted 1 line
Quoted 1 line
Quoted 1 line
? ???376? ?
???
Quoted 2 lines
Quoted 2 lines
}
Quoted 1 line
? ???377? ?
???
Quoted 4 lines
Quoted 4 lines
return 0;
Quoted 3 lines
? ???378? ? }
However looking at
pxa2xx_mfp_suspend()moreclosely it
Quoted 2 lines
Quoted 2 lines
is true that the
Quoted 1 line
GPDR registers are set before the PGSR values
take
Quoted 3 lines
Quoted 3 lines
effect (when the
Quoted 2 lines
processor enters sleep mode).
That is no different fromMFP_LPM_DRIVE_HIGHor
Quoted 5 lines
Quoted 5 lines
MFP_LPM_DRIVE_LOWthough.Well, it is different, because the in case of MFP_LPM_DRIVE_*,
the PGSR is set in the__mfp_config_gpio()functionand has
Quoted 3 lines
Quoted 1 line
a
_knownvalue_.
KEEP_OUTPUTdoes the same where GPIOs are configured asoutputs, as is
Quoted 2 lines
the case with corgi and hx4700.
Your valid objection is for cases where GPIOs areconfigured as inputs.
Quoted 1 line
So I presume that removing the (GPDR(i) &
GPIO_bit(i)) test will satisfyQuoted 1 line
your objection.
again, no, because it will change the meaning of the
MFP_LPM_KEEP_OUTPUTsymbol!Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
So the presumption must be that the GPIOs
configured as
Quoted 2 lines
Quoted 2 lines
DRIVE_HIGH,Quoted 1 line
DRIVER_LOWand nowKEEP_OUTPUTalready have avalid
Quoted 2 lines
Quoted 2 lines
direction and value
Quoted 1 line
set at the point the GPDR registers are
forced.
Quoted 4 lines
Quoted 4 lines
Yes. That is exactly my point here.
MFP_LPM_DRIVE_* has the value determined and set.MFP_LPM_KEEP_OUTPUTdoes not, but with your patchit will
Quoted 2 lines
Quoted 2 lines
effectively
force the GPIO to be output in sleep mode, but withno value
Quoted 3 lines
Quoted 1 line
set!
Only in cases where the GPIO is used as an input in
normal mode but
Quoted 2 lines
configured to be an output in sleep mode. Removing the (GPDR(i) &
GPIO_bit(i)) test addressesthat case.
No, because, if the GPIO is input, you will configure it for output
and set some arbitrary value that is seen on the input! This is bad!Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Why can't you use:
GPIO<n>_GPIO |MFP_LPM_DRIVE_<level>
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
?
The hx4700 has a couple of charging GPIOs which
we want
Quoted 4 lines
Quoted 4 lines
to keep HIGH or
Quoted 3 lines
LOW during sleep mode:
% fgrep
MFP_LPM_KEEP_OUTPUT
arch/arm/mach-pxa/hx4700.cQuoted 2 lines
Quoted 2 lines
Quoted 1 line
? ???GPIO72_GPIO |
MFP_LPM_KEEP_OUTPUT,? ? /*
BQ24022_nCHARGE_ENQuoted 3 lines
Quoted 3 lines
*/
Quoted 1 line
? ???GPIO96_GPIO |
MFP_LPM_KEEP_OUTPUT,? ? /*BQ24022_ISET2*/
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
%
I still, can't understand, why MFP_LPM_DRIVE_* does
not do
Quoted 2 lines
Quoted 2 lines
the job for you...
What's the real problem with usingMFP_LPM_DRIVE_*?
Quoted 3 lines
Quoted 1 line
Can't you specify it for those GPIO72/96?
The feeling was that if the unit was charging in normal
mode then it
Quoted 1 line
should remain charging in sleep mode, and if it wasn't
then it should
Quoted 1 line
remain not charging.
Ok, finally we are talking about a real problem... I see...
IMO, the best solution will be to add a genericGPIOx_GPIO_OUT
(as already proposed by Haojian) definition (where x is the required GPIO number)for your used GPIOs and use it in MFP config
structure for hx4700 along withMFP_LPM_KEEP_OUTPUT.Another solution would be (though a bit hackish):
GPIOx_GPIO|MFP_LPM_DRIVE_LOW|MFP_LPM_KEEP_OUTPUT
Quoted 7 lines
The above should work for you as you would expect - will set the GPIO
to be output low by default, then you will reconfigure it to the
appropriate level from your charger driver and the new level will be used
by the existing logic inpxa2xx_mfp_suspend().
Those solutions are fair enough.
Can we first answer the question of whether KEEP_OUTPUT, DRIVE_HIGH and DRIVE_LOW are optional or mandatory sleep mode configurations. That may determine the way forward.
Quoted 5 lines
Quoted 2 lines
Actually that's an interim solution until the
bootloader can take control
Quoted 1 line
of sleep mode charging, but we're not there yet.
Quoted 7 lines
still you don't want the turn on/off of the charger in the suspend sequence,
so IMO, it must also be fixed in Linux.
But, please, don't change the meaning ofMFP_LPM_KEEP_OUTPUT!
Because, currently it is safe to use it also with inputs and we don't want to break this assumption.
Regards,
Paul
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Quoted 127 lines · Paul Parsons
Hello Igor,
Quoted 124 lines · Igor Grinberg
Hi Paul,
Can you, please, configure your mailer to _not_ wrap the text?
It is rally hard to read it after a few replies...Quoted 3 lines · Paul Parsons
Hello Igor,
--- On Sun, 1/4/12, Igor Grinberg <[email protected]>
Quoted 5 lines · wrote:
Quoted 5 lines
Quoted 3 lines · Paul Parsons
Hello Igor,
--- On Sun, 1/4/12, Igor Grinberg <[email protected]>
Quoted 8 lines
Quoted 8 lines
Quoted 4 lines · wrote:
Quoted 4 lines
Hi Paul,
Quoted 1 line · Paul Parsons
Some MFP configurations specify
MFP_LPM_KEEP_OUTPUTtoQuoted 2 lines
Quoted 2 lines
preserve the gpio output
Quoted 1 line
value (HIGH or LOW) during sleep mode.
For
Quoted 3 lines
Quoted 3 lines
example:
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
GPIO72_GPIO|Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
Unfortunately
MFP_LPM_KEEP_OUTPUTmakesno
Quoted 6 lines
Quoted 6 lines
special
Quoted 2 lines
Quoted 2 lines
provision for setting the
Quoted 1 line
sleep mode gpio direction, unlike
MFP_LPM_DRIVE_HIGHQuoted 2 lines
Quoted 2 lines
and
MFP_LPM_DRIVE_LOW.Quoted 1 line
Consequently MFP configurations of the
form:
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
GPIO<n>_GPIO |
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
will set the sleep mode gpio direction
to
Quoted 3 lines
Quoted 3 lines
INPUT.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
This patch forces the sleep mode gpio
direction
Quoted 3 lines
Quoted 3 lines
to
Quoted 2 lines
Quoted 2 lines
OUTPUT in cases where
Quoted 1 line
MFP_LPM_KEEP_OUTPUTwas specified. Thisbrings
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
MFP_LPM_KEEP_OUTPUTinto lineQuoted 1 line
with
MFP_LPM_DRIVE_HIGHand
MFP_LPM_DRIVE_LOW.Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Signed-off-by Paul Parsons <[email protected]>---
diff --git
a/arch/arm/mach-pxa/mfp-pxa2xx.cQuoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 5 lines
b/arch/arm/mach-pxa/mfp-pxa2xx.carch/arm/mach-pxa/mfp-pxa2xx.c static int
Quoted 4 lines
index b0a8428..3b443199 100644
arch/arm/mach-pxa/mfp-pxa2xx.c +0
-0@@ -96,6 +96,9 @@ static int__mfp_config_gpio(unsigned
Quoted 8 lines
Quoted 8 lines
Quoted 2 lines
Quoted 2 lines
gpio, unsigned long c)
Quoted 1 line
break;Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
}+ if (c &
MFP_LPM_KEEP_OUTPUT)Quoted 1 line
Quoted 1 line
Quoted 1 line
+
is_out=1;
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
+
MFP_LPM_KEEP_OUTPUTdoes not meant to beused to
Quoted 4 lines
Quoted 4 lines
setup the
Quoted 3 lines
Quoted 1 line
mfp config,
As far as I can see,
MFP_LPM_KEEP_OUTPUTis*only* used
Quoted 10 lines
Quoted 10 lines
to setup the
Quoted 3 lines
mfp config:
% xzcat linux-3.4-rc1.tar.xz | fgrep -a
MFP_LPM_KEEP_OUTPUTQuoted 1 line
GPIO13_GPIO |
MFP_LPM_KEEP_OUTPUT, /*CORGI_GPIO_LED_ORANGE*/Quoted 1 line
GPIO38_GPIO |
MFP_LPM_KEEP_OUTPUT, /*
CORGI_GPIO_CHRG_ONQuoted 7 lines
Quoted 7 lines
*/
Quoted 1 line
GPIO43_GPIO |
MFP_LPM_KEEP_OUTPUT, /*CORGI_GPIO_CHRG_UKN*/Quoted 1 line
#define
MFP_LPM_KEEP_OUTPUT(0x1<< 25)
Quoted 1 line
/* set correspondingPGSR bit of
Quoted 3 lines
Quoted 3 lines
those marked
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
if
((gpio_desc[i].config &
MFP_LPM_KEEP_OUTPUT)&&
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
%
How can you be certain that you don't break corgi,
with the
Quoted 3 lines
Quoted 1 line
proposed patch?
On corgi, the three GPIOs configured as
MFP_LPM_KEEP_OUTPUT:Quoted 4 lines
CORGI_GPIO_LED_ORANGE
CORGI_GPIO_CHRG_ON
CORGI_GPIO_CHRG_UKN
are all used as outputs.
Quoted 8 lines
Quoted 3 lines
Have you verified it, because currently
MFP_LPM_KEEP_OUTPUTdoes not do a direction configuration... and IMO, it should not!Yes, all 3 GPIOs are configured as outputs:
CORGI_GPIO_LED_ORANGEindrivers/leds/leds-gpio.cCORGI_GPIO_CHRG_ONinarch/arm/mach-pxa/corgi_pm.cCORGI_GPIO_CHRG_UKNinarch/arm/mach-pxa/corgi_pm.c
Good, then they will be kept output also in the suspend mode, as for current implementation.
Quoted 120 lines
Quoted 98 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
but for pins that have been configured for
output
Quoted 5 lines
Quoted 5 lines
by
Quoted 4 lines
Quoted 2 lines
gpio_direction_out().
(Hint: *_KEEP_*).
MFP_LPM_KEEP_OUTPUTonly takes effect when thesystem
Quoted 2 lines
Quoted 2 lines
enters sleep mode,
Quoted 1 line
at which point the GPIO directions (GPDR
registers) are
Quoted 4 lines
Quoted 4 lines
forced from the
Quoted 1 line
values privately stored in gpdr_lpm[].
Correct, but with your patch, the direction will be
forced
Quoted 4 lines
Quoted 2 lines
to output,
but the value will be undefined...The values will be defined in
pxa2xx_mfp_suspend()whenit sets the PGSR
Quoted 1 line
registers. Or at least they will be on corgi and
hx4700, but see below...
No, they will not, because the direction can be input...
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
As far as I can tell
MFP_LPM_KEEP_OUTPUThas nodirect
Quoted 4 lines
Quoted 4 lines
connection to
Quoted 1 line
gpio_direction_output().Well, it has... in the
pxa2xx_mfp_suspend()function you've
Quoted 4 lines
Quoted 4 lines
pasted below.
Quoted 2 lines
Quoted 2 lines
Also, I don't think this is a good idea,
because
Quoted 3 lines
Quoted 3 lines
the patch
Quoted 2 lines
Quoted 2 lines
allows a pin
be configured as output, but does notforces a
Quoted 5 lines
Quoted 5 lines
value
Quoted 4 lines
Quoted 2 lines
(high/low)
and this is not safe.A value does not need to be provided until the
system
Quoted 2 lines
Quoted 2 lines
enters sleep mode,
Quoted 1 line
at which point the value is provided via the
PGSR
Quoted 8 lines
Quoted 4 lines
registers.
Yes, but you don't force the PGSR to be set...
and that is the problem.OK, see below...
Quoted 1 line
Quoted 1 line
353 static
int
Quoted 8 lines
Quoted 7 lines
pxa2xx_mfp_suspend(void)Quoted 2 lines
354 { 355int i;
Quoted 2 lines
356 357Quoted 8 lines
Quoted 8 lines
/* set corresponding PGSR bit of those marked
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
358for (i = 0; i <
pxa_last_gpio; i++) {Quoted 1 line
359if ((gpio_desc[i].config
&
Quoted 4 lines
Quoted 4 lines
MFP_LPM_KEEP_OUTPUT) &&Quoted 1 line
360(GPDR(i)&
Quoted 4 lines
Quoted 4 lines
GPIO_bit(i))) {Look at the check above...
the PGSR only gets set for the GPIOs configured tooutput
Quoted 5 lines
Quoted 1 line
(presumably by
gpio_direction_output()function).OK, I understand your objection here.
My feeling is that the (GPDR(i) &
GPIO_bit(i)) testis unwanted because
Quoted 1 line
the current state of GPDR (via
gpio_direction_output())Quoted 8 lines
does not apply in
Quoted 1 line
sleep mode,
It gets copied to PGSR in the
pxa2xx_mfp_suspend()and therefore it does apply!
That is exactly the meaning ofMFP_LPM_KEEP_OUTPUT:
_If_ the pin is output, then _keep_ it output with the _runtime_ value.OK, I see, your interpretation is that
MFP_LPM_KEEP_OUTPUTis optional:
it should not apply if the pin is an input at the timepxa2xx_mfp_suspend()is called.
My interpretation was thatMFP_LPM_KEEP_OUTPUTis mandatory: it always applies regardless of the current pin direction, exactly likeMFP_LPM_DRIVE_HIGHandMFP_LPM_DRIVE_LOW.If your interpretation is correct then
DRIVE_HIGHandDRIVE_LOWwill likewise need to check the state of GPDR at the timepxa2xx_mfp_suspend()is called.
If my interpretation is correct then havingKEEP_OUTPUTignore the state of GPDR inpxa2xx_mfp_suspend()is the correct thing to do.
Quoted 3 lines
Do you agree that
KEEP_OUTPUT,DRIVE_HIGHandDRIVE_LOWshould all be consistent in being either optional or mandatory sleep mode configurations?
No, according to current implementation (and IMO, it is _not_ a bug):DRIVE_HIGH and DRIVE_LOW are mandatory,KEEP_OUTPUT is optional.
Quoted 10 lines
Quoted 7 lines
Quoted 4 lines
yet for some reason it is being allowed to prevent the setting of PGSR in the case of GPIO inputs.
Because, the PGSR is valid only for GPIO outputs! and has nothing to do with inputs.
I know, it makes no sense to specify
KEEP_OUTPUT,DRIVE_HIGHorDRIVE_LOWfor GPIO inputs.
That's the point, that it does make sense for certain cases, when you want the GPIO to be bidirectional, but output in suspend. This allows certain flexibility.
Quoted 1 line
But since
DRIVE_HIGHorDRIVE_LOWcurrently don't prevent that,
Don't prevent what? DRIVE_HIGH and DRIVE_LOW allow you to do what ever you want with the GPIO in runtime, but have it strictly configured for the suspend.
Quoted 3 lines
the
presumption must be that GPIOs configured asDRIVE_HIGHorDRIVE_LOWare being used as outputs. Likewise forKEEP_OUTPUT?
KEEP_OUTPUT only affects the GPIOs configured for output in runtime and let you keep the last output value.
Quoted 11 lines
Quoted 9 lines
Quoted 4 lines
Consequently the (GPDR(i) &
GPIO_bit(i)) testshould be removed.
No, absolutely not!
This will change the meaning of theMFP_LPM_KEEP_OUTPUTsymbol!Only if you interpret
KEEP_OUTPUTas an optional sleep mode configuration.
That what the current implementation does and IMO, it is the right thing.
Quoted 9 lines
Quoted 3 lines
I have a feeling that you are trying to solve a problem that does not exist!
The problem is that MFP configurations of the form:
GPIO<n>_GPIO |MFP_LPM_KEEP_OUTPUT,
will always set the sleep mode gpio direction to INPUT. That is the case with corgi and would also be the case with hx4700. That is the problem which needs to be solved.
Yes, it is just there is no h/w MFP in PXA2xx and all the stuff done in s/w. That is the reason it is a bit mess.
IMO, the cleanest solution would be to have GPIO<n>_GPIO_OUT for each GPIO that needs to be configured as output instead of breaking the already fragile MFP logic.
Quoted 159 lines
Quoted 151 lines
Quoted 6 lines
Quoted 6 lines
Quoted 4 lines
361if (GPLR(i)&
Quoted 14 lines
Quoted 13 lines
GPIO_bit(i))Quoted 1 line
362PGSR(gpio_to_bank(i)) |=
GPIO_bit(i);Quoted 1 line
363else
Quoted 1 line
364PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
Quoted 1 line
365Quoted 8 lines
Quoted 8 lines
}Quoted 1 line
366}
Quoted 2 lines
367 368for (i = 0; i <=
gpio_to_bank(pxa_last_gpio);i++) {
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines
369 ... 375GPDR(i * 32) =gpdr_lpm[i];
Quoted 9 lines
Quoted 9 lines
Quoted 1 line
376}
Quoted 1 line
377return 0;
Quoted 3 lines
378 }However looking at
pxa2xx_mfp_suspend()moreclosely it
Quoted 2 lines
Quoted 2 lines
is true that the
Quoted 1 line
GPDR registers are set before the PGSR values
take
Quoted 3 lines
Quoted 3 lines
effect (when the
Quoted 2 lines
processor enters sleep mode).
That is no different fromMFP_LPM_DRIVE_HIGHor
Quoted 5 lines
Quoted 5 lines
MFP_LPM_DRIVE_LOWthough.Well, it is different, because the in case of MFP_LPM_DRIVE_*,
the PGSR is set in the__mfp_config_gpio()functionand has
Quoted 3 lines
Quoted 1 line
a
_knownvalue_.
KEEP_OUTPUTdoes the same where GPIOs are configured asoutputs, as is
Quoted 2 lines
the case with corgi and hx4700.
Your valid objection is for cases where GPIOs areconfigured as inputs.
Quoted 1 line
So I presume that removing the (GPDR(i) &
GPIO_bit(i)) test will satisfyQuoted 1 line
your objection.
again, no, because it will change the meaning of the
MFP_LPM_KEEP_OUTPUTsymbol!Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
So the presumption must be that the GPIOs
configured as
Quoted 2 lines
Quoted 2 lines
DRIVE_HIGH,Quoted 1 line
DRIVER_LOWand nowKEEP_OUTPUTalready have avalid
Quoted 2 lines
Quoted 2 lines
direction and value
Quoted 1 line
set at the point the GPDR registers are
forced.
Quoted 4 lines
Quoted 4 lines
Yes. That is exactly my point here.
MFP_LPM_DRIVE_* has the value determined and set.MFP_LPM_KEEP_OUTPUTdoes not, but with your patchit will
Quoted 2 lines
Quoted 2 lines
effectively
force the GPIO to be output in sleep mode, but withno value
Quoted 3 lines
Quoted 1 line
set!
Only in cases where the GPIO is used as an input in
normal mode but
Quoted 2 lines
configured to be an output in sleep mode. Removing the (GPDR(i) &
GPIO_bit(i)) test addressesthat case.
No, because, if the GPIO is input, you will configure it for output
and set some arbitrary value that is seen on the input! This is bad!Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Why can't you use:
GPIO<n>_GPIO |MFP_LPM_DRIVE_<level>
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
?
The hx4700 has a couple of charging GPIOs which
we want
Quoted 4 lines
Quoted 4 lines
to keep HIGH or
Quoted 3 lines
LOW during sleep mode:
% fgrep
MFP_LPM_KEEP_OUTPUT
arch/arm/mach-pxa/hx4700.cQuoted 2 lines
Quoted 2 lines
Quoted 1 line
GPIO72_GPIO |
MFP_LPM_KEEP_OUTPUT, /*
BQ24022_nCHARGE_ENQuoted 3 lines
Quoted 3 lines
*/
Quoted 1 line
GPIO96_GPIO |
MFP_LPM_KEEP_OUTPUT, /*BQ24022_ISET2*/
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
%
I still, can't understand, why MFP_LPM_DRIVE_* does
not do
Quoted 2 lines
Quoted 2 lines
the job for you...
What's the real problem with usingMFP_LPM_DRIVE_*?
Quoted 3 lines
Quoted 1 line
Can't you specify it for those GPIO72/96?
The feeling was that if the unit was charging in normal
mode then it
Quoted 1 line
should remain charging in sleep mode, and if it wasn't
then it should
Quoted 1 line
remain not charging.
Ok, finally we are talking about a real problem... I see...
IMO, the best solution will be to add a genericGPIOx_GPIO_OUT
(as already proposed by Haojian) definition (where x is the required GPIO number)for your used GPIOs and use it in MFP config
structure for hx4700 along withMFP_LPM_KEEP_OUTPUT.Another solution would be (though a bit hackish):
GPIOx_GPIO|MFP_LPM_DRIVE_LOW|MFP_LPM_KEEP_OUTPUTQuoted 7 lines
The above should work for you as you would expect - will set the GPIO
to be output low by default, then you will reconfigure it to the
appropriate level from your charger driver and the new level will be used
by the existing logic inpxa2xx_mfp_suspend().
Quoted 4 lines
Those solutions are fair enough.
Can we first answer the question of whetherKEEP_OUTPUT,DRIVE_HIGHandDRIVE_LOWare optional or mandatory sleep mode configurations. That may determine the way forward.
Well for the DRIVE_HIGH and DRIVE_LOW, the names speak for them selfs - MultiFunctionalPin_LowPowerManager_DRIVE_<HIGH|LOW> and there is no questions arise.
For the MFP_LPM_KEEP_OUTPUT - is PXA2xx specific, apparently it is confusing and probably has to have a comment explaining the meaning.
Quoted 1 line
From git log:
---------------cut---------------------
commit 1106143d7ab43ba07678c88c85417df219354ae8
Author: Eric Miao <[email protected]> Date: Mon Jan 11 21:25:15 2010 +0800
[ARM] pxa: add MFP_LPM_KEEP_OUTPUT flag to pin config
Some pins are expected to keep their last level during suspend, and introduce MFP_LPM_KEEP_OUTPUT for this.
---------------cut---------------------
The key words above are: "keep their last level".
Quoted 17 lines
Quoted 6 lines
Quoted 3 lines
Actually that's an interim solution until the
bootloader can take control
Quoted 1 line
of sleep mode charging, but we're not there yet.
Quoted 7 lines
still you don't want the turn on/off of the charger in the suspend sequence,
so IMO, it must also be fixed in Linux.
But, please, don't change the meaning ofMFP_LPM_KEEP_OUTPUT!
Because, currently it is safe to use it also with inputs and we don't want to break this assumption.Regards,
Paul
Signature · 2 lines
Regards, Igor.
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hello Igor,
Quoted 354 lines · Igor Grinberg
Quoted 3 lines · Paul Parsons
Hello Igor,
--- On Mon, 2/4/12, Igor Grinberg <[email protected]>
Quoted 3 lines · wrote:
Quoted 3 lines
Hi Paul,
Can you, please, configure your mailer to _not_
wrap the
Quoted 6 lines
Quoted 6 lines
text?
It is rally hard to read it after a few replies...Quoted 2 lines · Paul Parsons
Hello Igor,
Quoted 7 lines
Quoted 7 lines
Quoted 1 line
--- On Sun, 1/4/12, Igor Grinberg <[email protected]>
Quoted 5 lines · wrote:
Quoted 5 lines
Quoted 3 lines · Paul Parsons
Hello Igor,
--- On Sun, 1/4/12, Igor Grinberg
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines · wrote:
Quoted 3 lines
Hi Paul,
On 03/31/12 15:20, Paul Parsons
Quoted 1 line · wrote:
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Some MFP configurations
specify
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
MFP_LPM_KEEP_OUTPUTtoQuoted 2 lines
Quoted 2 lines
preserve the gpio output
Quoted 1 line
value (HIGH or LOW) during
sleep mode.
Quoted 8 lines
Quoted 8 lines
For
Quoted 3 lines
Quoted 3 lines
example:
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
? ?
? ?
GPIO72_GPIO|Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
Unfortunately
MFP_LPM_KEEP_OUTPUTmakesQuoted 4 lines
Quoted 4 lines
no
Quoted 3 lines
Quoted 3 lines
special
Quoted 2 lines
Quoted 2 lines
provision for setting the
Quoted 1 line
sleep mode gpio direction,
unlike
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
MFP_LPM_DRIVE_HIGHQuoted 2 lines
Quoted 2 lines
and
MFP_LPM_DRIVE_LOW.Quoted 1 line
Consequently MFP configurations
of the
Quoted 7 lines
Quoted 7 lines
form:
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
? ?
? ? GPIO<n>_GPIO |
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
MFP_LPM_KEEP_OUTPUT,Quoted 2 lines
will set the sleep mode gpio
direction
Quoted 4 lines
Quoted 4 lines
to
Quoted 3 lines
Quoted 3 lines
INPUT.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
This patch forces the sleep
mode gpio
Quoted 4 lines
Quoted 4 lines
direction
Quoted 3 lines
Quoted 3 lines
to
Quoted 2 lines
Quoted 2 lines
OUTPUT in cases where
Quoted 1 line
MFP_LPM_KEEP_OUTPUTwasspecified. This
Quoted 6 lines
Quoted 6 lines
brings
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
MFP_LPM_KEEP_OUTPUTinto lineQuoted 1 line
with
MFP_LPM_DRIVE_HIGHand
MFP_LPM_DRIVE_LOW.Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Signed-off-by Paul ParsonsQuoted 7 lines
Quoted 7 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
---
diff --git
a/arch/arm/mach-pxa/mfp-pxa2xx.cQuoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
b/arch/arm/mach-pxa/mfp-pxa2xx.cQuoted 2 lines
index b0a8428..3b443199 100644
---
a/arch/arm/mach-pxa/mfp-pxa2xx.cQuoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
+++
b/arch/arm/mach-pxa/mfp-pxa2xx.cQuoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line
Review static int
Quoted 1 line
(quoted diff) +0
-0@@ -96,6 +96,9 @@ static int__mfp_config_gpio(unsigned
Quoted 2 lines
Quoted 2 lines
gpio, unsigned long c)
Quoted 1 line
? ? ?
???
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
? ???break;
Quoted 1 line
Quoted 1 line
Quoted 1 line
? ? ?
???}
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
? ???
+? ? if (c &
MFP_LPM_KEEP_OUTPUT)Quoted 1 line
Quoted 1 line
Quoted 1 line
+? ? ? ?
is_out=Quoted 4 lines
Quoted 4 lines
1;
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
+
MFP_LPM_KEEP_OUTPUTdoes not meantto be
Quoted 5 lines
Quoted 5 lines
used to
Quoted 4 lines
Quoted 4 lines
setup the
Quoted 3 lines
Quoted 1 line
mfp config,
As far as I can see,
MFP_LPM_KEEP_OUTPUTisQuoted 5 lines
Quoted 5 lines
*only* used
Quoted 4 lines
Quoted 4 lines
to setup the
Quoted 3 lines
mfp config:
% xzcat linux-3.4-rc1.tar.xz | fgrep
-a
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
MFP_LPM_KEEP_OUTPUTQuoted 1 line
? ? ?
GPIO13_GPIO|
MFP_LPM_KEEP_OUTPUT,? ? /*CORGI_GPIO_LED_ORANGE*/Quoted 8 lines
Quoted 8 lines
Quoted 2 lines
Quoted 2 lines
Quoted 1 line
? ? ?
GPIO38_GPIO|
MFP_LPM_KEEP_OUTPUT,? ? /*
CORGI_GPIO_CHRG_ONQuoted 5 lines
Quoted 5 lines
*/
Quoted 1 line
? ? ?
GPIO43_GPIO|
MFP_LPM_KEEP_OUTPUT,? ? /*CORGI_GPIO_CHRG_UKN*/Quoted 1 line
#define
MFP_LPM_KEEP_OUTPUT?? (
0x1Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
<< 25)
Quoted 1 line
? ? ? /* set
corresponding
Quoted 4 lines
Quoted 4 lines
PGSR bit of
Quoted 3 lines
Quoted 3 lines
those marked
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
? ? ? ? ? if
((gpio_desc[i].config &
MFP_LPM_KEEP_OUTPUT)Quoted 4 lines
Quoted 4 lines
&&
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
%
How can you be certain that you don't break
corgi,
Quoted 11 lines
Quoted 11 lines
with the
Quoted 3 lines
Quoted 1 line
proposed patch?
On corgi, the three GPIOs configured as
MFP_LPM_KEEP_OUTPUT:Quoted 4 lines
? ? ?
CORGI_GPIO_LED_ORANGE
? ? ?CORGI_GPIO_CHRG_ON
? ? ?CORGI_GPIO_CHRG_UKN
are all used as outputs.Have you verified it, because currently
MFP_LPM_KEEP_OUTPUTQuoted 1 line
Quoted 1 line
does not do a direction configuration... and IMO,
it should
Quoted 6 lines
Quoted 1 line
not!
Yes, all 3 GPIOs are configured as outputs:
CORGI_GPIO_LED_ORANGEindrivers/leds/leds-gpio.cCORGI_GPIO_CHRG_ONinarch/arm/mach-pxa/corgi_pm.cCORGI_GPIO_CHRG_UKNinarch/arm/mach-pxa/corgi_pm.cGood, then they will be kept output also in the suspend mode,
as for current implementation.Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
but for pins that have been
configured for
Quoted 6 lines
Quoted 6 lines
output
Quoted 5 lines
Quoted 5 lines
by
Quoted 4 lines
Quoted 2 lines
gpio_direction_out().
(Hint: *_KEEP_*).
MFP_LPM_KEEP_OUTPUTonly takes effectwhen the
Quoted 3 lines
Quoted 3 lines
system
Quoted 2 lines
Quoted 2 lines
enters sleep mode,
Quoted 1 line
at which point the GPIO directions
(GPDR
Quoted 5 lines
Quoted 5 lines
registers) are
Quoted 4 lines
Quoted 4 lines
forced from the
Quoted 1 line
values privately stored in gpdr_lpm[].
Correct, but with your patch, the direction
will be
Quoted 5 lines
Quoted 5 lines
forced
Quoted 4 lines
Quoted 2 lines
to output,
but the value will be undefined...The values will be defined in
pxa2xx_mfp_suspend()whenQuoted 2 lines
Quoted 2 lines
it sets the PGSR
Quoted 1 line
registers. Or at least they will be on corgi
and
Quoted 3 lines
Quoted 3 lines
hx4700, but see below...
No, they will not, because the direction can be
input...
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
As far as I can tell
MFP_LPM_KEEP_OUTPUThas noQuoted 5 lines
Quoted 5 lines
direct
Quoted 4 lines
Quoted 4 lines
connection to
Quoted 1 line
gpio_direction_output().Well, it has... in the
pxa2xx_mfp_suspend()Quoted 5 lines
Quoted 5 lines
function you've
Quoted 4 lines
Quoted 4 lines
pasted below.
Quoted 2 lines
Quoted 2 lines
Also, I don't think this is a good
idea,
Quoted 4 lines
Quoted 4 lines
because
Quoted 3 lines
Quoted 3 lines
the patch
Quoted 2 lines
Quoted 2 lines
allows a pin
be configured as output, but doesnot
Quoted 6 lines
Quoted 6 lines
forces a
Quoted 5 lines
Quoted 5 lines
value
Quoted 4 lines
Quoted 2 lines
(high/low)
and this is not safe.A value does not need to be provided
until the
Quoted 3 lines
Quoted 3 lines
system
Quoted 2 lines
Quoted 2 lines
enters sleep mode,
Quoted 1 line
at which point the value is provided
via the
Quoted 4 lines
Quoted 4 lines
PGSR
Quoted 3 lines
Quoted 3 lines
registers.
Yes, but you don't force the PGSR to be
set...
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 1 line
and that is the problem.
OK, see below...
Quoted 1 line
Quoted 1 line
? ? ? 353? ?
static
Quoted 4 lines
Quoted 4 lines
int
Quoted 3 lines
Quoted 3 lines
pxa2xx_mfp_suspend(void)Quoted 2 lines
? ? ? 354? ? {
? ? ?355???
Quoted 4 lines
Quoted 4 lines
? ?
Quoted 3 lines
Quoted 3 lines
int i;
Quoted 2 lines
? ? ? 356? ?
? ? ?357???
Quoted 2 lines
Quoted 2 lines
? ?
Quoted 1 line
Quoted 1 line
/* set corresponding PGSR bit of those
marked
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
MFP_LPM_KEEP_OUTPUT*/Quoted 1 line
? ? ?
358???
Quoted 3 lines
Quoted 3 lines
? ?
Quoted 2 lines
Quoted 2 lines
for (i = 0; i <
pxa_last_gpio; i++) {Quoted 1 line
? ? ?
359???
Quoted 2 lines
Quoted 2 lines
? ?
Quoted 1 line
Quoted 1 line
? ? ? if
((gpio_desc[i].config
Quoted 3 lines
Quoted 3 lines
&
Quoted 2 lines
Quoted 2 lines
MFP_LPM_KEEP_OUTPUT) &&Quoted 1 line
? ? ?
360???
Quoted 7 lines
Quoted 7 lines
? ?
Quoted 1 line
Quoted 1 line
? ? ? ? ? (GPDR(i)
&
Quoted 4 lines
Quoted 4 lines
GPIO_bit(i))) {Look at the check above...
the PGSR only gets set for the GPIOsconfigured to
Quoted 2 lines
Quoted 2 lines
output
Quoted 1 line
Quoted 1 line
(presumably by
gpio_direction_output()function).
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
OK, I understand your objection here.
My feeling is that the (GPDR(i) &
GPIO_bit(i)) testQuoted 2 lines
Quoted 2 lines
is unwanted because
Quoted 1 line
the current state of GPDR (via
gpio_direction_output())Quoted 4 lines
Quoted 4 lines
does not apply in
Quoted 1 line
sleep mode,
It gets copied to PGSR in the
pxa2xx_mfp_suspend()and
Quoted 2 lines
Quoted 2 lines
therefore it does apply!
That is exactly the meaning of
MFP_LPM_KEEP_OUTPUT:Quoted 1 line
Quoted 1 line
_If_ the pin is output, then _keep_ it output with
the
Quoted 3 lines
Quoted 1 line
_runtime_ value.
OK, I see, your interpretation is that
MFP_LPM_KEEP_OUTPUTis optional:Quoted 3 lines
it should not apply if the pin is an input at the time
pxa2xx_mfp_suspend()is called.
My interpretation was thatMFP_LPM_KEEP_OUTPUTismandatory: it always
Quoted 1 line
applies regardless of the current pin direction,
exactly like
Quoted 3 lines
MFP_LPM_DRIVE_HIGHandMFP_LPM_DRIVE_LOW.If your interpretation is correct then
DRIVE_HIGHand
DRIVE_LOWwillQuoted 3 lines
likewise need to check the state of GPDR at the time
pxa2xx_mfp_suspend()is called.
If my interpretation is correct then havingKEEP_OUTPUTignore the state
Quoted 1 line
of GPDR in
pxa2xx_mfp_suspend()is the correct thing todo.
Quoted 2 lines
Do you agree that
KEEP_OUTPUT,DRIVE_HIGHandDRIVE_LOWshould all be
Quoted 1 line
consistent in being either optional or mandatory sleep
mode
Quoted 1 line
configurations?
No, according to current implementation (and IMO, it is _not_ a bug):
DRIVE_HIGHandDRIVE_LOWare mandatory,KEEP_OUTPUTis optional.Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
yet for some reason it is being allowed to
prevent the
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
setting of PGSR in the case of GPIO inputs.
Because, the PGSR is valid only for GPIO outputs! and has nothing to do with inputs.
I know, it makes no sense to specify
KEEP_OUTPUT,
DRIVE_HIGHorDRIVE_LOWQuoted 1 line
for GPIO inputs.
That's the point, that it does make sense for certain cases,
when you want the GPIO to be bidirectional, but output in suspend.
This allows certain flexibility.
Quoted 4 lines
Quoted 1 line
But since
DRIVE_HIGHorDRIVE_LOWcurrently don'tprevent that,
Don't prevent what?
Don't prevent a GPIO input being changed to an output when entering suspend().
By the way, there is still the issue of DRIVE_HIGH and DRIVE_LOW forcing the GPIO direction to output in pxa2xx_mfp_suspend() *before* the PGSR values take effect. Surely a bug?
Quoted 42 lines
DRIVE_HIGHandDRIVE_LOWallow you to do
what
ever you want with the GPIO in runtime, but have it strictly configured
for the suspend.Quoted 2 lines
the
presumption must be that GPIOs configured asDRIVE_HIGHor
DRIVE_LOWareQuoted 1 line
being used as outputs. Likewise for
KEEP_OUTPUT?
KEEP_OUTPUTonly affects the GPIOs configured for output in runtime
and let you keep the last output value.Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Consequently the (GPDR(i) &
GPIO_bit(i))test
Quoted 4 lines
Quoted 4 lines
should be removed.
No, absolutely not!
This will change the meaning of the
MFP_LPM_KEEP_OUTPUTQuoted 3 lines
Quoted 1 line
symbol!
Only if you interpret
KEEP_OUTPUTas an optional sleepmode configuration.
That what the current implementation does and IMO, it is the right thing.
Quoted 2 lines
Quoted 2 lines
I have a feeling that you are trying to solve a
problem that
Quoted 4 lines
Quoted 1 line
does not exist!
The problem is that MFP configurations of the form:
? ???GPIO<n>_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 1 line
will always set the sleep mode gpio direction to
Quoted 8 lines
INPUT.
Quoted 1 line
That is the case with corgi and would also be the case
with hx4700.
Quoted 1 line
That is the problem which needs to be solved.
Yes, it is just there is no h/w MFP in PXA2xx and all the stuff done in s/w.
That is the reason it is a bit mess.
It's more than a mess: it's broken, per the current corgi configuration.
Quoted 5 lines
IMO, the cleanest solution would be to have GPIO<n>_GPIO_OUT for each
GPIO that needs to be configured as output instead of breaking the
already fragile MFP logic.
And similarly fix the corgi configuration.
Quoted 238 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
? ? ?
361???
Quoted 2 lines
Quoted 2 lines
? ?
Quoted 1 line
Quoted 1 line
? ? ? ? ? if
(GPLR(i)
Quoted 3 lines
Quoted 3 lines
&
Quoted 2 lines
Quoted 2 lines
GPIO_bit(i))Quoted 1 line
? ? ?
362???
Quoted 2 lines
Quoted 2 lines
? ?
Quoted 1 line
Quoted 1 line
? ? ? ? ?
???
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
PGSR(gpio_to_bank(i)) |=
GPIO_bit(i);Quoted 1 line
? ? ?
363???
Quoted 3 lines
Quoted 3 lines
? ?
Quoted 2 lines
Quoted 2 lines
? ? ? ? ? else
Quoted 1 line
? ? ?
364???
Quoted 2 lines
Quoted 2 lines
? ?
Quoted 1 line
Quoted 1 line
? ? ? ? ?
???
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
Quoted 1 line
? ? ?
365???
Quoted 3 lines
Quoted 3 lines
? ?
Quoted 2 lines
Quoted 2 lines
? ? ? }
Quoted 1 line
? ? ?
366???
Quoted 4 lines
Quoted 4 lines
? ?
Quoted 3 lines
Quoted 3 lines
}
Quoted 2 lines
? ? ? 367? ?
? ? ?368???
Quoted 2 lines
Quoted 2 lines
? ?
Quoted 1 line
Quoted 1 line
for (i = 0; i <=
gpio_to_bank(pxa_last_gpio);Quoted 3 lines
Quoted 3 lines
i++) {
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
? ? ? 369? ?
? ? ? ????...
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
? ? ?
375???
Quoted 4 lines
Quoted 4 lines
? ?
Quoted 1 line
Quoted 1 line
? ? ?
GPDR(i * 32)=gpdr_lpm[i];
Quoted 1 line
Quoted 1 line
Quoted 1 line
? ? ?
376???
Quoted 3 lines
Quoted 3 lines
? ?
Quoted 2 lines
Quoted 2 lines
}
Quoted 1 line
? ? ?
377???
Quoted 5 lines
Quoted 5 lines
? ?
Quoted 4 lines
Quoted 4 lines
return 0;
Quoted 3 lines
? ? ? 378? ? }
However looking at
pxa2xx_mfp_suspend()more
Quoted 3 lines
Quoted 3 lines
closely it
Quoted 2 lines
Quoted 2 lines
is true that the
Quoted 1 line
GPDR registers are set before the PGSR
values
Quoted 4 lines
Quoted 4 lines
take
Quoted 3 lines
Quoted 3 lines
effect (when the
Quoted 2 lines
processor enters sleep mode).
That is no different from
MFP_LPM_DRIVE_HIGHQuoted 4 lines
Quoted 4 lines
or
Quoted 3 lines
Quoted 3 lines
MFP_LPM_DRIVE_LOWthough.Well, it is different, because the in case
of
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
MFP_LPM_DRIVE_*,
the PGSR is set in the__mfp_config_gpio()function
Quoted 4 lines
Quoted 4 lines
and has
Quoted 3 lines
Quoted 1 line
a
_knownvalue_.
KEEP_OUTPUTdoes the same where GPIOs areconfigured as
Quoted 3 lines
Quoted 3 lines
outputs, as is
Quoted 2 lines
the case with corgi and hx4700.
Your valid objection is for cases where GPIOsare
Quoted 6 lines
Quoted 6 lines
configured as inputs.
Quoted 1 line
So I presume that removing the (GPDR(i) &
GPIO_bit(i)) test will satisfyQuoted 1 line
your objection.
again, no, because it will change the meaning of
the
Quoted 4 lines
Quoted 4 lines
MFP_LPM_KEEP_OUTPUTsymbol!Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
So the presumption must be that the
GPIOs
Quoted 3 lines
Quoted 3 lines
configured as
Quoted 2 lines
Quoted 2 lines
DRIVE_HIGH,Quoted 1 line
DRIVER_LOWand nowKEEP_OUTPUTalreadyhave a
Quoted 3 lines
Quoted 3 lines
valid
Quoted 2 lines
Quoted 2 lines
direction and value
Quoted 1 line
set at the point the GPDR registers
are
Quoted 4 lines
Quoted 4 lines
forced.
Quoted 3 lines
Quoted 3 lines
Yes. That is exactly my point here. MFP_LPM_DRIVE_* has the value determined
and set.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
MFP_LPM_KEEP_OUTPUTdoes not, but with yourpatch
Quoted 3 lines
Quoted 3 lines
it will
Quoted 2 lines
Quoted 2 lines
effectively
force the GPIO to be output in sleep mode,but with
Quoted 4 lines
Quoted 4 lines
no value
Quoted 3 lines
Quoted 1 line
set!
Only in cases where the GPIO is used as an
input in
Quoted 3 lines
Quoted 3 lines
normal mode but
Quoted 2 lines
configured to be an output in sleep mode.
Removing the (GPDR(i) &GPIO_bit(i)) testaddresses
Quoted 3 lines
Quoted 3 lines
that case.
No, because, if the GPIO is input, you will
configure it for
Quoted 2 lines
Quoted 2 lines
output
and set some arbitrary value that is seen on theinput!
Quoted 9 lines
Quoted 9 lines
This is bad!
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Why can't you use:
GPIO<n>_GPIO |MFP_LPM_DRIVE_<level>
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
?
The hx4700 has a couple of charging
GPIOs which
Quoted 4 lines
Quoted 4 lines
we want
Quoted 3 lines
Quoted 3 lines
to keep HIGH or
Quoted 2 lines
LOW during sleep mode:
Quoted 8 lines
Quoted 8 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
% fgrep
MFP_LPM_KEEP_OUTPUT
arch/arm/mach-pxa/hx4700.cQuoted 2 lines
Quoted 2 lines
Quoted 1 line
? ? ?
GPIO72_GPIO|
MFP_LPM_KEEP_OUTPUT,? ? /*
BQ24022_nCHARGE_ENQuoted 3 lines
Quoted 3 lines
*/
Quoted 1 line
? ? ?
GPIO96_GPIO|
MFP_LPM_KEEP_OUTPUT,? ? /*
BQ24022_ISET2Quoted 4 lines
Quoted 4 lines
*/
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
%
I still, can't understand, why
MFP_LPM_DRIVE_* does
Quoted 7 lines
Quoted 7 lines
not do
Quoted 2 lines
Quoted 2 lines
the job for you...
What's the real problem with usingMFP_LPM_DRIVE_*?
Quoted 3 lines
Quoted 1 line
Can't you specify it for those GPIO72/96?
The feeling was that if the unit was charging
in normal
Quoted 2 lines
Quoted 2 lines
mode then it
Quoted 1 line
should remain charging in sleep mode, and if it
wasn't
Quoted 8 lines
Quoted 8 lines
then it should
Quoted 1 line
remain not charging.
Ok, finally we are talking about a real problem... I see...
IMO, the best solution will be to add a genericGPIOx_GPIO_OUT
(as already proposed by Haojian) definition (wherex is the
Quoted 1 line
Quoted 1 line
required GPIO number)for your used GPIOs and use it
in MFP
Quoted 2 lines
Quoted 2 lines
config
structure for hx4700 along with
MFP_LPM_KEEP_OUTPUT.Quoted 4 lines
Quoted 4 lines
Another solution would be (though a bit hackish):
GPIOx_GPIO|MFP_LPM_DRIVE_LOW|
MFP_LPM_KEEP_OUTPUTQuoted 2 lines
Quoted 2 lines
The above should work for you as you would expect -
will set
Quoted 2 lines
Quoted 2 lines
the GPIO
to be output low by default, then you willreconfigure it to
Quoted 2 lines
Quoted 2 lines
the
appropriate level from your charger driver and thenew level
Quoted 5 lines
Quoted 2 lines
will be used
by the existing logic inpxa2xx_mfp_suspend().Those solutions are fair enough.
Can we first answer the question of whether
KEEP_OUTPUT,DRIVE_HIGHandQuoted 1 line
DRIVE_LOWare optional or mandatory sleep modeconfigurations. That may
Quoted 1 line
determine the way forward.
Well for the
DRIVE_HIGHandDRIVE_LOW, the names speak for them selfs - MultiFunctionalPin_LowPowerManager_DRIVE_<HIGH|LOW> and there is no
questions arise.
For theMFP_LPM_KEEP_OUTPUT- is PXA2xx specific, apparently it is
confusing and probably has to have a comment explaining the meaning.From git log:
---------------cut---------------------
commit1106143d7ab43ba07678c88c85417df219354ae8
Author: Eric Miao <[email protected]>
Date:???Mon Jan 11 21:25:15 2010 +0800? ? [ARM] pxa: add
MFP_LPM_KEEP_OUTPUTflag to pin config
? ?
? ? Some pins are expected to keep their last level during suspend, and
? ? introduceMFP_LPM_KEEP_OUTPUTfor this. ? ?
? ? Signed-off-by: Eric Miao <[email protected]> ---------------cut---------------------
Quoted 1 line
The key words above are: "keep their last level".
Which is exactly what would have happened with my patch, since all cases of KEEP_OUTPUT were indeed being applied to outputs only.
Quoted 8 lines
Quoted 6 lines
Quoted 6 lines
Quoted 4 lines
Actually that's an interim solution until the
bootloader can take control
Quoted 1 line
of sleep mode charging, but we're not there
yet.
Quoted 1 line
Quoted 1 line
Quoted 9 lines
Quoted 1 line
Quoted 1 line
still you don't want the turn on/off of the charger
in the
Quoted 5 lines
Quoted 5 lines
suspend sequence,
so IMO, it must also be fixed in Linux. But, please, don't change the meaning ofMFP_LPM_KEEP_OUTPUT!
Because, currently it is safe to use it also withinputs
Quoted 1 line
Quoted 1 line
and we don't want to break this assumption.
Regards,
Paul
Haojian Zhuang
maintainerPATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
But since
DRIVE_HIGHorDRIVE_LOWcurrently don'tprevent that,
Don't prevent what?
Don't prevent a GPIO input being changed to an output when entering
suspend().
PGSRx register allow for selecting the output state (the driven value) of each GPIO pin when the processor enters and while it is in sleep mode.
Each bit of PGSRx register is named as SS (Sleep State of GPIO<n>).
SS '0' -- If GPIO is programmed as an output, the pin is driven and held low during the transition to and while in sleep mode.
SS '1' -- If GPIO is programmed as an output, the pin is driven and held high during the transition to and while in sleep mode.
So pin must be configured to GPIO output first before entering sleep mode.
Now the issue comes. If you use the pin as input, why do you need to change it into output mode in run time?
Quoted 4 lines
By the way, there is still the issue of
DRIVE_HIGHandDRIVE_LOWforcing the GPIO direction to output inpxa2xx_mfp_suspend()*before* the PGSR values take effect. Surely a bug?
It's evil to change pin from input mode to output mode if it's in active mode.
Actually we only need to configure control pins to peripherals on pxa27x. It's a little different from pxa3xx. For pxa3xx, we can even configure input pin in low power mode. PXA3xx has standby mode that internal device keeps its state. PXA27x doesn't have this feature. If we want to save power while PXA27x is suspend, the peripheral should be shutdown too.
Since we need to shutdown peripheral, control pin should always connect to
reset or chip select signal of peripheral, we can disable the peripheral. So
we needn't to configure low power mode of those input pins.
Thanks
Haojian
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hello Haojian,
Quoted 27 lines · Haojian Zhuang
Quoted 1 line
Quoted 1 line
Quoted 1 line
But since
DRIVE_HIGHor
DRIVE_LOWcurrently don'tQuoted 5 lines
Quoted 3 lines
prevent that,
Don't prevent what?
Don't prevent a GPIO input being changed to an output
when entering
Quoted 2 lines
suspend().PGSRx register allow for selecting the output state (the driven value)
of each GPIO pin when the processor enters and while it is in sleep
mode.Each bit of PGSRx register is named as SS (Sleep State of GPIO<n>).
SS '0' -- If GPIO is programmed as an output, the pin is driven and held
low during the transition to and while in sleep mode.SS '1' -- If GPIO is programmed as an output, the pin is driven and held
high during the transition to and while in sleep mode.
Quoted 6 lines
So pin must be configured to GPIO output first before entering sleep mode.
Now the issue comes. If you use the pin as input, why do you need to change
it into output mode in run time?
I cannot think of a reason why you would change an input to an output.
But the possibility that the direction could be changed from input to output has been cited as a reason why KEEP_OUTPUT cannot force the gpio direction to output.
It is relatively easy to verify that KEEP_OUTPUT does not change the direction from input to output, because currently only 2 platforms use KEEP_OUTPUT, namely corgi and hx4700.
It is less easy to verify that DRIVE_HIGH and DRIVE_LOW do not change the direction from input to output, because many more platforms use them; a cursory check suggests that up to 16 platforms use them.
Quoted 9 lines
Quoted 2 lines
By the way, there is still the issue of
DRIVE_HIGHand
DRIVE_LOWQuoted 1 line
forcing the GPIO direction to output in
pxa2xx_mfp_suspend()Quoted 2 lines
*before* the PGSR values take effect. Surely a bug?
It's evil to change pin from input mode to output mode if it's in active mode.
Agreed.
So pxa2xx_mfp_suspend() contains a potential bug, unless someone can verify that DRIVE_HIGH and DRIVE_LOW never change the direction from input to output.
Quoted 11 lines
Actually we only need to configure control pins to peripherals on pxa27x. It's
a little different from pxa3xx. For pxa3xx, we can even configure input pin
in low power mode. PXA3xx has standby mode that internal device keeps
its state. PXA27x doesn't have this feature. If we want to save power while
PXA27x is suspend, the peripheral should be shutdown too.
Quoted 5 lines
Since we need to shutdown peripheral, control pin should always connect to
reset or chip select signal of peripheral, we can disable
the peripheral. So
we needn't to configure low power mode of those input pins.
Regards,
Paul
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Quoted 30 lines · Paul Parsons
Hello Haojian,
Quoted 27 lines · Haojian Zhuang
Quoted 1 line
Quoted 1 line
Quoted 1 line
But since
DRIVE_HIGHor
DRIVE_LOWcurrently don'tQuoted 5 lines
Quoted 3 lines
prevent that,
Don't prevent what?
Don't prevent a GPIO input being changed to an output
when entering
Quoted 2 lines
suspend().PGSRx register allow for selecting the output state (the driven value)
of each GPIO pin when the processor enters and while it is in sleep
mode.Each bit of PGSRx register is named as SS (Sleep State of GPIO<n>).
SS '0' -- If GPIO is programmed as an output, the pin is driven and held
low during the transition to and while in sleep mode.SS '1' -- If GPIO is programmed as an output, the pin is driven and held
high during the transition to and while in sleep mode.
Quoted 8 lines
Quoted 6 lines
So pin must be configured to GPIO output first before entering sleep mode.
Now the issue comes. If you use the pin as input, why do you need to change
it into output mode in run time?I cannot think of a reason why you would change an input to an output.
One reason, I can think of is bidirectional pins:
the direction can change several times during runtime, but peripheral may require the pin to be in some defined state in suspend.
Quoted 4 lines
But the possibility that the direction could be changed from input to output has been cited as a reason why
KEEP_OUTPUTcannot force the gpio direction to output.
Indeed, and that's why your patch is wrong - it does exactly that, it enables the possibility to change the input to output and drive an undefined level.
Quoted 4 lines
It is relatively easy to verify that
KEEP_OUTPUTdoes not change the direction from input to output, because currently only 2 platforms useKEEP_OUTPUT, namely corgi and hx4700.
Again, with your patch it will make the change possible.
Quoted 4 lines
It is less easy to verify that
DRIVE_HIGHandDRIVE_LOWdo not change the direction from input to output, because many more platforms use them; a cursory check suggests that up to 16 platforms use them.
DRIVE_HIGH and DRIVE_LOW are used across several _different_ SoCs and care must be taken while changing something related to them.
The DRIVE_HIGH and DRIVE_LOW in current implementation _can_ change the inputs to outputs, but IMO it is the board support code responsibility to verify that the right thing is done.
Quoted 10 lines
Quoted 10 lines
Quoted 3 lines
By the way, there is still the issue of
DRIVE_HIGHand
DRIVE_LOWQuoted 1 line
forcing the GPIO direction to output in
pxa2xx_mfp_suspend()Quoted 2 lines
*before* the PGSR values take effect. Surely a bug?
It's evil to change pin from input mode to output mode if it's in active mode.
Unless, it is peripheral requirement.
Quoted 6 lines
Agreed.
So
pxa2xx_mfp_suspend()contains a potential bug, unless someone can verify thatDRIVE_HIGHandDRIVE_LOWnever change the direction from input to output.
They do, but I don't consider it a bug, but a flexibility. When you specify DRIVE_HIGH or DRIVE_LOW in the board pin config, you must know what you are doing and be responsible.
Signature · 2 lines
Regards, Igor.
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
In reply to Paul ParsonsQuoted 2 lines · Paul Parsons
Hello Igor,
[...] Remove the unreadable stuff...
Quoted 13 lines
Quoted 13 lines
Quoted 8 lines
Quoted 8 lines
Quoted 1 line
On corgi, the three GPIOs configured as
MFP_LPM_KEEP_OUTPUT:Quoted 4 lines
CORGI_GPIO_LED_ORANGE
CORGI_GPIO_CHRG_ON
CORGI_GPIO_CHRG_UKN
are all used as outputs.Have you verified it, because currently
MFP_LPM_KEEP_OUTPUTQuoted 1 line
Quoted 1 line
does not do a direction configuration... and IMO,
it should
Quoted 2 lines
Quoted 1 line
not!
Quoted 8 lines
Quoted 8 lines
Quoted 4 lines
Yes, all 3 GPIOs are configured as outputs:
CORGI_GPIO_LED_ORANGEindrivers/leds/leds-gpio.cCORGI_GPIO_CHRG_ONinarch/arm/mach-pxa/corgi_pm.cCORGI_GPIO_CHRG_UKNinarch/arm/mach-pxa/corgi_pm.cGood, then they will be kept output also in the suspend mode,
as for current implementation.
Now I can see that it will not... because of the below line:GPDR(i * 32) = gpdr_lpm[i];
in the pxa2xx_mfp_suspend() function.
[...] remove unreadable stuff...
Quoted 31 lines
Quoted 31 lines
Quoted 2 lines
Do you agree that
KEEP_OUTPUT,DRIVE_HIGHandDRIVE_LOWshould all be
Quoted 1 line
consistent in being either optional or mandatory sleep
mode
Quoted 1 line
configurations?
No, according to current implementation (and IMO, it is _not_ a bug):
DRIVE_HIGHandDRIVE_LOWare mandatory,KEEP_OUTPUTis optional.Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
yet for some reason it is being allowed to
prevent the
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
setting of PGSR in the case of GPIO inputs.
Because, the PGSR is valid only for GPIO outputs!
and has nothing to do with inputs.I know, it makes no sense to specify
KEEP_OUTPUT,
DRIVE_HIGHorDRIVE_LOWQuoted 1 line
for GPIO inputs.
That's the point, that it does make sense for certain cases,
when you want the GPIO to be bidirectional, but output in suspend.
This allows certain flexibility.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
But since
DRIVE_HIGHorDRIVE_LOWcurrently don'tprevent that,
Don't prevent what?
Don't prevent a GPIO input being changed to an output when entering
suspend().
Why should they prevent that? In case of bidirectional GPIOs it is perfectly fine.
Quoted 4 lines
By the way, there is still the issue of
DRIVE_HIGHandDRIVE_LOWforcing the GPIO direction to output inpxa2xx_mfp_suspend()*before* the PGSR values take effect. Surely a bug?
No, the order is not important as the final setting is done by the h/w during the suspend transition.
Quoted 45 lines
Quoted 45 lines
DRIVE_HIGHandDRIVE_LOWallow you to do
what
ever you want with the GPIO in runtime, but have it strictly configured
for the suspend.Quoted 2 lines
the
presumption must be that GPIOs configured asDRIVE_HIGHor
DRIVE_LOWareQuoted 1 line
being used as outputs. Likewise for
KEEP_OUTPUT?
KEEP_OUTPUTonly affects the GPIOs configured for output in runtime
and let you keep the last output value.Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Consequently the (GPDR(i) &
GPIO_bit(i))test
Quoted 4 lines
Quoted 4 lines
should be removed.
No, absolutely not!
This will change the meaning of the
MFP_LPM_KEEP_OUTPUTQuoted 3 lines
Quoted 1 line
symbol!
Only if you interpret
KEEP_OUTPUTas an optional sleepmode configuration.
That what the current implementation does and IMO, it is the right thing.
Quoted 2 lines
Quoted 2 lines
I have a feeling that you are trying to solve a
problem that
Quoted 4 lines
Quoted 1 line
does not exist!
The problem is that MFP configurations of the form:
GPIO<n>_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 1 line
will always set the sleep mode gpio direction to
INPUT.
Quoted 1 line
That is the case with corgi and would also be the case
Quoted 8 lines
Quoted 6 lines
with hx4700.
Quoted 1 line
That is the problem which needs to be solved.
Yes, it is just there is no h/w MFP in PXA2xx and all the stuff done in s/w.
That is the reason it is a bit mess.It's more than a mess: it's broken, per the current corgi configuration.
Ok. Indeed it looks broken even with my meaning of KEEP_OUTPUT, because of the line that sets all GPDRs to gpdr_lpm values in pxa2xx_mfp_suspend() function.
Quoted 8 lines
Quoted 6 lines
IMO, the cleanest solution would be to have GPIO<n>_GPIO_OUT for each
GPIO that needs to be configured as output instead of breaking the
already fragile MFP logic.And similarly fix the corgi configuration.
Please, check the attached patch.
It should not change the meaning of KEEP_OUTPUT, but fix the bug.
[...] remove unreadable stuff...
Quoted 66 lines
Quoted 66 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
The feeling was that if the unit was charging
in normal
Quoted 2 lines
Quoted 2 lines
mode then it
Quoted 1 line
should remain charging in sleep mode, and if it
wasn't
Quoted 8 lines
Quoted 8 lines
then it should
Quoted 1 line
remain not charging.
Ok, finally we are talking about a real problem... I see...
IMO, the best solution will be to add a genericGPIOx_GPIO_OUT
(as already proposed by Haojian) definition (wherex is the
Quoted 1 line
Quoted 1 line
required GPIO number)for your used GPIOs and use it
in MFP
Quoted 2 lines
Quoted 2 lines
config
structure for hx4700 along with
MFP_LPM_KEEP_OUTPUT.Quoted 4 lines
Quoted 4 lines
Another solution would be (though a bit hackish):
GPIOx_GPIO|MFP_LPM_DRIVE_LOW|
MFP_LPM_KEEP_OUTPUTQuoted 2 lines
Quoted 2 lines
The above should work for you as you would expect -
will set
Quoted 2 lines
Quoted 2 lines
the GPIO
to be output low by default, then you willreconfigure it to
Quoted 2 lines
Quoted 2 lines
the
appropriate level from your charger driver and thenew level
Quoted 5 lines
Quoted 2 lines
will be used
by the existing logic inpxa2xx_mfp_suspend().Those solutions are fair enough.
Can we first answer the question of whether
KEEP_OUTPUT,DRIVE_HIGHandQuoted 1 line
DRIVE_LOWare optional or mandatory sleep modeconfigurations. That may
Quoted 1 line
determine the way forward.
Well for the
DRIVE_HIGHandDRIVE_LOW, the names speak for them selfs - MultiFunctionalPin_LowPowerManager_DRIVE_<HIGH|LOW> and there is no
questions arise.
For theMFP_LPM_KEEP_OUTPUT- is PXA2xx specific, apparently it is
confusing and probably has to have a comment explaining the meaning.From git log:
---------------cut---------------------
commit1106143d7ab43ba07678c88c85417df219354ae8Author: Eric Miao <[email protected]> Date: Mon Jan 11 21:25:15 2010 +0800[ARM] pxa: add
MFP_LPM_KEEP_OUTPUTflag to pin
configSome pins are expected to keep their last
level during suspend, and
introduceMFP_LPM_KEEP_OUTPUTfor this.
Quoted 7 lines
Quoted 4 lines
Signed-off-by Eric Miao <[email protected]>---------------cut---------------------
The key words above are: "keep their last level".
Which is exactly what would have happened with my patch, since all cases of
KEEP_OUTPUTwere indeed being applied to outputs only.
No, your patch will change also the inputs to outputs. Because "last level" does not apply to input pins.
Signature · 9 lines
Regards, Igor. -------------- next part -------------- A non-text attachment was scrubbed... Name: pxa2xx-mfp.patch Type: text/x-patch Size: 545 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120403/b1cfe5ee/attachment.bin>
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hello Igor,
Quoted 35 lines · Igor Grinberg
Quoted 2 lines · Paul Parsons
Hello Igor,
[...] Remove the unreadable stuff...
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
On corgi, the three GPIOs configured
as
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
MFP_LPM_KEEP_OUTPUT:Quoted 1 line
? ?
???CORGI_GPIO_LED_ORANGE
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
? ?
???CORGI_GPIO_CHRG_ON
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
? ?
???CORGI_GPIO_CHRG_UKN
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
are all used as outputs.
Have you verified it, because currently
MFP_LPM_KEEP_OUTPUTQuoted 1 line
Quoted 1 line
does not do a direction configuration...
and IMO,
Quoted 5 lines
Quoted 5 lines
it should
Quoted 4 lines
Quoted 1 line
not!
Yes, all 3 GPIOs are configured as outputs:
CORGI_GPIO_LED_ORANGEin
drivers/leds/leds-gpio.cQuoted 1 line
Quoted 1 line
Quoted 1 line
CORGI_GPIO_CHRG_ONin
arch/arm/mach-pxa/corgi_pm.cQuoted 1 line
Quoted 1 line
Quoted 1 line
CORGI_GPIO_CHRG_UKNin
arch/arm/mach-pxa/corgi_pm.cQuoted 2 lines
Quoted 2 lines
Good, then they will be kept output also in the
suspend
Quoted 8 lines
Quoted 2 lines
Quoted 2 lines
mode,
as for current implementation.Now I can see that it will not... because of the below line:
GPDR(i * 32)= gpdr_lpm[i];in the
pxa2xx_mfp_suspend()function.#
Which is precisely the issue this patch addresses, namely to force the gpdr_lpm[] direction to output for KEEP_OUTPUT configurations.
Quoted 49 lines
[...] remove unreadable stuff...
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Do you agree that
KEEP_OUTPUT,DRIVE_HIGHand
DRIVE_LOWQuoted 2 lines
Quoted 2 lines
should all be
Quoted 1 line
consistent in being either optional or
mandatory sleep
Quoted 4 lines
Quoted 4 lines
mode
Quoted 1 line
configurations?
No, according to current implementation (and IMO,
it is
Quoted 7 lines
Quoted 7 lines
_not_ a bug):
DRIVE_HIGHandDRIVE_LOWare mandatory,KEEP_OUTPUTis optional.Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
yet for some reason it is being allowed
to
Quoted 2 lines
Quoted 2 lines
prevent the
Quoted 1 line
Quoted 1 line
Quoted 1 line
setting of PGSR in the case of GPIO
inputs.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Because, the PGSR is valid only for GPIO
outputs!
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
and has nothing to do with inputs.
I know, it makes no sense to specify
KEEP_OUTPUT,Quoted 4 lines
Quoted 4 lines
DRIVE_HIGHorDRIVE_LOWQuoted 1 line
for GPIO inputs.
That's the point, that it does make sense for
certain
Quoted 2 lines
Quoted 2 lines
cases,
when you want the GPIO to be bidirectional, butoutput in
Quoted 4 lines
Quoted 4 lines
suspend.
This allows certain flexibility.Quoted 1 line
But since
DRIVE_HIGHorDRIVE_LOWcurrentlydon't
Quoted 4 lines
Quoted 3 lines
prevent that,
Don't prevent what?
Quoted 7 lines
Quoted 1 line
Don't prevent a GPIO input being changed to an output
when entering
Quoted 1 line
suspend().Why should they prevent that? In case of bidirectional GPIOs it is
perfectly fine.
I didn't say they should prevent that. I said they don't prevent that, thereby allowing the direction of an input gpio to be changed to output before the PGSR value is applied.
Quoted 11 lines
Quoted 3 lines
By the way, there is still the issue of
DRIVE_HIGHand
DRIVE_LOWQuoted 1 line
forcing the GPIO direction to output in
pxa2xx_mfp_suspend()Quoted 1 line
*before* the PGSR values take effect. Surely a bug?
No, the order is not important as the final setting is done by the h/w
during the suspend transition.
No, the GPIO direction is changed by software, not hardware. Hardware suspend does not change the GPIO direction, it only drives the GPIO values from the PGSR registers.
Thus there is a definite window between the direction being changed by software and the PGSR value being driven by hardware.
Within that window, the output values are indeterminate, at least as far as the suspend software is concerned.
So unless valid output values have already been programmed onto those input GPIOs beforehand, this direction/PGSR window is a bug.
Quoted 79 lines
Quoted 5 lines
Quoted 5 lines
DRIVE_HIGHandDRIVE_LOWallow you to do what
ever you want with the GPIO in runtime, but have itstrictly
Quoted 5 lines
Quoted 5 lines
configured
for the suspend.Quoted 2 lines
the
presumption must be that GPIOs configured as
DRIVE_HIGHQuoted 2 lines
Quoted 2 lines
or
DRIVE_LOWareQuoted 1 line
being used as outputs. Likewise for
KEEP_OUTPUT?Quoted 2 lines
Quoted 2 lines
KEEP_OUTPUTonly affects the GPIOs configured foroutput in
Quoted 7 lines
Quoted 7 lines
runtime
and let you keep the last output value.Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Consequently the (GPDR(i) &
GPIO_bit(i))Quoted 9 lines
Quoted 9 lines
test
Quoted 4 lines
Quoted 4 lines
should be removed.
No, absolutely not!
This will change the meaning of the
MFP_LPM_KEEP_OUTPUTQuoted 3 lines
Quoted 1 line
symbol!
Only if you interpret
KEEP_OUTPUTas anoptional sleep
Quoted 3 lines
Quoted 3 lines
mode configuration.
That what the current implementation does and IMO,
it is the
Quoted 4 lines
Quoted 4 lines
right thing.
Quoted 2 lines
Quoted 2 lines
I have a feeling that you are trying to
solve a
Quoted 4 lines
Quoted 4 lines
problem that
Quoted 3 lines
Quoted 1 line
does not exist!
The problem is that MFP configurations of the
form:
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
? ? ? GPIO<n>_GPIO |
MFP_LPM_KEEP_OUTPUT,Quoted 1 line
will always set the sleep mode gpio direction
to
Quoted 2 lines
Quoted 2 lines
INPUT.
Quoted 1 line
That is the case with corgi and would also be
the case
Quoted 4 lines
Quoted 4 lines
with hx4700.
Quoted 1 line
That is the problem which needs to be solved.
Yes, it is just there is no h/w MFP in PXA2xx and
all the
Quoted 4 lines
Quoted 2 lines
stuff done in s/w.
That is the reason it is a bit mess.It's more than a mess: it's broken, per the current
corgi configuration.
Ok. Indeed it looks broken even with my meaning of
KEEP_OUTPUT,
because of the line that sets all GPDRs togpdr_lpmvalues inpxa2xx_mfp_suspend()function.Quoted 4 lines
Quoted 4 lines
IMO, the cleanest solution would be to have GPIO<n>_GPIO_OUT for each
GPIO that needs to be configured as output insteadof
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
breaking the
already fragile MFP logic.And similarly fix the corgi configuration.
Please, check the attached patch.
It should not change the meaning ofKEEP_OUTPUT, but fix the bug.
Yes, that fixes the KEEP_OUTPUT bug.
It would be beneficial if someone could formally document the precise meaning of KEEP_OUTPUT.
The direction/PGSR window bug is still present though.
I'm starting to think it would be better for pxa2xx_mfp_suspend() to not touch GPDR at all, ever. Thus outputs would remain outputs, inputs would remain inputs. That would solve the latter bug and simplify PXA2xx MFP, but at the cost of making DRIVE_HIGH/DRIVE_LOW conditional like KEEP_OUTPUT.
It would be beneficial if someone could formally document the precise meaning of DRIVE_HIGH/DRIVE_LOW.
Quoted 93 lines
[...] remove unreadable stuff...
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
The feeling was that if the unit was
charging
Quoted 3 lines
Quoted 3 lines
in normal
Quoted 2 lines
Quoted 2 lines
mode then it
Quoted 1 line
should remain charging in sleep mode,
and if it
Quoted 5 lines
Quoted 5 lines
wasn't
Quoted 4 lines
Quoted 4 lines
then it should
Quoted 1 line
remain not charging.
Ok, finally we are talking about a real
problem...
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
I see...
IMO, the best solution will be to add ageneric
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
GPIOx_GPIO_OUT
(as already proposed by Haojian) definition(where
Quoted 2 lines
Quoted 2 lines
x is the
Quoted 1 line
Quoted 1 line
required GPIO number)for your used GPIOs
and use it
Quoted 7 lines
Quoted 7 lines
in MFP
Quoted 2 lines
Quoted 2 lines
config
structure for hx4700 along with
MFP_LPM_KEEP_OUTPUT.Quoted 3 lines
Quoted 3 lines
Another solution would be (though a bit
hackish):
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line
GPIOx_GPIO|MFP_LPM_DRIVE_LOW|
MFP_LPM_KEEP_OUTPUTQuoted 2 lines
Quoted 2 lines
The above should work for you as you would
expect -
Quoted 6 lines
Quoted 6 lines
will set
Quoted 2 lines
Quoted 2 lines
the GPIO
to be output low by default, then you willreconfigure it to
Quoted 2 lines
Quoted 2 lines
the
appropriate level from your charger driverand the
Quoted 3 lines
Quoted 3 lines
new level
Quoted 2 lines
Quoted 2 lines
will be used
by the existing logic in
pxa2xx_mfp_suspend().Quoted 9 lines
Quoted 9 lines
Quoted 3 lines
Those solutions are fair enough.
Can we first answer the question of whether
KEEP_OUTPUT,DRIVE_HIGHandQuoted 1 line
DRIVE_LOWare optional or mandatory sleep modeconfigurations. That may
Quoted 1 line
determine the way forward.
Well for the
DRIVE_HIGHandDRIVE_LOW, the namesspeak for
Quoted 2 lines
Quoted 2 lines
them selfs -
MultiFunctionalPin_LowPowerManager_DRIVE_<HIGH|LOW>
Quoted 3 lines
Quoted 3 lines
and there is no
questions arise.
For theMFP_LPM_KEEP_OUTPUT- is PXA2xx specific,apparently
Quoted 2 lines
Quoted 2 lines
it is
confusing and probably has to have a commentexplaining the
Quoted 7 lines
Quoted 7 lines
meaning.
From git log:
---------------cut---------------------
commit1106143d7ab43ba07678c88c85417df219354ae8
Author: Eric Miao <[email protected]>
Date:???Mon Jan 11 21:25:15 2010+0800
Quoted 2 lines
Quoted 2 lines
? ???[ARM] pxa: add
MFP_LPM_KEEP_OUTPUTflag to pinQuoted 3 lines
Quoted 3 lines
config
? ???
? ???Some pins are expected tokeep their last
Quoted 2 lines
Quoted 2 lines
level during suspend, and
? ???introduce
MFP_LPM_KEEP_OUTPUTfor this.Quoted 2 lines
Quoted 2 lines
? ???
? ???Signed-off-by: Eric MiaoQuoted 4 lines
Quoted 3 lines
---------------cut---------------------
The key words above are: "keep their last level".
Quoted 7 lines
Quoted 1 line
Which is exactly what would have happened with my
patch, since all
Quoted 1 line
cases of
KEEP_OUTPUTwere indeed being applied tooutputs only.
No, your patch will change also the inputs to outputs. Because "last level" does not apply to input pins.
My point was that KEEP_OUTPUT configurations are only applied to GPIOs used as outputs. So no directions would be changed in practice.
Regards,
Paul
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Quoted 1 line · Paul Parsons
Hello Igor,
[...]
Quoted 8 lines
Quoted 5 lines
Now I can see that it will not... because of the below line:
GPDR(i * 32)= gpdr_lpm[i];in the
pxa2xx_mfp_suspend()function.#Which is precisely the issue this patch addresses, namely to force the gpdr_lpm[] direction to output for
KEEP_OUTPUTconfigurations.
Yes, but it changes the meaning of KEEP_OUTPUT and that is not good.
[...]
Quoted 11 lines
Quoted 7 lines
Quoted 1 line
Don't prevent a GPIO input being changed to an output
when entering
Quoted 1 line
suspend().Why should they prevent that? In case of bidirectional GPIOs it is
perfectly fine.I didn't say they should prevent that. I said they don't prevent that, thereby allowing the direction of an input gpio to be changed to output before the PGSR value is applied.
Ok, I see.
Quoted 9 lines
Quoted 9 lines
Quoted 4 lines
By the way, there is still the issue of
DRIVE_HIGHand
DRIVE_LOWQuoted 1 line
forcing the GPIO direction to output in
pxa2xx_mfp_suspend()Quoted 1 line
*before* the PGSR values take effect. Surely a bug?
Quoted 7 lines
Quoted 3 lines
No, the order is not important as the final setting is done by the h/w
during the suspend transition.No, the GPIO direction is changed by software, not hardware. Hardware suspend does not change the GPIO direction, it only drives the GPIO values from the PGSR registers.
Yes, that is correct.
Quoted 3 lines
Thus there is a definite window between the direction being changed by software and the PGSR value being driven by hardware.
Right, this is the cost of lack of the h/w MFP support :-(
Quoted 6 lines
Within that window, the output values are indeterminate, at least as far as the suspend software is concerned.
So unless valid output values have already been programmed onto those input GPIOs beforehand, this direction/PGSR window is a bug.
Yep, sounds correct.
[...]
Quoted 5 lines
Quoted 3 lines
Please, check the attached patch.
It should not change the meaning ofKEEP_OUTPUT, but fix the bug.Yes, that fixes the
KEEP_OUTPUTbug.
Can this be considered as Tested-by for the formal patch?
Quoted 3 lines
It would be beneficial if someone could formally document the precise meaning of
KEEP_OUTPUT.
I will try to do it along with the formal patch submission.
Quoted 2 lines
The direction/PGSR window bug is still present though.
Yet another patch "closing windows" attached,
care to check/test it please?
Quoted 6 lines
I'm starting to think it would be better for
pxa2xx_mfp_suspend()to not touch GPDR at all, ever. Thus outputs would remain outputs, inputs would remain inputs. That would solve the latter bug and simplify PXA2xx MFP, but at the cost of making DRIVE_HIGH/DRIVE_LOW conditional likeKEEP_OUTPUT.
I don't think it is a good idea, because then DRIVE_HIGH/DRIVE_LOW will have different meaning between the platforms (SoCs).
How about the attached patch to fix this "windows" thing for PXA2xx?
Quoted 3 lines
It would be beneficial if someone could formally document the precise meaning of DRIVE_HIGH/DRIVE_LOW.
I can try doing it along with the formal version of the attached patch, if we will consider it as a solution.
[...]
Quoted 5 lines
Quoted 2 lines
No, your patch will change also the inputs to outputs. Because "last level" does not apply to input pins.
My point was that
KEEP_OUTPUTconfigurations are only applied to GPIOs used as outputs. So no directions would be changed in practice.
I failed to understand that from your previous posts. Nevertheless, the patch in the previous email fixes exactly this.
Signature · 9 lines
Regards, Igor. -------------- next part -------------- A non-text attachment was scrubbed... Name: pxa2xx-mfp2.patch Type: text/x-patch Size: 763 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120403/03d40497/attachment.bin>
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hmmm....
If we change the GPSR and GPCR, the old levels should be reserved, right? Attached...
Signature · 9 lines
Regards, Igor. -------------- next part -------------- A non-text attachment was scrubbed... Name: pxa2xx-mfp2.patch Type: text/x-patch Size: 1444 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120403/c3e05cd2/attachment.bin>
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Quoted 4 lines · Igor Grinberg
Hmmm....
If we change the GPSR and GPCR, the old levels should be reserved, right?
Attached...
Yes, that sounds right: if resume() restores the old directions then it makes sense for it to restore the old levels first. Otherwise it encounters the same problem as suspend().
On that very subject, I notice that __mfp_config_gpio() also sets directions without first setting levels.
Problem is, it is not obvious what levels it should set. Perhaps it should likewise set the levels to the PGSR values, on the tenuous presumption that any hardware should already be in low power mode at the time __mfp_config_gpio() is called.
But then again maybe not. This is more tricky.
I'll give the patches a try before the end of the day.
Regards,
Paul
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hi Paul,
Sorry for a delay, I've been a bit busy with work...
Quoted 6 lines · Paul Parsons
Quoted 4 lines · Igor Grinberg
Hmmm....
If we change the GPSR and GPCR, the old levels should be reserved, right?
Attached...
Quoted 6 lines
Yes, that sounds right: if
resume()restores the old directions then it makes sense for it to restore the old levels first. Otherwise it encounters the same problem assuspend().On that very subject, I notice that
__mfp_config_gpio()also sets directions without first setting levels.
Hmmm... this is not good, but...
Quoted 6 lines
Problem is, it is not obvious what levels it should set. Perhaps it should likewise set the levels to the PGSR values, on the tenuous presumption that any hardware should already be in low power mode at the time
__mfp_config_gpio()is called.
But then again maybe not. This is more tricky.
Well, it looks like most of the cases the __mfp_config_gpio() is called during init time and the levels are setup only later and PGSR still has its reset values.
This leaves the direction outputs without a defined level, but having the MFP_CFG_IN() as the default setting is the right thing and probably assures the "safeness" of the __mfp_config_gpio().
Also, that is exactly why we should not use the MFP_CFG_OUT() directly.
I agree with you that probably the __mfp_config_gpio() function should not touch the GPDR, but changing this has affect on all PXA2xx boards, so I would *not* touch that until there is a real issue.
Quoted 2 lines
I'll give the patches a try before the end of the day.
Thanks
Signature · 2 lines
Regards, Igor.
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
In reply to Igor GrinbergHello Igor,
Quoted 4 lines · Igor Grinberg
Hmmm....
If we change the GPSR and GPCR, the old levels should be reserved, right?
Attached...
Your patch - pxa2xx-mfp2.patch - doesn't introduce any problems, but I never had a failure case that could be used to prove the patch fixes the direction/PGSR window bug. In theory the patch *should* fix it.
As for restoring the GPIO levels via GPSR and GPCR, that does seem to work. Certainly the regular GPIO (AF0) outputs have their levels restored OK.
Regards,
Paul
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
In reply to Igor GrinbergHello Igor,
Quoted 3 lines · Igor Grinberg
Please, check the attached patch.
It should not change the meaning ofKEEP_OUTPUT, but fix the bug.
Yes, your patch - pxa2xx-mfp.patch - does fix the KEEP_OUTPUT bug.
Regards,
Paul
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hi Paul,
Quoted 8 lines · Paul Parsons
Hello Igor,
Quoted 3 lines · Igor Grinberg
Please, check the attached patch.
It should not change the meaning ofKEEP_OUTPUT, but fix the bug.Yes, your patch - pxa2xx-mfp.patch - does fix the
KEEP_OUTPUTbug.
Looking at it one more time, we setup the GPDR with values from gpdr_lpm, and afterwards we setup them once again to update for KEEP_CONFIG. This can introduce a kind of spike on the GPIO (depending on how fast the system runs).
So, fixed patch attached. Can you please test it once more and I will submit it properly?
Signature · 9 lines
Regards, Igor. -------------- next part -------------- A non-text attachment was scrubbed... Name: pxa2xx-mfp.patch Type: text/x-patch Size: 817 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120405/abeb7b52/attachment.bin>
PATCH 1/1 ARM: pxa: mfp: Force gpio direction for MFP_LPM_KEEP_OUTPUT
Hello Igor,
Quoted 8 lines · Igor Grinberg
Quoted 2 lines
Quoted 2 lines
Please, check the attached patch.
It should not change the meaning ofKEEP_OUTPUT,but fix the
Quoted 3 lines
Quoted 1 line
bug.
Yes, your patch - pxa2xx-mfp.patch - does fix the
KEEP_OUTPUTbug.
Quoted 10 lines
Looking at it one more time, we setup the GPDR with values from
gpdr_lpm,
and afterwards we setup them once again to update forKEEP_CONFIG.
This can introduce a kind of spike on the GPIO (depending on how fast
the system runs).
So, fixed patch attached. Can you please test it once more and I will
submit it properly?
Yes, I've tested it and this new patch fixes the KEEP_OUTPUT bug.
Regards,
Paul