lkml.org 
[lkml]   [2018]   [Aug]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH v2 09/12] gpiolib: Identify GPIO descriptor arrays with direct mapping
    Date
    Certain GPIO array lookup results may map directly to GPIO pins of a
    single GPIO chip in hardware order. If that condition is recognized
    and handled efficiently, significant performance gain of get/set array
    functions may be possible.

    While processing a request for an array of GPIO descriptors, verify if
    the descriptors just collected represent consecutive pins of a single
    GPIO chip. Pass that information with the array to the caller so it
    can benefit from enhanced performance as soon as bitmap based get/set
    array functions which can make efficient use of that are available.

    Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
    ---
    Documentation/driver-api/gpio/consumer.rst | 4 +++-
    drivers/gpio/gpiolib.c | 14 ++++++++++++++
    include/linux/gpio/consumer.h | 1 +
    3 files changed, 18 insertions(+), 1 deletion(-)

    diff --git a/Documentation/driver-api/gpio/consumer.rst b/Documentation/driver-api/gpio/consumer.rst
    index aa03f389d41d..38a990b5f3b6 100644
    --- a/Documentation/driver-api/gpio/consumer.rst
    +++ b/Documentation/driver-api/gpio/consumer.rst
    @@ -109,11 +109,13 @@ For a function using multiple GPIOs all of those can be obtained with one call::
    enum gpiod_flags flags)

    This function returns a struct gpio_descs which contains an array of
    -descriptors::
    +descriptors. It may also contain a valid descriptor of a single GPIO chip in
    +case the array strictly matches pin hardware layout of the chip::

    struct gpio_descs {
    unsigned int ndescs;
    struct gpio_desc *desc[];
    + struct gpio_chip *chip;
    }

    The following function returns NULL instead of -ENOENT if no GPIOs have been
    diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
    index bdbfc95793e7..c50bcec6e2d7 100644
    --- a/drivers/gpio/gpiolib.c
    +++ b/drivers/gpio/gpiolib.c
    @@ -4161,6 +4161,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
    {
    struct gpio_desc *desc;
    struct gpio_descs *descs;
    + struct gpio_chip *chip;
    int count;

    count = gpiod_count(dev, con_id);
    @@ -4177,6 +4178,19 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
    gpiod_put_array(descs);
    return ERR_CAST(desc);
    }
    +
    + /*
    + * Verify if the array qualifies for fast bitmap operations
    + * (single chip, pins in hardware order starting from 0)
    + * and mark the array with the chip descriptor if true.
    + */
    + chip = gpiod_to_chip(desc);
    + if (descs->chip == NULL)
    + descs->chip = chip;
    + if (!IS_ERR(descs->chip) && (chip != descs->chip ||
    + gpio_chip_hwgpio(desc) != descs->ndescs))
    + descs->chip = ERR_PTR(-EINVAL);
    +
    descs->desc[descs->ndescs] = desc;
    descs->ndescs++;
    }
    diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
    index 21ddbe440030..862ee027a02f 100644
    --- a/include/linux/gpio/consumer.h
    +++ b/include/linux/gpio/consumer.h
    @@ -22,6 +22,7 @@ struct gpio_desc;
    * gpiod_get_array().
    */
    struct gpio_descs {
    + struct gpio_chip *chip;
    unsigned int ndescs;
    struct gpio_desc *desc[];
    };
    --
    2.16.4
    \
     
     \ /
      Last update: 2018-08-07 00:31    [W:2.285 / U:0.172 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site