Skip to content

Commit 8aaa112

Browse files
Nikita Danilovdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: Igor Russkikh <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 837c637 commit 8aaa112

File tree

3 files changed

+78
-48
lines changed

3 files changed

+78
-48
lines changed

drivers/net/ethernet/aquantia/atlantic/aq_nic.c

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,44 +1057,6 @@ void aq_nic_free_vectors(struct aq_nic_s *self)
10571057
err_exit:;
10581058
}
10591059

1060-
int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg)
1061-
{
1062-
int err = 0;
1063-
1064-
if (!netif_running(self->ndev)) {
1065-
err = 0;
1066-
goto out;
1067-
}
1068-
rtnl_lock();
1069-
if (pm_msg->event & PM_EVENT_SLEEP || pm_msg->event & PM_EVENT_FREEZE) {
1070-
self->power_state = AQ_HW_POWER_STATE_D3;
1071-
netif_device_detach(self->ndev);
1072-
netif_tx_stop_all_queues(self->ndev);
1073-
1074-
err = aq_nic_stop(self);
1075-
if (err < 0)
1076-
goto err_exit;
1077-
1078-
aq_nic_deinit(self, !self->aq_hw->aq_nic_cfg->wol);
1079-
} else {
1080-
err = aq_nic_init(self);
1081-
if (err < 0)
1082-
goto err_exit;
1083-
1084-
err = aq_nic_start(self);
1085-
if (err < 0)
1086-
goto err_exit;
1087-
1088-
netif_device_attach(self->ndev);
1089-
netif_tx_start_all_queues(self->ndev);
1090-
}
1091-
1092-
err_exit:
1093-
rtnl_unlock();
1094-
out:
1095-
return err;
1096-
}
1097-
10981060
void aq_nic_shutdown(struct aq_nic_s *self)
10991061
{
11001062
int err = 0;

drivers/net/ethernet/aquantia/atlantic/aq_nic.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
157157
const struct ethtool_link_ksettings *cmd);
158158
struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self);
159159
u32 aq_nic_get_fw_version(struct aq_nic_s *self);
160-
int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg);
161160
int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
162161
void aq_nic_shutdown(struct aq_nic_s *self);
163162
u8 aq_nic_reserve_filter(struct aq_nic_s *self, enum aq_rx_filter_type type);

drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -347,29 +347,98 @@ static void aq_pci_shutdown(struct pci_dev *pdev)
347347
}
348348
}
349349

350-
static int aq_pci_suspend(struct pci_dev *pdev, pm_message_t pm_msg)
350+
static int aq_suspend_common(struct device *dev, bool deep)
351351
{
352-
struct aq_nic_s *self = pci_get_drvdata(pdev);
352+
struct aq_nic_s *nic = pci_get_drvdata(to_pci_dev(dev));
353+
354+
rtnl_lock();
355+
356+
nic->power_state = AQ_HW_POWER_STATE_D3;
357+
netif_device_detach(nic->ndev);
358+
netif_tx_stop_all_queues(nic->ndev);
353359

354-
return aq_nic_change_pm_state(self, &pm_msg);
360+
aq_nic_stop(nic);
361+
362+
if (deep) {
363+
aq_nic_deinit(nic, !nic->aq_hw->aq_nic_cfg->wol);
364+
aq_nic_set_power(nic);
365+
}
366+
367+
rtnl_unlock();
368+
369+
return 0;
355370
}
356371

357-
static int aq_pci_resume(struct pci_dev *pdev)
372+
static int atl_resume_common(struct device *dev, bool deep)
358373
{
359-
struct aq_nic_s *self = pci_get_drvdata(pdev);
360-
pm_message_t pm_msg = PMSG_RESTORE;
374+
struct pci_dev *pdev = to_pci_dev(dev);
375+
struct aq_nic_s *nic;
376+
int ret;
377+
378+
nic = pci_get_drvdata(pdev);
379+
380+
rtnl_lock();
381+
382+
pci_set_power_state(pdev, PCI_D0);
383+
pci_restore_state(pdev);
384+
385+
if (deep) {
386+
ret = aq_nic_init(nic);
387+
if (ret)
388+
goto err_exit;
389+
}
390+
391+
ret = aq_nic_start(nic);
392+
if (ret)
393+
goto err_exit;
394+
395+
netif_device_attach(nic->ndev);
396+
netif_tx_start_all_queues(nic->ndev);
361397

362-
return aq_nic_change_pm_state(self, &pm_msg);
398+
err_exit:
399+
rtnl_unlock();
400+
401+
return ret;
402+
}
403+
404+
static int aq_pm_freeze(struct device *dev)
405+
{
406+
return aq_suspend_common(dev, false);
363407
}
364408

409+
static int aq_pm_suspend_poweroff(struct device *dev)
410+
{
411+
return aq_suspend_common(dev, true);
412+
}
413+
414+
static int aq_pm_thaw(struct device *dev)
415+
{
416+
return atl_resume_common(dev, false);
417+
}
418+
419+
static int aq_pm_resume_restore(struct device *dev)
420+
{
421+
return atl_resume_common(dev, true);
422+
}
423+
424+
const struct dev_pm_ops aq_pm_ops = {
425+
.suspend = aq_pm_suspend_poweroff,
426+
.poweroff = aq_pm_suspend_poweroff,
427+
.freeze = aq_pm_freeze,
428+
.resume = aq_pm_resume_restore,
429+
.restore = aq_pm_resume_restore,
430+
.thaw = aq_pm_thaw,
431+
};
432+
365433
static struct pci_driver aq_pci_ops = {
366434
.name = AQ_CFG_DRV_NAME,
367435
.id_table = aq_pci_tbl,
368436
.probe = aq_pci_probe,
369437
.remove = aq_pci_remove,
370-
.suspend = aq_pci_suspend,
371-
.resume = aq_pci_resume,
372438
.shutdown = aq_pci_shutdown,
439+
#ifdef CONFIG_PM
440+
.driver.pm = &aq_pm_ops,
441+
#endif
373442
};
374443

375444
int aq_pci_func_register_driver(void)

0 commit comments

Comments
 (0)