From patchwork Thu Aug 21 13:47:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tero Kristo X-Patchwork-Id: 35766 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f200.google.com (mail-pd0-f200.google.com [209.85.192.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5A96720540 for ; Thu, 21 Aug 2014 13:48:20 +0000 (UTC) Received: by mail-pd0-f200.google.com with SMTP id w10sf71162068pde.11 for ; Thu, 21 Aug 2014 06:48:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :mime-version:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe:content-type; bh=Ge75C5vlOma1M7lbh6x1kNX+r7kBWloySjAe+SZCWUE=; b=JxKQ8x0d9jQZBOrOOfOPNECOKpfOSrdwc04MtE0Q50S59FtV3X197jbuy3pbiNBQ2t /Ovtv0ogebHpC1fEpciXo2IkbJFiLHpmNTOL3yxJnf7XIfYw7kDOgXPOyfE+eA2afpGl ePOD81Vhg0bf2xipM6lWfMz6qs0/v8vdPAeVzYHaU4xDk8/y8avMkCYaf0OWl6g1DgHY mWosftWJ+1W1ZpfUnmkpThcX0Yt6hIt2NojgS4vvghIIpN9qvewptS6rKadRouthHenJ 8oINlu0ugtilLpMwkEi1bAsNGOjk54ftbFnpkZqq93JuZhdCcSxq4FXDnlvZu15O6e0v 3ZWA== X-Gm-Message-State: ALoCoQm0tX+CS7ivNE2N+7XOHn6+pEDtSeCpzWzDtwy1edfcjf683ayZmOCazjORXo8Xw/ZRAYnf X-Received: by 10.67.5.101 with SMTP id cl5mr4300768pad.41.1408628899489; Thu, 21 Aug 2014 06:48:19 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.25.148 with SMTP id 20ls771078qgt.86.gmail; Thu, 21 Aug 2014 06:48:19 -0700 (PDT) X-Received: by 10.52.62.195 with SMTP id a3mr119813vds.76.1408628899354; Thu, 21 Aug 2014 06:48:19 -0700 (PDT) Received: from mail-vc0-f175.google.com (mail-vc0-f175.google.com [209.85.220.175]) by mx.google.com with ESMTPS id tc7si11672585vdc.84.2014.08.21.06.48.19 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 21 Aug 2014 06:48:19 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.175 as permitted sender) client-ip=209.85.220.175; Received: by mail-vc0-f175.google.com with SMTP id ik5so10545619vcb.6 for ; Thu, 21 Aug 2014 06:48:19 -0700 (PDT) X-Received: by 10.52.69.172 with SMTP id f12mr17316836vdu.9.1408628899239; Thu, 21 Aug 2014 06:48:19 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.45.67 with SMTP id uj3csp137230vcb; Thu, 21 Aug 2014 06:48:18 -0700 (PDT) X-Received: by 10.70.140.139 with SMTP id rg11mr68655484pdb.13.1408628897833; Thu, 21 Aug 2014 06:48:17 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id pn7si36496509pbc.0.2014.08.21.06.48.16 for ; Thu, 21 Aug 2014 06:48:17 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755380AbaHUNsN (ORCPT + 26 others); Thu, 21 Aug 2014 09:48:13 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:56258 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754996AbaHUNsJ (ORCPT ); Thu, 21 Aug 2014 09:48:09 -0400 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id s7LDljus022889; Thu, 21 Aug 2014 08:47:45 -0500 Received: from DLEE70.ent.ti.com (dlee70.ent.ti.com [157.170.170.113]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s7LDljgk023249; Thu, 21 Aug 2014 08:47:45 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE70.ent.ti.com (157.170.170.113) with Microsoft SMTP Server id 14.3.174.1; Thu, 21 Aug 2014 08:47:44 -0500 Received: from localhost.localdomain (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id s7LDlgHp031898; Thu, 21 Aug 2014 08:47:43 -0500 From: Tero Kristo To: , , , , CC: Subject: [PATCH] clk: prevent erronous parsing of children during rate change Date: Thu, 21 Aug 2014 16:47:45 +0300 Message-ID: <1408628866-32351-1-git-send-email-t-kristo@ti.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: t-kristo@ti.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.175 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , In some cases, clocks can switch their parent with clk_set_rate, for example clk_mux can do this in some cases. Current implementation of clk_change_rate uses un-safe list iteration on the clock children, which will cause wrong clocks to be parsed in case any of the clock children change their parents during the change rate operation. Fixed by using the safe list iterator instead. The problem was detected due to some divide by zero errors generated by clock init on dra7-evm board, see discussion under http://article.gmane.org/gmane.linux.ports.arm.kernel/349180 for details. Signed-off-by: Tero Kristo To: Mike Turquette Reported-by: Nishanth Menon Tested-by: Nishanth Menon --- drivers/clk/clk.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b76fa69..bacc06f 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1467,6 +1467,7 @@ static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long even static void clk_change_rate(struct clk *clk) { struct clk *child; + struct hlist_node *tmp; unsigned long old_rate; unsigned long best_parent_rate = 0; bool skip_set_rate = false; @@ -1502,7 +1503,11 @@ static void clk_change_rate(struct clk *clk) if (clk->notifier_count && old_rate != clk->rate) __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); - hlist_for_each_entry(child, &clk->children, child_node) { + /* + * Use safe iteration, as change_rate can actually swap parents + * for certain clock types. + */ + hlist_for_each_entry_safe(child, tmp, &clk->children, child_node) { /* Skip children who will be reparented to another clock */ if (child->new_parent && child->new_parent != clk) continue;