linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] serial: omap: Fix missing pm_runtime_resume handling by simplifying code
@ 2014-03-25 18:48 Tony Lindgren
  2014-03-25 18:52 ` Felipe Balbi
  2014-04-10 21:47 ` Felipe Balbi
  0 siblings, 2 replies; 4+ messages in thread
From: Tony Lindgren @ 2014-03-25 18:48 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-serial, linux-omap, Jiri Slaby, Kevin Hilman, Felipe Balbi

The lack of pm_runtime_resume handling for the device state leads into
device wake-up interrupts not working after a while for runtime PM.

Also, serial-omap is confused about the use of device_may_wakeup.
The checks for device_may_wakeup should only be done for suspend and
resume, not for pm_runtime_suspend and pm_runtime_resume. The wake-up
events for PM runtime should always be enabled.

The lack of pm_runtime_resume handling leads into device wake-up
interrupts not working after a while for runtime PM.

Rather than try to patch over the issue of adding complex tests to
the pm_runtime_resume, let's fix the issues properly:

1. Make serial_omap_enable_wakeup deal with all internal PM state
   handling so we don't need to test for up->wakeups_enabled elsewhere.

   Later on once omap3 boots in device tree only mode we can also
   remove the up->wakeups_enabled flag and rely on the wake-up
   interrupt enable/disable state alone.

2. Do the device_may_wakeup checks in suspend and resume only,
   for runtime PM the wake-up events need to be always enabled.

3. Finally just call serial_omap_enable_wakeup and make sure we
   call it also in pm_runtime_resume.

4. Note that we also have to use disable_irq_nosync as serial_omap_irq
   calls pm_runtime_get_sync.

Fixes: 2a0b965cfb6e (serial: omap: Add support for optional wake-up)
Cc: stable@vger.kernel.org # v3.13+
Signed-off-by: Tony Lindgren <tony@atomide.com>

--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -225,14 +225,19 @@ static inline void serial_omap_enable_wakeirq(struct uart_omap_port *up,
 	if (enable)
 		enable_irq(up->wakeirq);
 	else
-		disable_irq(up->wakeirq);
+		disable_irq_nosync(up->wakeirq);
 }
 
 static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
 {
 	struct omap_uart_port_info *pdata = dev_get_platdata(up->dev);
 
+	if (enable == up->wakeups_enabled)
+		return;
+
 	serial_omap_enable_wakeirq(up, enable);
+	up->wakeups_enabled = enable;
+
 	if (!pdata || !pdata->enable_wakeup)
 		return;
 
@@ -1495,6 +1500,11 @@ static int serial_omap_suspend(struct device *dev)
 	uart_suspend_port(&serial_omap_reg, &up->port);
 	flush_work(&up->qos_work);
 
+	if (device_may_wakeup(dev))
+		serial_omap_enable_wakeup(up, true);
+	else
+		serial_omap_enable_wakeup(up, false);
+
 	return 0;
 }
 
@@ -1502,6 +1512,9 @@ static int serial_omap_resume(struct device *dev)
 {
 	struct uart_omap_port *up = dev_get_drvdata(dev);
 
+	if (device_may_wakeup(dev))
+		serial_omap_enable_wakeup(up, false);
+
 	uart_resume_port(&serial_omap_reg, &up->port);
 
 	return 0;
@@ -1877,17 +1890,7 @@ static int serial_omap_runtime_suspend(struct device *dev)
 
 	up->context_loss_cnt = serial_omap_get_context_loss_count(up);
 
-	if (device_may_wakeup(dev)) {
-		if (!up->wakeups_enabled) {
-			serial_omap_enable_wakeup(up, true);
-			up->wakeups_enabled = true;
-		}
-	} else {
-		if (up->wakeups_enabled) {
-			serial_omap_enable_wakeup(up, false);
-			up->wakeups_enabled = false;
-		}
-	}
+	serial_omap_enable_wakeup(up, true);
 
 	up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
 	schedule_work(&up->qos_work);
@@ -1901,6 +1904,8 @@ static int serial_omap_runtime_resume(struct device *dev)
 
 	int loss_cnt = serial_omap_get_context_loss_count(up);
 
+	serial_omap_enable_wakeup(up, false);
+
 	if (loss_cnt < 0) {
 		dev_dbg(dev, "serial_omap_get_context_loss_count failed : %d\n",
 			loss_cnt);

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] serial: omap: Fix missing pm_runtime_resume handling by simplifying code
  2014-03-25 18:48 [PATCH] serial: omap: Fix missing pm_runtime_resume handling by simplifying code Tony Lindgren
@ 2014-03-25 18:52 ` Felipe Balbi
  2014-03-25 19:28   ` Tony Lindgren
  2014-04-10 21:47 ` Felipe Balbi
  1 sibling, 1 reply; 4+ messages in thread
From: Felipe Balbi @ 2014-03-25 18:52 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Greg KH, linux-serial, linux-omap, Jiri Slaby, Kevin Hilman,
	Felipe Balbi

[-- Attachment #1: Type: text/plain, Size: 3980 bytes --]

On Tue, Mar 25, 2014 at 11:48:47AM -0700, Tony Lindgren wrote:
> The lack of pm_runtime_resume handling for the device state leads into
> device wake-up interrupts not working after a while for runtime PM.
> 
> Also, serial-omap is confused about the use of device_may_wakeup.
> The checks for device_may_wakeup should only be done for suspend and
> resume, not for pm_runtime_suspend and pm_runtime_resume. The wake-up
> events for PM runtime should always be enabled.
> 
> The lack of pm_runtime_resume handling leads into device wake-up
> interrupts not working after a while for runtime PM.
> 
> Rather than try to patch over the issue of adding complex tests to
> the pm_runtime_resume, let's fix the issues properly:
> 
> 1. Make serial_omap_enable_wakeup deal with all internal PM state
>    handling so we don't need to test for up->wakeups_enabled elsewhere.
> 
>    Later on once omap3 boots in device tree only mode we can also
>    remove the up->wakeups_enabled flag and rely on the wake-up
>    interrupt enable/disable state alone.
> 
> 2. Do the device_may_wakeup checks in suspend and resume only,
>    for runtime PM the wake-up events need to be always enabled.
> 
> 3. Finally just call serial_omap_enable_wakeup and make sure we
>    call it also in pm_runtime_resume.
> 
> 4. Note that we also have to use disable_irq_nosync as serial_omap_irq
>    calls pm_runtime_get_sync.
> 
> Fixes: 2a0b965cfb6e (serial: omap: Add support for optional wake-up)
> Cc: stable@vger.kernel.org # v3.13+
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> 
> --- a/drivers/tty/serial/omap-serial.c
> +++ b/drivers/tty/serial/omap-serial.c
> @@ -225,14 +225,19 @@ static inline void serial_omap_enable_wakeirq(struct uart_omap_port *up,
>  	if (enable)
>  		enable_irq(up->wakeirq);
>  	else
> -		disable_irq(up->wakeirq);
> +		disable_irq_nosync(up->wakeirq);

looks to me liket his should be a separate fix of its own...

>  static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
>  {
>  	struct omap_uart_port_info *pdata = dev_get_platdata(up->dev);
>  
> +	if (enable == up->wakeups_enabled)
> +		return;

is there any case where you would call this function twice with the same
argument ?

> +
>  	serial_omap_enable_wakeirq(up, enable);
> +	up->wakeups_enabled = enable;
> +
>  	if (!pdata || !pdata->enable_wakeup)
>  		return;
>  
> @@ -1495,6 +1500,11 @@ static int serial_omap_suspend(struct device *dev)
>  	uart_suspend_port(&serial_omap_reg, &up->port);
>  	flush_work(&up->qos_work);
>  
> +	if (device_may_wakeup(dev))
> +		serial_omap_enable_wakeup(up, true);
> +	else
> +		serial_omap_enable_wakeup(up, false);
> +
>  	return 0;
>  }
>  
> @@ -1502,6 +1512,9 @@ static int serial_omap_resume(struct device *dev)
>  {
>  	struct uart_omap_port *up = dev_get_drvdata(dev);
>  
> +	if (device_may_wakeup(dev))
> +		serial_omap_enable_wakeup(up, false);
> +
>  	uart_resume_port(&serial_omap_reg, &up->port);
>  
>  	return 0;
> @@ -1877,17 +1890,7 @@ static int serial_omap_runtime_suspend(struct device *dev)
>  
>  	up->context_loss_cnt = serial_omap_get_context_loss_count(up);
>  
> -	if (device_may_wakeup(dev)) {
> -		if (!up->wakeups_enabled) {
> -			serial_omap_enable_wakeup(up, true);
> -			up->wakeups_enabled = true;
> -		}
> -	} else {
> -		if (up->wakeups_enabled) {
> -			serial_omap_enable_wakeup(up, false);
> -			up->wakeups_enabled = false;
> -		}
> -	}
> +	serial_omap_enable_wakeup(up, true);
>  
>  	up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
>  	schedule_work(&up->qos_work);
> @@ -1901,6 +1904,8 @@ static int serial_omap_runtime_resume(struct device *dev)
>  
>  	int loss_cnt = serial_omap_get_context_loss_count(up);
>  
> +	serial_omap_enable_wakeup(up, false);
> +
>  	if (loss_cnt < 0) {
>  		dev_dbg(dev, "serial_omap_get_context_loss_count failed : %d\n",
>  			loss_cnt);

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] serial: omap: Fix missing pm_runtime_resume handling by simplifying code
  2014-03-25 18:52 ` Felipe Balbi
@ 2014-03-25 19:28   ` Tony Lindgren
  0 siblings, 0 replies; 4+ messages in thread
From: Tony Lindgren @ 2014-03-25 19:28 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, linux-serial, linux-omap, Jiri Slaby, Kevin Hilman

* Felipe Balbi <balbi@ti.com> [140325 11:57]:
> On Tue, Mar 25, 2014 at 11:48:47AM -0700, Tony Lindgren wrote:
> > The lack of pm_runtime_resume handling for the device state leads into
> > device wake-up interrupts not working after a while for runtime PM.
> > 
> > Also, serial-omap is confused about the use of device_may_wakeup.
> > The checks for device_may_wakeup should only be done for suspend and
> > resume, not for pm_runtime_suspend and pm_runtime_resume. The wake-up
> > events for PM runtime should always be enabled.
> > 
> > The lack of pm_runtime_resume handling leads into device wake-up
> > interrupts not working after a while for runtime PM.
> > 
> > Rather than try to patch over the issue of adding complex tests to
> > the pm_runtime_resume, let's fix the issues properly:
> > 
> > 1. Make serial_omap_enable_wakeup deal with all internal PM state
> >    handling so we don't need to test for up->wakeups_enabled elsewhere.
> > 
> >    Later on once omap3 boots in device tree only mode we can also
> >    remove the up->wakeups_enabled flag and rely on the wake-up
> >    interrupt enable/disable state alone.
> > 
> > 2. Do the device_may_wakeup checks in suspend and resume only,
> >    for runtime PM the wake-up events need to be always enabled.
> > 
> > 3. Finally just call serial_omap_enable_wakeup and make sure we
> >    call it also in pm_runtime_resume.
> > 
> > 4. Note that we also have to use disable_irq_nosync as serial_omap_irq
> >    calls pm_runtime_get_sync.
> > 
> > Fixes: 2a0b965cfb6e (serial: omap: Add support for optional wake-up)
> > Cc: stable@vger.kernel.org # v3.13+
> > Signed-off-by: Tony Lindgren <tony@atomide.com>
> > 
> > --- a/drivers/tty/serial/omap-serial.c
> > +++ b/drivers/tty/serial/omap-serial.c
> > @@ -225,14 +225,19 @@ static inline void serial_omap_enable_wakeirq(struct uart_omap_port *up,
> >  	if (enable)
> >  		enable_irq(up->wakeirq);
> >  	else
> > -		disable_irq(up->wakeirq);
> > +		disable_irq_nosync(up->wakeirq);
> 
> looks to me liket his should be a separate fix of its own...

I don't think fixing disable_irq_nosync here is not needed without
fixing the rest. We're currently never calling serial_omap_enable_wakeup
from the runtime PM resume path.

So serial_omap_enable_wakeirq(up, 0) would only get called in the case
of device_may_wakeup disabled from serial_omap_runtime_suspend, which is
not called from the interrupt context.
 
> >  static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
> >  {
> >  	struct omap_uart_port_info *pdata = dev_get_platdata(up->dev);
> >  
> > +	if (enable == up->wakeups_enabled)
> > +		return;
> 
> is there any case where you would call this function twice with the same
> argument ?

Yes at least when serial-omap is runtime PM enabled and doing a suspend
without device_may_wakeup being set.

I'd like to get rid of the wakeups_enabled, but it's probably safest to do
that when ripping out the remaining context_loos_cnt stuff after we've made
omap3 to boot also in device tree only mode.

Regards,

Tony

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] serial: omap: Fix missing pm_runtime_resume handling by simplifying code
  2014-03-25 18:48 [PATCH] serial: omap: Fix missing pm_runtime_resume handling by simplifying code Tony Lindgren
  2014-03-25 18:52 ` Felipe Balbi
@ 2014-04-10 21:47 ` Felipe Balbi
  1 sibling, 0 replies; 4+ messages in thread
From: Felipe Balbi @ 2014-04-10 21:47 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Greg KH, linux-serial, linux-omap, Jiri Slaby, Kevin Hilman,
	Felipe Balbi

[-- Attachment #1: Type: text/plain, Size: 1658 bytes --]

On Tue, Mar 25, 2014 at 11:48:47AM -0700, Tony Lindgren wrote:
> The lack of pm_runtime_resume handling for the device state leads into
> device wake-up interrupts not working after a while for runtime PM.
> 
> Also, serial-omap is confused about the use of device_may_wakeup.
> The checks for device_may_wakeup should only be done for suspend and
> resume, not for pm_runtime_suspend and pm_runtime_resume. The wake-up
> events for PM runtime should always be enabled.
> 
> The lack of pm_runtime_resume handling leads into device wake-up
> interrupts not working after a while for runtime PM.
> 
> Rather than try to patch over the issue of adding complex tests to
> the pm_runtime_resume, let's fix the issues properly:
> 
> 1. Make serial_omap_enable_wakeup deal with all internal PM state
>    handling so we don't need to test for up->wakeups_enabled elsewhere.
> 
>    Later on once omap3 boots in device tree only mode we can also
>    remove the up->wakeups_enabled flag and rely on the wake-up
>    interrupt enable/disable state alone.
> 
> 2. Do the device_may_wakeup checks in suspend and resume only,
>    for runtime PM the wake-up events need to be always enabled.
> 
> 3. Finally just call serial_omap_enable_wakeup and make sure we
>    call it also in pm_runtime_resume.
> 
> 4. Note that we also have to use disable_irq_nosync as serial_omap_irq
>    calls pm_runtime_get_sync.
> 
> Fixes: 2a0b965cfb6e (serial: omap: Add support for optional wake-up)
> Cc: stable@vger.kernel.org # v3.13+
> Signed-off-by: Tony Lindgren <tony@atomide.com>

FWIW:

Acked-by: Felipe Balbi <balbi@ti.com>

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-04-10 21:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-25 18:48 [PATCH] serial: omap: Fix missing pm_runtime_resume handling by simplifying code Tony Lindgren
2014-03-25 18:52 ` Felipe Balbi
2014-03-25 19:28   ` Tony Lindgren
2014-04-10 21:47 ` Felipe Balbi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).