gpio: omap: be more aggressive with pm_runtime
Subsystems (6)
PATCH 1/1 gpio: omap: be more aggressive with pm_runtime
try to keep gpio block suspended as much as possible.
Tested with pandaboard and a sysfs exported gpio.
---
I couldn't see any issues with this patch. I managed to export a gpio and change the direction with a while true loop with no issues whatsoever.
Any chance someone tells me how to reproduce the original wakeup problem we had ?
I wrote a simple script to dump gpio states while I had:
while true; do echo in > /sys/class/gpio/gpio2/direction; \
echo out > /sys/class/gpio/gpio2/direction; done &
running. Here's the ouput:
./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 11945runtime_suspended_time 1214578
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1226468
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1226562
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1226578
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1226593
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 12234runtime_suspended_time 1215257
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1227437
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1227531
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1227546
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1227562
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 12460runtime_suspended_time 1215882
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1228289
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1228382
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1228398
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1228414
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 12734runtime_suspended_time 1216453
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1229132
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1229226
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1229242
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1229257
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status activeruntime_active_time 13007runtime_suspended_time 1216960
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1229914
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1230007
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1230023
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1230039
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 13234runtime_suspended_time 1217492
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1230671
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1230765
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1230781
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1230796
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 13453runtime_suspended_time 1218023
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1231421
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1231515
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1231531
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1231546
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 13703runtime_suspended_time 1218539
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1232187
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1232281
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1232296
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1232312
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status activeruntime_active_time 13890runtime_suspended_time 1219125
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1232960
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1233054
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1233070
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1233085
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 14109runtime_suspended_time 1219601
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1233656
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1233750
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1233765
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1233781
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 14367runtime_suspended_time 1220109
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1234421
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1234515
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1234531
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1234546
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 14531runtime_suspended_time 1220648
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 78runtime_suspended_time 1235125
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1235218
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1235234
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 1235250
see that the active time changes for omap_gpio.0 (first gpio bank) because I'm constantly changing direction of the exported gpio2, but the other banks are kept in suspend state. I even managed to catch the gpio bank while it was still in active state. Before suspending again.
drivers/gpio/gpio-omap.c | 61 +++++++++++++++++++++++++++++++++------------- 1 files changed, 44 insertions(+), 17 deletions(-)
drivers/gpio/gpio-omap.c +44 -17
@@ -537,12 +537,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);unsigned long flags; -/* -* If this is the first gpio_request for the bank, -* enable the bank module. -*/ -if (!bank->mod_usage) -pm_runtime_get_sync (bank->dev); +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);/* Set trigger to none. You need to enable the desired trigger with
@@ -572,6 +567,8 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); +return 0 ; }
@@ -581,6 +578,8 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)void __iomem *base = bank->base;unsigned long flags; +pm_runtime_get_sync (bank->dev); +spin_lock_irqsave (&bank->lock, flags);if (bank->regs->wkup_en) {
@@ -606,12 +605,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)_reset_gpio (bank, bank->chip.base + offset);spin_unlock_irqrestore (&bank->lock, flags); -/* -* If this is the last gpio to be freed in the bank, -* disable the bank module. -*/ -if (!bank->mod_usage) -pm_runtime_put (bank->dev); +pm_runtime_put (bank->dev); }/*
@@ -707,9 +701,11 @@ static void gpio_irq_shutdown(struct irq_data *d)struct gpio_bank *bank =irq_data_get_irq_chip_data (d);unsigned long flags; +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);_reset_gpio (bank, gpio);spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); }static void gpio_ack_irq (struct irq_data *d)
@@ -717,7 +713,9 @@ static void gpio_ack_irq(struct irq_data *d)unsigned int gpio = d->irq -IH_GPIO_BASE ;struct gpio_bank *bank =irq_data_get_irq_chip_data (d); +pm_runtime_get_sync (bank->dev);_clear_gpio_irqstatus (bank, gpio); +pm_runtime_put (bank->dev); }static void gpio_mask_irq (struct irq_data *d)
@@ -726,10 +724,12 @@ static void gpio_mask_irq(struct irq_data *d)struct gpio_bank *bank =irq_data_get_irq_chip_data (d);unsigned long flags; +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);_set_gpio_irqenable (bank, gpio,0 );_set_gpio_triggering (bank,GPIO_INDEX (bank, gpio),IRQ_TYPE_NONE );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); }static void gpio_unmask_irq (struct irq_data *d)
@@ -740,6 +740,7 @@ static void gpio_unmask_irq(struct irq_data *d)u32 trigger =irqd_get_trigger_type (d);unsigned long flags; +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);if (trigger)_set_gpio_triggering (bank,GPIO_INDEX (bank, gpio), trigger);
@@ -753,6 +754,7 @@ static void gpio_unmask_irq(struct irq_data *d)_set_gpio_irqenable (bank, gpio,1 );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); }static struct irq_chip gpio_irq_chip = {
@@ -836,17 +838,26 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset)unsigned long flags; bank = container_of(chip, struct gpio_bank, chip); +pm_runtime_get_sync (bank->dev); +spin_lock_irqsave (&bank->lock, flags);_set_gpio_direction (bank, offset,1 );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); +return 0 ; }static int gpio_is_input (struct gpio_bank *bank,int mask) {void __iomem *reg = bank->base + bank->regs->direction; +u32 val; -return __raw_readl (reg) & mask; +pm_runtime_get_sync (bank->dev); + val =__raw_readl (reg) & mask; +pm_runtime_put (bank->dev); + +return val; }static int gpio_get (struct gpio_chip *chip,unsigned offset)
@@ -856,15 +867,20 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)int gpio;u32 mask; +int val; gpio = chip->base + offset; bank = container_of(chip, struct gpio_bank, chip); reg = bank->base; mask =GPIO_BIT (bank, gpio); +pm_runtime_get_sync (bank->dev);if (gpio_is_input (bank, mask)) -return _get_gpio_datain (bank, gpio); + val =_get_gpio_datain (bank, gpio);else -return _get_gpio_dataout (bank, gpio); + val =_get_gpio_dataout (bank, gpio); +pm_runtime_put (bank->dev); + +return val; }static int gpio_output (struct gpio_chip *chip,unsigned offset,int value)
@@ -873,10 +889,14 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)unsigned long flags; bank = container_of(chip, struct gpio_bank, chip); + +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags); bank->set_dataout (bank, offset, value);_set_gpio_direction (bank, offset,0 );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); +return 0 ; }
@@ -894,9 +914,11 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset,dev_err (bank->dev,"Could not get gpio dbck\n" ); } +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);_set_gpio_debounce (bank, offset, debounce);spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev);return 0 ; }
@@ -907,9 +929,12 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)unsigned long flags; bank = container_of(chip, struct gpio_bank, chip); + +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags); bank->set_dataout (bank, offset, value);spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); }static int gpio_2irq (struct gpio_chip *chip,unsigned offset)
@@ -1330,7 +1355,8 @@ void omap2_gpio_prepare_for_idle(int pwr_mode) bank->power_mode = pwr_mode; -pm_runtime_put_sync_suspend (bank->dev); +if (!pm_runtime_suspended (bank->dev)) +pm_runtime_suspend (bank->dev); } }
@@ -1342,7 +1368,8 @@ void omap2_gpio_resume_after_idle(void)if (!bank->mod_usage || !bank->loses_context)continue ; -pm_runtime_get_sync (bank->dev); +if (pm_runtime_suspended (bank->dev)) +pm_runtime_resume (bank->dev); } }
Signature · 1 line
1.7.9
PATCH 1/1 gpio: omap: be more aggressive with pm_runtime
Hi,
Quoted 10 lines · Felipe Balbi
try to keep gpio block suspended as much as possible.
Tested with pandaboard and a sysfs exported gpio.
Signed-off-by Felipe Balbi <[email protected]>---
I couldn't see any issues with this patch. I managed to export a gpio and change the direction with a while true loop with no issues whatsoever.
btw, I also played with gpios 7 and 8 because they have LEDs on them on pandaboard and everything seems to be fine.
I just want to be sure I can still go to OFF mode and wakeup, but on vanilla 3.3-rc2 after echo mem > /sys/power/state the systems freezes on panda, so I can't go any further.
Quoted 606 lines
Any chance someone tells me how to reproduce the original wakeup problem we had ?
I wrote a simple script to dump gpio states while I had:
while true; do echo in >
/sys/class/gpio/gpio2/direction; \
echo out >/sys/class/gpio/gpio2/direction; done &running. Here's the ouput:
./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time11945runtime_suspended_time1214578omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1226468omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1226562omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1226578omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1226593root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time12234runtime_suspended_time1215257omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1227437omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1227531omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1227546omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1227562root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time12460runtime_suspended_time1215882omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1228289omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1228382omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1228398omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1228414root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time12734runtime_suspended_time1216453omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1229132omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1229226omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1229242omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1229257root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statusactiveruntime_active_time13007runtime_suspended_time1216960omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1229914omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1230007omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1230023omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1230039root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time13234runtime_suspended_time1217492omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1230671omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1230765omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1230781omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1230796root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time13453runtime_suspended_time1218023omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1231421omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1231515omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1231531omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1231546root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time13703runtime_suspended_time1218539omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1232187omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1232281omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1232296omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1232312root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statusactiveruntime_active_time13890runtime_suspended_time1219125omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1232960omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1233054omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1233070omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1233085root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time14109runtime_suspended_time1219601omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1233656omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1233750omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1233765omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1233781root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time14367runtime_suspended_time1220109omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1234421omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1234515omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1234531omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1234546root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_statussuspendedruntime_active_time14531runtime_suspended_time1220648omap_gpio.1
control autoruntime_statussuspendedruntime_active_time78runtime_suspended_time1235125omap_gpio.2
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1235218omap_gpio.3
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1235234omap_gpio.4
control autoruntime_statussuspendedruntime_active_time0runtime_suspended_time1235250see that the active time changes for omap_gpio.0 (first gpio bank) because I'm constantly changing direction of the exported gpio2, but the other banks are kept in suspend state. I even managed to catch the gpio bank while it was still in active state. Before suspending again.
drivers/gpio/gpio-omap.c | 61 +++++++++++++++++++++++++++++++++------------- 1 files changed, 44 insertions(+), 17 deletions(-)drivers/gpio/gpio-omap.c +44
-17@@ -537,12 +537,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);unsigned long flags; -/* -* If this is the first gpio_request for the bank, -* enable the bank module. -*/ -if (!bank->mod_usage) -pm_runtime_get_sync (bank->dev); +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);/* Set trigger to none. You need to enable the desired trigger with @@ -572,6 +567,8 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); +return 0 ; }@@ -581,6 +578,8 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)void __iomem *base = bank->base;unsigned long flags; +pm_runtime_get_sync (bank->dev); +spin_lock_irqsave (&bank->lock, flags);if (bank->regs->wkup_en) {@@ -606,12 +605,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)_reset_gpio (bank, bank->chip.base + offset);spin_unlock_irqrestore (&bank->lock, flags); -/* -* If this is the last gpio to be freed in the bank, -* disable the bank module. -*/ -if (!bank->mod_usage) -pm_runtime_put (bank->dev); +pm_runtime_put (bank->dev); }/* @@ -707,9 +701,11 @@ static void gpio_irq_shutdown(struct irq_data *d)struct gpio_bank *bank =irq_data_get_irq_chip_data (d);unsigned long flags; +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);_reset_gpio (bank, gpio);spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); }static void gpio_ack_irq (struct irq_data *d)@@ -717,7 +713,9 @@ static void gpio_ack_irq(struct irq_data *d)unsigned int gpio = d->irq -IH_GPIO_BASE ;struct gpio_bank *bank =irq_data_get_irq_chip_data (d); +pm_runtime_get_sync (bank->dev);_clear_gpio_irqstatus (bank, gpio); +pm_runtime_put (bank->dev); }static void gpio_mask_irq (struct irq_data *d)@@ -726,10 +724,12 @@ static void gpio_mask_irq(struct irq_data *d)struct gpio_bank *bank =irq_data_get_irq_chip_data (d);unsigned long flags; +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);_set_gpio_irqenable (bank, gpio,0 );_set_gpio_triggering (bank,GPIO_INDEX (bank, gpio),IRQ_TYPE_NONE );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); }static void gpio_unmask_irq (struct irq_data *d)@@ -740,6 +740,7 @@ static void gpio_unmask_irq(struct irq_data *d)u32 trigger =irqd_get_trigger_type (d);unsigned long flags; +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);if (trigger)_set_gpio_triggering (bank,GPIO_INDEX (bank, gpio), trigger);@@ -753,6 +754,7 @@ static void gpio_unmask_irq(struct irq_data *d)_set_gpio_irqenable (bank, gpio,1 );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); }static struct irq_chip gpio_irq_chip = {@@ -836,17 +838,26 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset)unsigned long flags; bank = container_of(chip, struct gpio_bank, chip); +pm_runtime_get_sync (bank->dev); +spin_lock_irqsave (&bank->lock, flags);_set_gpio_direction (bank, offset,1 );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); +return 0 ; }static int gpio_is_input (struct gpio_bank *bank,int mask) {void __iomem *reg = bank->base + bank->regs->direction; +u32 val; -return __raw_readl (reg) & mask; +pm_runtime_get_sync (bank->dev); + val =__raw_readl (reg) & mask; +pm_runtime_put (bank->dev); + +return val; }static int gpio_get (struct gpio_chip *chip,unsigned offset)@@ -856,15 +867,20 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)int gpio;u32 mask; +int val; gpio = chip->base + offset; bank = container_of(chip, struct gpio_bank, chip); reg = bank->base; mask =GPIO_BIT (bank, gpio); +pm_runtime_get_sync (bank->dev);if (gpio_is_input (bank, mask)) -return _get_gpio_datain (bank, gpio); + val =_get_gpio_datain (bank, gpio);else -return _get_gpio_dataout (bank, gpio); + val =_get_gpio_dataout (bank, gpio); +pm_runtime_put (bank->dev); + +return val; }static int gpio_output (struct gpio_chip *chip,unsigned offset,int value)@@ -873,10 +889,14 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)unsigned long flags; bank = container_of(chip, struct gpio_bank, chip); + +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags); bank->set_dataout (bank, offset, value);_set_gpio_direction (bank, offset,0 );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); +return 0 ; }@@ -894,9 +914,11 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset,dev_err (bank->dev,"Could not get gpio dbck\n" ); } +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags);_set_gpio_debounce (bank, offset, debounce);spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev);return 0 ; }@@ -907,9 +929,12 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)unsigned long flags; bank = container_of(chip, struct gpio_bank, chip); + +pm_runtime_get_sync (bank->dev);spin_lock_irqsave (&bank->lock, flags); bank->set_dataout (bank, offset, value);spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put (bank->dev); }static int gpio_2irq (struct gpio_chip *chip,unsigned offset)@@ -1330,7 +1355,8 @@ void omap2_gpio_prepare_for_idle(int pwr_mode) bank->power_mode = pwr_mode; -pm_runtime_put_sync_suspend (bank->dev); +if (!pm_runtime_suspended (bank->dev)) +pm_runtime_suspend (bank->dev); } }@@ -1342,7 +1368,8 @@ void omap2_gpio_resume_after_idle(void)if (!bank->mod_usage || !bank->loses_context)continue ; -pm_runtime_get_sync (bank->dev); +if (pm_runtime_suspended (bank->dev)) +pm_runtime_resume (bank->dev); } }Signature · 1 line
1.7.9
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120208/322a03b0/attachment-0001.sig>
PATCH 1/1 gpio: omap: be more aggressive with pm_runtime
Quoted 14 lines · Felipe Balbi
Hi,
Quoted 10 lines · Felipe Balbi
try to keep gpio block suspended as much as possible.
Tested with pandaboard and a sysfs exported gpio.
Signed-off-by Felipe Balbi <[email protected]>---
I couldn't see any issues with this patch. I managed to export a gpio and change the direction with a while true loop with no issues whatsoever.
Quoted 6 lines
btw, I also played with gpios 7 and 8 because they have LEDs on them on pandaboard and everything seems to be fine.
I just want to be sure I can still go to OFF mode and wakeup, but on vanilla 3.3-rc2 after echo mem >
/sys/power/statethe systems freezes on panda, so I can't go any further.
I don't think it's frozen. I suspected it's suspended without any wakeups enabled. You probably haven't enabled UART wakeups. Try enabling them like this:
echo enabled > /sys/devices/platform/omap/omap_uart.2/tty/ttyO2/power/wakeup
before going into suspend.
Kevin
PATCH 1/1 gpio: omap: be more aggressive with pm_runtime
Quoted 23 lines · Kevin Hilman
Quoted 14 lines · Felipe Balbi
Hi,
Quoted 10 lines · Felipe Balbi
try to keep gpio block suspended as much as possible.
Tested with pandaboard and a sysfs exported gpio.
Signed-off-by Felipe Balbi <[email protected]>---
I couldn't see any issues with this patch. I managed to export a gpio and change the direction with a while true loop with no issues whatsoever.
Quoted 6 lines
btw, I also played with gpios 7 and 8 because they have LEDs on them on pandaboard and everything seems to be fine.
I just want to be sure I can still go to OFF mode and wakeup, but on vanilla 3.3-rc2 after echo mem >
/sys/power/statethe systems freezes on panda, so I can't go any further.
Quoted 7 lines
I don't think it's frozen. I suspected it's suspended without any wakeups enabled. You probably haven't enabled UART wakeups. Try enabling them like this:
echo enabled >
/sys/devices/platform/omap/omap_uart.2/tty/ttyO2/power/wakeupbefore going into suspend.
that did the trick. But not having UART with wakeup enabled by default prevents us from doing suspend/resume tests during bootup, because the system won't wakeup through console.
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120209/b0ab2319/attachment.sig>
PATCH 1/1 gpio: omap: be more aggressive with pm_runtime
In reply to Felipe BalbiQuoted 6 lines · Felipe Balbi
try to keep gpio block suspended as much as possible.
Tested with pandaboard and a sysfs exported gpio.
Signed-off-by Felipe Balbi <[email protected]>---
Looks like you need a few more get/puts around other places where registers are accessed. It currently causes a boot crash on OMAP3 in _set_gpio_triggering().
Did you test GPIO wakeups? both IO ring wakeups and GPIO module-level wakeups?
Kevin
PATCH 1/1 gpio: omap: be more aggressive with pm_runtime
Hi,
Quoted 4 lines · Kevin Hilman
Quoted 2 lines · Felipe Balbi
try to keep gpio block suspended as much as possible.
Quoted 8 lines
Quoted 4 lines
Tested with pandaboard and a sysfs exported gpio.
Signed-off-by Felipe Balbi <[email protected]>---
Looks like you need a few more get/puts around other places where registers are accessed. It currently causes a boot crash on OMAP3 in
_set_gpio_triggering().
it was a missing get/put on gpio_irq_set_type(). Fixed.
Quoted 2 lines
Did you test GPIO wakeups? both IO ring wakeups and GPIO module-level wakeups?
how can I test that easily with panda ?
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120209/fcca7d4e/attachment-0001.sig>
PATCH 1/1 gpio: omap: be more aggressive with pm_runtime
Hi again,
Quoted 14 lines · Felipe Balbi
Quoted 4 lines · Kevin Hilman
Quoted 2 lines · Felipe Balbi
try to keep gpio block suspended as much as possible.
Quoted 8 lines
Quoted 4 lines
Tested with pandaboard and a sysfs exported gpio.
Signed-off-by Felipe Balbi <[email protected]>---
Looks like you need a few more get/puts around other places where registers are accessed. It currently causes a boot crash on OMAP3 in
_set_gpio_triggering().
Quoted 6 lines
it was a missing get/put on
gpio_irq_set_type(). Fixed.Quoted 2 lines
Did you test GPIO wakeups? both IO ring wakeups and GPIO module-level wakeups?
how can I test that easily with panda ?
Ok, I have added gpio-keys to panda's boardfile:
arch/arm/mach-omap2/board-omap4panda.c +24 -0
@@ -23,6 +23,7 @@#include <linux/io.h> #include <linux/leds.h> #include <linux/gpio.h> +#include <linux/gpio_keys.h> #include <linux/usb/otg.h> #include <linux/i2c/twl.h> #include <linux/regulator/machine.h>
@@ -90,7 +91,30 @@ static struct platform_device leds_gpio = { }, }; +static struct gpio_keys_button gpio_buttons[] = { + { + .code =BTN_EXTRA , + .gpio =121 , + .desc ="user" , + .wakeup =1 , + }, +}; + +static struct gpio_keys_platform_data gpio_key_info = { + .buttons = gpio_buttons, + .nbuttons =ARRAY_SIZE (gpio_buttons), +}; + +static struct platform_device keys_gpio = { + .name ="gpio-keys" , + .id =-1 , + .dev = { + .platform_data = &gpio_key_info, + }, +}; +static struct platform_device *panda_devices[]__initdata = { + &keys_gpio, &leds_gpio, &wl1271_device, };
Then I enabled IRQ wake on gpio-keys driver:
drivers/input/keyboard/gpio_keys.c +2 -0
@@ -410,6 +410,8 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, goto fail3; } +enable_irq_wake (irq); + irqflags =IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING ;/* * If platform has specified that the button can be disabled,
and enabled wakeup on the gpio-keys:
# echo enabled > /sys/devices/platform/gpio-keys/power/wakeup
suspended the device, and woke it up by pressing S2 (user button). It almost works, hehe. I can suspend and wake pandaboard up with the user button. But after that, GPIO module is dead. BTW, I had to prevent gpio's suspend/resume functions from being called. For some reason, pm-core is still calling them:
drivers/gpio/gpio-omap.c +6 -0
@@ -1170,6 +1170,9 @@ static int omap_gpio_suspend(struct device *dev)void __iomem *wakeup_enable;unsigned long flags; +if (pm_runtime_suspended (dev)) +return 0 ; +if (!bank->mod_usage || !bank->loses_context)return 0 ;
@@ -1194,6 +1197,9 @@ static int omap_gpio_resume(struct device *dev)void __iomem *base = bank->base;unsigned long flags; +if (pm_runtime_suspended (dev)) +return 0 ; +if (!bank->mod_usage || !bank->loses_context)return 0 ;
I will continue debugging this, I think it's just something stupid that I did. Here's entire log:
root at legalas:~# echo enabled > /sys/devices/platform/gpio-keys/power/wakeup root at legolas:~# echo enabled > /sys/devices/platform/omap/omap_uart.2/power/wakeup root at legolas:~# grep user /proc/interrupts
281: 0 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 2 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 5 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 7 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 8 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 9 0 GPIO user
root at legolas:~#
root at legolas:~#
root at legolas:~# echo mem > /sys/power/state
[ 62.593200] PM: Syncing filesystems ... done. [ 62.605743] Freezing user space processes ... (elapsed 0.03 seconds) done. [ 62.636230] Freezing remaining freezable tasks ... (elapsed 0.04 seconds) done. [ 62.692993] Suspending console(s) (use no_console_suspend to debug) [ 62.709960] PM: suspend of devices complete after 8.270 msecs [ 62.711853] PM: late suspend of devices complete after 1.770 msecs [ 62.711853] Disabling non-boot CPUs ... [ 62.715118] CPU1: shutdown [ 65.369873] Successfully put all powerdomains to target state [ 65.369995] Enabling non-boot CPUs ... [ 65.371612] CPU1: Booted secondary processor [ 65.372161] Calibrating delay loop (skipped) already calibrated this CPU [ 65.372741] CPU1 is up [ 65.373962] PM: early resume of devices complete after 1.220 msecs [ 65.373962] ------------[ cut here ]------------ [ 65.374114] WARNING: at arch/arm/mach-omap2/omap_l3_noc.c:113 l3_interrupt_handler+0x184/0x1c4() [ 65.374114] L3 custom error: MASTER:MPU TARGET:L4 PER2 [ 65.374114] Modules linked in: [ 65.374114] [<c001b824>] (unwind_backtrace+0x0/0xf0) from [<c0042a60>] (warn_slowpath_common+0x4c/0x64) [ 65.374206] [<c0042a60>] (warn_slowpath_common+0x4c/0x64) from [<c0042b0c>] (warn_slowpath_fmt+0x30/0x40) [ 65.374206] [<c0042b0c>] (warn_slowpath_fmt+0x30/0x40) from [<c0034a88>] (l3_interrupt_handler+0x184/0x1c4) [ 65.374267] [<c0034a88>] (l3_interrupt_handler+0x184/0x1c4) from [<c00a1ef8>] (handle_irq_event_percpu+0x5c/0x22c) [ 65.374267] [<c00a1ef8>] (handle_irq_event_percpu+0x5c/0x22c) from [<c00a2104>] (handle_irq_event+0x3c/0x5c) [ 65.374298] [<c00a2104>] (handle_irq_event+0x3c/0x5c) from [<c00a4ba0>] (handle_fasteoi_irq+0x98/0x140) [ 65.374328] [<c00a4ba0>] (handle_fasteoi_irq+0x98/0x140) from [<c00a170c>] (generic_handle_irq+0x30/0x48) [ 65.374328] [<c00a170c>] (generic_handle_irq+0x30/0x48) from [<c0014bd8>] (handle_IRQ+0x4c/0xac) [ 65.374389] [<c0014bd8>] (handle_IRQ+0x4c/0xac) from [<c000848c>] (gic_handle_irq+0x28/0xac) [ 65.374389] [<c000848c>] (gic_handle_irq+0x28/0xac) from [<c04809e4>] (__irq_svc+0x44/0x60) [ 65.374389] Exception stack(0xee147e60 to 0xee147ea8) [ 65.374450] 7e60: 00011de7 00000003 00000000 ee0f7580 60000113 c068c194 00000000 c068c194 [ 65.374450] 7e80: 60000113 ee04d780 c068c140 000d7518 00001584 ee147ea8 00011de8 c04807a4 [ 65.374450] 7ea0: 20000113 ffffffff [ 65.374481] [<c04809e4>] (__irq_svc+0x44/0x60) from [<c04807a4>] (_raw_spin_unlock_irqrestore+0x34/0x44) [ 65.374481] [<c04807a4>] (_raw_spin_unlock_irqrestore+0x34/0x44) from [<c00a717c>] (resume_irqs+0x9c/0xbc) [ 65.374511] [<c00a717c>] (resume_irqs+0x9c/0xbc) from [<c0080998>] (suspend_enter+0xa4/0x168) [ 65.374542] [<c0080998>] (suspend_enter+0xa4/0x168) from [<c0080b0c>] (suspend_devices_and_enter+0xb0/0x18c) [ 65.374542] [<c0080b0c>] (suspend_devices_and_enter+0xb0/0x18c) from [<c0080d24>] (enter_state+0x13c/0x17c) [ 65.374572] [<c0080d24>] (enter_state+0x13c/0x17c) from [<c007fa1c>] (state_store+0xd0/0x178) [ 65.374603] [<c007fa1c>] (state_store+0xd0/0x178) from [<c0258f48>] (kobj_attr_store+0x14/0x20) [ 65.374603] [<c0258f48>] (kobj_attr_store+0x14/0x20) from [<c0169958>] (sysfs_write_file+0x100/0x184) [ 65.374633] [<c0169958>] (sysfs_write_file+0x100/0x184) from [<c0109d10>] (vfs_write+0xb4/0x148) [ 65.374664] [<c0109d10>] (vfs_write+0xb4/0x148) from [<c0109f98>] (sys_write+0x40/0x70) [ 65.374664] [<c0109f98>] (sys_write+0x40/0x70) from [<c0013cc0>] (ret_fast_syscall+0x0/0x3c) [ 65.374694] ---[ end trace 4898b0d1d1bc4fab ]--- [ 65.374694] ------------[ cut here ]------------ [ 65.374694] WARNING: at arch/arm/mach-omap2/omap_l3_noc.c:113 l3_interrupt_handler+0x184/0x1c4() [ 65.374694] L3 custom error: MASTER:MPU TARGET:L4 PER2 [ 65.375305] Modules linked in: [ 65.375305] [<c001b824>] (unwind_backtrace+0x0/0xf0) from [<c0042a60>] (warn_slowpath_common+0x4c/0x64) [ 65.375335] [<c0042a60>] (warn_slowpath_common+0x4c/0x64) from [<c0042b0c>] (warn_slowpath_fmt+0x30/0x40) [ 65.375335] [<c0042b0c>] (warn_slowpath_fmt+0x30/0x40) from [<c0034a88>] (l3_interrupt_handler+0x184/0x1c4) [ 65.375366] [<c0034a88>] (l3_interrupt_handler+0x184/0x1c4) from [<c00a1ef8>] (handle_irq_event_percpu+0x5c/0x22c) [ 65.375396] [<c00a1ef8>] (handle_irq_event_percpu+0x5c/0x22c) from [<c00a2104>] (handle_irq_event+0x3c/0x5c) [ 65.375396] [<c00a2104>] (handle_irq_event+0x3c/0x5c) from [<c00a4ba0>] (handle_fasteoi_irq+0x98/0x140) [ 65.375427] [<c00a4ba0>] (handle_fasteoi_irq+0x98/0x140) from [<c00a170c>] (generic_handle_irq+0x30/0x48) [ 65.375427] [<c00a170c>] (generic_handle_irq+0x30/0x48) from [<c0014bd8>] (handle_IRQ+0x4c/0xac) [ 65.375457] [<c0014bd8>] (handle_IRQ+0x4c/0xac) from [<c000848c>] (gic_handle_irq+0x28/0xac) [ 65.375457] [<c000848c>] (gic_handle_irq+0x28/0xac) from [<c04809e4>] (__irq_svc+0x44/0x60) [ 65.375488] Exception stack(0xee147e60 to 0xee147ea8) [ 65.375488] 7e60: 00011fc7 00000003 00000000 ee0f7580 60000113 c06974d4 00000000 c06974d4 [ 65.375488] 7e80: 60000113 ee04d780 c0697480 000d7518 00001584 ee147ea8 00011fc8 c04807a4 [ 65.375518] 7ea0: 20000113 ffffffff [ 65.375518] [<c04809e4>] (__irq_svc+0x44/0x60) from [<c04807a4>] (_raw_spin_unlock_irqrestore+0x34/0x44) [ 65.375549] [<c04807a4>] (_raw_spin_unlock_irqrestore+0x34/0x44) from [<c00a717c>] (resume_irqs+0x9c/0xbc) [ 65.375549] [<c00a717c>] (resume_irqs+0x9c/0xbc) from [<c0080998>] (suspend_enter+0xa4/0x168) [ 65.375579] [<c0080998>] (suspend_enter+0xa4/0x168) from [<c0080b0c>] (suspend_devices_and_enter+0xb0/0x18c) [ 65.375579] [<c0080b0c>] (suspend_devices_and_enter+0xb0/0x18c) from [<c0080d24>] (enter_state+0x13c/0x17c) [ 65.375610] [<c0080d24>] (enter_state+0x13c/0x17c) from [<c007fa1c>] (state_store+0xd0/0x178) [ 65.375610] [<c007fa1c>] (state_store+0xd0/0x178) from [<c0258f48>] (kobj_attr_store+0x14/0x20) [ 65.375640] [<c0258f48>] (kobj_attr_store+0x14/0x20) from [<c0169958>] (sysfs_write_file+0x100/0x184) [ 65.375640] [<c0169958>] (sysfs_write_file+0x100/0x184) from [<c0109d10>] (vfs_write+0xb4/0x148) [ 65.375671] [<c0109d10>] (vfs_write+0xb4/0x148) from [<c0109f98>] (sys_write+0x40/0x70) [ 65.375671] [<c0109f98>] (sys_write+0x40/0x70) from [<c0013cc0>] (ret_fast_syscall+0x0/0x3c) [ 65.375671] ---[ end trace 4898b0d1d1bc4fac ]--- [ 65.375701] ------------[ cut here ]------------ [ 65.375762] WARNING: at arch/arm/mach-omap2/omap_l3_noc.c:113 l3_interrupt_handler+0x184/0x1c4() [ 65.375762] L3 custom error: MASTER:MPU TARGET:L4 PER2 [ 65.375762] Modules linked in: [ 65.375793] [<c001b824>] (unwind_backtrace+0x0/0xf0) from [<c0042a60>] (warn_slowpath_common+0x4c/0x64) [ 65.375793] [<c0042a60>] (warn_slowpath_common+0x4c/0x64) from [<c0042b0c>] (warn_slowpath_fmt+0x30/0x40) [ 65.375823] [<c0042b0c>] (warn_slowpath_fmt+0x30/0x40) from [<c0034a88>] (l3_interrupt_handler+0x184/0x1c4) [ 65.375854] [<c0034a88>] (l3_interrupt_handler+0x184/0x1c4) from [<c00a1ef8>] (handle_irq_event_percpu+0x5c/0x22c) [ 65.375854] [<c00a1ef8>] (handle_irq_event_percpu+0x5c/0x22c) from [<c00a2104>] (handle_irq_event+0x3c/0x5c) [ 65.375885] [<c00a2104>] (handle_irq_event+0x3c/0x5c) from [<c00a4ba0>] (handle_fasteoi_irq+0x98/0x140) [ 65.375885] [<c00a4ba0>] (handle_fasteoi_irq+0x98/0x140) from [<c00a170c>] (generic_handle_irq+0x30/0x48) [ 65.375915] [<c00a170c>] (generic_handle_irq+0x30/0x48) from [<c0014bd8>] (handle_IRQ+0x4c/0xac) [ 65.375915] [<c0014bd8>] (handle_IRQ+0x4c/0xac) from [<c000848c>] (gic_handle_irq+0x28/0xac) [ 65.375946] [<c000848c>] (gic_handle_irq+0x28/0xac) from [<c04809e4>] (__irq_svc+0x44/0x60) [ 65.375946] Exception stack(0xee147d60 to 0xee147da8) [ 65.375946] 7d60: 00011fce 00000003 00000000 ee0f7580 c0697480 00000119 c06e669c c06e669c [ 65.375976] 7d80: 00000000 c06854a8 c069f108 c0723300 00000000 ee147da8 00011fcf c00a4224 [ 65.375976] 7da0: 60000113 ffffffff [ 65.375976] [<c04809e4>] (__irq_svc+0x44/0x60) from [<c00a4224>] (resend_irqs+0x50/0x74) [ 65.376007] [<c00a4224>] (resend_irqs+0x50/0x74) from [<c0049990>] (tasklet_action+0x80/0x180) [ 65.376037] [<c0049990>] (tasklet_action+0x80/0x180) from [<c0049f04>] (__do_softirq+0xd0/0x200) [ 65.376037] [<c0049f04>] (__do_softirq+0xd0/0x200) from [<c004a4c0>] (irq_exit+0x94/0x9c) [ 65.376068] [<c004a4c0>] (irq_exit+0x94/0x9c) from [<c0014bdc>] (handle_IRQ+0x50/0xac) [ 65.376068] [<c0014bdc>] (handle_IRQ+0x50/0xac) from [<c000848c>] (gic_handle_irq+0x28/0xac) [ 65.376098] [<c000848c>] (gic_handle_irq+0x28/0xac) from [<c04809e4>] (__irq_svc+0x44/0x60) [ 65.376098] Exception stack(0xee147e60 to 0xee147ea8) [ 65.376098] 7e60: 00011fc7 00000003 00000000 ee0f7580 60000113 c06974d4 00000000 c06974d4 [ 65.376129] 7e80: 60000113 ee04d780 c0697480 000d7518 00001584 ee147ea8 00011fc8 c04807a4 [ 65.376129] 7ea0: 20000113 ffffffff [ 65.376159] [<c04809e4>] (__irq_svc+0x44/0x60) from [<c04807a4>] (_raw_spin_unlock_irqrestore+0x34/0x44) [ 65.376159] [<c04807a4>] (_raw_spin_unlock_irqrestore+0x34/0x44) from [<c00a717c>] (resume_irqs+0x9c/0xbc) [ 65.376190] [<c00a717c>] (resume_irqs+0x9c/0xbc) from [<c0080998>] (suspend_enter+0xa4/0x168) [ 65.376190] [<c0080998>] (suspend_enter+0xa4/0x168) from [<c0080b0c>] (suspend_devices_and_enter+0xb0/0x18c) [ 65.376220] [<c0080b0c>] (suspend_devices_and_enter+0xb0/0x18c) from [<c0080d24>] (enter_state+0x13c/0x17c) [ 65.376220] [<c0080d24>] (enter_state+0x13c/0x17c) from [<c007fa1c>] (state_store+0xd0/0x178) [ 65.376220] [<c007fa1c>] (state_store+0xd0/0x178) from [<c0258f48>] (kobj_attr_store+0x14/0x20) [ 65.376251] [<c0258f48>] (kobj_attr_store+0x14/0x20) from [<c0169958>] (sysfs_write_file+0x100/0x184) [ 65.376281] [<c0169958>] (sysfs_write_file+0x100/0x184) from [<c0109d10>] (vfs_write+0xb4/0x148) [ 65.376281] [<c0109d10>] (vfs_write+0xb4/0x148) from [<c0109f98>] (sys_write+0x40/0x70) [ 65.376312] [<c0109f98>] (sys_write+0x40/0x70) from [<c0013cc0>] (ret_fast_syscall+0x0/0x3c) [ 65.376312] ---[ end trace 4898b0d1d1bc4fad ]--- [ 66.479217] PM: resume of devices complete after 1102.905 msecs [ 67.393280] Restarting tasks ... done. root at legolas:~# [ 71.719665] mmcblk0: error -110 transferring data, sector 3557217, nr 72, cmd response 0x900, card status 0xc00 [ 71.730468] end_request: I/O error, dev mmcblk0, sector 3557280 [ 71.730651] end_request: I/O error, dev mmcblk0, sector 3557281 [ 71.743591] Aborting journal on device mmcblk0p2. [ 71.753845] EXT3-fs (mmcblk0p2): error: ext3_journal_start_sb: Detected aborted journal [ 71.753845] EXT3-fs (mmcblk0p2): error: remounting filesystem read-only
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 10 0 GPIO user
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120209/1f0bec5b/attachment-0001.sig>
PATCH 1/1 gpio: omap: be more aggressive with pm_runtime
Hi,
Quoted 2 lines · Felipe Balbi
I will continue debugging this, I think it's just something stupid that I did. Here's entire log:
Indeed some stupidity of mine. I know the following is wrong, but I just wanted to test it out. I have added the following to gpio-omap.c:
drivers/gpio/gpio-omap.c +4 -0
@@ -1178,11 +1178,13 @@ static int omap_gpio_suspend(struct device *dev) wakeup_enable = bank->base + bank->regs->wkup_en; +pm_runtime_get_sync (dev);spin_lock_irqsave (&bank->lock, flags); bank->saved_wakeup =__raw_readl (wakeup_enable);_gpio_rmw (base, bank->regs->wkup_en,0xffffffff ,0 );_gpio_rmw (base, bank->regs->wkup_en, bank->suspend_wakeup,1 );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put_sync (dev);return 0 ; }
@@ -1200,10 +1202,12 @@ static int omap_gpio_resume(struct device *dev)if (!bank->regs->wkup_en || !bank->saved_wakeup)return 0 ; +pm_runtime_get_sync (dev);spin_lock_irqsave (&bank->lock, flags);_gpio_rmw (base, bank->regs->wkup_en,0xffffffff ,0 );_gpio_rmw (base, bank->regs->wkup_en, bank->saved_wakeup,1 );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put_sync (dev);return 0 ; }
so, the main problem is that when we try to resume, our clocks aren't on (off course). I wonder what should really be done here. Should I go ahead and use the clock API to fix this issue or should I believe omap PM layer will be able to enable the hwmod so I can resume properly ?
Bellow, you can see entire log. Note that I can only reach suspend once.
Quoted 1 line
From that point on, MPU never reaches low power anymore; and there is
this L3 debug IRQ happening:
echo enabled > /sys/devices/platform/gpio-keys/power/wakeup root at legolas:~# grep user /proc/interrupts
281: 0 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 2 0 GPIO user
root at legolas:~#
root at legolas:~# echo mem > /sys/power/state
[ 36.300933] PM: Syncing filesystems ... done. [ 36.312561] Freezing user space processes ... (elapsed 0.02 seconds) done. [ 36.347015] Freezing remaining freezable tasks ... (elapsed 0.03 seconds) done. [ 36.381072] Suspending console(s) (use no_console_suspend to debug) [ 36.397827] PM: suspend of devices complete after 14.768 msecs [ 36.399780] PM: late suspend of devices complete after 1.952 msecs [ 36.399780] Disabling non-boot CPUs ... [ 36.402984] CPU1: shutdown [ 37.953826] Successfully put all powerdomains to target state [ 37.953948] Enabling non-boot CPUs ... [ 37.955566] CPU1: Booted secondary processor [ 37.956115] Calibrating delay loop (skipped) already calibrated this CPU [ 37.956695] CPU1 is up [ 37.957946] PM: early resume of devices complete after 1.251 msecs [ 37.957946] ------------[ cut here ]------------ [ 37.958068] WARNING: at arch/arm/mach-omap2/omap_l3_noc.c:113 l3_interrupt_handler+0x184/0x1c4() [ 37.958068] L3 custom error: MASTER:MPU TARGET:L4 PER2 [ 37.958068] Modules linked in: [ 37.958068] [<c001b824>] (unwind_backtrace+0x0/0xf0) from [<c0042a60>] (warn_slowpath_common+0x4c/0x64) [ 37.958190] [<c0042a60>] (warn_slowpath_common+0x4c/0x64) from [<c0042b0c>] (warn_slowpath_fmt+0x30/0x40) [ 37.958190] [<c0042b0c>] (warn_slowpath_fmt+0x30/0x40) from [<c0034a88>] (l3_interrupt_handler+0x184/0x1c4) [ 37.958221] [<c0034a88>] (l3_interrupt_handler+0x184/0x1c4) from [<c00a1ef8>] (handle_irq_event_percpu+0x5c/0x22c) [ 37.958221] [<c00a1ef8>] (handle_irq_event_percpu+0x5c/0x22c) from [<c00a2104>] (handle_irq_event+0x3c/0x5c) [ 37.958282] [<c00a2104>] (handle_irq_event+0x3c/0x5c) from [<c00a4ba0>] (handle_fasteoi_irq+0x98/0x140) [ 37.958312] [<c00a4ba0>] (handle_fasteoi_irq+0x98/0x140) from [<c00a170c>] (generic_handle_irq+0x30/0x48) [ 37.958312] [<c00a170c>] (generic_handle_irq+0x30/0x48) from [<c0014bd8>] (handle_IRQ+0x4c/0xac) [ 37.958374] [<c0014bd8>] (handle_IRQ+0x4c/0xac) from [<c000848c>] (gic_handle_irq+0x28/0xac) [ 37.958374] [<c000848c>] (gic_handle_irq+0x28/0xac) from [<c04809e4>] (__irq_svc+0x44/0x60) [ 37.958374] Exception stack(0xee2dbe60 to 0xee2dbea8) [ 37.958435] be60: 0000c439 00000003 00000000 ee1e4040 60000113 c068c194 00000000 c068c194 [ 37.958435] be80: 60000113 ee04d780 c068c140 000d7238 00001584 ee2dbea8 0000c43a c04807a4 [ 37.958435] bea0: 20000113 ffffffff [ 37.958465] [<c04809e4>] (__irq_svc+0x44/0x60) from [<c04807a4>] (_raw_spin_unlock_irqrestore+0x34/0x44) [ 37.958465] [<c04807a4>] (_raw_spin_unlock_irqrestore+0x34/0x44) from [<c00a717c>] (resume_irqs+0x9c/0xbc) [ 37.958465] [<c00a717c>] (resume_irqs+0x9c/0xbc) from [<c0080998>] (suspend_enter+0xa4/0x168) [ 37.958526] [<c0080998>] (suspend_enter+0xa4/0x168) from [<c0080b0c>] (suspend_devices_and_enter+0xb0/0x18c) [ 37.958526] [<c0080b0c>] (suspend_devices_and_enter+0xb0/0x18c) from [<c0080d24>] (enter_state+0x13c/0x17c) [ 37.958557] [<c0080d24>] (enter_state+0x13c/0x17c) from [<c007fa1c>] (state_store+0xd0/0x178) [ 37.958587] [<c007fa1c>] (state_store+0xd0/0x178) from [<c0258f48>] (kobj_attr_store+0x14/0x20) [ 37.958587] [<c0258f48>] (kobj_attr_store+0x14/0x20) from [<c0169958>] (sysfs_write_file+0x100/0x184) [ 37.958587] [<c0169958>] (sysfs_write_file+0x100/0x184) from [<c0109d10>] (vfs_write+0xb4/0x148) [ 37.958587] [<c0109d10>] (vfs_write+0xb4/0x148) from [<c0109f98>] (sys_write+0x40/0x70) [ 37.958587] [<c0109f98>] (sys_write+0x40/0x70) from [<c0013cc0>] (ret_fast_syscall+0x0/0x3c) [ 37.958679] ---[ end trace 09fd5633fca7e7bc ]--- [ 39.104858] PM: resume of devices complete after 1146.177 msecs [ 39.418762] Restarting tasks ... done.
root at legolas:~# echo mem > /sys/power/state root at legolas:~# grep user /proc/interrupts
281: 4 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 7 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 9 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 11 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 13 0 GPIO user
root at legolas:~# grep user /proc/interrupts
281: 15 0 GPIO user
root at legolas:~# grep user /proc/interrupts root at legolas:~# echo mem > /sys/power/state
[ 55.532073] PM: Syncing filesystems ... done. [ 57.044281] Freezing user space processes ... (elapsed 0.02 seconds) done. [ 57.066711] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) done. [ 57.100799] Suspending console(s) (use no_console_suspend to debug) [ 57.116302] PM: suspend of devices complete after 6.959 msecs [ 57.117980] PM: late suspend of devices complete after 1.678 msecs [ 57.118041] Disabling non-boot CPUs ... [ 57.119628] CPU1: shutdown [ 57.121124] Powerdomain (mpu_pwrdm) didn't enter target state 1 [ 57.121154] Could not enter target state in pm_suspend [ 57.121185] Enabling non-boot CPUs ... [ 57.122680] CPU1: Booted secondary processor [ 57.123352] Calibrating delay loop (skipped) already calibrated this CPU [ 57.123382] CPU1: Unknown IPI message 0x1 [ 57.123779] CPU1 is up [ 57.124938] PM: early resume of devices complete after 1.159 msecs [ 58.112426] PM: resume of devices complete after 987.488 msecs [ 58.179656] Restarting tasks ... done. root at legolas:~# echo mem > /sys/power/state [ 60.363983] PM: Syncing filesystems ... done. [ 61.850616] Freezing user space processes ... (elapsed 0.03 seconds) done. [ 61.889984] Freezing remaining freezable tasks ... (elapsed 0.03 seconds) done. [ 61.928985] Suspending console(s) (use no_console_suspend to debug) [ 61.944213] PM: suspend of devices complete after 6.744 msecs [ 61.945892] PM: late suspend of devices complete after 1.678 msecs [ 61.945953] Disabling non-boot CPUs ... [ 61.947296] CPU1: shutdown [ 61.948608] Powerdomain (mpu_pwrdm) didn't enter target state 1 [ 61.948638] Could not enter target state in pm_suspend [ 61.948669] Enabling non-boot CPUs ... [ 61.950744] CPU1: Booted secondary processor [ 61.950775] Calibrating delay loop (skipped) already calibrated this CPU [ 61.950805] CPU1: Unknown IPI message 0x1 [ 61.951232] CPU1 is up [ 61.952362] PM: early resume of devices complete after 0.305 msecs [ 62.871063] PM: resume of devices complete after 918.396 msecs [ 62.938262] Restarting tasks ... done.
root at legolas:~# ./show_gpios.sh
omap_gpio.0
control autoruntime_status suspendedruntime_active_time 7runtime_suspended_time 97625
omap_gpio.1
control autoruntime_status suspendedruntime_active_time 296runtime_suspended_time 97351
omap_gpio.2
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 97671
omap_gpio.3
control autoruntime_status suspendedruntime_active_time 6906runtime_suspended_time 90773
omap_gpio.4
control autoruntime_status suspendedruntime_active_time 0runtime_suspended_time 97695
root at legolas:~# echo mem > /sys/power/state
[ 118.066925] PM: Syncing filesystems ... done. [ 118.313720] Freezing user space processes ... (elapsed 0.04 seconds) done. [ 118.359130] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) done. [ 118.390228] Suspending console(s) (use no_console_suspend to debug) [ 118.405578] PM: suspend of devices complete after 15.075 msecs [ 118.407379] PM: late suspend of devices complete after 1.708 msecs [ 118.407379] Disabling non-boot CPUs ... [ 118.408752] CPU1: shutdown [ 118.410186] Powerdomain (mpu_pwrdm) didn't enter target state 1 [ 118.410186] Could not enter target state in pm_suspend [ 118.410217] Enabling non-boot CPUs ... [ 118.411865] CPU1: Booted secondary processor [ 118.411865] Calibrating delay loop (skipped) already calibrated this CPU [ 118.412445] CPU1: Unknown IPI message 0x1 [ 118.412872] CPU1 is up [ 118.414031] PM: early resume of devices complete after 0.335 msecs [ 119.316711] PM: resume of devices complete after 902.374 msecs [ 119.384063] Restarting tasks ... done.
root at legolas:~#
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120209/59f57792/attachment.sig>
PATCH 1/1 gpio: omap: be more aggressive with pm_runtime
In reply to Felipe BalbiQuoted 39 lines · Felipe Balbi
Hi again,
Quoted 14 lines · Felipe Balbi
Quoted 4 lines · Kevin Hilman
Quoted 2 lines · Felipe Balbi
try to keep gpio block suspended as much as possible.
Quoted 8 lines
Quoted 4 lines
Tested with pandaboard and a sysfs exported gpio.
Signed-off-by Felipe Balbi <[email protected]>---
Looks like you need a few more get/puts around other places where registers are accessed. ?It currently causes a boot crash on OMAP3 in
_set_gpio_triggering().Quoted 6 lines
it was a missing get/put on
gpio_irq_set_type(). Fixed.Quoted 2 lines
Did you test GPIO wakeups? ?both IO ring wakeups and GPIO module-level wakeups?
how can I test that easily with panda ?
Ok, I have added gpio-keys to panda's boardfile:
arch/arm/mach-omap2/board-omap4panda.c +0
-0@@ -23,6 +23,7 @@?#include <
linux/io.h>
?#include <linux/leds.h>
?#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
?#include <linux/usb/otg.h>
?#include <linux/i2c/twl.h>
?#include <linux/regulator/machine.h>
arch/arm/mach-omap2/board-omap4panda.c static struct platform_device leds_gpio = { · line 99
Quoted 9 lines
arch/arm/mach-omap2/board-omap4panda.c +6
-0@@ -90,7 +91,30 @@ static struct platform_device leds_gpio = { ? ? ? ?}, ?}; +static struct gpio_keys_button gpio_buttons[] = { + ? ? ? { + ? ? ? ? ? ? ? .code ? ? ? ? ? = BTN_EXTRA, + ? ? ? ? ? ? ? .gpio ? ? ? ? ? = 121, + ? ? ? ? ? ? ? .desc ? ? ? ? ? = "user", + ? ? ? ? ? ? ? .wakeup ? ? ? ? = 1,
While at it, could you also test GPIO module wakeups with debounce feature enabled? Kevin says it should work but it doesn't for me. Just add:
.debounce_interval = 10,
Signature · 1 line
Gra?vydas