mbox series

[v2,0/5] ARM: Add GPIO support

Message ID 20230531151918.105223-1-nick.hawkins@hpe.com
Headers show
Series ARM: Add GPIO support | expand

Message

Hawkins, Nick May 31, 2023, 3:19 p.m. UTC
From: Nick Hawkins <nick.hawkins@hpe.com>

Note: The previous version of this patchset was titled "Add GPIO and PSU
support". Based on feedback and in an effort to reduce size PSU has been
removed. Link:
https://lore.kernel.org/all/20230418152824.110823-1-nick.hawkins@hpe.com/

The GXP SoC supports GPIO on multiple interfaces. The interfaces are
CPLD and Host. The GPIOs is a combination of both physical and virtual
I/O across the interfaces. The gpio-gxp driver specifically covers the
CSM(physical), FN2(virtual), and VUHC(virtual) which are the host. The
gpio-gxp-pl driver covers the CPLD which takes physical I/O from the
board and shares it with GXP via a propriety interface that maps the I/O
onto a specific register area of the GXP. The drivers both support
interrupts but from different interrupt parents.

There is a need for both the host OpenBMC and the gxp-fan-ctrl driver to
access the same GPIO information from the CPLD. The OpenBMC stack is
reacting to changes in GPIOs and taking action. This requires it to hold
the GPIO which creates a problem where both the host and linux cannot
have the same GPIO. Thus an attempt to remedy this was to add a shared
variable between the GPIO driver and the fan control driver to provide
fan presence and failure information. This is why hwmon has been included
in this patchset.

---

Changes since v1:
 *Removed ARM device tree changes and defconfig changes to reduce
  patchset size
 *Removed GXP PSU changes to reduce patchset size
 *Corrected hpe,gxp-gpio YAML file based on feedback
 *Created new gpio-gxp-pl file to reduce complexity
 *Separated code into two files to keep size down: gpio-gxp.c and
  gpio-gxp-pl.c
 *Fixed Kconfig indentation as well as add new entry for gpio-gxp-pl
 *Removed use of linux/of.h and linux/of_device.h
 *Added mod_devicetable.h and property.h
 *Fixed indentation of defines and uses consistent number of digits
 *Corrected defines with improper GPIO_ namespace.
 *For masks now use BIT()
 *Added comment for PLREG offsets
 *Move gpio_chip to be first in structure
 *Calculate offset for high and low byte GPIO reads instead of having
  H(High) and L(Low) letters added to the variables.
 *Removed repeditive use of "? 1 : 0"
 *Switched to handle_bad_irq()
 *Removed improper bailout on gpiochip_add_data
 *Used GENMASK to arm interrupts
 *Removed use of of_match_device
 *fixed sizeof in devm_kzalloc
 *Added COMPILE_TEST to Kconfig
 *Added dev_err_probe where applicable
 *Removed unecessary parent and compatible checks

Nick Hawkins (5):
  dt-bindings: gpio: Add HPE GXP GPIO
  gpio: gxp: Add HPE GXP GPIO
  dt-bindings: hwmon: hpe,gxp-fanctrl: remove fn2 and pl regs
  hwmon: (gxp_fan_ctrl) Provide fan info via gpio
  MAINTAINERS: hpe: Add GPIO

 .../bindings/gpio/hpe,gxp-gpio.yaml           | 190 ++++++
 .../bindings/hwmon/hpe,gxp-fan-ctrl.yaml      |  16 +-
 MAINTAINERS                                   |   2 +
 drivers/gpio/Kconfig                          |  18 +
 drivers/gpio/Makefile                         |   2 +
 drivers/gpio/gpio-gxp-pl.c                    | 536 +++++++++++++++
 drivers/gpio/gpio-gxp.c                       | 637 ++++++++++++++++++
 drivers/hwmon/Kconfig                         |   2 +-
 drivers/hwmon/gxp-fan-ctrl.c                  |  61 +-
 drivers/hwmon/gxp-gpio.h                      |  13 +
 10 files changed, 1409 insertions(+), 68 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/hpe,gxp-gpio.yaml
 create mode 100644 drivers/gpio/gpio-gxp-pl.c
 create mode 100644 drivers/gpio/gpio-gxp.c
 create mode 100644 drivers/hwmon/gxp-gpio.h

Comments

Krzysztof Kozlowski June 1, 2023, 6:52 a.m. UTC | #1
On 31/05/2023 17:19, nick.hawkins@hpe.com wrote:
> From: Nick Hawkins <nick.hawkins@hpe.com>
> 
> Provide access to the register regions and interrupt for GPIO. There
> will be two drivers available. The first driver under the hpe,gxp-gpio
> binding will provide GPIO information for the VUHC, CSM, and FN2
> host interfaces. The second driver under the hpe,gxp-gpio-pl will
> provide GPIO information from the CPLD interface. The main difference
> and need for two separate bindings is they have different interrupt
> parents. The other is hpe,gxp-gpio is a combination of physical
> and virtual GPIOs where as hpe,gxp-gpio-pl are all physical
> GPIOs from the CPLD.
> 
> Signed-off-by: Nick Hawkins <nick.hawkins@hpe.com>
> 
> ---
> 
> v2:
>  *Put binding patch before the driver in the series
>  *Improved patch description
>  *Removed oneOf and items in compatible definition
>  *Moved additionalProperties definition to correct spot in file
>  *Fixed indentation on example

I don't think it was fixed.

>  *Improved description in .yaml
> ---
>  .../bindings/gpio/hpe,gxp-gpio.yaml           | 190 ++++++++++++++++++
>  1 file changed, 190 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/hpe,gxp-gpio.yaml
> 
> diff --git a/Documentation/devicetree/bindings/gpio/hpe,gxp-gpio.yaml b/Documentation/devicetree/bindings/gpio/hpe,gxp-gpio.yaml
> new file mode 100644
> index 000000000000..b92b7d72d39b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/hpe,gxp-gpio.yaml
> @@ -0,0 +1,190 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/gpio/hpe,gxp-gpio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: HPE GXP gpio controllers
> +
> +maintainers:
> +  - Nick Hawkins <nick.hawkins@hpe.com>
> +
> +description:
> +  Interruptable GPIO drivers for the HPE GXP that covers multiple interfaces
> +  of both physical and virtual GPIO pins.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - hpe,gxp-gpio
> +      - hpe,gxp-gpio-pl
> +
> +  reg:
> +    minItems: 2
> +    maxItems: 6
> +
> +  reg-names:
> +    minItems: 2
> +    maxItems: 6
> +
> +  gpio-controller: true
> +
> +  "#gpio-cells":
> +    const: 2
> +
> +  gpio-line-names:
> +    minItems: 80
> +    maxItems: 300
> +
> +  interrupts:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - gpio-controller
> +  - "#gpio-cells"
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - hpe,gxp-gpio
> +    then:
> +      properties:
> +        reg:
> +          items:
> +            - description: CSM GPIO interface
> +            - description: fn2 virtual button GPIO
> +            - description: fn2 system status GPIO
> +            - description: vuhc GPIO status interface
> +        reg-names:
> +          items:
> +            - const: csm
> +            - const: fn2-vbtn
> +            - const: fn2-stat
> +            - const: vuhc
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - hpe,gxp-gpio-pl
> +    then:
> +      properties:
> +        reg:
> +          items:
> +            - description: Programmable logic device GPIO
> +            - description: Programmable logic device interrupt GPIO
> +        reg-names:
> +          items:
> +            - const: base
> +            - const: interrupt
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    gpio@0 {
> +        compatible = "hpe,gxp-gpio";
> +        reg = <0x0 0x400>, <0x200046 0x1>, <0x200070 0x08>, <0x400064 0x80>;
> +        reg-names = "csm", "fn2-vbtn", "fn2-stat", "vuhc";
> +        gpio-controller;
> +        #gpio-cells = <2>;
> +        interrupt-parent = <&vic0>;
> +        interrupts = <10>;
> +        gpio-line-names = "IOP_LED1", "IOP_LED2",
> +        "IOP_LED3", "IOP_LED4",

Broken indentation. This is aligned with opening " in previous line.

> +        "IOP_LED5", "IOP_LED6",
> +        "IOP_LED7", "IOP_LED8",
> +        "FAN1_INST", "FAN2_INST",
> +        "FAN3_INST", "FAN4_INST",
> +        "FAN5_INST", "FAN6_INST",
> +        "FAN7_INST", "FAN8_INST",
> +        "FAN1_FAIL", "FAN2_FAIL",
> +        "FAN3_FAIL", "FAN4_FAIL",
> +        "FAN5_FAIL", "FAN6_FAIL",
> +        "FAN7_FAIL", "FAN8_FAIL",
> +        "FAN1_ID", "FAN2_ID",
> +        "FAN3_ID", "FAN4_ID",
> +        "FAN5_ID", "FAN6_ID",
> +        "FAN7_ID", "FAN8_ID",
> +        "IDENTIFY", "HEALTH_RED",
> +        "HEALTH_AMBER", "POWER_BUTTON",
> +        "UID_PRESS", "SLP",
> +        "NMI_BUTTON", "RESET_BUTTON",
> +        "SIO_S5", "SO_ON_CONTROL",
> +        "PSU1_INST", "PSU2_INST",
> +        "PSU3_INST", "PSU4_INST",
> +        "PSU5_INST", "PSU6_INST",
> +        "PSU7_INST", "PSU8_INST",
> +        "PSU1_AC", "PSU2_AC",
> +        "PSU3_AC", "PSU4_AC",
> +        "PSU5_AC", "PSU6_AC",
> +        "PSU7_AC", "PSU8_AC",
> +        "PSU1_DC", "PSU2_DC",
> +        "PSU3_DC", "PSU4_DC",
> +        "PSU5_DC", "PSU6_DC",
> +        "PSU7_DC", "PSU8_DC",
> +        "", "",
> +        "", "",
> +        "", "",
> +        "", "",
> +        "", "",
> +        "", "",
> +        "", "";
> +    };
> +
> +  - |
> +    gpio@51000300 {
> +        compatible = "hpe,gxp-gpio-pl";
> +        reg = <0x51000300 0x40>, <0x51000380 0x10>;
> +        reg-names = "base", "interrupt";

One example is enough, because this almost does not differ from previous.

Best regards,
Krzysztof
Hawkins, Nick June 1, 2023, 3:47 p.m. UTC | #2
> If the host wants to own the fan status from gpio pins, it has to live up to
> it and own it entirely. The kernel hwmon driver does not have access in that
> case.

> In a more "normal" world, the hwmon driver would "own" the gpio pin(s)
> and user space would listen to associated hwmon attribute events (presumably
> fan_enable and fan_fault), either by listening for sysfs attribute events
> or via udev or both. Again, if you don't want to do that, and want user space
> to have access to the raw gpio pins, you'll have to live with the consequences.
> I don't see the need to bypass existing mechanisms just because user space
> programmers want direct access to gpio pins.

Greetings Guenter,

Thank you for your valuable feedback with the solutions you have provided.
Before I proceed though I have a quick query about the fan driver.
If I were to let the user space "own" gpio pins, would it be permissible for
the userspace to feed a kernel driver data via sysfs?

Ex:
GPIO Driver -> (OpenBMC) -> Fandriver (sysfs).

Here the GPIO driver would provide fan presence information to OpenBMC
and then OpenBMC would provide fan presence info to the fan driver.

If it were permissible to provide data to the driver via this method I could
apply it to the PSU driver as well. the PSU driver which requires presence
info to verify a PSU is inserted / removed.

Thanks,

-Nick Hawkins
Linus Walleij June 1, 2023, 5:11 p.m. UTC | #3
On Thu, Jun 1, 2023 at 5:48 PM Hawkins, Nick <nick.hawkins@hpe.com> wrote:

> Thank you for your valuable feedback with the solutions you have provided.
> Before I proceed though I have a quick query about the fan driver.
> If I were to let the user space "own" gpio pins, would it be permissible for
> the userspace to feed a kernel driver data via sysfs?
>
> Ex:
> GPIO Driver -> (OpenBMC) -> Fandriver (sysfs).
>
> Here the GPIO driver would provide fan presence information to OpenBMC
> and then OpenBMC would provide fan presence info to the fan driver.

But why? Don't be so obsessed about userspace doing stuff using
sysfs, usually it is a better idea to let the kernel handle hardware.

I think this is a simple thermal zone you can define in the device
tree as indicated in my previous comment.

> If it were permissible to provide data to the driver via this method I could
> apply it to the PSU driver as well. the PSU driver which requires presence
> info to verify a PSU is inserted / removed.

It feels like you are looking for a way for two drivers to communicate
with each other.

This can be done several ways, the most straight-forward is notifiers.
include/linux/notifier.h

Yours,
Linus Walleij
Guenter Roeck June 1, 2023, 5:45 p.m. UTC | #4
On 6/1/23 10:11, Linus Walleij wrote:
> On Thu, Jun 1, 2023 at 5:48 PM Hawkins, Nick <nick.hawkins@hpe.com> wrote:
> 
>> Thank you for your valuable feedback with the solutions you have provided.
>> Before I proceed though I have a quick query about the fan driver.
>> If I were to let the user space "own" gpio pins, would it be permissible for
>> the userspace to feed a kernel driver data via sysfs?
>>
>> Ex:
>> GPIO Driver -> (OpenBMC) -> Fandriver (sysfs).
>>
>> Here the GPIO driver would provide fan presence information to OpenBMC
>> and then OpenBMC would provide fan presence info to the fan driver.
> 
> But why? Don't be so obsessed about userspace doing stuff using
> sysfs, usually it is a better idea to let the kernel handle hardware.
> 
> I think this is a simple thermal zone you can define in the device
> tree as indicated in my previous comment.
> 
>> If it were permissible to provide data to the driver via this method I could
>> apply it to the PSU driver as well. the PSU driver which requires presence
>> info to verify a PSU is inserted / removed.
> 
> It feels like you are looking for a way for two drivers to communicate
> with each other.
> 
> This can be done several ways, the most straight-forward is notifiers.
> include/linux/notifier.h
> 

This is all unnecessary. The hwmon driver could register a gpio pin,
including interrupt, and then report state changes to userspace with
sysfs or udev events on the registered hwmon sysfs attributes.

If they really want to use userspace for everything, they should
just use userspace for everything and not bother with a kernel driver.

Guenter
Hawkins, Nick June 2, 2023, 3:02 p.m. UTC | #5
> > 
> > This can be done several ways, the most straight-forward is notifiers.
> > include/linux/notifier.h
> > 


> This is all unnecessary. The hwmon driver could register a gpio pin,
> including interrupt, and then report state changes to userspace with
> sysfs or udev events on the registered hwmon sysfs attributes.


> If they really want to use userspace for everything, they should
> just use userspace for everything and not bother with a kernel driver.

Greetings Guenter and Linus,

Thank you for your feedback and assistance. I discussed this with my
team and the direction they are leaning is that they want to own the
GPIOs in user space. The fan driver it would still need to be used
to set and read PWMs as they are kernel protected registers. It will
also need to be there to coordinate the proper offset in the GXP
registers to control a particular fans PWM.

For hot pluggable devices such as fans and psu they will need to
bind/unbind the hwmon driver of the device as it is inserted/removed.

Is this an acceptable path forward?

If it is I will revise this patchset once more to make the fan independent
of the GPIO driver.

Thanks again for all the guidance,

-Nick Hawkins