From patchwork Thu Feb 11 10:26:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 61713 Delivered-To: patch@linaro.org Received: by 10.112.43.199 with SMTP id y7csp105175lbl; Thu, 11 Feb 2016 02:26:46 -0800 (PST) X-Received: by 10.66.55.73 with SMTP id q9mr65375611pap.44.1455186405025; Thu, 11 Feb 2016 02:26:45 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 22si7240467pfq.57.2016.02.11.02.26.44; Thu, 11 Feb 2016 02:26:45 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dkim=neutral (body hash did not verify) header.i=@linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750925AbcBKK0n (ORCPT + 4 others); Thu, 11 Feb 2016 05:26:43 -0500 Received: from mail-wm0-f50.google.com ([74.125.82.50]:38384 "EHLO mail-wm0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751374AbcBKK0k (ORCPT ); Thu, 11 Feb 2016 05:26:40 -0500 Received: by mail-wm0-f50.google.com with SMTP id p63so61845004wmp.1 for ; Thu, 11 Feb 2016 02:26:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=q3XkTUHWFakNxfULS+YD82+s2Dx+6XHZceC4qffn6Fk=; b=WACMrD0QEuDI4SOf3oTYwBMPIPFvNkZnDq0XvtNB/yWQy1GWL2OujGFEiKFDx0mBLA EnSx0t4PfCyUVjNGsOg9Oe5dIuhSAPC7vsYit+4+A4Ku1irHaQBJFrFJMM1OVmZp+Pmo 5Zi8nZOaw+7awY8nESVGLVmsfIa0oMsv3VzP0= 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=q3XkTUHWFakNxfULS+YD82+s2Dx+6XHZceC4qffn6Fk=; b=Wizs78oYAIeVp2QQmR8A6RxffigZV44N87TsKmk3rBpvCDM2ZBUsLmqzJPgJdnwvEj 2SNm68VdiNjHeVoIjaLidpfq2rfxZ4h2USSWfGKe78UiI6Ibl16Kf6t7Yzh5z3QLKJ4m NTzse1cw8MWjTcKY1oOXK1dm6m93I1dSKdV2AsANYlxvNDkfB2ZixwpvsRsZBLO8TGxU FTLSPk3a2ZNZ6FRgCqqHCvsvkmhUg8htYAFTFpQP+c63cMx+buicUYTb9fXBrgJ5T9tt yujq6FUgcrzmSzI3n8MWY73nCSPP6FgvWk3Tf52thGaV8DPUR0Byx7S9w0s6nQNiLhGd SHvg== X-Gm-Message-State: AG10YOSaBT6qGbeTuvzWM0VywPdbf8r6tXAea0fIISddfH5oWbqIfMK3OLzU4SQk9gX1FsD0 X-Received: by 10.28.186.10 with SMTP id k10mr15673077wmf.99.1455186399292; Thu, 11 Feb 2016 02:26:39 -0800 (PST) Received: from localhost.localdomain ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id jo6sm6856241wjb.48.2016.02.11.02.26.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 11 Feb 2016 02:26:38 -0800 (PST) From: Linus Walleij To: linux-gpio@vger.kernel.org, Alexandre Courbot , Johan Hovold , Michael Welling , Markus Pargmann Cc: Bamvor Jian Zhang , Grant Likely , Linus Walleij Subject: [PATCH 3/6] gpio: move descriptors into gpio_device Date: Thu, 11 Feb 2016 11:26:20 +0100 Message-Id: <1455186383-28004-4-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1455186383-28004-1-git-send-email-linus.walleij@linaro.org> References: <1455186383-28004-1-git-send-email-linus.walleij@linaro.org> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org We need gpio_device to hold the descriptors so that they can be lifecycled with the struct gpio_device held from userspace. Move the descriptor array into gpio_device. Also rename it from "desc" (singularis) to "descs" (pluralis) to reflect the fact that it is an array. Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-sysfs.c | 2 +- drivers/gpio/gpiolib.c | 53 ++++++++++++++++++-------------------------- drivers/gpio/gpiolib.h | 4 +++- include/linux/gpio/driver.h | 2 -- 4 files changed, 26 insertions(+), 35 deletions(-) -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 94ba4bb8b4f8..de65633471af 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -765,7 +765,7 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev) /* unregister gpiod class devices owned by sysfs */ for (i = 0; i < chip->ngpio; i++) { - desc = &chip->desc[i]; + desc = &chip->gpiodev->descs[i]; if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) gpiod_free(desc); } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5763290f777c..f3fcd415a77b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -88,7 +88,7 @@ struct gpio_desc *gpio_to_desc(unsigned gpio) if (gdev->chip->base <= gpio && gdev->chip->base + gdev->chip->ngpio > gpio) { spin_unlock_irqrestore(&gpio_lock, flags); - return &gdev->chip->desc[gpio - gdev->chip->base]; + return &gdev->descs[gpio - gdev->chip->base]; } } @@ -110,7 +110,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, if (hwnum >= chip->ngpio) return ERR_PTR(-EINVAL); - return &chip->desc[hwnum]; + return &chip->gpiodev->descs[hwnum]; } /** @@ -120,7 +120,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, */ int desc_to_gpio(const struct gpio_desc *desc) { - return desc->chip->base + (desc - &desc->chip->desc[0]); + return desc->chip->base + (desc - &desc->chip->gpiodev->descs[0]); } EXPORT_SYMBOL_GPL(desc_to_gpio); @@ -277,7 +277,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name) int i; for (i = 0; i != gdev->chip->ngpio; ++i) { - struct gpio_desc *gpio = &gdev->chip->desc[i]; + struct gpio_desc *gpio = &gdev->descs[i]; if (!gpio->name || !name) continue; @@ -320,7 +320,7 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc) /* Then add all names to the GPIO descriptors */ for (i = 0; i != gc->ngpio; ++i) - gc->desc[i].name = gc->names[i]; + gc->gpiodev->descs[i].name = gc->names[i]; return 0; } @@ -431,7 +431,6 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) int status = 0; unsigned i; int base = chip->base; - struct gpio_desc *descs; struct gpio_device *gdev; /* @@ -470,9 +469,9 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) else gdev->owner = THIS_MODULE; - /* FIXME: devm_kcalloc() these and move to gpio_device */ - descs = kcalloc(chip->ngpio, sizeof(descs[0]), GFP_KERNEL); - if (!descs) { + gdev->descs = devm_kcalloc(&gdev->dev, chip->ngpio, + sizeof(gdev->descs[0]), GFP_KERNEL); + if (!gdev->descs) { status = -ENOMEM; goto err_free_gdev; } @@ -483,7 +482,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) if (chip->ngpio == 0) { chip_err(chip, "tried to insert a GPIO chip with zero lines\n"); status = -EINVAL; - goto err_free_descs; + goto err_free_gdev; } spin_lock_irqsave(&gpio_lock, flags); @@ -493,7 +492,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) if (base < 0) { status = base; spin_unlock_irqrestore(&gpio_lock, flags); - goto err_free_descs; + goto err_free_gdev; } chip->base = base; } @@ -501,11 +500,11 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) status = gpiodev_add_to_list(gdev); if (status) { spin_unlock_irqrestore(&gpio_lock, flags); - goto err_free_descs; + goto err_free_gdev; } for (i = 0; i < chip->ngpio; i++) { - struct gpio_desc *desc = &descs[i]; + struct gpio_desc *desc = &gdev->descs[i]; /* REVISIT: maybe a pointer to gpio_device is better */ desc->chip = chip; @@ -518,7 +517,6 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) */ desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0; } - chip->desc = descs; spin_unlock_irqrestore(&gpio_lock, flags); @@ -583,9 +581,6 @@ err_remove_from_list: spin_lock_irqsave(&gpio_lock, flags); list_del(&gdev->list); spin_unlock_irqrestore(&gpio_lock, flags); - chip->desc = NULL; -err_free_descs: - kfree(descs); err_free_gdev: ida_simple_remove(&gpio_ida, gdev->id); kfree(gdev); @@ -608,7 +603,7 @@ void gpiochip_remove(struct gpio_chip *chip) struct gpio_device *gdev = chip->gpiodev; struct gpio_desc *desc; unsigned long flags; - unsigned id; + unsigned i; bool requested = false; /* Numb the device, cancelling all outstanding operations */ @@ -623,8 +618,8 @@ void gpiochip_remove(struct gpio_chip *chip) of_gpiochip_remove(chip); spin_lock_irqsave(&gpio_lock, flags); - for (id = 0; id < chip->ngpio; id++) { - desc = &chip->desc[id]; + for (i = 0; i < chip->ngpio; i++) { + desc = &gdev->descs[i]; desc->chip = NULL; if (test_bit(FLAG_REQUESTED, &desc->flags)) requested = true; @@ -635,10 +630,6 @@ void gpiochip_remove(struct gpio_chip *chip) dev_crit(&chip->gpiodev->dev, "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); - /* FIXME: need to be moved to gpio_device and held there */ - kfree(chip->desc); - chip->desc = NULL; - /* * The gpiochip side puts its use of the device to rest here: * if there are no userspace clients, the chardev and device will @@ -1250,7 +1241,7 @@ const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) if (offset >= chip->ngpio) return NULL; - desc = &chip->desc[offset]; + desc = &chip->gpiodev->descs[offset]; if (test_bit(FLAG_REQUESTED, &desc->flags) == 0) return NULL; @@ -1837,14 +1828,14 @@ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) if (offset >= chip->ngpio) return -EINVAL; - if (test_bit(FLAG_IS_OUT, &chip->desc[offset].flags)) { + if (test_bit(FLAG_IS_OUT, &chip->gpiodev->descs[offset].flags)) { chip_err(chip, "%s: tried to flag a GPIO set as output for IRQ\n", __func__); return -EIO; } - set_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); + set_bit(FLAG_USED_AS_IRQ, &chip->gpiodev->descs[offset].flags); return 0; } EXPORT_SYMBOL_GPL(gpiochip_lock_as_irq); @@ -1862,7 +1853,7 @@ void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) if (offset >= chip->ngpio) return; - clear_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); + clear_bit(FLAG_USED_AS_IRQ, &chip->gpiodev->descs[offset].flags); } EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq); @@ -2549,8 +2540,8 @@ static void gpiochip_free_hogs(struct gpio_chip *chip) int id; for (id = 0; id < chip->ngpio; id++) { - if (test_bit(FLAG_IS_HOGGED, &chip->desc[id].flags)) - gpiochip_free_own_desc(&chip->desc[id]); + if (test_bit(FLAG_IS_HOGGED, &chip->gpiodev->descs[id].flags)) + gpiochip_free_own_desc(&chip->gpiodev->descs[id]); } } @@ -2673,7 +2664,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) { unsigned i; unsigned gpio = chip->base; - struct gpio_desc *gdesc = &chip->desc[0]; + struct gpio_desc *gdesc = &chip->gpiodev->descs[0]; int is_out; int is_irq; diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index c5a5b57463c7..39b8301c98b6 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -32,6 +32,7 @@ struct acpi_device; * @owner: helps prevent removal of modules exporting active GPIOs * @chip: pointer to the corresponding gpiochip, holding static * data for this device + * @descs: array of ngpio descriptors. * @list: links gpio_device:s together for traversal * * This state container holds most of the runtime variable data @@ -46,6 +47,7 @@ struct gpio_device { struct device *mockdev; struct module *owner; struct gpio_chip *chip; + struct gpio_desc *descs; struct list_head list; }; @@ -152,7 +154,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name, */ static int __maybe_unused gpio_chip_hwgpio(const struct gpio_desc *desc) { - return desc - &desc->chip->desc[0]; + return desc - &desc->chip->gpiodev->descs[0]; } /* With descriptor prefix */ diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 4db64ab534ef..bfc842c2fc57 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -52,7 +52,6 @@ struct gpio_device; * get rid of the static GPIO number space in the long run. * @ngpio: the number of GPIOs handled by this controller; the last GPIO * handled is (base + ngpio - 1). - * @desc: array of ngpio descriptors. Private. * @names: if set, must be an array of strings to use as alternative * names for the GPIOs in this chip. Any entry in the array * may be NULL if there is no alias for the GPIO, however the @@ -140,7 +139,6 @@ struct gpio_chip { struct gpio_chip *chip); int base; u16 ngpio; - struct gpio_desc *desc; const char *const *names; bool can_sleep; bool irq_not_threaded;