From patchwork Sun Sep 3 19:17:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 719905 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33983C83F2D for ; Sun, 3 Sep 2023 19:17:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346818AbjICTR7 (ORCPT ); Sun, 3 Sep 2023 15:17:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35714 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236403AbjICTR7 (ORCPT ); Sun, 3 Sep 2023 15:17:59 -0400 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1183494 for ; Sun, 3 Sep 2023 12:17:56 -0700 (PDT) Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-401187f8071so4646145e9.0 for ; Sun, 03 Sep 2023 12:17:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1693768674; x=1694373474; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=/RBewlV8Y3c6D5oogGIYUYf4bPTuckmkgGp46yjrg5k=; b=uXaBb4ETW7LpgKv6VNU9DQ7xudR7+FSPuiesvnZ+XlIMf6KerYCqWTnnB62sFKHuV/ DgM5VsNfyCGSC8eU+DsfpEautCew4ZiRo/AeM3MQaTZfXysQsVBCoSB4XXMFO6SHYYv6 3PgPElf4WOktYOQ591KuN/3ccAwDrWBcUb6CaINN/rRq8EfNHxM1CP/hQ1WRwYzCTNQ/ 2jID2lEUxwiafZ0bHNjsv53tgOpib0zinxQwwWBaA+xN1qwf8k9TOu2LgsotgWjN7ECH O0cLO/SDlPWYWKrO+QIBgud8GZQnhfzZT4WljV/TTzIiltPEqHdLw7+R4u15u0PMM8DF 4XoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693768674; x=1694373474; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=/RBewlV8Y3c6D5oogGIYUYf4bPTuckmkgGp46yjrg5k=; b=S0U32bgI7obz1AwF8YAcCw+jJHVuU3K/Ui3HDhJqHcuMLTo7PsRlRGyD2TRyDqnIHY WfFmpRNgHhHu8ld2ZPs0G1IjmEPg/66AgfoMZBHIntZczmzEinsAs1pWGniIvpFXkVHW Yeh2vXaxAxrcQYDgaLXM+S3fGDezqUkFSVjg8BvTBxJBqcyb0SwIVcDfAH8aRcy4JD+I 6HWBHU5wGRkz/Y+La/3VrBHJ7STXE3bWR+Kep8CefxEpm0V36VOmTcnrtKsyV5ucnGY1 mxy0yZaugcpFyroIL6wc0Pe69IbI3faI5rwTZNJ/yxUkjpeosAVbXfu22JJWFAv6fkb4 wHZQ== X-Gm-Message-State: AOJu0YzTXOcS6jlWAK32i9TVwhQ3lEnP1Q3khEucxbGR7z7yhxPRPKgX jxtwujumbj3TMt04PaVY8GJOiA== X-Google-Smtp-Source: AGHT+IGbzmNX0V2BeY9RKGQICBQ4uxCHs/dWhNbpz842xXIAzUH/nOFiEPWZOuHbOeGVb01RCP2l0Q== X-Received: by 2002:a05:600c:2286:b0:401:b3a5:ec04 with SMTP id 6-20020a05600c228600b00401b3a5ec04mr6132584wmf.16.1693768674204; Sun, 03 Sep 2023 12:17:54 -0700 (PDT) Received: from brgl-uxlite.home ([2a01:cb1d:334:ac00:3591:d7b7:f0c6:6e52]) by smtp.gmail.com with ESMTPSA id c10-20020a05600c0aca00b003fc0505be19sm11846149wmr.37.2023.09.03.12.17.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Sep 2023 12:17:53 -0700 (PDT) From: Bartosz Golaszewski To: Linus Walleij , Andy Shevchenko , Kent Gibson Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [PATCH v2] gpio: sim: don't fiddle with GPIOLIB private members Date: Sun, 3 Sep 2023 21:17:48 +0200 Message-Id: <20230903191748.12535-1-brgl@bgdev.pl> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Bartosz Golaszewski We access internals of struct gpio_device and struct gpio_desc because it's easier but it can actually be avoided and we're working towards a better encapsulation of GPIO data structures across the kernel so let's start at home. Instead of checking gpio_desc flags, let's just track the requests of GPIOs in the driver. We also already store the information about direction of simulated lines. For kobjects needed by sysfs callbacks: we can leverage the fact that once created for a software node, struct device is accessible from that fwnode_handle. We don't need to dereference gpio_device. While at it: fix one line break and remove the untrue part about configfs callbacks using dev_get_drvdata() from a comment. Signed-off-by: Bartosz Golaszewski --- v1 -> v2: - use get_dev_from_fwnode() instead of dereferencing fwnode directly drivers/gpio/gpio-sim.c | 65 +++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c index 271db3639a78..7796249f9058 100644 --- a/drivers/gpio/gpio-sim.c +++ b/drivers/gpio/gpio-sim.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -30,8 +31,6 @@ #include #include -#include "gpiolib.h" - #define GPIO_SIM_NGPIO_MAX 1024 #define GPIO_SIM_PROP_MAX 4 /* Max 3 properties + sentinel. */ #define GPIO_SIM_NUM_ATTRS 3 /* value, pull and sentinel */ @@ -40,6 +39,8 @@ static DEFINE_IDA(gpio_sim_ida); struct gpio_sim_chip { struct gpio_chip gc; + struct device *dev; + unsigned long *request_map; unsigned long *direction_map; unsigned long *value_map; unsigned long *pull_map; @@ -63,16 +64,11 @@ static int gpio_sim_apply_pull(struct gpio_sim_chip *chip, unsigned int offset, int value) { int irq, irq_type, ret; - struct gpio_desc *desc; - struct gpio_chip *gc; - - gc = &chip->gc; - desc = &gc->gpiodev->descs[offset]; guard(mutex)(&chip->lock); - if (test_bit(FLAG_REQUESTED, &desc->flags) && - !test_bit(FLAG_IS_OUT, &desc->flags)) { + if (test_bit(offset, chip->request_map) && + test_bit(offset, chip->direction_map)) { if (value == !!test_bit(offset, chip->value_map)) goto set_pull; @@ -99,8 +95,8 @@ static int gpio_sim_apply_pull(struct gpio_sim_chip *chip, set_value: /* Change the value unless we're actively driving the line. */ - if (!test_bit(FLAG_REQUESTED, &desc->flags) || - !test_bit(FLAG_IS_OUT, &desc->flags)) + if (!test_bit(offset, chip->request_map) || + test_bit(offset, chip->direction_map)) __assign_bit(offset, chip->value_map, value); set_pull: @@ -181,7 +177,7 @@ static int gpio_sim_get_direction(struct gpio_chip *gc, unsigned int offset) } static int gpio_sim_set_config(struct gpio_chip *gc, - unsigned int offset, unsigned long config) + unsigned int offset, unsigned long config) { struct gpio_sim_chip *chip = gpiochip_get_data(gc); @@ -204,13 +200,25 @@ static int gpio_sim_to_irq(struct gpio_chip *gc, unsigned int offset) return irq_create_mapping(chip->irq_sim, offset); } -static void gpio_sim_free(struct gpio_chip *gc, unsigned int offset) +static int gpio_sim_request(struct gpio_chip *gc, unsigned int offset) { struct gpio_sim_chip *chip = gpiochip_get_data(gc); scoped_guard(mutex, &chip->lock) + __set_bit(offset, chip->request_map); + + return 0; +} + +static void gpio_sim_free(struct gpio_chip *gc, unsigned int offset) +{ + struct gpio_sim_chip *chip = gpiochip_get_data(gc); + + scoped_guard(mutex, &chip->lock) { __assign_bit(offset, chip->value_map, !!test_bit(offset, chip->pull_map)); + __clear_bit(offset, chip->request_map); + } } static ssize_t gpio_sim_sysfs_val_show(struct device *dev, @@ -291,11 +299,18 @@ static void gpio_sim_dispose_mappings(void *data) irq_dispose_mapping(irq_find_mapping(chip->irq_sim, i)); } +static void gpio_sim_put_chip_device(void *data) +{ + struct device *dev = data; + + put_device(dev); +} + static void gpio_sim_sysfs_remove(void *data) { struct gpio_sim_chip *chip = data; - sysfs_remove_groups(&chip->gc.gpiodev->dev.kobj, chip->attr_groups); + sysfs_remove_groups(&chip->dev->kobj, chip->attr_groups); } static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip) @@ -352,8 +367,7 @@ static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip) chip->attr_groups[i] = attr_group; } - ret = sysfs_create_groups(&chip->gc.gpiodev->dev.kobj, - chip->attr_groups); + ret = sysfs_create_groups(&chip->dev->kobj, chip->attr_groups); if (ret) return ret; @@ -387,6 +401,11 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev) if (!chip) return -ENOMEM; + + chip->request_map = devm_bitmap_zalloc(dev, num_lines, GFP_KERNEL); + if (!chip->request_map) + return -ENOMEM; + chip->direction_map = devm_bitmap_alloc(dev, num_lines, GFP_KERNEL); if (!chip->direction_map) return -ENOMEM; @@ -432,6 +451,7 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev) gc->get_direction = gpio_sim_get_direction; gc->set_config = gpio_sim_set_config; gc->to_irq = gpio_sim_to_irq; + gc->request = gpio_sim_request; gc->free = gpio_sim_free; gc->can_sleep = true; @@ -439,8 +459,17 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev) if (ret) return ret; - /* Used by sysfs and configfs callbacks. */ - dev_set_drvdata(&gc->gpiodev->dev, chip); + chip->dev = get_dev_from_fwnode(swnode); + if (!chip->dev) + return -ENODEV; + + ret = devm_add_action_or_reset(dev, gpio_sim_put_chip_device, + chip->dev); + if (ret) + return ret; + + /* Used by sysfs callbacks. */ + dev_set_drvdata(chip->dev, chip); return gpio_sim_setup_sysfs(chip); }