From patchwork Sat Sep 29 22:34:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Kemnade X-Patchwork-Id: 10621023 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2F73615A7 for ; Sat, 29 Sep 2018 22:34:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 15F8929C8C for ; Sat, 29 Sep 2018 22:34:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 070F829D03; Sat, 29 Sep 2018 22:34:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D47A229C8C for ; Sat, 29 Sep 2018 22:34:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726358AbeI3FEv (ORCPT ); Sun, 30 Sep 2018 01:04:51 -0400 Received: from mail.andi.de1.cc ([85.214.239.24]:47880 "EHLO h2641619.stratoserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726166AbeI3FEv (ORCPT ); Sun, 30 Sep 2018 01:04:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kemnade.info; s=20180802; h=Message-Id:Date:Subject:Cc:To:From:Sender: Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=wMN31O39KSxIDao2GhmLfH2m/CJJ7gmcyTTJCreCk6w=; b=l6iZNFMu27JvtideO5DRAE21ut ThpEq+H1f4d0VVCD4I0q12i+j5DScEJLEQi9luY7t4axUaYdK3x3XmIevRXIZLoBM/Q7ppKJRtjol TPEG8wKdpYoMEade1NNXUbnrtwYSezbePOYVcscl1KW1SYiSBKoxaQ1BM5G5CBhRXB2U=; Received: from p200300ccfbf72f001a3da2fffebfd33a.dip0.t-ipconnect.de ([2003:cc:fbf7:2f00:1a3d:a2ff:febf:d33a] helo=aktux) by h2641619.stratoserver.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1g6Noo-0000ij-3U; Sun, 30 Sep 2018 00:34:34 +0200 Received: from andi by aktux with local (Exim 4.89) (envelope-from ) id 1g6Non-0000Bw-No; Sun, 30 Sep 2018 00:34:33 +0200 From: Andreas Kemnade To: linux-omap@vger.kernel.org, Tero Kristo , Evgeniy Polyakov , Tony Lindgren , Discussions about the Letux Kernel Cc: Andreas Kemnade Subject: [PATCH RFC] w1: omap: disable iclk autoidle Date: Sun, 30 Sep 2018 00:34:21 +0200 Message-Id: <20180929223421.32556-1-andreas@kemnade.info> X-Mailer: git-send-email 2.11.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On the gta04 in DM3730, omap_hdq gets stuck whenever autosuspend is enabled for UART1/2. The system will go into a lower power state then. According to the TRM, the module has no way to prevent the ick from being but during a transfer if autoidle is enabled. So disable autoidle. Having omap_hdq working on the gta04 is important for measuring currents through a bq27000. The question is what is the best place to do this. Perhaps better in arch/arm/mach-omap2 somehow, so no additional exported symbols are needed. But there seems to be no simple flag to set there. Maybe we need something like arch/arm/mach-omap2/mcbsp.c? And also the affected platforms need to be checked. Probably omap_hdq_get/put should also be cleaned up and stuff from there should be put into a runtime_suspend/resume handler. Signed-off-by: Andreas Kemnade --- drivers/clk/ti/autoidle.c | 2 ++ drivers/w1/masters/omap_hdq.c | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/clk/ti/autoidle.c b/drivers/clk/ti/autoidle.c index 7bb9afbe4058..b8970006efd9 100644 --- a/drivers/clk/ti/autoidle.c +++ b/drivers/clk/ti/autoidle.c @@ -52,6 +52,7 @@ int omap2_clk_deny_idle(struct clk *clk) c->ops->deny_idle(c); return 0; } +EXPORT_SYMBOL(omap2_clk_deny_idle); /** * omap2_clk_allow_idle - enable autoidle on an OMAP clock @@ -68,6 +69,7 @@ int omap2_clk_allow_idle(struct clk *clk) c->ops->allow_idle(c); return 0; } +EXPORT_SYMBOL(omap2_clk_allow_idle); static void _allow_autoidle(struct clk_ti_autoidle *clk) { diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 3099052e1243..e3aeba8a1155 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include @@ -59,6 +61,14 @@ MODULE_PARM_DESC(w1_id, "1-wire id for the slave detection in HDQ mode"); struct hdq_data { struct device *dev; + /* + * needed to disable autoidle, if system power state is too low + * hdq transactions will not work correctly, although registers + * are accessible. + * According to AM/DM3730 TRM p.2879 the hwmod has to way to + * keep iclk running during a transfer if autoidle is enabled + */ + struct clk *ick; void __iomem *hdq_base; /* lock status update */ struct mutex hdq_mutex; @@ -414,6 +424,9 @@ static int omap_hdq_get(struct hdq_data *hdq_data) try_module_get(THIS_MODULE); if (1 == hdq_data->hdq_usecount) { + if (!IS_ERR_OR_NULL(hdq_data->ick)) + omap2_clk_deny_idle(hdq_data->ick); + pm_runtime_get_sync(hdq_data->dev); /* make sure HDQ/1W is out of reset */ @@ -460,8 +473,11 @@ static int omap_hdq_put(struct hdq_data *hdq_data) } else { hdq_data->hdq_usecount--; module_put(THIS_MODULE); - if (0 == hdq_data->hdq_usecount) + if (hdq_data->hdq_usecount == 0) { pm_runtime_put_sync(hdq_data->dev); + if (!IS_ERR_OR_NULL(hdq_data->ick)) + omap2_clk_allow_idle(hdq_data->ick); + } } mutex_unlock(&hdq_data->hdq_mutex); @@ -681,8 +697,15 @@ static int omap_hdq_probe(struct platform_device *pdev) hdq_data->hdq_usecount = 0; hdq_data->rrw = 0; + hdq_data->ick = devm_clk_get(dev, "hdq_ick"); + if (IS_ERR_OR_NULL(hdq_data->ick)) + dev_info(dev, "no hdq_ick, lets hope autoidle behaves!"); + mutex_init(&hdq_data->hdq_mutex); + if (!IS_ERR_OR_NULL(hdq_data->ick)) + omap2_clk_deny_idle(hdq_data->ick); + pm_runtime_enable(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) { @@ -718,6 +741,8 @@ static int omap_hdq_probe(struct platform_device *pdev) omap_hdq_break(hdq_data); pm_runtime_put_sync(&pdev->dev); + if (!IS_ERR_OR_NULL(hdq_data->ick)) + omap2_clk_allow_idle(hdq_data->ick); ret = of_property_read_string(pdev->dev.of_node, "ti,mode", &mode); if (ret < 0 || !strcmp(mode, "hdq")) {