diff options
author | Kristen Carlson Accardi <kristen@linux.intel.com> | 2011-08-26 06:35:16 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-26 14:01:13 -0400 |
commit | 88e5173ff12e6832899ac74ed0f3395107af2811 (patch) | |
tree | 579faa69677a23a264c0523ca8fbbdb314c2c7b1 /drivers/tty/serial/mfd.c | |
parent | 0b058353abfcdba4403af60f06998da590ebeffe (diff) |
hsu: add runtime pm support
Doesn't appear to be much to do here, however having the suspend/resume
functions will allow the d3/d0 transitions to be sent by the pci core.
Signed-off-by: Kristen Carlson Accardi <kristen@linux.intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty/serial/mfd.c')
-rw-r--r-- | drivers/tty/serial/mfd.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index cab52f4a88b0..cfa750163672 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/io.h> | 39 | #include <linux/io.h> |
40 | #include <linux/debugfs.h> | 40 | #include <linux/debugfs.h> |
41 | #include <linux/pm_runtime.h> | ||
41 | 42 | ||
42 | #define HSU_DMA_BUF_SIZE 2048 | 43 | #define HSU_DMA_BUF_SIZE 2048 |
43 | 44 | ||
@@ -764,6 +765,8 @@ static int serial_hsu_startup(struct uart_port *port) | |||
764 | container_of(port, struct uart_hsu_port, port); | 765 | container_of(port, struct uart_hsu_port, port); |
765 | unsigned long flags; | 766 | unsigned long flags; |
766 | 767 | ||
768 | pm_runtime_get_sync(up->dev); | ||
769 | |||
767 | /* | 770 | /* |
768 | * Clear the FIFO buffers and disable them. | 771 | * Clear the FIFO buffers and disable them. |
769 | * (they will be reenabled in set_termios()) | 772 | * (they will be reenabled in set_termios()) |
@@ -871,6 +874,8 @@ static void serial_hsu_shutdown(struct uart_port *port) | |||
871 | UART_FCR_CLEAR_RCVR | | 874 | UART_FCR_CLEAR_RCVR | |
872 | UART_FCR_CLEAR_XMIT); | 875 | UART_FCR_CLEAR_XMIT); |
873 | serial_out(up, UART_FCR, 0); | 876 | serial_out(up, UART_FCR, 0); |
877 | |||
878 | pm_runtime_put(up->dev); | ||
874 | } | 879 | } |
875 | 880 | ||
876 | static void | 881 | static void |
@@ -1249,6 +1254,39 @@ static int serial_hsu_resume(struct pci_dev *pdev) | |||
1249 | #define serial_hsu_resume NULL | 1254 | #define serial_hsu_resume NULL |
1250 | #endif | 1255 | #endif |
1251 | 1256 | ||
1257 | #ifdef CONFIG_PM_RUNTIME | ||
1258 | static int serial_hsu_runtime_idle(struct device *dev) | ||
1259 | { | ||
1260 | int err; | ||
1261 | |||
1262 | err = pm_schedule_suspend(dev, 500); | ||
1263 | if (err) | ||
1264 | return -EBUSY; | ||
1265 | |||
1266 | return 0; | ||
1267 | } | ||
1268 | |||
1269 | static int serial_hsu_runtime_suspend(struct device *dev) | ||
1270 | { | ||
1271 | return 0; | ||
1272 | } | ||
1273 | |||
1274 | static int serial_hsu_runtime_resume(struct device *dev) | ||
1275 | { | ||
1276 | return 0; | ||
1277 | } | ||
1278 | #else | ||
1279 | #define serial_hsu_runtime_idle NULL | ||
1280 | #define serial_hsu_runtime_suspend NULL | ||
1281 | #define serial_hsu_runtime_resume NULL | ||
1282 | #endif | ||
1283 | |||
1284 | static const struct dev_pm_ops serial_hsu_pm_ops = { | ||
1285 | .runtime_suspend = serial_hsu_runtime_suspend, | ||
1286 | .runtime_resume = serial_hsu_runtime_resume, | ||
1287 | .runtime_idle = serial_hsu_runtime_idle, | ||
1288 | }; | ||
1289 | |||
1252 | /* temp global pointer before we settle down on using one or four PCI dev */ | 1290 | /* temp global pointer before we settle down on using one or four PCI dev */ |
1253 | static struct hsu_port *phsu; | 1291 | static struct hsu_port *phsu; |
1254 | 1292 | ||
@@ -1315,6 +1353,9 @@ static int serial_hsu_probe(struct pci_dev *pdev, | |||
1315 | pci_set_drvdata(pdev, uport); | 1353 | pci_set_drvdata(pdev, uport); |
1316 | } | 1354 | } |
1317 | 1355 | ||
1356 | pm_runtime_put_noidle(&pdev->dev); | ||
1357 | pm_runtime_allow(&pdev->dev); | ||
1358 | |||
1318 | return 0; | 1359 | return 0; |
1319 | 1360 | ||
1320 | err_disable: | 1361 | err_disable: |
@@ -1411,6 +1452,9 @@ static void serial_hsu_remove(struct pci_dev *pdev) | |||
1411 | if (!priv) | 1452 | if (!priv) |
1412 | return; | 1453 | return; |
1413 | 1454 | ||
1455 | pm_runtime_forbid(&pdev->dev); | ||
1456 | pm_runtime_get_noresume(&pdev->dev); | ||
1457 | |||
1414 | /* For port 0/1/2, priv is the address of uart_hsu_port */ | 1458 | /* For port 0/1/2, priv is the address of uart_hsu_port */ |
1415 | if (pdev->device != 0x081E) { | 1459 | if (pdev->device != 0x081E) { |
1416 | up = priv; | 1460 | up = priv; |
@@ -1438,6 +1482,9 @@ static struct pci_driver hsu_pci_driver = { | |||
1438 | .remove = __devexit_p(serial_hsu_remove), | 1482 | .remove = __devexit_p(serial_hsu_remove), |
1439 | .suspend = serial_hsu_suspend, | 1483 | .suspend = serial_hsu_suspend, |
1440 | .resume = serial_hsu_resume, | 1484 | .resume = serial_hsu_resume, |
1485 | .driver = { | ||
1486 | .pm = &serial_hsu_pm_ops, | ||
1487 | }, | ||
1441 | }; | 1488 | }; |
1442 | 1489 | ||
1443 | static int __init hsu_pci_init(void) | 1490 | static int __init hsu_pci_init(void) |