This is the bulk of pin control changes for the v4.8 kernel cycle.

New drivers:
 
 - New driver for Oxnas pin control and GPIO. This ARM-based chipset
   is used in a few storage (NAS) type devices.
 
 - New driver for the MAX77620/MAX20024 pin controller portions.
 
 - New driver for the Intel Merrifield pin controller.
 
 New subdrivers:
 
 - New subdriver for the Qualcomm MDM9615
 
 - New subdriver for the STM32F746 MCU
 
 - New subdriver for the Broadcom NSP SoC.
 
 Cleanups:
 
 - Demodularization of bool compiled-in drivers.
 
 Apart from this there is just regular incremental improvements to
 a lot of drivers, especially Uniphier and PFC.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJXmcthAAoJEEEQszewGV1z2ukP/1T34tgMllEzBcnyTM28pnPl
 80anOiCi/jkLuW1hYTLc4Rx0tZT2oWw9hrZdKGNMuzNCaJSmFaRhUrbzxhZ8E+6O
 3AHYSopAYUTKVYJsuY+fs3HbNajKBsSWYdmxin4e953BPudLjhZ2WliDXxupsbwZ
 /KI6s8J2pDZcPurrlozT5Avp3BTwwCq+fo12NIMkkmuhURb69OsDAVjPlwjocq73
 BKcdH8AdgO7w5Ss5/IQbvrhyuFc2kCQ/wH1tiuE2a4iYWhp+QkMOEqWUSdYs33bx
 Sbn3KTK6IYYS1eb4xharh7H/zoBs20aCQ2kS8qbYmG+Fv7rB7qboI0qM7m7+25O8
 7F6Tf4F0HUg6IjcABcI5lFuTxACBG8p5ZlmQAp/36EaeIblLALBCvd1ArmZ6fdG+
 Pzu5vLaZBAmxQn6EseHLAJkH4FEzV7II/Sk7U23TINHUpl/L2GJO+6irz7eelKAk
 XED6mrNU8rRnZMka02ZnIgIbABG7ELNJsRxEnf8k9CX7cfi4p568eZeR1nfKcy4+
 uldJLipNv3NfwuRY5JEEa7pFW4azYmnzS1GcoVYPy7snYc4Rr8cbBD6YvcxyMhVz
 RXHc21mj45JnboldAYU59t5BbVZNwZqF8hmg935ngoaZjYfhhnfGoNQF7hy6/1fS
 bwojoQtBqGcriKZYGs0o
 =po0g
 -----END PGP SIGNATURE-----

Merge tag 'pinctrl-v4.8-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.8 kernel cycle.

  Nothing stands out as especially exiting: new drivers, new subdrivers,
  lots of cleanups and incremental features.

  Business as usual.

  New drivers:

   - New driver for Oxnas pin control and GPIO.  This ARM-based chipset
     is used in a few storage (NAS) type devices.

   - New driver for the MAX77620/MAX20024 pin controller portions.

   - New driver for the Intel Merrifield pin controller.

  New subdrivers:

   - New subdriver for the Qualcomm MDM9615

   - New subdriver for the STM32F746 MCU

   - New subdriver for the Broadcom NSP SoC.

  Cleanups:

   - Demodularization of bool compiled-in drivers.

  Apart from this there is just regular incremental improvements to a
  lot of drivers, especially Uniphier and PFC"

* tag 'pinctrl-v4.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (131 commits)
  pinctrl: fix pincontrol definition for marvell
  pinctrl: xway: fix typo
  Revert "pinctrl: amd: make it explicitly non-modular"
  pinctrl: iproc: Add NSP and Stingray GPIO support
  pinctrl: Update iProc GPIO DT bindings
  pinctrl: bcm: add OF dependencies
  pinctrl: ns2: remove redundant dev_err call in ns2_pinmux_probe()
  pinctrl: Add STM32F746 MCU support
  pinctrl: intel: Protect set wake flow by spin lock
  pinctrl: nsp: remove redundant dev_err call in nsp_pinmux_probe()
  pinctrl: uniphier: add Ethernet pin-mux settings
  sh-pfc: Use PTR_ERR_OR_ZERO() to simplify the code
  pinctrl: ns2: fix return value check in ns2_pinmux_probe()
  pinctrl: qcom: update DT bindings with ebi2 groups
  pinctrl: qcom: establish proper EBI2 pin groups
  pinctrl: imx21: Remove the MODULE_DEVICE_TABLE() macro
  Documentation: dt: Add new compatible to STM32 pinctrl driver bindings
  includes: dt-bindings: Add STM32F746 pinctrl DT bindings
  pinctrl: sunxi: fix nand0 function name for sun8i
  pinctrl: uniphier: remove pointless pin-mux settings for PH1-LD11
  ...
This commit is contained in:
Linus Torvalds 2016-07-28 17:06:51 -07:00
commit d94ba9e7d8
119 changed files with 12550 additions and 2698 deletions

View File

@ -0,0 +1,47 @@
* Oxford Semiconductor OXNAS SoC GPIO Controller
Please refer to gpio.txt for generic information regarding GPIO bindings.
Required properties:
- compatible: "oxsemi,ox810se-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
- 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
- gpio-ranges: Interaction with the PINCTRL subsystem, it also specifies the
gpio base and count, should be in the format of numeric-gpio-range as
specified in the gpio.txt file.
Example:
gpio0: gpio@0 {
compatible = "oxsemi,ox810se-gpio";
reg = <0x000000 0x100000>;
interrupts = <21>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
gpio-ranges = <&pinctrl 0 0 32>;
};
keys {
...
button-esc {
label = "ESC";
linux,code = <1>;
gpios = <&gpio0 12 0>;
};
};

View File

@ -3,8 +3,22 @@ Broadcom iProc GPIO/PINCONF Controller
Required properties:
- compatible:
Must be "brcm,cygnus-ccm-gpio", "brcm,cygnus-asiu-gpio",
"brcm,cygnus-crmu-gpio" or "brcm,iproc-gpio"
"brcm,iproc-gpio" for the generic iProc based GPIO controller IP that
supports full-featured pinctrl and GPIO functions used in various iProc
based SoCs
May contain an SoC-specific compatibility string to accommodate any
SoC-specific features
"brcm,cygnus-ccm-gpio", "brcm,cygnus-asiu-gpio", or
"brcm,cygnus-crmu-gpio" for Cygnus SoCs
"brcm,iproc-nsp-gpio" for the iProc NSP SoC that has drive strength support
disabled
"brcm,iproc-stingray-gpio" for the iProc Stingray SoC that has the general
pinctrl support completely disabled in this IP block. In Stingray, a
different IP block is used to handle pinctrl related functions
- reg:
Define the base and range of the I/O address space that contains SoC

View File

@ -0,0 +1,79 @@
Broadcom NSP (Northstar plus) IOMUX Controller
The NSP IOMUX controller supports group based mux configuration. In
addition, certain pins can be muxed to GPIO function individually.
Required properties:
- compatible:
Must be "brcm,nsp-pinmux"
- reg:
Should contain the register physical address and length for each of
GPIO_CONTROL0, GP_AUX_SEL and IPROC_CONFIG IOMUX registers
Properties in subnodes:
- function:
The mux function to select
- groups:
The list of groups to select with a given function
For more details, refer to
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
For example:
pinmux: pinmux@1803f1c0 {
compatible = "brcm,nsp-pinmux";
reg = <0x1803f1c0 0x04>,
<0x18030028 0x04>,
<0x1803f408 0x04>;
pinctrl-names = "default";
pinctrl-0 = <&pwm &gpio_b &nand_sel>;
pwm: pwm {
function = "pwm";
groups = "pwm0_grp", "pwm1_grp";
};
gpio_b: gpio_b {
function = "gpio_b";
groups = "gpio_b_0_grp", "gpio_b_1_grp";
};
nand_sel: nand_sel {
function = "nand";
groups = "nand_grp";
};
};
List of supported functions and groups in Northstar Plus:
"spi": "spi_grp"
"i2c": "i2c_grp"
"mdio": "mdio_grp"
"pwm": "pwm0_grp", "pwm1_grp", "pwm2_grp", "pwm3_grp"
"gpio_b": "gpio_b_0_grp", "gpio_b_1_grp", "gpio_b_2_grp", "gpio_b_3_grp"
"uart1": "uart1_grp"
"uart2": "uart2_grp"
"synce": "synce_grp"
"sata_led_grps": "sata0_led_grp", "sata1_led_grp"
"xtal_out": "xtal_out_grp"
"sdio": "sdio_pwr_grp", "sdio_1p8v_grp"
"switch_led": "switch_p05_led0_grp", "switch_p05_led1_grp"
"nand": "nand_grp"
"emmc": "emmc_grp"

View File

@ -0,0 +1,57 @@
* Oxford Semiconductor OXNAS SoC Family 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.
OXNAS 'pin configuration node' is a node of a group of pins which can be
used for a specific device or function. This node represents configurations of
pins, optional function, and optional mux related configuration.
Required properties for pin controller node:
- compatible: "oxsemi,ox810se-pinctrl"
- oxsemi,sys-ctrl: a phandle to the system controller syscon node
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.
Example:
pinctrl: pinctrl {
compatible = "oxsemi,ox810se-pinctrl";
/* Regmap for sys registers */
oxsemi,sys-ctrl = <&sys>;
pinctrl_uart2: pinctrl_uart2 {
uart2a {
pins = "gpio31";
function = "fct3";
};
uart2b {
pins = "gpio32";
function = "fct3";
};
};
};
uart2: serial@900000 {
compatible = "ns16550a";
reg = <0x900000 0x100000>;
clocks = <&sysclk>;
interrupts = <29>;
reg-shift = <0>;
fifo-size = <16>;
reg-io-width = <1>;
current-speed = <115200>;
no-loopback-test;
status = "disabled";
resets = <&reset 22>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
};

View File

@ -0,0 +1,127 @@
Pincontrol driver for MAX77620 Power management IC from Maxim Semiconductor.
Device has 8 GPIO pins which can be configured as GPIO as well as the
special IO functions.
Please refer file <devicetree/bindings/pinctrl/pinctrl-bindings.txt>
for details of the common pinctrl bindings used by client devices,
including the meaning of the phrase "pin configuration node".
Optional Pinmux properties:
--------------------------
Following properties are required if default setting of pins are required
at boot.
- pinctrl-names: A pinctrl state named per <pinctrl-binding.txt>.
- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per
<pinctrl-binding.txt>.
The pin configurations are defined as child of the pinctrl states node. Each
sub-node have following properties:
Required properties:
------------------
- pins: List of pins. Valid values of pins properties are:
gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7.
Optional properties:
-------------------
Following are optional properties defined as pinmux DT binding document
<pinctrl-bindings.txt>. Absence of properties will leave the configuration
on default.
function,
drive-push-pull,
drive-open-drain,
bias-pull-up,
bias-pull-down.
Valid values for function properties are:
gpio, lpm-control-in, fps-out, 32k-out, sd0-dvs-in, sd1-dvs-in,
reference-out
Theres is also customised properties for the GPIO1, GPIO2 and GPIO3. These
customised properties are required to configure FPS configuration parameters
of these GPIOs. Please refer <devicetree/bindings/mfd/max77620.txt> for more
detail of Flexible Power Sequence (FPS).
- maxim,active-fps-source: FPS source for the GPIOs to get
enabled/disabled when system is in
active state. Valid values are:
- MAX77620_FPS_SRC_0,
FPS source is FPS0.
- MAX77620_FPS_SRC_1,
FPS source is FPS1
- MAX77620_FPS_SRC_2 and
FPS source is FPS2
- MAX77620_FPS_SRC_NONE.
GPIO is not controlled
by FPS events and it gets
enabled/disabled by register
access.
Absence of this property will leave
the FPS configuration register for that
GPIO to default configuration.
- maxim,active-fps-power-up-slot: Sequencing event slot number on which
the GPIO get enabled when
master FPS input event set to HIGH.
Valid values are 0 to 7.
This is applicable if FPS source is
selected as FPS0, FPS1 or FPS2.
- maxim,active-fps-power-down-slot: Sequencing event slot number on which
the GPIO get disabled when master
FPS input event set to LOW.
Valid values are 0 to 7.
This is applicable if FPS source is
selected as FPS0, FPS1 or FPS2.
- maxim,suspend-fps-source: This is same as property
"maxim,active-fps-source" but value
get configured when system enters in
to suspend state.
- maxim,suspend-fps-power-up-slot: This is same as property
"maxim,active-fps-power-up-slot" but
this value get configured into FPS
configuration register when system
enters into suspend.
This is applicable if suspend state
FPS source is selected as FPS0, FPS1 or
- maxim,suspend-fps-power-down-slot: This is same as property
"maxim,active-fps-power-down-slot" but
this value get configured into FPS
configuration register when system
enters into suspend.
This is applicable if suspend state
FPS source is selected as FPS0, FPS1 or
FPS2.
Example:
--------
#include <dt-bindings/mfd/max77620.h>
...
max77620@3c {
pinctrl-names = "default";
pinctrl-0 = <&spmic_default>;
spmic_default: pinmux@0 {
pin_gpio0 {
pins = "gpio0";
function = "gpio";
};
pin_gpio1 {
pins = "gpio1";
function = "fps-out";
maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
};
pin_gpio2 {
pins = "gpio2";
function = "fps-out";
maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
};
};
};

View File

@ -0,0 +1,152 @@
Qualcomm MDM9615 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
MDM9615 platform.
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,mdm9615-pinctrl"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of the TLMM register space.
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the TLMM summary IRQ.
- interrupt-controller:
Usage: required
Value type: <none>
Definition: identifies this node as an interrupt controller
- #interrupt-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/interrupt-controller/irq.h>
- gpio-controller:
Usage: required
Value type: <none>
Definition: identifies this node as a gpio controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/gpio/gpio.h>
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
PIN CONFIGURATION NODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of gpio pins affected by the properties specified in
this subnode. Valid pins are:
gpio0-gpio87
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins.
Valid values are:
gpio, gsbi2_i2c, gsbi3, gsbi4, gsbi5_i2c, gsbi5_uart,
sdc2, ebi2_lcdc, ps_hold, prim_audio, sec_audio,
cdc_mclk
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as no pull.
- bias-pull-down:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull down.
- bias-pull-up:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull up.
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
- drive-strength:
Usage: optional
Value type: <u32>
Definition: Selects the drive strength for the specified pins, in mA.
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
Example:
msmgpio: pinctrl@800000 {
compatible = "qcom,mdm9615-pinctrl";
reg = <0x800000 0x4000>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <0 16 0x4>;
gsbi8_uart: gsbi8-uart {
mux {
pins = "gpio34", "gpio35";
function = "gsbi8";
};
tx {
pins = "gpio34";
drive-strength = <4>;
bias-disable;
};
rx {
pins = "gpio35";
drive-strength = <2>;
bias-pull-up;
};
};
};

View File

@ -52,7 +52,7 @@ Valid values for function are:
gsbi2_spi_cs3_n, gsbi3, gsbi3_spi_cs1_n, gsbi3_spi_cs2_n, gsbi3_spi_cs3_n,
gsbi4, gsbi5, gsbi6, gsbi7, gsbi8, gsbi9, gsbi10, gsbi11, gsbi12, hdmi, i2s,
lcdc, mdp_vsync, mi2s, pcm, ps_hold, sdc1, sdc2, sdc5, tsif1, tsif2, usb_fs1,
usb_fs1_oe_n, usb_fs2, usb_fs2_oe_n, vfe, vsens_alarm,
usb_fs1_oe_n, usb_fs2, usb_fs2_oe_n, vfe, vsens_alarm, ebi2, ebi2cs
Example:

View File

@ -49,6 +49,9 @@ Valid values for pins are:
sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data
Supports bias and drive-strength
hsic_data, hsic_strobe
Supports only mux
Valid values for function are:
cci_i2c0, cci_i2c1, uim1, uim2, uim_batt_alarm,
blsp_uim1, blsp_uart1, blsp_i2c1, blsp_spi1,
@ -70,7 +73,7 @@ Valid values for function are:
cam_mckl0, cam_mclk1, cam_mclk2, cam_mclk3, mdp_vsync, hdmi_cec, hdmi_ddc,
hdmi_hpd, edp_hpd, gp_pdm0, gp_pdm1, gp_pdm2, gp_pdm3, gp0_clk, gp1_clk,
gp_mn, tsif1, tsif2, hsic, grfc, audio_ref_clk, qua_mi2s, pri_mi2s, spkr_mi2s,
ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, gpio
ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, hsic_ctl, gpio
(Note that this is not yet the complete list of functions)

View File

@ -9,6 +9,7 @@ of PMIC's from Qualcomm.
Definition: Should contain one of:
"qcom,pm8018-mpp",
"qcom,pm8038-mpp",
"qcom,pm8058-mpp",
"qcom,pm8821-mpp",
"qcom,pm8841-mpp",
"qcom,pm8916-mpp",

View File

@ -72,7 +72,7 @@ Pin Configuration Node Properties:
The pin configuration parameters use the generic pinconf bindings defined in
pinctrl-bindings.txt in this directory. The supported parameters are
bias-disable, bias-pull-up, bias-pull-down, drive strength and power-source. For
bias-disable, bias-pull-up, bias-pull-down, drive-strength and power-source. For
pins that have a configurable I/O voltage, the power-source value should be the
nominal I/O voltage in millivolts.

View File

@ -9,6 +9,7 @@ Pin controller node:
Required properies:
- compatible: value should be one of the following:
(a) "st,stm32f429-pinctrl"
(b) "st,stm32f746-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

View File

@ -286,13 +286,13 @@ see the section named "pin control requests from drivers" and
"drivers needing both pin control and GPIOs" below for details. But in some
situations a cross-subsystem mapping between pins and GPIOs is needed.
Since the pin controller subsystem have its pinspace local to the pin
controller we need a mapping so that the pin control subsystem can figure out
which pin controller handles control of a certain GPIO pin. Since a single
pin controller may be muxing several GPIO ranges (typically SoCs that have
one set of pins, but internally several GPIO silicon blocks, each modelled as
a struct gpio_chip) any number of GPIO ranges can be added to a pin controller
instance like this:
Since the pin controller subsystem has its pinspace local to the pin controller
we need a mapping so that the pin control subsystem can figure out which pin
controller handles control of a certain GPIO pin. Since a single pin controller
may be muxing several GPIO ranges (typically SoCs that have one set of pins,
but internally several GPIO silicon blocks, each modelled as a struct
gpio_chip) any number of GPIO ranges can be added to a pin controller instance
like this:
struct gpio_chip chip_a;
struct gpio_chip chip_b;
@ -493,12 +493,12 @@ Definitions:
- The combination of a FUNCTION and a PIN GROUP determine a certain function
for a certain set of pins. The knowledge of the functions and pin groups
and their machine-specific particulars are kept inside the pinmux driver,
from the outside only the enumerators are known, and the driver core can:
from the outside only the enumerators are known, and the driver core can
request:
- Request the name of a function with a certain selector (>= 0)
- The name of a function with a certain selector (>= 0)
- A list of groups associated with a certain function
- Request that a certain group in that list to be activated for a certain
function
- That a certain group in that list to be activated for a certain function
As already described above, pin groups are in turn self-descriptive, so
the core will retrieve the actual pin range in a certain group from the
@ -831,7 +831,7 @@ separate memory range only intended for GPIO driving, and the register
range dealing with pin config and pin multiplexing get placed into a
different memory range and a separate section of the data sheet.
A flag "strict" in struct pinctrl_desc is available to check and deny
A flag "strict" in struct pinmux_ops is available to check and deny
simultaneous access to the same pin from GPIO and pin multiplexing
consumers on hardware of this type. The pinctrl driver should set this flag
accordingly.

View File

@ -35,7 +35,7 @@ config PINCTRL_ADI2
machine and arch are selected to build.
config PINCTRL_AS3722
bool "Pinctrl and GPIO driver for ams AS3722 PMIC"
tristate "Pinctrl and GPIO driver for ams AS3722 PMIC"
depends on MFD_AS3722 && GPIOLIB
select PINMUX
select GENERIC_PINCONF
@ -129,6 +129,17 @@ config PINCTRL_MESON
select OF_GPIO
select REGMAP_MMIO
config PINCTRL_OXNAS
bool
depends on OF
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB
select OF_GPIO
select GPIOLIB_IRQCHIP
select MFD_SYSCON
config PINCTRL_ROCKCHIP
bool
select PINMUX
@ -196,8 +207,19 @@ config PINCTRL_COH901
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
ports of 8 GPIO pins each.
config PINCTRL_MAX77620
tristate "MAX77620/MAX20024 Pincontrol support"
depends on MFD_MAX77620
select PINMUX
select GENERIC_PINCONF
help
Say Yes here to enable Pin control support for Maxim PMIC MAX77620.
This PMIC has 8 GPIO pins that work as GPIO as well as special
function in alternate mode. This driver also configure push-pull,
open drain, FPS slots etc.
config PINCTRL_PALMAS
bool "Pinctrl driver for the PALMAS Series MFD devices"
tristate "Pinctrl driver for the PALMAS Series MFD devices"
depends on OF && MFD_PALMAS
select PINMUX
select GENERIC_PINCONF

View File

@ -16,7 +16,9 @@ obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o
obj-$(CONFIG_PINCTRL_MESON) += meson/
obj-$(CONFIG_PINCTRL_OXNAS) += pinctrl-oxnas.o
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
@ -35,7 +37,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
obj-$(CONFIG_ARCH_BCM) += bcm/
obj-y += bcm/
obj-$(CONFIG_PINCTRL_BERLIN) += berlin/
obj-y += freescale/
obj-$(CONFIG_X86) += intel/

View File

@ -60,6 +60,7 @@ config PINCTRL_IPROC_GPIO
config PINCTRL_CYGNUS_MUX
bool "Broadcom Cygnus IOMUX driver"
depends on (ARCH_BCM_CYGNUS || COMPILE_TEST)
depends on OF
select PINMUX
select GENERIC_PINCONF
default ARCH_BCM_CYGNUS
@ -99,3 +100,17 @@ config PINCTRL_NS2_MUX
The Broadcom Northstar2 IOMUX driver supports group based IOMUX
configuration.
config PINCTRL_NSP_MUX
bool "Broadcom NSP IOMUX driver"
depends on (ARCH_BCM_NSP || COMPILE_TEST)
depends on OF
select PINMUX
select GENERIC_PINCONF
default ARCH_BCM_NSP
help
Say yes here to enable the Broadcom NSP SOC IOMUX driver.
The Broadcom Northstar Plus IOMUX driver supports pin based IOMUX
configuration, with certain individual pins can be overridden
to GPIO function.

View File

@ -6,3 +6,4 @@ obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o
obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o
obj-$(CONFIG_PINCTRL_NSP_GPIO) += pinctrl-nsp-gpio.o
obj-$(CONFIG_PINCTRL_NS2_MUX) += pinctrl-ns2-mux.o
obj-$(CONFIG_PINCTRL_NSP_MUX) += pinctrl-nsp-mux.o

View File

@ -66,6 +66,14 @@
#define GPIO_DRV_STRENGTH_BITS 3
#define GPIO_DRV_STRENGTH_BIT_MASK ((1 << GPIO_DRV_STRENGTH_BITS) - 1)
enum iproc_pinconf_param {
IPROC_PINCONF_DRIVE_STRENGTH = 0,
IPROC_PINCONF_BIAS_DISABLE,
IPROC_PINCONF_BIAS_PULL_UP,
IPROC_PINCONF_BIAS_PULL_DOWN,
IPROC_PINCON_MAX,
};
/*
* Iproc GPIO core
*
@ -78,6 +86,10 @@
* @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs
* @pinmux_is_supported: flag to indicate this GPIO controller contains pins
* that can be individually muxed to GPIO
* @pinconf_disable: contains a list of PINCONF parameters that need to be
* disabled
* @nr_pinconf_disable: total number of PINCONF parameters that need to be
* disabled
* @pctl: pointer to pinctrl_dev
* @pctldesc: pinctrl descriptor
*/
@ -94,6 +106,9 @@ struct iproc_gpio {
bool pinmux_is_supported;
enum pin_config_param *pinconf_disable;
unsigned int nr_pinconf_disable;
struct pinctrl_dev *pctl;
struct pinctrl_desc pctldesc;
};
@ -360,6 +375,65 @@ static int iproc_gpio_get(struct gpio_chip *gc, unsigned gpio)
return !!(readl(chip->base + offset) & BIT(shift));
}
/*
* Mapping of the iProc PINCONF parameters to the generic pin configuration
* parameters
*/
static const enum pin_config_param iproc_pinconf_disable_map[] = {
[IPROC_PINCONF_DRIVE_STRENGTH] = PIN_CONFIG_DRIVE_STRENGTH,
[IPROC_PINCONF_BIAS_DISABLE] = PIN_CONFIG_BIAS_DISABLE,
[IPROC_PINCONF_BIAS_PULL_UP] = PIN_CONFIG_BIAS_PULL_UP,
[IPROC_PINCONF_BIAS_PULL_DOWN] = PIN_CONFIG_BIAS_PULL_DOWN,
};
static bool iproc_pinconf_param_is_disabled(struct iproc_gpio *chip,
enum pin_config_param param)
{
unsigned int i;
if (!chip->nr_pinconf_disable)
return false;
for (i = 0; i < chip->nr_pinconf_disable; i++)
if (chip->pinconf_disable[i] == param)
return true;
return false;
}
static int iproc_pinconf_disable_map_create(struct iproc_gpio *chip,
unsigned long disable_mask)
{
unsigned int map_size = ARRAY_SIZE(iproc_pinconf_disable_map);
unsigned int bit, nbits = 0;
/* figure out total number of PINCONF parameters to disable */
for_each_set_bit(bit, &disable_mask, map_size)
nbits++;
if (!nbits)
return 0;
/*
* Allocate an array to store PINCONF parameters that need to be
* disabled
*/
chip->pinconf_disable = devm_kcalloc(chip->dev, nbits,
sizeof(*chip->pinconf_disable),
GFP_KERNEL);
if (!chip->pinconf_disable)
return -ENOMEM;
chip->nr_pinconf_disable = nbits;
/* now store these parameters */
nbits = 0;
for_each_set_bit(bit, &disable_mask, map_size)
chip->pinconf_disable[nbits++] = iproc_pinconf_disable_map[bit];
return 0;
}
static int iproc_get_groups_count(struct pinctrl_dev *pctldev)
{
return 1;
@ -500,6 +574,9 @@ static int iproc_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
bool disable, pull_up;
int ret;
if (iproc_pinconf_param_is_disabled(chip, param))
return -ENOTSUPP;
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
iproc_gpio_get_pull(chip, gpio, &disable, &pull_up);
@ -548,6 +625,10 @@ static int iproc_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
if (iproc_pinconf_param_is_disabled(chip, param))
return -ENOTSUPP;
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
@ -633,11 +714,13 @@ static int iproc_gpio_register_pinconf(struct iproc_gpio *chip)
}
static const struct of_device_id iproc_gpio_of_match[] = {
{ .compatible = "brcm,iproc-gpio" },
{ .compatible = "brcm,cygnus-ccm-gpio" },
{ .compatible = "brcm,cygnus-asiu-gpio" },
{ .compatible = "brcm,cygnus-crmu-gpio" },
{ .compatible = "brcm,iproc-gpio" },
{ }
{ .compatible = "brcm,iproc-nsp-gpio" },
{ .compatible = "brcm,iproc-stingray-gpio" },
{ /* sentinel */ }
};
static int iproc_gpio_probe(struct platform_device *pdev)
@ -646,8 +729,17 @@ static int iproc_gpio_probe(struct platform_device *pdev)
struct resource *res;
struct iproc_gpio *chip;
struct gpio_chip *gc;
u32 ngpios;
u32 ngpios, pinconf_disable_mask = 0;
int irq, ret;
bool no_pinconf = false;
/* NSP does not support drive strength config */
if (of_device_is_compatible(dev->of_node, "brcm,iproc-nsp-gpio"))
pinconf_disable_mask = BIT(IPROC_PINCONF_DRIVE_STRENGTH);
/* Stingray does not support pinconf in this controller */
else if (of_device_is_compatible(dev->of_node,
"brcm,iproc-stingray-gpio"))
no_pinconf = true;
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
@ -702,10 +794,22 @@ static int iproc_gpio_probe(struct platform_device *pdev)
return ret;
}
ret = iproc_gpio_register_pinconf(chip);
if (ret) {
dev_err(dev, "unable to register pinconf\n");
goto err_rm_gpiochip;
if (!no_pinconf) {
ret = iproc_gpio_register_pinconf(chip);
if (ret) {
dev_err(dev, "unable to register pinconf\n");
goto err_rm_gpiochip;
}
if (pinconf_disable_mask) {
ret = iproc_pinconf_disable_map_create(chip,
pinconf_disable_mask);
if (ret) {
dev_err(dev,
"unable to create pinconf disable map\n");
goto err_rm_gpiochip;
}
}
}
/* optional GPIO interrupt support */

View File

@ -1044,10 +1044,8 @@ static int ns2_pinmux_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pinctrl->base0)) {
dev_err(&pdev->dev, "unable to map I/O space\n");
if (IS_ERR(pinctrl->base0))
return PTR_ERR(pinctrl->base0);
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
pinctrl->base1 = devm_ioremap_nocache(&pdev->dev, res->start,
@ -1059,10 +1057,8 @@ static int ns2_pinmux_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
pinctrl->pinconf_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pinctrl->pinconf_base)) {
dev_err(&pdev->dev, "unable to map I/O space\n");
if (IS_ERR(pinctrl->pinconf_base))
return PTR_ERR(pinctrl->pinconf_base);
}
ret = ns2_mux_log_init(pinctrl);
if (ret) {
@ -1089,9 +1085,9 @@ static int ns2_pinmux_probe(struct platform_device *pdev)
pinctrl->pctl = pinctrl_register(&ns2_pinctrl_desc, &pdev->dev,
pinctrl);
if (!pinctrl->pctl) {
if (IS_ERR(pinctrl->pctl)) {
dev_err(&pdev->dev, "unable to register IOMUX pinctrl\n");
return -EINVAL;
return PTR_ERR(pinctrl->pctl);
}
return 0;

View File

@ -458,13 +458,15 @@ static int nsp_gpio_get_strength(struct nsp_gpio *chip, unsigned gpio,
return 0;
}
int nsp_pin_config_group_get(struct pinctrl_dev *pctldev, unsigned selector,
static int nsp_pin_config_group_get(struct pinctrl_dev *pctldev,
unsigned selector,
unsigned long *config)
{
return 0;
}
int nsp_pin_config_group_set(struct pinctrl_dev *pctldev, unsigned selector,
static int nsp_pin_config_group_set(struct pinctrl_dev *pctldev,
unsigned selector,
unsigned long *configs, unsigned num_configs)
{
return 0;

View File

@ -0,0 +1,642 @@
/* Copyright (C) 2015 Broadcom Corporation
*
* 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 the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This file contains the Northstar plus (NSP) IOMUX driver that supports
* group based PINMUX configuration. The Northstar plus IOMUX controller
* allows pins to be individually muxed to GPIO function. The NAND and MMC is
* a group based selection. The gpio_a 8 - 11 are muxed with gpio_b and pwm.
* To select PWM, one need to enable the corresponding gpio_b as well.
*
* gpio_a (8 - 11)
* +----------
* |
* gpio_a (8-11) | gpio_b (0 - 3)
* ------------------------+-------+----------
* |
* | pwm (0 - 3)
* +----------
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "../core.h"
#include "../pinctrl-utils.h"
#define NSP_MUX_BASE0 0x00
#define NSP_MUX_BASE1 0x01
#define NSP_MUX_BASE2 0x02
/*
* nsp IOMUX register description
*
* @base: base 0 or base 1
* @shift: bit shift for mux configuration of a group
* @mask: bit mask of the function
* @alt: alternate function to set to
*/
struct nsp_mux {
unsigned int base;
unsigned int shift;
unsigned int mask;
unsigned int alt;
};
/*
* Keep track of nsp IOMUX configuration and prevent double configuration
*
* @nsp_mux: nsp IOMUX register description
* @is_configured: flag to indicate whether a mux setting has already been
* configured
*/
struct nsp_mux_log {
struct nsp_mux mux;
bool is_configured;
};
/*
* Group based IOMUX configuration
*
* @name: name of the group
* @pins: array of pins used by this group
* @num_pins: total number of pins used by this group
* @mux: nsp group based IOMUX configuration
*/
struct nsp_pin_group {
const char *name;
const unsigned int *pins;
const unsigned int num_pins;
const struct nsp_mux mux;
};
/*
* nsp mux function and supported pin groups
*
* @name: name of the function
* @groups: array of groups that can be supported by this function
* @num_groups: total number of groups that can be supported by this function
*/
struct nsp_pin_function {
const char *name;
const char * const *groups;
const unsigned int num_groups;
};
/*
* nsp IOMUX pinctrl core
*
* @pctl: pointer to pinctrl_dev
* @dev: pointer to device
* @base0: first mux register
* @base1: second mux register
* @base2: third mux register
* @groups: pointer to array of groups
* @num_groups: total number of groups
* @functions: pointer to array of functions
* @num_functions: total number of functions
* @mux_log: pointer to the array of mux logs
* @lock: lock to protect register access
*/
struct nsp_pinctrl {
struct pinctrl_dev *pctl;
struct device *dev;
void __iomem *base0;
void __iomem *base1;
void __iomem *base2;
const struct nsp_pin_group *groups;
unsigned int num_groups;
const struct nsp_pin_function *functions;
unsigned int num_functions;
struct nsp_mux_log *mux_log;
spinlock_t lock;
};
/*
* Description of a pin in nsp
*
* @pin: pin number
* @name: pin name
* @gpio_select: reg data to select GPIO
*/
struct nsp_pin {
unsigned int pin;
char *name;
unsigned int gpio_select;
};
#define NSP_PIN_DESC(p, n, g) \
{ \
.pin = p, \
.name = n, \
.gpio_select = g, \
}
/*
* List of muxable pins in nsp
*/
static struct nsp_pin nsp_pins[] = {
NSP_PIN_DESC(0, "spi_clk", 1),
NSP_PIN_DESC(1, "spi_ss", 1),
NSP_PIN_DESC(2, "spi_mosi", 1),
NSP_PIN_DESC(3, "spi_miso", 1),
NSP_PIN_DESC(4, "scl", 1),
NSP_PIN_DESC(5, "sda", 1),
NSP_PIN_DESC(6, "mdc", 1),
NSP_PIN_DESC(7, "mdio", 1),
NSP_PIN_DESC(8, "pwm0", 1),
NSP_PIN_DESC(9, "pwm1", 1),
NSP_PIN_DESC(10, "pwm2", 1),
NSP_PIN_DESC(11, "pwm3", 1),
NSP_PIN_DESC(12, "uart1_rx", 1),
NSP_PIN_DESC(13, "uart1_tx", 1),
NSP_PIN_DESC(14, "uart1_cts", 1),
NSP_PIN_DESC(15, "uart1_rts", 1),
NSP_PIN_DESC(16, "uart2_rx", 1),
NSP_PIN_DESC(17, "uart2_tx", 1),
NSP_PIN_DESC(18, "synce", 0),
NSP_PIN_DESC(19, "sata0_led", 0),
NSP_PIN_DESC(20, "sata1_led", 0),
NSP_PIN_DESC(21, "xtal_out", 1),
NSP_PIN_DESC(22, "sdio_pwr", 1),
NSP_PIN_DESC(23, "sdio_en_1p8v", 1),
NSP_PIN_DESC(24, "gpio_24", 1),
NSP_PIN_DESC(25, "gpio_25", 1),
NSP_PIN_DESC(26, "p5_led0", 0),
NSP_PIN_DESC(27, "p5_led1", 0),
NSP_PIN_DESC(28, "gpio_28", 1),
NSP_PIN_DESC(29, "gpio_29", 1),
NSP_PIN_DESC(30, "gpio_30", 1),
NSP_PIN_DESC(31, "gpio_31", 1),
NSP_PIN_DESC(32, "nand_ale", 0),
NSP_PIN_DESC(33, "nand_ce0", 0),
NSP_PIN_DESC(34, "nand_r/b", 0),
NSP_PIN_DESC(35, "nand_dq0", 0),
NSP_PIN_DESC(36, "nand_dq1", 0),
NSP_PIN_DESC(37, "nand_dq2", 0),
NSP_PIN_DESC(38, "nand_dq3", 0),
NSP_PIN_DESC(39, "nand_dq4", 0),
NSP_PIN_DESC(40, "nand_dq5", 0),
NSP_PIN_DESC(41, "nand_dq6", 0),
NSP_PIN_DESC(42, "nand_dq7", 0),
};
/*
* List of groups of pins
*/
static const unsigned int spi_pins[] = {0, 1, 2, 3};
static const unsigned int i2c_pins[] = {4, 5};
static const unsigned int mdio_pins[] = {6, 7};
static const unsigned int pwm0_pins[] = {8};
static const unsigned int gpio_b_0_pins[] = {8};
static const unsigned int pwm1_pins[] = {9};
static const unsigned int gpio_b_1_pins[] = {9};
static const unsigned int pwm2_pins[] = {10};
static const unsigned int gpio_b_2_pins[] = {10};
static const unsigned int pwm3_pins[] = {11};
static const unsigned int gpio_b_3_pins[] = {11};
static const unsigned int uart1_pins[] = {12, 13, 14, 15};
static const unsigned int uart2_pins[] = {16, 17};
static const unsigned int synce_pins[] = {18};
static const unsigned int sata0_led_pins[] = {19};
static const unsigned int sata1_led_pins[] = {20};
static const unsigned int xtal_out_pins[] = {21};
static const unsigned int sdio_pwr_pins[] = {22};
static const unsigned int sdio_1p8v_pins[] = {23};
static const unsigned int switch_p05_led0_pins[] = {26};
static const unsigned int switch_p05_led1_pins[] = {27};
static const unsigned int nand_pins[] = {32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42};
static const unsigned int emmc_pins[] = {32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42};
#define NSP_PIN_GROUP(group_name, ba, sh, ma, al) \
{ \
.name = __stringify(group_name) "_grp", \
.pins = group_name ## _pins, \
.num_pins = ARRAY_SIZE(group_name ## _pins), \
.mux = { \
.base = ba, \
.shift = sh, \
.mask = ma, \
.alt = al, \
} \
}
/*
* List of nsp pin groups
*/
static const struct nsp_pin_group nsp_pin_groups[] = {
NSP_PIN_GROUP(spi, NSP_MUX_BASE0, 0, 0x0f, 0x00),
NSP_PIN_GROUP(i2c, NSP_MUX_BASE0, 3, 0x03, 0x00),
NSP_PIN_GROUP(mdio, NSP_MUX_BASE0, 5, 0x03, 0x00),
NSP_PIN_GROUP(gpio_b_0, NSP_MUX_BASE0, 7, 0x01, 0x00),
NSP_PIN_GROUP(pwm0, NSP_MUX_BASE1, 0, 0x01, 0x01),
NSP_PIN_GROUP(gpio_b_1, NSP_MUX_BASE0, 8, 0x01, 0x00),
NSP_PIN_GROUP(pwm1, NSP_MUX_BASE1, 1, 0x01, 0x01),
NSP_PIN_GROUP(gpio_b_2, NSP_MUX_BASE0, 9, 0x01, 0x00),
NSP_PIN_GROUP(pwm2, NSP_MUX_BASE1, 2, 0x01, 0x01),
NSP_PIN_GROUP(gpio_b_3, NSP_MUX_BASE0, 10, 0x01, 0x00),
NSP_PIN_GROUP(pwm3, NSP_MUX_BASE1, 3, 0x01, 0x01),
NSP_PIN_GROUP(uart1, NSP_MUX_BASE0, 11, 0x0f, 0x00),
NSP_PIN_GROUP(uart2, NSP_MUX_BASE0, 15, 0x03, 0x00),
NSP_PIN_GROUP(synce, NSP_MUX_BASE0, 17, 0x01, 0x01),
NSP_PIN_GROUP(sata0_led, NSP_MUX_BASE0, 18, 0x01, 0x01),
NSP_PIN_GROUP(sata1_led, NSP_MUX_BASE0, 19, 0x01, 0x01),
NSP_PIN_GROUP(xtal_out, NSP_MUX_BASE0, 20, 0x01, 0x00),
NSP_PIN_GROUP(sdio_pwr, NSP_MUX_BASE0, 21, 0x01, 0x00),
NSP_PIN_GROUP(sdio_1p8v, NSP_MUX_BASE0, 22, 0x01, 0x00),
NSP_PIN_GROUP(switch_p05_led0, NSP_MUX_BASE0, 26, 0x01, 0x01),
NSP_PIN_GROUP(switch_p05_led1, NSP_MUX_BASE0, 27, 0x01, 0x01),
NSP_PIN_GROUP(nand, NSP_MUX_BASE2, 0, 0x01, 0x00),
NSP_PIN_GROUP(emmc, NSP_MUX_BASE2, 0, 0x01, 0x01)
};
/*
* List of groups supported by functions
*/
static const char * const spi_grps[] = {"spi_grp"};
static const char * const i2c_grps[] = {"i2c_grp"};
static const char * const mdio_grps[] = {"mdio_grp"};
static const char * const pwm_grps[] = {"pwm0_grp", "pwm1_grp", "pwm2_grp"
, "pwm3_grp"};
static const char * const gpio_b_grps[] = {"gpio_b_0_grp", "gpio_b_1_grp",
"gpio_b_2_grp", "gpio_b_3_grp"};
static const char * const uart1_grps[] = {"uart1_grp"};
static const char * const uart2_grps[] = {"uart2_grp"};
static const char * const synce_grps[] = {"synce_grp"};
static const char * const sata_led_grps[] = {"sata0_led_grp", "sata1_led_grp"};
static const char * const xtal_out_grps[] = {"xtal_out_grp"};
static const char * const sdio_grps[] = {"sdio_pwr_grp", "sdio_1p8v_grp"};
static const char * const switch_led_grps[] = {"switch_p05_led0_grp",
"switch_p05_led1_grp"};
static const char * const nand_grps[] = {"nand_grp"};
static const char * const emmc_grps[] = {"emmc_grp"};
#define NSP_PIN_FUNCTION(func) \
{ \
.name = #func, \
.groups = func ## _grps, \
.num_groups = ARRAY_SIZE(func ## _grps), \
}
/*
* List of supported functions in nsp
*/
static const struct nsp_pin_function nsp_pin_functions[] = {
NSP_PIN_FUNCTION(spi),
NSP_PIN_FUNCTION(i2c),
NSP_PIN_FUNCTION(mdio),
NSP_PIN_FUNCTION(pwm),
NSP_PIN_FUNCTION(gpio_b),
NSP_PIN_FUNCTION(uart1),
NSP_PIN_FUNCTION(uart2),
NSP_PIN_FUNCTION(synce),
NSP_PIN_FUNCTION(sata_led),
NSP_PIN_FUNCTION(xtal_out),
NSP_PIN_FUNCTION(sdio),
NSP_PIN_FUNCTION(switch_led),
NSP_PIN_FUNCTION(nand),
NSP_PIN_FUNCTION(emmc)
};
static int nsp_get_groups_count(struct pinctrl_dev *pctrl_dev)
{
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
return pinctrl->num_groups;
}
static const char *nsp_get_group_name(struct pinctrl_dev *pctrl_dev,
unsigned int selector)
{
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
return pinctrl->groups[selector].name;
}
static int nsp_get_group_pins(struct pinctrl_dev *pctrl_dev,
unsigned int selector, const unsigned int **pins,
unsigned int *num_pins)
{
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
*pins = pinctrl->groups[selector].pins;
*num_pins = pinctrl->groups[selector].num_pins;
return 0;
}
static void nsp_pin_dbg_show(struct pinctrl_dev *pctrl_dev,
struct seq_file *s, unsigned int offset)
{
seq_printf(s, " %s", dev_name(pctrl_dev->dev));
}
static struct pinctrl_ops nsp_pinctrl_ops = {
.get_groups_count = nsp_get_groups_count,
.get_group_name = nsp_get_group_name,
.get_group_pins = nsp_get_group_pins,
.pin_dbg_show = nsp_pin_dbg_show,
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
.dt_free_map = pinctrl_utils_free_map,
};
static int nsp_get_functions_count(struct pinctrl_dev *pctrl_dev)
{
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
return pinctrl->num_functions;
}
static const char *nsp_get_function_name(struct pinctrl_dev *pctrl_dev,
unsigned int selector)
{
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
return pinctrl->functions[selector].name;
}
static int nsp_get_function_groups(struct pinctrl_dev *pctrl_dev,
unsigned int selector,
const char * const **groups,
unsigned * const num_groups)
{
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
*groups = pinctrl->functions[selector].groups;
*num_groups = pinctrl->functions[selector].num_groups;
return 0;
}
static int nsp_pinmux_set(struct nsp_pinctrl *pinctrl,
const struct nsp_pin_function *func,
const struct nsp_pin_group *grp,
struct nsp_mux_log *mux_log)
{
const struct nsp_mux *mux = &grp->mux;
int i;
u32 val, mask;
unsigned long flags;
void __iomem *base_address;
for (i = 0; i < pinctrl->num_groups; i++) {
if ((mux->shift != mux_log[i].mux.shift) ||
(mux->base != mux_log[i].mux.base))
continue;
/* if this is a new configuration, just do it! */
if (!mux_log[i].is_configured)
break;
/*
* IOMUX has been configured previously and one is trying to
* configure it to a different function
*/
if (mux_log[i].mux.alt != mux->alt) {
dev_err(pinctrl->dev,
"double configuration error detected!\n");
dev_err(pinctrl->dev, "func:%s grp:%s\n",
func->name, grp->name);
return -EINVAL;
}
return 0;
}
if (i == pinctrl->num_groups)
return -EINVAL;
mask = mux->mask;
mux_log[i].mux.alt = mux->alt;
mux_log[i].is_configured = true;
switch (mux->base) {
case NSP_MUX_BASE0:
base_address = pinctrl->base0;
break;
case NSP_MUX_BASE1:
base_address = pinctrl->base1;
break;
case NSP_MUX_BASE2:
base_address = pinctrl->base2;
break;
default:
return -EINVAL;
}
spin_lock_irqsave(&pinctrl->lock, flags);
val = readl(base_address);
val &= ~(mask << grp->mux.shift);
val |= grp->mux.alt << grp->mux.shift;
writel(val, base_address);
spin_unlock_irqrestore(&pinctrl->lock, flags);
return 0;
}
static int nsp_pinmux_enable(struct pinctrl_dev *pctrl_dev,
unsigned int func_select, unsigned int grp_select)
{
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
const struct nsp_pin_function *func;
const struct nsp_pin_group *grp;
if (grp_select > pinctrl->num_groups ||
func_select > pinctrl->num_functions)
return -EINVAL;
func = &pinctrl->functions[func_select];
grp = &pinctrl->groups[grp_select];
dev_dbg(pctrl_dev->dev, "func:%u name:%s grp:%u name:%s\n",
func_select, func->name, grp_select, grp->name);
dev_dbg(pctrl_dev->dev, "shift:%u alt:%u\n", grp->mux.shift,
grp->mux.alt);
return nsp_pinmux_set(pinctrl, func, grp, pinctrl->mux_log);
}
static int nsp_gpio_request_enable(struct pinctrl_dev *pctrl_dev,
struct pinctrl_gpio_range *range,
unsigned int pin)
{
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
u32 *gpio_select = pctrl_dev->desc->pins[pin].drv_data;
u32 val;
unsigned long flags;
spin_lock_irqsave(&pinctrl->lock, flags);
val = readl(pinctrl->base0);
if ((val & BIT(pin)) != (*gpio_select << pin)) {
val &= ~BIT(pin);
val |= *gpio_select << pin;
writel(val, pinctrl->base0);
}
spin_unlock_irqrestore(&pinctrl->lock, flags);
return 0;
}
static void nsp_gpio_disable_free(struct pinctrl_dev *pctrl_dev,
struct pinctrl_gpio_range *range,
unsigned int pin)
{
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
u32 *gpio_select = pctrl_dev->desc->pins[pin].drv_data;
u32 val;
unsigned long flags;
spin_lock_irqsave(&pinctrl->lock, flags);
val = readl(pinctrl->base0);
if ((val & (1 << pin)) == (*gpio_select << pin)) {
val &= ~(1 << pin);
if (!(*gpio_select))
val |= (1 << pin);
writel(val, pinctrl->base0);
}
spin_unlock_irqrestore(&pinctrl->lock, flags);
}
static struct pinmux_ops nsp_pinmux_ops = {
.get_functions_count = nsp_get_functions_count,
.get_function_name = nsp_get_function_name,
.get_function_groups = nsp_get_function_groups,
.set_mux = nsp_pinmux_enable,
.gpio_request_enable = nsp_gpio_request_enable,
.gpio_disable_free = nsp_gpio_disable_free,
};
static struct pinctrl_desc nsp_pinctrl_desc = {
.name = "nsp-pinmux",
.pctlops = &nsp_pinctrl_ops,
.pmxops = &nsp_pinmux_ops,
};
static int nsp_mux_log_init(struct nsp_pinctrl *pinctrl)
{
struct nsp_mux_log *log;
unsigned int i;
u32 no_of_groups = ARRAY_SIZE(nsp_pin_groups);
pinctrl->mux_log = devm_kcalloc(pinctrl->dev, no_of_groups,
sizeof(struct nsp_mux_log),
GFP_KERNEL);
if (!pinctrl->mux_log)
return -ENOMEM;
for (i = 0; i < no_of_groups; i++) {
log = &pinctrl->mux_log[i];
log->mux.base = nsp_pin_groups[i].mux.base;
log->mux.shift = nsp_pin_groups[i].mux.shift;
log->mux.alt = 0;
log->is_configured = false;
}
return 0;
}
static int nsp_pinmux_probe(struct platform_device *pdev)
{
struct nsp_pinctrl *pinctrl;
struct resource *res;
int i, ret;
struct pinctrl_pin_desc *pins;
unsigned int num_pins = ARRAY_SIZE(nsp_pins);
pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL);
if (!pinctrl)
return -ENOMEM;
pinctrl->dev = &pdev->dev;
platform_set_drvdata(pdev, pinctrl);
spin_lock_init(&pinctrl->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pinctrl->base0))
return PTR_ERR(pinctrl->base0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
pinctrl->base1 = devm_ioremap_nocache(&pdev->dev, res->start,
resource_size(res));
if (!pinctrl->base1) {
dev_err(&pdev->dev, "unable to map I/O space\n");
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
pinctrl->base2 = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pinctrl->base2))
return PTR_ERR(pinctrl->base2);
ret = nsp_mux_log_init(pinctrl);
if (ret) {
dev_err(&pdev->dev, "unable to initialize IOMUX log\n");
return ret;
}
pins = devm_kcalloc(&pdev->dev, num_pins, sizeof(*pins), GFP_KERNEL);
if (!pins)
return -ENOMEM;
for (i = 0; i < num_pins; i++) {
pins[i].number = nsp_pins[i].pin;
pins[i].name = nsp_pins[i].name;
pins[i].drv_data = &nsp_pins[i].gpio_select;
}
pinctrl->groups = nsp_pin_groups;
pinctrl->num_groups = ARRAY_SIZE(nsp_pin_groups);
pinctrl->functions = nsp_pin_functions;
pinctrl->num_functions = ARRAY_SIZE(nsp_pin_functions);
nsp_pinctrl_desc.pins = pins;
nsp_pinctrl_desc.npins = num_pins;
pinctrl->pctl = devm_pinctrl_register(&pdev->dev, &nsp_pinctrl_desc,
pinctrl);
if (IS_ERR(pinctrl->pctl)) {
dev_err(&pdev->dev, "unable to register nsp IOMUX pinctrl\n");
return PTR_ERR(pinctrl->pctl);
}
return 0;
}
static const struct of_device_id nsp_pinmux_of_match[] = {
{ .compatible = "brcm,nsp-pinmux" },
{ }
};
static struct platform_driver nsp_pinmux_driver = {
.driver = {
.name = "nsp-pinmux",
.of_match_table = nsp_pinmux_of_match,
},
.probe = nsp_pinmux_probe,
};
static int __init nsp_pinmux_init(void)
{
return platform_driver_register(&nsp_pinmux_driver);
}
arch_initcall(nsp_pinmux_init);

View File

@ -225,13 +225,14 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
}
static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
unsigned number, const char *name)
const struct pinctrl_pin_desc *pin)
{
struct pin_desc *pindesc;
pindesc = pin_desc_get(pctldev, number);
pindesc = pin_desc_get(pctldev, pin->number);
if (pindesc != NULL) {
dev_err(pctldev->dev, "pin %d already registered\n", number);
dev_err(pctldev->dev, "pin %d already registered\n",
pin->number);
return -EINVAL;
}
@ -245,10 +246,10 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
pindesc->pctldev = pctldev;
/* Copy basic pin info */
if (name) {
pindesc->name = name;
if (pin->name) {
pindesc->name = pin->name;
} else {
pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number);
pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number);
if (pindesc->name == NULL) {
kfree(pindesc);
return -ENOMEM;
@ -256,9 +257,11 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
pindesc->dynamic_name = true;
}
radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc);
pindesc->drv_data = pin->drv_data;
radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc);
pr_debug("registered pin %d (%s) on %s\n",
number, pindesc->name, pctldev->desc->name);
pin->number, pindesc->name, pctldev->desc->name);
return 0;
}
@ -270,8 +273,7 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev,
int ret = 0;
for (i = 0; i < num_descs; i++) {
ret = pinctrl_register_one_pin(pctldev,
pins[i].number, pins[i].name);
ret = pinctrl_register_one_pin(pctldev, &pins[i]);
if (ret)
return ret;
}
@ -1367,8 +1369,7 @@ static int pinctrl_pins_show(struct seq_file *s, void *what)
if (desc == NULL)
continue;
seq_printf(s, "pin %d (%s) ", pin,
desc->name ? desc->name : "unnamed");
seq_printf(s, "pin %d (%s) ", pin, desc->name);
/* Driver-specific info per pin */
if (ops->pin_dbg_show)

View File

@ -134,6 +134,7 @@ struct pinctrl_setting {
* @name: a name for the pin, e.g. the name of the pin/pad/finger on a
* datasheet or such
* @dynamic_name: if the name of this pin was dynamically allocated
* @drv_data: driver-defined per-pin data. pinctrl core does not touch this
* @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL.
* If non-zero, this pin is claimed by @owner. This field is an integer
* rather than a boolean, since pinctrl_get() might process multiple
@ -148,6 +149,7 @@ struct pin_desc {
struct pinctrl_dev *pctldev;
const char *name;
bool dynamic_name;
void *drv_data;
/* These fields only added when supporting pinmux drivers */
#ifdef CONFIG_PINMUX
unsigned mux_usecount;

View File

@ -195,8 +195,13 @@ int pinctrl_dt_to_map(struct pinctrl *p)
propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
prop = of_find_property(np, propname, &size);
kfree(propname);
if (!prop)
if (!prop) {
if (state == 0) {
of_node_put(np);
return -ENODEV;
}
break;
}
list = prop->value;
size /= sizeof(*list);

View File

@ -16,7 +16,6 @@
#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>
#include <linux/of_address.h>
@ -46,7 +45,7 @@ struct imx_pinctrl {
const struct imx_pinctrl_soc_info *info;
};
static const inline struct imx_pin_group *imx_pinctrl_find_group_by_name(
static inline const struct imx_pin_group *imx_pinctrl_find_group_by_name(
const struct imx_pinctrl_soc_info *info,
const char *name)
{
@ -513,13 +512,6 @@ static const struct pinconf_ops imx_pinconf_ops = {
.pin_config_group_dbg_show = imx_pinconf_group_dbg_show,
};
static struct pinctrl_desc imx_pinctrl_desc = {
.pctlops = &imx_pctrl_ops,
.pmxops = &imx_pmx_ops,
.confops = &imx_pinconf_ops,
.owner = THIS_MODULE,
};
/*
* Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and
* 1 u32 CONFIG, so 24 types in total for each pin.
@ -722,6 +714,7 @@ int imx_pinctrl_probe(struct platform_device *pdev,
{
struct regmap_config config = { .name = "gpr" };
struct device_node *dev_np = pdev->dev.of_node;
struct pinctrl_desc *imx_pinctrl_desc;
struct device_node *np;
struct imx_pinctrl *ipctl;
struct resource *res;
@ -776,9 +769,18 @@ int imx_pinctrl_probe(struct platform_device *pdev,
}
}
imx_pinctrl_desc.name = dev_name(&pdev->dev);
imx_pinctrl_desc.pins = info->pins;
imx_pinctrl_desc.npins = info->npins;
imx_pinctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*imx_pinctrl_desc),
GFP_KERNEL);
if (!imx_pinctrl_desc)
return -ENOMEM;
imx_pinctrl_desc->name = dev_name(&pdev->dev);
imx_pinctrl_desc->pins = info->pins;
imx_pinctrl_desc->npins = info->npins;
imx_pinctrl_desc->pctlops = &imx_pctrl_ops,
imx_pinctrl_desc->pmxops = &imx_pmx_ops,
imx_pinctrl_desc->confops = &imx_pinconf_ops,
imx_pinctrl_desc->owner = THIS_MODULE,
ret = imx_pinctrl_probe_dt(pdev, info);
if (ret) {
@ -789,7 +791,8 @@ int imx_pinctrl_probe(struct platform_device *pdev,
ipctl->info = info;
ipctl->dev = info->dev;
platform_set_drvdata(pdev, ipctl);
ipctl->pctl = devm_pinctrl_register(&pdev->dev, &imx_pinctrl_desc, ipctl);
ipctl->pctl = devm_pinctrl_register(&pdev->dev,
imx_pinctrl_desc, ipctl);
if (IS_ERR(ipctl->pctl)) {
dev_err(&pdev->dev, "could not register IMX pinctrl driver\n");
return PTR_ERR(ipctl->pctl);

View File

@ -19,7 +19,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/machine.h>
@ -157,7 +156,7 @@ static int imx1_read_bit(struct imx1_pinctrl *ipctl, unsigned int pin_id,
return !!(readl(reg) & BIT(offset));
}
static const inline struct imx1_pin_group *imx1_pinctrl_find_group_by_name(
static inline const struct imx1_pin_group *imx1_pinctrl_find_group_by_name(
const struct imx1_pinctrl_soc_info *info,
const char *name)
{

View File

@ -9,7 +9,7 @@
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -262,7 +262,6 @@ static const struct of_device_id imx1_pinctrl_of_match[] = {
{ .compatible = "fsl,imx1-iomuxc", },
{ }
};
MODULE_DEVICE_TABLE(of, imx1_pinctrl_of_match);
static struct platform_driver imx1_pinctrl_driver = {
.driver = {
@ -270,8 +269,4 @@ static struct platform_driver imx1_pinctrl_driver = {
.of_match_table = imx1_pinctrl_of_match,
},
};
module_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe);
MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
MODULE_DESCRIPTION("Freescale i.MX1 pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe);

View File

@ -9,7 +9,7 @@
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -325,7 +325,6 @@ static const struct of_device_id imx21_pinctrl_of_match[] = {
{ .compatible = "fsl,imx21-iomuxc", },
{ }
};
MODULE_DEVICE_TABLE(of, imx21_pinctrl_of_match);
static struct platform_driver imx21_pinctrl_driver = {
.driver = {
@ -333,8 +332,4 @@ static struct platform_driver imx21_pinctrl_driver = {
.of_match_table = imx21_pinctrl_of_match,
},
};
module_platform_driver_probe(imx21_pinctrl_driver, imx21_pinctrl_probe);
MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
MODULE_DESCRIPTION("Freescale i.MX21 pinctrl driver");
MODULE_LICENSE("GPL");
builtin_platform_driver_probe(imx21_pinctrl_driver, imx21_pinctrl_probe);

View File

@ -1,4 +1,7 @@
/*
* Freescale i.MX23 pinctrl driver
*
* Author: Shawn Guo <shawn.guo@linaro.org>
* Copyright 2012 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
@ -10,7 +13,6 @@
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-mxs.h"
@ -276,15 +278,14 @@ static const struct of_device_id imx23_pinctrl_of_match[] = {
{ .compatible = "fsl,imx23-pinctrl", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx23_pinctrl_of_match);
static struct platform_driver imx23_pinctrl_driver = {
.driver = {
.name = "imx23-pinctrl",
.suppress_bind_attrs = true,
.of_match_table = imx23_pinctrl_of_match,
},
.probe = imx23_pinctrl_probe,
.remove = mxs_pinctrl_remove,
};
static int __init imx23_pinctrl_init(void)
@ -292,13 +293,3 @@ static int __init imx23_pinctrl_init(void)
return platform_driver_register(&imx23_pinctrl_driver);
}
postcore_initcall(imx23_pinctrl_init);
static void __exit imx23_pinctrl_exit(void)
{
platform_driver_unregister(&imx23_pinctrl_driver);
}
module_exit(imx23_pinctrl_exit);
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
MODULE_DESCRIPTION("Freescale i.MX23 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -18,7 +18,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -338,12 +337,3 @@ static int __init imx25_pinctrl_init(void)
return platform_driver_register(&imx25_pinctrl_driver);
}
arch_initcall(imx25_pinctrl_init);
static void __exit imx25_pinctrl_exit(void)
{
platform_driver_unregister(&imx25_pinctrl_driver);
}
module_exit(imx25_pinctrl_exit);
MODULE_AUTHOR("Denis Carikli <denis@eukrea.com>");
MODULE_DESCRIPTION("Freescale IMX25 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -14,7 +14,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -412,12 +411,3 @@ static int __init imx27_pinctrl_init(void)
return platform_driver_register(&imx27_pinctrl_driver);
}
arch_initcall(imx27_pinctrl_init);
static void __exit imx27_pinctrl_exit(void)
{
platform_driver_unregister(&imx27_pinctrl_driver);
}
module_exit(imx27_pinctrl_exit);
MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
MODULE_DESCRIPTION("Freescale IMX27 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,4 +1,7 @@
/*
* Freescale i.MX28 pinctrl driver
*
* Author: Shawn Guo <shawn.guo@linaro.org>
* Copyright 2012 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
@ -10,7 +13,6 @@
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-mxs.h"
@ -392,15 +394,14 @@ static const struct of_device_id imx28_pinctrl_of_match[] = {
{ .compatible = "fsl,imx28-pinctrl", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx28_pinctrl_of_match);
static struct platform_driver imx28_pinctrl_driver = {
.driver = {
.name = "imx28-pinctrl",
.suppress_bind_attrs = true,
.of_match_table = imx28_pinctrl_of_match,
},
.probe = imx28_pinctrl_probe,
.remove = mxs_pinctrl_remove,
};
static int __init imx28_pinctrl_init(void)
@ -408,13 +409,3 @@ static int __init imx28_pinctrl_init(void)
return platform_driver_register(&imx28_pinctrl_driver);
}
postcore_initcall(imx28_pinctrl_init);
static void __exit imx28_pinctrl_exit(void)
{
platform_driver_unregister(&imx28_pinctrl_driver);
}
module_exit(imx28_pinctrl_exit);
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
MODULE_DESCRIPTION("Freescale i.MX28 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -16,7 +16,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -1028,12 +1027,3 @@ static int __init imx35_pinctrl_init(void)
return platform_driver_register(&imx35_pinctrl_driver);
}
arch_initcall(imx35_pinctrl_init);
static void __exit imx35_pinctrl_exit(void)
{
platform_driver_unregister(&imx35_pinctrl_driver);
}
module_exit(imx35_pinctrl_exit);
MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
MODULE_DESCRIPTION("Freescale IMX35 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -14,7 +14,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -415,11 +414,3 @@ static int __init imx50_pinctrl_init(void)
return platform_driver_register(&imx50_pinctrl_driver);
}
arch_initcall(imx50_pinctrl_init);
static void __exit imx50_pinctrl_exit(void)
{
platform_driver_unregister(&imx50_pinctrl_driver);
}
module_exit(imx50_pinctrl_exit);
MODULE_DESCRIPTION("Freescale IMX50 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -15,7 +15,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -791,12 +790,3 @@ static int __init imx51_pinctrl_init(void)
return platform_driver_register(&imx51_pinctrl_driver);
}
arch_initcall(imx51_pinctrl_init);
static void __exit imx51_pinctrl_exit(void)
{
platform_driver_unregister(&imx51_pinctrl_driver);
}
module_exit(imx51_pinctrl_exit);
MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
MODULE_DESCRIPTION("Freescale IMX51 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -15,7 +15,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -478,12 +477,3 @@ static int __init imx53_pinctrl_init(void)
return platform_driver_register(&imx53_pinctrl_driver);
}
arch_initcall(imx53_pinctrl_init);
static void __exit imx53_pinctrl_exit(void)
{
platform_driver_unregister(&imx53_pinctrl_driver);
}
module_exit(imx53_pinctrl_exit);
MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
MODULE_DESCRIPTION("Freescale IMX53 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,4 +1,7 @@
/*
* Freescale imx6dl pinctrl driver
*
* Author: Shawn Guo <shawn.guo@linaro.org>
* Copyright (C) 2013 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
@ -9,7 +12,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -484,13 +486,3 @@ static int __init imx6dl_pinctrl_init(void)
return platform_driver_register(&imx6dl_pinctrl_driver);
}
arch_initcall(imx6dl_pinctrl_init);
static void __exit imx6dl_pinctrl_exit(void)
{
platform_driver_unregister(&imx6dl_pinctrl_driver);
}
module_exit(imx6dl_pinctrl_exit);
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
MODULE_DESCRIPTION("Freescale imx6dl pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -15,7 +15,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -490,12 +489,3 @@ static int __init imx6q_pinctrl_init(void)
return platform_driver_register(&imx6q_pinctrl_driver);
}
arch_initcall(imx6q_pinctrl_init);
static void __exit imx6q_pinctrl_exit(void)
{
platform_driver_unregister(&imx6q_pinctrl_driver);
}
module_exit(imx6q_pinctrl_exit);
MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
MODULE_DESCRIPTION("Freescale IMX6Q pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,4 +1,7 @@
/*
* Freescale imx6sl pinctrl driver
*
* Author: Shawn Guo <shawn.guo@linaro.org>
* Copyright (C) 2013 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
@ -9,7 +12,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -371,7 +373,6 @@ static const struct of_device_id imx6sl_pinctrl_of_match[] = {
{ .compatible = "fsl,imx6sl-iomuxc", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx6sl_pinctrl_of_match);
static int imx6sl_pinctrl_probe(struct platform_device *pdev)
{
@ -391,13 +392,3 @@ static int __init imx6sl_pinctrl_init(void)
return platform_driver_register(&imx6sl_pinctrl_driver);
}
arch_initcall(imx6sl_pinctrl_init);
static void __exit imx6sl_pinctrl_exit(void)
{
platform_driver_unregister(&imx6sl_pinctrl_driver);
}
module_exit(imx6sl_pinctrl_exit);
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
MODULE_DESCRIPTION("Freescale imx6sl pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,4 +1,7 @@
/*
* Freescale imx6sx pinctrl driver
*
* Author: Anson Huang <Anson.Huang@freescale.com>
* Copyright (C) 2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
@ -9,7 +12,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -394,13 +396,3 @@ static int __init imx6sx_pinctrl_init(void)
return platform_driver_register(&imx6sx_pinctrl_driver);
}
arch_initcall(imx6sx_pinctrl_init);
static void __exit imx6sx_pinctrl_exit(void)
{
platform_driver_unregister(&imx6sx_pinctrl_driver);
}
module_exit(imx6sx_pinctrl_exit);
MODULE_AUTHOR("Anson Huang <Anson.Huang@freescale.com>");
MODULE_DESCRIPTION("Freescale imx6sx pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,4 +1,7 @@
/*
* Freescale imx6ul pinctrl driver
*
* Author: Anson Huang <Anson.Huang@freescale.com>
* Copyright (C) 2015 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
@ -9,7 +12,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -310,13 +312,3 @@ static int __init imx6ul_pinctrl_init(void)
return platform_driver_register(&imx6ul_pinctrl_driver);
}
arch_initcall(imx6ul_pinctrl_init);
static void __exit imx6ul_pinctrl_exit(void)
{
platform_driver_unregister(&imx6ul_pinctrl_driver);
}
module_exit(imx6ul_pinctrl_exit);
MODULE_AUTHOR("Anson Huang <Anson.Huang@freescale.com>");
MODULE_DESCRIPTION("Freescale imx6ul pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,4 +1,7 @@
/*
* Freescale imx7d pinctrl driver
*
* Author: Anson Huang <Anson.Huang@freescale.com>
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
@ -9,7 +12,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -402,13 +404,3 @@ static int __init imx7d_pinctrl_init(void)
return platform_driver_register(&imx7d_pinctrl_driver);
}
arch_initcall(imx7d_pinctrl_init);
static void __exit imx7d_pinctrl_exit(void)
{
platform_driver_unregister(&imx7d_pinctrl_driver);
}
module_exit(imx7d_pinctrl_exit);
MODULE_AUTHOR("Anson Huang <Anson.Huang@freescale.com>");
MODULE_DESCRIPTION("Freescale imx7d pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -12,7 +12,6 @@
#include <linux/err.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/machine.h>
@ -553,14 +552,3 @@ err:
return ret;
}
EXPORT_SYMBOL_GPL(mxs_pinctrl_probe);
int mxs_pinctrl_remove(struct platform_device *pdev)
{
struct mxs_pinctrl_data *d = platform_get_drvdata(pdev);
pinctrl_unregister(d->pctl);
iounmap(d->base);
return 0;
}
EXPORT_SYMBOL_GPL(mxs_pinctrl_remove);

View File

@ -86,6 +86,5 @@ struct mxs_pinctrl_soc_data {
int mxs_pinctrl_probe(struct platform_device *pdev,
struct mxs_pinctrl_soc_data *soc);
int mxs_pinctrl_remove(struct platform_device *pdev);
#endif /* __PINCTRL_MXS_H */

View File

@ -12,7 +12,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -325,12 +324,3 @@ static int __init vf610_pinctrl_init(void)
return platform_driver_register(&vf610_pinctrl_driver);
}
arch_initcall(vf610_pinctrl_init);
static void __exit vf610_pinctrl_exit(void)
{
platform_driver_unregister(&vf610_pinctrl_driver);
}
module_exit(vf610_pinctrl_exit);
MODULE_DESCRIPTION("Freescale VF610 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -29,6 +29,17 @@ config PINCTRL_CHERRYVIEW
Cherryview/Braswell pinctrl driver provides an interface that
allows configuring of SoC pins and using them as GPIOs.
config PINCTRL_MERRIFIELD
tristate "Intel Merrifield pinctrl driver"
depends on X86_INTEL_MID
select PINMUX
select PINCONF
select GENERIC_PINCONF
help
Merrifield Family-Level Interface Shim (FLIS) driver provides an
interface that allows configuring of SoC pins and using them as
GPIOs.
config PINCTRL_INTEL
tristate
select PINMUX

View File

@ -2,6 +2,7 @@
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o
obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o
obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o
obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o
obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o

View File

@ -15,7 +15,6 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/bitops.h>
@ -1822,17 +1821,6 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
return 0;
}
static int byt_pinctrl_remove(struct platform_device *pdev)
{
struct byt_gpio *vg = platform_get_drvdata(pdev);
pm_runtime_disable(&pdev->dev);
gpiochip_remove(&vg->chip);
pinctrl_unregister(vg->pctl_dev);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int byt_gpio_suspend(struct device *dev)
{
@ -1930,10 +1918,11 @@ static const struct dev_pm_ops byt_gpio_pm_ops = {
static struct platform_driver byt_gpio_driver = {
.probe = byt_pinctrl_probe,
.remove = byt_pinctrl_remove,
.driver = {
.name = "byt_gpio",
.pm = &byt_gpio_pm_ops,
.name = "byt_gpio",
.pm = &byt_gpio_pm_ops,
.suppress_bind_attrs = true,
.acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
},
};
@ -1943,9 +1932,3 @@ static int __init byt_gpio_init(void)
return platform_driver_register(&byt_gpio_driver);
}
subsys_initcall(byt_gpio_init);
static void __exit byt_gpio_exit(void)
{
platform_driver_unregister(&byt_gpio_driver);
}
module_exit(byt_gpio_exit);

View File

@ -1,7 +1,7 @@
/*
* Intel Broxton SoC pinctrl/GPIO driver
*
* Copyright (C) 2015, Intel Corporation
* Copyright (C) 2015, 2016 Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
@ -1003,29 +1003,46 @@ static const struct acpi_device_id bxt_pinctrl_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, bxt_pinctrl_acpi_match);
static const struct platform_device_id bxt_pinctrl_platform_ids[] = {
{ "apl-pinctrl", (kernel_ulong_t)&apl_pinctrl_soc_data },
{ "broxton-pinctrl", (kernel_ulong_t)&bxt_pinctrl_soc_data },
{ },
};
static int bxt_pinctrl_probe(struct platform_device *pdev)
{
const struct intel_pinctrl_soc_data *soc_data = NULL;
const struct intel_pinctrl_soc_data **soc_table;
const struct acpi_device_id *id;
struct acpi_device *adev;
int i;
adev = ACPI_COMPANION(&pdev->dev);
if (!adev)
return -ENODEV;
if (adev) {
const struct acpi_device_id *id;
id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev);
if (!id)
return -ENODEV;
id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev);
if (!id)
return -ENODEV;
soc_table = (const struct intel_pinctrl_soc_data **)id->driver_data;
soc_table = (const struct intel_pinctrl_soc_data **)
id->driver_data;
for (i = 0; soc_table[i]; i++) {
if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
soc_data = soc_table[i];
break;
for (i = 0; soc_table[i]; i++) {
if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
soc_data = soc_table[i];
break;
}
}
} else {
const struct platform_device_id *pid;
pid = platform_get_device_id(pdev);
if (!pid)
return -ENODEV;
soc_table = (const struct intel_pinctrl_soc_data **)
pid->driver_data;
soc_data = soc_table[pdev->id];
}
if (!soc_data)
@ -1047,6 +1064,7 @@ static struct platform_driver bxt_pinctrl_driver = {
.acpi_match_table = bxt_pinctrl_acpi_match,
.pm = &bxt_pinctrl_pm_ops,
},
.id_table = bxt_pinctrl_platform_ids,
};
static int __init bxt_pinctrl_init(void)
@ -1064,3 +1082,4 @@ module_exit(bxt_pinctrl_exit);
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
MODULE_DESCRIPTION("Intel Broxton SoC pinctrl/GPIO driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:broxton-pinctrl");

View File

@ -160,7 +160,6 @@ struct chv_pin_context {
* @pctldev: Pointer to the pin controller device
* @chip: GPIO chip in this pin controller
* @regs: MMIO registers
* @lock: Lock to serialize register accesses
* @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO
* offset (in GPIO number space)
* @community: Community this pinctrl instance represents
@ -174,7 +173,6 @@ struct chv_pinctrl {
struct pinctrl_dev *pctldev;
struct gpio_chip chip;
void __iomem *regs;
raw_spinlock_t lock;
unsigned intr_lines[16];
const struct chv_community *community;
u32 saved_intmask;
@ -657,6 +655,17 @@ static const struct chv_community *chv_communities[] = {
&southeast_community,
};
/*
* Lock to serialize register accesses
*
* Due to a silicon issue, a shared lock must be used to prevent
* concurrent accesses across the 4 GPIO controllers.
*
* See Intel Atom Z8000 Processor Series Specification Update (Rev. 005),
* errata #CHT34, for further information.
*/
static DEFINE_RAW_SPINLOCK(chv_lock);
static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned offset,
unsigned reg)
{
@ -718,13 +727,13 @@ static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
u32 ctrl0, ctrl1;
bool locked;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1));
locked = chv_pad_locked(pctrl, offset);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
if (ctrl0 & CHV_PADCTRL0_GPIOEN) {
seq_puts(s, "GPIO ");
@ -787,14 +796,14 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
grp = &pctrl->community->groups[group];
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
/* Check first that the pad is not locked */
for (i = 0; i < grp->npins; i++) {
if (chv_pad_locked(pctrl, grp->pins[i])) {
dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n",
grp->pins[i]);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return -EBUSY;
}
}
@ -837,7 +846,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
pin, altfunc->mode, altfunc->invert_oe ? "" : "not ");
}
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return 0;
}
@ -851,13 +860,13 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev,
void __iomem *reg;
u32 value;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
if (chv_pad_locked(pctrl, offset)) {
value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
if (!(value & CHV_PADCTRL0_GPIOEN)) {
/* Locked so cannot enable */
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return -EBUSY;
}
} else {
@ -897,7 +906,7 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev,
chv_writel(value, reg);
}
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return 0;
}
@ -911,13 +920,13 @@ static void chv_gpio_disable_free(struct pinctrl_dev *pctldev,
void __iomem *reg;
u32 value;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
value = readl(reg) & ~CHV_PADCTRL0_GPIOEN;
chv_writel(value, reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
}
static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
@ -929,7 +938,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
unsigned long flags;
u32 ctrl0;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK;
if (input)
@ -938,7 +947,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT;
chv_writel(ctrl0, reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return 0;
}
@ -963,10 +972,10 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin,
u16 arg = 0;
u32 term;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1));
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT;
@ -1040,7 +1049,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
unsigned long flags;
u32 ctrl0, pull;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
ctrl0 = readl(reg);
switch (param) {
@ -1063,7 +1072,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
break;
default:
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return -EINVAL;
}
@ -1081,7 +1090,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
break;
default:
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return -EINVAL;
}
@ -1089,12 +1098,33 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
break;
default:
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return -EINVAL;
}
chv_writel(ctrl0, reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return 0;
}
static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin,
bool enable)
{
void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1);
unsigned long flags;
u32 ctrl1;
raw_spin_lock_irqsave(&chv_lock, flags);
ctrl1 = readl(reg);
if (enable)
ctrl1 |= CHV_PADCTRL1_ODEN;
else
ctrl1 &= ~CHV_PADCTRL1_ODEN;
chv_writel(ctrl1, reg);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return 0;
}
@ -1123,6 +1153,18 @@ static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin,
return ret;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
ret = chv_config_set_oden(pctrl, pin, false);
if (ret)
return ret;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
ret = chv_config_set_oden(pctrl, pin, true);
if (ret)
return ret;
break;
default:
return -ENOTSUPP;
}
@ -1134,10 +1176,52 @@ static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin,
return 0;
}
static int chv_config_group_get(struct pinctrl_dev *pctldev,
unsigned int group,
unsigned long *config)
{
const unsigned int *pins;
unsigned int npins;
int ret;
ret = chv_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
ret = chv_config_get(pctldev, pins[0], config);
if (ret)
return ret;
return 0;
}
static int chv_config_group_set(struct pinctrl_dev *pctldev,
unsigned int group, unsigned long *configs,
unsigned int num_configs)
{
const unsigned int *pins;
unsigned int npins;
int i, ret;
ret = chv_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
for (i = 0; i < npins; i++) {
ret = chv_config_set(pctldev, pins[i], configs, num_configs);
if (ret)
return ret;
}
return 0;
}
static const struct pinconf_ops chv_pinconf_ops = {
.is_generic = true,
.pin_config_set = chv_config_set,
.pin_config_get = chv_config_get,
.pin_config_group_get = chv_config_group_get,
.pin_config_group_set = chv_config_group_set,
};
static struct pinctrl_desc chv_pinctrl_desc = {
@ -1160,9 +1244,9 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
u32 ctrl0, cfg;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
@ -1180,7 +1264,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
void __iomem *reg;
u32 ctrl0;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
ctrl0 = readl(reg);
@ -1192,7 +1276,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
chv_writel(ctrl0, reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
}
static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
@ -1202,9 +1286,9 @@ static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
u32 ctrl0, direction;
unsigned long flags;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
@ -1242,14 +1326,14 @@ static void chv_gpio_irq_ack(struct irq_data *d)
int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d));
u32 intr_line;
raw_spin_lock(&pctrl->lock);
raw_spin_lock(&chv_lock);
intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
intr_line &= CHV_PADCTRL0_INTSEL_MASK;
intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT;
chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT);
raw_spin_unlock(&pctrl->lock);
raw_spin_unlock(&chv_lock);
}
static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
@ -1260,7 +1344,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
u32 value, intr_line;
unsigned long flags;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
intr_line &= CHV_PADCTRL0_INTSEL_MASK;
@ -1273,7 +1357,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
value |= BIT(intr_line);
chv_writel(value, pctrl->regs + CHV_INTMASK);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
}
static void chv_gpio_irq_mask(struct irq_data *d)
@ -1307,7 +1391,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
unsigned long flags;
u32 intsel, value;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
intsel &= CHV_PADCTRL0_INTSEL_MASK;
intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
@ -1322,7 +1406,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
irq_set_handler_locked(d, handler);
pctrl->intr_lines[intsel] = offset;
}
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
}
chv_gpio_irq_unmask(d);
@ -1338,7 +1422,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
unsigned long flags;
u32 value;
raw_spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&chv_lock, flags);
/*
* Pins which can be used as shared interrupt are configured in
@ -1387,7 +1471,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
else if (type & IRQ_TYPE_LEVEL_MASK)
irq_set_handler_locked(d, handle_level_irq);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&chv_lock, flags);
return 0;
}
@ -1499,7 +1583,6 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
if (i == ARRAY_SIZE(chv_communities))
return -ENODEV;
raw_spin_lock_init(&pctrl->lock);
pctrl->dev = &pdev->dev;
#ifdef CONFIG_PM_SLEEP

View File

@ -89,7 +89,7 @@ struct intel_pinctrl_context {
*/
struct intel_pinctrl {
struct device *dev;
spinlock_t lock;
raw_spinlock_t lock;
struct pinctrl_desc pctldesc;
struct pinctrl_dev *pctldev;
struct gpio_chip chip;
@ -318,7 +318,7 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
unsigned long flags;
int i;
spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&pctrl->lock, flags);
/*
* All pins in the groups needs to be accessible and writable
@ -326,7 +326,7 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
*/
for (i = 0; i < grp->npins; i++) {
if (!intel_pad_usable(pctrl, grp->pins[i])) {
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return -EBUSY;
}
}
@ -345,7 +345,7 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
writel(value, padcfg0);
}
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
@ -359,10 +359,10 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
unsigned long flags;
u32 value;
spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&pctrl->lock, flags);
if (!intel_pad_usable(pctrl, pin)) {
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return -EBUSY;
}
@ -377,7 +377,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
value |= PADCFG0_GPIOTXDIS;
writel(value, padcfg0);
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
@ -391,7 +391,7 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev,
unsigned long flags;
u32 value;
spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&pctrl->lock, flags);
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
@ -402,7 +402,7 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev,
value &= ~PADCFG0_GPIOTXDIS;
writel(value, padcfg0);
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
@ -490,7 +490,7 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin,
int ret = 0;
u32 value;
spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&pctrl->lock, flags);
padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
value = readl(padcfg1);
@ -544,7 +544,7 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin,
if (!ret)
writel(value, padcfg1);
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return ret;
}
@ -611,14 +611,14 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
unsigned long flags;
u32 padcfg0;
spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&pctrl->lock, flags);
padcfg0 = readl(reg);
if (value)
padcfg0 |= PADCFG0_GPIOTXSTATE;
else
padcfg0 &= ~PADCFG0_GPIOTXSTATE;
writel(padcfg0, reg);
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
}
@ -651,7 +651,7 @@ static void intel_gpio_irq_ack(struct irq_data *d)
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
spin_lock(&pctrl->lock);
raw_spin_lock(&pctrl->lock);
community = intel_get_community(pctrl, pin);
if (community) {
@ -662,7 +662,7 @@ static void intel_gpio_irq_ack(struct irq_data *d)
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
}
spin_unlock(&pctrl->lock);
raw_spin_unlock(&pctrl->lock);
}
static void intel_gpio_irq_enable(struct irq_data *d)
@ -673,7 +673,7 @@ static void intel_gpio_irq_enable(struct irq_data *d)
unsigned pin = irqd_to_hwirq(d);
unsigned long flags;
spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&pctrl->lock, flags);
community = intel_get_community(pctrl, pin);
if (community) {
@ -691,7 +691,7 @@ static void intel_gpio_irq_enable(struct irq_data *d)
writel(value, community->regs + community->ie_offset + gpp * 4);
}
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
@ -702,7 +702,7 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
unsigned pin = irqd_to_hwirq(d);
unsigned long flags;
spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&pctrl->lock, flags);
community = intel_get_community(pctrl, pin);
if (community) {
@ -721,7 +721,7 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
writel(value, reg);
}
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
static void intel_gpio_irq_mask(struct irq_data *d)
@ -757,7 +757,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
return -EPERM;
}
spin_lock_irqsave(&pctrl->lock, flags);
raw_spin_lock_irqsave(&pctrl->lock, flags);
value = readl(reg);
@ -784,7 +784,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
else if (type & IRQ_TYPE_LEVEL_MASK)
irq_set_handler_locked(d, handle_level_irq);
spin_unlock_irqrestore(&pctrl->lock, flags);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
@ -796,12 +796,15 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
unsigned padno, gpp, gpp_offset;
unsigned long flags;
u32 gpe_en;
community = intel_get_community(pctrl, pin);
if (!community)
return -EINVAL;
raw_spin_lock_irqsave(&pctrl->lock, flags);
padno = pin_to_padno(community, pin);
gpp = padno / community->gpp_size;
gpp_offset = padno % community->gpp_size;
@ -821,6 +824,8 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
gpe_en &= ~BIT(gpp_offset);
writel(gpe_en, community->regs + GPI_GPE_EN + gpp * 4);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin);
return 0;
}
@ -919,7 +924,8 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
* to the irq directly) because on some platforms several GPIO
* controllers share the same interrupt line.
*/
ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq, IRQF_SHARED,
ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq,
IRQF_SHARED | IRQF_NO_THREAD,
dev_name(pctrl->dev), pctrl);
if (ret) {
dev_err(pctrl->dev, "failed to request interrupt\n");
@ -995,7 +1001,7 @@ int intel_pinctrl_probe(struct platform_device *pdev,
pctrl->dev = &pdev->dev;
pctrl->soc = soc_data;
spin_lock_init(&pctrl->lock);
raw_spin_lock_init(&pctrl->lock);
/*
* Make a copy of the communities which we can use to hold pointers

View File

@ -0,0 +1,911 @@
/*
* Intel Merrifield SoC pinctrl driver
*
* Copyright (C) 2016, Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "pinctrl-intel.h"
#define MRFLD_FAMILY_NR 64
#define MRFLD_FAMILY_LEN 0x400
#define SLEW_OFFSET 0x000
#define BUFCFG_OFFSET 0x100
#define MISC_OFFSET 0x300
#define BUFCFG_PINMODE_SHIFT 0
#define BUFCFG_PINMODE_MASK GENMASK(2, 0)
#define BUFCFG_PINMODE_GPIO 0
#define BUFCFG_PUPD_VAL_SHIFT 4
#define BUFCFG_PUPD_VAL_MASK GENMASK(5, 4)
#define BUFCFG_PUPD_VAL_2K 0
#define BUFCFG_PUPD_VAL_20K 1
#define BUFCFG_PUPD_VAL_50K 2
#define BUFCFG_PUPD_VAL_910 3
#define BUFCFG_PU_EN BIT(8)
#define BUFCFG_PD_EN BIT(9)
#define BUFCFG_Px_EN_MASK GENMASK(9, 8)
#define BUFCFG_SLEWSEL BIT(10)
#define BUFCFG_OVINEN BIT(12)
#define BUFCFG_OVINEN_EN BIT(13)
#define BUFCFG_OVINEN_MASK GENMASK(13, 12)
#define BUFCFG_OVOUTEN BIT(14)
#define BUFCFG_OVOUTEN_EN BIT(15)
#define BUFCFG_OVOUTEN_MASK GENMASK(15, 14)
#define BUFCFG_INDATAOV_VAL BIT(16)
#define BUFCFG_INDATAOV_EN BIT(17)
#define BUFCFG_INDATAOV_MASK GENMASK(17, 16)
#define BUFCFG_OUTDATAOV_VAL BIT(18)
#define BUFCFG_OUTDATAOV_EN BIT(19)
#define BUFCFG_OUTDATAOV_MASK GENMASK(19, 18)
#define BUFCFG_OD_EN BIT(21)
/**
* struct mrfld_family - Intel pin family description
* @barno: MMIO BAR number where registers for this family reside
* @pin_base: Starting pin of pins in this family
* @npins: Number of pins in this family
* @protected: True if family is protected by access
* @regs: family specific common registers
*/
struct mrfld_family {
unsigned int barno;
unsigned int pin_base;
size_t npins;
bool protected;
void __iomem *regs;
};
#define MRFLD_FAMILY(b, s, e) \
{ \
.barno = (b), \
.pin_base = (s), \
.npins = (e) - (s) + 1, \
}
#define MRFLD_FAMILY_PROTECTED(b, s, e) \
{ \
.barno = (b), \
.pin_base = (s), \
.npins = (e) - (s) + 1, \
.protected = true, \
}
static const struct pinctrl_pin_desc mrfld_pins[] = {
/* Family 0: OCP2SSC (0 pins) */
/* Family 1: ULPI (13 pins) */
PINCTRL_PIN(0, "ULPI_CLK"),
PINCTRL_PIN(1, "ULPI_D0"),
PINCTRL_PIN(2, "ULPI_D1"),
PINCTRL_PIN(3, "ULPI_D2"),
PINCTRL_PIN(4, "ULPI_D3"),
PINCTRL_PIN(5, "ULPI_D4"),
PINCTRL_PIN(6, "ULPI_D5"),
PINCTRL_PIN(7, "ULPI_D6"),
PINCTRL_PIN(8, "ULPI_D7"),
PINCTRL_PIN(9, "ULPI_DIR"),
PINCTRL_PIN(10, "ULPI_NXT"),
PINCTRL_PIN(11, "ULPI_REFCLK"),
PINCTRL_PIN(12, "ULPI_STP"),
/* Family 2: eMMC (24 pins) */
PINCTRL_PIN(13, "EMMC_CLK"),
PINCTRL_PIN(14, "EMMC_CMD"),
PINCTRL_PIN(15, "EMMC_D0"),
PINCTRL_PIN(16, "EMMC_D1"),
PINCTRL_PIN(17, "EMMC_D2"),
PINCTRL_PIN(18, "EMMC_D3"),
PINCTRL_PIN(19, "EMMC_D4"),
PINCTRL_PIN(20, "EMMC_D5"),
PINCTRL_PIN(21, "EMMC_D6"),
PINCTRL_PIN(22, "EMMC_D7"),
PINCTRL_PIN(23, "EMMC_RST_N"),
PINCTRL_PIN(24, "GP154"),
PINCTRL_PIN(25, "GP155"),
PINCTRL_PIN(26, "GP156"),
PINCTRL_PIN(27, "GP157"),
PINCTRL_PIN(28, "GP158"),
PINCTRL_PIN(29, "GP159"),
PINCTRL_PIN(30, "GP160"),
PINCTRL_PIN(31, "GP161"),
PINCTRL_PIN(32, "GP162"),
PINCTRL_PIN(33, "GP163"),
PINCTRL_PIN(34, "GP97"),
PINCTRL_PIN(35, "GP14"),
PINCTRL_PIN(36, "GP15"),
/* Family 3: SDIO (20 pins) */
PINCTRL_PIN(37, "GP77_SD_CD"),
PINCTRL_PIN(38, "GP78_SD_CLK"),
PINCTRL_PIN(39, "GP79_SD_CMD"),
PINCTRL_PIN(40, "GP80_SD_D0"),
PINCTRL_PIN(41, "GP81_SD_D1"),
PINCTRL_PIN(42, "GP82_SD_D2"),
PINCTRL_PIN(43, "GP83_SD_D3"),
PINCTRL_PIN(44, "GP84_SD_LS_CLK_FB"),
PINCTRL_PIN(45, "GP85_SD_LS_CMD_DIR"),
PINCTRL_PIN(46, "GP86_SD_LVL_D_DIR"),
PINCTRL_PIN(47, "GP88_SD_LS_SEL"),
PINCTRL_PIN(48, "GP87_SD_PD"),
PINCTRL_PIN(49, "GP89_SD_WP"),
PINCTRL_PIN(50, "GP90_SDIO_CLK"),
PINCTRL_PIN(51, "GP91_SDIO_CMD"),
PINCTRL_PIN(52, "GP92_SDIO_D0"),
PINCTRL_PIN(53, "GP93_SDIO_D1"),
PINCTRL_PIN(54, "GP94_SDIO_D2"),
PINCTRL_PIN(55, "GP95_SDIO_D3"),
PINCTRL_PIN(56, "GP96_SDIO_PD"),
/* Family 4: HSI (8 pins) */
PINCTRL_PIN(57, "HSI_ACDATA"),
PINCTRL_PIN(58, "HSI_ACFLAG"),
PINCTRL_PIN(59, "HSI_ACREADY"),
PINCTRL_PIN(60, "HSI_ACWAKE"),
PINCTRL_PIN(61, "HSI_CADATA"),
PINCTRL_PIN(62, "HSI_CAFLAG"),
PINCTRL_PIN(63, "HSI_CAREADY"),
PINCTRL_PIN(64, "HSI_CAWAKE"),
/* Family 5: SSP Audio (14 pins) */
PINCTRL_PIN(65, "GP70"),
PINCTRL_PIN(66, "GP71"),
PINCTRL_PIN(67, "GP32_I2S_0_CLK"),
PINCTRL_PIN(68, "GP33_I2S_0_FS"),
PINCTRL_PIN(69, "GP34_I2S_0_RXD"),
PINCTRL_PIN(70, "GP35_I2S_0_TXD"),
PINCTRL_PIN(71, "GP36_I2S_1_CLK"),
PINCTRL_PIN(72, "GP37_I2S_1_FS"),
PINCTRL_PIN(73, "GP38_I2S_1_RXD"),
PINCTRL_PIN(74, "GP39_I2S_1_TXD"),
PINCTRL_PIN(75, "GP40_I2S_2_CLK"),
PINCTRL_PIN(76, "GP41_I2S_2_FS"),
PINCTRL_PIN(77, "GP42_I2S_2_RXD"),
PINCTRL_PIN(78, "GP43_I2S_2_TXD"),
/* Family 6: GP SSP (22 pins) */
PINCTRL_PIN(79, "GP120_SPI_3_CLK"),
PINCTRL_PIN(80, "GP121_SPI_3_SS"),
PINCTRL_PIN(81, "GP122_SPI_3_RXD"),
PINCTRL_PIN(82, "GP123_SPI_3_TXD"),
PINCTRL_PIN(83, "GP102_SPI_4_CLK"),
PINCTRL_PIN(84, "GP103_SPI_4_SS_0"),
PINCTRL_PIN(85, "GP104_SPI_4_SS_1"),
PINCTRL_PIN(86, "GP105_SPI_4_SS_2"),
PINCTRL_PIN(87, "GP106_SPI_4_SS_3"),
PINCTRL_PIN(88, "GP107_SPI_4_RXD"),
PINCTRL_PIN(89, "GP108_SPI_4_TXD"),
PINCTRL_PIN(90, "GP109_SPI_5_CLK"),
PINCTRL_PIN(91, "GP110_SPI_5_SS_0"),
PINCTRL_PIN(92, "GP111_SPI_5_SS_1"),
PINCTRL_PIN(93, "GP112_SPI_5_SS_2"),
PINCTRL_PIN(94, "GP113_SPI_5_SS_3"),
PINCTRL_PIN(95, "GP114_SPI_5_RXD"),
PINCTRL_PIN(96, "GP115_SPI_5_TXD"),
PINCTRL_PIN(97, "GP116_SPI_6_CLK"),
PINCTRL_PIN(98, "GP117_SPI_6_SS"),
PINCTRL_PIN(99, "GP118_SPI_6_RXD"),
PINCTRL_PIN(100, "GP119_SPI_6_TXD"),
/* Family 7: I2C (14 pins) */
PINCTRL_PIN(101, "GP19_I2C_1_SCL"),
PINCTRL_PIN(102, "GP20_I2C_1_SDA"),
PINCTRL_PIN(103, "GP21_I2C_2_SCL"),
PINCTRL_PIN(104, "GP22_I2C_2_SDA"),
PINCTRL_PIN(105, "GP17_I2C_3_SCL_HDMI"),
PINCTRL_PIN(106, "GP18_I2C_3_SDA_HDMI"),
PINCTRL_PIN(107, "GP23_I2C_4_SCL"),
PINCTRL_PIN(108, "GP24_I2C_4_SDA"),
PINCTRL_PIN(109, "GP25_I2C_5_SCL"),
PINCTRL_PIN(110, "GP26_I2C_5_SDA"),
PINCTRL_PIN(111, "GP27_I2C_6_SCL"),
PINCTRL_PIN(112, "GP28_I2C_6_SDA"),
PINCTRL_PIN(113, "GP29_I2C_7_SCL"),
PINCTRL_PIN(114, "GP30_I2C_7_SDA"),
/* Family 8: UART (12 pins) */
PINCTRL_PIN(115, "GP124_UART_0_CTS"),
PINCTRL_PIN(116, "GP125_UART_0_RTS"),
PINCTRL_PIN(117, "GP126_UART_0_RX"),
PINCTRL_PIN(118, "GP127_UART_0_TX"),
PINCTRL_PIN(119, "GP128_UART_1_CTS"),
PINCTRL_PIN(120, "GP129_UART_1_RTS"),
PINCTRL_PIN(121, "GP130_UART_1_RX"),
PINCTRL_PIN(122, "GP131_UART_1_TX"),
PINCTRL_PIN(123, "GP132_UART_2_CTS"),
PINCTRL_PIN(124, "GP133_UART_2_RTS"),
PINCTRL_PIN(125, "GP134_UART_2_RX"),
PINCTRL_PIN(126, "GP135_UART_2_TX"),
/* Family 9: GPIO South (19 pins) */
PINCTRL_PIN(127, "GP177"),
PINCTRL_PIN(128, "GP178"),
PINCTRL_PIN(129, "GP179"),
PINCTRL_PIN(130, "GP180"),
PINCTRL_PIN(131, "GP181"),
PINCTRL_PIN(132, "GP182_PWM2"),
PINCTRL_PIN(133, "GP183_PWM3"),
PINCTRL_PIN(134, "GP184"),
PINCTRL_PIN(135, "GP185"),
PINCTRL_PIN(136, "GP186"),
PINCTRL_PIN(137, "GP187"),
PINCTRL_PIN(138, "GP188"),
PINCTRL_PIN(139, "GP189"),
PINCTRL_PIN(140, "GP64_FAST_INT0"),
PINCTRL_PIN(141, "GP65_FAST_INT1"),
PINCTRL_PIN(142, "GP66_FAST_INT2"),
PINCTRL_PIN(143, "GP67_FAST_INT3"),
PINCTRL_PIN(144, "GP12_PWM0"),
PINCTRL_PIN(145, "GP13_PWM1"),
/* Family 10: Camera Sideband (12 pins) */
PINCTRL_PIN(146, "GP0"),
PINCTRL_PIN(147, "GP1"),
PINCTRL_PIN(148, "GP2"),
PINCTRL_PIN(149, "GP3"),
PINCTRL_PIN(150, "GP4"),
PINCTRL_PIN(151, "GP5"),
PINCTRL_PIN(152, "GP6"),
PINCTRL_PIN(153, "GP7"),
PINCTRL_PIN(154, "GP8"),
PINCTRL_PIN(155, "GP9"),
PINCTRL_PIN(156, "GP10"),
PINCTRL_PIN(157, "GP11"),
/* Family 11: Clock (22 pins) */
PINCTRL_PIN(158, "GP137"),
PINCTRL_PIN(159, "GP138"),
PINCTRL_PIN(160, "GP139"),
PINCTRL_PIN(161, "GP140"),
PINCTRL_PIN(162, "GP141"),
PINCTRL_PIN(163, "GP142"),
PINCTRL_PIN(164, "GP16_HDMI_HPD"),
PINCTRL_PIN(165, "GP68_DSI_A_TE"),
PINCTRL_PIN(166, "GP69_DSI_C_TE"),
PINCTRL_PIN(167, "OSC_CLK_CTRL0"),
PINCTRL_PIN(168, "OSC_CLK_CTRL1"),
PINCTRL_PIN(169, "OSC_CLK0"),
PINCTRL_PIN(170, "OSC_CLK1"),
PINCTRL_PIN(171, "OSC_CLK2"),
PINCTRL_PIN(172, "OSC_CLK3"),
PINCTRL_PIN(173, "OSC_CLK4"),
PINCTRL_PIN(174, "RESETOUT"),
PINCTRL_PIN(175, "PMODE"),
PINCTRL_PIN(176, "PRDY"),
PINCTRL_PIN(177, "PREQ"),
PINCTRL_PIN(178, "GP190"),
PINCTRL_PIN(179, "GP191"),
/* Family 12: MSIC (15 pins) */
PINCTRL_PIN(180, "I2C_0_SCL"),
PINCTRL_PIN(181, "I2C_0_SDA"),
PINCTRL_PIN(182, "IERR"),
PINCTRL_PIN(183, "JTAG_TCK"),
PINCTRL_PIN(184, "JTAG_TDI"),
PINCTRL_PIN(185, "JTAG_TDO"),
PINCTRL_PIN(186, "JTAG_TMS"),
PINCTRL_PIN(187, "JTAG_TRST"),
PINCTRL_PIN(188, "PROCHOT"),
PINCTRL_PIN(189, "RTC_CLK"),
PINCTRL_PIN(190, "SVID_ALERT"),
PINCTRL_PIN(191, "SVID_CLK"),
PINCTRL_PIN(192, "SVID_D"),
PINCTRL_PIN(193, "THERMTRIP"),
PINCTRL_PIN(194, "STANDBY"),
/* Family 13: Keyboard (20 pins) */
PINCTRL_PIN(195, "GP44"),
PINCTRL_PIN(196, "GP45"),
PINCTRL_PIN(197, "GP46"),
PINCTRL_PIN(198, "GP47"),
PINCTRL_PIN(199, "GP48"),
PINCTRL_PIN(200, "GP49"),
PINCTRL_PIN(201, "GP50"),
PINCTRL_PIN(202, "GP51"),
PINCTRL_PIN(203, "GP52"),
PINCTRL_PIN(204, "GP53"),
PINCTRL_PIN(205, "GP54"),
PINCTRL_PIN(206, "GP55"),
PINCTRL_PIN(207, "GP56"),
PINCTRL_PIN(208, "GP57"),
PINCTRL_PIN(209, "GP58"),
PINCTRL_PIN(210, "GP59"),
PINCTRL_PIN(211, "GP60"),
PINCTRL_PIN(212, "GP61"),
PINCTRL_PIN(213, "GP62"),
PINCTRL_PIN(214, "GP63"),
/* Family 14: GPIO North (13 pins) */
PINCTRL_PIN(215, "GP164"),
PINCTRL_PIN(216, "GP165"),
PINCTRL_PIN(217, "GP166"),
PINCTRL_PIN(218, "GP167"),
PINCTRL_PIN(219, "GP168_MJTAG_TCK"),
PINCTRL_PIN(220, "GP169_MJTAG_TDI"),
PINCTRL_PIN(221, "GP170_MJTAG_TDO"),
PINCTRL_PIN(222, "GP171_MJTAG_TMS"),
PINCTRL_PIN(223, "GP172_MJTAG_TRST"),
PINCTRL_PIN(224, "GP173"),
PINCTRL_PIN(225, "GP174"),
PINCTRL_PIN(226, "GP175"),
PINCTRL_PIN(227, "GP176"),
/* Family 15: PTI (5 pins) */
PINCTRL_PIN(228, "GP72_PTI_CLK"),
PINCTRL_PIN(229, "GP73_PTI_D0"),
PINCTRL_PIN(230, "GP74_PTI_D1"),
PINCTRL_PIN(231, "GP75_PTI_D2"),
PINCTRL_PIN(232, "GP76_PTI_D3"),
/* Family 16: USB3 (0 pins) */
/* Family 17: HSIC (0 pins) */
/* Family 18: Broadcast (0 pins) */
};
static const unsigned int mrfld_sdio_pins[] = { 50, 51, 52, 53, 54, 55, 56 };
static const unsigned int mrfld_spi5_pins[] = { 90, 91, 92, 93, 94, 95, 96 };
static const unsigned int mrfld_uart0_pins[] = { 124, 125, 126, 127 };
static const unsigned int mrfld_uart1_pins[] = { 128, 129, 130, 131 };
static const unsigned int mrfld_uart2_pins[] = { 132, 133, 134, 135 };
static const unsigned int mrfld_pwm0_pins[] = { 144 };
static const unsigned int mrfld_pwm1_pins[] = { 145 };
static const unsigned int mrfld_pwm2_pins[] = { 132 };
static const unsigned int mrfld_pwm3_pins[] = { 133 };
static const struct intel_pingroup mrfld_groups[] = {
PIN_GROUP("sdio_grp", mrfld_sdio_pins, 1),
PIN_GROUP("spi5_grp", mrfld_spi5_pins, 1),
PIN_GROUP("uart0_grp", mrfld_uart0_pins, 1),
PIN_GROUP("uart1_grp", mrfld_uart1_pins, 1),
PIN_GROUP("uart2_grp", mrfld_uart2_pins, 1),
PIN_GROUP("pwm0_grp", mrfld_pwm0_pins, 1),
PIN_GROUP("pwm1_grp", mrfld_pwm1_pins, 1),
PIN_GROUP("pwm2_grp", mrfld_pwm2_pins, 1),
PIN_GROUP("pwm3_grp", mrfld_pwm3_pins, 1),
};
static const char * const mrfld_sdio_groups[] = { "sdio_grp" };
static const char * const mrfld_spi5_groups[] = { "spi5_grp" };
static const char * const mrfld_uart0_groups[] = { "uart0_grp" };
static const char * const mrfld_uart1_groups[] = { "uart1_grp" };
static const char * const mrfld_uart2_groups[] = { "uart2_grp" };
static const char * const mrfld_pwm0_groups[] = { "pwm0_grp" };
static const char * const mrfld_pwm1_groups[] = { "pwm1_grp" };
static const char * const mrfld_pwm2_groups[] = { "pwm2_grp" };
static const char * const mrfld_pwm3_groups[] = { "pwm3_grp" };
static const struct intel_function mrfld_functions[] = {
FUNCTION("sdio", mrfld_sdio_groups),
FUNCTION("spi5", mrfld_spi5_groups),
FUNCTION("uart0", mrfld_uart0_groups),
FUNCTION("uart1", mrfld_uart1_groups),
FUNCTION("uart2", mrfld_uart2_groups),
FUNCTION("pwm0", mrfld_pwm0_groups),
FUNCTION("pwm1", mrfld_pwm1_groups),
FUNCTION("pwm2", mrfld_pwm2_groups),
FUNCTION("pwm3", mrfld_pwm3_groups),
};
static const struct mrfld_family mrfld_families[] = {
MRFLD_FAMILY(1, 0, 12),
MRFLD_FAMILY(2, 13, 36),
MRFLD_FAMILY(3, 37, 56),
MRFLD_FAMILY(4, 57, 64),
MRFLD_FAMILY(5, 65, 78),
MRFLD_FAMILY(6, 79, 100),
MRFLD_FAMILY_PROTECTED(7, 101, 114),
MRFLD_FAMILY(8, 115, 126),
MRFLD_FAMILY(9, 127, 145),
MRFLD_FAMILY(10, 146, 157),
MRFLD_FAMILY(11, 158, 179),
MRFLD_FAMILY_PROTECTED(12, 180, 194),
MRFLD_FAMILY(13, 195, 214),
MRFLD_FAMILY(14, 215, 227),
MRFLD_FAMILY(15, 228, 232),
};
/**
* struct mrfld_pinctrl - Intel Merrifield pinctrl private structure
* @dev: Pointer to the device structure
* @lock: Lock to serialize register access
* @pctldesc: Pin controller description
* @pctldev: Pointer to the pin controller device
* @families: Array of families this pinctrl handles
* @nfamilies: Number of families in the array
* @functions: Array of functions
* @nfunctions: Number of functions in the array
* @groups: Array of pin groups
* @ngroups: Number of groups in the array
* @pins: Array of pins this pinctrl controls
* @npins: Number of pins in the array
*/
struct mrfld_pinctrl {
struct device *dev;
raw_spinlock_t lock;
struct pinctrl_desc pctldesc;
struct pinctrl_dev *pctldev;
/* Pin controller configuration */
const struct mrfld_family *families;
size_t nfamilies;
const struct intel_function *functions;
size_t nfunctions;
const struct intel_pingroup *groups;
size_t ngroups;
const struct pinctrl_pin_desc *pins;
size_t npins;
};
#define pin_to_bufno(f, p) ((p) - (f)->pin_base)
static const struct mrfld_family *mrfld_get_family(struct mrfld_pinctrl *mp,
unsigned int pin)
{
const struct mrfld_family *family;
unsigned int i;
for (i = 0; i < mp->nfamilies; i++) {
family = &mp->families[i];
if (pin >= family->pin_base &&
pin < family->pin_base + family->npins)
return family;
}
dev_warn(mp->dev, "failed to find family for pin %u\n", pin);
return NULL;
}
static bool mrfld_buf_available(struct mrfld_pinctrl *mp, unsigned int pin)
{
const struct mrfld_family *family;
family = mrfld_get_family(mp, pin);
if (!family)
return false;
return !family->protected;
}
static void __iomem *mrfld_get_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin)
{
const struct mrfld_family *family;
unsigned int bufno;
family = mrfld_get_family(mp, pin);
if (!family)
return NULL;
bufno = pin_to_bufno(family, pin);
return family->regs + BUFCFG_OFFSET + bufno * 4;
}
static int mrfld_get_groups_count(struct pinctrl_dev *pctldev)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
return mp->ngroups;
}
static const char *mrfld_get_group_name(struct pinctrl_dev *pctldev,
unsigned int group)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
return mp->groups[group].name;
}
static int mrfld_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
const unsigned int **pins, unsigned int *npins)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
*pins = mp->groups[group].pins;
*npins = mp->groups[group].npins;
return 0;
}
static void mrfld_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
unsigned int pin)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
void __iomem *bufcfg;
u32 value, mode;
if (!mrfld_buf_available(mp, pin)) {
seq_puts(s, "not available");
return;
}
bufcfg = mrfld_get_bufcfg(mp, pin);
value = readl(bufcfg);
mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT;
if (!mode)
seq_puts(s, "GPIO ");
else
seq_printf(s, "mode %d ", mode);
seq_printf(s, "0x%08x", value);
}
static const struct pinctrl_ops mrfld_pinctrl_ops = {
.get_groups_count = mrfld_get_groups_count,
.get_group_name = mrfld_get_group_name,
.get_group_pins = mrfld_get_group_pins,
.pin_dbg_show = mrfld_pin_dbg_show,
};
static int mrfld_get_functions_count(struct pinctrl_dev *pctldev)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
return mp->nfunctions;
}
static const char *mrfld_get_function_name(struct pinctrl_dev *pctldev,
unsigned int function)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
return mp->functions[function].name;
}
static int mrfld_get_function_groups(struct pinctrl_dev *pctldev,
unsigned int function,
const char * const **groups,
unsigned int * const ngroups)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
*groups = mp->functions[function].groups;
*ngroups = mp->functions[function].ngroups;
return 0;
}
static void mrfld_update_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin,
u32 bits, u32 mask)
{
void __iomem *bufcfg;
u32 value;
bufcfg = mrfld_get_bufcfg(mp, pin);
value = readl(bufcfg);
value &= ~mask;
value |= bits & mask;
writel(value, bufcfg);
}
static int mrfld_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int function,
unsigned int group)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
const struct intel_pingroup *grp = &mp->groups[group];
u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT;
u32 mask = BUFCFG_PINMODE_MASK;
unsigned long flags;
unsigned int i;
/*
* All pins in the groups needs to be accessible and writable
* before we can enable the mux for this group.
*/
for (i = 0; i < grp->npins; i++) {
if (!mrfld_buf_available(mp, grp->pins[i]))
return -EBUSY;
}
/* Now enable the mux setting for each pin in the group */
raw_spin_lock_irqsave(&mp->lock, flags);
for (i = 0; i < grp->npins; i++)
mrfld_update_bufcfg(mp, grp->pins[i], bits, mask);
raw_spin_unlock_irqrestore(&mp->lock, flags);
return 0;
}
static int mrfld_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int pin)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT;
u32 mask = BUFCFG_PINMODE_MASK;
unsigned long flags;
if (!mrfld_buf_available(mp, pin))
return -EBUSY;
raw_spin_lock_irqsave(&mp->lock, flags);
mrfld_update_bufcfg(mp, pin, bits, mask);
raw_spin_unlock_irqrestore(&mp->lock, flags);
return 0;
}
static const struct pinmux_ops mrfld_pinmux_ops = {
.get_functions_count = mrfld_get_functions_count,
.get_function_name = mrfld_get_function_name,
.get_function_groups = mrfld_get_function_groups,
.set_mux = mrfld_pinmux_set_mux,
.gpio_request_enable = mrfld_gpio_request_enable,
};
static int mrfld_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
u32 value, term;
u16 arg = 0;
if (!mrfld_buf_available(mp, pin))
return -ENOTSUPP;
value = readl(mrfld_get_bufcfg(mp, pin));
term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT;
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
if (value & BUFCFG_Px_EN_MASK)
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_UP:
if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN)
return -EINVAL;
switch (term) {
case BUFCFG_PUPD_VAL_910:
arg = 910;
break;
case BUFCFG_PUPD_VAL_2K:
arg = 2000;
break;
case BUFCFG_PUPD_VAL_20K:
arg = 20000;
break;
case BUFCFG_PUPD_VAL_50K:
arg = 50000;
break;
}
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN)
return -EINVAL;
switch (term) {
case BUFCFG_PUPD_VAL_910:
arg = 910;
break;
case BUFCFG_PUPD_VAL_2K:
arg = 2000;
break;
case BUFCFG_PUPD_VAL_20K:
arg = 20000;
break;
case BUFCFG_PUPD_VAL_50K:
arg = 50000;
break;
}
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
if (!(value & BUFCFG_OD_EN))
return -EINVAL;
break;
case PIN_CONFIG_SLEW_RATE:
if (!(value & BUFCFG_SLEWSEL))
arg = 0;
else
arg = 1;
break;
default:
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int mrfld_config_set_pin(struct mrfld_pinctrl *mp, unsigned int pin,
unsigned long config)
{
unsigned int param = pinconf_to_config_param(config);
unsigned int arg = pinconf_to_config_argument(config);
u32 bits = 0, mask = 0;
unsigned long flags;
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
break;
case PIN_CONFIG_BIAS_PULL_UP:
mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
bits |= BUFCFG_PU_EN;
switch (arg) {
case 50000:
bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT;
break;
case 20000:
bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT;
break;
case 2000:
bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT;
break;
default:
return -EINVAL;
}
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
bits |= BUFCFG_PD_EN;
switch (arg) {
case 50000:
bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT;
break;
case 20000:
bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT;
break;
case 2000:
bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT;
break;
default:
return -EINVAL;
}
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
mask |= BUFCFG_OD_EN;
if (arg)
bits |= BUFCFG_OD_EN;
break;
case PIN_CONFIG_SLEW_RATE:
mask |= BUFCFG_SLEWSEL;
if (arg)
bits |= BUFCFG_SLEWSEL;
break;
}
raw_spin_lock_irqsave(&mp->lock, flags);
mrfld_update_bufcfg(mp, pin, bits, mask);
raw_spin_unlock_irqrestore(&mp->lock, flags);
return 0;
}
static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int nconfigs)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
unsigned int i;
int ret;
for (i = 0; i < nconfigs; i++) {
switch (pinconf_to_config_param(configs[i])) {
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN:
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
case PIN_CONFIG_SLEW_RATE:
ret = mrfld_config_set_pin(mp, pin, configs[i]);
if (ret)
return ret;
break;
default:
return -ENOTSUPP;
}
}
return 0;
}
static const struct pinconf_ops mrfld_pinconf_ops = {
.is_generic = true,
.pin_config_get = mrfld_config_get,
.pin_config_set = mrfld_config_set,
};
static const struct pinctrl_desc mrfld_pinctrl_desc = {
.pctlops = &mrfld_pinctrl_ops,
.pmxops = &mrfld_pinmux_ops,
.confops = &mrfld_pinconf_ops,
.owner = THIS_MODULE,
};
static int mrfld_pinctrl_probe(struct platform_device *pdev)
{
struct mrfld_family *families;
struct mrfld_pinctrl *mp;
struct resource *mem;
void __iomem *regs;
size_t nfamilies;
unsigned int i;
mp = devm_kzalloc(&pdev->dev, sizeof(*mp), GFP_KERNEL);
if (!mp)
return -ENOMEM;
mp->dev = &pdev->dev;
raw_spin_lock_init(&mp->lock);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(regs))
return PTR_ERR(regs);
/*
* Make a copy of the families which we can use to hold pointers
* to the registers.
*/
nfamilies = ARRAY_SIZE(mrfld_families),
families = devm_kmemdup(&pdev->dev, mrfld_families,
nfamilies * sizeof(mrfld_families),
GFP_KERNEL);
if (!families)
return -ENOMEM;
/* Splice memory resource by chunk per family */
for (i = 0; i < nfamilies; i++) {
struct mrfld_family *family = &families[i];
family->regs = regs + family->barno * MRFLD_FAMILY_LEN;
}
mp->families = families;
mp->nfamilies = nfamilies;
mp->functions = mrfld_functions;
mp->nfunctions = ARRAY_SIZE(mrfld_functions);
mp->groups = mrfld_groups;
mp->ngroups = ARRAY_SIZE(mrfld_groups);
mp->pctldesc = mrfld_pinctrl_desc;
mp->pctldesc.name = dev_name(&pdev->dev);
mp->pctldesc.pins = mrfld_pins;
mp->pctldesc.npins = ARRAY_SIZE(mrfld_pins);
mp->pctldev = devm_pinctrl_register(&pdev->dev, &mp->pctldesc, mp);
if (IS_ERR(mp->pctldev)) {
dev_err(&pdev->dev, "failed to register pinctrl driver\n");
return PTR_ERR(mp->pctldev);
}
platform_set_drvdata(pdev, mp);
return 0;
}
static struct platform_driver mrfld_pinctrl_driver = {
.probe = mrfld_pinctrl_probe,
.driver = {
.name = "pinctrl-merrifield",
},
};
static int __init mrfld_pinctrl_init(void)
{
return platform_driver_register(&mrfld_pinctrl_driver);
}
subsys_initcall(mrfld_pinctrl_init);
static void __exit mrfld_pinctrl_exit(void)
{
platform_driver_unregister(&mrfld_pinctrl_driver);
}
module_exit(mrfld_pinctrl_exit);
MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
MODULE_DESCRIPTION("Intel Merrifield SoC pinctrl driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:pinctrl-merrifield");

View File

@ -1183,8 +1183,8 @@ static int mtk_eint_resume(struct device *device)
}
const struct dev_pm_ops mtk_eint_pm_ops = {
.suspend = mtk_eint_suspend,
.resume = mtk_eint_resume,
.suspend_noirq = mtk_eint_suspend,
.resume_noirq = mtk_eint_resume,
};
static void mtk_eint_ack(struct irq_data *d)

View File

@ -147,6 +147,52 @@ static const struct pinctrl_pin_desc meson_gxbb_periphs_pins[] = {
MESON_PIN(GPIO_TEST_N, EE_OFF),
};
static const unsigned int emmc_nand_d07_pins[] = {
PIN(BOOT_0, EE_OFF), PIN(BOOT_1, EE_OFF), PIN(BOOT_2, EE_OFF),
PIN(BOOT_3, EE_OFF), PIN(BOOT_4, EE_OFF), PIN(BOOT_5, EE_OFF),
PIN(BOOT_6, EE_OFF), PIN(BOOT_7, EE_OFF),
};
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 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) };
static const unsigned int sdcard_d3_pins[] = { PIN(CARD_4, EE_OFF) };
static const unsigned int sdcard_cmd_pins[] = { PIN(CARD_3, EE_OFF) };
static const unsigned int sdcard_clk_pins[] = { PIN(CARD_2, EE_OFF) };
static const unsigned int uart_tx_a_pins[] = { PIN(GPIOX_12, EE_OFF) };
static const unsigned int uart_rx_a_pins[] = { PIN(GPIOX_13, EE_OFF) };
static const unsigned int uart_cts_a_pins[] = { PIN(GPIOX_14, EE_OFF) };
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(GPIOY_13, EE_OFF) };
static const unsigned int uart_rx_c_pins[] = { PIN(GPIOY_14, EE_OFF) };
static const unsigned int uart_cts_c_pins[] = { PIN(GPIOX_11, EE_OFF) };
static const unsigned int uart_rts_c_pins[] = { PIN(GPIOX_12, 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) };
static const unsigned int eth_rx_dv_pins[] = { PIN(GPIOZ_3, EE_OFF) };
static const unsigned int eth_rxd0_pins[] = { PIN(GPIOZ_4, EE_OFF) };
static const unsigned int eth_rxd1_pins[] = { PIN(GPIOZ_5, EE_OFF) };
static const unsigned int eth_rxd2_pins[] = { PIN(GPIOZ_6, EE_OFF) };
static const unsigned int eth_rxd3_pins[] = { PIN(GPIOZ_7, EE_OFF) };
static const unsigned int eth_rgmii_tx_clk_pins[] = { PIN(GPIOZ_8, EE_OFF) };
static const unsigned int eth_tx_en_pins[] = { PIN(GPIOZ_9, EE_OFF) };
static const unsigned int eth_txd0_pins[] = { PIN(GPIOZ_10, EE_OFF) };
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 struct pinctrl_pin_desc meson_gxbb_aobus_pins[] = {
MESON_PIN(GPIOAO_0, 0),
MESON_PIN(GPIOAO_1, 0),
@ -168,6 +214,16 @@ 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_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_0, 0) };
static const unsigned int uart_rx_ao_b_pins[] = { PIN(GPIOAO_1, 0),
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 struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GPIO_GROUP(GPIOZ_0, EE_OFF),
@ -297,6 +353,54 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GPIO_GROUP(GPIOCLK_3, EE_OFF),
GPIO_GROUP(GPIO_TEST_N, EE_OFF),
/* Bank X */
GROUP(uart_tx_a, 4, 13),
GROUP(uart_rx_a, 4, 12),
GROUP(uart_cts_a, 4, 11),
GROUP(uart_rts_a, 4, 10),
/* Bank Y */
GROUP(uart_cts_c, 1, 19),
GROUP(uart_rts_c, 1, 18),
GROUP(uart_tx_c, 1, 17),
GROUP(uart_rx_c, 1, 16),
/* Bank Z */
GROUP(eth_mdio, 6, 1),
GROUP(eth_mdc, 6, 0),
GROUP(eth_clk_rx_clk, 6, 13),
GROUP(eth_rx_dv, 6, 12),
GROUP(eth_rxd0, 6, 11),
GROUP(eth_rxd1, 6, 10),
GROUP(eth_rxd2, 6, 9),
GROUP(eth_rxd3, 6, 8),
GROUP(eth_rgmii_tx_clk, 6, 7),
GROUP(eth_tx_en, 6, 6),
GROUP(eth_txd0, 6, 5),
GROUP(eth_txd1, 6, 4),
GROUP(eth_txd2, 6, 3),
GROUP(eth_txd3, 6, 2),
/* Bank DV */
GROUP(uart_tx_b, 2, 29),
GROUP(uart_rx_b, 2, 28),
GROUP(uart_cts_b, 2, 27),
GROUP(uart_rts_b, 2, 26),
/* Bank BOOT */
GROUP(emmc_nand_d07, 4, 30),
GROUP(emmc_clk, 4, 18),
GROUP(emmc_cmd, 4, 19),
GROUP(emmc_ds, 4, 31),
/* Bank CARD */
GROUP(sdcard_d1, 2, 14),
GROUP(sdcard_d0, 2, 15),
GROUP(sdcard_d3, 2, 12),
GROUP(sdcard_d2, 2, 13),
GROUP(sdcard_cmd, 2, 10),
GROUP(sdcard_clk, 2, 11),
};
static struct meson_pmx_group meson_gxbb_aobus_groups[] = {
@ -316,10 +420,18 @@ static struct meson_pmx_group meson_gxbb_aobus_groups[] = {
GPIO_GROUP(GPIOAO_13, 0),
/* bank AO */
GROUP(uart_tx_ao_b, 0, 26),
GROUP(uart_rx_ao_b, 0, 25),
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),
};
static const char * const gpio_periphs_groups[] = {
@ -359,6 +471,34 @@ static const char * const gpio_periphs_groups[] = {
"GPIO_TEST_N",
};
static const char * const emmc_groups[] = {
"emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
};
static const char * const sdcard_groups[] = {
"sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3",
"sdcard_cmd", "sdcard_clk",
};
static const char * const uart_a_groups[] = {
"uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a",
};
static const char * const uart_b_groups[] = {
"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_cts_c", "uart_rts_c",
};
static const char * const eth_groups[] = {
"eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv",
"eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3",
"eth_rgmii_tx_clk", "eth_tx_en",
"eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3",
};
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",
@ -366,16 +506,37 @@ static const char * const gpio_aobus_groups[] = {
};
static const char * const uart_ao_groups[] = {
"uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a"
"uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a",
};
static const char * const uart_ao_b_groups[] = {
"uart_tx_ao_b", "uart_rx_ao_b", "uart_cts_ao_b", "uart_rts_ao_b",
};
static const char * const i2c_ao_groups[] = {
"i2c_sdk_ao", "i2c_sda_ao",
};
static const char * const i2c_slave_ao_groups[] = {
"i2c_slave_sdk_ao", "i2c_slave_sda_ao",
};
static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
FUNCTION(gpio_periphs),
FUNCTION(emmc),
FUNCTION(sdcard),
FUNCTION(uart_a),
FUNCTION(uart_b),
FUNCTION(uart_c),
FUNCTION(eth),
};
static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
FUNCTION(gpio_aobus),
FUNCTION(uart_ao),
FUNCTION(uart_ao_b),
FUNCTION(i2c_ao),
FUNCTION(i2c_slave_ao),
};
static struct meson_bank meson_gxbb_periphs_banks[] = {

View File

@ -168,87 +168,87 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1, 1))),
MPP_MODE(20,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1, 0)),
MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0, 0))),
MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 0, 0, 0, 0, 0))),
MPP_MODE(21,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(22,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(23,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(24,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(25,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(26,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(27,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(28,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(29,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 0, 0, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(30,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
@ -280,65 +280,65 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(35,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)),
MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1, 0)),
MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1, 0))),
MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 1, 1, 1, 1, 0))),
MPP_MODE(36,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(37,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(38,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(39,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(40,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(41,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(42,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(43,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(44,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 1, 1, 0)),
MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1, 0))),
MPP_MODE(45,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
@ -371,11 +371,12 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
};
static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
MPP_FUNC_CTRL(0, 29, NULL, kirkwood_mpp_ctrl),
MPP_FUNC_CTRL(0, 44, NULL, kirkwood_mpp_ctrl),
};
static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
MPP_GPIO_RANGE(0, 0, 0, 30),
MPP_GPIO_RANGE(0, 0, 0, 20),
MPP_GPIO_RANGE(1, 35, 35, 10),
};
static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = {

View File

@ -1033,102 +1033,6 @@ static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
#define nmk_gpio_dbg_show NULL
#endif
void nmk_gpio_clocks_enable(void)
{
int i;
for (i = 0; i < NUM_BANKS; i++) {
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
if (!chip)
continue;
clk_enable(chip->clk);
}
}
void nmk_gpio_clocks_disable(void)
{
int i;
for (i = 0; i < NUM_BANKS; i++) {
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
if (!chip)
continue;
clk_disable(chip->clk);
}
}
/*
* Called from the suspend/resume path to only keep the real wakeup interrupts
* (those that have had set_irq_wake() called on them) as wakeup interrupts,
* and not the rest of the interrupts which we needed to have as wakeups for
* cpuidle.
*
* PM ops are not used since this needs to be done at the end, after all the
* other drivers are done with their suspend callbacks.
*/
void nmk_gpio_wakeups_suspend(void)
{
int i;
for (i = 0; i < NUM_BANKS; i++) {
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
if (!chip)
break;
clk_enable(chip->clk);
writel(chip->rwimsc & chip->real_wake,
chip->addr + NMK_GPIO_RWIMSC);
writel(chip->fwimsc & chip->real_wake,
chip->addr + NMK_GPIO_FWIMSC);
clk_disable(chip->clk);
}
}
void nmk_gpio_wakeups_resume(void)
{
int i;
for (i = 0; i < NUM_BANKS; i++) {
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
if (!chip)
break;
clk_enable(chip->clk);
writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
clk_disable(chip->clk);
}
}
/*
* Read the pull up/pull down status.
* A bit set in 'pull_up' means that pull up
* is selected if pull is enabled in PDIS register.
* Note: only pull up/down set via this driver can
* be detected due to HW limitations.
*/
void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
{
if (gpio_bank < NUM_BANKS) {
struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank];
if (!chip)
return;
*pull_up = chip->pull_up;
}
}
/*
* We will allocate memory for the state container using devm* allocators
* binding to the first device reaching this point, it doesn't matter if

View File

@ -53,7 +53,7 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
struct seq_file *s, const char *gname,
unsigned pin,
const struct pin_config_item *items,
int nitems)
int nitems, int *print_sep)
{
int i;
@ -75,8 +75,10 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
continue;
}
/* Space between multiple configs */
seq_puts(s, " ");
/* comma between multiple configs */
if (*print_sep)
seq_puts(s, ", ");
*print_sep = 1;
seq_puts(s, items[i].display);
/* Print unit if available */
if (items[i].has_arg) {
@ -105,19 +107,21 @@ void pinconf_generic_dump_pins(struct pinctrl_dev *pctldev, struct seq_file *s,
const char *gname, unsigned pin)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
int print_sep = 0;
if (!ops->is_generic)
return;
/* generic parameters */
pinconf_generic_dump_one(pctldev, s, gname, pin, conf_items,
ARRAY_SIZE(conf_items));
ARRAY_SIZE(conf_items), &print_sep);
/* driver-specific parameters */
if (pctldev->desc->num_custom_params &&
pctldev->desc->custom_conf_items)
pinconf_generic_dump_one(pctldev, s, gname, pin,
pctldev->desc->custom_conf_items,
pctldev->desc->num_custom_params);
pctldev->desc->num_custom_params,
&print_sep);
}
void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
@ -391,4 +395,12 @@ exit:
}
EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map);
void pinconf_generic_dt_free_map(struct pinctrl_dev *pctldev,
struct pinctrl_map *map,
unsigned num_maps)
{
pinctrl_utils_free_map(pctldev, map, num_maps);
}
EXPORT_SYMBOL_GPL(pinconf_generic_dt_free_map);
#endif

View File

@ -258,8 +258,7 @@ void pinconf_show_setting(struct seq_file *s,
case PIN_MAP_TYPE_CONFIGS_PIN:
desc = pin_desc_get(setting->pctldev,
setting->data.configs.group_or_pin);
seq_printf(s, "pin %s (%d)",
desc->name ? desc->name : "unnamed",
seq_printf(s, "pin %s (%d)", desc->name,
setting->data.configs.group_or_pin);
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
@ -311,8 +310,7 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
if (desc == NULL)
continue;
seq_printf(s, "pin %d (%s):", pin,
desc->name ? desc->name : "unnamed");
seq_printf(s, "pin %d (%s): ", pin, desc->name);
pinconf_dump_pin(pctldev, s, pin);
@ -349,7 +347,7 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
while (selector < ngroups) {
const char *gname = pctlops->get_group_name(pctldev, selector);
seq_printf(s, "%u (%s):", selector, gname);
seq_printf(s, "%u (%s): ", selector, gname);
pinconf_dump_group(pctldev, s, selector, gname);
seq_printf(s, "\n");

View File

@ -20,7 +20,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinconf.h>
@ -421,8 +421,8 @@ static int atmel_pctl_get_group_pins(struct pinctrl_dev *pctldev,
return 0;
}
struct atmel_group *atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev,
unsigned pin)
static struct atmel_group *
atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev, unsigned pin)
{
struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
int i;
@ -879,7 +879,6 @@ static const struct of_device_id atmel_pctrl_of_match[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, atmel_pctrl_of_match);
static int atmel_pinctrl_probe(struct platform_device *pdev)
{
@ -1074,28 +1073,13 @@ clk_prepare_enable_error:
return ret;
}
int atmel_pinctrl_remove(struct platform_device *pdev)
{
struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
irq_domain_remove(atmel_pioctrl->irq_domain);
clk_disable_unprepare(atmel_pioctrl->clk);
gpiochip_remove(atmel_pioctrl->gpio_chip);
return 0;
}
static struct platform_driver atmel_pinctrl_driver = {
.driver = {
.name = "pinctrl-at91-pio4",
.of_match_table = atmel_pctrl_of_match,
.pm = &atmel_pctrl_pm_ops,
.suppress_bind_attrs = true,
},
.probe = atmel_pinctrl_probe,
.remove = atmel_pinctrl_remove,
};
module_platform_driver(atmel_pinctrl_driver);
MODULE_AUTHOR(Ludovic Desroches <ludovic.desroches@atmel.com>);
MODULE_DESCRIPTION("Atmel PIO4 pinctrl driver");
MODULE_LICENSE("GPL v2");
builtin_platform_driver(atmel_pinctrl_driver);

View File

@ -9,7 +9,6 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
@ -189,7 +188,7 @@ struct at91_pinctrl {
struct at91_pinctrl_mux_ops *ops;
};
static const inline struct at91_pin_group *at91_pinctrl_find_group_by_name(
static inline const struct at91_pin_group *at91_pinctrl_find_group_by_name(
const struct at91_pinctrl *info,
const char *name)
{
@ -1818,13 +1817,3 @@ static int __init at91_pinctrl_init(void)
return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
}
arch_initcall(at91_pinctrl_init);
static void __exit at91_pinctrl_exit(void)
{
platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
}
module_exit(at91_pinctrl_exit);
MODULE_AUTHOR("Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>");
MODULE_DESCRIPTION("Atmel AT91 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -15,7 +15,7 @@
* - Pin pad configuration (pull up/down, strength)
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
@ -335,27 +335,17 @@ static int dc_pinctrl_probe(struct platform_device *pdev)
return dc_gpiochip_add(pmap, pdev->dev.of_node);
}
static int dc_pinctrl_remove(struct platform_device *pdev)
{
struct dc_pinmap *pmap = platform_get_drvdata(pdev);
gpiochip_remove(&pmap->chip);
return 0;
}
static const struct of_device_id dc_pinctrl_ids[] = {
{ .compatible = "cnxt,cx92755-pinctrl" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_pinctrl_ids);
static struct platform_driver dc_pinctrl_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = dc_pinctrl_ids,
.suppress_bind_attrs = true,
},
.probe = dc_pinctrl_probe,
.remove = dc_pinctrl_remove,
};
module_platform_driver(dc_pinctrl_driver);
builtin_platform_driver(dc_pinctrl_driver);

View File

@ -11,7 +11,7 @@
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -1365,31 +1365,17 @@ static int lpc18xx_scu_probe(struct platform_device *pdev)
return 0;
}
static int lpc18xx_scu_remove(struct platform_device *pdev)
{
struct lpc18xx_scu_data *scu = platform_get_drvdata(pdev);
clk_disable_unprepare(scu->clk);
return 0;
}
static const struct of_device_id lpc18xx_scu_match[] = {
{ .compatible = "nxp,lpc1850-scu" },
{},
};
MODULE_DEVICE_TABLE(of, lpc18xx_scu_match);
static struct platform_driver lpc18xx_scu_driver = {
.probe = lpc18xx_scu_probe,
.remove = lpc18xx_scu_remove,
.driver = {
.name = "lpc18xx-scu",
.of_match_table = lpc18xx_scu_match,
.suppress_bind_attrs = true,
},
};
module_platform_driver(lpc18xx_scu_driver);
MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
MODULE_DESCRIPTION("Pinctrl driver for NXP LPC18xx/43xx SCU");
MODULE_LICENSE("GPL v2");
builtin_platform_driver(lpc18xx_scu_driver);

View File

@ -0,0 +1,673 @@
/*
* MAX77620 pin control driver.
*
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
*
* Author:
* Chaitanya Bandi <bandik@nvidia.com>
* Laxman Dewangan <ldewangan@nvidia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*/
#include <linux/mfd/max77620.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include "core.h"
#include "pinconf.h"
#include "pinctrl-utils.h"
#define MAX77620_PIN_NUM 8
enum max77620_pin_ppdrv {
MAX77620_PIN_UNCONFIG_DRV,
MAX77620_PIN_OD_DRV,
MAX77620_PIN_PP_DRV,
};
enum max77620_pinconf_param {
MAX77620_ACTIVE_FPS_SOURCE = PIN_CONFIG_END + 1,
MAX77620_ACTIVE_FPS_POWER_ON_SLOTS,
MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS,
MAX77620_SUSPEND_FPS_SOURCE,
MAX77620_SUSPEND_FPS_POWER_ON_SLOTS,
MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS,
};
struct max77620_pin_function {
const char *name;
const char * const *groups;
unsigned int ngroups;
int mux_option;
};
static const struct pinconf_generic_params max77620_cfg_params[] = {
{
.property = "maxim,active-fps-source",
.param = MAX77620_ACTIVE_FPS_SOURCE,
}, {
.property = "maxim,active-fps-power-up-slot",
.param = MAX77620_ACTIVE_FPS_POWER_ON_SLOTS,
}, {
.property = "maxim,active-fps-power-down-slot",
.param = MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS,
}, {
.property = "maxim,suspend-fps-source",
.param = MAX77620_SUSPEND_FPS_SOURCE,
}, {
.property = "maxim,suspend-fps-power-up-slot",
.param = MAX77620_SUSPEND_FPS_POWER_ON_SLOTS,
}, {
.property = "maxim,suspend-fps-power-down-slot",
.param = MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS,
},
};
enum max77620_alternate_pinmux_option {
MAX77620_PINMUX_GPIO = 0,
MAX77620_PINMUX_LOW_POWER_MODE_CONTROL_IN = 1,
MAX77620_PINMUX_FLEXIBLE_POWER_SEQUENCER_OUT = 2,
MAX77620_PINMUX_32K_OUT1 = 3,
MAX77620_PINMUX_SD0_DYNAMIC_VOLTAGE_SCALING_IN = 4,
MAX77620_PINMUX_SD1_DYNAMIC_VOLTAGE_SCALING_IN = 5,
MAX77620_PINMUX_REFERENCE_OUT = 6,
};
struct max77620_pingroup {
const char *name;
const unsigned int pins[1];
unsigned int npins;
enum max77620_alternate_pinmux_option alt_option;
};
struct max77620_pin_info {
enum max77620_pin_ppdrv drv_type;
int pull_config;
};
struct max77620_fps_config {
int active_fps_src;
int active_power_up_slots;
int active_power_down_slots;
int suspend_fps_src;
int suspend_power_up_slots;
int suspend_power_down_slots;
};
struct max77620_pctrl_info {
struct device *dev;
struct pinctrl_dev *pctl;
struct regmap *rmap;
int pins_current_opt[MAX77620_GPIO_NR];
const struct max77620_pin_function *functions;
unsigned int num_functions;
const struct max77620_pingroup *pin_groups;
int num_pin_groups;
const struct pinctrl_pin_desc *pins;
unsigned int num_pins;
struct max77620_pin_info pin_info[MAX77620_PIN_NUM];
struct max77620_fps_config fps_config[MAX77620_PIN_NUM];
};
static const struct pinctrl_pin_desc max77620_pins_desc[] = {
PINCTRL_PIN(MAX77620_GPIO0, "gpio0"),
PINCTRL_PIN(MAX77620_GPIO1, "gpio1"),
PINCTRL_PIN(MAX77620_GPIO2, "gpio2"),
PINCTRL_PIN(MAX77620_GPIO3, "gpio3"),
PINCTRL_PIN(MAX77620_GPIO4, "gpio4"),
PINCTRL_PIN(MAX77620_GPIO5, "gpio5"),
PINCTRL_PIN(MAX77620_GPIO6, "gpio6"),
PINCTRL_PIN(MAX77620_GPIO7, "gpio7"),
};
static const char * const gpio_groups[] = {
"gpio0",
"gpio1",
"gpio2",
"gpio3",
"gpio4",
"gpio5",
"gpio6",
"gpio7",
};
#define FUNCTION_GROUP(fname, mux) \
{ \
.name = fname, \
.groups = gpio_groups, \
.ngroups = ARRAY_SIZE(gpio_groups), \
.mux_option = MAX77620_PINMUX_##mux, \
}
static const struct max77620_pin_function max77620_pin_function[] = {
FUNCTION_GROUP("gpio", GPIO),
FUNCTION_GROUP("lpm-control-in", LOW_POWER_MODE_CONTROL_IN),
FUNCTION_GROUP("fps-out", FLEXIBLE_POWER_SEQUENCER_OUT),
FUNCTION_GROUP("32k-out1", 32K_OUT1),
FUNCTION_GROUP("sd0-dvs-in", SD0_DYNAMIC_VOLTAGE_SCALING_IN),
FUNCTION_GROUP("sd1-dvs-in", SD1_DYNAMIC_VOLTAGE_SCALING_IN),
FUNCTION_GROUP("reference-out", REFERENCE_OUT),
};
#define MAX77620_PINGROUP(pg_name, pin_id, option) \
{ \
.name = #pg_name, \
.pins = {MAX77620_##pin_id}, \
.npins = 1, \
.alt_option = MAX77620_PINMUX_##option, \
}
static const struct max77620_pingroup max77620_pingroups[] = {
MAX77620_PINGROUP(gpio0, GPIO0, LOW_POWER_MODE_CONTROL_IN),
MAX77620_PINGROUP(gpio1, GPIO1, FLEXIBLE_POWER_SEQUENCER_OUT),
MAX77620_PINGROUP(gpio2, GPIO2, FLEXIBLE_POWER_SEQUENCER_OUT),
MAX77620_PINGROUP(gpio3, GPIO3, FLEXIBLE_POWER_SEQUENCER_OUT),
MAX77620_PINGROUP(gpio4, GPIO4, 32K_OUT1),
MAX77620_PINGROUP(gpio5, GPIO5, SD0_DYNAMIC_VOLTAGE_SCALING_IN),
MAX77620_PINGROUP(gpio6, GPIO6, SD1_DYNAMIC_VOLTAGE_SCALING_IN),
MAX77620_PINGROUP(gpio7, GPIO7, REFERENCE_OUT),
};
static int max77620_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
{
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
return mpci->num_pin_groups;
}
static const char *max77620_pinctrl_get_group_name(
struct pinctrl_dev *pctldev, unsigned int group)
{
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
return mpci->pin_groups[group].name;
}
static int max77620_pinctrl_get_group_pins(
struct pinctrl_dev *pctldev, unsigned int group,
const unsigned int **pins, unsigned int *num_pins)
{
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
*pins = mpci->pin_groups[group].pins;
*num_pins = mpci->pin_groups[group].npins;
return 0;
}
static const struct pinctrl_ops max77620_pinctrl_ops = {
.get_groups_count = max77620_pinctrl_get_groups_count,
.get_group_name = max77620_pinctrl_get_group_name,
.get_group_pins = max77620_pinctrl_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
.dt_free_map = pinctrl_utils_free_map,
};
static int max77620_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
{
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
return mpci->num_functions;
}
static const char *max77620_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
unsigned int function)
{
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
return mpci->functions[function].name;
}
static int max77620_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
unsigned int function,
const char * const **groups,
unsigned int * const num_groups)
{
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
*groups = mpci->functions[function].groups;
*num_groups = mpci->functions[function].ngroups;
return 0;
}
static int max77620_pinctrl_enable(struct pinctrl_dev *pctldev,
unsigned int function, unsigned int group)
{
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
u8 val;
int ret;
if (function == MAX77620_PINMUX_GPIO) {
val = 0;
} else if (function == mpci->pin_groups[group].alt_option) {
val = 1 << group;
} else {
dev_err(mpci->dev, "GPIO %u doesn't have function %u\n",
group, function);
return -EINVAL;
}
ret = regmap_update_bits(mpci->rmap, MAX77620_REG_AME_GPIO,
BIT(group), val);
if (ret < 0)
dev_err(mpci->dev, "REG AME GPIO update failed: %d\n", ret);
return ret;
}
static const struct pinmux_ops max77620_pinmux_ops = {
.get_functions_count = max77620_pinctrl_get_funcs_count,
.get_function_name = max77620_pinctrl_get_func_name,
.get_function_groups = max77620_pinctrl_get_func_groups,
.set_mux = max77620_pinctrl_enable,
};
static int max77620_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *config)
{
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
struct device *dev = mpci->dev;
enum pin_config_param param = pinconf_to_config_param(*config);
unsigned int val;
int arg = 0;
int ret;
switch (param) {
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
if (mpci->pin_info[pin].drv_type == MAX77620_PIN_OD_DRV)
arg = 1;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
if (mpci->pin_info[pin].drv_type == MAX77620_PIN_PP_DRV)
arg = 1;
break;
case PIN_CONFIG_BIAS_PULL_UP:
ret = regmap_read(mpci->rmap, MAX77620_REG_PUE_GPIO, &val);
if (ret < 0) {
dev_err(dev, "Reg PUE_GPIO read failed: %d\n", ret);
return ret;
}
if (val & BIT(pin))
arg = 1;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
ret = regmap_read(mpci->rmap, MAX77620_REG_PDE_GPIO, &val);
if (ret < 0) {
dev_err(dev, "Reg PDE_GPIO read failed: %d\n", ret);
return ret;
}
if (val & BIT(pin))
arg = 1;
break;
default:
dev_err(dev, "Properties not supported\n");
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, (u16)arg);
return 0;
}
static int max77620_get_default_fps(struct max77620_pctrl_info *mpci,
int addr, int *fps)
{
unsigned int val;
int ret;
ret = regmap_read(mpci->rmap, addr, &val);
if (ret < 0) {
dev_err(mpci->dev, "Reg PUE_GPIO read failed: %d\n", ret);
return ret;
}
*fps = (val & MAX77620_FPS_SRC_MASK) >> MAX77620_FPS_SRC_SHIFT;
return 0;
}
static int max77620_set_fps_param(struct max77620_pctrl_info *mpci,
int pin, int param)
{
struct max77620_fps_config *fps_config = &mpci->fps_config[pin];
int addr, ret;
int param_val;
int mask, shift;
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
return 0;
addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
switch (param) {
case MAX77620_ACTIVE_FPS_SOURCE:
case MAX77620_SUSPEND_FPS_SOURCE:
mask = MAX77620_FPS_SRC_MASK;
shift = MAX77620_FPS_SRC_SHIFT;
param_val = fps_config->active_fps_src;
if (param == MAX77620_SUSPEND_FPS_SOURCE)
param_val = fps_config->suspend_fps_src;
break;
case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS:
case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS:
mask = MAX77620_FPS_PU_PERIOD_MASK;
shift = MAX77620_FPS_PU_PERIOD_SHIFT;
param_val = fps_config->active_power_up_slots;
if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS)
param_val = fps_config->suspend_power_up_slots;
break;
case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS:
case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS:
mask = MAX77620_FPS_PD_PERIOD_MASK;
shift = MAX77620_FPS_PD_PERIOD_SHIFT;
param_val = fps_config->active_power_down_slots;
if (param == MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS)
param_val = fps_config->suspend_power_down_slots;
break;
default:
dev_err(mpci->dev, "Invalid parameter %d for pin %d\n",
param, pin);
return -EINVAL;
}
if (param_val < 0)
return 0;
ret = regmap_update_bits(mpci->rmap, addr, mask, param_val << shift);
if (ret < 0)
dev_err(mpci->dev, "Reg 0x%02x update failed %d\n", addr, ret);
return ret;
}
static int max77620_pinconf_set(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *configs,
unsigned int num_configs)
{
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
struct device *dev = mpci->dev;
struct max77620_fps_config *fps_config;
int param;
u16 param_val;
unsigned int val;
unsigned int pu_val;
unsigned int pd_val;
int addr, ret;
int i;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
param_val = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
val = param_val ? 0 : 1;
ret = regmap_update_bits(mpci->rmap,
MAX77620_REG_GPIO0 + pin,
MAX77620_CNFG_GPIO_DRV_MASK,
val);
if (ret < 0) {
dev_err(dev, "Reg 0x%02x update failed %d\n",
MAX77620_REG_GPIO0 + pin, ret);
return ret;
}
mpci->pin_info[pin].drv_type = val ?
MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
val = param_val ? 1 : 0;
ret = regmap_update_bits(mpci->rmap,
MAX77620_REG_GPIO0 + pin,
MAX77620_CNFG_GPIO_DRV_MASK,
val);
if (ret < 0) {
dev_err(dev, "Reg 0x%02x update failed %d\n",
MAX77620_REG_GPIO0 + pin, ret);
return ret;
}
mpci->pin_info[pin].drv_type = val ?
MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
break;
case MAX77620_ACTIVE_FPS_SOURCE:
case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS:
case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS:
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
return -EINVAL;
fps_config = &mpci->fps_config[pin];
if ((param == MAX77620_ACTIVE_FPS_SOURCE) &&
(param_val == MAX77620_FPS_SRC_DEF)) {
addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
ret = max77620_get_default_fps(
mpci, addr,
&fps_config->active_fps_src);
if (ret < 0)
return ret;
break;
}
if (param == MAX77620_ACTIVE_FPS_SOURCE)
fps_config->active_fps_src = param_val;
else if (param == MAX77620_ACTIVE_FPS_POWER_ON_SLOTS)
fps_config->active_power_up_slots = param_val;
else
fps_config->active_power_down_slots = param_val;
ret = max77620_set_fps_param(mpci, pin, param);
if (ret < 0)
return ret;
break;
case MAX77620_SUSPEND_FPS_SOURCE:
case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS:
case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS:
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
return -EINVAL;
fps_config = &mpci->fps_config[pin];
if ((param == MAX77620_SUSPEND_FPS_SOURCE) &&
(param_val == MAX77620_FPS_SRC_DEF)) {
addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
ret = max77620_get_default_fps(
mpci, addr,
&fps_config->suspend_fps_src);
if (ret < 0)
return ret;
break;
}
if (param == MAX77620_SUSPEND_FPS_SOURCE)
fps_config->suspend_fps_src = param_val;
else if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS)
fps_config->suspend_power_up_slots = param_val;
else
fps_config->suspend_power_down_slots =
param_val;
break;
case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN:
pu_val = (param == PIN_CONFIG_BIAS_PULL_UP) ?
BIT(pin) : 0;
pd_val = (param == PIN_CONFIG_BIAS_PULL_DOWN) ?
BIT(pin) : 0;
ret = regmap_update_bits(mpci->rmap,
MAX77620_REG_PUE_GPIO,
BIT(pin), pu_val);
if (ret < 0) {
dev_err(dev, "PUE_GPIO update failed: %d\n",
ret);
return ret;
}
ret = regmap_update_bits(mpci->rmap,
MAX77620_REG_PDE_GPIO,
BIT(pin), pd_val);
if (ret < 0) {
dev_err(dev, "PDE_GPIO update failed: %d\n",
ret);
return ret;
}
break;
default:
dev_err(dev, "Properties not supported\n");
return -ENOTSUPP;
}
}
return 0;
}
static const struct pinconf_ops max77620_pinconf_ops = {
.pin_config_get = max77620_pinconf_get,
.pin_config_set = max77620_pinconf_set,
};
static struct pinctrl_desc max77620_pinctrl_desc = {
.pctlops = &max77620_pinctrl_ops,
.pmxops = &max77620_pinmux_ops,
.confops = &max77620_pinconf_ops,
};
static int max77620_pinctrl_probe(struct platform_device *pdev)
{
struct max77620_chip *max77620 = dev_get_drvdata(pdev->dev.parent);
struct max77620_pctrl_info *mpci;
int i;
mpci = devm_kzalloc(&pdev->dev, sizeof(*mpci), GFP_KERNEL);
if (!mpci)
return -ENOMEM;
mpci->dev = &pdev->dev;
mpci->dev->of_node = pdev->dev.parent->of_node;
mpci->rmap = max77620->rmap;
mpci->pins = max77620_pins_desc;
mpci->num_pins = ARRAY_SIZE(max77620_pins_desc);
mpci->functions = max77620_pin_function;
mpci->num_functions = ARRAY_SIZE(max77620_pin_function);
mpci->pin_groups = max77620_pingroups;
mpci->num_pin_groups = ARRAY_SIZE(max77620_pingroups);
platform_set_drvdata(pdev, mpci);
max77620_pinctrl_desc.name = dev_name(&pdev->dev);
max77620_pinctrl_desc.pins = max77620_pins_desc;
max77620_pinctrl_desc.npins = ARRAY_SIZE(max77620_pins_desc);
max77620_pinctrl_desc.num_custom_params =
ARRAY_SIZE(max77620_cfg_params);
max77620_pinctrl_desc.custom_params = max77620_cfg_params;
for (i = 0; i < MAX77620_PIN_NUM; ++i) {
mpci->fps_config[i].active_fps_src = -1;
mpci->fps_config[i].active_power_up_slots = -1;
mpci->fps_config[i].active_power_down_slots = -1;
mpci->fps_config[i].suspend_fps_src = -1;
mpci->fps_config[i].suspend_power_up_slots = -1;
mpci->fps_config[i].suspend_power_down_slots = -1;
}
mpci->pctl = devm_pinctrl_register(&pdev->dev, &max77620_pinctrl_desc,
mpci);
if (IS_ERR(mpci->pctl)) {
dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
return PTR_ERR(mpci->pctl);
}
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int max77620_suspend_fps_param[] = {
MAX77620_SUSPEND_FPS_SOURCE,
MAX77620_SUSPEND_FPS_POWER_ON_SLOTS,
MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS,
};
static int max77620_active_fps_param[] = {
MAX77620_ACTIVE_FPS_SOURCE,
MAX77620_ACTIVE_FPS_POWER_ON_SLOTS,
MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS,
};
static int max77620_pinctrl_suspend(struct device *dev)
{
struct max77620_pctrl_info *mpci = dev_get_drvdata(dev);
int pin, p;
for (pin = 0; pin < MAX77620_PIN_NUM; ++pin) {
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
continue;
for (p = 0; p < 3; ++p)
max77620_set_fps_param(
mpci, pin, max77620_suspend_fps_param[p]);
}
return 0;
};
static int max77620_pinctrl_resume(struct device *dev)
{
struct max77620_pctrl_info *mpci = dev_get_drvdata(dev);
int pin, p;
for (pin = 0; pin < MAX77620_PIN_NUM; ++pin) {
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
continue;
for (p = 0; p < 3; ++p)
max77620_set_fps_param(
mpci, pin, max77620_active_fps_param[p]);
}
return 0;
}
#endif
static const struct dev_pm_ops max77620_pinctrl_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(
max77620_pinctrl_suspend, max77620_pinctrl_resume)
};
static const struct platform_device_id max77620_pinctrl_devtype[] = {
{ .name = "max77620-pinctrl", },
{ .name = "max20024-pinctrl", },
{},
};
MODULE_DEVICE_TABLE(platform, max77620_pinctrl_devtype);
static struct platform_driver max77620_pinctrl_driver = {
.driver = {
.name = "max77620-pinctrl",
.pm = &max77620_pinctrl_pm_ops,
},
.probe = max77620_pinctrl_probe,
.id_table = max77620_pinctrl_devtype,
};
module_platform_driver(max77620_pinctrl_driver);
MODULE_DESCRIPTION("MAX77620/MAX20024 pin control driver");
MODULE_AUTHOR("Chaitanya Bandi<bandik@nvidia.com>");
MODULE_AUTHOR("Laxman Dewangan<ldewangan@nvidia.com>");
MODULE_ALIAS("platform:max77620-pinctrl");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,846 @@
/*
* Oxford Semiconductor OXNAS SoC Family pinctrl driver
*
* Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
*
* Based on pinctrl-pic32.c
* Joshua Henderson, <joshua.henderson@microchip.com>
* Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include "pinctrl-utils.h"
#define PINS_PER_BANK 32
#define GPIO_BANK_START(bank) ((bank) * PINS_PER_BANK)
/* Regmap Offsets */
#define PINMUX_PRIMARY_SEL0 0x0c
#define PINMUX_SECONDARY_SEL0 0x14
#define PINMUX_TERTIARY_SEL0 0x8c
#define PINMUX_PRIMARY_SEL1 0x10
#define PINMUX_SECONDARY_SEL1 0x18
#define PINMUX_TERTIARY_SEL1 0x90
#define PINMUX_PULLUP_CTRL0 0xac
#define PINMUX_PULLUP_CTRL1 0xb0
/* GPIO Registers */
#define INPUT_VALUE 0x00
#define OUTPUT_EN 0x04
#define IRQ_PENDING 0x0c
#define OUTPUT_SET 0x14
#define OUTPUT_CLEAR 0x18
#define OUTPUT_EN_SET 0x1c
#define OUTPUT_EN_CLEAR 0x20
#define RE_IRQ_ENABLE 0x28
#define FE_IRQ_ENABLE 0x2c
struct oxnas_function {
const char *name;
const char * const *groups;
unsigned int ngroups;
};
struct oxnas_pin_group {
const char *name;
unsigned int pin;
unsigned int bank;
struct oxnas_desc_function *functions;
};
struct oxnas_desc_function {
const char *name;
unsigned int fct;
};
struct oxnas_gpio_bank {
void __iomem *reg_base;
struct gpio_chip gpio_chip;
struct irq_chip irq_chip;
unsigned int id;
};
struct oxnas_pinctrl {
struct regmap *regmap;
struct device *dev;
struct pinctrl_dev *pctldev;
const struct pinctrl_pin_desc *pins;
unsigned int npins;
const struct oxnas_function *functions;
unsigned int nfunctions;
const struct oxnas_pin_group *groups;
unsigned int ngroups;
struct oxnas_gpio_bank *gpio_banks;
unsigned int nbanks;
};
static const struct pinctrl_pin_desc oxnas_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, "gpio32"),
PINCTRL_PIN(33, "gpio33"),
PINCTRL_PIN(34, "gpio34"),
};
static const char * const oxnas_fct0_group[] = {
"gpio0", "gpio1", "gpio2", "gpio3",
"gpio4", "gpio5", "gpio6", "gpio7",
"gpio8", "gpio9", "gpio10", "gpio11",
"gpio12", "gpio13", "gpio14", "gpio15",
"gpio16", "gpio17", "gpio18", "gpio19",
"gpio20", "gpio21", "gpio22", "gpio23",
"gpio24", "gpio25", "gpio26", "gpio27",
"gpio28", "gpio29", "gpio30", "gpio31",
"gpio32", "gpio33", "gpio34"
};
static const char * const oxnas_fct3_group[] = {
"gpio0", "gpio1", "gpio2", "gpio3",
"gpio4", "gpio5", "gpio6", "gpio7",
"gpio8", "gpio9",
"gpio20",
"gpio22", "gpio23", "gpio24", "gpio25",
"gpio26", "gpio27", "gpio28", "gpio29",
"gpio30", "gpio31", "gpio32", "gpio33",
"gpio34"
};
#define FUNCTION(_name, _gr) \
{ \
.name = #_name, \
.groups = oxnas_##_gr##_group, \
.ngroups = ARRAY_SIZE(oxnas_##_gr##_group), \
}
static const struct oxnas_function oxnas_functions[] = {
FUNCTION(gpio, fct0),
FUNCTION(fct3, fct3),
};
#define OXNAS_PINCTRL_GROUP(_pin, _name, ...) \
{ \
.name = #_name, \
.pin = _pin, \
.bank = _pin / PINS_PER_BANK, \
.functions = (struct oxnas_desc_function[]){ \
__VA_ARGS__, { } }, \
}
#define OXNAS_PINCTRL_FUNCTION(_name, _fct) \
{ \
.name = #_name, \
.fct = _fct, \
}
static const struct oxnas_pin_group oxnas_groups[] = {
OXNAS_PINCTRL_GROUP(0, gpio0,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(1, gpio1,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(2, gpio2,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(3, gpio3,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(4, gpio4,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(5, gpio5,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(6, gpio6,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(7, gpio7,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(8, gpio8,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(9, gpio9,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(10, gpio10,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(11, gpio11,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(12, gpio12,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(13, gpio13,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(14, gpio14,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(15, gpio15,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(16, gpio16,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(17, gpio17,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(18, gpio18,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(19, gpio19,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(20, gpio20,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(21, gpio21,
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
OXNAS_PINCTRL_GROUP(22, gpio22,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(23, gpio23,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(24, gpio24,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(25, gpio25,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(26, gpio26,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(27, gpio27,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(28, gpio28,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(29, gpio29,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(30, gpio30,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(31, gpio31,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(32, gpio32,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(33, gpio33,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
OXNAS_PINCTRL_GROUP(34, gpio34,
OXNAS_PINCTRL_FUNCTION(gpio, 0),
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
};
static inline struct oxnas_gpio_bank *pctl_to_bank(struct oxnas_pinctrl *pctl,
unsigned int pin)
{
return &pctl->gpio_banks[pin / PINS_PER_BANK];
}
static int oxnas_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
return pctl->ngroups;
}
static const char *oxnas_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned int group)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
return pctl->groups[group].name;
}
static int oxnas_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int group,
const unsigned int **pins,
unsigned int *num_pins)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
*pins = &pctl->groups[group].pin;
*num_pins = 1;
return 0;
}
static const struct pinctrl_ops oxnas_pinctrl_ops = {
.get_groups_count = oxnas_pinctrl_get_groups_count,
.get_group_name = oxnas_pinctrl_get_group_name,
.get_group_pins = oxnas_pinctrl_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
.dt_free_map = pinctrl_utils_free_map,
};
static int oxnas_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
return pctl->nfunctions;
}
static const char *
oxnas_pinmux_get_function_name(struct pinctrl_dev *pctldev, unsigned int func)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
return pctl->functions[func].name;
}
static int oxnas_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
unsigned int func,
const char * const **groups,
unsigned int * const num_groups)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
*groups = pctl->functions[func].groups;
*num_groups = pctl->functions[func].ngroups;
return 0;
}
static int oxnas_pinmux_enable(struct pinctrl_dev *pctldev,
unsigned int func, unsigned int group)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
const struct oxnas_pin_group *pg = &pctl->groups[group];
const struct oxnas_function *pf = &pctl->functions[func];
const char *fname = pf->name;
struct oxnas_desc_function *functions = pg->functions;
u32 mask = BIT(pg->pin);
while (functions->name) {
if (!strcmp(functions->name, fname)) {
dev_dbg(pctl->dev,
"setting function %s bank %d pin %d fct %d mask %x\n",
fname, pg->bank, pg->pin,
functions->fct, mask);
regmap_write_bits(pctl->regmap,
(pg->bank ?
PINMUX_PRIMARY_SEL1 :
PINMUX_PRIMARY_SEL0),
mask,
(functions->fct == 1 ?
mask : 0));
regmap_write_bits(pctl->regmap,
(pg->bank ?
PINMUX_SECONDARY_SEL1 :
PINMUX_SECONDARY_SEL0),
mask,
(functions->fct == 2 ?
mask : 0));
regmap_write_bits(pctl->regmap,
(pg->bank ?
PINMUX_TERTIARY_SEL1 :
PINMUX_TERTIARY_SEL0),
mask,
(functions->fct == 3 ?
mask : 0));
return 0;
}
functions++;
}
dev_err(pctl->dev, "cannot mux pin %u to function %u\n", group, func);
return -EINVAL;
}
static int oxnas_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct oxnas_gpio_bank *bank = gpiochip_get_data(range->gc);
u32 mask = BIT(offset - bank->gpio_chip.base);
dev_dbg(pctl->dev, "requesting gpio %d in bank %d (id %d) with mask 0x%x\n",
offset, bank->gpio_chip.base, bank->id, mask);
regmap_write_bits(pctl->regmap,
(bank->id ?
PINMUX_PRIMARY_SEL1 :
PINMUX_PRIMARY_SEL0),
mask, 0);
regmap_write_bits(pctl->regmap,
(bank->id ?
PINMUX_SECONDARY_SEL1 :
PINMUX_SECONDARY_SEL0),
mask, 0);
regmap_write_bits(pctl->regmap,
(bank->id ?
PINMUX_TERTIARY_SEL1 :
PINMUX_TERTIARY_SEL0),
mask, 0);
return 0;
}
static int oxnas_gpio_get_direction(struct gpio_chip *chip,
unsigned int offset)
{
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
u32 mask = BIT(offset);
return !(readl_relaxed(bank->reg_base + OUTPUT_EN) & mask);
}
static int oxnas_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
u32 mask = BIT(offset);
writel_relaxed(mask, bank->reg_base + OUTPUT_EN_CLEAR);
return 0;
}
static int oxnas_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
u32 mask = BIT(offset);
return (readl_relaxed(bank->reg_base + INPUT_VALUE) & mask) != 0;
}
static void oxnas_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
u32 mask = BIT(offset);
if (value)
writel_relaxed(mask, bank->reg_base + OUTPUT_SET);
else
writel_relaxed(mask, bank->reg_base + OUTPUT_CLEAR);
}
static int oxnas_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value)
{
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
u32 mask = BIT(offset);
oxnas_gpio_set(chip, offset, value);
writel_relaxed(mask, bank->reg_base + OUTPUT_EN_SET);
return 0;
}
static int oxnas_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset, bool input)
{
struct gpio_chip *chip = range->gc;
if (input)
oxnas_gpio_direction_input(chip, offset);
else
oxnas_gpio_direction_output(chip, offset, 0);
return 0;
}
static const struct pinmux_ops oxnas_pinmux_ops = {
.get_functions_count = oxnas_pinmux_get_functions_count,
.get_function_name = oxnas_pinmux_get_function_name,
.get_function_groups = oxnas_pinmux_get_function_groups,
.set_mux = oxnas_pinmux_enable,
.gpio_request_enable = oxnas_gpio_request_enable,
.gpio_set_direction = oxnas_gpio_set_direction,
};
static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
unsigned int param = pinconf_to_config_param(*config);
u32 mask = BIT(pin - bank->gpio_chip.base);
int ret;
u32 arg;
switch (param) {
case PIN_CONFIG_BIAS_PULL_UP:
ret = regmap_read(pctl->regmap,
(bank->id ?
PINMUX_PULLUP_CTRL1 :
PINMUX_PULLUP_CTRL0),
&arg);
if (ret)
return ret;
arg = !!(arg & mask);
break;
default:
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
unsigned int param;
u32 arg;
unsigned int i;
u32 offset = pin - bank->gpio_chip.base;
u32 mask = BIT(offset);
dev_dbg(pctl->dev, "setting pin %d bank %d mask 0x%x\n",
pin, bank->gpio_chip.base, mask);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_PULL_UP:
dev_dbg(pctl->dev, " pullup\n");
regmap_write_bits(pctl->regmap,
(bank->id ?
PINMUX_PULLUP_CTRL1 :
PINMUX_PULLUP_CTRL0),
mask, mask);
break;
default:
dev_err(pctl->dev, "Property %u not supported\n",
param);
return -ENOTSUPP;
}
}
return 0;
}
static const struct pinconf_ops oxnas_pinconf_ops = {
.pin_config_get = oxnas_pinconf_get,
.pin_config_set = oxnas_pinconf_set,
.is_generic = true,
};
static struct pinctrl_desc oxnas_pinctrl_desc = {
.name = "oxnas-pinctrl",
.pctlops = &oxnas_pinctrl_ops,
.pmxops = &oxnas_pinmux_ops,
.confops = &oxnas_pinconf_ops,
.owner = THIS_MODULE,
};
static void oxnas_gpio_irq_ack(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
u32 mask = BIT(data->hwirq);
writel(mask, bank->reg_base + IRQ_PENDING);
}
static void oxnas_gpio_irq_mask(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
unsigned int type = irqd_get_trigger_type(data);
u32 mask = BIT(data->hwirq);
if (type & IRQ_TYPE_EDGE_RISING)
writel(readl(bank->reg_base + RE_IRQ_ENABLE) & ~mask,
bank->reg_base + RE_IRQ_ENABLE);
if (type & IRQ_TYPE_EDGE_FALLING)
writel(readl(bank->reg_base + FE_IRQ_ENABLE) & ~mask,
bank->reg_base + FE_IRQ_ENABLE);
}
static void oxnas_gpio_irq_unmask(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
unsigned int type = irqd_get_trigger_type(data);
u32 mask = BIT(data->hwirq);
if (type & IRQ_TYPE_EDGE_RISING)
writel(readl(bank->reg_base + RE_IRQ_ENABLE) | mask,
bank->reg_base + RE_IRQ_ENABLE);
if (type & IRQ_TYPE_EDGE_FALLING)
writel(readl(bank->reg_base + FE_IRQ_ENABLE) | mask,
bank->reg_base + FE_IRQ_ENABLE);
}
static unsigned int oxnas_gpio_irq_startup(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
oxnas_gpio_direction_input(chip, data->hwirq);
oxnas_gpio_irq_unmask(data);
return 0;
}
static int oxnas_gpio_irq_set_type(struct irq_data *data, unsigned int type)
{
if ((type & (IRQ_TYPE_EDGE_RISING|IRQ_TYPE_EDGE_FALLING)) == 0)
return -EINVAL;
irq_set_handler_locked(data, handle_edge_irq);
return 0;
}
static void oxnas_gpio_irq_handler(struct irq_desc *desc)
{
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct oxnas_gpio_bank *bank = gpiochip_get_data(gc);
struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned long stat;
unsigned int pin;
chained_irq_enter(chip, desc);
stat = readl(bank->reg_base + IRQ_PENDING);
for_each_set_bit(pin, &stat, BITS_PER_LONG)
generic_handle_irq(irq_linear_revmap(gc->irqdomain, pin));
chained_irq_exit(chip, desc);
}
#define GPIO_BANK(_bank) \
{ \
.gpio_chip = { \
.label = "GPIO" #_bank, \
.request = gpiochip_generic_request, \
.free = gpiochip_generic_free, \
.get_direction = oxnas_gpio_get_direction, \
.direction_input = oxnas_gpio_direction_input, \
.direction_output = oxnas_gpio_direction_output, \
.get = oxnas_gpio_get, \
.set = oxnas_gpio_set, \
.ngpio = PINS_PER_BANK, \
.base = GPIO_BANK_START(_bank), \
.owner = THIS_MODULE, \
.can_sleep = 0, \
}, \
.irq_chip = { \
.name = "GPIO" #_bank, \
.irq_startup = oxnas_gpio_irq_startup, \
.irq_ack = oxnas_gpio_irq_ack, \
.irq_mask = oxnas_gpio_irq_mask, \
.irq_unmask = oxnas_gpio_irq_unmask, \
.irq_set_type = oxnas_gpio_irq_set_type, \
}, \
}
static struct oxnas_gpio_bank oxnas_gpio_banks[] = {
GPIO_BANK(0),
GPIO_BANK(1),
};
static int oxnas_pinctrl_probe(struct platform_device *pdev)
{
struct oxnas_pinctrl *pctl;
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
if (!pctl)
return -ENOMEM;
pctl->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, pctl);
pctl->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
"oxsemi,sys-ctrl");
if (IS_ERR(pctl->regmap)) {
dev_err(&pdev->dev, "failed to get sys ctrl regmap\n");
return -ENODEV;
}
pctl->pins = oxnas_pins;
pctl->npins = ARRAY_SIZE(oxnas_pins);
pctl->functions = oxnas_functions;
pctl->nfunctions = ARRAY_SIZE(oxnas_functions);
pctl->groups = oxnas_groups;
pctl->ngroups = ARRAY_SIZE(oxnas_groups);
pctl->gpio_banks = oxnas_gpio_banks;
pctl->nbanks = ARRAY_SIZE(oxnas_gpio_banks);
oxnas_pinctrl_desc.pins = pctl->pins;
oxnas_pinctrl_desc.npins = pctl->npins;
pctl->pctldev = pinctrl_register(&oxnas_pinctrl_desc,
&pdev->dev, pctl);
if (IS_ERR(pctl->pctldev)) {
dev_err(&pdev->dev, "Failed to register pinctrl device\n");
return PTR_ERR(pctl->pctldev);
}
return 0;
}
static int oxnas_gpio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct of_phandle_args pinspec;
struct oxnas_gpio_bank *bank;
unsigned int id, ngpios;
int irq, ret;
struct resource *res;
if (of_parse_phandle_with_fixed_args(np, "gpio-ranges",
3, 0, &pinspec)) {
dev_err(&pdev->dev, "gpio-ranges property not found\n");
return -EINVAL;
}
id = pinspec.args[1] / PINS_PER_BANK;
ngpios = pinspec.args[2];
if (id >= ARRAY_SIZE(oxnas_gpio_banks)) {
dev_err(&pdev->dev, "invalid gpio-ranges base arg\n");
return -EINVAL;
}
if (ngpios > PINS_PER_BANK) {
dev_err(&pdev->dev, "invalid gpio-ranges count arg\n");
return -EINVAL;
}
bank = &oxnas_gpio_banks[id];
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bank->reg_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(bank->reg_base))
return PTR_ERR(bank->reg_base);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "irq get failed\n");
return irq;
}
bank->id = id;
bank->gpio_chip.parent = &pdev->dev;
bank->gpio_chip.of_node = np;
bank->gpio_chip.ngpio = ngpios;
ret = gpiochip_add_data(&bank->gpio_chip, bank);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to add GPIO chip %u: %d\n",
id, ret);
return ret;
}
ret = gpiochip_irqchip_add(&bank->gpio_chip, &bank->irq_chip,
0, handle_level_irq, IRQ_TYPE_NONE);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to add IRQ chip %u: %d\n",
id, ret);
gpiochip_remove(&bank->gpio_chip);
return ret;
}
gpiochip_set_chained_irqchip(&bank->gpio_chip, &bank->irq_chip,
irq, oxnas_gpio_irq_handler);
return 0;
}
static const struct of_device_id oxnas_pinctrl_of_match[] = {
{ .compatible = "oxsemi,ox810se-pinctrl", },
{ },
};
static struct platform_driver oxnas_pinctrl_driver = {
.driver = {
.name = "oxnas-pinctrl",
.of_match_table = oxnas_pinctrl_of_match,
.suppress_bind_attrs = true,
},
.probe = oxnas_pinctrl_probe,
};
static const struct of_device_id oxnas_gpio_of_match[] = {
{ .compatible = "oxsemi,ox810se-gpio", },
{ },
};
static struct platform_driver oxnas_gpio_driver = {
.driver = {
.name = "oxnas-gpio",
.of_match_table = oxnas_gpio_of_match,
.suppress_bind_attrs = true,
},
.probe = oxnas_gpio_probe,
};
static int __init oxnas_gpio_register(void)
{
return platform_driver_register(&oxnas_gpio_driver);
}
arch_initcall(oxnas_gpio_register);
static int __init oxnas_pinctrl_register(void)
{
return platform_driver_register(&oxnas_pinctrl_driver);
}
arch_initcall(oxnas_pinctrl_register);

View File

@ -360,7 +360,7 @@ static struct regmap_config rockchip_regmap_config = {
.reg_stride = 4,
};
static const inline struct rockchip_pin_group *pinctrl_name_to_group(
static inline const struct rockchip_pin_group *pinctrl_name_to_group(
const struct rockchip_pinctrl *info,
const char *name)
{
@ -2007,7 +2007,7 @@ static void rockchip_irq_gc_mask_clr_bit(struct irq_data *d)
irq_gc_mask_clr_bit(d);
}
void rockchip_irq_gc_mask_set_bit(struct irq_data *d)
static void rockchip_irq_gc_mask_set_bit(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct rockchip_pin_bank *bank = gc->private;

View File

@ -844,7 +844,7 @@ static int st_pctl_get_group_pins(struct pinctrl_dev *pctldev,
return 0;
}
static const inline struct st_pctl_group *st_pctl_find_group_by_name(
static inline const struct st_pctl_group *st_pctl_find_group_by_name(
const struct st_pinctrl *info, const char *name)
{
int i;

View File

@ -670,7 +670,7 @@ struct u300_pmx {
* u300_pmx_registers - the array of registers read/written for each pinmux
* shunt setting
*/
const u32 u300_pmx_registers[] = {
static const u32 u300_pmx_registers[] = {
U300_SYSCON_PMC1LR,
U300_SYSCON_PMC1HR,
U300_SYSCON_PMC2R,

View File

@ -1616,50 +1616,74 @@ struct pinctrl_xway_soc {
/* xway xr9 series (DEPRECATED: Use XWAY xRX100/xRX200 Family) */
static struct pinctrl_xway_soc xr9_pinctrl = {
XR9_MAX_PIN, xway_mfp,
xway_grps, ARRAY_SIZE(xway_grps),
xrx_funcs, ARRAY_SIZE(xrx_funcs),
xway_exin_pin_map, 6
.pin_count = XR9_MAX_PIN,
.mfp = xway_mfp,
.grps = xway_grps,
.num_grps = ARRAY_SIZE(xway_grps),
.funcs = xrx_funcs,
.num_funcs = ARRAY_SIZE(xrx_funcs),
.exin = xway_exin_pin_map,
.num_exin = 6
};
/* XWAY AMAZON Family */
static struct pinctrl_xway_soc ase_pinctrl = {
ASE_MAX_PIN, ase_mfp,
ase_grps, ARRAY_SIZE(ase_grps),
ase_funcs, ARRAY_SIZE(ase_funcs),
ase_exin_pin_map, 3
.pin_count = ASE_MAX_PIN,
.mfp = ase_mfp,
.grps = ase_grps,
.num_grps = ARRAY_SIZE(ase_grps),
.funcs = ase_funcs,
.num_funcs = ARRAY_SIZE(ase_funcs),
.exin = ase_exin_pin_map,
.num_exin = 3
};
/* XWAY DANUBE Family */
static struct pinctrl_xway_soc danube_pinctrl = {
DANUBE_MAX_PIN, danube_mfp,
danube_grps, ARRAY_SIZE(danube_grps),
danube_funcs, ARRAY_SIZE(danube_funcs),
danube_exin_pin_map, 3
.pin_count = DANUBE_MAX_PIN,
.mfp = danube_mfp,
.grps = danube_grps,
.num_grps = ARRAY_SIZE(danube_grps),
.funcs = danube_funcs,
.num_funcs = ARRAY_SIZE(danube_funcs),
.exin = danube_exin_pin_map,
.num_exin = 3
};
/* XWAY xRX100 Family */
static struct pinctrl_xway_soc xrx100_pinctrl = {
XRX100_MAX_PIN, xrx100_mfp,
xrx100_grps, ARRAY_SIZE(xrx100_grps),
xrx100_funcs, ARRAY_SIZE(xrx100_funcs),
xrx100_exin_pin_map, 6
.pin_count = XRX100_MAX_PIN,
.mfp = xrx100_mfp,
.grps = xrx100_grps,
.num_grps = ARRAY_SIZE(xrx100_grps),
.funcs = xrx100_funcs,
.num_funcs = ARRAY_SIZE(xrx100_funcs),
.exin = xrx100_exin_pin_map,
.num_exin = 6
};
/* XWAY xRX200 Family */
static struct pinctrl_xway_soc xrx200_pinctrl = {
XRX200_MAX_PIN, xrx200_mfp,
xrx200_grps, ARRAY_SIZE(xrx200_grps),
xrx200_funcs, ARRAY_SIZE(xrx200_funcs),
xrx200_exin_pin_map, 6
.pin_count = XRX200_MAX_PIN,
.mfp = xrx200_mfp,
.grps = xrx200_grps,
.num_grps = ARRAY_SIZE(xrx200_grps),
.funcs = xrx200_funcs,
.num_funcs = ARRAY_SIZE(xrx200_funcs),
.exin = xrx200_exin_pin_map,
.num_exin = 6
};
/* XWAY xRX300 Family */
static struct pinctrl_xway_soc xrx300_pinctrl = {
XRX300_MAX_PIN, xrx300_mfp,
xrx300_grps, ARRAY_SIZE(xrx300_grps),
xrx300_funcs, ARRAY_SIZE(xrx300_funcs),
xrx300_exin_pin_map, 5
.pin_count = XRX300_MAX_PIN,
.mfp = xrx300_mfp,
.grps = xrx300_grps,
.num_grps = ARRAY_SIZE(xrx300_grps),
.funcs = xrx300_funcs,
.num_funcs = ARRAY_SIZE(xrx300_funcs),
.exin = xrx300_exin_pin_map,
.num_exin = 5
};
static struct pinctrl_gpio_range xway_gpio_range = {

View File

@ -20,7 +20,7 @@
*/
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -1210,7 +1210,6 @@ static const struct of_device_id zynq_pinctrl_of_match[] = {
{ .compatible = "xlnx,pinctrl-zynq" },
{ }
};
MODULE_DEVICE_TABLE(of, zynq_pinctrl_of_match);
static struct platform_driver zynq_pinctrl_driver = {
.driver = {
@ -1225,13 +1224,3 @@ static int __init zynq_pinctrl_init(void)
return platform_driver_register(&zynq_pinctrl_driver);
}
arch_initcall(zynq_pinctrl_init);
static void __exit zynq_pinctrl_exit(void)
{
platform_driver_unregister(&zynq_pinctrl_driver);
}
module_exit(zynq_pinctrl_exit);
MODULE_AUTHOR("Sören Brinkmann <soren.brinkmann@xilinx.com>");
MODULE_DESCRIPTION("Xilinx Zynq pinctrl driver");
MODULE_LICENSE("GPL");

View File

@ -256,7 +256,7 @@ int pinmux_request_gpio(struct pinctrl_dev *pctldev,
/* Conjure some name stating what chip and pin this is taken by */
owner = kasprintf(GFP_KERNEL, "%s:%d", range->name, gpio);
if (!owner)
return -EINVAL;
return -ENOMEM;
ret = pin_request(pctldev, pin, owner, range);
if (ret < 0)
@ -606,23 +606,17 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
if (pmxops->strict) {
if (desc->mux_owner)
seq_printf(s, "pin %d (%s): device %s%s",
pin,
desc->name ? desc->name : "unnamed",
desc->mux_owner,
pin, desc->name, desc->mux_owner,
is_hog ? " (HOG)" : "");
else if (desc->gpio_owner)
seq_printf(s, "pin %d (%s): GPIO %s",
pin,
desc->name ? desc->name : "unnamed",
desc->gpio_owner);
pin, desc->name, desc->gpio_owner);
else
seq_printf(s, "pin %d (%s): UNCLAIMED",
pin,
desc->name ? desc->name : "unnamed");
pin, desc->name);
} else {
/* For non-strict controllers */
seq_printf(s, "pin %d (%s): %s %s%s", pin,
desc->name ? desc->name : "unnamed",
seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name,
desc->mux_owner ? desc->mux_owner
: "(MUX UNCLAIMED)",
desc->gpio_owner ? desc->gpio_owner

View File

@ -55,6 +55,14 @@ config PINCTRL_MSM8960
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 8960 platform.
config PINCTRL_MDM9615
tristate "Qualcomm 9615 pin controller driver"
depends on GPIOLIB && OF
select PINCTRL_MSM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 9615 platform.
config PINCTRL_MSM8X74
tristate "Qualcomm 8x74 pin controller driver"
depends on GPIOLIB && OF

View File

@ -10,6 +10,7 @@ obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
obj-$(CONFIG_PINCTRL_MSM8916) += pinctrl-msm8916.o
obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o
obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o
obj-$(CONFIG_PINCTRL_MDM9615) += pinctrl-mdm9615.o
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o
obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o

View File

@ -0,0 +1,483 @@
/*
* Copyright (c) 2014, Sony Mobile Communications AB.
* Copyright (c) 2016 BayLibre, SAS.
* Author : Neil Armstrong <narmstrong@baylibre.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "pinctrl-msm.h"
static const struct pinctrl_pin_desc mdm9615_pins[] = {
PINCTRL_PIN(0, "GPIO_0"),
PINCTRL_PIN(1, "GPIO_1"),
PINCTRL_PIN(2, "GPIO_2"),
PINCTRL_PIN(3, "GPIO_3"),
PINCTRL_PIN(4, "GPIO_4"),
PINCTRL_PIN(5, "GPIO_5"),
PINCTRL_PIN(6, "GPIO_6"),
PINCTRL_PIN(7, "GPIO_7"),
PINCTRL_PIN(8, "GPIO_8"),
PINCTRL_PIN(9, "GPIO_9"),
PINCTRL_PIN(10, "GPIO_10"),
PINCTRL_PIN(11, "GPIO_11"),
PINCTRL_PIN(12, "GPIO_12"),
PINCTRL_PIN(13, "GPIO_13"),
PINCTRL_PIN(14, "GPIO_14"),
PINCTRL_PIN(15, "GPIO_15"),
PINCTRL_PIN(16, "GPIO_16"),
PINCTRL_PIN(17, "GPIO_17"),
PINCTRL_PIN(18, "GPIO_18"),
PINCTRL_PIN(19, "GPIO_19"),
PINCTRL_PIN(20, "GPIO_20"),
PINCTRL_PIN(21, "GPIO_21"),
PINCTRL_PIN(22, "GPIO_22"),
PINCTRL_PIN(23, "GPIO_23"),
PINCTRL_PIN(24, "GPIO_24"),
PINCTRL_PIN(25, "GPIO_25"),
PINCTRL_PIN(26, "GPIO_26"),
PINCTRL_PIN(27, "GPIO_27"),
PINCTRL_PIN(28, "GPIO_28"),
PINCTRL_PIN(29, "GPIO_29"),
PINCTRL_PIN(30, "GPIO_30"),
PINCTRL_PIN(31, "GPIO_31"),
PINCTRL_PIN(32, "GPIO_32"),
PINCTRL_PIN(33, "GPIO_33"),
PINCTRL_PIN(34, "GPIO_34"),
PINCTRL_PIN(35, "GPIO_35"),
PINCTRL_PIN(36, "GPIO_36"),
PINCTRL_PIN(37, "GPIO_37"),
PINCTRL_PIN(38, "GPIO_38"),
PINCTRL_PIN(39, "GPIO_39"),
PINCTRL_PIN(40, "GPIO_40"),
PINCTRL_PIN(41, "GPIO_41"),
PINCTRL_PIN(42, "GPIO_42"),
PINCTRL_PIN(43, "GPIO_43"),
PINCTRL_PIN(44, "GPIO_44"),
PINCTRL_PIN(45, "GPIO_45"),
PINCTRL_PIN(46, "GPIO_46"),
PINCTRL_PIN(47, "GPIO_47"),
PINCTRL_PIN(48, "GPIO_48"),
PINCTRL_PIN(49, "GPIO_49"),
PINCTRL_PIN(50, "GPIO_50"),
PINCTRL_PIN(51, "GPIO_51"),
PINCTRL_PIN(52, "GPIO_52"),
PINCTRL_PIN(53, "GPIO_53"),
PINCTRL_PIN(54, "GPIO_54"),
PINCTRL_PIN(55, "GPIO_55"),
PINCTRL_PIN(56, "GPIO_56"),
PINCTRL_PIN(57, "GPIO_57"),
PINCTRL_PIN(58, "GPIO_58"),
PINCTRL_PIN(59, "GPIO_59"),
PINCTRL_PIN(60, "GPIO_60"),
PINCTRL_PIN(61, "GPIO_61"),
PINCTRL_PIN(62, "GPIO_62"),
PINCTRL_PIN(63, "GPIO_63"),
PINCTRL_PIN(64, "GPIO_64"),
PINCTRL_PIN(65, "GPIO_65"),
PINCTRL_PIN(66, "GPIO_66"),
PINCTRL_PIN(67, "GPIO_67"),
PINCTRL_PIN(68, "GPIO_68"),
PINCTRL_PIN(69, "GPIO_69"),
PINCTRL_PIN(70, "GPIO_70"),
PINCTRL_PIN(71, "GPIO_71"),
PINCTRL_PIN(72, "GPIO_72"),
PINCTRL_PIN(73, "GPIO_73"),
PINCTRL_PIN(74, "GPIO_74"),
PINCTRL_PIN(75, "GPIO_75"),
PINCTRL_PIN(76, "GPIO_76"),
PINCTRL_PIN(77, "GPIO_77"),
PINCTRL_PIN(78, "GPIO_78"),
PINCTRL_PIN(79, "GPIO_79"),
PINCTRL_PIN(80, "GPIO_80"),
PINCTRL_PIN(81, "GPIO_81"),
PINCTRL_PIN(82, "GPIO_82"),
PINCTRL_PIN(83, "GPIO_83"),
PINCTRL_PIN(84, "GPIO_84"),
PINCTRL_PIN(85, "GPIO_85"),
PINCTRL_PIN(86, "GPIO_86"),
PINCTRL_PIN(87, "GPIO_87"),
};
#define DECLARE_MSM_GPIO_PINS(pin) \
static const unsigned int gpio##pin##_pins[] = { pin }
DECLARE_MSM_GPIO_PINS(0);
DECLARE_MSM_GPIO_PINS(1);
DECLARE_MSM_GPIO_PINS(2);
DECLARE_MSM_GPIO_PINS(3);
DECLARE_MSM_GPIO_PINS(4);
DECLARE_MSM_GPIO_PINS(5);
DECLARE_MSM_GPIO_PINS(6);
DECLARE_MSM_GPIO_PINS(7);
DECLARE_MSM_GPIO_PINS(8);
DECLARE_MSM_GPIO_PINS(9);
DECLARE_MSM_GPIO_PINS(10);
DECLARE_MSM_GPIO_PINS(11);
DECLARE_MSM_GPIO_PINS(12);
DECLARE_MSM_GPIO_PINS(13);
DECLARE_MSM_GPIO_PINS(14);
DECLARE_MSM_GPIO_PINS(15);
DECLARE_MSM_GPIO_PINS(16);
DECLARE_MSM_GPIO_PINS(17);
DECLARE_MSM_GPIO_PINS(18);
DECLARE_MSM_GPIO_PINS(19);
DECLARE_MSM_GPIO_PINS(20);
DECLARE_MSM_GPIO_PINS(21);
DECLARE_MSM_GPIO_PINS(22);
DECLARE_MSM_GPIO_PINS(23);
DECLARE_MSM_GPIO_PINS(24);
DECLARE_MSM_GPIO_PINS(25);
DECLARE_MSM_GPIO_PINS(26);
DECLARE_MSM_GPIO_PINS(27);
DECLARE_MSM_GPIO_PINS(28);
DECLARE_MSM_GPIO_PINS(29);
DECLARE_MSM_GPIO_PINS(30);
DECLARE_MSM_GPIO_PINS(31);
DECLARE_MSM_GPIO_PINS(32);
DECLARE_MSM_GPIO_PINS(33);
DECLARE_MSM_GPIO_PINS(34);
DECLARE_MSM_GPIO_PINS(35);
DECLARE_MSM_GPIO_PINS(36);
DECLARE_MSM_GPIO_PINS(37);
DECLARE_MSM_GPIO_PINS(38);
DECLARE_MSM_GPIO_PINS(39);
DECLARE_MSM_GPIO_PINS(40);
DECLARE_MSM_GPIO_PINS(41);
DECLARE_MSM_GPIO_PINS(42);
DECLARE_MSM_GPIO_PINS(43);
DECLARE_MSM_GPIO_PINS(44);
DECLARE_MSM_GPIO_PINS(45);
DECLARE_MSM_GPIO_PINS(46);
DECLARE_MSM_GPIO_PINS(47);
DECLARE_MSM_GPIO_PINS(48);
DECLARE_MSM_GPIO_PINS(49);
DECLARE_MSM_GPIO_PINS(50);
DECLARE_MSM_GPIO_PINS(51);
DECLARE_MSM_GPIO_PINS(52);
DECLARE_MSM_GPIO_PINS(53);
DECLARE_MSM_GPIO_PINS(54);
DECLARE_MSM_GPIO_PINS(55);
DECLARE_MSM_GPIO_PINS(56);
DECLARE_MSM_GPIO_PINS(57);
DECLARE_MSM_GPIO_PINS(58);
DECLARE_MSM_GPIO_PINS(59);
DECLARE_MSM_GPIO_PINS(60);
DECLARE_MSM_GPIO_PINS(61);
DECLARE_MSM_GPIO_PINS(62);
DECLARE_MSM_GPIO_PINS(63);
DECLARE_MSM_GPIO_PINS(64);
DECLARE_MSM_GPIO_PINS(65);
DECLARE_MSM_GPIO_PINS(66);
DECLARE_MSM_GPIO_PINS(67);
DECLARE_MSM_GPIO_PINS(68);
DECLARE_MSM_GPIO_PINS(69);
DECLARE_MSM_GPIO_PINS(70);
DECLARE_MSM_GPIO_PINS(71);
DECLARE_MSM_GPIO_PINS(72);
DECLARE_MSM_GPIO_PINS(73);
DECLARE_MSM_GPIO_PINS(74);
DECLARE_MSM_GPIO_PINS(75);
DECLARE_MSM_GPIO_PINS(76);
DECLARE_MSM_GPIO_PINS(77);
DECLARE_MSM_GPIO_PINS(78);
DECLARE_MSM_GPIO_PINS(79);
DECLARE_MSM_GPIO_PINS(80);
DECLARE_MSM_GPIO_PINS(81);
DECLARE_MSM_GPIO_PINS(82);
DECLARE_MSM_GPIO_PINS(83);
DECLARE_MSM_GPIO_PINS(84);
DECLARE_MSM_GPIO_PINS(85);
DECLARE_MSM_GPIO_PINS(86);
DECLARE_MSM_GPIO_PINS(87);
#define FUNCTION(fname) \
[MSM_MUX_##fname] = { \
.name = #fname, \
.groups = fname##_groups, \
.ngroups = ARRAY_SIZE(fname##_groups), \
}
#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \
{ \
.name = "gpio" #id, \
.pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \
MSM_MUX_gpio, \
MSM_MUX_##f1, \
MSM_MUX_##f2, \
MSM_MUX_##f3, \
MSM_MUX_##f4, \
MSM_MUX_##f5, \
MSM_MUX_##f6, \
MSM_MUX_##f7, \
MSM_MUX_##f8, \
MSM_MUX_##f9, \
MSM_MUX_##f10, \
MSM_MUX_##f11 \
}, \
.nfuncs = 12, \
.ctl_reg = 0x1000 + 0x10 * id, \
.io_reg = 0x1004 + 0x10 * id, \
.intr_cfg_reg = 0x1008 + 0x10 * id, \
.intr_status_reg = 0x100c + 0x10 * id, \
.intr_target_reg = 0x400 + 0x4 * id, \
.mux_bit = 2, \
.pull_bit = 0, \
.drv_bit = 6, \
.oe_bit = 9, \
.in_bit = 0, \
.out_bit = 1, \
.intr_enable_bit = 0, \
.intr_status_bit = 0, \
.intr_ack_high = 1, \
.intr_target_bit = 0, \
.intr_target_kpss_val = 4, \
.intr_raw_status_bit = 3, \
.intr_polarity_bit = 1, \
.intr_detection_bit = 2, \
.intr_detection_width = 1, \
}
enum mdm9615_functions {
MSM_MUX_gpio,
MSM_MUX_gsbi2_i2c,
MSM_MUX_gsbi3,
MSM_MUX_gsbi4,
MSM_MUX_gsbi5_i2c,
MSM_MUX_gsbi5_uart,
MSM_MUX_sdc2,
MSM_MUX_ebi2_lcdc,
MSM_MUX_ps_hold,
MSM_MUX_prim_audio,
MSM_MUX_sec_audio,
MSM_MUX_cdc_mclk,
MSM_MUX_NA,
};
static const char * const gpio_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
"gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
"gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
"gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
"gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
"gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
"gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
"gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
"gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
"gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
"gpio85", "gpio86", "gpio87"
};
static const char * const gsbi2_i2c_groups[] = {
"gpio4", "gpio5"
};
static const char * const gsbi3_groups[] = {
"gpio8", "gpio9", "gpio10", "gpio11"
};
static const char * const gsbi4_groups[] = {
"gpio12", "gpio13", "gpio14", "gpio15"
};
static const char * const gsbi5_i2c_groups[] = {
"gpio16", "gpio17"
};
static const char * const gsbi5_uart_groups[] = {
"gpio18", "gpio19"
};
static const char * const sdc2_groups[] = {
"gpio25", "gpio26", "gpio27", "gpio28", "gpio29", "gpio30",
};
static const char * const ebi2_lcdc_groups[] = {
"gpio21", "gpio22", "gpio24",
};
static const char * const ps_hold_groups[] = {
"gpio83",
};
static const char * const prim_audio_groups[] = {
"gpio20", "gpio21", "gpio22", "gpio23",
};
static const char * const sec_audio_groups[] = {
"gpio25", "gpio26", "gpio27", "gpio28",
};
static const char * const cdc_mclk_groups[] = {
"gpio24",
};
static const struct msm_function mdm9615_functions[] = {
FUNCTION(gpio),
FUNCTION(gsbi2_i2c),
FUNCTION(gsbi3),
FUNCTION(gsbi4),
FUNCTION(gsbi5_i2c),
FUNCTION(gsbi5_uart),
FUNCTION(sdc2),
FUNCTION(ebi2_lcdc),
FUNCTION(ps_hold),
FUNCTION(prim_audio),
FUNCTION(sec_audio),
FUNCTION(cdc_mclk),
};
static const struct msm_pingroup mdm9615_groups[] = {
PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(4, gsbi2_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(5, gsbi2_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(6, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(8, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(9, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(10, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(11, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(12, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(13, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(14, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(15, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(16, gsbi5_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(17, gsbi5_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(18, gsbi5_uart, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(19, gsbi5_uart, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(20, prim_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(21, prim_audio, ebi2_lcdc, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(22, prim_audio, ebi2_lcdc, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(23, prim_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(24, cdc_mclk, NA, ebi2_lcdc, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(25, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(26, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(27, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(28, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(29, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(30, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(31, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(32, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(33, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(34, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(35, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(36, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(37, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(39, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(41, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(42, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(47, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(48, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(49, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(50, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(51, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(52, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(53, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(54, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(55, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(56, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(57, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(58, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(59, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(60, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(61, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(62, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(63, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(65, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(67, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(68, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(69, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(70, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(71, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(82, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(83, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(84, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(85, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
};
#define NUM_GPIO_PINGROUPS 88
static const struct msm_pinctrl_soc_data mdm9615_pinctrl = {
.pins = mdm9615_pins,
.npins = ARRAY_SIZE(mdm9615_pins),
.functions = mdm9615_functions,
.nfunctions = ARRAY_SIZE(mdm9615_functions),
.groups = mdm9615_groups,
.ngroups = ARRAY_SIZE(mdm9615_groups),
.ngpios = NUM_GPIO_PINGROUPS,
};
static int mdm9615_pinctrl_probe(struct platform_device *pdev)
{
return msm_pinctrl_probe(pdev, &mdm9615_pinctrl);
}
static const struct of_device_id mdm9615_pinctrl_of_match[] = {
{ .compatible = "qcom,mdm9615-pinctrl", },
{ },
};
static struct platform_driver mdm9615_pinctrl_driver = {
.driver = {
.name = "mdm9615-pinctrl",
.of_match_table = mdm9615_pinctrl_of_match,
},
.probe = mdm9615_pinctrl_probe,
.remove = msm_pinctrl_remove,
};
static int __init mdm9615_pinctrl_init(void)
{
return platform_driver_register(&mdm9615_pinctrl_driver);
}
arch_initcall(mdm9615_pinctrl_init);
static void __exit mdm9615_pinctrl_exit(void)
{
platform_driver_unregister(&mdm9615_pinctrl_driver);
}
module_exit(mdm9615_pinctrl_exit);
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
MODULE_DESCRIPTION("Qualcomm MDM9615 pinctrl driver");
MODULE_LICENSE("GPL v2");
MODULE_DEVICE_TABLE(of, mdm9615_pinctrl_of_match);

View File

@ -29,6 +29,7 @@
#include <linux/spinlock.h>
#include <linux/reboot.h>
#include <linux/pm.h>
#include <linux/log2.h>
#include "../core.h"
#include "../pinconf.h"
@ -138,10 +139,11 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct msm_pingroup *g;
unsigned long flags;
u32 val;
u32 val, mask;
int i;
g = &pctrl->soc->groups[group];
mask = GENMASK(g->mux_bit + order_base_2(g->nfuncs) - 1, g->mux_bit);
for (i = 0; i < g->nfuncs; i++) {
if (g->funcs[i] == function)
@ -154,7 +156,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->ctl_reg);
val &= ~(0x7 << g->mux_bit);
val &= mask;
val |= i << g->mux_bit;
writel(val, pctrl->regs + g->ctl_reg);

View File

@ -506,6 +506,8 @@ enum msm8660_functions {
MSM_MUX_usb_fs2_oe_n,
MSM_MUX_vfe,
MSM_MUX_vsens_alarm,
MSM_MUX_ebi2cs,
MSM_MUX_ebi2,
MSM_MUX__,
};
@ -696,6 +698,36 @@ static const char * const vfe_groups[] = {
static const char * const vsens_alarm_groups[] = {
"gpio127"
};
static const char * const ebi2cs_groups[] = {
"gpio39", /* CS1A */
"gpio40", /* CS2A */
"gpio123", /* CS1B */
"gpio124", /* CS2B */
"gpio131", /* CS5 */
"gpio132", /* CS4 */
"gpio133", /* CS3 */
"gpio134", /* CS0 */
};
static const char * const ebi2_groups[] = {
/* ADDR9 & ADDR8 */
"gpio37", "gpio38",
/* ADDR7 - ADDR 0 */
"gpio123", "gpio124", "gpio125", "gpio126",
"gpio127", "gpio128", "gpio129", "gpio130",
/* (muxed address+data) AD15 - AD0 */
"gpio135", "gpio136", "gpio137", "gpio138", "gpio139",
"gpio140", "gpio141", "gpio142", "gpio143", "gpio144",
"gpio145", "gpio146", "gpio147", "gpio148", "gpio149",
"gpio150",
"gpio151", /* OE output enable */
"gpio152", /* clock */
"gpio153", /* ADV */
"gpio154", /* WAIT (input) */
"gpio155", /* UB Upper Byte Enable */
"gpio156", /* LB Lower Byte Enable */
"gpio157", /* WE Write Enable */
"gpio158", /* busy */
};
static const struct msm_function msm8660_functions[] = {
FUNCTION(gpio),
@ -749,6 +781,8 @@ static const struct msm_function msm8660_functions[] = {
FUNCTION(usb_fs2_oe_n),
FUNCTION(vfe),
FUNCTION(vsens_alarm),
FUNCTION(ebi2cs), /* for EBI2 chip selects */
FUNCTION(ebi2), /* for general EBI2 pins */
};
static const struct msm_pingroup msm8660_groups[] = {
@ -789,10 +823,10 @@ static const struct msm_pingroup msm8660_groups[] = {
PINGROUP(34, gsbi1, _, _, _, _, _, _),
PINGROUP(35, gsbi1, _, _, _, _, _, _),
PINGROUP(36, gsbi1, _, _, _, _, _, _),
PINGROUP(37, gsbi2, _, _, _, _, _, _),
PINGROUP(38, gsbi2, _, _, _, _, _, _),
PINGROUP(39, gsbi2, _, mdp_vsync, _, _, _, _),
PINGROUP(40, gsbi2, _, _, _, _, _, _),
PINGROUP(37, gsbi2, ebi2, _, _, _, _, _),
PINGROUP(38, gsbi2, ebi2, _, _, _, _, _),
PINGROUP(39, gsbi2, ebi2cs, mdp_vsync, _, _, _, _),
PINGROUP(40, gsbi2, ebi2cs, _, _, _, _, _),
PINGROUP(41, gsbi3, mdp_vsync, _, _, _, _, _),
PINGROUP(42, gsbi3, vfe, _, _, _, _, _),
PINGROUP(43, gsbi3, _, _, _, _, _, _),
@ -875,42 +909,42 @@ static const struct msm_pingroup msm8660_groups[] = {
PINGROUP(120, i2s, _, _, _, _, _, _),
PINGROUP(121, i2s, _, _, _, _, _, _),
PINGROUP(122, i2s, gp_clk_1b, _, _, _, _, _),
PINGROUP(123, _, gsbi2_spi_cs1_n, _, _, _, _, _),
PINGROUP(124, _, gsbi2_spi_cs2_n, _, _, _, _, _),
PINGROUP(125, _, gsbi2_spi_cs3_n, _, _, _, _, _),
PINGROUP(126, _, _, _, _, _, _, _),
PINGROUP(127, _, vsens_alarm, _, _, _, _, _),
PINGROUP(128, _, _, _, _, _, _, _),
PINGROUP(129, _, _, _, _, _, _, _),
PINGROUP(130, _, _, _, _, _, _, _),
PINGROUP(131, _, _, _, _, _, _, _),
PINGROUP(132, _, _, _, _, _, _, _),
PINGROUP(133, _, _, _, _, _, _, _),
PINGROUP(134, _, _, _, _, _, _, _),
PINGROUP(135, _, _, _, _, _, _, _),
PINGROUP(136, _, _, _, _, _, _, _),
PINGROUP(137, _, _, _, _, _, _, _),
PINGROUP(138, _, _, _, _, _, _, _),
PINGROUP(139, _, _, _, _, _, _, _),
PINGROUP(140, _, _, _, _, _, _, _),
PINGROUP(141, _, _, _, _, _, _, _),
PINGROUP(142, _, _, _, _, _, _, _),
PINGROUP(143, _, sdc2, _, _, _, _, _),
PINGROUP(144, _, sdc2, _, _, _, _, _),
PINGROUP(145, _, sdc2, _, _, _, _, _),
PINGROUP(146, _, sdc2, _, _, _, _, _),
PINGROUP(147, _, sdc2, _, _, _, _, _),
PINGROUP(148, _, sdc2, _, _, _, _, _),
PINGROUP(149, _, sdc2, _, _, _, _, _),
PINGROUP(150, _, sdc2, _, _, _, _, _),
PINGROUP(151, _, sdc2, _, _, _, _, _),
PINGROUP(152, _, sdc2, _, _, _, _, _),
PINGROUP(153, _, _, _, _, _, _, _),
PINGROUP(154, _, _, _, _, _, _, _),
PINGROUP(155, _, _, _, _, _, _, _),
PINGROUP(156, _, _, _, _, _, _, _),
PINGROUP(157, _, _, _, _, _, _, _),
PINGROUP(158, _, _, _, _, _, _, _),
PINGROUP(123, ebi2, gsbi2_spi_cs1_n, ebi2cs, _, _, _, _),
PINGROUP(124, ebi2, gsbi2_spi_cs2_n, ebi2cs, _, _, _, _),
PINGROUP(125, ebi2, gsbi2_spi_cs3_n, _, _, _, _, _),
PINGROUP(126, ebi2, _, _, _, _, _, _),
PINGROUP(127, ebi2, vsens_alarm, _, _, _, _, _),
PINGROUP(128, ebi2, _, _, _, _, _, _),
PINGROUP(129, ebi2, _, _, _, _, _, _),
PINGROUP(130, ebi2, _, _, _, _, _, _),
PINGROUP(131, ebi2cs, _, _, _, _, _, _),
PINGROUP(132, ebi2cs, _, _, _, _, _, _),
PINGROUP(133, ebi2cs, _, _, _, _, _, _),
PINGROUP(134, ebi2cs, _, _, _, _, _, _),
PINGROUP(135, ebi2, _, _, _, _, _, _),
PINGROUP(136, ebi2, _, _, _, _, _, _),
PINGROUP(137, ebi2, _, _, _, _, _, _),
PINGROUP(138, ebi2, _, _, _, _, _, _),
PINGROUP(139, ebi2, _, _, _, _, _, _),
PINGROUP(140, ebi2, _, _, _, _, _, _),
PINGROUP(141, ebi2, _, _, _, _, _, _),
PINGROUP(142, ebi2, _, _, _, _, _, _),
PINGROUP(143, ebi2, sdc2, _, _, _, _, _),
PINGROUP(144, ebi2, sdc2, _, _, _, _, _),
PINGROUP(145, ebi2, sdc2, _, _, _, _, _),
PINGROUP(146, ebi2, sdc2, _, _, _, _, _),
PINGROUP(147, ebi2, sdc2, _, _, _, _, _),
PINGROUP(148, ebi2, sdc2, _, _, _, _, _),
PINGROUP(149, ebi2, sdc2, _, _, _, _, _),
PINGROUP(150, ebi2, sdc2, _, _, _, _, _),
PINGROUP(151, ebi2, sdc2, _, _, _, _, _),
PINGROUP(152, ebi2, sdc2, _, _, _, _, _),
PINGROUP(153, ebi2, _, _, _, _, _, _),
PINGROUP(154, ebi2, _, _, _, _, _, _),
PINGROUP(155, ebi2, _, _, _, _, _, _),
PINGROUP(156, ebi2, _, _, _, _, _, _),
PINGROUP(157, ebi2, _, _, _, _, _, _),
PINGROUP(158, ebi2, _, _, _, _, _, _),
PINGROUP(159, sdc1, _, _, _, _, _, _),
PINGROUP(160, sdc1, _, _, _, _, _, _),
PINGROUP(161, sdc1, _, _, _, _, _, _),

View File

@ -172,6 +172,8 @@ static const struct pinctrl_pin_desc msm8x74_pins[] = {
PINCTRL_PIN(149, "SDC2_CLK"),
PINCTRL_PIN(150, "SDC2_CMD"),
PINCTRL_PIN(151, "SDC2_DATA"),
PINCTRL_PIN(152, "HSIC_STROBE"),
PINCTRL_PIN(153, "HSIC_DATA"),
};
#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
@ -328,6 +330,8 @@ static const unsigned int sdc1_data_pins[] = { 148 };
static const unsigned int sdc2_clk_pins[] = { 149 };
static const unsigned int sdc2_cmd_pins[] = { 150 };
static const unsigned int sdc2_data_pins[] = { 151 };
static const unsigned int hsic_strobe_pins[] = { 152 };
static const unsigned int hsic_data_pins[] = { 153 };
#define FUNCTION(fname) \
[MSM_MUX_##fname] = { \
@ -399,6 +403,37 @@ static const unsigned int sdc2_data_pins[] = { 151 };
.intr_detection_width = -1, \
}
#define HSIC_PINGROUP(pg_name, ctl) \
{ \
.name = #pg_name, \
.pins = pg_name##_pins, \
.npins = ARRAY_SIZE(pg_name##_pins), \
.funcs = (int[]){ \
MSM_MUX_gpio, \
MSM_MUX_hsic_ctl, \
}, \
.nfuncs = 2, \
.ctl_reg = ctl, \
.io_reg = 0, \
.intr_cfg_reg = 0, \
.intr_status_reg = 0, \
.intr_target_reg = 0, \
.mux_bit = 25, \
.pull_bit = -1, \
.drv_bit = -1, \
.oe_bit = -1, \
.in_bit = -1, \
.out_bit = -1, \
.intr_enable_bit = -1, \
.intr_status_bit = -1, \
.intr_target_bit = -1, \
.intr_target_kpss_val = -1, \
.intr_raw_status_bit = -1, \
.intr_polarity_bit = -1, \
.intr_detection_bit = -1, \
.intr_detection_width = -1, \
}
/*
* TODO: Add the rest of the possible functions and fill out
* the pingroup table below.
@ -509,6 +544,7 @@ enum msm8x74_functions {
MSM_MUX_fm,
MSM_MUX_wlan,
MSM_MUX_slimbus,
MSM_MUX_hsic_ctl,
MSM_MUX_NA,
};
@ -534,7 +570,8 @@ static const char * const gpio_groups[] = {
"gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
"gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
"gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
"gpio141", "gpio142", "gpio143", "gpio144", "gpio145"
"gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "hsic_data",
"hsic_strobe",
};
static const char * const blsp_uart1_groups[] = {
@ -754,6 +791,7 @@ static const char * const wlan_groups[] = {
};
static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
static const char * const hsic_ctl_groups[] = { "hsic_strobe", "hsic_data" };
static const struct msm_function msm8x74_functions[] = {
FUNCTION(gpio),
@ -861,6 +899,7 @@ static const struct msm_function msm8x74_functions[] = {
FUNCTION(fm),
FUNCTION(wlan),
FUNCTION(slimbus),
FUNCTION(hsic_ctl),
};
static const struct msm_pingroup msm8x74_groups[] = {
@ -1016,6 +1055,8 @@ static const struct msm_pingroup msm8x74_groups[] = {
SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6),
SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3),
SDC_PINGROUP(sdc2_data, 0x2048, 9, 0),
HSIC_PINGROUP(hsic_strobe, 0x2050),
HSIC_PINGROUP(hsic_data, 0x2054),
};
#define NUM_GPIO_PINGROUPS 146

View File

@ -744,6 +744,7 @@ static int pm8xxx_pin_populate(struct pm8xxx_mpp *pctrl,
static const struct of_device_id pm8xxx_mpp_of_match[] = {
{ .compatible = "qcom,pm8018-mpp" },
{ .compatible = "qcom,pm8038-mpp" },
{ .compatible = "qcom,pm8058-mpp" },
{ .compatible = "qcom,pm8917-mpp" },
{ .compatible = "qcom,pm8821-mpp" },
{ .compatible = "qcom,pm8921-mpp" },

View File

@ -998,6 +998,7 @@ static struct platform_driver exynos5440_pinctrl_driver = {
.driver = {
.name = "exynos5440-pinctrl",
.of_match_table = exynos5440_pinctrl_dt_match,
.suppress_bind_attrs = true,
},
};

View File

@ -1274,6 +1274,7 @@ static struct platform_driver samsung_pinctrl_driver = {
.driver = {
.name = "samsung-pinctrl",
.of_match_table = samsung_pinctrl_dt_match,
.suppress_bind_attrs = true,
},
};

View File

@ -598,15 +598,6 @@ static int sh_pfc_probe(struct platform_device *pdev)
return 0;
}
static int sh_pfc_remove(struct platform_device *pdev)
{
#ifdef CONFIG_PINCTRL_SH_PFC_GPIO
sh_pfc_unregister_gpiochip(platform_get_drvdata(pdev));
#endif
return 0;
}
static const struct platform_device_id sh_pfc_id_table[] = {
#ifdef CONFIG_PINCTRL_PFC_SH7203
{ "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info },
@ -650,7 +641,6 @@ static const struct platform_device_id sh_pfc_id_table[] = {
static struct platform_driver sh_pfc_driver = {
.probe = sh_pfc_probe,
.remove = sh_pfc_remove,
.id_table = sh_pfc_id_table,
.driver = {
.name = DRV_NAME,

View File

@ -10,50 +10,16 @@
#ifndef __SH_PFC_CORE_H__
#define __SH_PFC_CORE_H__
#include <linux/compiler.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include "sh_pfc.h"
struct sh_pfc_window {
phys_addr_t phys;
void __iomem *virt;
unsigned long size;
};
struct sh_pfc_chip;
struct sh_pfc_pinctrl;
struct sh_pfc_pin_range {
u16 start;
u16 end;
};
struct sh_pfc {
struct device *dev;
const struct sh_pfc_soc_info *info;
spinlock_t lock;
unsigned int num_windows;
struct sh_pfc_window *windows;
unsigned int num_irqs;
unsigned int *irqs;
struct sh_pfc_pin_range *ranges;
unsigned int nr_ranges;
unsigned int nr_gpio_pins;
struct sh_pfc_chip *gpio;
#ifdef CONFIG_SUPERH
struct sh_pfc_chip *func;
#endif
};
int sh_pfc_register_gpiochip(struct sh_pfc *pfc);
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc);
int sh_pfc_register_pinctrl(struct sh_pfc *pfc);
@ -67,28 +33,4 @@ void sh_pfc_write_reg(struct sh_pfc *pfc, u32 reg, unsigned int width,
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin);
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type);
extern const struct sh_pfc_soc_info emev2_pinmux_info;
extern const struct sh_pfc_soc_info r8a73a4_pinmux_info;
extern const struct sh_pfc_soc_info r8a7740_pinmux_info;
extern const struct sh_pfc_soc_info r8a7778_pinmux_info;
extern const struct sh_pfc_soc_info r8a7779_pinmux_info;
extern const struct sh_pfc_soc_info r8a7790_pinmux_info;
extern const struct sh_pfc_soc_info r8a7791_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 sh7203_pinmux_info;
extern const struct sh_pfc_soc_info sh7264_pinmux_info;
extern const struct sh_pfc_soc_info sh7269_pinmux_info;
extern const struct sh_pfc_soc_info sh73a0_pinmux_info;
extern const struct sh_pfc_soc_info sh7720_pinmux_info;
extern const struct sh_pfc_soc_info sh7722_pinmux_info;
extern const struct sh_pfc_soc_info sh7723_pinmux_info;
extern const struct sh_pfc_soc_info sh7724_pinmux_info;
extern const struct sh_pfc_soc_info sh7734_pinmux_info;
extern const struct sh_pfc_soc_info sh7757_pinmux_info;
extern const struct sh_pfc_soc_info sh7785_pinmux_info;
extern const struct sh_pfc_soc_info sh7786_pinmux_info;
extern const struct sh_pfc_soc_info shx3_pinmux_info;
#endif /* __SH_PFC_CORE_H__ */

View File

@ -318,7 +318,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *),
if (ret < 0)
return ERR_PTR(ret);
ret = gpiochip_add_data(&chip->gpio_chip, chip);
ret = devm_gpiochip_add_data(pfc->dev, &chip->gpio_chip, chip);
if (unlikely(ret < 0))
return ERR_PTR(ret);
@ -399,18 +399,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup, NULL);
if (IS_ERR(chip))
return PTR_ERR(chip);
pfc->func = chip;
#endif /* CONFIG_SUPERH */
return 0;
}
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
{
gpiochip_remove(&pfc->gpio->gpio_chip);
#ifdef CONFIG_SUPERH
gpiochip_remove(&pfc->func->gpio_chip);
#endif
return 0;
}

View File

@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "core.h"
#include "sh_pfc.h"
#define CPU_ALL_PORT(fn, pfx, sfx) \

View File

@ -22,7 +22,6 @@
#include <linux/kernel.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "core.h"
#include "sh_pfc.h"
#define CPU_ALL_PORT(fn, pfx, sfx) \

View File

@ -23,7 +23,7 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "core.h"
#include "sh_pfc.h"
#define PORT_GP_PUP_1(bank, pin, fn, sfx) \

View File

@ -24,7 +24,6 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include "core.h"
#include "sh_pfc.h"
/*
@ -4696,47 +4695,6 @@ static const char * const vin3_groups[] = {
"vin3_clk",
};
#define IOCTRL6 0x8c
static int r8a7790_get_io_voltage(struct sh_pfc *pfc, unsigned int pin)
{
u32 data, mask;
if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin))
return -EINVAL;
data = ioread32(pfc->windows->virt + IOCTRL6),
/* Bits in IOCTRL6 are numbered in opposite order to pins */
mask = 0x80000000 >> (pin & 0x1f);
return (data & mask) ? 3300 : 1800;
}
static int r8a7790_set_io_voltage(struct sh_pfc *pfc, unsigned int pin, u16 mV)
{
u32 data, mask;
if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin))
return -EINVAL;
if (mV != 1800 && mV != 3300)
return -EINVAL;
data = ioread32(pfc->windows->virt + IOCTRL6);
/* Bits in IOCTRL6 are numbered in opposite order to pins */
mask = 0x80000000 >> (pin & 0x1f);
if (mV == 3300)
data |= mask;
else
data &= ~mask;
iowrite32(~data, pfc->windows->virt); /* unlock reg */
iowrite32(data, pfc->windows->virt + IOCTRL6);
return 0;
}
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(audio_clk),
SH_PFC_FUNCTION(avb),
@ -5736,14 +5694,23 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
{ },
};
static const struct sh_pfc_soc_operations pinmux_ops = {
.get_io_voltage = r8a7790_get_io_voltage,
.set_io_voltage = r8a7790_set_io_voltage,
static int r8a7790_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
{
if (pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31))
return -EINVAL;
*pocctrl = 0xe606008c;
return 31 - (pin & 0x1f);
}
static const struct sh_pfc_soc_operations r8a7790_pinmux_ops = {
.pin_to_pocctrl = r8a7790_pin_to_pocctrl,
};
const struct sh_pfc_soc_info r8a7790_pinmux_info = {
.name = "r8a77900_pfc",
.ops = &pinmux_ops,
.ops = &r8a7790_pinmux_ops,
.unlock_reg = 0xe6060000, /* PMMR */
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },

View File

@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include "core.h"
#include "sh_pfc.h"
#define CPU_ALL_PORT(fn, sfx) \

View File

@ -17,8 +17,12 @@
PORT_GP_CFG_16(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_15(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_16(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_18(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_12(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_IO_VOLTAGE), \
PORT_GP_CFG_1(3, 12, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_1(3, 13, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_1(3, 14, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_1(3, 15, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_18(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_IO_VOLTAGE), \
PORT_GP_CFG_26(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_32(6, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_4(7, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH)
@ -552,6 +556,9 @@ static const u16 pinmux_data[] = {
PINMUX_SINGLE(AVS2),
PINMUX_SINGLE(HDMI0_CEC),
PINMUX_SINGLE(HDMI1_CEC),
PINMUX_SINGLE(I2C_SEL_0_1),
PINMUX_SINGLE(I2C_SEL_3_1),
PINMUX_SINGLE(I2C_SEL_5_1),
PINMUX_SINGLE(MSIOF0_RXD),
PINMUX_SINGLE(MSIOF0_SCK),
PINMUX_SINGLE(MSIOF0_TXD),
@ -1401,11 +1408,6 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP17_7_4, STP_ISSYNC_0_E, SEL_SSP1_0_4),
PINMUX_IPSR_MSEL(IP17_7_4, RIF2_D1_B, SEL_DRIF2_1),
PINMUX_IPSR_GPSR(IP17_7_4, TPU0TO3),
/* I2C */
PINMUX_IPSR_NOGP(0, I2C_SEL_0_1),
PINMUX_IPSR_NOGP(0, I2C_SEL_3_1),
PINMUX_IPSR_NOGP(0, I2C_SEL_5_1),
};
static const struct sh_pfc_pin pinmux_pins[] = {
@ -1654,6 +1656,221 @@ static const unsigned int canfd1_data_mux[] = {
CANFD1_TX_MARK, CANFD1_RX_MARK,
};
/* - DRIF0 --------------------------------------------------------------- */
static const unsigned int drif0_ctrl_a_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9),
};
static const unsigned int drif0_ctrl_a_mux[] = {
RIF0_CLK_A_MARK, RIF0_SYNC_A_MARK,
};
static const unsigned int drif0_data0_a_pins[] = {
/* D0 */
RCAR_GP_PIN(6, 10),
};
static const unsigned int drif0_data0_a_mux[] = {
RIF0_D0_A_MARK,
};
static const unsigned int drif0_data1_a_pins[] = {
/* D1 */
RCAR_GP_PIN(6, 7),
};
static const unsigned int drif0_data1_a_mux[] = {
RIF0_D1_A_MARK,
};
static const unsigned int drif0_ctrl_b_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 4),
};
static const unsigned int drif0_ctrl_b_mux[] = {
RIF0_CLK_B_MARK, RIF0_SYNC_B_MARK,
};
static const unsigned int drif0_data0_b_pins[] = {
/* D0 */
RCAR_GP_PIN(5, 1),
};
static const unsigned int drif0_data0_b_mux[] = {
RIF0_D0_B_MARK,
};
static const unsigned int drif0_data1_b_pins[] = {
/* D1 */
RCAR_GP_PIN(5, 2),
};
static const unsigned int drif0_data1_b_mux[] = {
RIF0_D1_B_MARK,
};
static const unsigned int drif0_ctrl_c_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(5, 12), RCAR_GP_PIN(5, 15),
};
static const unsigned int drif0_ctrl_c_mux[] = {
RIF0_CLK_C_MARK, RIF0_SYNC_C_MARK,
};
static const unsigned int drif0_data0_c_pins[] = {
/* D0 */
RCAR_GP_PIN(5, 13),
};
static const unsigned int drif0_data0_c_mux[] = {
RIF0_D0_C_MARK,
};
static const unsigned int drif0_data1_c_pins[] = {
/* D1 */
RCAR_GP_PIN(5, 14),
};
static const unsigned int drif0_data1_c_mux[] = {
RIF0_D1_C_MARK,
};
/* - DRIF1 --------------------------------------------------------------- */
static const unsigned int drif1_ctrl_a_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18),
};
static const unsigned int drif1_ctrl_a_mux[] = {
RIF1_CLK_A_MARK, RIF1_SYNC_A_MARK,
};
static const unsigned int drif1_data0_a_pins[] = {
/* D0 */
RCAR_GP_PIN(6, 19),
};
static const unsigned int drif1_data0_a_mux[] = {
RIF1_D0_A_MARK,
};
static const unsigned int drif1_data1_a_pins[] = {
/* D1 */
RCAR_GP_PIN(6, 20),
};
static const unsigned int drif1_data1_a_mux[] = {
RIF1_D1_A_MARK,
};
static const unsigned int drif1_ctrl_b_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 3),
};
static const unsigned int drif1_ctrl_b_mux[] = {
RIF1_CLK_B_MARK, RIF1_SYNC_B_MARK,
};
static const unsigned int drif1_data0_b_pins[] = {
/* D0 */
RCAR_GP_PIN(5, 7),
};
static const unsigned int drif1_data0_b_mux[] = {
RIF1_D0_B_MARK,
};
static const unsigned int drif1_data1_b_pins[] = {
/* D1 */
RCAR_GP_PIN(5, 8),
};
static const unsigned int drif1_data1_b_mux[] = {
RIF1_D1_B_MARK,
};
static const unsigned int drif1_ctrl_c_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 11),
};
static const unsigned int drif1_ctrl_c_mux[] = {
RIF1_CLK_C_MARK, RIF1_SYNC_C_MARK,
};
static const unsigned int drif1_data0_c_pins[] = {
/* D0 */
RCAR_GP_PIN(5, 6),
};
static const unsigned int drif1_data0_c_mux[] = {
RIF1_D0_C_MARK,
};
static const unsigned int drif1_data1_c_pins[] = {
/* D1 */
RCAR_GP_PIN(5, 10),
};
static const unsigned int drif1_data1_c_mux[] = {
RIF1_D1_C_MARK,
};
/* - DRIF2 --------------------------------------------------------------- */
static const unsigned int drif2_ctrl_a_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9),
};
static const unsigned int drif2_ctrl_a_mux[] = {
RIF2_CLK_A_MARK, RIF2_SYNC_A_MARK,
};
static const unsigned int drif2_data0_a_pins[] = {
/* D0 */
RCAR_GP_PIN(6, 7),
};
static const unsigned int drif2_data0_a_mux[] = {
RIF2_D0_A_MARK,
};
static const unsigned int drif2_data1_a_pins[] = {
/* D1 */
RCAR_GP_PIN(6, 10),
};
static const unsigned int drif2_data1_a_mux[] = {
RIF2_D1_A_MARK,
};
static const unsigned int drif2_ctrl_b_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(6, 26), RCAR_GP_PIN(6, 27),
};
static const unsigned int drif2_ctrl_b_mux[] = {
RIF2_CLK_B_MARK, RIF2_SYNC_B_MARK,
};
static const unsigned int drif2_data0_b_pins[] = {
/* D0 */
RCAR_GP_PIN(6, 30),
};
static const unsigned int drif2_data0_b_mux[] = {
RIF2_D0_B_MARK,
};
static const unsigned int drif2_data1_b_pins[] = {
/* D1 */
RCAR_GP_PIN(6, 31),
};
static const unsigned int drif2_data1_b_mux[] = {
RIF2_D1_B_MARK,
};
/* - DRIF3 --------------------------------------------------------------- */
static const unsigned int drif3_ctrl_a_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18),
};
static const unsigned int drif3_ctrl_a_mux[] = {
RIF3_CLK_A_MARK, RIF3_SYNC_A_MARK,
};
static const unsigned int drif3_data0_a_pins[] = {
/* D0 */
RCAR_GP_PIN(6, 19),
};
static const unsigned int drif3_data0_a_mux[] = {
RIF3_D0_A_MARK,
};
static const unsigned int drif3_data1_a_pins[] = {
/* D1 */
RCAR_GP_PIN(6, 20),
};
static const unsigned int drif3_data1_a_mux[] = {
RIF3_D1_A_MARK,
};
static const unsigned int drif3_ctrl_b_pins[] = {
/* CLK, SYNC */
RCAR_GP_PIN(6, 24), RCAR_GP_PIN(6, 25),
};
static const unsigned int drif3_ctrl_b_mux[] = {
RIF3_CLK_B_MARK, RIF3_SYNC_B_MARK,
};
static const unsigned int drif3_data0_b_pins[] = {
/* D0 */
RCAR_GP_PIN(6, 28),
};
static const unsigned int drif3_data0_b_mux[] = {
RIF3_D0_B_MARK,
};
static const unsigned int drif3_data1_b_pins[] = {
/* D1 */
RCAR_GP_PIN(6, 29),
};
static const unsigned int drif3_data1_b_mux[] = {
RIF3_D1_B_MARK,
};
/* - HSCIF0 ----------------------------------------------------------------- */
static const unsigned int hscif0_data_pins[] = {
/* RX, TX */
@ -3346,6 +3563,36 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(canfd0_data_a),
SH_PFC_PIN_GROUP(canfd0_data_b),
SH_PFC_PIN_GROUP(canfd1_data),
SH_PFC_PIN_GROUP(drif0_ctrl_a),
SH_PFC_PIN_GROUP(drif0_data0_a),
SH_PFC_PIN_GROUP(drif0_data1_a),
SH_PFC_PIN_GROUP(drif0_ctrl_b),
SH_PFC_PIN_GROUP(drif0_data0_b),
SH_PFC_PIN_GROUP(drif0_data1_b),
SH_PFC_PIN_GROUP(drif0_ctrl_c),
SH_PFC_PIN_GROUP(drif0_data0_c),
SH_PFC_PIN_GROUP(drif0_data1_c),
SH_PFC_PIN_GROUP(drif1_ctrl_a),
SH_PFC_PIN_GROUP(drif1_data0_a),
SH_PFC_PIN_GROUP(drif1_data1_a),
SH_PFC_PIN_GROUP(drif1_ctrl_b),
SH_PFC_PIN_GROUP(drif1_data0_b),
SH_PFC_PIN_GROUP(drif1_data1_b),
SH_PFC_PIN_GROUP(drif1_ctrl_c),
SH_PFC_PIN_GROUP(drif1_data0_c),
SH_PFC_PIN_GROUP(drif1_data1_c),
SH_PFC_PIN_GROUP(drif2_ctrl_a),
SH_PFC_PIN_GROUP(drif2_data0_a),
SH_PFC_PIN_GROUP(drif2_data1_a),
SH_PFC_PIN_GROUP(drif2_ctrl_b),
SH_PFC_PIN_GROUP(drif2_data0_b),
SH_PFC_PIN_GROUP(drif2_data1_b),
SH_PFC_PIN_GROUP(drif3_ctrl_a),
SH_PFC_PIN_GROUP(drif3_data0_a),
SH_PFC_PIN_GROUP(drif3_data1_a),
SH_PFC_PIN_GROUP(drif3_ctrl_b),
SH_PFC_PIN_GROUP(drif3_data0_b),
SH_PFC_PIN_GROUP(drif3_data1_b),
SH_PFC_PIN_GROUP(hscif0_data),
SH_PFC_PIN_GROUP(hscif0_clk),
SH_PFC_PIN_GROUP(hscif0_ctrl),
@ -3629,6 +3876,48 @@ static const char * const canfd1_groups[] = {
"canfd1_data",
};
static const char * const drif0_groups[] = {
"drif0_ctrl_a",
"drif0_data0_a",
"drif0_data1_a",
"drif0_ctrl_b",
"drif0_data0_b",
"drif0_data1_b",
"drif0_ctrl_c",
"drif0_data0_c",
"drif0_data1_c",
};
static const char * const drif1_groups[] = {
"drif1_ctrl_a",
"drif1_data0_a",
"drif1_data1_a",
"drif1_ctrl_b",
"drif1_data0_b",
"drif1_data1_b",
"drif1_ctrl_c",
"drif1_data0_c",
"drif1_data1_c",
};
static const char * const drif2_groups[] = {
"drif2_ctrl_a",
"drif2_data0_a",
"drif2_data1_a",
"drif2_ctrl_b",
"drif2_data0_b",
"drif2_data1_b",
};
static const char * const drif3_groups[] = {
"drif3_ctrl_a",
"drif3_data0_a",
"drif3_data1_a",
"drif3_ctrl_b",
"drif3_data0_b",
"drif3_data1_b",
};
static const char * const hscif0_groups[] = {
"hscif0_data",
"hscif0_clk",
@ -3972,6 +4261,10 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(can_clk),
SH_PFC_FUNCTION(canfd0),
SH_PFC_FUNCTION(canfd1),
SH_PFC_FUNCTION(drif0),
SH_PFC_FUNCTION(drif1),
SH_PFC_FUNCTION(drif2),
SH_PFC_FUNCTION(drif3),
SH_PFC_FUNCTION(hscif0),
SH_PFC_FUNCTION(hscif1),
SH_PFC_FUNCTION(hscif2),
@ -4765,8 +5058,28 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = {
{ },
};
static int r8a7795_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
{
int bit = -EINVAL;
*pocctrl = 0xe6060380;
if (pin >= RCAR_GP_PIN(3, 0) && pin <= RCAR_GP_PIN(3, 11))
bit = pin & 0x1f;
if (pin >= RCAR_GP_PIN(4, 0) && pin <= RCAR_GP_PIN(4, 17))
bit = (pin & 0x1f) + 12;
return bit;
}
static const struct sh_pfc_soc_operations r8a7795_pinmux_ops = {
.pin_to_pocctrl = r8a7795_pin_to_pocctrl,
};
const struct sh_pfc_soc_info r8a7795_pinmux_info = {
.name = "r8a77950_pfc",
.ops = &r8a7795_pinmux_ops,
.unlock_reg = 0xe6060000, /* PMMR */
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },

View File

@ -1625,7 +1625,6 @@ static const struct pinmux_func pinmux_func_gpios[] = {
GPIO_FN(VBIOS_CS),
/* PTW (mobule: LBSC, EVC, SCIF) */
GPIO_FN(A16),
GPIO_FN(A15),
GPIO_FN(A14),
GPIO_FN(A13),

View File

@ -632,19 +632,21 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
}
case PIN_CONFIG_POWER_SOURCE: {
int ret;
u32 pocctrl, val;
int bit;
if (!pfc->info->ops || !pfc->info->ops->get_io_voltage)
if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl)
return -ENOTSUPP;
bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl);
if (WARN(bit < 0, "invalid pin %#x", _pin))
return bit;
spin_lock_irqsave(&pfc->lock, flags);
ret = pfc->info->ops->get_io_voltage(pfc, _pin);
val = sh_pfc_read_reg(pfc, pocctrl, 32);
spin_unlock_irqrestore(&pfc->lock, flags);
if (ret < 0)
return ret;
*config = ret;
*config = (val & BIT(bit)) ? 3300 : 1800;
break;
}
@ -696,19 +698,28 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
}
case PIN_CONFIG_POWER_SOURCE: {
unsigned int arg =
pinconf_to_config_argument(configs[i]);
int ret;
unsigned int mV = pinconf_to_config_argument(configs[i]);
u32 pocctrl, val;
int bit;
if (!pfc->info->ops || !pfc->info->ops->set_io_voltage)
if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl)
return -ENOTSUPP;
spin_lock_irqsave(&pfc->lock, flags);
ret = pfc->info->ops->set_io_voltage(pfc, _pin, arg);
spin_unlock_irqrestore(&pfc->lock, flags);
bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl);
if (WARN(bit < 0, "invalid pin %#x", _pin))
return bit;
if (ret)
return ret;
if (mV != 1800 && mV != 3300)
return -EINVAL;
spin_lock_irqsave(&pfc->lock, flags);
val = sh_pfc_read_reg(pfc, pocctrl, 32);
if (mV == 3300)
val |= BIT(bit);
else
val &= ~BIT(bit);
sh_pfc_write_reg(pfc, pocctrl, 32, val);
spin_unlock_irqrestore(&pfc->lock, flags);
break;
}
@ -803,8 +814,5 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
pmx->pctl_desc.npins = pfc->info->nr_pins;
pmx->pctl = devm_pinctrl_register(pfc->dev, &pmx->pctl_desc, pmx);
if (IS_ERR(pmx->pctl))
return PTR_ERR(pmx->pctl);
return 0;
return PTR_ERR_OR_ZERO(pmx->pctl);
}

View File

@ -13,6 +13,7 @@
#include <linux/bug.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/spinlock.h>
#include <linux/stringify.h>
enum {
@ -182,16 +183,38 @@ struct pinmux_range {
u16 force;
};
struct sh_pfc;
struct sh_pfc_window {
phys_addr_t phys;
void __iomem *virt;
unsigned long size;
};
struct sh_pfc_pin_range;
struct sh_pfc {
struct device *dev;
const struct sh_pfc_soc_info *info;
spinlock_t lock;
unsigned int num_windows;
struct sh_pfc_window *windows;
unsigned int num_irqs;
unsigned int *irqs;
struct sh_pfc_pin_range *ranges;
unsigned int nr_ranges;
unsigned int nr_gpio_pins;
struct sh_pfc_chip *gpio;
};
struct sh_pfc_soc_operations {
int (*init)(struct sh_pfc *pfc);
unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin);
void (*set_bias)(struct sh_pfc *pfc, unsigned int pin,
unsigned int bias);
int (*get_io_voltage)(struct sh_pfc *pfc, unsigned int pin);
int (*set_io_voltage)(struct sh_pfc *pfc, unsigned int pin,
u16 voltage_mV);
int (*pin_to_pocctrl)(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl);
};
struct sh_pfc_soc_info {
@ -227,6 +250,30 @@ struct sh_pfc_soc_info {
u32 unlock_reg;
};
extern const struct sh_pfc_soc_info emev2_pinmux_info;
extern const struct sh_pfc_soc_info r8a73a4_pinmux_info;
extern const struct sh_pfc_soc_info r8a7740_pinmux_info;
extern const struct sh_pfc_soc_info r8a7778_pinmux_info;
extern const struct sh_pfc_soc_info r8a7779_pinmux_info;
extern const struct sh_pfc_soc_info r8a7790_pinmux_info;
extern const struct sh_pfc_soc_info r8a7791_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 sh7203_pinmux_info;
extern const struct sh_pfc_soc_info sh7264_pinmux_info;
extern const struct sh_pfc_soc_info sh7269_pinmux_info;
extern const struct sh_pfc_soc_info sh73a0_pinmux_info;
extern const struct sh_pfc_soc_info sh7720_pinmux_info;
extern const struct sh_pfc_soc_info sh7722_pinmux_info;
extern const struct sh_pfc_soc_info sh7723_pinmux_info;
extern const struct sh_pfc_soc_info sh7724_pinmux_info;
extern const struct sh_pfc_soc_info sh7734_pinmux_info;
extern const struct sh_pfc_soc_info sh7757_pinmux_info;
extern const struct sh_pfc_soc_info sh7785_pinmux_info;
extern const struct sh_pfc_soc_info sh7786_pinmux_info;
extern const struct sh_pfc_soc_info shx3_pinmux_info;
/* -----------------------------------------------------------------------------
* Helper macros to create pin and port lists
*/

View File

@ -5424,8 +5424,10 @@ static int atlas7_pinmux_probe(struct platform_device *pdev)
if (ret)
return ret;
pmx->sys2pci_base = devm_ioremap_resource(&pdev->dev, &res);
if (IS_ERR(pmx->sys2pci_base))
if (IS_ERR(pmx->sys2pci_base)) {
of_node_put(sys2pci_np);
return -ENOMEM;
}
pmx->dev = &pdev->dev;

View File

@ -13,4 +13,10 @@ config PINCTRL_STM32F429
default MACH_STM32F429
select PINCTRL_STM32
config PINCTRL_STM32F746
bool "STMicroelectronics STM32F746 pin control" if COMPILE_TEST && !MACH_STM32F746
depends on OF
default MACH_STM32F746
select PINCTRL_STM32
endif

View File

@ -3,3 +3,4 @@ obj-$(CONFIG_PINCTRL_STM32) += pinctrl-stm32.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_STM32F429) += pinctrl-stm32f429.o
obj-$(CONFIG_PINCTRL_STM32F746) += pinctrl-stm32f746.o

View File

@ -638,8 +638,8 @@ static u32 stm32_pconf_get_bias(struct stm32_gpio_bank *bank,
return (val >> (offset * 2));
}
static bool stm32_pconf_input_get(struct stm32_gpio_bank *bank,
unsigned int offset)
static bool stm32_pconf_get(struct stm32_gpio_bank *bank,
unsigned int offset, bool dir)
{
unsigned long flags;
u32 val;
@ -647,23 +647,12 @@ static bool stm32_pconf_input_get(struct stm32_gpio_bank *bank,
clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
val = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset));
spin_unlock_irqrestore(&bank->lock, flags);
clk_disable(bank->clk);
return val;
}
static bool stm32_pconf_output_get(struct stm32_gpio_bank *bank,
unsigned int offset)
{
unsigned long flags;
u32 val;
clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
val = !!(readl_relaxed(bank->base + STM32_GPIO_ODR) & BIT(offset));
if (dir)
val = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) &
BIT(offset));
else
val = !!(readl_relaxed(bank->base + STM32_GPIO_ODR) &
BIT(offset));
spin_unlock_irqrestore(&bank->lock, flags);
clk_disable(bank->clk);
@ -772,7 +761,7 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev,
switch (mode) {
/* input */
case 0:
val = stm32_pconf_input_get(bank, offset);
val = stm32_pconf_get(bank, offset, true);
seq_printf(s, "- %s - %s",
val ? "high" : "low",
biasing[bias]);
@ -782,7 +771,7 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev,
case 1:
drive = stm32_pconf_get_driving(bank, offset);
speed = stm32_pconf_get_speed(bank, offset);
val = stm32_pconf_output_get(bank, offset);
val = stm32_pconf_get(bank, offset, false);
seq_printf(s, "- %s - %s - %s - %s %s",
val ? "high" : "low",
drive ? "open drain" : "push pull",

File diff suppressed because it is too large Load Diff

View File

@ -180,17 +180,17 @@ static const struct sunxi_desc_pin sun8i_a23_pins[] = {
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand"), /* DQS */
SUNXI_FUNCTION(0x2, "nand0"), /* DQS */
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),

View File

@ -140,17 +140,17 @@ static const struct sunxi_desc_pin sun8i_a33_pins[] = {
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand"), /* DQS */
SUNXI_FUNCTION(0x2, "nand0"), /* DQS */
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),

View File

@ -219,17 +219,17 @@ static const struct sunxi_desc_pin sun8i_h3_pins[] = {
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand"), /* DQS */
SUNXI_FUNCTION(0x2, "nand0"), /* DQS */
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),

View File

@ -632,11 +632,11 @@ static void tegra_pinctrl_clear_parked_bits(struct tegra_pmx *pmx)
u32 val;
for (i = 0; i < pmx->soc->ngroups; ++i) {
if (pmx->soc->groups[i].parked_reg >= 0) {
g = &pmx->soc->groups[i];
val = pmx_readl(pmx, g->parked_bank, g->parked_reg);
g = &pmx->soc->groups[i];
if (g->parked_bit >= 0) {
val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
val &= ~(1 << g->parked_bit);
pmx_writel(pmx, val, g->parked_bank, g->parked_reg);
pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
}
}
}

View File

@ -93,9 +93,7 @@ struct tegra_function {
* @tri_reg: Tri-state register offset.
* @tri_bank: Tri-state register bank.
* @tri_bit: Tri-state register bit.
* @parked_reg: Parked register offset. -1 if unsupported.
* @parked_bank: Parked register bank. 0 if unsupported.
* @parked_bit: Parked register bit. 0 if unsupported.
* @parked_bit: Parked register bit. -1 if unsupported.
* @einput_bit: Enable-input register bit.
* @odrain_bit: Open-drain register bit.
* @lock_bit: Lock register bit.
@ -138,12 +136,10 @@ struct tegra_pingroup {
s16 pupd_reg;
s16 tri_reg;
s16 drv_reg;
s16 parked_reg;
u32 mux_bank:2;
u32 pupd_bank:2;
u32 tri_bank:2;
u32 drv_bank:2;
u32 parked_bank:2;
s32 mux_bit:6;
s32 pupd_bit:6;
s32 tri_bit:6;

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