2020-07-01 16:53:43

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 00/11] net: ethernet: use generic power management

Linux Kernel Mentee: Remove Legacy Power Management.

The purpose of this patch series is to remove legacy power management callbacks
from net ethernet drivers.

The callbacks performing suspend() and resume() operations are still calling
pci_save_state(), pci_set_power_state(), etc. and handling the power management
themselves, which is not recommended.

The conversion requires the removal of the those function calls and change the
callback definition accordingly and make use of dev_pm_ops structure.

All patches are compile-tested only.

Vaibhav Gupta (11):
typhoon: use generic power management
ne2k-pci: use generic power management
starfire: use generic power management
ena_netdev: use generic power management
liquidio: use generic power management
sundance: use generic power management
benet: use generic power management
mlx4: use generic power management
ksz884x: use generic power management
vxge: use generic power management
natsemi: use generic power management

drivers/net/ethernet/3com/typhoon.c | 53 +++++++++++--------
drivers/net/ethernet/8390/ne2k-pci.c | 29 +++-------
drivers/net/ethernet/adaptec/starfire.c | 23 +++-----
drivers/net/ethernet/amazon/ena/ena_netdev.c | 22 ++++----
.../net/ethernet/cavium/liquidio/lio_main.c | 31 ++---------
drivers/net/ethernet/dlink/sundance.c | 27 +++-------
drivers/net/ethernet/emulex/benet/be_main.c | 22 +++-----
drivers/net/ethernet/mellanox/mlx4/main.c | 11 ++--
drivers/net/ethernet/micrel/ksz884x.c | 25 ++++-----
drivers/net/ethernet/natsemi/natsemi.c | 26 +++------
.../net/ethernet/neterion/vxge/vxge-main.c | 14 ++---
11 files changed, 101 insertions(+), 182 deletions(-)

--
2.27.0


2020-07-01 16:54:00

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 03/11] starfire: use generic power management

With legacy PM, drivers themselves were responsible for managing the
device's power states and takes care of register states.

After upgrading to the generic structure, PCI core will take care of
required tasks and drivers should do only device-specific operations.

Thus, there is no need to call the PCI helper functions like
pci_save/restore_sate() and pci_set_power_state().

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
drivers/net/ethernet/adaptec/starfire.c | 23 ++++++-----------------
1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
index a64191fc2af9..ba0055bb1614 100644
--- a/drivers/net/ethernet/adaptec/starfire.c
+++ b/drivers/net/ethernet/adaptec/starfire.c
@@ -1984,28 +1984,21 @@ static int netdev_close(struct net_device *dev)
return 0;
}

-#ifdef CONFIG_PM
-static int starfire_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused starfire_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);

if (netif_running(dev)) {
netif_device_detach(dev);
netdev_close(dev);
}

- pci_save_state(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev,state));
-
return 0;
}

-static int starfire_resume(struct pci_dev *pdev)
+static int __maybe_unused starfire_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);

if (netif_running(dev)) {
netdev_open(dev);
@@ -2014,8 +2007,6 @@ static int starfire_resume(struct pci_dev *pdev)

return 0;
}
-#endif /* CONFIG_PM */
-

static void starfire_remove_one(struct pci_dev *pdev)
{
@@ -2040,15 +2031,13 @@ static void starfire_remove_one(struct pci_dev *pdev)
free_netdev(dev); /* Will also free np!! */
}

+static SIMPLE_DEV_PM_OPS(starfire_pm_ops, starfire_suspend, starfire_resume);

static struct pci_driver starfire_driver = {
.name = DRV_NAME,
.probe = starfire_init_one,
.remove = starfire_remove_one,
-#ifdef CONFIG_PM
- .suspend = starfire_suspend,
- .resume = starfire_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &starfire_pm_ops,
.id_table = starfire_pci_tbl,
};

--
2.27.0

2020-07-01 16:54:14

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 04/11] ena_netdev: use generic power management

With legacy PM, drivers themselves were responsible for managing the
device's power states and takes care of register states.

After upgrading to the generic structure, PCI core will take care of
required tasks and drivers should do only device-specific operations.

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
drivers/net/ethernet/amazon/ena/ena_netdev.c | 22 ++++++++------------
1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index dda4b8fc9525..91be3ffa1c5c 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -4420,13 +4420,12 @@ static void ena_shutdown(struct pci_dev *pdev)
__ena_shutoff(pdev, true);
}

-#ifdef CONFIG_PM
/* ena_suspend - PM suspend callback
- * @pdev: PCI device information struct
- * @state:power state
+ * @dev_d: Device information struct
*/
-static int ena_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused ena_suspend(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct ena_adapter *adapter = pci_get_drvdata(pdev);

u64_stats_update_begin(&adapter->syncp);
@@ -4445,12 +4444,11 @@ static int ena_suspend(struct pci_dev *pdev, pm_message_t state)
}

/* ena_resume - PM resume callback
- * @pdev: PCI device information struct
- *
+ * @dev_d: Device information struct
*/
-static int ena_resume(struct pci_dev *pdev)
+static int __maybe_unused ena_resume(struct device *dev_d)
{
- struct ena_adapter *adapter = pci_get_drvdata(pdev);
+ struct ena_adapter *adapter = dev_get_drvdata(dev_d);
int rc;

u64_stats_update_begin(&adapter->syncp);
@@ -4462,7 +4460,8 @@ static int ena_resume(struct pci_dev *pdev)
rtnl_unlock();
return rc;
}
-#endif
+
+static SIMPLE_DEV_PM_OPS(ena_pm_ops, ena_suspend, ena_resume);

static struct pci_driver ena_pci_driver = {
.name = DRV_MODULE_NAME,
@@ -4470,10 +4469,7 @@ static struct pci_driver ena_pci_driver = {
.probe = ena_probe,
.remove = ena_remove,
.shutdown = ena_shutdown,
-#ifdef CONFIG_PM
- .suspend = ena_suspend,
- .resume = ena_resume,
-#endif
+ .driver.pm = &ena_pm_ops,
.sriov_configure = pci_sriov_configure_simple,
};

--
2.27.0

2020-07-01 16:54:23

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 05/11] liquidio: use generic power management

Drivers should not use legacy power management as they have to manage power
states and related operations, for the device, themselves. This driver was
handling them with the help of PCI helper functions.

With generic PM, all essentials will be handled by the PCI core. Driver
needs to do only device-specific operations.

The driver defined empty-body .suspend() and .resume() callbacks earlier.
They can now be define NULL and bind with "struct dev_pm_ops" variable.

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
.../net/ethernet/cavium/liquidio/lio_main.c | 31 +++----------------
1 file changed, 5 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 66d31c018c7e..19689d72bc4e 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -405,27 +405,8 @@ static void liquidio_pcie_resume(struct pci_dev *pdev __attribute__((unused)))
/* Nothing to be done here. */
}

-#ifdef CONFIG_PM
-/**
- * \brief called when suspending
- * @param pdev Pointer to PCI device
- * @param state state to suspend to
- */
-static int liquidio_suspend(struct pci_dev *pdev __attribute__((unused)),
- pm_message_t state __attribute__((unused)))
-{
- return 0;
-}
-
-/**
- * \brief called when resuming
- * @param pdev Pointer to PCI device
- */
-static int liquidio_resume(struct pci_dev *pdev __attribute__((unused)))
-{
- return 0;
-}
-#endif
+#define liquidio_suspend NULL
+#define liquidio_resume NULL

/* For PCI-E Advanced Error Recovery (AER) Interface */
static const struct pci_error_handlers liquidio_err_handler = {
@@ -451,17 +432,15 @@ static const struct pci_device_id liquidio_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, liquidio_pci_tbl);

+static SIMPLE_DEV_PM_OPS(liquidio_pm_ops, liquidio_suspend, liquidio_resume);
+
static struct pci_driver liquidio_pci_driver = {
.name = "LiquidIO",
.id_table = liquidio_pci_tbl,
.probe = liquidio_probe,
.remove = liquidio_remove,
.err_handler = &liquidio_err_handler, /* For AER */
-
-#ifdef CONFIG_PM
- .suspend = liquidio_suspend,
- .resume = liquidio_resume,
-#endif
+ .driver.pm = &liquidio_pm_ops,
#ifdef CONFIG_PCI_IOV
.sriov_configure = liquidio_enable_sriov,
#endif
--
2.27.0

2020-07-01 16:54:37

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 06/11] sundance: use generic power management

With legacy PM, drivers themselves were responsible for managing the
device's power states and takes care of register states.

After upgrading to the generic structure, PCI core will take care of
required tasks and drivers should do only device-specific operations.

Thus, there is no need to call the PCI helper functions like
pci_enable/disable_device(), pci_save/restore_sate() and
pci_set_power_state().

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
drivers/net/ethernet/dlink/sundance.c | 27 ++++++++-------------------
1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
index dc566fcc3ba9..ca97e321082d 100644
--- a/drivers/net/ethernet/dlink/sundance.c
+++ b/drivers/net/ethernet/dlink/sundance.c
@@ -1928,11 +1928,9 @@ static void sundance_remove1(struct pci_dev *pdev)
}
}

-#ifdef CONFIG_PM
-
-static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
+static int __maybe_unused sundance_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pci_dev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base;

@@ -1942,30 +1940,24 @@ static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
netdev_close(dev);
netif_device_detach(dev);

- pci_save_state(pci_dev);
if (np->wol_enabled) {
iowrite8(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
iowrite16(RxEnable, ioaddr + MACCtrl1);
}
- pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state),
- np->wol_enabled);
- pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+
+ device_set_wakeup_enable(dev_d, np->wol_enabled);

return 0;
}

-static int sundance_resume(struct pci_dev *pci_dev)
+static int __maybe_unused sundance_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pci_dev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
int err = 0;

if (!netif_running(dev))
return 0;

- pci_set_power_state(pci_dev, PCI_D0);
- pci_restore_state(pci_dev);
- pci_enable_wake(pci_dev, PCI_D0, 0);
-
err = netdev_open(dev);
if (err) {
printk(KERN_ERR "%s: Can't resume interface!\n",
@@ -1979,17 +1971,14 @@ static int sundance_resume(struct pci_dev *pci_dev)
return err;
}

-#endif /* CONFIG_PM */
+static SIMPLE_DEV_PM_OPS(sundance_pm_ops, sundance_suspend, sundance_resume);

static struct pci_driver sundance_driver = {
.name = DRV_NAME,
.id_table = sundance_pci_tbl,
.probe = sundance_probe1,
.remove = sundance_remove1,
-#ifdef CONFIG_PM
- .suspend = sundance_suspend,
- .resume = sundance_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &sundance_pm_ops,
};

static int __init sundance_init(void)
--
2.27.0

2020-07-01 16:55:03

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 08/11] mlx4: use generic power management

With legacy PM, drivers themselves were responsible for managing the
device's power states and takes care of register states.

After upgrading to the generic structure, PCI core will take care of
required tasks and drivers should do only device-specific operations.

Use "struct dev_pm_ops" variable to bind the callbacks.

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
drivers/net/ethernet/mellanox/mlx4/main.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 3d9aa7da95e9..4cae7db8d49c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -4370,8 +4370,9 @@ static const struct pci_error_handlers mlx4_err_handler = {
.resume = mlx4_pci_resume,
};

-static int mlx4_suspend(struct pci_dev *pdev, pm_message_t state)
+static int mlx4_suspend(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
struct mlx4_dev *dev = persist->dev;

@@ -4384,8 +4385,9 @@ static int mlx4_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}

-static int mlx4_resume(struct pci_dev *pdev)
+static int mlx4_resume(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
struct mlx4_dev *dev = persist->dev;
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -4414,14 +4416,15 @@ static int mlx4_resume(struct pci_dev *pdev)
return ret;
}

+static SIMPLE_DEV_PM_OPS(mlx4_pm_ops, mlx4_suspend, mlx4_resume);
+
static struct pci_driver mlx4_driver = {
.name = DRV_NAME,
.id_table = mlx4_pci_table,
.probe = mlx4_init_one,
.shutdown = mlx4_shutdown,
.remove = mlx4_remove_one,
- .suspend = mlx4_suspend,
- .resume = mlx4_resume,
+ .driver.pm = &mlx4_pm_ops,
.err_handler = &mlx4_err_handler,
};

--
2.27.0

2020-07-01 16:55:17

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 09/11] ksz884x: use generic power management

With legacy PM, drivers themselves were responsible for managing the
device's power states and takes care of register states.

After upgrading to the generic structure, PCI core will take care of
required tasks and drivers should do only device-specific operations.

Thus, there is no need to call the PCI helper functions like
pci_enable_wake(), pci_save/restore_sate() and
pci_set_power_state().

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
drivers/net/ethernet/micrel/ksz884x.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index 4fe6aedca22f..24901342ecc0 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -7155,17 +7155,14 @@ static void pcidev_exit(struct pci_dev *pdev)
kfree(info);
}

-#ifdef CONFIG_PM
-static int pcidev_resume(struct pci_dev *pdev)
+static int __maybe_unused pcidev_resume(struct device *dev_d)
{
int i;
- struct platform_info *info = pci_get_drvdata(pdev);
+ struct platform_info *info = dev_get_drvdata(dev_d);
struct dev_info *hw_priv = &info->dev_info;
struct ksz_hw *hw = &hw_priv->hw;

- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D0, 0);
+ device_wakeup_disable(dev_d);

if (hw_priv->wol_enable)
hw_cfg_wol_pme(hw, 0);
@@ -7182,10 +7179,10 @@ static int pcidev_resume(struct pci_dev *pdev)
return 0;
}

-static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state)
+static int pcidev_suspend(struct device *dev_d)
{
int i;
- struct platform_info *info = pci_get_drvdata(pdev);
+ struct platform_info *info = dev_get_drvdata(dev_d);
struct dev_info *hw_priv = &info->dev_info;
struct ksz_hw *hw = &hw_priv->hw;

@@ -7207,12 +7204,9 @@ static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state)
hw_cfg_wol_pme(hw, 1);
}

- pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ device_wakeup_enable(dev_d);
return 0;
}
-#endif

static char pcidev_name[] = "ksz884xp";

@@ -7226,11 +7220,10 @@ static const struct pci_device_id pcidev_table[] = {

MODULE_DEVICE_TABLE(pci, pcidev_table);

+static SIMPLE_DEV_PM_OPS(pcidev_pm_ops, pcidev_suspend, pcidev_resume);
+
static struct pci_driver pci_device_driver = {
-#ifdef CONFIG_PM
- .suspend = pcidev_suspend,
- .resume = pcidev_resume,
-#endif
+ .driver.pm = &pcidev_pm_ops,
.name = pcidev_name,
.id_table = pcidev_table,
.probe = pcidev_init,
--
2.27.0

2020-07-01 16:55:46

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 10/11] vxge: use generic power management

With legacy PM, drivers themselves were responsible for managing the
device's power states and takes care of register states.

After upgrading to the generic structure, PCI core will take care of
required tasks and drivers should do only device-specific operations.

Use "struct dev_pm_ops" variable to bind the callbacks.

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
drivers/net/ethernet/neterion/vxge/vxge-main.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
index 9b63574b6202..5de85b9e9e35 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -3999,12 +3999,11 @@ static void vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask)
}
}

-#ifdef CONFIG_PM
/**
* vxge_pm_suspend - vxge power management suspend entry point
*
*/
-static int vxge_pm_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused vxge_pm_suspend(struct device *dev_d)
{
return -ENOSYS;
}
@@ -4012,13 +4011,11 @@ static int vxge_pm_suspend(struct pci_dev *pdev, pm_message_t state)
* vxge_pm_resume - vxge power management resume entry point
*
*/
-static int vxge_pm_resume(struct pci_dev *pdev)
+static int __maybe_unused vxge_pm_resume(struct device *dev_d)
{
return -ENOSYS;
}

-#endif
-
/**
* vxge_io_error_detected - called when PCI error is detected
* @pdev: Pointer to PCI device
@@ -4796,15 +4793,14 @@ static const struct pci_error_handlers vxge_err_handler = {
.resume = vxge_io_resume,
};

+static SIMPLE_DEV_PM_OPS(vxge_pm_ops, vxge_pm_suspend, vxge_pm_resume);
+
static struct pci_driver vxge_driver = {
.name = VXGE_DRIVER_NAME,
.id_table = vxge_id_table,
.probe = vxge_probe,
.remove = vxge_remove,
-#ifdef CONFIG_PM
- .suspend = vxge_pm_suspend,
- .resume = vxge_pm_resume,
-#endif
+ .driver.pm = &vxge_pm_ops,
.err_handler = &vxge_err_handler,
};

--
2.27.0

2020-07-01 16:55:50

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 02/11] ne2k-pci: use generic power management

With legacy PM, drivers themselves were responsible for managing the
device's power states and takes care of register states.

After upgrading to the generic structure, PCI core will take care of
required tasks and drivers should do only device-specific operations.

Thus, there is no need to call the PCI helper functions like
pci_enable/disable_device(), pci_save/restore_sate() and
pci_set_power_state().

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
drivers/net/ethernet/8390/ne2k-pci.c | 29 ++++++----------------------
1 file changed, 6 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c
index 77d78b4c59c4..e500f0c05725 100644
--- a/drivers/net/ethernet/8390/ne2k-pci.c
+++ b/drivers/net/ethernet/8390/ne2k-pci.c
@@ -699,30 +699,18 @@ static void ne2k_pci_remove_one(struct pci_dev *pdev)
pci_disable_device(pdev);
}

-#ifdef CONFIG_PM
-static int ne2k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused ne2k_pci_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);

netif_device_detach(dev);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));

return 0;
}

-static int ne2k_pci_resume(struct pci_dev *pdev)
+static int __maybe_unused ne2k_pci_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
- int rc;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
- rc = pci_enable_device(pdev);
- if (rc)
- return rc;
+ struct net_device *dev = dev_get_drvdata(dev_d);

NS8390_init(dev, 1);
netif_device_attach(dev);
@@ -730,19 +718,14 @@ static int ne2k_pci_resume(struct pci_dev *pdev)
return 0;
}

-#endif /* CONFIG_PM */
-
+static SIMPLE_DEV_PM_OPS(ne2k_pci_pm_ops, ne2k_pci_suspend, ne2k_pci_resume);

static struct pci_driver ne2k_driver = {
.name = DRV_NAME,
.probe = ne2k_pci_init_one,
.remove = ne2k_pci_remove_one,
.id_table = ne2k_pci_tbl,
-#ifdef CONFIG_PM
- .suspend = ne2k_pci_suspend,
- .resume = ne2k_pci_resume,
-#endif
-
+ .driver.pm = &ne2k_pci_pm_ops,
};


--
2.27.0

2020-07-01 16:56:49

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 07/11] benet: use generic power management

With legacy PM, drivers themselves were responsible for managing the
device's power states and takes care of register states.

After upgrading to the generic structure, PCI core will take care of
required tasks and drivers should do only device-specific operations.

Thus, there is no need to call the PCI helper functions like
pci_enable/disable_device(), pci_save/restore_sate() and
pci_set_power_state().

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
drivers/net/ethernet/emulex/benet/be_main.c | 22 +++++++--------------
1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a7ac23a6862b..e26f59336cfd 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -6037,32 +6037,23 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
return status;
}

-static int be_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused be_suspend(struct device *dev_d)
{
- struct be_adapter *adapter = pci_get_drvdata(pdev);
+ struct be_adapter *adapter = dev_get_drvdata(dev_d);

be_intr_set(adapter, false);
be_cancel_err_detection(adapter);

be_cleanup(adapter);

- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}

-static int be_pci_resume(struct pci_dev *pdev)
+static int __maybe_unused be_pci_resume(struct device *dev_d)
{
- struct be_adapter *adapter = pci_get_drvdata(pdev);
+ struct be_adapter *adapter = dev_get_drvdata(dev_d);
int status = 0;

- status = pci_enable_device(pdev);
- if (status)
- return status;
-
- pci_restore_state(pdev);
-
status = be_resume(adapter);
if (status)
return status;
@@ -6234,13 +6225,14 @@ static const struct pci_error_handlers be_eeh_handlers = {
.resume = be_eeh_resume,
};

+static SIMPLE_DEV_PM_OPS(be_pci_pm_ops, be_suspend, be_pci_resume);
+
static struct pci_driver be_driver = {
.name = DRV_NAME,
.id_table = be_dev_ids,
.probe = be_probe,
.remove = be_remove,
- .suspend = be_suspend,
- .resume = be_pci_resume,
+ .driver.pm = &be_pci_pm_ops,
.shutdown = be_shutdown,
.sriov_configure = be_pci_sriov_configure,
.err_handler = &be_eeh_handlers
--
2.27.0

2020-07-01 16:57:39

by Vaibhav Gupta

[permalink] [raw]
Subject: [PATCH v2 11/11] natsemi: use generic power management

With legacy PM, drivers themselves were responsible for managing the
device's power states and takes care of register states.

After upgrading to the generic structure, PCI core will take care of
required tasks and drivers should do only device-specific operations.

Thus, there is no need to call the PCI helper functions like
pci_enable_device, which is not recommended. Hence, removed.

Compile-tested only.

Signed-off-by: Vaibhav Gupta <[email protected]>
---
drivers/net/ethernet/natsemi/natsemi.c | 26 +++++++-------------------
1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index d21d706b83a7..c2867fe995bc 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -3247,8 +3247,6 @@ static void natsemi_remove1(struct pci_dev *pdev)
free_netdev (dev);
}

-#ifdef CONFIG_PM
-
/*
* The ns83815 chip doesn't have explicit RxStop bits.
* Kicking the Rx or Tx process for a new packet reenables the Rx process
@@ -3275,9 +3273,9 @@ static void natsemi_remove1(struct pci_dev *pdev)
* Interrupts must be disabled, otherwise hands_off can cause irq storms.
*/

-static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused natsemi_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata (pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev);
void __iomem * ioaddr = ns_ioaddr(dev);

@@ -3326,11 +3324,10 @@ static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state)
}


-static int natsemi_resume (struct pci_dev *pdev)
+static int __maybe_unused natsemi_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata (pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev);
- int ret = 0;

rtnl_lock();
if (netif_device_present(dev))
@@ -3339,12 +3336,6 @@ static int natsemi_resume (struct pci_dev *pdev)
const int irq = np->pci_dev->irq;

BUG_ON(!np->hands_off);
- ret = pci_enable_device(pdev);
- if (ret < 0) {
- dev_err(&pdev->dev,
- "pci_enable_device() failed: %d\n", ret);
- goto out;
- }
/* pci_power_on(pdev); */

napi_enable(&np->napi);
@@ -3364,20 +3355,17 @@ static int natsemi_resume (struct pci_dev *pdev)
netif_device_attach(dev);
out:
rtnl_unlock();
- return ret;
+ return 0;
}

-#endif /* CONFIG_PM */
+static SIMPLE_DEV_PM_OPS(natsemi_pm_ops, natsemi_suspend, natsemi_resume);

static struct pci_driver natsemi_driver = {
.name = DRV_NAME,
.id_table = natsemi_pci_tbl,
.probe = natsemi_probe1,
.remove = natsemi_remove1,
-#ifdef CONFIG_PM
- .suspend = natsemi_suspend,
- .resume = natsemi_resume,
-#endif
+ .driver.pm = &natsemi_pm_ops,
};

static int __init natsemi_init_mod (void)
--
2.27.0

2020-07-01 20:00:06

by David Miller

[permalink] [raw]
Subject: Re: [PATCH v2 00/11] net: ethernet: use generic power management

From: Vaibhav Gupta <[email protected]>
Date: Wed, 1 Jul 2020 22:20:46 +0530

> Linux Kernel Mentee: Remove Legacy Power Management.
>
> The purpose of this patch series is to remove legacy power management callbacks
> from net ethernet drivers.
>
> The callbacks performing suspend() and resume() operations are still calling
> pci_save_state(), pci_set_power_state(), etc. and handling the power management
> themselves, which is not recommended.
>
> The conversion requires the removal of the those function calls and change the
> callback definition accordingly and make use of dev_pm_ops structure.
>
> All patches are compile-tested only.

Series applied, thanks.

2020-07-03 16:19:01

by Denis Kirjanov

[permalink] [raw]
Subject: Re: [PATCH v2 06/11] sundance: use generic power management

On 7/1/20, Vaibhav Gupta <[email protected]> wrote:
> With legacy PM, drivers themselves were responsible for managing the
> device's power states and takes care of register states.
>
> After upgrading to the generic structure, PCI core will take care of
> required tasks and drivers should do only device-specific operations.
>
> Thus, there is no need to call the PCI helper functions like
> pci_enable/disable_device(), pci_save/restore_sate() and
> pci_set_power_state().
>
> Compile-tested only.
>
> Signed-off-by: Vaibhav Gupta <[email protected]>

Should be fine. I'll try to test it in the upcoming weekend

> ---
> drivers/net/ethernet/dlink/sundance.c | 27 ++++++++-------------------
> 1 file changed, 8 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/net/ethernet/dlink/sundance.c
> b/drivers/net/ethernet/dlink/sundance.c
> index dc566fcc3ba9..ca97e321082d 100644
> --- a/drivers/net/ethernet/dlink/sundance.c
> +++ b/drivers/net/ethernet/dlink/sundance.c
> @@ -1928,11 +1928,9 @@ static void sundance_remove1(struct pci_dev *pdev)
> }
> }
>
> -#ifdef CONFIG_PM
> -
> -static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
> +static int __maybe_unused sundance_suspend(struct device *dev_d)
> {
> - struct net_device *dev = pci_get_drvdata(pci_dev);
> + struct net_device *dev = dev_get_drvdata(dev_d);
> struct netdev_private *np = netdev_priv(dev);
> void __iomem *ioaddr = np->base;
>
> @@ -1942,30 +1940,24 @@ static int sundance_suspend(struct pci_dev *pci_dev,
> pm_message_t state)
> netdev_close(dev);
> netif_device_detach(dev);
>
> - pci_save_state(pci_dev);
> if (np->wol_enabled) {
> iowrite8(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
> iowrite16(RxEnable, ioaddr + MACCtrl1);
> }
> - pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state),
> - np->wol_enabled);
> - pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
> +
> + device_set_wakeup_enable(dev_d, np->wol_enabled);
>
> return 0;
> }
>
> -static int sundance_resume(struct pci_dev *pci_dev)
> +static int __maybe_unused sundance_resume(struct device *dev_d)
> {
> - struct net_device *dev = pci_get_drvdata(pci_dev);
> + struct net_device *dev = dev_get_drvdata(dev_d);
> int err = 0;
>
> if (!netif_running(dev))
> return 0;
>
> - pci_set_power_state(pci_dev, PCI_D0);
> - pci_restore_state(pci_dev);
> - pci_enable_wake(pci_dev, PCI_D0, 0);
> -
> err = netdev_open(dev);
> if (err) {
> printk(KERN_ERR "%s: Can't resume interface!\n",
> @@ -1979,17 +1971,14 @@ static int sundance_resume(struct pci_dev *pci_dev)
> return err;
> }
>
> -#endif /* CONFIG_PM */
> +static SIMPLE_DEV_PM_OPS(sundance_pm_ops, sundance_suspend,
> sundance_resume);
>
> static struct pci_driver sundance_driver = {
> .name = DRV_NAME,
> .id_table = sundance_pci_tbl,
> .probe = sundance_probe1,
> .remove = sundance_remove1,
> -#ifdef CONFIG_PM
> - .suspend = sundance_suspend,
> - .resume = sundance_resume,
> -#endif /* CONFIG_PM */
> + .driver.pm = &sundance_pm_ops,
> };
>
> static int __init sundance_init(void)
> --
> 2.27.0
>
>

2020-07-08 10:44:16

by Denis Kirjanov

[permalink] [raw]
Subject: Re: [PATCH v2 06/11] sundance: use generic power management

On 7/3/20, Denis Kirjanov <[email protected]> wrote:
> On 7/1/20, Vaibhav Gupta <[email protected]> wrote:
>> With legacy PM, drivers themselves were responsible for managing the
>> device's power states and takes care of register states.
>>
>> After upgrading to the generic structure, PCI core will take care of
>> required tasks and drivers should do only device-specific operations.
>>
>> Thus, there is no need to call the PCI helper functions like
>> pci_enable/disable_device(), pci_save/restore_sate() and
>> pci_set_power_state().
>>
>> Compile-tested only.
>>
>> Signed-off-by: Vaibhav Gupta <[email protected]>
>
> Should be fine. I'll try to test it in the upcoming weekend

Unfortunately the suspend mode is broken on my test machine so I will
take some time :/

>
>> ---
>> drivers/net/ethernet/dlink/sundance.c | 27 ++++++++-------------------
>> 1 file changed, 8 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/dlink/sundance.c
>> b/drivers/net/ethernet/dlink/sundance.c
>> index dc566fcc3ba9..ca97e321082d 100644
>> --- a/drivers/net/ethernet/dlink/sundance.c
>> +++ b/drivers/net/ethernet/dlink/sundance.c
>> @@ -1928,11 +1928,9 @@ static void sundance_remove1(struct pci_dev *pdev)
>> }
>> }
>>
>> -#ifdef CONFIG_PM
>> -
>> -static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
>> +static int __maybe_unused sundance_suspend(struct device *dev_d)
>> {
>> - struct net_device *dev = pci_get_drvdata(pci_dev);
>> + struct net_device *dev = dev_get_drvdata(dev_d);
>> struct netdev_private *np = netdev_priv(dev);
>> void __iomem *ioaddr = np->base;
>>
>> @@ -1942,30 +1940,24 @@ static int sundance_suspend(struct pci_dev
>> *pci_dev,
>> pm_message_t state)
>> netdev_close(dev);
>> netif_device_detach(dev);
>>
>> - pci_save_state(pci_dev);
>> if (np->wol_enabled) {
>> iowrite8(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
>> iowrite16(RxEnable, ioaddr + MACCtrl1);
>> }
>> - pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state),
>> - np->wol_enabled);
>> - pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
>> +
>> + device_set_wakeup_enable(dev_d, np->wol_enabled);
>>
>> return 0;
>> }
>>
>> -static int sundance_resume(struct pci_dev *pci_dev)
>> +static int __maybe_unused sundance_resume(struct device *dev_d)
>> {
>> - struct net_device *dev = pci_get_drvdata(pci_dev);
>> + struct net_device *dev = dev_get_drvdata(dev_d);
>> int err = 0;
>>
>> if (!netif_running(dev))
>> return 0;
>>
>> - pci_set_power_state(pci_dev, PCI_D0);
>> - pci_restore_state(pci_dev);
>> - pci_enable_wake(pci_dev, PCI_D0, 0);
>> -
>> err = netdev_open(dev);
>> if (err) {
>> printk(KERN_ERR "%s: Can't resume interface!\n",
>> @@ -1979,17 +1971,14 @@ static int sundance_resume(struct pci_dev
>> *pci_dev)
>> return err;
>> }
>>
>> -#endif /* CONFIG_PM */
>> +static SIMPLE_DEV_PM_OPS(sundance_pm_ops, sundance_suspend,
>> sundance_resume);
>>
>> static struct pci_driver sundance_driver = {
>> .name = DRV_NAME,
>> .id_table = sundance_pci_tbl,
>> .probe = sundance_probe1,
>> .remove = sundance_remove1,
>> -#ifdef CONFIG_PM
>> - .suspend = sundance_suspend,
>> - .resume = sundance_resume,
>> -#endif /* CONFIG_PM */
>> + .driver.pm = &sundance_pm_ops,
>> };
>>
>> static int __init sundance_init(void)
>> --
>> 2.27.0
>>
>>
>