From patchwork Fri Jan 27 14:42:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabio Estevam X-Patchwork-Id: 138240 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id BDEA4B6EFE for ; Sat, 28 Jan 2012 01:45:13 +1100 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Rqn0a-0000o8-Ey; Fri, 27 Jan 2012 14:42:32 +0000 Received: from va3ehsobe003.messaging.microsoft.com ([216.32.180.13] helo=VA3EHSOBE009.bigfish.com) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Rqn0W-0000nu-RW for linux-arm-kernel@lists.infradead.org; Fri, 27 Jan 2012 14:42:29 +0000 Received: from mail47-va3-R.bigfish.com (10.7.14.236) by VA3EHSOBE009.bigfish.com (10.7.40.29) with Microsoft SMTP Server id 14.1.225.23; Fri, 27 Jan 2012 14:42:25 +0000 Received: from mail47-va3 (localhost [127.0.0.1]) by mail47-va3-R.bigfish.com (Postfix) with ESMTP id 8A2643E03FB; Fri, 27 Jan 2012 14:42:25 +0000 (UTC) X-SpamScore: 0 X-BigFish: VS0(zzzz1202hzz8275bhz2dhc1bhc31hc1ah2a8h668h839h) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI Received: from mail47-va3 (localhost.localdomain [127.0.0.1]) by mail47-va3 (MessageSwitch) id 132767533364324_27039; Fri, 27 Jan 2012 14:42:13 +0000 (UTC) Received: from VA3EHSMHS012.bigfish.com (unknown [10.7.14.242]) by mail47-va3.bigfish.com (Postfix) with ESMTP id D27C6240089; Fri, 27 Jan 2012 14:42:11 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by VA3EHSMHS012.bigfish.com (10.7.99.22) with Microsoft SMTP Server (TLS) id 14.1.225.23; Fri, 27 Jan 2012 14:42:10 +0000 Received: from az33smr02.freescale.net (10.64.34.200) by 039-SN1MMR1-002.039d.mgd.msft.net (10.84.1.15) with Microsoft SMTP Server id 14.1.355.3; Fri, 27 Jan 2012 08:42:09 -0600 Received: from fabio-Latitude-E6410.am.freescale.net ([10.29.240.140]) by az33smr02.freescale.net (8.13.1/8.13.0) with ESMTP id q0REg7TI017311; Fri, 27 Jan 2012 08:42:08 -0600 (CST) From: Fabio Estevam To: Subject: [PATCH v2] ARM: mx28: clock-mx28: Use a proper timeout mechanism Date: Fri, 27 Jan 2012 12:42:04 -0200 Message-ID: <1327675324-11307-1-git-send-email-fabio.estevam@freescale.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1327329667-25512-1-git-send-email-fabio.estevam@freescale.com> References: <1327329667-25512-1-git-send-email-fabio.estevam@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [216.32.180.13 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Fabio Estevam , shawn.guo@freescale.com, kernel@pengutronix.de, w.sang@pengutronix.de X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org Introduce a function for checking the busy bits of CLKCTRL register that uses a proper timeout mechanism. Remove parts of code that use busy loops and replace them with the mxs_clkctrl_timeout() function. Tested on a mx28evk by performing audio playback. Suggested-by: Wolfram Sang Signed-off-by: Fabio Estevam --- Changes since v1: - Removed empty lines - Removed _func_ from error message - Put mxs_clkctrl_timeout in common file - Change mx23 too - Fixed comment about jiffy arch/arm/mach-mxs/clock-mx23.c | 34 +++------------------ arch/arm/mach-mxs/clock-mx28.c | 49 ++++--------------------------- arch/arm/mach-mxs/include/mach/common.h | 2 + arch/arm/mach-mxs/system.c | 16 ++++++++++ 4 files changed, 29 insertions(+), 72 deletions(-) diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c index e12e112..293958b 100644 --- a/arch/arm/mach-mxs/clock-mx23.c +++ b/arch/arm/mach-mxs/clock-mx23.c @@ -223,7 +223,6 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate) { u32 reg, bm_busy, div_max, d, f, div, frac; unsigned long diff, parent_rate, calc_rate; - int i; parent_rate = clk_get_rate(clk->parent); @@ -275,14 +274,7 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate) reg |= div << BP_CLKCTRL_CPU_DIV_CPU; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU); - for (i = 10000; i; i--) - if (!(__raw_readl(CLKCTRL_BASE_ADDR + - HW_CLKCTRL_CPU) & bm_busy)) - break; - if (!i) { - pr_err("%s: divider writing timeout\n", __func__); - return -ETIMEDOUT; - } + mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy); return 0; } @@ -292,7 +284,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ { \ u32 reg, div_max, div; \ unsigned long parent_rate; \ - int i; \ \ parent_rate = clk_get_rate(clk->parent); \ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ @@ -310,15 +301,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ } \ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ \ - for (i = 10000; i; i--) \ - if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ - HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \ - break; \ - if (!i) { \ - pr_err("%s: divider writing timeout\n", __func__); \ - return -ETIMEDOUT; \ - } \ - \ + mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY); \ return 0; \ } @@ -461,7 +444,7 @@ static struct clk_lookup lookups[] = { static int clk_misc_init(void) { u32 reg; - int i; + int ret; /* Fix up parent per register setting */ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ); @@ -510,14 +493,7 @@ static int clk_misc_init(void) reg |= 3 << BP_CLKCTRL_HBUS_DIV; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS); - for (i = 10000; i; i--) - if (!(__raw_readl(CLKCTRL_BASE_ADDR + - HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY)) - break; - if (!i) { - pr_err("%s: divider writing timeout\n", __func__); - return -ETIMEDOUT; - } + ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY); /* Gate off cpu clock in WFI for power saving */ __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT, @@ -532,7 +508,7 @@ static int clk_misc_init(void) reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC); - return 0; + return ret; } int __init mx23_clocks_init(void) diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c index 5d68e41..f91b8fb 100644 --- a/arch/arm/mach-mxs/clock-mx28.c +++ b/arch/arm/mach-mxs/clock-mx28.c @@ -322,7 +322,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ { \ u32 reg, bm_busy, div_max, d, f, div, frac; \ unsigned long diff, parent_rate, calc_rate; \ - int i; \ \ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ bm_busy = BM_CLKCTRL_##dr##_BUSY; \ @@ -396,16 +395,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ } \ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ \ - for (i = 10000; i; i--) \ - if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ - HW_CLKCTRL_##dr) & bm_busy)) \ - break; \ - if (!i) { \ - pr_err("%s: divider writing timeout\n", __func__); \ - return -ETIMEDOUT; \ - } \ - \ - return 0; \ + return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy); \ } _CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU) @@ -421,7 +411,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ { \ u32 reg, div_max, div; \ unsigned long parent_rate; \ - int i; \ \ parent_rate = clk_get_rate(clk->parent); \ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ @@ -439,16 +428,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ } \ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ \ - for (i = 10000; i; i--) \ - if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ - HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \ - break; \ - if (!i) { \ - pr_err("%s: divider writing timeout\n", __func__); \ - return -ETIMEDOUT; \ - } \ - \ - return 0; \ + return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\ } _CLK_SET_RATE1(xbus_clk, XBUS) @@ -461,7 +441,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ u32 reg; \ u64 lrate; \ unsigned long parent_rate; \ - int i; \ \ parent_rate = clk_get_rate(clk->parent); \ if (rate > parent_rate) \ @@ -479,16 +458,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ reg |= div << BP_CLKCTRL_##rs##_DIV; \ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \ \ - for (i = 10000; i; i--) \ - if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ - HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY)) \ - break; \ - if (!i) { \ - pr_err("%s: divider writing timeout\n", __func__); \ - return -ETIMEDOUT; \ - } \ - \ - return 0; \ + return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\ } _CLK_SET_RATE_SAIF(saif0_clk, SAIF0) @@ -676,7 +646,7 @@ static struct clk_lookup lookups[] = { static int clk_misc_init(void) { u32 reg; - int i; + int ret; /* Fix up parent per register setting */ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ); @@ -756,14 +726,7 @@ static int clk_misc_init(void) reg |= 3 << BP_CLKCTRL_HBUS_DIV; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS); - for (i = 10000; i; i--) - if (!(__raw_readl(CLKCTRL_BASE_ADDR + - HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY)) - break; - if (!i) { - pr_err("%s: divider writing timeout\n", __func__); - return -ETIMEDOUT; - } + ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY); /* Gate off cpu clock in WFI for power saving */ __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT, @@ -790,7 +753,7 @@ static int clk_misc_init(void) reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0); - return 0; + return ret; } int __init mx28_clocks_init(void) diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h index e1237ab..c50c3ea 100644 --- a/arch/arm/mach-mxs/include/mach/common.h +++ b/arch/arm/mach-mxs/include/mach/common.h @@ -31,4 +31,6 @@ extern void mx28_init_irq(void); extern void icoll_init_irq(void); +extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask); + #endif /* __MACH_MXS_COMMON_H__ */ diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c index 54f91ad..98e2de0 100644 --- a/arch/arm/mach-mxs/system.c +++ b/arch/arm/mach-mxs/system.c @@ -37,6 +37,8 @@ #define MXS_MODULE_CLKGATE (1 << 30) #define MXS_MODULE_SFTRST (1 << 31) +#define CLKCTRL_TIMEOUT 10 /* 10 ms */ + static void __iomem *mxs_clkctrl_reset_addr; /* @@ -137,3 +139,17 @@ error: return -ETIMEDOUT; } EXPORT_SYMBOL(mxs_reset_block); + +int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT); + while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR) + + reg_offset) & mask) { + if (time_after(jiffies, timeout)) { + pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset); + return -ETIMEDOUT; + } + } + + return 0; +}