Commit 5ca5446e authored by Linus Torvalds's avatar Linus Torvalds

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

Pull pin control updates from Linus Walleij:
 "An almost purely driver related set of changes with no major changes
  to the framework, only one patch adding an unlocked version of the
  pinctrl_find_gpio_range_from_pin() library call.

  New drivers:
   - ST Microelectronics STM32 MCU support: this is a non-MMU low-end
     platform for IoT things (etc).
   - Microchip PIC32 MCU support: same story as for STM32.

  New subdrivers:
   - Allwinner SunXi H3 R_PIO controller support.
   - Qualcomm IPQ4019 support.
   - MediaTek MT2701 and MT7623.
   - Allwinner A64

  Non-critical fixes:
   - gpio_disable_free() for the Vybrid.
   - pinctrl single: use a separate lockdep class.

  Misc:
   - Substantial cleanups and rewrites for the Super-H PFC driver and
     subdrivers.
   - Various fixes and cleanups, especially Paul Gortmakers work to make
     nonmodular drivers nonmodular"

* tag 'pinctrl-v4.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (75 commits)
  pinctrl: single: Use a separate lockdep class
  drivers: pinctrl: add driver for Allwinner A64 SoC
  pinctrl: Broadcom Northstar2 pinctrl device tree bindings
  pinctrl: amlogic: Make driver independent from two-domain configuration
  pinctrl: amlogic: Separate some pin functions for Meson8 / Meson8b
  pinctrl: at91: use __maybe_unused to hide pm functions
  pinctrl: sh-pfc: core: don't open code of_device_get_match_data()
  pinctrl: uniphier: rename CONFIG options and file names
  pinctrl: sunxi: make A80 explicitly non-modular
  pinctrl: stm32: make explicitly non-modular
  pinctrl: sh-pfc: make explicitly non-modular
  pinctrl: meson: make explicitly non-modular
  pinctrl: pinctrl-mt6397 driver explicitly non-modular
  pinctrl: sunxi: does not need module.h
  pinctrl: pxa2xx: export symbols
  pinctrl: sunxi: Change mux setting on PI irq pins
  pinctrl: sunxi: Remove non existing irq's
  pinctrl: imx: attach iomuxc device to gpr syscon
  pinctrl-bcm2835: Fix cut-and-paste error in "pull" parsing
  pinctrl: lpc1850-scu: document nxp,gpio-pin-interrupt
  ...
parents 710d60cb 3c177a16
* Microchip PIC32 GPIO devices (PIO).
Required properties:
- compatible: "microchip,pic32mzda-gpio"
- reg: Base address and length for the device.
- interrupts: The port interrupt shared by all pins.
- gpio-controller: Marks the port as GPIO controller.
- #gpio-cells: Two. The first cell is the pin number and
the second cell is used to specify the gpio polarity as defined in
defined in <dt-bindings/gpio/gpio.h>:
0 = GPIO_ACTIVE_HIGH
1 = GPIO_ACTIVE_LOW
2 = GPIO_OPEN_DRAIN
- interrupt-controller: Marks the device node as an interrupt controller.
- #interrupt-cells: Two. The first cell is the GPIO number and second cell
is used to specify the trigger type as defined in
<dt-bindings/interrupt-controller/irq.h>:
IRQ_TYPE_EDGE_RISING
IRQ_TYPE_EDGE_FALLING
IRQ_TYPE_EDGE_BOTH
- clocks: Clock specifier (see clock bindings for details).
- microchip,gpio-bank: Specifies which bank a controller owns.
- gpio-ranges: Interaction with the PINCTRL subsystem.
Example:
/* PORTA */
gpio0: gpio0@1f860000 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860000 0x100>;
interrupts = <118 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <0>;
gpio-ranges = <&pic32_pinctrl 0 0 16>;
};
keys {
...
button@sw1 {
label = "ESC";
linux,code = <1>;
gpios = <&gpio0 12 0>;
};
};
......@@ -21,6 +21,8 @@ Required properties:
"allwinner,sun9i-a80-r-pinctrl"
"allwinner,sun8i-a83t-pinctrl"
"allwinner,sun8i-h3-pinctrl"
"allwinner,sun8i-h3-r-pinctrl"
"allwinner,sun50i-a64-pinctrl"
- reg: Should contain the register physical address and length for the
pin controller.
......
Broadcom Northstar2 IOMUX Controller
The Northstar2 IOMUX controller supports group based mux configuration. There
are some individual pins that support modifying the pinconf parameters.
Required properties:
- compatible:
Must be "brcm,ns2-pinmux"
- reg:
Define the base and range of the I/O address space that contains the
Northstar2 IOMUX and pin configuration registers.
Properties in sub nodes:
- function:
The mux function to select
- groups:
The list of groups to select with a given function
- pins:
List of pin names to change configuration
The generic properties bias-disable, bias-pull-down, bias-pull-up,
drive-strength, slew-rate, input-enable, input-disable are supported
for some individual pins listed at the end.
For more details, refer to
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
For example:
pinctrl: pinctrl@6501d130 {
compatible = "brcm,ns2-pinmux";
reg = <0x6501d130 0x08>,
<0x660a0028 0x04>,
<0x660009b0 0x40>;
pinctrl-names = "default";
pinctrl-0 = <&nand_sel &uart3_rx &sdio0_d4>;
/* Select nand function */
nand_sel: nand_sel {
function = "nand";
groups = "nand_grp";
};
/* Pull up the uart3 rx pin */
uart3_rx: uart3_rx {
pins = "uart3_sin";
bias-pull-up;
};
/* Set the drive strength of sdio d4 pin */
sdio0_d4: sdio0_d4 {
pins = "sdio0_data4";
drive-strength = <8>;
};
};
List of supported functions and groups in Northstar2:
"nand": "nand_grp"
"nor": "nor_data_grp", "nor_adv_grp", "nor_addr_0_3_grp", "nor_addr_4_5_grp",
"nor_addr_6_7_grp", "nor_addr_8_9_grp", "nor_addr_10_11_grp",
"nor_addr_12_15_grp"
"gpio": "gpio_0_1_grp", "gpio_2_5_grp", "gpio_6_7_grp", "gpio_8_9_grp",
"gpio_10_11_grp", "gpio_12_13_grp", "gpio_14_17_grp", "gpio_18_19_grp",
"gpio_20_21_grp", "gpio_22_23_grp", "gpio_24_25_grp", "gpio_26_27_grp",
"gpio_28_29_grp", "gpio_30_31_grp"
"pcie": "pcie_ab1_clk_wak_grp", "pcie_a3_clk_wak_grp", "pcie_b3_clk_wak_grp",
"pcie_b2_clk_wak_grp", "pcie_a2_clk_wak_grp"
"uart0": "uart0_modem_grp", "uart0_rts_cts_grp", "uart0_in_out_grp"
"uart1": "uart1_ext_clk_grp", "uart1_dcd_dsr_grp", "uart1_ri_dtr_grp",
"uart1_rts_cts_grp", "uart1_in_out_grp"
"uart2": "uart2_rts_cts_grp"
"pwm": "pwm_0_grp", "pwm_1_grp", "pwm_2_grp", "pwm_3_grp"
List of pins that support pinconf parameters:
"qspi_wp", "qspi_hold", "qspi_cs", "qspi_sck", "uart3_sin", "uart3_sout",
"qspi_mosi", "qspi_miso", "spi0_fss", "spi0_rxd", "spi0_txd", "spi0_sck",
"spi1_fss", "spi1_rxd", "spi1_txd", "spi1_sck", "sdio0_data7",
"sdio0_emmc_rst", "sdio0_led_on", "sdio0_wp", "sdio0_data3", "sdio0_data4",
"sdio0_data5", "sdio0_data6", "sdio0_cmd", "sdio0_data0", "sdio0_data1",
"sdio0_data2", "sdio1_led_on", "sdio1_wp", "sdio0_cd_l", "sdio0_clk",
"sdio1_data5", "sdio1_data6", "sdio1_data7", "sdio1_emmc_rst", "sdio1_data1",
"sdio1_data2", "sdio1_data3", "sdio1_data4", "sdio1_cd_l", "sdio1_clk",
"sdio1_cmd", "sdio1_data0", "ext_mdio_0", "ext_mdc_0", "usb3_p1_vbus_ppc",
"usb3_p1_overcurrent", "usb3_p0_vbus_ppc", "usb3_p0_overcurrent",
"usb2_presence_indication", "usb2_vbus_present", "usb2_vbus_ppc",
"usb2_overcurrent", "sata_led1", "sata_led0"
* Microchip PIC32 Pin Controller
Please refer to pinctrl-bindings.txt, ../gpio/gpio.txt, and
../interrupt-controller/interrupts.txt for generic information regarding
pin controller, GPIO, and interrupt bindings.
PIC32 'pin configuration node' is a node of a group of pins which can be
used for a specific device or function. This node represents configuraions of
pins, optional function, and optional mux related configuration.
Required properties for pin controller node:
- compatible: "microchip,pic32mada-pinctrl"
- reg: Address range of the pinctrl registers.
- clocks: Clock specifier (see clock bindings for details)
Required properties for pin configuration sub-nodes:
- pins: List of pins to which the configuration applies.
Optional properties for pin configuration sub-nodes:
----------------------------------------------------
- function: Mux function for the specified pins.
- bias-pull-up: Enable weak pull-up.
- bias-pull-down: Enable weak pull-down.
- input-enable: Set the pin as an input.
- output-low: Set the pin as an output level low.
- output-high: Set the pin as an output level high.
- microchip,digital: Enable digital I/O.
- microchip,analog: Enable analog I/O.
Example:
pic32_pinctrl: pinctrl@1f801400{
#address-cells = <1>;
#size-cells = <1>;
compatible = "microchip,pic32mzda-pinctrl";
reg = <0x1f801400 0x400>;
clocks = <&PBCLK1>;
pinctrl_uart2: pinctrl_uart2 {
uart2-tx {
pins = "G9";
function = "U2TX";
microchip,digital;
output-low;
};
uart2-rx {
pins = "B0";
function = "U2RX";
microchip,digital;
input-enable;
};
};
};
uart2: serial@1f822200 {
compatible = "microchip,pic32mzda-uart";
reg = <0x1f822200 0x50>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
};
......@@ -22,6 +22,10 @@ The following generic nodes are supported:
- input-schmitt-disable
- slew-rate
NXP specific properties:
- nxp,gpio-pin-interrupt : Assign pin to gpio pin interrupt controller
irq number 0 to 7. See example below.
Not all pins support all properties so either refer to the NXP 1850/4350
user manual or the pin table in the pinctrl-lpc18xx driver for supported
pin properties.
......@@ -54,4 +58,14 @@ pinctrl: pinctrl@40086000 {
bias-disable;
};
};
gpio_joystick_pins: gpio-joystick-pins {
gpio_joystick_1_cfg {
pins = "p9_0";
function = "gpio";
nxp,gpio-pin-interrupt = <0>;
input-enable;
bias-disable;
};
};
};
......@@ -6,6 +6,7 @@ Required properties:
- compatible: value should be one of the following.
"mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl.
"mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
"mediatek,mt7623-pinctrl", compatible with mt7623 pinctrl.
"mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
"mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
"mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
......
Qualcomm Atheros IPQ4019 TLMM block
This is the Top Level Mode Multiplexor block found on the Qualcomm IPQ8019
platform, it provides pinctrl, pinmux, pinconf, and gpiolib facilities.
Required properties:
- compatible: "qcom,ipq4019-pinctrl"
- reg: Should be the base address and length of the TLMM block.
- interrupts: Should be the parent IRQ of the TLMM block.
- interrupt-controller: Marks the device node as an interrupt controller.
- #interrupt-cells: Should be two.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells : Should be two.
The first cell is the gpio pin number and the
second cell is used for optional parameters.
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an abitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
pins, function, bias-disable, bias-pull-down, bias-pull,up, drive-strength.
Non-empty subnodes must specify the 'pins' property.
Note that not all properties are valid for all pins.
Valid values for qcom,pins are:
gpio0-gpio99
Supports mux, bias and drive-strength
Valid values for qcom,function are:
gpio, blsp_uart1, blsp_i2c0, blsp_i2c1, blsp_uart0, blsp_spi1, blsp_spi0
Example:
tlmm: pinctrl@1000000 {
compatible = "qcom,ipq4019-pinctrl";
reg = <0x1000000 0x300000>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <0 208 0>;
serial_pins: serial_pinmux {
mux {
pins = "gpio60", "gpio61";
function = "blsp_uart0";
bias-disable;
};
};
};
......@@ -22,7 +22,7 @@ Required properties for iomux controller:
- compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
"rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
"rockchip,rk3228-pinctrl", "rockchip,rk3288-pinctrl"
"rockchip,rk3368-pinctrl"
"rockchip,rk3368-pinctrl", "rockchip,rk3399-pinctrl"
- rockchip,grf: phandle referencing a syscon providing the
"general register files"
......
* STM32 GPIO and Pin Mux/Config controller
STMicroelectronics's STM32 MCUs intregrate a GPIO and Pin mux/config hardware
controller. It controls the input/output settings on the available pins and
also provides ability to multiplex and configure the output of various on-chip
controllers onto these pads.
Pin controller node:
Required properies:
- compatible: value should be one of the following:
(a) "st,stm32f429-pinctrl"
- #address-cells: The value of this property must be 1
- #size-cells : The value of this property must be 1
- ranges : defines mapping between pin controller node (parent) to
gpio-bank node (children).
- pins-are-numbered: Specify the subnodes are using numbered pinmux to
specify pins.
GPIO controller/bank node:
Required properties:
- gpio-controller : Indicates this device is a GPIO controller
- #gpio-cells : Should be two.
The first cell is the pin number
The second one is the polarity:
- 0 for active high
- 1 for active low
- reg : The gpio address range, relative to the pinctrl range
- clocks : clock that drives this bank
- st,bank-name : Should be a name string for this bank as specified in
the datasheet
Optional properties:
- reset: : Reference to the reset controller
Example:
#include <dt-bindings/pinctrl/stm32f429-pinfunc.h>
...
pin-controller {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stm32f429-pinctrl";
ranges = <0 0x40020000 0x3000>;
pins-are-numbered;
gpioa: gpio@40020000 {
gpio-controller;
#gpio-cells = <2>;
reg = <0x0 0x400>;
resets = <&reset_ahb1 0>;
st,bank-name = "GPIOA";
};
...
pin-functions nodes follow...
};
Contents of function subnode node:
----------------------------------
Subnode format
A pinctrl node should contain at least one subnode representing the
pinctrl group available on the machine. Each subnode will list the
pins it needs, and how they should be configured, with regard to muxer
configuration, pullups, drive, output high/low and output speed.
node {
pinmux = <PIN_NUMBER_PINMUX>;
GENERIC_PINCONFIG;
};
Required properties:
- pinmux: integer array, represents gpio pin number and mux setting.
Supported pin number and mux varies for different SoCs, and are defined in
dt-bindings/pinctrl/<soc>-pinfunc.h directly.
These defines are calculated as:
((port * 16 + line) << 8) | function
With:
- port: The gpio port index (PA = 0, PB = 1, ..., PK = 11)
- line: The line offset within the port (PA0 = 0, PA1 = 1, ..., PA15 = 15)
- function: The function number, can be:
* 0 : GPIO
* 1 : Alternate Function 0
* 2 : Alternate Function 1
* 3 : Alternate Function 2
* ...
* 16 : Alternate Function 15
* 17 : Analog
Optional properties:
- GENERIC_PINCONFIG: is the generic pinconfig options to use.
Available options are:
- bias-disable,
- bias-pull-down,
- bias-pull-up,
- drive-push-pull,
- drive-open-drain,
- output-low
- output-high
- slew-rate = <x>, with x being:
< 0 > : Low speed
< 1 > : Medium speed
< 2 > : Fast speed
< 3 > : High speed
Example:
pin-controller {
...
usart1_pins_a: usart1@0 {
pins1 {
pinmux = <STM32F429_PA9_FUNC_USART1_TX>;
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
pins2 {
pinmux = <STM32F429_PA10_FUNC_USART1_RX>;
bias-disable;
};
};
};
&usart1 {
pinctrl-0 = <&usart1_pins_a>;
pinctrl-names = "default";
status = "okay";
};
This diff is collapsed.
......@@ -79,7 +79,7 @@ config PINCTRL_AT91PIO4
controller available on sama5d2 SoC.
config PINCTRL_AMD
bool "AMD GPIO pin control"
tristate "AMD GPIO pin control"
depends on GPIOLIB
select GPIOLIB_IRQCHIP
select PINCONF
......@@ -168,37 +168,6 @@ config PINCTRL_ST
select PINCONF
select GPIOLIB_IRQCHIP
config PINCTRL_TEGRA
bool
select PINMUX
select PINCONF
config PINCTRL_TEGRA20
bool
select PINCTRL_TEGRA
config PINCTRL_TEGRA30
bool
select PINCTRL_TEGRA
config PINCTRL_TEGRA114
bool
select PINCTRL_TEGRA
config PINCTRL_TEGRA124
bool
select PINCTRL_TEGRA
config PINCTRL_TEGRA210
bool
select PINCTRL_TEGRA
config PINCTRL_TEGRA_XUSB
def_bool y if ARCH_TEGRA
select GENERIC_PHY
select PINCONF
select PINMUX
config PINCTRL_TZ1090
bool "Toumaz Xenif TZ1090 pin control driver"
depends on SOC_TZ1090
......@@ -238,6 +207,23 @@ config PINCTRL_PALMAS
open drain configuration for the Palmas series devices like
TPS65913, TPS80036 etc.
config PINCTRL_PIC32
bool "Microchip PIC32 pin controller driver"
depends on OF
depends on MACH_PIC32
select PINMUX
select GENERIC_PINCONF
select GPIOLIB_IRQCHIP
select OF_GPIO
help
This is the pin controller and gpio driver for Microchip PIC32
microcontrollers. This option is selected automatically when specific
machine and arch are selected to build.
config PINCTRL_PIC32MZDA
def_bool y if PIC32MZDA
select PINCTRL_PIC32
config PINCTRL_ZYNQ
bool "Pinctrl driver for Xilinx Zynq"
depends on ARCH_ZYNQ
......@@ -257,7 +243,9 @@ source "drivers/pinctrl/qcom/Kconfig"
source "drivers/pinctrl/samsung/Kconfig"
source "drivers/pinctrl/sh-pfc/Kconfig"
source "drivers/pinctrl/spear/Kconfig"
source "drivers/pinctrl/stm32/Kconfig"
source "drivers/pinctrl/sunxi/Kconfig"
source "drivers/pinctrl/tegra/Kconfig"
source "drivers/pinctrl/uniphier/Kconfig"
source "drivers/pinctrl/vt8500/Kconfig"
source "drivers/pinctrl/mediatek/Kconfig"
......
......@@ -18,17 +18,12 @@ obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MESON) += meson/
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_SIRF) += sirf/
obj-$(CONFIG_PINCTRL_TEGRA) += pinctrl-tegra.o
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_TEGRA114) += pinctrl-tegra114.o
obj-$(CONFIG_PINCTRL_TEGRA124) += pinctrl-tegra124.o
obj-$(CONFIG_PINCTRL_TEGRA210) += pinctrl-tegra210.o
obj-$(CONFIG_PINCTRL_TEGRA_XUSB) += pinctrl-tegra-xusb.o
obj-$(CONFIG_PINCTRL_TEGRA) += tegra/
obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o
obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
......@@ -46,12 +41,13 @@ obj-y += freescale/
obj-$(CONFIG_X86) += intel/
obj-$(CONFIG_PINCTRL_MVEBU) += mvebu/
obj-y += nomadik/
obj-$(CONFIG_ARCH_PXA) += pxa/
obj-$(CONFIG_PINCTRL_PXA) += pxa/
obj-$(CONFIG_ARCH_QCOM) += qcom/
obj-$(CONFIG_PINCTRL_SAMSUNG) += samsung/
obj-$(CONFIG_PINCTRL_SH_PFC) += sh-pfc/
obj-$(CONFIG_PINCTRL_SPEAR) += spear/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_PINCTRL_STM32) += stm32/
obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/
obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-$(CONFIG_PINCTRL_MTK) += mediatek/
......@@ -779,7 +779,7 @@ static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
}
if (num_pulls) {
err = of_property_read_u32_index(np, "brcm,pull",
(num_funcs > 1) ? i : 0, &pull);
(num_pulls > 1) ? i : 0, &pull);
if (err)
goto out;
err = bcm2835_pctl_dt_node_to_map_pull(pc, np, pin,
......
......@@ -481,18 +481,12 @@ int pinctrl_get_group_pins(struct pinctrl_dev *pctldev, const char *pin_group,
}
EXPORT_SYMBOL_GPL(pinctrl_get_group_pins);
/**
* pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin
* @pctldev: the pin controller device to look in
* @pin: a controller-local number to find the range for
*/
struct pinctrl_gpio_range *
pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
unsigned int pin)
pinctrl_find_gpio_range_from_pin_nolock(struct pinctrl_dev *pctldev,
unsigned int pin)
{
struct pinctrl_gpio_range *range;
mutex_lock(&pctldev->mutex);
/* Loop over the ranges */
list_for_each_entry(range, &pctldev->gpio_ranges, node) {
/* Check if we're in the valid range */
......@@ -500,15 +494,32 @@ pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
int a;
for (a = 0; a < range->npins; a++) {
if (range->pins[a] == pin)
goto out;
return range;
}
} else if (pin >= range->pin_base &&
pin < range->pin_base + range->npins)
goto out;
return range;
}
range = NULL;
out:
return NULL;
}
EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin_nolock);
/**
* pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin
* @pctldev: the pin controller device to look in
* @pin: a controller-local number to find the range for
*/
struct pinctrl_gpio_range *
pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
unsigned int pin)
{
struct pinctrl_gpio_range *range;
mutex_lock(&pctldev->mutex);
range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin);
mutex_unlock(&pctldev->mutex);
return range;
}
EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin);
......
......@@ -182,6 +182,10 @@ static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev,
return radix_tree_lookup(&pctldev->pin_desc_tree, pin);
}
extern struct pinctrl_gpio_range *
pinctrl_find_gpio_range_from_pin_nolock(struct pinctrl_dev *pctldev,
unsigned int pin);
int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
bool dup);
void pinctrl_unregister_map(struct pinctrl_map const *map);
......
......@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
......@@ -24,6 +25,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include "../core.h"
#include "pinctrl-imx.h"
......@@ -341,6 +343,31 @@ static int imx_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
return 0;
}
static void imx_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned offset)
{
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
const struct imx_pinctrl_soc_info *info = ipctl->info;
const struct imx_pin_reg *pin_reg;
u32 reg;
/*
* Only Vybrid has the input/output buffer enable flags (IBE/OBE)
* They are part of the shared mux/conf register.
*/
if (!(info->flags & SHARE_MUX_CONF_REG))
return;
pin_reg = &info->pin_regs[offset];
if (pin_reg->mux_reg == -1)
return;
/* Clear IBE/OBE/PUE to disable the pin (Hi-Z) */
reg = readl(ipctl->base + pin_reg->mux_reg);
reg &= ~0x7;
writel(reg, ipctl->base + pin_reg->mux_reg);
}
static int imx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned offset, bool input)
{
......@@ -377,6 +404,7 @@ static const struct pinmux_ops imx_pmx_ops = {
.get_function_groups = imx_pmx_get_groups,
.set_mux = imx_pmx_set,
.gpio_request_enable = imx_pmx_gpio_request_enable,
.gpio_disable_free = imx_pmx_gpio_disable_free,
.gpio_set_direction = imx_pmx_gpio_set_direction,
};
......@@ -692,10 +720,12 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev,
int imx_pinctrl_probe(struct platform_device *pdev,
struct imx_pinctrl_soc_info *info)
{
struct regmap_config config = { .name = "gpr" };
struct device_node *dev_np = pdev->dev.of_node;
struct device_node *np;
struct imx_pinctrl *ipctl;
struct resource *res;
struct regmap *gpr;
int ret, i;
if (!info || !info->pins || !info->npins) {
......@@ -704,6 +734,12 @@ int imx_pinctrl_probe(struct platform_device *pdev,
}
info->dev = &pdev->dev;
if (info->gpr_compatible) {
gpr = syscon_regmap_lookup_by_compatible(info->gpr_compatible);
if (!IS_ERR(gpr))
regmap_attach_dev(&pdev->dev, gpr, &config);
}
/* Create state holders etc for this driver */
ipctl = devm_kzalloc(&pdev->dev, sizeof(*ipctl), GFP_KERNEL);
if (!ipctl)
......
......@@ -82,6 +82,7 @@ struct imx_pinctrl_soc_info {
struct imx_pmx_func *functions;
unsigned int nfunctions;
unsigned int flags;
const char *gpr_compatible;
};
#define SHARE_MUX_CONF_REG 0x1
......
......@@ -389,6 +389,7 @@ static const struct pinctrl_pin_desc imx50_pinctrl_pads[] = {
static struct imx_pinctrl_soc_info imx50_pinctrl_info = {
.pins = imx50_pinctrl_pads,
.npins = ARRAY_SIZE(imx50_pinctrl_pads),
.gpr_compatible = "fsl,imx50-iomuxc-gpr",
};
static const struct of_device_id imx50_pinctrl_of_match[] = {
......
......@@ -452,6 +452,7 @@ static const struct pinctrl_pin_desc imx53_pinctrl_pads[] = {
static struct imx_pinctrl_soc_info imx53_pinctrl_info = {
.pins = imx53_pinctrl_pads,
.npins = ARRAY_SIZE(imx53_pinctrl_pads),
.gpr_compatible = "fsl,imx53-iomuxc-gpr",
};
static const struct of_device_id imx53_pinctrl_of_match[] = {
......
......@@ -458,6 +458,7 @@ static const struct pinctrl_pin_desc imx6dl_pinctrl_pads[] = {
static struct imx_pinctrl_soc_info imx6dl_pinctrl_info = {
.pins = imx6dl_pinctrl_pads,
.npins = ARRAY_SIZE(imx6dl_pinctrl_pads),
.gpr_compatible = "fsl,imx6q-iomuxc-gpr",
};
static const struct of_device_id imx6dl_pinctrl_of_match[] = {
......
......@@ -464,6 +464,7 @@ static const struct pinctrl_pin_desc imx6q_pinctrl_pads[] = {
static struct imx_pinctrl_soc_info imx6q_pinctrl_info = {
.pins = imx6q_pinctrl_pads,
.npins = ARRAY_SIZE(imx6q_pinctrl_pads),
.gpr_compatible = "fsl,imx6q-iomuxc-gpr",
};
static const struct of_device_id imx6q_pinctrl_of_match[] = {
......
......@@ -364,6 +364,7 @@ static const struct pinctrl_pin_desc imx6sl_pinctrl_pads[] = {
static struct imx_pinctrl_soc_info imx6sl_pinctrl_info = {
.pins = imx6sl_pinctrl_pads,
.npins = ARRAY_SIZE(imx6sl_pinctrl_pads),
.gpr_compatible = "fsl,imx6sl-iomuxc-gpr",
};
static const struct of_device_id imx6sl_pinctrl_of_match[] = {
......
......@@ -368,6 +368,7 @@ static const struct pinctrl_pin_desc imx6sx_pinctrl_pads[] = {
static struct imx_pinctrl_soc_info imx6sx_pinctrl_info = {
.pins = imx6sx_pinctrl_pads,
.npins = ARRAY_SIZE(imx6sx_pinctrl_pads),
.gpr_compatible = "fsl,imx6sx-iomuxc-gpr",
};
static const struct of_device_id imx6sx_pinctrl_of_match[] = {
......
......@@ -284,6 +284,7 @@ static const struct pinctrl_pin_desc imx6ul_pinctrl_pads[] = {
static struct imx_pinctrl_soc_info imx6ul_pinctrl_info = {
.pins = imx6ul_pinctrl_pads,
.npins = ARRAY_SIZE(imx6ul_pinctrl_pads),
.gpr_compatible = "fsl,imx6ul-iomuxc-gpr",
};
static struct of_device_id imx6ul_pinctrl_of_match[] = {
......
......@@ -359,6 +359,7 @@ static const struct pinctrl_pin_desc imx7d_lpsr_pinctrl_pads[] = {
static struct imx_pinctrl_soc_info imx7d_pinctrl_info = {
.pins = imx7d_pinctrl_pads,
.npins = ARRAY_SIZE(imx7d_pinctrl_pads),
.gpr_compatible = "fsl,imx7d-iomuxc-gpr",
};
static struct imx_pinctrl_soc_info imx7d_lpsr_pinctrl_info = {
......
......@@ -11,13 +11,9 @@
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/acpi.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
......
if ARCH_MEDIATEK || COMPILE_TEST
config PINCTRL_MTK_COMMON
config PINCTRL_MTK
bool
depends on OF
select PINMUX
......@@ -9,17 +9,29 @@ config PINCTRL_MTK_COMMON
select OF_GPIO
# For ARMv7 SoCs
config PINCTRL_MT2701
bool "Mediatek MT2701 pin control" if COMPILE_TEST && !MACH_MT2701
depends on OF
default MACH_MT2701
select PINCTRL_MTK
config PINCTRL_MT7623
bool "Mediatek MT7623 pin control" if COMPILE_TEST && !MACH_MT7623
depends on OF
default MACH_MT7623
select PINCTRL_MTK_COMMON
config PINCTRL_MT8135
bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135
depends on OF
default MACH_MT8135
select PINCTRL_MTK_COMMON
select PINCTRL_MTK
config PINCTRL_MT8127
bool "Mediatek MT8127 pin control" if COMPILE_TEST && !MACH_MT8127
depends on OF
default MACH_MT8127
select PINCTRL_MTK_COMMON
select PINCTRL_MTK
# For ARMv8 SoCs
config PINCTRL_MT8173
......@@ -27,13 +39,13 @@ config PINCTRL_MT8173
depends on OF
depends on ARM64 || COMPILE_TEST
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK_COMMON
select PINCTRL_MTK
# For PMIC
config PINCTRL_MT6397
bool "Mediatek MT6397 pin control" if COMPILE_TEST && !MFD_MT6397
depends on OF
default MFD_MT6397
select PINCTRL_MTK_COMMON
select PINCTRL_MTK
endif
# Core
obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o
obj-y += pinctrl-mtk-common.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
obj-$(CONFIG_PINCTRL_MT6397) += pinctrl-mt6397.o
obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
obj-$(CONFIG_PINCTRL_MT6397) += pinctrl-mt6397.o
This diff is collapsed.
......@@ -12,7 +12,7 @@
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
......@@ -55,7 +55,6 @@ static const struct of_device_id mt6397_pctrl_match[] = {
{ .compatible = "mediatek,mt6397-pinctrl", },
{ }
};
MODULE_DEVICE_TABLE(of, mt6397_pctrl_match);
static struct platform_driver mtk_pinctrl_driver = {
.probe = mt6397_pinctrl_probe,
......@@ -69,9 +68,4 @@ static int __init mtk_pinctrl_init(void)
{
return platform_driver_register(&mtk_pinctrl_driver);
}
module_init(mtk_pinctrl_init);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek MT6397 Pinctrl Driver");
MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>");
device_initcall(mtk_pinctrl_init);
This diff is collapsed.
......@@ -13,7 +13,7 @@
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
......@@ -336,7 +336,6 @@ static const struct of_device_id mt8127_pctrl_match[] = {
{ .compatible = "mediatek,mt8127-pinctrl", },
{ }
};
MODULE_DEVICE_TABLE(of, mt8127_pctrl_match);
static struct platform_driver mtk_pinctrl_driver = {
.probe = mt8127_pinctrl_probe,
......@@ -350,9 +349,4 @@ static int __init mtk_pinctrl_init(void)
{
return platform_driver_register(&mtk_pinctrl_driver);
}
arch_initcall(mtk_pinctrl_init);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek MT8127 Pinctrl Driver");
MODULE_AUTHOR("Yingjoe Chen <yingjoe.chen@mediatek.com>");
......@@ -12,7 +12,7 @@
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
......@@ -351,7 +351,6 @@ static const struct of_device_id mt8135_pctrl_match[] = {
},
{ }
};
MODULE_DEVICE_TABLE(of, mt8135_pctrl_match);
static struct platform_driver mtk_pinctrl_driver = {
.probe = mt8135_pinctrl_probe,
......@@ -365,9 +364,4 @@ static int __init mtk_pinctrl_init(void)
{
return platform_driver_register(&mtk_pinctrl_driver);
}
arch_initcall(mtk_pinctrl_init);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MediaTek Pinctrl Driver");
MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>");
......@@ -12,7 +12,7 @@
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
......@@ -378,7 +378,6 @@ static const struct of_device_id mt8173_pctrl_match[] = {
},
{ }
};
MODULE_DEVICE_TABLE(of, mt8173_pctrl_match);
static struct platform_driver mtk_pinctrl_driver = {
.probe = mt8173_pinctrl_probe,
......@@ -393,9 +392,4 @@ static int __init mtk_pinctrl_init(void)
{
return platform_driver_register(&mtk_pinctrl_driver);
}
arch_initcall(mtk_pinctrl_init);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek Pinctrl Driver");
MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>");
......@@ -43,10 +43,13 @@
#define MAX_GPIO_MODE_PER_REG 5
#define GPIO_MODE_BITS 3
#define GPIO_MODE_PREFIX "GPIO"
static const char * const mtk_gpio_functions[] = {
"func0", "func1", "func2", "func3",
"func4", "func5", "func6", "func7",
"func8", "func9", "func10", "func11",
"func12", "func13", "func14", "func15",
};
/*
......@@ -81,6 +84,9 @@ static int mtk_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
bit = BIT(offset & 0xf);
if (pctl->devdata->spec_dir_set)
pctl->devdata->spec_dir_set(&reg_addr, offset);
if (input)
/* Different SoC has different alignment offset. */
reg_addr = CLR_ADDR(reg_addr, pctl);
......@@ -677,9 +683,14 @@ static int mtk_pmx_set_mode(struct pinctrl_dev *pctldev,
unsigned int mask = (1L << GPIO_MODE_BITS) - 1;
struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
if (pctl->devdata->spec_pinmux_set)
pctl->devdata->spec_pinmux_set(mtk_get_regmap(pctl, pin),
pin, mode);
reg_addr = ((pin / MAX_GPIO_MODE_PER_REG) << pctl->devdata->port_shf)
+ pctl->devdata->pinmux_offset;
mode &= mask;
bit = pin % MAX_GPIO_MODE_PER_REG;
mask <<= (GPIO_MODE_BITS * bit);
val = (mode << (GPIO_MODE_BITS * bit));
......@@ -725,12 +736,48 @@ static int mtk_pmx_set_mux(struct pinctrl_dev *pctldev,
return 0;
}
static int mtk_pmx_find_gpio_mode(struct mtk_pinctrl *pctl,
unsigned offset)
{
const struct mtk_desc_pin *pin = pctl->devdata->pins + offset;
const struct mtk_desc_function *func = pin->functions;
while (func && func->name) {
if (!strncmp(func->name, GPIO_MODE_PREFIX,
sizeof(GPIO_MODE_PREFIX)-1))
return func->muxval;
func++;
}
return -EINVAL;
}
static int mtk_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
{
int muxval;
struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
muxval = mtk_pmx_find_gpio_mode(pctl, offset);
if (muxval < 0) {
dev_err(pctl->dev, "invalid gpio pin %d.\n", offset);
return -EINVAL;
}
mtk_pmx_set_mode(pctldev, offset, muxval);
mtk_pconf_set_ies_smt(pctl, offset, 1, PIN_CONFIG_INPUT_ENABLE);
return 0;
}
static const struct pinmux_ops mtk_pmx_ops = {
.get_functions_count = mtk_pmx_get_funcs_cnt,
.get_function_name = mtk_pmx_get_func_name,
.get_function_groups = mtk_pmx_get_func_groups,
.set_mux = mtk_pmx_set_mux,
.gpio_set_direction = mtk_pmx_gpio_set_direction,
.gpio_request_enable = mtk_pmx_gpio_request_enable,
};
static int mtk_gpio_direction_input(struct gpio_chip *chip,
......@@ -756,6 +803,10 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
bit = BIT(offset & 0xf);
if (pctl->devdata->spec_dir_set)
pctl->devdata->spec_dir_set(&reg_addr, offset);
regmap_read(pctl->regmap1, reg_addr, &read_val);
return !(read_val & bit);
}
......@@ -814,6 +865,10 @@ static int mtk_pinctrl_irq_request_resources(struct irq_data *d)
/* set mux to INT mode */
mtk_pmx_set_mode(pctl->pctl_dev, pin->pin.number, pin->eint.eintmux);
/* set gpio direction to input */
mtk_pmx_gpio_set_direction(pctl->pctl_dev, NULL, pin->pin.number, true);
/* set input-enable */
mtk_pconf_set_ies_smt(pctl, pin->pin.number, 1, PIN_CONFIG_INPUT_ENABLE);
return 0;
}
......
......@@ -209,7 +209,14 @@ struct mtk_eint_offsets {
* means when user set smt, input enable is set at the same time. So they
* also need special control. If special control is success, this should
* return 0, otherwise return non-zero value.
*
* @spec_pinmux_set: In some cases, there are two pinmux functions share
* the same value in the same segment of pinmux control register. If user
* want to use one of the two functions, they need an extra bit setting to
* select the right one.
* @spec_dir_set: In very few SoCs, direction control registers are not
* arranged continuously, they may be cut to parts. So they need special
* dir setting.
* @dir_offset: The direction register offset.
* @pullen_offset: The pull-up/pull-down enable register offset.
* @pinmux_offset: The pinmux register offset.
......@@ -234,6 +241,9 @@ struct mtk_pinctrl_devdata {
unsigned char align, bool isup, unsigned int arg);
int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin,
unsigned char align, int value, enum pin_config_param arg);
void (*spec_pinmux_set)(struct regmap *reg, unsigned int pin,
unsigned int mode);
void (*spec_dir_set)(unsigned int *reg_addr, unsigned int pin);
unsigned int dir_offset;
unsigned int ies_offset;
unsigned int smt_offset;
......
This diff is collapsed.
This diff is collapsed.
......@@ -49,7 +49,6 @@
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/pinctrl/pinconf-generic.h>
......@@ -104,15 +103,13 @@ static int meson_get_domain_and_bank(struct meson_pinctrl *pc, unsigned int pin,
struct meson_bank **bank)
{
struct meson_domain *d;
int i;
for (i = 0; i < pc->data->num_domains; i++) {
d = &pc->domains[i];
if (pin >= d->data->pin_base &&
pin < d->data->pin_base + d->data->num_pins) {
*domain = d;
return meson_get_bank(d, pin, bank);
}
d = pc->domain;
if (pin >= d->data->pin_base &&
pin < d->data->pin_base + d->data->num_pins) {
*domain = d;
return meson_get_bank(d, pin, bank);
}
return -EINVAL;
......@@ -204,7 +201,7 @@ static void meson_pmx_disable_other_groups(struct meson_pinctrl *pc,
for (j = 0; j < group->num_pins; j++) {
if (group->pins[j] == pin) {
/* We have found a group using the pin */
domain = &pc->domains[group->domain];
domain = pc->domain;
regmap_update_bits(domain->reg_mux,
group->reg * 4,
BIT(group->bit), 0);
......@@ -219,7 +216,7 @@ static int meson_pmx_set_mux(struct pinctrl_dev *pcdev, unsigned func_num,
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
struct meson_pmx_func *func = &pc->data->funcs[func_num];
struct meson_pmx_group *group = &pc->data->groups[group_num];
struct meson_domain *domain = &pc->domains[group->domain];
struct meson_domain *domain = pc->domain;
int i, ret = 0;
dev_dbg(pc->dev, "enable function %s, group %s\n", func->name,
......@@ -537,76 +534,67 @@ static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
static const struct of_device_id meson_pinctrl_dt_match[] = {
{
.compatible = "amlogic,meson8-pinctrl",
.data = &meson8_pinctrl_data,
.compatible = "amlogic,meson8-cbus-pinctrl",
.data = &meson8_cbus_pinctrl_data,
},
{
.compatible = "amlogic,meson8b-cbus-pinctrl",
.data = &meson8b_cbus_pinctrl_data,
},
{
.compatible = "amlogic,meson8-aobus-pinctrl",
.data = &meson8_aobus_pinctrl_data,
},
{
.compatible = "amlogic,meson8b-pinctrl",
.data = &meson8b_pinctrl_data,
.compatible = "amlogic,meson8b-aobus-pinctrl",
.data = &meson8b_aobus_pinctrl_data,
},
{ },
};
MODULE_DEVICE_TABLE(of, meson_pinctrl_dt_match);
static int meson_gpiolib_register(struct meson_pinctrl *pc)
{
struct meson_domain *domain;
int i, ret;
int ret;
for (i = 0; i < pc->data->num_domains; i++) {
domain = &pc->domains[i];
domain->chip.label = domain->data->name;
domain->chip.parent = pc->dev;
domain->chip.request = meson_gpio_request;
domain->chip.free = meson_gpio_free;
domain->chip.direction_input = meson_gpio_direction_input;
domain->chip.direction_output = meson_gpio_direction_output;
domain->chip.get = meson_gpio_get;
domain->chip.set = meson_gpio_set;
domain->chip.base = domain->data->pin_base;
domain->chip.ngpio = domain->data->num_pins;
domain->chip.can_sleep = false;
domain->chip.of_node = domain->of_node;
domain->chip.of_gpio_n_cells = 2;
ret = gpiochip_add_data(&domain->chip, domain);
if (ret) {
dev_err(pc->dev, "can't add gpio chip %s\n",
domain->data->name);
goto fail;
}
domain = pc->domain;
domain->chip.label = domain->data->name;
domain->chip.parent = pc->dev;
domain->chip.request = meson_gpio_request;
domain->chip.free = meson_gpio_free;
domain->chip.direction_input = meson_gpio_direction_input;
domain->chip.direction_output = meson_gpio_direction_output;
domain->chip.get = meson_gpio_get;
domain->chip.set = meson_gpio_set;
domain->chip.base = domain->data->pin_base;
domain->chip.ngpio = domain->data->num_pins;
domain->chip.can_sleep = false;
domain->chip.of_node = domain->of_node;
domain->chip.of_gpio_n_cells = 2;
ret = gpiochip_add_data(&domain->chip, domain);
if (ret) {
dev_err(pc->dev, "can't add gpio chip %s\n",
domain->data->name);
goto fail;
}
ret = gpiochip_add_pin_range(&domain->chip, dev_name(pc->dev),
0, domain->data->pin_base,
domain->chip.ngpio);
if (ret) {
dev_err(pc->dev, "can't add pin range\n");
goto fail;
}
ret = gpiochip_add_pin_range(&domain->chip, dev_name(pc->dev),
0, domain->data->pin_base,
domain->chip.ngpio);
if (ret) {
dev_err(pc->dev, "can't add pin range\n");
goto fail;
}
return 0;
fail:
for (i--; i >= 0; i--)
gpiochip_remove(&pc->domains[i].chip);
gpiochip_remove(&pc->domain->chip);
return ret;
}
static struct meson_domain_data *meson_get_domain_data(struct meson_pinctrl *pc,
struct device_node *np)
{
int i;
for (i = 0; i < pc->data->num_domains; i++) {
if (!strcmp(np->name, pc->data->domain_data[i].name))
return &pc->data->domain_data[i];
}
return NULL;
}
static struct regmap_config meson_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
......@@ -643,7 +631,7 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
{
struct device_node *np;
struct meson_domain *domain;
int i = 0, num_domains = 0;
int num_domains = 0;
for_each_child_of_node(node, np) {
if (!of_find_property(np, "gpio-controller", NULL))
......@@ -651,29 +639,22 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
num_domains++;
}
if (num_domains != pc->data->num_domains) {
if (num_domains != 1) {
dev_err(pc->dev, "wrong number of subnodes\n");
return -EINVAL;
}
pc->domains = devm_kzalloc(pc->dev, num_domains *
sizeof(struct meson_domain), GFP_KERNEL);
if (!pc->domains)
pc->domain = devm_kzalloc(pc->dev, sizeof(struct meson_domain), GFP_KERNEL);
if (!pc->domain)
return -ENOMEM;
domain = pc->domain;
domain->data = pc->data->domain_data;
for_each_child_of_node(node, np) {
if (!of_find_property(np, "gpio-controller", NULL))
continue;
domain = &pc->domains[i];
domain->data = meson_get_domain_data(pc, np);
if (!domain->data) {
dev_err(pc->dev, "domain data not found for node %s\n",
np->name);
return -ENODEV;
}
domain->of_node = np;
domain->reg_mux = meson_map_resource(pc, np, "mux");
......@@ -699,7 +680,7 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
return PTR_ERR(domain->reg_gpio);
}
i++;
break;
}
return 0;
......@@ -718,7 +699,7 @@ static int meson_pinctrl_probe(struct platform_device *pdev)
pc->dev = dev;
match = of_match_node(meson_pinctrl_dt_match, pdev->dev.of_node);
pc->data = (struct meson_pinctrl_data *)match->data;
pc->data = (struct meson_pinctrl_data *) match->data;
ret = meson_pinctrl_parse_dt(pc, pdev->dev.of_node);
if (ret)
......@@ -754,8 +735,4 @@ static struct platform_driver meson_pinctrl_driver = {
.of_match_table = meson_pinctrl_dt_match,
},
};
module_platform_driver(meson_pinctrl_driver);
MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
MODULE_DESCRIPTION("Amlogic Meson pinctrl driver");
MODULE_LICENSE("GPL v2");
builtin_platform_driver(meson_pinctrl_driver);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -287,6 +287,10 @@ static const unsigned i2c0_a_1_pins[] = { STN8815_PIN_D3, STN8815_PIN_D2 };
/* Altfunction B */
static const unsigned u1_b_1_pins[] = { STN8815_PIN_B16, STN8815_PIN_A16 };
static const unsigned i2cusb_b_1_pins[] = { STN8815_PIN_C21, STN8815_PIN_C20 };
static const unsigned clcd_16_23_b_1_pins[] = { STN8815_PIN_AB6,
STN8815_PIN_AA6, STN8815_PIN_Y6, STN8815_PIN_Y5, STN8815_PIN_AA5,
STN8815_PIN_AB5, STN8815_PIN_AB4, STN8815_PIN_Y4 };
#define STN8815_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \
.npins = ARRAY_SIZE(a##_pins), .altsetting = b }
......@@ -302,6 +306,7 @@ static const struct nmk_pingroup nmk_stn8815_groups[] = {
STN8815_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
STN8815_PIN_GROUP(u1_b_1, NMK_GPIO_ALT_B),
STN8815_PIN_GROUP(i2cusb_b_1, NMK_GPIO_ALT_B),
STN8815_PIN_GROUP(clcd_16_23_b_1, NMK_GPIO_ALT_B),
};
/* We use this macro to define the groups applicable to a function */
......@@ -314,6 +319,7 @@ STN8815_FUNC_GROUPS(u1, "u1_a_1", "u1_b_1");
STN8815_FUNC_GROUPS(i2c1, "i2c1_a_1");
STN8815_FUNC_GROUPS(i2c0, "i2c0_a_1");
STN8815_FUNC_GROUPS(i2cusb, "i2cusb_b_1");
STN8815_FUNC_GROUPS(clcd, "clcd_16_23_b_1");
#define FUNCTION(fname) \
{ \
......@@ -329,6 +335,7 @@ static const struct nmk_function nmk_stn8815_functions[] = {
FUNCTION(i2c1),
FUNCTION(i2c0),
FUNCTION(i2cusb),
FUNCTION(clcd),
};
static const struct nmk_pinctrl_soc_data nmk_stn8815_soc = {
......
......@@ -753,8 +753,8 @@ static int amd_gpio_probe(struct platform_device *pdev)
gpio_dev->base = devm_ioremap_nocache(&pdev->dev, res->start,
resource_size(res));
if (IS_ERR(gpio_dev->base))
return PTR_ERR(gpio_dev->base);
if (!gpio_dev->base)
return -ENOMEM;
irq_base = platform_get_irq(pdev, 0);
if (irq_base < 0) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# Core
obj-$(CONFIG_PINCTRL_STM32) += pinctrl-stm32.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_STM32F429) += pinctrl-stm32f429.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment