aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Vaga <federico.vaga@gmail.com>2013-04-15 16:01:07 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-05-07 19:57:22 -0700
commit70f4184b8eeb04a2b8ad2778a76ffac3a0d4e4d2 (patch)
tree5bc7205e8c0730cbcf15fa8cdbcd98ca47194a45
parentf7cfcd277732f50bbdaf56880546faddbb2a73ba (diff)
serial_core.c: add put_device() after device_find_child()
commit 5a65dcc04cda41f4122aacc37a5a348454645399 upstream. The serial core uses device_find_child() but does not drop the reference to the retrieved child after using it. This patch add the missing put_device(). What I have done to test this issue. I used a machine with an AMBA PL011 serial driver. I tested the patch on next-20120408 because the last branch [next-20120415] does not boot on this board. For test purpose, I added some pr_info() messages to print the refcount after device_find_child() (lines: 1937,2009), and after put_device() (lines: 1947, 2021). Boot the machine *without* put_device(). Then: echo reboot > /sys/power/disk echo disk > /sys/power/state [ 87.058575] uart_suspend_port:1937 refcount 4 [ 87.058582] uart_suspend_port:1947 refcount 4 [ 87.098083] uart_resume_port:2009refcount 5 [ 87.098088] uart_resume_port:2021 refcount 5 echo disk > /sys/power/state [ 103.055574] uart_suspend_port:1937 refcount 6 [ 103.055580] uart_suspend_port:1947 refcount 6 [ 103.095322] uart_resume_port:2009 refcount 7 [ 103.095327] uart_resume_port:2021 refcount 7 echo disk > /sys/power/state [ 252.459580] uart_suspend_port:1937 refcount 8 [ 252.459586] uart_suspend_port:1947 refcount 8 [ 252.499611] uart_resume_port:2009 refcount 9 [ 252.499616] uart_resume_port:2021 refcount 9 The refcount continuously increased. Boot the machine *with* this patch. Then: echo reboot > /sys/power/disk echo disk > /sys/power/state [ 159.333559] uart_suspend_port:1937 refcount 4 [ 159.333566] uart_suspend_port:1947 refcount 3 [ 159.372751] uart_resume_port:2009 refcount 4 [ 159.372755] uart_resume_port:2021 refcount 3 echo disk > /sys/power/state [ 185.713614] uart_suspend_port:1937 refcount 4 [ 185.713621] uart_suspend_port:1947 refcount 3 [ 185.752935] uart_resume_port:2009 refcount 4 [ 185.752940] uart_resume_port:2021 refcount 3 echo disk > /sys/power/state [ 207.458584] uart_suspend_port:1937 refcount 4 [ 207.458591] uart_suspend_port:1947 refcount 3 [ 207.498598] uart_resume_port:2009 refcount 4 [ 207.498605] uart_resume_port:2021 refcount 3 The refcount correctly handled. Signed-off-by: Federico Vaga <federico.vaga@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/serial_core.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index de5e33fc129..28630b61ad1 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1917,6 +1917,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
mutex_unlock(&port->mutex);
return 0;
}
+ put_device(tty_dev);
+
if (console_suspend_enabled || !uart_console(uport))
uport->suspended = 1;
@@ -1982,9 +1984,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
disable_irq_wake(uport->irq);
uport->irq_wake = 0;
}
+ put_device(tty_dev);
mutex_unlock(&port->mutex);
return 0;
}
+ put_device(tty_dev);
uport->suspended = 0;
/*