From patchwork Sat Jan 30 04:26:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "David Rivshin (Allworx)" X-Patchwork-Id: 8169531 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 67F4DBEEE5 for ; Sat, 30 Jan 2016 04:32:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8408A20142 for ; Sat, 30 Jan 2016 04:32:42 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AF9BD20396 for ; Sat, 30 Jan 2016 04:32:41 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aPNC0-00080J-3c; Sat, 30 Jan 2016 04:31:24 +0000 Received: from mail-qk0-x241.google.com ([2607:f8b0:400d:c09::241]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aPNBX-0007k8-GQ for linux-arm-kernel@lists.infradead.org; Sat, 30 Jan 2016 04:30:56 +0000 Received: by mail-qk0-x241.google.com with SMTP id q184so2656431qkb.0 for ; Fri, 29 Jan 2016 20:30:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=d1vnCutbeV5s2NJkeHGdV/wuPkLm/NOR+2qOsI3m1D8=; b=Stel/552aWXyqPDHtRuZjD1CnCqO0IT9HMmMlm71wMii0XLZdQB1btal5CjpGHfrww NkSIOAZ6oXrmRblNS7DEb4vwfipDjLVP/b4IZKImliSXCZORX0lPC8R6/WgXUmhAA5Ba Zk6gzvtRpiTADdhY9cYtQ/t3iBgIpOEzDGuZ09/4dMsoOEyRbxIEpWhdmYb0OpuIreCk kR3yjq3ZeIt3VlB358JWBGkkfx0VHbiSg1hC+dBPcP+7T+O8oLIoQUJYyoGJUEf+TLUa +5OLBNxzB5EGX52xWFG09EPy15R+oNgfkeGNb4tA6NOAtd7GQET7r5HLbIrjrQmS8hp9 Pjug== 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=d1vnCutbeV5s2NJkeHGdV/wuPkLm/NOR+2qOsI3m1D8=; b=DZo4qDmXwAOSPE1sIjtoMknLyJW38BoNv9vhpA0QHm+iM7Ow7e2cIhMMhoBRuem00R TLKjeq9xdzaqDy5VQ6jiNwz+USJr50WlFuI4SfrDx5OvUBIR27oUiReRnm4svPJVHTJb 133s3dHdi3TGdABdTLM9Pm/ndseKHoYA1OwxSrph1k+b8O0h9kHM2wSgVbijrrrI/oiy 9q8ATPTgV+63NSYXhzZ6iaIsD8TzCQfUwksdtjhI492EUBbxlzK6ynDUKXfu6Q2gQm1W S+823MgImcAkcOvVXjD2TJxvRrwiYTuVHIFUcfqpDsydmBqejnaOwAOZN3YRMpoEKnSO VVvA== X-Gm-Message-State: AG10YOSiwq3WdFvKKg72dLL8/LQ+UMlzDDd01uqqfrBINlyGMCrsx33BuYqiITNtFnyaTw== X-Received: by 10.55.192.7 with SMTP id o7mr15110082qki.93.1454128234419; Fri, 29 Jan 2016 20:30:34 -0800 (PST) Received: from drivshin-linux.crosskeys.inscitek.com ([24.213.148.66]) by smtp.gmail.com with ESMTPSA id y104sm8404563qgd.33.2016.01.29.20.30.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 29 Jan 2016 20:30:34 -0800 (PST) From: "David Rivshin (Allworx)" To: linux-pwm@vger.kernel.org, Thierry Reding , Neil Armstrong Subject: [PATCH 2/4] pwm: omap-dmtimer: add sanity checking for load and match values Date: Fri, 29 Jan 2016 23:26:52 -0500 Message-Id: <1454128014-22866-3-git-send-email-drivshin.allworx@gmail.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1454128014-22866-1-git-send-email-drivshin.allworx@gmail.com> References: <1454128014-22866-1-git-send-email-drivshin.allworx@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160129_203055_747933_CF63BDB4 X-CRM114-Status: GOOD ( 14.66 ) X-Spam-Score: -2.7 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Tony Lindgren , Joachim Eastwood , NeilBrown , Grant Erickson , linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: David Rivshin Add sanity checking to ensure that we do not program load or match values that are out of range if a user requests period or duty_cycle values which are not achievable. The match value cannot be less than the load value (but can be equal), and neither can be 0xffffffff. This means that there must be at least one fclk cycle between load and match, and another between match and overflow. Fixes: 6604c6556db9 ("pwm: Add PWM driver for OMAP using dual-mode timers") Signed-off-by: David Rivshin Acked-by: Neil Armstrong --- drivers/pwm/pwm-omap-dmtimer.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c index 0083e75..103d729 100644 --- a/drivers/pwm/pwm-omap-dmtimer.c +++ b/drivers/pwm/pwm-omap-dmtimer.c @@ -119,15 +119,13 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, fclk = omap->pdata->get_fclk(omap->dm_timer); if (!fclk) { dev_err(chip->dev, "invalid pmtimer fclk\n"); - mutex_unlock(&omap->mutex); - return -EINVAL; + goto err_einval; } clk_rate = clk_get_rate(fclk); if (!clk_rate) { dev_err(chip->dev, "invalid pmtimer fclk rate\n"); - mutex_unlock(&omap->mutex); - return -EINVAL; + goto err_einval; } dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate); @@ -142,6 +140,8 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, * The non-active time is the remainder: (DM_TIMER_MAX-match_value) * clock cycles. * + * NOTE: It is required that: load_value <= match_value < DM_TIMER_MAX + * * References: * OMAP4430/60/70 TRM sections 22.2.4.10 and 22.2.4.11 * AM335x Sitara TRM sections 20.1.3.5 and 20.1.3.6 @@ -149,6 +149,24 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, period_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, period_ns); duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns); + if (period_cycles < 2) { + dev_info(chip->dev, + "period %dns is too short for clock rate %luHz\n", + period_ns, clk_rate); + goto err_einval; + } + if (duty_cycles < 1) { + dev_dbg(chip->dev, + "duty cycle %dns is too short for clock rate %luHz, using minimum of 1 clock cycle\n", + duty_ns, clk_rate); + duty_cycles = 1; + } else if (duty_cycles >= period_cycles) { + dev_dbg(chip->dev, + "duty cycle %dns is too long for period %dns at clock rate %luHz, using maximum of 1 clock cycle less than period\n", + duty_ns, period_ns, clk_rate); + duty_cycles = period_cycles - 1; + } + load_value = (DM_TIMER_MAX - period_cycles) + 1; match_value = load_value + duty_cycles - 1; @@ -179,6 +197,11 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, mutex_unlock(&omap->mutex); return 0; + +err_einval: + mutex_unlock(&omap->mutex); + + return -EINVAL; } static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,