diff options
author | Jun Chen <jun.d.chen@intel.com> | 2012-11-23 06:07:27 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-11-26 18:45:17 -0500 |
commit | 72d4724ea54c360115bca7979167850dfa37ec65 (patch) | |
tree | 0b06a626860799dacbd6fdc64f5fcb76b9e33288 /drivers/tty/serial | |
parent | d7ffb9329012a517575e4c4d49480b6ce0d1529e (diff) |
serial: ifx6x60: Add modem power off function in the platform reboot process
This patch add modem power off function in the reboot process according registering
reboot callback to the reboot_notifier_list. Also realizing the spi shutdown function.
Signed-off-by: Bi Chao <chao.bi@intel.com>
Signed-off-by: Chen Jun <jun.d.chen@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/ifx6x60.c | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 6356dba49e6c..675d94ab0aff 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #include <linux/pm_runtime.h> | 60 | #include <linux/pm_runtime.h> |
61 | #include <linux/spi/ifx_modem.h> | 61 | #include <linux/spi/ifx_modem.h> |
62 | #include <linux/delay.h> | 62 | #include <linux/delay.h> |
63 | #include <linux/reboot.h> | ||
63 | 64 | ||
64 | #include "ifx6x60.h" | 65 | #include "ifx6x60.h" |
65 | 66 | ||
@@ -72,8 +73,14 @@ | |||
72 | #define IFX_SPI_HEADER_0 (-1) | 73 | #define IFX_SPI_HEADER_0 (-1) |
73 | #define IFX_SPI_HEADER_F (-2) | 74 | #define IFX_SPI_HEADER_F (-2) |
74 | 75 | ||
76 | #define PO_POST_DELAY 200 | ||
77 | #define IFX_MDM_RST_PMU 4 | ||
78 | |||
75 | /* forward reference */ | 79 | /* forward reference */ |
76 | static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev); | 80 | static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev); |
81 | static int ifx_modem_reboot_callback(struct notifier_block *nfb, | ||
82 | unsigned long event, void *data); | ||
83 | static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev); | ||
77 | 84 | ||
78 | /* local variables */ | 85 | /* local variables */ |
79 | static int spi_bpw = 16; /* 8, 16 or 32 bit word length */ | 86 | static int spi_bpw = 16; /* 8, 16 or 32 bit word length */ |
@@ -81,6 +88,29 @@ static struct tty_driver *tty_drv; | |||
81 | static struct ifx_spi_device *saved_ifx_dev; | 88 | static struct ifx_spi_device *saved_ifx_dev; |
82 | static struct lock_class_key ifx_spi_key; | 89 | static struct lock_class_key ifx_spi_key; |
83 | 90 | ||
91 | static struct notifier_block ifx_modem_reboot_notifier_block = { | ||
92 | .notifier_call = ifx_modem_reboot_callback, | ||
93 | }; | ||
94 | |||
95 | static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev) | ||
96 | { | ||
97 | gpio_set_value(IFX_MDM_RST_PMU, 1); | ||
98 | msleep(PO_POST_DELAY); | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int ifx_modem_reboot_callback(struct notifier_block *nfb, | ||
104 | unsigned long event, void *data) | ||
105 | { | ||
106 | if (saved_ifx_dev) | ||
107 | ifx_modem_power_off(saved_ifx_dev); | ||
108 | else | ||
109 | pr_warn("no ifx modem active;\n"); | ||
110 | |||
111 | return NOTIFY_OK; | ||
112 | } | ||
113 | |||
84 | /* GPIO/GPE settings */ | 114 | /* GPIO/GPE settings */ |
85 | 115 | ||
86 | /** | 116 | /** |
@@ -1287,6 +1317,9 @@ static int ifx_spi_spi_remove(struct spi_device *spi) | |||
1287 | 1317 | ||
1288 | static void ifx_spi_spi_shutdown(struct spi_device *spi) | 1318 | static void ifx_spi_spi_shutdown(struct spi_device *spi) |
1289 | { | 1319 | { |
1320 | struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi); | ||
1321 | |||
1322 | ifx_modem_power_off(ifx_dev); | ||
1290 | } | 1323 | } |
1291 | 1324 | ||
1292 | /* | 1325 | /* |
@@ -1422,7 +1455,9 @@ static void __exit ifx_spi_exit(void) | |||
1422 | { | 1455 | { |
1423 | /* unregister */ | 1456 | /* unregister */ |
1424 | tty_unregister_driver(tty_drv); | 1457 | tty_unregister_driver(tty_drv); |
1458 | put_tty_driver(tty_drv); | ||
1425 | spi_unregister_driver((void *)&ifx_spi_driver); | 1459 | spi_unregister_driver((void *)&ifx_spi_driver); |
1460 | unregister_reboot_notifier(&ifx_modem_reboot_notifier_block); | ||
1426 | } | 1461 | } |
1427 | 1462 | ||
1428 | /** | 1463 | /** |
@@ -1457,16 +1492,31 @@ static int __init ifx_spi_init(void) | |||
1457 | if (result) { | 1492 | if (result) { |
1458 | pr_err("%s: tty_register_driver failed(%d)", | 1493 | pr_err("%s: tty_register_driver failed(%d)", |
1459 | DRVNAME, result); | 1494 | DRVNAME, result); |
1460 | put_tty_driver(tty_drv); | 1495 | goto err_free_tty; |
1461 | return result; | ||
1462 | } | 1496 | } |
1463 | 1497 | ||
1464 | result = spi_register_driver((void *)&ifx_spi_driver); | 1498 | result = spi_register_driver((void *)&ifx_spi_driver); |
1465 | if (result) { | 1499 | if (result) { |
1466 | pr_err("%s: spi_register_driver failed(%d)", | 1500 | pr_err("%s: spi_register_driver failed(%d)", |
1467 | DRVNAME, result); | 1501 | DRVNAME, result); |
1468 | tty_unregister_driver(tty_drv); | 1502 | goto err_unreg_tty; |
1503 | } | ||
1504 | |||
1505 | result = register_reboot_notifier(&ifx_modem_reboot_notifier_block); | ||
1506 | if (result) { | ||
1507 | pr_err("%s: register ifx modem reboot notifier failed(%d)", | ||
1508 | DRVNAME, result); | ||
1509 | goto err_unreg_spi; | ||
1469 | } | 1510 | } |
1511 | |||
1512 | return 0; | ||
1513 | err_unreg_spi: | ||
1514 | spi_unregister_driver((void *)&ifx_spi_driver); | ||
1515 | err_unreg_tty: | ||
1516 | tty_unregister_driver(tty_drv); | ||
1517 | err_free_tty: | ||
1518 | put_tty_driver(tty_drv); | ||
1519 | |||
1470 | return result; | 1520 | return result; |
1471 | } | 1521 | } |
1472 | 1522 | ||