This is the bulk of pin control changes for the v5.5 kernel

series:
 
 Core changes:
 
 - Avoid taking direct references to device tree-supplied
   device names: these may changed at runtime under certain
   circumstances to kstrdup them.
 
 GPIO related:
 
 - Work is ongoing to move to passing the irqchip along as a
   templated struct gpio_irq_chip when adding a standard
   gpiolib-based irqchip to a GPIO controller, a few patches
   in this cycle switches a few pin control drivers over to
   using this method.
 
 New hardware support:
 
 - Intel Lightning Mountain SoC pin controller and GPIO
   support, a first Intel platform to use device tree rather
   than ACPI to configure the system. News reports says that
   this SoC is a network processor.
 
 - Qualcomm MSM8976 and MSM8956
 
 - Qualcomm PMIC GPIO now also supports PM6150 and PM6150L
 
 - Qualcomm SPMI MPP and SPMI GPIO for PM8950 and PMI8950
 
 - Rockchip RK3308
 
 - Renesas R8A77961
 
 - Allwinner Meson-A1
 
 Driver improvements:
 
 - get_multiple and set_multiple support for the AT91-PIO4 driver.
 
 - Convert Qualcomm SSBI GPIO to use the hierarchical IRQ helpers
   in the GPIOlib irqchip.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAl3dPAMACgkQQRCzN7AZ
 XXOckA/+K8++XpN15+DR3tWD6QOKU1pXH9Mam/41yDi5eHJZ8TOTZA9V3rXvy53e
 6QYj0OOXnbLm0UhcbJRA2lOPFLHlaK3aZExfQcNT4U/qklZxyteJ8fxNFDzADqAd
 7FrrdrWBW8bJw4GwGeV0jwjJENUAQ2WJ3W9rHX3WDoABIMEqxBmZtPmcK+HpnZFW
 P6Gt0kMDS70IE4W+2IzXhpKWE41IwH6WV8QqOnCN1aIwmI9KhsFJ3WlbiowcRZoS
 yyDgLryt5gEvSIZNzG0rnOC+Mn21gQn3KyuQdGalm4OfW2TT7IuPXJF/ZT502lGv
 ypIhdjxwSIn4OxexS80j5HG8p/RNP2qjK3z8WBwh+IVUepPSV89kuk1lzH66B8VO
 FXnH+lhd1WJTttBkcjHOO/pkK09WTO1MOyu+iYXZQ/cYJADCHL/KHvK30unuvrL4
 J/npJbOzxzbxor/132hrjJCFo9VHDViInWrt4lC2MaBi3gBcsgukROBYIqCBHO7T
 UtdemwB056sYr3WtwAsJ5GsBkFhhFmWUBf5i/hWGFT3vcop55Lnlo4HZ5ipSxjIc
 1NAuymO/xyH6uDhQhfN7h7Dxc8fLYmslvOyiCROVxBBnzP0Am3UAb/fL7RXztHle
 v1E4786GH/IGL6Q1q2U2NTNfAm2CPdB/yF2pN1DluIM+U1spAKU=
 =uPLY
 -----END PGP SIGNATURE-----

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

Pull pin control updates from Linus Walleij:
 "This is the bulk of pin control changes for v5.5.

  It is pretty much business as usual, the most interesting thing I
  think is the pin controller for a new Intel chip called Lightning
  Mountain, which is according to news reports some kind of embedded
  network processor and what is surprising about it is that Intel have
  decided to use device tree to describe the system rather than ACPI
  that they have traditionally favored.

  Core changes:

   - Avoid taking direct references to device tree-supplied device
     names: these may changed at runtime under certain circumstances to
     kstrdup them.

  GPIO related:

   - Work is ongoing to move to passing the irqchip along as a templated
     struct gpio_irq_chip when adding a standard gpiolib-based irqchip
     to a GPIO controller, a few patches in this cycle switches a few
     pin control drivers over to using this method.

  New hardware support:

   - Intel Lightning Mountain SoC pin controller and GPIO support, a
     first Intel platform to use device tree rather than ACPI to
     configure the system. News reports says that this SoC is a network
     processor.

   - Qualcomm MSM8976 and MSM8956

   - Qualcomm PMIC GPIO now also supports PM6150 and PM6150L

   - Qualcomm SPMI MPP and SPMI GPIO for PM8950 and PMI8950

   - Rockchip RK3308

   - Renesas R8A77961

   - Allwinner Meson-A1

  Driver improvements:

   - get_multiple and set_multiple support for the AT91-PIO4 driver.

   - Convert Qualcomm SSBI GPIO to use the hierarchical IRQ helpers in
     the GPIOlib irqchip"

* tag 'pinctrl-v5.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (93 commits)
  pinctrl: ingenic: Add OTG VBUS pin for the JZ4770
  pinctrl: ingenic: Handle PIN_CONFIG_OUTPUT config
  pinctrl: Fix Kconfig indentation
  pinctrl: lewisburg: Update pin list according to v1.1v6
  MAINTAINERS: Replace my email by one @kernel.org
  pinctrl: armada-37xx: Fix irq mask access in armada_37xx_irq_set_type()
  dt-bindings: pinctrl: intel: Add for new SoC
  pinctrl: Add pinmux & GPIO controller driver for a new SoC
  pinctrl: rza1: remove unnecessary static inline function
  pinctrl: meson: add pinctrl driver support for Meson-A1 SoC
  pinctrl: meson: add a new callback for SoCs fixup
  pinctrl: nomadik: db8500: Add mc0_a_2 pin group without direction control
  dt-bindings: pinctrl: Convert generic pin mux and config properties to schema
  pinctrl: cherryview: Missed type change to unsigned int
  pinctrl: intel: Missed type change to unsigned int
  pinctrl: use devm_platform_ioremap_resource() to simplify code
  pinctrl: just return if no valid maps
  dt-bindings: pinctrl: qcom-pmic-mpp: Add support for PM/PMI8950
  pinctrl: qcom: spmi-mpp: Add PM/PMI8950 compatible strings
  dt-bindings: pinctrl: qcom-pmic-gpio: Add support for PM/PMI8950
  ...
This commit is contained in:
Linus Torvalds 2019-11-27 10:00:33 -08:00
commit dc5fa46568
113 changed files with 6416 additions and 1664 deletions

View File

@ -0,0 +1,243 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/allwinner,sun4i-a10-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Allwinner A10 Pin Controller Device Tree Bindings
maintainers:
- Chen-Yu Tsai <wens@csie.org>
- Maxime Ripard <maxime.ripard@bootlin.com>
properties:
"#gpio-cells":
const: 3
description:
GPIO consumers must use three arguments, first the number of the
bank, then the pin number inside that bank, and finally the GPIO
flags.
"#interrupt-cells":
const: 3
description:
Interrupts consumers must use three arguments, first the number
of the bank, then the pin number inside that bank, and finally
the interrupts flags.
compatible:
enum:
- allwinner,sun4i-a10-pinctrl
- allwinner,sun5i-a10s-pinctrl
- allwinner,sun5i-a13-pinctrl
- allwinner,sun6i-a31-pinctrl
- allwinner,sun6i-a31-r-pinctrl
- allwinner,sun6i-a31s-pinctrl
- allwinner,sun7i-a20-pinctrl
- allwinner,sun8i-a23-pinctrl
- allwinner,sun8i-a23-r-pinctrl
- allwinner,sun8i-a33-pinctrl
- allwinner,sun8i-a83t-pinctrl
- allwinner,sun8i-a83t-r-pinctrl
- allwinner,sun8i-h3-pinctrl
- allwinner,sun8i-h3-r-pinctrl
- allwinner,sun8i-r40-pinctrl
- allwinner,sun8i-v3-pinctrl
- allwinner,sun8i-v3s-pinctrl
- allwinner,sun9i-a80-pinctrl
- allwinner,sun9i-a80-r-pinctrl
- allwinner,sun50i-a64-pinctrl
- allwinner,sun50i-a64-r-pinctrl
- allwinner,sun50i-h5-pinctrl
- allwinner,sun50i-h6-pinctrl
- allwinner,sun50i-h6-r-pinctrl
- allwinner,suniv-f1c100s-pinctrl
- nextthing,gr8-pinctrl
reg:
maxItems: 1
interrupts:
minItems: 1
maxItems: 5
description:
One interrupt per external interrupt bank supported on the
controller, sorted by bank number ascending order.
clocks:
items:
- description: Bus Clock
- description: High Frequency Oscillator
- description: Low Frequency Oscillator
clock-names:
items:
- const: apb
- const: hosc
- const: losc
resets:
maxItems: 1
gpio-controller: true
interrupt-controller: true
gpio-line-names: true
input-debounce:
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-array
- minItems: 1
maxItems: 5
description:
Debouncing periods in microseconds, one period per interrupt
bank found in the controller
patternProperties:
# It's pretty scary, but the basic idea is that:
# - One node name can start with either s- or r- for PRCM nodes,
# - Then, the name itself can be any repetition of <string>- (to
# accomodate with nodes like uart4-rts-cts-pins), where each
# string can be either starting with 'p' but in a string longer
# than 3, or something that doesn't start with 'p',
# - Then, the bank name is optional and will be between pa and pg,
# pl or pm. Some pins groups that have several options will have
# the pin numbers then,
# - Finally, the name will end with either -pin or pins.
"^([rs]-)?(([a-z0-9]{3,}|[a-oq-z][a-z0-9]*?)?-)+?(p[a-ilm][0-9]*?-)??pins?$":
type: object
properties:
pins: true
function: true
bias-disable: true
bias-pull-up: true
bias-pull-down: true
drive-strength:
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [ 10, 20, 30, 40 ]
required:
- pins
- function
additionalProperties: false
"^vcc-p[a-hlm]-supply$":
description:
Power supplies for pin banks.
required:
- "#gpio-cells"
- "#interrupt-cells"
- compatible
- reg
- interrupts
- clocks
- clock-names
- gpio-controller
- interrupt-controller
allOf:
# FIXME: We should have the pin bank supplies here, but not a lot of
# boards are defining it at the moment so it would generate a lot of
# warnings.
- if:
properties:
compatible:
enum:
- allwinner,sun9i-a80-pinctrl
then:
properties:
interrupts:
minItems: 5
maxItems: 5
else:
if:
properties:
compatible:
enum:
- allwinner,sun6i-a31-pinctrl
- allwinner,sun6i-a31s-pinctrl
- allwinner,sun50i-h6-pinctrl
then:
properties:
interrupts:
minItems: 4
maxItems: 4
else:
if:
properties:
compatible:
enum:
- allwinner,sun8i-a23-pinctrl
- allwinner,sun8i-a83t-pinctrl
- allwinner,sun50i-a64-pinctrl
- allwinner,sun50i-h5-pinctrl
- allwinner,suniv-f1c100s-pinctrl
then:
properties:
interrupts:
minItems: 3
maxItems: 3
else:
if:
properties:
compatible:
enum:
- allwinner,sun6i-a31-r-pinctrl
- allwinner,sun8i-a33-pinctrl
- allwinner,sun8i-h3-pinctrl
- allwinner,sun8i-v3-pinctrl
- allwinner,sun8i-v3s-pinctrl
- allwinner,sun9i-a80-r-pinctrl
- allwinner,sun50i-h6-r-pinctrl
then:
properties:
interrupts:
minItems: 2
maxItems: 2
else:
properties:
interrupts:
minItems: 1
maxItems: 1
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/sun5i-ccu.h>
pio: pinctrl@1c20800 {
compatible = "allwinner,sun5i-a13-pinctrl";
reg = <0x01c20800 0x400>;
interrupts = <28>;
clocks = <&ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
#gpio-cells = <3>;
uart1_pe_pins: uart1-pe-pins {
pins = "PE10", "PE11";
function = "uart1";
};
uart1_pg_pins: uart1-pg-pins {
pins = "PG3", "PG4";
function = "uart1";
};
};

View File

@ -1,164 +0,0 @@
* Allwinner A1X Pin Controller
The pins controlled by sunXi pin controller are organized in banks,
each bank has 32 pins. Each pin has 7 multiplexing functions, with
the first two functions being GPIO in and out. The configuration on
the pins includes drive strength and pull-up.
Required properties:
- compatible: Should be one of the following (depending on your SoC):
"allwinner,sun4i-a10-pinctrl"
"allwinner,sun5i-a10s-pinctrl"
"allwinner,sun5i-a13-pinctrl"
"allwinner,sun6i-a31-pinctrl"
"allwinner,sun6i-a31s-pinctrl"
"allwinner,sun6i-a31-r-pinctrl"
"allwinner,sun7i-a20-pinctrl"
"allwinner,sun8i-a23-pinctrl"
"allwinner,sun8i-a23-r-pinctrl"
"allwinner,sun8i-a33-pinctrl"
"allwinner,sun9i-a80-pinctrl"
"allwinner,sun9i-a80-r-pinctrl"
"allwinner,sun8i-a83t-pinctrl"
"allwinner,sun8i-a83t-r-pinctrl"
"allwinner,sun8i-h3-pinctrl"
"allwinner,sun8i-h3-r-pinctrl"
"allwinner,sun8i-r40-pinctrl"
"allwinner,sun8i-v3-pinctrl"
"allwinner,sun8i-v3s-pinctrl"
"allwinner,sun50i-a64-pinctrl"
"allwinner,sun50i-a64-r-pinctrl"
"allwinner,sun50i-h5-pinctrl"
"allwinner,sun50i-h6-pinctrl"
"allwinner,sun50i-h6-r-pinctrl"
"allwinner,suniv-f1c100s-pinctrl"
"nextthing,gr8-pinctrl"
- reg: Should contain the register physical address and length for the
pin controller.
- clocks: phandle to the clocks feeding the pin controller:
- "apb": the gated APB parent clock
- "hosc": the high frequency oscillator in the system
- "losc": the low frequency oscillator in the system
Note: For backward compatibility reasons, the hosc and losc clocks are only
required if you need to use the optional input-debounce property. Any new
device tree should set them.
Each pin bank, depending on the SoC, can have an associated regulator:
- vcc-pa-supply: for the A10, A20, A31, A31s, A80 and R40 SoCs
- vcc-pb-supply: for the A31, A31s, A80 and V3s SoCs
- vcc-pc-supply: for the A10, A20, A31, A31s, A64, A80, H5, R40 and V3s SoCs
- vcc-pd-supply: for the A23, A31, A31s, A64, A80, A83t, H3, H5 and R40 SoCs
- vcc-pe-supply: for the A10, A20, A31, A31s, A64, A80, R40 and V3s SoCs
- vcc-pf-supply: for the A10, A20, A31, A31s, A80, R40 and V3s SoCs
- vcc-pg-supply: for the A10, A20, A31, A31s, A64, A80, H3, H5, R40 and V3s SoCs
- vcc-ph-supply: for the A31, A31s and A80 SoCs
- vcc-pl-supply: for the r-pinctrl of the A64, A80 and A83t SoCs
- vcc-pm-supply: for the r-pinctrl of the A31, A31s and A80 SoCs
Optional properties:
- input-debounce: Array of debouncing periods in microseconds. One period per
irq bank found in the controller. 0 if no setup required.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices.
A pinctrl node should contain at least one subnodes representing the
pinctrl groups available on the machine. Each subnode will list the
pins it needs, and how they should be configured, with regard to muxer
configuration, drive strength and pullups. If one of these options is
not set, its actual value will be unspecified.
Allwinner A1X Pin Controller supports the generic pin multiplexing and
configuration bindings. For details on each properties, you can refer to
./pinctrl-bindings.txt.
Required sub-node properties:
- pins
- function
Optional sub-node properties:
- bias-disable
- bias-pull-up
- bias-pull-down
- drive-strength
*** Deprecated pin configuration and multiplexing binding
Required subnode-properties:
- allwinner,pins: List of strings containing the pin name.
- allwinner,function: Function to mux the pins listed above to.
Optional subnode-properties:
- allwinner,drive: Integer. Represents the current sent to the pin
0: 10 mA
1: 20 mA
2: 30 mA
3: 40 mA
- allwinner,pull: Integer.
0: No resistor
1: Pull-up resistor
2: Pull-down resistor
Examples:
pio: pinctrl@1c20800 {
compatible = "allwinner,sun5i-a13-pinctrl";
reg = <0x01c20800 0x400>;
#address-cells = <1>;
#size-cells = <0>;
uart1_pins_a: uart1@0 {
allwinner,pins = "PE10", "PE11";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
uart1_pins_b: uart1@1 {
allwinner,pins = "PG3", "PG4";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
};
GPIO and interrupt controller
-----------------------------
This hardware also acts as a GPIO controller and an interrupt
controller.
Consumers that would want to refer to one or the other (or both)
should provide through the usual *-gpios and interrupts properties a
cell with 3 arguments, first the number of the bank, then the pin
inside that bank, and finally the flags for the GPIO/interrupts.
Example:
xio: gpio@38 {
compatible = "nxp,pcf8574a";
reg = <0x38>;
gpio-controller;
#gpio-cells = <2>;
interrupt-parent = <&pio>;
interrupts = <6 0 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <2>;
};
reg_usb1_vbus: usb1-vbus {
compatible = "regulator-fixed";
regulator-name = "usb1-vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>;
};

View File

@ -0,0 +1,116 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/bindings/pinctrl/intel,lgm-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Intel Lightning Mountain SoC pinmux & GPIO controller binding
maintainers:
- Rahul Tanwar <rahul.tanwar@linux.intel.com>
description: |
Pinmux & GPIO controller controls pin multiplexing & configuration including
GPIO function selection & GPIO attributes configuration.
Please refer to [1] for details of the common pinctrl bindings used by the
client devices.
[1] Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
properties:
compatible:
const: intel,lgm-io
reg:
maxItems: 1
# Client device subnode's properties
patternProperties:
'-pins$':
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
properties:
function:
$ref: /schemas/types.yaml#/definitions/string
description:
A string containing the name of the function to mux to the group.
groups:
$ref: /schemas/types.yaml#/definitions/string-array
description:
An array of strings identifying the list of groups.
pins:
$ref: /schemas/types.yaml#/definitions/uint32-array
description:
List of pins to select with this function.
pinmux:
description: The applicable mux group.
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32-array"
bias-pull-up:
type: boolean
bias-pull-down:
type: boolean
drive-strength:
description: |
Selects the drive strength for the specified pins in mA.
0: 2 mA
1: 4 mA
2: 8 mA
3: 12 mA
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [0, 1, 2, 3]
slew-rate:
type: boolean
description: |
Sets slew rate for specified pins.
0: slow slew
1: fast slew
drive-open-drain:
type: boolean
output-enable:
type: boolean
required:
- function
- groups
additionalProperties: false
required:
- compatible
- reg
additionalProperties: false
examples:
# Pinmux controller node
- |
pinctrl: pinctrl@e2880000 {
compatible = "intel,lgm-pinctrl";
reg = <0xe2880000 0x100000>;
uart0-pins {
pins = <64>, /* UART_RX0 */
<65>; /* UART_TX0 */
function = "CONSOLE_UART0";
pinmux = <1>,
<1>;
groups = "CONSOLE_UART0";
};
};
...

View File

@ -15,6 +15,7 @@ Required properties for the root node:
"amlogic,meson-axg-aobus-pinctrl"
"amlogic,meson-g12a-periphs-pinctrl"
"amlogic,meson-g12a-aobus-pinctrl"
"amlogic,meson-a1-periphs-pinctrl"
- reg: address and size of registers controlling irq functionality
=== GPIO sub-nodes ===

View File

@ -0,0 +1,140 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/pincfg-node.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Generic pin configuration node schema
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
description:
Many data items that are represented in a pin configuration node are common
and generic. Pin control bindings should use the properties defined below
where they are applicable; not all of these properties are relevant or useful
for all hardware or binding structures. Each individual binding document
should state which of these generic properties, if any, are used, and the
structure of the DT nodes that contain these properties.
properties:
bias-disable:
type: boolean
description: disable any pin bias
bias-high-impedance:
type: boolean
description: high impedance mode ("third-state", "floating")
bias-bus-hold:
type: boolean
description: latch weakly
bias-pull-up:
oneOf:
- type: boolean
- $ref: /schemas/types.yaml#/definitions/uint32
description: pull up the pin. Takes as optional argument on hardware
supporting it the pull strength in Ohm.
bias-pull-down:
oneOf:
- type: boolean
- $ref: /schemas/types.yaml#/definitions/uint32
description: pull down the pin. Takes as optional argument on hardware
supporting it the pull strength in Ohm.
bias-pull-pin-default:
oneOf:
- type: boolean
- $ref: /schemas/types.yaml#/definitions/uint32
description: use pin-default pull state. Takes as optional argument on
hardware supporting it the pull strength in Ohm.
drive-push-pull:
type: boolean
description: drive actively high and low
drive-open-drain:
type: boolean
description: drive with open drain
drive-open-source:
type: boolean
description: drive with open source
drive-strength:
$ref: /schemas/types.yaml#/definitions/uint32
description: sink or source at most X mA
drive-strength-microamp:
description: sink or source at most X uA
input-enable:
type: boolean
description: enable input on pin (no effect on output, such as
enabling an input buffer)
input-disable:
type: boolean
description: disable input on pin (no effect on output, such as
disabling an input buffer)
input-schmitt-enable:
type: boolean
description: enable schmitt-trigger mode
input-schmitt-disable:
type: boolean
description: disable schmitt-trigger mode
input-debounce:
$ref: /schemas/types.yaml#/definitions/uint32
description: Takes the debounce time in usec as argument or 0 to disable
debouncing
power-source:
$ref: /schemas/types.yaml#/definitions/uint32
description: select between different power supplies
low-power-enable:
type: boolean
description: enable low power mode
low-power-disable:
type: boolean
description: disable low power mode
output-disable:
type: boolean
description: disable output on a pin (such as disable an output buffer)
output-enable:
type: boolean
description: enable output on a pin without actively driving it
(such as enabling an output buffer)
output-low:
type: boolean
description: set the pin to output mode with low level
output-high:
type: boolean
description: set the pin to output mode with high level
sleep-hardware-state:
type: boolean
description: indicate this is sleep related state which will be
programmed into the registers for the sleep state.
slew-rate:
$ref: /schemas/types.yaml#/definitions/uint32
description: set the slew rate
skew-delay:
$ref: /schemas/types.yaml#/definitions/uint32
description:
this affects the expected clock skew on input pins
and the delay before latching a value to an output
pin. Typically indicates how many double-inverters are
used to delay the signal.

View File

@ -141,196 +141,8 @@ controller device.
== Generic pin multiplexing node content ==
pin multiplexing nodes:
function - the mux function to select
groups - the list of groups to select with this function
(either this or "pins" must be specified)
pins - the list of pins to select with this function (either
this or "groups" must be specified)
Example:
state_0_node_a {
uart0 {
function = "uart0";
groups = "u0rxtx", "u0rtscts";
};
};
state_1_node_a {
spi0 {
function = "spi0";
groups = "spi0pins";
};
};
state_2_node_a {
function = "i2c0";
pins = "mfio29", "mfio30";
};
Optionally an alternative binding can be used if more suitable depending on the
pin controller hardware. For hardware where there is a large number of identical
pin controller instances, naming each pin and function can easily become
unmaintainable. This is especially the case if the same controller is used for
different pins and functions depending on the SoC revision and packaging.
For cases like this, the pin controller driver may use pinctrl-pin-array helper
binding with a hardware based index and a number of pin configuration values:
pincontroller {
... /* Standard DT properties for the device itself elided */
#pinctrl-cells = <2>;
state_0_node_a {
pinctrl-pin-array = <
0 A_DELAY_PS(0) G_DELAY_PS(120)
4 A_DELAY_PS(0) G_DELAY_PS(360)
...
>;
};
...
};
Above #pinctrl-cells specifies the number of value cells in addition to the
index of the registers. This is similar to the interrupts-extended binding with
one exception. There is no need to specify the phandle for each entry as that
is already known as the defined pins are always children of the pin controller
node. Further having the phandle pointing to another pin controller would not
currently work as the pinctrl framework uses named modes to group pins for each
pin control device.
The index for pinctrl-pin-array must relate to the hardware for the pinctrl
registers, and must not be a virtual index of pin instances. The reason for
this is to avoid mapping of the index in the dts files and the pin controller
driver as it can change.
For hardware where pin multiplexing configurations have to be specified for
each single pin the number of required sub-nodes containing "pin" and
"function" properties can quickly escalate and become hard to write and
maintain.
For cases like this, the pin controller driver may use the pinmux helper
property, where the pin identifier is provided with mux configuration settings
in a pinmux group. A pinmux group consists of the pin identifier and mux
settings represented as a single integer or an array of integers.
The pinmux property accepts an array of pinmux groups, each of them describing
a single pin multiplexing configuration.
pincontroller {
state_0_node_a {
pinmux = <PINMUX_GROUP>, <PINMUX_GROUP>, ...;
};
};
Each individual pin controller driver bindings documentation shall specify
how pin IDs and pin multiplexing configuration are defined and assembled
together in a pinmux group.
See pinmux-node.yaml
== Generic pin configuration node content ==
Many data items that are represented in a pin configuration node are common
and generic. Pin control bindings should use the properties defined below
where they are applicable; not all of these properties are relevant or useful
for all hardware or binding structures. Each individual binding document
should state which of these generic properties, if any, are used, and the
structure of the DT nodes that contain these properties.
Supported generic properties are:
pins - the list of pins that properties in the node
apply to (either this, "group" or "pinmux" has to be
specified)
group - the group to apply the properties to, if the driver
supports configuration of whole groups rather than
individual pins (either this, "pins" or "pinmux" has
to be specified)
pinmux - the list of numeric pin ids and their mux settings
that properties in the node apply to (either this,
"pins" or "groups" have to be specified)
bias-disable - disable any pin bias
bias-high-impedance - high impedance mode ("third-state", "floating")
bias-bus-hold - latch weakly
bias-pull-up - pull up the pin
bias-pull-down - pull down the pin
bias-pull-pin-default - use pin-default pull state
drive-push-pull - drive actively high and low
drive-open-drain - drive with open drain
drive-open-source - drive with open source
drive-strength - sink or source at most X mA
drive-strength-microamp - sink or source at most X uA
input-enable - enable input on pin (no effect on output, such as
enabling an input buffer)
input-disable - disable input on pin (no effect on output, such as
disabling an input buffer)
input-schmitt-enable - enable schmitt-trigger mode
input-schmitt-disable - disable schmitt-trigger mode
input-debounce - debounce mode with debound time X
power-source - select between different power supplies
low-power-enable - enable low power mode
low-power-disable - disable low power mode
output-disable - disable output on a pin (such as disable an output
buffer)
output-enable - enable output on a pin without actively driving it
(such as enabling an output buffer)
output-low - set the pin to output mode with low level
output-high - set the pin to output mode with high level
sleep-hardware-state - indicate this is sleep related state which will be programmed
into the registers for the sleep state.
slew-rate - set the slew rate
skew-delay - this affects the expected clock skew on input pins
and the delay before latching a value to an output
pin. Typically indicates how many double-inverters are
used to delay the signal.
For example:
state_0_node_a {
cts_rxd {
pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
bias-pull-up;
};
};
state_1_node_a {
rts_txd {
pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
output-high;
};
};
state_2_node_a {
foo {
group = "foo-group";
bias-pull-up;
};
};
state_3_node_a {
mux {
pinmux = <GPIOx_PINm_MUXn>, <GPIOx_PINj_MUXk)>;
input-enable;
};
};
Some of the generic properties take arguments. For those that do, the
arguments are described below.
- pins takes a list of pin names or IDs as a required argument. The specific
binding for the hardware defines:
- Whether the entries are integers or strings, and their meaning.
- pinmux takes a list of pin IDs and mux settings as required argument. The
specific bindings for the hardware defines:
- How pin IDs and mux settings are defined and assembled together in a single
integer or an array of integers.
- bias-pull-up, -down and -pin-default take as optional argument on hardware
supporting it the pull strength in Ohm. bias-disable will disable the pull.
- drive-strength takes as argument the target strength in mA.
- drive-strength-microamp takes as argument the target strength in uA.
- input-debounce takes the debounce time in usec as argument
or 0 to disable debouncing
More in-depth documentation on these parameters can be found in
<include/linux/pinctrl/pinconf-generic.h>
See pincfg-node.yaml

View File

@ -0,0 +1,132 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/pinmux-node.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Generic pin multiplexing node schema
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
description: |
The contents of the pin configuration child nodes are defined by the binding
for the individual pin controller device. The pin configuration nodes need not
be direct children of the pin controller device; they may be grandchildren,
for example. Whether this is legal, and whether there is any interaction
between the child and intermediate parent nodes, is again defined entirely by
the binding for the individual pin controller device.
While not required to be used, there are 3 generic forms of pin muxing nodes
which pin controller devices can use.
pin multiplexing nodes:
Example:
state_0_node_a {
uart0 {
function = "uart0";
groups = "u0rxtx", "u0rtscts";
};
};
state_1_node_a {
spi0 {
function = "spi0";
groups = "spi0pins";
};
};
state_2_node_a {
function = "i2c0";
pins = "mfio29", "mfio30";
};
Optionally an alternative binding can be used if more suitable depending on the
pin controller hardware. For hardware where there is a large number of identical
pin controller instances, naming each pin and function can easily become
unmaintainable. This is especially the case if the same controller is used for
different pins and functions depending on the SoC revision and packaging.
For cases like this, the pin controller driver may use pinctrl-pin-array helper
binding with a hardware based index and a number of pin configuration values:
pincontroller {
... /* Standard DT properties for the device itself elided */
#pinctrl-cells = <2>;
state_0_node_a {
pinctrl-pin-array = <
0 A_DELAY_PS(0) G_DELAY_PS(120)
4 A_DELAY_PS(0) G_DELAY_PS(360)
...
>;
};
...
};
Above #pinctrl-cells specifies the number of value cells in addition to the
index of the registers. This is similar to the interrupts-extended binding with
one exception. There is no need to specify the phandle for each entry as that
is already known as the defined pins are always children of the pin controller
node. Further having the phandle pointing to another pin controller would not
currently work as the pinctrl framework uses named modes to group pins for each
pin control device.
The index for pinctrl-pin-array must relate to the hardware for the pinctrl
registers, and must not be a virtual index of pin instances. The reason for
this is to avoid mapping of the index in the dts files and the pin controller
driver as it can change.
For hardware where pin multiplexing configurations have to be specified for
each single pin the number of required sub-nodes containing "pin" and
"function" properties can quickly escalate and become hard to write and
maintain.
For cases like this, the pin controller driver may use the pinmux helper
property, where the pin identifier is provided with mux configuration settings
in a pinmux group. A pinmux group consists of the pin identifier and mux
settings represented as a single integer or an array of integers.
The pinmux property accepts an array of pinmux groups, each of them describing
a single pin multiplexing configuration.
pincontroller {
state_0_node_a {
pinmux = <PINMUX_GROUP>, <PINMUX_GROUP>, ...;
};
};
Each individual pin controller driver bindings documentation shall specify
how pin IDs and pin multiplexing configuration are defined and assembled
together in a pinmux group.
properties:
function:
$ref: /schemas/types.yaml#/definitions/string
description: The mux function to select
pins:
oneOf:
- $ref: /schemas/types.yaml#/definitions/uint32-array
- $ref: /schemas/types.yaml#/definitions/string-array
description:
The list of pin identifiers that properties in the node apply to. The
specific binding for the hardware defines whether the entries are integers
or strings, and their meaning.
group:
$ref: /schemas/types.yaml#/definitions/string-array
description:
the group to apply the properties to, if the driver supports
configuration of whole groups rather than individual pins (either
this, "pins" or "pinmux" has to be specified)
pinmux:
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-array
description:
The list of numeric pin ids and their mux settings that properties in the
node apply to (either this, "pins" or "groups" have to be specified)
pinctrl-pin-array:
$ref: /schemas/types.yaml#/definitions/uint32-array

View File

@ -0,0 +1,183 @@
Qualcomm MSM8976 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
MSM8956 and MSM8976 platforms.
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,msm8976-pinctrl"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of the TLMM register space.
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the TLMM summary IRQ.
- interrupt-controller:
Usage: required
Value type: <none>
Definition: identifies this node as an interrupt controller
- #interrupt-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/interrupt-controller/irq.h>
- gpio-controller:
Usage: required
Value type: <none>
Definition: identifies this node as a gpio controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/gpio/gpio.h>
- gpio-ranges:
Usage: required
Definition: see ../gpio/gpio.txt
- gpio-reserved-ranges:
Usage: optional
Definition: see ../gpio/gpio.txt
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
PIN CONFIGURATION NODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of gpio pins affected by the properties specified in
this subnode.
Valid pins are:
gpio0-gpio145
Supports mux, bias and drive-strength
sdc1_clk, sdc1_cmd, sdc1_data,
sdc2_clk, sdc2_cmd, sdc2_data,
sdc3_clk, sdc3_cmd, sdc3_data
Supports bias and drive-strength
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Functions are only valid for gpio pins.
Valid values are:
gpio, blsp_uart1, blsp_spi1, smb_int, blsp_i2c1, blsp_spi2,
blsp_uart2, blsp_i2c2, gcc_gp1_clk_b, blsp_spi3,
qdss_tracedata_b, blsp_i2c3, gcc_gp2_clk_b, gcc_gp3_clk_b,
blsp_spi4, cap_int, blsp_i2c4, blsp_spi5, blsp_uart5,
qdss_traceclk_a, m_voc, blsp_i2c5, qdss_tracectl_a,
qdss_tracedata_a, blsp_spi6, blsp_uart6, qdss_tracectl_b,
blsp_i2c6, qdss_traceclk_b, mdp_vsync, pri_mi2s_mclk_a,
sec_mi2s_mclk_a, cam_mclk, cci0_i2c, cci1_i2c, blsp1_spi,
blsp3_spi, gcc_gp1_clk_a, gcc_gp2_clk_a, gcc_gp3_clk_a,
uim_batt, sd_write, uim1_data, uim1_clk, uim1_reset,
uim1_present, uim2_data, uim2_clk, uim2_reset,
uim2_present, ts_xvdd, mipi_dsi0, us_euro, ts_resout,
ts_sample, sec_mi2s_mclk_b, pri_mi2s, codec_reset,
cdc_pdm0, us_emitter, pri_mi2s_mclk_b, pri_mi2s_mclk_c,
lpass_slimbus, lpass_slimbus0, lpass_slimbus1, codec_int1,
codec_int2, wcss_bt, sdc3, wcss_wlan2, wcss_wlan1,
wcss_wlan0, wcss_wlan, wcss_fm, key_volp, key_snapshot,
key_focus, key_home, pwr_down, dmic0_clk, hdmi_int,
dmic0_data, wsa_vi, wsa_en, blsp_spi8, wsa_irq, blsp_i2c8,
pa_indicator, modem_tsync, ssbi_wtr1, gsm1_tx, gsm0_tx,
sdcard_det, sec_mi2s, ss_switch,
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as no pull.
- bias-pull-down:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as pull down.
- bias-pull-up:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as pull up.
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
Not valid for sdc pins.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
Not valid for sdc pins.
- drive-strength:
Usage: optional
Value type: <u32>
Definition: Selects the drive strength for the specified pins, in mA.
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
Example:
tlmm: pinctrl@1000000 {
compatible = "qcom,msm8976-pinctrl";
reg = <0x1000000 0x300000>;
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&tlmm 0 0 145>;
interrupt-controller;
#interrupt-cells = <2>;
blsp1_uart2_active: blsp1_uart2_active {
mux {
pins = "gpio4", "gpio5", "gpio6", "gpio7";
function = "blsp_uart2";
};
config {
pins = "gpio4", "gpio5", "gpio6", "gpio7";
drive-strength = <2>;
bias-disable;
};
};
};

View File

@ -15,14 +15,18 @@ PMIC's from Qualcomm.
"qcom,pm8917-gpio"
"qcom,pm8921-gpio"
"qcom,pm8941-gpio"
"qcom,pm8950-gpio"
"qcom,pm8994-gpio"
"qcom,pm8998-gpio"
"qcom,pma8084-gpio"
"qcom,pmi8950-gpio"
"qcom,pmi8994-gpio"
"qcom,pmi8998-gpio"
"qcom,pms405-gpio"
"qcom,pm8150-gpio"
"qcom,pm8150b-gpio"
"qcom,pm6150-gpio"
"qcom,pm6150l-gpio"
And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio"
if the device is on an spmi bus or an ssbi bus respectively
@ -91,15 +95,19 @@ to specify in a pin configuration subnode:
gpio1-gpio38 for pm8917
gpio1-gpio44 for pm8921
gpio1-gpio36 for pm8941
gpio1-gpio8 for pm8950 (hole on gpio3)
gpio1-gpio22 for pm8994
gpio1-gpio26 for pm8998
gpio1-gpio22 for pma8084
gpio1-gpio2 for pmi8950
gpio1-gpio10 for pmi8994
gpio1-gpio12 for pms405 (holes on gpio1, gpio9 and gpio10)
gpio1-gpio10 for pm8150 (holes on gpio2, gpio5, gpio7
and gpio8)
gpio1-gpio12 for pm8150b (holes on gpio3, gpio4, gpio7)
gpio1-gpio12 for pm8150l (hole on gpio7)
gpio1-gpio10 for pm6150
gpio1-gpio12 for pm6150l
- function:
Usage: required

View File

@ -16,6 +16,8 @@ of PMIC's from Qualcomm.
"qcom,pm8917-mpp",
"qcom,pm8921-mpp",
"qcom,pm8941-mpp",
"qcom,pm8950-mpp",
"qcom,pmi8950-mpp",
"qcom,pm8994-mpp",
"qcom,pma8084-mpp",
@ -80,6 +82,8 @@ to specify in a pin configuration subnode:
mpp1-mpp4 for pm8841
mpp1-mpp4 for pm8916
mpp1-mpp8 for pm8941
mpp1-mpp4 for pm8950
mpp1-mpp4 for pmi8950
mpp1-mpp4 for pma8084
- function:

View File

@ -18,6 +18,7 @@ Required Properties:
- "renesas,pfc-r8a7745": for R8A7745 (RZ/G1E) compatible pin-controller.
- "renesas,pfc-r8a77470": for R8A77470 (RZ/G1C) compatible pin-controller.
- "renesas,pfc-r8a774a1": for R8A774A1 (RZ/G2M) compatible pin-controller.
- "renesas,pfc-r8a774b1": for R8A774B1 (RZ/G2N) compatible pin-controller.
- "renesas,pfc-r8a774c0": for R8A774C0 (RZ/G2E) compatible pin-controller.
- "renesas,pfc-r8a7778": for R8A7778 (R-Car M1) compatible pin-controller.
- "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller.
@ -27,7 +28,8 @@ Required Properties:
- "renesas,pfc-r8a7793": for R8A7793 (R-Car M2-N) compatible pin-controller.
- "renesas,pfc-r8a7794": for R8A7794 (R-Car E2) compatible pin-controller.
- "renesas,pfc-r8a7795": for R8A7795 (R-Car H3) compatible pin-controller.
- "renesas,pfc-r8a7796": for R8A7796 (R-Car M3-W) compatible pin-controller.
- "renesas,pfc-r8a7796": for R8A77960 (R-Car M3-W) compatible pin-controller.
- "renesas,pfc-r8a77961": for R8A77961 (R-Car M3-W+) compatible pin-controller.
- "renesas,pfc-r8a77965": for R8A77965 (R-Car M3-N) compatible pin-controller.
- "renesas,pfc-r8a77970": for R8A77970 (R-Car V3M) compatible pin-controller.
- "renesas,pfc-r8a77980": for R8A77980 (R-Car V3H) compatible pin-controller.

View File

@ -29,6 +29,7 @@ Required properties for iomux controller:
"rockchip,rk3188-pinctrl": for Rockchip RK3188
"rockchip,rk3228-pinctrl": for Rockchip RK3228
"rockchip,rk3288-pinctrl": for Rockchip RK3288
"rockchip,rk3308-pinctrl": for Rockchip RK3308
"rockchip,rk3328-pinctrl": for Rockchip RK3328
"rockchip,rk3368-pinctrl": for Rockchip RK3368
"rockchip,rk3399-pinctrl": for Rockchip RK3399

View File

@ -12975,7 +12975,7 @@ F: Documentation/devicetree/bindings/pinctrl/fsl,*
PIN CONTROLLER - INTEL
M: Mika Westerberg <mika.westerberg@linux.intel.com>
M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
M: Andy Shevchenko <andy@kernel.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git
S: Maintained
F: drivers/pinctrl/intel/

View File

@ -134,7 +134,7 @@ enum {
GPIO_FN_EX_WAIT1, GPIO_FN_SD1_DAT0_A, GPIO_FN_DREQ2, GPIO_FN_CAN1_TX_C,
GPIO_FN_ET0_LINK_C, GPIO_FN_ET0_ETXD5_A,
GPIO_FN_EX_WAIT0, GPIO_FN_TCLK1_B,
GPIO_FN_RD_WR, GPIO_FN_TCLK0,
GPIO_FN_RD_WR, GPIO_FN_TCLK0, GPIO_FN_CAN_CLK_B, GPIO_FN_ET0_ETXD4,
GPIO_FN_EX_CS5, GPIO_FN_SD1_CMD_A, GPIO_FN_ATADIR, GPIO_FN_QSSL_B,
GPIO_FN_ET0_ETXD3_A,
GPIO_FN_EX_CS4, GPIO_FN_SD1_WP_A, GPIO_FN_ATAWR, GPIO_FN_QMI_QIO1_B,

View File

@ -420,4 +420,22 @@ config PINCTRL_TB10X
depends on OF && ARC_PLAT_TB10X
select GPIOLIB
config PINCTRL_EQUILIBRIUM
tristate "Generic pinctrl and GPIO driver for Intel Lightning Mountain SoC"
select PINMUX
select PINCONF
select GPIOLIB
select GPIO_GENERIC
select GPIOLIB_IRQCHIP
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
help
Equilibrium pinctrl driver is a pinctrl & GPIO driver for Intel Lightning
Mountain network processor SoC that supports both the linux GPIO and pin
control frameworks. It provides interfaces to setup pinmux, assign desired
pin functions, configure GPIO attributes for LGM SoC pins. Pinmux and
pinconf settings are retrieved from device tree.
endif

View File

@ -46,6 +46,7 @@ obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
obj-$(CONFIG_PINCTRL_INGENIC) += pinctrl-ingenic.o
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
obj-$(CONFIG_PINCTRL_OCELOT) += pinctrl-ocelot.o
obj-$(CONFIG_PINCTRL_EQUILIBRIUM) += pinctrl-equilibrium.o
obj-y += actions/
obj-$(CONFIG_ARCH_ASPEED) += aspeed/

View File

@ -915,7 +915,6 @@ static int owl_gpio_init(struct owl_pinctrl *pctrl)
int owl_pinctrl_probe(struct platform_device *pdev,
struct owl_pinctrl_soc_data *soc_data)
{
struct resource *res;
struct owl_pinctrl *pctrl;
int ret, i;
@ -923,8 +922,7 @@ int owl_pinctrl_probe(struct platform_device *pdev,
if (!pctrl)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctrl->base = devm_ioremap_resource(&pdev->dev, res);
pctrl->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctrl->base))
return PTR_ERR(pctrl->base);

View File

@ -1400,12 +1400,10 @@ static struct pinctrl_desc bcm281xx_pinctrl_desc = {
static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
{
struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
struct resource *res;
struct pinctrl_dev *pctl;
/* So far We can assume there is only 1 bank of registers */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pdata->reg_base = devm_ioremap_resource(&pdev->dev, res);
pdata->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->reg_base)) {
dev_err(&pdev->dev, "Failed to ioremap MEM resource\n");
return -ENODEV;

View File

@ -940,7 +940,6 @@ static int cygnus_mux_log_init(struct cygnus_pinctrl *pinctrl)
static int cygnus_pinmux_probe(struct platform_device *pdev)
{
struct cygnus_pinctrl *pinctrl;
struct resource *res;
int i, ret;
struct pinctrl_pin_desc *pins;
unsigned num_pins = ARRAY_SIZE(cygnus_pins);
@ -953,15 +952,13 @@ static int cygnus_pinmux_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pinctrl);
spin_lock_init(&pinctrl->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res);
pinctrl->base0 = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pinctrl->base0)) {
dev_err(&pdev->dev, "unable to map I/O space\n");
return PTR_ERR(pinctrl->base0);
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
pinctrl->base1 = devm_ioremap_resource(&pdev->dev, res);
pinctrl->base1 = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(pinctrl->base1)) {
dev_err(&pdev->dev, "unable to map I/O space\n");
return PTR_ERR(pinctrl->base1);

View File

@ -795,8 +795,7 @@ static int iproc_gpio_probe(struct platform_device *pdev)
chip->dev = dev;
platform_set_drvdata(pdev, chip);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
chip->base = devm_ioremap_resource(dev, res);
chip->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(chip->base)) {
dev_err(dev, "unable to map I/O memory\n");
return PTR_ERR(chip->base);
@ -850,7 +849,7 @@ static int iproc_gpio_probe(struct platform_device *pdev)
struct gpio_irq_chip *girq;
irqc = &chip->irqchip;
irqc->name = "bcm-iproc-gpio";
irqc->name = dev_name(dev);
irqc->irq_ack = iproc_gpio_irq_ack;
irqc->irq_mask = iproc_gpio_irq_mask;
irqc->irq_unmask = iproc_gpio_irq_unmask;

View File

@ -1042,8 +1042,7 @@ static int ns2_pinmux_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pinctrl);
spin_lock_init(&pinctrl->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res);
pinctrl->base0 = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pinctrl->base0))
return PTR_ERR(pinctrl->base0);
@ -1057,8 +1056,7 @@ static int ns2_pinmux_probe(struct platform_device *pdev)
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
pinctrl->pinconf_base = devm_ioremap_resource(&pdev->dev, res);
pinctrl->pinconf_base = devm_platform_ioremap_resource(pdev, 2);
if (IS_ERR(pinctrl->pinconf_base))
return PTR_ERR(pinctrl->pinconf_base);

View File

@ -64,17 +64,16 @@
* @gc: GPIO chip
* @pctl: pointer to pinctrl_dev
* @pctldesc: pinctrl descriptor
* @irq_domain: pointer to irq domain
* @lock: lock to protect access to I/O registers
*/
struct nsp_gpio {
struct device *dev;
void __iomem *base;
void __iomem *io_ctrl;
struct irq_chip irqchip;
struct gpio_chip gc;
struct pinctrl_dev *pctl;
struct pinctrl_desc pctldesc;
struct irq_domain *irq_domain;
raw_spinlock_t lock;
};
@ -136,8 +135,8 @@ static inline bool nsp_get_bit(struct nsp_gpio *chip, enum base_type address,
static irqreturn_t nsp_gpio_irq_handler(int irq, void *data)
{
struct nsp_gpio *chip = (struct nsp_gpio *)data;
struct gpio_chip gc = chip->gc;
struct gpio_chip *gc = (struct gpio_chip *)data;
struct nsp_gpio *chip = gpiochip_get_data(gc);
int bit;
unsigned long int_bits = 0;
u32 int_status;
@ -155,14 +154,14 @@ static irqreturn_t nsp_gpio_irq_handler(int irq, void *data)
level &= readl(chip->base + NSP_GPIO_INT_MASK);
int_bits = level | event;
for_each_set_bit(bit, &int_bits, gc.ngpio) {
for_each_set_bit(bit, &int_bits, gc->ngpio) {
/*
* Clear the interrupt before invoking the
* handler, so we do not leave any window
*/
writel(BIT(bit), chip->base + NSP_GPIO_EVENT);
generic_handle_irq(
irq_linear_revmap(chip->irq_domain, bit));
irq_linear_revmap(gc->irq.domain, bit));
}
}
@ -171,7 +170,8 @@ static irqreturn_t nsp_gpio_irq_handler(int irq, void *data)
static void nsp_gpio_irq_ack(struct irq_data *d)
{
struct nsp_gpio *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned gpio = d->hwirq;
u32 val = BIT(gpio);
u32 trigger_type;
@ -189,7 +189,8 @@ static void nsp_gpio_irq_ack(struct irq_data *d)
*/
static void nsp_gpio_irq_set_mask(struct irq_data *d, bool unmask)
{
struct nsp_gpio *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned gpio = d->hwirq;
u32 trigger_type;
@ -202,7 +203,8 @@ static void nsp_gpio_irq_set_mask(struct irq_data *d, bool unmask)
static void nsp_gpio_irq_mask(struct irq_data *d)
{
struct nsp_gpio *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
raw_spin_lock_irqsave(&chip->lock, flags);
@ -212,7 +214,8 @@ static void nsp_gpio_irq_mask(struct irq_data *d)
static void nsp_gpio_irq_unmask(struct irq_data *d)
{
struct nsp_gpio *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
raw_spin_lock_irqsave(&chip->lock, flags);
@ -222,7 +225,8 @@ static void nsp_gpio_irq_unmask(struct irq_data *d)
static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
struct nsp_gpio *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned gpio = d->hwirq;
bool level_low;
bool falling;
@ -265,16 +269,6 @@ static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type)
return 0;
}
static struct irq_chip nsp_gpio_irq_chip = {
.name = "gpio-a",
.irq_enable = nsp_gpio_irq_unmask,
.irq_disable = nsp_gpio_irq_mask,
.irq_ack = nsp_gpio_irq_ack,
.irq_mask = nsp_gpio_irq_mask,
.irq_unmask = nsp_gpio_irq_unmask,
.irq_set_type = nsp_gpio_irq_set_type,
};
static int nsp_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
{
struct nsp_gpio *chip = gpiochip_get_data(gc);
@ -303,6 +297,19 @@ static int nsp_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
return 0;
}
static int nsp_gpio_get_direction(struct gpio_chip *gc, unsigned gpio)
{
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
int val;
raw_spin_lock_irqsave(&chip->lock, flags);
val = nsp_get_bit(chip, REG, NSP_GPIO_OUT_EN, gpio);
raw_spin_unlock_irqrestore(&chip->lock, flags);
return !val;
}
static void nsp_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
{
struct nsp_gpio *chip = gpiochip_get_data(gc);
@ -322,13 +329,6 @@ static int nsp_gpio_get(struct gpio_chip *gc, unsigned gpio)
return !!(readl(chip->base + NSP_GPIO_DATA_IN) & BIT(gpio));
}
static int nsp_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct nsp_gpio *chip = gpiochip_get_data(gc);
return irq_linear_revmap(chip->irq_domain, offset);
}
static int nsp_get_groups_count(struct pinctrl_dev *pctldev)
{
return 1;
@ -613,10 +613,9 @@ static const struct of_device_id nsp_gpio_of_match[] = {
static int nsp_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *res;
struct nsp_gpio *chip;
struct gpio_chip *gc;
u32 val, count;
u32 val;
int irq, ret;
if (of_property_read_u32(pdev->dev.of_node, "ngpios", &val)) {
@ -631,15 +630,13 @@ static int nsp_gpio_probe(struct platform_device *pdev)
chip->dev = dev;
platform_set_drvdata(pdev, chip);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
chip->base = devm_ioremap_resource(dev, res);
chip->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(chip->base)) {
dev_err(dev, "unable to map I/O memory\n");
return PTR_ERR(chip->base);
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
chip->io_ctrl = devm_ioremap_resource(dev, res);
chip->io_ctrl = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(chip->io_ctrl)) {
dev_err(dev, "unable to map I/O memory\n");
return PTR_ERR(chip->io_ctrl);
@ -657,46 +654,47 @@ static int nsp_gpio_probe(struct platform_device *pdev)
gc->free = gpiochip_generic_free;
gc->direction_input = nsp_gpio_direction_input;
gc->direction_output = nsp_gpio_direction_output;
gc->get_direction = nsp_gpio_get_direction;
gc->set = nsp_gpio_set;
gc->get = nsp_gpio_get;
gc->to_irq = nsp_gpio_to_irq;
/* optional GPIO interrupt support */
irq = platform_get_irq(pdev, 0);
if (irq > 0) {
/* Create irq domain so that each pin can be assigned an IRQ.*/
chip->irq_domain = irq_domain_add_linear(gc->of_node, gc->ngpio,
&irq_domain_simple_ops,
chip);
if (!chip->irq_domain) {
dev_err(&pdev->dev, "Couldn't allocate IRQ domain\n");
return -ENXIO;
}
struct gpio_irq_chip *girq;
struct irq_chip *irqc;
/* Map each gpio to an IRQ and set the handler for gpiolib. */
for (count = 0; count < gc->ngpio; count++) {
int irq = irq_create_mapping(chip->irq_domain, count);
irq_set_chip_and_handler(irq, &nsp_gpio_irq_chip,
handle_simple_irq);
irq_set_chip_data(irq, chip);
}
/* Install ISR for this GPIO controller. */
ret = devm_request_irq(&pdev->dev, irq, nsp_gpio_irq_handler,
IRQF_SHARED, "gpio-a", chip);
if (ret) {
dev_err(&pdev->dev, "Unable to request IRQ%d: %d\n",
irq, ret);
goto err_rm_gpiochip;
}
irqc = &chip->irqchip;
irqc->name = "gpio-a";
irqc->irq_ack = nsp_gpio_irq_ack;
irqc->irq_mask = nsp_gpio_irq_mask;
irqc->irq_unmask = nsp_gpio_irq_unmask;
irqc->irq_set_type = nsp_gpio_irq_set_type;
val = readl(chip->base + NSP_CHIP_A_INT_MASK);
val = val | NSP_CHIP_A_GPIO_INT_BIT;
writel(val, (chip->base + NSP_CHIP_A_INT_MASK));
/* Install ISR for this GPIO controller. */
ret = devm_request_irq(dev, irq, nsp_gpio_irq_handler,
IRQF_SHARED, "gpio-a", &chip->gc);
if (ret) {
dev_err(&pdev->dev, "Unable to request IRQ%d: %d\n",
irq, ret);
return ret;
}
ret = gpiochip_add_data(gc, chip);
girq = &chip->gc.irq;
girq->chip = irqc;
/* This will let us handle the parent IRQ in the driver */
girq->parent_handler = NULL;
girq->num_parents = 0;
girq->parents = NULL;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_simple_irq;
}
ret = devm_gpiochip_add_data(dev, gc, chip);
if (ret < 0) {
dev_err(dev, "unable to add GPIO chip\n");
return ret;
@ -705,15 +703,10 @@ static int nsp_gpio_probe(struct platform_device *pdev)
ret = nsp_gpio_register_pinconf(chip);
if (ret) {
dev_err(dev, "unable to register pinconf\n");
goto err_rm_gpiochip;
return ret;
}
return 0;
err_rm_gpiochip:
gpiochip_remove(gc);
return ret;
}
static struct platform_driver nsp_gpio_driver = {

View File

@ -571,8 +571,7 @@ static int nsp_pinmux_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pinctrl);
spin_lock_init(&pinctrl->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res);
pinctrl->base0 = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pinctrl->base0))
return PTR_ERR(pinctrl->base0);
@ -586,8 +585,7 @@ static int nsp_pinmux_probe(struct platform_device *pdev)
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
pinctrl->base2 = devm_ioremap_resource(&pdev->dev, res);
pinctrl->base2 = devm_platform_ioremap_resource(pdev, 2);
if (IS_ERR(pinctrl->base2))
return PTR_ERR(pinctrl->base2);

View File

@ -29,6 +29,13 @@ struct pinctrl_dt_map {
static void dt_free_map(struct pinctrl_dev *pctldev,
struct pinctrl_map *map, unsigned num_maps)
{
int i;
for (i = 0; i < num_maps; ++i) {
kfree_const(map[i].dev_name);
map[i].dev_name = NULL;
}
if (pctldev) {
const struct pinctrl_ops *ops = pctldev->desc->pctlops;
if (ops->dt_free_map)
@ -63,7 +70,13 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
/* Initialize common mapping table entry fields */
for (i = 0; i < num_maps; i++) {
map[i].dev_name = dev_name(p->dev);
const char *devname;
devname = kstrdup_const(dev_name(p->dev), GFP_KERNEL);
if (!devname)
goto err_free_map;
map[i].dev_name = devname;
map[i].name = statename;
if (pctldev)
map[i].ctrl_dev_name = dev_name(pctldev->dev);
@ -71,10 +84,8 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
/* Remember the converted mapping table entries */
dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL);
if (!dt_map) {
dt_free_map(pctldev, map, num_maps);
return -ENOMEM;
}
if (!dt_map)
goto err_free_map;
dt_map->pctldev = pctldev;
dt_map->map = map;
@ -82,6 +93,10 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
list_add_tail(&dt_map->node, &p->dt_maps);
return pinctrl_register_map(map, num_maps, false);
err_free_map:
dt_free_map(pctldev, map, num_maps);
return -ENOMEM;
}
struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
@ -147,6 +162,16 @@ static int dt_to_map_one_config(struct pinctrl *p,
ret = ops->dt_node_to_map(pctldev, np_config, &map, &num_maps);
if (ret < 0)
return ret;
else if (num_maps == 0) {
/*
* If we have no valid maps (maybe caused by empty pinctrl node
* or typing error) ther is no need remember this, so just
* return.
*/
dev_info(p->dev,
"there is not valid maps for state %s\n", statename);
return 0;
}
/* Stash the mapping table chunk away for later use */
return dt_remember_or_free_map(p, statename, pctldev, map, num_maps);
@ -166,21 +191,6 @@ static int dt_remember_dummy_state(struct pinctrl *p, const char *statename)
return dt_remember_or_free_map(p, statename, NULL, map, 1);
}
bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev)
{
struct device_node *np;
struct property *prop;
int size;
np = pctldev->dev->of_node;
if (!np)
return false;
prop = of_find_property(np, "pinctrl-0", &size);
return prop ? true : false;
}
int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
{
struct device_node *np = p->dev->of_node;

View File

@ -9,8 +9,6 @@ struct of_phandle_args;
#ifdef CONFIG_OF
bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev);
void pinctrl_dt_free_maps(struct pinctrl *p);
int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev);
@ -23,11 +21,6 @@ int pinctrl_parse_index_with_args(const struct device_node *np,
#else
static inline bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev)
{
return false;
}
static inline int pinctrl_dt_to_map(struct pinctrl *p,
struct pinctrl_dev *pctldev)
{

View File

@ -115,4 +115,11 @@ config PINCTRL_SUNRISEPOINT
provides an interface that allows configuring of PCH pins and
using them as GPIOs.
config PINCTRL_TIGERLAKE
tristate "Intel Tiger Lake pinctrl and GPIO driver"
depends on ACPI
select PINCTRL_INTEL
help
This pinctrl driver provides an interface that allows configuring
of Intel Tiger Lake PCH pins and using them as GPIOs.
endif

View File

@ -13,3 +13,4 @@ obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o
obj-$(CONFIG_PINCTRL_ICELAKE) += pinctrl-icelake.o
obj-$(CONFIG_PINCTRL_LEWISBURG) += pinctrl-lewisburg.o
obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o
obj-$(CONFIG_PINCTRL_TIGERLAKE) += pinctrl-tigerlake.o

View File

@ -165,7 +165,7 @@ struct chv_pinctrl {
struct gpio_chip chip;
struct irq_chip irqchip;
void __iomem *regs;
unsigned intr_lines[16];
unsigned int intr_lines[16];
const struct chv_community *community;
u32 saved_intmask;
struct chv_pin_context *saved_pin_context;
@ -379,7 +379,7 @@ static const struct chv_community southwest_community = {
.gpio_ranges = southwest_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges),
/*
* Southwest community can benerate GPIO interrupts only for the
* Southwest community can generate GPIO interrupts only for the
* first 8 interrupts. The upper half (8-15) can only be used to
* trigger GPEs.
*/
@ -1480,7 +1480,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc)
pending = readl(pctrl->regs + CHV_INTSTAT);
for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) {
unsigned irq, offset;
unsigned int irq, offset;
offset = pctrl->intr_lines[intr_line];
irq = irq_find_mapping(gc->irq.domain, offset);

View File

@ -1131,7 +1131,7 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
pending &= enabled;
for_each_set_bit(gpp_offset, &pending, padgrp->size) {
unsigned irq;
unsigned int irq;
irq = irq_find_mapping(gc->irq.domain,
padgrp->gpio_base + gpp_offset);
@ -1181,7 +1181,7 @@ static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl,
return ret;
}
static unsigned intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
{
const struct intel_community *community;
unsigned int ngpio = 0;
@ -1595,16 +1595,65 @@ intel_gpio_is_requested(struct gpio_chip *chip, int base, unsigned int size)
return requested;
}
static u32
intel_gpio_update_pad_mode(void __iomem *hostown, u32 mask, u32 value)
static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value)
{
u32 curr, updated;
curr = readl(hostown);
updated = (curr & ~mask) | (value & mask);
writel(updated, hostown);
curr = readl(reg);
return curr;
updated = (curr & ~mask) | (value & mask);
if (curr == updated)
return false;
writel(updated, reg);
return true;
}
static void intel_restore_hostown(struct intel_pinctrl *pctrl, unsigned int c,
void __iomem *base, unsigned int gpp, u32 saved)
{
const struct intel_community *community = &pctrl->communities[c];
const struct intel_padgroup *padgrp = &community->gpps[gpp];
struct device *dev = pctrl->dev;
u32 requested;
if (padgrp->gpio_base < 0)
return;
requested = intel_gpio_is_requested(&pctrl->chip, padgrp->gpio_base, padgrp->size);
if (!intel_gpio_update_reg(base + gpp * 4, requested, saved))
return;
dev_dbg(dev, "restored hostown %u/%u %#08x\n", c, gpp, readl(base + gpp * 4));
}
static void intel_restore_intmask(struct intel_pinctrl *pctrl, unsigned int c,
void __iomem *base, unsigned int gpp, u32 saved)
{
struct device *dev = pctrl->dev;
if (!intel_gpio_update_reg(base + gpp * 4, ~0U, saved))
return;
dev_dbg(dev, "restored mask %u/%u %#08x\n", c, gpp, readl(base + gpp * 4));
}
static void intel_restore_padcfg(struct intel_pinctrl *pctrl, unsigned int pin,
unsigned int reg, u32 saved)
{
u32 mask = (reg == PADCFG0) ? PADCFG0_GPIORXSTATE : 0;
unsigned int n = reg / sizeof(u32);
struct device *dev = pctrl->dev;
void __iomem *padcfg;
padcfg = intel_get_padcfg(pctrl, pin, reg);
if (!padcfg)
return;
if (!intel_gpio_update_reg(padcfg, ~mask, saved))
return;
dev_dbg(dev, "restored pin %u padcfg%u %#08x\n", pin, n, readl(padcfg));
}
int intel_pinctrl_resume_noirq(struct device *dev)
@ -1620,37 +1669,13 @@ int intel_pinctrl_resume_noirq(struct device *dev)
pads = pctrl->context.pads;
for (i = 0; i < pctrl->soc->npins; i++) {
const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
void __iomem *padcfg;
u32 val;
if (!intel_pinctrl_should_save(pctrl, desc->number))
continue;
padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG0);
val = readl(padcfg) & ~PADCFG0_GPIORXSTATE;
if (val != pads[i].padcfg0) {
writel(pads[i].padcfg0, padcfg);
dev_dbg(dev, "restored pin %u padcfg0 %#08x\n",
desc->number, readl(padcfg));
}
padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG1);
val = readl(padcfg);
if (val != pads[i].padcfg1) {
writel(pads[i].padcfg1, padcfg);
dev_dbg(dev, "restored pin %u padcfg1 %#08x\n",
desc->number, readl(padcfg));
}
padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG2);
if (padcfg) {
val = readl(padcfg);
if (val != pads[i].padcfg2) {
writel(pads[i].padcfg2, padcfg);
dev_dbg(dev, "restored pin %u padcfg2 %#08x\n",
desc->number, readl(padcfg));
}
}
intel_restore_padcfg(pctrl, desc->number, PADCFG0, pads[i].padcfg0);
intel_restore_padcfg(pctrl, desc->number, PADCFG1, pads[i].padcfg1);
intel_restore_padcfg(pctrl, desc->number, PADCFG2, pads[i].padcfg2);
}
communities = pctrl->context.communities;
@ -1660,30 +1685,12 @@ int intel_pinctrl_resume_noirq(struct device *dev)
unsigned int gpp;
base = community->regs + community->ie_offset;
for (gpp = 0; gpp < community->ngpps; gpp++) {
writel(communities[i].intmask[gpp], base + gpp * 4);
dev_dbg(dev, "restored mask %d/%u %#08x\n", i, gpp,
readl(base + gpp * 4));
}
for (gpp = 0; gpp < community->ngpps; gpp++)
intel_restore_intmask(pctrl, i, base, gpp, communities[i].intmask[gpp]);
base = community->regs + community->hostown_offset;
for (gpp = 0; gpp < community->ngpps; gpp++) {
const struct intel_padgroup *padgrp = &community->gpps[gpp];
u32 requested = 0, value = 0;
u32 saved = communities[i].hostown[gpp];
if (padgrp->gpio_base < 0)
continue;
requested = intel_gpio_is_requested(&pctrl->chip,
padgrp->gpio_base, padgrp->size);
value = intel_gpio_update_pad_mode(base + gpp * 4,
requested, saved);
if ((value ^ saved) & requested) {
dev_warn(dev, "restore hostown %d/%u %#8x->%#8x\n",
i, gpp, value, saved);
}
}
for (gpp = 0; gpp < community->ngpps; gpp++)
intel_restore_hostown(pctrl, i, base, gpp, communities[i].hostown[gpp]);
}
return 0;

View File

@ -33,6 +33,7 @@
.npins = ((e) - (s) + 1), \
}
/* Lewisburg */
static const struct pinctrl_pin_desc lbg_pins[] = {
/* GPP_A */
PINCTRL_PIN(0, "RCINB"),
@ -72,7 +73,7 @@ static const struct pinctrl_pin_desc lbg_pins[] = {
PINCTRL_PIN(33, "SRCCLKREQB_4"),
PINCTRL_PIN(34, "SRCCLKREQB_5"),
PINCTRL_PIN(35, "GPP_B_11"),
PINCTRL_PIN(36, "GLB_RST_WARN_N"),
PINCTRL_PIN(36, "SLP_S0B"),
PINCTRL_PIN(37, "PLTRSTB"),
PINCTRL_PIN(38, "SPKR"),
PINCTRL_PIN(39, "GPP_B_15"),
@ -185,96 +186,96 @@ static const struct pinctrl_pin_desc lbg_pins[] = {
PINCTRL_PIN(141, "GBE_PCI_DIS"),
PINCTRL_PIN(142, "GBE_LAN_DIS"),
PINCTRL_PIN(143, "GPP_I_10"),
PINCTRL_PIN(144, "GPIO_RCOMP_3P3"),
/* GPP_J */
PINCTRL_PIN(145, "GBE_LED_0_0"),
PINCTRL_PIN(146, "GBE_LED_0_1"),
PINCTRL_PIN(147, "GBE_LED_1_0"),
PINCTRL_PIN(148, "GBE_LED_1_1"),
PINCTRL_PIN(149, "GBE_LED_2_0"),
PINCTRL_PIN(150, "GBE_LED_2_1"),
PINCTRL_PIN(151, "GBE_LED_3_0"),
PINCTRL_PIN(152, "GBE_LED_3_1"),
PINCTRL_PIN(153, "GBE_SCL_0"),
PINCTRL_PIN(154, "GBE_SDA_0"),
PINCTRL_PIN(155, "GBE_SCL_1"),
PINCTRL_PIN(156, "GBE_SDA_1"),
PINCTRL_PIN(157, "GBE_SCL_2"),
PINCTRL_PIN(158, "GBE_SDA_2"),
PINCTRL_PIN(159, "GBE_SCL_3"),
PINCTRL_PIN(160, "GBE_SDA_3"),
PINCTRL_PIN(161, "GBE_SDP_0_0"),
PINCTRL_PIN(162, "GBE_SDP_0_1"),
PINCTRL_PIN(163, "GBE_SDP_1_0"),
PINCTRL_PIN(164, "GBE_SDP_1_1"),
PINCTRL_PIN(165, "GBE_SDP_2_0"),
PINCTRL_PIN(166, "GBE_SDP_2_1"),
PINCTRL_PIN(167, "GBE_SDP_3_0"),
PINCTRL_PIN(168, "GBE_SDP_3_1"),
PINCTRL_PIN(144, "GBE_LED_0_0"),
PINCTRL_PIN(145, "GBE_LED_0_1"),
PINCTRL_PIN(146, "GBE_LED_1_0"),
PINCTRL_PIN(147, "GBE_LED_1_1"),
PINCTRL_PIN(148, "GBE_LED_2_0"),
PINCTRL_PIN(149, "GBE_LED_2_1"),
PINCTRL_PIN(150, "GBE_LED_3_0"),
PINCTRL_PIN(151, "GBE_LED_3_1"),
PINCTRL_PIN(152, "GBE_SCL_0"),
PINCTRL_PIN(153, "GBE_SDA_0"),
PINCTRL_PIN(154, "GBE_SCL_1"),
PINCTRL_PIN(155, "GBE_SDA_1"),
PINCTRL_PIN(156, "GBE_SCL_2"),
PINCTRL_PIN(157, "GBE_SDA_2"),
PINCTRL_PIN(158, "GBE_SCL_3"),
PINCTRL_PIN(159, "GBE_SDA_3"),
PINCTRL_PIN(160, "GBE_SDP_0_0"),
PINCTRL_PIN(161, "GBE_SDP_0_1"),
PINCTRL_PIN(162, "GBE_SDP_1_0"),
PINCTRL_PIN(163, "GBE_SDP_1_1"),
PINCTRL_PIN(164, "GBE_SDP_2_0"),
PINCTRL_PIN(165, "GBE_SDP_2_1"),
PINCTRL_PIN(166, "GBE_SDP_3_0"),
PINCTRL_PIN(167, "GBE_SDP_3_1"),
/* GPP_K */
PINCTRL_PIN(169, "GBE_RMIICLK"),
PINCTRL_PIN(170, "GBE_RMII_TXD_0"),
PINCTRL_PIN(171, "GBE_RMII_TXD_1"),
PINCTRL_PIN(168, "GBE_RMIICLK"),
PINCTRL_PIN(169, "GBE_RMII_RXD_0"),
PINCTRL_PIN(170, "GBE_RMII_RXD_1"),
PINCTRL_PIN(171, "GBE_RMII_CRS_DV"),
PINCTRL_PIN(172, "GBE_RMII_TX_EN"),
PINCTRL_PIN(173, "GBE_RMII_CRS_DV"),
PINCTRL_PIN(174, "GBE_RMII_RXD_0"),
PINCTRL_PIN(175, "GBE_RMII_RXD_1"),
PINCTRL_PIN(176, "GBE_RMII_RX_ER"),
PINCTRL_PIN(177, "GBE_RMII_ARBIN"),
PINCTRL_PIN(178, "GBE_RMII_ARB_OUT"),
PINCTRL_PIN(179, "PE_RST_N"),
PINCTRL_PIN(180, "GPIO_RCOMP_1P8_3P3"),
PINCTRL_PIN(173, "GBE_RMII_TXD_0"),
PINCTRL_PIN(174, "GBE_RMII_TXD_1"),
PINCTRL_PIN(175, "GBE_RMII_RX_ER"),
PINCTRL_PIN(176, "GBE_RMII_ARBIN"),
PINCTRL_PIN(177, "GBE_RMII_ARB_OUT"),
PINCTRL_PIN(178, "PE_RST_N"),
/* GPP_G */
PINCTRL_PIN(181, "FAN_TACH_0"),
PINCTRL_PIN(182, "FAN_TACH_1"),
PINCTRL_PIN(183, "FAN_TACH_2"),
PINCTRL_PIN(184, "FAN_TACH_3"),
PINCTRL_PIN(185, "FAN_TACH_4"),
PINCTRL_PIN(186, "FAN_TACH_5"),
PINCTRL_PIN(187, "FAN_TACH_6"),
PINCTRL_PIN(188, "FAN_TACH_7"),
PINCTRL_PIN(189, "FAN_PWM_0"),
PINCTRL_PIN(190, "FAN_PWM_1"),
PINCTRL_PIN(191, "FAN_PWM_2"),
PINCTRL_PIN(192, "FAN_PWM_3"),
PINCTRL_PIN(193, "GSXDOUT"),
PINCTRL_PIN(194, "GSXSLOAD"),
PINCTRL_PIN(195, "GSXDIN"),
PINCTRL_PIN(196, "GSXSRESETB"),
PINCTRL_PIN(197, "GSXCLK"),
PINCTRL_PIN(198, "ADR_COMPLETE"),
PINCTRL_PIN(199, "NMIB"),
PINCTRL_PIN(200, "SMIB"),
PINCTRL_PIN(201, "SSATA_DEVSLP_0"),
PINCTRL_PIN(202, "SSATA_DEVSLP_1"),
PINCTRL_PIN(203, "SSATA_DEVSLP_2"),
PINCTRL_PIN(204, "SSATAXPCIE0_SSATAGP0"),
PINCTRL_PIN(179, "FAN_TACH_0"),
PINCTRL_PIN(180, "FAN_TACH_1"),
PINCTRL_PIN(181, "FAN_TACH_2"),
PINCTRL_PIN(182, "FAN_TACH_3"),
PINCTRL_PIN(183, "FAN_TACH_4"),
PINCTRL_PIN(184, "FAN_TACH_5"),
PINCTRL_PIN(185, "FAN_TACH_6"),
PINCTRL_PIN(186, "FAN_TACH_7"),
PINCTRL_PIN(187, "FAN_PWM_0"),
PINCTRL_PIN(188, "FAN_PWM_1"),
PINCTRL_PIN(189, "FAN_PWM_2"),
PINCTRL_PIN(190, "FAN_PWM_3"),
PINCTRL_PIN(191, "GSXDOUT"),
PINCTRL_PIN(192, "GSXSLOAD"),
PINCTRL_PIN(193, "GSXDIN"),
PINCTRL_PIN(194, "GSXSRESETB"),
PINCTRL_PIN(195, "GSXCLK"),
PINCTRL_PIN(196, "ADR_COMPLETE"),
PINCTRL_PIN(197, "NMIB"),
PINCTRL_PIN(198, "SMIB"),
PINCTRL_PIN(199, "SSATA_DEVSLP_0"),
PINCTRL_PIN(200, "SSATA_DEVSLP_1"),
PINCTRL_PIN(201, "SSATA_DEVSLP_2"),
PINCTRL_PIN(202, "SSATAXPCIE0_SSATAGP0"),
/* GPP_H */
PINCTRL_PIN(205, "SRCCLKREQB_6"),
PINCTRL_PIN(206, "SRCCLKREQB_7"),
PINCTRL_PIN(207, "SRCCLKREQB_8"),
PINCTRL_PIN(208, "SRCCLKREQB_9"),
PINCTRL_PIN(209, "SRCCLKREQB_10"),
PINCTRL_PIN(210, "SRCCLKREQB_11"),
PINCTRL_PIN(211, "SRCCLKREQB_12"),
PINCTRL_PIN(212, "SRCCLKREQB_13"),
PINCTRL_PIN(213, "SRCCLKREQB_14"),
PINCTRL_PIN(214, "SRCCLKREQB_15"),
PINCTRL_PIN(215, "SML2CLK"),
PINCTRL_PIN(216, "SML2DATA"),
PINCTRL_PIN(217, "SML2ALERTB"),
PINCTRL_PIN(218, "SML3CLK"),
PINCTRL_PIN(219, "SML3DATA"),
PINCTRL_PIN(220, "SML3ALERTB"),
PINCTRL_PIN(221, "SML4CLK"),
PINCTRL_PIN(222, "SML4DATA"),
PINCTRL_PIN(223, "SML4ALERTB"),
PINCTRL_PIN(224, "SSATAXPCIE1_SSATAGP1"),
PINCTRL_PIN(225, "SSATAXPCIE2_SSATAGP2"),
PINCTRL_PIN(226, "SSATAXPCIE3_SSATAGP3"),
PINCTRL_PIN(227, "SSATAXPCIE4_SSATAGP4"),
PINCTRL_PIN(228, "SSATAXPCIE5_SSATAGP5"),
PINCTRL_PIN(203, "SRCCLKREQB_6"),
PINCTRL_PIN(204, "SRCCLKREQB_7"),
PINCTRL_PIN(205, "SRCCLKREQB_8"),
PINCTRL_PIN(206, "SRCCLKREQB_9"),
PINCTRL_PIN(207, "SRCCLKREQB_10"),
PINCTRL_PIN(208, "SRCCLKREQB_11"),
PINCTRL_PIN(209, "SRCCLKREQB_12"),
PINCTRL_PIN(210, "SRCCLKREQB_13"),
PINCTRL_PIN(211, "SRCCLKREQB_14"),
PINCTRL_PIN(212, "SRCCLKREQB_15"),
PINCTRL_PIN(213, "SML2CLK"),
PINCTRL_PIN(214, "SML2DATA"),
PINCTRL_PIN(215, "SML2ALERTB"),
PINCTRL_PIN(216, "SML3CLK"),
PINCTRL_PIN(217, "SML3DATA"),
PINCTRL_PIN(218, "SML3ALERTB"),
PINCTRL_PIN(219, "SML4CLK"),
PINCTRL_PIN(220, "SML4DATA"),
PINCTRL_PIN(221, "SML4ALERTB"),
PINCTRL_PIN(222, "SSATAXPCIE1_SSATAGP1"),
PINCTRL_PIN(223, "SSATAXPCIE2_SSATAGP2"),
PINCTRL_PIN(224, "SSATAXPCIE3_SSATAGP3"),
PINCTRL_PIN(225, "SSATAXPCIE4_SSATAGP4"),
PINCTRL_PIN(226, "SSATAXPCIE5_SSATAGP5"),
/* GPP_L */
PINCTRL_PIN(227, "GPP_L_0"),
PINCTRL_PIN(228, "EC_CSME_INTR_OUT"),
PINCTRL_PIN(229, "VISA2CH0_D0"),
PINCTRL_PIN(230, "VISA2CH0_D1"),
PINCTRL_PIN(231, "VISA2CH0_D2"),

View File

@ -0,0 +1,454 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Intel Tiger Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2019, Intel Corporation
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
#define TGL_PAD_OWN 0x020
#define TGL_PADCFGLOCK 0x080
#define TGL_HOSTSW_OWN 0x0b0
#define TGL_GPI_IS 0x100
#define TGL_GPI_IE 0x120
#define TGL_GPP(r, s, e) \
{ \
.reg_num = (r), \
.base = (s), \
.size = ((e) - (s) + 1), \
}
#define TGL_COMMUNITY(s, e, g) \
{ \
.padown_offset = TGL_PAD_OWN, \
.padcfglock_offset = TGL_PADCFGLOCK, \
.hostown_offset = TGL_HOSTSW_OWN, \
.is_offset = TGL_GPI_IS, \
.ie_offset = TGL_GPI_IE, \
.pin_base = (s), \
.npins = ((e) - (s) + 1), \
.gpps = (g), \
.ngpps = ARRAY_SIZE(g), \
}
/* Tiger Lake-LP */
static const struct pinctrl_pin_desc tgllp_community0_pins[] = {
/* GPP_B */
PINCTRL_PIN(0, "CORE_VID_0"),
PINCTRL_PIN(1, "CORE_VID_1"),
PINCTRL_PIN(2, "VRALERTB"),
PINCTRL_PIN(3, "CPU_GP_2"),
PINCTRL_PIN(4, "CPU_GP_3"),
PINCTRL_PIN(5, "ISH_I2C0_SDA"),
PINCTRL_PIN(6, "ISH_I2C0_SCL"),
PINCTRL_PIN(7, "ISH_I2C1_SDA"),
PINCTRL_PIN(8, "ISH_I2C1_SCL"),
PINCTRL_PIN(9, "I2C5_SDA"),
PINCTRL_PIN(10, "I2C5_SCL"),
PINCTRL_PIN(11, "PMCALERTB"),
PINCTRL_PIN(12, "SLP_S0B"),
PINCTRL_PIN(13, "PLTRSTB"),
PINCTRL_PIN(14, "SPKR"),
PINCTRL_PIN(15, "GSPI0_CS0B"),
PINCTRL_PIN(16, "GSPI0_CLK"),
PINCTRL_PIN(17, "GSPI0_MISO"),
PINCTRL_PIN(18, "GSPI0_MOSI"),
PINCTRL_PIN(19, "GSPI1_CS0B"),
PINCTRL_PIN(20, "GSPI1_CLK"),
PINCTRL_PIN(21, "GSPI1_MISO"),
PINCTRL_PIN(22, "GSPI1_MOSI"),
PINCTRL_PIN(23, "SML1ALERTB"),
PINCTRL_PIN(24, "GSPI0_CLK_LOOPBK"),
PINCTRL_PIN(25, "GSPI1_CLK_LOOPBK"),
/* GPP_T */
PINCTRL_PIN(26, "I2C6_SDA"),
PINCTRL_PIN(27, "I2C6_SCL"),
PINCTRL_PIN(28, "I2C7_SDA"),
PINCTRL_PIN(29, "I2C7_SCL"),
PINCTRL_PIN(30, "UART4_RXD"),
PINCTRL_PIN(31, "UART4_TXD"),
PINCTRL_PIN(32, "UART4_RTSB"),
PINCTRL_PIN(33, "UART4_CTSB"),
PINCTRL_PIN(34, "UART5_RXD"),
PINCTRL_PIN(35, "UART5_TXD"),
PINCTRL_PIN(36, "UART5_RTSB"),
PINCTRL_PIN(37, "UART5_CTSB"),
PINCTRL_PIN(38, "UART6_RXD"),
PINCTRL_PIN(39, "UART6_TXD"),
PINCTRL_PIN(40, "UART6_RTSB"),
PINCTRL_PIN(41, "UART6_CTSB"),
/* GPP_A */
PINCTRL_PIN(42, "ESPI_IO_0"),
PINCTRL_PIN(43, "ESPI_IO_1"),
PINCTRL_PIN(44, "ESPI_IO_2"),
PINCTRL_PIN(45, "ESPI_IO_3"),
PINCTRL_PIN(46, "ESPI_CSB"),
PINCTRL_PIN(47, "ESPI_CLK"),
PINCTRL_PIN(48, "ESPI_RESETB"),
PINCTRL_PIN(49, "I2S2_SCLK"),
PINCTRL_PIN(50, "I2S2_SFRM"),
PINCTRL_PIN(51, "I2S2_TXD"),
PINCTRL_PIN(52, "I2S2_RXD"),
PINCTRL_PIN(53, "PMC_I2C_SDA"),
PINCTRL_PIN(54, "SATAXPCIE_1"),
PINCTRL_PIN(55, "PMC_I2C_SCL"),
PINCTRL_PIN(56, "USB2_OCB_1"),
PINCTRL_PIN(57, "USB2_OCB_2"),
PINCTRL_PIN(58, "USB2_OCB_3"),
PINCTRL_PIN(59, "DDSP_HPD_C"),
PINCTRL_PIN(60, "DDSP_HPD_B"),
PINCTRL_PIN(61, "DDSP_HPD_1"),
PINCTRL_PIN(62, "DDSP_HPD_2"),
PINCTRL_PIN(63, "GPPC_A_21"),
PINCTRL_PIN(64, "GPPC_A_22"),
PINCTRL_PIN(65, "I2S1_SCLK"),
PINCTRL_PIN(66, "ESPI_CLK_LOOPBK"),
};
static const struct intel_padgroup tgllp_community0_gpps[] = {
TGL_GPP(0, 0, 25), /* GPP_B */
TGL_GPP(1, 26, 41), /* GPP_T */
TGL_GPP(2, 42, 66), /* GPP_A */
};
static const struct intel_community tgllp_community0[] = {
TGL_COMMUNITY(0, 66, tgllp_community0_gpps),
};
static const struct intel_pinctrl_soc_data tgllp_community0_soc_data = {
.uid = "0",
.pins = tgllp_community0_pins,
.npins = ARRAY_SIZE(tgllp_community0_pins),
.communities = tgllp_community0,
.ncommunities = ARRAY_SIZE(tgllp_community0),
};
static const struct pinctrl_pin_desc tgllp_community1_pins[] = {
/* GPP_S */
PINCTRL_PIN(0, "SNDW0_CLK"),
PINCTRL_PIN(1, "SNDW0_DATA"),
PINCTRL_PIN(2, "SNDW1_CLK"),
PINCTRL_PIN(3, "SNDW1_DATA"),
PINCTRL_PIN(4, "SNDW2_CLK"),
PINCTRL_PIN(5, "SNDW2_DATA"),
PINCTRL_PIN(6, "SNDW3_CLK"),
PINCTRL_PIN(7, "SNDW3_DATA"),
/* GPP_H */
PINCTRL_PIN(8, "GPPC_H_0"),
PINCTRL_PIN(9, "GPPC_H_1"),
PINCTRL_PIN(10, "GPPC_H_2"),
PINCTRL_PIN(11, "SX_EXIT_HOLDOFFB"),
PINCTRL_PIN(12, "I2C2_SDA"),
PINCTRL_PIN(13, "I2C2_SCL"),
PINCTRL_PIN(14, "I2C3_SDA"),
PINCTRL_PIN(15, "I2C3_SCL"),
PINCTRL_PIN(16, "I2C4_SDA"),
PINCTRL_PIN(17, "I2C4_SCL"),
PINCTRL_PIN(18, "SRCCLKREQB_4"),
PINCTRL_PIN(19, "SRCCLKREQB_5"),
PINCTRL_PIN(20, "M2_SKT2_CFG_0"),
PINCTRL_PIN(21, "M2_SKT2_CFG_1"),
PINCTRL_PIN(22, "M2_SKT2_CFG_2"),
PINCTRL_PIN(23, "M2_SKT2_CFG_3"),
PINCTRL_PIN(24, "DDPB_CTRLCLK"),
PINCTRL_PIN(25, "DDPB_CTRLDATA"),
PINCTRL_PIN(26, "CPU_C10_GATEB"),
PINCTRL_PIN(27, "TIME_SYNC_0"),
PINCTRL_PIN(28, "IMGCLKOUT_1"),
PINCTRL_PIN(29, "IMGCLKOUT_2"),
PINCTRL_PIN(30, "IMGCLKOUT_3"),
PINCTRL_PIN(31, "IMGCLKOUT_4"),
/* GPP_D */
PINCTRL_PIN(32, "ISH_GP_0"),
PINCTRL_PIN(33, "ISH_GP_1"),
PINCTRL_PIN(34, "ISH_GP_2"),
PINCTRL_PIN(35, "ISH_GP_3"),
PINCTRL_PIN(36, "IMGCLKOUT_0"),
PINCTRL_PIN(37, "SRCCLKREQB_0"),
PINCTRL_PIN(38, "SRCCLKREQB_1"),
PINCTRL_PIN(39, "SRCCLKREQB_2"),
PINCTRL_PIN(40, "SRCCLKREQB_3"),
PINCTRL_PIN(41, "ISH_SPI_CSB"),
PINCTRL_PIN(42, "ISH_SPI_CLK"),
PINCTRL_PIN(43, "ISH_SPI_MISO"),
PINCTRL_PIN(44, "ISH_SPI_MOSI"),
PINCTRL_PIN(45, "ISH_UART0_RXD"),
PINCTRL_PIN(46, "ISH_UART0_TXD"),
PINCTRL_PIN(47, "ISH_UART0_RTSB"),
PINCTRL_PIN(48, "ISH_UART0_CTSB"),
PINCTRL_PIN(49, "ISH_GP_4"),
PINCTRL_PIN(50, "ISH_GP_5"),
PINCTRL_PIN(51, "I2S_MCLK1_OUT"),
PINCTRL_PIN(52, "GSPI2_CLK_LOOPBK"),
/* GPP_U */
PINCTRL_PIN(53, "UART3_RXD"),
PINCTRL_PIN(54, "UART3_TXD"),
PINCTRL_PIN(55, "UART3_RTSB"),
PINCTRL_PIN(56, "UART3_CTSB"),
PINCTRL_PIN(57, "GSPI3_CS0B"),
PINCTRL_PIN(58, "GSPI3_CLK"),
PINCTRL_PIN(59, "GSPI3_MISO"),
PINCTRL_PIN(60, "GSPI3_MOSI"),
PINCTRL_PIN(61, "GSPI4_CS0B"),
PINCTRL_PIN(62, "GSPI4_CLK"),
PINCTRL_PIN(63, "GSPI4_MISO"),
PINCTRL_PIN(64, "GSPI4_MOSI"),
PINCTRL_PIN(65, "GSPI5_CS0B"),
PINCTRL_PIN(66, "GSPI5_CLK"),
PINCTRL_PIN(67, "GSPI5_MISO"),
PINCTRL_PIN(68, "GSPI5_MOSI"),
PINCTRL_PIN(69, "GSPI6_CS0B"),
PINCTRL_PIN(70, "GSPI6_CLK"),
PINCTRL_PIN(71, "GSPI6_MISO"),
PINCTRL_PIN(72, "GSPI6_MOSI"),
PINCTRL_PIN(73, "GSPI3_CLK_LOOPBK"),
PINCTRL_PIN(74, "GSPI4_CLK_LOOPBK"),
PINCTRL_PIN(75, "GSPI5_CLK_LOOPBK"),
PINCTRL_PIN(76, "GSPI6_CLK_LOOPBK"),
/* vGPIO */
PINCTRL_PIN(77, "CNV_BTEN"),
PINCTRL_PIN(78, "CNV_BT_HOST_WAKEB"),
PINCTRL_PIN(79, "CNV_BT_IF_SELECT"),
PINCTRL_PIN(80, "vCNV_BT_UART_TXD"),
PINCTRL_PIN(81, "vCNV_BT_UART_RXD"),
PINCTRL_PIN(82, "vCNV_BT_UART_CTS_B"),
PINCTRL_PIN(83, "vCNV_BT_UART_RTS_B"),
PINCTRL_PIN(84, "vCNV_MFUART1_TXD"),
PINCTRL_PIN(85, "vCNV_MFUART1_RXD"),
PINCTRL_PIN(86, "vCNV_MFUART1_CTS_B"),
PINCTRL_PIN(87, "vCNV_MFUART1_RTS_B"),
PINCTRL_PIN(88, "vUART0_TXD"),
PINCTRL_PIN(89, "vUART0_RXD"),
PINCTRL_PIN(90, "vUART0_CTS_B"),
PINCTRL_PIN(91, "vUART0_RTS_B"),
PINCTRL_PIN(92, "vISH_UART0_TXD"),
PINCTRL_PIN(93, "vISH_UART0_RXD"),
PINCTRL_PIN(94, "vISH_UART0_CTS_B"),
PINCTRL_PIN(95, "vISH_UART0_RTS_B"),
PINCTRL_PIN(96, "vCNV_BT_I2S_BCLK"),
PINCTRL_PIN(97, "vCNV_BT_I2S_WS_SYNC"),
PINCTRL_PIN(98, "vCNV_BT_I2S_SDO"),
PINCTRL_PIN(99, "vCNV_BT_I2S_SDI"),
PINCTRL_PIN(100, "vI2S2_SCLK"),
PINCTRL_PIN(101, "vI2S2_SFRM"),
PINCTRL_PIN(102, "vI2S2_TXD"),
PINCTRL_PIN(103, "vI2S2_RXD"),
};
static const struct intel_padgroup tgllp_community1_gpps[] = {
TGL_GPP(0, 0, 7), /* GPP_S */
TGL_GPP(1, 8, 31), /* GPP_H */
TGL_GPP(2, 32, 52), /* GPP_D */
TGL_GPP(3, 53, 76), /* GPP_U */
TGL_GPP(4, 77, 103), /* vGPIO */
};
static const struct intel_community tgllp_community1[] = {
TGL_COMMUNITY(0, 103, tgllp_community1_gpps),
};
static const struct intel_pinctrl_soc_data tgllp_community1_soc_data = {
.uid = "1",
.pins = tgllp_community1_pins,
.npins = ARRAY_SIZE(tgllp_community1_pins),
.communities = tgllp_community1,
.ncommunities = ARRAY_SIZE(tgllp_community1),
};
static const struct pinctrl_pin_desc tgllp_community4_pins[] = {
/* GPP_C */
PINCTRL_PIN(0, "SMBCLK"),
PINCTRL_PIN(1, "SMBDATA"),
PINCTRL_PIN(2, "SMBALERTB"),
PINCTRL_PIN(3, "SML0CLK"),
PINCTRL_PIN(4, "SML0DATA"),
PINCTRL_PIN(5, "SML0ALERTB"),
PINCTRL_PIN(6, "SML1CLK"),
PINCTRL_PIN(7, "SML1DATA"),
PINCTRL_PIN(8, "UART0_RXD"),
PINCTRL_PIN(9, "UART0_TXD"),
PINCTRL_PIN(10, "UART0_RTSB"),
PINCTRL_PIN(11, "UART0_CTSB"),
PINCTRL_PIN(12, "UART1_RXD"),
PINCTRL_PIN(13, "UART1_TXD"),
PINCTRL_PIN(14, "UART1_RTSB"),
PINCTRL_PIN(15, "UART1_CTSB"),
PINCTRL_PIN(16, "I2C0_SDA"),
PINCTRL_PIN(17, "I2C0_SCL"),
PINCTRL_PIN(18, "I2C1_SDA"),
PINCTRL_PIN(19, "I2C1_SCL"),
PINCTRL_PIN(20, "UART2_RXD"),
PINCTRL_PIN(21, "UART2_TXD"),
PINCTRL_PIN(22, "UART2_RTSB"),
PINCTRL_PIN(23, "UART2_CTSB"),
/* GPP_F */
PINCTRL_PIN(24, "CNV_BRI_DT"),
PINCTRL_PIN(25, "CNV_BRI_RSP"),
PINCTRL_PIN(26, "CNV_RGI_DT"),
PINCTRL_PIN(27, "CNV_RGI_RSP"),
PINCTRL_PIN(28, "CNV_RF_RESET_B"),
PINCTRL_PIN(29, "GPPC_F_5"),
PINCTRL_PIN(30, "CNV_PA_BLANKING"),
PINCTRL_PIN(31, "GPPC_F_7"),
PINCTRL_PIN(32, "I2S_MCLK2_INOUT"),
PINCTRL_PIN(33, "BOOTMPC"),
PINCTRL_PIN(34, "GPPC_F_10"),
PINCTRL_PIN(35, "GPPC_F_11"),
PINCTRL_PIN(36, "GSXDOUT"),
PINCTRL_PIN(37, "GSXSLOAD"),
PINCTRL_PIN(38, "GSXDIN"),
PINCTRL_PIN(39, "GSXSRESETB"),
PINCTRL_PIN(40, "GSXCLK"),
PINCTRL_PIN(41, "GMII_MDC"),
PINCTRL_PIN(42, "GMII_MDIO"),
PINCTRL_PIN(43, "SRCCLKREQB_6"),
PINCTRL_PIN(44, "EXT_PWR_GATEB"),
PINCTRL_PIN(45, "EXT_PWR_GATE2B"),
PINCTRL_PIN(46, "VNN_CTRL"),
PINCTRL_PIN(47, "V1P05_CTRL"),
PINCTRL_PIN(48, "GPPF_CLK_LOOPBACK"),
/* HVCMOS */
PINCTRL_PIN(49, "L_BKLTEN"),
PINCTRL_PIN(50, "L_BKLTCTL"),
PINCTRL_PIN(51, "L_VDDEN"),
PINCTRL_PIN(52, "SYS_PWROK"),
PINCTRL_PIN(53, "SYS_RESETB"),
PINCTRL_PIN(54, "MLK_RSTB"),
/* GPP_E */
PINCTRL_PIN(55, "SATAXPCIE_0"),
PINCTRL_PIN(56, "SPI1_IO_2"),
PINCTRL_PIN(57, "SPI1_IO_3"),
PINCTRL_PIN(58, "CPU_GP_0"),
PINCTRL_PIN(59, "SATA_DEVSLP_0"),
PINCTRL_PIN(60, "SATA_DEVSLP_1"),
PINCTRL_PIN(61, "GPPC_E_6"),
PINCTRL_PIN(62, "CPU_GP_1"),
PINCTRL_PIN(63, "SPI1_CS1B"),
PINCTRL_PIN(64, "USB2_OCB_0"),
PINCTRL_PIN(65, "SPI1_CSB"),
PINCTRL_PIN(66, "SPI1_CLK"),
PINCTRL_PIN(67, "SPI1_MISO_IO_1"),
PINCTRL_PIN(68, "SPI1_MOSI_IO_0"),
PINCTRL_PIN(69, "DDSP_HPD_A"),
PINCTRL_PIN(70, "ISH_GP_6"),
PINCTRL_PIN(71, "ISH_GP_7"),
PINCTRL_PIN(72, "GPPC_E_17"),
PINCTRL_PIN(73, "DDP1_CTRLCLK"),
PINCTRL_PIN(74, "DDP1_CTRLDATA"),
PINCTRL_PIN(75, "DDP2_CTRLCLK"),
PINCTRL_PIN(76, "DDP2_CTRLDATA"),
PINCTRL_PIN(77, "DDPA_CTRLCLK"),
PINCTRL_PIN(78, "DDPA_CTRLDATA"),
PINCTRL_PIN(79, "SPI1_CLK_LOOPBK"),
/* JTAG */
PINCTRL_PIN(80, "JTAG_TDO"),
PINCTRL_PIN(81, "JTAGX"),
PINCTRL_PIN(82, "PRDYB"),
PINCTRL_PIN(83, "PREQB"),
PINCTRL_PIN(84, "CPU_TRSTB"),
PINCTRL_PIN(85, "JTAG_TDI"),
PINCTRL_PIN(86, "JTAG_TMS"),
PINCTRL_PIN(87, "JTAG_TCK"),
PINCTRL_PIN(88, "DBG_PMODE"),
};
static const struct intel_padgroup tgllp_community4_gpps[] = {
TGL_GPP(0, 0, 23), /* GPP_C */
TGL_GPP(1, 24, 48), /* GPP_F */
TGL_GPP(2, 49, 54), /* HVCMOS */
TGL_GPP(3, 55, 79), /* GPP_E */
TGL_GPP(4, 80, 88), /* JTAG */
};
static const struct intel_community tgllp_community4[] = {
TGL_COMMUNITY(0, 88, tgllp_community4_gpps),
};
static const struct intel_pinctrl_soc_data tgllp_community4_soc_data = {
.uid = "4",
.pins = tgllp_community4_pins,
.npins = ARRAY_SIZE(tgllp_community4_pins),
.communities = tgllp_community4,
.ncommunities = ARRAY_SIZE(tgllp_community4),
};
static const struct pinctrl_pin_desc tgllp_community5_pins[] = {
/* GPP_R */
PINCTRL_PIN(0, "HDA_BCLK"),
PINCTRL_PIN(1, "HDA_SYNC"),
PINCTRL_PIN(2, "HDA_SDO"),
PINCTRL_PIN(3, "HDA_SDI_0"),
PINCTRL_PIN(4, "HDA_RSTB"),
PINCTRL_PIN(5, "HDA_SDI_1"),
PINCTRL_PIN(6, "GPP_R_6"),
PINCTRL_PIN(7, "GPP_R_7"),
/* SPI */
PINCTRL_PIN(8, "SPI0_IO_2"),
PINCTRL_PIN(9, "SPI0_IO_3"),
PINCTRL_PIN(10, "SPI0_MOSI_IO_0"),
PINCTRL_PIN(11, "SPI0_MISO_IO_1"),
PINCTRL_PIN(12, "SPI0_TPM_CSB"),
PINCTRL_PIN(13, "SPI0_FLASH_0_CSB"),
PINCTRL_PIN(14, "SPI0_FLASH_1_CSB"),
PINCTRL_PIN(15, "SPI0_CLK"),
PINCTRL_PIN(16, "SPI0_CLK_LOOPBK"),
};
static const struct intel_padgroup tgllp_community5_gpps[] = {
TGL_GPP(0, 0, 7), /* GPP_R */
TGL_GPP(1, 8, 16), /* SPI */
};
static const struct intel_community tgllp_community5[] = {
TGL_COMMUNITY(0, 16, tgllp_community5_gpps),
};
static const struct intel_pinctrl_soc_data tgllp_community5_soc_data = {
.uid = "5",
.pins = tgllp_community5_pins,
.npins = ARRAY_SIZE(tgllp_community5_pins),
.communities = tgllp_community5,
.ncommunities = ARRAY_SIZE(tgllp_community5),
};
static const struct intel_pinctrl_soc_data *tgllp_soc_data_array[] = {
&tgllp_community0_soc_data,
&tgllp_community1_soc_data,
&tgllp_community4_soc_data,
&tgllp_community5_soc_data,
NULL
};
static const struct acpi_device_id tgl_pinctrl_acpi_match[] = {
{ "INT34C5", (kernel_ulong_t)tgllp_soc_data_array },
{ }
};
MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match);
static INTEL_PINCTRL_PM_OPS(tgl_pinctrl_pm_ops);
static struct platform_driver tgl_pinctrl_driver = {
.probe = intel_pinctrl_probe_by_uid,
.driver = {
.name = "tigerlake-pinctrl",
.acpi_match_table = tgl_pinctrl_acpi_match,
.pm = &tgl_pinctrl_pm_ops,
},
};
module_platform_driver(tgl_pinctrl_driver);
MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
MODULE_DESCRIPTION("Intel Tiger Lake PCH pinctrl/GPIO driver");
MODULE_LICENSE("GPL v2");

View File

@ -982,7 +982,6 @@ static const struct mtk_eint_xt mtk_eint_xt = {
static int mtk_eint_init(struct mtk_pinctrl *pctl, struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct resource *res;
if (!of_property_read_bool(np, "interrupt-controller"))
return -ENODEV;
@ -991,8 +990,7 @@ static int mtk_eint_init(struct mtk_pinctrl *pctl, struct platform_device *pdev)
if (!pctl->eint)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctl->eint->base = devm_ioremap_resource(&pdev->dev, res);
pctl->eint->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctl->eint->base))
return PTR_ERR(pctl->eint->base);

View File

@ -54,4 +54,10 @@ config PINCTRL_MESON_G12A
select PINCTRL_MESON_AXG_PMX
default y
config PINCTRL_MESON_A1
bool "Meson a1 Soc pinctrl driver"
depends on ARM64
select PINCTRL_MESON_AXG_PMX
default y
endif

View File

@ -8,3 +8,4 @@ obj-$(CONFIG_PINCTRL_MESON_GXL) += pinctrl-meson-gxl.o
obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o
obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o
obj-$(CONFIG_PINCTRL_MESON_G12A) += pinctrl-meson-g12a.o
obj-$(CONFIG_PINCTRL_MESON_A1) += pinctrl-meson-a1.o

View File

@ -0,0 +1,942 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Pin controller and GPIO driver for Amlogic Meson A1 SoC.
*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
* Author: Qianggui Song <qianggui.song@amlogic.com>
*/
#include <dt-bindings/gpio/meson-a1-gpio.h>
#include "pinctrl-meson.h"
#include "pinctrl-meson-axg-pmx.h"
static const struct pinctrl_pin_desc meson_a1_periphs_pins[] = {
MESON_PIN(GPIOP_0),
MESON_PIN(GPIOP_1),
MESON_PIN(GPIOP_2),
MESON_PIN(GPIOP_3),
MESON_PIN(GPIOP_4),
MESON_PIN(GPIOP_5),
MESON_PIN(GPIOP_6),
MESON_PIN(GPIOP_7),
MESON_PIN(GPIOP_8),
MESON_PIN(GPIOP_9),
MESON_PIN(GPIOP_10),
MESON_PIN(GPIOP_11),
MESON_PIN(GPIOP_12),
MESON_PIN(GPIOB_0),
MESON_PIN(GPIOB_1),
MESON_PIN(GPIOB_2),
MESON_PIN(GPIOB_3),
MESON_PIN(GPIOB_4),
MESON_PIN(GPIOB_5),
MESON_PIN(GPIOB_6),
MESON_PIN(GPIOX_0),
MESON_PIN(GPIOX_1),
MESON_PIN(GPIOX_2),
MESON_PIN(GPIOX_3),
MESON_PIN(GPIOX_4),
MESON_PIN(GPIOX_5),
MESON_PIN(GPIOX_6),
MESON_PIN(GPIOX_7),
MESON_PIN(GPIOX_8),
MESON_PIN(GPIOX_9),
MESON_PIN(GPIOX_10),
MESON_PIN(GPIOX_11),
MESON_PIN(GPIOX_12),
MESON_PIN(GPIOX_13),
MESON_PIN(GPIOX_14),
MESON_PIN(GPIOX_15),
MESON_PIN(GPIOX_16),
MESON_PIN(GPIOF_0),
MESON_PIN(GPIOF_1),
MESON_PIN(GPIOF_2),
MESON_PIN(GPIOF_3),
MESON_PIN(GPIOF_4),
MESON_PIN(GPIOF_5),
MESON_PIN(GPIOF_6),
MESON_PIN(GPIOF_7),
MESON_PIN(GPIOF_8),
MESON_PIN(GPIOF_9),
MESON_PIN(GPIOF_10),
MESON_PIN(GPIOF_11),
MESON_PIN(GPIOF_12),
MESON_PIN(GPIOA_0),
MESON_PIN(GPIOA_1),
MESON_PIN(GPIOA_2),
MESON_PIN(GPIOA_3),
MESON_PIN(GPIOA_4),
MESON_PIN(GPIOA_5),
MESON_PIN(GPIOA_6),
MESON_PIN(GPIOA_7),
MESON_PIN(GPIOA_8),
MESON_PIN(GPIOA_9),
MESON_PIN(GPIOA_10),
MESON_PIN(GPIOA_11),
};
/* psram */
static const unsigned int psram_clkn_pins[] = { GPIOP_0 };
static const unsigned int psram_clkp_pins[] = { GPIOP_1 };
static const unsigned int psram_ce_n_pins[] = { GPIOP_2 };
static const unsigned int psram_rst_n_pins[] = { GPIOP_3 };
static const unsigned int psram_adq0_pins[] = { GPIOP_4 };
static const unsigned int psram_adq1_pins[] = { GPIOP_5 };
static const unsigned int psram_adq2_pins[] = { GPIOP_6 };
static const unsigned int psram_adq3_pins[] = { GPIOP_7 };
static const unsigned int psram_adq4_pins[] = { GPIOP_8 };
static const unsigned int psram_adq5_pins[] = { GPIOP_9 };
static const unsigned int psram_adq6_pins[] = { GPIOP_10 };
static const unsigned int psram_adq7_pins[] = { GPIOP_11 };
static const unsigned int psram_dqs_dm_pins[] = { GPIOP_12 };
/* sdcard */
static const unsigned int sdcard_d0_b_pins[] = { GPIOB_0 };
static const unsigned int sdcard_d1_b_pins[] = { GPIOB_1 };
static const unsigned int sdcard_d2_b_pins[] = { GPIOB_2 };
static const unsigned int sdcard_d3_b_pins[] = { GPIOB_3 };
static const unsigned int sdcard_clk_b_pins[] = { GPIOB_4 };
static const unsigned int sdcard_cmd_b_pins[] = { GPIOB_5 };
static const unsigned int sdcard_d0_x_pins[] = { GPIOX_0 };
static const unsigned int sdcard_d1_x_pins[] = { GPIOX_1 };
static const unsigned int sdcard_d2_x_pins[] = { GPIOX_2 };
static const unsigned int sdcard_d3_x_pins[] = { GPIOX_3 };
static const unsigned int sdcard_clk_x_pins[] = { GPIOX_4 };
static const unsigned int sdcard_cmd_x_pins[] = { GPIOX_5 };
/* spif */
static const unsigned int spif_mo_pins[] = { GPIOB_0 };
static const unsigned int spif_mi_pins[] = { GPIOB_1 };
static const unsigned int spif_wp_n_pins[] = { GPIOB_2 };
static const unsigned int spif_hold_n_pins[] = { GPIOB_3 };
static const unsigned int spif_clk_pins[] = { GPIOB_4 };
static const unsigned int spif_cs_pins[] = { GPIOB_5 };
/* i2c0 */
static const unsigned int i2c0_sck_f9_pins[] = { GPIOF_9 };
static const unsigned int i2c0_sda_f10_pins[] = { GPIOF_10 };
static const unsigned int i2c0_sck_f11_pins[] = { GPIOF_11 };
static const unsigned int i2c0_sda_f12_pins[] = { GPIOF_12 };
/* i2c1 */
static const unsigned int i2c1_sda_x_pins[] = { GPIOX_9 };
static const unsigned int i2c1_sck_x_pins[] = { GPIOX_10 };
static const unsigned int i2c1_sda_a_pins[] = { GPIOA_10 };
static const unsigned int i2c1_sck_a_pins[] = { GPIOA_11 };
/* i2c2 */
static const unsigned int i2c2_sck_x0_pins[] = { GPIOX_0 };
static const unsigned int i2c2_sda_x1_pins[] = { GPIOX_1 };
static const unsigned int i2c2_sck_x15_pins[] = { GPIOX_15 };
static const unsigned int i2c2_sda_x16_pins[] = { GPIOX_16 };
static const unsigned int i2c2_sck_a4_pins[] = { GPIOA_4 };
static const unsigned int i2c2_sda_a5_pins[] = { GPIOA_5 };
static const unsigned int i2c2_sck_a8_pins[] = { GPIOA_8 };
static const unsigned int i2c2_sda_a9_pins[] = { GPIOA_9 };
/* i2c3 */
static const unsigned int i2c3_sck_f_pins[] = { GPIOF_4 };
static const unsigned int i2c3_sda_f_pins[] = { GPIOF_5 };
static const unsigned int i2c3_sck_x_pins[] = { GPIOX_11 };
static const unsigned int i2c3_sda_x_pins[] = { GPIOX_12 };
/* i2c slave */
static const unsigned int i2c_slave_sck_a_pins[] = { GPIOA_10 };
static const unsigned int i2c_slave_sda_a_pins[] = { GPIOA_11 };
static const unsigned int i2c_slave_sck_f_pins[] = { GPIOF_11 };
static const unsigned int i2c_slave_sda_f_pins[] = { GPIOF_12 };
/* uart_a */
static const unsigned int uart_a_tx_pins[] = { GPIOX_11 };
static const unsigned int uart_a_rx_pins[] = { GPIOX_12 };
static const unsigned int uart_a_cts_pins[] = { GPIOX_13 };
static const unsigned int uart_a_rts_pins[] = { GPIOX_14 };
/* uart_b */
static const unsigned int uart_b_tx_x_pins[] = { GPIOX_7 };
static const unsigned int uart_b_rx_x_pins[] = { GPIOX_8 };
static const unsigned int uart_b_tx_f_pins[] = { GPIOF_0 };
static const unsigned int uart_b_rx_f_pins[] = { GPIOF_1 };
/* uart_c */
static const unsigned int uart_c_tx_x0_pins[] = { GPIOX_0 };
static const unsigned int uart_c_rx_x1_pins[] = { GPIOX_1 };
static const unsigned int uart_c_cts_pins[] = { GPIOX_2 };
static const unsigned int uart_c_rts_pins[] = { GPIOX_3 };
static const unsigned int uart_c_tx_x15_pins[] = { GPIOX_15 };
static const unsigned int uart_c_rx_x16_pins[] = { GPIOX_16 };
/* pmw_a */
static const unsigned int pwm_a_x6_pins[] = { GPIOX_6 };
static const unsigned int pwm_a_x7_pins[] = { GPIOX_7 };
static const unsigned int pwm_a_f6_pins[] = { GPIOF_6 };
static const unsigned int pwm_a_f10_pins[] = { GPIOF_10 };
static const unsigned int pwm_a_a_pins[] = { GPIOA_5 };
/* pmw_b */
static const unsigned int pwm_b_x_pins[] = { GPIOX_8 };
static const unsigned int pwm_b_f_pins[] = { GPIOF_7 };
static const unsigned int pwm_b_a_pins[] = { GPIOA_11 };
/* pmw_c */
static const unsigned int pwm_c_x_pins[] = { GPIOX_9 };
static const unsigned int pwm_c_f3_pins[] = { GPIOF_3 };
static const unsigned int pwm_c_f8_pins[] = { GPIOF_8 };
static const unsigned int pwm_c_a_pins[] = { GPIOA_10 };
/* pwm_d */
static const unsigned int pwm_d_x10_pins[] = { GPIOX_10 };
static const unsigned int pwm_d_x13_pins[] = { GPIOX_13 };
static const unsigned int pwm_d_x15_pins[] = { GPIOX_15 };
static const unsigned int pwm_d_f_pins[] = { GPIOF_11 };
/* pwm_e */
static const unsigned int pwm_e_p_pins[] = { GPIOP_3 };
static const unsigned int pwm_e_x2_pins[] = { GPIOX_2 };
static const unsigned int pwm_e_x14_pins[] = { GPIOX_14 };
static const unsigned int pwm_e_x16_pins[] = { GPIOX_16 };
static const unsigned int pwm_e_f_pins[] = { GPIOF_3 };
static const unsigned int pwm_e_a_pins[] = { GPIOA_0 };
/* pwm_f */
static const unsigned int pwm_f_b_pins[] = { GPIOB_6 };
static const unsigned int pwm_f_x_pins[] = { GPIOX_3 };
static const unsigned int pwm_f_f4_pins[] = { GPIOF_4 };
static const unsigned int pwm_f_f12_pins[] = { GPIOF_12 };
/* pwm_a_hiz */
static const unsigned int pwm_a_hiz_f8_pins[] = { GPIOF_8 };
static const unsigned int pwm_a_hiz_f10_pins[] = { GPIOF_10 };
static const unsigned int pmw_a_hiz_f6_pins[] = { GPIOF_6 };
/* pwm_b_hiz */
static const unsigned int pwm_b_hiz_pins[] = { GPIOF_7 };
/* pmw_c_hiz */
static const unsigned int pwm_c_hiz_pins[] = { GPIOF_8 };
/* tdm_a */
static const unsigned int tdm_a_dout1_pins[] = { GPIOX_7 };
static const unsigned int tdm_a_dout0_pins[] = { GPIOX_8 };
static const unsigned int tdm_a_fs_pins[] = { GPIOX_9 };
static const unsigned int tdm_a_sclk_pins[] = { GPIOX_10 };
static const unsigned int tdm_a_din1_pins[] = { GPIOX_7 };
static const unsigned int tdm_a_din0_pins[] = { GPIOX_8 };
static const unsigned int tdm_a_slv_fs_pins[] = { GPIOX_9 };
static const unsigned int tdm_a_slv_sclk_pins[] = { GPIOX_10 };
/* spi_a */
static const unsigned int spi_a_mosi_x2_pins[] = { GPIOX_2 };
static const unsigned int spi_a_ss0_x3_pins[] = { GPIOX_3 };
static const unsigned int spi_a_sclk_x4_pins[] = { GPIOX_4 };
static const unsigned int spi_a_miso_x5_pins[] = { GPIOX_5 };
static const unsigned int spi_a_mosi_x7_pins[] = { GPIOX_7 };
static const unsigned int spi_a_miso_x8_pins[] = { GPIOX_8 };
static const unsigned int spi_a_ss0_x9_pins[] = { GPIOX_9 };
static const unsigned int spi_a_sclk_x10_pins[] = { GPIOX_10 };
static const unsigned int spi_a_mosi_a_pins[] = { GPIOA_6 };
static const unsigned int spi_a_miso_a_pins[] = { GPIOA_7 };
static const unsigned int spi_a_ss0_a_pins[] = { GPIOA_8 };
static const unsigned int spi_a_sclk_a_pins[] = { GPIOA_9 };
/* pdm */
static const unsigned int pdm_din0_x_pins[] = { GPIOX_7 };
static const unsigned int pdm_din1_x_pins[] = { GPIOX_8 };
static const unsigned int pdm_din2_x_pins[] = { GPIOX_9 };
static const unsigned int pdm_dclk_x_pins[] = { GPIOX_10 };
static const unsigned int pdm_din2_a_pins[] = { GPIOA_6 };
static const unsigned int pdm_din1_a_pins[] = { GPIOA_7 };
static const unsigned int pdm_din0_a_pins[] = { GPIOA_8 };
static const unsigned int pdm_dclk_pins[] = { GPIOA_9 };
/* gen_clk */
static const unsigned int gen_clk_x_pins[] = { GPIOX_7 };
static const unsigned int gen_clk_f8_pins[] = { GPIOF_8 };
static const unsigned int gen_clk_f10_pins[] = { GPIOF_10 };
static const unsigned int gen_clk_a_pins[] = { GPIOA_11 };
/* jtag_a */
static const unsigned int jtag_a_clk_pins[] = { GPIOF_4 };
static const unsigned int jtag_a_tms_pins[] = { GPIOF_5 };
static const unsigned int jtag_a_tdi_pins[] = { GPIOF_6 };
static const unsigned int jtag_a_tdo_pins[] = { GPIOF_7 };
/* clk_32_in */
static const unsigned int clk_32k_in_pins[] = { GPIOF_2 };
/* ir in */
static const unsigned int remote_input_f_pins[] = { GPIOF_3 };
static const unsigned int remote_input_a_pins[] = { GPIOA_11 };
/* ir out */
static const unsigned int remote_out_pins[] = { GPIOF_5 };
/* spdif */
static const unsigned int spdif_in_f6_pins[] = { GPIOF_6 };
static const unsigned int spdif_in_f7_pins[] = { GPIOF_7 };
/* sw */
static const unsigned int swclk_pins[] = { GPIOF_4 };
static const unsigned int swdio_pins[] = { GPIOF_5 };
/* clk_25 */
static const unsigned int clk25_pins[] = { GPIOF_10 };
/* cec_a */
static const unsigned int cec_a_pins[] = { GPIOF_2 };
/* cec_b */
static const unsigned int cec_b_pins[] = { GPIOF_2 };
/* clk12_24 */
static const unsigned int clk12_24_pins[] = { GPIOF_10 };
/* mclk_0 */
static const unsigned int mclk_0_pins[] = { GPIOA_0 };
/* tdm_b */
static const unsigned int tdm_b_sclk_pins[] = { GPIOA_1 };
static const unsigned int tdm_b_fs_pins[] = { GPIOA_2 };
static const unsigned int tdm_b_dout0_pins[] = { GPIOA_3 };
static const unsigned int tdm_b_dout1_pins[] = { GPIOA_4 };
static const unsigned int tdm_b_dout2_pins[] = { GPIOA_5 };
static const unsigned int tdm_b_dout3_pins[] = { GPIOA_6 };
static const unsigned int tdm_b_dout4_pins[] = { GPIOA_7 };
static const unsigned int tdm_b_dout5_pins[] = { GPIOA_8 };
static const unsigned int tdm_b_slv_sclk_pins[] = { GPIOA_5 };
static const unsigned int tdm_b_slv_fs_pins[] = { GPIOA_6 };
static const unsigned int tdm_b_din0_pins[] = { GPIOA_7 };
static const unsigned int tdm_b_din1_pins[] = { GPIOA_8 };
static const unsigned int tdm_b_din2_pins[] = { GPIOA_9 };
/* mclk_vad */
static const unsigned int mclk_vad_pins[] = { GPIOA_0 };
/* tdm_vad */
static const unsigned int tdm_vad_sclk_a1_pins[] = { GPIOA_1 };
static const unsigned int tdm_vad_fs_a2_pins[] = { GPIOA_2 };
static const unsigned int tdm_vad_sclk_a5_pins[] = { GPIOA_5 };
static const unsigned int tdm_vad_fs_a6_pins[] = { GPIOA_6 };
/* tst_out */
static const unsigned int tst_out0_pins[] = { GPIOA_0 };
static const unsigned int tst_out1_pins[] = { GPIOA_1 };
static const unsigned int tst_out2_pins[] = { GPIOA_2 };
static const unsigned int tst_out3_pins[] = { GPIOA_3 };
static const unsigned int tst_out4_pins[] = { GPIOA_4 };
static const unsigned int tst_out5_pins[] = { GPIOA_5 };
static const unsigned int tst_out6_pins[] = { GPIOA_6 };
static const unsigned int tst_out7_pins[] = { GPIOA_7 };
static const unsigned int tst_out8_pins[] = { GPIOA_8 };
static const unsigned int tst_out9_pins[] = { GPIOA_9 };
static const unsigned int tst_out10_pins[] = { GPIOA_10 };
static const unsigned int tst_out11_pins[] = { GPIOA_11 };
/* mute */
static const unsigned int mute_key_pins[] = { GPIOA_4 };
static const unsigned int mute_en_pins[] = { GPIOA_5 };
static struct meson_pmx_group meson_a1_periphs_groups[] = {
GPIO_GROUP(GPIOP_0),
GPIO_GROUP(GPIOP_1),
GPIO_GROUP(GPIOP_2),
GPIO_GROUP(GPIOP_3),
GPIO_GROUP(GPIOP_4),
GPIO_GROUP(GPIOP_5),
GPIO_GROUP(GPIOP_6),
GPIO_GROUP(GPIOP_7),
GPIO_GROUP(GPIOP_8),
GPIO_GROUP(GPIOP_9),
GPIO_GROUP(GPIOP_10),
GPIO_GROUP(GPIOP_11),
GPIO_GROUP(GPIOP_12),
GPIO_GROUP(GPIOB_0),
GPIO_GROUP(GPIOB_1),
GPIO_GROUP(GPIOB_2),
GPIO_GROUP(GPIOB_3),
GPIO_GROUP(GPIOB_4),
GPIO_GROUP(GPIOB_5),
GPIO_GROUP(GPIOB_6),
GPIO_GROUP(GPIOX_0),
GPIO_GROUP(GPIOX_1),
GPIO_GROUP(GPIOX_2),
GPIO_GROUP(GPIOX_3),
GPIO_GROUP(GPIOX_4),
GPIO_GROUP(GPIOX_5),
GPIO_GROUP(GPIOX_6),
GPIO_GROUP(GPIOX_7),
GPIO_GROUP(GPIOX_8),
GPIO_GROUP(GPIOX_9),
GPIO_GROUP(GPIOX_10),
GPIO_GROUP(GPIOX_11),
GPIO_GROUP(GPIOX_12),
GPIO_GROUP(GPIOX_13),
GPIO_GROUP(GPIOX_14),
GPIO_GROUP(GPIOX_15),
GPIO_GROUP(GPIOX_16),
GPIO_GROUP(GPIOF_0),
GPIO_GROUP(GPIOF_1),
GPIO_GROUP(GPIOF_2),
GPIO_GROUP(GPIOF_3),
GPIO_GROUP(GPIOF_4),
GPIO_GROUP(GPIOF_5),
GPIO_GROUP(GPIOF_6),
GPIO_GROUP(GPIOF_7),
GPIO_GROUP(GPIOF_8),
GPIO_GROUP(GPIOF_9),
GPIO_GROUP(GPIOF_10),
GPIO_GROUP(GPIOF_11),
GPIO_GROUP(GPIOF_12),
GPIO_GROUP(GPIOA_0),
GPIO_GROUP(GPIOA_1),
GPIO_GROUP(GPIOA_2),
GPIO_GROUP(GPIOA_3),
GPIO_GROUP(GPIOA_4),
GPIO_GROUP(GPIOA_5),
GPIO_GROUP(GPIOA_6),
GPIO_GROUP(GPIOA_7),
GPIO_GROUP(GPIOA_8),
GPIO_GROUP(GPIOA_9),
GPIO_GROUP(GPIOA_10),
GPIO_GROUP(GPIOA_11),
/* bank P func1 */
GROUP(psram_clkn, 1),
GROUP(psram_clkp, 1),
GROUP(psram_ce_n, 1),
GROUP(psram_rst_n, 1),
GROUP(psram_adq0, 1),
GROUP(psram_adq1, 1),
GROUP(psram_adq2, 1),
GROUP(psram_adq3, 1),
GROUP(psram_adq4, 1),
GROUP(psram_adq5, 1),
GROUP(psram_adq6, 1),
GROUP(psram_adq7, 1),
GROUP(psram_dqs_dm, 1),
/*bank P func2 */
GROUP(pwm_e_p, 2),
/*bank B func1 */
GROUP(spif_mo, 1),
GROUP(spif_mi, 1),
GROUP(spif_wp_n, 1),
GROUP(spif_hold_n, 1),
GROUP(spif_clk, 1),
GROUP(spif_cs, 1),
GROUP(pwm_f_b, 1),
/*bank B func2 */
GROUP(sdcard_d0_b, 2),
GROUP(sdcard_d1_b, 2),
GROUP(sdcard_d2_b, 2),
GROUP(sdcard_d3_b, 2),
GROUP(sdcard_clk_b, 2),
GROUP(sdcard_cmd_b, 2),
/*bank X func1 */
GROUP(sdcard_d0_x, 1),
GROUP(sdcard_d1_x, 1),
GROUP(sdcard_d2_x, 1),
GROUP(sdcard_d3_x, 1),
GROUP(sdcard_clk_x, 1),
GROUP(sdcard_cmd_x, 1),
GROUP(pwm_a_x6, 1),
GROUP(tdm_a_dout1, 1),
GROUP(tdm_a_dout0, 1),
GROUP(tdm_a_fs, 1),
GROUP(tdm_a_sclk, 1),
GROUP(uart_a_tx, 1),
GROUP(uart_a_rx, 1),
GROUP(uart_a_cts, 1),
GROUP(uart_a_rts, 1),
GROUP(pwm_d_x15, 1),
GROUP(pwm_e_x16, 1),
/*bank X func2 */
GROUP(i2c2_sck_x0, 2),
GROUP(i2c2_sda_x1, 2),
GROUP(spi_a_mosi_x2, 2),
GROUP(spi_a_ss0_x3, 2),
GROUP(spi_a_sclk_x4, 2),
GROUP(spi_a_miso_x5, 2),
GROUP(tdm_a_din1, 2),
GROUP(tdm_a_din0, 2),
GROUP(tdm_a_slv_fs, 2),
GROUP(tdm_a_slv_sclk, 2),
GROUP(i2c3_sck_x, 2),
GROUP(i2c3_sda_x, 2),
GROUP(pwm_d_x13, 2),
GROUP(pwm_e_x14, 2),
GROUP(i2c2_sck_x15, 2),
GROUP(i2c2_sda_x16, 2),
/*bank X func3 */
GROUP(uart_c_tx_x0, 3),
GROUP(uart_c_rx_x1, 3),
GROUP(uart_c_cts, 3),
GROUP(uart_c_rts, 3),
GROUP(pdm_din0_x, 3),
GROUP(pdm_din1_x, 3),
GROUP(pdm_din2_x, 3),
GROUP(pdm_dclk_x, 3),
GROUP(uart_c_tx_x15, 3),
GROUP(uart_c_rx_x16, 3),
/*bank X func4 */
GROUP(pwm_e_x2, 4),
GROUP(pwm_f_x, 4),
GROUP(spi_a_mosi_x7, 4),
GROUP(spi_a_miso_x8, 4),
GROUP(spi_a_ss0_x9, 4),
GROUP(spi_a_sclk_x10, 4),
/*bank X func5 */
GROUP(uart_b_tx_x, 5),
GROUP(uart_b_rx_x, 5),
GROUP(i2c1_sda_x, 5),
GROUP(i2c1_sck_x, 5),
/*bank X func6 */
GROUP(pwm_a_x7, 6),
GROUP(pwm_b_x, 6),
GROUP(pwm_c_x, 6),
GROUP(pwm_d_x10, 6),
/*bank X func7 */
GROUP(gen_clk_x, 7),
/*bank F func1 */
GROUP(uart_b_tx_f, 1),
GROUP(uart_b_rx_f, 1),
GROUP(remote_input_f, 1),
GROUP(jtag_a_clk, 1),
GROUP(jtag_a_tms, 1),
GROUP(jtag_a_tdi, 1),
GROUP(jtag_a_tdo, 1),
GROUP(gen_clk_f8, 1),
GROUP(pwm_a_f10, 1),
GROUP(i2c0_sck_f11, 1),
GROUP(i2c0_sda_f12, 1),
/*bank F func2 */
GROUP(clk_32k_in, 2),
GROUP(pwm_e_f, 2),
GROUP(pwm_f_f4, 2),
GROUP(remote_out, 2),
GROUP(spdif_in_f6, 2),
GROUP(spdif_in_f7, 2),
GROUP(pwm_a_hiz_f8, 2),
GROUP(pwm_a_hiz_f10, 2),
GROUP(pwm_d_f, 2),
GROUP(pwm_f_f12, 2),
/*bank F func3 */
GROUP(pwm_c_f3, 3),
GROUP(swclk, 3),
GROUP(swdio, 3),
GROUP(pwm_a_f6, 3),
GROUP(pwm_b_f, 3),
GROUP(pwm_c_f8, 3),
GROUP(clk25, 3),
GROUP(i2c_slave_sck_f, 3),
GROUP(i2c_slave_sda_f, 3),
/*bank F func4 */
GROUP(cec_a, 4),
GROUP(i2c3_sck_f, 4),
GROUP(i2c3_sda_f, 4),
GROUP(pmw_a_hiz_f6, 4),
GROUP(pwm_b_hiz, 4),
GROUP(pwm_c_hiz, 4),
GROUP(i2c0_sck_f9, 4),
GROUP(i2c0_sda_f10, 4),
/*bank F func5 */
GROUP(cec_b, 5),
GROUP(clk12_24, 5),
/*bank F func7 */
GROUP(gen_clk_f10, 7),
/*bank A func1 */
GROUP(mclk_0, 1),
GROUP(tdm_b_sclk, 1),
GROUP(tdm_b_fs, 1),
GROUP(tdm_b_dout0, 1),
GROUP(tdm_b_dout1, 1),
GROUP(tdm_b_dout2, 1),
GROUP(tdm_b_dout3, 1),
GROUP(tdm_b_dout4, 1),
GROUP(tdm_b_dout5, 1),
GROUP(remote_input_a, 1),
/*bank A func2 */
GROUP(pwm_e_a, 2),
GROUP(tdm_b_slv_sclk, 2),
GROUP(tdm_b_slv_fs, 2),
GROUP(tdm_b_din0, 2),
GROUP(tdm_b_din1, 2),
GROUP(tdm_b_din2, 2),
GROUP(i2c1_sda_a, 2),
GROUP(i2c1_sck_a, 2),
/*bank A func3 */
GROUP(i2c2_sck_a4, 3),
GROUP(i2c2_sda_a5, 3),
GROUP(pdm_din2_a, 3),
GROUP(pdm_din1_a, 3),
GROUP(pdm_din0_a, 3),
GROUP(pdm_dclk, 3),
GROUP(pwm_c_a, 3),
GROUP(pwm_b_a, 3),
/*bank A func4 */
GROUP(pwm_a_a, 4),
GROUP(spi_a_mosi_a, 4),
GROUP(spi_a_miso_a, 4),
GROUP(spi_a_ss0_a, 4),
GROUP(spi_a_sclk_a, 4),
GROUP(i2c_slave_sck_a, 4),
GROUP(i2c_slave_sda_a, 4),
/*bank A func5 */
GROUP(mclk_vad, 5),
GROUP(tdm_vad_sclk_a1, 5),
GROUP(tdm_vad_fs_a2, 5),
GROUP(tdm_vad_sclk_a5, 5),
GROUP(tdm_vad_fs_a6, 5),
GROUP(i2c2_sck_a8, 5),
GROUP(i2c2_sda_a9, 5),
/*bank A func6 */
GROUP(tst_out0, 6),
GROUP(tst_out1, 6),
GROUP(tst_out2, 6),
GROUP(tst_out3, 6),
GROUP(tst_out4, 6),
GROUP(tst_out5, 6),
GROUP(tst_out6, 6),
GROUP(tst_out7, 6),
GROUP(tst_out8, 6),
GROUP(tst_out9, 6),
GROUP(tst_out10, 6),
GROUP(tst_out11, 6),
/*bank A func7 */
GROUP(mute_key, 7),
GROUP(mute_en, 7),
GROUP(gen_clk_a, 7),
};
static const char * const gpio_periphs_groups[] = {
"GPIOP_0", "GPIOP_1", "GPIOP_2", "GPIOP_3", "GPIOP_4",
"GPIOP_5", "GPIOP_6", "GPIOP_7", "GPIOP_8", "GPIOP_9",
"GPIOP_10", "GPIOP_11", "GPIOP_12",
"GPIOB_0", "GPIOB_1", "GPIOB_2", "GPIOB_3", "GPIOB_4",
"GPIOB_5", "GPIOB_6",
"GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4",
"GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
"GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
"GPIOX_15", "GPIOX_16",
"GPIOF_0", "GPIOF_1", "GPIOF_2", "GPIOF_3", "GPIOF_4",
"GPIOF_5", "GPIOF_6", "GPIOF_7", "GPIOF_8", "GPIOF_9",
"GPIOF_10", "GPIOF_11", "GPIOF_12",
"GPIOA_0", "GPIOA_1", "GPIOA_2", "GPIOA_3", "GPIOA_4",
"GPIOA_5", "GPIOA_6", "GPIOA_7", "GPIOA_8", "GPIOA_9",
"GPIOA_10", "GPIOA_11",
};
static const char * const psram_groups[] = {
"psram_clkn", "psram_clkp", "psram_ce_n", "psram_rst_n", "psram_adq0",
"psram_adq1", "psram_adq2", "psram_adq3", "psram_adq4", "psram_adq5",
"psram_adq6", "psram_adq7", "psram_dqs_dm",
};
static const char * const pwm_a_groups[] = {
"pwm_a_x6", "pwm_a_x7", "pwm_a_f10", "pwm_a_f6", "pwm_a_a",
};
static const char * const pwm_b_groups[] = {
"pwm_b_x", "pwm_b_f", "pwm_b_a",
};
static const char * const pwm_c_groups[] = {
"pwm_c_x", "pwm_c_f3", "pwm_c_f8", "pwm_c_a",
};
static const char * const pwm_d_groups[] = {
"pwm_d_x15", "pwm_d_x13", "pwm_d_x10", "pwm_d_f",
};
static const char * const pwm_e_groups[] = {
"pwm_e_p", "pwm_e_x16", "pwm_e_x14", "pwm_e_x2", "pwm_e_f",
"pwm_e_a",
};
static const char * const pwm_f_groups[] = {
"pwm_f_b", "pwm_f_x", "pwm_f_f4", "pwm_f_f12",
};
static const char * const pwm_a_hiz_groups[] = {
"pwm_a_hiz_f8", "pwm_a_hiz_f10", "pwm_a_hiz_f6",
};
static const char * const pwm_b_hiz_groups[] = {
"pwm_b_hiz",
};
static const char * const pwm_c_hiz_groups[] = {
"pwm_c_hiz",
};
static const char * const spif_groups[] = {
"spif_mo", "spif_mi", "spif_wp_n", "spif_hold_n", "spif_clk",
"spif_cs",
};
static const char * const sdcard_groups[] = {
"sdcard_d0_b", "sdcard_d1_b", "sdcard_d2_b", "sdcard_d3_b",
"sdcard_clk_b", "sdcard_cmd_b",
"sdcard_d0_x", "sdcard_d1_x", "sdcard_d2_x", "sdcard_d3_x",
"sdcard_clk_x", "sdcard_cmd_x",
};
static const char * const tdm_a_groups[] = {
"tdm_a_din0", "tdm_a_din1", "tdm_a_fs", "tdm_a_sclk",
"tdm_a_slv_fs", "tdm_a_slv_sclk", "tdm_a_dout0", "tdm_a_dout1",
};
static const char * const uart_a_groups[] = {
"uart_a_tx", "uart_a_rx", "uart_a_cts", "uart_a_rts",
};
static const char * const uart_b_groups[] = {
"uart_b_tx_x", "uart_b_rx_x", "uart_b_tx_f", "uart_b_rx_f",
};
static const char * const uart_c_groups[] = {
"uart_c_tx_x0", "uart_c_rx_x1", "uart_c_cts", "uart_c_rts",
"uart_c_tx_x15", "uart_c_rx_x16",
};
static const char * const i2c0_groups[] = {
"i2c0_sck_f11", "i2c0_sda_f12", "i2c0_sck_f9", "i2c0_sda_f10",
};
static const char * const i2c1_groups[] = {
"i2c1_sda_x", "i2c1_sck_x", "i2c1_sda_a", "i2c1_sck_a",
};
static const char * const i2c2_groups[] = {
"i2c2_sck_x0", "i2c2_sda_x1", "i2c2_sck_x15", "i2c2_sda_x16",
"i2c2_sck_a4", "i2c2_sda_a5", "i2c2_sck_a8", "i2c2_sda_a9",
};
static const char * const i2c3_groups[] = {
"i2c3_sck_x", "i2c3_sda_x", "i2c3_sck_f", "i2c3_sda_f",
};
static const char * const i2c_slave_groups[] = {
"i2c_slave_sda_a", "i2c_slave_sck_a",
"i2c_slave_sda_f", "i2c_slave_sck_f",
};
static const char * const spi_a_groups[] = {
"spi_a_mosi_x2", "spi_a_ss0_x3", "spi_a_sclk_x4", "spi_a_miso_x5",
"spi_a_mosi_x7", "spi_a_miso_x8", "spi_a_ss0_x9", "spi_a_sclk_x10",
"spi_a_mosi_a", "spi_a_miso_a", "spi_a_ss0_a", "spi_a_sclk_a",
};
static const char * const pdm_groups[] = {
"pdm_din0_x", "pdm_din1_x", "pdm_din2_x", "pdm_dclk_x", "pdm_din2_a",
"pdm_din1_a", "pdm_din0_a", "pdm_dclk",
};
static const char * const gen_clk_groups[] = {
"gen_clk_x", "gen_clk_f8", "gen_clk_f10", "gen_clk_a",
};
static const char * const remote_input_groups[] = {
"remote_input_f",
"remote_input_a",
};
static const char * const jtag_a_groups[] = {
"jtag_a_clk", "jtag_a_tms", "jtag_a_tdi", "jtag_a_tdo",
};
static const char * const clk_32k_in_groups[] = {
"clk_32k_in",
};
static const char * const remote_out_groups[] = {
"remote_out",
};
static const char * const spdif_in_groups[] = {
"spdif_in_f6", "spdif_in_f7",
};
static const char * const sw_groups[] = {
"swclk", "swdio",
};
static const char * const clk25_groups[] = {
"clk_25",
};
static const char * const cec_a_groups[] = {
"cec_a",
};
static const char * const cec_b_groups[] = {
"cec_b",
};
static const char * const clk12_24_groups[] = {
"clk12_24",
};
static const char * const mclk_0_groups[] = {
"mclk_0",
};
static const char * const tdm_b_groups[] = {
"tdm_b_din0", "tdm_b_din1", "tdm_b_din2",
"tdm_b_sclk", "tdm_b_fs", "tdm_b_dout0", "tdm_b_dout1",
"tdm_b_dout2", "tdm_b_dout3", "tdm_b_dout4", "tdm_b_dout5",
"tdm_b_slv_sclk", "tdm_b_slv_fs",
};
static const char * const mclk_vad_groups[] = {
"mclk_vad",
};
static const char * const tdm_vad_groups[] = {
"tdm_vad_sclk_a1", "tdm_vad_fs_a2", "tdm_vad_sclk_a5", "tdm_vad_fs_a6",
};
static const char * const tst_out_groups[] = {
"tst_out0", "tst_out1", "tst_out2", "tst_out3",
"tst_out4", "tst_out5", "tst_out6", "tst_out7",
"tst_out8", "tst_out9", "tst_out10", "tst_out11",
};
static const char * const mute_groups[] = {
"mute_key", "mute_en",
};
static struct meson_pmx_func meson_a1_periphs_functions[] = {
FUNCTION(gpio_periphs),
FUNCTION(psram),
FUNCTION(pwm_a),
FUNCTION(pwm_b),
FUNCTION(pwm_c),
FUNCTION(pwm_d),
FUNCTION(pwm_e),
FUNCTION(pwm_f),
FUNCTION(pwm_a_hiz),
FUNCTION(pwm_b_hiz),
FUNCTION(pwm_c_hiz),
FUNCTION(spif),
FUNCTION(sdcard),
FUNCTION(tdm_a),
FUNCTION(uart_a),
FUNCTION(uart_b),
FUNCTION(uart_c),
FUNCTION(i2c0),
FUNCTION(i2c1),
FUNCTION(i2c2),
FUNCTION(i2c3),
FUNCTION(spi_a),
FUNCTION(pdm),
FUNCTION(gen_clk),
FUNCTION(remote_input),
FUNCTION(jtag_a),
FUNCTION(clk_32k_in),
FUNCTION(remote_out),
FUNCTION(spdif_in),
FUNCTION(sw),
FUNCTION(clk25),
FUNCTION(cec_a),
FUNCTION(cec_b),
FUNCTION(clk12_24),
FUNCTION(mclk_0),
FUNCTION(tdm_b),
FUNCTION(mclk_vad),
FUNCTION(tdm_vad),
FUNCTION(tst_out),
FUNCTION(mute),
};
static struct meson_bank meson_a1_periphs_banks[] = {
/* name first last irq pullen pull dir out in ds*/
BANK_DS("P", GPIOP_0, GPIOP_12, 0, 12, 0x3, 0, 0x4, 0,
0x2, 0, 0x1, 0, 0x0, 0, 0x5, 0),
BANK_DS("B", GPIOB_0, GPIOB_6, 13, 19, 0x13, 0, 0x14, 0,
0x12, 0, 0x11, 0, 0x10, 0, 0x15, 0),
BANK_DS("X", GPIOX_0, GPIOX_16, 20, 36, 0x23, 0, 0x24, 0,
0x22, 0, 0x21, 0, 0x20, 0, 0x25, 0),
BANK_DS("F", GPIOF_0, GPIOF_12, 37, 49, 0x33, 0, 0x34, 0,
0x32, 0, 0x31, 0, 0x30, 0, 0x35, 0),
BANK_DS("A", GPIOA_0, GPIOA_11, 50, 61, 0x43, 0, 0x44, 0,
0x42, 0, 0x41, 0, 0x40, 0, 0x45, 0),
};
static struct meson_pmx_bank meson_a1_periphs_pmx_banks[] = {
/* name first lask reg offset */
BANK_PMX("P", GPIOP_0, GPIOP_12, 0x0, 0),
BANK_PMX("B", GPIOB_0, GPIOB_6, 0x2, 0),
BANK_PMX("X", GPIOX_0, GPIOX_16, 0x3, 0),
BANK_PMX("F", GPIOF_0, GPIOF_12, 0x6, 0),
BANK_PMX("A", GPIOA_0, GPIOA_11, 0x8, 0),
};
static struct meson_axg_pmx_data meson_a1_periphs_pmx_banks_data = {
.pmx_banks = meson_a1_periphs_pmx_banks,
.num_pmx_banks = ARRAY_SIZE(meson_a1_periphs_pmx_banks),
};
static struct meson_pinctrl_data meson_a1_periphs_pinctrl_data = {
.name = "periphs-banks",
.pins = meson_a1_periphs_pins,
.groups = meson_a1_periphs_groups,
.funcs = meson_a1_periphs_functions,
.banks = meson_a1_periphs_banks,
.num_pins = ARRAY_SIZE(meson_a1_periphs_pins),
.num_groups = ARRAY_SIZE(meson_a1_periphs_groups),
.num_funcs = ARRAY_SIZE(meson_a1_periphs_functions),
.num_banks = ARRAY_SIZE(meson_a1_periphs_banks),
.pmx_ops = &meson_axg_pmx_ops,
.pmx_data = &meson_a1_periphs_pmx_banks_data,
.parse_dt = &meson_a1_parse_dt_extra,
};
static const struct of_device_id meson_a1_pinctrl_dt_match[] = {
{
.compatible = "amlogic,meson-a1-periphs-pinctrl",
.data = &meson_a1_periphs_pinctrl_data,
},
{ },
};
static struct platform_driver meson_a1_pinctrl_driver = {
.probe = meson_pinctrl_probe,
.driver = {
.name = "meson-a1-pinctrl",
.of_match_table = meson_a1_pinctrl_dt_match,
},
};
builtin_platform_driver(meson_a1_pinctrl_driver);

View File

@ -1066,6 +1066,7 @@ static struct meson_pinctrl_data meson_axg_aobus_pinctrl_data = {
.num_banks = ARRAY_SIZE(meson_axg_aobus_banks),
.pmx_ops = &meson_axg_pmx_ops,
.pmx_data = &meson_axg_aobus_pmx_banks_data,
.parse_dt = meson8_aobus_parse_dt_extra,
};
static const struct of_device_id meson_axg_pinctrl_dt_match[] = {

View File

@ -1362,6 +1362,14 @@ static struct meson_axg_pmx_data meson_g12a_aobus_pmx_banks_data = {
.num_pmx_banks = ARRAY_SIZE(meson_g12a_aobus_pmx_banks),
};
static int meson_g12a_aobus_parse_dt_extra(struct meson_pinctrl *pc)
{
pc->reg_pull = pc->reg_gpio;
pc->reg_pullen = pc->reg_gpio;
return 0;
}
static struct meson_pinctrl_data meson_g12a_periphs_pinctrl_data = {
.name = "periphs-banks",
.pins = meson_g12a_periphs_pins,
@ -1388,6 +1396,7 @@ static struct meson_pinctrl_data meson_g12a_aobus_pinctrl_data = {
.num_banks = ARRAY_SIZE(meson_g12a_aobus_banks),
.pmx_ops = &meson_axg_pmx_ops,
.pmx_data = &meson_g12a_aobus_pmx_banks_data,
.parse_dt = meson_g12a_aobus_parse_dt_extra,
};
static const struct of_device_id meson_g12a_pinctrl_dt_match[] = {

View File

@ -851,6 +851,7 @@ static struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = {
.num_funcs = ARRAY_SIZE(meson_gxbb_aobus_functions),
.num_banks = ARRAY_SIZE(meson_gxbb_aobus_banks),
.pmx_ops = &meson8_pmx_ops,
.parse_dt = meson8_aobus_parse_dt_extra,
};
static const struct of_device_id meson_gxbb_pinctrl_dt_match[] = {

View File

@ -820,6 +820,7 @@ static struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = {
.num_funcs = ARRAY_SIZE(meson_gxl_aobus_functions),
.num_banks = ARRAY_SIZE(meson_gxl_aobus_banks),
.pmx_ops = &meson8_pmx_ops,
.parse_dt = meson8_aobus_parse_dt_extra,
};
static const struct of_device_id meson_gxl_pinctrl_dt_match[] = {

View File

@ -625,7 +625,7 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
i = of_property_match_string(node, "reg-names", name);
if (of_address_to_resource(node, i, &res))
return ERR_PTR(-ENOENT);
return NULL;
base = devm_ioremap_resource(pc->dev, &res);
if (IS_ERR(base))
@ -665,26 +665,24 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
pc->of_node = gpio_np;
pc->reg_mux = meson_map_resource(pc, gpio_np, "mux");
if (IS_ERR(pc->reg_mux)) {
if (IS_ERR_OR_NULL(pc->reg_mux)) {
dev_err(pc->dev, "mux registers not found\n");
return PTR_ERR(pc->reg_mux);
return pc->reg_mux ? PTR_ERR(pc->reg_mux) : -ENOENT;
}
pc->reg_gpio = meson_map_resource(pc, gpio_np, "gpio");
if (IS_ERR(pc->reg_gpio)) {
if (IS_ERR_OR_NULL(pc->reg_gpio)) {
dev_err(pc->dev, "gpio registers not found\n");
return PTR_ERR(pc->reg_gpio);
return pc->reg_gpio ? PTR_ERR(pc->reg_gpio) : -ENOENT;
}
pc->reg_pull = meson_map_resource(pc, gpio_np, "pull");
/* Use gpio region if pull one is not present */
if (IS_ERR(pc->reg_pull))
pc->reg_pull = pc->reg_gpio;
pc->reg_pull = NULL;
pc->reg_pullen = meson_map_resource(pc, gpio_np, "pull-enable");
/* Use pull region if pull-enable one is not present */
if (IS_ERR(pc->reg_pullen))
pc->reg_pullen = pc->reg_pull;
pc->reg_pullen = NULL;
pc->reg_ds = meson_map_resource(pc, gpio_np, "ds");
if (IS_ERR(pc->reg_ds)) {
@ -692,6 +690,28 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
pc->reg_ds = NULL;
}
if (pc->data->parse_dt)
return pc->data->parse_dt(pc);
return 0;
}
int meson8_aobus_parse_dt_extra(struct meson_pinctrl *pc)
{
if (!pc->reg_pull)
return -EINVAL;
pc->reg_pullen = pc->reg_pull;
return 0;
}
int meson_a1_parse_dt_extra(struct meson_pinctrl *pc)
{
pc->reg_pull = pc->reg_gpio;
pc->reg_pullen = pc->reg_gpio;
pc->reg_ds = pc->reg_gpio;
return 0;
}

View File

@ -11,6 +11,8 @@
#include <linux/regmap.h>
#include <linux/types.h>
struct meson_pinctrl;
/**
* struct meson_pmx_group - a pinmux group
*
@ -114,6 +116,7 @@ struct meson_pinctrl_data {
unsigned int num_banks;
const struct pinmux_ops *pmx_ops;
void *pmx_data;
int (*parse_dt)(struct meson_pinctrl *pc);
};
struct meson_pinctrl {
@ -171,3 +174,7 @@ int meson_pmx_get_groups(struct pinctrl_dev *pcdev,
/* Common probe function */
int meson_pinctrl_probe(struct platform_device *pdev);
/* Common ao groups extra dt parse function for SoCs before g12a */
int meson8_aobus_parse_dt_extra(struct meson_pinctrl *pc);
/* Common extra dt parse function for SoCs like A1 */
int meson_a1_parse_dt_extra(struct meson_pinctrl *pc);

View File

@ -1103,6 +1103,7 @@ static struct meson_pinctrl_data meson8_aobus_pinctrl_data = {
.num_funcs = ARRAY_SIZE(meson8_aobus_functions),
.num_banks = ARRAY_SIZE(meson8_aobus_banks),
.pmx_ops = &meson8_pmx_ops,
.parse_dt = &meson8_aobus_parse_dt_extra,
};
static const struct of_device_id meson8_pinctrl_dt_match[] = {

View File

@ -962,6 +962,7 @@ static struct meson_pinctrl_data meson8b_aobus_pinctrl_data = {
.num_funcs = ARRAY_SIZE(meson8b_aobus_functions),
.num_banks = ARRAY_SIZE(meson8b_aobus_banks),
.pmx_ops = &meson8_pmx_ops,
.parse_dt = &meson8_aobus_parse_dt_extra,
};
static const struct of_device_id meson8b_pinctrl_dt_match[] = {

View File

@ -595,10 +595,10 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
regmap_read(info->regmap, in_reg, &in_val);
/* Set initial polarity based on current input level. */
if (in_val & d->mask)
val |= d->mask; /* falling */
if (in_val & BIT(d->hwirq % GPIO_PER_REG))
val |= BIT(d->hwirq % GPIO_PER_REG); /* falling */
else
val &= ~d->mask; /* rising */
val &= ~(BIT(d->hwirq % GPIO_PER_REG)); /* rising */
break;
}
default:
@ -722,6 +722,8 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
struct device_node *np = info->dev->of_node;
struct gpio_chip *gc = &info->gpio_chip;
struct irq_chip *irqchip = &info->irq_chip;
struct gpio_irq_chip *girq = &gc->irq;
struct device *dev = &pdev->dev;
struct resource res;
int ret = -ENODEV, i, nr_irq_parent;
@ -732,19 +734,21 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
break;
}
};
if (ret)
if (ret) {
dev_err(dev, "no gpio-controller child node\n");
return ret;
}
nr_irq_parent = of_irq_count(np);
spin_lock_init(&info->irq_lock);
if (!nr_irq_parent) {
dev_err(&pdev->dev, "Invalid or no IRQ\n");
dev_err(dev, "invalid or no IRQ\n");
return 0;
}
if (of_address_to_resource(info->dev->of_node, 1, &res)) {
dev_err(info->dev, "cannot find IO resource\n");
dev_err(dev, "cannot find IO resource\n");
return -ENOENT;
}
@ -759,27 +763,27 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
irqchip->irq_set_type = armada_37xx_irq_set_type;
irqchip->irq_startup = armada_37xx_irq_startup;
irqchip->name = info->data->name;
ret = gpiochip_irqchip_add(gc, irqchip, 0,
handle_edge_irq, IRQ_TYPE_NONE);
if (ret) {
dev_info(&pdev->dev, "could not add irqchip\n");
return ret;
}
girq->chip = irqchip;
girq->parent_handler = armada_37xx_irq_handler;
/*
* Many interrupts are connected to the parent interrupt
* controller. But we do not take advantage of this and use
* the chained irq with all of them.
*/
girq->num_parents = nr_irq_parent;
girq->parents = devm_kcalloc(&pdev->dev, nr_irq_parent,
sizeof(*girq->parents), GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
for (i = 0; i < nr_irq_parent; i++) {
int irq = irq_of_parse_and_map(np, i);
if (irq < 0)
continue;
gpiochip_set_chained_irqchip(gc, irqchip, irq,
armada_37xx_irq_handler);
girq->parents[i] = irq;
}
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_edge_irq;
return 0;
}
@ -809,10 +813,10 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
gc->of_node = np;
gc->label = info->data->name;
ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
ret = armada_37xx_irqchip_register(pdev, info);
if (ret)
return ret;
ret = armada_37xx_irqchip_register(pdev, info);
ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
if (ret)
return ret;

View File

@ -759,12 +759,10 @@ int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
struct mvebu_mpp_ctrl_data *mpp_data;
struct resource *res;
void __iomem *base;
int i;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);

View File

@ -220,17 +220,14 @@ static int orion_pinctrl_probe(struct platform_device *pdev)
{
const struct of_device_id *match =
of_match_device(orion_pinctrl_of_match, &pdev->dev);
struct resource *res;
pdev->dev.platform_data = (void*)match->data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mpp_base = devm_ioremap_resource(&pdev->dev, res);
mpp_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mpp_base))
return PTR_ERR(mpp_base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
high_mpp_base = devm_ioremap_resource(&pdev->dev, res);
high_mpp_base = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(high_mpp_base))
return PTR_ERR(high_mpp_base);

View File

@ -391,6 +391,15 @@ static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, /* MC0_CMDDIR */
DB8500_PIN_AA2, /* MC0_DAT2 */
DB8500_PIN_AA1 /* MC0_DAT3 */
};
/* MMC/SD card 0 interface without CMD/DAT0/DAT2 direction control */
static const unsigned mc0_a_2_pins[] = { DB8500_PIN_AA3, /* MC0_FBCLK */
DB8500_PIN_AA4, /* MC0_CLK */
DB8500_PIN_AB2, /* MC0_CMD */
DB8500_PIN_Y4, /* MC0_DAT0 */
DB8500_PIN_Y2, /* MC0_DAT1 */
DB8500_PIN_AA2, /* MC0_DAT2 */
DB8500_PIN_AA1 /* MC0_DAT3 */
};
/* Often only 4 bits are used, then these are not needed (only used for MMC) */
static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, /* MC0_DAT4 */
DB8500_PIN_W3, /* MC0_DAT5 */
@ -670,6 +679,7 @@ static const struct nmk_pingroup nmk_db8500_groups[] = {
DB8500_PIN_GROUP(msp0tfstck_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(msp0rfsrck_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc0_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc0_a_2, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc0_dat47_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc0dat31dir_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(msp1txrx_a_1, NMK_GPIO_ALT_A),
@ -828,7 +838,7 @@ DB8500_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2");
*/
DB8500_FUNC_GROUPS(msp0, "msp0txrx_a_1", "msp0tfstck_a_1", "msp0rfstck_a_1",
"msp0txrx_b_1", "msp0sck_b_1");
DB8500_FUNC_GROUPS(mc0, "mc0_a_1", "mc0_dat47_a_1", "mc0dat31dir_a_1");
DB8500_FUNC_GROUPS(mc0, "mc0_a_1", "mc0_a_2", "mc0_dat47_a_1", "mc0dat31dir_a_1");
/* MSP0 can swap RX/TX like MSP0 but has no SCK pin available */
DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1");
DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1");

View File

@ -248,9 +248,6 @@ struct nmk_gpio_chip {
void __iomem *addr;
struct clk *clk;
unsigned int bank;
unsigned int parent_irq;
int latent_parent_irq;
u32 (*get_latent_status)(unsigned int bank);
void (*set_ioforce)(bool enable);
spinlock_t lock;
bool sleepmode;
@ -802,13 +799,19 @@ static void nmk_gpio_irq_shutdown(struct irq_data *d)
clk_disable(nmk_chip->clk);
}
static void __nmk_gpio_irq_handler(struct irq_desc *desc, u32 status)
static void nmk_gpio_irq_handler(struct irq_desc *desc)
{
struct irq_chip *host_chip = irq_desc_get_chip(desc);
struct gpio_chip *chip = irq_desc_get_handler_data(desc);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
u32 status;
chained_irq_enter(host_chip, desc);
clk_enable(nmk_chip->clk);
status = readl(nmk_chip->addr + NMK_GPIO_IS);
clk_disable(nmk_chip->clk);
while (status) {
int bit = __ffs(status);
@ -819,28 +822,6 @@ static void __nmk_gpio_irq_handler(struct irq_desc *desc, u32 status)
chained_irq_exit(host_chip, desc);
}
static void nmk_gpio_irq_handler(struct irq_desc *desc)
{
struct gpio_chip *chip = irq_desc_get_handler_data(desc);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
u32 status;
clk_enable(nmk_chip->clk);
status = readl(nmk_chip->addr + NMK_GPIO_IS);
clk_disable(nmk_chip->clk);
__nmk_gpio_irq_handler(desc, status);
}
static void nmk_gpio_latent_irq_handler(struct irq_desc *desc)
{
struct gpio_chip *chip = irq_desc_get_handler_data(desc);
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
u32 status = nmk_chip->get_latent_status(nmk_chip->bank);
__nmk_gpio_irq_handler(desc, status);
}
/* I/O Functions */
static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned offset)
@ -1103,8 +1084,8 @@ static int nmk_gpio_probe(struct platform_device *dev)
struct device_node *np = dev->dev.of_node;
struct nmk_gpio_chip *nmk_chip;
struct gpio_chip *chip;
struct gpio_irq_chip *girq;
struct irq_chip *irqchip;
int latent_irq;
bool supports_sleepmode;
int irq;
int ret;
@ -1125,15 +1106,10 @@ static int nmk_gpio_probe(struct platform_device *dev)
if (irq < 0)
return irq;
/* It's OK for this IRQ not to be present */
latent_irq = platform_get_irq(dev, 1);
/*
* 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->parent_irq = irq;
nmk_chip->latent_parent_irq = latent_irq;
nmk_chip->sleepmode = supports_sleepmode;
spin_lock_init(&nmk_chip->lock);
@ -1163,6 +1139,19 @@ static int nmk_gpio_probe(struct platform_device *dev)
chip->base,
chip->base + chip->ngpio - 1);
girq = &chip->irq;
girq->chip = irqchip;
girq->parent_handler = nmk_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(&dev->dev, 1,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_edge_irq;
clk_enable(nmk_chip->clk);
nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
clk_disable(nmk_chip->clk);
@ -1174,33 +1163,7 @@ static int nmk_gpio_probe(struct platform_device *dev)
platform_set_drvdata(dev, nmk_chip);
/*
* Let the generic code handle this edge IRQ, the the chained
* handler will perform the actual work of handling the parent
* interrupt.
*/
ret = gpiochip_irqchip_add(chip,
irqchip,
0,
handle_edge_irq,
IRQ_TYPE_NONE);
if (ret) {
dev_err(&dev->dev, "could not add irqchip\n");
gpiochip_remove(&nmk_chip->chip);
return -ENODEV;
}
/* Then register the chain on the parent IRQ */
gpiochip_set_chained_irqchip(chip,
irqchip,
nmk_chip->parent_irq,
nmk_gpio_irq_handler);
if (nmk_chip->latent_parent_irq > 0)
gpiochip_set_chained_irqchip(chip,
irqchip,
nmk_chip->latent_parent_irq,
nmk_gpio_latent_irq_handler);
dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
dev_info(&dev->dev, "chip registered\n");
return 0;
}

View File

@ -1954,6 +1954,22 @@ static int npcm7xx_gpio_register(struct npcm7xx_pinctrl *pctrl)
int ret, id;
for (id = 0 ; id < pctrl->bank_num ; id++) {
struct gpio_irq_chip *girq;
girq = &pctrl->gpio_bank[id].gc.irq;
girq->chip = &pctrl->gpio_bank[id].irq_chip;
girq->parent_handler = npcmgpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(pctrl->dev, 1,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents) {
ret = -ENOMEM;
goto err_register;
}
girq->parents[0] = pctrl->gpio_bank[id].irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
ret = devm_gpiochip_add_data(pctrl->dev,
&pctrl->gpio_bank[id].gc,
&pctrl->gpio_bank[id]);
@ -1972,22 +1988,6 @@ static int npcm7xx_gpio_register(struct npcm7xx_pinctrl *pctrl)
gpiochip_remove(&pctrl->gpio_bank[id].gc);
goto err_register;
}
ret = gpiochip_irqchip_add(&pctrl->gpio_bank[id].gc,
&pctrl->gpio_bank[id].irq_chip,
0, handle_level_irq,
IRQ_TYPE_NONE);
if (ret < 0) {
dev_err(pctrl->dev,
"Failed to add IRQ chip %u\n", id);
gpiochip_remove(&pctrl->gpio_bank[id].gc);
goto err_register;
}
gpiochip_set_chained_irqchip(&pctrl->gpio_bank[id].gc,
&pctrl->gpio_bank[id].irq_chip,
pctrl->gpio_bank[id].irq,
npcmgpio_irq_handler);
}
return 0;

View File

@ -540,7 +540,8 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
irqreturn_t ret = IRQ_NONE;
unsigned int i, irqnr;
unsigned long flags;
u32 *regs, regval;
u32 __iomem *regs;
u32 regval;
u64 status, mask;
/* Read the wake status */

View File

@ -936,7 +936,6 @@ static void artpec6_pmx_reset(struct artpec6_pmx *pmx)
static int artpec6_pmx_probe(struct platform_device *pdev)
{
struct artpec6_pmx *pmx;
struct resource *res;
pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
if (!pmx)
@ -944,8 +943,7 @@ static int artpec6_pmx_probe(struct platform_device *pdev)
pmx->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pmx->base = devm_ioremap_resource(&pdev->dev, res);
pmx->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pmx->base))
return PTR_ERR(pmx->base);

View File

@ -328,6 +328,33 @@ static int atmel_gpio_get(struct gpio_chip *chip, unsigned offset)
return !!(reg & BIT(pin->line));
}
static int atmel_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
unsigned long *bits)
{
struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip);
unsigned int bank;
bitmap_zero(bits, atmel_pioctrl->npins);
for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) {
unsigned int word = bank;
unsigned int offset = 0;
unsigned int reg;
#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG
word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK);
offset = bank * ATMEL_PIO_NPINS_PER_BANK % BITS_PER_LONG;
#endif
if (!mask[word])
continue;
reg = atmel_gpio_read(atmel_pioctrl, bank, ATMEL_PIO_PDSR);
bits[word] |= mask[word] & (reg << offset);
}
return 0;
}
static int atmel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
int value)
{
@ -358,11 +385,46 @@ static void atmel_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
BIT(pin->line));
}
static void atmel_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask,
unsigned long *bits)
{
struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip);
unsigned int bank;
for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) {
unsigned int bitmask;
unsigned int word = bank;
/*
* On a 64-bit platform, BITS_PER_LONG is 64 so it is necessary to iterate over
* two 32bit words to handle the whole bitmask
*/
#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG
word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK);
#endif
if (!mask[word])
continue;
bitmask = mask[word] & bits[word];
atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_SODR, bitmask);
bitmask = mask[word] & ~bits[word];
atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_CODR, bitmask);
#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG
mask[word] >>= ATMEL_PIO_NPINS_PER_BANK;
bits[word] >>= ATMEL_PIO_NPINS_PER_BANK;
#endif
}
}
static struct gpio_chip atmel_gpio_chip = {
.direction_input = atmel_gpio_direction_input,
.get = atmel_gpio_get,
.get_multiple = atmel_gpio_get_multiple,
.direction_output = atmel_gpio_direction_output,
.set = atmel_gpio_set,
.set_multiple = atmel_gpio_set_multiple,
.to_irq = atmel_gpio_to_irq,
.base = 0,
};
@ -955,8 +1017,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
atmel_pioctrl->nbanks = atmel_pioctrl_data->nbanks;
atmel_pioctrl->npins = atmel_pioctrl->nbanks * ATMEL_PIO_NPINS_PER_BANK;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
atmel_pioctrl->reg_base = devm_ioremap_resource(dev, res);
atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(atmel_pioctrl->reg_base))
return -EINVAL;

View File

@ -85,8 +85,8 @@ enum drive_strength_bit {
DRIVE_STRENGTH_SHIFT)
enum slewrate_bit {
SLEWRATE_BIT_DIS,
SLEWRATE_BIT_ENA,
SLEWRATE_BIT_DIS,
};
#define SLEWRATE_BIT_MSK(name) (SLEWRATE_BIT_##name << SLEWRATE_SHIFT)
@ -669,7 +669,7 @@ static void at91_mux_sam9x60_set_slewrate(void __iomem *pio, unsigned pin,
{
unsigned int tmp;
if (setting < SLEWRATE_BIT_DIS || setting > SLEWRATE_BIT_ENA)
if (setting < SLEWRATE_BIT_ENA || setting > SLEWRATE_BIT_DIS)
return;
tmp = readl_relaxed(pio + SAM9X60_PIO_SLEWR);
@ -1723,9 +1723,11 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev,
struct at91_gpio_chip *prev = NULL;
struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq);
struct irq_chip *gpio_irqchip;
int ret, i;
struct gpio_irq_chip *girq;
int i;
gpio_irqchip = devm_kzalloc(&pdev->dev, sizeof(*gpio_irqchip), GFP_KERNEL);
gpio_irqchip = devm_kzalloc(&pdev->dev, sizeof(*gpio_irqchip),
GFP_KERNEL);
if (!gpio_irqchip)
return -ENOMEM;
@ -1747,33 +1749,30 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev,
* handler will perform the actual work of handling the parent
* interrupt.
*/
ret = gpiochip_irqchip_add(&at91_gpio->chip,
gpio_irqchip,
0,
handle_edge_irq,
IRQ_TYPE_NONE);
if (ret) {
dev_err(&pdev->dev, "at91_gpio.%d: Couldn't add irqchip to gpiochip.\n",
at91_gpio->pioc_idx);
return ret;
}
girq = &at91_gpio->chip.irq;
girq->chip = gpio_irqchip;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_edge_irq;
/* The top level handler handles one bank of GPIOs, except
/*
* The top level handler handles one bank of GPIOs, except
* on some SoC it can handle up to three...
* We only set up the handler for the first of the list.
*/
gpiochip_prev = irq_get_handler_data(at91_gpio->pioc_virq);
if (!gpiochip_prev) {
/* Then register the chain on the parent IRQ */
gpiochip_set_chained_irqchip(&at91_gpio->chip,
gpio_irqchip,
at91_gpio->pioc_virq,
gpio_irq_handler);
girq->parent_handler = gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(&pdev->dev, 1,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = at91_gpio->pioc_virq;
return 0;
}
prev = gpiochip_get_data(gpiochip_prev);
/* we can only have 2 banks before */
for (i = 0; i < 2; i++) {
if (prev->next) {
@ -1812,7 +1811,6 @@ static const struct of_device_id at91_gpio_of_match[] = {
static int at91_gpio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct resource *res;
struct at91_gpio_chip *at91_chip = NULL;
struct gpio_chip *chip;
struct pinctrl_gpio_range *range;
@ -1840,8 +1838,7 @@ static int at91_gpio_probe(struct platform_device *pdev)
goto err;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
at91_chip->regbase = devm_ioremap_resource(&pdev->dev, res);
at91_chip->regbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(at91_chip->regbase)) {
ret = PTR_ERR(at91_chip->regbase);
goto err;
@ -1903,6 +1900,10 @@ static int at91_gpio_probe(struct platform_device *pdev)
range->npins = chip->ngpio;
range->gc = chip;
ret = at91_gpio_of_irq_setup(pdev, at91_chip);
if (ret)
goto gpiochip_add_err;
ret = gpiochip_add_data(chip, at91_chip);
if (ret)
goto gpiochip_add_err;
@ -1910,16 +1911,10 @@ static int at91_gpio_probe(struct platform_device *pdev)
gpio_chips[alias_idx] = at91_chip;
gpio_banks = max(gpio_banks, alias_idx + 1);
ret = at91_gpio_of_irq_setup(pdev, at91_chip);
if (ret)
goto irq_setup_err;
dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase);
return 0;
irq_setup_err:
gpiochip_remove(chip);
gpiochip_add_err:
clk_enable_err:
clk_disable_unprepare(at91_chip->clock);

View File

@ -1308,15 +1308,13 @@ static struct pinctrl_desc bm1880_desc = {
static int bm1880_pinctrl_probe(struct platform_device *pdev)
{
struct resource *res;
struct bm1880_pinctrl *pctrl;
pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctrl->base = devm_ioremap_resource(&pdev->dev, res);
pctrl->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctrl->base))
return PTR_ERR(pctrl->base);

View File

@ -615,7 +615,7 @@ static struct coh901_pinpair coh901_pintable[] = {
static int __init u300_gpio_probe(struct platform_device *pdev)
{
struct u300_gpio *gpio;
struct resource *memres;
struct gpio_irq_chip *girq;
int err = 0;
int portno;
u32 val;
@ -632,8 +632,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
gpio->chip.base = 0;
gpio->dev = &pdev->dev;
memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
gpio->base = devm_ioremap_resource(&pdev->dev, memres);
gpio->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(gpio->base))
return PTR_ERR(gpio->base);
@ -672,26 +671,17 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
gpio->base + U300_GPIO_CR);
u300_gpio_init_coh901571(gpio);
#ifdef CONFIG_OF_GPIO
gpio->chip.of_node = pdev->dev.of_node;
#endif
err = gpiochip_add_data(&gpio->chip, gpio);
if (err) {
dev_err(gpio->dev, "unable to add gpiochip: %d\n", err);
goto err_no_chip;
girq = &gpio->chip.irq;
girq->chip = &u300_gpio_irqchip;
girq->parent_handler = u300_gpio_irq_handler;
girq->num_parents = U300_GPIO_NUM_PORTS;
girq->parents = devm_kcalloc(gpio->dev, U300_GPIO_NUM_PORTS,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents) {
err = -ENOMEM;
goto err_dis_clk;
}
err = gpiochip_irqchip_add(&gpio->chip,
&u300_gpio_irqchip,
0,
handle_simple_irq,
IRQ_TYPE_EDGE_FALLING);
if (err) {
dev_err(gpio->dev, "no GPIO irqchip\n");
goto err_no_irqchip;
}
/* Add each port with its IRQ separately */
for (portno = 0 ; portno < U300_GPIO_NUM_PORTS; portno++) {
struct u300_gpio_port *port = &gpio->ports[portno];
@ -700,16 +690,21 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
port->gpio = gpio;
port->irq = platform_get_irq(pdev, portno);
gpiochip_set_chained_irqchip(&gpio->chip,
&u300_gpio_irqchip,
port->irq,
u300_gpio_irq_handler);
girq->parents[portno] = port->irq;
/* Turns off irq force (test register) for this port */
writel(0x0, gpio->base + portno * gpio->stride + ifr);
}
dev_dbg(gpio->dev, "initialized %d GPIO ports\n", portno);
girq->default_type = IRQ_TYPE_EDGE_FALLING;
girq->handler = handle_simple_irq;
#ifdef CONFIG_OF_GPIO
gpio->chip.of_node = pdev->dev.of_node;
#endif
err = gpiochip_add_data(&gpio->chip, gpio);
if (err) {
dev_err(gpio->dev, "unable to add gpiochip: %d\n", err);
goto err_dis_clk;
}
/*
* Add pinctrl pin ranges, the pin controller must be registered
@ -729,9 +724,8 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
return 0;
err_no_range:
err_no_irqchip:
gpiochip_remove(&gpio->chip);
err_no_chip:
err_dis_clk:
clk_disable_unprepare(gpio->clk);
dev_err(&pdev->dev, "module ERROR:%d\n", err);
return err;

View File

@ -146,14 +146,12 @@ static int da850_pupd_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct da850_pupd_data *data;
struct resource *res;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->base = devm_ioremap_resource(dev, res);
data->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->base)) {
dev_err(dev, "Could not map resource\n");
return PTR_ERR(data->base);

View File

@ -270,7 +270,6 @@ static int dc_gpiochip_add(struct dc_pinmap *pmap, struct device_node *np)
static int dc_pinctrl_probe(struct platform_device *pdev)
{
struct dc_pinmap *pmap;
struct resource *r;
struct pinctrl_pin_desc *pins;
struct pinctrl_desc *pctl_desc;
char *pin_names;
@ -281,8 +280,7 @@ static int dc_pinctrl_probe(struct platform_device *pdev)
if (!pmap)
return -ENOMEM;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pmap->regs = devm_ioremap_resource(&pdev->dev, r);
pmap->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pmap->regs))
return PTR_ERR(pmap->regs);

View File

@ -0,0 +1,944 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2019 Intel Corporation */
#include <linux/gpio/driver.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include "core.h"
#include "pinconf.h"
#include "pinmux.h"
#include "pinctrl-equilibrium.h"
#define PIN_NAME_FMT "io-%d"
#define PIN_NAME_LEN 10
#define PAD_REG_OFF 0x100
static void eqbr_gpio_disable_irq(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
unsigned int offset = irqd_to_hwirq(d);
unsigned long flags;
raw_spin_lock_irqsave(&gctrl->lock, flags);
writel(BIT(offset), gctrl->membase + GPIO_IRNENCLR);
raw_spin_unlock_irqrestore(&gctrl->lock, flags);
}
static void eqbr_gpio_enable_irq(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
unsigned int offset = irqd_to_hwirq(d);
unsigned long flags;
gc->direction_input(gc, offset);
raw_spin_lock_irqsave(&gctrl->lock, flags);
writel(BIT(offset), gctrl->membase + GPIO_IRNRNSET);
raw_spin_unlock_irqrestore(&gctrl->lock, flags);
}
static void eqbr_gpio_ack_irq(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
unsigned int offset = irqd_to_hwirq(d);
unsigned long flags;
raw_spin_lock_irqsave(&gctrl->lock, flags);
writel(BIT(offset), gctrl->membase + GPIO_IRNCR);
raw_spin_unlock_irqrestore(&gctrl->lock, flags);
}
static void eqbr_gpio_mask_ack_irq(struct irq_data *d)
{
eqbr_gpio_disable_irq(d);
eqbr_gpio_ack_irq(d);
}
static inline void eqbr_cfg_bit(void __iomem *addr,
unsigned int offset, unsigned int set)
{
if (set)
writel(readl(addr) | BIT(offset), addr);
else
writel(readl(addr) & ~BIT(offset), addr);
}
static int eqbr_irq_type_cfg(struct gpio_irq_type *type,
struct eqbr_gpio_ctrl *gctrl,
unsigned int offset)
{
unsigned long flags;
raw_spin_lock_irqsave(&gctrl->lock, flags);
eqbr_cfg_bit(gctrl->membase + GPIO_IRNCFG, offset, type->trig_type);
eqbr_cfg_bit(gctrl->membase + GPIO_EXINTCR1, offset, type->trig_type);
eqbr_cfg_bit(gctrl->membase + GPIO_EXINTCR0, offset, type->logic_type);
raw_spin_unlock_irqrestore(&gctrl->lock, flags);
return 0;
}
static int eqbr_gpio_set_irq_type(struct irq_data *d, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
unsigned int offset = irqd_to_hwirq(d);
struct gpio_irq_type it;
memset(&it, 0, sizeof(it));
if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_NONE)
return 0;
switch (type) {
case IRQ_TYPE_EDGE_RISING:
it.trig_type = GPIO_EDGE_TRIG;
it.edge_type = GPIO_SINGLE_EDGE;
it.logic_type = GPIO_POSITIVE_TRIG;
break;
case IRQ_TYPE_EDGE_FALLING:
it.trig_type = GPIO_EDGE_TRIG;
it.edge_type = GPIO_SINGLE_EDGE;
it.logic_type = GPIO_NEGATIVE_TRIG;
break;
case IRQ_TYPE_EDGE_BOTH:
it.trig_type = GPIO_EDGE_TRIG;
it.edge_type = GPIO_BOTH_EDGE;
it.logic_type = GPIO_POSITIVE_TRIG;
break;
case IRQ_TYPE_LEVEL_HIGH:
it.trig_type = GPIO_LEVEL_TRIG;
it.edge_type = GPIO_SINGLE_EDGE;
it.logic_type = GPIO_POSITIVE_TRIG;
break;
case IRQ_TYPE_LEVEL_LOW:
it.trig_type = GPIO_LEVEL_TRIG;
it.edge_type = GPIO_SINGLE_EDGE;
it.logic_type = GPIO_NEGATIVE_TRIG;
break;
default:
return -EINVAL;
}
eqbr_irq_type_cfg(&it, gctrl, offset);
if (it.trig_type == GPIO_EDGE_TRIG)
irq_set_handler_locked(d, handle_edge_irq);
else
irq_set_handler_locked(d, handle_level_irq);
return 0;
}
static void eqbr_irq_handler(struct irq_desc *desc)
{
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
struct irq_chip *ic = irq_desc_get_chip(desc);
unsigned long pins, offset;
chained_irq_enter(ic, desc);
pins = readl(gctrl->membase + GPIO_IRNCR);
for_each_set_bit(offset, &pins, gc->ngpio)
generic_handle_irq(irq_find_mapping(gc->irq.domain, offset));
chained_irq_exit(ic, desc);
}
static int gpiochip_setup(struct device *dev, struct eqbr_gpio_ctrl *gctrl)
{
struct gpio_irq_chip *girq;
struct gpio_chip *gc;
gc = &gctrl->chip;
gc->label = gctrl->name;
#if defined(CONFIG_OF_GPIO)
gc->of_node = gctrl->node;
#endif
if (!of_property_read_bool(gctrl->node, "interrupt-controller")) {
dev_dbg(dev, "gc %s: doesn't act as interrupt controller!\n",
gctrl->name);
return 0;
}
gctrl->ic.name = "gpio_irq";
gctrl->ic.irq_mask = eqbr_gpio_disable_irq;
gctrl->ic.irq_unmask = eqbr_gpio_enable_irq;
gctrl->ic.irq_ack = eqbr_gpio_ack_irq;
gctrl->ic.irq_mask_ack = eqbr_gpio_mask_ack_irq;
gctrl->ic.irq_set_type = eqbr_gpio_set_irq_type;
girq = &gctrl->chip.irq;
girq->chip = &gctrl->ic;
girq->parent_handler = eqbr_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] = gctrl->virq;
return 0;
}
static int gpiolib_reg(struct eqbr_pinctrl_drv_data *drvdata)
{
struct device *dev = drvdata->dev;
struct eqbr_gpio_ctrl *gctrl;
struct device_node *np;
struct resource res;
int i, ret;
for (i = 0; i < drvdata->nr_gpio_ctrls; i++) {
gctrl = drvdata->gpio_ctrls + i;
np = gctrl->node;
gctrl->name = devm_kasprintf(dev, GFP_KERNEL, "gpiochip%d", i);
if (!gctrl->name)
return -ENOMEM;
if (of_address_to_resource(np, 0, &res)) {
dev_err(dev, "Failed to get GPIO register address\n");
return -ENXIO;
}
gctrl->membase = devm_ioremap_resource(dev, &res);
if (IS_ERR(gctrl->membase))
return PTR_ERR(gctrl->membase);
gctrl->virq = irq_of_parse_and_map(np, 0);
if (!gctrl->virq) {
dev_err(dev, "%s: failed to parse and map irq\n",
gctrl->name);
return -ENXIO;
}
raw_spin_lock_init(&gctrl->lock);
ret = bgpio_init(&gctrl->chip, dev, gctrl->bank->nr_pins / 8,
gctrl->membase + GPIO_IN,
gctrl->membase + GPIO_OUTSET,
gctrl->membase + GPIO_OUTCLR,
gctrl->membase + GPIO_DIR,
NULL, 0);
if (ret) {
dev_err(dev, "unable to init generic GPIO\n");
return ret;
}
ret = gpiochip_setup(dev, gctrl);
if (ret)
return ret;
ret = devm_gpiochip_add_data(dev, &gctrl->chip, gctrl);
if (ret)
return ret;
}
return 0;
}
static inline struct eqbr_pin_bank
*find_pinbank_via_pin(struct eqbr_pinctrl_drv_data *pctl, unsigned int pin)
{
struct eqbr_pin_bank *bank;
int i;
for (i = 0; i < pctl->nr_banks; i++) {
bank = &pctl->pin_banks[i];
if (pin >= bank->pin_base &&
(pin - bank->pin_base) < bank->nr_pins)
return bank;
}
return NULL;
}
static const struct pinctrl_ops eqbr_pctl_ops = {
.get_groups_count = pinctrl_generic_get_group_count,
.get_group_name = pinctrl_generic_get_group_name,
.get_group_pins = pinctrl_generic_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
.dt_free_map = pinconf_generic_dt_free_map,
};
static int eqbr_set_pin_mux(struct eqbr_pinctrl_drv_data *pctl,
unsigned int pmx, unsigned int pin)
{
struct eqbr_pin_bank *bank;
unsigned long flags;
unsigned int offset;
void __iomem *mem;
bank = find_pinbank_via_pin(pctl, pin);
if (!bank) {
dev_err(pctl->dev, "Couldn't find pin bank for pin %u\n", pin);
return -ENODEV;
}
mem = bank->membase;
offset = pin - bank->pin_base;
if (!(bank->aval_pinmap & BIT(offset))) {
dev_err(pctl->dev,
"PIN: %u is not valid, pinbase: %u, bitmap: %u\n",
pin, bank->pin_base, bank->aval_pinmap);
return -ENODEV;
}
raw_spin_lock_irqsave(&pctl->lock, flags);
writel(pmx, mem + (offset * 4));
raw_spin_unlock_irqrestore(&pctl->lock, flags);
return 0;
}
static int eqbr_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned int group)
{
struct eqbr_pinctrl_drv_data *pctl = pinctrl_dev_get_drvdata(pctldev);
struct function_desc *func;
struct group_desc *grp;
unsigned int *pinmux;
int i;
func = pinmux_generic_get_function(pctldev, selector);
if (!func)
return -EINVAL;
grp = pinctrl_generic_get_group(pctldev, group);
if (!grp)
return -EINVAL;
pinmux = grp->data;
for (i = 0; i < grp->num_pins; i++)
eqbr_set_pin_mux(pctl, pinmux[i], grp->pins[i]);
return 0;
}
static int eqbr_pinmux_gpio_request(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int pin)
{
struct eqbr_pinctrl_drv_data *pctl = pinctrl_dev_get_drvdata(pctldev);
return eqbr_set_pin_mux(pctl, EQBR_GPIO_MODE, pin);
}
static const struct pinmux_ops eqbr_pinmux_ops = {
.get_functions_count = pinmux_generic_get_function_count,
.get_function_name = pinmux_generic_get_function_name,
.get_function_groups = pinmux_generic_get_function_groups,
.set_mux = eqbr_pinmux_set_mux,
.gpio_request_enable = eqbr_pinmux_gpio_request,
.strict = true,
};
static int get_drv_cur(void __iomem *mem, unsigned int offset)
{
unsigned int idx = offset / DRV_CUR_PINS; /* 0-15, 16-31 per register*/
unsigned int pin_offset = offset % DRV_CUR_PINS;
return PARSE_DRV_CURRENT(readl(mem + REG_DRCC(idx)), pin_offset);
}
static struct eqbr_gpio_ctrl
*get_gpio_ctrls_via_bank(struct eqbr_pinctrl_drv_data *pctl,
struct eqbr_pin_bank *bank)
{
int i;
for (i = 0; i < pctl->nr_gpio_ctrls; i++) {
if (pctl->gpio_ctrls[i].bank == bank)
return &pctl->gpio_ctrls[i];
}
return NULL;
}
static int eqbr_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config)
{
struct eqbr_pinctrl_drv_data *pctl = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
struct eqbr_gpio_ctrl *gctrl;
struct eqbr_pin_bank *bank;
unsigned long flags;
unsigned int offset;
void __iomem *mem;
u32 val;
bank = find_pinbank_via_pin(pctl, pin);
if (!bank) {
dev_err(pctl->dev, "Couldn't find pin bank for pin %u\n", pin);
return -ENODEV;
}
mem = bank->membase;
offset = pin - bank->pin_base;
if (!(bank->aval_pinmap & BIT(offset))) {
dev_err(pctl->dev,
"PIN: %u is not valid, pinbase: %u, bitmap: %u\n",
pin, bank->pin_base, bank->aval_pinmap);
return -ENODEV;
}
raw_spin_lock_irqsave(&pctl->lock, flags);
switch (param) {
case PIN_CONFIG_BIAS_PULL_UP:
val = !!(readl(mem + REG_PUEN) & BIT(offset));
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
val = !!(readl(mem + REG_PDEN) & BIT(offset));
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
val = !!(readl(mem + REG_OD) & BIT(offset));
break;
case PIN_CONFIG_DRIVE_STRENGTH:
val = get_drv_cur(mem, offset);
break;
case PIN_CONFIG_SLEW_RATE:
val = !!(readl(mem + REG_SRC) & BIT(offset));
break;
case PIN_CONFIG_OUTPUT_ENABLE:
gctrl = get_gpio_ctrls_via_bank(pctl, bank);
if (!gctrl) {
dev_err(pctl->dev, "Failed to find gpio via bank pinbase: %u, pin: %u\n",
bank->pin_base, pin);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
return -ENODEV;
}
val = !!(readl(gctrl->membase + GPIO_DIR) & BIT(offset));
break;
default:
raw_spin_unlock_irqrestore(&pctl->lock, flags);
return -ENOTSUPP;
}
raw_spin_unlock_irqrestore(&pctl->lock, flags);
*config = pinconf_to_config_packed(param, val);
;
return 0;
}
static int eqbr_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct eqbr_pinctrl_drv_data *pctl = pinctrl_dev_get_drvdata(pctldev);
struct eqbr_gpio_ctrl *gctrl;
enum pin_config_param param;
struct eqbr_pin_bank *bank;
unsigned int val, offset;
struct gpio_chip *gc;
unsigned long flags;
void __iomem *mem;
u32 regval, mask;
int i;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
val = pinconf_to_config_argument(configs[i]);
bank = find_pinbank_via_pin(pctl, pin);
if (!bank) {
dev_err(pctl->dev,
"Couldn't find pin bank for pin %u\n", pin);
return -ENODEV;
}
mem = bank->membase;
offset = pin - bank->pin_base;
switch (param) {
case PIN_CONFIG_BIAS_PULL_UP:
mem += REG_PUEN;
mask = BIT(offset);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
mem += REG_PDEN;
mask = BIT(offset);
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
mem += REG_OD;
mask = BIT(offset);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
mem += REG_DRCC(offset / DRV_CUR_PINS);
offset = (offset % DRV_CUR_PINS) * 2;
mask = GENMASK(1, 0) << offset;
break;
case PIN_CONFIG_SLEW_RATE:
mem += REG_SRC;
mask = BIT(offset);
break;
case PIN_CONFIG_OUTPUT_ENABLE:
gctrl = get_gpio_ctrls_via_bank(pctl, bank);
if (!gctrl) {
dev_err(pctl->dev, "Failed to find gpio via bank pinbase: %u, pin: %u\n",
bank->pin_base, pin);
return -ENODEV;
}
gc = &gctrl->chip;
gc->direction_output(gc, offset, 0);
continue;
default:
return -ENOTSUPP;
}
raw_spin_lock_irqsave(&pctl->lock, flags);
regval = readl(mem);
regval = (regval & ~mask) | ((val << offset) & mask);
writel(regval, mem);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
return 0;
}
static int eqbr_pinconf_group_get(struct pinctrl_dev *pctldev,
unsigned int group, unsigned long *config)
{
unsigned int i, npins, old = 0;
const unsigned int *pins;
int ret;
ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
for (i = 0; i < npins; i++) {
if (eqbr_pinconf_get(pctldev, pins[i], config))
return -ENOTSUPP;
if (i && old != *config)
return -ENOTSUPP;
old = *config;
}
return 0;
}
static int eqbr_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned int group, unsigned long *configs,
unsigned int num_configs)
{
const unsigned int *pins;
unsigned int i, npins;
int ret;
ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
for (i = 0; i < npins; i++) {
ret = eqbr_pinconf_set(pctldev, pins[i], configs, num_configs);
if (ret)
return ret;
}
return 0;
}
static const struct pinconf_ops eqbr_pinconf_ops = {
.is_generic = true,
.pin_config_get = eqbr_pinconf_get,
.pin_config_set = eqbr_pinconf_set,
.pin_config_group_get = eqbr_pinconf_group_get,
.pin_config_group_set = eqbr_pinconf_group_set,
.pin_config_config_dbg_show = pinconf_generic_dump_config,
};
static bool is_func_exist(struct eqbr_pmx_func *funcs, const char *name,
unsigned int nr_funcs, unsigned int *idx)
{
int i;
if (!funcs)
return false;
for (i = 0; i < nr_funcs; i++) {
if (funcs[i].name && !strcmp(funcs[i].name, name)) {
*idx = i;
return true;
}
}
return false;
}
static int funcs_utils(struct device *dev, struct eqbr_pmx_func *funcs,
unsigned int *nr_funcs, funcs_util_ops op)
{
struct device_node *node = dev->of_node;
struct device_node *np;
struct property *prop;
const char *fn_name;
unsigned int fid;
int i, j;
i = 0;
for_each_child_of_node(node, np) {
prop = of_find_property(np, "groups", NULL);
if (!prop)
continue;
if (of_property_read_string(np, "function", &fn_name)) {
/* some groups may not have function, it's OK */
dev_dbg(dev, "Group %s: not function binded!\n",
(char *)prop->value);
continue;
}
switch (op) {
case OP_COUNT_NR_FUNCS:
if (!is_func_exist(funcs, fn_name, *nr_funcs, &fid))
*nr_funcs = *nr_funcs + 1;
break;
case OP_ADD_FUNCS:
if (!is_func_exist(funcs, fn_name, *nr_funcs, &fid))
funcs[i].name = fn_name;
break;
case OP_COUNT_NR_FUNC_GRPS:
if (is_func_exist(funcs, fn_name, *nr_funcs, &fid))
funcs[fid].nr_groups++;
break;
case OP_ADD_FUNC_GRPS:
if (is_func_exist(funcs, fn_name, *nr_funcs, &fid)) {
for (j = 0; j < funcs[fid].nr_groups; j++)
if (!funcs[fid].groups[j])
break;
funcs[fid].groups[j] = prop->value;
}
break;
default:
return -EINVAL;
}
i++;
}
return 0;
}
static int eqbr_build_functions(struct eqbr_pinctrl_drv_data *drvdata)
{
struct device *dev = drvdata->dev;
struct eqbr_pmx_func *funcs = NULL;
unsigned int nr_funcs = 0;
int i, ret;
ret = funcs_utils(dev, funcs, &nr_funcs, OP_COUNT_NR_FUNCS);
if (ret)
return ret;
funcs = devm_kcalloc(dev, nr_funcs, sizeof(*funcs), GFP_KERNEL);
if (!funcs)
return -ENOMEM;
ret = funcs_utils(dev, funcs, &nr_funcs, OP_ADD_FUNCS);
if (ret)
return ret;
ret = funcs_utils(dev, funcs, &nr_funcs, OP_COUNT_NR_FUNC_GRPS);
if (ret)
return ret;
for (i = 0; i < nr_funcs; i++) {
if (!funcs[i].nr_groups)
continue;
funcs[i].groups = devm_kcalloc(dev, funcs[i].nr_groups,
sizeof(*(funcs[i].groups)),
GFP_KERNEL);
if (!funcs[i].groups)
return -ENOMEM;
}
ret = funcs_utils(dev, funcs, &nr_funcs, OP_ADD_FUNC_GRPS);
if (ret)
return ret;
for (i = 0; i < nr_funcs; i++) {
ret = pinmux_generic_add_function(drvdata->pctl_dev,
funcs[i].name,
funcs[i].groups,
funcs[i].nr_groups,
drvdata);
if (ret < 0) {
dev_err(dev, "Failed to register function %s\n",
funcs[i].name);
return ret;
}
}
return 0;
}
static int eqbr_build_groups(struct eqbr_pinctrl_drv_data *drvdata)
{
struct device *dev = drvdata->dev;
struct device_node *node = dev->of_node;
unsigned int *pinmux, pin_id, pinmux_id;
struct group_desc group;
struct device_node *np;
struct property *prop;
int j, err;
for_each_child_of_node(node, np) {
prop = of_find_property(np, "groups", NULL);
if (!prop)
continue;
group.num_pins = of_property_count_u32_elems(np, "pins");
if (group.num_pins < 0) {
dev_err(dev, "No pins in the group: %s\n", prop->name);
return -EINVAL;
}
group.name = prop->value;
group.pins = devm_kcalloc(dev, group.num_pins,
sizeof(*(group.pins)), GFP_KERNEL);
if (!group.pins)
return -ENOMEM;
pinmux = devm_kcalloc(dev, group.num_pins, sizeof(*pinmux),
GFP_KERNEL);
if (!pinmux)
return -ENOMEM;
for (j = 0; j < group.num_pins; j++) {
if (of_property_read_u32_index(np, "pins", j, &pin_id)) {
dev_err(dev, "Group %s: Read intel pins id failed\n",
group.name);
return -EINVAL;
}
if (pin_id >= drvdata->pctl_desc.npins) {
dev_err(dev, "Group %s: Invalid pin ID, idx: %d, pin %u\n",
group.name, j, pin_id);
return -EINVAL;
}
group.pins[j] = pin_id;
if (of_property_read_u32_index(np, "pinmux", j, &pinmux_id)) {
dev_err(dev, "Group %s: Read intel pinmux id failed\n",
group.name);
return -EINVAL;
}
pinmux[j] = pinmux_id;
}
err = pinctrl_generic_add_group(drvdata->pctl_dev, group.name,
group.pins, group.num_pins,
pinmux);
if (err < 0) {
dev_err(dev, "Failed to register group %s\n", group.name);
return err;
}
memset(&group, 0, sizeof(group));
pinmux = NULL;
}
return 0;
}
static int pinctrl_reg(struct eqbr_pinctrl_drv_data *drvdata)
{
struct pinctrl_desc *pctl_desc;
struct pinctrl_pin_desc *pdesc;
struct device *dev;
unsigned int nr_pins;
char *pin_names;
int i, ret;
dev = drvdata->dev;
pctl_desc = &drvdata->pctl_desc;
pctl_desc->name = "eqbr-pinctrl";
pctl_desc->owner = THIS_MODULE;
pctl_desc->pctlops = &eqbr_pctl_ops;
pctl_desc->pmxops = &eqbr_pinmux_ops;
pctl_desc->confops = &eqbr_pinconf_ops;
raw_spin_lock_init(&drvdata->lock);
for (i = 0, nr_pins = 0; i < drvdata->nr_banks; i++)
nr_pins += drvdata->pin_banks[i].nr_pins;
pdesc = devm_kcalloc(dev, nr_pins, sizeof(*pdesc), GFP_KERNEL);
if (!pdesc)
return -ENOMEM;
pin_names = devm_kcalloc(dev, nr_pins, PIN_NAME_LEN, GFP_KERNEL);
if (!pin_names)
return -ENOMEM;
for (i = 0; i < nr_pins; i++) {
sprintf(pin_names, PIN_NAME_FMT, i);
pdesc[i].number = i;
pdesc[i].name = pin_names;
pin_names += PIN_NAME_LEN;
}
pctl_desc->pins = pdesc;
pctl_desc->npins = nr_pins;
dev_dbg(dev, "pinctrl total pin number: %u\n", nr_pins);
ret = devm_pinctrl_register_and_init(dev, pctl_desc, drvdata,
&drvdata->pctl_dev);
if (ret)
return ret;
ret = eqbr_build_groups(drvdata);
if (ret) {
dev_err(dev, "Failed to build groups\n");
return ret;
}
ret = eqbr_build_functions(drvdata);
if (ret) {
dev_err(dev, "Failed to build groups\n");
return ret;
}
return pinctrl_enable(drvdata->pctl_dev);
}
static int pinbank_init(struct device_node *np,
struct eqbr_pinctrl_drv_data *drvdata,
struct eqbr_pin_bank *bank, unsigned int id)
{
struct device *dev = drvdata->dev;
struct of_phandle_args spec;
int ret;
bank->membase = drvdata->membase + id * PAD_REG_OFF;
ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &spec);
if (ret) {
dev_err(dev, "gpio-range not available!\n");
return ret;
}
bank->pin_base = spec.args[1];
bank->nr_pins = spec.args[2];
bank->aval_pinmap = readl(bank->membase + REG_AVAIL);
bank->id = id;
dev_dbg(dev, "pinbank id: %d, reg: %px, pinbase: %u, pin number: %u, pinmap: 0x%x\n",
id, bank->membase, bank->pin_base,
bank->nr_pins, bank->aval_pinmap);
return ret;
}
static int pinbank_probe(struct eqbr_pinctrl_drv_data *drvdata)
{
struct device *dev = drvdata->dev;
struct device_node *np_gpio;
struct eqbr_gpio_ctrl *gctrls;
struct eqbr_pin_bank *banks;
int i, nr_gpio;
/* Count gpio bank number */
nr_gpio = 0;
for_each_node_by_name(np_gpio, "gpio") {
if (of_device_is_available(np_gpio))
nr_gpio++;
}
if (!nr_gpio) {
dev_err(dev, "NO pin bank available!\n");
return -ENODEV;
}
/* Count pin bank number and gpio controller number */
banks = devm_kcalloc(dev, nr_gpio, sizeof(*banks), GFP_KERNEL);
if (!banks)
return -ENOMEM;
gctrls = devm_kcalloc(dev, nr_gpio, sizeof(*gctrls), GFP_KERNEL);
if (!gctrls)
return -ENOMEM;
dev_dbg(dev, "found %d gpio controller!\n", nr_gpio);
/* Initialize Pin bank */
i = 0;
for_each_node_by_name(np_gpio, "gpio") {
if (!of_device_is_available(np_gpio))
continue;
pinbank_init(np_gpio, drvdata, banks + i, i);
gctrls[i].node = np_gpio;
gctrls[i].bank = banks + i;
i++;
}
drvdata->pin_banks = banks;
drvdata->nr_banks = nr_gpio;
drvdata->gpio_ctrls = gctrls;
drvdata->nr_gpio_ctrls = nr_gpio;
return 0;
}
static int eqbr_pinctrl_probe(struct platform_device *pdev)
{
struct eqbr_pinctrl_drv_data *drvdata;
struct device *dev = &pdev->dev;
int ret;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->dev = dev;
drvdata->membase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(drvdata->membase))
return PTR_ERR(drvdata->membase);
ret = pinbank_probe(drvdata);
if (ret)
return ret;
ret = pinctrl_reg(drvdata);
if (ret)
return ret;
ret = gpiolib_reg(drvdata);
if (ret)
return ret;
platform_set_drvdata(pdev, drvdata);
return 0;
}
static const struct of_device_id eqbr_pinctrl_dt_match[] = {
{ .compatible = "intel,lgm-io" },
{}
};
static struct platform_driver eqbr_pinctrl_driver = {
.probe = eqbr_pinctrl_probe,
.driver = {
.name = "eqbr-pinctrl",
.of_match_table = eqbr_pinctrl_dt_match,
},
};
module_platform_driver(eqbr_pinctrl_driver);
MODULE_AUTHOR("Zhu Yixin <yixin.zhu@intel.com>, Rahul Tanwar <rahul.tanwar@intel.com>");
MODULE_DESCRIPTION("Pinctrl Driver for LGM SoC (Equilibrium)");

View File

@ -0,0 +1,144 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2019 Intel Corporation.
*/
#ifndef __PINCTRL_EQUILIBRIUM_H
#define __PINCTRL_EQUILIBRIUM_H
/* PINPAD register offset */
#define REG_PMX_BASE 0x0 /* Port Multiplexer Control Register */
#define REG_PUEN 0x80 /* PULL UP Enable Register */
#define REG_PDEN 0x84 /* PULL DOWN Enable Register */
#define REG_SRC 0x88 /* Slew Rate Control Register */
#define REG_DCC0 0x8C /* Drive Current Control Register 0 */
#define REG_DCC1 0x90 /* Drive Current Control Register 1 */
#define REG_OD 0x94 /* Open Drain Enable Register */
#define REG_AVAIL 0x98 /* Pad Control Availability Register */
#define DRV_CUR_PINS 16 /* Drive Current pin number per register */
#define REG_DRCC(x) (REG_DCC0 + (x) * 4) /* Driver current macro */
/* GPIO register offset */
#define GPIO_OUT 0x0 /* Data Output Register */
#define GPIO_IN 0x4 /* Data Input Register */
#define GPIO_DIR 0x8 /* Direction Register */
#define GPIO_EXINTCR0 0x18 /* External Interrupt Control Register 0 */
#define GPIO_EXINTCR1 0x1C /* External Interrupt Control Register 1 */
#define GPIO_IRNCR 0x20 /* IRN Capture Register */
#define GPIO_IRNICR 0x24 /* IRN Interrupt Control Register */
#define GPIO_IRNEN 0x28 /* IRN Interrupt Enable Register */
#define GPIO_IRNCFG 0x2C /* IRN Interrupt Configuration Register */
#define GPIO_IRNRNSET 0x30 /* IRN Interrupt Enable Set Register */
#define GPIO_IRNENCLR 0x34 /* IRN Interrupt Enable Clear Register */
#define GPIO_OUTSET 0x40 /* Output Set Register */
#define GPIO_OUTCLR 0x44 /* Output Clear Register */
#define GPIO_DIRSET 0x48 /* Direction Set Register */
#define GPIO_DIRCLR 0x4C /* Direction Clear Register */
/* parse given pin's driver current value */
#define PARSE_DRV_CURRENT(val, pin) (((val) >> ((pin) * 2)) & 0x3)
#define GPIO_EDGE_TRIG 0
#define GPIO_LEVEL_TRIG 1
#define GPIO_SINGLE_EDGE 0
#define GPIO_BOTH_EDGE 1
#define GPIO_POSITIVE_TRIG 0
#define GPIO_NEGATIVE_TRIG 1
#define EQBR_GPIO_MODE 0
typedef enum {
OP_COUNT_NR_FUNCS,
OP_ADD_FUNCS,
OP_COUNT_NR_FUNC_GRPS,
OP_ADD_FUNC_GRPS,
OP_NONE,
} funcs_util_ops;
/**
* struct gpio_irq_type: gpio irq configuration
* @trig_type: level trigger or edge trigger
* @edge_type: sigle edge or both edge
* @logic_type: positive trigger or negative trigger
*/
struct gpio_irq_type {
unsigned int trig_type;
unsigned int edge_type;
unsigned int logic_type;
};
/**
* struct eqbr_pmx_func: represent a pin function.
* @name: name of the pin function, used to lookup the function.
* @groups: one or more names of pin groups that provide this function.
* @nr_groups: number of groups included in @groups.
*/
struct eqbr_pmx_func {
const char *name;
const char **groups;
unsigned int nr_groups;
};
/**
* struct eqbr_pin_bank: represent a pin bank.
* @membase: base address of the pin bank register.
* @id: bank id, to idenify the unique bank.
* @pin_base: starting pin number of the pin bank.
* @nr_pins: number of the pins of the pin bank.
* @aval_pinmap: available pin bitmap of the pin bank.
*/
struct eqbr_pin_bank {
void __iomem *membase;
unsigned int id;
unsigned int pin_base;
unsigned int nr_pins;
u32 aval_pinmap;
};
/**
* struct eqbr_gpio_ctrl: represent a gpio controller.
* @node: device node of gpio controller.
* @bank: pointer to corresponding pin bank.
* @membase: base address of the gpio controller.
* @chip: gpio chip.
* @ic: irq chip.
* @name: gpio chip name.
* @virq: irq number of the gpio chip to parent's irq domain.
* @lock: spin lock to protect gpio register write.
*/
struct eqbr_gpio_ctrl {
struct device_node *node;
struct eqbr_pin_bank *bank;
void __iomem *membase;
struct gpio_chip chip;
struct irq_chip ic;
const char *name;
unsigned int virq;
raw_spinlock_t lock; /* protect gpio register */
};
/**
* struct eqbr_pinctrl_drv_data:
* @dev: device instance representing the controller.
* @pctl_desc: pin controller descriptor.
* @pctl_dev: pin control class device
* @membase: base address of pin controller
* @pin_banks: list of pin banks of the driver.
* @nr_banks: number of pin banks.
* @gpio_ctrls: list of gpio controllers.
* @nr_gpio_ctrls: number of gpio controllers.
* @lock: protect pinctrl register write
*/
struct eqbr_pinctrl_drv_data {
struct device *dev;
struct pinctrl_desc pctl_desc;
struct pinctrl_dev *pctl_dev;
void __iomem *membase;
struct eqbr_pin_bank *pin_banks;
unsigned int nr_banks;
struct eqbr_gpio_ctrl *gpio_ctrls;
unsigned int nr_gpio_ctrls;
raw_spinlock_t lock; /* protect pinpad register */
};
#endif /* __PINCTRL_EQUILIBRIUM_H */

View File

@ -686,6 +686,7 @@ static int jz4770_mac_rmii_pins[] = {
0xa9, 0xab, 0xaa, 0xac, 0xa5, 0xa4, 0xad, 0xae, 0xa6, 0xa8,
};
static int jz4770_mac_mii_pins[] = { 0xa7, 0xaf, };
static int jz4770_otg_pins[] = { 0x8a, };
static int jz4770_uart0_data_funcs[] = { 0, 0, };
static int jz4770_uart0_hwflow_funcs[] = { 0, 0, };
@ -744,6 +745,7 @@ static int jz4770_pwm_pwm6_funcs[] = { 0, };
static int jz4770_pwm_pwm7_funcs[] = { 0, };
static int jz4770_mac_rmii_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
static int jz4770_mac_mii_funcs[] = { 0, 0, };
static int jz4770_otg_funcs[] = { 0, };
static const struct group_desc jz4770_groups[] = {
INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
@ -799,6 +801,7 @@ static const struct group_desc jz4770_groups[] = {
INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7),
INGENIC_PIN_GROUP("mac-rmii", jz4770_mac_rmii),
INGENIC_PIN_GROUP("mac-mii", jz4770_mac_mii),
INGENIC_PIN_GROUP("otg-vbus", jz4770_otg),
};
static const char *jz4770_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
@ -841,6 +844,7 @@ static const char *jz4770_pwm5_groups[] = { "pwm5", };
static const char *jz4770_pwm6_groups[] = { "pwm6", };
static const char *jz4770_pwm7_groups[] = { "pwm7", };
static const char *jz4770_mac_groups[] = { "mac-rmii", "mac-mii", };
static const char *jz4770_otg_groups[] = { "otg-vbus", };
static const struct function_desc jz4770_functions[] = {
{ "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
@ -871,6 +875,7 @@ static const struct function_desc jz4770_functions[] = {
{ "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
{ "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
{ "mac", jz4770_mac_groups, ARRAY_SIZE(jz4770_mac_groups), },
{ "otg", jz4770_otg_groups, ARRAY_SIZE(jz4770_otg_groups), },
};
static const struct ingenic_chip_info jz4770_chip_info = {
@ -1801,19 +1806,30 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled);
}
static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc,
unsigned int pin, bool high)
{
if (jzpc->version >= ID_JZ4770)
ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, high);
else
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DATA, high);
}
static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
unsigned int idx = pin % PINS_PER_GPIO_CHIP;
unsigned int offt = pin / PINS_PER_GPIO_CHIP;
unsigned int cfg;
unsigned int cfg, arg;
int ret;
for (cfg = 0; cfg < num_configs; cfg++) {
switch (pinconf_to_config_param(configs[cfg])) {
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN:
case PIN_CONFIG_OUTPUT:
continue;
default:
return -ENOTSUPP;
@ -1821,6 +1837,8 @@ static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
}
for (cfg = 0; cfg < num_configs; cfg++) {
arg = pinconf_to_config_argument(configs[cfg]);
switch (pinconf_to_config_param(configs[cfg])) {
case PIN_CONFIG_BIAS_DISABLE:
dev_dbg(jzpc->dev, "disable pull-over for pin P%c%u\n",
@ -1844,6 +1862,14 @@ static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
ingenic_set_bias(jzpc, pin, true);
break;
case PIN_CONFIG_OUTPUT:
ret = pinctrl_gpio_direction_output(pin);
if (ret)
return ret;
ingenic_set_output_level(jzpc, pin, arg);
break;
default:
unreachable();
}
@ -1940,6 +1966,7 @@ static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc,
{
struct ingenic_gpio_chip *jzgc;
struct device *dev = jzpc->dev;
struct gpio_irq_chip *girq;
unsigned int bank;
int err;
@ -1982,10 +2009,6 @@ static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc,
jzgc->gc.free = gpiochip_generic_free;
}
err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
if (err)
return err;
jzgc->irq = irq_of_parse_and_map(node, 0);
if (!jzgc->irq)
return -EINVAL;
@ -2000,13 +2023,22 @@ static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc,
jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
err = gpiochip_irqchip_add(&jzgc->gc, &jzgc->irq_chip, 0,
handle_level_irq, IRQ_TYPE_NONE);
girq = &jzgc->gc.irq;
girq->chip = &jzgc->irq_chip;
girq->parent_handler = ingenic_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = jzgc->irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
if (err)
return err;
gpiochip_set_chained_irqchip(&jzgc->gc, &jzgc->irq_chip,
jzgc->irq, ingenic_gpio_irq_handler);
return 0;
}

View File

@ -1324,15 +1324,13 @@ static int lpc18xx_create_group_func_map(struct device *dev,
static int lpc18xx_scu_probe(struct platform_device *pdev)
{
struct lpc18xx_scu_data *scu;
struct resource *res;
int ret;
scu = devm_kzalloc(&pdev->dev, sizeof(*scu), GFP_KERNEL);
if (!scu)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
scu->base = devm_ioremap_resource(&pdev->dev, res);
scu->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(scu->base))
return PTR_ERR(scu->base);

View File

@ -736,6 +736,7 @@ static int ocelot_gpiochip_register(struct platform_device *pdev,
struct ocelot_pinctrl *info)
{
struct gpio_chip *gc;
struct gpio_irq_chip *girq;
int ret, irq;
info->gpio_chip = ocelot_gpiolib_chip;
@ -747,22 +748,26 @@ static int ocelot_gpiochip_register(struct platform_device *pdev,
gc->of_node = info->dev->of_node;
gc->label = "ocelot-gpio";
ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
if (ret)
return ret;
irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
if (irq <= 0)
return irq;
ret = gpiochip_irqchip_add(gc, &ocelot_irqchip, 0, handle_edge_irq,
IRQ_TYPE_NONE);
girq = &gc->irq;
girq->chip = &ocelot_irqchip;
girq->parent_handler = ocelot_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_edge_irq;
ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
if (ret)
return ret;
gpiochip_set_chained_irqchip(gc, &ocelot_irqchip, irq,
ocelot_irq_handler);
return 0;
}

View File

@ -1196,7 +1196,7 @@ static int oxnas_gpio_probe(struct platform_device *pdev)
struct oxnas_gpio_bank *bank;
unsigned int id, ngpios;
int irq, ret;
struct resource *res;
struct gpio_irq_chip *girq;
if (of_parse_phandle_with_fixed_args(np, "gpio-ranges",
3, 0, &pinspec)) {
@ -1219,8 +1219,7 @@ static int oxnas_gpio_probe(struct platform_device *pdev)
bank = &oxnas_gpio_banks[id];
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bank->reg_base = devm_ioremap_resource(&pdev->dev, res);
bank->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(bank->reg_base))
return PTR_ERR(bank->reg_base);
@ -1232,6 +1231,18 @@ static int oxnas_gpio_probe(struct platform_device *pdev)
bank->gpio_chip.parent = &pdev->dev;
bank->gpio_chip.of_node = np;
bank->gpio_chip.ngpio = ngpios;
girq = &bank->gpio_chip.irq;
girq->chip = &bank->irq_chip;
girq->parent_handler = oxnas_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
ret = gpiochip_add_data(&bank->gpio_chip, bank);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to add GPIO chip %u: %d\n",
@ -1239,18 +1250,6 @@ static int oxnas_gpio_probe(struct platform_device *pdev)
return ret;
}
ret = gpiochip_irqchip_add(&bank->gpio_chip, &bank->irq_chip,
0, handle_level_irq, IRQ_TYPE_NONE);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to add IRQ chip %u: %d\n",
id, ret);
gpiochip_remove(&bank->gpio_chip);
return ret;
}
gpiochip_set_chained_irqchip(&bank->gpio_chip, &bank->irq_chip,
irq, oxnas_gpio_irq_handler);
return 0;
}

View File

@ -2202,7 +2202,7 @@ static int pic32_gpio_probe(struct platform_device *pdev)
struct pic32_gpio_bank *bank;
u32 id;
int irq, ret;
struct resource *res;
struct gpio_irq_chip *girq;
if (of_property_read_u32(np, "microchip,gpio-bank", &id)) {
dev_err(&pdev->dev, "microchip,gpio-bank property not found\n");
@ -2216,8 +2216,7 @@ static int pic32_gpio_probe(struct platform_device *pdev)
bank = &pic32_gpio_banks[id];
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bank->reg_base = devm_ioremap_resource(&pdev->dev, res);
bank->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(bank->reg_base))
return PTR_ERR(bank->reg_base);
@ -2240,25 +2239,23 @@ static int pic32_gpio_probe(struct platform_device *pdev)
bank->gpio_chip.parent = &pdev->dev;
bank->gpio_chip.of_node = np;
girq = &bank->gpio_chip.irq;
girq->chip = &bank->irq_chip;
girq->parent_handler = pic32_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
girq->parents[0] = irq;
ret = gpiochip_add_data(&bank->gpio_chip, bank);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to add GPIO chip %u: %d\n",
id, ret);
return ret;
}
ret = gpiochip_irqchip_add(&bank->gpio_chip, &bank->irq_chip,
0, handle_level_irq, IRQ_TYPE_NONE);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to add IRQ chip %u: %d\n",
id, ret);
gpiochip_remove(&bank->gpio_chip);
return ret;
}
gpiochip_set_chained_irqchip(&bank->gpio_chip, &bank->irq_chip,
irq, pic32_gpio_irq_handler);
return 0;
}

View File

@ -1352,6 +1352,7 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl)
for (i = 0; i < pctl->nbanks; i++) {
char child_name[sizeof("gpioXX")];
struct device_node *child;
struct gpio_irq_chip *girq;
snprintf(child_name, sizeof(child_name), "gpio%d", i);
child = of_get_child_by_name(node, child_name);
@ -1383,6 +1384,22 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl)
bank->gpio_chip.parent = pctl->dev;
bank->gpio_chip.of_node = child;
girq = &bank->gpio_chip.irq;
girq->chip = &bank->irq_chip;
girq->parent_handler = pistachio_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(pctl->dev, 1,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents) {
ret = -ENOMEM;
goto err;
}
girq->parents[0] = irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
ret = gpiochip_add_data(&bank->gpio_chip, bank);
if (ret < 0) {
dev_err(pctl->dev, "Failed to add GPIO chip %u: %d\n",
@ -1390,17 +1407,6 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl)
goto err;
}
ret = gpiochip_irqchip_add(&bank->gpio_chip, &bank->irq_chip,
0, handle_level_irq, IRQ_TYPE_NONE);
if (ret < 0) {
dev_err(pctl->dev, "Failed to add IRQ chip %u: %d\n",
i, ret);
gpiochip_remove(&bank->gpio_chip);
goto err;
}
gpiochip_set_chained_irqchip(&bank->gpio_chip, &bank->irq_chip,
irq, pistachio_gpio_irq_handler);
ret = gpiochip_add_pin_range(&bank->gpio_chip,
dev_name(pctl->dev), 0,
bank->pin_base, bank->npins);
@ -1429,7 +1435,6 @@ static const struct of_device_id pistachio_pinctrl_of_match[] = {
static int pistachio_pinctrl_probe(struct platform_device *pdev)
{
struct pistachio_pinctrl *pctl;
struct resource *res;
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
if (!pctl)
@ -1437,8 +1442,7 @@ static int pistachio_pinctrl_probe(struct platform_device *pdev)
pctl->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, pctl);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctl->base = devm_ioremap_resource(&pdev->dev, res);
pctl->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctl->base))
return PTR_ERR(pctl->base);

View File

@ -58,6 +58,7 @@ enum rockchip_pinctrl_type {
RK3128,
RK3188,
RK3288,
RK3308,
RK3368,
RK3399,
};
@ -70,6 +71,7 @@ enum rockchip_pinctrl_type {
#define IOMUX_SOURCE_PMU BIT(2)
#define IOMUX_UNROUTED BIT(3)
#define IOMUX_WIDTH_3BIT BIT(4)
#define IOMUX_WIDTH_2BIT BIT(5)
/**
* @type: iomux variant using IOMUX_* constants
@ -656,6 +658,100 @@ static struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = {
},
};
static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
{
.num = 1,
.pin = 14,
.reg = 0x28,
.bit = 12,
.mask = 0xf
}, {
.num = 1,
.pin = 15,
.reg = 0x2c,
.bit = 0,
.mask = 0x3
}, {
.num = 1,
.pin = 18,
.reg = 0x30,
.bit = 4,
.mask = 0xf
}, {
.num = 1,
.pin = 19,
.reg = 0x30,
.bit = 8,
.mask = 0xf
}, {
.num = 1,
.pin = 20,
.reg = 0x30,
.bit = 12,
.mask = 0xf
}, {
.num = 1,
.pin = 21,
.reg = 0x34,
.bit = 0,
.mask = 0xf
}, {
.num = 1,
.pin = 22,
.reg = 0x34,
.bit = 4,
.mask = 0xf
}, {
.num = 1,
.pin = 23,
.reg = 0x34,
.bit = 8,
.mask = 0xf
}, {
.num = 3,
.pin = 12,
.reg = 0x68,
.bit = 8,
.mask = 0xf
}, {
.num = 3,
.pin = 13,
.reg = 0x68,
.bit = 12,
.mask = 0xf
}, {
.num = 2,
.pin = 2,
.reg = 0x608,
.bit = 0,
.mask = 0x7
}, {
.num = 2,
.pin = 3,
.reg = 0x608,
.bit = 4,
.mask = 0x7
}, {
.num = 2,
.pin = 16,
.reg = 0x610,
.bit = 8,
.mask = 0x7
}, {
.num = 3,
.pin = 10,
.reg = 0x610,
.bit = 0,
.mask = 0x7
}, {
.num = 3,
.pin = 11,
.reg = 0x610,
.bit = 4,
.mask = 0x7
},
};
static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = {
{
.num = 2,
@ -982,6 +1078,192 @@ static struct rockchip_mux_route_data rk3288_mux_route_data[] = {
},
};
static struct rockchip_mux_route_data rk3308_mux_route_data[] = {
{
/* rtc_clk */
.bank_num = 0,
.pin = 19,
.func = 1,
.route_offset = 0x314,
.route_val = BIT(16 + 0) | BIT(0),
}, {
/* uart2_rxm0 */
.bank_num = 1,
.pin = 22,
.func = 2,
.route_offset = 0x314,
.route_val = BIT(16 + 2) | BIT(16 + 3),
}, {
/* uart2_rxm1 */
.bank_num = 4,
.pin = 26,
.func = 2,
.route_offset = 0x314,
.route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2),
}, {
/* i2c3_sdam0 */
.bank_num = 0,
.pin = 15,
.func = 2,
.route_offset = 0x608,
.route_val = BIT(16 + 8) | BIT(16 + 9),
}, {
/* i2c3_sdam1 */
.bank_num = 3,
.pin = 12,
.func = 2,
.route_offset = 0x608,
.route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8),
}, {
/* i2c3_sdam2 */
.bank_num = 2,
.pin = 0,
.func = 3,
.route_offset = 0x608,
.route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9),
}, {
/* i2s-8ch-1-sclktxm0 */
.bank_num = 1,
.pin = 3,
.func = 2,
.route_offset = 0x308,
.route_val = BIT(16 + 3),
}, {
/* i2s-8ch-1-sclkrxm0 */
.bank_num = 1,
.pin = 4,
.func = 2,
.route_offset = 0x308,
.route_val = BIT(16 + 3),
}, {
/* i2s-8ch-1-sclktxm1 */
.bank_num = 1,
.pin = 13,
.func = 2,
.route_offset = 0x308,
.route_val = BIT(16 + 3) | BIT(3),
}, {
/* i2s-8ch-1-sclkrxm1 */
.bank_num = 1,
.pin = 14,
.func = 2,
.route_offset = 0x308,
.route_val = BIT(16 + 3) | BIT(3),
}, {
/* pdm-clkm0 */
.bank_num = 1,
.pin = 4,
.func = 3,
.route_offset = 0x308,
.route_val = BIT(16 + 12) | BIT(16 + 13),
}, {
/* pdm-clkm1 */
.bank_num = 1,
.pin = 14,
.func = 4,
.route_offset = 0x308,
.route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
}, {
/* pdm-clkm2 */
.bank_num = 2,
.pin = 6,
.func = 2,
.route_offset = 0x308,
.route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
}, {
/* pdm-clkm-m2 */
.bank_num = 2,
.pin = 4,
.func = 3,
.route_offset = 0x600,
.route_val = BIT(16 + 2) | BIT(2),
}, {
/* spi1_miso */
.bank_num = 3,
.pin = 10,
.func = 3,
.route_offset = 0x314,
.route_val = BIT(16 + 9),
}, {
/* spi1_miso_m1 */
.bank_num = 2,
.pin = 4,
.func = 2,
.route_offset = 0x314,
.route_val = BIT(16 + 9) | BIT(9),
}, {
/* owire_m0 */
.bank_num = 0,
.pin = 11,
.func = 3,
.route_offset = 0x314,
.route_val = BIT(16 + 10) | BIT(16 + 11),
}, {
/* owire_m1 */
.bank_num = 1,
.pin = 22,
.func = 7,
.route_offset = 0x314,
.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
}, {
/* owire_m2 */
.bank_num = 2,
.pin = 2,
.func = 5,
.route_offset = 0x314,
.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
}, {
/* can_rxd_m0 */
.bank_num = 0,
.pin = 11,
.func = 2,
.route_offset = 0x314,
.route_val = BIT(16 + 12) | BIT(16 + 13),
}, {
/* can_rxd_m1 */
.bank_num = 1,
.pin = 22,
.func = 5,
.route_offset = 0x314,
.route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
}, {
/* can_rxd_m2 */
.bank_num = 2,
.pin = 2,
.func = 4,
.route_offset = 0x314,
.route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
}, {
/* mac_rxd0_m0 */
.bank_num = 1,
.pin = 20,
.func = 3,
.route_offset = 0x314,
.route_val = BIT(16 + 14),
}, {
/* mac_rxd0_m1 */
.bank_num = 4,
.pin = 2,
.func = 2,
.route_offset = 0x314,
.route_val = BIT(16 + 14) | BIT(14),
}, {
/* uart3_rx */
.bank_num = 3,
.pin = 12,
.func = 4,
.route_offset = 0x314,
.route_val = BIT(16 + 15),
}, {
/* uart3_rx_m1 */
.bank_num = 0,
.pin = 17,
.func = 3,
.route_offset = 0x314,
.route_val = BIT(16 + 15) | BIT(15),
},
};
static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
{
/* uart2dbg_rxm0 */
@ -1475,6 +1757,26 @@ static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
return 0;
}
#define RK3308_SCHMITT_PINS_PER_REG 8
#define RK3308_SCHMITT_BANK_STRIDE 16
#define RK3308_SCHMITT_GRF_OFFSET 0x1a0
static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit)
{
struct rockchip_pinctrl *info = bank->drvdata;
*regmap = info->regmap_base;
*reg = RK3308_SCHMITT_GRF_OFFSET;
*reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE;
*reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4);
*bit = pin_num % RK3308_SCHMITT_PINS_PER_REG;
return 0;
}
#define RK2928_PULL_OFFSET 0x118
#define RK2928_PULL_PINS_PER_REG 16
#define RK2928_PULL_BANK_STRIDE 8
@ -1646,6 +1948,40 @@ static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
*bit *= RK3288_DRV_BITS_PER_PIN;
}
#define RK3308_PULL_OFFSET 0xa0
static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit)
{
struct rockchip_pinctrl *info = bank->drvdata;
*regmap = info->regmap_base;
*reg = RK3308_PULL_OFFSET;
*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
*bit *= RK3188_PULL_BITS_PER_PIN;
}
#define RK3308_DRV_GRF_OFFSET 0x100
static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit)
{
struct rockchip_pinctrl *info = bank->drvdata;
*regmap = info->regmap_base;
*reg = RK3308_DRV_GRF_OFFSET;
*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
*bit *= RK3288_DRV_BITS_PER_PIN;
}
#define RK3368_PULL_GRF_OFFSET 0x100
#define RK3368_PULL_PMU_OFFSET 0x10
@ -1986,6 +2322,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
case RV1108:
case RK3188:
case RK3288:
case RK3308:
case RK3368:
case RK3399:
pull_type = bank->pull_type[pin_num / 8];
@ -2030,6 +2367,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
case RV1108:
case RK3188:
case RK3288:
case RK3308:
case RK3368:
case RK3399:
pull_type = bank->pull_type[pin_num / 8];
@ -2293,6 +2631,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
case RV1108:
case RK3188:
case RK3288:
case RK3308:
case RK3368:
case RK3399:
return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
@ -3303,7 +3642,8 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
* 4bit iomux'es are spread over two registers.
*/
inc = (iom->type & (IOMUX_WIDTH_4BIT |
IOMUX_WIDTH_3BIT)) ? 8 : 4;
IOMUX_WIDTH_3BIT |
IOMUX_WIDTH_2BIT)) ? 8 : 4;
if (iom->type & IOMUX_SOURCE_PMU)
pmu_offs += inc;
else
@ -3709,6 +4049,44 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
.drv_calc_reg = rk3288_calc_drv_reg_and_bit,
};
static struct rockchip_pin_bank rk3308_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT),
PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT),
PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT),
PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT),
PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT,
IOMUX_WIDTH_2BIT),
};
static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
.pin_banks = rk3308_pin_banks,
.nr_banks = ARRAY_SIZE(rk3308_pin_banks),
.label = "RK3308-GPIO",
.type = RK3308,
.grf_mux_offset = 0x0,
.iomux_recalced = rk3308_mux_recalced_data,
.niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data),
.iomux_routes = rk3308_mux_route_data,
.niomux_routes = ARRAY_SIZE(rk3308_mux_route_data),
.pull_calc_reg = rk3308_calc_pull_reg_and_bit,
.drv_calc_reg = rk3308_calc_drv_reg_and_bit,
.schmitt_calc_reg = rk3308_calc_schmitt_reg_and_bit,
};
static struct rockchip_pin_bank rk3328_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0),
PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
@ -3849,6 +4227,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
.data = &rk3228_pin_ctrl },
{ .compatible = "rockchip,rk3288-pinctrl",
.data = &rk3288_pin_ctrl },
{ .compatible = "rockchip,rk3308-pinctrl",
.data = &rk3308_pin_ctrl },
{ .compatible = "rockchip,rk3328-pinctrl",
.data = &rk3328_pin_ctrl },
{ .compatible = "rockchip,rk3368-pinctrl",

View File

@ -617,12 +617,6 @@ static void rza1_pin_reset(struct rza1_port *port, unsigned int pin)
spin_unlock_irqrestore(&port->lock, irqflags);
}
static inline int rza1_pin_get_direction(struct rza1_port *port,
unsigned int pin)
{
return !!rza1_get_bit(port, RZA1_PM_REG, pin);
}
/**
* rza1_pin_set_direction() - set I/O direction on a pin in port mode
*
@ -783,7 +777,7 @@ static int rza1_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
{
struct rza1_port *port = gpiochip_get_data(chip);
return rza1_pin_get_direction(port, gpio);
return !!rza1_get_bit(port, RZA1_PM_REG, gpio);
}
static int rza1_gpio_direction_input(struct gpio_chip *chip,

View File

@ -213,8 +213,8 @@ static const char * const rza2_gpio_names[] = {
"PC_0", "PC_1", "PC_2", "PC_3", "PC_4", "PC_5", "PC_6", "PC_7",
"PD_0", "PD_1", "PD_2", "PD_3", "PD_4", "PD_5", "PD_6", "PD_7",
"PE_0", "PE_1", "PE_2", "PE_3", "PE_4", "PE_5", "PE_6", "PE_7",
"PF_0", "PF_1", "PF_2", "PF_3", "P0_4", "PF_5", "PF_6", "PF_7",
"PG_0", "PG_1", "PG_2", "P0_3", "PG_4", "PG_5", "PG_6", "PG_7",
"PF_0", "PF_1", "PF_2", "PF_3", "PF_4", "PF_5", "PF_6", "PF_7",
"PG_0", "PG_1", "PG_2", "PG_3", "PG_4", "PG_5", "PG_6", "PG_7",
"PH_0", "PH_1", "PH_2", "PH_3", "PH_4", "PH_5", "PH_6", "PH_7",
/* port I does not exist */
"PJ_0", "PJ_1", "PJ_2", "PJ_3", "PJ_4", "PJ_5", "PJ_6", "PJ_7",
@ -462,7 +462,6 @@ static const struct pinmux_ops rza2_pinmux_ops = {
static int rza2_pinctrl_probe(struct platform_device *pdev)
{
struct rza2_pinctrl_priv *priv;
struct resource *res;
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@ -471,8 +470,7 @@ static int rza2_pinctrl_probe(struct platform_device *pdev)
priv->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(&pdev->dev, res);
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);

View File

@ -487,7 +487,7 @@ static int rzn1_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
const u32 reg_drive[4] = { 4, 6, 8, 12 };
static const u32 reg_drive[4] = { 4, 6, 8, 12 };
u32 pull, drive, l1mux;
u32 l1, l2, arg = 0;

View File

@ -1477,7 +1477,7 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
struct device *dev = info->dev;
int bank_num = of_alias_get_id(np, "gpio");
struct resource res, irq_res;
int gpio_irq = 0, err;
int err;
if (of_address_to_resource(np, 0, &res))
return -ENODEV;
@ -1500,12 +1500,6 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
range->pin_base = range->base = range->id * ST_GPIO_PINS_PER_BANK;
range->npins = bank->gpio_chip.ngpio;
range->gc = &bank->gpio_chip;
err = gpiochip_add_data(&bank->gpio_chip, bank);
if (err) {
dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_num);
return err;
}
dev_info(dev, "%s bank added.\n", range->name);
/**
* GPIO bank can have one of the two possible types of
@ -1527,23 +1521,40 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
*/
if (of_irq_to_resource(np, 0, &irq_res) > 0) {
gpio_irq = irq_res.start;
gpiochip_set_chained_irqchip(&bank->gpio_chip, &st_gpio_irqchip,
gpio_irq, st_gpio_irq_handler);
struct gpio_irq_chip *girq;
int gpio_irq = irq_res.start;
/* This is not a valid IRQ */
if (gpio_irq <= 0) {
dev_err(dev, "invalid IRQ for %pOF bank\n", np);
goto skip_irq;
}
/* We need to have a mux as well */
if (!info->irqmux_base) {
dev_err(dev, "no irqmux for %pOF bank\n", np);
goto skip_irq;
}
if (info->irqmux_base || gpio_irq > 0) {
err = gpiochip_irqchip_add(&bank->gpio_chip, &st_gpio_irqchip,
0, handle_simple_irq,
IRQ_TYPE_NONE);
girq = &bank->gpio_chip.irq;
girq->chip = &st_gpio_irqchip;
girq->parent_handler = st_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = gpio_irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_simple_irq;
}
skip_irq:
err = gpiochip_add_data(&bank->gpio_chip, bank);
if (err) {
gpiochip_remove(&bank->gpio_chip);
dev_info(dev, "could not add irqchip\n");
dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_num);
return err;
}
} else {
dev_info(dev, "No IRQ support for %pOF bank\n", np);
}
dev_info(dev, "%s bank added.\n", range->name);
return 0;
}

View File

@ -505,6 +505,25 @@ static void stmfx_pinctrl_irq_bus_sync_unlock(struct irq_data *data)
mutex_unlock(&pctl->lock);
}
static int stmfx_gpio_irq_request_resources(struct irq_data *data)
{
struct gpio_chip *gpio_chip = irq_data_get_irq_chip_data(data);
int ret;
ret = stmfx_gpio_direction_input(gpio_chip, data->hwirq);
if (ret)
return ret;
return gpiochip_reqres_irq(gpio_chip, data->hwirq);
}
static void stmfx_gpio_irq_release_resources(struct irq_data *data)
{
struct gpio_chip *gpio_chip = irq_data_get_irq_chip_data(data);
return gpiochip_relres_irq(gpio_chip, data->hwirq);
}
static void stmfx_pinctrl_irq_toggle_trigger(struct stmfx_pinctrl *pctl,
unsigned int offset)
{
@ -664,6 +683,8 @@ static int stmfx_pinctrl_probe(struct platform_device *pdev)
pctl->irq_chip.irq_set_type = stmfx_pinctrl_irq_set_type;
pctl->irq_chip.irq_bus_lock = stmfx_pinctrl_irq_bus_lock;
pctl->irq_chip.irq_bus_sync_unlock = stmfx_pinctrl_irq_bus_sync_unlock;
pctl->irq_chip.irq_request_resources = stmfx_gpio_irq_request_resources;
pctl->irq_chip.irq_release_resources = stmfx_gpio_irq_release_resources;
ret = gpiochip_irqchip_add_nested(&pctl->gpio_chip, &pctl->irq_chip,
0, handle_bad_irq, IRQ_TYPE_NONE);

View File

@ -747,7 +747,6 @@ static struct pinctrl_desc tb10x_pindesc = {
static int tb10x_pinctrl_probe(struct platform_device *pdev)
{
int ret = -EINVAL;
struct resource *mem;
struct device *dev = &pdev->dev;
struct device_node *of_node = dev->of_node;
struct device_node *child;
@ -768,8 +767,7 @@ static int tb10x_pinctrl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, state);
mutex_init(&state->mutex);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
state->base = devm_ioremap_resource(dev, mem);
state->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(state->base)) {
ret = PTR_ERR(state->base);
goto fail;

View File

@ -1055,7 +1055,6 @@ static struct pinctrl_desc u300_pmx_desc = {
static int u300_pmx_probe(struct platform_device *pdev)
{
struct u300_pmx *upmx;
struct resource *res;
/* Create state holders etc for this driver */
upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
@ -1064,8 +1063,7 @@ static int u300_pmx_probe(struct platform_device *pdev)
upmx->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
upmx->virtbase = devm_ioremap_resource(&pdev->dev, res);
upmx->virtbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(upmx->virtbase))
return PTR_ERR(upmx->virtbase);

View File

@ -1705,12 +1705,10 @@ static int pinmux_xway_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
const struct pinctrl_xway_soc *xway_soc;
struct resource *res;
int ret, i;
/* get and remap our register range */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
xway_info.membase[0] = devm_ioremap_resource(&pdev->dev, res);
xway_info.membase[0] = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(xway_info.membase[0]))
return PTR_ERR(xway_info.membase[0]);

View File

@ -216,25 +216,20 @@ static int pxa25x_pinctrl_probe(struct platform_device *pdev)
void __iomem *base_af[8];
void __iomem *base_dir[4];
void __iomem *base_sleep[4];
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base_af[0] = devm_ioremap_resource(&pdev->dev, res);
base_af[0] = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base_af[0]))
return PTR_ERR(base_af[0]);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
base_dir[0] = devm_ioremap_resource(&pdev->dev, res);
base_dir[0] = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(base_dir[0]))
return PTR_ERR(base_dir[0]);
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
base_dir[3] = devm_ioremap_resource(&pdev->dev, res);
base_dir[3] = devm_platform_ioremap_resource(pdev, 2);
if (IS_ERR(base_dir[3]))
return PTR_ERR(base_dir[3]);
res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
base_sleep[0] = devm_ioremap_resource(&pdev->dev, res);
base_sleep[0] = devm_platform_ioremap_resource(pdev, 3);
if (IS_ERR(base_sleep[0]))
return PTR_ERR(base_sleep[0]);

View File

@ -508,25 +508,20 @@ static int pxa27x_pinctrl_probe(struct platform_device *pdev)
void __iomem *base_af[8];
void __iomem *base_dir[4];
void __iomem *base_sleep[4];
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base_af[0] = devm_ioremap_resource(&pdev->dev, res);
base_af[0] = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base_af[0]))
return PTR_ERR(base_af[0]);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
base_dir[0] = devm_ioremap_resource(&pdev->dev, res);
base_dir[0] = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(base_dir[0]))
return PTR_ERR(base_dir[0]);
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
base_dir[3] = devm_ioremap_resource(&pdev->dev, res);
base_dir[3] = devm_platform_ioremap_resource(pdev, 2);
if (IS_ERR(base_dir[3]))
return PTR_ERR(base_dir[3]);
res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
base_sleep[0] = devm_ioremap_resource(&pdev->dev, res);
base_sleep[0] = devm_platform_ioremap_resource(pdev, 3);
if (IS_ERR(base_sleep[0]))
return PTR_ERR(base_sleep[0]);

View File

@ -90,6 +90,16 @@ config PINCTRL_MSM8916
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found on the Qualcomm 8916 platform.
config PINCTRL_MSM8976
tristate "Qualcomm 8976 pin controller driver"
depends on GPIOLIB && OF
select PINCTRL_MSM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found on the Qualcomm MSM8976 platform.
The Qualcomm MSM8956, APQ8056, APQ8076 platforms are also
supported by this driver.
config PINCTRL_MSM8994
tristate "Qualcomm 8994 pin controller driver"
depends on GPIOLIB && OF
@ -152,6 +162,7 @@ config PINCTRL_QCOM_SSBI_PMIC
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB_IRQCHIP
select IRQ_DOMAIN_HIERARCHY
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the

View File

@ -10,6 +10,7 @@ obj-$(CONFIG_PINCTRL_MSM8660) += pinctrl-msm8660.o
obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o
obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
obj-$(CONFIG_PINCTRL_MSM8916) += pinctrl-msm8916.o
obj-$(CONFIG_PINCTRL_MSM8976) += pinctrl-msm8976.o
obj-$(CONFIG_PINCTRL_MSM8994) += pinctrl-msm8994.o
obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o
obj-$(CONFIG_PINCTRL_MSM8998) += pinctrl-msm8998.o

View File

@ -1150,8 +1150,7 @@ int msm_pinctrl_probe(struct platform_device *pdev,
return PTR_ERR(pctrl->regs[i]);
}
} else {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctrl->regs[0] = devm_ioremap_resource(&pdev->dev, res);
pctrl->regs[0] = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctrl->regs[0]))
return PTR_ERR(pctrl->regs[0]);
}

File diff suppressed because it is too large Load Diff

View File

@ -77,6 +77,7 @@ enum {
.intr_cfg_reg = 0, \
.intr_status_reg = 0, \
.intr_target_reg = 0, \
.tile = SOUTH, \
.mux_bit = -1, \
.pull_bit = pull, \
.drv_bit = drv, \
@ -102,6 +103,7 @@ enum {
.intr_cfg_reg = 0, \
.intr_status_reg = 0, \
.intr_target_reg = 0, \
.tile = SOUTH, \
.mux_bit = -1, \
.pull_bit = 3, \
.drv_bit = 0, \
@ -1087,14 +1089,14 @@ static const struct msm_pingroup sc7180_groups[] = {
[116] = PINGROUP(116, WEST, qup04, qup04, _, _, _, _, _, _, _),
[117] = PINGROUP(117, WEST, dp_hot, _, _, _, _, _, _, _, _),
[118] = PINGROUP(118, WEST, _, _, _, _, _, _, _, _, _),
[119] = UFS_RESET(ufs_reset, 0x97f000),
[120] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x97a000, 15, 0),
[121] = SDC_QDSD_PINGROUP(sdc1_clk, 0x97a000, 13, 6),
[122] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x97a000, 11, 3),
[123] = SDC_QDSD_PINGROUP(sdc1_data, 0x97a000, 9, 0),
[124] = SDC_QDSD_PINGROUP(sdc2_clk, 0x97b000, 14, 6),
[125] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x97b000, 11, 3),
[126] = SDC_QDSD_PINGROUP(sdc2_data, 0x97b000, 9, 0),
[119] = UFS_RESET(ufs_reset, 0x7f000),
[120] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x7a000, 15, 0),
[121] = SDC_QDSD_PINGROUP(sdc1_clk, 0x7a000, 13, 6),
[122] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x7a000, 11, 3),
[123] = SDC_QDSD_PINGROUP(sdc1_data, 0x7a000, 9, 0),
[124] = SDC_QDSD_PINGROUP(sdc2_clk, 0x7b000, 14, 6),
[125] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x7b000, 11, 3),
[126] = SDC_QDSD_PINGROUP(sdc2_data, 0x7b000, 9, 0),
};
static const struct msm_pinctrl_soc_data sc7180_pinctrl = {

View File

@ -1108,6 +1108,9 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm8005-gpio", .data = (void *) 4 },
{ .compatible = "qcom,pm8916-gpio", .data = (void *) 4 },
{ .compatible = "qcom,pm8941-gpio", .data = (void *) 36 },
/* pm8950 has 8 GPIOs with holes on 3 */
{ .compatible = "qcom,pm8950-gpio", .data = (void *) 8 },
{ .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 },
{ .compatible = "qcom,pm8994-gpio", .data = (void *) 22 },
{ .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pm8998-gpio", .data = (void *) 26 },
@ -1121,6 +1124,8 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm8150b-gpio", .data = (void *) 12 },
/* pm8150l has 12 GPIOs with holes on 7 */
{ .compatible = "qcom,pm8150l-gpio", .data = (void *) 12 },
{ .compatible = "qcom,pm6150-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 },
{ },
};

View File

@ -915,6 +915,8 @@ static const struct of_device_id pmic_mpp_of_match[] = {
{ .compatible = "qcom,pm8841-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pm8916-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pm8941-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,pm8950-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pmi8950-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pm8994-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,pma8084-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,spmi-mpp" }, /* Generic */

View File

@ -56,7 +56,6 @@
/**
* struct pm8xxx_pin_data - dynamic configuration for a pin
* @reg: address of the control register
* @irq: IRQ from the PMIC interrupt controller
* @power_source: logical selected voltage source, mapping in static data
* is used translate to register values
* @mode: operating mode for the pin (input/output)
@ -72,7 +71,6 @@
*/
struct pm8xxx_pin_data {
unsigned reg;
int irq;
u8 power_source;
u8 mode;
bool open_drain;
@ -93,9 +91,6 @@ struct pm8xxx_gpio {
struct pinctrl_desc desc;
unsigned npins;
struct fwnode_handle *fwnode;
struct irq_domain *domain;
};
static const struct pinconf_generic_params pm8xxx_gpio_bindings[] = {
@ -491,13 +486,16 @@ static int pm8xxx_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
int ret, irq;
bool state;
int ret;
if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT) {
ret = pin->output_value;
} else if (pin->irq >= 0) {
ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state);
if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT)
return pin->output_value;
irq = chip->to_irq(chip, offset);
if (irq >= 0) {
ret = irq_get_irqchip_state(irq, IRQCHIP_STATE_LINE_LEVEL,
&state);
if (!ret)
ret = !!state;
} else
@ -535,37 +533,6 @@ static int pm8xxx_gpio_of_xlate(struct gpio_chip *chip,
}
static int pm8xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
struct irq_fwspec fwspec;
int ret;
fwspec.fwnode = pctrl->fwnode;
fwspec.param_count = 2;
fwspec.param[0] = offset + PM8XXX_GPIO_PHYSICAL_OFFSET;
fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
ret = irq_create_fwspec_mapping(&fwspec);
/*
* Cache the IRQ since pm8xxx_gpio_get() needs this to get determine the
* line level.
*/
pin->irq = ret;
return ret;
}
static void pm8xxx_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
pin->irq = -1;
}
#ifdef CONFIG_DEBUG_FS
#include <linux/seq_file.h>
@ -624,13 +591,11 @@ static void pm8xxx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
#endif
static const struct gpio_chip pm8xxx_gpio_template = {
.free = pm8xxx_gpio_free,
.direction_input = pm8xxx_gpio_direction_input,
.direction_output = pm8xxx_gpio_direction_output,
.get = pm8xxx_gpio_get,
.set = pm8xxx_gpio_set,
.of_xlate = pm8xxx_gpio_of_xlate,
.to_irq = pm8xxx_gpio_to_irq,
.dbg_show = pm8xxx_gpio_dbg_show,
.owner = THIS_MODULE,
};
@ -712,42 +677,23 @@ static int pm8xxx_domain_translate(struct irq_domain *domain,
return 0;
}
static int pm8xxx_domain_alloc(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs, void *data)
static unsigned int pm8xxx_child_offset_to_irq(struct gpio_chip *chip,
unsigned int offset)
{
struct pm8xxx_gpio *pctrl = container_of(domain->host_data,
struct pm8xxx_gpio, chip);
struct irq_fwspec *fwspec = data;
struct irq_fwspec parent_fwspec;
irq_hw_number_t hwirq;
unsigned int type;
int ret, i;
ret = pm8xxx_domain_translate(domain, fwspec, &hwirq, &type);
if (ret)
return ret;
for (i = 0; i < nr_irqs; i++)
irq_domain_set_info(domain, virq + i, hwirq + i,
&pm8xxx_irq_chip, pctrl, handle_level_irq,
NULL, NULL);
parent_fwspec.fwnode = domain->parent->fwnode;
parent_fwspec.param_count = 2;
parent_fwspec.param[0] = hwirq + 0xc0;
parent_fwspec.param[1] = fwspec->param[1];
return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
&parent_fwspec);
return offset + PM8XXX_GPIO_PHYSICAL_OFFSET;
}
static const struct irq_domain_ops pm8xxx_domain_ops = {
.activate = gpiochip_irq_domain_activate,
.alloc = pm8xxx_domain_alloc,
.deactivate = gpiochip_irq_domain_deactivate,
.free = irq_domain_free_irqs_common,
.translate = pm8xxx_domain_translate,
};
static int pm8xxx_child_to_parent_hwirq(struct gpio_chip *chip,
unsigned int child_hwirq,
unsigned int child_type,
unsigned int *parent_hwirq,
unsigned int *parent_type)
{
*parent_hwirq = child_hwirq + 0xc0;
*parent_type = child_type;
return 0;
}
static const struct of_device_id pm8xxx_gpio_of_match[] = {
{ .compatible = "qcom,pm8018-gpio", .data = (void *) 6 },
@ -765,6 +711,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
struct irq_domain *parent_domain;
struct device_node *parent_node;
struct pinctrl_pin_desc *pins;
struct gpio_irq_chip *girq;
struct pm8xxx_gpio *pctrl;
int ret, i;
@ -800,7 +747,6 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
for (i = 0; i < pctrl->desc.npins; i++) {
pin_data[i].reg = SSBI_REG_ADDR_GPIO(i);
pin_data[i].irq = -1;
ret = pm8xxx_pin_populate(pctrl, &pin_data[i]);
if (ret)
@ -841,19 +787,21 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
if (!parent_domain)
return -ENXIO;
pctrl->fwnode = of_node_to_fwnode(pctrl->dev->of_node);
pctrl->domain = irq_domain_create_hierarchy(parent_domain, 0,
pctrl->chip.ngpio,
pctrl->fwnode,
&pm8xxx_domain_ops,
&pctrl->chip);
if (!pctrl->domain)
return -ENODEV;
girq = &pctrl->chip.irq;
girq->chip = &pm8xxx_irq_chip;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
girq->fwnode = of_node_to_fwnode(pctrl->dev->of_node);
girq->parent_domain = parent_domain;
girq->child_to_parent_hwirq = pm8xxx_child_to_parent_hwirq;
girq->populate_parent_fwspec = gpiochip_populate_parent_fwspec_fourcell;
girq->child_offset_to_irq = pm8xxx_child_offset_to_irq;
girq->child_irq_domain_ops.translate = pm8xxx_domain_translate;
ret = gpiochip_add_data(&pctrl->chip, pctrl);
if (ret) {
dev_err(&pdev->dev, "failed register gpiochip\n");
goto err_chip_add_data;
return ret;
}
/*
@ -883,8 +831,6 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
unregister_gpiochip:
gpiochip_remove(&pctrl->chip);
err_chip_add_data:
irq_domain_remove(pctrl->domain);
return ret;
}
@ -894,7 +840,6 @@ static int pm8xxx_gpio_remove(struct platform_device *pdev)
struct pm8xxx_gpio *pctrl = platform_get_drvdata(pdev);
gpiochip_remove(&pctrl->chip);
irq_domain_remove(pctrl->domain);
return 0;
}

View File

@ -486,8 +486,10 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
if (match) {
irq_chip = kmemdup(match->data,
sizeof(*irq_chip), GFP_KERNEL);
if (!irq_chip)
if (!irq_chip) {
of_node_put(np);
return -ENOMEM;
}
wkup_np = np;
break;
}
@ -504,6 +506,7 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
bank->nr_pins, &exynos_eint_irqd_ops, bank);
if (!bank->irq_domain) {
dev_err(dev, "wkup irq domain add failed\n");
of_node_put(wkup_np);
return -ENXIO;
}
@ -518,8 +521,10 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
weint_data = devm_kcalloc(dev,
bank->nr_pins, sizeof(*weint_data),
GFP_KERNEL);
if (!weint_data)
if (!weint_data) {
of_node_put(wkup_np);
return -ENOMEM;
}
for (idx = 0; idx < bank->nr_pins; ++idx) {
irq = irq_of_parse_and_map(bank->of_node, idx);
@ -536,10 +541,13 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
}
}
if (!muxed_banks)
if (!muxed_banks) {
of_node_put(wkup_np);
return 0;
}
irq = irq_of_parse_and_map(wkup_np, 0);
of_node_put(wkup_np);
if (!irq) {
dev_err(dev, "irq number for muxed EINTs not found\n");
return 0;

View File

@ -490,8 +490,10 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
return -ENODEV;
eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL);
if (!eint_data)
if (!eint_data) {
of_node_put(eint_np);
return -ENOMEM;
}
eint_data->drvdata = d;
@ -503,12 +505,14 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
irq = irq_of_parse_and_map(eint_np, i);
if (!irq) {
dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
of_node_put(eint_np);
return -ENXIO;
}
eint_data->parents[i] = irq;
irq_set_chained_handler_and_data(irq, handlers[i], eint_data);
}
of_node_put(eint_np);
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank) {

View File

@ -704,8 +704,10 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
return -ENODEV;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
if (!data) {
of_node_put(eint0_np);
return -ENOMEM;
}
data->drvdata = d;
for (i = 0; i < NUM_EINT0_IRQ; ++i) {
@ -714,6 +716,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
irq = irq_of_parse_and_map(eint0_np, i);
if (!irq) {
dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
of_node_put(eint0_np);
return -ENXIO;
}
@ -721,6 +724,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
s3c64xx_eint0_handlers[i],
data);
}
of_node_put(eint0_np);
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank) {

View File

@ -272,6 +272,7 @@ static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
&reserved_maps, num_maps);
if (ret < 0) {
samsung_dt_free_map(pctldev, *map, *num_maps);
of_node_put(np);
return ret;
}
}
@ -785,8 +786,10 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions(
if (!of_get_child_count(cfg_np)) {
ret = samsung_pinctrl_create_function(dev, drvdata,
cfg_np, func);
if (ret < 0)
if (ret < 0) {
of_node_put(cfg_np);
return ERR_PTR(ret);
}
if (ret > 0) {
++func;
++func_cnt;
@ -797,8 +800,11 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions(
for_each_child_of_node(cfg_np, func_np) {
ret = samsung_pinctrl_create_function(dev, drvdata,
func_np, func);
if (ret < 0)
if (ret < 0) {
of_node_put(func_np);
of_node_put(cfg_np);
return ERR_PTR(ret);
}
if (ret > 0) {
++func;
++func_cnt;

View File

@ -17,6 +17,7 @@ config PINCTRL_SH_PFC
select PINCTRL_PFC_R8A7745 if ARCH_R8A7745
select PINCTRL_PFC_R8A77470 if ARCH_R8A77470
select PINCTRL_PFC_R8A774A1 if ARCH_R8A774A1
select PINCTRL_PFC_R8A774B1 if ARCH_R8A774B1
select PINCTRL_PFC_R8A774C0 if ARCH_R8A774C0
select PINCTRL_PFC_R8A7778 if ARCH_R8A7778
select PINCTRL_PFC_R8A7779 if ARCH_R8A7779
@ -26,7 +27,8 @@ config PINCTRL_SH_PFC
select PINCTRL_PFC_R8A7793 if ARCH_R8A7793
select PINCTRL_PFC_R8A7794 if ARCH_R8A7794
select PINCTRL_PFC_R8A7795 if ARCH_R8A7795
select PINCTRL_PFC_R8A7796 if ARCH_R8A7796
select PINCTRL_PFC_R8A77960 if ARCH_R8A77960 || ARCH_R8A7796
select PINCTRL_PFC_R8A77961 if ARCH_R8A77961
select PINCTRL_PFC_R8A77965 if ARCH_R8A77965
select PINCTRL_PFC_R8A77970 if ARCH_R8A77970
select PINCTRL_PFC_R8A77980 if ARCH_R8A77980
@ -86,6 +88,9 @@ config PINCTRL_PFC_R8A77470
config PINCTRL_PFC_R8A774A1
bool "RZ/G2M pin control support" if COMPILE_TEST
config PINCTRL_PFC_R8A774B1
bool "RZ/G2N pin control support" if COMPILE_TEST
config PINCTRL_PFC_R8A774C0
bool "RZ/G2E pin control support" if COMPILE_TEST
@ -113,9 +118,12 @@ config PINCTRL_PFC_R8A7794
config PINCTRL_PFC_R8A7795
bool "R-Car H3 pin control support" if COMPILE_TEST
config PINCTRL_PFC_R8A7796
config PINCTRL_PFC_R8A77960
bool "R-Car M3-W pin control support" if COMPILE_TEST
config PINCTRL_PFC_R8A77961
bool "R-Car M3-W+ pin control support" if COMPILE_TEST
config PINCTRL_PFC_R8A77965
bool "R-Car M3-N pin control support" if COMPILE_TEST

View File

@ -9,6 +9,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7744) += pfc-r8a7791.o
obj-$(CONFIG_PINCTRL_PFC_R8A7745) += pfc-r8a7794.o
obj-$(CONFIG_PINCTRL_PFC_R8A77470) += pfc-r8a77470.o
obj-$(CONFIG_PINCTRL_PFC_R8A774A1) += pfc-r8a7796.o
obj-$(CONFIG_PINCTRL_PFC_R8A774B1) += pfc-r8a77965.o
obj-$(CONFIG_PINCTRL_PFC_R8A774C0) += pfc-r8a77990.o
obj-$(CONFIG_PINCTRL_PFC_R8A7778) += pfc-r8a7778.o
obj-$(CONFIG_PINCTRL_PFC_R8A7779) += pfc-r8a7779.o
@ -19,7 +20,8 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7793) += pfc-r8a7791.o
obj-$(CONFIG_PINCTRL_PFC_R8A7794) += pfc-r8a7794.o
obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795.o
obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795-es1.o
obj-$(CONFIG_PINCTRL_PFC_R8A7796) += pfc-r8a7796.o
obj-$(CONFIG_PINCTRL_PFC_R8A77960) += pfc-r8a7796.o
obj-$(CONFIG_PINCTRL_PFC_R8A77961) += pfc-r8a7796.o
obj-$(CONFIG_PINCTRL_PFC_R8A77965) += pfc-r8a77965.o
obj-$(CONFIG_PINCTRL_PFC_R8A77970) += pfc-r8a77970.o
obj-$(CONFIG_PINCTRL_PFC_R8A77980) += pfc-r8a77980.o

View File

@ -29,12 +29,12 @@
static int sh_pfc_map_resources(struct sh_pfc *pfc,
struct platform_device *pdev)
{
unsigned int num_windows, num_irqs;
struct sh_pfc_window *windows;
unsigned int *irqs = NULL;
unsigned int num_windows;
struct resource *res;
unsigned int i;
int irq;
int num_irqs;
/* Count the MEM and IRQ resources. */
for (num_windows = 0;; num_windows++) {
@ -42,17 +42,13 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc,
if (!res)
break;
}
for (num_irqs = 0;; num_irqs++) {
irq = platform_get_irq(pdev, num_irqs);
if (irq == -EPROBE_DEFER)
return irq;
if (irq < 0)
break;
}
if (num_windows == 0)
return -EINVAL;
num_irqs = platform_irq_count(pdev);
if (num_irqs < 0)
return num_irqs;
/* Allocate memory windows and IRQs arrays. */
windows = devm_kcalloc(pfc->dev, num_windows, sizeof(*windows),
GFP_KERNEL);
@ -518,6 +514,12 @@ static const struct of_device_id sh_pfc_of_table[] = {
.data = &r8a774a1_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A774B1
{
.compatible = "renesas,pfc-r8a774b1",
.data = &r8a774b1_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A774C0
{
.compatible = "renesas,pfc-r8a774c0",
@ -579,10 +581,16 @@ static const struct of_device_id sh_pfc_of_table[] = {
},
#endif /* DEBUG */
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7796
#ifdef CONFIG_PINCTRL_PFC_R8A77960
{
.compatible = "renesas,pfc-r8a7796",
.data = &r8a7796_pinmux_info,
.data = &r8a77960_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A77961
{
.compatible = "renesas,pfc-r8a77961",
.data = &r8a77961_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A77965

View File

@ -718,7 +718,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, HRX3_D, I2C_SEL_3_0, SEL_HSCIF3_3),
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, VI4_DATA7_B, I2C_SEL_3_0, SEL_VIN4_1),
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, IERX_B, I2C_SEL_3_0, SEL_IEBUS_1),
PINMUX_IPSR_PHYS(IP0_23_20, SCL3, I2C_SEL_3_1),
PINMUX_IPSR_PHYS(IP1_23_20, SCL3, I2C_SEL_3_1),
PINMUX_IPSR_PHYS_MSEL(IP1_27_24, PWM2_A, I2C_SEL_3_0, SEL_PWM2_0),
PINMUX_IPSR_MSEL(IP1_27_24, A20, I2C_SEL_3_0),

View File

@ -726,7 +726,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, HRX3_D, I2C_SEL_3_0, SEL_HSCIF3_3),
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, VI4_DATA7_B, I2C_SEL_3_0, SEL_VIN4_1),
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, IERX_B, I2C_SEL_3_0, SEL_IEBUS_1),
PINMUX_IPSR_PHYS(IP0_23_20, SCL3, I2C_SEL_3_1),
PINMUX_IPSR_PHYS(IP1_23_20, SCL3, I2C_SEL_3_1),
PINMUX_IPSR_PHYS_MSEL(IP1_27_24, PWM2_A, I2C_SEL_3_0, SEL_PWM2_0),
PINMUX_IPSR_PHYS_MSEL(IP1_27_24, HTX3_D, I2C_SEL_3_0, SEL_HSCIF3_3),

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
* R8A7796 processor support - PFC hardware block.
* R8A7796 (R-Car M3-W/W+) support - PFC hardware block.
*
* Copyright (C) 2016-2019 Renesas Electronics Corp.
*
@ -729,7 +729,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, HRX3_D, I2C_SEL_3_0, SEL_HSCIF3_3),
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, VI4_DATA7_B, I2C_SEL_3_0, SEL_VIN4_1),
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, IERX_B, I2C_SEL_3_0, SEL_IEBUS_1),
PINMUX_IPSR_PHYS(IP0_23_20, SCL3, I2C_SEL_3_1),
PINMUX_IPSR_PHYS(IP1_23_20, SCL3, I2C_SEL_3_1),
PINMUX_IPSR_PHYS_MSEL(IP1_27_24, PWM2_A, I2C_SEL_3_0, SEL_PWM2_0),
PINMUX_IPSR_PHYS_MSEL(IP1_27_24, HTX3_D, I2C_SEL_3_0, SEL_HSCIF3_3),
@ -6210,8 +6210,8 @@ const struct sh_pfc_soc_info r8a774a1_pinmux_info = {
};
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7796
const struct sh_pfc_soc_info r8a7796_pinmux_info = {
#ifdef CONFIG_PINCTRL_PFC_R8A77960
const struct sh_pfc_soc_info r8a77960_pinmux_info = {
.name = "r8a77960_pfc",
.ops = &r8a7796_pinmux_ops,
.unlock_reg = 0xe6060000, /* PMMR */
@ -6236,3 +6236,30 @@ const struct sh_pfc_soc_info r8a7796_pinmux_info = {
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
};
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A77961
const struct sh_pfc_soc_info r8a77961_pinmux_info = {
.name = "r8a77961_pfc",
.ops = &r8a7796_pinmux_ops,
.unlock_reg = 0xe6060000, /* PMMR */
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
.pins = pinmux_pins,
.nr_pins = ARRAY_SIZE(pinmux_pins),
.groups = pinmux_groups.common,
.nr_groups = ARRAY_SIZE(pinmux_groups.common) +
ARRAY_SIZE(pinmux_groups.automotive),
.functions = pinmux_functions.common,
.nr_functions = ARRAY_SIZE(pinmux_functions.common) +
ARRAY_SIZE(pinmux_functions.automotive),
.cfg_regs = pinmux_config_regs,
.drive_regs = pinmux_drive_regs,
.bias_regs = pinmux_bias_regs,
.ioctrl_regs = pinmux_ioctrl_regs,
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
};
#endif

View File

@ -732,7 +732,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, HRX3_D, I2C_SEL_3_0, SEL_HSCIF3_3),
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, VI4_DATA7_B, I2C_SEL_3_0, SEL_VIN4_1),
PINMUX_IPSR_PHYS_MSEL(IP1_23_20, IERX_B, I2C_SEL_3_0, SEL_IEBUS_1),
PINMUX_IPSR_PHYS(IP0_23_20, SCL3, I2C_SEL_3_1),
PINMUX_IPSR_PHYS(IP1_23_20, SCL3, I2C_SEL_3_1),
PINMUX_IPSR_PHYS_MSEL(IP1_27_24, PWM2_A, I2C_SEL_3_0, SEL_PWM2_0),
PINMUX_IPSR_PHYS_MSEL(IP1_27_24, HTX3_D, I2C_SEL_3_0, SEL_HSCIF3_3),
@ -4378,7 +4378,11 @@ static const unsigned int vin5_clk_mux[] = {
VI5_CLK_MARK,
};
static const struct sh_pfc_pin_group pinmux_groups[] = {
static const struct {
struct sh_pfc_pin_group common[318];
struct sh_pfc_pin_group automotive[30];
} pinmux_groups = {
.common = {
SH_PFC_PIN_GROUP(audio_clk_a_a),
SH_PFC_PIN_GROUP(audio_clk_a_b),
SH_PFC_PIN_GROUP(audio_clk_a_c),
@ -4414,36 +4418,6 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(canfd0_data_a),
SH_PFC_PIN_GROUP(canfd0_data_b),
SH_PFC_PIN_GROUP(canfd1_data),
SH_PFC_PIN_GROUP(drif0_ctrl_a),
SH_PFC_PIN_GROUP(drif0_data0_a),
SH_PFC_PIN_GROUP(drif0_data1_a),
SH_PFC_PIN_GROUP(drif0_ctrl_b),
SH_PFC_PIN_GROUP(drif0_data0_b),
SH_PFC_PIN_GROUP(drif0_data1_b),
SH_PFC_PIN_GROUP(drif0_ctrl_c),
SH_PFC_PIN_GROUP(drif0_data0_c),
SH_PFC_PIN_GROUP(drif0_data1_c),
SH_PFC_PIN_GROUP(drif1_ctrl_a),
SH_PFC_PIN_GROUP(drif1_data0_a),
SH_PFC_PIN_GROUP(drif1_data1_a),
SH_PFC_PIN_GROUP(drif1_ctrl_b),
SH_PFC_PIN_GROUP(drif1_data0_b),
SH_PFC_PIN_GROUP(drif1_data1_b),
SH_PFC_PIN_GROUP(drif1_ctrl_c),
SH_PFC_PIN_GROUP(drif1_data0_c),
SH_PFC_PIN_GROUP(drif1_data1_c),
SH_PFC_PIN_GROUP(drif2_ctrl_a),
SH_PFC_PIN_GROUP(drif2_data0_a),
SH_PFC_PIN_GROUP(drif2_data1_a),
SH_PFC_PIN_GROUP(drif2_ctrl_b),
SH_PFC_PIN_GROUP(drif2_data0_b),
SH_PFC_PIN_GROUP(drif2_data1_b),
SH_PFC_PIN_GROUP(drif3_ctrl_a),
SH_PFC_PIN_GROUP(drif3_data0_a),
SH_PFC_PIN_GROUP(drif3_data1_a),
SH_PFC_PIN_GROUP(drif3_ctrl_b),
SH_PFC_PIN_GROUP(drif3_data0_b),
SH_PFC_PIN_GROUP(drif3_data1_b),
SH_PFC_PIN_GROUP(du_rgb666),
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
@ -4727,6 +4701,39 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(vin5_field),
SH_PFC_PIN_GROUP(vin5_clkenb),
SH_PFC_PIN_GROUP(vin5_clk),
},
.automotive = {
SH_PFC_PIN_GROUP(drif0_ctrl_a),
SH_PFC_PIN_GROUP(drif0_data0_a),
SH_PFC_PIN_GROUP(drif0_data1_a),
SH_PFC_PIN_GROUP(drif0_ctrl_b),
SH_PFC_PIN_GROUP(drif0_data0_b),
SH_PFC_PIN_GROUP(drif0_data1_b),
SH_PFC_PIN_GROUP(drif0_ctrl_c),
SH_PFC_PIN_GROUP(drif0_data0_c),
SH_PFC_PIN_GROUP(drif0_data1_c),
SH_PFC_PIN_GROUP(drif1_ctrl_a),
SH_PFC_PIN_GROUP(drif1_data0_a),
SH_PFC_PIN_GROUP(drif1_data1_a),
SH_PFC_PIN_GROUP(drif1_ctrl_b),
SH_PFC_PIN_GROUP(drif1_data0_b),
SH_PFC_PIN_GROUP(drif1_data1_b),
SH_PFC_PIN_GROUP(drif1_ctrl_c),
SH_PFC_PIN_GROUP(drif1_data0_c),
SH_PFC_PIN_GROUP(drif1_data1_c),
SH_PFC_PIN_GROUP(drif2_ctrl_a),
SH_PFC_PIN_GROUP(drif2_data0_a),
SH_PFC_PIN_GROUP(drif2_data1_a),
SH_PFC_PIN_GROUP(drif2_ctrl_b),
SH_PFC_PIN_GROUP(drif2_data0_b),
SH_PFC_PIN_GROUP(drif2_data1_b),
SH_PFC_PIN_GROUP(drif3_ctrl_a),
SH_PFC_PIN_GROUP(drif3_data0_a),
SH_PFC_PIN_GROUP(drif3_data1_a),
SH_PFC_PIN_GROUP(drif3_ctrl_b),
SH_PFC_PIN_GROUP(drif3_data0_b),
SH_PFC_PIN_GROUP(drif3_data1_b),
}
};
static const char * const audio_clk_groups[] = {
@ -5241,7 +5248,11 @@ static const char * const vin5_groups[] = {
"vin5_clk",
};
static const struct sh_pfc_function pinmux_functions[] = {
static const struct {
struct sh_pfc_function common[51];
struct sh_pfc_function automotive[4];
} pinmux_functions = {
.common = {
SH_PFC_FUNCTION(audio_clk),
SH_PFC_FUNCTION(avb),
SH_PFC_FUNCTION(can0),
@ -5249,10 +5260,6 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(can_clk),
SH_PFC_FUNCTION(canfd0),
SH_PFC_FUNCTION(canfd1),
SH_PFC_FUNCTION(drif0),
SH_PFC_FUNCTION(drif1),
SH_PFC_FUNCTION(drif2),
SH_PFC_FUNCTION(drif3),
SH_PFC_FUNCTION(du),
SH_PFC_FUNCTION(hscif0),
SH_PFC_FUNCTION(hscif1),
@ -5297,6 +5304,13 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(usb30),
SH_PFC_FUNCTION(vin4),
SH_PFC_FUNCTION(vin5),
},
.automotive = {
SH_PFC_FUNCTION(drif0),
SH_PFC_FUNCTION(drif1),
SH_PFC_FUNCTION(drif2),
SH_PFC_FUNCTION(drif3),
}
};
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
@ -6425,8 +6439,9 @@ static const struct sh_pfc_soc_operations r8a77965_pinmux_ops = {
.set_bias = r8a77965_pinmux_set_bias,
};
const struct sh_pfc_soc_info r8a77965_pinmux_info = {
.name = "r8a77965_pfc",
#ifdef CONFIG_PINCTRL_PFC_R8A774B1
const struct sh_pfc_soc_info r8a774b1_pinmux_info = {
.name = "r8a774b1_pfc",
.ops = &r8a77965_pinmux_ops,
.unlock_reg = 0xe6060000, /* PMMR */
@ -6434,10 +6449,10 @@ const struct sh_pfc_soc_info r8a77965_pinmux_info = {
.pins = pinmux_pins,
.nr_pins = ARRAY_SIZE(pinmux_pins),
.groups = pinmux_groups,
.nr_groups = ARRAY_SIZE(pinmux_groups),
.functions = pinmux_functions,
.nr_functions = ARRAY_SIZE(pinmux_functions),
.groups = pinmux_groups.common,
.nr_groups = ARRAY_SIZE(pinmux_groups.common),
.functions = pinmux_functions.common,
.nr_functions = ARRAY_SIZE(pinmux_functions.common),
.cfg_regs = pinmux_config_regs,
.drive_regs = pinmux_drive_regs,
@ -6447,3 +6462,31 @@ const struct sh_pfc_soc_info r8a77965_pinmux_info = {
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
};
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A77965
const struct sh_pfc_soc_info r8a77965_pinmux_info = {
.name = "r8a77965_pfc",
.ops = &r8a77965_pinmux_ops,
.unlock_reg = 0xe6060000, /* PMMR */
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
.pins = pinmux_pins,
.nr_pins = ARRAY_SIZE(pinmux_pins),
.groups = pinmux_groups.common,
.nr_groups = ARRAY_SIZE(pinmux_groups.common) +
ARRAY_SIZE(pinmux_groups.automotive),
.functions = pinmux_functions.common,
.nr_functions = ARRAY_SIZE(pinmux_functions.common) +
ARRAY_SIZE(pinmux_functions.automotive),
.cfg_regs = pinmux_config_regs,
.drive_regs = pinmux_drive_regs,
.bias_regs = pinmux_bias_regs,
.ioctrl_regs = pinmux_ioctrl_regs,
.pinmux_data = pinmux_data,
.pinmux_data_size = ARRAY_SIZE(pinmux_data),
};
#endif

View File

@ -232,8 +232,8 @@
#define IP2_11_8 FM(AVB_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_15_12 FM(BS_N) FM(PWM0_A) FM(AVB_MAGIC) FM(VI4_CLK) F_(0, 0) FM(TX3_C) F_(0, 0) FM(VI5_CLK_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_19_16 FM(RD_N) FM(PWM1_A) FM(AVB_LINK) FM(VI4_FIELD) F_(0, 0) FM(RX3_C) FM(FSCLKST2_N_A) FM(VI5_DATA0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_23_20 FM(RD_WR_N) FM(SCL7_A) FM(AVB_AVTP_MATCH_A) FM(VI4_VSYNC_N) FM(TX5_B) FM(SCK3_C) FM(PWM5_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_27_24 FM(EX_WAIT0) FM(SDA7_A) FM(AVB_AVTP_CAPTURE_A) FM(VI4_HSYNC_N) FM(RX5_B) FM(PWM6_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_23_20 FM(RD_WR_N) FM(SCL7_A) FM(AVB_AVTP_MATCH) FM(VI4_VSYNC_N) FM(TX5_B) FM(SCK3_C) FM(PWM5_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_27_24 FM(EX_WAIT0) FM(SDA7_A) FM(AVB_AVTP_CAPTURE) FM(VI4_HSYNC_N) FM(RX5_B) FM(PWM6_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP2_31_28 FM(A0) FM(IRQ0) FM(PWM2_A) FM(MSIOF3_SS1_B) FM(VI5_CLK_A) FM(DU_CDE) FM(HRX3_D) FM(IERX) FM(QSTB_QHE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP3_3_0 FM(A1) FM(IRQ1) FM(PWM3_A) FM(DU_DOTCLKIN1) FM(VI5_DATA0_A) FM(DU_DISP_CDE) FM(SDA6_B) FM(IETX) FM(QCPV_QDE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP3_7_4 FM(A2) FM(IRQ2) FM(AVB_AVTP_PPS) FM(VI4_CLKENB) FM(VI5_DATA1_A) FM(DU_DISP) FM(SCL6_B) F_(0, 0) FM(QSTVB_QVE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
@ -448,6 +448,8 @@ FM(IP12_31_28) IP12_31_28 FM(IP13_31_28) IP13_31_28 FM(IP14_31_28) IP14_31_28 FM
#define MOD_SEL0_1_0 REV4(FM(SEL_SPEED_PULSE_IF_0), FM(SEL_SPEED_PULSE_IF_1), FM(SEL_SPEED_PULSE_IF_2), F_(0, 0))
/* MOD_SEL1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */
#define MOD_SEL1_31 FM(SEL_SIMCARD_0) FM(SEL_SIMCARD_1)
#define MOD_SEL1_30 FM(SEL_SSI2_0) FM(SEL_SSI2_1)
#define MOD_SEL1_29 FM(SEL_TIMER_TMU_0) FM(SEL_TIMER_TMU_1)
#define MOD_SEL1_28 FM(SEL_USB_20_CH0_0) FM(SEL_USB_20_CH0_1)
#define MOD_SEL1_26 FM(SEL_DRIF2_0) FM(SEL_DRIF2_1)
@ -468,7 +470,8 @@ FM(IP12_31_28) IP12_31_28 FM(IP13_31_28) IP13_31_28 FM(IP14_31_28) IP14_31_28 FM
#define PINMUX_MOD_SELS \
\
MOD_SEL0_30_29 \
MOD_SEL1_31 \
MOD_SEL0_30_29 MOD_SEL1_30 \
MOD_SEL1_29 \
MOD_SEL0_28 MOD_SEL1_28 \
MOD_SEL0_27_26 \
@ -634,7 +637,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_GPSR(IP2_23_20, RD_WR_N),
PINMUX_IPSR_MSEL(IP2_23_20, SCL7_A, SEL_I2C7_0),
PINMUX_IPSR_GPSR(IP2_23_20, AVB_AVTP_MATCH_A),
PINMUX_IPSR_GPSR(IP2_23_20, AVB_AVTP_MATCH),
PINMUX_IPSR_GPSR(IP2_23_20, VI4_VSYNC_N),
PINMUX_IPSR_GPSR(IP2_23_20, TX5_B),
PINMUX_IPSR_MSEL(IP2_23_20, SCK3_C, SEL_SCIF3_2),
@ -642,7 +645,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_GPSR(IP2_27_24, EX_WAIT0),
PINMUX_IPSR_MSEL(IP2_27_24, SDA7_A, SEL_I2C7_0),
PINMUX_IPSR_GPSR(IP2_27_24, AVB_AVTP_CAPTURE_A),
PINMUX_IPSR_GPSR(IP2_27_24, AVB_AVTP_CAPTURE),
PINMUX_IPSR_GPSR(IP2_27_24, VI4_HSYNC_N),
PINMUX_IPSR_MSEL(IP2_27_24, RX5_B, SEL_SCIF5_1),
PINMUX_IPSR_MSEL(IP2_27_24, PWM6_A, SEL_PWM6_0),
@ -1058,7 +1061,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP10_27_24, RIF0_CLK_B, SEL_DRIF0_1),
PINMUX_IPSR_MSEL(IP10_27_24, SCL2_B, SEL_I2C2_1),
PINMUX_IPSR_MSEL(IP10_27_24, TCLK1_A, SEL_TIMER_TMU_0),
PINMUX_IPSR_GPSR(IP10_27_24, SSI_SCK2_B),
PINMUX_IPSR_MSEL(IP10_27_24, SSI_SCK2_B, SEL_SSI2_1),
PINMUX_IPSR_GPSR(IP10_27_24, TS_SCK0),
PINMUX_IPSR_GPSR(IP10_31_28, SD0_WP),
@ -1067,7 +1070,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP10_31_28, RIF0_D0_B, SEL_DRIF0_1),
PINMUX_IPSR_MSEL(IP10_31_28, SDA2_B, SEL_I2C2_1),
PINMUX_IPSR_MSEL(IP10_31_28, TCLK2_A, SEL_TIMER_TMU_0),
PINMUX_IPSR_GPSR(IP10_31_28, SSI_WS2_B),
PINMUX_IPSR_MSEL(IP10_31_28, SSI_WS2_B, SEL_SSI2_1),
PINMUX_IPSR_GPSR(IP10_31_28, TS_SDAT0),
/* IPSR11 */
@ -1085,13 +1088,13 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP11_11_8, RX0_A, SEL_SCIF0_0),
PINMUX_IPSR_MSEL(IP11_11_8, HRX1_A, SEL_HSCIF1_0),
PINMUX_IPSR_GPSR(IP11_11_8, SSI_SCK2_A),
PINMUX_IPSR_MSEL(IP11_11_8, SSI_SCK2_A, SEL_SSI2_0),
PINMUX_IPSR_GPSR(IP11_11_8, RIF1_SYNC),
PINMUX_IPSR_GPSR(IP11_11_8, TS_SCK1),
PINMUX_IPSR_MSEL(IP11_15_12, TX0_A, SEL_SCIF0_0),
PINMUX_IPSR_GPSR(IP11_15_12, HTX1_A),
PINMUX_IPSR_GPSR(IP11_15_12, SSI_WS2_A),
PINMUX_IPSR_MSEL(IP11_15_12, SSI_WS2_A, SEL_SSI2_0),
PINMUX_IPSR_GPSR(IP11_15_12, RIF1_D0),
PINMUX_IPSR_GPSR(IP11_15_12, TS_SDAT1),
@ -1196,7 +1199,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP13_19_16, RIF0_D1_A, SEL_DRIF0_0),
PINMUX_IPSR_MSEL(IP13_19_16, SDA1_B, SEL_I2C1_1),
PINMUX_IPSR_MSEL(IP13_19_16, TCLK2_B, SEL_TIMER_TMU_1),
PINMUX_IPSR_GPSR(IP13_19_16, SIM0_D_A),
PINMUX_IPSR_MSEL(IP13_19_16, SIM0_D_A, SEL_SIMCARD_0),
PINMUX_IPSR_GPSR(IP13_23_20, MLB_DAT),
PINMUX_IPSR_MSEL(IP13_23_20, TX0_B, SEL_SCIF0_1),
@ -1264,7 +1267,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_GPSR(IP15_15_12, TPU0TO2),
PINMUX_IPSR_MSEL(IP15_15_12, SDA1_D, SEL_I2C1_3),
PINMUX_IPSR_MSEL(IP15_15_12, FSO_CFE_1_N_B, SEL_FSO_1),
PINMUX_IPSR_GPSR(IP15_15_12, SIM0_D_B),
PINMUX_IPSR_MSEL(IP15_15_12, SIM0_D_B, SEL_SIMCARD_1),
PINMUX_IPSR_GPSR(IP15_19_16, SSI_SDATA6),
PINMUX_IPSR_MSEL(IP15_19_16, HRTS2_N_A, SEL_HSCIF2_0),
@ -1524,22 +1527,22 @@ static const unsigned int avb_avtp_pps_mux[] = {
AVB_AVTP_PPS_MARK,
};
static const unsigned int avb_avtp_match_a_pins[] = {
/* AVB_AVTP_MATCH_A */
static const unsigned int avb_avtp_match_pins[] = {
/* AVB_AVTP_MATCH */
RCAR_GP_PIN(2, 24),
};
static const unsigned int avb_avtp_match_a_mux[] = {
AVB_AVTP_MATCH_A_MARK,
static const unsigned int avb_avtp_match_mux[] = {
AVB_AVTP_MATCH_MARK,
};
static const unsigned int avb_avtp_capture_a_pins[] = {
/* AVB_AVTP_CAPTURE_A */
static const unsigned int avb_avtp_capture_pins[] = {
/* AVB_AVTP_CAPTURE */
RCAR_GP_PIN(2, 25),
};
static const unsigned int avb_avtp_capture_a_mux[] = {
AVB_AVTP_CAPTURE_A_MARK,
static const unsigned int avb_avtp_capture_mux[] = {
AVB_AVTP_CAPTURE_MARK,
};
/* - CAN ------------------------------------------------------------------ */
@ -3784,8 +3787,8 @@ static const struct {
SH_PFC_PIN_GROUP(avb_phy_int),
SH_PFC_PIN_GROUP(avb_mii),
SH_PFC_PIN_GROUP(avb_avtp_pps),
SH_PFC_PIN_GROUP(avb_avtp_match_a),
SH_PFC_PIN_GROUP(avb_avtp_capture_a),
SH_PFC_PIN_GROUP(avb_avtp_match),
SH_PFC_PIN_GROUP(avb_avtp_capture),
SH_PFC_PIN_GROUP(can0_data),
SH_PFC_PIN_GROUP(can1_data),
SH_PFC_PIN_GROUP(can_clk),
@ -4061,8 +4064,8 @@ static const char * const avb_groups[] = {
"avb_phy_int",
"avb_mii",
"avb_avtp_pps",
"avb_avtp_match_a",
"avb_avtp_capture_a",
"avb_avtp_match",
"avb_avtp_capture",
};
static const char * const can0_groups[] = {
@ -4957,11 +4960,11 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
MOD_SEL0_1_0 ))
},
{ PINMUX_CFG_REG_VAR("MOD_SEL1", 0xe6060504, 32,
GROUP(2, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1,
2, 2, 2, 1, 1, 2, 1, 4),
GROUP(1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1,
1, 2, 2, 2, 1, 1, 2, 1, 4),
GROUP(
/* RESERVED 31, 30 */
0, 0, 0, 0,
MOD_SEL1_31
MOD_SEL1_30
MOD_SEL1_29
MOD_SEL1_28
/* RESERVED 27 */

View File

@ -1450,7 +1450,7 @@ static const struct pinmux_func pinmux_func_gpios[] = {
GPIO_FN(ET0_ETXD2_A),
GPIO_FN(EX_CS5), GPIO_FN(SD1_CMD_A), GPIO_FN(ATADIR), GPIO_FN(QSSL_B),
GPIO_FN(ET0_ETXD3_A),
GPIO_FN(RD_WR), GPIO_FN(TCLK1_B),
GPIO_FN(RD_WR), GPIO_FN(TCLK0), GPIO_FN(CAN_CLK_B), GPIO_FN(ET0_ETXD4),
GPIO_FN(EX_WAIT0), GPIO_FN(TCLK1_B),
GPIO_FN(EX_WAIT1), GPIO_FN(SD1_DAT0_A), GPIO_FN(DREQ2),
GPIO_FN(CAN1_TX_C), GPIO_FN(ET0_LINK_C), GPIO_FN(ET0_ETXD5_A),
@ -1949,7 +1949,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
/* IP3_20 [1] */
FN_EX_WAIT0, FN_TCLK1_B,
/* IP3_19_18 [2] */
FN_RD_WR, FN_TCLK1_B, 0, 0,
FN_RD_WR, FN_TCLK0, FN_CAN_CLK_B, FN_ET0_ETXD4,
/* IP3_17_15 [3] */
FN_EX_CS5, FN_SD1_CMD_A, FN_ATADIR, FN_QSSL_B,
FN_ET0_ETXD3_A, 0, 0, 0,

View File

@ -309,6 +309,7 @@ extern const struct sh_pfc_soc_info r8a7744_pinmux_info;
extern const struct sh_pfc_soc_info r8a7745_pinmux_info;
extern const struct sh_pfc_soc_info r8a77470_pinmux_info;
extern const struct sh_pfc_soc_info r8a774a1_pinmux_info;
extern const struct sh_pfc_soc_info r8a774b1_pinmux_info;
extern const struct sh_pfc_soc_info r8a774c0_pinmux_info;
extern const struct sh_pfc_soc_info r8a7778_pinmux_info;
extern const struct sh_pfc_soc_info r8a7779_pinmux_info;
@ -319,7 +320,8 @@ extern const struct sh_pfc_soc_info r8a7793_pinmux_info;
extern const struct sh_pfc_soc_info r8a7794_pinmux_info;
extern const struct sh_pfc_soc_info r8a7795_pinmux_info;
extern const struct sh_pfc_soc_info r8a7795es1_pinmux_info;
extern const struct sh_pfc_soc_info r8a7796_pinmux_info;
extern const struct sh_pfc_soc_info r8a77960_pinmux_info;
extern const struct sh_pfc_soc_info r8a77961_pinmux_info;
extern const struct sh_pfc_soc_info r8a77965_pinmux_info;
extern const struct sh_pfc_soc_info r8a77970_pinmux_info;
extern const struct sh_pfc_soc_info r8a77980_pinmux_info;
@ -422,12 +424,12 @@ extern const struct sh_pfc_soc_info shx3_pinmux_info;
/*
* Describe a pinmux configuration in which a pin is physically multiplexed
* with other pins.
* - ipsr: IPSR field (unused, for documentation purposes only)
* - ipsr: IPSR field
* - fn: Function name
* - psel: Physical multiplexing selector
*/
#define PINMUX_IPSR_PHYS(ipsr, fn, psel) \
PINMUX_DATA(fn##_MARK, FN_##psel)
PINMUX_DATA(fn##_MARK, FN_##psel, FN_##ipsr)
/*
* Describe a pinmux configuration for a single-function pin with GPIO

View File

@ -5996,6 +5996,7 @@ static int atlas7_gpio_probe(struct platform_device *pdev)
struct gpio_chip *chip;
u32 nbank;
int ret, idx;
struct gpio_irq_chip *girq;
ret = of_property_read_u32(np, "gpio-banks", &nbank);
if (ret) {
@ -6048,24 +6049,15 @@ static int atlas7_gpio_probe(struct platform_device *pdev)
chip->of_gpio_n_cells = 2;
chip->parent = &pdev->dev;
/* Add gpio chip to system */
ret = gpiochip_add_data(chip, a7gc);
if (ret) {
dev_err(&pdev->dev,
"%pOF: error in probe function with status %d\n",
np, ret);
goto failed;
}
/* Add gpio chip to irq subsystem */
ret = gpiochip_irqchip_add(chip, &atlas7_gpio_irq_chip,
0, handle_level_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(&pdev->dev,
"could not connect irqchip to gpiochip\n");
goto failed;
}
girq = &chip->irq;
girq->chip = &atlas7_gpio_irq_chip;
girq->parent_handler = atlas7_gpio_handle_irq;
girq->num_parents = nbank;
girq->parents = devm_kcalloc(&pdev->dev, nbank,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
for (idx = 0; idx < nbank; idx++) {
struct atlas7_gpio_bank *bank;
@ -6084,9 +6076,18 @@ static int atlas7_gpio_probe(struct platform_device *pdev)
goto failed;
}
bank->irq = ret;
girq->parents[idx] = ret;
}
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
gpiochip_set_chained_irqchip(chip, &atlas7_gpio_irq_chip,
bank->irq, atlas7_gpio_handle_irq);
/* Add gpio chip to system */
ret = gpiochip_add_data(chip, a7gc);
if (ret) {
dev_err(&pdev->dev,
"%pOF: error in probe function with status %d\n",
np, ret);
goto failed;
}
platform_set_drvdata(pdev, a7gc);

View File

@ -785,6 +785,7 @@ static int sirfsoc_gpio_probe(struct device_node *np)
struct sirfsoc_gpio_bank *bank;
void __iomem *regs;
struct platform_device *pdev;
struct gpio_irq_chip *girq;
u32 pullups[SIRFSOC_GPIO_NO_OF_BANKS], pulldowns[SIRFSOC_GPIO_NO_OF_BANKS];
@ -816,36 +817,33 @@ static int sirfsoc_gpio_probe(struct device_node *np)
sgpio->chip.gc.parent = &pdev->dev;
sgpio->chip.regs = regs;
err = gpiochip_add_data(&sgpio->chip.gc, sgpio);
if (err) {
dev_err(&pdev->dev, "%pOF: error in probe function with status %d\n",
np, err);
goto out;
}
err = gpiochip_irqchip_add(&sgpio->chip.gc,
&sirfsoc_irq_chip,
0, handle_level_irq,
IRQ_TYPE_NONE);
if (err) {
dev_err(&pdev->dev,
"could not connect irqchip to gpiochip\n");
goto out_banks;
}
girq = &sgpio->chip.gc.irq;
girq->chip = &sirfsoc_irq_chip;
girq->parent_handler = sirfsoc_gpio_handle_irq;
girq->num_parents = SIRFSOC_GPIO_NO_OF_BANKS;
girq->parents = devm_kcalloc(&pdev->dev, SIRFSOC_GPIO_NO_OF_BANKS,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
bank = &sgpio->sgpio_bank[i];
spin_lock_init(&bank->lock);
bank->parent_irq = platform_get_irq(pdev, i);
if (bank->parent_irq < 0) {
err = bank->parent_irq;
goto out_banks;
goto out;
}
girq->parents[i] = bank->parent_irq;
}
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
gpiochip_set_chained_irqchip(&sgpio->chip.gc,
&sirfsoc_irq_chip,
bank->parent_irq,
sirfsoc_gpio_handle_irq);
err = gpiochip_add_data(&sgpio->chip.gc, sgpio);
if (err) {
dev_err(&pdev->dev, "%pOF: error in probe function with status %d\n",
np, err);
goto out;
}
err = gpiochip_add_pin_range(&sgpio->chip.gc, dev_name(&pdev->dev),
@ -867,7 +865,6 @@ static int sirfsoc_gpio_probe(struct device_node *np)
return 0;
out_no_range:
out_banks:
gpiochip_remove(&sgpio->chip.gc);
out:
iounmap(regs);

Some files were not shown because too many files have changed in this diff Show More