From patchwork Tue Jul 17 22:05:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Kleine-Budde X-Patchwork-Id: 1207341 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 4518ADF25A for ; Tue, 17 Jul 2012 22:10:04 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1SrFuQ-0002ZZ-Vq; Tue, 17 Jul 2012 22:06:23 +0000 Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1SrFuG-0002YG-4V for linux-arm-kernel@lists.infradead.org; Tue, 17 Jul 2012 22:06:14 +0000 Received: from gallifrey.ext.pengutronix.de ([2001:6f8:1178:4:5054:ff:fe8d:eefb] helo=hardanger.do.blackshift.org) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1SrFu2-0001vB-Ra; Wed, 18 Jul 2012 00:05:58 +0200 From: Marc Kleine-Budde To: linux-can@vger.kernel.org Subject: [PATCH] can: flexcan: add 2nd clock to support imx53 and newer Date: Wed, 18 Jul 2012 00:05:48 +0200 Message-Id: <1342562748-24701-1-git-send-email-mkl@pengutronix.de> X-Mailer: git-send-email 1.7.10 X-SA-Exim-Connect-IP: 2001:6f8:1178:4:5054:ff:fe8d:eefb X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Hui Wang , Sascha Hauer , Shawn Guo , Marc Kleine-Budde , kernel@pengutronix.de, Steffen Trumtrar , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Steffen Trumtrar This patch add support for a second clock to the flexcan driver. On modern freescale ARM cores like the imx53 and imx6q two clocks ("ipg" and "per") must be enabled in order to access the CAN core. In the original driver, the clock was requested without specifying the connection id, further all mainline ARM archs with flexcan support (imx28, imx25, imx35) register their flexcan clock without a connection id, too. This patch first renames the existing clk variable to clk_ipg and adds the connection id "ipg" to the clk_get() call. Then a second clock "per" is requested. As all archs don't specify a connection id, both clk_get return the same clock. This ensures compatibility to existing flexcan support and adds support for imx53 at the same time. After this patch hits mainline, the archs may give their existing flexcan clock the "ipg" connection id and implement a dummy "per" clock. This patch has been tested on imx28 (unmodified clk tree) and on imx53 with a seperate "ipg" and "per" clock. Cc: Sascha Hauer Cc: Shawn Guo Cc: Hui Wang Signed-off-by: Steffen Trumtrar Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 52 ++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index c8a6fc7..281d51f 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -190,7 +190,8 @@ struct flexcan_priv { u32 reg_esr; u32 reg_ctrl_default; - struct clk *clk; + struct clk *clk_ipg; + struct clk *clk_per; struct flexcan_platform_data *pdata; const struct flexcan_devtype_data *devtype_data; }; @@ -828,7 +829,8 @@ static int flexcan_open(struct net_device *dev) struct flexcan_priv *priv = netdev_priv(dev); int err; - clk_prepare_enable(priv->clk); + clk_prepare_enable(priv->clk_ipg); + clk_prepare_enable(priv->clk_per); err = open_candev(dev); if (err) @@ -850,7 +852,8 @@ static int flexcan_open(struct net_device *dev) out_close: close_candev(dev); out: - clk_disable_unprepare(priv->clk); + clk_disable_unprepare(priv->clk_per); + clk_disable_unprepare(priv->clk_ipg); return err; } @@ -864,7 +867,8 @@ static int flexcan_close(struct net_device *dev) flexcan_chip_stop(dev); free_irq(dev->irq, dev); - clk_disable_unprepare(priv->clk); + clk_disable_unprepare(priv->clk_per); + clk_disable_unprepare(priv->clk_ipg); close_candev(dev); @@ -903,7 +907,8 @@ static int __devinit register_flexcandev(struct net_device *dev) struct flexcan_regs __iomem *regs = priv->base; u32 reg, err; - clk_prepare_enable(priv->clk); + clk_prepare_enable(priv->clk_ipg); + clk_prepare_enable(priv->clk_per); /* select "bus clock", chip must be disabled */ flexcan_chip_disable(priv); @@ -936,7 +941,8 @@ static int __devinit register_flexcandev(struct net_device *dev) out: /* disable core and turn off clocks */ flexcan_chip_disable(priv); - clk_disable_unprepare(priv->clk); + clk_disable_unprepare(priv->clk_per); + clk_disable_unprepare(priv->clk_ipg); return err; } @@ -964,7 +970,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev) struct net_device *dev; struct flexcan_priv *priv; struct resource *mem; - struct clk *clk = NULL; + struct clk *clk_ipg = NULL, *clk_per = NULL; struct pinctrl *pinctrl; void __iomem *base; resource_size_t mem_size; @@ -980,13 +986,20 @@ static int __devinit flexcan_probe(struct platform_device *pdev) "clock-frequency", &clock_freq); if (!clock_freq) { - clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "no clock defined\n"); - err = PTR_ERR(clk); + clk_ipg = clk_get(&pdev->dev, "ipg"); + if (IS_ERR(clk_ipg)) { + dev_err(&pdev->dev, "no ipg clock defined\n"); + err = PTR_ERR(clk_ipg); + goto failed_clock; + } + clock_freq = clk_get_rate(clk_ipg); + + clk_per = clk_get(&pdev->dev, "per"); + if (IS_ERR(clk_per)) { + dev_err(&pdev->dev, "no per clock defined\n"); + err = PTR_ERR(clk_per); goto failed_clock; } - clock_freq = clk_get_rate(clk); } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1039,7 +1052,8 @@ static int __devinit flexcan_probe(struct platform_device *pdev) CAN_CTRLMODE_BERR_REPORTING; priv->base = base; priv->dev = dev; - priv->clk = clk; + priv->clk_ipg = clk_ipg; + priv->clk_per = clk_per; priv->pdata = pdev->dev.platform_data; priv->devtype_data = devtype_data; @@ -1067,9 +1081,11 @@ static int __devinit flexcan_probe(struct platform_device *pdev) failed_map: release_mem_region(mem->start, mem_size); failed_get: - if (clk) - clk_put(clk); failed_clock: + if (clk_per) + clk_put(clk_per); + if (clk_ipg) + clk_put(clk_ipg); return err; } @@ -1086,8 +1102,10 @@ static int __devexit flexcan_remove(struct platform_device *pdev) mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(mem->start, resource_size(mem)); - if (priv->clk) - clk_put(priv->clk); + if (priv->clk_per) + clk_put(priv->clk_per); + if (priv->clk_ipg) + clk_put(priv->clk_ipg); free_candev(dev);