Commit b3c0eccb authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'gpio-updates-for-v6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio updates from Bartosz Golaszewski:
 "The majority of added lines are two new modules: the GPIO virtual
  consumer module that improves our ability to add automated tests for
  the kernel API and the "sloppy" logic analyzer module that uses the
  GPIO API to implement a coarse-grained debugging tool for useful for
  remote development.

  Other than that we have the usual assortment of various driver
  extensions, improvements to the core GPIO code, DT-bindings and other
  documentation updates as well as an extension to the interrupt
  simulator:

  GPIOLIB core:
   - rework kfifo handling rework in the character device code
   - improve the labeling of GPIOs requested as interrupts and show more
     info on interrupt-only GPIOs in debugfs
   - remove unused APIs
   - unexport interfaces that are only used from the core GPIO code
   - drop the return value from gpiochip_set_desc_names() as it cannot
     fail
   - move a string array definition out of a header and into a specific
     compilation unit
   - convert the last user of gpiochip_get_desc() other than GPIO core
     to using a safer alternative
   - use array_index_nospec() where applicable

  New drivers:
   - add a "virtual GPIO consumer" module that allows requesting GPIOs
     from actual hardware and driving tests of the in-kernel GPIO API
     from user-space over debugfs
   - add a GPIO-based "sloppy" logic analyzer module useful for "first
     glance" debugging on remote boards

  Driver improvements:
   - add support for a new model to gpio-pca953x
   - lock GPIOs as interrupts in gpio-sim when the lines are requested
     as irqs via the simulator domain + some other minor improvements
   - improve error reporting in gpio-syscon
   - convert gpio-ath79 to using dynamic GPIO base and range
   - use pcibios_err_to_errno() for converting PCIBIOS error codes to
     errno vaues in gpio-amd8111 and gpio-rdc321x
   - allow building gpio-brcmstb for the BCM2835 architecture

  DT bindings:
   - convert DT bindings for lsi,zevio, mpc8xxx, and atmel to DT schema
   - document new properties for aspeed,gpio, fsl,qoriq-gpio and
     gpio-vf610
   - document new compatibles for pca953x and fsl,qoriq-gpio

  Documentation:
   - document stricter behavior of the GPIO character device uAPI with
     regards to reconfiguring requested line without direction set
   - clarify the effect of the active-low flag on line values and edges
   - remove documentation for the legacy GPIO API in order to stop
     tempting people to use it
   - document the preference for using pread() for reading edge events
     in the sysfs API

  Other:
   - add an extended initializer to the interrupt simulator allowing to
     specify a number of callbacks callers can use to be notified about
     irqs being requested and released"

* tag 'gpio-updates-for-v6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (41 commits)
  gpio: mc33880: Convert comma to semicolon
  gpio: virtuser: actually use the "trimmed" local variable
  dt-bindings: gpio: convert Atmel GPIO to json-schema
  gpio: virtuser: new virtual testing driver for the GPIO API
  dt-bindings: gpio: vf610: Allow gpio-line-names to be set
  gpio: sim: lock GPIOs as interrupts when they are requested
  genirq/irq_sim: add an extended irq_sim initializer
  dt-bindings: gpio: fsl,qoriq-gpio: Add compatible string fsl,ls1046a-gpio
  gpiolib: unexport gpiochip_get_desc()
  gpio: add sloppy logic analyzer using polling
  Documentation: gpio: Reconfiguration with unset direction (uAPI v2)
  Documentation: gpio: Reconfiguration with unset direction (uAPI v1)
  dt-bindings: gpio: fsl,qoriq-gpio: add common property gpio-line-names
  gpio: ath79: convert to dynamic GPIO base allocation
  pinctrl: da9062: replace gpiochip_get_desc() with gpio_device_get_desc()
  gpiolib: put gpio_suffixes in a single compilation unit
  Documentation: gpio: Clarify effect of active low flag on line edges
  Documentation: gpio: Clarify effect of active low flag on line values
  gpiolib: Remove data-less gpiochip_add() function
  gpio: sim: use devm_mutex_init()
  ...
parents 3f32ab14 dfda97e3
Loading
Loading
Loading
Loading
+177 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0-only

Virtual GPIO Consumer
=====================

The virtual GPIO Consumer module allows users to instantiate virtual devices
that request GPIOs and then control their behavior over debugfs. Virtual
consumer devices can be instantiated from device-tree or over configfs.

A virtual consumer uses the driver-facing GPIO APIs and allows to cover it with
automated tests driven by user-space. The GPIOs are requested using
``gpiod_get_array()`` and so we support multiple GPIOs per connector ID.

Creating GPIO consumers
-----------------------

The gpio-consumer module registers a configfs subsystem called
``'gpio-virtuser'``. For details of the configfs filesystem, please refer to
the configfs documentation.

The user can create a hierarchy of configfs groups and items as well as modify
values of exposed attributes. Once the consumer is instantiated, this hierarchy
will be translated to appropriate device properties. The general structure is:

**Group:** ``/config/gpio-virtuser``

This is the top directory of the gpio-consumer configfs tree.

**Group:** ``/config/gpio-consumer/example-name``

**Attribute:** ``/config/gpio-consumer/example-name/live``

**Attribute:** ``/config/gpio-consumer/example-name/dev_name``

This is a directory representing a GPIO consumer device.

The read-only ``dev_name`` attribute exposes the name of the device as it will
appear in the system on the platform bus. This is useful for locating the
associated debugfs directory under
``/sys/kernel/debug/gpio-virtuser/$dev_name``.

The ``'live'`` attribute allows to trigger the actual creation of the device
once it's fully configured. The accepted values are: ``'1'`` to enable the
virtual device and ``'0'`` to disable and tear it down.

Creating GPIO lookup tables
---------------------------

Users can create a number of configfs groups under the device group:

**Group:** ``/config/gpio-consumer/example-name/con_id``

The ``'con_id'`` directory represents a single GPIO lookup and its value maps
to the ``'con_id'`` argument of the ``gpiod_get()`` function. For example:
``con_id`` == ``'reset'`` maps to the ``reset-gpios`` device property.

Users can assign a number of GPIOs to each lookup. Each GPIO is a sub-directory
with a user-defined name under the ``'con_id'`` group.

**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/key``

**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/offset``

**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/drive``

**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/pull``

**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/active_low``

**Attribute:** ``/config/gpio-consumer/example-name/con_id/0/transitory``

This is a group describing a single GPIO in the ``con_id-gpios`` property.

For virtual consumers created using configfs we use machine lookup tables so
this group can be considered as a mapping between the filesystem and the fields
of a single entry in ``'struct gpiod_lookup'``.

The ``'key'`` attribute represents either the name of the chip this GPIO
belongs to or the GPIO line name. This depends on the value of the ``'offset'``
attribute: if its value is >= 0, then ``'key'`` represents the label of the
chip to lookup while ``'offset'`` represents the offset of the line in that
chip. If ``'offset'`` is < 0, then ``'key'`` represents the name of the line.

The remaining attributes map to the ``'flags'`` field of the GPIO lookup
struct. The first two take string values as arguments:

**``'drive'``:** ``'push-pull'``, ``'open-drain'``, ``'open-source'``
**``'pull'``:** ``'pull-up'``, ``'pull-down'``, ``'pull-disabled'``, ``'as-is'``

``'active_low'`` and ``'transitory'`` are boolean attributes.

Activating GPIO consumers
-------------------------

Once the confiuration is complete, the ``'live'`` attribute must be set to 1 in
order to instantiate the consumer. It can be set back to 0 to destroy the
virtual device. The module will synchronously wait for the new simulated device
to be successfully probed and if this doesn't happen, writing to ``'live'`` will
result in an error.

Device-tree
-----------

Virtual GPIO consumers can also be defined in device-tree. The compatible string
must be: ``"gpio-virtuser"`` with at least one property following the
standardized GPIO pattern.

An example device-tree code defining a virtual GPIO consumer:

.. code-block :: none

    gpio-virt-consumer {
        compatible = "gpio-virtuser";

        foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>, <&gpio1 2 0>;
        bar-gpios = <&gpio0 6 0>;
    };

Controlling virtual GPIO consumers
----------------------------------

Once active, the device will export debugfs attributes for controlling GPIO
arrays as well as each requested GPIO line separately. Let's consider the
following device property: ``foo-gpios = <&gpio0 0 0>, <&gpio0 4 0>;``.

The following debugfs attribute groups will be created:

**Group:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/``

This is the group that will contain the attributes for the entire GPIO array.

**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values``

**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values_atomic``

Both attributes allow to read and set arrays of GPIO values. User must pass
exactly the number of values that the array contains in the form of a string
containing zeroes and ones representing inactive and active GPIO states
respectively. In this example: ``echo 11 > values``.

The ``values_atomic`` attribute works the same as ``values`` but the kernel
will execute the GPIO driver callbacks in interrupt context.

**Group:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/``

This is a group that represents a single GPIO with ``$index`` being its offset
in the array.

**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/consumer``

Allows to set and read the consumer label of the GPIO line.

**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/debounce``

Allows to set and read the debounce period of the GPIO line.

**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/direction``

**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/direction_atomic``

These two attributes allow to set the direction of the GPIO line. They accept
"input" and "output" as values. The atomic variant executes the driver callback
in interrupt context.

**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/interrupts``

If the line is requested in input mode, writing ``1`` to this attribute will
make the module listen for edge interrupts on the GPIO. Writing ``0`` disables
the monitoring. Reading this attribute returns the current number of registered
interrupts (both edges).

**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/value``

**Attribute:** ``/sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/value_atomic``

Both attributes allow to read and set values of individual requested GPIO lines.
They accept the following values: ``1`` and ``0``.
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ GPIO
    Character Device Userspace API <../../userspace-api/gpio/chardev>
    gpio-aggregator
    gpio-sim
    gpio-virtuser
    Obsolete APIs <obsolete>

.. only::  subproject and html
+93 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

=============================================
Linux Kernel GPIO based sloppy logic analyzer
=============================================

:Author: Wolfram Sang

Introduction
============

This document briefly describes how to run the GPIO based in-kernel sloppy
logic analyzer running on an isolated CPU.

The sloppy logic analyzer will utilize a few GPIO lines in input mode on a
system to rapidly sample these digital lines, which will, if the Nyquist
criteria is met, result in a time series log with approximate waveforms as they
appeared on these lines. One way to use it is to analyze external traffic
connected to these GPIO lines with wires (i.e. digital probes), acting as a
common logic analyzer.

Another feature is to snoop on on-chip peripherals if the I/O cells of these
peripherals can be used in GPIO input mode at the same time as they are being
used as inputs or outputs for the peripheral. That means you could e.g. snoop
I2C traffic without any wiring (if your hardware supports it). In the pin
control subsystem such pin controllers are called "non-strict": a certain pin
can be used with a certain peripheral and as a GPIO input line at the same
time.

Note that this is a last resort analyzer which can be affected by latencies,
non-deterministic code paths and non-maskable interrupts. It is called 'sloppy'
for a reason. However, for e.g. remote development, it may be useful to get a
first view and aid further debugging.

Setup
=====

Your kernel must have CONFIG_DEBUG_FS and CONFIG_CPUSETS enabled. Ideally, your
runtime environment does not utilize cpusets otherwise, then isolation of a CPU
core is easiest. If you do need cpusets, check that helper script for the
sloppy logic analyzer does not interfere with your other settings.

Tell the kernel which GPIOs are used as probes. For a Device Tree based system,
you need to use the following bindings. Because these bindings are only for
debugging, there is no official schema::

    i2c-analyzer {
            compatible = "gpio-sloppy-logic-analyzer";
            probe-gpios = <&gpio6 21 GPIO_OPEN_DRAIN>, <&gpio6 4 GPIO_OPEN_DRAIN>;
            probe-names = "SCL", "SDA";
    };

Note that you must provide a name for every GPIO specified. Currently a
maximum of 8 probes are supported. 32 are likely possible but are not
implemented yet.

Usage
=====

The logic analyzer is configurable via files in debugfs. However, it is
strongly recommended to not use them directly, but to use the script
``tools/gpio/gpio-sloppy-logic-analyzer``. Besides checking parameters more
extensively, it will isolate the CPU core so you will have the least
disturbance while measuring.

The script has a help option explaining the parameters. For the above DT
snippet which analyzes an I2C bus at 400kHz on a Renesas Salvator-XS board, the
following settings are used: The isolated CPU shall be CPU1 because it is a big
core in a big.LITTLE setup. Because CPU1 is the default, we don't need a
parameter. The bus speed is 400kHz. So, the sampling theorem says we need to
sample at least at 800kHz. However, falling edges of both signals in an I2C
start condition happen faster, so we need a higher sampling frequency, e.g.
``-s 1500000`` for 1.5MHz. Also, we don't want to sample right away but wait
for a start condition on an idle bus. So, we need to set a trigger to a falling
edge on SDA while SCL stays high, i.e. ``-t 1H+2F``. Last is the duration, let
us assume 15ms here which results in the parameter ``-d 15000``. So,
altogether::

    gpio-sloppy-logic-analyzer -s 1500000 -t 1H+2F -d 15000

Note that the process will return you back to the prompt but a sub-process is
still sampling in the background. Unless this has finished, you will not find a
result file in the current or specified directory. For the above example, we
will then need to trigger I2C communication::

    i2cdetect -y -r <your bus number>

Result is a .sr file to be consumed with PulseView or sigrok-cli from the free
`sigrok`_ project. It is a zip file which also contains the binary sample data
which may be consumed by other software. The filename is the logic analyzer
instance name plus a since-epoch timestamp.

.. _sigrok: https://sigrok.org/
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ Documentation/dev-tools/testing-overview.rst
   kunit/index
   ktap
   checkuapi
   gpio-sloppy-logic-analyzer


.. only::  subproject and html
+10 −0
Original line number Diff line number Diff line
@@ -33,6 +33,11 @@ properties:

  gpio-controller: true

  # Each SGPIO is represented as a pair of input and output GPIOs
  gpio-line-names:
    minItems: 160
    maxItems: 256

  '#gpio-cells':
    const: 2

@@ -41,6 +46,9 @@ properties:

  interrupt-controller: true

  '#interrupt-cells':
    const: 2

  clocks:
    maxItems: 1

@@ -55,6 +63,7 @@ required:
  - '#gpio-cells'
  - interrupts
  - interrupt-controller
  - '#interrupt-cells'
  - ngpios
  - clocks
  - bus-frequency
@@ -72,6 +81,7 @@ examples:
        reg = <0x1e780200 0x0100>;
        clocks = <&syscon ASPEED_CLK_APB>;
        interrupt-controller;
        #interrupt-cells = <2>;
        ngpios = <80>;
        bus-frequency = <12000000>;
    };
Loading