[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20161202203023.25526-5-grygorii.strashko@ti.com>
Date: Fri, 2 Dec 2016 14:30:14 -0600
From: Grygorii Strashko <grygorii.strashko@...com>
To: "David S. Miller" <davem@...emloft.net>, <netdev@...r.kernel.org>,
Mugunthan V N <mugunthanvnm@...com>,
Richard Cochran <richardcochran@...il.com>
CC: Sekhar Nori <nsekhar@...com>, <linux-kernel@...r.kernel.org>,
<linux-omap@...r.kernel.org>, Rob Herring <robh+dt@...nel.org>,
<devicetree@...r.kernel.org>,
Murali Karicheri <m-karicheri2@...com>,
Wingman Kwok <w-kwok2@...com>,
Thomas Gleixner <tglx@...utronix.de>,
Grygorii Strashko <grygorii.strashko@...com>
Subject: [PATCH v3 04/13] net: ethernet: ti: cpts: fix unbalanced clk api usage in cpts_register/unregister
There are two issues with TI CPTS code which are reproducible when TI
CPSW ethX device passes few up/down iterations:
- cpts refclk prepare counter continuously incremented after each
up/down iteration;
- devm_clk_get(dev, "cpts") is called many times.
Hence, fix these issues by using clk_disable_unprepare() in
cpts_clk_release() and skipping devm_clk_get() if cpts refclk has been
acquired already.
Acked-by: Richard Cochran <richardcochran@...il.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@...com>
---
drivers/net/ethernet/ti/cpts.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 8cb0369..61198f1 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -230,18 +230,20 @@ static void cpts_overflow_check(struct work_struct *work)
static void cpts_clk_init(struct device *dev, struct cpts *cpts)
{
- cpts->refclk = devm_clk_get(dev, "cpts");
- if (IS_ERR(cpts->refclk)) {
- dev_err(dev, "Failed to get cpts refclk\n");
- cpts->refclk = NULL;
- return;
+ if (!cpts->refclk) {
+ cpts->refclk = devm_clk_get(dev, "cpts");
+ if (IS_ERR(cpts->refclk)) {
+ dev_err(dev, "Failed to get cpts refclk\n");
+ cpts->refclk = NULL;
+ return;
+ }
}
clk_prepare_enable(cpts->refclk);
}
static void cpts_clk_release(struct cpts *cpts)
{
- clk_disable(cpts->refclk);
+ clk_disable_unprepare(cpts->refclk);
}
static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
--
2.10.1
Powered by blists - more mailing lists