From patchwork Fri Apr 1 09:33:31 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Rosengren X-Patchwork-Id: 874 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:46:53 -0000 Delivered-To: patches@linaro.org Received: by 10.42.161.68 with SMTP id s4cs201395icx; Fri, 1 Apr 2011 02:34:54 -0700 (PDT) Received: by 10.227.176.72 with SMTP id bd8mr3910225wbb.196.1301650493278; Fri, 01 Apr 2011 02:34:53 -0700 (PDT) Received: from eu1sys200aog105.obsmtp.com (eu1sys200aog105.obsmtp.com [207.126.144.119]) by mx.google.com with SMTP id d17si4173438wbh.102.2011.04.01.02.34.46 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 01 Apr 2011 02:34:51 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.119 is neither permitted nor denied by best guess record for domain of robert.rosengren@stericsson.com) client-ip=207.126.144.119; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.119 is neither permitted nor denied by best guess record for domain of robert.rosengren@stericsson.com) smtp.mail=robert.rosengren@stericsson.com Received: from source ([164.129.1.35]) (using TLSv1) by eu1sys200aob105.postini.com ([207.126.147.11]) with SMTP ID DSNKTZWcNvKJTj09+4KKyPVa2lpCZp8e/i49@postini.com; Fri, 01 Apr 2011 09:34:51 UTC Received: from zeta.dmz-eu.st.com (ns2.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 12407101; Fri, 1 Apr 2011 09:34:36 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 8862D1ED9; Fri, 1 Apr 2011 09:34:36 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id ED76D24C2E5; Fri, 1 Apr 2011 11:34:00 +0200 (CEST) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.2.254.0; Fri, 1 Apr 2011 11:34:06 +0200 From: Robert Rosengren To: Liam Girdwood , Mark Brown , Cc: Bengt Jonsson , Linus Walleij , Robert Rosengren Subject: [PATCH] regulator: recursive locking detected Date: Fri, 1 Apr 2011 11:33:31 +0200 Message-ID: <1301650411-17762-1-git-send-email-robert.rosengren@stericsson.com> X-Mailer: git-send-email 1.7.4.1 MIME-Version: 1.0 "possible recursive locking detected"-warnings are issued when a regulator has specified supply regulator. Both when enabling and disabling regulators uses recursive call chains for notify the supply regulators. This is due to locking mutexes of the same lock class, i.e. the locks reside in the regulator_dev struct. Since this is valid behavior for the regulators, this patch changes the mutex lock into nested, as suggested in lockdep-design.txt. Signed-off-by: Robert Rosengren Acked-by: Linus Walleij --- drivers/regulator/core.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 3ffc697..2a66c6b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -87,7 +87,7 @@ static int _regulator_get_voltage(struct regulator_dev *rdev); static int _regulator_get_current_limit(struct regulator_dev *rdev); static unsigned int _regulator_get_mode(struct regulator_dev *rdev); static void _notifier_call_chain(struct regulator_dev *rdev, - unsigned long event, void *data); + unsigned long event, void *data, int lock_sublevel); static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV); @@ -1407,7 +1407,7 @@ static int _regulator_disable(struct regulator_dev *rdev, trace_regulator_disable_complete(rdev_get_name(rdev)); _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, - NULL); + NULL, 0); } /* decrease our supplies ref count and disable if required */ @@ -1477,7 +1477,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev, } /* notify other consumers that power has been forced off */ _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE | - REGULATOR_EVENT_DISABLE, NULL); + REGULATOR_EVENT_DISABLE, NULL, 0); } /* decrease our supplies ref count and disable if required */ @@ -1699,7 +1699,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, if (ret == 0) _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, - NULL); + NULL, 0); trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector); @@ -2167,19 +2167,23 @@ EXPORT_SYMBOL_GPL(regulator_unregister_notifier); /* notify regulator consumers and downstream regulator consumers. * Note mutex must be held by caller. + * lock_sublevel should always be 0, only used for recursive calls. */ static void _notifier_call_chain(struct regulator_dev *rdev, - unsigned long event, void *data) + unsigned long event, void *data, int lock_sublevel) { struct regulator_dev *_rdev; /* call rdev chain first */ blocking_notifier_call_chain(&rdev->notifier, event, NULL); + /* increase sublevel before stepping into nested regulators */ + lock_sublevel++; + /* now notify regulator we supply */ list_for_each_entry(_rdev, &rdev->supply_list, slist) { - mutex_lock(&_rdev->mutex); - _notifier_call_chain(_rdev, event, data); + mutex_lock_nested(&_rdev->mutex, lock_sublevel); + _notifier_call_chain(_rdev, event, data, lock_sublevel); mutex_unlock(&_rdev->mutex); } } @@ -2333,7 +2337,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free); int regulator_notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data) { - _notifier_call_chain(rdev, event, data); + _notifier_call_chain(rdev, event, data, 0); return NOTIFY_DONE; }