From patchwork Fri Mar 10 16:35:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 737460 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3vftFv6zKVz9s80 for ; Sat, 11 Mar 2017 03:37:07 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="eCo4Gq5v"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933757AbdCJQgv (ORCPT ); Fri, 10 Mar 2017 11:36:51 -0500 Received: from mail-wm0-f68.google.com ([74.125.82.68]:34625 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933388AbdCJQfg (ORCPT ); Fri, 10 Mar 2017 11:35:36 -0500 Received: by mail-wm0-f68.google.com with SMTP id u132so3115242wmg.1; Fri, 10 Mar 2017 08:35:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ij+PiRZeJgyIKHs64QzSmjeIxEjCi5z07MgEVko5AuI=; b=eCo4Gq5vVZXiPWAmMxNkIbcq+vz1kfD2Qbyp4Z3xXCAPy4DvqozBNGhWAa9+T5bf5b ehOiJoNsq295y1kFwN6ouqRP0k0MRHzwf6F8uKZ1PlzXdQJc4qghVCJ0ENOo3DJtQ/+v rZkjFodJv3/P/f2z9YmURBkubBRDwJQCbbQ4fKKWkWsEVHqBSSGzMaX5rERvYfZffCPh 7+ObhKI/wWwyj+sfirJxiD5EyTZGkujFRFbrPrjlObXF3jzpBLQfcihrPrBdwXxAzHFB VJbl/5XA5PKPTjGJ3id/YXtUCm//lDkET7mlIZKXn3Pe9ROr1Hm36aYSyXAp20kqGDOs 9Skg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Ij+PiRZeJgyIKHs64QzSmjeIxEjCi5z07MgEVko5AuI=; b=Esco1wk5CUIvM8PQbYca7fxnOUqGy3S0flOFyje9qv9jPVJ4cM1OrJ1wcW+wYaApqU sJal/sIVSuZ/gSKRBLXw8EPNfwQMHXiCkhRC8zHARtZ6dZpSBxBqCYVPwVHMNdaAZPD5 ant8kZTrqXWo8AeMsvl6LsAPBTeqigGigGJivgUBcB3SPOBdkFVzUMsvsgwOPaPssUCQ VbBf1N+ETzMR/Yu8DOLgoFEAHoYHMZkDyhp0IjmkPbiaTvcWroPunBuHA7z9NlZ/XClm WquDo+7DNHEBkp6mE2qBmPEnjg4cnDn9xjePNJsNCsb9mIS2IDxgxTqpbRjYqT5Odl8c t7UQ== X-Gm-Message-State: AFeK/H0NQpb+8dH8mfOokmRNKtlGTEOZV9YwNacywNQX6uzZli6qTvatnTUToGVpvdIP7w== X-Received: by 10.28.234.20 with SMTP id i20mr3307890wmh.91.1489163718135; Fri, 10 Mar 2017 08:35:18 -0800 (PST) Received: from localhost (port-55061.pppoe.wtnet.de. [46.59.215.197]) by smtp.gmail.com with ESMTPSA id 53sm3459651wrt.52.2017.03.10.08.35.16 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 10 Mar 2017 08:35:16 -0800 (PST) From: Thierry Reding To: "David S . Miller" Cc: Giuseppe Cavallaro , Alexandre Torgue , Joao Pinto , Jon Hunter , Mikko Perttunen , netdev@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 8/9] net: stmmac: dwc-qos: Split out ->probe() and ->remove() Date: Fri, 10 Mar 2017 17:35:00 +0100 Message-Id: <20170310163501.31811-9-thierry.reding@gmail.com> X-Mailer: git-send-email 2.12.0 In-Reply-To: <20170310163501.31811-1-thierry.reding@gmail.com> References: <20170310163501.31811-1-thierry.reding@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Thierry Reding Split out the binding specific parts of ->probe() and ->remove() to enable the driver to support variants of the binding. This is useful in order to keep backwards-compatibility while making it easy for a sub- driver to deal only with the updated bindings rather than having to add compatibility quirks all over the place. Reviewed-by: Mikko Perttunen Reviewed-By: Joao Pinto Signed-off-by: Thierry Reding --- Changes in v2: - check return values from the clock API .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 124 ++++++++++++++++----- 1 file changed, 98 insertions(+), 26 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c index 1a3fa3d9f855..319232021bb7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -106,13 +107,80 @@ static int dwc_eth_dwmac_config_dt(struct platform_device *pdev, return 0; } +static void *dwc_qos_probe(struct platform_device *pdev, + struct plat_stmmacenet_data *plat_dat, + struct stmmac_resources *stmmac_res) +{ + int err; + + plat_dat->stmmac_clk = devm_clk_get(&pdev->dev, "apb_pclk"); + if (IS_ERR(plat_dat->stmmac_clk)) { + dev_err(&pdev->dev, "apb_pclk clock not found.\n"); + return ERR_CAST(plat_dat->stmmac_clk); + } + + err = clk_prepare_enable(plat_dat->stmmac_clk); + if (err < 0) { + dev_err(&pdev->dev, "failed to enable apb_pclk clock: %d\n", + err); + return ERR_PTR(err); + } + + plat_dat->pclk = devm_clk_get(&pdev->dev, "phy_ref_clk"); + if (IS_ERR(plat_dat->pclk)) { + dev_err(&pdev->dev, "phy_ref_clk clock not found.\n"); + err = PTR_ERR(plat_dat->pclk); + goto disable; + } + + err = clk_prepare_enable(plat_dat->pclk); + if (err < 0) { + dev_err(&pdev->dev, "failed to enable phy_ref clock: %d\n", + err); + goto disable; + } + + return NULL; + +disable: + clk_disable_unprepare(plat_dat->stmmac_clk); + return ERR_PTR(err); +} + +static int dwc_qos_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct stmmac_priv *priv = netdev_priv(ndev); + + clk_disable_unprepare(priv->plat->pclk); + clk_disable_unprepare(priv->plat->stmmac_clk); + + return 0; +} + +struct dwc_eth_dwmac_data { + void *(*probe)(struct platform_device *pdev, + struct plat_stmmacenet_data *data, + struct stmmac_resources *res); + int (*remove)(struct platform_device *pdev); +}; + +static const struct dwc_eth_dwmac_data dwc_qos_data = { + .probe = dwc_qos_probe, + .remove = dwc_qos_remove, +}; + static int dwc_eth_dwmac_probe(struct platform_device *pdev) { + const struct dwc_eth_dwmac_data *data; struct plat_stmmacenet_data *plat_dat; struct stmmac_resources stmmac_res; struct resource *res; + void *priv; int ret; + data = of_device_get_match_data(&pdev->dev); + memset(&stmmac_res, 0, sizeof(struct stmmac_resources)); /** @@ -138,39 +206,26 @@ static int dwc_eth_dwmac_probe(struct platform_device *pdev) if (IS_ERR(plat_dat)) return PTR_ERR(plat_dat); - plat_dat->stmmac_clk = devm_clk_get(&pdev->dev, "apb_pclk"); - if (IS_ERR(plat_dat->stmmac_clk)) { - dev_err(&pdev->dev, "apb_pclk clock not found.\n"); - ret = PTR_ERR(plat_dat->stmmac_clk); - plat_dat->stmmac_clk = NULL; - goto err_remove_config_dt; + priv = data->probe(pdev, plat_dat, &stmmac_res); + if (IS_ERR(priv)) { + ret = PTR_ERR(priv); + dev_err(&pdev->dev, "failed to probe subdriver: %d\n", ret); + goto remove_config; } - clk_prepare_enable(plat_dat->stmmac_clk); - - plat_dat->pclk = devm_clk_get(&pdev->dev, "phy_ref_clk"); - if (IS_ERR(plat_dat->pclk)) { - dev_err(&pdev->dev, "phy_ref_clk clock not found.\n"); - ret = PTR_ERR(plat_dat->pclk); - plat_dat->pclk = NULL; - goto err_out_clk_dis_phy; - } - clk_prepare_enable(plat_dat->pclk); ret = dwc_eth_dwmac_config_dt(pdev, plat_dat); if (ret) - goto err_out_clk_dis_aper; + goto remove; ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); if (ret) - goto err_out_clk_dis_aper; + goto remove; - return 0; + return ret; -err_out_clk_dis_aper: - clk_disable_unprepare(plat_dat->pclk); -err_out_clk_dis_phy: - clk_disable_unprepare(plat_dat->stmmac_clk); -err_remove_config_dt: +remove: + data->remove(pdev); +remove_config: stmmac_remove_config_dt(pdev, plat_dat); return ret; @@ -178,11 +233,28 @@ static int dwc_eth_dwmac_probe(struct platform_device *pdev) static int dwc_eth_dwmac_remove(struct platform_device *pdev) { - return stmmac_pltfr_remove(pdev); + struct net_device *ndev = platform_get_drvdata(pdev); + struct stmmac_priv *priv = netdev_priv(ndev); + const struct dwc_eth_dwmac_data *data; + int err; + + data = of_device_get_match_data(&pdev->dev); + + err = stmmac_dvr_remove(&pdev->dev); + if (err < 0) + dev_err(&pdev->dev, "failed to remove platform: %d\n", err); + + err = data->remove(pdev); + if (err < 0) + dev_err(&pdev->dev, "failed to remove subdriver: %d\n", err); + + stmmac_remove_config_dt(pdev, priv->plat); + + return err; } static const struct of_device_id dwc_eth_dwmac_match[] = { - { .compatible = "snps,dwc-qos-ethernet-4.10", }, + { .compatible = "snps,dwc-qos-ethernet-4.10", .data = &dwc_qos_data }, { } }; MODULE_DEVICE_TABLE(of, dwc_eth_dwmac_match);