From patchwork Tue Nov 7 18:15:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 835398 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="gcODElrv"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yWd0z6vYBz9sQl for ; Wed, 8 Nov 2017 05:16:35 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932485AbdKGSQc (ORCPT ); Tue, 7 Nov 2017 13:16:32 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:54162 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757472AbdKGSQ0 (ORCPT ); Tue, 7 Nov 2017 13:16:26 -0500 Received: by mail-wm0-f67.google.com with SMTP id r196so5852705wmf.2; Tue, 07 Nov 2017 10:16:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=UJPstvtFteabNuezpm+eKf4J9TRaMjJFiQbCGv3oY+o=; b=gcODElrvTXj4fSl0sRN3jfhKdd4PeMTt0qH8cHxcWwMOKil/5ePkZXneu40Dfy1JZ+ Fiptk4E6pAbwOWJQR1ArUtAkK+ZzwkZmoGx3G64HXY280AIO+ZBAXc3ZWSYhAxFVgy5B hV4meaSbd9oq5Lhhup+54rHL2jnoSDZMOHCHx2WuSDnjhlNFrTe6VMrpfGjjLYcbWpc3 gNI6X14TPFL8J/oWZlpqIlf9RdD4mAkOXF179egbGf/HZsTwSaTx+jegHeBL3/0+grOx g8sFUlXWId5U4Y8i/UjiL/eTYyqMnI4IMy0i/dfm6VhToUESzKNxI8VsQZl4hrwMlold PztQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=UJPstvtFteabNuezpm+eKf4J9TRaMjJFiQbCGv3oY+o=; b=iON1wbpIFUptCVNLcIuJE7w2Cn708UCVd4hR3zx4gHXfUlKqdYu0GfgrOwGGurhJVW oCiXKL+E+3jDboHMxBeKtHOsPAEJP5FSeF6XWjqPcntjNr1hDH5FVahONotWMM24aHJz HvmXJGt5rluJ+g9WX3K4RkVa5BCUFLEaduTnGLAqAPv54Sko/Wu+aTUPkGUYhfGdKv6P Xcm7mDpJM1J1GUgiCSSkYZ+mRCCtNl9oxFiNcEpxKo5UheFvRUSqHHYq5D6GfJEzwuEv OnT625zL/ce6RvEXPJAPfQ1UQZqEDglADfgzqgn5lnUm6s1aOSFOtMRDC7v2LEfPQetZ /tKg== X-Gm-Message-State: AJaThX6qY6d+iOstR+f/ErSl3YFNmWNxxIYcMQdzluy2ewqD3Tj9gyad bSglosTVVlB4tqm0k0qBrPM= X-Google-Smtp-Source: ABhQp+RTTEJY0ALdwKviBOn4gf0xNHmLSlMIoiXLagl3PTe5uJyHPQAGQwbW52nFhKiWHDookDPwHg== X-Received: by 10.28.216.5 with SMTP id p5mr28772wmg.155.1510078584492; Tue, 07 Nov 2017 10:16:24 -0800 (PST) Received: from localhost (p200300E41BC8E9001FF851737372D2C2.dip0.t-ipconnect.de. [2003:e4:1bc8:e900:1ff8:5173:7372:d2c2]) by smtp.gmail.com with ESMTPSA id c143sm13264926wmd.0.2017.11.07.10.16.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Nov 2017 10:16:23 -0800 (PST) From: Thierry Reding To: Linus Walleij , Grygorii Strashko Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 15/15] gpio: Automatically add lockdep keys Date: Tue, 7 Nov 2017 19:15:59 +0100 Message-Id: <20171107181559.6318-16-thierry.reding@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171107181559.6318-1-thierry.reding@gmail.com> References: <20171107181559.6318-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to avoid lockdep boilerplate in individual drivers, turn the gpiochip_add_data() function into a macro that creates a unique class key for each driver. Note that this has the slight disadvantage of adding a key for each driver registered with the system. However, these keys are 8 bytes in size, which is negligible and a small price to pay for generic infrastructure. Suggested-by: Grygorii Strashko Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib.c | 41 ++++++++++++----------------------------- include/linux/gpio/driver.h | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 35fb13e98d84..f227a2af2314 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -72,7 +72,8 @@ static LIST_HEAD(gpio_lookup_list); LIST_HEAD(gpio_devices); static void gpiochip_free_hogs(struct gpio_chip *chip); -static int gpiochip_add_irqchip(struct gpio_chip *gpiochip); +static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, + struct lock_class_key *key); static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip); static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip); @@ -1098,30 +1099,8 @@ static void gpiochip_setup_devs(void) } } -/** - * gpiochip_add_data() - register a gpio_chip - * @chip: the chip to register, with chip->base initialized - * @data: driver-private data associated with this chip - * - * Context: potentially before irqs will work - * - * When gpiochip_add_data() is called very early during boot, so that GPIOs - * can be freely used, the chip->parent device must be registered before - * the gpio framework's arch_initcall(). Otherwise sysfs initialization - * for GPIOs will fail rudely. - * - * gpiochip_add_data() must only be called after gpiolib initialization, - * ie after core_initcall(). - * - * If chip->base is negative, this requests dynamic assignment of - * a range of valid GPIOs. - * - * Returns: - * A negative errno if the chip can't be registered, such as because the - * chip->base is invalid or already associated with a different chip. - * Otherwise it returns zero as a success code. - */ -int gpiochip_add_data(struct gpio_chip *chip, void *data) +int __gpiochip_add_data(struct gpio_chip *chip, void *data, + struct lock_class_key *key) { unsigned long flags; int status = 0; @@ -1267,7 +1246,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) if (status) goto err_remove_from_list; - status = gpiochip_add_irqchip(chip); + status = gpiochip_add_irqchip(chip, key); if (status) goto err_remove_chip; @@ -1314,7 +1293,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) kfree(gdev); return status; } -EXPORT_SYMBOL_GPL(gpiochip_add_data); +EXPORT_SYMBOL_GPL(__gpiochip_add_data); /** * gpiochip_get_data() - get per-subdriver data for the chip @@ -1733,8 +1712,10 @@ static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) /** * gpiochip_add_irqchip() - adds an IRQ chip to a GPIO chip * @gpiochip: the GPIO chip to add the IRQ chip to + * @lock_key: lockdep class */ -static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) +static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, + struct lock_class_key *lock_key) { struct irq_chip *irqchip = gpiochip->irq.chip; const struct irq_domain_ops *ops; @@ -1771,6 +1752,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) gpiochip->to_irq = gpiochip_to_irq; gpiochip->irq.default_type = type; + gpiochip->irq.lock_key = lock_key; if (gpiochip->irq.domain_ops) ops = gpiochip->irq.domain_ops; @@ -1957,7 +1939,8 @@ EXPORT_SYMBOL_GPL(gpiochip_irqchip_add_key); #else /* CONFIG_GPIOLIB_IRQCHIP */ -static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip) +static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip, + struct lock_dep_class *lock_key) { return 0; } diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 241af05498f9..a6d1a1931e86 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -322,7 +322,41 @@ extern const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset); /* add/remove chips */ -extern int gpiochip_add_data(struct gpio_chip *chip, void *data); +extern int __gpiochip_add_data(struct gpio_chip *chip, void *data, + struct lock_class_key *lock_key); + +/** + * gpiochip_add_data() - register a gpio_chip + * @chip: the chip to register, with chip->base initialized + * @data: driver-private data associated with this chip + * + * Context: potentially before irqs will work + * + * When gpiochip_add_data() is called very early during boot, so that GPIOs + * can be freely used, the chip->parent device must be registered before + * the gpio framework's arch_initcall(). Otherwise sysfs initialization + * for GPIOs will fail rudely. + * + * gpiochip_add_data() must only be called after gpiolib initialization, + * ie after core_initcall(). + * + * If chip->base is negative, this requests dynamic assignment of + * a range of valid GPIOs. + * + * Returns: + * A negative errno if the chip can't be registered, such as because the + * chip->base is invalid or already associated with a different chip. + * Otherwise it returns zero as a success code. + */ +#ifdef CONFIG_LOCKDEP +#define gpiochip_add_data(chip, data) ({ \ + static struct lock_class_key key; \ + __gpiochip_add_data(chip, data, &key); \ + }) +#else +#define gpiochip_add_data(chip, data) __gpiochip_add_data(chip, data, NULL) +#endif + static inline int gpiochip_add(struct gpio_chip *chip) { return gpiochip_add_data(chip, NULL);