From patchwork Wed Jun 1 08:34:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 68985 Delivered-To: patch@linaro.org Received: by 10.140.92.199 with SMTP id b65csp2402384qge; Wed, 1 Jun 2016 01:36:06 -0700 (PDT) X-Received: by 10.98.43.210 with SMTP id r201mr6210535pfr.9.1464770162034; Wed, 01 Jun 2016 01:36:02 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f191si49677911pfc.101.2016.06.01.01.36.01; Wed, 01 Jun 2016 01:36:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757835AbcFAIfx (ORCPT + 30 others); Wed, 1 Jun 2016 04:35:53 -0400 Received: from mail-wm0-f50.google.com ([74.125.82.50]:38545 "EHLO mail-wm0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757756AbcFAIfm (ORCPT ); Wed, 1 Jun 2016 04:35:42 -0400 Received: by mail-wm0-f50.google.com with SMTP id a20so16536620wma.1 for ; Wed, 01 Jun 2016 01:35:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7NV8Bk3zK20cWfXlslvFsDdJLx2EC5efBEZGBs/1EnM=; b=X/9wVDGVXDudGiHAKl2Du7Z6yxXqUK56OYuEPeJcaTd3JUJFuesFD+pTxeqhWWZU3k crLHjUZen43ix3t80hGhxXgnKNqePQurWdHA/RahqctXVUrHGqbI7jxm0tZeoXOstzxO wOJHbzaBAYa5fetkPJzQjqY9gV8AgN3UoOQx0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7NV8Bk3zK20cWfXlslvFsDdJLx2EC5efBEZGBs/1EnM=; b=R42tpgSFMBJtyNj0PWFm+LTFKFjjo8b1AsIXwoNOhcfVXSh0e5xYCrstrC0W81cYTO baK+18gGuGU1QHHLD2BGJif1+i52XzA8EPmPwhIpfazmY0bavUGd4/Q54lQPi99hWBsD Hj45cg6yUzh6tD1zwJIzSG+2X3LFW+JlRuKpYpXqLx1h6MpdKLtRMXaouWQCkkOtET3S t/+Jsx3IynTiVh89qIBuHtd9W2XVFVbluy6ZH/+4Re4G9t9bqE6OaE7U8CCaNqHVMrdM rSbmpZZiONNfh2aSL402g2R7wVpLyvqZFmJjSvDZV1bRNJ8hZvjpgLft0Qn3SPvOX1Rv uiuQ== X-Gm-Message-State: ALyK8tLi2u9kvJUGz46xzJQxSdq20qPGX3QMi+bXciEpyMx7WxODssskeQwFUqLj08gm3MqT X-Received: by 10.28.150.80 with SMTP id y77mr21526458wmd.62.1464770140811; Wed, 01 Jun 2016 01:35:40 -0700 (PDT) Received: from localhost.localdomain (sju31-1-78-210-255-2.fbx.proxad.net. [78.210.255.2]) by smtp.gmail.com with ESMTPSA id t3sm33542865wmf.20.2016.06.01.01.35.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 01 Jun 2016 01:35:40 -0700 (PDT) From: Daniel Lezcano To: daniel.lezcano@linaro.org, tglx@linutronix.de Cc: linux-kernel@vger.kernel.org, Michal Simek , =?UTF-8?q?S=C3=B6ren=20Brinkmann?= , linux-arm-kernel@lists.infradead.org (moderated list:ARM/ZYNQ ARCHITEC...) Subject: [PATCH 7/9] clocksource/drivers/cadence_ttc: Convert init function to return error Date: Wed, 1 Jun 2016 10:34:50 +0200 Message-Id: <1464770093-12667-8-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1464770093-12667-1-git-send-email-daniel.lezcano@linaro.org> References: <1464770093-12667-1-git-send-email-daniel.lezcano@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The init functions do not return any error. They behave as the following: - panic, thus leading to a kernel crash while another timer may work and make the system boot up correctly or - print an error and let the caller unaware if the state of the system Change that by converting the init functions to return an error conforming to the CLOCKSOURCE_OF_RET prototype. Proper error handling (rollback, errno value) will be changed later case by case, thus this change just return back an error or success in the init function. Signed-off-by: Daniel Lezcano --- drivers/clocksource/cadence_ttc_timer.c | 82 +++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 34 deletions(-) -- 1.9.1 diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c index 9be6018..aa36cbf 100644 --- a/drivers/clocksource/cadence_ttc_timer.c +++ b/drivers/clocksource/cadence_ttc_timer.c @@ -322,22 +322,22 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, return NOTIFY_DONE; } -static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, +static int __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, u32 timer_width) { struct ttc_timer_clocksource *ttccs; int err; ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL); - if (WARN_ON(!ttccs)) - return; + if (!ttccs) + return -ENOMEM; ttccs->ttc.clk = clk; err = clk_prepare_enable(ttccs->ttc.clk); - if (WARN_ON(err)) { + if (err) { kfree(ttccs); - return; + return err; } ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk); @@ -345,9 +345,13 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, ttccs->ttc.clk_rate_change_nb.notifier_call = ttc_rate_change_clocksource_cb; ttccs->ttc.clk_rate_change_nb.next = NULL; - if (clk_notifier_register(ttccs->ttc.clk, - &ttccs->ttc.clk_rate_change_nb)) + + err = clk_notifier_register(ttccs->ttc.clk, + &ttccs->ttc.clk_rate_change_nb); + if (err) { pr_warn("Unable to register clock notifier.\n"); + return err; + } ttccs->ttc.base_addr = base; ttccs->cs.name = "ttc_clocksource"; @@ -368,14 +372,16 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE); - if (WARN_ON(err)) { + if (err) { kfree(ttccs); - return; + return err; } ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; sched_clock_register(ttc_sched_clock_read, timer_width, ttccs->ttc.freq / PRESCALE); + + return 0; } static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, @@ -401,30 +407,35 @@ static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, } } -static void __init ttc_setup_clockevent(struct clk *clk, - void __iomem *base, u32 irq) +static int __init ttc_setup_clockevent(struct clk *clk, + void __iomem *base, u32 irq) { struct ttc_timer_clockevent *ttcce; int err; ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL); - if (WARN_ON(!ttcce)) - return; + if (!ttcce) + return -ENOMEM; ttcce->ttc.clk = clk; err = clk_prepare_enable(ttcce->ttc.clk); - if (WARN_ON(err)) { + if (err) { kfree(ttcce); - return; + return err; } ttcce->ttc.clk_rate_change_nb.notifier_call = ttc_rate_change_clockevent_cb; ttcce->ttc.clk_rate_change_nb.next = NULL; - if (clk_notifier_register(ttcce->ttc.clk, - &ttcce->ttc.clk_rate_change_nb)) + + err = clk_notifier_register(ttcce->ttc.clk, + &ttcce->ttc.clk_rate_change_nb); + if (err) { pr_warn("Unable to register clock notifier.\n"); + return err; + } + ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); ttcce->ttc.base_addr = base; @@ -451,13 +462,15 @@ static void __init ttc_setup_clockevent(struct clk *clk, err = request_irq(irq, ttc_clock_event_interrupt, IRQF_TIMER, ttcce->ce.name, ttcce); - if (WARN_ON(err)) { + if (err) { kfree(ttcce); - return; + return err; } clockevents_config_and_register(&ttcce->ce, ttcce->ttc.freq / PRESCALE, 1, 0xfffe); + + return 0; } /** @@ -466,20 +479,14 @@ static void __init ttc_setup_clockevent(struct clk *clk, * Initializes the timer hardware and register the clock source and clock event * timers with Linux kernal timer framework */ -static void __init ttc_timer_init(struct device_node *timer) +static int __init ttc_timer_init(struct device_node *timer) { unsigned int irq; void __iomem *timer_baseaddr; struct clk *clk_cs, *clk_ce; - static int initialized; - int clksel; + int clksel, ret; u32 timer_width = 16; - if (initialized) - return; - - initialized = 1; - /* * Get the 1st Triple Timer Counter (TTC) block from the device tree * and use it. Note that the event timer uses the interrupt and it's the @@ -488,13 +495,13 @@ static void __init ttc_timer_init(struct device_node *timer) timer_baseaddr = of_iomap(timer, 0); if (!timer_baseaddr) { pr_err("ERROR: invalid timer base address\n"); - BUG(); + return -ENXIO; } irq = irq_of_parse_and_map(timer, 1); if (irq <= 0) { pr_err("ERROR: invalid interrupt number\n"); - BUG(); + return -EINVAL; } of_property_read_u32(timer, "timer-width", &timer_width); @@ -504,7 +511,7 @@ static void __init ttc_timer_init(struct device_node *timer) clk_cs = of_clk_get(timer, clksel); if (IS_ERR(clk_cs)) { pr_err("ERROR: timer input clock not found\n"); - BUG(); + return PTR_ERR(clk_cs); } clksel = readl_relaxed(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET); @@ -512,13 +519,20 @@ static void __init ttc_timer_init(struct device_node *timer) clk_ce = of_clk_get(timer, clksel); if (IS_ERR(clk_ce)) { pr_err("ERROR: timer input clock not found\n"); - BUG(); + return PTR_ERR(clk_cs); } - ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); - ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); + ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); + if (ret) + return ret; + + ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); + if (ret) + return ret; pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq); + + return 0; } -CLOCKSOURCE_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init); +CLOCKSOURCE_OF_DECLARE_RET(ttc, "cdns,ttc", ttc_timer_init);