Merge tag 'v3.10.107' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / tty / serial / 8250 / 8250_pci.c
index 98b8423793fd09f1a486a92fbd2118aa910da279..9243dd729dd4914054310cde00b983d186cdc449 100644 (file)
@@ -55,6 +55,7 @@ struct serial_private {
        unsigned int            nr;
        void __iomem            *remapped_bar[PCI_NUM_BAR_RESOURCES];
        struct pci_serial_quirk *quirk;
+       const struct pciserial_board *board;
        int                     line[0];
 };
 
@@ -3374,6 +3375,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
                }
        }
        priv->nr = i;
+       priv->board = board;
        return priv;
 
 err_deinit:
@@ -3384,7 +3386,7 @@ err_out:
 }
 EXPORT_SYMBOL_GPL(pciserial_init_ports);
 
-void pciserial_remove_ports(struct serial_private *priv)
+void pciserial_detach_ports(struct serial_private *priv)
 {
        struct pci_serial_quirk *quirk;
        int i;
@@ -3404,7 +3406,11 @@ void pciserial_remove_ports(struct serial_private *priv)
        quirk = find_quirk(priv->dev);
        if (quirk->exit)
                quirk->exit(priv->dev);
+}
 
+void pciserial_remove_ports(struct serial_private *priv)
+{
+       pciserial_detach_ports(priv);
        kfree(priv);
 }
 EXPORT_SYMBOL_GPL(pciserial_remove_ports);
@@ -4943,7 +4949,7 @@ static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev,
                return PCI_ERS_RESULT_DISCONNECT;
 
        if (priv)
-               pciserial_suspend_ports(priv);
+               pciserial_detach_ports(priv);
 
        pci_disable_device(dev);
 
@@ -4968,9 +4974,18 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
 static void serial8250_io_resume(struct pci_dev *dev)
 {
        struct serial_private *priv = pci_get_drvdata(dev);
+       const struct pciserial_board *board;
 
-       if (priv)
-               pciserial_resume_ports(priv);
+       if (!priv)
+               return;
+
+       board = priv->board;
+       kfree(priv);
+       priv = pciserial_init_ports(dev, board);
+
+       if (!IS_ERR(priv)) {
+               pci_set_drvdata(dev, priv);
+       }
 }
 
 static const struct pci_error_handlers serial8250_err_handler = {