@@ -1959,16 +1959,21 @@ static int ravb_open(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
+ struct device *dev = &priv->pdev->dev;
int error;
napi_enable(&priv->napi[RAVB_BE]);
if (info->nc_queues)
napi_enable(&priv->napi[RAVB_NC]);
+ error = pm_runtime_resume_and_get(dev);
+ if (error < 0)
+ goto out_napi_off;
+
/* Set AVB config mode */
error = ravb_set_config_mode(ndev);
if (error)
- goto out_napi_off;
+ goto out_rpm_put;
ravb_set_delay_mode(ndev);
ravb_write(ndev, priv->desc_bat_dma, DBAT);
@@ -2002,6 +2007,9 @@ static int ravb_open(struct net_device *ndev)
ravb_stop_dma(ndev);
out_set_reset:
ravb_set_opmode(ndev, CCC_OPC_RESET);
+out_rpm_put:
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
out_napi_off:
if (info->nc_queues)
napi_disable(&priv->napi[RAVB_NC]);
@@ -2342,6 +2350,8 @@ static int ravb_close(struct net_device *ndev)
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
struct ravb_tstamp_skb *ts_skb, *ts_skb2;
+ struct device *dev = &priv->pdev->dev;
+ int error;
netif_tx_stop_all_queues(ndev);
@@ -2391,7 +2401,14 @@ static int ravb_close(struct net_device *ndev)
ravb_get_stats(ndev);
/* Set reset mode. */
- return ravb_set_opmode(ndev, CCC_OPC_RESET);
+ error = ravb_set_opmode(ndev, CCC_OPC_RESET);
+ if (error)
+ return error;
+
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+
+ return 0;
}
static int ravb_hwtstamp_get(struct net_device *ndev, struct ifreq *req)
@@ -2946,6 +2963,8 @@ static int ravb_probe(struct platform_device *pdev)
clk_prepare(priv->refclk);
platform_set_drvdata(pdev, ndev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
+ pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
error = pm_runtime_resume_and_get(&pdev->dev);
if (error < 0)
@@ -3051,6 +3070,9 @@ static int ravb_probe(struct platform_device *pdev)
netdev_info(ndev, "Base address at %#x, %pM, IRQ %d.\n",
(u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_put_autosuspend(&pdev->dev);
+
return 0;
out_napi_del:
@@ -3068,6 +3090,7 @@ static int ravb_probe(struct platform_device *pdev)
pm_runtime_put(&pdev->dev);
out_rpm_disable:
pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
clk_unprepare(priv->refclk);
out_reset_assert:
reset_control_assert(rstc);
@@ -3081,6 +3104,12 @@ static int ravb_remove(struct platform_device *pdev)
struct net_device *ndev = platform_get_drvdata(pdev);
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
+ struct device *dev = &priv->pdev->dev;
+ int error;
+
+ error = pm_runtime_resume_and_get(dev);
+ if (error < 0)
+ return error;
unregister_netdev(ndev);
if (info->nc_queues)
@@ -3092,8 +3121,9 @@ static int ravb_remove(struct platform_device *pdev)
dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat,
priv->desc_bat_dma);
- pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_put_sync_suspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(dev);
clk_unprepare(priv->refclk);
reset_control_assert(priv->rstc);
free_netdev(ndev);
@@ -3177,6 +3207,10 @@ static int __maybe_unused ravb_suspend(struct device *dev)
if (ret)
return ret;
+ ret = pm_runtime_force_suspend(&priv->pdev->dev);
+ if (ret)
+ return ret;
+
reset_assert:
return reset_control_assert(priv->rstc);
}
@@ -3199,16 +3233,28 @@ static int __maybe_unused ravb_resume(struct device *dev)
ret = ravb_wol_restore(ndev);
if (ret)
return ret;
+ } else {
+ ret = pm_runtime_force_resume(dev);
+ if (ret)
+ return ret;
}
/* Reopening the interface will restore the device to the working state. */
ret = ravb_open(ndev);
if (ret < 0)
- return ret;
+ goto out_rpm_put;
ravb_set_rx_mode(ndev);
netif_device_attach(ndev);
+ return 0;
+
+out_rpm_put:
+ if (!priv->wol_enabled) {
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+ }
+
return ret;
}