|
@@ -52,6 +52,7 @@ struct serial_private {
|
|
struct pci_dev *dev;
|
|
struct pci_dev *dev;
|
|
unsigned int nr;
|
|
unsigned int nr;
|
|
struct pci_serial_quirk *quirk;
|
|
struct pci_serial_quirk *quirk;
|
|
|
|
+ const struct pciserial_board *board;
|
|
int line[0];
|
|
int line[0];
|
|
};
|
|
};
|
|
|
|
|
|
@@ -3896,6 +3897,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
priv->nr = i;
|
|
priv->nr = i;
|
|
|
|
+ priv->board = board;
|
|
return priv;
|
|
return priv;
|
|
|
|
|
|
err_deinit:
|
|
err_deinit:
|
|
@@ -3906,7 +3908,7 @@ err_out:
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(pciserial_init_ports);
|
|
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;
|
|
struct pci_serial_quirk *quirk;
|
|
int i;
|
|
int i;
|
|
@@ -3920,7 +3922,11 @@ void pciserial_remove_ports(struct serial_private *priv)
|
|
quirk = find_quirk(priv->dev);
|
|
quirk = find_quirk(priv->dev);
|
|
if (quirk->exit)
|
|
if (quirk->exit)
|
|
quirk->exit(priv->dev);
|
|
quirk->exit(priv->dev);
|
|
|
|
+}
|
|
|
|
|
|
|
|
+void pciserial_remove_ports(struct serial_private *priv)
|
|
|
|
+{
|
|
|
|
+ pciserial_detach_ports(priv);
|
|
kfree(priv);
|
|
kfree(priv);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(pciserial_remove_ports);
|
|
EXPORT_SYMBOL_GPL(pciserial_remove_ports);
|
|
@@ -5611,7 +5617,7 @@ static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev,
|
|
return PCI_ERS_RESULT_DISCONNECT;
|
|
return PCI_ERS_RESULT_DISCONNECT;
|
|
|
|
|
|
if (priv)
|
|
if (priv)
|
|
- pciserial_suspend_ports(priv);
|
|
|
|
|
|
+ pciserial_detach_ports(priv);
|
|
|
|
|
|
pci_disable_device(dev);
|
|
pci_disable_device(dev);
|
|
|
|
|
|
@@ -5636,9 +5642,18 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
|
|
static void serial8250_io_resume(struct pci_dev *dev)
|
|
static void serial8250_io_resume(struct pci_dev *dev)
|
|
{
|
|
{
|
|
struct serial_private *priv = pci_get_drvdata(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 = {
|
|
static const struct pci_error_handlers serial8250_err_handler = {
|