Skip to contentSkip to conversation

ARM: PXA: Zipit Z2: Fix oops in z2_power_off

PATCH New Vasily Khoruzhick 3 participants 18 messages Feb 26, 2012 – Feb 27, 2012

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/3 ARM: PXA: Zipit Z2: Fix oops in z2_power_off

pxa27x_set_pwrmode is marked with __init, so it's not legitimate to call it in pm_power_off hook.

---
 arch/arm/mach-pxa/include/mach/pxa27x.h |    2 +-
 arch/arm/mach-pxa/pxa27x.c              |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
arch/arm/mach-pxa/include/mach/pxa27x.h +1 -1
index 7cff640..66c4cbf 100644
@@ -21,7 +21,7 @@
 
 extern void __init pxa27x_map_io(void);
 extern void __init pxa27x_init_irq(void);
-extern int __init pxa27x_set_pwrmode(unsigned int mode);
+extern int pxa27x_set_pwrmode(unsigned int mode);
 extern void pxa27x_cpu_pm_enter(suspend_state_t state);
 
 #define pxa27x_handle_irq	ichp_handle_irq
arch/arm/mach-pxa/pxa27x.c +1 -1
index bc5a98e..acbaa2b 100644
@@ -241,7 +241,7 @@ static struct clk_lookup pxa27x_clkregs[] = {
  */
 static unsigned int pwrmode = PWRMODE_SLEEP;
 
-int __init pxa27x_set_pwrmode(unsigned int mode)
+int pxa27x_set_pwrmode(unsigned int mode)
 {
 	switch (mode) {
 	case PWRMODE_SLEEP:
Signature · 1 line
1.7.9.2
#1 lore raw

PATCH 2/3 ARM: PXA27x: save/restore PWER on suspend/resume

Bootloader can clobber PWER value, so save it state on suspend.

---
 arch/arm/mach-pxa/pxa27x.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/arm/mach-pxa/pxa27x.c +3 -1
index acbaa2b..2951872 100644
@@ -262,6 +262,7 @@ enum {
 	SLEEP_SAVE_PSTR,
 	SLEEP_SAVE_MDREFR,
 	SLEEP_SAVE_PCFR,
+	SLEEP_SAVE_PWER,
 	SLEEP_SAVE_COUNT
 };
 
@@ -269,7 +270,7 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save)
 {
 	sleep_save[SLEEP_SAVE_MDREFR] = __raw_readl(MDREFR);
 	SAVE(PCFR);
-
+	SAVE(PWER);
 	SAVE(PSTR);
 }
 
@@ -281,6 +282,7 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
 	PSSR = PSSR_RDH | PSSR_PH;
 
 	RESTORE(PSTR);
+	RESTORE(PWER);
 }
 
 void pxa27x_cpu_pm_enter(suspend_state_t state)
Signature · 1 line
1.7.9.2
#2 lore raw

PATCH 2/3 ARM: PXA27x: save/restore PWER on suspend/resume

Quoted 1 line · Vasily Khoruzhick

Bootloader can clobber PWER value, so save it state on suspend.

What boot loader is this, and why is it being so idiotic? Why can't it be fixed?

#3 lore raw

PATCH 2/3 ARM: PXA27x: save/restore PWER on suspend/resume

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 5 lines · Vasily Khoruzhick
Quoted 1 line

Bootloader can clobber PWER value, so save it state on suspend.

What boot loader is this, and why is it being so idiotic? ?Why can't it be fixed?

I'm using u-boot on this machine...
Hmm, I've looked throuhg its sources and did not find where it can clobber it. But PWER register value is not preserved across suspend for some reason (at least bit 0). Maybe it's some conflict with gpiolib? But gpio_set_wake() doesn't work
for me on PXA.

Regards
Vasily

#4 lore raw

PATCH 2/3 ARM: PXA27x: save/restore PWER on suspend/resume

Quoted 7 lines · Vasily Khoruzhick

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 5 lines · Vasily Khoruzhick
Quoted 1 line

Bootloader can clobber PWER value, so save it state on suspend.

What boot loader is this, and why is it being so idiotic? ?Why can't it be fixed?

Quoted 6 lines

I'm using u-boot on this machine...
Hmm, I've looked throuhg its sources and did not find where it can clobber it. But PWER register value is not preserved across suspend for some reason (at least bit 0). Maybe it's some conflict with gpiolib? But gpio_set_wake() doesn't work
for me on PXA.

It sounds like some more debugging is required.

I assume that you've done some basic things, such as:

(1) checking the return value of gpio_set_wake()
(2) checking what's going on internally in gpio_set_wake()

Most users of gpio_set_wake() do not seem to check its return value, so if it fails you'll never know about it except by seeing incorrect values in PWER.

#5 lore raw

PATCH 2/3 ARM: PXA27x: save/restore PWER on suspend/resume

In reply to Russell King - ARM Linux
Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

Bootloader can clobber PWER value, so save it state on suspend.

What boot loader is this,

U-Boot, patched, not mainline.

Quoted 1 line

and why is it being so idiotic?

Mainline doesn't touch PWER, so please be careful about your accusations.

Quoted 2 lines

Why can't it
be fixed?

Yes, either by using mainline uboot (to rule out the bootloader problem), finding bug in linux kernel or reading the CPU manual.

M

PS. Vasily, keep me in Cc next time.

#6 lore raw

PATCH 2/3 ARM: PXA27x: save/restore PWER on suspend/resume

Quoted 9 lines · Marek Vasut
Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

Bootloader can clobber PWER value, so save it state on suspend.

What boot loader is this,

U-Boot, patched, not mainline.

Quoted 1 line

and why is it being so idiotic?

Quoted 7 lines

Mainline doesn't touch PWER, so please be careful about your accusations.

Quoted 2 lines

Why can't it
be fixed?

Yes, either by using mainline uboot (to rule out the bootloader problem), finding bug in linux kernel or reading the CPU manual.

Was there supposed to be any useful information in your reply, or are you just trying to be your usual antagonistic self?

#7 lore raw

PATCH 2/3 ARM: PXA27x: save/restore PWER on suspend/resume

Quoted 12 lines · Marek Vasut
Quoted 11 lines
Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

Bootloader can clobber PWER value, so save it state on suspend.

What boot loader is this,

U-Boot, patched, not mainline.

Quoted 1 line

and why is it being so idiotic?

Mainline doesn't touch PWER, so please be careful about your accusations.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Why can't it
be fixed?

Yes, either by using mainline uboot (to rule out the bootloader problem), finding bug in linux kernel or reading the CPU manual.

Was there supposed to be any useful information in your reply, or are you just trying to be your usual antagonistic self?

Um ...

1) PWER isn't reconfigured by uboot (see above)
2) That you should try mainline uboot to avoid debugging problems with not- mainlined patches
3) That the bug with PWER is likely in kernel, since there's an issue with gpio_set_wake() on PXA
4) That the CPU might not preserve PWER throughout the suspend and that this information might be found in the CPU manual

I was a bit terse there, sorry.

M

#8 lore raw

PATCH 2/3 ARM: PXA27x: save/restore PWER on suspend/resume

Quoted 18 lines · Marek Vasut
Quoted 18 lines · Marek Vasut
Quoted 16 lines
Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

Bootloader can clobber PWER value, so save it state on suspend.

What boot loader is this,

U-Boot, patched, not mainline.

Quoted 1 line

and why is it being so idiotic?

Mainline doesn't touch PWER, so please be careful about your accusations.

Quoted 2 lines

Why can't it
be fixed?

Yes, either by using mainline uboot (to rule out the bootloader problem), finding bug in linux kernel or reading the CPU manual.

Quoted 6 lines
Quoted 2 lines

Was there supposed to be any useful information in your reply, or are you just trying to be your usual antagonistic self?

Um ...

1) PWER isn't reconfigured by uboot (see above)

Given that virtually everyone seems to use a modified version of uboot, how can you be so sure?

Quoted 2 lines

2) That you should try mainline uboot to avoid debugging problems with not- mainlined patches

Why should _I_ try anything with uboot? I'm not the one experiencing problems.

I'll point out that Vasily is reporting that _his_ boot loader, whatever it is, is clobbering the PWER register. That's *his* statement in the commit log, and I have no reason *not* to think that he's put in the research to confirm that. Otherwise, why make such a positive statement about where the problem lies?

Quoted 2 lines

3) That the bug with PWER is likely in kernel, since there's an issue with gpio_set_wake() on PXA

I've reviewed this function and its associated data, and can't see anything wrong with it (see below).

Quoted 2 lines

4) That the CPU might not preserve PWER throughout the suspend and that this information might be found in the CPU manual

No. The PXA270 manual says that this register is preserved on exit from deep sleep and sleep modes. It appends a note against each bit in the reset status for the PWER register which says "Exit from sleep or deep sleep mode does not clear or set this bit".

The setup for GPIO0 is:

        for (i = 0; i <= 15; i++) {
                /* skip GPIO2, 5, 6, 7, 8 */
                if (GPIO_bit(i) & 0x1e4)
                        continue;

                gpio_desc[i].can_wakeup = 1;
                gpio_desc[i].mask = GPIO_bit(i);
        }

So, gpio_desc[0].can_wakeup = 1 and gpio_desc[0].mask is the bitmask for GPIO0.

gpio_set_wake() does this:

        d = &gpio_desc[gpio];
        c = d->config;

        if (!d->valid)
                return -EINVAL;

well, that's already been set valid by pxa27x_mfp_init().

        if (d->keypad_gpio && (MFP_AF(d->config) == 0) &&

it's not a keypad gpio...

        mux_taken = (PWER & d->mux_mask) & (~d->mask);
        if (on && mux_taken)
                return -EBUSY;

well, d->mux_mask is zero, so this check fails.

        if (d->can_wakeup && (c & MFP_LPM_CAN_WAKEUP)) {
                if (on) {
                        PWER = (PWER & ~d->mux_mask) | d->mask;

Now, we know d->can_wakeup is true. However, what about the MFP configuration?

Well, that depends on the platform. I suspect that's where the problem with wakeup sources not working is located, because the MFP configuration hasn't been properly set, and that comes from platform code.

So please, stop blaming PXA code without full and proper analysis of bugs. It's a waste of everyone's time, and it hurts proper kernel maintenance if these ill-researched 'workarounds' get merged instead of proper fixes.

#9 lore raw

PATCH 2/3 ARM: PXA27x: save/restore PWER on suspend/resume

Quoted 23 lines · Marek Vasut
Quoted 22 lines
Quoted 21 lines · Marek Vasut
Quoted 9 lines
Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

Bootloader can clobber PWER value, so save it state on suspend.

What boot loader is this,

U-Boot, patched, not mainline.

Quoted 1 line

and why is it being so idiotic?

Quoted 8 lines

Mainline doesn't touch PWER, so please be careful about your accusations.

Quoted 2 lines

Why can't it
be fixed?

Yes, either by using mainline uboot (to rule out the bootloader problem), finding bug in linux kernel or reading the CPU manual.

Was there supposed to be any useful information in your reply, or are you just trying to be your usual antagonistic self?

Quoted 6 lines
Quoted 3 lines

Um ...

1) PWER isn't reconfigured by uboot (see above)

Given that virtually everyone seems to use a modified version of uboot, how can you be so sure?

It's impossible to support every single version of some bootloader patched in various obscure ways, sorry.

Quoted 4 lines
Quoted 3 lines

2) That you should try mainline uboot to avoid debugging problems with not- mainlined patches

Quoted 8 lines

Why should _I_ try anything with uboot? I'm not the one experiencing problems.

I'll point out that Vasily is reporting that _his_ boot loader, whatever it is, is clobbering the PWER register. That's *his* statement in the commit log, and I have no reason *not* to think that he's put in the research to confirm that. Otherwise, why make such a positive statement about where the problem lies?

Well if it does clober the register, he should use bootloader that's not broken.

Quoted 53 lines
Quoted 3 lines

3) That the bug with PWER is likely in kernel, since there's an issue with gpio_set_wake() on PXA

I've reviewed this function and its associated data, and can't see anything wrong with it (see below).

Quoted 2 lines

4) That the CPU might not preserve PWER throughout the suspend and that this information might be found in the CPU manual

No. The PXA270 manual says that this register is preserved on exit from deep sleep and sleep modes. It appends a note against each bit in the reset status for the PWER register which says "Exit from sleep or deep sleep mode does not clear or set this bit".

The setup for GPIO0 is:

        for (i = 0; i <= 15; i++) {
                /* skip GPIO2, 5, 6, 7, 8 */
                if (GPIO_bit(i) & 0x1e4)
                        continue;

                gpio_desc[i].can_wakeup = 1;
                gpio_desc[i].mask = GPIO_bit(i);
        }

So, gpio_desc[0].can_wakeup = 1 and gpio_desc[0].mask is the bitmask for GPIO0.

gpio_set_wake() does this:

        d = &gpio_desc[gpio];
        c = d->config;

        if (!d->valid)
                return -EINVAL;

well, that's already been set valid by pxa27x_mfp_init().

        if (d->keypad_gpio && (MFP_AF(d->config) == 0) &&

it's not a keypad gpio...

        mux_taken = (PWER & d->mux_mask) & (~d->mask);
        if (on && mux_taken)
                return -EBUSY;

well, d->mux_mask is zero, so this check fails.

        if (d->can_wakeup && (c & MFP_LPM_CAN_WAKEUP)) {
                if (on) {
                        PWER = (PWER & ~d->mux_mask) | d->mask;
Quoted 6 lines

Now, we know d->can_wakeup is true. However, what about the MFP configuration?

Well, that depends on the platform. I suspect that's where the problem with wakeup sources not working is located, because the MFP configuration hasn't been properly set, and that comes from platform code.

Ok, agreed.

Quoted 3 lines

So please, stop blaming PXA code without full and proper analysis of bugs.

I said in kernel, not in PXA code.

Quoted 3 lines

It's a waste of everyone's time, and it hurts proper kernel maintenance if these ill-researched 'workarounds' get merged instead of proper fixes.

Agreed. So this all boils down to the point where Vasily should check his MFP settings.

M

#10 lore raw

PATCH 3/3 ARM: PXA27x: Zipit Z2: disable wake on GPIO0

In reply to Vasily Khoruzhick

We don't want machine to wake up on AC state change

---
 arch/arm/mach-pxa/z2.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
arch/arm/mach-pxa/z2.c +8 -1
index 0fb5617..bb672ee 100644
@@ -746,6 +746,13 @@ static void z2_power_off(void)
 #define z2_power_off   NULL
 #endif
 
+static void __init z2_map_io(void)
+{
+	pxa27x_map_io();
+
+	PWER &= ~(1 << 0);
+}
+
 /******************************************************************************
  * Machine init
  ******************************************************************************/
@@ -776,7 +783,7 @@ static void __init z2_init(void)
 
 MACHINE_START(ZIPIT2, "Zipit Z2")
 	.atag_offset	= 0x100,
-	.map_io		= pxa27x_map_io,
+	.map_io		= z2_map_io,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
Signature · 1 line
1.7.9.2
#11 lore raw

PATCH 3/3 ARM: PXA27x: Zipit Z2: disable wake on GPIO0

Quoted 1 line · Vasily Khoruzhick

We don't want machine to wake up on AC state change

NAK. Stop polluting the machine callback methods. Use the right one.

Quoted 41 lines
---
 arch/arm/mach-pxa/z2.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
arch/arm/mach-pxa/z2.c +8 -1
index 0fb5617..bb672ee 100644
@@ -746,6 +746,13 @@ static void z2_power_off(void)
 #define z2_power_off   NULL
 #endif
 
+static void __init z2_map_io(void)
+{
+	pxa27x_map_io();
+
+	PWER &= ~(1 << 0);
+}
+
 /******************************************************************************
  * Machine init
  ******************************************************************************/
@@ -776,7 +783,7 @@ static void __init z2_init(void)
 
 MACHINE_START(ZIPIT2, "Zipit Z2")
 	.atag_offset	= 0x100,
-	.map_io		= pxa27x_map_io,
+	.map_io		= z2_map_io,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
Signature · 7 lines
1.7.9.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
#12 lore raw

PATCH 3/3 ARM: PXA27x: Zipit Z2: disable wake on GPIO0

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

We don't want machine to wake up on AC state change

NAK. ?Stop polluting the machine callback methods. ?Use the right one.

Ok, what's right one?

#13 lore raw

PATCH 3/3 ARM: PXA27x: Zipit Z2: disable wake on GPIO0

Quoted 7 lines · Vasily Khoruzhick

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

We don't want machine to wake up on AC state change

NAK. ?Stop polluting the machine callback methods. ?Use the right one.

Ok, what's right one?

void (*fixup)(struct tag *, char **,
struct meminfo *);
void (*reserve)(void);/* reserve mem blocks */
void (*map_io)(void);/* IO mapping function */
void (*init_early)(void);
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);

and chose a more appropriate one from that? Maybe init_early() if it has to be done early, or preferably the init_machine() if it can wait until arch_initcall() time.

But stuffing it into fixup, reserve, map_io, init_irq or the timer initialization is pure abuse of those callbacks.

#14 lore raw

PATCH 3/3 ARM: PXA27x: Zipit Z2: disable wake on GPIO0

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 18 lines · Vasily Khoruzhick
Quoted 7 lines

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

We don't want machine to wake up on AC state change

NAK. ?Stop polluting the machine callback methods. ?Use the right one.

Ok, what's right one?

? ? ? ?void ? ? ? ? ? ? ? ? ? ?(*fixup)(struct tag *, char **, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct meminfo *);
? ? ? ?void ? ? ? ? ? ? ? ? ? ?(*reserve)(void);/* reserve mem blocks ?*/ ? ? ? ?void ? ? ? ? ? ? ? ? ? ?(*map_io)(void);/* IO mapping function ?*/ ? ? ? ?void ? ? ? ? ? ? ? ? ? ?(*init_early)(void);
? ? ? ?void ? ? ? ? ? ? ? ? ? ?(*init_irq)(void);
? ? ? ?struct sys_timer ? ? ? ?*timer; ? ? ? ? /* system tick timer ? ?*/ ? ? ? ?void ? ? ? ? ? ? ? ? ? ?(*init_machine)(void);

Quoted 6 lines

and chose a more appropriate one from that? ?Maybe init_early() if it has to be done early, or preferably the init_machine() if it can wait until arch_initcall() time.

But stuffing it into fixup, reserve, map_io, init_irq or the timer initialization is pure abuse of those callbacks.

Ok, thanks.

Regards
Vasily

#15 lore raw

PATCH 3/3 ARM: PXA27x: Zipit Z2: disable wake on GPIO0

Quoted 19 lines

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 18 lines · Vasily Khoruzhick
Quoted 7 lines

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

We don't want machine to wake up on AC state change

NAK. Stop polluting the machine callback methods. Use the right one.

Ok, what's right one?

void (*fixup)(struct tag *, char **,
struct meminfo *);
void (*reserve)(void);/* reserve mem blocks */
void (*map_io)(void);/* IO mapping function */
void (*init_early)(void);
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);

Quoted 9 lines
Quoted 6 lines

and chose a more appropriate one from that? Maybe init_early() if it has to be done early, or preferably the init_machine() if it can wait until arch_initcall() time.

But stuffing it into fixup, reserve, map_io, init_irq or the timer initialization is pure abuse of those callbacks.

Ok, thanks.

Or this should be patched in the bootloader too. Also, please dont introduce ad- hoc constants like "1 << 0", ever!

M

#16 lore raw

PATCH 3/3 ARM: PXA27x: Zipit Z2: disable wake on GPIO0

Quoted 23 lines · Marek Vasut
Quoted 23 lines

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 22 lines · Vasily Khoruzhick
Quoted 7 lines

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 4 lines · Vasily Khoruzhick
Quoted 1 line

We don't want machine to wake up on AC state change

NAK. Stop polluting the machine callback methods. Use the right one.

Ok, what's right one?

void (*fixup)(struct tag *, char **,
struct meminfo *);
void (*reserve)(void);/* reserve mem blocks */
void (*map_io)(void);/* IO mapping function */
void (*init_early)(void);
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);

and chose a more appropriate one from that? Maybe init_early() if it has to be done early, or preferably the init_machine() if it can wait until arch_initcall() time.

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

But stuffing it into fixup, reserve, map_io, init_irq or the timer initialization is pure abuse of those callbacks.

Ok, thanks.

Or this should be patched in the bootloader too. Also, please dont

* introduce ad-hoc constants like "1 << 0", ever!

Fiddling with PWER should not be in the boot loader. The kernel handles PWER just fine.

#17 lore raw

PATCH 3/3 ARM: PXA27x: Zipit Z2: disable wake on GPIO0

Quoted 30 lines · Marek Vasut
Quoted 29 lines
Quoted 29 lines

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 27 lines · Vasily Khoruzhick
Quoted 9 lines

2012/2/26 Russell King - ARM Linux <[email protected]>:

Quoted 5 lines · Vasily Khoruzhick
Quoted 1 line

We don't want machine to wake up on AC state change

NAK. Stop polluting the machine callback methods. Use the right one.

Ok, what's right one?

       void                    (*fixup)(struct tag *, char **,
       
                                        struct meminfo *);
       
       void                    (*reserve)(void);/* reserve mem blocks
        */ void                    (*map_io)(void);/* IO mapping
       function  */ void                    (*init_early)(void);
       void                    (*init_irq)(void);
       struct sys_timer        *timer;         /* system tick timer  
        */ void                    (*init_machine)(void);

and chose a more appropriate one from that? Maybe init_early() if it has to be done early, or preferably the init_machine() if it can wait until arch_initcall() time.

But stuffing it into fixup, reserve, map_io, init_irq or the timer initialization is pure abuse of those callbacks.

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

Ok, thanks.

Or this should be patched in the bootloader too. Also, please dont

* introduce ad-hoc constants like "1 << 0", ever!

Fiddling with PWER should not be in the boot loader. The kernel handles PWER just fine.

Right, good point