Pin control changes for the v6.9 kernel cycle:

No core changes this time around.
 
 New drivers:
 
 - New driver for Renesas R8A779H0 also known as R-Car V4M.
 
 - New driver for the Awinic AW9523/B I2C GPIO expander.
   I found this living out-of-tree in OpenWrt as an upstream
   attempt had stalled on the finishing line, so I picked it
   up and finished the job.
 
 Improvements:
 
 - The Nomadik pin control driver was for years re-used out of
   tree for the ST STA chips, and now the IP was re-used in a
   MIPS automotive SoC called MobilEyeq5, so it has been split
   in pin control and GPIO drivers so the latter can be reused
   by MobilEyeq5. (Along with a long list of cleanups.)
 
 - A lot of overall cleanup and tidying up.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAmXyJa8ACgkQQRCzN7AZ
 XXMQQw//aq+HJt4vtX4s9v+g/aYBDoasxOgryz96/yq+CqTBBiYh0ib7MJvy/rFs
 bBufH4DEvlpjzgsvaN14L6H+3hFDXKeN6VnAs3DPeBkda4bTS3VOpqNzSoOTeqG9
 4a1jTe3SHche80SNW1YskTAMT0lG6WqC4RvipQ8K14DqIioX0AmgF7nJ1cddKaTK
 tXCWkqKY3TW2Z4edi9ZJLL6vRSQ9tJP9AugjkPX3F91yqwGHb8PV7Ggb1EXzC/X0
 SW7F7Ke0lIvCYidDUpr04TOKdPTmzl2j6zoZfGU1WbypxG0LVhTKAMVk2DL2/v7T
 E8NNimVtGJtqxDfCVSbLc6jRgdYaLRa4dLhMCRWmevfEqFfrA79XFY6BS084T3oP
 619RqbOtxc21AzlJjy2Kp7v3YpmXi6pX5E23L/d8U+0poEiM5qPqdYZaTbGNcGsV
 Yg4xCtxtBfPUdE3SqUCbHDzpWdSDGFsT3LSAUionvYyoW4iF8AXg8SBV1QpfzLM8
 KTWTmsWG/15lCZyf7tq83EJjjVgYhGL4SMnkE8fT+smiXm95Muj1tzUjgapspMiU
 VpnhwtKj1hQrButWlN7+HXKseMrJ8zQJszcP5e3QdWOm7vzZGP3nXpgWosqGCImq
 ThjtyOKvc4+/AqgbIojDCz2BfxD8a7OPOkYHkLGJ96fA5JscBoU=
 =Pt9Y
 -----END PGP SIGNATURE-----

Merge tag 'pinctrl-v6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control updates from Linus Walleij:
 "No core changes this time around.

  New drivers:

   - New driver for Renesas R8A779H0 also known as R-Car V4M.

   - New driver for the Awinic AW9523/B I2C GPIO expander. I found this
     living out-of-tree in OpenWrt as an upstream attempt had stalled on
     the finishing line, so I picked it up and finished the job.

  Improvements:

   - The Nomadik pin control driver was for years re-used out of tree
     for the ST STA chips, and now the IP was re-used in a MIPS
     automotive SoC called MobilEyeq5, so it has been split in pin
     control and GPIO drivers so the latter can be reused by MobilEyeq5.
     (Along with a long list of cleanups)

   - A lot of overall cleanup and tidying up"

* tag 'pinctrl-v6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (87 commits)
  drivers/gpio/nomadik: move dummy nmk_gpio_dbg_show_one() to header
  gpio: nomadik: remove BUG_ON() in nmk_gpio_populate_chip()
  dt-bindings: pinctrl: qcom: update compatible name for match with driver
  pinctrl: aw9523: Make the driver tristate
  pinctrl: nomadik: fix dereference of error pointer
  gpio: nomadik: Back out some managed resources
  pinctrl: aw9523: Add proper terminator
  pinctrl: core: comment that pinctrl_add_gpio_range() is deprecated
  pinctrl: pinmux: Suppress error message for -EPROBE_DEFER
  pinctrl: Add driver for Awinic AW9523/B I2C GPIO Expander
  dt-bindings: pinctrl: Add bindings for Awinic AW9523/AW9523B
  gpio: nomadik: Finish conversion to use firmware node APIs
  gpio: nomadik: fix Kconfig dependencies inbetween pinctrl & GPIO
  pinctrl: da9062: Add OF table
  dt-bindings: pinctrl: at91: add sam9x7
  pinctrl: ocelot: remove redundant assignment to variable ret
  gpio: nomadik: grab optional reset control and deassert it at probe
  gpio: nomadik: support mobileye,eyeq5-gpio
  gpio: nomadik: handle variadic GPIO count
  gpio: nomadik: support shared GPIO IRQs
  ...
This commit is contained in:
Linus Torvalds 2024-03-14 10:22:26 -07:00
commit a3df5d5422
55 changed files with 7496 additions and 1046 deletions

View File

@ -1,31 +0,0 @@
Nomadik GPIO controller
Required properties:
- compatible : Should be "st,nomadik-gpio".
- reg : Physical base address and length of the controller's registers.
- interrupts : The interrupt outputs from the controller.
- #gpio-cells : Should be two:
The first cell is the pin number.
The second cell is used to specify optional parameters:
- bits[3:0] trigger type and level flags:
1 = low-to-high edge triggered.
2 = high-to-low edge triggered.
4 = active high level-sensitive.
8 = active low level-sensitive.
- gpio-controller : Marks the device node as a GPIO controller.
- interrupt-controller : Marks the device node as an interrupt controller.
- gpio-bank : Specifies which bank a controller owns.
- st,supports-sleepmode : Specifies whether controller can sleep or not
Example:
gpio1: gpio@8012e080 {
compatible = "st,nomadik-gpio";
reg = <0x8012e080 0x80>;
interrupts = <0 120 0x4>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
st,supports-sleepmode;
gpio-bank = <1>;
};

View File

@ -0,0 +1,95 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/st,nomadik-gpio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Nomadik GPIO controller
description:
The Nomadik GPIO driver handles Nomadik SoC GPIO blocks. This block has also
been called ST STA2X11. On the Nomadik platform, this driver is intertwined
with pinctrl-nomadik.
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
properties:
$nodename:
pattern: "^gpio@[0-9a-f]+$"
compatible:
enum:
- st,nomadik-gpio
- mobileye,eyeq5-gpio
reg:
maxItems: 1
interrupts:
maxItems: 1
"#gpio-cells":
const: 2
gpio-controller: true
interrupt-controller: true
"#interrupt-cells":
const: 2
gpio-bank:
description: System-wide GPIO bank index.
$ref: /schemas/types.yaml#/definitions/uint32
st,supports-sleepmode:
description: Whether the controller can sleep or not.
$ref: /schemas/types.yaml#/definitions/flag
clocks:
maxItems: 1
gpio-ranges:
maxItems: 1
ngpios:
minimum: 0
maximum: 32
resets:
maxItems: 1
required:
- compatible
- reg
- interrupts
- "#gpio-cells"
- gpio-controller
- interrupt-controller
- gpio-bank
unevaluatedProperties: false
allOf:
- if:
properties:
compatible:
contains:
const: mobileye,eyeq5-gpio
then:
properties:
st,supports-sleepmode: false
examples:
- |
gpio@8012e080 {
compatible = "st,nomadik-gpio";
reg = <0x8012e080 0x80>;
interrupts = <0 120 0x4>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
st,supports-sleepmode;
gpio-bank = <1>;
};

View File

@ -24,7 +24,7 @@ required:
- compatible
patternProperties:
"^bank@[0-9a-z]+$":
"^bank@[0-9a-f]+$":
$ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio
unevaluatedProperties: false

View File

@ -21,7 +21,7 @@ required:
- compatible
patternProperties:
"^bank@[0-9a-z]+$":
"^bank@[0-9a-f]+$":
$ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio
unevaluatedProperties: false

View File

@ -21,7 +21,7 @@ required:
- compatible
patternProperties:
"^bank@[0-9a-z]+$":
"^bank@[0-9a-f]+$":
$ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio
unevaluatedProperties: false

View File

@ -29,7 +29,7 @@ required:
- compatible
patternProperties:
"^bank@[0-9a-z]+$":
"^bank@[0-9a-f]+$":
$ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio
unevaluatedProperties: false

View File

@ -29,7 +29,7 @@ required:
- compatible
patternProperties:
"^bank@[0-9a-z]+$":
"^bank@[0-9a-f]+$":
$ref: amlogic,meson-pinctrl-common.yaml#/$defs/meson-gpio
unevaluatedProperties: false

View File

@ -20,6 +20,7 @@ such as pull-up, multi drive, etc.
Required properties for iomux controller:
- compatible: "atmel,at91rm9200-pinctrl" or "atmel,at91sam9x5-pinctrl"
or "atmel,sama5d3-pinctrl" or "microchip,sam9x60-pinctrl"
or "microchip,sam9x7-pinctrl", "microchip,sam9x60-pinctrl"
- atmel,mux-mask: array of mask (periph per bank) to describe if a pin can be
configured in this periph mode. All the periph and bank need to be describe.
@ -120,6 +121,7 @@ Some requirements for using atmel,at91rm9200-pinctrl binding:
For each bank the required properties are:
- compatible: "atmel,at91sam9x5-gpio" or "atmel,at91rm9200-gpio" or
"microchip,sam9x60-gpio"
or "microchip,sam9x7-gpio", "microchip,sam9x60-gpio", "atmel,at91rm9200-gpio"
- reg: physical base address and length of the controller's registers
- interrupts: interrupt outputs from the controller
- interrupt-controller: marks the device node as an interrupt controller

View File

@ -0,0 +1,139 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/awinic,aw9523-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Awinic AW9523/AW9523B I2C GPIO Expander
maintainers:
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
description: |
The Awinic AW9523/AW9523B I2C GPIO Expander featuring 16 multi-function
I/O, 256 steps PWM mode and interrupt support.
properties:
compatible:
const: awinic,aw9523-pinctrl
reg:
maxItems: 1
'#gpio-cells':
description: |
Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-controller: true
gpio-ranges:
maxItems: 1
interrupt-controller: true
interrupts:
maxItems: 1
description: Specifies the INTN pin IRQ.
'#interrupt-cells':
description:
Specifies the PIN numbers and Flags, as defined in defined in
include/dt-bindings/interrupt-controller/irq.h
const: 2
reset-gpios:
maxItems: 1
# PIN CONFIGURATION NODES
patternProperties:
'-pins$':
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: /schemas/pinctrl/pincfg-node.yaml
properties:
pins:
description:
List of gpio pins affected by the properties specified in
this subnode.
items:
pattern: "^gpio([0-9]|1[0-5])$"
minItems: 1
maxItems: 16
function:
description:
Specify the alternative function to be configured for the
specified pins.
enum: [ gpio, pwm ]
bias-disable: true
bias-pull-down: true
bias-pull-up: true
drive-open-drain: true
drive-push-pull: true
input-enable: true
input-disable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
required:
- compatible
- reg
- gpio-controller
- '#gpio-cells'
- gpio-ranges
additionalProperties: false
examples:
# Example configuration to drive pins for a keyboard matrix
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
aw9523: gpio-expander@58 {
compatible = "awinic,aw9523-pinctrl";
reg = <0x58>;
interrupt-parent = <&tlmm>;
interrupts = <50 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&tlmm 0 0 16>;
interrupt-controller;
#interrupt-cells = <2>;
reset-gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
keyboard-matrix-col-pins {
pins = "gpio8", "gpio9", "gpio10", "gpio11",
"gpio12", "gpio13", "gpio14", "gpio15";
function = "gpio";
input-disable;
output-low;
};
keyboard-matrix-row-pins {
pins = "gpio0", "gpio1", "gpio2", "gpio3",
"gpio4", "gpio5", "gpio6", "gpio7";
function = "gpio";
bias-pull-up;
drive-open-drain;
input-enable;
};
};
};

View File

@ -93,7 +93,8 @@ properties:
input-schmitt-disable: true
input-debounce: true
input-debounce:
maxItems: 1
output-low: true

View File

@ -45,7 +45,8 @@ properties:
maxItems: 1
gpio-reserved-ranges:
maxItems: 1
minItems: 1
maxItems: 60
vdd-supply:
description:
@ -85,6 +86,8 @@ patternProperties:
bias-disable: true
input-enable: true
output-high: true
output-low: true
@ -133,6 +136,23 @@ examples:
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
vdd-supply = <&p3v3>;
gpio-reserved-ranges = <5 1>;
gpio-reserved-ranges = <1 2>, <6 1>, <10 1>, <15 1>;
pinctrl-0 = <&U62160_pins>, <&U62160_ipins>;
pinctrl-names = "default";
U62160_pins: cfg-pins {
pins = "gp03", "gp16", "gp20", "gp50", "gp51";
function = "gpio";
input-enable;
bias-pull-up;
};
U62160_ipins: icfg-pins {
pins = "gp04", "gp17", "gp21", "gp52", "gp53";
function = "gpio";
input-enable;
bias-pull-up;
};
};
};

View File

@ -0,0 +1,242 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/mobileye,eyeq5-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mobileye EyeQ5 pin controller
description: >
The EyeQ5 pin controller handles the two pin banks of the system. It belongs
to a system-controller block called OLB.
Pin control is about bias (pull-down, pull-up), drive strength and muxing. Pin
muxing supports two functions for each pin: first is GPIO, second is
pin-dependent.
Pins and groups are bijective.
maintainers:
- Grégory Clement <gregory.clement@bootlin.com>
- Théo Lebrun <theo.lebrun@bootlin.com>
- Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
$ref: pinctrl.yaml#
properties:
compatible:
enum:
- mobileye,eyeq5-pinctrl
reg:
maxItems: 1
patternProperties:
"-pins?$":
type: object
description: Pin muxing configuration.
$ref: pinmux-node.yaml#
additionalProperties: false
properties:
pins: true
function:
enum: [gpio,
# Bank A
timer0, timer1, timer2, timer5, uart0, uart1, can0, can1, spi0,
spi1, refclk0,
# Bank B
timer3, timer4, timer6, uart2, can2, spi2, spi3, mclk0]
bias-disable: true
bias-pull-down: true
bias-pull-up: true
drive-strength: true
required:
- pins
- function
allOf:
- if:
properties:
function:
const: gpio
then:
properties:
pins:
items: # PA0 - PA28, PB0 - PB22
pattern: '^(P(A|B)1?[0-9]|PA2[0-8]|PB2[0-2])$'
- if:
properties:
function:
const: timer0
then:
properties:
pins:
items:
enum: [PA0, PA1]
- if:
properties:
function:
const: timer1
then:
properties:
pins:
items:
enum: [PA2, PA3]
- if:
properties:
function:
const: timer2
then:
properties:
pins:
items:
enum: [PA4, PA5]
- if:
properties:
function:
const: timer5
then:
properties:
pins:
items:
enum: [PA6, PA7, PA8, PA9]
- if:
properties:
function:
const: uart0
then:
properties:
pins:
items:
enum: [PA10, PA11]
- if:
properties:
function:
const: uart1
then:
properties:
pins:
items:
enum: [PA12, PA13]
- if:
properties:
function:
const: can0
then:
properties:
pins:
items:
enum: [PA14, PA15]
- if:
properties:
function:
const: can1
then:
properties:
pins:
items:
enum: [PA16, PA17]
- if:
properties:
function:
const: spi0
then:
properties:
pins:
items:
enum: [PA18, PA19, PA20, PA21, PA22]
- if:
properties:
function:
const: spi1
then:
properties:
pins:
items:
enum: [PA23, PA24, PA25, PA26, PA27]
- if:
properties:
function:
const: refclk0
then:
properties:
pins:
items:
enum: [PA28]
- if:
properties:
function:
const: timer3
then:
properties:
pins:
items:
enum: [PB0, PB1]
- if:
properties:
function:
const: timer4
then:
properties:
pins:
items:
enum: [PB2, PB3]
- if:
properties:
function:
const: timer6
then:
properties:
pins:
items:
enum: [PB4, PB5, PB6, PB7]
- if:
properties:
function:
const: uart2
then:
properties:
pins:
items:
enum: [PB8, PB9]
- if:
properties:
function:
const: can2
then:
properties:
pins:
items:
enum: [PB10, PB11]
- if:
properties:
function:
const: spi2
then:
properties:
pins:
items:
enum: [PB12, PB13, PB14, PB15, PB16]
- if:
properties:
function:
const: spi3
then:
properties:
pins:
items:
enum: [PB17, PB18, PB19, PB20, PB21]
- if:
properties:
function:
const: mclk0
then:
properties:
pins:
items:
enum: [PB22]
required:
- compatible
- reg
additionalProperties: false

View File

@ -152,7 +152,6 @@ patternProperties:
description:
Debouncing periods in microseconds, one period per interrupt
bank found in the controller
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 4
@ -160,7 +159,6 @@ patternProperties:
description: |
0: Low rate
1: High rate
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1]
drive-strength:

View File

@ -103,7 +103,8 @@ patternProperties:
items:
pattern: "^gpio1?[0-9]{1,2}$"
input-debounce: true
input-debounce:
maxItems: 1
additionalProperties: false

View File

@ -10,18 +10,21 @@ maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jon Hunter <jonathanh@nvidia.com>
$ref: nvidia,tegra234-pinmux-common.yaml
properties:
compatible:
const: nvidia,tegra234-pinmux-aon
reg:
maxItems: 1
patternProperties:
"^pinmux(-[a-z0-9-]+)?$":
type: object
# pin groups
additionalProperties:
$ref: nvidia,tegra234-pinmux-common.yaml
properties:
nvidia,pins:
items:

View File

@ -10,57 +10,43 @@ maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jon Hunter <jonathanh@nvidia.com>
$ref: nvidia,tegra-pinmux-common.yaml
properties:
reg:
items:
- description: pinmux registers
nvidia,function:
enum: [ gp, uartc, i2c8, spi2, i2c2, can1, can0, rsvd0, eth0, eth2,
eth1, dp, eth3, i2c4, i2c7, i2c9, eqos, pe2, pe1, pe0, pe3,
pe4, pe5, pe6, pe7, pe8, pe9, pe10, qspi0, qspi1, qpsi,
sdmmc1, sce, soc, gpio, hdmi, ufs0, spi3, spi1, uartb, uarte,
usb, extperiph2, extperiph1, i2c3, vi0, i2c5, uarta, uartd,
i2c1, i2s4, i2s6, aud, spi5, touch, uartj, rsvd1, wdt, tsc,
dmic3, led, vi0_alt, i2s5, nv, extperiph3, extperiph4, spi4,
ccla, i2s1, i2s2, i2s3, i2s8, rsvd2, dmic5, dca, displayb,
displaya, vi1, dcb, dmic1, dmic4, i2s7, dmic2, dspk0, rsvd3,
tsc_alt, istctrl, vi1_alt, dspk1, igpu ]
patternProperties:
"^pinmux(-[a-z0-9-]+)?$":
type: object
# pin groups
additionalProperties:
$ref: nvidia,tegra-pinmux-common.yaml
# We would typically use unevaluatedProperties here but that has the
# downside that all the properties in the common bindings become valid
# for all chip generations. In this case, however, we want the per-SoC
# bindings to be able to override which of the common properties are
# allowed, since not all pinmux generations support the same sets of
# properties. This way, the common bindings define the format of the
# properties but the per-SoC bindings define which of them apply to a
# given chip.
additionalProperties: false
properties:
nvidia,function:
enum: [ gp, uartc, i2c8, spi2, i2c2, can1, can0, rsvd0, eth0, eth2,
eth1, dp, eth3, i2c4, i2c7, i2c9, eqos, pe2, pe1, pe0, pe3,
pe4, pe5, pe6, pe7, pe8, pe9, pe10, qspi0, qspi1, qpsi,
sdmmc1, sce, soc, gpio, hdmi, ufs0, spi3, spi1, uartb, uarte,
usb, extperiph2, extperiph1, i2c3, vi0, i2c5, uarta, uartd,
i2c1, i2s4, i2s6, aud, spi5, touch, uartj, rsvd1, wdt, tsc,
dmic3, led, vi0_alt, i2s5, nv, extperiph3, extperiph4, spi4,
ccla, i2s1, i2s2, i2s3, i2s8, rsvd2, dmic5, dca, displayb,
displaya, vi1, dcb, dmic1, dmic4, i2s7, dmic2, dspk0, rsvd3,
tsc_alt, istctrl, vi1_alt, dspk1, igpu ]
# out of the common properties, only these are allowed for Tegra234
nvidia,pins: true
nvidia,pull: true
nvidia,tristate: true
nvidia,schmitt: true
nvidia,enable-input: true
nvidia,open-drain: true
nvidia,lock: true
nvidia,drive-type: true
nvidia,io-hv: true
required:
- nvidia,pins
# out of the common properties, only these are allowed for Tegra234
nvidia,pins: true
nvidia,pull: true
nvidia,tristate: true
nvidia,schmitt: true
nvidia,enable-input: true
nvidia,open-drain: true
nvidia,lock: true
nvidia,drive-type: true
nvidia,io-hv: true
required:
- compatible
- reg
- nvidia,pins
# We would typically use unevaluatedProperties here but that has the
# downside that all the properties in the common bindings become valid
# for all chip generations. In this case, however, we want the per-SoC
# bindings to be able to override which of the common properties are
# allowed, since not all pinmux generations support the same sets of
# properties. This way, the common bindings define the format of the
# properties but the per-SoC bindings define which of them apply to a
# given chip.
additionalProperties: false
additionalProperties: true
...

View File

@ -10,18 +10,21 @@ maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jon Hunter <jonathanh@nvidia.com>
$ref: nvidia,tegra234-pinmux-common.yaml
properties:
compatible:
const: nvidia,tegra234-pinmux
reg:
maxItems: 1
patternProperties:
"^pinmux(-[a-z0-9-]+)?$":
type: object
# pin groups
additionalProperties:
$ref: nvidia,tegra234-pinmux-common.yaml
properties:
nvidia,pins:
items:

View File

@ -97,7 +97,7 @@ properties:
description: disable schmitt-trigger mode
input-debounce:
$ref: /schemas/types.yaml#/definitions/uint32
$ref: /schemas/types.yaml#/definitions/uint32-array
description: Takes the debounce time in usec as argument or 0 to disable
debouncing

View File

@ -17,7 +17,7 @@ allOf:
properties:
compatible:
const: qcom,sm4450-pinctrl
const: qcom,sm4450-tlmm
reg:
maxItems: 1

View File

@ -46,6 +46,7 @@ properties:
- renesas,pfc-r8a779a0 # R-Car V3U
- renesas,pfc-r8a779f0 # R-Car S4-8
- renesas,pfc-r8a779g0 # R-Car V4H
- renesas,pfc-r8a779h0 # R-Car V4M
- renesas,pfc-sh73a0 # SH-Mobile AG5
reg:

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/xlnx,zynq-pinctrl.yaml#
$id: http://devicetree.org/schemas/pinctrl/xlnx,pinctrl-zynq.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Xilinx Zynq Pinctrl
@ -28,7 +28,7 @@ description: |
properties:
compatible:
const: xlnx,zynq-pinctrl
const: xlnx,pinctrl-zynq
reg:
description: Specifies the base address and size of the SLCR space.
@ -181,7 +181,7 @@ examples:
- |
#include <dt-bindings/pinctrl/pinctrl-zynq.h>
pinctrl0: pinctrl@700 {
compatible = "xlnx,zynq-pinctrl";
compatible = "xlnx,pinctrl-zynq";
reg = <0x700 0x200>;
syscon = <&slcr>;

View File

@ -2471,6 +2471,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
F: Documentation/devicetree/bindings/arm/ste-*
F: Documentation/devicetree/bindings/arm/ux500.yaml
F: Documentation/devicetree/bindings/arm/ux500/
F: Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
F: Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
F: arch/arm/boot/dts/st/ste-*
F: arch/arm/mach-nomadik/
@ -2479,6 +2480,7 @@ F: drivers/clk/clk-nomadik.c
F: drivers/clocksource/clksrc-dbx500-prcmu.c
F: drivers/dma/ste_dma40*
F: drivers/pmdomain/st/ste-ux500-pm-domain.c
F: drivers/gpio/gpio-nomadik.c
F: drivers/hwspinlock/u8500_hsem.c
F: drivers/i2c/busses/i2c-nomadik.c
F: drivers/iio/adc/ab8500-gpadc.c

View File

@ -46,6 +46,10 @@
};
};
&pinctrl {
gpio-ranges = <&pinctrl 0 0 232>;
};
&soc {
dma-noncoherent;
interrupt-parent = <&plic>;

View File

@ -478,6 +478,18 @@ config GPIO_MXS
select GPIO_GENERIC
select GENERIC_IRQ_CHIP
config GPIO_NOMADIK
bool "Nomadik GPIO driver"
depends on ARCH_U8500 || ARCH_NOMADIK || MACH_EYEQ5 || COMPILE_TEST
select GPIOLIB_IRQCHIP
help
Say yes here to support the Nomadik SoC GPIO block. This block is also
used by the Mobileye EyeQ5 SoC.
It handles up to 32 GPIOs per bank, that can all be interrupt sources.
It is deeply interconnected with the associated pinctrl driver as GPIO
registers handle muxing ("alternate functions") as well.
config GPIO_NPCM_SGPIO
bool "Nuvoton SGPIO support"
depends on ARCH_NPCM || COMPILE_TEST

View File

@ -117,6 +117,7 @@ obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o
obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
obj-$(CONFIG_GPIO_NOMADIK) += gpio-nomadik.o
obj-$(CONFIG_GPIO_NPCM_SGPIO) += gpio-npcm-sgpio.o
obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o
obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o

730
drivers/gpio/gpio-nomadik.c Normal file
View File

@ -0,0 +1,730 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* GPIO driver for the IP block found in the Nomadik SoC; it is an AMBA device,
* managing 32 pins with alternate functions. It can also handle the STA2X11
* block from ST.
*
* The GPIO chips are shared with pinctrl-nomadik if used; it needs access for
* pinmuxing functionality and others.
*
* This driver also handles the mobileye,eyeq5-gpio compatible. It is an STA2X11
* but with only data, direction and interrupts register active. We want to
* avoid touching SLPM, RWIMSC, FWIMSC, AFSLA and AFSLB registers; that is,
* wake and alternate function registers. It is NOT compatible with
* pinctrl-nomadik.
*
* Copyright (C) 2008,2009 STMicroelectronics
* Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
* Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
* Copyright (C) 2011-2013 Linus Walleij <linus.walleij@linaro.org>
*/
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/reset.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/gpio/gpio-nomadik.h>
#ifndef CONFIG_PINCTRL_NOMADIK
static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
#endif
void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset,
enum nmk_gpio_slpm mode)
{
u32 slpm;
/* We should NOT have been called. */
if (WARN_ON(nmk_chip->is_mobileye_soc))
return;
slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
if (mode == NMK_GPIO_SLPM_NOCHANGE)
slpm |= BIT(offset);
else
slpm &= ~BIT(offset);
writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
}
static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
unsigned int offset, int val)
{
if (val)
writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATS);
else
writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATC);
}
void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
unsigned int offset, int val)
{
writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRS);
__nmk_gpio_set_output(nmk_chip, offset, val);
}
/* IRQ functions */
static void nmk_gpio_irq_ack(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
clk_enable(nmk_chip->clk);
writel(BIT(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
clk_disable(nmk_chip->clk);
}
enum nmk_gpio_irq_type {
NORMAL,
WAKE,
};
static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
int offset, enum nmk_gpio_irq_type which,
bool enable)
{
u32 *rimscval;
u32 *fimscval;
u32 rimscreg;
u32 fimscreg;
if (which == NORMAL) {
rimscreg = NMK_GPIO_RIMSC;
fimscreg = NMK_GPIO_FIMSC;
rimscval = &nmk_chip->rimsc;
fimscval = &nmk_chip->fimsc;
} else {
/* We should NOT have been called. */
if (WARN_ON(nmk_chip->is_mobileye_soc))
return;
rimscreg = NMK_GPIO_RWIMSC;
fimscreg = NMK_GPIO_FWIMSC;
rimscval = &nmk_chip->rwimsc;
fimscval = &nmk_chip->fwimsc;
}
/* we must individually set/clear the two edges */
if (nmk_chip->edge_rising & BIT(offset)) {
if (enable)
*rimscval |= BIT(offset);
else
*rimscval &= ~BIT(offset);
writel(*rimscval, nmk_chip->addr + rimscreg);
}
if (nmk_chip->edge_falling & BIT(offset)) {
if (enable)
*fimscval |= BIT(offset);
else
*fimscval &= ~BIT(offset);
writel(*fimscval, nmk_chip->addr + fimscreg);
}
}
static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
int offset, bool on)
{
/* We should NOT have been called. */
if (WARN_ON(nmk_chip->is_mobileye_soc))
return;
/*
* Ensure WAKEUP_ENABLE is on. No need to disable it if wakeup is
* disabled, since setting SLPM to 1 increases power consumption, and
* wakeup is anyhow controlled by the RIMSC and FIMSC registers.
*/
if (nmk_chip->sleepmode && on) {
__nmk_gpio_set_slpm(nmk_chip, offset,
NMK_GPIO_SLPM_WAKEUP_ENABLE);
}
__nmk_gpio_irq_modify(nmk_chip, offset, WAKE, on);
}
static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip,
struct irq_data *d, bool enable)
{
unsigned long flags;
clk_enable(nmk_chip->clk);
spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
spin_lock(&nmk_chip->lock);
__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
if (!nmk_chip->is_mobileye_soc && !(nmk_chip->real_wake & BIT(d->hwirq)))
__nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
spin_unlock(&nmk_chip->lock);
spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
clk_disable(nmk_chip->clk);
}
static void nmk_gpio_irq_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
nmk_gpio_irq_maskunmask(nmk_chip, d, false);
gpiochip_disable_irq(gc, irqd_to_hwirq(d));
}
static void nmk_gpio_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
gpiochip_enable_irq(gc, irqd_to_hwirq(d));
nmk_gpio_irq_maskunmask(nmk_chip, d, true);
}
static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
unsigned long flags;
/* Handler is registered in all cases. */
if (nmk_chip->is_mobileye_soc)
return -ENXIO;
clk_enable(nmk_chip->clk);
spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
spin_lock(&nmk_chip->lock);
if (irqd_irq_disabled(d))
__nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
if (on)
nmk_chip->real_wake |= BIT(d->hwirq);
else
nmk_chip->real_wake &= ~BIT(d->hwirq);
spin_unlock(&nmk_chip->lock);
spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
clk_disable(nmk_chip->clk);
return 0;
}
static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
bool enabled = !irqd_irq_disabled(d);
bool wake = irqd_is_wakeup_set(d);
unsigned long flags;
if (type & IRQ_TYPE_LEVEL_HIGH)
return -EINVAL;
if (type & IRQ_TYPE_LEVEL_LOW)
return -EINVAL;
clk_enable(nmk_chip->clk);
spin_lock_irqsave(&nmk_chip->lock, flags);
if (enabled)
__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
if (!nmk_chip->is_mobileye_soc && (enabled || wake))
__nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
nmk_chip->edge_rising &= ~BIT(d->hwirq);
if (type & IRQ_TYPE_EDGE_RISING)
nmk_chip->edge_rising |= BIT(d->hwirq);
nmk_chip->edge_falling &= ~BIT(d->hwirq);
if (type & IRQ_TYPE_EDGE_FALLING)
nmk_chip->edge_falling |= BIT(d->hwirq);
if (enabled)
__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
if (!nmk_chip->is_mobileye_soc && (enabled || wake))
__nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
spin_unlock_irqrestore(&nmk_chip->lock, flags);
clk_disable(nmk_chip->clk);
return 0;
}
static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
clk_enable(nmk_chip->clk);
nmk_gpio_irq_unmask(d);
return 0;
}
static void nmk_gpio_irq_shutdown(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
nmk_gpio_irq_mask(d);
clk_disable(nmk_chip->clk);
}
static irqreturn_t nmk_gpio_irq_handler(int irq, void *dev_id)
{
struct nmk_gpio_chip *nmk_chip = dev_id;
struct gpio_chip *chip = &nmk_chip->chip;
unsigned long mask = GENMASK(chip->ngpio - 1, 0);
unsigned long status;
int bit;
clk_enable(nmk_chip->clk);
status = readl(nmk_chip->addr + NMK_GPIO_IS);
/* Ensure we cannot leave pending bits; this should never occur. */
if (unlikely(status & ~mask))
writel(status & ~mask, nmk_chip->addr + NMK_GPIO_IC);
clk_disable(nmk_chip->clk);
for_each_set_bit(bit, &status, chip->ngpio)
generic_handle_domain_irq_safe(chip->irq.domain, bit);
return IRQ_RETVAL((status & mask) != 0);
}
/* I/O Functions */
static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned int offset)
{
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
int dir;
clk_enable(nmk_chip->clk);
dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset);
clk_disable(nmk_chip->clk);
if (dir)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned int offset)
{
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
clk_enable(nmk_chip->clk);
writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
clk_disable(nmk_chip->clk);
return 0;
}
static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned int offset)
{
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
int value;
clk_enable(nmk_chip->clk);
value = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
clk_disable(nmk_chip->clk);
return value;
}
static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned int offset,
int val)
{
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
clk_enable(nmk_chip->clk);
__nmk_gpio_set_output(nmk_chip, offset, val);
clk_disable(nmk_chip->clk);
}
static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned int offset,
int val)
{
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
clk_enable(nmk_chip->clk);
__nmk_gpio_make_output(nmk_chip, offset, val);
clk_disable(nmk_chip->clk);
return 0;
}
#ifdef CONFIG_DEBUG_FS
static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset)
{
u32 afunc, bfunc;
/* We don't support modes. */
if (nmk_chip->is_mobileye_soc)
return NMK_GPIO_ALT_GPIO;
clk_enable(nmk_chip->clk);
afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & BIT(offset);
bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & BIT(offset);
clk_disable(nmk_chip->clk);
return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
}
void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev,
struct gpio_chip *chip, unsigned int offset,
unsigned int gpio)
{
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
int mode;
bool is_out;
bool data_out;
bool pull;
static const char * const modes[] = {
[NMK_GPIO_ALT_GPIO] = "gpio",
[NMK_GPIO_ALT_A] = "altA",
[NMK_GPIO_ALT_B] = "altB",
[NMK_GPIO_ALT_C] = "altC",
[NMK_GPIO_ALT_C + 1] = "altC1",
[NMK_GPIO_ALT_C + 2] = "altC2",
[NMK_GPIO_ALT_C + 3] = "altC3",
[NMK_GPIO_ALT_C + 4] = "altC4",
};
char *label = gpiochip_dup_line_label(chip, offset);
if (IS_ERR(label))
return;
clk_enable(nmk_chip->clk);
is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & BIT(offset));
data_out = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
mode = nmk_gpio_get_mode(nmk_chip, offset);
#ifdef CONFIG_PINCTRL_NOMADIK
if (mode == NMK_GPIO_ALT_C && pctldev)
mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
#endif
if (is_out) {
seq_printf(s, " gpio-%-3d (%-20.20s) out %s %s",
gpio,
label ?: "(none)",
data_out ? "hi" : "lo",
(mode < 0) ? "unknown" : modes[mode]);
} else {
int irq = chip->to_irq(chip, offset);
const int pullidx = pull ? 1 : 0;
int val;
static const char * const pulls[] = {
"none ",
"pull enabled",
};
seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s",
gpio,
label ?: "(none)",
pulls[pullidx],
(mode < 0) ? "unknown" : modes[mode]);
val = nmk_gpio_get_input(chip, offset);
seq_printf(s, " VAL %d", val);
/*
* This races with request_irq(), set_irq_type(),
* and set_irq_wake() ... but those are "rare".
*/
if (irq > 0 && irq_has_action(irq)) {
char *trigger;
bool wake;
if (nmk_chip->edge_rising & BIT(offset))
trigger = "edge-rising";
else if (nmk_chip->edge_falling & BIT(offset))
trigger = "edge-falling";
else
trigger = "edge-undefined";
wake = !!(nmk_chip->real_wake & BIT(offset));
seq_printf(s, " irq-%d %s%s",
irq, trigger, wake ? " wakeup" : "");
}
}
clk_disable(nmk_chip->clk);
}
static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
unsigned int i, gpio = chip->base;
for (i = 0; i < chip->ngpio; i++, gpio++) {
nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio);
seq_puts(s, "\n");
}
}
#else
#define nmk_gpio_dbg_show NULL
#endif
/*
* We will allocate memory for the state container using devm* allocators
* binding to the first device reaching this point, it doesn't matter if
* it is the pin controller or GPIO driver. However we need to use the right
* platform device when looking up resources so pay attention to pdev.
*/
struct nmk_gpio_chip *nmk_gpio_populate_chip(struct fwnode_handle *fwnode,
struct platform_device *pdev)
{
struct nmk_gpio_chip *nmk_chip;
struct platform_device *gpio_pdev;
struct device *dev = &pdev->dev;
struct reset_control *reset;
struct device *gpio_dev;
struct gpio_chip *chip;
struct resource *res;
struct clk *clk;
void __iomem *base;
u32 id, ngpio;
int ret;
gpio_dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
if (!gpio_dev) {
dev_err(dev, "populate \"%pfwP\": device not found\n", fwnode);
return ERR_PTR(-ENODEV);
}
gpio_pdev = to_platform_device(gpio_dev);
if (device_property_read_u32(gpio_dev, "gpio-bank", &id)) {
dev_err(dev, "populate: gpio-bank property not found\n");
platform_device_put(gpio_pdev);
return ERR_PTR(-EINVAL);
}
#ifdef CONFIG_PINCTRL_NOMADIK
if (id >= ARRAY_SIZE(nmk_gpio_chips)) {
dev_err(dev, "populate: invalid id: %u\n", id);
platform_device_put(gpio_pdev);
return ERR_PTR(-EINVAL);
}
/* Already populated? */
nmk_chip = nmk_gpio_chips[id];
if (nmk_chip) {
platform_device_put(gpio_pdev);
return nmk_chip;
}
#endif
nmk_chip = devm_kzalloc(dev, sizeof(*nmk_chip), GFP_KERNEL);
if (!nmk_chip) {
platform_device_put(gpio_pdev);
return ERR_PTR(-ENOMEM);
}
if (device_property_read_u32(gpio_dev, "ngpios", &ngpio)) {
ngpio = NMK_GPIO_PER_CHIP;
dev_dbg(dev, "populate: using default ngpio (%u)\n", ngpio);
}
nmk_chip->is_mobileye_soc = device_is_compatible(gpio_dev,
"mobileye,eyeq5-gpio");
nmk_chip->bank = id;
chip = &nmk_chip->chip;
chip->base = -1;
chip->ngpio = ngpio;
chip->label = dev_name(gpio_dev);
chip->parent = gpio_dev;
/* NOTE: different devices! No devm_platform_ioremap_resource() here! */
res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base)) {
platform_device_put(gpio_pdev);
return ERR_CAST(base);
}
nmk_chip->addr = base;
/* NOTE: do not use devm_ here! */
clk = clk_get_optional(gpio_dev, NULL);
if (IS_ERR(clk)) {
platform_device_put(gpio_pdev);
return ERR_CAST(clk);
}
clk_prepare(clk);
nmk_chip->clk = clk;
/* NOTE: do not use devm_ here! */
reset = reset_control_get_optional_shared(gpio_dev, NULL);
if (IS_ERR(reset)) {
clk_unprepare(clk);
clk_put(clk);
platform_device_put(gpio_pdev);
dev_err(dev, "failed getting reset control: %pe\n",
reset);
return ERR_CAST(reset);
}
/*
* Reset might be shared and asserts/deasserts calls are unbalanced. We
* only support sharing this reset with other gpio-nomadik devices that
* use this reset to ensure deassertion at probe.
*/
ret = reset_control_deassert(reset);
if (ret) {
reset_control_put(reset);
clk_unprepare(clk);
clk_put(clk);
platform_device_put(gpio_pdev);
dev_err(dev, "failed reset deassert: %d\n", ret);
return ERR_PTR(ret);
}
#ifdef CONFIG_PINCTRL_NOMADIK
nmk_gpio_chips[id] = nmk_chip;
#endif
return nmk_chip;
}
static void nmk_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
seq_printf(p, "nmk%u-%u-%u", nmk_chip->bank,
gc->base, gc->base + gc->ngpio - 1);
}
static const struct irq_chip nmk_irq_chip = {
.irq_ack = nmk_gpio_irq_ack,
.irq_mask = nmk_gpio_irq_mask,
.irq_unmask = nmk_gpio_irq_unmask,
.irq_set_type = nmk_gpio_irq_set_type,
.irq_set_wake = nmk_gpio_irq_set_wake,
.irq_startup = nmk_gpio_irq_startup,
.irq_shutdown = nmk_gpio_irq_shutdown,
.irq_print_chip = nmk_gpio_irq_print_chip,
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE,
GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
static int nmk_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct nmk_gpio_chip *nmk_chip;
struct gpio_irq_chip *girq;
bool supports_sleepmode;
struct gpio_chip *chip;
int irq;
int ret;
nmk_chip = nmk_gpio_populate_chip(dev_fwnode(dev), pdev);
if (IS_ERR(nmk_chip)) {
dev_err(dev, "could not populate nmk chip struct\n");
return PTR_ERR(nmk_chip);
}
supports_sleepmode =
device_property_read_bool(dev, "st,supports-sleepmode");
/* Correct platform device ID */
pdev->id = nmk_chip->bank;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
/*
* The virt address in nmk_chip->addr is in the nomadik register space,
* so we can simply convert the resource address, without remapping
*/
nmk_chip->sleepmode = supports_sleepmode;
spin_lock_init(&nmk_chip->lock);
chip = &nmk_chip->chip;
chip->parent = dev;
chip->request = gpiochip_generic_request;
chip->free = gpiochip_generic_free;
chip->get_direction = nmk_gpio_get_dir;
chip->direction_input = nmk_gpio_make_input;
chip->get = nmk_gpio_get_input;
chip->direction_output = nmk_gpio_make_output;
chip->set = nmk_gpio_set_output;
chip->dbg_show = nmk_gpio_dbg_show;
chip->can_sleep = false;
chip->owner = THIS_MODULE;
girq = &chip->irq;
gpio_irq_chip_set_chip(girq, &nmk_irq_chip);
girq->parent_handler = NULL;
girq->num_parents = 0;
girq->parents = NULL;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_edge_irq;
ret = devm_request_irq(dev, irq, nmk_gpio_irq_handler, IRQF_SHARED,
dev_name(dev), nmk_chip);
if (ret) {
dev_err(dev, "failed requesting IRQ\n");
return ret;
}
if (!nmk_chip->is_mobileye_soc) {
clk_enable(nmk_chip->clk);
nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
clk_disable(nmk_chip->clk);
}
ret = gpiochip_add_data(chip, nmk_chip);
if (ret)
return ret;
platform_set_drvdata(pdev, nmk_chip);
dev_info(dev, "chip registered\n");
return 0;
}
static const struct of_device_id nmk_gpio_match[] = {
{ .compatible = "st,nomadik-gpio", },
{ .compatible = "mobileye,eyeq5-gpio", },
{}
};
static struct platform_driver nmk_gpio_driver = {
.driver = {
.name = "nomadik-gpio",
.of_match_table = nmk_gpio_match,
.suppress_bind_attrs = true,
},
.probe = nmk_gpio_probe,
};
static int __init nmk_gpio_init(void)
{
return platform_driver_register(&nmk_gpio_driver);
}
subsys_initcall(nmk_gpio_init);

View File

@ -127,6 +127,24 @@ config PINCTRL_AXP209
selected.
Say Y to enable pinctrl and GPIO support for the AXP209 PMIC.
config PINCTRL_AW9523
tristate "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver"
depends on OF && I2C
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB
select GPIOLIB_IRQCHIP
select REGMAP
select REGMAP_I2C
help
The Awinic AW9523/AW9523B is a multi-function I2C GPIO
expander with PWM functionality. This driver bundles a
pinctrl driver to select the function muxing and a GPIO
driver to handle GPIO, when the GPIO function is selected.
Say yes to enable pinctrl and GPIO support for the AW9523(B).
config PINCTRL_BM1880
bool "Bitmain BM1880 Pinctrl driver"
depends on OF && (ARCH_BITMAIN || COMPILE_TEST)

View File

@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl-artpec6.o
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o
obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o
obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o
obj-$(CONFIG_PINCTRL_CY8C95X0) += pinctrl-cy8c95x0.o

View File

@ -5,10 +5,10 @@
// Copyright (c) 2023 Cirrus Logic, Inc. and
// Cirrus Logic International Semiconductor Ltd.
#include <linux/array_size.h>
#include <linux/bits.h>
#include <linux/build_bug.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/gpio/driver.h>
#include <linux/mfd/cs42l43.h>
#include <linux/mfd/cs42l43-regs.h>
@ -17,7 +17,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/string_helpers.h>
#include <linux/string_choices.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinctrl.h>
@ -276,7 +276,7 @@ static const struct pinmux_ops cs42l43_pin_mux_ops = {
static const unsigned int cs42l43_pin_drv_str_ma[] = { 1, 2, 4, 8, 9, 10, 12, 16 };
static inline int cs42l43_pin_get_drv_str(struct cs42l43_pin *priv, unsigned int pin)
static int cs42l43_pin_get_drv_str(struct cs42l43_pin *priv, unsigned int pin)
{
const struct cs42l43_pin_data *pdat = cs42l43_pin_pins[pin].drv_data;
unsigned int val;
@ -289,8 +289,8 @@ static inline int cs42l43_pin_get_drv_str(struct cs42l43_pin *priv, unsigned int
return cs42l43_pin_drv_str_ma[(val & pdat->mask) >> pdat->shift];
}
static inline int cs42l43_pin_set_drv_str(struct cs42l43_pin *priv, unsigned int pin,
unsigned int ma)
static int cs42l43_pin_set_drv_str(struct cs42l43_pin *priv, unsigned int pin,
unsigned int ma)
{
const struct cs42l43_pin_data *pdat = cs42l43_pin_pins[pin].drv_data;
int i;
@ -314,7 +314,7 @@ err:
return -EINVAL;
}
static inline int cs42l43_pin_get_db(struct cs42l43_pin *priv, unsigned int pin)
static int cs42l43_pin_get_db(struct cs42l43_pin *priv, unsigned int pin)
{
unsigned int val;
int ret;
@ -332,8 +332,8 @@ static inline int cs42l43_pin_get_db(struct cs42l43_pin *priv, unsigned int pin)
return 85; // Debounce is roughly 85uS
}
static inline int cs42l43_pin_set_db(struct cs42l43_pin *priv, unsigned int pin,
unsigned int us)
static int cs42l43_pin_set_db(struct cs42l43_pin *priv, unsigned int pin,
unsigned int us)
{
if (pin >= CS42L43_NUM_GPIOS)
return -ENOTSUPP;
@ -490,7 +490,7 @@ static void cs42l43_gpio_set(struct gpio_chip *chip, unsigned int offset, int va
int ret;
dev_dbg(priv->dev, "Setting gpio%d to %s\n",
offset + 1, value ? "high" : "low");
offset + 1, str_high_low(value));
ret = pm_runtime_resume_and_get(priv->dev);
if (ret) {

View File

@ -412,6 +412,10 @@ static int pinctrl_get_device_gpio_range(struct gpio_chip *gc,
* @pctldev: pin controller device to add the range to
* @range: the GPIO range to add
*
* DEPRECATED: Don't use this function in new code. See section 2 of
* Documentation/devicetree/bindings/gpio/gpio.txt on how to bind pinctrl and
* gpio drivers.
*
* This adds a range of GPIOs to be handled by a certain pin controller. Call
* this to register handled ranges after registering your pin controller.
*/

View File

@ -700,6 +700,15 @@ static int mt7981_drv_vbus_pins[] = { 14, };
static int mt7981_drv_vbus_funcs[] = { 1, };
/* EMMC */
static int mt7981_emmc_reset_pins[] = { 15, };
static int mt7981_emmc_reset_funcs[] = { 2, };
static int mt7981_emmc_4_pins[] = { 16, 17, 18, 19, 24, 25, };
static int mt7981_emmc_4_funcs[] = { 2, 2, 2, 2, 2, 2, };
static int mt7981_emmc_8_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, };
static int mt7981_emmc_8_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, };
static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
@ -737,6 +746,9 @@ static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, };
static int mt7981_uart1_2_pins[] = { 9, 10, };
static int mt7981_uart1_2_funcs[] = { 2, 2, };
static int mt7981_uart1_3_pins[] = { 26, 27, };
static int mt7981_uart1_3_funcs[] = { 2, 2, };
/* UART2 */
static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, };
static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, };
@ -851,6 +863,12 @@ static const struct group_desc mt7981_groups[] = {
PINCTRL_PIN_GROUP("udi", mt7981_udi),
/* @GPIO(14) DRV_VBUS(1) */
PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus),
/* @GPIO(15): EMMC_RSTB(2) */
PINCTRL_PIN_GROUP("emmc_reset", mt7981_emmc_reset),
/* @GPIO(16,17,18,19,24,25): EMMC_DATx, EMMC_CLK, EMMC_CMD */
PINCTRL_PIN_GROUP("emmc_4", mt7981_emmc_4),
/* @GPIO(16,17,18,19,20,21,22,23,24,25): EMMC_DATx, EMMC_CLK, EMMC_CMD */
PINCTRL_PIN_GROUP("emmc_8", mt7981_emmc_8),
/* @GPIO(15,25): EMMC(2) */
PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45),
/* @GPIO(16,21): SNFI(3) */
@ -871,6 +889,8 @@ static const struct group_desc mt7981_groups[] = {
PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1),
/* @GPIO(9,10): UART1(2) */
PINCTRL_PIN_GROUP("uart1_2", mt7981_uart1_2),
/* @GPIO(26,27): UART1(2) */
PINCTRL_PIN_GROUP("uart1_3", mt7981_uart1_3),
/* @GPIO(22,25): UART1(3) */
PINCTRL_PIN_GROUP("uart2_1", mt7981_uart2_1),
/* @GPIO(22,24) PTA_EXT(4) */
@ -933,7 +953,7 @@ static const struct group_desc mt7981_groups[] = {
static const char *mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", "wm_aice1_1",
"wa_aice3", "wm_aice1_2", };
static const char *mt7981_uart_groups[] = { "net_wo0_uart_txd_0", "net_wo0_uart_txd_1",
"net_wo0_uart_txd_2", "uart0", "uart1_0", "uart1_1", "uart1_2", "uart2_0",
"net_wo0_uart_txd_2", "uart0", "uart1_0", "uart1_1", "uart1_2", "uart1_3", "uart2_0",
"uart2_0_tx_rx", "uart2_1", "wm_uart_0", "wm_aurt_1", "wm_aurt_2", };
static const char *mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", };
static const char *mt7981_wdt_groups[] = { "watchdog", "watchdog1", };
@ -952,7 +972,7 @@ static const char *mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1", "u2_phy_i2c",
static const char *mt7981_pcm_groups[] = { "pcm", };
static const char *mt7981_udi_groups[] = { "udi", };
static const char *mt7981_usb_groups[] = { "drv_vbus", };
static const char *mt7981_flash_groups[] = { "emmc_45", "snfi", };
static const char *mt7981_flash_groups[] = { "emmc_reset", "emmc_4", "emmc_8", "emmc_45", "snfi", };
static const char *mt7981_ethernet_groups[] = { "smi_mdc_mdio", "gbe_ext_mdc_mdio",
"wf0_mode1", "wf0_mode3", "mt7531_int", };
static const char *mt7981_ant_groups[] = { "ant_sel", };

View File

@ -16,7 +16,7 @@
PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
_x_bits, 32, 0)
/**
/*
* enum - Locking variants of the iocfg bases
*
* MT7986 have multiple bases to program pin configuration listed as the below:

View File

@ -1198,7 +1198,6 @@ static const struct mtk_pin_reg_calc mt8186_reg_cals[PINCTRL_PIN_REG_MAX] = {
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8186_pin_dir_range),
[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8186_pin_di_range),
[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8186_pin_do_range),
[PINCTRL_PIN_REG_SR] = MTK_RANGE(mt8186_pin_dir_range),
[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8186_pin_smt_range),
[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8186_pin_ies_range),
[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8186_pin_pu_range),

View File

@ -1379,7 +1379,6 @@ static const struct mtk_pin_reg_calc mt8192_reg_cals[PINCTRL_PIN_REG_MAX] = {
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8192_pin_dir_range),
[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8192_pin_di_range),
[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8192_pin_do_range),
[PINCTRL_PIN_REG_SR] = MTK_RANGE(mt8192_pin_dir_range),
[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8192_pin_smt_range),
[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8192_pin_ies_range),
[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8192_pin_pu_range),

View File

@ -18,15 +18,15 @@ config PINCTRL_AB8505
endif
if (ARCH_U8500 || ARCH_NOMADIK)
if (ARCH_U8500 || ARCH_NOMADIK || COMPILE_TEST)
config PINCTRL_NOMADIK
bool "Nomadik pin controller driver"
depends on OF && GPIOLIB
depends on OF
select PINMUX
select PINCONF
select OF_GPIO
select GPIOLIB_IRQCHIP
select GPIOLIB
select GPIO_NOMADIK
config PINCTRL_STN8815
bool "STN8815 pin controller driver"

View File

@ -3,8 +3,9 @@
#include <linux/types.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/gpio/driver.h>
#include "pinctrl-nomadik.h"
#include <linux/gpio/gpio-nomadik.h>
/* All the pins that can be used for GPIO and some other functions */
#define _GPIO(offset) (offset)

View File

@ -3,8 +3,9 @@
#include <linux/types.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/gpio/driver.h>
#include "pinctrl-nomadik.h"
#include <linux/gpio/gpio-nomadik.h>
/* All the pins that can be used for GPIO and some other functions */
#define _GPIO(offset) (offset)

File diff suppressed because it is too large Load Diff

View File

@ -474,7 +474,7 @@ enum {
#undef WPCM450_GRP
};
static struct pingroup wpcm450_groups[] = {
static const struct pingroup wpcm450_groups[] = {
#define WPCM450_GRP(x) PINCTRL_PINGROUP(#x, x ## _pins, ARRAY_SIZE(x ## _pins))
WPCM450_GRPS
#undef WPCM450_GRP

File diff suppressed because it is too large Load Diff

View File

@ -281,10 +281,17 @@ static int da9062_pctl_probe(struct platform_device *pdev)
return devm_gpiochip_add_data(&pdev->dev, &pctl->gc, pctl);
}
static const struct of_device_id da9062_compatible_reg_id_table[] = {
{ .compatible = "dlg,da9062-gpio" },
{ }
};
MODULE_DEVICE_TABLE(of, da9062_compatible_reg_id_table);
static struct platform_driver da9062_pctl_driver = {
.probe = da9062_pctl_probe,
.driver = {
.name = "da9062-gpio",
.of_match_table = da9062_compatible_reg_id_table,
},
};
module_platform_driver(da9062_pctl_driver);

View File

@ -375,7 +375,8 @@ mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value)
static irqreturn_t mcp23s08_irq(int irq, void *data)
{
struct mcp23s08 *mcp = data;
int intcap, intcon, intf, i, gpio, gpio_orig, intcap_mask, defval;
int intcap, intcon, intf, i, gpio, gpio_orig, intcap_mask, defval, gpinten;
unsigned long int enabled_interrupts;
unsigned int child_irq;
bool intf_set, intcap_changed, gpio_bit_changed,
defval_changed, gpio_set;
@ -395,6 +396,9 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
if (mcp_read(mcp, MCP_INTCON, &intcon))
goto unlock;
if (mcp_read(mcp, MCP_GPINTEN, &gpinten))
goto unlock;
if (mcp_read(mcp, MCP_DEFVAL, &defval))
goto unlock;
@ -410,9 +414,12 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
"intcap 0x%04X intf 0x%04X gpio_orig 0x%04X gpio 0x%04X\n",
intcap, intf, gpio_orig, gpio);
for (i = 0; i < mcp->chip.ngpio; i++) {
/* We must check all of the inputs on the chip,
* otherwise we may not notice a change on >=2 pins.
enabled_interrupts = gpinten;
for_each_set_bit(i, &enabled_interrupts, mcp->chip.ngpio) {
/*
* We must check all of the inputs with enabled interrupts
* on the chip, otherwise we may not notice a change
* on more than one pin.
*
* On at least the mcp23s17, INTCAP is only updated
* one byte at a time(INTCAPA and INTCAPB are

View File

@ -1401,7 +1401,6 @@ static int ocelot_hw_set_value(struct ocelot_pinctrl *info,
if (info->pincfg) {
const struct ocelot_pincfg_data *opd = info->pincfg_data;
ret = 0;
switch (reg) {
case PINCONF_BIAS:
ret = ocelot_pincfg_clrsetbits(info, pin,

View File

@ -723,9 +723,8 @@ static int st_gpio_direction_output(struct gpio_chip *chip,
struct st_gpio_bank *bank = gpiochip_get_data(chip);
__st_gpio_set(bank, offset, value);
pinctrl_gpio_direction_output(chip, offset);
return 0;
return pinctrl_gpio_direction_output(chip, offset);
}
static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset)

View File

@ -562,7 +562,7 @@ static int zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,
const char **fgroups;
int ret, index, i;
fgroups = devm_kzalloc(dev, sizeof(*fgroups) * func->ngroups, GFP_KERNEL);
fgroups = devm_kcalloc(dev, func->ngroups, sizeof(*fgroups), GFP_KERNEL);
if (!fgroups)
return -ENOMEM;
@ -754,7 +754,7 @@ static int zynqmp_pinctrl_prepare_function_info(struct device *dev,
if (ret)
return ret;
funcs = devm_kzalloc(dev, sizeof(*funcs) * pctrl->nfuncs, GFP_KERNEL);
funcs = devm_kcalloc(dev, pctrl->nfuncs, sizeof(*funcs), GFP_KERNEL);
if (!funcs)
return -ENOMEM;
@ -768,7 +768,7 @@ static int zynqmp_pinctrl_prepare_function_info(struct device *dev,
pctrl->ngroups += funcs[i].ngroups;
}
groups = devm_kzalloc(dev, sizeof(*groups) * pctrl->ngroups, GFP_KERNEL);
groups = devm_kcalloc(dev, pctrl->ngroups, sizeof(*groups), GFP_KERNEL);
if (!groups)
return -ENOMEM;
@ -830,7 +830,7 @@ static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev,
if (ret)
return ret;
pins = devm_kzalloc(dev, sizeof(*pins) * *npins, GFP_KERNEL);
pins = devm_kcalloc(dev, *npins, sizeof(*pins), GFP_KERNEL);
if (!pins)
return -ENOMEM;

View File

@ -188,8 +188,8 @@ out_free_pin:
}
out:
if (status)
dev_err(pctldev->dev, "pin-%d (%s) status %d\n",
pin, owner, status);
dev_err_probe(pctldev->dev, status, "pin-%d (%s)\n",
pin, owner);
return status;
}
@ -441,7 +441,7 @@ int pinmux_enable_setting(const struct pinctrl_setting *setting)
pname = desc ? desc->name : "non-existing";
gname = pctlops->get_group_name(pctldev,
setting->data.mux.group);
dev_err(pctldev->dev,
dev_err_probe(pctldev->dev, ret,
"could not request pin %d (%s) from group %s "
" on device %s\n",
pins[i], pname, gname,

View File

@ -125,7 +125,7 @@ config PINCTRL_SM8550_LPASS_LPI
platform.
config PINCTRL_SM8650_LPASS_LPI
tristate "Qualcomm Technologies Inc SM8550 LPASS LPI pin controller driver"
tristate "Qualcomm Technologies Inc SM8650 LPASS LPI pin controller driver"
depends on ARM64 || COMPILE_TEST
depends on PINCTRL_LPASS_LPI
help

View File

@ -38,6 +38,7 @@ config PINCTRL_RENESAS
select PINCTRL_PFC_R8A779A0 if ARCH_R8A779A0
select PINCTRL_PFC_R8A779F0 if ARCH_R8A779F0
select PINCTRL_PFC_R8A779G0 if ARCH_R8A779G0
select PINCTRL_PFC_R8A779H0 if ARCH_R8A779H0
select PINCTRL_RZG2L if ARCH_RZG2L
select PINCTRL_RZV2M if ARCH_R9A09G011
select PINCTRL_PFC_SH7203 if CPU_SUBTYPE_SH7203
@ -154,6 +155,10 @@ config PINCTRL_PFC_R8A779G0
bool "pin control support for R-Car V4H" if COMPILE_TEST
select PINCTRL_SH_PFC
config PINCTRL_PFC_R8A779H0
bool "pin control support for R-Car V4M" if COMPILE_TEST
select PINCTRL_SH_PFC
config PINCTRL_PFC_R8A7740
bool "pin control support for R-Mobile A1" if COMPILE_TEST
select PINCTRL_SH_PFC_GPIO
@ -187,9 +192,11 @@ config PINCTRL_RZG2L
bool "pin control support for RZ/{G2L,G2UL,V2L}" if COMPILE_TEST
depends on OF
select GPIOLIB
select GPIOLIB_IRQCHIP
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select GENERIC_PINCONF
select IRQ_DOMAIN_HIERARCHY
help
This selects GPIO and pinctrl driver for Renesas RZ/{G2L,G2UL,V2L}
platforms.

View File

@ -31,6 +31,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A77995) += pfc-r8a77995.o
obj-$(CONFIG_PINCTRL_PFC_R8A779A0) += pfc-r8a779a0.o
obj-$(CONFIG_PINCTRL_PFC_R8A779F0) += pfc-r8a779f0.o
obj-$(CONFIG_PINCTRL_PFC_R8A779G0) += pfc-r8a779g0.o
obj-$(CONFIG_PINCTRL_PFC_R8A779H0) += pfc-r8a779h0.o
obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o
obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o
obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o

View File

@ -638,6 +638,12 @@ static const struct of_device_id sh_pfc_of_table[] = {
.data = &r8a779g0_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A779H0
{
.compatible = "renesas,pfc-r8a779h0",
.data = &r8a779h0_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_SH73A0
{
.compatible = "renesas,pfc-sh73a0",
@ -731,10 +737,12 @@ static int sh_pfc_resume_noirq(struct device *dev)
sh_pfc_walk_regs(pfc, sh_pfc_restore_reg);
return 0;
}
#define pm_psci_sleep_ptr(_ptr) pm_sleep_ptr(_ptr)
#else
static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; }
static int sh_pfc_suspend_noirq(struct device *dev) { return 0; }
static int sh_pfc_resume_noirq(struct device *dev) { return 0; }
#define pm_psci_sleep_ptr(_ptr) PTR_IF(false, (_ptr))
#endif /* CONFIG_ARM_PSCI_FW */
static DEFINE_NOIRQ_DEV_PM_OPS(sh_pfc_pm, sh_pfc_suspend_noirq, sh_pfc_resume_noirq);
@ -907,9 +915,11 @@ static void __init sh_pfc_check_cfg_reg(const char *drvname,
sh_pfc_err("reg 0x%x: var_field_width declares %u instead of %u bits\n",
cfg_reg->reg, rw, cfg_reg->reg_width);
if (n != cfg_reg->nr_enum_ids)
if (n != cfg_reg->nr_enum_ids) {
sh_pfc_err("reg 0x%x: enum_ids[] has %u instead of %u values\n",
cfg_reg->reg, cfg_reg->nr_enum_ids, n);
n = cfg_reg->nr_enum_ids;
}
check_enum_ids:
sh_pfc_check_reg_enums(drvname, cfg_reg->reg, cfg_reg->enum_ids, n);
@ -1415,7 +1425,7 @@ static struct platform_driver sh_pfc_driver = {
.driver = {
.name = DRV_NAME,
.of_match_table = of_match_ptr(sh_pfc_of_table),
.pm = pm_sleep_ptr(&sh_pfc_pm),
.pm = pm_psci_sleep_ptr(&sh_pfc_pm),
},
};

View File

@ -2384,6 +2384,14 @@ static const unsigned int scif_clk_mux[] = {
SCIF_CLK_MARK,
};
static const unsigned int scif_clk2_pins[] = {
/* SCIF_CLK2 */
RCAR_GP_PIN(8, 11),
};
static const unsigned int scif_clk2_mux[] = {
SCIF_CLK2_MARK,
};
/* - SSI ------------------------------------------------- */
static const unsigned int ssi_data_pins[] = {
/* SSI_SD */
@ -2694,6 +2702,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(scif4_clk),
SH_PFC_PIN_GROUP(scif4_ctrl),
SH_PFC_PIN_GROUP(scif_clk),
SH_PFC_PIN_GROUP(scif_clk2),
SH_PFC_PIN_GROUP(ssi_data),
SH_PFC_PIN_GROUP(ssi_ctrl),
@ -3015,6 +3024,10 @@ static const char * const scif_clk_groups[] = {
"scif_clk",
};
static const char * const scif_clk2_groups[] = {
"scif_clk2",
};
static const char * const ssi_groups[] = {
"ssi_data",
"ssi_ctrl",
@ -3102,6 +3115,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(scif3),
SH_PFC_FUNCTION(scif4),
SH_PFC_FUNCTION(scif_clk),
SH_PFC_FUNCTION(scif_clk2),
SH_PFC_FUNCTION(ssi),

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -322,6 +322,7 @@ extern const struct sh_pfc_soc_info r8a77995_pinmux_info;
extern const struct sh_pfc_soc_info r8a779a0_pinmux_info;
extern const struct sh_pfc_soc_info r8a779f0_pinmux_info;
extern const struct sh_pfc_soc_info r8a779g0_pinmux_info;
extern const struct sh_pfc_soc_info r8a779h0_pinmux_info;
extern const struct sh_pfc_soc_info sh7203_pinmux_info;
extern const struct sh_pfc_soc_info sh7264_pinmux_info;
extern const struct sh_pfc_soc_info sh7269_pinmux_info;

View File

@ -1,16 +1,77 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef PINCTRL_PINCTRL_NOMADIK_H
#define PINCTRL_PINCTRL_NOMADIK_H
#ifndef __LINUX_GPIO_NOMADIK_H
#define __LINUX_GPIO_NOMADIK_H
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pinctrl/pinctrl.h>
struct fwnode_handle;
/* Package definitions */
#define PINCTRL_NMK_STN8815 0
#define PINCTRL_NMK_DB8500 1
#define GPIO_BLOCK_SHIFT 5
#define NMK_GPIO_PER_CHIP BIT(GPIO_BLOCK_SHIFT)
#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP)
/* Register in the logic block */
#define NMK_GPIO_DAT 0x00
#define NMK_GPIO_DATS 0x04
#define NMK_GPIO_DATC 0x08
#define NMK_GPIO_PDIS 0x0c
#define NMK_GPIO_DIR 0x10
#define NMK_GPIO_DIRS 0x14
#define NMK_GPIO_DIRC 0x18
#define NMK_GPIO_SLPC 0x1c
#define NMK_GPIO_AFSLA 0x20
#define NMK_GPIO_AFSLB 0x24
#define NMK_GPIO_LOWEMI 0x28
#define NMK_GPIO_RIMSC 0x40
#define NMK_GPIO_FIMSC 0x44
#define NMK_GPIO_IS 0x48
#define NMK_GPIO_IC 0x4c
#define NMK_GPIO_RWIMSC 0x50
#define NMK_GPIO_FWIMSC 0x54
#define NMK_GPIO_WKS 0x58
/* These appear in DB8540 and later ASICs */
#define NMK_GPIO_EDGELEVEL 0x5C
#define NMK_GPIO_LEVEL 0x60
/* Pull up/down values */
enum nmk_gpio_pull {
NMK_GPIO_PULL_NONE,
NMK_GPIO_PULL_UP,
NMK_GPIO_PULL_DOWN,
};
/* Sleep mode */
enum nmk_gpio_slpm {
NMK_GPIO_SLPM_INPUT,
NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
NMK_GPIO_SLPM_NOCHANGE,
NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
};
struct nmk_gpio_chip {
struct gpio_chip chip;
void __iomem *addr;
struct clk *clk;
unsigned int bank;
void (*set_ioforce)(bool enable);
spinlock_t lock;
bool sleepmode;
bool is_mobileye_soc;
/* Keep track of configured edges */
u32 edge_rising;
u32 edge_falling;
u32 real_wake;
u32 rwimsc;
u32 fwimsc;
u32 rimsc;
u32 fimsc;
u32 pull_up;
u32 lowemi;
};
/* Alternate functions: function C is set in hw by setting both A and B */
#define NMK_GPIO_ALT_GPIO 0
#define NMK_GPIO_ALT_A 1
@ -104,7 +165,7 @@ struct prcm_gpiocr_altcx_pin_desc {
struct nmk_function {
const char *name;
const char * const *groups;
unsigned ngroups;
unsigned int ngroups;
};
/**
@ -141,13 +202,13 @@ struct nmk_pingroup {
*/
struct nmk_pinctrl_soc_data {
const struct pinctrl_pin_desc *pins;
unsigned npins;
unsigned int npins;
const struct nmk_function *functions;
unsigned nfunctions;
unsigned int nfunctions;
const struct nmk_pingroup *groups;
unsigned ngroups;
unsigned int ngroups;
const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
unsigned npins_altcx;
unsigned int npins_altcx;
const u16 *prcm_gpiocr_registers;
};
@ -177,4 +238,57 @@ nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
#endif
#endif /* PINCTRL_PINCTRL_NOMADIK_H */
#ifdef CONFIG_PINCTRL_DB8540
void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc);
#else
static inline void
nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
{
}
#endif
struct platform_device;
#ifdef CONFIG_DEBUG_FS
/*
* Symbols declared in gpio-nomadik used by pinctrl-nomadik. If pinctrl-nomadik
* is enabled, then gpio-nomadik is enabled as well; the reverse if not always
* true.
*/
void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev,
struct gpio_chip *chip, unsigned int offset,
unsigned int gpio);
#else
static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
struct pinctrl_dev *pctldev,
struct gpio_chip *chip,
unsigned int offset,
unsigned int gpio)
{
}
#endif
void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
unsigned int offset, int val);
void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset,
enum nmk_gpio_slpm mode);
struct nmk_gpio_chip *nmk_gpio_populate_chip(struct fwnode_handle *fwnode,
struct platform_device *pdev);
/* Symbols declared in pinctrl-nomadik used by gpio-nomadik. */
#ifdef CONFIG_PINCTRL_NOMADIK
extern struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
extern spinlock_t nmk_gpio_slpm_lock;
int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev,
int gpio);
#endif
#endif /* __LINUX_GPIO_NOMADIK_H */