123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- This is a place for planning the ongoing long-term work in the GPIO
- subsystem.
- GPIO descriptors
- Starting with commit 79a9becda894 the GPIO subsystem embarked on a journey
- to move away from the global GPIO numberspace and toward a descriptor-based
- approach. This means that GPIO consumers, drivers and machine descriptions
- ideally have no use or idea of the global GPIO numberspace that has/was
- used in the inception of the GPIO subsystem.
- The numberspace issue is the same as to why irq is moving away from irq
- numbers to IRQ descriptors.
- The underlying motivation for this is that the GPIO numberspace has become
- unmanageable: machine board files tend to become full of macros trying to
- establish the numberspace at compile-time, making it hard to add any numbers
- in the middle (such as if you missed a pin on a chip) without the numberspace
- breaking.
- Machine descriptions such as device tree or ACPI does not have a concept of the
- Linux GPIO number as those descriptions are external to the Linux kernel
- and treat GPIO lines as abstract entities.
- The runtime-assigned GPIO numberspace (what you get if you assign the GPIO
- base as -1 in struct gpio_chip) has also became unpredictable due to factors
- such as probe ordering and the introduction of -EPROBE_DEFER making probe
- ordering of independent GPIO chips essentially unpredictable, as their base
- number will be assigned on a first come first serve basis.
- The best way to get out of the problem is to make the global GPIO numbers
- unimportant by simply not using them. GPIO descriptors deal with this.
- Work items:
- - Convert all GPIO device drivers to only #include <linux/gpio/driver.h>
- - Convert all consumer drivers to only #include <linux/gpio/consumer.h>
- - Convert all machine descriptors in "boardfiles" to only
- #include <linux/gpio/machine.h>, the other option being to convert it
- to a machine description such as device tree, ACPI or fwnode that
- implicitly does not use global GPIO numbers.
- - When this work is complete (will require some of the items in the
- following ongoing work as well) we can delete the old global
- numberspace accessors from <linux/gpio.h> and eventually delete
- <linux/gpio.h> altogether.
- Get rid of <linux/of_gpio.h>
- This header and helpers appeared at one point when there was no proper
- driver infrastructure for doing simpler MMIO GPIO devices and there was
- no core support for parsing device tree GPIOs from the core library with
- the [devm_]gpiod_get() calls we have today that will implicitly go into
- the device tree back-end. It is legacy and should not be used in new code.
- Work items:
- - Get rid of struct of_mm_gpio_chip altogether: use the generic MMIO
- GPIO for all current users (see below). Delete struct of_mm_gpio_chip,
- to_of_mm_gpio_chip(), of_mm_gpiochip_add_data(), of_mm_gpiochip_add()
- of_mm_gpiochip_remove() from the kernel.
- - Change all consumer drivers that #include <linux/of_gpio.h> to
- #include <linux/gpio/consumer.h> and stop doing custom parsing of the
- GPIO lines from the device tree. This can be tricky and often ivolves
- changing boardfiles, etc.
- - Pull semantics for legacy device tree (OF) GPIO lookups into
- gpiolib-of.c: in some cases subsystems are doing custom flags and
- lookups for polarity inversion, open drain and what not. As we now
- handle this with generic OF bindings, pull all legacy handling into
- gpiolib so the library API becomes narrow and deep and handle all
- legacy bindings internally. (See e.g. commits 6953c57ab172,
- 6a537d48461d etc)
- - Delete <linux/of_gpio.h> when all the above is complete and everything
- uses <linux/gpio/consumer.h> or <linux/gpio/driver.h> instead.
- Get rid of <linux/gpio.h>
- This legacy header is a one stop shop for anything GPIO is closely tied
- to the global GPIO numberspace. The endgame of the above refactorings will
- be the removal of <linux/gpio.h> and from that point only the specialized
- headers under <linux/gpio/*.h> will be used. This requires all the above to
- be completed and is expected to take a long time.
- Collect drivers
- Collect GPIO drivers from arch/* and other places that should be placed
- in drivers/gpio/gpio-*. Augment platforms to create platform devices or
- similar and probe a proper driver in the gpiolib subsystem.
- In some cases it makes sense to create a GPIO chip from the local driver
- for a few GPIOs. Those should stay where they are.
- At the same time it makes sense to get rid of code duplication in existing or
- new coming drivers. For example, gpio-ml-ioh should be incorporated into
- gpio-pch. In similar way gpio-intel-mid into gpio-pxa.
- Generic MMIO GPIO
- The GPIO drivers can utilize the generic MMIO helper library in many
- cases, and the helper library should be as helpful as possible for MMIO
- drivers. (drivers/gpio/gpio-mmio.c)
- Work items:
- - Look over and identify any remaining easily converted drivers and
- dry-code conversions to MMIO GPIO for maintainers to test
- - Expand the MMIO GPIO or write a new library for regmap-based I/O
- helpers for GPIO drivers on regmap that simply use offsets
- 0..n in some register to drive GPIO lines
- - Expand the MMIO GPIO or write a new library for port-mapped I/O
- helpers (x86 inb()/outb()) and convert port-mapped I/O drivers to use
- this with dry-coding and sending to maintainers to test
- GPIOLIB irqchip
- The GPIOLIB irqchip is a helper irqchip for "simple cases" that should
- try to cover any generic kind of irqchip cascaded from a GPIO.
- - Convert all the GPIOLIB_IRQCHIP users to pass an irqchip template,
- parent and flags before calling [devm_]gpiochip_add[_data]().
- Currently we set up the irqchip after setting up the gpiochip
- using gpiochip_irqchip_add() and gpiochip_set_[chained|nested]_irqchip().
- This is too complex, so convert all users over to just set up
- the irqchip before registering the gpio_chip, typical example:
- /* Typical state container with dynamic irqchip */
- struct my_gpio {
- struct gpio_chip gc;
- struct irq_chip irq;
- };
- int irq; /* from platform etc */
- struct my_gpio *g;
- struct gpio_irq_chip *girq;
- /* Set up the irqchip dynamically */
- g->irq.name = "my_gpio_irq";
- g->irq.irq_ack = my_gpio_ack_irq;
- g->irq.irq_mask = my_gpio_mask_irq;
- g->irq.irq_unmask = my_gpio_unmask_irq;
- g->irq.irq_set_type = my_gpio_set_irq_type;
- /* Get a pointer to the gpio_irq_chip */
- girq = &g->gc.irq;
- girq->chip = &g->irq;
- girq->parent_handler = ftgpio_gpio_irq_handler;
- girq->num_parents = 1;
- girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
- GFP_KERNEL);
- if (!girq->parents)
- return -ENOMEM;
- girq->default_type = IRQ_TYPE_NONE;
- girq->handler = handle_bad_irq;
- girq->parents[0] = irq;
- When this is done, we will delete the old APIs for instatiating
- GPIOLIB_IRQCHIP and simplify the code.
- - Look over and identify any remaining easily converted drivers and
- dry-code conversions to gpiolib irqchip for maintainers to test
- - Drop gpiochip_set_chained_irqchip() when all the chained irqchips
- have been converted to the above infrastructure.
- - Add more infrastructure to make it possible to also pass a threaded
- irqchip in struct gpio_irq_chip.
- - Drop gpiochip_irqchip_add_nested() when all the chained irqchips
- have been converted to the above infrastructure.
- Increase integration with pin control
- There are already ways to use pin control as back-end for GPIO and
- it may make sense to bring these subsystems closer. One reason for
- creating pin control as its own subsystem was that we could avoid any
- use of the global GPIO numbers. Once the above is complete, it may
- make sense to simply join the subsystems into one and make pin
- multiplexing, pin configuration, GPIO, etc selectable options in one
- and the same pin control and GPIO subsystem.
|