mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-16 21:57:31 +07:00
net: atlantic: refactoring pm logic
We now implement .driver.pm callbacks, these allows driver to work correctly in hibernate usecases, especially when used in conjunction with WOL feature. Before that driver only reacted to legacy .suspend/.resume callbacks, that was a limitation in some cases. Signed-off-by: Nikita Danilov <ndanilov@marvell.com> Signed-off-by: Igor Russkikh <irusskikh@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
837c637869
commit
8aaa112a57
@ -1057,44 +1057,6 @@ void aq_nic_free_vectors(struct aq_nic_s *self)
|
||||
err_exit:;
|
||||
}
|
||||
|
||||
int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!netif_running(self->ndev)) {
|
||||
err = 0;
|
||||
goto out;
|
||||
}
|
||||
rtnl_lock();
|
||||
if (pm_msg->event & PM_EVENT_SLEEP || pm_msg->event & PM_EVENT_FREEZE) {
|
||||
self->power_state = AQ_HW_POWER_STATE_D3;
|
||||
netif_device_detach(self->ndev);
|
||||
netif_tx_stop_all_queues(self->ndev);
|
||||
|
||||
err = aq_nic_stop(self);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
aq_nic_deinit(self, !self->aq_hw->aq_nic_cfg->wol);
|
||||
} else {
|
||||
err = aq_nic_init(self);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
err = aq_nic_start(self);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
netif_device_attach(self->ndev);
|
||||
netif_tx_start_all_queues(self->ndev);
|
||||
}
|
||||
|
||||
err_exit:
|
||||
rtnl_unlock();
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
void aq_nic_shutdown(struct aq_nic_s *self)
|
||||
{
|
||||
int err = 0;
|
||||
|
@ -157,7 +157,6 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
|
||||
const struct ethtool_link_ksettings *cmd);
|
||||
struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self);
|
||||
u32 aq_nic_get_fw_version(struct aq_nic_s *self);
|
||||
int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg);
|
||||
int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
|
||||
void aq_nic_shutdown(struct aq_nic_s *self);
|
||||
u8 aq_nic_reserve_filter(struct aq_nic_s *self, enum aq_rx_filter_type type);
|
||||
|
@ -347,29 +347,98 @@ static void aq_pci_shutdown(struct pci_dev *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
static int aq_pci_suspend(struct pci_dev *pdev, pm_message_t pm_msg)
|
||||
static int aq_suspend_common(struct device *dev, bool deep)
|
||||
{
|
||||
struct aq_nic_s *self = pci_get_drvdata(pdev);
|
||||
struct aq_nic_s *nic = pci_get_drvdata(to_pci_dev(dev));
|
||||
|
||||
return aq_nic_change_pm_state(self, &pm_msg);
|
||||
rtnl_lock();
|
||||
|
||||
nic->power_state = AQ_HW_POWER_STATE_D3;
|
||||
netif_device_detach(nic->ndev);
|
||||
netif_tx_stop_all_queues(nic->ndev);
|
||||
|
||||
aq_nic_stop(nic);
|
||||
|
||||
if (deep) {
|
||||
aq_nic_deinit(nic, !nic->aq_hw->aq_nic_cfg->wol);
|
||||
aq_nic_set_power(nic);
|
||||
}
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aq_pci_resume(struct pci_dev *pdev)
|
||||
static int atl_resume_common(struct device *dev, bool deep)
|
||||
{
|
||||
struct aq_nic_s *self = pci_get_drvdata(pdev);
|
||||
pm_message_t pm_msg = PMSG_RESTORE;
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct aq_nic_s *nic;
|
||||
int ret;
|
||||
|
||||
return aq_nic_change_pm_state(self, &pm_msg);
|
||||
nic = pci_get_drvdata(pdev);
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
|
||||
if (deep) {
|
||||
ret = aq_nic_init(nic);
|
||||
if (ret)
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
ret = aq_nic_start(nic);
|
||||
if (ret)
|
||||
goto err_exit;
|
||||
|
||||
netif_device_attach(nic->ndev);
|
||||
netif_tx_start_all_queues(nic->ndev);
|
||||
|
||||
err_exit:
|
||||
rtnl_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aq_pm_freeze(struct device *dev)
|
||||
{
|
||||
return aq_suspend_common(dev, false);
|
||||
}
|
||||
|
||||
static int aq_pm_suspend_poweroff(struct device *dev)
|
||||
{
|
||||
return aq_suspend_common(dev, true);
|
||||
}
|
||||
|
||||
static int aq_pm_thaw(struct device *dev)
|
||||
{
|
||||
return atl_resume_common(dev, false);
|
||||
}
|
||||
|
||||
static int aq_pm_resume_restore(struct device *dev)
|
||||
{
|
||||
return atl_resume_common(dev, true);
|
||||
}
|
||||
|
||||
const struct dev_pm_ops aq_pm_ops = {
|
||||
.suspend = aq_pm_suspend_poweroff,
|
||||
.poweroff = aq_pm_suspend_poweroff,
|
||||
.freeze = aq_pm_freeze,
|
||||
.resume = aq_pm_resume_restore,
|
||||
.restore = aq_pm_resume_restore,
|
||||
.thaw = aq_pm_thaw,
|
||||
};
|
||||
|
||||
static struct pci_driver aq_pci_ops = {
|
||||
.name = AQ_CFG_DRV_NAME,
|
||||
.id_table = aq_pci_tbl,
|
||||
.probe = aq_pci_probe,
|
||||
.remove = aq_pci_remove,
|
||||
.suspend = aq_pci_suspend,
|
||||
.resume = aq_pci_resume,
|
||||
.shutdown = aq_pci_shutdown,
|
||||
#ifdef CONFIG_PM
|
||||
.driver.pm = &aq_pm_ops,
|
||||
#endif
|
||||
};
|
||||
|
||||
int aq_pci_func_register_driver(void)
|
||||
|
Loading…
Reference in New Issue
Block a user