linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: sudeep.holla@arm.com, cristian.marussi@arm.com,
	robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org,
	conor+dt@kernel.org, Oleksii_Moisieiev@epam.com,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org
Subject: Re: [RFC 3/4] gpio: scmi: add SCMI pinctrl based gpio driver
Date: Thu, 5 Oct 2023 11:42:47 +0900	[thread overview]
Message-ID: <ZR4ipzoAU7lv/zv4@octopus> (raw)
In-Reply-To: <CACRpkdY=5hYONDcXW4omcX7=r-JtH=AvOSVMkj72LKiaF_wJuA@mail.gmail.com>

Hi Linus,

On Wed, Oct 04, 2023 at 10:35:05AM +0200, Linus Walleij wrote:
> Hi Takahiro,
> 
> I see you are on track with this!
> 
> Some clarifications:
> 
> On Wed, Oct 4, 2023 at 8:53???AM AKASHI Takahiro
> <takahiro.akashi@linaro.org> wrote:
> 
> > I'm still not sure whether my approach can be applied to any other
> > pinctrl-based gpio drivers, in which extra (driver-specific) operations
> > might be needed around the generic pinctrl_gpio helpers (i.e. gpiolib.c).
> > For instance, look at gpio-tegra.c:
> 
> Yeah, it kind of requires a "pure" pin controller underneath that don't
> want to do anything else on any operations, otherwise we are back
> to a per-soc pin control driver.
> 
> But I think it is appropriate for abstractions that strive to provide
> "total abstraction behind a firmware", so such as SCMI or ACPI (heh).

Right. So we are on the same page now.

> > > Skip this, let's use device properties instead. They will anyways just translate
> > > to OF properties in the OF case.
> >
> > Okay, I don't know how device properties work, though.
> 
> They are pretty much 1-to-1 slot-ins for the corresponding of_*
> functions, passing struct device * instead of struct device_node *,
> if you look in include/linux/property.h you will feel at home very
> quickly.
> 
> > > > +static int scmi_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
> > >
> > > Rename all functions pinctrl_gpio_*
> >
> > Well, this change will result in name conflicts against existing
> > pinctrl_gpio_direction_[in|out]out(). So use "pin_control_gpio_" prefix.
> 
> Yeah that works, or pincontro_by_gpio_ or such.

I will use "pin_control_gpio_", which still sounds confusing though.
Please modify it if you don't like.

> > Not sure how the last case (in_en && out_en && DRIVE_OPEN_DRAIN) works.
> 
> I wrote some documentation! But it is hidden deep in the docs:
> https://docs.kernel.org/driver-api/gpio/driver.html#gpio-lines-with-open-drain-source-support
> 
> > In order to be able to read a value as an input pin, I think, we need
> > to set the output status to Hi-Z. Then we should recognize it as "INPUT"?
> > In this case, however, we cannot distinguish the other case where we want
> > to use the pin as OUTPUT and drive it to (active) high.
> 
> With open drain, on GPIO controllers that do not support a native
> open drain mode, we emulate open drain output high by switching
> the line into input mode. The line in this case has a pull-up resistor
> (internal or external) and as input mode is high-Z the pull up resistor
> will pull the signal high, to any level - could be e.g 48V which is
> helpful for some serial links.

I now think I see what you meant here, but still not sure why we need to
assert CONFIG_INPUT and CONFIG_OUT at the same time from API viewpoint.

Anyhow, I will follow the logic that you suggested.

> But this case is really tricky so it can be hard to get things right,
> I get a bit confused and so we need to think about it a few times.
> 
> > > > +static void scmi_gpio_set(struct gpio_chip *chip, unsigned int offset, int val)
> > >
> > > static int?
> >
> > Unfortunately, the function prototype of "set" in struct gpio_device is
> >         void (*set)(struct gpio_chip *gc, unsigned int offset, int value);
> >
> > So we cannot propagate an error to the caller.
> 
> Grrr that must be my fault. Sorry about not fixing this :(
> 
> > > No need to add & 0x01, the gpiolib core already does this.
> >
> > Which part of gpiolib core?
> 
> chip->set = scmi_gpio_set; gets called like this in gpiolib:
> 
>  gpiod_direction_output_raw_commit(..., int value)
> {
>     int val = !!value;
> (...)
>     gc->set(gc, gpio_chip_hwgpio(desc), val);
> 
> Notice clamping int val = !!value; will make the passed val 0 or 1.

Yeah.

> > > > +static u16 sum_up_ngpios(struct gpio_chip *chip)
> > > > +{
> > > > +       struct gpio_pin_range *range;
> > > > +       struct gpio_device *gdev = chip->gpiodev;
> > > > +       u16 ngpios = 0;
> > > > +
> > > > +       list_for_each_entry(range, &gdev->pin_ranges, node) {
> > > > +               ngpios += range->range.npins;
> > > > +       }
> > >
> > > This works but isn't really the intended use case of the ranges.
> > > Feel a bit uncertain about it, but I can't think of anything better.
> > > And I guess these come directly out of SCMI so it's first hand
> > > information about all GPIOs.
> >
> > I don't get your point.
> > However many pins SCMI firmware (or other normal pin controllers) might
> > expose, the total number of pins available by this driver is limited by
> > "gpio-ranges" property.
> > So the sum as "ngpios" should make sense unless a user accidentally
> > specifies a wrong range of pins.
> 
> Yes.
> 
> And it is this fact that the same number need to appear in two places
> and double-specification will sooner or later bring us to the situation
> where the two do not agree, and what do we do then?
> 
> If the ranges come from firmware, which is subject to change such
> as "oops we forgot this pin", the GPIO number will just insert itself
> among the already existing ones: say we have two ranges:
> 
> 1: 0..5
> 2: 6..9
> 
> Ooops forgot a GPIO in the first range, it has to be bumped to
> 0..6.
> 
> But somewhere in the device tree there is:
> 
> foo-gpios = <&scmi_gpio 7 GPIO_OUT_LOW>;
> 
> So now this is wrong (need to be changed to 8) and we have zero tooling
> to detect this, the author just has to be very careful all the time.

Well, even without a change by an user, this kind of human error
may happen. There is no way to verify the correct *pin number*,
say, if I specify 100 instead of 7 in an above example.

> But I honestly do not know any better way.

One good practice to mitigate those cases might be to use a (gpio or
gpio-group) name instead of a pin number, or a "virtual" gpio device.

        foo_gpio: gpio@0 {
            compatibles = "pin-control-gpio";

            gpio-range = <&scmi_pinctrl 0 0 0>;
            gpio-range-group-name = "pins_for_foo";
        }
        baa_gpio: gpio@1 {
            compatibles = "pin-control-gpio";

            gpio-range = <&scmi_pinctrl 0 0 0>;
            gpio-range-group-name = "pins_for_baa";
        }

# Not sure multiple "pin-control-gpio" devices are possible.

-Takahiro Akashi

> > > which in turn becomes just pinctrl_gpio_set_config(), which
> > > is what we want.
> > >
> > > The second cell in two-cell GPIOs already supports passing
> > > GPIO_PUSH_PULL, GPIO_OPEN_DRAIN, GPIO_OPEN_SOURCE,
> > > GPIO_PULL_UP, GPIO_PULL_DOWN, GPIO_PULL_DISABLE,
> > > which you can this way trivially pass down to the pin control driver.
> > >
> > > NB: make sure the scmi pin control driver returns error for
> > > unknown configs.
> >
> > Well, the error will be determined by SCMI firmware(server)
> > not the driver itself :)
> 
> Hehe, I think it is good that the SCMI firmware gets some exercise
> from day 1!
> 
> Yours,
> Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2023-10-05  2:43 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-02  2:15 [RFC 0/4] gpio: add SCMI pinctrl based driver AKASHI Takahiro
2023-10-02  2:15 ` [RFC 1/4] pinctrl: define PIN_CONFIG_INPUT AKASHI Takahiro
2023-10-03 20:49   ` Linus Walleij
2023-10-04  6:54     ` AKASHI Takahiro
2023-10-02  2:16 ` [RFC 2/4] pinctrl: add pinctrl_gpio_get_config() AKASHI Takahiro
2023-10-03 20:52   ` Linus Walleij
2023-10-02  2:16 ` [RFC 3/4] gpio: scmi: add SCMI pinctrl based gpio driver AKASHI Takahiro
2023-10-03 21:35   ` Linus Walleij
2023-10-04  6:53     ` AKASHI Takahiro
2023-10-04  8:35       ` Linus Walleij
2023-10-05  2:42         ` AKASHI Takahiro [this message]
2023-10-02  2:16 ` [RFC 4/4] dt-bindings: gpio: Add bindings for SCMI pinctrl based gpio AKASHI Takahiro
2023-10-02  3:25   ` Rob Herring
2023-10-02 14:41   ` Rob Herring
2023-10-02 14:58     ` Cristian Marussi
2023-10-03  1:34       ` AKASHI Takahiro
2023-10-03  0:41     ` AKASHI Takahiro
2023-10-03  8:43       ` Krzysztof Kozlowski
2023-10-03 13:16   ` Linus Walleij
2023-10-04  7:08     ` AKASHI Takahiro

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=ZR4ipzoAU7lv/zv4@octopus \
    --to=takahiro.akashi@linaro.org \
    --cc=Oleksii_Moisieiev@epam.com \
    --cc=conor+dt@kernel.org \
    --cc=cristian.marussi@arm.com \
    --cc=devicetree@vger.kernel.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=sudeep.holla@arm.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).