This is the bulk of pin control changes for the v4.12 cycle:

Core changes:
 
 - Add bi-directional and output-enable pin configurations to
   the generic bindings and generic pin controlling core.
 
 New drivers or subdrivers:
 
 - Armada 37xx SoC pin controller and GPIO support.
 
 - Axis ARTPEC-6 SoC pin controller support.
 
 - AllWinner A64 R_PIO controller support, and opening up the
   AllWinner sunxi driver for ARM64 use.
 
 - Rockchip RK3328 support.
 
 - Renesas R-Car H3 ES2.0 support.
 
 - STM32F469 support in the STM32 driver.
 
 - Aspeed G4 and G5 pin controller support.
 
 Improvements:
 
 - A whole slew of realtime improvements to drivers implementing
   irqchips: BCM, AMD, SiRF, sunxi, rockchip.
 
 - Switch meson driver to get the GPIO ranges from the device
   tree.
 
 - Input schmitt trigger support on the Rockchip driver.
 
 - Enable the sunxi (AllWinner) driver to also be used on ARM64
   silicon.
 
 - Name the Qualcomm QDF2xxx GPIO lines.
 
 - Support GMMR GPIO regions on the Intel Cherryview. This
   fixes a serialization problem on these platforms.
 
 - Pad retention support for the Samsung Exynos 5433.
 
 - Handle suspend-to-ram in the AT91-pio4 driver.
 
 - Pin configuration support in the Aspeed driver.
 
 Cleanups:
 
 - The final name of Rockchip RK1108 was RV1108 so rename the
   driver and variables to stay consistent.
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJZCG0aAAoJEEEQszewGV1zBpcP/37y0m2ZFIqVJrqlPKVeZbRa
 aYwsbY3l9OGeocLXSRWaqLJkwJ+WaG8ascoXHLMgk4jFC2CutwUea0fzhy9Li2VO
 Sqd/BN9iNd/g2lTf8o37NM5qYF5IvStZu12DzFPRFpec6pEiYOHVmRiSlIK5lREG
 v/NGNAIzLPH59jRHA17sLT1lkHmiT43S4Gm38nvpar8vfO+2UkAwGVPQPC8dGuL9
 gydMLLtx3d1SzWqicbMSICa/F7kjWz5I4jL6KM7ohVGXgDn8tdZk+7rERfBD9qoR
 eDNPZvXajaC6y3S3h6Ynv094X30w3VA0xtj9kPVhJsS1yUlVli5GlC3WHPArwrRQ
 sXx29UsdTmAjzHHns4OZfxKnEVvHbXtW1XmX+ks248f/k8hCVWpQA9ZENvVHjLvu
 NkDwXOmTWOxjutDveZqm7RM6z+99+lRgzLgwB3GMENIUC8ohH79W/R9GYHvrqOZI
 hWX+G/q3nnnW3cIPc15rN2MC3fkjE2mdFC0N+/kDlKtzPabCS8U6JZsfQDulX5m1
 I2xF2DY+1WWCy1mMDpyTdYNDlkOGU8j/N5MXx9z1629m+vjg0KZo35+mGwJh5mA1
 gQ6rI3DdhS5qVK2Gj/joYkwQ1cKpdEtljlpI9A+WdXx1eO7RKVK1m1fxbd8c47L/
 I0qdXsL66ZtiKDOIDPau
 =BCaA
 -----END PGP SIGNATURE-----

Merge tag 'pinctrl-v4.12-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 the v4.12 cycle.

  The extra week before the merge window actually resulted in some of
  the type of fixes that usually arrive after the merge window already
  starting to trickle in from eager developers using -next, I'm
  impressed.

  I have recruited a Samsung subsubsystem maintainer (Krzysztof) to deal
  with the onset of Samsung patches. It works great.

  Apart from that it is a boring round, just incremental updates and
  fixes all over the place, no serious core changes or anything exciting
  like that. The most pleasing to see is Julia Cartwrights work to audit
  the irqchip-providing drivers for realtime locking compliance. It's
  one of those "I should really get around to looking into that" things
  that have been on my TODO list since forever.

  Summary:

  Core changes:

   - add bi-directional and output-enable pin configurations to the
     generic bindings and generic pin controlling core.

  New drivers or subdrivers:

   - Armada 37xx SoC pin controller and GPIO support.

   - Axis ARTPEC-6 SoC pin controller support.

   - AllWinner A64 R_PIO controller support, and opening up the
     AllWinner sunxi driver for ARM64 use.

   - Rockchip RK3328 support.

   - Renesas R-Car H3 ES2.0 support.

   - STM32F469 support in the STM32 driver.

   - Aspeed G4 and G5 pin controller support.

  Improvements:

   - a whole slew of realtime improvements to drivers implementing
     irqchips: BCM, AMD, SiRF, sunxi, rockchip.

   - switch meson driver to get the GPIO ranges from the device tree.

   - input schmitt trigger support on the Rockchip driver.

   - enable the sunxi (AllWinner) driver to also be used on ARM64
     silicon.

   - name the Qualcomm QDF2xxx GPIO lines.

   - support GMMR GPIO regions on the Intel Cherryview. This fixes a
     serialization problem on these platforms.

   - pad retention support for the Samsung Exynos 5433.

   - handle suspend-to-ram in the AT91-pio4 driver.

   - pin configuration support in the Aspeed driver.

  Cleanups:

   - the final name of Rockchip RK1108 was RV1108 so rename the driver
     and variables to stay consistent"

* tag 'pinctrl-v4.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (80 commits)
  pinctrl: mediatek: Add missing pinctrl bindings for mt7623
  pinctrl: artpec6: Fix return value check in artpec6_pmx_probe()
  pinctrl: artpec6: Remove .owner field for driver
  pinctrl: tegra: xusb: Silence sparse warnings
  ARM: at91/at91-pinctrl documentation: fix spelling mistake: "contoller" -> "controller"
  pinctrl: make artpec6 explicitly non-modular
  pinctrl: aspeed: g5: Add pinconf support
  pinctrl: aspeed: g4: Add pinconf support
  pinctrl: aspeed: Add core pinconf support
  pinctrl: aspeed: Document pinconf in devicetree bindings
  pinctrl: Add st,stm32f469-pinctrl compatible to stm32-pinctrl
  pinctrl: stm32: Add STM32F469 MCU support
  Documentation: dt: Remove ngpios from stm32-pinctrl binding
  pinctrl: stm32: replace device_initcall() with arch_initcall()
  pinctrl: stm32: add possibility to use gpio-ranges to declare bank range
  pinctrl: armada-37xx: Add gpio support
  pinctrl: armada-37xx: Add pin controller support for Armada 37xx
  pinctrl: dt-bindings: Add documentation for Armada 37xx pin controllers
  pinctrl: core: Make pinctrl_init_controller() static
  pinctrl: generic: Add bi-directional and output-enable
  ...
This commit is contained in:
Linus Torvalds 2017-05-02 17:59:33 -07:00
commit 68fed41e0f
73 changed files with 11810 additions and 3900 deletions

View File

@ -5,6 +5,7 @@ reading the gpio latch register.
This node must be a subnode of the node exposing the register address
of the GPIO block where the gpio latch is located.
See Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt
Required properties:
- compatible : shall be one of the following:
@ -16,9 +17,9 @@ Optional properties:
output names ("xtal")
Example:
gpio1: gpio@13800 {
compatible = "marvell,armada-3700-gpio", "syscon", "simple-mfd";
reg = <0x13800 0x1000>;
pinctrl_nb: pinctrl-nb@13800 {
compatible = "armada3710-nb-pinctrl", "syscon", "simple-mfd";
reg = <0x13800 0x100>, <0x13C00 0x20>;
xtalclk: xtal-clk {
compatible = "marvell,armada-3700-xtal-clock";

View File

@ -23,7 +23,8 @@ Required properties:
"allwinner,sun8i-h3-pinctrl"
"allwinner,sun8i-h3-r-pinctrl"
"allwinner,sun50i-a64-pinctrl"
"allwinner,sun50i-h5-r-pinctrl"
"allwinner,sun50i-a64-r-pinctrl"
"allwinner,sun50i-h5-pinctrl"
"nextthing,gr8-pinctrl"
- reg: Should contain the register physical address and length for the

View File

@ -4,7 +4,7 @@ The AT91 Pinmux Controller, enables the IC
to share one PAD to several functional blocks. The sharing is done by
multiplexing the PAD input/output signals. For each PAD there are up to
8 muxing options (called periph modes). Since different modules require
different PAD settings (like pull up, keeper, etc) the contoller controls
different PAD settings (like pull up, keeper, etc) the controller controls
also the PAD settings parameters.
Please refer to pinctrl-bindings.txt in this directory for details of the

View File

@ -0,0 +1,85 @@
Axis ARTPEC-6 Pin Controller
Required properties:
- compatible: "axis,artpec6-pinctrl".
- reg: Should contain the register physical address and length for the pin
controller.
A pinctrl node should contain at least one subnode representing the pinctrl
groups available on the machine. Each subnode will list the mux function
required and what pin group it will use. Each subnode will also configure the
drive strength and bias pullup of the pin group. If either of these options is
not set, its actual value will be unspecified.
Required subnode-properties:
- function: Function to mux.
- groups: Name of the pin group to use for the function above.
Available functions and groups (function: group0, group1...):
gpio: cpuclkoutgrp0, udlclkoutgrp0, i2c1grp0, i2c2grp0,
i2c3grp0, i2s0grp0, i2s1grp0, i2srefclkgrp0, spi0grp0,
spi1grp0, pciedebuggrp0, uart0grp0, uart0grp1, uart1grp0,
uart2grp0, uart2grp1, uart3grp0, uart4grp0, uart5grp0
cpuclkout: cpuclkoutgrp0
udlclkout: udlclkoutgrp0
i2c1: i2c1grp0
i2c2: i2c2grp0
i2c3: i2c3grp0
i2s0: i2s0grp0
i2s1: i2s1grp0
i2srefclk: i2srefclkgrp0
spi0: spi0grp0
spi1: spi1grp0
pciedebug: pciedebuggrp0
uart0: uart0grp0, uart0grp1
uart1: uart1grp0
uart2: uart2grp0, uart2grp1
uart3: uart3grp0
uart4: uart4grp0
uart5: uart5grp0
nand: nandgrp0
sdio0: sdio0grp0
sdio1: sdio1grp0
ethernet: ethernetgrp0
Optional subnode-properties (see pinctrl-bindings.txt):
- drive-strength: 4, 6, 8, 9 mA. For SD and NAND pins, this is for 3.3V VCCQ3.
- bias-pull-up
- bias-disable
Examples:
pinctrl@f801d000 {
compatible = "axis,artpec6-pinctrl";
reg = <0xf801d000 0x400>;
pinctrl_uart0: uart0grp {
function = "uart0";
groups = "uart0grp0";
drive-strength = <4>;
bias-pull-up;
};
pinctrl_uart3: uart3grp {
function = "uart3";
groups = "uart3grp0";
};
};
uart0: uart@f8036000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0xf8036000 0x1000>;
interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&pll2div24>, <&apb_pclk>;
clock-names = "uart_clk", "apb_pclk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart0>;
};
uart3: uart@f8039000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0xf8039000 0x1000>;
interrupts = <0 128 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&pll2div24>, <&apb_pclk>;
clock-names = "uart_clk", "apb_pclk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
};

View File

@ -0,0 +1,183 @@
* Marvell Armada 37xx SoC pin and gpio controller
Each Armada 37xx SoC come with two pin and gpio controller one for the
south bridge and the other for the north bridge.
Inside this set of register the gpio latch allows exposing some
configuration of the SoC and especially the clock frequency of the
xtal. Hence, this node is a represent as syscon allowing sharing the
register between multiple hardware block.
GPIO and pin controller:
------------------------
Main node:
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".
Required properties for pinctrl driver:
- compatible: "marvell,armada3710-sb-pinctrl", "syscon, "simple-mfd"
for the south bridge
"marvell,armada3710-nb-pinctrl", "syscon, "simple-mfd"
for the north bridge
- reg: The first set of register are for pinctrl/gpio and the second
set for the interrupt controller
- interrupts: list of the interrupt use by the gpio
Available groups and functions for the North bridge:
group: jtag
- pins 20-24
- functions jtag, gpio
group sdio0
- pins 8-10
- functions sdio, gpio
group emmc_nb
- pins 27-35
- functions emmc, gpio
group pwm0
- pin 11 (GPIO1-11)
- functions pwm, gpio
group pwm1
- pin 12
- functions pwm, gpio
group pwm2
- pin 13
- functions pwm, gpio
group pwm3
- pin 14
- functions pwm, gpio
group pmic1
- pin 17
- functions pmic, gpio
group pmic0
- pin 16
- functions pmic, gpio
group i2c2
- pins 2-3
- functions i2c, gpio
group i2c1
- pins 0-1
- functions i2c, gpio
group spi_cs1
- pin 17
- functions spi, gpio
group spi_cs2
- pin 18
- functions spi, gpio
group spi_cs3
- pin 19
- functions spi, gpio
group onewire
- pin 4
- functions onewire, gpio
group uart1
- pins 25-26
- functions uart, gpio
group spi_quad
- pins 15-16
- functions spi, gpio
group uart_2
- pins 9-10
- functions uart, gpio
Available groups and functions for the South bridge:
group usb32_drvvbus0
- pin 36
- functions drvbus, gpio
group usb2_drvvbus1
- pin 37
- functions drvbus, gpio
group sdio_sb
- pins 60-64
- functions sdio, gpio
group rgmii
- pins 42-55
- functions mii, gpio
group pcie1
- pins 39-40
- functions pcie, gpio
group ptp
- pins 56-58
- functions ptp, gpio
group ptp_clk
- pin 57
- functions ptp, mii
group ptp_trig
- pin 58
- functions ptp, mii
group mii_col
- pin 59
- functions mii, mii_err
GPIO subnode:
Please refer to gpio.txt in this directory for details of gpio-ranges property
and the common GPIO bindings used by client devices.
Required properties for gpio driver under the gpio subnode:
- interrupts: List of interrupt specifier for the controllers interrupt.
- gpio-controller: Marks the device node as a gpio controller.
- #gpio-cells: Should be 2. The first cell is the GPIO number and the
second cell specifies GPIO flags, as defined in
<dt-bindings/gpio/gpio.h>. Only the GPIO_ACTIVE_HIGH and
GPIO_ACTIVE_LOW flags are supported.
- gpio-ranges: Range of pins managed by the GPIO controller.
Xtal Clock bindings for Marvell Armada 37xx SoCs
------------------------------------------------
see Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt
Example:
pinctrl_sb: pinctrl-sb@18800 {
compatible = "marvell,armada3710-sb-pinctrl", "syscon", "simple-mfd";
reg = <0x18800 0x100>, <0x18C00 0x20>;
gpio {
#gpio-cells = <2>;
gpio-ranges = <&pinctrl_sb 0 0 29>;
gpio-controller;
interrupts =
<GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
};
rgmii_pins: mii-pins {
groups = "rgmii";
function = "mii";
};
};

View File

@ -34,13 +34,28 @@ Documentation/devicetree/bindings/mfd/syscon.txt
Subnode Format
==============
The required properties of child nodes are (as defined in pinctrl-bindings):
- function
- groups
The required properties of pinmux child nodes are:
- function: the mux function to select
- groups : the list of groups to select with this function
Each function has only one associated pin group. Each group is named by its
function. The following values for the function and groups properties are
supported:
Required properties of pinconf child nodes are:
- groups: A list of groups to select (either this or "pins" must be
specified)
- pins : A list of ball names as strings, eg "D14" (either this or "groups"
must be specified)
Optional properties of pinconf child nodes are:
- bias-disable : disable any pin bias
- bias-pull-down: pull down the pin
- drive-strength: sink or source at most X mA
Definitions are as specified in
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt, with any
further limitations as described above.
For pinmux, each mux function has only one associated pin group. Each group is
named by its function. The following values for the function and groups
properties are supported:
aspeed,ast2400-pinctrl, aspeed,g4-pinctrl:
@ -90,6 +105,11 @@ syscon: scu@1e6e2000 {
function = "I2C3";
groups = "I2C3";
};
pinctrl_gpioh0_unbiased_default: gpioh0 {
pins = "A8";
bias-disable;
};
};
};
@ -110,6 +130,11 @@ ahb {
function = "I2C3";
groups = "I2C3";
};
pinctrl_gpioh0_unbiased_default: gpioh0 {
pins = "A18";
bias-disable;
};
};
};
@ -143,6 +168,3 @@ ahb {
};
};
};
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices.

View File

@ -162,8 +162,8 @@ state_2_node_a {
pins = "mfio29", "mfio30";
};
Optionally an altenative binding can be used if more suitable depending on the
pin controller hardware. For hardaware where there is a large number of identical
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.
@ -198,6 +198,28 @@ 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 packed with mux configuration settings
in a single integer.
The pinmux property accepts an array of integers, each of them describing
a single pin multiplexing configuration.
pincontroller {
state_0_node_a {
pinmux = <PIN_ID_AND_MUX>, <PIN_ID_AND_MUX>, ...;
};
};
Each individual pin controller driver bindings documentation shall specify
how those values (pin IDs and pin multiplexing configuration) are defined and
assembled together.
== Generic pin configuration node content ==
Many data items that are represented in a pin configuration node are common
@ -210,18 +232,22 @@ 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 or "group" has to be
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 or "pins" has to be
specified)
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
bi-directional - pin supports simultaneous input/output operations
drive-push-pull - drive actively high and low
drive-open-drain - drive with open drain
drive-open-source - drive with open source
@ -234,6 +260,7 @@ 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-enable - enable output on pin regardless of output value
output-low - set the pin to output mode with low level
output-high - set the pin to output mode with high level
slew-rate - set the slew rate
@ -258,6 +285,12 @@ state_2_node_a {
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.
@ -266,6 +299,11 @@ arguments are described below.
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.
- 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.

View File

@ -19,11 +19,18 @@ The pins are grouped into up to 5 individual pin banks which need to be
defined as gpio sub-nodes of the pinmux controller.
Required properties for iomux controller:
- compatible: one of "rockchip,rk1108-pinctrl", "rockchip,rk2928-pinctrl"
"rockchip,rk3066a-pinctrl", "rockchip,rk3066b-pinctrl"
"rockchip,rk3188-pinctrl", "rockchip,rk3228-pinctrl"
"rockchip,rk3288-pinctrl", "rockchip,rk3368-pinctrl"
"rockchip,rk3399-pinctrl"
- compatible: should be
"rockchip,rv1108-pinctrl": for Rockchip RV1108
"rockchip,rk2928-pinctrl": for Rockchip RK2928
"rockchip,rk3066a-pinctrl": for Rockchip RK3066a
"rockchip,rk3066b-pinctrl": for Rockchip RK3066b
"rockchip,rk3188-pinctrl": for Rockchip RK3188
"rockchip,rk3228-pinctrl": for Rockchip RK3228
"rockchip,rk3288-pinctrl": for Rockchip RK3288
"rockchip,rk3328-pinctrl": for Rockchip RK3328
"rockchip,rk3368-pinctrl": for Rockchip RK3368
"rockchip,rk3399-pinctrl": for Rockchip RK3399
- rockchip,grf: phandle referencing a syscon providing the
"general register files"

View File

@ -9,6 +9,7 @@ Pin controller node:
Required properies:
- compatible: value should be one of the following:
"st,stm32f429-pinctrl"
"st,stm32f469-pinctrl"
"st,stm32f746-pinctrl"
"st,stm32h743-pinctrl"
- #address-cells: The value of this property must be 1
@ -38,8 +39,6 @@ Optional properties:
- st,syscfg: Should be phandle/offset pair. The phandle to the syscon node
which includes IRQ mux selection register, and the offset of the IRQ mux
selection register.
- ngpios: Number of gpios in a bank (to use if bank gpio numbers is less
than 16).
- gpio-ranges: Define a dedicated mapping between a pin-controller and
a gpio controller. Format is <&phandle a b c> with:
-(phandle): phandle of pin-controller.

View File

@ -1095,6 +1095,8 @@ L: linux-arm-kernel@axis.com
F: arch/arm/mach-artpec
F: arch/arm/boot/dts/artpec6*
F: drivers/clk/axis
F: drivers/pinctrl/pinctrl-artpec*
F: Documentation/devicetree/bindings/pinctrl/axis,artpec6-pinctrl.txt
ARM/ASPEED MACHINE SUPPORT
M: Joel Stanley <joel@jms.id.au>
@ -9973,6 +9975,8 @@ M: Krzysztof Kozlowski <krzk@kernel.org>
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
S: Maintained
F: drivers/pinctrl/samsung/
F: include/dt-bindings/pinctrl/samsung.h

View File

@ -222,7 +222,7 @@
};
pinctrl: pinctrl {
compatible = "rockchip,rk1108-pinctrl";
compatible = "rockchip,rv1108-pinctrl";
rockchip,grf = <&grf>;
rockchip,pmu = <&pmugrf>;
#address-cells = <1>;

View File

@ -41,6 +41,17 @@ config PINCTRL_ADI2
future processors. This option is selected automatically when specific
machine and arch are selected to build.
config PINCTRL_ARTPEC6
bool "Axis ARTPEC-6 pin controller driver"
depends on MACH_ARTPEC6
select PINMUX
select GENERIC_PINCONF
help
This is the driver for the Axis ARTPEC-6 pin controller. This driver
supports pin function multiplexing as well as pin bias and drive
strength configuration. Device tree integration instructions can be
found in Documentation/devicetree/bindings/pinctrl/axis,artpec6-pinctrl.txt
config PINCTRL_AS3722
tristate "Pinctrl and GPIO driver for ams AS3722 PMIC"
depends on MFD_AS3722 && GPIOLIB

View File

@ -8,6 +8,7 @@ obj-$(CONFIG_PINCONF) += pinconf.o
obj-$(CONFIG_OF) += devicetree.o
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_PINCTRL_ADI2) += pinctrl-adi2.o
obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl-artpec6.o
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o
obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
@ -44,7 +45,7 @@ obj-y += bcm/
obj-$(CONFIG_PINCTRL_BERLIN) += berlin/
obj-y += freescale/
obj-$(CONFIG_X86) += intel/
obj-$(CONFIG_PINCTRL_MVEBU) += mvebu/
obj-y += mvebu/
obj-y += nomadik/
obj-$(CONFIG_PINCTRL_PXA) += pxa/
obj-$(CONFIG_ARCH_QCOM) += qcom/

View File

@ -856,8 +856,8 @@ SIG_EXPR_DECL(VPIG3, VPI18, VPI18_DESC, AB1_DESC);
SIG_EXPR_DECL(VPIG3, VPI24, VPI24_DESC, AB1_DESC);
SIG_EXPR_DECL(VPIG3, VPI30, VPI30_DESC, AB1_DESC);
SIG_EXPR_LIST_DECL(VPIG3, SIG_EXPR_PTR(VPIG3, VPI18),
SIG_EXPR_PTR(VPIG2, VPI24),
SIG_EXPR_PTR(VPIG2, VPI30));
SIG_EXPR_PTR(VPIG3, VPI24),
SIG_EXPR_PTR(VPIG3, VPI30));
SIG_EXPR_LIST_DECL_SINGLE(PWM3, PWM3, AB1_DESC);
MS_PIN_DECL(AB1, GPION3, VPIG3, PWM3);
FUNC_GROUP_DECL(PWM3, AB1);
@ -868,8 +868,8 @@ SIG_EXPR_DECL(VPIG4, VPI18, VPI18_DESC, W5_DESC);
SIG_EXPR_DECL(VPIG4, VPI24, VPI24_DESC, W5_DESC);
SIG_EXPR_DECL(VPIG4, VPI30, VPI30_DESC, W5_DESC);
SIG_EXPR_LIST_DECL(VPIG4, SIG_EXPR_PTR(VPIG4, VPI18),
SIG_EXPR_PTR(VPIG2, VPI24),
SIG_EXPR_PTR(VPIG2, VPI30));
SIG_EXPR_PTR(VPIG4, VPI24),
SIG_EXPR_PTR(VPIG4, VPI30));
SIG_EXPR_LIST_DECL_SINGLE(PWM4, PWM4, W5_DESC);
MS_PIN_DECL(W5, GPION4, VPIG4, PWM4);
FUNC_GROUP_DECL(PWM4, W5);
@ -880,8 +880,8 @@ SIG_EXPR_DECL(VPIG5, VPI18, VPI18_DESC, Y4_DESC);
SIG_EXPR_DECL(VPIG5, VPI24, VPI24_DESC, Y4_DESC);
SIG_EXPR_DECL(VPIG5, VPI30, VPI30_DESC, Y4_DESC);
SIG_EXPR_LIST_DECL(VPIG5, SIG_EXPR_PTR(VPIG5, VPI18),
SIG_EXPR_PTR(VPIG2, VPI24),
SIG_EXPR_PTR(VPIG2, VPI30));
SIG_EXPR_PTR(VPIG5, VPI24),
SIG_EXPR_PTR(VPIG5, VPI30));
SIG_EXPR_LIST_DECL_SINGLE(PWM5, PWM5, Y4_DESC);
MS_PIN_DECL(Y4, GPION5, VPIG5, PWM5);
FUNC_GROUP_DECL(PWM5, Y4);
@ -2234,6 +2234,110 @@ static const struct aspeed_pin_function aspeed_g4_functions[] = {
ASPEED_PINCTRL_FUNC(WDTRST2),
};
static const struct aspeed_pin_config aspeed_g4_configs[] = {
/* GPIO banks ranges [A, B], [D, J], [M, R] */
{ PIN_CONFIG_BIAS_PULL_DOWN, { D6, D5 }, SCU8C, 16 },
{ PIN_CONFIG_BIAS_DISABLE, { D6, D5 }, SCU8C, 16 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { J21, E18 }, SCU8C, 17 },
{ PIN_CONFIG_BIAS_DISABLE, { J21, E18 }, SCU8C, 17 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { A18, E15 }, SCU8C, 19 },
{ PIN_CONFIG_BIAS_DISABLE, { A18, E15 }, SCU8C, 19 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { D15, B14 }, SCU8C, 20 },
{ PIN_CONFIG_BIAS_DISABLE, { D15, B14 }, SCU8C, 20 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { D18, C17 }, SCU8C, 21 },
{ PIN_CONFIG_BIAS_DISABLE, { D18, C17 }, SCU8C, 21 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { A14, U18 }, SCU8C, 22 },
{ PIN_CONFIG_BIAS_DISABLE, { A14, U18 }, SCU8C, 22 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { A8, E7 }, SCU8C, 23 },
{ PIN_CONFIG_BIAS_DISABLE, { A8, E7 }, SCU8C, 23 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { C22, E20 }, SCU8C, 24 },
{ PIN_CONFIG_BIAS_DISABLE, { C22, E20 }, SCU8C, 24 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { J5, T1 }, SCU8C, 25 },
{ PIN_CONFIG_BIAS_DISABLE, { J5, T1 }, SCU8C, 25 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { U1, U5 }, SCU8C, 26 },
{ PIN_CONFIG_BIAS_DISABLE, { U1, U5 }, SCU8C, 26 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { V3, V5 }, SCU8C, 27 },
{ PIN_CONFIG_BIAS_DISABLE, { V3, V5 }, SCU8C, 27 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { W4, AB2 }, SCU8C, 28 },
{ PIN_CONFIG_BIAS_DISABLE, { W4, AB2 }, SCU8C, 28 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { V6, V7 }, SCU8C, 29 },
{ PIN_CONFIG_BIAS_DISABLE, { V6, V7 }, SCU8C, 29 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { Y6, AB7 }, SCU8C, 30 },
{ PIN_CONFIG_BIAS_DISABLE, { Y6, AB7 }, SCU8C, 30 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { V20, A5 }, SCU8C, 31 },
{ PIN_CONFIG_BIAS_DISABLE, { V20, A5 }, SCU8C, 31 },
/* GPIOs T[0-5] (RGMII1 Tx pins) */
{ PIN_CONFIG_DRIVE_STRENGTH, { A12, A13 }, SCU90, 9 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { A12, A13 }, SCU90, 12 },
{ PIN_CONFIG_BIAS_DISABLE, { A12, A13 }, SCU90, 12 },
/* GPIOs T[6-7], U[0-3] (RGMII2 TX pins) */
{ PIN_CONFIG_DRIVE_STRENGTH, { D9, D10 }, SCU90, 11 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { D9, D10 }, SCU90, 14 },
{ PIN_CONFIG_BIAS_DISABLE, { D9, D10 }, SCU90, 14 },
/* GPIOs U[4-7], V[0-1] (RGMII1 Rx pins) */
{ PIN_CONFIG_BIAS_PULL_DOWN, { E11, E10 }, SCU90, 13 },
{ PIN_CONFIG_BIAS_DISABLE, { E11, E10 }, SCU90, 13 },
/* GPIOs V[2-7] (RGMII2 Rx pins) */
{ PIN_CONFIG_BIAS_PULL_DOWN, { C9, C8 }, SCU90, 15 },
{ PIN_CONFIG_BIAS_DISABLE, { C9, C8 }, SCU90, 15 },
/* ADC pull-downs (SCUA8[19:4]) */
{ PIN_CONFIG_BIAS_PULL_DOWN, { L5, L5 }, SCUA8, 4 },
{ PIN_CONFIG_BIAS_DISABLE, { L5, L5 }, SCUA8, 4 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { L4, L4 }, SCUA8, 5 },
{ PIN_CONFIG_BIAS_DISABLE, { L4, L4 }, SCUA8, 5 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { L3, L3 }, SCUA8, 6 },
{ PIN_CONFIG_BIAS_DISABLE, { L3, L3 }, SCUA8, 6 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { L2, L2 }, SCUA8, 7 },
{ PIN_CONFIG_BIAS_DISABLE, { L2, L2 }, SCUA8, 7 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { L1, L1 }, SCUA8, 8 },
{ PIN_CONFIG_BIAS_DISABLE, { L1, L1 }, SCUA8, 8 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { M5, M5 }, SCUA8, 9 },
{ PIN_CONFIG_BIAS_DISABLE, { M5, M5 }, SCUA8, 9 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { M4, M4 }, SCUA8, 10 },
{ PIN_CONFIG_BIAS_DISABLE, { M4, M4 }, SCUA8, 10 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { M3, M3 }, SCUA8, 11 },
{ PIN_CONFIG_BIAS_DISABLE, { M3, M3 }, SCUA8, 11 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { M2, M2 }, SCUA8, 12 },
{ PIN_CONFIG_BIAS_DISABLE, { M2, M2 }, SCUA8, 12 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { M1, M1 }, SCUA8, 13 },
{ PIN_CONFIG_BIAS_DISABLE, { M1, M1 }, SCUA8, 13 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { N5, N5 }, SCUA8, 14 },
{ PIN_CONFIG_BIAS_DISABLE, { N5, N5 }, SCUA8, 14 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { N4, N4 }, SCUA8, 15 },
{ PIN_CONFIG_BIAS_DISABLE, { N4, N4 }, SCUA8, 15 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { N3, N3 }, SCUA8, 16 },
{ PIN_CONFIG_BIAS_DISABLE, { N3, N3 }, SCUA8, 16 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { N2, N2 }, SCUA8, 17 },
{ PIN_CONFIG_BIAS_DISABLE, { N2, N2 }, SCUA8, 17 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { N1, N1 }, SCUA8, 18 },
{ PIN_CONFIG_BIAS_DISABLE, { N1, N1 }, SCUA8, 18 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { P5, P5 }, SCUA8, 19 },
{ PIN_CONFIG_BIAS_DISABLE, { P5, P5 }, SCUA8, 19 },
/*
* Debounce settings for GPIOs D and E passthrough mode are in
* SCUA8[27:20] and so are managed by pinctrl. Normal GPIO debounce for
* banks D and E is handled by the GPIO driver - GPIO passthrough is
* treated like any other non-GPIO mux function. There is a catch
* however, in that the debounce period is configured in the GPIO
* controller. Due to this tangle between GPIO and pinctrl we don't yet
* fully support pass-through debounce.
*/
{ PIN_CONFIG_INPUT_DEBOUNCE, { A18, D16 }, SCUA8, 20 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { B17, A17 }, SCUA8, 21 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { C16, B16 }, SCUA8, 22 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { A16, E15 }, SCUA8, 23 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { D15, C15 }, SCUA8, 24 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { B15, A15 }, SCUA8, 25 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { E14, D14 }, SCUA8, 26 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { C14, B14 }, SCUA8, 27 },
};
static struct aspeed_pinctrl_data aspeed_g4_pinctrl_data = {
.pins = aspeed_g4_pins,
.npins = ARRAY_SIZE(aspeed_g4_pins),
@ -2241,6 +2345,8 @@ static struct aspeed_pinctrl_data aspeed_g4_pinctrl_data = {
.ngroups = ARRAY_SIZE(aspeed_g4_groups),
.functions = aspeed_g4_functions,
.nfunctions = ARRAY_SIZE(aspeed_g4_functions),
.configs = aspeed_g4_configs,
.nconfigs = ARRAY_SIZE(aspeed_g4_configs),
};
static struct pinmux_ops aspeed_g4_pinmux_ops = {
@ -2257,16 +2363,25 @@ static struct pinctrl_ops aspeed_g4_pinctrl_ops = {
.get_group_name = aspeed_pinctrl_get_group_name,
.get_group_pins = aspeed_pinctrl_get_group_pins,
.pin_dbg_show = aspeed_pinctrl_pin_dbg_show,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
.dt_free_map = pinctrl_utils_free_map,
};
static const struct pinconf_ops aspeed_g4_conf_ops = {
.is_generic = true,
.pin_config_get = aspeed_pin_config_get,
.pin_config_set = aspeed_pin_config_set,
.pin_config_group_get = aspeed_pin_config_group_get,
.pin_config_group_set = aspeed_pin_config_group_set,
};
static struct pinctrl_desc aspeed_g4_pinctrl_desc = {
.name = "aspeed-g4-pinctrl",
.pins = aspeed_g4_pins,
.npins = ARRAY_SIZE(aspeed_g4_pins),
.pctlops = &aspeed_g4_pinctrl_ops,
.pmxops = &aspeed_g4_pinmux_ops,
.confops = &aspeed_g4_conf_ops,
};
static int aspeed_g4_pinctrl_probe(struct platform_device *pdev)

View File

@ -2285,6 +2285,146 @@ static const struct aspeed_pin_function aspeed_g5_functions[] = {
ASPEED_PINCTRL_FUNC(WDTRST2),
};
static struct aspeed_pin_config aspeed_g5_configs[] = {
/* GPIOA, GPIOQ */
{ PIN_CONFIG_BIAS_PULL_DOWN, { B14, B13 }, SCU8C, 16 },
{ PIN_CONFIG_BIAS_DISABLE, { B14, B13 }, SCU8C, 16 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { A11, N20 }, SCU8C, 16 },
{ PIN_CONFIG_BIAS_DISABLE, { A11, N20 }, SCU8C, 16 },
/* GPIOB, GPIOR */
{ PIN_CONFIG_BIAS_PULL_DOWN, { K19, H20 }, SCU8C, 17 },
{ PIN_CONFIG_BIAS_DISABLE, { K19, H20 }, SCU8C, 17 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { AA19, E10 }, SCU8C, 17 },
{ PIN_CONFIG_BIAS_DISABLE, { AA19, E10 }, SCU8C, 17 },
/* GPIOC, GPIOS*/
{ PIN_CONFIG_BIAS_PULL_DOWN, { C12, B11 }, SCU8C, 18 },
{ PIN_CONFIG_BIAS_DISABLE, { C12, B11 }, SCU8C, 18 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { V20, AA20 }, SCU8C, 18 },
{ PIN_CONFIG_BIAS_DISABLE, { V20, AA20 }, SCU8C, 18 },
/* GPIOD, GPIOY */
{ PIN_CONFIG_BIAS_PULL_DOWN, { F19, C21 }, SCU8C, 19 },
{ PIN_CONFIG_BIAS_DISABLE, { F19, C21 }, SCU8C, 19 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { R22, P20 }, SCU8C, 19 },
{ PIN_CONFIG_BIAS_DISABLE, { R22, P20 }, SCU8C, 19 },
/* GPIOE, GPIOZ */
{ PIN_CONFIG_BIAS_PULL_DOWN, { B20, B19 }, SCU8C, 20 },
{ PIN_CONFIG_BIAS_DISABLE, { B20, B19 }, SCU8C, 20 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { Y20, W21 }, SCU8C, 20 },
{ PIN_CONFIG_BIAS_DISABLE, { Y20, W21 }, SCU8C, 20 },
/* GPIOF, GPIOAA */
{ PIN_CONFIG_BIAS_PULL_DOWN, { J19, H18 }, SCU8C, 21 },
{ PIN_CONFIG_BIAS_DISABLE, { J19, H18 }, SCU8C, 21 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { Y21, P19 }, SCU8C, 21 },
{ PIN_CONFIG_BIAS_DISABLE, { Y21, P19 }, SCU8C, 21 },
/* GPIOG, GPIOAB */
{ PIN_CONFIG_BIAS_PULL_DOWN, { A19, E14 }, SCU8C, 22 },
{ PIN_CONFIG_BIAS_DISABLE, { A19, E14 }, SCU8C, 22 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { N19, R20 }, SCU8C, 22 },
{ PIN_CONFIG_BIAS_DISABLE, { N19, R20 }, SCU8C, 22 },
/* GPIOH, GPIOAC */
{ PIN_CONFIG_BIAS_PULL_DOWN, { A18, D18 }, SCU8C, 23 },
{ PIN_CONFIG_BIAS_DISABLE, { A18, D18 }, SCU8C, 23 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { G21, G22 }, SCU8C, 23 },
{ PIN_CONFIG_BIAS_DISABLE, { G21, G22 }, SCU8C, 23 },
/* GPIOs [I, P] */
{ PIN_CONFIG_BIAS_PULL_DOWN, { C18, A15 }, SCU8C, 24 },
{ PIN_CONFIG_BIAS_DISABLE, { C18, A15 }, SCU8C, 24 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { R2, T3 }, SCU8C, 25 },
{ PIN_CONFIG_BIAS_DISABLE, { R2, T3 }, SCU8C, 25 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { L3, R1 }, SCU8C, 26 },
{ PIN_CONFIG_BIAS_DISABLE, { L3, R1 }, SCU8C, 26 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { T2, W1 }, SCU8C, 27 },
{ PIN_CONFIG_BIAS_DISABLE, { T2, W1 }, SCU8C, 27 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { Y1, T5 }, SCU8C, 28 },
{ PIN_CONFIG_BIAS_DISABLE, { Y1, T5 }, SCU8C, 28 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { V2, T4 }, SCU8C, 29 },
{ PIN_CONFIG_BIAS_DISABLE, { V2, T4 }, SCU8C, 29 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { U5, W4 }, SCU8C, 30 },
{ PIN_CONFIG_BIAS_DISABLE, { U5, W4 }, SCU8C, 30 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { V4, V6 }, SCU8C, 31 },
{ PIN_CONFIG_BIAS_DISABLE, { V4, V6 }, SCU8C, 31 },
/* GPIOs T[0-5] (RGMII1 Tx pins) */
{ PIN_CONFIG_DRIVE_STRENGTH, { B5, B5 }, SCU90, 8 },
{ PIN_CONFIG_DRIVE_STRENGTH, { E9, A5 }, SCU90, 9 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { B5, D7 }, SCU90, 12 },
{ PIN_CONFIG_BIAS_DISABLE, { B5, D7 }, SCU90, 12 },
/* GPIOs T[6-7], U[0-3] (RGMII2 TX pins) */
{ PIN_CONFIG_DRIVE_STRENGTH, { B2, B2 }, SCU90, 10 },
{ PIN_CONFIG_DRIVE_STRENGTH, { B1, B3 }, SCU90, 11 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { B2, D4 }, SCU90, 14 },
{ PIN_CONFIG_BIAS_DISABLE, { B2, D4 }, SCU90, 14 },
/* GPIOs U[4-7], V[0-1] (RGMII1 Rx pins) */
{ PIN_CONFIG_BIAS_PULL_DOWN, { B4, C4 }, SCU90, 13 },
{ PIN_CONFIG_BIAS_DISABLE, { B4, C4 }, SCU90, 13 },
/* GPIOs V[2-7] (RGMII2 Rx pins) */
{ PIN_CONFIG_BIAS_PULL_DOWN, { C2, E6 }, SCU90, 15 },
{ PIN_CONFIG_BIAS_DISABLE, { C2, E6 }, SCU90, 15 },
/* ADC pull-downs (SCUA8[19:4]) */
{ PIN_CONFIG_BIAS_PULL_DOWN, { F4, F4 }, SCUA8, 4 },
{ PIN_CONFIG_BIAS_DISABLE, { F4, F4 }, SCUA8, 4 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { F5, F5 }, SCUA8, 5 },
{ PIN_CONFIG_BIAS_DISABLE, { F5, F5 }, SCUA8, 5 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { E2, E2 }, SCUA8, 6 },
{ PIN_CONFIG_BIAS_DISABLE, { E2, E2 }, SCUA8, 6 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { E1, E1 }, SCUA8, 7 },
{ PIN_CONFIG_BIAS_DISABLE, { E1, E1 }, SCUA8, 7 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { F3, F3 }, SCUA8, 8 },
{ PIN_CONFIG_BIAS_DISABLE, { F3, F3 }, SCUA8, 8 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { E3, E3 }, SCUA8, 9 },
{ PIN_CONFIG_BIAS_DISABLE, { E3, E3 }, SCUA8, 9 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { G5, G5 }, SCUA8, 10 },
{ PIN_CONFIG_BIAS_DISABLE, { G5, G5 }, SCUA8, 10 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { G4, G4 }, SCUA8, 11 },
{ PIN_CONFIG_BIAS_DISABLE, { G4, G4 }, SCUA8, 11 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { F2, F2 }, SCUA8, 12 },
{ PIN_CONFIG_BIAS_DISABLE, { F2, F2 }, SCUA8, 12 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { G3, G3 }, SCUA8, 13 },
{ PIN_CONFIG_BIAS_DISABLE, { G3, G3 }, SCUA8, 13 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { G2, G2 }, SCUA8, 14 },
{ PIN_CONFIG_BIAS_DISABLE, { G2, G2 }, SCUA8, 14 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { F1, F1 }, SCUA8, 15 },
{ PIN_CONFIG_BIAS_DISABLE, { F1, F1 }, SCUA8, 15 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { H5, H5 }, SCUA8, 16 },
{ PIN_CONFIG_BIAS_DISABLE, { H5, H5 }, SCUA8, 16 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { G1, G1 }, SCUA8, 17 },
{ PIN_CONFIG_BIAS_DISABLE, { G1, G1 }, SCUA8, 17 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { H3, H3 }, SCUA8, 18 },
{ PIN_CONFIG_BIAS_DISABLE, { H3, H3 }, SCUA8, 18 },
{ PIN_CONFIG_BIAS_PULL_DOWN, { H4, H4 }, SCUA8, 19 },
{ PIN_CONFIG_BIAS_DISABLE, { H4, H4 }, SCUA8, 19 },
/*
* Debounce settings for GPIOs D and E passthrough mode are in
* SCUA8[27:20] and so are managed by pinctrl. Normal GPIO debounce for
* banks D and E is handled by the GPIO driver - GPIO passthrough is
* treated like any other non-GPIO mux function. There is a catch
* however, in that the debounce period is configured in the GPIO
* controller. Due to this tangle between GPIO and pinctrl we don't yet
* fully support pass-through debounce.
*/
{ PIN_CONFIG_INPUT_DEBOUNCE, { F19, E21 }, SCUA8, 20 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { F20, D20 }, SCUA8, 21 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { D21, E20 }, SCUA8, 22 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { G18, C21 }, SCUA8, 23 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { B20, C20 }, SCUA8, 24 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { F18, F17 }, SCUA8, 25 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { E18, D19 }, SCUA8, 26 },
{ PIN_CONFIG_INPUT_DEBOUNCE, { A20, B19 }, SCUA8, 27 },
};
static struct aspeed_pinctrl_data aspeed_g5_pinctrl_data = {
.pins = aspeed_g5_pins,
.npins = ARRAY_SIZE(aspeed_g5_pins),
@ -2292,6 +2432,8 @@ static struct aspeed_pinctrl_data aspeed_g5_pinctrl_data = {
.ngroups = ARRAY_SIZE(aspeed_g5_groups),
.functions = aspeed_g5_functions,
.nfunctions = ARRAY_SIZE(aspeed_g5_functions),
.configs = aspeed_g5_configs,
.nconfigs = ARRAY_SIZE(aspeed_g5_configs),
};
static struct pinmux_ops aspeed_g5_pinmux_ops = {
@ -2308,16 +2450,25 @@ static struct pinctrl_ops aspeed_g5_pinctrl_ops = {
.get_group_name = aspeed_pinctrl_get_group_name,
.get_group_pins = aspeed_pinctrl_get_group_pins,
.pin_dbg_show = aspeed_pinctrl_pin_dbg_show,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
.dt_free_map = pinctrl_utils_free_map,
};
static struct pinconf_ops aspeed_g5_conf_ops = {
.is_generic = true,
.pin_config_get = aspeed_pin_config_get,
.pin_config_set = aspeed_pin_config_set,
.pin_config_group_get = aspeed_pin_config_group_get,
.pin_config_group_set = aspeed_pin_config_group_set,
};
static struct pinctrl_desc aspeed_g5_pinctrl_desc = {
.name = "aspeed-g5-pinctrl",
.pins = aspeed_g5_pins,
.npins = ARRAY_SIZE(aspeed_g5_pins),
.pctlops = &aspeed_g5_pinctrl_ops,
.pmxops = &aspeed_g5_pinmux_ops,
.confops = &aspeed_g5_conf_ops,
};
static int aspeed_g5_pinctrl_probe(struct platform_device *pdev)

View File

@ -198,9 +198,19 @@ static int aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
* them. This may mean that certain functions cannot be
* deconfigured and is the reason we re-evaluate after writing
* all descriptor bits.
*
* Port D and port E GPIO loopback modes are the only exception
* as those are commonly used with front-panel buttons to allow
* normal operation of the host when the BMC is powered off or
* fails to boot. Once the BMC has booted, the loopback mode
* must be disabled for the BMC to control host power-on and
* reset.
*/
if ((desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2) &&
desc->ip == ASPEED_IP_SCU)
if (desc->ip == ASPEED_IP_SCU && desc->reg == HW_STRAP1 &&
!(desc->mask & (BIT(21) | BIT(22))))
continue;
if (desc->ip == ASPEED_IP_SCU && desc->reg == HW_STRAP2)
continue;
ret = regmap_update_bits(maps[desc->ip], desc->reg,
@ -537,3 +547,214 @@ int aspeed_pinctrl_probe(struct platform_device *pdev,
return 0;
}
static inline bool pin_in_config_range(unsigned int offset,
const struct aspeed_pin_config *config)
{
return offset >= config->pins[0] && offset <= config->pins[1];
}
static inline const struct aspeed_pin_config *find_pinconf_config(
const struct aspeed_pinctrl_data *pdata,
unsigned int offset,
enum pin_config_param param)
{
unsigned int i;
for (i = 0; i < pdata->nconfigs; i++) {
if (param == pdata->configs[i].param &&
pin_in_config_range(offset, &pdata->configs[i]))
return &pdata->configs[i];
}
return NULL;
}
/**
* @param: pinconf configuration parameter
* @arg: The supported argument for @param, or -1 if any value is supported
* @value: The register value to write to configure @arg for @param
*
* The map is to be used in conjunction with the configuration array supplied
* by the driver implementation.
*/
struct aspeed_pin_config_map {
enum pin_config_param param;
s32 arg;
u32 val;
};
enum aspeed_pin_config_map_type { MAP_TYPE_ARG, MAP_TYPE_VAL };
/* Aspeed consistently both:
*
* 1. Defines "disable bits" for internal pull-downs
* 2. Uses 8mA or 16mA drive strengths
*/
static const struct aspeed_pin_config_map pin_config_map[] = {
{ PIN_CONFIG_BIAS_PULL_DOWN, 0, 1 },
{ PIN_CONFIG_BIAS_PULL_DOWN, -1, 0 },
{ PIN_CONFIG_BIAS_DISABLE, -1, 1 },
{ PIN_CONFIG_DRIVE_STRENGTH, 8, 0 },
{ PIN_CONFIG_DRIVE_STRENGTH, 16, 1 },
};
static const struct aspeed_pin_config_map *find_pinconf_map(
enum pin_config_param param,
enum aspeed_pin_config_map_type type,
s64 value)
{
int i;
for (i = 0; i < ARRAY_SIZE(pin_config_map); i++) {
const struct aspeed_pin_config_map *elem;
bool match;
elem = &pin_config_map[i];
switch (type) {
case MAP_TYPE_ARG:
match = (elem->arg == -1 || elem->arg == value);
break;
case MAP_TYPE_VAL:
match = (elem->val == value);
break;
}
if (param == elem->param && match)
return elem;
}
return NULL;
}
int aspeed_pin_config_get(struct pinctrl_dev *pctldev, unsigned int offset,
unsigned long *config)
{
const enum pin_config_param param = pinconf_to_config_param(*config);
const struct aspeed_pin_config_map *pmap;
const struct aspeed_pinctrl_data *pdata;
const struct aspeed_pin_config *pconf;
unsigned int val;
int rc = 0;
u32 arg;
pdata = pinctrl_dev_get_drvdata(pctldev);
pconf = find_pinconf_config(pdata, offset, param);
if (!pconf)
return -ENOTSUPP;
rc = regmap_read(pdata->maps[ASPEED_IP_SCU], pconf->reg, &val);
if (rc < 0)
return rc;
pmap = find_pinconf_map(param, MAP_TYPE_VAL,
(val & BIT(pconf->bit)) >> pconf->bit);
if (!pmap)
return -EINVAL;
if (param == PIN_CONFIG_DRIVE_STRENGTH)
arg = (u32) pmap->arg;
else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
arg = !!pmap->arg;
else
arg = 1;
if (!arg)
return -EINVAL;
*config = pinconf_to_config_packed(param, arg);
return 0;
}
int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
unsigned long *configs, unsigned int num_configs)
{
const struct aspeed_pinctrl_data *pdata;
unsigned int i;
int rc = 0;
pdata = pinctrl_dev_get_drvdata(pctldev);
for (i = 0; i < num_configs; i++) {
const struct aspeed_pin_config_map *pmap;
const struct aspeed_pin_config *pconf;
enum pin_config_param param;
unsigned int val;
u32 arg;
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
pconf = find_pinconf_config(pdata, offset, param);
if (!pconf)
return -ENOTSUPP;
pmap = find_pinconf_map(param, MAP_TYPE_ARG, arg);
if (unlikely(WARN_ON(!pmap)))
return -EINVAL;
val = pmap->val << pconf->bit;
rc = regmap_update_bits(pdata->maps[ASPEED_IP_SCU], pconf->reg,
BIT(pconf->bit), val);
if (rc < 0)
return rc;
pr_debug("%s: Set SCU%02X[%d]=%d for param %d(=%d) on pin %d\n",
__func__, pconf->reg, pconf->bit, pmap->val,
param, arg, offset);
}
return 0;
}
int aspeed_pin_config_group_get(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *config)
{
const unsigned int *pins;
unsigned int npins;
int rc;
rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
if (rc < 0)
return rc;
if (!npins)
return -ENODEV;
rc = aspeed_pin_config_get(pctldev, pins[0], config);
return rc;
}
int aspeed_pin_config_group_set(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *configs,
unsigned int num_configs)
{
const unsigned int *pins;
unsigned int npins;
int rc;
int i;
pr_debug("%s: Fetching pins for group selector %d\n",
__func__, selector);
rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
if (rc < 0)
return rc;
for (i = 0; i < npins; i++) {
rc = aspeed_pin_config_set(pctldev, pins[i], configs,
num_configs);
if (rc < 0)
return rc;
}
return 0;
}

View File

@ -514,6 +514,20 @@ struct aspeed_pin_desc {
SIG_EXPR_LIST_DECL_SINGLE(gpio, gpio); \
MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(gpio))
/**
* @param The pinconf parameter type
* @pins The pin range this config struct covers, [low, high]
* @reg The register housing the configuration bits
* @mask The mask to select the bits of interest in @reg
*/
struct aspeed_pin_config {
enum pin_config_param param;
unsigned int pins[2];
unsigned int reg;
u8 bit;
u8 value;
};
struct aspeed_pinctrl_data {
struct regmap *maps[ASPEED_NR_PINMUX_IPS];
@ -525,6 +539,9 @@ struct aspeed_pinctrl_data {
const struct aspeed_pin_function *functions;
const unsigned int nfunctions;
const struct aspeed_pin_config *configs;
const unsigned int nconfigs;
};
#define ASPEED_PINCTRL_PIN(name_) \
@ -580,5 +597,16 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
int aspeed_pinctrl_probe(struct platform_device *pdev,
struct pinctrl_desc *pdesc,
struct aspeed_pinctrl_data *pdata);
int aspeed_pin_config_get(struct pinctrl_dev *pctldev, unsigned int offset,
unsigned long *config);
int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
unsigned long *configs, unsigned int num_configs);
int aspeed_pin_config_group_get(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *config);
int aspeed_pin_config_group_set(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *configs,
unsigned int num_configs);
#endif /* PINCTRL_ASPEED */

View File

@ -99,7 +99,7 @@ struct iproc_gpio {
void __iomem *base;
void __iomem *io_ctrl;
spinlock_t lock;
raw_spinlock_t lock;
struct gpio_chip gc;
unsigned num_banks;
@ -221,9 +221,9 @@ static void iproc_gpio_irq_mask(struct irq_data *d)
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
iproc_gpio_irq_set_mask(d, false);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static void iproc_gpio_irq_unmask(struct irq_data *d)
@ -232,9 +232,9 @@ static void iproc_gpio_irq_unmask(struct irq_data *d)
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
iproc_gpio_irq_set_mask(d, true);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type)
@ -274,13 +274,13 @@ static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
iproc_set_bit(chip, IPROC_GPIO_INT_TYPE_OFFSET, gpio,
level_triggered);
iproc_set_bit(chip, IPROC_GPIO_INT_DE_OFFSET, gpio, dual_edge);
iproc_set_bit(chip, IPROC_GPIO_INT_EDGE_OFFSET, gpio,
rising_or_high);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev,
"gpio:%u level_triggered:%d dual_edge:%d rising_or_high:%d\n",
@ -328,9 +328,9 @@ static int iproc_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
iproc_set_bit(chip, IPROC_GPIO_OUT_EN_OFFSET, gpio, false);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set input\n", gpio);
@ -343,10 +343,10 @@ static int iproc_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
iproc_set_bit(chip, IPROC_GPIO_OUT_EN_OFFSET, gpio, true);
iproc_set_bit(chip, IPROC_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val);
@ -358,9 +358,9 @@ static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
iproc_set_bit(chip, IPROC_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val);
}
@ -461,7 +461,7 @@ static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
{
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
if (disable) {
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, false);
@ -471,7 +471,7 @@ static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, true);
}
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);
@ -483,10 +483,10 @@ static void iproc_gpio_get_pull(struct iproc_gpio *chip, unsigned gpio,
{
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
*disable = !iproc_get_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio);
*pull_up = iproc_get_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
@ -515,7 +515,7 @@ static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio,
strength);
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
strength = (strength / 2) - 1;
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
val = readl(base + offset);
@ -524,7 +524,7 @@ static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
writel(val, base + offset);
offset += 4;
}
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@ -548,7 +548,7 @@ static int iproc_gpio_get_strength(struct iproc_gpio *chip, unsigned gpio,
shift = IPROC_GPIO_SHIFT(gpio);
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
*strength = 0;
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
val = readl(base + offset) & BIT(shift);
@ -559,7 +559,7 @@ static int iproc_gpio_get_strength(struct iproc_gpio *chip, unsigned gpio,
/* convert to mA */
*strength = (*strength + 1) * 2;
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@ -769,7 +769,7 @@ static int iproc_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
spin_lock_init(&chip->lock);
raw_spin_lock_init(&chip->lock);
gc = &chip->gc;
gc->base = -1;

View File

@ -73,7 +73,7 @@ struct nsp_gpio {
struct pinctrl_dev *pctl;
struct pinctrl_desc pctldesc;
struct irq_domain *irq_domain;
spinlock_t lock;
raw_spinlock_t lock;
};
enum base_type {
@ -203,9 +203,9 @@ static void nsp_gpio_irq_mask(struct irq_data *d)
struct nsp_gpio *chip = irq_data_get_irq_chip_data(d);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
nsp_gpio_irq_set_mask(d, false);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static void nsp_gpio_irq_unmask(struct irq_data *d)
@ -213,9 +213,9 @@ static void nsp_gpio_irq_unmask(struct irq_data *d)
struct nsp_gpio *chip = irq_data_get_irq_chip_data(d);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
nsp_gpio_irq_set_mask(d, true);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type)
@ -226,7 +226,7 @@ static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type)
bool falling;
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
falling = nsp_get_bit(chip, REG, NSP_GPIO_EVENT_INT_POLARITY, gpio);
level_low = nsp_get_bit(chip, REG, NSP_GPIO_INT_POLARITY, gpio);
@ -250,13 +250,13 @@ static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type)
default:
dev_err(chip->dev, "invalid GPIO IRQ type 0x%x\n",
type);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
return -EINVAL;
}
nsp_set_bit(chip, REG, NSP_GPIO_EVENT_INT_POLARITY, gpio, falling);
nsp_set_bit(chip, REG, NSP_GPIO_INT_POLARITY, gpio, level_low);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u level_low:%s falling:%s\n", gpio,
level_low ? "true" : "false", falling ? "true" : "false");
@ -295,9 +295,9 @@ static int nsp_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
nsp_set_bit(chip, REG, NSP_GPIO_OUT_EN, gpio, false);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set input\n", gpio);
return 0;
@ -309,10 +309,10 @@ static int nsp_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
nsp_set_bit(chip, REG, NSP_GPIO_OUT_EN, gpio, true);
nsp_set_bit(chip, REG, NSP_GPIO_DATA_OUT, gpio, !!(val));
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val);
return 0;
@ -323,9 +323,9 @@ static void nsp_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
nsp_set_bit(chip, REG, NSP_GPIO_DATA_OUT, gpio, !!(val));
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val);
}
@ -381,10 +381,10 @@ static int nsp_gpio_set_pull(struct nsp_gpio *chip, unsigned gpio,
{
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
nsp_set_bit(chip, IO_CTRL, NSP_PULL_DOWN_EN, gpio, pull_down);
nsp_set_bit(chip, IO_CTRL, NSP_PULL_UP_EN, gpio, pull_up);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set pullup:%d pulldown: %d\n",
gpio, pull_up, pull_down);
@ -396,10 +396,10 @@ static void nsp_gpio_get_pull(struct nsp_gpio *chip, unsigned gpio,
{
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
*pull_up = nsp_get_bit(chip, IO_CTRL, NSP_PULL_UP_EN, gpio);
*pull_down = nsp_get_bit(chip, IO_CTRL, NSP_PULL_DOWN_EN, gpio);
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static int nsp_gpio_set_strength(struct nsp_gpio *chip, unsigned gpio,
@ -417,7 +417,7 @@ static int nsp_gpio_set_strength(struct nsp_gpio *chip, unsigned gpio,
offset = NSP_GPIO_DRV_CTRL;
dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio,
strength);
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
strength = (strength / 2) - 1;
for (i = GPIO_DRV_STRENGTH_BITS; i > 0; i--) {
val = readl(chip->io_ctrl + offset);
@ -426,7 +426,7 @@ static int nsp_gpio_set_strength(struct nsp_gpio *chip, unsigned gpio,
writel(val, chip->io_ctrl + offset);
offset += 4;
}
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@ -442,7 +442,7 @@ static int nsp_gpio_get_strength(struct nsp_gpio *chip, unsigned gpio,
offset = NSP_GPIO_DRV_CTRL;
shift = gpio;
spin_lock_irqsave(&chip->lock, flags);
raw_spin_lock_irqsave(&chip->lock, flags);
*strength = 0;
for (i = (GPIO_DRV_STRENGTH_BITS - 1); i >= 0; i--) {
val = readl(chip->io_ctrl + offset) & BIT(shift);
@ -453,7 +453,7 @@ static int nsp_gpio_get_strength(struct nsp_gpio *chip, unsigned gpio,
/* convert to mA */
*strength = (*strength + 1) * 2;
spin_unlock_irqrestore(&chip->lock, flags);
raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@ -660,7 +660,7 @@ static int nsp_gpio_probe(struct platform_device *pdev)
return PTR_ERR(chip->io_ctrl);
}
spin_lock_init(&chip->lock);
raw_spin_lock_init(&chip->lock);
gc = &chip->gc;
gc->base = -1;
gc->can_sleep = false;

View File

@ -525,7 +525,7 @@ pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin);
/**
* pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller
* pinctrl_remove_gpio_range() - remove a range of GPIOs from a pin controller
* @pctldev: pin controller device to remove the range from
* @range: the GPIO range to remove
*/
@ -1062,7 +1062,7 @@ static struct pinctrl *create_pinctrl(struct device *dev,
mutex_unlock(&pinctrl_maps_mutex);
if (ret < 0) {
/* If some other error than deferral occured, return here */
/* If some other error than deferral occurred, return here */
pinctrl_free(p, false);
return ERR_PTR(ret);
}
@ -1939,9 +1939,9 @@ static int pinctrl_check_ops(struct pinctrl_dev *pctldev)
* @dev: parent device for this pin controller
* @driver_data: private pin controller data for this pin controller
*/
struct pinctrl_dev *pinctrl_init_controller(struct pinctrl_desc *pctldesc,
struct device *dev,
void *driver_data)
static struct pinctrl_dev *
pinctrl_init_controller(struct pinctrl_desc *pctldesc, struct device *dev,
void *driver_data)
{
struct pinctrl_dev *pctldev;
int ret;

View File

@ -149,6 +149,7 @@ struct chv_community {
size_t ngpio_ranges;
size_t ngpios;
size_t nirqs;
acpi_adr_space_type acpi_space_id;
};
struct chv_pin_context {
@ -405,6 +406,7 @@ static const struct chv_community southwest_community = {
* trigger GPEs.
*/
.nirqs = 8,
.acpi_space_id = 0x91,
};
static const struct pinctrl_pin_desc north_pins[] = {
@ -494,6 +496,7 @@ static const struct chv_community north_community = {
* GPEs.
*/
.nirqs = 8,
.acpi_space_id = 0x92,
};
static const struct pinctrl_pin_desc east_pins[] = {
@ -537,6 +540,7 @@ static const struct chv_community east_community = {
.ngpio_ranges = ARRAY_SIZE(east_gpio_ranges),
.ngpios = ARRAY_SIZE(east_pins),
.nirqs = 16,
.acpi_space_id = 0x93,
};
static const struct pinctrl_pin_desc southeast_pins[] = {
@ -663,6 +667,7 @@ static const struct chv_community southeast_community = {
.ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges),
.ngpios = ARRAY_SIZE(southeast_pins),
.nirqs = 16,
.acpi_space_id = 0x94,
};
static const struct chv_community *chv_communities[] = {
@ -1608,11 +1613,34 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
return 0;
}
static acpi_status chv_pinctrl_mmio_access_handler(u32 function,
acpi_physical_address address, u32 bits, u64 *value,
void *handler_context, void *region_context)
{
struct chv_pinctrl *pctrl = region_context;
unsigned long flags;
acpi_status ret = AE_OK;
raw_spin_lock_irqsave(&chv_lock, flags);
if (function == ACPI_WRITE)
chv_writel((u32)(*value), pctrl->regs + (u32)address);
else if (function == ACPI_READ)
*value = readl(pctrl->regs + (u32)address);
else
ret = AE_BAD_PARAMETER;
raw_spin_unlock_irqrestore(&chv_lock, flags);
return ret;
}
static int chv_pinctrl_probe(struct platform_device *pdev)
{
struct chv_pinctrl *pctrl;
struct acpi_device *adev;
struct resource *res;
acpi_status status;
int ret, irq, i;
adev = ACPI_COMPANION(&pdev->dev);
@ -1668,11 +1696,29 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
if (ret)
return ret;
status = acpi_install_address_space_handler(adev->handle,
pctrl->community->acpi_space_id,
chv_pinctrl_mmio_access_handler,
NULL, pctrl);
if (ACPI_FAILURE(status))
dev_err(&pdev->dev, "failed to install ACPI addr space handler\n");
platform_set_drvdata(pdev, pctrl);
return 0;
}
static int chv_pinctrl_remove(struct platform_device *pdev)
{
struct chv_pinctrl *pctrl = platform_get_drvdata(pdev);
acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev),
pctrl->community->acpi_space_id,
chv_pinctrl_mmio_access_handler);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int chv_pinctrl_suspend_noirq(struct device *dev)
{
@ -1780,6 +1826,7 @@ MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match);
static struct platform_driver chv_pinctrl_driver = {
.probe = chv_pinctrl_probe,
.remove = chv_pinctrl_remove,
.driver = {
.name = "cherryview-pinctrl",
.pm = &chv_pinctrl_pm_ops,

View File

@ -236,6 +236,12 @@ static const unsigned int hdmi_hpd_pins[] = { PIN(GPIOH_0, EE_OFF) };
static const unsigned int hdmi_sda_pins[] = { PIN(GPIOH_1, EE_OFF) };
static const unsigned int hdmi_scl_pins[] = { PIN(GPIOH_2, EE_OFF) };
static const unsigned int i2s_out_ch23_y_pins[] = { PIN(GPIOY_8, EE_OFF) };
static const unsigned int i2s_out_ch45_y_pins[] = { PIN(GPIOY_9, EE_OFF) };
static const unsigned int i2s_out_ch67_y_pins[] = { PIN(GPIOY_10, EE_OFF) };
static const unsigned int spdif_out_y_pins[] = { PIN(GPIOY_12, EE_OFF) };
static const struct pinctrl_pin_desc meson_gxbb_aobus_pins[] = {
MESON_PIN(GPIOAO_0, 0),
MESON_PIN(GPIOAO_1, 0),
@ -274,6 +280,16 @@ static const unsigned int pwm_ao_a_6_pins[] = { PIN(GPIOAO_6, 0) };
static const unsigned int pwm_ao_a_12_pins[] = { PIN(GPIOAO_12, 0) };
static const unsigned int pwm_ao_b_pins[] = { PIN(GPIOAO_13, 0) };
static const unsigned int i2s_am_clk_pins[] = { PIN(GPIOAO_8, 0) };
static const unsigned int i2s_out_ao_clk_pins[] = { PIN(GPIOAO_9, 0) };
static const unsigned int i2s_out_lr_clk_pins[] = { PIN(GPIOAO_10, 0) };
static const unsigned int i2s_out_ch01_ao_pins[] = { PIN(GPIOAO_11, 0) };
static const unsigned int i2s_out_ch23_ao_pins[] = { PIN(GPIOAO_12, 0) };
static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_13, 0) };
static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, 0) };
static const unsigned int spdif_out_ao_13_pins[] = { PIN(GPIOAO_13, 0) };
static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GPIO_GROUP(GPIOZ_0, EE_OFF),
GPIO_GROUP(GPIOZ_1, EE_OFF),
@ -426,6 +442,10 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GROUP(uart_rx_c, 1, 16),
GROUP(pwm_a_y, 1, 21),
GROUP(pwm_f_y, 1, 20),
GROUP(i2s_out_ch23_y, 1, 5),
GROUP(i2s_out_ch45_y, 1, 6),
GROUP(i2s_out_ch67_y, 1, 7),
GROUP(spdif_out_y, 1, 9),
/* Bank Z */
GROUP(eth_mdio, 6, 1),
@ -523,6 +543,14 @@ static struct meson_pmx_group meson_gxbb_aobus_groups[] = {
GROUP(pwm_ao_a_6, 0, 18),
GROUP(pwm_ao_a_12, 0, 17),
GROUP(pwm_ao_b, 0, 3),
GROUP(i2s_am_clk, 0, 30),
GROUP(i2s_out_ao_clk, 0, 29),
GROUP(i2s_out_lr_clk, 0, 28),
GROUP(i2s_out_ch01_ao, 0, 27),
GROUP(i2s_out_ch23_ao, 1, 0),
GROUP(i2s_out_ch45_ao, 1, 1),
GROUP(spdif_out_ao_6, 0, 16),
GROUP(spdif_out_ao_13, 0, 4),
};
static const char * const gpio_periphs_groups[] = {
@ -652,6 +680,14 @@ static const char * const hdmi_i2c_groups[] = {
"hdmi_sda", "hdmi_scl",
};
static const char * const i2s_out_groups[] = {
"i2s_out_ch23_y", "i2s_out_ch45_y", "i2s_out_ch67_y",
};
static const char * const spdif_out_groups[] = {
"spdif_out_y",
};
static const char * const gpio_aobus_groups[] = {
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
@ -694,6 +730,15 @@ static const char * const pwm_ao_b_groups[] = {
"pwm_ao_b",
};
static const char * const i2s_out_ao_groups[] = {
"i2s_am_clk", "i2s_out_ao_clk", "i2s_out_lr_clk",
"i2s_out_ch01_ao", "i2s_out_ch23_ao", "i2s_out_ch45_ao",
};
static const char * const spdif_out_ao_groups[] = {
"spdif_out_ao_6", "spdif_out_ao_13",
};
static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
FUNCTION(gpio_periphs),
FUNCTION(emmc),
@ -717,6 +762,8 @@ static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
FUNCTION(pwm_f_y),
FUNCTION(hdmi_hpd),
FUNCTION(hdmi_i2c),
FUNCTION(i2s_out),
FUNCTION(spdif_out),
};
static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
@ -730,6 +777,8 @@ static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
FUNCTION(pwm_ao_a_6),
FUNCTION(pwm_ao_a_12),
FUNCTION(pwm_ao_b),
FUNCTION(i2s_out_ao),
FUNCTION(spdif_out_ao),
};
static struct meson_bank meson_gxbb_periphs_banks[] = {

View File

@ -136,6 +136,11 @@ static const unsigned int emmc_clk_pins[] = { PIN(BOOT_8, EE_OFF) };
static const unsigned int emmc_cmd_pins[] = { PIN(BOOT_10, EE_OFF) };
static const unsigned int emmc_ds_pins[] = { PIN(BOOT_15, EE_OFF) };
static const unsigned int nor_d_pins[] = { PIN(BOOT_11, EE_OFF) };
static const unsigned int nor_q_pins[] = { PIN(BOOT_12, EE_OFF) };
static const unsigned int nor_c_pins[] = { PIN(BOOT_13, EE_OFF) };
static const unsigned int nor_cs_pins[] = { PIN(BOOT_15, EE_OFF) };
static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) };
static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) };
static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) };
@ -167,9 +172,13 @@ static const unsigned int uart_rts_a_pins[] = { PIN(GPIOX_15, EE_OFF) };
static const unsigned int uart_tx_b_pins[] = { PIN(GPIODV_24, EE_OFF) };
static const unsigned int uart_rx_b_pins[] = { PIN(GPIODV_25, EE_OFF) };
static const unsigned int uart_cts_b_pins[] = { PIN(GPIODV_26, EE_OFF) };
static const unsigned int uart_rts_b_pins[] = { PIN(GPIODV_27, EE_OFF) };
static const unsigned int uart_tx_c_pins[] = { PIN(GPIOX_8, EE_OFF) };
static const unsigned int uart_rx_c_pins[] = { PIN(GPIOX_9, EE_OFF) };
static const unsigned int uart_cts_c_pins[] = { PIN(GPIOX_10, EE_OFF) };
static const unsigned int uart_rts_c_pins[] = { PIN(GPIOX_11, EE_OFF) };
static const unsigned int i2c_sck_a_pins[] = { PIN(GPIODV_25, EE_OFF) };
static const unsigned int i2c_sda_a_pins[] = { PIN(GPIODV_24, EE_OFF) };
@ -180,6 +189,9 @@ static const unsigned int i2c_sda_b_pins[] = { PIN(GPIODV_26, EE_OFF) };
static const unsigned int i2c_sck_c_pins[] = { PIN(GPIODV_29, EE_OFF) };
static const unsigned int i2c_sda_c_pins[] = { PIN(GPIODV_28, EE_OFF) };
static const unsigned int i2c_sck_c_dv19_pins[] = { PIN(GPIODV_19, EE_OFF) };
static const unsigned int i2c_sda_c_dv18_pins[] = { PIN(GPIODV_18, EE_OFF) };
static const unsigned int eth_mdio_pins[] = { PIN(GPIOZ_0, EE_OFF) };
static const unsigned int eth_mdc_pins[] = { PIN(GPIOZ_1, EE_OFF) };
static const unsigned int eth_clk_rx_clk_pins[] = { PIN(GPIOZ_2, EE_OFF) };
@ -195,12 +207,33 @@ static const unsigned int eth_txd1_pins[] = { PIN(GPIOZ_11, EE_OFF) };
static const unsigned int eth_txd2_pins[] = { PIN(GPIOZ_12, EE_OFF) };
static const unsigned int eth_txd3_pins[] = { PIN(GPIOZ_13, EE_OFF) };
static const unsigned int pwm_a_pins[] = { PIN(GPIOX_6, EE_OFF) };
static const unsigned int pwm_b_pins[] = { PIN(GPIODV_29, EE_OFF) };
static const unsigned int pwm_c_pins[] = { PIN(GPIOZ_15, EE_OFF) };
static const unsigned int pwm_d_pins[] = { PIN(GPIODV_28, EE_OFF) };
static const unsigned int pwm_e_pins[] = { PIN(GPIOX_16, EE_OFF) };
static const unsigned int pwm_f_clk_pins[] = { PIN(GPIOCLK_1, EE_OFF) };
static const unsigned int pwm_f_x_pins[] = { PIN(GPIOX_7, EE_OFF) };
static const unsigned int hdmi_hpd_pins[] = { PIN(GPIOH_0, EE_OFF) };
static const unsigned int hdmi_sda_pins[] = { PIN(GPIOH_1, EE_OFF) };
static const unsigned int hdmi_scl_pins[] = { PIN(GPIOH_2, EE_OFF) };
static const unsigned int i2s_am_clk_pins[] = { PIN(GPIOH_6, EE_OFF) };
static const unsigned int i2s_out_ao_clk_pins[] = { PIN(GPIOH_7, EE_OFF) };
static const unsigned int i2s_out_lr_clk_pins[] = { PIN(GPIOH_8, EE_OFF) };
static const unsigned int i2s_out_ch01_pins[] = { PIN(GPIOH_9, EE_OFF) };
static const unsigned int i2s_out_ch23_z_pins[] = { PIN(GPIOZ_5, EE_OFF) };
static const unsigned int i2s_out_ch45_z_pins[] = { PIN(GPIOZ_6, EE_OFF) };
static const unsigned int i2s_out_ch67_z_pins[] = { PIN(GPIOZ_7, EE_OFF) };
static const unsigned int spdif_out_h_pins[] = { PIN(GPIOH_4, EE_OFF) };
static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = {
MESON_PIN(GPIOAO_0, 0),
MESON_PIN(GPIOAO_1, 0),
@ -216,6 +249,8 @@ static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = {
static const unsigned int uart_tx_ao_a_pins[] = { PIN(GPIOAO_0, 0) };
static const unsigned int uart_rx_ao_a_pins[] = { PIN(GPIOAO_1, 0) };
static const unsigned int uart_tx_ao_b_0_pins[] = { PIN(GPIOAO_0, 0) };
static const unsigned int uart_rx_ao_b_1_pins[] = { PIN(GPIOAO_1, 0) };
static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, 0) };
static const unsigned int uart_rts_ao_a_pins[] = { PIN(GPIOAO_3, 0) };
static const unsigned int uart_tx_ao_b_pins[] = { PIN(GPIOAO_4, 0) };
@ -223,9 +258,24 @@ static const unsigned int uart_rx_ao_b_pins[] = { PIN(GPIOAO_5, 0) };
static const unsigned int uart_cts_ao_b_pins[] = { PIN(GPIOAO_2, 0) };
static const unsigned int uart_rts_ao_b_pins[] = { PIN(GPIOAO_3, 0) };
static const unsigned int i2c_sck_ao_pins[] = {PIN(GPIOAO_4, 0) };
static const unsigned int i2c_sda_ao_pins[] = {PIN(GPIOAO_5, 0) };
static const unsigned int i2c_slave_sck_ao_pins[] = {PIN(GPIOAO_4, 0) };
static const unsigned int i2c_slave_sda_ao_pins[] = {PIN(GPIOAO_5, 0) };
static const unsigned int remote_input_ao_pins[] = {PIN(GPIOAO_7, 0) };
static const unsigned int pwm_ao_a_3_pins[] = { PIN(GPIOAO_3, 0) };
static const unsigned int pwm_ao_a_8_pins[] = { PIN(GPIOAO_8, 0) };
static const unsigned int pwm_ao_b_pins[] = { PIN(GPIOAO_9, 0) };
static const unsigned int pwm_ao_b_6_pins[] = { PIN(GPIOAO_6, 0) };
static const unsigned int i2s_out_ch23_ao_pins[] = { PIN(GPIOAO_8, EE_OFF) };
static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_9, EE_OFF) };
static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, EE_OFF) };
static const unsigned int spdif_out_ao_9_pins[] = { PIN(GPIOAO_9, EE_OFF) };
static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GPIO_GROUP(GPIOZ_0, EE_OFF),
@ -341,8 +391,8 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(sdio_d1, 5, 30),
GROUP(sdio_d2, 5, 29),
GROUP(sdio_d3, 5, 28),
GROUP(sdio_cmd, 5, 27),
GROUP(sdio_clk, 5, 26),
GROUP(sdio_clk, 5, 27),
GROUP(sdio_cmd, 5, 26),
GROUP(sdio_irq, 5, 24),
GROUP(uart_tx_a, 5, 19),
GROUP(uart_rx_a, 5, 18),
@ -350,11 +400,15 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(uart_rts_a, 5, 16),
GROUP(uart_tx_c, 5, 13),
GROUP(uart_rx_c, 5, 12),
GROUP(uart_cts_c, 5, 11),
GROUP(uart_rts_c, 5, 10),
GROUP(pwm_a, 5, 25),
GROUP(pwm_e, 5, 15),
GROUP(pwm_f_x, 5, 14),
/* Bank Z */
GROUP(eth_mdio, 4, 22),
GROUP(eth_mdc, 4, 23),
GROUP(eth_mdio, 4, 23),
GROUP(eth_mdc, 4, 22),
GROUP(eth_clk_rx_clk, 4, 21),
GROUP(eth_rx_dv, 4, 20),
GROUP(eth_rxd0, 4, 19),
@ -367,27 +421,46 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(eth_txd1, 4, 12),
GROUP(eth_txd2, 4, 11),
GROUP(eth_txd3, 4, 10),
GROUP(pwm_c, 3, 20),
GROUP(i2s_out_ch23_z, 3, 26),
GROUP(i2s_out_ch45_z, 3, 25),
GROUP(i2s_out_ch67_z, 3, 24),
/* Bank H */
GROUP(hdmi_hpd, 6, 31),
GROUP(hdmi_sda, 6, 30),
GROUP(hdmi_scl, 6, 29),
GROUP(i2s_am_clk, 6, 26),
GROUP(i2s_out_ao_clk, 6, 25),
GROUP(i2s_out_lr_clk, 6, 24),
GROUP(i2s_out_ch01, 6, 23),
GROUP(spdif_out_h, 6, 28),
/* Bank DV */
GROUP(uart_tx_b, 2, 16),
GROUP(uart_rx_b, 2, 15),
GROUP(i2c_sck_a, 1, 15),
GROUP(i2c_sda_a, 1, 14),
GROUP(i2c_sck_b, 1, 13),
GROUP(i2c_sda_b, 1, 12),
GROUP(i2c_sck_c, 1, 11),
GROUP(i2c_sda_c, 1, 10),
GROUP(uart_cts_b, 2, 14),
GROUP(uart_rts_b, 2, 13),
GROUP(i2c_sda_c_dv18, 1, 17),
GROUP(i2c_sck_c_dv19, 1, 16),
GROUP(i2c_sda_a, 1, 15),
GROUP(i2c_sck_a, 1, 14),
GROUP(i2c_sda_b, 1, 13),
GROUP(i2c_sck_b, 1, 12),
GROUP(i2c_sda_c, 1, 11),
GROUP(i2c_sck_c, 1, 10),
GROUP(pwm_b, 2, 11),
GROUP(pwm_d, 2, 12),
/* Bank BOOT */
GROUP(emmc_nand_d07, 7, 31),
GROUP(emmc_clk, 7, 30),
GROUP(emmc_cmd, 7, 29),
GROUP(emmc_ds, 7, 28),
GROUP(nor_d, 7, 13),
GROUP(nor_q, 7, 12),
GROUP(nor_c, 7, 11),
GROUP(nor_cs, 7, 10),
GROUP(nand_ce0, 7, 7),
GROUP(nand_ce1, 7, 6),
GROUP(nand_rb0, 7, 5),
@ -404,6 +477,9 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(sdcard_d2, 6, 0),
GROUP(sdcard_cmd, 6, 2),
GROUP(sdcard_clk, 6, 3),
/* Bank CLK */
GROUP(pwm_f_clk, 8, 30),
};
static struct meson_pmx_group meson_gxl_aobus_groups[] = {
@ -419,16 +495,29 @@ static struct meson_pmx_group meson_gxl_aobus_groups[] = {
GPIO_GROUP(GPIOAO_9, 0),
/* bank AO */
GROUP(uart_tx_ao_b_0, 0, 26),
GROUP(uart_rx_ao_b_1, 0, 25),
GROUP(uart_tx_ao_b, 0, 24),
GROUP(uart_rx_ao_b, 0, 25),
GROUP(uart_rx_ao_b, 0, 23),
GROUP(uart_tx_ao_a, 0, 12),
GROUP(uart_rx_ao_a, 0, 11),
GROUP(uart_cts_ao_a, 0, 10),
GROUP(uart_rts_ao_a, 0, 9),
GROUP(uart_cts_ao_b, 0, 8),
GROUP(uart_rts_ao_b, 0, 7),
GROUP(i2c_sck_ao, 0, 6),
GROUP(i2c_sda_ao, 0, 5),
GROUP(i2c_slave_sck_ao, 0, 2),
GROUP(i2c_slave_sda_ao, 0, 1),
GROUP(remote_input_ao, 0, 0),
GROUP(pwm_ao_a_3, 0, 22),
GROUP(pwm_ao_b_6, 0, 18),
GROUP(pwm_ao_a_8, 0, 17),
GROUP(pwm_ao_b, 0, 3),
GROUP(i2s_out_ch23_ao, 1, 0),
GROUP(i2s_out_ch45_ao, 1, 1),
GROUP(spdif_out_ao_6, 0, 16),
GROUP(spdif_out_ao_9, 0, 4),
};
static const char * const gpio_periphs_groups[] = {
@ -467,6 +556,10 @@ static const char * const emmc_groups[] = {
"emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
};
static const char * const nor_groups[] = {
"nor_d", "nor_q", "nor_c", "nor_cs",
};
static const char * const sdcard_groups[] = {
"sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3",
"sdcard_cmd", "sdcard_clk",
@ -487,11 +580,11 @@ static const char * const uart_a_groups[] = {
};
static const char * const uart_b_groups[] = {
"uart_tx_b", "uart_rx_b",
"uart_tx_b", "uart_rx_b", "uart_cts_b", "uart_rts_b",
};
static const char * const uart_c_groups[] = {
"uart_tx_c", "uart_rx_c",
"uart_tx_c", "uart_rx_c", "uart_cts_c", "uart_rts_c",
};
static const char * const i2c_a_groups[] = {
@ -503,7 +596,7 @@ static const char * const i2c_b_groups[] = {
};
static const char * const i2c_c_groups[] = {
"i2c_sck_c", "i2c_sda_c",
"i2c_sck_c", "i2c_sda_c", "i2c_sda_c_dv18", "i2c_sck_c_dv19",
};
static const char * const eth_groups[] = {
@ -513,10 +606,30 @@ static const char * const eth_groups[] = {
"eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3",
};
static const char * const pwm_a_groups[] = {
"pwm_a",
};
static const char * const pwm_b_groups[] = {
"pwm_b",
};
static const char * const pwm_c_groups[] = {
"pwm_c",
};
static const char * const pwm_d_groups[] = {
"pwm_d",
};
static const char * const pwm_e_groups[] = {
"pwm_e",
};
static const char * const pwm_f_groups[] = {
"pwm_f_clk", "pwm_f_x",
};
static const char * const hdmi_hpd_groups[] = {
"hdmi_hpd",
};
@ -525,6 +638,15 @@ static const char * const hdmi_i2c_groups[] = {
"hdmi_sda", "hdmi_scl",
};
static const char * const i2s_out_groups[] = {
"i2s_am_clk", "i2s_out_ao_clk", "i2s_out_lr_clk",
"i2s_out_ch01", "i2s_out_ch23_z", "i2s_out_ch45_z", "i2s_out_ch67_z",
};
static const char * const spdif_out_groups[] = {
"spdif_out_h",
};
static const char * const gpio_aobus_groups[] = {
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
@ -536,19 +658,41 @@ static const char * const uart_ao_groups[] = {
static const char * const uart_ao_b_groups[] = {
"uart_tx_ao_b", "uart_rx_ao_b", "uart_cts_ao_b", "uart_rts_ao_b",
"uart_tx_ao_b_0", "uart_rx_ao_b_1",
};
static const char * const i2c_ao_groups[] = {
"i2c_sck_ao", "i2c_sda_ao",
};
static const char * const i2c_slave_ao_groups[] = {
"i2c_slave_sck_ao", "i2c_slave_sda_ao",
};
static const char * const remote_input_ao_groups[] = {
"remote_input_ao",
};
static const char * const pwm_ao_a_groups[] = {
"pwm_ao_a_3", "pwm_ao_a_8",
};
static const char * const pwm_ao_b_groups[] = {
"pwm_ao_b",
"pwm_ao_b", "pwm_ao_b_6",
};
static const char * const i2s_out_ao_groups[] = {
"i2s_out_ch23_ao", "i2s_out_ch45_ao",
};
static const char * const spdif_out_ao_groups[] = {
"spdif_out_ao_6", "spdif_out_ao_9",
};
static struct meson_pmx_func meson_gxl_periphs_functions[] = {
FUNCTION(gpio_periphs),
FUNCTION(emmc),
FUNCTION(nor),
FUNCTION(sdcard),
FUNCTION(sdio),
FUNCTION(nand),
@ -559,17 +703,29 @@ static struct meson_pmx_func meson_gxl_periphs_functions[] = {
FUNCTION(i2c_b),
FUNCTION(i2c_c),
FUNCTION(eth),
FUNCTION(pwm_a),
FUNCTION(pwm_b),
FUNCTION(pwm_c),
FUNCTION(pwm_d),
FUNCTION(pwm_e),
FUNCTION(pwm_f),
FUNCTION(hdmi_hpd),
FUNCTION(hdmi_i2c),
FUNCTION(i2s_out),
FUNCTION(spdif_out),
};
static struct meson_pmx_func meson_gxl_aobus_functions[] = {
FUNCTION(gpio_aobus),
FUNCTION(uart_ao),
FUNCTION(uart_ao_b),
FUNCTION(i2c_ao),
FUNCTION(i2c_slave_ao),
FUNCTION(remote_input_ao),
FUNCTION(pwm_ao_a),
FUNCTION(pwm_ao_b),
FUNCTION(i2s_out_ao),
FUNCTION(spdif_out_ao),
};
static struct meson_bank meson_gxl_periphs_banks[] = {

View File

@ -555,22 +555,10 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc)
if (ret) {
dev_err(pc->dev, "can't add gpio chip %s\n",
pc->data->name);
goto fail;
}
ret = gpiochip_add_pin_range(&pc->chip, dev_name(pc->dev),
0, pc->data->pin_base,
pc->chip.ngpio);
if (ret) {
dev_err(pc->dev, "can't add pin range\n");
goto fail;
return ret;
}
return 0;
fail:
gpiochip_remove(&pc->chip);
return ret;
}
static struct regmap_config meson_regmap_config = {

View File

@ -267,8 +267,8 @@ static const unsigned int nand_ale_pins[] = { PIN(BOOT_11, 0) };
static const unsigned int nand_cle_pins[] = { PIN(BOOT_12, 0) };
static const unsigned int nand_wen_clk_pins[] = { PIN(BOOT_13, 0) };
static const unsigned int nand_ren_clk_pins[] = { PIN(BOOT_14, 0) };
static const unsigned int nand_dqs_0_pins[] = { PIN(BOOT_15, 0) };
static const unsigned int nand_dqs_1_pins[] = { PIN(BOOT_18, 0) };
static const unsigned int nand_dqs_15_pins[] = { PIN(BOOT_15, 0) };
static const unsigned int nand_dqs_18_pins[] = { PIN(BOOT_18, 0) };
static const unsigned int sdxc_d0_c_pins[] = { PIN(BOOT_0, 0)};
static const unsigned int sdxc_d13_c_pins[] = { PIN(BOOT_1, 0), PIN(BOOT_2, 0),
@ -527,8 +527,8 @@ static struct meson_pmx_group meson8b_cbus_groups[] = {
GROUP(nand_cle, 2, 20),
GROUP(nand_wen_clk, 2, 19),
GROUP(nand_ren_clk, 2, 18),
GROUP(nand_dqs_0, 2, 27),
GROUP(nand_dqs_1, 2, 28),
GROUP(nand_dqs_15, 2, 27),
GROUP(nand_dqs_18, 2, 28),
GROUP(sdxc_d0_c, 4, 30),
GROUP(sdxc_d13_c, 4, 29),
GROUP(sdxc_d47_c, 4, 28),
@ -739,8 +739,8 @@ static const char * const sdxc_c_groups[] = {
static const char * const nand_groups[] = {
"nand_io", "nand_io_ce0", "nand_io_ce1",
"nand_io_rb0", "nand_ale", "nand_cle",
"nand_wen_clk", "nand_ren_clk", "nand_dqs0",
"nand_dqs1"
"nand_wen_clk", "nand_ren_clk", "nand_dqs_15",
"nand_dqs_18"
};
static const char * const nor_groups[] = {

View File

@ -39,3 +39,10 @@ config PINCTRL_ORION
select PINCTRL_MVEBU
endif
config PINCTRL_ARMADA_37XX
bool
select GENERIC_PINCONF
select MFD_SYSCON
select PINCONF
select PINMUX

View File

@ -1,4 +1,4 @@
obj-y += pinctrl-mvebu.o
obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o
obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
@ -6,4 +6,5 @@ obj-$(CONFIG_PINCTRL_ARMADA_375) += pinctrl-armada-375.o
obj-$(CONFIG_PINCTRL_ARMADA_38X) += pinctrl-armada-38x.o
obj-$(CONFIG_PINCTRL_ARMADA_39X) += pinctrl-armada-39x.o
obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o
obj-$(CONFIG_PINCTRL_ARMADA_37XX) += pinctrl-armada-37xx.o
obj-$(CONFIG_PINCTRL_ORION) += pinctrl-orion.o

View File

@ -0,0 +1,748 @@
/*
* Marvell 37xx SoC pinctrl driver
*
* Copyright (C) 2017 Marvell
*
* Gregory CLEMENT <gregory.clement@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2 or later. This program is licensed "as is"
* without any warranty of any kind, whether express or implied.
*/
#include <linux/gpio/driver.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include "../pinctrl-utils.h"
#define OUTPUT_EN 0x0
#define INPUT_VAL 0x10
#define OUTPUT_VAL 0x18
#define OUTPUT_CTL 0x20
#define SELECTION 0x30
#define NB_FUNCS 2
#define GPIO_PER_REG 32
/**
* struct armada_37xx_pin_group: represents group of pins of a pinmux function.
* The pins of a pinmux groups are composed of one or two groups of contiguous
* pins.
* @name: Name of the pin group, used to lookup the group.
* @start_pins: Index of the first pin of the main range of pins belonging to
* the group
* @npins: Number of pins included in the first range
* @reg_mask: Bit mask matching the group in the selection register
* @extra_pins: Index of the first pin of the optional second range of pins
* belonging to the group
* @npins: Number of pins included in the second optional range
* @funcs: A list of pinmux functions that can be selected for this group.
* @pins: List of the pins included in the group
*/
struct armada_37xx_pin_group {
const char *name;
unsigned int start_pin;
unsigned int npins;
u32 reg_mask;
u32 val[NB_FUNCS];
unsigned int extra_pin;
unsigned int extra_npins;
const char *funcs[NB_FUNCS];
unsigned int *pins;
};
struct armada_37xx_pin_data {
u8 nr_pins;
char *name;
struct armada_37xx_pin_group *groups;
int ngroups;
};
struct armada_37xx_pmx_func {
const char *name;
const char **groups;
unsigned int ngroups;
};
struct armada_37xx_pinctrl {
struct regmap *regmap;
const struct armada_37xx_pin_data *data;
struct device *dev;
struct gpio_chip gpio_chip;
struct pinctrl_desc pctl;
struct pinctrl_dev *pctl_dev;
struct armada_37xx_pin_group *groups;
unsigned int ngroups;
struct armada_37xx_pmx_func *funcs;
unsigned int nfuncs;
};
#define PIN_GRP(_name, _start, _nr, _mask, _func1, _func2) \
{ \
.name = _name, \
.start_pin = _start, \
.npins = _nr, \
.reg_mask = _mask, \
.val = {0, _mask}, \
.funcs = {_func1, _func2} \
}
#define PIN_GRP_GPIO(_name, _start, _nr, _mask, _func1) \
{ \
.name = _name, \
.start_pin = _start, \
.npins = _nr, \
.reg_mask = _mask, \
.val = {0, _mask}, \
.funcs = {_func1, "gpio"} \
}
#define PIN_GRP_GPIO_2(_name, _start, _nr, _mask, _val1, _val2, _func1) \
{ \
.name = _name, \
.start_pin = _start, \
.npins = _nr, \
.reg_mask = _mask, \
.val = {_val1, _val2}, \
.funcs = {_func1, "gpio"} \
}
#define PIN_GRP_EXTRA(_name, _start, _nr, _mask, _v1, _v2, _start2, _nr2, \
_f1, _f2) \
{ \
.name = _name, \
.start_pin = _start, \
.npins = _nr, \
.reg_mask = _mask, \
.val = {_v1, _v2}, \
.extra_pin = _start2, \
.extra_npins = _nr2, \
.funcs = {_f1, _f2} \
}
static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"),
PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"),
PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"),
PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"),
PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"),
PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"),
PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"),
PIN_GRP_GPIO("pmic1", 17, 1, BIT(7), "pmic"),
PIN_GRP_GPIO("pmic0", 16, 1, BIT(8), "pmic"),
PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"),
PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"),
PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"),
PIN_GRP_GPIO_2("spi_cs2", 18, 1, BIT(13) | BIT(19), 0, BIT(13), "spi"),
PIN_GRP_GPIO_2("spi_cs3", 19, 1, BIT(14) | BIT(19), 0, BIT(14), "spi"),
PIN_GRP_GPIO("onewire", 4, 1, BIT(16), "onewire"),
PIN_GRP_GPIO("uart1", 25, 2, BIT(17), "uart"),
PIN_GRP_GPIO("spi_quad", 15, 2, BIT(18), "spi"),
PIN_GRP_EXTRA("uart2", 9, 2, BIT(13) | BIT(14) | BIT(19),
BIT(13) | BIT(14), BIT(19), 18, 2, "gpio", "uart"),
PIN_GRP_GPIO("led0_od", 11, 1, BIT(20), "led"),
PIN_GRP_GPIO("led1_od", 12, 1, BIT(21), "led"),
PIN_GRP_GPIO("led2_od", 13, 1, BIT(22), "led"),
PIN_GRP_GPIO("led3_od", 14, 1, BIT(23), "led"),
};
static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"),
PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"),
PIN_GRP_GPIO("sdio_sb", 24, 5, BIT(2), "sdio"),
PIN_GRP_EXTRA("rgmii", 6, 14, BIT(3), 0, BIT(3), 23, 1, "mii", "gpio"),
PIN_GRP_GPIO("pcie1", 3, 2, BIT(4), "pcie"),
PIN_GRP_GPIO("ptp", 20, 3, BIT(5), "ptp"),
PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"),
PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"),
PIN_GRP("mii_col", 23, 1, BIT(8), "mii", "mii_err"),
};
const struct armada_37xx_pin_data armada_37xx_pin_nb = {
.nr_pins = 36,
.name = "GPIO1",
.groups = armada_37xx_nb_groups,
.ngroups = ARRAY_SIZE(armada_37xx_nb_groups),
};
const struct armada_37xx_pin_data armada_37xx_pin_sb = {
.nr_pins = 29,
.name = "GPIO2",
.groups = armada_37xx_sb_groups,
.ngroups = ARRAY_SIZE(armada_37xx_sb_groups),
};
static inline void armada_37xx_update_reg(unsigned int *reg,
unsigned int offset)
{
/* We never have more than 2 registers */
if (offset >= GPIO_PER_REG) {
offset -= GPIO_PER_REG;
*reg += sizeof(u32);
}
}
static int armada_37xx_get_func_reg(struct armada_37xx_pin_group *grp,
const char *func)
{
int f;
for (f = 0; f < NB_FUNCS; f++)
if (!strcmp(grp->funcs[f], func))
return f;
return -ENOTSUPP;
}
static struct armada_37xx_pin_group *armada_37xx_find_next_grp_by_pin(
struct armada_37xx_pinctrl *info, int pin, int *grp)
{
while (*grp < info->ngroups) {
struct armada_37xx_pin_group *group = &info->groups[*grp];
int j;
*grp = *grp + 1;
for (j = 0; j < (group->npins + group->extra_npins); j++)
if (group->pins[j] == pin)
return group;
}
return NULL;
}
static int armada_37xx_pin_config_group_get(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned long *config)
{
return -ENOTSUPP;
}
static int armada_37xx_pin_config_group_set(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned long *configs,
unsigned int num_configs)
{
return -ENOTSUPP;
}
static struct pinconf_ops armada_37xx_pinconf_ops = {
.is_generic = true,
.pin_config_group_get = armada_37xx_pin_config_group_get,
.pin_config_group_set = armada_37xx_pin_config_group_set,
};
static int armada_37xx_get_groups_count(struct pinctrl_dev *pctldev)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
return info->ngroups;
}
static const char *armada_37xx_get_group_name(struct pinctrl_dev *pctldev,
unsigned int group)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
return info->groups[group].name;
}
static int armada_37xx_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int selector,
const unsigned int **pins,
unsigned int *npins)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
if (selector >= info->ngroups)
return -EINVAL;
*pins = info->groups[selector].pins;
*npins = info->groups[selector].npins +
info->groups[selector].extra_npins;
return 0;
}
static const struct pinctrl_ops armada_37xx_pctrl_ops = {
.get_groups_count = armada_37xx_get_groups_count,
.get_group_name = armada_37xx_get_group_name,
.get_group_pins = armada_37xx_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
.dt_free_map = pinctrl_utils_free_map,
};
/*
* Pinmux_ops handling
*/
static int armada_37xx_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
return info->nfuncs;
}
static const char *armada_37xx_pmx_get_func_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
return info->funcs[selector].name;
}
static int armada_37xx_pmx_get_groups(struct pinctrl_dev *pctldev,
unsigned int selector,
const char * const **groups,
unsigned int * const num_groups)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
*groups = info->funcs[selector].groups;
*num_groups = info->funcs[selector].ngroups;
return 0;
}
static int armada_37xx_pmx_set_by_name(struct pinctrl_dev *pctldev,
const char *name,
struct armada_37xx_pin_group *grp)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
unsigned int reg = SELECTION;
unsigned int mask = grp->reg_mask;
int func, val;
dev_dbg(info->dev, "enable function %s group %s\n",
name, grp->name);
func = armada_37xx_get_func_reg(grp, name);
if (func < 0)
return func;
val = grp->val[func];
regmap_update_bits(info->regmap, reg, mask, val);
return 0;
}
static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned int group)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct armada_37xx_pin_group *grp = &info->groups[group];
const char *name = info->funcs[selector].name;
return armada_37xx_pmx_set_by_name(pctldev, name, grp);
}
static int armada_37xx_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
unsigned int reg = OUTPUT_EN;
unsigned int mask;
armada_37xx_update_reg(&reg, offset);
mask = BIT(offset);
return regmap_update_bits(info->regmap, reg, mask, 0);
}
static int armada_37xx_gpio_get_direction(struct gpio_chip *chip,
unsigned int offset)
{
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
unsigned int reg = OUTPUT_EN;
unsigned int val, mask;
armada_37xx_update_reg(&reg, offset);
mask = BIT(offset);
regmap_read(info->regmap, reg, &val);
return !(val & mask);
}
static int armada_37xx_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value)
{
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
unsigned int reg = OUTPUT_EN;
unsigned int mask;
armada_37xx_update_reg(&reg, offset);
mask = BIT(offset);
return regmap_update_bits(info->regmap, reg, mask, mask);
}
static int armada_37xx_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
unsigned int reg = INPUT_VAL;
unsigned int val, mask;
armada_37xx_update_reg(&reg, offset);
mask = BIT(offset);
regmap_read(info->regmap, reg, &val);
return (val & mask) != 0;
}
static void armada_37xx_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
unsigned int reg = OUTPUT_VAL;
unsigned int mask, val;
armada_37xx_update_reg(&reg, offset);
mask = BIT(offset);
val = value ? mask : 0;
regmap_update_bits(info->regmap, reg, mask, val);
}
static int armada_37xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset, bool input)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct gpio_chip *chip = range->gc;
dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
offset, range->name, offset, input ? "input" : "output");
if (input)
armada_37xx_gpio_direction_input(chip, offset);
else
armada_37xx_gpio_direction_output(chip, offset, 0);
return 0;
}
static int armada_37xx_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct armada_37xx_pin_group *group;
int grp = 0;
dev_dbg(info->dev, "requesting gpio %d\n", offset);
while ((group = armada_37xx_find_next_grp_by_pin(info, offset, &grp)))
armada_37xx_pmx_set_by_name(pctldev, "gpio", group);
return 0;
}
static const struct pinmux_ops armada_37xx_pmx_ops = {
.get_functions_count = armada_37xx_pmx_get_funcs_count,
.get_function_name = armada_37xx_pmx_get_func_name,
.get_function_groups = armada_37xx_pmx_get_groups,
.set_mux = armada_37xx_pmx_set,
.gpio_request_enable = armada_37xx_gpio_request_enable,
.gpio_set_direction = armada_37xx_pmx_gpio_set_direction,
};
static const struct gpio_chip armada_37xx_gpiolib_chip = {
.request = gpiochip_generic_request,
.free = gpiochip_generic_free,
.set = armada_37xx_gpio_set,
.get = armada_37xx_gpio_get,
.get_direction = armada_37xx_gpio_get_direction,
.direction_input = armada_37xx_gpio_direction_input,
.direction_output = armada_37xx_gpio_direction_output,
.owner = THIS_MODULE,
};
static int armada_37xx_gpiochip_register(struct platform_device *pdev,
struct armada_37xx_pinctrl *info)
{
struct device_node *np;
struct gpio_chip *gc;
int ret = -ENODEV;
for_each_child_of_node(info->dev->of_node, np) {
if (of_find_property(np, "gpio-controller", NULL)) {
ret = 0;
break;
}
};
if (ret)
return ret;
info->gpio_chip = armada_37xx_gpiolib_chip;
gc = &info->gpio_chip;
gc->ngpio = info->data->nr_pins;
gc->parent = &pdev->dev;
gc->base = -1;
gc->of_node = np;
gc->label = info->data->name;
ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
if (ret)
return ret;
return 0;
}
/**
* armada_37xx_add_function() - Add a new function to the list
* @funcs: array of function to add the new one
* @funcsize: size of the remaining space for the function
* @name: name of the function to add
*
* If it is a new function then create it by adding its name else
* increment the number of group associated to this function.
*/
static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
int *funcsize, const char *name)
{
int i = 0;
if (*funcsize <= 0)
return -EOVERFLOW;
while (funcs->ngroups) {
/* function already there */
if (strcmp(funcs->name, name) == 0) {
funcs->ngroups++;
return -EEXIST;
}
funcs++;
i++;
}
/* append new unique function */
funcs->name = name;
funcs->ngroups = 1;
(*funcsize)--;
return 0;
}
/**
* armada_37xx_fill_group() - complete the group array
* @info: info driver instance
*
* Based on the data available from the armada_37xx_pin_group array
* completes the last member of the struct for each function: the list
* of the groups associated to this function.
*
*/
static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
{
int n, num = 0, funcsize = info->data->nr_pins;
for (n = 0; n < info->ngroups; n++) {
struct armada_37xx_pin_group *grp = &info->groups[n];
int i, j, f;
grp->pins = devm_kzalloc(info->dev,
(grp->npins + grp->extra_npins) *
sizeof(*grp->pins), GFP_KERNEL);
if (!grp->pins)
return -ENOMEM;
for (i = 0; i < grp->npins; i++)
grp->pins[i] = grp->start_pin + i;
for (j = 0; j < grp->extra_npins; j++)
grp->pins[i+j] = grp->extra_pin + j;
for (f = 0; f < NB_FUNCS; f++) {
int ret;
/* check for unique functions and count groups */
ret = armada_37xx_add_function(info->funcs, &funcsize,
grp->funcs[f]);
if (ret == -EOVERFLOW)
dev_err(info->dev,
"More functions than pins(%d)\n",
info->data->nr_pins);
if (ret < 0)
continue;
num++;
}
}
info->nfuncs = num;
return 0;
}
/**
* armada_37xx_fill_funcs() - complete the funcs array
* @info: info driver instance
*
* Based on the data available from the armada_37xx_pin_group array
* completes the last two member of the struct for each group:
* - the list of the pins included in the group
* - the list of pinmux functions that can be selected for this group
*
*/
static int armada_37xx_fill_func(struct armada_37xx_pinctrl *info)
{
struct armada_37xx_pmx_func *funcs = info->funcs;
int n;
for (n = 0; n < info->nfuncs; n++) {
const char *name = funcs[n].name;
const char **groups;
int g;
funcs[n].groups = devm_kzalloc(info->dev, funcs[n].ngroups *
sizeof(*(funcs[n].groups)),
GFP_KERNEL);
if (!funcs[n].groups)
return -ENOMEM;
groups = funcs[n].groups;
for (g = 0; g < info->ngroups; g++) {
struct armada_37xx_pin_group *gp = &info->groups[g];
int f;
for (f = 0; f < NB_FUNCS; f++) {
if (strcmp(gp->funcs[f], name) == 0) {
*groups = gp->name;
groups++;
}
}
}
}
return 0;
}
static int armada_37xx_pinctrl_register(struct platform_device *pdev,
struct armada_37xx_pinctrl *info)
{
const struct armada_37xx_pin_data *pin_data = info->data;
struct pinctrl_desc *ctrldesc = &info->pctl;
struct pinctrl_pin_desc *pindesc, *pdesc;
int pin, ret;
info->groups = pin_data->groups;
info->ngroups = pin_data->ngroups;
ctrldesc->name = "armada_37xx-pinctrl";
ctrldesc->owner = THIS_MODULE;
ctrldesc->pctlops = &armada_37xx_pctrl_ops;
ctrldesc->pmxops = &armada_37xx_pmx_ops;
ctrldesc->confops = &armada_37xx_pinconf_ops;
pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
pin_data->nr_pins, GFP_KERNEL);
if (!pindesc)
return -ENOMEM;
ctrldesc->pins = pindesc;
ctrldesc->npins = pin_data->nr_pins;
pdesc = pindesc;
for (pin = 0; pin < pin_data->nr_pins; pin++) {
pdesc->number = pin;
pdesc->name = kasprintf(GFP_KERNEL, "%s-%d",
pin_data->name, pin);
pdesc++;
}
/*
* we allocate functions for number of pins and hope there are
* fewer unique functions than pins available
*/
info->funcs = devm_kzalloc(&pdev->dev, pin_data->nr_pins *
sizeof(struct armada_37xx_pmx_func), GFP_KERNEL);
if (!info->funcs)
return -ENOMEM;
ret = armada_37xx_fill_group(info);
if (ret)
return ret;
ret = armada_37xx_fill_func(info);
if (ret)
return ret;
info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info);
if (IS_ERR(info->pctl_dev)) {
dev_err(&pdev->dev, "could not register pinctrl driver\n");
return PTR_ERR(info->pctl_dev);
}
return 0;
}
static const struct of_device_id armada_37xx_pinctrl_of_match[] = {
{
.compatible = "marvell,armada3710-sb-pinctrl",
.data = (void *)&armada_37xx_pin_sb,
},
{
.compatible = "marvell,armada3710-nb-pinctrl",
.data = (void *)&armada_37xx_pin_nb,
},
{ },
};
static int __init armada_37xx_pinctrl_probe(struct platform_device *pdev)
{
struct armada_37xx_pinctrl *info;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct regmap *regmap;
int ret;
info = devm_kzalloc(dev, sizeof(struct armada_37xx_pinctrl),
GFP_KERNEL);
if (!info)
return -ENOMEM;
info->dev = dev;
regmap = syscon_node_to_regmap(np);
if (IS_ERR(regmap)) {
dev_err(&pdev->dev, "cannot get regmap\n");
return PTR_ERR(regmap);
}
info->regmap = regmap;
info->data = of_device_get_match_data(dev);
ret = armada_37xx_pinctrl_register(pdev, info);
if (ret)
return ret;
ret = armada_37xx_gpiochip_register(pdev, info);
if (ret)
return ret;
platform_set_drvdata(pdev, info);
return 0;
}
static struct platform_driver armada_37xx_pinctrl_driver = {
.driver = {
.name = "armada-37xx-pinctrl",
.of_match_table = armada_37xx_pinctrl_of_match,
},
};
builtin_platform_driver_probe(armada_37xx_pinctrl_driver,
armada_37xx_pinctrl_probe);

View File

@ -35,6 +35,7 @@ static const struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
"input bias pull to pin specific state", NULL, false),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL, false),
PCONFDUMP(PIN_CONFIG_BIDIRECTIONAL, "bi-directional pin operations", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL, false),
@ -160,6 +161,7 @@ static const struct pinconf_generic_params dt_params[] = {
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
{ "bi-directional", PIN_CONFIG_BIDIRECTIONAL, 1 },
{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
{ "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
@ -172,6 +174,7 @@ static const struct pinconf_generic_params dt_params[] = {
{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
{ "output-enable", PIN_CONFIG_OUTPUT, 1, },
{ "output-high", PIN_CONFIG_OUTPUT, 1, },
{ "output-low", PIN_CONFIG_OUTPUT, 0, },
{ "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
@ -187,7 +190,7 @@ static const struct pinconf_generic_params dt_params[] = {
* @ncfg: Number of entries in @cfg
*
* Parse the config options described in @params from @np and puts the result
* in @cfg. @cfg does not need to be empty, entries are added beggining at
* in @cfg. @cfg does not need to be empty, entries are added beginning at
* @ncfg. @ncfg is updated to reflect the number of entries after parsing. @cfg
* needs to have enough memory allocated to hold all possible entries.
*/

View File

@ -284,7 +284,7 @@ void pinconf_show_setting(struct seq_file *s,
}
/*
* FIXME: We should really get the pin controler to dump the config
* FIXME: We should really get the pin controller to dump the config
* values, so they can be decoded to something meaningful.
*/
pinconf_show_config(s, pctldev, setting->data.configs.configs,
@ -473,7 +473,7 @@ exit:
* "config_pin" or "config_group", alternatives like config_mux are not
* supported yet.
* <devicename> <state> <name> are values that should match the pinctrl-maps
* <newvalue> reflects the new config and is driver dependant
* <newvalue> reflects the new config and is driver dependent
*/
static ssize_t pinconf_dbg_config_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)

View File

@ -41,11 +41,11 @@ static int amd_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
u32 pin_reg;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
pin_reg &= ~BIT(OUTPUT_ENABLE_OFF);
writel(pin_reg, gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return 0;
}
@ -57,7 +57,7 @@ static int amd_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
unsigned long flags;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
pin_reg |= BIT(OUTPUT_ENABLE_OFF);
if (value)
@ -65,7 +65,7 @@ static int amd_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
else
pin_reg &= ~BIT(OUTPUT_VALUE_OFF);
writel(pin_reg, gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return 0;
}
@ -76,9 +76,9 @@ static int amd_gpio_get_value(struct gpio_chip *gc, unsigned offset)
unsigned long flags;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return !!(pin_reg & BIT(PIN_STS_OFF));
}
@ -89,14 +89,14 @@ static void amd_gpio_set_value(struct gpio_chip *gc, unsigned offset, int value)
unsigned long flags;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
if (value)
pin_reg |= BIT(OUTPUT_VALUE_OFF);
else
pin_reg &= ~BIT(OUTPUT_VALUE_OFF);
writel(pin_reg, gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset,
@ -108,7 +108,7 @@ static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset,
unsigned long flags;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
if (debounce) {
@ -159,7 +159,7 @@ static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset,
pin_reg &= ~DB_CNTRl_MASK;
}
writel(pin_reg, gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret;
}
@ -224,9 +224,9 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
}
for (; i < pin_num; i++) {
seq_printf(s, "pin%d\t", i);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + i * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
if (pin_reg & BIT(INTERRUPT_ENABLE_OFF)) {
interrupt_enable = "interrupt is enabled|";
@ -331,12 +331,12 @@ static void amd_gpio_irq_enable(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
pin_reg |= BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_disable(struct irq_data *d)
@ -346,12 +346,12 @@ static void amd_gpio_irq_disable(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg &= ~BIT(INTERRUPT_ENABLE_OFF);
pin_reg &= ~BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_mask(struct irq_data *d)
@ -361,11 +361,11 @@ static void amd_gpio_irq_mask(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg &= ~BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_unmask(struct irq_data *d)
@ -375,11 +375,11 @@ static void amd_gpio_irq_unmask(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg |= BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_eoi(struct irq_data *d)
@ -389,11 +389,11 @@ static void amd_gpio_irq_eoi(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
reg |= EOI_MASK;
writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
@ -404,7 +404,7 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
/* Ignore the settings coming from the client and
@ -469,7 +469,7 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
pin_reg |= CLR_INTR_STAT << INTERRUPT_STS_OFF;
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret;
}
@ -511,14 +511,14 @@ static void amd_gpio_irq_handler(struct irq_desc *desc)
chained_irq_enter(chip, desc);
/*enable GPIO interrupt again*/
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
reg64 = reg;
reg64 = reg64 << 32;
reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
reg64 |= reg;
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
/*
* first 46 bits indicates interrupt status.
@ -546,11 +546,11 @@ static void amd_gpio_irq_handler(struct irq_desc *desc)
if (handled == 0)
handle_bad_irq(desc);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
reg |= EOI_MASK;
writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
chained_irq_exit(chip, desc);
}
@ -602,9 +602,9 @@ static int amd_pinconf_get(struct pinctrl_dev *pctldev,
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + pin*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
switch (param) {
case PIN_CONFIG_INPUT_DEBOUNCE:
arg = pin_reg & DB_TMR_OUT_MASK;
@ -644,7 +644,7 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
enum pin_config_param param;
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
spin_lock_irqsave(&gpio_dev->lock, flags);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
@ -683,7 +683,7 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
writel(pin_reg, gpio_dev->base + pin*4);
}
spin_unlock_irqrestore(&gpio_dev->lock, flags);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret;
}
@ -751,7 +751,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
if (!gpio_dev)
return -ENOMEM;
spin_lock_init(&gpio_dev->lock);
raw_spin_lock_init(&gpio_dev->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {

View File

@ -87,7 +87,7 @@ struct amd_function {
};
struct amd_gpio {
spinlock_t lock;
raw_spinlock_t lock;
void __iomem *base;
const struct amd_pingroup *groups;

View File

@ -0,0 +1,979 @@
/*
* Driver for the Axis ARTPEC-6 pin controller
*
* Author: Chris Paterson <chris.paterson@linux.pieboy.co.uk>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/slab.h>
#include "core.h"
#include "pinconf.h"
#include "pinctrl-utils.h"
#define ARTPEC6_LAST_PIN 97 /* 97 pins in pinmux */
#define ARTPEC6_MAX_MUXABLE 35 /* Last pin with muxable function */
/* Pinmux control register bit definitions */
#define ARTPEC6_PINMUX_UDC0_MASK 0x00000001
#define ARTPEC6_PINMUX_UDC0_SHIFT 0
#define ARTPEC6_PINMUX_UDC1_MASK 0x00000002
#define ARTPEC6_PINMUX_UDC1_SHIFT 1
#define ARTPEC6_PINMUX_DRV_MASK 0x00000060
#define ARTPEC6_PINMUX_DRV_SHIFT 5
#define ARTPEC6_PINMUX_SEL_MASK 0x00003000
#define ARTPEC6_PINMUX_SEL_SHIFT 12
/* Pinmux configurations */
#define ARTPEC6_CONFIG_0 0
#define ARTPEC6_CONFIG_1 1
#define ARTPEC6_CONFIG_2 2
#define ARTPEC6_CONFIG_3 3
/* Pin drive strength options */
#define ARTPEC6_DRIVE_4mA 4
#define ARTPEC6_DRIVE_4mA_SET 0
#define ARTPEC6_DRIVE_6mA 6
#define ARTPEC6_DRIVE_6mA_SET 1
#define ARTPEC6_DRIVE_8mA 8
#define ARTPEC6_DRIVE_8mA_SET 2
#define ARTPEC6_DRIVE_9mA 9
#define ARTPEC6_DRIVE_9mA_SET 3
struct artpec6_pmx {
struct device *dev;
struct pinctrl_dev *pctl;
void __iomem *base;
struct pinctrl_pin_desc *pins;
unsigned int num_pins;
const struct artpec6_pin_group *pin_groups;
unsigned int num_pin_groups;
const struct artpec6_pmx_func *functions;
unsigned int num_functions;
};
struct artpec6_pin_group {
const char *name;
const unsigned int *pins;
const unsigned int num_pins;
unsigned char config;
};
struct artpec6_pmx_func {
const char *name;
const char * const *groups;
const unsigned int num_groups;
};
/* pins */
static struct pinctrl_pin_desc artpec6_pins[] = {
PINCTRL_PIN(0, "GPIO0"),
PINCTRL_PIN(1, "GPIO1"),
PINCTRL_PIN(2, "GPIO2"),
PINCTRL_PIN(3, "GPIO3"),
PINCTRL_PIN(4, "GPIO4"),
PINCTRL_PIN(5, "GPIO5"),
PINCTRL_PIN(6, "GPIO6"),
PINCTRL_PIN(7, "GPIO7"),
PINCTRL_PIN(8, "GPIO8"),
PINCTRL_PIN(9, "GPIO9"),
PINCTRL_PIN(10, "GPIO10"),
PINCTRL_PIN(11, "GPIO11"),
PINCTRL_PIN(12, "GPIO12"),
PINCTRL_PIN(13, "GPIO13"),
PINCTRL_PIN(14, "GPIO14"),
PINCTRL_PIN(15, "GPIO15"),
PINCTRL_PIN(16, "GPIO16"),
PINCTRL_PIN(17, "GPIO17"),
PINCTRL_PIN(18, "GPIO18"),
PINCTRL_PIN(19, "GPIO19"),
PINCTRL_PIN(20, "GPIO20"),
PINCTRL_PIN(21, "GPIO21"),
PINCTRL_PIN(22, "GPIO22"),
PINCTRL_PIN(23, "GPIO23"),
PINCTRL_PIN(24, "GPIO24"),
PINCTRL_PIN(25, "GPIO25"),
PINCTRL_PIN(26, "GPIO26"),
PINCTRL_PIN(27, "GPIO27"),
PINCTRL_PIN(28, "GPIO28"),
PINCTRL_PIN(29, "GPIO29"),
PINCTRL_PIN(30, "GPIO30"),
PINCTRL_PIN(31, "GPIO31"),
PINCTRL_PIN(32, "UART3_TXD"),
PINCTRL_PIN(33, "UART3_RXD"),
PINCTRL_PIN(34, "UART3_RTS"),
PINCTRL_PIN(35, "UART3_CTS"),
PINCTRL_PIN(36, "NF_ALE"),
PINCTRL_PIN(37, "NF_CE0_N"),
PINCTRL_PIN(38, "NF_CE1_N"),
PINCTRL_PIN(39, "NF_CLE"),
PINCTRL_PIN(40, "NF_RE_N"),
PINCTRL_PIN(41, "NF_WE_N"),
PINCTRL_PIN(42, "NF_WP0_N"),
PINCTRL_PIN(43, "NF_WP1_N"),
PINCTRL_PIN(44, "NF_IO0"),
PINCTRL_PIN(45, "NF_IO1"),
PINCTRL_PIN(46, "NF_IO2"),
PINCTRL_PIN(47, "NF_IO3"),
PINCTRL_PIN(48, "NF_IO4"),
PINCTRL_PIN(49, "NF_IO5"),
PINCTRL_PIN(50, "NF_IO6"),
PINCTRL_PIN(51, "NF_IO7"),
PINCTRL_PIN(52, "NF_RB0_N"),
PINCTRL_PIN(53, "SDIO0_CLK"),
PINCTRL_PIN(54, "SDIO0_CMD"),
PINCTRL_PIN(55, "SDIO0_DAT0"),
PINCTRL_PIN(56, "SDIO0_DAT1"),
PINCTRL_PIN(57, "SDIO0_DAT2"),
PINCTRL_PIN(58, "SDIO0_DAT3"),
PINCTRL_PIN(59, "SDI0_CD"),
PINCTRL_PIN(60, "SDI0_WP"),
PINCTRL_PIN(61, "SDIO1_CLK"),
PINCTRL_PIN(62, "SDIO1_CMD"),
PINCTRL_PIN(63, "SDIO1_DAT0"),
PINCTRL_PIN(64, "SDIO1_DAT1"),
PINCTRL_PIN(65, "SDIO1_DAT2"),
PINCTRL_PIN(66, "SDIO1_DAT3"),
PINCTRL_PIN(67, "SDIO1_CD"),
PINCTRL_PIN(68, "SDIO1_WP"),
PINCTRL_PIN(69, "GBE_REFCLk"),
PINCTRL_PIN(70, "GBE_GTX_CLK"),
PINCTRL_PIN(71, "GBE_TX_CLK"),
PINCTRL_PIN(72, "GBE_TX_EN"),
PINCTRL_PIN(73, "GBE_TX_ER"),
PINCTRL_PIN(74, "GBE_TXD0"),
PINCTRL_PIN(75, "GBE_TXD1"),
PINCTRL_PIN(76, "GBE_TXD2"),
PINCTRL_PIN(77, "GBE_TXD3"),
PINCTRL_PIN(78, "GBE_TXD4"),
PINCTRL_PIN(79, "GBE_TXD5"),
PINCTRL_PIN(80, "GBE_TXD6"),
PINCTRL_PIN(81, "GBE_TXD7"),
PINCTRL_PIN(82, "GBE_RX_CLK"),
PINCTRL_PIN(83, "GBE_RX_DV"),
PINCTRL_PIN(84, "GBE_RX_ER"),
PINCTRL_PIN(85, "GBE_RXD0"),
PINCTRL_PIN(86, "GBE_RXD1"),
PINCTRL_PIN(87, "GBE_RXD2"),
PINCTRL_PIN(88, "GBE_RXD3"),
PINCTRL_PIN(89, "GBE_RXD4"),
PINCTRL_PIN(90, "GBE_RXD5"),
PINCTRL_PIN(91, "GBE_RXD6"),
PINCTRL_PIN(92, "GBE_RXD7"),
PINCTRL_PIN(93, "GBE_CRS"),
PINCTRL_PIN(94, "GBE_COL"),
PINCTRL_PIN(95, "GBE_MDC"),
PINCTRL_PIN(96, "GBE_MDIO"),
};
static const unsigned int cpuclkout_pins0[] = { 0 };
static const unsigned int udlclkout_pins0[] = { 1 };
static const unsigned int i2c1_pins0[] = { 2, 3 };
static const unsigned int i2c2_pins0[] = { 4, 5 };
static const unsigned int i2c3_pins0[] = { 6, 7 };
static const unsigned int i2s0_pins0[] = { 8, 9, 10, 11 };
static const unsigned int i2s1_pins0[] = { 12, 13, 14, 15 };
static const unsigned int i2srefclk_pins0[] = { 19 };
static const unsigned int spi0_pins0[] = { 12, 13, 14, 15 };
static const unsigned int spi1_pins0[] = { 16, 17, 18, 19 };
static const unsigned int pciedebug_pins0[] = { 12, 13, 14, 15 };
static const unsigned int uart0_pins0[] = { 16, 17, 18, 19, 20,
21, 22, 23, 24, 25 };
static const unsigned int uart0_pins1[] = { 20, 21, 22, 23 };
static const unsigned int uart1_pins0[] = { 24, 25, 26, 27 };
static const unsigned int uart2_pins0[] = { 26, 27, 28, 29, 30,
31, 32, 33, 34, 35 };
static const unsigned int uart2_pins1[] = { 28, 29, 30, 31 };
static const unsigned int uart3_pins0[] = { 32, 33, 34, 35 };
static const unsigned int uart4_pins0[] = { 20, 21, 22, 23 };
static const unsigned int uart5_pins0[] = { 28, 29, 30, 31 };
static const unsigned int nand_pins0[] = { 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52 };
static const unsigned int sdio0_pins0[] = { 53, 54, 55, 56, 57, 58, 59, 60 };
static const unsigned int sdio1_pins0[] = { 61, 62, 63, 64, 65, 66, 67, 68 };
static const unsigned int ethernet_pins0[] = { 69, 70, 71, 72, 73, 74, 75,
76, 77, 78, 79, 80, 81, 82,
83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96 };
static const struct artpec6_pin_group artpec6_pin_groups[] = {
{
.name = "cpuclkoutgrp0",
.pins = cpuclkout_pins0,
.num_pins = ARRAY_SIZE(cpuclkout_pins0),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "udlclkoutgrp0",
.pins = udlclkout_pins0,
.num_pins = ARRAY_SIZE(udlclkout_pins0),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "i2c1grp0",
.pins = i2c1_pins0,
.num_pins = ARRAY_SIZE(i2c1_pins0),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "i2c2grp0",
.pins = i2c2_pins0,
.num_pins = ARRAY_SIZE(i2c2_pins0),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "i2c3grp0",
.pins = i2c3_pins0,
.num_pins = ARRAY_SIZE(i2c3_pins0),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "i2s0grp0",
.pins = i2s0_pins0,
.num_pins = ARRAY_SIZE(i2s0_pins0),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "i2s1grp0",
.pins = i2s1_pins0,
.num_pins = ARRAY_SIZE(i2s1_pins0),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "i2srefclkgrp0",
.pins = i2srefclk_pins0,
.num_pins = ARRAY_SIZE(i2srefclk_pins0),
.config = ARTPEC6_CONFIG_3,
},
{
.name = "spi0grp0",
.pins = spi0_pins0,
.num_pins = ARRAY_SIZE(spi0_pins0),
.config = ARTPEC6_CONFIG_2,
},
{
.name = "spi1grp0",
.pins = spi1_pins0,
.num_pins = ARRAY_SIZE(spi1_pins0),
.config = ARTPEC6_CONFIG_2,
},
{
.name = "pciedebuggrp0",
.pins = pciedebug_pins0,
.num_pins = ARRAY_SIZE(pciedebug_pins0),
.config = ARTPEC6_CONFIG_3,
},
{
.name = "uart0grp0",
.pins = uart0_pins0,
.num_pins = ARRAY_SIZE(uart0_pins0),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "uart0grp1",
.pins = uart0_pins1,
.num_pins = ARRAY_SIZE(uart0_pins1),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "uart1grp0",
.pins = uart1_pins0,
.num_pins = ARRAY_SIZE(uart1_pins0),
.config = ARTPEC6_CONFIG_2,
},
{
.name = "uart2grp0",
.pins = uart2_pins0,
.num_pins = ARRAY_SIZE(uart2_pins0),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "uart2grp1",
.pins = uart2_pins1,
.num_pins = ARRAY_SIZE(uart2_pins1),
.config = ARTPEC6_CONFIG_1,
},
{
.name = "uart3grp0",
.pins = uart3_pins0,
.num_pins = ARRAY_SIZE(uart3_pins0),
.config = ARTPEC6_CONFIG_0,
},
{
.name = "uart4grp0",
.pins = uart4_pins0,
.num_pins = ARRAY_SIZE(uart4_pins0),
.config = ARTPEC6_CONFIG_2,
},
{
.name = "uart5grp0",
.pins = uart5_pins0,
.num_pins = ARRAY_SIZE(uart5_pins0),
.config = ARTPEC6_CONFIG_2,
},
{
.name = "uart5nocts",
.pins = uart5_pins0,
.num_pins = ARRAY_SIZE(uart5_pins0) - 1,
.config = ARTPEC6_CONFIG_2,
},
{
.name = "nandgrp0",
.pins = nand_pins0,
.num_pins = ARRAY_SIZE(nand_pins0),
.config = ARTPEC6_CONFIG_0,
},
{
.name = "sdio0grp0",
.pins = sdio0_pins0,
.num_pins = ARRAY_SIZE(sdio0_pins0),
.config = ARTPEC6_CONFIG_0,
},
{
.name = "sdio1grp0",
.pins = sdio1_pins0,
.num_pins = ARRAY_SIZE(sdio1_pins0),
.config = ARTPEC6_CONFIG_0,
},
{
.name = "ethernetgrp0",
.pins = ethernet_pins0,
.num_pins = ARRAY_SIZE(ethernet_pins0),
.config = ARTPEC6_CONFIG_0,
},
};
struct pin_register {
unsigned int start;
unsigned int end;
unsigned int reg_base;
};
/*
* The register map has two holes where the pin number
* no longer fits directly with the register offset.
* This table allows us to map this easily.
*/
static const struct pin_register pin_register[] = {
{ 0, 35, 0x0 }, /* 0x0 - 0x8c */
{ 36, 52, 0x100 }, /* 0x100 - 0x140 */
{ 53, 96, 0x180 }, /* 0x180 - 0x22c */
};
static unsigned int artpec6_pmx_reg_offset(unsigned int pin)
{
int i;
for (i = 0; i < ARRAY_SIZE(pin_register); i++) {
if (pin <= pin_register[i].end) {
return (pin - pin_register[i].start) * 4 +
pin_register[i].reg_base;
}
}
/*
* Anything we return here is wrong, but we can only
* get here if pin is outside registered range.
*/
pr_err("%s: Impossible pin %d\n", __func__, pin);
return 0;
}
static int artpec6_get_groups_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(artpec6_pin_groups);
}
static const char *artpec6_get_group_name(struct pinctrl_dev *pctldev,
unsigned int group)
{
return artpec6_pin_groups[group].name;
}
static int artpec6_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int group,
const unsigned int **pins,
unsigned int *num_pins)
{
*pins = (unsigned int *)artpec6_pin_groups[group].pins;
*num_pins = artpec6_pin_groups[group].num_pins;
return 0;
}
static int artpec6_pconf_drive_mA_to_field(unsigned int mA)
{
switch (mA) {
case ARTPEC6_DRIVE_4mA:
return ARTPEC6_DRIVE_4mA_SET;
case ARTPEC6_DRIVE_6mA:
return ARTPEC6_DRIVE_6mA_SET;
case ARTPEC6_DRIVE_8mA:
return ARTPEC6_DRIVE_8mA_SET;
case ARTPEC6_DRIVE_9mA:
return ARTPEC6_DRIVE_9mA_SET;
default:
return -EINVAL;
}
}
static unsigned int artpec6_pconf_drive_field_to_mA(int field)
{
switch (field) {
case ARTPEC6_DRIVE_4mA_SET:
return ARTPEC6_DRIVE_4mA;
case ARTPEC6_DRIVE_6mA_SET:
return ARTPEC6_DRIVE_6mA;
case ARTPEC6_DRIVE_8mA_SET:
return ARTPEC6_DRIVE_8mA;
case ARTPEC6_DRIVE_9mA_SET:
return ARTPEC6_DRIVE_9mA;
default:
/* Shouldn't happen */
return 0;
}
}
static struct pinctrl_ops artpec6_pctrl_ops = {
.get_group_pins = artpec6_get_group_pins,
.get_groups_count = artpec6_get_groups_count,
.get_group_name = artpec6_get_group_name,
.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
.dt_free_map = pinctrl_utils_free_map,
};
static const char * const gpiogrps[] = {
"cpuclkoutgrp0", "udlclkoutgrp0", "i2c1grp0", "i2c2grp0",
"i2c3grp0", "i2s0grp0", "i2s1grp0", "i2srefclkgrp0",
"spi0grp0", "spi1grp0", "pciedebuggrp0", "uart0grp0",
"uart0grp1", "uart1grp0", "uart2grp0", "uart2grp1",
"uart4grp0", "uart5grp0",
};
static const char * const cpuclkoutgrps[] = { "cpuclkoutgrp0" };
static const char * const udlclkoutgrps[] = { "udlclkoutgrp0" };
static const char * const i2c1grps[] = { "i2c1grp0" };
static const char * const i2c2grps[] = { "i2c2grp0" };
static const char * const i2c3grps[] = { "i2c3grp0" };
static const char * const i2s0grps[] = { "i2s0grp0" };
static const char * const i2s1grps[] = { "i2s1grp0" };
static const char * const i2srefclkgrps[] = { "i2srefclkgrp0" };
static const char * const spi0grps[] = { "spi0grp0" };
static const char * const spi1grps[] = { "spi1grp0" };
static const char * const pciedebuggrps[] = { "pciedebuggrp0" };
static const char * const uart0grps[] = { "uart0grp0", "uart0grp1" };
static const char * const uart1grps[] = { "uart1grp0" };
static const char * const uart2grps[] = { "uart2grp0", "uart2grp1" };
static const char * const uart3grps[] = { "uart3grp0" };
static const char * const uart4grps[] = { "uart4grp0" };
static const char * const uart5grps[] = { "uart5grp0", "uart5nocts" };
static const char * const nandgrps[] = { "nandgrp0" };
static const char * const sdio0grps[] = { "sdio0grp0" };
static const char * const sdio1grps[] = { "sdio1grp0" };
static const char * const ethernetgrps[] = { "ethernetgrp0" };
static const struct artpec6_pmx_func artpec6_pmx_functions[] = {
{
.name = "gpio",
.groups = gpiogrps,
.num_groups = ARRAY_SIZE(gpiogrps),
},
{
.name = "cpuclkout",
.groups = cpuclkoutgrps,
.num_groups = ARRAY_SIZE(cpuclkoutgrps),
},
{
.name = "udlclkout",
.groups = udlclkoutgrps,
.num_groups = ARRAY_SIZE(udlclkoutgrps),
},
{
.name = "i2c1",
.groups = i2c1grps,
.num_groups = ARRAY_SIZE(i2c1grps),
},
{
.name = "i2c2",
.groups = i2c2grps,
.num_groups = ARRAY_SIZE(i2c2grps),
},
{
.name = "i2c3",
.groups = i2c3grps,
.num_groups = ARRAY_SIZE(i2c3grps),
},
{
.name = "i2s0",
.groups = i2s0grps,
.num_groups = ARRAY_SIZE(i2s0grps),
},
{
.name = "i2s1",
.groups = i2s1grps,
.num_groups = ARRAY_SIZE(i2s1grps),
},
{
.name = "i2srefclk",
.groups = i2srefclkgrps,
.num_groups = ARRAY_SIZE(i2srefclkgrps),
},
{
.name = "spi0",
.groups = spi0grps,
.num_groups = ARRAY_SIZE(spi0grps),
},
{
.name = "spi1",
.groups = spi1grps,
.num_groups = ARRAY_SIZE(spi1grps),
},
{
.name = "pciedebug",
.groups = pciedebuggrps,
.num_groups = ARRAY_SIZE(pciedebuggrps),
},
{
.name = "uart0",
.groups = uart0grps,
.num_groups = ARRAY_SIZE(uart0grps),
},
{
.name = "uart1",
.groups = uart1grps,
.num_groups = ARRAY_SIZE(uart1grps),
},
{
.name = "uart2",
.groups = uart2grps,
.num_groups = ARRAY_SIZE(uart2grps),
},
{
.name = "uart3",
.groups = uart3grps,
.num_groups = ARRAY_SIZE(uart3grps),
},
{
.name = "uart4",
.groups = uart4grps,
.num_groups = ARRAY_SIZE(uart4grps),
},
{
.name = "uart5",
.groups = uart5grps,
.num_groups = ARRAY_SIZE(uart5grps),
},
{
.name = "nand",
.groups = nandgrps,
.num_groups = ARRAY_SIZE(nandgrps),
},
{
.name = "sdio0",
.groups = sdio0grps,
.num_groups = ARRAY_SIZE(sdio0grps),
},
{
.name = "sdio1",
.groups = sdio1grps,
.num_groups = ARRAY_SIZE(sdio1grps),
},
{
.name = "ethernet",
.groups = ethernetgrps,
.num_groups = ARRAY_SIZE(ethernetgrps),
},
};
static int artpec6_pmx_get_functions_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(artpec6_pmx_functions);
}
static const char *artpec6_pmx_get_fname(struct pinctrl_dev *pctldev,
unsigned int function)
{
return artpec6_pmx_functions[function].name;
}
static int artpec6_pmx_get_fgroups(struct pinctrl_dev *pctldev,
unsigned int function,
const char * const **groups,
unsigned int * const num_groups)
{
*groups = artpec6_pmx_functions[function].groups;
*num_groups = artpec6_pmx_functions[function].num_groups;
return 0;
}
static void artpec6_pmx_select_func(struct pinctrl_dev *pctldev,
unsigned int function, unsigned int group,
bool enable)
{
unsigned int regval, val;
unsigned int reg;
int i;
struct artpec6_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
for (i = 0; i < artpec6_pin_groups[group].num_pins; i++) {
/*
* Registers for pins above a ARTPEC6_MAX_MUXABLE
* do not have a SEL field and are always selected.
*/
if (artpec6_pin_groups[group].pins[i] > ARTPEC6_MAX_MUXABLE)
continue;
if (!strcmp(artpec6_pmx_get_fname(pctldev, function), "gpio")) {
/* GPIO is always config 0 */
val = ARTPEC6_CONFIG_0 << ARTPEC6_PINMUX_SEL_SHIFT;
} else {
if (enable)
val = artpec6_pin_groups[group].config
<< ARTPEC6_PINMUX_SEL_SHIFT;
else
val = ARTPEC6_CONFIG_0
<< ARTPEC6_PINMUX_SEL_SHIFT;
}
reg = artpec6_pmx_reg_offset(artpec6_pin_groups[group].pins[i]);
regval = readl(pmx->base + reg);
regval &= ~ARTPEC6_PINMUX_SEL_MASK;
regval |= val;
writel(regval, pmx->base + reg);
}
}
int artpec6_pmx_enable(struct pinctrl_dev *pctldev, unsigned int function,
unsigned int group)
{
struct artpec6_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
dev_dbg(pmx->dev, "enabling %s function for pin group %s\n",
artpec6_pmx_get_fname(pctldev, function),
artpec6_get_group_name(pctldev, group));
artpec6_pmx_select_func(pctldev, function, group, true);
return 0;
}
void artpec6_pmx_disable(struct pinctrl_dev *pctldev, unsigned int function,
unsigned int group)
{
struct artpec6_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
dev_dbg(pmx->dev, "disabling %s function for pin group %s\n",
artpec6_pmx_get_fname(pctldev, function),
artpec6_get_group_name(pctldev, group));
artpec6_pmx_select_func(pctldev, function, group, false);
}
static int artpec6_pmx_request_gpio(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int pin)
{
struct artpec6_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
unsigned int reg = artpec6_pmx_reg_offset(pin);
u32 val;
if (pin >= 32)
return -EINVAL;
val = readl_relaxed(pmx->base + reg);
val &= ~ARTPEC6_PINMUX_SEL_MASK;
val |= ARTPEC6_CONFIG_0 << ARTPEC6_PINMUX_SEL_SHIFT;
writel_relaxed(val, pmx->base + reg);
return 0;
}
static const struct pinmux_ops artpec6_pmx_ops = {
.get_functions_count = artpec6_pmx_get_functions_count,
.get_function_name = artpec6_pmx_get_fname,
.get_function_groups = artpec6_pmx_get_fgroups,
.set_mux = artpec6_pmx_enable,
.gpio_request_enable = artpec6_pmx_request_gpio,
};
static int artpec6_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config)
{
struct artpec6_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
unsigned int regval;
/* Check for valid pin */
if (pin >= pmx->num_pins) {
dev_dbg(pmx->dev, "pinconf is not supported for pin %s\n",
pmx->pins[pin].name);
return -ENOTSUPP;
}
dev_dbg(pmx->dev, "getting configuration for pin %s\n",
pmx->pins[pin].name);
/* Read pin register values */
regval = readl(pmx->base + artpec6_pmx_reg_offset(pin));
/* If valid, get configuration for parameter */
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
if (!(regval & ARTPEC6_PINMUX_UDC1_MASK))
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN:
if (regval & ARTPEC6_PINMUX_UDC1_MASK)
return -EINVAL;
regval = regval & ARTPEC6_PINMUX_UDC0_MASK;
if ((param == PIN_CONFIG_BIAS_PULL_UP && !regval) ||
(param == PIN_CONFIG_BIAS_PULL_DOWN && regval))
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
regval = (regval & ARTPEC6_PINMUX_DRV_MASK)
>> ARTPEC6_PINMUX_DRV_SHIFT;
regval = artpec6_pconf_drive_field_to_mA(regval);
*config = pinconf_to_config_packed(param, regval);
break;
default:
return -ENOTSUPP;
}
return 0;
}
/*
* Valid combinations of param and arg:
*
* param arg
* PIN_CONFIG_BIAS_DISABLE: x (disable bias)
* PIN_CONFIG_BIAS_PULL_UP: 1 (pull up bias + enable)
* PIN_CONFIG_BIAS_PULL_DOWN: 1 (pull down bias + enable)
* PIN_CONFIG_DRIVE_STRENGTH: x (4mA, 6mA, 8mA, 9mA)
*
* All other args are invalid. All other params are not supported.
*/
static int artpec6_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct artpec6_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param;
unsigned int arg;
unsigned int regval;
unsigned int *reg;
int i;
/* Check for valid pin */
if (pin >= pmx->num_pins) {
dev_dbg(pmx->dev, "pinconf is not supported for pin %s\n",
pmx->pins[pin].name);
return -ENOTSUPP;
}
dev_dbg(pmx->dev, "setting configuration for pin %s\n",
pmx->pins[pin].name);
reg = pmx->base + artpec6_pmx_reg_offset(pin);
/* For each config */
for (i = 0; i < num_configs; i++) {
int drive;
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
regval = readl(reg);
regval |= (1 << ARTPEC6_PINMUX_UDC1_SHIFT);
writel(regval, reg);
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (arg != 1) {
dev_dbg(pctldev->dev, "%s: arg %u out of range\n",
__func__, arg);
return -EINVAL;
}
regval = readl(reg);
regval |= (arg << ARTPEC6_PINMUX_UDC0_SHIFT);
regval &= ~ARTPEC6_PINMUX_UDC1_MASK; /* Enable */
writel(regval, reg);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (arg != 1) {
dev_dbg(pctldev->dev, "%s: arg %u out of range\n",
__func__, arg);
return -EINVAL;
}
regval = readl(reg);
regval &= ~(arg << ARTPEC6_PINMUX_UDC0_SHIFT);
regval &= ~ARTPEC6_PINMUX_UDC1_MASK; /* Enable */
writel(regval, reg);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
drive = artpec6_pconf_drive_mA_to_field(arg);
if (drive < 0) {
dev_dbg(pctldev->dev, "%s: arg %u out of range\n",
__func__, arg);
return -EINVAL;
}
regval = readl(reg);
regval &= ~ARTPEC6_PINMUX_DRV_MASK;
regval |= (drive << ARTPEC6_PINMUX_DRV_SHIFT);
writel(regval, reg);
break;
default:
dev_dbg(pmx->dev, "parameter not supported\n");
return -ENOTSUPP;
}
}
return 0;
}
static int artpec6_pconf_group_set(struct pinctrl_dev *pctldev,
unsigned int group, unsigned long *configs,
unsigned int num_configs)
{
unsigned int num_pins, current_pin;
int ret;
dev_dbg(pctldev->dev, "setting group %s configuration\n",
artpec6_get_group_name(pctldev, group));
num_pins = artpec6_pin_groups[group].num_pins;
for (current_pin = 0; current_pin < num_pins; current_pin++) {
ret = artpec6_pconf_set(pctldev,
artpec6_pin_groups[group].pins[current_pin],
configs, num_configs);
if (ret < 0)
return ret;
}
return 0;
}
static const struct pinconf_ops artpec6_pconf_ops = {
.is_generic = true,
.pin_config_get = artpec6_pconf_get,
.pin_config_set = artpec6_pconf_set,
.pin_config_group_set = artpec6_pconf_group_set,
};
static struct pinctrl_desc artpec6_desc = {
.name = "artpec6-pinctrl",
.owner = THIS_MODULE,
.pins = artpec6_pins,
.npins = ARRAY_SIZE(artpec6_pins),
.pctlops = &artpec6_pctrl_ops,
.pmxops = &artpec6_pmx_ops,
.confops = &artpec6_pconf_ops,
};
/* The reset values say 4mA, but we want 8mA as default. */
static void artpec6_pmx_reset(struct artpec6_pmx *pmx)
{
void __iomem *base = pmx->base;
int i;
for (i = 0; i < ARTPEC6_LAST_PIN; i++) {
u32 val;
val = readl_relaxed(base + artpec6_pmx_reg_offset(i));
val &= ~ARTPEC6_PINMUX_DRV_MASK;
val |= ARTPEC6_DRIVE_8mA_SET << ARTPEC6_PINMUX_DRV_SHIFT;
writel_relaxed(val, base + artpec6_pmx_reg_offset(i));
}
}
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)
return -ENOMEM;
pmx->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pmx->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pmx->base))
return PTR_ERR(pmx->base);
artpec6_pmx_reset(pmx);
pmx->pins = artpec6_pins;
pmx->num_pins = ARRAY_SIZE(artpec6_pins);
pmx->functions = artpec6_pmx_functions;
pmx->num_functions = ARRAY_SIZE(artpec6_pmx_functions);
pmx->pin_groups = artpec6_pin_groups;
pmx->num_pin_groups = ARRAY_SIZE(artpec6_pin_groups);
pmx->pctl = pinctrl_register(&artpec6_desc, &pdev->dev, pmx);
if (IS_ERR(pmx->pctl)) {
dev_err(&pdev->dev, "could not register pinctrl driver\n");
return PTR_ERR(pmx->pctl);
}
platform_set_drvdata(pdev, pmx);
dev_info(&pdev->dev, "initialised Axis ARTPEC-6 pinctrl driver\n");
return 0;
}
static int artpec6_pmx_remove(struct platform_device *pdev)
{
struct artpec6_pmx *pmx = platform_get_drvdata(pdev);
pinctrl_unregister(pmx->pctl);
return 0;
}
static const struct of_device_id artpec6_pinctrl_match[] = {
{ .compatible = "axis,artpec6-pinctrl" },
{},
};
static struct platform_driver artpec6_pmx_driver = {
.driver = {
.name = "artpec6-pinctrl",
.of_match_table = artpec6_pinctrl_match,
},
.probe = artpec6_pmx_probe,
.remove = artpec6_pmx_remove,
};
static int __init artpec6_pmx_init(void)
{
return platform_driver_register(&artpec6_pmx_driver);
}
arch_initcall(artpec6_pmx_init);

View File

@ -126,7 +126,11 @@ struct atmel_pioctrl {
struct irq_domain *irq_domain;
int *irqs;
unsigned *pm_wakeup_sources;
unsigned *pm_suspend_backup;
struct {
u32 imr;
u32 odsr;
u32 cfgr[ATMEL_PIO_NPINS_PER_BANK];
} *pm_suspend_backup;
struct device *dev;
struct device_node *node;
};
@ -830,17 +834,26 @@ static int __maybe_unused atmel_pctrl_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
int i;
int i, j;
/*
* For each bank, save IMR to restore it later and disable all GPIO
* interrupts excepting the ones marked as wakeup sources.
*/
for (i = 0; i < atmel_pioctrl->nbanks; i++) {
atmel_pioctrl->pm_suspend_backup[i] =
atmel_pioctrl->pm_suspend_backup[i].imr =
atmel_gpio_read(atmel_pioctrl, i, ATMEL_PIO_IMR);
atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_IDR,
~atmel_pioctrl->pm_wakeup_sources[i]);
atmel_pioctrl->pm_suspend_backup[i].odsr =
atmel_gpio_read(atmel_pioctrl, i, ATMEL_PIO_ODSR);
for (j = 0; j < ATMEL_PIO_NPINS_PER_BANK; j++) {
atmel_gpio_write(atmel_pioctrl, i,
ATMEL_PIO_MSKR, BIT(j));
atmel_pioctrl->pm_suspend_backup[i].cfgr[j] =
atmel_gpio_read(atmel_pioctrl, i,
ATMEL_PIO_CFGR);
}
}
return 0;
@ -850,11 +863,20 @@ static int __maybe_unused atmel_pctrl_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
int i;
int i, j;
for (i = 0; i < atmel_pioctrl->nbanks; i++)
for (i = 0; i < atmel_pioctrl->nbanks; i++) {
atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_IER,
atmel_pioctrl->pm_suspend_backup[i]);
atmel_pioctrl->pm_suspend_backup[i].imr);
atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_SODR,
atmel_pioctrl->pm_suspend_backup[i].odsr);
for (j = 0; j < ATMEL_PIO_NPINS_PER_BANK; j++) {
atmel_gpio_write(atmel_pioctrl, i,
ATMEL_PIO_MSKR, BIT(j));
atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_CFGR,
atmel_pioctrl->pm_suspend_backup[i].cfgr[j]);
}
}
return 0;
}

View File

@ -59,7 +59,7 @@
#define GPIO_LS_SYNC 0x60
enum rockchip_pinctrl_type {
RK1108,
RV1108,
RK2928,
RK3066B,
RK3188,
@ -75,6 +75,8 @@ enum rockchip_pinctrl_type {
#define IOMUX_WIDTH_4BIT BIT(1)
#define IOMUX_SOURCE_PMU BIT(2)
#define IOMUX_UNROUTED BIT(3)
#define IOMUX_WIDTH_3BIT BIT(4)
#define IOMUX_RECALCED BIT(5)
/**
* @type: iomux variant using IOMUX_* constants
@ -141,6 +143,9 @@ struct rockchip_drv {
* @gpio_chip: gpiolib chip
* @grange: gpio range
* @slock: spinlock for the gpio bank
* @irq_lock: bus lock for irq chip
* @new_irqs: newly configured irqs which must be muxed as GPIOs in
* irq_bus_sync_unlock()
*/
struct rockchip_pin_bank {
void __iomem *reg_base;
@ -161,8 +166,10 @@ struct rockchip_pin_bank {
struct irq_domain *domain;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range grange;
spinlock_t slock;
raw_spinlock_t slock;
u32 toggle_edge_mode;
struct mutex irq_lock;
u32 new_irqs;
};
#define PIN_BANK(id, pins, label) \
@ -304,6 +311,11 @@ struct rockchip_pin_ctrl {
void (*drv_calc_reg)(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit);
void (*iomux_recalc)(u8 bank_num, int pin, int *reg,
u8 *bit, int *mask);
int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit);
};
struct rockchip_pin_config {
@ -355,6 +367,22 @@ struct rockchip_pinctrl {
unsigned int nfunctions;
};
/**
* struct rockchip_mux_recalced_data: represent a pin iomux data.
* @num: bank number.
* @pin: pin number.
* @bit: index at register.
* @reg: register offset.
* @mask: mask bit
*/
struct rockchip_mux_recalced_data {
u8 num;
u8 pin;
u8 reg;
u8 bit;
u8 mask;
};
static struct regmap_config rockchip_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
@ -514,13 +542,57 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
* Hardware access
*/
static const struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = {
{
.num = 2,
.pin = 12,
.reg = 0x24,
.bit = 8,
.mask = 0x3
}, {
.num = 2,
.pin = 15,
.reg = 0x28,
.bit = 0,
.mask = 0x7
}, {
.num = 2,
.pin = 23,
.reg = 0x30,
.bit = 14,
.mask = 0x3
},
};
static void rk3328_recalc_mux(u8 bank_num, int pin, int *reg,
u8 *bit, int *mask)
{
const struct rockchip_mux_recalced_data *data = NULL;
int i;
for (i = 0; i < ARRAY_SIZE(rk3328_mux_recalced_data); i++)
if (rk3328_mux_recalced_data[i].num == bank_num &&
rk3328_mux_recalced_data[i].pin == pin) {
data = &rk3328_mux_recalced_data[i];
break;
}
if (!data)
return;
*reg = data->reg;
*mask = data->mask;
*bit = data->bit;
}
static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
{
struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl;
int iomux_num = (pin / 8);
struct regmap *regmap;
unsigned int val;
int reg, ret, mask;
int reg, ret, mask, mux_type;
u8 bit;
if (iomux_num > 3)
@ -538,16 +610,26 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
? info->regmap_pmu : info->regmap_base;
/* get basic quadrupel of mux registers and the correct reg inside */
mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
mux_type = bank->iomux[iomux_num].type;
reg = bank->iomux[iomux_num].offset;
if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
if (mux_type & IOMUX_WIDTH_4BIT) {
if ((pin % 8) >= 4)
reg += 0x4;
bit = (pin % 4) * 4;
mask = 0xf;
} else if (mux_type & IOMUX_WIDTH_3BIT) {
if ((pin % 8) >= 5)
reg += 0x4;
bit = (pin % 8 % 5) * 3;
mask = 0x7;
} else {
bit = (pin % 8) * 2;
mask = 0x3;
}
if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
ctrl->iomux_recalc(bank->bank_num, pin, &reg, &bit, &mask);
ret = regmap_read(regmap, reg, &val);
if (ret)
return ret;
@ -555,6 +637,31 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
return ((val >> bit) & mask);
}
static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
int pin, int mux)
{
struct rockchip_pinctrl *info = bank->drvdata;
int iomux_num = (pin / 8);
if (iomux_num > 3)
return -EINVAL;
if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
dev_err(info->dev, "pin %d is unrouted\n", pin);
return -EINVAL;
}
if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
if (mux != RK_FUNC_GPIO) {
dev_err(info->dev,
"pin %d only supports a gpio mux\n", pin);
return -ENOTSUPP;
}
}
return 0;
}
/*
* Set a new mux function for a pin.
*
@ -571,30 +678,19 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
{
struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl;
int iomux_num = (pin / 8);
struct regmap *regmap;
int reg, ret, mask;
unsigned long flags;
int reg, ret, mask, mux_type;
u8 bit;
u32 data, rmask;
if (iomux_num > 3)
return -EINVAL;
ret = rockchip_verify_mux(bank, pin, mux);
if (ret < 0)
return ret;
if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
dev_err(info->dev, "pin %d is unrouted\n", pin);
return -EINVAL;
}
if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
if (mux != RK_FUNC_GPIO) {
dev_err(info->dev,
"pin %d only supports a gpio mux\n", pin);
return -ENOTSUPP;
} else {
return 0;
}
}
if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
return 0;
dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
bank->bank_num, pin, mux);
@ -603,35 +699,41 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
? info->regmap_pmu : info->regmap_base;
/* get basic quadrupel of mux registers and the correct reg inside */
mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
mux_type = bank->iomux[iomux_num].type;
reg = bank->iomux[iomux_num].offset;
if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
if (mux_type & IOMUX_WIDTH_4BIT) {
if ((pin % 8) >= 4)
reg += 0x4;
bit = (pin % 4) * 4;
mask = 0xf;
} else if (mux_type & IOMUX_WIDTH_3BIT) {
if ((pin % 8) >= 5)
reg += 0x4;
bit = (pin % 8 % 5) * 3;
mask = 0x7;
} else {
bit = (pin % 8) * 2;
mask = 0x3;
}
spin_lock_irqsave(&bank->slock, flags);
if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
ctrl->iomux_recalc(bank->bank_num, pin, &reg, &bit, &mask);
data = (mask << (bit + 16));
rmask = data | (data >> 16);
data |= (mux & mask) << bit;
ret = regmap_update_bits(regmap, reg, rmask, data);
spin_unlock_irqrestore(&bank->slock, flags);
return ret;
}
#define RK1108_PULL_PMU_OFFSET 0x10
#define RK1108_PULL_OFFSET 0x110
#define RK1108_PULL_PINS_PER_REG 8
#define RK1108_PULL_BITS_PER_PIN 2
#define RK1108_PULL_BANK_STRIDE 16
#define RV1108_PULL_PMU_OFFSET 0x10
#define RV1108_PULL_OFFSET 0x110
#define RV1108_PULL_PINS_PER_REG 8
#define RV1108_PULL_BITS_PER_PIN 2
#define RV1108_PULL_BANK_STRIDE 16
static void rk1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit)
{
@ -640,27 +742,27 @@ static void rk1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
/* The first 24 pins of the first bank are located in PMU */
if (bank->bank_num == 0) {
*regmap = info->regmap_pmu;
*reg = RK1108_PULL_PMU_OFFSET;
*reg = RV1108_PULL_PMU_OFFSET;
} else {
*reg = RK1108_PULL_OFFSET;
*reg = RV1108_PULL_OFFSET;
*regmap = info->regmap_base;
/* correct the offset, as we're starting with the 2nd bank */
*reg -= 0x10;
*reg += bank->bank_num * RK1108_PULL_BANK_STRIDE;
*reg += bank->bank_num * RV1108_PULL_BANK_STRIDE;
}
*reg += ((pin_num / RK1108_PULL_PINS_PER_REG) * 4);
*bit = (pin_num % RK1108_PULL_PINS_PER_REG);
*bit *= RK1108_PULL_BITS_PER_PIN;
*reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4);
*bit = (pin_num % RV1108_PULL_PINS_PER_REG);
*bit *= RV1108_PULL_BITS_PER_PIN;
}
#define RK1108_DRV_PMU_OFFSET 0x20
#define RK1108_DRV_GRF_OFFSET 0x210
#define RK1108_DRV_BITS_PER_PIN 2
#define RK1108_DRV_PINS_PER_REG 8
#define RK1108_DRV_BANK_STRIDE 16
#define RV1108_DRV_PMU_OFFSET 0x20
#define RV1108_DRV_GRF_OFFSET 0x210
#define RV1108_DRV_BITS_PER_PIN 2
#define RV1108_DRV_PINS_PER_REG 8
#define RV1108_DRV_BANK_STRIDE 16
static void rk1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit)
{
@ -669,19 +771,19 @@ static void rk1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
/* The first 24 pins of the first bank are located in PMU */
if (bank->bank_num == 0) {
*regmap = info->regmap_pmu;
*reg = RK1108_DRV_PMU_OFFSET;
*reg = RV1108_DRV_PMU_OFFSET;
} else {
*regmap = info->regmap_base;
*reg = RK1108_DRV_GRF_OFFSET;
*reg = RV1108_DRV_GRF_OFFSET;
/* correct the offset, as we're starting with the 2nd bank */
*reg -= 0x10;
*reg += bank->bank_num * RK1108_DRV_BANK_STRIDE;
*reg += bank->bank_num * RV1108_DRV_BANK_STRIDE;
}
*reg += ((pin_num / RK1108_DRV_PINS_PER_REG) * 4);
*bit = pin_num % RK1108_DRV_PINS_PER_REG;
*bit *= RK1108_DRV_BITS_PER_PIN;
*reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4);
*bit = pin_num % RV1108_DRV_PINS_PER_REG;
*bit *= RV1108_DRV_BITS_PER_PIN;
}
#define RK2928_PULL_OFFSET 0x118
@ -1047,7 +1149,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
unsigned long flags;
int reg, ret, i;
u32 data, rmask, rmask_bits, temp;
u8 bit;
@ -1075,8 +1176,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
return ret;
}
spin_lock_irqsave(&bank->slock, flags);
switch (drv_type) {
case DRV_TYPE_IO_1V8_3V0_AUTO:
case DRV_TYPE_IO_3V3_ONLY:
@ -1097,17 +1196,14 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
rmask = BIT(15) | BIT(31);
data |= BIT(31);
ret = regmap_update_bits(regmap, reg, rmask, data);
if (ret) {
spin_unlock_irqrestore(&bank->slock, flags);
if (ret)
return ret;
}
rmask = 0x3 | (0x3 << 16);
temp |= (0x3 << 16);
reg += 0x4;
ret = regmap_update_bits(regmap, reg, rmask, temp);
spin_unlock_irqrestore(&bank->slock, flags);
return ret;
case 18 ... 21:
/* setting fully enclosed in the second register */
@ -1115,7 +1211,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
bit -= 16;
break;
default:
spin_unlock_irqrestore(&bank->slock, flags);
dev_err(info->dev, "unsupported bit: %d for pinctrl drive type: %d\n",
bit, drv_type);
return -EINVAL;
@ -1127,7 +1222,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
rmask_bits = RK3288_DRV_BITS_PER_PIN;
break;
default:
spin_unlock_irqrestore(&bank->slock, flags);
dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
drv_type);
return -EINVAL;
@ -1139,7 +1233,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
data |= (ret << bit);
ret = regmap_update_bits(regmap, reg, rmask, data);
spin_unlock_irqrestore(&bank->slock, flags);
return ret;
}
@ -1183,7 +1276,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
return !(data & BIT(bit))
? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
: PIN_CONFIG_BIAS_DISABLE;
case RK1108:
case RV1108:
case RK3188:
case RK3288:
case RK3368:
@ -1206,7 +1299,6 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
int reg, ret, i, pull_type;
unsigned long flags;
u8 bit;
u32 data, rmask;
@ -1221,16 +1313,12 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
switch (ctrl->type) {
case RK2928:
spin_lock_irqsave(&bank->slock, flags);
data = BIT(bit + 16);
if (pull == PIN_CONFIG_BIAS_DISABLE)
data |= BIT(bit);
ret = regmap_write(regmap, reg, data);
spin_unlock_irqrestore(&bank->slock, flags);
break;
case RK1108:
case RV1108:
case RK3188:
case RK3288:
case RK3368:
@ -1251,16 +1339,12 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
return ret;
}
spin_lock_irqsave(&bank->slock, flags);
/* enable the write to the equivalent lower bits */
data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
rmask = data | (data >> 16);
data |= (ret << bit);
ret = regmap_update_bits(regmap, reg, rmask, data);
spin_unlock_irqrestore(&bank->slock, flags);
break;
default:
dev_err(info->dev, "unsupported pinctrl type\n");
@ -1270,6 +1354,73 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
return ret;
}
#define RK3328_SCHMITT_BITS_PER_PIN 1
#define RK3328_SCHMITT_PINS_PER_REG 16
#define RK3328_SCHMITT_BANK_STRIDE 8
#define RK3328_SCHMITT_GRF_OFFSET 0x380
static int rk3328_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 = RK3328_SCHMITT_GRF_OFFSET;
*reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE;
*reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4);
*bit = pin_num % RK3328_SCHMITT_PINS_PER_REG;
return 0;
}
static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
{
struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
int reg, ret;
u8 bit;
u32 data;
ret = ctrl->schmitt_calc_reg(bank, pin_num, &regmap, &reg, &bit);
if (ret)
return ret;
ret = regmap_read(regmap, reg, &data);
if (ret)
return ret;
data >>= bit;
return data & 0x1;
}
static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
int pin_num, int enable)
{
struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
int reg, ret;
u8 bit;
u32 data, rmask;
dev_dbg(info->dev, "setting input schmitt of GPIO%d-%d to %d\n",
bank->bank_num, pin_num, enable);
ret = ctrl->schmitt_calc_reg(bank, pin_num, &regmap, &reg, &bit);
if (ret)
return ret;
/* enable the write to the equivalent lower bits */
data = BIT(bit + 16) | (enable << bit);
rmask = BIT(bit + 16) | BIT(bit);
return regmap_update_bits(regmap, reg, rmask, data);
}
/*
* Pinmux_ops handling
*/
@ -1366,7 +1517,7 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
return ret;
clk_enable(bank->clk);
spin_lock_irqsave(&bank->slock, flags);
raw_spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
/* set bit to 1 for output, 0 for input */
@ -1376,7 +1527,7 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
data &= ~BIT(pin);
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
spin_unlock_irqrestore(&bank->slock, flags);
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->clk);
return 0;
@ -1420,7 +1571,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
pull == PIN_CONFIG_BIAS_DISABLE);
case RK3066B:
return pull ? false : true;
case RK1108:
case RV1108:
case RK3188:
case RK3288:
case RK3368:
@ -1489,6 +1640,15 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
if (rc < 0)
return rc;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
if (!info->ctrl->schmitt_calc_reg)
return -ENOTSUPP;
rc = rockchip_set_schmitt(bank,
pin - bank->pin_base, arg);
if (rc < 0)
return rc;
break;
default:
return -ENOTSUPP;
break;
@ -1547,6 +1707,16 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
if (rc < 0)
return rc;
arg = rc;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
if (!info->ctrl->schmitt_calc_reg)
return -ENOTSUPP;
rc = rockchip_get_schmitt(bank, pin - bank->pin_base);
if (rc < 0)
return rc;
arg = rc;
break;
default:
@ -1807,7 +1977,7 @@ static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
u32 data;
clk_enable(bank->clk);
spin_lock_irqsave(&bank->slock, flags);
raw_spin_lock_irqsave(&bank->slock, flags);
data = readl(reg);
data &= ~BIT(offset);
@ -1815,7 +1985,7 @@ static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
data |= BIT(offset);
writel(data, reg);
spin_unlock_irqrestore(&bank->slock, flags);
raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->clk);
}
@ -1927,7 +2097,7 @@ static void rockchip_irq_demux(struct irq_desc *desc)
data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT);
do {
spin_lock_irqsave(&bank->slock, flags);
raw_spin_lock_irqsave(&bank->slock, flags);
polarity = readl_relaxed(bank->reg_base +
GPIO_INT_POLARITY);
@ -1938,7 +2108,7 @@ static void rockchip_irq_demux(struct irq_desc *desc)
writel(polarity,
bank->reg_base + GPIO_INT_POLARITY);
spin_unlock_irqrestore(&bank->slock, flags);
raw_spin_unlock_irqrestore(&bank->slock, flags);
data_old = data;
data = readl_relaxed(bank->reg_base +
@ -1964,25 +2134,26 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
int ret;
/* make sure the pin is configured as gpio input */
ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
ret = rockchip_verify_mux(bank, d->hwirq, RK_FUNC_GPIO);
if (ret < 0)
return ret;
clk_enable(bank->clk);
spin_lock_irqsave(&bank->slock, flags);
bank->new_irqs |= mask;
raw_spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
data &= ~mask;
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
spin_unlock_irqrestore(&bank->slock, flags);
raw_spin_unlock_irqrestore(&bank->slock, flags);
if (type & IRQ_TYPE_EDGE_BOTH)
irq_set_handler_locked(d, handle_edge_irq);
else
irq_set_handler_locked(d, handle_level_irq);
spin_lock_irqsave(&bank->slock, flags);
raw_spin_lock_irqsave(&bank->slock, flags);
irq_gc_lock(gc);
level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL);
@ -2025,8 +2196,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
break;
default:
irq_gc_unlock(gc);
spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->clk);
raw_spin_unlock_irqrestore(&bank->slock, flags);
return -EINVAL;
}
@ -2034,8 +2204,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY);
irq_gc_unlock(gc);
spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->clk);
raw_spin_unlock_irqrestore(&bank->slock, flags);
return 0;
}
@ -2061,7 +2230,7 @@ static void rockchip_irq_resume(struct irq_data *d)
clk_disable(bank->clk);
}
static void rockchip_irq_gc_mask_clr_bit(struct irq_data *d)
static void rockchip_irq_enable(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct rockchip_pin_bank *bank = gc->private;
@ -2070,7 +2239,7 @@ static void rockchip_irq_gc_mask_clr_bit(struct irq_data *d)
irq_gc_mask_clr_bit(d);
}
static void rockchip_irq_gc_mask_set_bit(struct irq_data *d)
static void rockchip_irq_disable(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct rockchip_pin_bank *bank = gc->private;
@ -2079,6 +2248,34 @@ static void rockchip_irq_gc_mask_set_bit(struct irq_data *d)
clk_disable(bank->clk);
}
static void rockchip_irq_bus_lock(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct rockchip_pin_bank *bank = gc->private;
clk_enable(bank->clk);
mutex_lock(&bank->irq_lock);
}
static void rockchip_irq_bus_sync_unlock(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct rockchip_pin_bank *bank = gc->private;
while (bank->new_irqs) {
unsigned int irq = __ffs(bank->new_irqs);
int ret;
ret = rockchip_set_mux(bank, irq, RK_FUNC_GPIO);
WARN_ON(ret < 0);
bank->new_irqs &= ~BIT(irq);
}
mutex_unlock(&bank->irq_lock);
clk_disable(bank->clk);
}
static int rockchip_interrupts_register(struct platform_device *pdev,
struct rockchip_pinctrl *info)
{
@ -2137,13 +2334,17 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
gc->chip_types[0].regs.mask = GPIO_INTMASK;
gc->chip_types[0].regs.ack = GPIO_PORTS_EOI;
gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
gc->chip_types[0].chip.irq_mask = rockchip_irq_gc_mask_set_bit;
gc->chip_types[0].chip.irq_unmask =
rockchip_irq_gc_mask_clr_bit;
gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
gc->chip_types[0].chip.irq_enable = rockchip_irq_enable;
gc->chip_types[0].chip.irq_disable = rockchip_irq_disable;
gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend;
gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;
gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;
gc->chip_types[0].chip.irq_bus_lock = rockchip_irq_bus_lock;
gc->chip_types[0].chip.irq_bus_sync_unlock =
rockchip_irq_bus_sync_unlock;
gc->wake_enabled = IRQ_MSK(bank->nr_pins);
irq_set_chained_handler_and_data(bank->irq,
@ -2316,7 +2517,8 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
int bank_pins = 0;
spin_lock_init(&bank->slock);
raw_spin_lock_init(&bank->slock);
mutex_init(&bank->irq_lock);
bank->drvdata = d;
bank->pin_base = ctrl->nr_pins;
ctrl->nr_pins += bank->nr_pins;
@ -2359,7 +2561,8 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
* Increase offset according to iomux width.
* 4bit iomux'es are spread over two registers.
*/
inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4;
inc = (iom->type & (IOMUX_WIDTH_4BIT |
IOMUX_WIDTH_3BIT)) ? 8 : 4;
if (iom->type & IOMUX_SOURCE_PMU)
pmu_offs += inc;
else
@ -2518,7 +2721,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
return 0;
}
static struct rockchip_pin_bank rk1108_pin_banks[] = {
static struct rockchip_pin_bank rv1108_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU,
@ -2528,15 +2731,15 @@ static struct rockchip_pin_bank rk1108_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0),
};
static struct rockchip_pin_ctrl rk1108_pin_ctrl = {
.pin_banks = rk1108_pin_banks,
.nr_banks = ARRAY_SIZE(rk1108_pin_banks),
.label = "RK1108-GPIO",
.type = RK1108,
static struct rockchip_pin_ctrl rv1108_pin_ctrl = {
.pin_banks = rv1108_pin_banks,
.nr_banks = ARRAY_SIZE(rv1108_pin_banks),
.label = "RV1108-GPIO",
.type = RV1108,
.grf_mux_offset = 0x10,
.pmu_mux_offset = 0x0,
.pull_calc_reg = rk1108_calc_pull_reg_and_bit,
.drv_calc_reg = rk1108_calc_drv_reg_and_bit,
.pull_calc_reg = rv1108_calc_pull_reg_and_bit,
.drv_calc_reg = rv1108_calc_drv_reg_and_bit,
};
static struct rockchip_pin_bank rk2928_pin_banks[] = {
@ -2679,6 +2882,32 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
.drv_calc_reg = rk3288_calc_drv_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),
PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0,
IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
0),
PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
IOMUX_WIDTH_3BIT,
IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
0,
0),
};
static struct rockchip_pin_ctrl rk3328_pin_ctrl = {
.pin_banks = rk3328_pin_banks,
.nr_banks = ARRAY_SIZE(rk3328_pin_banks),
.label = "RK3328-GPIO",
.type = RK3288,
.grf_mux_offset = 0x0,
.pull_calc_reg = rk3228_calc_pull_reg_and_bit,
.drv_calc_reg = rk3228_calc_drv_reg_and_bit,
.iomux_recalc = rk3328_recalc_mux,
.schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit,
};
static struct rockchip_pin_bank rk3368_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU,
@ -2768,8 +2997,8 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
};
static const struct of_device_id rockchip_pinctrl_dt_match[] = {
{ .compatible = "rockchip,rk1108-pinctrl",
.data = (void *)&rk1108_pin_ctrl },
{ .compatible = "rockchip,rv1108-pinctrl",
.data = (void *)&rv1108_pin_ctrl },
{ .compatible = "rockchip,rk2928-pinctrl",
.data = (void *)&rk2928_pin_ctrl },
{ .compatible = "rockchip,rk3036-pinctrl",
@ -2784,6 +3013,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
.data = (void *)&rk3228_pin_ctrl },
{ .compatible = "rockchip,rk3288-pinctrl",
.data = (void *)&rk3288_pin_ctrl },
{ .compatible = "rockchip,rk3328-pinctrl",
.data = (void *)&rk3328_pin_ctrl },
{ .compatible = "rockchip,rk3368-pinctrl",
.data = (void *)&rk3368_pin_ctrl },
{ .compatible = "rockchip,rk3399-pinctrl",

View File

@ -763,7 +763,7 @@ struct function_desc *pinmux_generic_get_function(struct pinctrl_dev *pctldev,
EXPORT_SYMBOL_GPL(pinmux_generic_get_function);
/**
* pinmux_generic_get_function_groups() - gets the function groups
* pinmux_generic_add_function() - adds a function group
* @pctldev: pin controller device
* @name: name of the function
* @groups: array of pin groups

View File

@ -35,10 +35,14 @@ static struct msm_pinctrl_soc_data qdf2xxx_pinctrl;
/* A reasonable limit to the number of GPIOS */
#define MAX_GPIOS 256
/* maximum size of each gpio name (enough room for "gpioXXX" + null) */
#define NAME_SIZE 8
static int qdf2xxx_pinctrl_probe(struct platform_device *pdev)
{
struct pinctrl_pin_desc *pins;
struct msm_pingroup *groups;
char (*names)[NAME_SIZE];
unsigned int i;
u32 num_gpios;
int ret;
@ -59,15 +63,21 @@ static int qdf2xxx_pinctrl_probe(struct platform_device *pdev)
sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
groups = devm_kcalloc(&pdev->dev, num_gpios,
sizeof(struct msm_pingroup), GFP_KERNEL);
names = devm_kcalloc(&pdev->dev, num_gpios, NAME_SIZE, GFP_KERNEL);
if (!pins || !groups)
if (!pins || !groups || !names)
return -ENOMEM;
for (i = 0; i < num_gpios; i++) {
pins[i].number = i;
snprintf(names[i], NAME_SIZE, "gpio%u", i);
groups[i].npins = 1,
pins[i].number = i;
pins[i].name = names[i];
groups[i].npins = 1;
groups[i].name = names[i];
groups[i].pins = &pins[i].number;
groups[i].ctl_reg = 0x10000 * i;
groups[i].io_reg = 0x04 + 0x10000 * i;
groups[i].intr_cfg_reg = 0x08 + 0x10000 * i;

View File

@ -777,6 +777,7 @@ exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
{
struct samsung_retention_ctrl *ctrl;
struct regmap *pmu_regs;
int i;
ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
@ -794,6 +795,10 @@ exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
ctrl->enable = exynos_retention_enable;
ctrl->disable = exynos_retention_disable;
/* Ensure that retention is disabled on driver init */
for (i = 0; i < ctrl->nr_regs; i++)
regmap_write(pmu_regs, ctrl->regs[i], ctrl->value);
return ctrl;
}
@ -1546,6 +1551,54 @@ static const struct samsung_pin_bank_data exynos5433_pin_banks9[] __initconst =
EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00),
};
/* PMU pin retention groups registers for Exynos5433 (without audio & fsys) */
static const u32 exynos5433_retention_regs[] = {
EXYNOS5433_PAD_RETENTION_TOP_OPTION,
EXYNOS5433_PAD_RETENTION_UART_OPTION,
EXYNOS5433_PAD_RETENTION_EBIA_OPTION,
EXYNOS5433_PAD_RETENTION_EBIB_OPTION,
EXYNOS5433_PAD_RETENTION_SPI_OPTION,
EXYNOS5433_PAD_RETENTION_MIF_OPTION,
EXYNOS5433_PAD_RETENTION_USBXTI_OPTION,
EXYNOS5433_PAD_RETENTION_BOOTLDO_OPTION,
EXYNOS5433_PAD_RETENTION_UFS_OPTION,
EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION,
};
static const struct samsung_retention_data exynos5433_retention_data __initconst = {
.regs = exynos5433_retention_regs,
.nr_regs = ARRAY_SIZE(exynos5433_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.refcnt = &exynos_shared_retention_refcnt,
.init = exynos_retention_init,
};
/* PMU retention control for audio pins can be tied to audio pin bank */
static const u32 exynos5433_audio_retention_regs[] = {
EXYNOS5433_PAD_RETENTION_AUD_OPTION,
};
static const struct samsung_retention_data exynos5433_audio_retention_data __initconst = {
.regs = exynos5433_audio_retention_regs,
.nr_regs = ARRAY_SIZE(exynos5433_audio_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.init = exynos_retention_init,
};
/* PMU retention control for mmc pins can be tied to fsys pin bank */
static const u32 exynos5433_fsys_retention_regs[] = {
EXYNOS5433_PAD_RETENTION_MMC0_OPTION,
EXYNOS5433_PAD_RETENTION_MMC1_OPTION,
EXYNOS5433_PAD_RETENTION_MMC2_OPTION,
};
static const struct samsung_retention_data exynos5433_fsys_retention_data __initconst = {
.regs = exynos5433_fsys_retention_regs,
.nr_regs = ARRAY_SIZE(exynos5433_fsys_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.init = exynos_retention_init,
};
/*
* Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes
* ten gpio/pin-mux/pinconfig controllers.
@ -1559,6 +1612,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.nr_ext_resources = 1,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5433_pin_banks1,
@ -1566,6 +1620,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_audio_retention_data,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5433_pin_banks2,
@ -1573,6 +1628,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5433_pin_banks3,
@ -1580,6 +1636,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 4 data */
.pin_banks = exynos5433_pin_banks4,
@ -1587,6 +1644,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 5 data */
.pin_banks = exynos5433_pin_banks5,
@ -1594,6 +1652,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_fsys_retention_data,
}, {
/* pin-controller instance 6 data */
.pin_banks = exynos5433_pin_banks6,
@ -1601,6 +1660,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 7 data */
.pin_banks = exynos5433_pin_banks7,
@ -1608,6 +1668,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 8 data */
.pin_banks = exynos5433_pin_banks8,
@ -1615,6 +1676,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 9 data */
.pin_banks = exynos5433_pin_banks9,
@ -1622,6 +1684,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
},
};

View File

@ -566,13 +566,11 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc,
{
const struct samsung_pin_bank_type *type;
struct samsung_pin_bank *bank;
struct samsung_pinctrl_drv_data *drvdata;
void __iomem *reg;
u32 data, mask, shift;
bank = gpiochip_get_data(gc);
type = bank->type;
drvdata = bank->drvdata;
reg = bank->pctl_base + bank->pctl_offset
+ type->reg_offset[PINCFG_TYPE_FUNC];
@ -884,7 +882,7 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
pin_bank->grange.id = bank;
pin_bank->grange.pin_base = drvdata->pin_base
+ pin_bank->pin_base;
pin_bank->grange.base = pin_bank->gpio_chip.base;
pin_bank->grange.base = pin_bank->grange.pin_base;
pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
pin_bank->grange.gc = &pin_bank->gpio_chip;
pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange);
@ -893,6 +891,19 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
return 0;
}
/* unregister the pinctrl interface with the pinctrl subsystem */
static int samsung_pinctrl_unregister(struct platform_device *pdev,
struct samsung_pinctrl_drv_data *drvdata)
{
struct samsung_pin_bank *bank = drvdata->pin_banks;
int i;
for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
pinctrl_remove_gpio_range(drvdata->pctl_dev, &bank->grange);
return 0;
}
static const struct gpio_chip samsung_gpiolib_chip = {
.request = gpiochip_generic_request,
.free = gpiochip_generic_free,
@ -917,39 +928,21 @@ static int samsung_gpiolib_register(struct platform_device *pdev,
bank->gpio_chip = samsung_gpiolib_chip;
gc = &bank->gpio_chip;
gc->base = drvdata->pin_base + bank->pin_base;
gc->base = bank->grange.base;
gc->ngpio = bank->nr_pins;
gc->parent = &pdev->dev;
gc->of_node = bank->of_node;
gc->label = bank->name;
ret = gpiochip_add_data(gc, bank);
ret = devm_gpiochip_add_data(&pdev->dev, gc, bank);
if (ret) {
dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
gc->label, ret);
goto fail;
return ret;
}
}
return 0;
fail:
for (--i, --bank; i >= 0; --i, --bank)
gpiochip_remove(&bank->gpio_chip);
return ret;
}
/* unregister the gpiolib interface with the gpiolib subsystem */
static int samsung_gpiolib_unregister(struct platform_device *pdev,
struct samsung_pinctrl_drv_data *drvdata)
{
struct samsung_pin_bank *bank = drvdata->pin_banks;
int i;
for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
gpiochip_remove(&bank->gpio_chip);
return 0;
}
/* retrieve the soc specific data */
@ -1069,13 +1062,13 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
return PTR_ERR(drvdata->retention_ctrl);
}
ret = samsung_gpiolib_register(pdev, drvdata);
ret = samsung_pinctrl_register(pdev, drvdata);
if (ret)
return ret;
ret = samsung_pinctrl_register(pdev, drvdata);
ret = samsung_gpiolib_register(pdev, drvdata);
if (ret) {
samsung_gpiolib_unregister(pdev, drvdata);
samsung_pinctrl_unregister(pdev, drvdata);
return ret;
}

View File

@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7792) += pfc-r8a7792.o
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_SH7203) += pfc-sh7203.o
obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o

View File

@ -586,6 +586,9 @@ static int sh_pfc_probe(struct platform_device *pdev)
ret = info->ops->init(pfc);
if (ret < 0)
return ret;
/* .init() may have overridden pfc->info */
info = pfc->info;
}
/* Enable dummy states for those platforms without pinctrl support */

View File

@ -203,7 +203,7 @@ enum {
/* IPSR6 */
FN_AUDIO_CLKB, FN_STP_OPWM_0_B, FN_MSIOF1_SCK_B,
FN_SCIF_CLK, FN_BPFCLK_E,
FN_SCIF_CLK, FN_DVC_MUTE, FN_BPFCLK_E,
FN_AUDIO_CLKC, FN_SCIFB0_SCK_C, FN_MSIOF1_SYNC_B, FN_RX2,
FN_SCIFA2_RXD, FN_FMIN_E,
FN_AUDIO_CLKOUT, FN_MSIOF1_SS1_B, FN_TX2, FN_SCIFA2_TXD,
@ -573,7 +573,7 @@ enum {
/* IPSR6 */
AUDIO_CLKB_MARK, STP_OPWM_0_B_MARK, MSIOF1_SCK_B_MARK,
SCIF_CLK_MARK, BPFCLK_E_MARK,
SCIF_CLK_MARK, DVC_MUTE_MARK, BPFCLK_E_MARK,
AUDIO_CLKC_MARK, SCIFB0_SCK_C_MARK, MSIOF1_SYNC_B_MARK, RX2_MARK,
SCIFA2_RXD_MARK, FMIN_E_MARK,
AUDIO_CLKOUT_MARK, MSIOF1_SS1_B_MARK, TX2_MARK, SCIFA2_TXD_MARK,
@ -1010,14 +1010,17 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP4_12_10, SCL2, SEL_IIC2_0),
PINMUX_IPSR_MSEL(IP4_12_10, GPS_CLK_B, SEL_GPS_1),
PINMUX_IPSR_MSEL(IP4_12_10, GLO_Q0_D, SEL_GPS_3),
PINMUX_IPSR_MSEL(IP4_12_10, HSCK1_E, SEL_HSCIF1_4),
PINMUX_IPSR_GPSR(IP4_15_13, SSI_WS2),
PINMUX_IPSR_MSEL(IP4_15_13, SDA2, SEL_IIC2_0),
PINMUX_IPSR_MSEL(IP4_15_13, GPS_SIGN_B, SEL_GPS_1),
PINMUX_IPSR_MSEL(IP4_15_13, RX2_E, SEL_SCIF2_4),
PINMUX_IPSR_MSEL(IP4_15_13, GLO_Q1_D, SEL_GPS_3),
PINMUX_IPSR_MSEL(IP4_15_13, HCTS1_N_E, SEL_HSCIF1_4),
PINMUX_IPSR_GPSR(IP4_18_16, SSI_SDATA2),
PINMUX_IPSR_MSEL(IP4_18_16, GPS_MAG_B, SEL_GPS_1),
PINMUX_IPSR_MSEL(IP4_18_16, TX2_E, SEL_SCIF2_4),
PINMUX_IPSR_MSEL(IP4_18_16, HRTS1_N_E, SEL_HSCIF1_4),
PINMUX_IPSR_GPSR(IP4_19, SSI_SCK34),
PINMUX_IPSR_GPSR(IP4_20, SSI_WS34),
PINMUX_IPSR_GPSR(IP4_21, SSI_SDATA3),
@ -1090,6 +1093,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP6_2_0, STP_OPWM_0_B, SEL_SSP_1),
PINMUX_IPSR_MSEL(IP6_2_0, MSIOF1_SCK_B, SEL_SOF1_1),
PINMUX_IPSR_MSEL(IP6_2_0, SCIF_CLK, SEL_SCIF_0),
PINMUX_IPSR_GPSR(IP6_2_0, DVC_MUTE),
PINMUX_IPSR_MSEL(IP6_2_0, BPFCLK_E, SEL_FM_4),
PINMUX_IPSR_GPSR(IP6_5_3, AUDIO_CLKC),
PINMUX_IPSR_MSEL(IP6_5_3, SCIFB0_SCK_C, SEL_SCIFB_2),
@ -1099,7 +1103,7 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP6_5_3, FMIN_E, SEL_FM_4),
PINMUX_IPSR_GPSR(IP6_7_6, AUDIO_CLKOUT),
PINMUX_IPSR_MSEL(IP6_7_6, MSIOF1_SS1_B, SEL_SOF1_1),
PINMUX_IPSR_MSEL(IP6_5_3, TX2, SEL_SCIF2_0),
PINMUX_IPSR_MSEL(IP6_7_6, TX2, SEL_SCIF2_0),
PINMUX_IPSR_MSEL(IP6_7_6, SCIFA2_TXD, SEL_SCIFA2_0),
PINMUX_IPSR_GPSR(IP6_9_8, IRQ0),
PINMUX_IPSR_MSEL(IP6_9_8, SCIFB1_RXD_D, SEL_SCIFB1_3),
@ -5707,7 +5711,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
},
{ PINMUX_CFG_REG_VAR("IPSR2", 0xE6060028, 32,
2, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 3) {
/* IP2_31_20 [2] */
/* IP2_31_30 [2] */
0, 0, 0, 0,
/* IP2_29_27 [3] */
FN_EX_CS3_N, FN_ATADIR0_N, FN_MSIOF2_TXD,
@ -5727,7 +5731,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
/* IP2_15_13 [3] */
FN_A24, FN_DREQ2, FN_IO3, FN_TX1, FN_SCIFA1_TXD,
0, 0, 0,
/* IP2_12_0 [3] */
/* IP2_12_10 [3] */
FN_A23, FN_IO2, FN_BPFCLK_B, FN_RX0, FN_SCIFA0_RXD,
0, 0, 0,
/* IP2_9_7 [3] */
@ -5896,7 +5900,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
0, 0,
/* IP6_2_0 [3] */
FN_AUDIO_CLKB, FN_STP_OPWM_0_B, FN_MSIOF1_SCK_B,
FN_SCIF_CLK, 0, FN_BPFCLK_E,
FN_SCIF_CLK, FN_DVC_MUTE, FN_BPFCLK_E,
0, 0, }
},
{ PINMUX_CFG_REG_VAR("IPSR7", 0xE606003C, 32,
@ -6038,7 +6042,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
/* IP10_24_22 [3] */
FN_VI0_R1, FN_VI2_DATA2, FN_GLO_I1_B, FN_TS_SCK0_C, FN_ATAG1_N,
0, 0, 0,
/* IP10_21_29 [3] */
/* IP10_21_19 [3] */
FN_VI0_R0, FN_VI2_DATA1, FN_GLO_I0_B,
FN_TS_SDATA0_C, FN_ATACS11_N,
0, 0, 0,

View File

@ -281,8 +281,8 @@ enum {
FN_AVB_AVTP_CAPTURE, FN_ETH_CRS_DV_B, FN_SSI_WS1, FN_SCIF1_TXD_B,
FN_IIC1_SDA_C, FN_VI1_DATA0, FN_CAN0_TX_D, FN_AVB_AVTP_MATCH,
FN_ETH_RX_ER_B, FN_SSI_SDATA1, FN_HSCIF1_HRX_B, FN_SDATA, FN_VI1_DATA1,
FN_ATAG0_N, FN_ETH_RXD0_B, FN_SSI_SCK2, FN_HSCIF1_HTX_B, FN_VI1_DATA2,
FN_MDATA, FN_ATAWR0_N, FN_ETH_RXD1_B,
FN_ATAWR0_N, FN_ETH_RXD0_B, FN_SSI_SCK2, FN_HSCIF1_HTX_B, FN_VI1_DATA2,
FN_MDATA, FN_ATAG0_N, FN_ETH_RXD1_B,
/* IPSR13 */
FN_SSI_WS2, FN_HSCIF1_HCTS_N_B, FN_SCIFA0_RXD_D, FN_VI1_DATA3, FN_SCKZ,
@ -575,8 +575,8 @@ enum {
ETH_CRS_DV_B_MARK, SSI_WS1_MARK, SCIF1_TXD_B_MARK, IIC1_SDA_C_MARK,
VI1_DATA0_MARK, CAN0_TX_D_MARK, AVB_AVTP_MATCH_MARK, ETH_RX_ER_B_MARK,
SSI_SDATA1_MARK, HSCIF1_HRX_B_MARK, VI1_DATA1_MARK, SDATA_MARK,
ATAG0_N_MARK, ETH_RXD0_B_MARK, SSI_SCK2_MARK, HSCIF1_HTX_B_MARK,
VI1_DATA2_MARK, MDATA_MARK, ATAWR0_N_MARK, ETH_RXD1_B_MARK,
ATAWR0_N_MARK, ETH_RXD0_B_MARK, SSI_SCK2_MARK, HSCIF1_HTX_B_MARK,
VI1_DATA2_MARK, MDATA_MARK, ATAG0_N_MARK, ETH_RXD1_B_MARK,
/* IPSR13 */
SSI_WS2_MARK, HSCIF1_HCTS_N_B_MARK, SCIFA0_RXD_D_MARK, VI1_DATA3_MARK,
@ -1413,13 +1413,13 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP12_26_24, HSCIF1_HRX_B, SEL_HSCIF1_1),
PINMUX_IPSR_GPSR(IP12_26_24, VI1_DATA1),
PINMUX_IPSR_MSEL(IP12_26_24, SDATA, SEL_FSN_0),
PINMUX_IPSR_GPSR(IP12_26_24, ATAG0_N),
PINMUX_IPSR_GPSR(IP12_26_24, ATAWR0_N),
PINMUX_IPSR_MSEL(IP12_26_24, ETH_RXD0_B, SEL_ETH_1),
PINMUX_IPSR_MSEL(IP12_29_27, SSI_SCK2, SEL_SSI2_0),
PINMUX_IPSR_MSEL(IP12_29_27, HSCIF1_HTX_B, SEL_HSCIF1_1),
PINMUX_IPSR_GPSR(IP12_29_27, VI1_DATA2),
PINMUX_IPSR_MSEL(IP12_29_27, MDATA, SEL_FSN_0),
PINMUX_IPSR_GPSR(IP12_29_27, ATAWR0_N),
PINMUX_IPSR_GPSR(IP12_29_27, ATAG0_N),
PINMUX_IPSR_MSEL(IP12_29_27, ETH_RXD1_B, SEL_ETH_1),
/* IPSR13 */
@ -4938,10 +4938,10 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
0, 0, 0, 0,
/* IP12_29_27 [3] */
FN_SSI_SCK2, FN_HSCIF1_HTX_B, FN_VI1_DATA2, FN_MDATA,
FN_ATAWR0_N, FN_ETH_RXD1_B, 0, 0,
FN_ATAG0_N, FN_ETH_RXD1_B, 0, 0,
/* IP12_26_24 [3] */
FN_SSI_SDATA1, FN_HSCIF1_HRX_B, FN_VI1_DATA1, FN_SDATA,
FN_ATAG0_N, FN_ETH_RXD0_B, 0, 0,
FN_ATAWR0_N, FN_ETH_RXD0_B, 0, 0,
/* IP12_23_21 [3] */
FN_SSI_WS1, FN_SCIF1_TXD_B, FN_IIC1_SDA_C, FN_VI1_DATA0,
FN_CAN0_TX_D, FN_AVB_AVTP_MATCH, FN_ETH_RX_ER_B, 0,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -267,6 +267,7 @@ extern const struct sh_pfc_soc_info r8a7792_pinmux_info;
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 sh7203_pinmux_info;
extern const struct sh_pfc_soc_info sh7264_pinmux_info;

View File

@ -352,7 +352,7 @@ struct atlas7_gpio_chip {
void __iomem *reg;
struct clk *clk;
int nbank;
spinlock_t lock;
raw_spinlock_t lock;
struct gpio_chip chip;
struct atlas7_gpio_bank banks[0];
};
@ -5650,13 +5650,13 @@ static void atlas7_gpio_irq_ack(struct irq_data *d)
pin_in_bank = d->hwirq - bank->gpio_offset;
ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank);
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
val = readl(ctrl_reg);
/* clear interrupt status */
writel(val, ctrl_reg);
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
}
static void __atlas7_gpio_irq_mask(struct atlas7_gpio_chip *a7gc, int idx)
@ -5681,11 +5681,11 @@ static void atlas7_gpio_irq_mask(struct irq_data *d)
struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
__atlas7_gpio_irq_mask(a7gc, d->hwirq);
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
}
static void atlas7_gpio_irq_unmask(struct irq_data *d)
@ -5701,14 +5701,14 @@ static void atlas7_gpio_irq_unmask(struct irq_data *d)
pin_in_bank = d->hwirq - bank->gpio_offset;
ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank);
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
val = readl(ctrl_reg);
val &= ~ATLAS7_GPIO_CTL_INTR_STATUS_MASK;
val |= ATLAS7_GPIO_CTL_INTR_EN_MASK;
writel(val, ctrl_reg);
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
}
static int atlas7_gpio_irq_type(struct irq_data *d,
@ -5725,7 +5725,7 @@ static int atlas7_gpio_irq_type(struct irq_data *d,
pin_in_bank = d->hwirq - bank->gpio_offset;
ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank);
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
val = readl(ctrl_reg);
val &= ~(ATLAS7_GPIO_CTL_INTR_STATUS_MASK |
@ -5768,7 +5768,7 @@ static int atlas7_gpio_irq_type(struct irq_data *d,
writel(val, ctrl_reg);
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return 0;
}
@ -5863,7 +5863,7 @@ static int atlas7_gpio_request(struct gpio_chip *chip,
if (pinctrl_request_gpio(chip->base + gpio))
return -ENODEV;
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
/*
* default status:
@ -5872,7 +5872,7 @@ static int atlas7_gpio_request(struct gpio_chip *chip,
__atlas7_gpio_set_input(a7gc, gpio);
__atlas7_gpio_irq_mask(a7gc, gpio);
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return 0;
}
@ -5883,12 +5883,12 @@ static void atlas7_gpio_free(struct gpio_chip *chip,
struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip);
unsigned long flags;
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
__atlas7_gpio_irq_mask(a7gc, gpio);
__atlas7_gpio_set_input(a7gc, gpio);
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
pinctrl_free_gpio(chip->base + gpio);
}
@ -5899,11 +5899,11 @@ static int atlas7_gpio_direction_input(struct gpio_chip *chip,
struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip);
unsigned long flags;
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
__atlas7_gpio_set_input(a7gc, gpio);
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return 0;
}
@ -5936,11 +5936,11 @@ static int atlas7_gpio_direction_output(struct gpio_chip *chip,
struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip);
unsigned long flags;
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
__atlas7_gpio_set_output(a7gc, gpio, value);
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return 0;
}
@ -5956,11 +5956,11 @@ static int atlas7_gpio_get_value(struct gpio_chip *chip,
bank = atlas7_gpio_to_bank(a7gc, gpio);
pin_in_bank = gpio - bank->gpio_offset;
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
val = readl(ATLAS7_GPIO_CTRL(bank, pin_in_bank));
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return !!(val & ATLAS7_GPIO_CTL_DATAIN_MASK);
}
@ -5978,7 +5978,7 @@ static void atlas7_gpio_set_value(struct gpio_chip *chip,
pin_in_bank = gpio - bank->gpio_offset;
ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank);
spin_lock_irqsave(&a7gc->lock, flags);
raw_spin_lock_irqsave(&a7gc->lock, flags);
ctrl = readl(ctrl_reg);
if (value)
@ -5987,7 +5987,7 @@ static void atlas7_gpio_set_value(struct gpio_chip *chip,
ctrl &= ~ATLAS7_GPIO_CTL_DATAOUT_MASK;
writel(ctrl, ctrl_reg);
spin_unlock_irqrestore(&a7gc->lock, flags);
raw_spin_unlock_irqrestore(&a7gc->lock, flags);
}
static const struct of_device_id atlas7_gpio_ids[] = {
@ -6036,7 +6036,7 @@ static int atlas7_gpio_probe(struct platform_device *pdev)
}
a7gc->nbank = nbank;
spin_lock_init(&a7gc->lock);
raw_spin_lock_init(&a7gc->lock);
/* Setup GPIO Chip */
chip = &a7gc->chip;

View File

@ -14,6 +14,12 @@ config PINCTRL_STM32F429
default MACH_STM32F429
select PINCTRL_STM32
config PINCTRL_STM32F469
bool "STMicroelectronics STM32F469 pin control" if COMPILE_TEST && !MACH_STM32F469
depends on OF && IRQ_DOMAIN_HIERARCHY
default MACH_STM32F469
select PINCTRL_STM32
config PINCTRL_STM32F746
bool "STMicroelectronics STM32F746 pin control" if COMPILE_TEST && !MACH_STM32F746
depends on OF && IRQ_DOMAIN_HIERARCHY

View File

@ -3,5 +3,6 @@ obj-$(CONFIG_PINCTRL_STM32) += pinctrl-stm32.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_STM32F429) += pinctrl-stm32f429.o
obj-$(CONFIG_PINCTRL_STM32F469) += pinctrl-stm32f469.o
obj-$(CONFIG_PINCTRL_STM32F746) += pinctrl-stm32f746.o
obj-$(CONFIG_PINCTRL_STM32H743) += pinctrl-stm32h743.o

View File

@ -71,6 +71,7 @@ struct stm32_gpio_bank {
struct pinctrl_gpio_range range;
struct fwnode_handle *fwnode;
struct irq_domain *domain;
u32 bank_nr;
};
struct stm32_pinctrl {
@ -138,6 +139,17 @@ static inline void __stm32_gpio_set(struct stm32_gpio_bank *bank,
static int stm32_gpio_request(struct gpio_chip *chip, unsigned offset)
{
struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
struct pinctrl_gpio_range *range;
int pin = offset + (bank->bank_nr * STM32_GPIO_PINS_PER_BANK);
range = pinctrl_find_gpio_range_from_pin_nolock(pctl->pctl_dev, pin);
if (!range) {
dev_err(pctl->dev, "pin %d not in range.\n", pin);
return -EINVAL;
}
return pinctrl_request_gpio(chip->base + offset);
}
@ -235,7 +247,7 @@ static void stm32_gpio_domain_activate(struct irq_domain *d,
struct stm32_gpio_bank *bank = d->host_data;
struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
regmap_field_write(pctl->irqmux[irq_data->hwirq], bank->range.id);
regmap_field_write(pctl->irqmux[irq_data->hwirq], bank->bank_nr);
gpiochip_lock_as_irq(&bank->gpio_chip, irq_data->hwirq);
}
@ -589,7 +601,7 @@ static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev,
}
range = pinctrl_find_gpio_range_from_pin(pctldev, g->pin);
bank = gpio_range_to_bank(range);
bank = gpiochip_get_data(range->gc);
pin = stm32_gpio_pin(g->pin);
mode = stm32_gpio_get_mode(function);
@ -604,7 +616,7 @@ static int stm32_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned gpio,
bool input)
{
struct stm32_gpio_bank *bank = gpio_range_to_bank(range);
struct stm32_gpio_bank *bank = gpiochip_get_data(range->gc);
int pin = stm32_gpio_pin(gpio);
stm32_pmx_set_mode(bank, pin, !input, 0);
@ -762,7 +774,7 @@ static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev,
int offset, ret = 0;
range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
bank = gpio_range_to_bank(range);
bank = gpiochip_get_data(range->gc);
offset = stm32_gpio_pin(pin);
switch (param) {
@ -843,7 +855,7 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev,
bool val;
range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin);
bank = gpio_range_to_bank(range);
bank = gpiochip_get_data(range->gc);
offset = stm32_gpio_pin(pin);
stm32_pmx_get_mode(bank, offset, &mode, &alt);
@ -898,13 +910,14 @@ static const struct pinconf_ops stm32_pconf_ops = {
static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
struct device_node *np)
{
int bank_nr = pctl->nbanks;
struct stm32_gpio_bank *bank = &pctl->banks[bank_nr];
struct stm32_gpio_bank *bank = &pctl->banks[pctl->nbanks];
struct pinctrl_gpio_range *range = &bank->range;
struct of_phandle_args args;
struct device *dev = pctl->dev;
struct resource res;
struct reset_control *rstc;
int err, npins;
int npins = STM32_GPIO_PINS_PER_BANK;
int bank_nr, err;
rstc = of_reset_control_get(np, NULL);
if (!IS_ERR(rstc))
@ -929,28 +942,33 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
return err;
}
npins = pctl->match_data->npins;
npins -= bank_nr * STM32_GPIO_PINS_PER_BANK;
if (npins < 0)
return -EINVAL;
else if (npins > STM32_GPIO_PINS_PER_BANK)
npins = STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip = stm32_gpio_template;
of_property_read_string(np, "st,bank-name", &bank->gpio_chip.label);
if (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args)) {
bank_nr = args.args[1] / STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip.base = args.args[1];
} else {
bank_nr = pctl->nbanks;
bank->gpio_chip.base = bank_nr * STM32_GPIO_PINS_PER_BANK;
range->name = bank->gpio_chip.label;
range->id = bank_nr;
range->pin_base = range->id * STM32_GPIO_PINS_PER_BANK;
range->base = range->id * STM32_GPIO_PINS_PER_BANK;
range->npins = npins;
range->gc = &bank->gpio_chip;
pinctrl_add_gpio_range(pctl->pctl_dev,
&pctl->banks[bank_nr].range);
}
bank->gpio_chip.base = bank_nr * STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip.ngpio = npins;
bank->gpio_chip.of_node = np;
bank->gpio_chip.parent = dev;
bank->bank_nr = bank_nr;
spin_lock_init(&bank->lock);
of_property_read_string(np, "st,bank-name", &range->name);
bank->gpio_chip.label = range->name;
range->id = bank_nr;
range->pin_base = range->base = range->id * STM32_GPIO_PINS_PER_BANK;
range->npins = bank->gpio_chip.ngpio;
range->gc = &bank->gpio_chip;
/* create irq hierarchical domain */
bank->fwnode = of_node_to_fwnode(np);
@ -967,7 +985,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
return err;
}
dev_info(dev, "%s bank added\n", range->name);
dev_info(dev, "%s bank added\n", bank->gpio_chip.label);
return 0;
}
@ -1086,30 +1104,6 @@ int stm32_pctl_probe(struct platform_device *pdev)
return ret;
}
for_each_child_of_node(np, child)
if (of_property_read_bool(child, "gpio-controller"))
banks++;
if (!banks) {
dev_err(dev, "at least one GPIO bank is required\n");
return -EINVAL;
}
pctl->banks = devm_kcalloc(dev, banks, sizeof(*pctl->banks),
GFP_KERNEL);
if (!pctl->banks)
return -ENOMEM;
for_each_child_of_node(np, child) {
if (of_property_read_bool(child, "gpio-controller")) {
ret = stm32_gpiolib_register_bank(pctl, child);
if (ret)
return ret;
pctl->nbanks++;
}
}
pins = devm_kcalloc(&pdev->dev, pctl->match_data->npins, sizeof(*pins),
GFP_KERNEL);
if (!pins)
@ -1129,13 +1123,34 @@ int stm32_pctl_probe(struct platform_device *pdev)
pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, &pctl->pctl_desc,
pctl);
if (IS_ERR(pctl->pctl_dev)) {
dev_err(&pdev->dev, "Failed pinctrl registration\n");
return PTR_ERR(pctl->pctl_dev);
}
for (i = 0; i < pctl->nbanks; i++)
pinctrl_add_gpio_range(pctl->pctl_dev, &pctl->banks[i].range);
for_each_child_of_node(np, child)
if (of_property_read_bool(child, "gpio-controller"))
banks++;
if (!banks) {
dev_err(dev, "at least one GPIO bank is required\n");
return -EINVAL;
}
pctl->banks = devm_kcalloc(dev, banks, sizeof(*pctl->banks),
GFP_KERNEL);
if (!pctl->banks)
return -ENOMEM;
for_each_child_of_node(np, child) {
if (of_property_read_bool(child, "gpio-controller")) {
ret = stm32_gpiolib_register_bank(pctl, child);
if (ret)
return ret;
pctl->nbanks++;
}
}
dev_info(dev, "Pinctrl STM32 initialized\n");

View File

@ -1584,4 +1584,8 @@ static struct platform_driver stm32f429_pinctrl_driver = {
},
};
builtin_platform_driver(stm32f429_pinctrl_driver);
static int __init stm32f429_pinctrl_init(void)
{
return platform_driver_register(&stm32f429_pinctrl_driver);
}
arch_initcall(stm32f429_pinctrl_init);

File diff suppressed because it is too large Load Diff

View File

@ -1678,4 +1678,9 @@ static struct platform_driver stm32f746_pinctrl_driver = {
.of_match_table = stm32f746_pctrl_match,
},
};
builtin_platform_driver(stm32f746_pinctrl_driver);
static int __init stm32f746_pinctrl_init(void)
{
return platform_driver_register(&stm32f746_pinctrl_driver);
}
arch_initcall(stm32f746_pinctrl_init);

View File

@ -1977,4 +1977,8 @@ static struct platform_driver stm32h743_pinctrl_driver = {
},
};
builtin_platform_driver(stm32h743_pinctrl_driver);
static int __init stm32h743_pinctrl_init(void)
{
return platform_driver_register(&stm32h743_pinctrl_driver);
}
arch_initcall(stm32h743_pinctrl_init);

View File

@ -4,6 +4,7 @@ config PINCTRL_SUNXI
bool
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
config PINCTRL_SUN4I_A10
def_bool MACH_SUN4I
@ -48,8 +49,8 @@ config PINCTRL_SUN8I_H3
select PINCTRL_SUNXI
config PINCTRL_SUN8I_H3_R
def_bool MACH_SUN8I
select PINCTRL_SUNXI_COMMON
def_bool MACH_SUN8I || (ARM64 && ARCH_SUNXI)
select PINCTRL_SUNXI
config PINCTRL_SUN8I_V3S
def_bool MACH_SUN8I
@ -65,11 +66,15 @@ config PINCTRL_SUN9I_A80_R
select PINCTRL_SUNXI
config PINCTRL_SUN50I_A64
bool
def_bool ARM64 && ARCH_SUNXI
select PINCTRL_SUNXI
config PINCTRL_SUN50I_A64_R
def_bool ARM64 && ARCH_SUNXI
select PINCTRL_SUNXI
config PINCTRL_SUN50I_H5
bool
def_bool ARM64 && ARCH_SUNXI
select PINCTRL_SUNXI
endif

View File

@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o
obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o
obj-$(CONFIG_PINCTRL_SUN8I_A33) += pinctrl-sun8i-a33.o
obj-$(CONFIG_PINCTRL_SUN50I_A64) += pinctrl-sun50i-a64.o
obj-$(CONFIG_PINCTRL_SUN50I_A64_R) += pinctrl-sun50i-a64-r.o
obj-$(CONFIG_PINCTRL_SUN8I_A83T) += pinctrl-sun8i-a83t.o
obj-$(CONFIG_PINCTRL_SUN8I_H3) += pinctrl-sun8i-h3.o
obj-$(CONFIG_PINCTRL_SUN8I_H3_R) += pinctrl-sun8i-h3-r.o

View File

@ -0,0 +1,125 @@
/*
* Allwinner A64 SoCs special pins pinctrl driver.
*
* Based on pinctrl-sun8i-a23-r.c
*
* Copyright (C) 2016 Icenowy Zheng
* Icenowy Zheng <icenowy@aosc.xyz>
*
* Copyright (C) 2014 Chen-Yu Tsai
* Chen-Yu Tsai <wens@csie.org>
*
* Copyright (C) 2014 Boris Brezillon
* Boris Brezillon <boris.brezillon@free-electrons.com>
*
* Copyright (C) 2014 Maxime Ripard
* Maxime Ripard <maxime.ripard@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include "pinctrl-sunxi.h"
static const struct sunxi_desc_pin sun50i_a64_r_pins[] = {
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */
SUNXI_FUNCTION(0x3, "s_i2c"), /* SCK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PL_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */
SUNXI_FUNCTION(0x3, "s_i2c"), /* SDA */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PL_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_uart"), /* TX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PL_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_uart"), /* RX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PL_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_jtag"), /* MS */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PL_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_jtag"), /* CK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PL_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_jtag"), /* DO */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PL_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_jtag"), /* DI */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PL_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_i2c"), /* SCK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PL_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_i2c"), /* SDA */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PL_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_pwm"),
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PL_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "s_cir_rx"),
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PL_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PL_EINT12 */
};
static const struct sunxi_pinctrl_desc sun50i_a64_r_pinctrl_data = {
.pins = sun50i_a64_r_pins,
.npins = ARRAY_SIZE(sun50i_a64_r_pins),
.pin_base = PL_BASE,
.irq_banks = 1,
};
static int sun50i_a64_r_pinctrl_probe(struct platform_device *pdev)
{
return sunxi_pinctrl_init(pdev,
&sun50i_a64_r_pinctrl_data);
}
static const struct of_device_id sun50i_a64_r_pinctrl_match[] = {
{ .compatible = "allwinner,sun50i-a64-r-pinctrl", },
{}
};
static struct platform_driver sun50i_a64_r_pinctrl_driver = {
.probe = sun50i_a64_r_pinctrl_probe,
.driver = {
.name = "sun50i-a64-r-pinctrl",
.of_match_table = sun50i_a64_r_pinctrl_match,
},
};
builtin_platform_driver(sun50i_a64_r_pinctrl_driver);

View File

@ -581,11 +581,11 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
return -ENOTSUPP;
}
spin_lock_irqsave(&pctl->lock, flags);
raw_spin_lock_irqsave(&pctl->lock, flags);
reg = readl(pctl->membase + offset);
reg &= ~(mask << shift);
writel(reg | val << shift, pctl->membase + offset);
spin_unlock_irqrestore(&pctl->lock, flags);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
} /* for each config */
return 0;
@ -634,7 +634,7 @@ static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
unsigned long flags;
u32 val, mask;
spin_lock_irqsave(&pctl->lock, flags);
raw_spin_lock_irqsave(&pctl->lock, flags);
pin -= pctl->desc->pin_base;
val = readl(pctl->membase + sunxi_mux_reg(pin));
@ -642,7 +642,7 @@ static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
writel((val & ~mask) | config << sunxi_mux_offset(pin),
pctl->membase + sunxi_mux_reg(pin));
spin_unlock_irqrestore(&pctl->lock, flags);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
static int sunxi_pmx_set_mux(struct pinctrl_dev *pctldev,
@ -733,7 +733,7 @@ static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
unsigned long flags;
u32 regval;
spin_lock_irqsave(&pctl->lock, flags);
raw_spin_lock_irqsave(&pctl->lock, flags);
regval = readl(pctl->membase + reg);
@ -744,7 +744,7 @@ static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
writel(regval, pctl->membase + reg);
spin_unlock_irqrestore(&pctl->lock, flags);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
@ -856,7 +856,7 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
spin_lock_irqsave(&pctl->lock, flags);
raw_spin_lock_irqsave(&pctl->lock, flags);
if (type & IRQ_TYPE_LEVEL_MASK)
irq_set_chip_handler_name_locked(d, &sunxi_pinctrl_level_irq_chip,
@ -869,7 +869,7 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
regval &= ~(IRQ_CFG_IRQ_MASK << index);
writel(regval | (mode << index), pctl->membase + reg);
spin_unlock_irqrestore(&pctl->lock, flags);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
return 0;
}
@ -893,13 +893,13 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d)
unsigned long flags;
u32 val;
spin_lock_irqsave(&pctl->lock, flags);
raw_spin_lock_irqsave(&pctl->lock, flags);
/* Mask the IRQ */
val = readl(pctl->membase + reg);
writel(val & ~(1 << idx), pctl->membase + reg);
spin_unlock_irqrestore(&pctl->lock, flags);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
@ -910,13 +910,13 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
unsigned long flags;
u32 val;
spin_lock_irqsave(&pctl->lock, flags);
raw_spin_lock_irqsave(&pctl->lock, flags);
/* Unmask the IRQ */
val = readl(pctl->membase + reg);
writel(val | (1 << idx), pctl->membase + reg);
spin_unlock_irqrestore(&pctl->lock, flags);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d)
@ -1253,7 +1253,7 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
return -ENOMEM;
platform_set_drvdata(pdev, pctl);
spin_lock_init(&pctl->lock);
raw_spin_lock_init(&pctl->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctl->membase = devm_ioremap_resource(&pdev->dev, res);

View File

@ -134,7 +134,7 @@ struct sunxi_pinctrl {
unsigned ngroups;
int *irq;
unsigned *irq_array;
spinlock_t lock;
raw_spinlock_t lock;
struct pinctrl_dev *pctl_dev;
unsigned long variant;
};

View File

@ -873,6 +873,10 @@ static const struct of_device_id tegra_xusb_padctl_of_match[] = {
};
MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match);
/* predeclare these in order to silence sparse */
int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev);
int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev)
{
struct tegra_xusb_padctl *padctl;

View File

@ -9,35 +9,35 @@ menuconfig PINCTRL_UNIPHIER
if PINCTRL_UNIPHIER
config PINCTRL_UNIPHIER_LD4
tristate "UniPhier PH1-LD4 SoC pinctrl driver"
bool "UniPhier LD4 SoC pinctrl driver"
default ARM
config PINCTRL_UNIPHIER_PRO4
tristate "UniPhier PH1-Pro4 SoC pinctrl driver"
bool "UniPhier Pro4 SoC pinctrl driver"
default ARM
config PINCTRL_UNIPHIER_SLD8
tristate "UniPhier PH1-sLD8 SoC pinctrl driver"
bool "UniPhier sLD8 SoC pinctrl driver"
default ARM
config PINCTRL_UNIPHIER_PRO5
tristate "UniPhier PH1-Pro5 SoC pinctrl driver"
bool "UniPhier Pro5 SoC pinctrl driver"
default ARM
config PINCTRL_UNIPHIER_PXS2
tristate "UniPhier ProXstream2 SoC pinctrl driver"
bool "UniPhier PXs2 SoC pinctrl driver"
default ARM
config PINCTRL_UNIPHIER_LD6B
tristate "UniPhier PH1-LD6b SoC pinctrl driver"
bool "UniPhier LD6b SoC pinctrl driver"
default ARM
config PINCTRL_UNIPHIER_LD11
tristate "UniPhier PH1-LD11 SoC pinctrl driver"
bool "UniPhier LD11 SoC pinctrl driver"
default ARM64
config PINCTRL_UNIPHIER_LD20
tristate "UniPhier PH1-LD20 SoC pinctrl driver"
bool "UniPhier LD20 SoC pinctrl driver"
default ARM64
endif

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
* Copyright (C) 2015-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,11 +27,18 @@
#include "../pinctrl-utils.h"
#include "pinctrl-uniphier.h"
#define UNIPHIER_PINCTRL_PINMUX_BASE 0x1000
#define UNIPHIER_PINCTRL_LOAD_PINMUX 0x1700
#define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x1800
#define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x1900
#define UNIPHIER_PINCTRL_DRV3CTRL_BASE 0x1980
#define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0x1a00
#define UNIPHIER_PINCTRL_IECTRL 0x1d00
struct uniphier_pinctrl_priv {
struct pinctrl_desc pctldesc;
struct pinctrl_dev *pctldev;
struct regmap *regmap;
unsigned int regbase;
struct uniphier_pinctrl_socdata *socdata;
};
@ -171,7 +179,7 @@ static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev,
reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
shift = pupdctrl % 32;
ret = regmap_read(priv->regmap, priv->regbase + reg, &val);
ret = regmap_read(priv->regmap, reg, &val);
if (ret)
return ret;
@ -231,7 +239,7 @@ static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
shift = drvctrl % 32;
mask = (1U << width) - 1;
ret = regmap_read(priv->regmap, priv->regbase + reg, &val);
ret = regmap_read(priv->regmap, reg, &val);
if (ret)
return ret;
@ -252,8 +260,7 @@ static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev,
/* This pin is always input-enabled. */
return 0;
ret = regmap_read(priv->regmap,
priv->regbase + UNIPHIER_PINCTRL_IECTRL, &val);
ret = regmap_read(priv->regmap, UNIPHIER_PINCTRL_IECTRL, &val);
if (ret)
return ret;
@ -366,8 +373,7 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev,
reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
shift = pupdctrl % 32;
return regmap_update_bits(priv->regmap, priv->regbase + reg,
1 << shift, val << shift);
return regmap_update_bits(priv->regmap, reg, 1 << shift, val << shift);
}
static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
@ -427,7 +433,7 @@ static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
shift = drvctrl % 32;
mask = (1U << width) - 1;
return regmap_update_bits(priv->regmap, priv->regbase + reg,
return regmap_update_bits(priv->regmap, reg,
mask << shift, val << shift);
}
@ -451,7 +457,7 @@ static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev,
if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
return enable ? 0 : -EINVAL;
reg = priv->regbase + UNIPHIER_PINCTRL_IECTRL + iectrl / 32 * 4;
reg = UNIPHIER_PINCTRL_IECTRL + iectrl / 32 * 4;
mask = BIT(iectrl % 32);
return regmap_update_bits(priv->regmap, reg, mask, enable ? mask : 0);
@ -601,7 +607,7 @@ static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin,
* stored in the offset+4.
*/
for (; reg < reg_end; reg += 4) {
ret = regmap_update_bits(priv->regmap, priv->regbase + reg,
ret = regmap_update_bits(priv->regmap, reg,
mask << shift, muxval << shift);
if (ret)
return ret;
@ -610,8 +616,7 @@ static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin,
if (load_pinctrl) {
ret = regmap_write(priv->regmap,
priv->regbase + UNIPHIER_PINCTRL_LOAD_PINMUX,
1);
UNIPHIER_PINCTRL_LOAD_PINMUX, 1);
if (ret)
return ret;
}
@ -698,20 +703,9 @@ int uniphier_pinctrl_probe(struct platform_device *pdev,
if (!priv)
return -ENOMEM;
if (of_device_is_compatible(dev->of_node, "socionext,ph1-ld4-pinctrl") ||
of_device_is_compatible(dev->of_node, "socionext,ph1-pro4-pinctrl") ||
of_device_is_compatible(dev->of_node, "socionext,ph1-sld8-pinctrl") ||
of_device_is_compatible(dev->of_node, "socionext,ph1-pro5-pinctrl") ||
of_device_is_compatible(dev->of_node, "socionext,proxstream2-pinctrl") ||
of_device_is_compatible(dev->of_node, "socionext,ph1-ld6b-pinctrl")) {
/* old binding */
priv->regmap = syscon_node_to_regmap(dev->of_node);
} else {
priv->regbase = 0x1000;
parent = of_get_parent(dev->of_node);
priv->regmap = syscon_node_to_regmap(parent);
of_node_put(parent);
}
parent = of_get_parent(dev->of_node);
priv->regmap = syscon_node_to_regmap(parent);
of_node_put(parent);
if (IS_ERR(priv->regmap)) {
dev_err(dev, "failed to get regmap\n");

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Socionext Inc.
* Copyright (C) 2016-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
@ -14,7 +14,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
@ -936,7 +936,6 @@ static const struct of_device_id uniphier_ld11_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-ld11-pinctrl" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_ld11_pinctrl_match);
static struct platform_driver uniphier_ld11_pinctrl_driver = {
.probe = uniphier_ld11_pinctrl_probe,
@ -945,8 +944,4 @@ static struct platform_driver uniphier_ld11_pinctrl_driver = {
.of_match_table = uniphier_ld11_pinctrl_match,
},
};
module_platform_driver(uniphier_ld11_pinctrl_driver);
MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier PH1-LD11 pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(uniphier_ld11_pinctrl_driver);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Socionext Inc.
* Copyright (C) 2016-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
@ -14,7 +14,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
@ -1034,7 +1034,6 @@ static const struct of_device_id uniphier_ld20_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-ld20-pinctrl" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_ld20_pinctrl_match);
static struct platform_driver uniphier_ld20_pinctrl_driver = {
.probe = uniphier_ld20_pinctrl_probe,
@ -1043,8 +1042,4 @@ static struct platform_driver uniphier_ld20_pinctrl_driver = {
.of_match_table = uniphier_ld20_pinctrl_match,
},
};
module_platform_driver(uniphier_ld20_pinctrl_driver);
MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier PH1-LD20 pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(uniphier_ld20_pinctrl_driver);

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
* Copyright (C) 2015-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -13,7 +14,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
@ -929,10 +930,8 @@ static int uniphier_ld4_pinctrl_probe(struct platform_device *pdev)
static const struct of_device_id uniphier_ld4_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-ld4-pinctrl" },
{ .compatible = "socionext,ph1-ld4-pinctrl" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_ld4_pinctrl_match);
static struct platform_driver uniphier_ld4_pinctrl_driver = {
.probe = uniphier_ld4_pinctrl_probe,
@ -941,8 +940,4 @@ static struct platform_driver uniphier_ld4_pinctrl_driver = {
.of_match_table = uniphier_ld4_pinctrl_match,
},
};
module_platform_driver(uniphier_ld4_pinctrl_driver);
MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier PH1-LD4 pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(uniphier_ld4_pinctrl_driver);

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
* Copyright (C) 2015-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -13,7 +14,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
@ -1290,10 +1291,8 @@ static int uniphier_ld6b_pinctrl_probe(struct platform_device *pdev)
static const struct of_device_id uniphier_ld6b_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-ld6b-pinctrl" },
{ .compatible = "socionext,ph1-ld6b-pinctrl" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_ld6b_pinctrl_match);
static struct platform_driver uniphier_ld6b_pinctrl_driver = {
.probe = uniphier_ld6b_pinctrl_probe,
@ -1302,8 +1301,4 @@ static struct platform_driver uniphier_ld6b_pinctrl_driver = {
.of_match_table = uniphier_ld6b_pinctrl_match,
},
};
module_platform_driver(uniphier_ld6b_pinctrl_driver);
MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier PH1-LD6b pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(uniphier_ld6b_pinctrl_driver);

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
* Copyright (C) 2015-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -13,7 +14,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
@ -1600,10 +1601,8 @@ static int uniphier_pro4_pinctrl_probe(struct platform_device *pdev)
static const struct of_device_id uniphier_pro4_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-pro4-pinctrl" },
{ .compatible = "socionext,ph1-pro4-pinctrl" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_pro4_pinctrl_match);
static struct platform_driver uniphier_pro4_pinctrl_driver = {
.probe = uniphier_pro4_pinctrl_probe,
@ -1612,8 +1611,4 @@ static struct platform_driver uniphier_pro4_pinctrl_driver = {
.of_match_table = uniphier_pro4_pinctrl_match,
},
};
module_platform_driver(uniphier_pro4_pinctrl_driver);
MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier PH1-Pro4 pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(uniphier_pro4_pinctrl_driver);

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
* Copyright (C) 2015-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -13,7 +14,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
@ -1365,10 +1366,8 @@ static int uniphier_pro5_pinctrl_probe(struct platform_device *pdev)
static const struct of_device_id uniphier_pro5_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-pro5-pinctrl" },
{ .compatible = "socionext,ph1-pro5-pinctrl" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_pro5_pinctrl_match);
static struct platform_driver uniphier_pro5_pinctrl_driver = {
.probe = uniphier_pro5_pinctrl_probe,
@ -1377,8 +1376,4 @@ static struct platform_driver uniphier_pro5_pinctrl_driver = {
.of_match_table = uniphier_pro5_pinctrl_match,
},
};
module_platform_driver(uniphier_pro5_pinctrl_driver);
MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier PH1-Pro5 pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(uniphier_pro5_pinctrl_driver);

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
* Copyright (C) 2015-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -13,7 +14,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
@ -1277,10 +1278,8 @@ static int uniphier_pxs2_pinctrl_probe(struct platform_device *pdev)
static const struct of_device_id uniphier_pxs2_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-pxs2-pinctrl" },
{ .compatible = "socionext,proxstream2-pinctrl" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_pxs2_pinctrl_match);
static struct platform_driver uniphier_pxs2_pinctrl_driver = {
.probe = uniphier_pxs2_pinctrl_probe,
@ -1289,8 +1288,4 @@ static struct platform_driver uniphier_pxs2_pinctrl_driver = {
.of_match_table = uniphier_pxs2_pinctrl_match,
},
};
module_platform_driver(uniphier_pxs2_pinctrl_driver);
MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier ProXstream2 pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(uniphier_pxs2_pinctrl_driver);

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
* Copyright (C) 2015-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -13,7 +14,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
@ -856,10 +857,8 @@ static int uniphier_sld8_pinctrl_probe(struct platform_device *pdev)
static const struct of_device_id uniphier_sld8_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-sld8-pinctrl" },
{ .compatible = "socionext,ph1-sld8-pinctrl" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_sld8_pinctrl_match);
static struct platform_driver uniphier_sld8_pinctrl_driver = {
.probe = uniphier_sld8_pinctrl_probe,
@ -868,8 +867,4 @@ static struct platform_driver uniphier_sld8_pinctrl_driver = {
.of_match_table = uniphier_sld8_pinctrl_match,
},
};
module_platform_driver(uniphier_sld8_pinctrl_driver);
MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier PH1-sLD8 pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(uniphier_sld8_pinctrl_driver);

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
* Copyright (C) 2015-2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,14 +23,6 @@
struct platform_device;
#define UNIPHIER_PINCTRL_PINMUX_BASE 0x0
#define UNIPHIER_PINCTRL_LOAD_PINMUX 0x700
#define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x800
#define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x900
#define UNIPHIER_PINCTRL_DRV3CTRL_BASE 0x980
#define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0xa00
#define UNIPHIER_PINCTRL_IECTRL 0xd00
/* input enable control register bit */
#define UNIPHIER_PIN_IECTRL_SHIFT 0
#define UNIPHIER_PIN_IECTRL_BITS 8

View File

@ -185,6 +185,12 @@
#define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MO (MTK_PIN_NO(56) | 1)
#define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MI (MTK_PIN_NO(56) | 2)
#define MT7623_PIN_57_SDA1_FUNC_GPIO57 (MTK_PIN_NO(57) | 0)
#define MT7623_PIN_57_SDA1_FUNC_SDA1 (MTK_PIN_NO(57) | 1)
#define MT7623_PIN_58_SCL1_FUNC_GPIO58 (MTK_PIN_NO(58) | 0)
#define MT7623_PIN_58_SCL1_FUNC_SCL1 (MTK_PIN_NO(58) | 1)
#define MT7623_PIN_60_WB_RSTB_FUNC_GPIO60 (MTK_PIN_NO(60) | 0)
#define MT7623_PIN_60_WB_RSTB_FUNC_WB_RSTB (MTK_PIN_NO(60) | 1)
@ -244,6 +250,22 @@
#define MT7623_PIN_76_SCL0_FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
#define MT7623_PIN_76_SCL0_FUNC_SCL0 (MTK_PIN_NO(76) | 1)
#define MT7623_PIN_79_URXD0_FUNC_GPIO79 (MTK_PIN_NO(79) | 0)
#define MT7623_PIN_79_URXD0_FUNC_URXD0 (MTK_PIN_NO(79) | 1)
#define MT7623_PIN_79_URXD0_FUNC_UTXD0 (MTK_PIN_NO(79) | 2)
#define MT7623_PIN_80_UTXD0_FUNC_GPIO80 (MTK_PIN_NO(80) | 0)
#define MT7623_PIN_80_UTXD0_FUNC_UTXD0 (MTK_PIN_NO(80) | 1)
#define MT7623_PIN_80_UTXD0_FUNC_URXD0 (MTK_PIN_NO(80) | 2)
#define MT7623_PIN_81_URXD1_FUNC_GPIO81 (MTK_PIN_NO(81) | 0)
#define MT7623_PIN_81_URXD1_FUNC_URXD1 (MTK_PIN_NO(81) | 1)
#define MT7623_PIN_81_URXD1_FUNC_UTXD1 (MTK_PIN_NO(81) | 2)
#define MT7623_PIN_82_UTXD1_FUNC_GPIO82 (MTK_PIN_NO(82) | 0)
#define MT7623_PIN_82_UTXD1_FUNC_UTXD1 (MTK_PIN_NO(82) | 1)
#define MT7623_PIN_82_UTXD1_FUNC_URXD1 (MTK_PIN_NO(82) | 2)
#define MT7623_PIN_83_LCM_RST_FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
#define MT7623_PIN_83_LCM_RST_FUNC_LCM_RST (MTK_PIN_NO(83) | 1)
@ -351,10 +373,10 @@
#define MT7623_PIN_122_GPIO122_FUNC_SDA2 (MTK_PIN_NO(122) | 4)
#define MT7623_PIN_122_GPIO122_FUNC_URXD0 (MTK_PIN_NO(122) | 5)
#define MT7623_PIN_123_GPIO123_FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
#define MT7623_PIN_123_GPIO123_FUNC_TEST (MTK_PIN_NO(123) | 1)
#define MT7623_PIN_123_GPIO123_FUNC_SCL2 (MTK_PIN_NO(123) | 4)
#define MT7623_PIN_123_GPIO123_FUNC_UTXD0 (MTK_PIN_NO(123) | 5)
#define MT7623_PIN_123_HTPLG_FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
#define MT7623_PIN_123_HTPLG_FUNC_HTPLG (MTK_PIN_NO(123) | 1)
#define MT7623_PIN_123_HTPLG_FUNC_SCL2 (MTK_PIN_NO(123) | 4)
#define MT7623_PIN_123_HTPLG_FUNC_UTXD0 (MTK_PIN_NO(123) | 5)
#define MT7623_PIN_124_GPIO124_FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
#define MT7623_PIN_124_GPIO124_FUNC_TEST (MTK_PIN_NO(124) | 1)

View File

@ -42,6 +42,8 @@
* @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high
* impedance to VDD). If the argument is != 0 pull-up is enabled,
* if it is 0, pull-up is total, i.e. the pin is connected to VDD.
* @PIN_CONFIG_BIDIRECTIONAL: the pin will be configured to allow simultaneous
* input and output operations.
* @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open
* collector) which means it is usually wired with other output ports
* which are then pulled up with an external resistor. Setting this
@ -96,6 +98,7 @@ enum pin_config_param {
PIN_CONFIG_BIAS_PULL_DOWN,
PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
PIN_CONFIG_BIAS_PULL_UP,
PIN_CONFIG_BIDIRECTIONAL,
PIN_CONFIG_DRIVE_OPEN_DRAIN,
PIN_CONFIG_DRIVE_OPEN_SOURCE,
PIN_CONFIG_DRIVE_PUSH_PULL,