diff options
Diffstat (limited to 'drivers/serial/jsm/jsm_driver.c')
-rw-r--r-- | drivers/serial/jsm/jsm_driver.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index b3604aa322a4..eaf545014119 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c | |||
@@ -26,6 +26,7 @@ | |||
26 | ***********************************************************************/ | 26 | ***********************************************************************/ |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include "jsm.h" | 31 | #include "jsm.h" |
31 | 32 | ||
@@ -48,6 +49,17 @@ struct uart_driver jsm_uart_driver = { | |||
48 | .nr = NR_PORTS, | 49 | .nr = NR_PORTS, |
49 | }; | 50 | }; |
50 | 51 | ||
52 | static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev, | ||
53 | pci_channel_state_t state); | ||
54 | static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev); | ||
55 | static void jsm_io_resume(struct pci_dev *pdev); | ||
56 | |||
57 | static struct pci_error_handlers jsm_err_handler = { | ||
58 | .error_detected = jsm_io_error_detected, | ||
59 | .slot_reset = jsm_io_slot_reset, | ||
60 | .resume = jsm_io_resume, | ||
61 | }; | ||
62 | |||
51 | int jsm_debug; | 63 | int jsm_debug; |
52 | module_param(jsm_debug, int, 0); | 64 | module_param(jsm_debug, int, 0); |
53 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); | 65 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); |
@@ -123,7 +135,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device | |||
123 | } | 135 | } |
124 | 136 | ||
125 | rc = request_irq(brd->irq, brd->bd_ops->intr, | 137 | rc = request_irq(brd->irq, brd->bd_ops->intr, |
126 | IRQF_DISABLED|IRQF_SHARED, "JSM", brd); | 138 | IRQF_SHARED, "JSM", brd); |
127 | if (rc) { | 139 | if (rc) { |
128 | printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq); | 140 | printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq); |
129 | goto out_iounmap; | 141 | goto out_iounmap; |
@@ -164,9 +176,11 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device | |||
164 | } | 176 | } |
165 | 177 | ||
166 | pci_set_drvdata(pdev, brd); | 178 | pci_set_drvdata(pdev, brd); |
179 | pci_save_state(pdev); | ||
167 | 180 | ||
168 | return 0; | 181 | return 0; |
169 | out_free_irq: | 182 | out_free_irq: |
183 | jsm_remove_uart_port(brd); | ||
170 | free_irq(brd->irq, brd); | 184 | free_irq(brd->irq, brd); |
171 | out_iounmap: | 185 | out_iounmap: |
172 | iounmap(brd->re_map_membase); | 186 | iounmap(brd->re_map_membase); |
@@ -222,8 +236,42 @@ static struct pci_driver jsm_driver = { | |||
222 | .id_table = jsm_pci_tbl, | 236 | .id_table = jsm_pci_tbl, |
223 | .probe = jsm_probe_one, | 237 | .probe = jsm_probe_one, |
224 | .remove = __devexit_p(jsm_remove_one), | 238 | .remove = __devexit_p(jsm_remove_one), |
239 | .err_handler = &jsm_err_handler, | ||
225 | }; | 240 | }; |
226 | 241 | ||
242 | static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev, | ||
243 | pci_channel_state_t state) | ||
244 | { | ||
245 | struct jsm_board *brd = pci_get_drvdata(pdev); | ||
246 | |||
247 | jsm_remove_uart_port(brd); | ||
248 | |||
249 | return PCI_ERS_RESULT_NEED_RESET; | ||
250 | } | ||
251 | |||
252 | static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev) | ||
253 | { | ||
254 | int rc; | ||
255 | |||
256 | rc = pci_enable_device(pdev); | ||
257 | |||
258 | if (rc) | ||
259 | return PCI_ERS_RESULT_DISCONNECT; | ||
260 | |||
261 | pci_set_master(pdev); | ||
262 | |||
263 | return PCI_ERS_RESULT_RECOVERED; | ||
264 | } | ||
265 | |||
266 | static void jsm_io_resume(struct pci_dev *pdev) | ||
267 | { | ||
268 | struct jsm_board *brd = pci_get_drvdata(pdev); | ||
269 | |||
270 | pci_restore_state(pdev); | ||
271 | |||
272 | jsm_uart_port_init(brd); | ||
273 | } | ||
274 | |||
227 | static int __init jsm_init_module(void) | 275 | static int __init jsm_init_module(void) |
228 | { | 276 | { |
229 | int rc; | 277 | int rc; |