Commit a654f6e8 authored by Claudiu Beznea's avatar Claudiu Beznea Committed by Paolo Abeni

net: ravb: Move reference clock enable/disable on runtime PM APIs

Reference clock could be or not be part of the power domain. If it is part
of the power domain, the power domain takes care of properly setting it. In
case it is not part of the power domain and full runtime PM support is
available in driver the clock will not be propertly disabled/enabled at
runtime. For this, keep the prepare/unprepare operations in the driver's
probe()/remove() functions and move the enable/disable in runtime PM
functions.

By doing this, the previous ravb_runtime_nop() function was renamed
ravb_runtime_suspend() and the comment was removed. A proper runtime PM
resume function was added (ravb_runtime_resume()). The current driver
still don't need to make any register settings on runtime suspend/resume
(as expressed in the removed comment) because, currently,
pm_runtime_put_sync() is called on the driver remove function. This will be
changed in the next commits (that extends the runtime PM support) such
that proper register settings (along with runtime resume/suspend) will be
done on ravb_open()/ravb_close().

Along with it, the other clock request operations were moved close to
reference clock request and prepare to have all the clock requests
specific code grouped together.
Signed-off-by: default avatarClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: default avatarSergey Shtylyov <s.shtylyov@omp.ru>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent c5c0714e
...@@ -2664,11 +2664,6 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2664,11 +2664,6 @@ static int ravb_probe(struct platform_device *pdev)
if (error) if (error)
goto out_free_netdev; goto out_free_netdev;
pm_runtime_enable(&pdev->dev);
error = pm_runtime_resume_and_get(&pdev->dev);
if (error < 0)
goto out_rpm_disable;
if (info->multi_irqs) { if (info->multi_irqs) {
if (info->err_mgmt_irqs) if (info->err_mgmt_irqs)
irq = platform_get_irq_byname(pdev, "dia"); irq = platform_get_irq_byname(pdev, "dia");
...@@ -2679,7 +2674,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2679,7 +2674,7 @@ static int ravb_probe(struct platform_device *pdev)
} }
if (irq < 0) { if (irq < 0) {
error = irq; error = irq;
goto out_release; goto out_reset_assert;
} }
ndev->irq = irq; ndev->irq = irq;
...@@ -2697,10 +2692,37 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2697,10 +2692,37 @@ static int ravb_probe(struct platform_device *pdev)
priv->num_rx_ring[RAVB_NC] = NC_RX_RING_SIZE; priv->num_rx_ring[RAVB_NC] = NC_RX_RING_SIZE;
} }
priv->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(priv->clk)) {
error = PTR_ERR(priv->clk);
goto out_reset_assert;
}
if (info->gptp_ref_clk) {
priv->gptp_clk = devm_clk_get(&pdev->dev, "gptp");
if (IS_ERR(priv->gptp_clk)) {
error = PTR_ERR(priv->gptp_clk);
goto out_reset_assert;
}
}
priv->refclk = devm_clk_get_optional(&pdev->dev, "refclk");
if (IS_ERR(priv->refclk)) {
error = PTR_ERR(priv->refclk);
goto out_reset_assert;
}
clk_prepare(priv->refclk);
platform_set_drvdata(pdev, ndev);
pm_runtime_enable(&pdev->dev);
error = pm_runtime_resume_and_get(&pdev->dev);
if (error < 0)
goto out_rpm_disable;
priv->addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res); priv->addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(priv->addr)) { if (IS_ERR(priv->addr)) {
error = PTR_ERR(priv->addr); error = PTR_ERR(priv->addr);
goto out_release; goto out_rpm_put;
} }
/* The Ether-specific entries in the device structure. */ /* The Ether-specific entries in the device structure. */
...@@ -2711,7 +2733,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2711,7 +2733,7 @@ static int ravb_probe(struct platform_device *pdev)
error = of_get_phy_mode(np, &priv->phy_interface); error = of_get_phy_mode(np, &priv->phy_interface);
if (error && error != -ENODEV) if (error && error != -ENODEV)
goto out_release; goto out_rpm_put;
priv->no_avb_link = of_property_read_bool(np, "renesas,no-ether-link"); priv->no_avb_link = of_property_read_bool(np, "renesas,no-ether-link");
priv->avb_link_active_low = priv->avb_link_active_low =
...@@ -2724,14 +2746,14 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2724,14 +2746,14 @@ static int ravb_probe(struct platform_device *pdev)
irq = platform_get_irq_byname(pdev, "ch24"); irq = platform_get_irq_byname(pdev, "ch24");
if (irq < 0) { if (irq < 0) {
error = irq; error = irq;
goto out_release; goto out_rpm_put;
} }
priv->emac_irq = irq; priv->emac_irq = irq;
for (i = 0; i < NUM_RX_QUEUE; i++) { for (i = 0; i < NUM_RX_QUEUE; i++) {
irq = platform_get_irq_byname(pdev, ravb_rx_irqs[i]); irq = platform_get_irq_byname(pdev, ravb_rx_irqs[i]);
if (irq < 0) { if (irq < 0) {
error = irq; error = irq;
goto out_release; goto out_rpm_put;
} }
priv->rx_irqs[i] = irq; priv->rx_irqs[i] = irq;
} }
...@@ -2739,7 +2761,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2739,7 +2761,7 @@ static int ravb_probe(struct platform_device *pdev)
irq = platform_get_irq_byname(pdev, ravb_tx_irqs[i]); irq = platform_get_irq_byname(pdev, ravb_tx_irqs[i]);
if (irq < 0) { if (irq < 0) {
error = irq; error = irq;
goto out_release; goto out_rpm_put;
} }
priv->tx_irqs[i] = irq; priv->tx_irqs[i] = irq;
} }
...@@ -2748,40 +2770,19 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2748,40 +2770,19 @@ static int ravb_probe(struct platform_device *pdev)
irq = platform_get_irq_byname(pdev, "err_a"); irq = platform_get_irq_byname(pdev, "err_a");
if (irq < 0) { if (irq < 0) {
error = irq; error = irq;
goto out_release; goto out_rpm_put;
} }
priv->erra_irq = irq; priv->erra_irq = irq;
irq = platform_get_irq_byname(pdev, "mgmt_a"); irq = platform_get_irq_byname(pdev, "mgmt_a");
if (irq < 0) { if (irq < 0) {
error = irq; error = irq;
goto out_release; goto out_rpm_put;
} }
priv->mgmta_irq = irq; priv->mgmta_irq = irq;
} }
} }
priv->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(priv->clk)) {
error = PTR_ERR(priv->clk);
goto out_release;
}
priv->refclk = devm_clk_get_optional(&pdev->dev, "refclk");
if (IS_ERR(priv->refclk)) {
error = PTR_ERR(priv->refclk);
goto out_release;
}
clk_prepare_enable(priv->refclk);
if (info->gptp_ref_clk) {
priv->gptp_clk = devm_clk_get(&pdev->dev, "gptp");
if (IS_ERR(priv->gptp_clk)) {
error = PTR_ERR(priv->gptp_clk);
goto out_disable_refclk;
}
}
ndev->max_mtu = info->rx_max_buf_size - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN); ndev->max_mtu = info->rx_max_buf_size - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
ndev->min_mtu = ETH_MIN_MTU; ndev->min_mtu = ETH_MIN_MTU;
...@@ -2799,13 +2800,13 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2799,13 +2800,13 @@ static int ravb_probe(struct platform_device *pdev)
/* Set AVB config mode */ /* Set AVB config mode */
error = ravb_set_config_mode(ndev); error = ravb_set_config_mode(ndev);
if (error) if (error)
goto out_disable_refclk; goto out_rpm_put;
if (info->gptp || info->ccc_gac) { if (info->gptp || info->ccc_gac) {
/* Set GTI value */ /* Set GTI value */
error = ravb_set_gti(ndev); error = ravb_set_gti(ndev);
if (error) if (error)
goto out_disable_refclk; goto out_rpm_put;
/* Request GTI loading */ /* Request GTI loading */
ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI); ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
...@@ -2825,7 +2826,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2825,7 +2826,7 @@ static int ravb_probe(struct platform_device *pdev)
"Cannot allocate desc base address table (size %d bytes)\n", "Cannot allocate desc base address table (size %d bytes)\n",
priv->desc_bat_size); priv->desc_bat_size);
error = -ENOMEM; error = -ENOMEM;
goto out_disable_refclk; goto out_rpm_put;
} }
for (q = RAVB_BE; q < DBAT_ENTRY_NUM; q++) for (q = RAVB_BE; q < DBAT_ENTRY_NUM; q++)
priv->desc_bat[q].die_dt = DT_EOS; priv->desc_bat[q].die_dt = DT_EOS;
...@@ -2871,8 +2872,6 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2871,8 +2872,6 @@ static int ravb_probe(struct platform_device *pdev)
netdev_info(ndev, "Base address at %#x, %pM, IRQ %d.\n", netdev_info(ndev, "Base address at %#x, %pM, IRQ %d.\n",
(u32)ndev->base_addr, ndev->dev_addr, ndev->irq); (u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
platform_set_drvdata(pdev, ndev);
return 0; return 0;
out_napi_del: out_napi_del:
...@@ -2888,12 +2887,12 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2888,12 +2887,12 @@ static int ravb_probe(struct platform_device *pdev)
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (info->ccc_gac) if (info->ccc_gac)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
out_disable_refclk: out_rpm_put:
clk_disable_unprepare(priv->refclk);
out_release:
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
out_rpm_disable: out_rpm_disable:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
clk_unprepare(priv->refclk);
out_reset_assert:
reset_control_assert(rstc); reset_control_assert(rstc);
out_free_netdev: out_free_netdev:
free_netdev(ndev); free_netdev(ndev);
...@@ -2922,10 +2921,9 @@ static void ravb_remove(struct platform_device *pdev) ...@@ -2922,10 +2921,9 @@ static void ravb_remove(struct platform_device *pdev)
ravb_set_opmode(ndev, CCC_OPC_RESET); ravb_set_opmode(ndev, CCC_OPC_RESET);
clk_disable_unprepare(priv->refclk);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
clk_unprepare(priv->refclk);
reset_control_assert(priv->rstc); reset_control_assert(priv->rstc);
free_netdev(ndev); free_netdev(ndev);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
...@@ -3060,21 +3058,27 @@ static int ravb_resume(struct device *dev) ...@@ -3060,21 +3058,27 @@ static int ravb_resume(struct device *dev)
return ret; return ret;
} }
static int ravb_runtime_nop(struct device *dev) static int ravb_runtime_suspend(struct device *dev)
{ {
/* Runtime PM callback shared between ->runtime_suspend() struct net_device *ndev = dev_get_drvdata(dev);
* and ->runtime_resume(). Simply returns success. struct ravb_private *priv = netdev_priv(ndev);
*
* This driver re-initializes all registers after clk_disable(priv->refclk);
* pm_runtime_get_sync() anyway so there is no need
* to save and restore registers here.
*/
return 0; return 0;
} }
static int ravb_runtime_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct ravb_private *priv = netdev_priv(ndev);
return clk_enable(priv->refclk);
}
static const struct dev_pm_ops ravb_dev_pm_ops = { static const struct dev_pm_ops ravb_dev_pm_ops = {
SYSTEM_SLEEP_PM_OPS(ravb_suspend, ravb_resume) SYSTEM_SLEEP_PM_OPS(ravb_suspend, ravb_resume)
RUNTIME_PM_OPS(ravb_runtime_nop, ravb_runtime_nop, NULL) RUNTIME_PM_OPS(ravb_runtime_suspend, ravb_runtime_resume, NULL)
}; };
static struct platform_driver ravb_driver = { static struct platform_driver ravb_driver = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment