From patchwork Sun Jan 17 21:01:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anand Moon X-Patchwork-Id: 569310 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id F095414076E for ; Mon, 18 Jan 2016 08:02:23 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=Wxj2JVpA; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752743AbcAQVCX (ORCPT ); Sun, 17 Jan 2016 16:02:23 -0500 Received: from mail-pf0-f175.google.com ([209.85.192.175]:34543 "EHLO mail-pf0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752554AbcAQVCW (ORCPT ); Sun, 17 Jan 2016 16:02:22 -0500 Received: by mail-pf0-f175.google.com with SMTP id q63so150569103pfb.1; Sun, 17 Jan 2016 13:02:21 -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; bh=dnq/603AvL6PyD8Yem6HFcfxdqg++F+ZbEMahFIl0ZM=; b=Wxj2JVpAjhPaE9f5MplDr9JQaFoRaKOGW9Xmi2PrYWkHy5vrzU5XXk8n/pFAZ8cAFs bLzWucLS9Hd5cOfP3qoqoaAw+PmJOpWj+MygN5Hvx2G0W/Q8vC/95IyTQGaXvfL3qkD6 QJxWs6H6vCjbSukKdJw5X8xZwOJKctBGH99sc8vlFim+6L5A5Ly0k/xvZb/RLxIi6T+g PCxyigxYstdnJz7iCgSUOVBJYzazQNswDpn2FGq0PZEV328RMpxZWCVJOfDqA5MUuuMM J78DlORgjYWxeHgiT4wk23ZXiXk7oSXRhBAB0BGh99lghb8NZSf9w1F16qCQkRLux5/0 8pww== 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; bh=dnq/603AvL6PyD8Yem6HFcfxdqg++F+ZbEMahFIl0ZM=; b=j3levf8k+hVBpyZYiFmTHOMUQF1PdSykLD7dbJWebx+ICordu1rYL9WsRHAAH/ZMJ1 6T48O4u56hLwoW7kHcOMqgPaP0IVUivFBZKG1kT1KnZD7TY2YNaUenmsaRUqxJPBLMEI Xqke8ELweYhja8xW9zP2E3+UBZCpt6+NoEg73cY9iKMYLHOxmLnLX4HD+dVp9Zli6uJX FMUeEutskLE2oW1nLPUWSdK4Nagh/fvk8qJonHqsdc11ephoNyncFAsQPouJ6Mb+ka4Q iw6KYVMHiYRONywQQrhdwL71NiG212Vim1qHwDeOR1ptfjVcZqlrAzZQf/7UmZLl4D0E P4ng== X-Gm-Message-State: ALoCoQk7kmDaGqMigRXwsX8I1rjPx4r0SqoGNqzt0P/eyCPTQ1iiOO4D0zzHlc6pxwhkeCFqEeHoLs/X1aX9yWtrRd0RZr4ICw== X-Received: by 10.98.67.14 with SMTP id q14mr31697040pfa.137.1453064541258; Sun, 17 Jan 2016 13:02:21 -0800 (PST) Received: from localhost.localdomain ([115.112.130.211]) by smtp.gmail.com with ESMTPSA id p20sm28831022pfi.86.2016.01.17.13.02.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 17 Jan 2016 13:02:20 -0800 (PST) From: Anand Moon To: Guenter Roeck , Thierry Reding , Krzysztof Kozlowski , Javier Martinez Canillas , Anand Moon Cc: linux-pwm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org Subject: [PATCHv2] pwm: avoid holding mutex in interrupt context Date: Sun, 17 Jan 2016 21:01:57 +0000 Message-Id: <1453064517-12315-1-git-send-email-linux.amoon@gmail.com> X-Mailer: git-send-email 2.1.4 Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org The introduction of the mutex in commit d1cd21427747 ("pwm: Set enable state properly on failed call to enable") effectively makes all PWM drivers potentially sleeping. That in turn makes the .can_sleep field obsolete since all drivers can now sleep. Changes fix the below bug by using spinlocks instead of mutex [ 22.300239] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:97 [ 22.307212] in_atomic(): 1, irqs_disabled(): 0, pid: 2257, name: sh [ 22.313454] Preemption disabled at:[< (null)>] (null) [ 23.655232] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:97 [ 23.662174] in_atomic(): 1, irqs_disabled(): 0, pid: 2404, name: upowerd [ 23.668932] Preemption disabled at:[< (null)>] (null) [ 25.010207] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:97 [ 25.017125] in_atomic(): 1, irqs_disabled(): 0, pid: 2262, name: indicator-keybo [ 25.024491] Preemption disabled at:[< (null)>] (null) [ 26.355237] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:97 [ 26.362141] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0 [ 26.368728] Preemption disabled at:[< (null)>] (null) [ 27.680220] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:97 [ 27.687119] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0 [ 27.693698] Preemption disabled at:[< (null)>] (null) [ 29.005199] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:97 [ 29.012124] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0 [thierry.reding@gmail.com: Fixed the commit message] Signed-off-by: Anand Moon --- Changes logs: droped my prevoius approch. --- drivers/pwm/core.c | 10 +++++----- include/linux/pwm.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index d24ca5f..58e7091 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -269,7 +269,7 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip, pwm->pwm = chip->base + i; pwm->hwpwm = i; pwm->polarity = polarity; - mutex_init(&pwm->lock); + spin_lock_init(&pwm->lock); radix_tree_insert(&pwm_tree, pwm->pwm, pwm); } @@ -474,7 +474,7 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity) if (!pwm->chip->ops->set_polarity) return -ENOSYS; - mutex_lock(&pwm->lock); + spin_lock_irq(&pwm->lock); if (pwm_is_enabled(pwm)) { err = -EBUSY; @@ -488,7 +488,7 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity) pwm->polarity = polarity; unlock: - mutex_unlock(&pwm->lock); + spin_unlock_irq(&pwm->lock); return err; } EXPORT_SYMBOL_GPL(pwm_set_polarity); @@ -506,7 +506,7 @@ int pwm_enable(struct pwm_device *pwm) if (!pwm) return -EINVAL; - mutex_lock(&pwm->lock); + spin_lock_irq(&pwm->lock); if (!test_and_set_bit(PWMF_ENABLED, &pwm->flags)) { err = pwm->chip->ops->enable(pwm->chip, pwm); @@ -514,7 +514,7 @@ int pwm_enable(struct pwm_device *pwm) clear_bit(PWMF_ENABLED, &pwm->flags); } - mutex_unlock(&pwm->lock); + spin_unlock_irq(&pwm->lock); return err; } diff --git a/include/linux/pwm.h b/include/linux/pwm.h index cfc3ed4..86ad4c2 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -2,7 +2,7 @@ #define __LINUX_PWM_H #include -#include +#include #include struct pwm_device; @@ -100,7 +100,7 @@ struct pwm_device { unsigned int pwm; struct pwm_chip *chip; void *chip_data; - struct mutex lock; + spinlock_t lock; unsigned int period; unsigned int duty_cycle;