linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Gilles BULOZ <gilles.buloz@kontron.com>
To: Kent Gibson <warthog618@gmail.com>
Cc: Bartosz Golaszewski <brgl@bgdev.pl>, linux-gpio@vger.kernel.org
Subject: Re: [questions] : gpiolib and gpioset behaviour
Date: Fri, 26 Apr 2024 18:16:28 +0200	[thread overview]
Message-ID: <7a0b23d9-1a4c-337c-dda4-b6935e563ff0@kontron.com> (raw)
In-Reply-To: <20240426133751.GA380503@rigel>

On Fri, Apr 26, 2024 at 03:37 PM, Kent Gibson wrote :
> On Fri, Apr 26, 2024 at 03:08:33PM +0200, Gilles BULOZ wrote:
>> On Fri, Apr 26, 2024 at 04:07 AM, Kent Gibson wrote :
>>> On Mon, Apr 22, 2024 at 06:49:05PM +0200, Gilles BULOZ wrote:
>>>> On Mon, Apr 22, 2024 at 3:55 PM Bartosz Golaszewski wrote :
>>>>> On Mon, Apr 22, 2024 at 2:44 PM Gilles BULOZ <gilles.buloz@kontron.com> wrote:
>>>>>>
>
>>>>
>>>
>>> I suspect you are referring to gpiolib here - the mask in gc->get_multiple()
>>> being unsigned long*.
>>>
>>> The uAPI that libgpiod uses is limited to 64 lines per request, but that is
>>> only relevant if you want to request more than 64 lines at once from userspace
>>> (you would have to break that into two requests to access all 112 lines).
>>>
>>> Note that the mask in gc->get_multiple() is unsigned long*, so it is a
>>> pointer to an array of unsigned long.  Its width is not limited by
>>> unsigned long, but by the bits parameter.  In your case the mask you pass
>>> should contain multiple unsigned longs to achieve 112 bits.
>>> Refer to gpiod_get_array_value_complex() for an example of building bitmap
>>> masks to pass to gc->get_multiple(), in that case via
>>> gpio_chip_get_multiple().
>>>
>>
>> I was refering the get_multiple/set_multiple callbacks in struct gpio_chip
>> that are defined like this :
>>  int (*get_multiple)(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits);
>>  void (*set_multiple)(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits);
>> With some debug in my GPIO chip driver implementing these functions, I saw that
>> the bits set in "mask" and the ones used in "bits" are the ones whose bit
>> numbers are directly matching the GPIO offset/line numbers of the chip. But I
>> only used unsigned long, not arrays, so I thought I was limited to offset/line
>> 31 on 32bit arch, and 63 on 64bit arch.
>> As you suggested, I'm currently having a look to gpiod_get_array_value_complex()
>> but I must admit I'm currently a little bit lost. I've never thought GPIO
>> implementation could become so complex for my brain :-)
>>
>
> The bit of primary interest that I was referring to was the DECLARE_BITMAP()
> as used for the fastpath mask:
>
>                 DECLARE_BITMAP(fastpath_mask, FASTPATH_NGPIO);
>
> That does the sizing math for you.  In your case you would use 112 for
> the NGPIO.  There are also examples of using __set_bit() to set bits in
> the mask.  Take a look in linux/bitmaps.h and linux/bitops.h for the
> relevant definitions if you want to dig deeper.
>
> And, yeah, the amount of work that goes into just driving physical
> lines up and down, fundamentally just toggling bits, frequently makes my brain
> hurt too ;-).
>

Thanks very much for the tips !
I've added some debug in my GPIO chip driver in get_multiple()/set_multiple()
and clearly see that when using an unsigned long array for "mask" and "bits",
the second unsigned long in array is used starting from GPIO offset/line 64,
starting from bit 0, then 1 for offset/line 65...
For instance when I run "gpioget 0 65", get_multiple() is called with bit 1 of
mask[1] set and I return the level on bit 1 of bits[1] that is correctly
reported by gpioget.

But get_multiple is called by gpio_chip_get_multiple() than is called by
gpiod_get_array_value_complex() that is called either from 
 linehandle_ioctl() for GPIOHANDLE_GET_LINE_VALUES_IOCTL where we have DECLARE_BITMAP(vals, GPIOHANDLES_MAX);
 linereq_get_values() for GPIO_V2_LINE_GET_VALUES_IOCTL  where we have DECLARE_BITMAP(vals, GPIO_V2_LINES_MAX);
so both vals with 64bits (GPIOHANDLES_MAX=GPIO_V2_LINES_MAX=64) so only one unsigned long.
But vals is passed as last argument unsigned long *value_bitmap to
gpiod_get_array_value_complex() that is passed as last argument
unsigned long *bits to gpio_chip_get_multiple() that
is passed as last argument unsigned long *bits to get_multiple() of my driver
where I'm supposed to fill data in the second unsigned logn of array for GPIO
offset/line >= 64 where we have only allocated one.
I'm probably wrong somewhere.

> Cheers,
> Kent.
> .


  reply	other threads:[~2024-04-26 16:16 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-22 12:44 [questions] : gpiolib and gpioset behaviour Gilles BULOZ
2024-04-22 15:55 ` Bartosz Golaszewski
2024-04-22 16:49   ` Gilles BULOZ
2024-04-22 18:04     ` Bartosz Golaszewski
2024-04-26  2:07     ` Kent Gibson
2024-04-26 13:08       ` Gilles BULOZ
2024-04-26 13:37         ` Kent Gibson
2024-04-26 16:16           ` Gilles BULOZ [this message]
2024-04-27  0:23             ` Kent Gibson
2024-04-27 12:09       ` Kent Gibson
2024-04-29  8:50         ` Gilles BULOZ

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7a0b23d9-1a4c-337c-dda4-b6935e563ff0@kontron.com \
    --to=gilles.buloz@kontron.com \
    --cc=brgl@bgdev.pl \
    --cc=linux-gpio@vger.kernel.org \
    --cc=warthog618@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).