net: ti: icssg-prueth: Add Power management support
authorMD Danish Anwar <danishanwar@ti.com>
Tue, 1 Aug 2023 09:14:28 +0000 (14:44 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 2 Aug 2023 09:38:11 +0000 (10:38 +0100)
Add suspend / resume APIs to support power management in ICSSG ethernet
driver.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/ti/icssg/icssg_prueth.c

index 80721d82f6c5faa1d90b53c09a247a904640417b..47b941fb0198dd7848372e1eae955ccddb45ea55 100644 (file)
@@ -1813,6 +1813,62 @@ static void prueth_remove(struct platform_device *pdev)
                prueth_put_cores(prueth, ICSS_SLICE0);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int prueth_suspend(struct device *dev)
+{
+       struct prueth *prueth = dev_get_drvdata(dev);
+       struct net_device *ndev;
+       int i, ret;
+
+       for (i = 0; i < PRUETH_NUM_MACS; i++) {
+               ndev = prueth->registered_netdevs[i];
+
+               if (!ndev)
+                       continue;
+
+               if (netif_running(ndev)) {
+                       netif_device_detach(ndev);
+                       ret = emac_ndo_stop(ndev);
+                       if (ret < 0) {
+                               netdev_err(ndev, "failed to stop: %d", ret);
+                               return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int prueth_resume(struct device *dev)
+{
+       struct prueth *prueth = dev_get_drvdata(dev);
+       struct net_device *ndev;
+       int i, ret;
+
+       for (i = 0; i < PRUETH_NUM_MACS; i++) {
+               ndev = prueth->registered_netdevs[i];
+
+               if (!ndev)
+                       continue;
+
+               if (netif_running(ndev)) {
+                       ret = emac_ndo_open(ndev);
+                       if (ret < 0) {
+                               netdev_err(ndev, "failed to start: %d", ret);
+                               return ret;
+                       }
+                       netif_device_attach(ndev);
+               }
+       }
+
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops prueth_dev_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(prueth_suspend, prueth_resume)
+};
+
 static const struct prueth_pdata am654_icssg_pdata = {
        .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE,
        .quirk_10m_link_issue = 1,
@@ -1830,6 +1886,7 @@ static struct platform_driver prueth_driver = {
        .driver = {
                .name = "icssg-prueth",
                .of_match_table = prueth_dt_match,
+               .pm = &prueth_dev_pm_ops,
        },
 };
 module_platform_driver(prueth_driver);