diff options
author | Jingchang Lu <jingchang.lu@freescale.com> | 2014-11-11 02:09:05 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-11-25 20:06:40 -0500 |
commit | 8ad3b1352693972b737607c7b9c89b56d45fea9b (patch) | |
tree | 97e18010e637f02ad4740511d8e43837d2b88e72 /drivers/tty | |
parent | 261119f727a4c7cfc001eed0d94cea70e662433a (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.c | 66 |
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 | ||
253 | static 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 | |||
263 | static 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 | ||
274 | static inline void of_serial_suspend_8250(struct of_serial_info *info) | ||
275 | { | ||
276 | } | ||
277 | |||
278 | static inline void of_serial_resume_8250(struct of_serial_info *info) | ||
279 | { | ||
280 | } | ||
281 | #endif | ||
282 | |||
283 | static 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 | |||
298 | static 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 | ||
313 | static 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, |