diff options
author | Michael Reed <mreed@linux.vnet.ibm.com> | 2011-05-31 12:06:28 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-06-07 09:42:05 -0700 |
commit | 2807190b69f60ce4a04a9c7c523c9bce8cb62b2e (patch) | |
tree | dc13059e5a1ea8fd224af1fdcd9f8bcc8a50135d /drivers/tty | |
parent | ae92c1f5e7b6708371365d262625ac19e67c1e79 (diff) |
8250_pci Add EEH support to the 8250 driver for IBM/Digi PCIe 2-port Adapter
The purpose of the patch is to add EEH support to the 8250_PCI driver
for the IBM/Digi PCIE 2port Async EIA-232 Adapter that uses a PLX
chipset on the PPC platforrm. Basic support for this adapter was
recently added https://lkml.org/lkml/2011/5/11/341
This patch was created against the linux-next kernel
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Breno Leitao <leitao@linux.vnet.ibm.com>
Cc: Scott Kilau <scottk@digi.com>
Signed-off-by: Michael Reed <mreed@linux.vnet.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/8250_pci.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index e1d4668f86a..ae2188ce067 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c @@ -2708,6 +2708,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) board = &pci_boards[ent->driver_data]; rc = pci_enable_device(dev); + pci_save_state(dev); if (rc) return rc; @@ -4002,6 +4003,51 @@ static struct pci_device_id serial_pci_tbl[] = { { 0, } }; +static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev, + pci_channel_state_t state) +{ + struct serial_private *priv = pci_get_drvdata(dev); + + if (state == pci_channel_io_perm_failure) + return PCI_ERS_RESULT_DISCONNECT; + + if (priv) + pciserial_suspend_ports(priv); + + pci_disable_device(dev); + + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev) +{ + int rc; + + rc = pci_enable_device(dev); + + if (rc) + return PCI_ERS_RESULT_DISCONNECT; + + pci_restore_state(dev); + pci_save_state(dev); + + return PCI_ERS_RESULT_RECOVERED; +} + +static void serial8250_io_resume(struct pci_dev *dev) +{ + struct serial_private *priv = pci_get_drvdata(dev); + + if (priv) + pciserial_resume_ports(priv); +} + +static struct pci_error_handlers serial8250_err_handler = { + .error_detected = serial8250_io_error_detected, + .slot_reset = serial8250_io_slot_reset, + .resume = serial8250_io_resume, +}; + static struct pci_driver serial_pci_driver = { .name = "serial", .probe = pciserial_init_one, @@ -4011,6 +4057,7 @@ static struct pci_driver serial_pci_driver = { .resume = pciserial_resume_one, #endif .id_table = serial_pci_tbl, + .err_handler = &serial8250_err_handler, }; static int __init serial8250_pci_init(void) |