aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorJingchang Lu <jingchang.lu@freescale.com>2014-11-11 02:09:05 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-11-25 20:06:40 -0500
commit8ad3b1352693972b737607c7b9c89b56d45fea9b (patch)
tree97e18010e637f02ad4740511d8e43837d2b88e72 /drivers/tty
parent261119f727a4c7cfc001eed0d94cea70e662433a (diff)
serial: of-serial: add PM suspend/resume support
This adds suspend/resume support for the of-serial driver to provide power management support on devices attatched. The handling may vary since not every of_serial device is an 8250 port. Currently only 8250 port handling is added in the suspend/resume function based on the type switch. Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Tested-by: Joseph Lo <josephl@nvidia.com> Reviewed-by: Peter Hurley <peter@hurleysoftware.com> Tested-by: Florina Fainelli <f.fainelli@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/of_serial.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 12c95cc64c00..58830bcddb7f 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -9,6 +9,7 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 * 10 *
11 */ 11 */
12#include <linux/console.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/slab.h> 14#include <linux/slab.h>
14#include <linux/delay.h> 15#include <linux/delay.h>
@@ -247,6 +248,70 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
247 return 0; 248 return 0;
248} 249}
249 250
251#ifdef CONFIG_PM_SLEEP
252#ifdef CONFIG_SERIAL_8250
253static void of_serial_suspend_8250(struct of_serial_info *info)
254{
255 struct uart_8250_port *port8250 = serial8250_get_port(info->line);
256 struct uart_port *port = &port8250->port;
257
258 serial8250_suspend_port(info->line);
259 if (info->clk && (!uart_console(port) || console_suspend_enabled))
260 clk_disable_unprepare(info->clk);
261}
262
263static void of_serial_resume_8250(struct of_serial_info *info)
264{
265 struct uart_8250_port *port8250 = serial8250_get_port(info->line);
266 struct uart_port *port = &port8250->port;
267
268 if (info->clk && (!uart_console(port) || console_suspend_enabled))
269 clk_prepare_enable(info->clk);
270
271 serial8250_resume_port(info->line);
272}
273#else
274static inline void of_serial_suspend_8250(struct of_serial_info *info)
275{
276}
277
278static inline void of_serial_resume_8250(struct of_serial_info *info)
279{
280}
281#endif
282
283static int of_serial_suspend(struct device *dev)
284{
285 struct of_serial_info *info = dev_get_drvdata(dev);
286
287 switch (info->type) {
288 case PORT_8250 ... PORT_MAX_8250:
289 of_serial_suspend_8250(info);
290 break;
291 default:
292 break;
293 }
294
295 return 0;
296}
297
298static int of_serial_resume(struct device *dev)
299{
300 struct of_serial_info *info = dev_get_drvdata(dev);
301
302 switch (info->type) {
303 case PORT_8250 ... PORT_MAX_8250:
304 of_serial_resume_8250(info);
305 break;
306 default:
307 break;
308 }
309
310 return 0;
311}
312#endif
313static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume);
314
250/* 315/*
251 * A few common types, add more as needed. 316 * A few common types, add more as needed.
252 */ 317 */
@@ -279,6 +344,7 @@ static struct platform_driver of_platform_serial_driver = {
279 .name = "of_serial", 344 .name = "of_serial",
280 .owner = THIS_MODULE, 345 .owner = THIS_MODULE,
281 .of_match_table = of_platform_serial_table, 346 .of_match_table = of_platform_serial_table,
347 .pm = &of_serial_pm_ops,
282 }, 348 },
283 .probe = of_platform_serial_probe, 349 .probe = of_platform_serial_probe,
284 .remove = of_platform_serial_remove, 350 .remove = of_platform_serial_remove,