mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-08-26 16:51:08 +00:00
gve: Implement suspend/resume/shutdown
Add support for suspend, resume and shutdown. Signed-off-by: Catherine Sullivan <csully@google.com> Signed-off-by: David Awogbemila <awogbemila@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
497dbb2b97
commit
974365e518
@ -557,6 +557,8 @@ struct gve_priv {
|
||||
u32 page_alloc_fail; /* count of page alloc fails */
|
||||
u32 dma_mapping_error; /* count of dma mapping errors */
|
||||
u32 stats_report_trigger_cnt; /* count of device-requested stats-reports since last reset */
|
||||
u32 suspend_cnt; /* count of times suspended */
|
||||
u32 resume_cnt; /* count of times resumed */
|
||||
struct workqueue_struct *gve_wq;
|
||||
struct work_struct service_task;
|
||||
struct work_struct stats_report_task;
|
||||
@ -573,6 +575,7 @@ struct gve_priv {
|
||||
|
||||
/* Gvnic device link speed from hypervisor. */
|
||||
u64 link_speed;
|
||||
bool up_before_suspend; /* True if dev was up before suspend */
|
||||
|
||||
struct gve_options_dqo_rda options_dqo_rda;
|
||||
struct gve_ptype_lut *ptype_lut_dqo;
|
||||
|
@ -1676,6 +1676,58 @@ static void gve_remove(struct pci_dev *pdev)
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static void gve_shutdown(struct pci_dev *pdev)
|
||||
{
|
||||
struct net_device *netdev = pci_get_drvdata(pdev);
|
||||
struct gve_priv *priv = netdev_priv(netdev);
|
||||
bool was_up = netif_carrier_ok(priv->dev);
|
||||
|
||||
rtnl_lock();
|
||||
if (was_up && gve_close(priv->dev)) {
|
||||
/* If the dev was up, attempt to close, if close fails, reset */
|
||||
gve_reset_and_teardown(priv, was_up);
|
||||
} else {
|
||||
/* If the dev wasn't up or close worked, finish tearing down */
|
||||
gve_teardown_priv_resources(priv);
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int gve_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
{
|
||||
struct net_device *netdev = pci_get_drvdata(pdev);
|
||||
struct gve_priv *priv = netdev_priv(netdev);
|
||||
bool was_up = netif_carrier_ok(priv->dev);
|
||||
|
||||
priv->suspend_cnt++;
|
||||
rtnl_lock();
|
||||
if (was_up && gve_close(priv->dev)) {
|
||||
/* If the dev was up, attempt to close, if close fails, reset */
|
||||
gve_reset_and_teardown(priv, was_up);
|
||||
} else {
|
||||
/* If the dev wasn't up or close worked, finish tearing down */
|
||||
gve_teardown_priv_resources(priv);
|
||||
}
|
||||
priv->up_before_suspend = was_up;
|
||||
rtnl_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gve_resume(struct pci_dev *pdev)
|
||||
{
|
||||
struct net_device *netdev = pci_get_drvdata(pdev);
|
||||
struct gve_priv *priv = netdev_priv(netdev);
|
||||
int err;
|
||||
|
||||
priv->resume_cnt++;
|
||||
rtnl_lock();
|
||||
err = gve_reset_recovery(priv, priv->up_before_suspend);
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static const struct pci_device_id gve_id_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_GOOGLE, PCI_DEV_ID_GVNIC) },
|
||||
{ }
|
||||
@ -1686,6 +1738,11 @@ static struct pci_driver gvnic_driver = {
|
||||
.id_table = gve_id_table,
|
||||
.probe = gve_probe,
|
||||
.remove = gve_remove,
|
||||
.shutdown = gve_shutdown,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = gve_suspend,
|
||||
.resume = gve_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
module_pci_driver(gvnic_driver);
|
||||
|
Loading…
Reference in New Issue
Block a user