Commit 3dbde57a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pinctrl-for-v3.11-1' of...

Merge tag 'pinctrl-for-v3.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control changes from Linus Walleij:

 - A large slew of improvements of the Genric pin configuration support,
   and deployment in four different platforms: Rockchip, Super-H PFC,
   ABx500 and TZ1090.  Support BIAS_BUS_HOLD, get device tree parsing
   and debugfs support into shape.

 - We also have device tree support with generic naming conventions for
   the generic pin configuration.

 - Delete the unused and confusing direct pinconf API.  Now state
   transitions is *the* way to control pins and multiplexing.

 - New drivers for Rockchip, TZ1090, and TZ1090 PDC.

 - Two pin control states related to power management are now handled in
   the device core: "sleep" and "idle", removing a lot of boilerplate
   code in drivers.  We do not yet know if this is the final word for
   pin PM, but it already make things a lot easier to handle.

 - Handle sparse GPIO ranges passing a list of disparate pins, and
   utilize these in the new BayTrail (x86 Atom SoC) driver.

 - Make the sunxi (AllWinner) driver handle external interrupts.

 - Make it possible for pinctrl-single to handle the case where several
   pins are managed by a single register, and augment it to handle sleep
   modes.

 - Cleanups and improvements for the abx500 drivers.

 - Move Sirf pin control drivers to their own directory, support
   save/restore of context and add support for the SiRFatlas6 SoC.

 - PMU muxing for the Dove pinctrl driver.

 - Finalization and support for VF610 in the i.MX6 pinctrl driver.

 - Smoothen out various Exynos rough edges.

 - Generic cleanups of various kinds.

* tag 'pinctrl-for-v3.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (82 commits)
  pinctrl: vt8500: wmt: remove redundant dev_err call in wmt_pinctrl_probe()
  pinctrl: remove bindings for pinconf options needing more thought
  pinctrl: remove slew-rate parameter from tz1090
  pinctrl: set unit for debounce time pinconfig to usec
  pinctrl: more clarifications for generic pull configs
  pinctrl: rip out the direct pinconf API
  pinctrl-tz1090-pdc: add TZ1090 PDC pinctrl driver
  pinctrl-tz1090: add TZ1090 pinctrl driver
  pinctrl: samsung: Staticize drvdata_list
  pinctrl: rockchip: Add missing irq_gc_unlock() call before return error
  pinctrl: abx500: rework error path
  pinctrl: abx500: suppress hardcoded value
  pinctrl: abx500: factorize code
  pinctrl: abx500: fix abx500_gpio_get()
  pinctrl: abx500: fix abx500_pin_config_set()
  pinctrl: abx500: Add device tree support
  sh-pfc: Guard DT parsing with #ifdef CONFIG_OF
  pinctrl: add Intel BayTrail GPIO/pinctrl support
  pinctrl: fix pinconf_ops::pin_config_dbg_parse_modify kerneldoc
  pinctrl: Staticize local symbols
  ...

Conflicts:
	drivers/net/ethernet/ti/davinci_mdio.c
	drivers/pinctrl/Makefile
parents a6e6d863 2207a4e1
Freescale Vybrid VF610 IOMUX Controller
Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
and usage.
Required properties:
- compatible: "fsl,vf610-iomuxc"
- fsl,pins: two integers array, represents a group of pins mux and config
setting. The format is fsl,pins = <PIN_FUNC_ID CONFIG>, PIN_FUNC_ID is
a pin working on a specific function, CONFIG is the pad setting value
such as pull-up, speed, ode for this pin. Please refer to Vybrid VF610
datasheet for the valid pad config settings.
CONFIG bits definition:
PAD_CTL_SPEED_LOW (1 << 12)
PAD_CTL_SPEED_MED (2 << 12)
PAD_CTL_SPEED_HIGH (3 << 12)
PAD_CTL_SRE_FAST (1 << 11)
PAD_CTL_SRE_SLOW (0 << 11)
PAD_CTL_ODE (1 << 10)
PAD_CTL_HYS (1 << 9)
PAD_CTL_DSE_DISABLE (0 << 6)
PAD_CTL_DSE_150ohm (1 << 6)
PAD_CTL_DSE_75ohm (2 << 6)
PAD_CTL_DSE_50ohm (3 << 6)
PAD_CTL_DSE_37ohm (4 << 6)
PAD_CTL_DSE_30ohm (5 << 6)
PAD_CTL_DSE_25ohm (6 << 6)
PAD_CTL_DSE_20ohm (7 << 6)
PAD_CTL_PUS_100K_DOWN (0 << 4)
PAD_CTL_PUS_47K_UP (1 << 4)
PAD_CTL_PUS_100K_UP (2 << 4)
PAD_CTL_PUS_22K_UP (3 << 4)
PAD_CTL_PKE (1 << 3)
PAD_CTL_PUE (1 << 2)
PAD_CTL_OBE_ENABLE (1 << 1)
PAD_CTL_IBE_ENABLE (1 << 0)
PAD_CTL_OBE_IBE_ENABLE (3 << 0)
Please refer to vf610-pinfunc.h in device tree source folder
for all available PIN_FUNC_ID for Vybrid VF610.
ImgTec TZ1090 PDC pin controller
Required properties:
- compatible: "img,tz1090-pdc-pinctrl"
- reg: Should contain the register physical address and length of the
SOC_GPIO_CONTROL registers in the PDC register region.
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".
TZ1090-PDC's pin configuration nodes act as a container for an abitrary number
of subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function. For this reason, even seemingly boolean
values are actually tristates in this binding: unspecified, off, or on.
Unspecified is represented as an absent property, and off/on are represented as
integer values 0 and 1.
Required subnode-properties:
- tz1090,pins : An array of strings. Each string contains the name of a pin or
group. Valid values for these names are listed below.
Optional subnode-properties:
- tz1090,function: A string containing the name of the function to mux to the
pin or group. Valid values for function names are listed below, including
which pingroups can be muxed to them.
- supported generic pinconfig properties (for further details see
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt):
- bias-disable
- bias-high-impedance
- bias-bus-hold
- bias-pull-up
- bias-pull-down
- input-schmitt-enable
- input-schmitt-disable
- drive-strength: Integer, control drive strength of pins in mA.
2: 2mA
4: 4mA
8: 8mA
12: 12mA
- low-power-enable: Flag, power-on-start weak pull-down for invalid power.
- low-power-disable: Flag, power-on-start weak pull-down disabled.
Note that many of these properties are only valid for certain specific pins
or groups. See the TZ1090 TRM for complete details regarding which groups
support which functionality. The Linux pinctrl driver may also be a useful
reference.
Valid values for pin and group names are:
pins:
These all support bias-high-impediance, bias-pull-up, bias-pull-down, and
bias-bus-hold (which can also be provided to any of the groups below to set
it for all gpio pins in that group).
gpio0, gpio1, sys_wake0, sys_wake1, sys_wake2, ir_data, ext_power.
mux groups:
These all support function.
gpio0
pins: gpio0.
function: ir_mod_stable_out.
gpio1
pins: gpio1.
function: ir_mod_power_out.
drive groups:
These support input-schmitt-enable, input-schmitt-disable,
drive-strength, low-power-enable, and low-power-disable.
pdc
pins: gpio0, gpio1, sys_wake0, sys_wake1, sys_wake2, ir_data,
ext_power.
Example:
pinctrl_pdc: pinctrl@02006500 {
#gpio-range-cells = <3>;
compatible = "img,tz1090-pdc-pinctrl";
reg = <0x02006500 0x100>;
};
Example board file extracts:
&pinctrl_pdc {
pinctrl-names = "default";
pinctrl-0 = <&syswake_default>;
syswake_default: syswakes {
syswake_cfg {
tz1090,pins = "sys_wake0",
"sys_wake1",
"sys_wake2";
pull-up;
};
};
irmod_default: irmod {
gpio0_cfg {
tz1090,pins = "gpio0";
tz1090,function = "ir_mod_stable_out";
};
gpio1_cfg {
tz1090,pins = "gpio1";
tz1090,function = "ir_mod_power_out";
};
};
};
ir: ir@02006200 {
pinctrl-names = "default";
pinctrl-0 = <&irmod_default>;
};
ImgTec TZ1090 pin controller
Required properties:
- compatible: "img,tz1090-pinctrl"
- reg: Should contain the register physical address and length of the pad
configuration registers (CR_PADS_* and CR_IF_CTL0).
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".
TZ1090's pin configuration nodes act as a container for an abitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function. For this reason, even seemingly boolean
values are actually tristates in this binding: unspecified, off, or on.
Unspecified is represented as an absent property, and off/on are represented as
integer values 0 and 1.
Required subnode-properties:
- tz1090,pins : An array of strings. Each string contains the name of a pin or
group. Valid values for these names are listed below.
Optional subnode-properties:
- tz1090,function: A string containing the name of the function to mux to the
pin or group. Valid values for function names are listed below, including
which pingroups can be muxed to them.
- supported generic pinconfig properties (for further details see
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt):
- bias-disable
- bias-high-impedance
- bias-bus-hold
- bias-pull-up
- bias-pull-down
- input-schmitt-enable
- input-schmitt-disable
- drive-strength: Integer, control drive strength of pins in mA.
2: 2mA
4: 4mA
8: 8mA
12: 12mA
Note that many of these properties are only valid for certain specific pins
or groups. See the TZ1090 TRM for complete details regarding which groups
support which functionality. The Linux pinctrl driver may also be a useful
reference.
Valid values for pin and group names are:
gpio pins:
These all support bias-high-impediance, bias-pull-up, bias-pull-down, and
bias-bus-hold (which can also be provided to any of the groups below to set
it for all pins in that group).
They also all support the some form of muxing. Any pins which are contained
in one of the mux groups (see below) can be muxed only to the functions
supported by the mux group. All other pins can be muxed to the "perip"
function which which enables them with their intended peripheral.
Different pins in the same mux group cannot be muxed to different functions,
however it is possible to mux only a subset of the pins in a mux group to a
particular function and leave the remaining pins unmuxed. This is useful if
the board connects certain pins in a group to other devices to be controlled
by GPIO, and you don't want the usual peripheral to have any control of the
pin.
ant_sel0, ant_sel1, gain0, gain1, gain2, gain3, gain4, gain5, gain6, gain7,
i2s_bclk_out, i2s_din, i2s_dout0, i2s_dout1, i2s_dout2, i2s_lrclk_out,
i2s_mclk, pa_on, pdm_a, pdm_b, pdm_c, pdm_d, pll_on, rx_hp, rx_on,
scb0_sclk, scb0_sdat, scb1_sclk, scb1_sdat, scb2_sclk, scb2_sdat, sdh_cd,
sdh_clk_in, sdh_wp, sdio_clk, sdio_cmd, sdio_d0, sdio_d1, sdio_d2, sdio_d3,
spi0_cs0, spi0_cs1, spi0_cs2, spi0_din, spi0_dout, spi0_mclk, spi1_cs0,
spi1_cs1, spi1_cs2, spi1_din, spi1_dout, spi1_mclk, tft_blank_ls, tft_blue0,
tft_blue1, tft_blue2, tft_blue3, tft_blue4, tft_blue5, tft_blue6, tft_blue7,
tft_green0, tft_green1, tft_green2, tft_green3, tft_green4, tft_green5,
tft_green6, tft_green7, tft_hsync_nr, tft_panelclk, tft_pwrsave, tft_red0,
tft_red1, tft_red2, tft_red3, tft_red4, tft_red5, tft_red6, tft_red7,
tft_vd12acb, tft_vdden_gd, tft_vsync_ns, tx_on, uart0_cts, uart0_rts,
uart0_rxd, uart0_txd, uart1_rxd, uart1_txd.
bias-high-impediance: supported.
bias-pull-up: supported.
bias-pull-down: supported.
bias-bus-hold: supported.
function: perip or those supported by pin's mux group.
other pins:
These other pins are part of various pin groups below, but can't be
controlled as GPIOs. They do however support bias-high-impediance,
bias-pull-up, bias-pull-down, and bias-bus-hold (which can also be provided
to any of the groups below to set it for all pins in that group).
clk_out0, clk_out1, tck, tdi, tdo, tms, trst.
bias-high-impediance: supported.
bias-pull-up: supported.
bias-pull-down: supported.
bias-bus-hold: supported.
mux groups:
These all support function, and some support drive configs.
afe
pins: tx_on, rx_on, pll_on, pa_on, rx_hp, ant_sel0,
ant_sel1, gain0, gain1, gain2, gain3, gain4,
gain5, gain6, gain7.
function: afe, ts_out_0.
input-schmitt-enable: supported.
input-schmitt-disable: supported.
drive-strength: supported.
pdm_d
pins: pdm_d.
function: pdm_dac, usb_vbus.
sdh
pins: sdh_cd, sdh_wp, sdh_clk_in.
function: sdh, sdio.
sdio
pins: sdio_clk, sdio_cmd, sdio_d0, sdio_d1, sdio_d2,
sdio_d3.
function: sdio, sdh.
spi1_cs2
pins: spi1_cs2.
function: spi1_cs2, usb_vbus.
tft
pins: tft_red0, tft_red1, tft_red2, tft_red3,
tft_red4, tft_red5, tft_red6, tft_red7,
tft_green0, tft_green1, tft_green2, tft_green3,
tft_green4, tft_green5, tft_green6, tft_green7,
tft_blue0, tft_blue1, tft_blue2, tft_blue3,
tft_blue4, tft_blue5, tft_blue6, tft_blue7,
tft_vdden_gd, tft_panelclk, tft_blank_ls,
tft_vsync_ns, tft_hsync_nr, tft_vd12acb,
tft_pwrsave.
function: tft, ext_dac, not_iqadc_stb, iqdac_stb, ts_out_1,
lcd_trace, phy_ringosc.
input-schmitt-enable: supported.
input-schmitt-disable: supported.
drive-strength: supported.
drive groups:
These all support input-schmitt-enable, input-schmitt-disable,
and drive-strength.
jtag
pins: tck, trst, tdi, tdo, tms.
scb1
pins: scb1_sdat, scb1_sclk.
scb2
pins: scb2_sdat, scb2_sclk.
spi0
pins: spi0_mclk, spi0_cs0, spi0_cs1, spi0_cs2, spi0_dout, spi0_din.
spi1
pins: spi1_mclk, spi1_cs0, spi1_cs1, spi1_cs2, spi1_dout, spi1_din.
uart
pins: uart0_txd, uart0_rxd, uart0_rts, uart0_cts,
uart1_txd, uart1_rxd.
drive_i2s
pins: clk_out1, i2s_din, i2s_dout0, i2s_dout1, i2s_dout2,
i2s_lrclk_out, i2s_bclk_out, i2s_mclk.
drive_pdm
pins: clk_out0, pdm_b, pdm_a.
drive_scb0
pins: scb0_sclk, scb0_sdat, pdm_d, pdm_c.
drive_sdio
pins: sdio_clk, sdio_cmd, sdio_d0, sdio_d1, sdio_d2, sdio_d3,
sdh_wp, sdh_cd, sdh_clk_in.
convenience groups:
These are just convenient groupings of pins and don't support any drive
configs.
uart0
pins: uart0_cts, uart0_rts, uart0_rxd, uart0_txd.
uart1
pins: uart1_rxd, uart1_txd.
scb0
pins: scb0_sclk, scb0_sdat.
i2s
pins: i2s_bclk_out, i2s_din, i2s_dout0, i2s_dout1, i2s_dout2,
i2s_lrclk_out, i2s_mclk.
Example:
pinctrl: pinctrl@02005800 {
#gpio-range-cells = <3>;
compatible = "img,tz1090-pinctrl";
reg = <0x02005800 0xe4>;
};
Example board file extract:
&pinctrl {
uart0_default: uart0 {
uart0_cfg {
tz1090,pins = "uart0_rxd",
"uart0_txd";
tz1090,function = "perip";
};
};
tft_default: tft {
tft_cfg {
tz1090,pins = "tft";
tz1090,function = "tft";
};
};
};
uart@02004b00 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_default>;
};
...@@ -10,29 +10,31 @@ Required properties: ...@@ -10,29 +10,31 @@ Required properties:
Available mpp pins/groups and functions: Available mpp pins/groups and functions:
Note: brackets (x) are not part of the mpp name for marvell,function and given Note: brackets (x) are not part of the mpp name for marvell,function and given
only for more detailed description in this document. only for more detailed description in this document.
Note: pmu* also allows for Power Management functions listed below
name pins functions name pins functions
================================================================================ ================================================================================
mpp0 0 gpio, pmu, uart2(rts), sdio0(cd), lcd0(pwm) mpp0 0 gpio, pmu, uart2(rts), sdio0(cd), lcd0(pwm), pmu*
mpp1 1 gpio, pmu, uart2(cts), sdio0(wp), lcd1(pwm) mpp1 1 gpio, pmu, uart2(cts), sdio0(wp), lcd1(pwm), pmu*
mpp2 2 gpio, pmu, uart2(txd), sdio0(buspwr), sata(prsnt), mpp2 2 gpio, pmu, uart2(txd), sdio0(buspwr), sata(prsnt),
uart1(rts) uart1(rts), pmu*
mpp3 3 gpio, pmu, uart2(rxd), sdio0(ledctrl), sata(act), mpp3 3 gpio, pmu, uart2(rxd), sdio0(ledctrl), sata(act),
uart1(cts), lcd-spi(cs1) uart1(cts), lcd-spi(cs1), pmu*
mpp4 4 gpio, pmu, uart3(rts), sdio1(cd), spi1(miso) mpp4 4 gpio, pmu, uart3(rts), sdio1(cd), spi1(miso), pmu*
mpp5 5 gpio, pmu, uart3(cts), sdio1(wp), spi1(cs) mpp5 5 gpio, pmu, uart3(cts), sdio1(wp), spi1(cs), pmu*
mpp6 6 gpio, pmu, uart3(txd), sdio1(buspwr), spi1(mosi) mpp6 6 gpio, pmu, uart3(txd), sdio1(buspwr), spi1(mosi), pmu*
mpp7 7 gpio, pmu, uart3(rxd), sdio1(ledctrl), spi1(sck) mpp7 7 gpio, pmu, uart3(rxd), sdio1(ledctrl), spi1(sck), pmu*
mpp8 8 gpio, pmu, watchdog(rstout) mpp8 8 gpio, pmu, watchdog(rstout), pmu*
mpp9 9 gpio, pmu, pex1(clkreq) mpp9 9 gpio, pmu, pex1(clkreq), pmu*
mpp10 10 gpio, pmu, ssp(sclk) mpp10 10 gpio, pmu, ssp(sclk), pmu*
mpp11 11 gpio, pmu, sata(prsnt), sata-1(act), sdio0(ledctrl), mpp11 11 gpio, pmu, sata(prsnt), sata-1(act), sdio0(ledctrl),
sdio1(ledctrl), pex0(clkreq) sdio1(ledctrl), pex0(clkreq), pmu*
mpp12 12 gpio, pmu, uart2(rts), audio0(extclk), sdio1(cd), sata(act) mpp12 12 gpio, pmu, uart2(rts), audio0(extclk), sdio1(cd),
sata(act), pmu*
mpp13 13 gpio, pmu, uart2(cts), audio1(extclk), sdio1(wp), mpp13 13 gpio, pmu, uart2(cts), audio1(extclk), sdio1(wp),
ssp(extclk) ssp(extclk), pmu*
mpp14 14 gpio, pmu, uart2(txd), sdio1(buspwr), ssp(rxd) mpp14 14 gpio, pmu, uart2(txd), sdio1(buspwr), ssp(rxd), pmu*
mpp15 15 gpio, pmu, uart2(rxd), sdio1(ledctrl), ssp(sfrm) mpp15 15 gpio, pmu, uart2(rxd), sdio1(ledctrl), ssp(sfrm), pmu*
mpp16 16 gpio, uart3(rts), sdio0(cd), ac97(sdi1), lcd-spi(cs1) mpp16 16 gpio, uart3(rts), sdio0(cd), ac97(sdi1), lcd-spi(cs1)
mpp17 17 gpio, uart3(cts), sdio0(wp), ac97(sdi2), twsi(sda), mpp17 17 gpio, uart3(cts), sdio0(wp), ac97(sdi2), twsi(sda),
ac97-1(sysclko) ac97-1(sysclko)
...@@ -57,6 +59,21 @@ mpp_nand 64-71 gpo, nand ...@@ -57,6 +59,21 @@ mpp_nand 64-71 gpo, nand
audio0 - i2s, ac97 audio0 - i2s, ac97
twsi - none, opt1, opt2, opt3 twsi - none, opt1, opt2, opt3
Power Management functions (pmu*):
pmu-nc Pin not driven by any PM function
pmu-low Pin driven low (0)
pmu-high Pin driven high (1)
pmic(sdi) Pin is used for PMIC SDI
cpu-pwr-down Pin is used for CPU_PWRDWN
standby-pwr-down Pin is used for STBY_PWRDWN
core-pwr-good Pin is used for CORE_PWR_GOOD (Pins 0-7 only)
cpu-pwr-good Pin is used for CPU_PWR_GOOD (Pins 8-15 only)
bat-fault Pin is used for BATTERY_FAULT
ext0-wakeup Pin is used for EXT0_WU
ext1-wakeup Pin is used for EXT0_WU
ext2-wakeup Pin is used for EXT0_WU
pmu-blink Pin is used for blink function
Notes: Notes:
* group "mpp_audio1" allows the following functions and gpio pins: * group "mpp_audio1" allows the following functions and gpio pins:
- gpio : gpio on pins 52-57 - gpio : gpio on pins 52-57
......
...@@ -126,3 +126,51 @@ device; they may be grandchildren, for example. Whether this is legal, and ...@@ -126,3 +126,51 @@ device; they may be grandchildren, for example. Whether this is legal, and
whether there is any interaction between the child and intermediate parent whether there is any interaction between the child and intermediate parent
nodes, is again defined entirely by the binding for the individual pin nodes, is again defined entirely by the binding for the individual pin
controller device. controller device.
== Using generic pinconfig options ==
Generic pinconfig parameters can be used by defining a separate node containing
the applicable parameters (and optional values), like:
pcfg_pull_up: pcfg_pull_up {
bias-pull-up;
drive-strength = <20>;
};
This node should then be referenced in the appropriate pinctrl node as a phandle
and parsed in the driver using the pinconf_generic_parse_dt_config function.
Supported configuration parameters are:
bias-disable - disable any pin bias
bias-high-impedance - high impedance mode ("third-state", "floating")
bias-bus-hold - latch weakly
bias-pull-up - pull up the pin
bias-pull-down - pull down the pin
bias-pull-pin-default - use pin-default pull state
drive-push-pull - drive actively high and low
drive-open-drain - drive with open drain
drive-open-source - drive with open source
drive-strength - sink or source at most X mA
input-schmitt-enable - enable schmitt-trigger mode
input-schmitt-disable - disable schmitt-trigger mode
input-debounce - debounce mode with debound time X
low-power-enable - enable low power mode
low-power-disable - disable low power mode
output-low - set the pin to output mode with low level
output-high - set the pin to output mode with high level
Arguments for parameters:
- bias-pull-up, -down and -pin-default take as optional argument on hardware
supporting it the pull strength in Ohm. bias-disable will disable the pull.
- drive-strength takes as argument the target strength in mA.
- input-debounce takes the debounce time in usec as argument
or 0 to disable debouncing
All parameters not listed here, do not take an argument.
More in-depth documentation on these parameters can be found in
<include/linux/pinctrl/pinconfig-generic.h>
...@@ -18,7 +18,8 @@ Optional properties: ...@@ -18,7 +18,8 @@ Optional properties:
pin functions is ignored pin functions is ignored
- pinctrl-single,bit-per-mux : boolean to indicate that one register controls - pinctrl-single,bit-per-mux : boolean to indicate that one register controls
more than one pin more than one pin, for which "pinctrl-single,function-mask" property specifies
position mask of pin.
- pinctrl-single,drive-strength : array of value that are used to configure - pinctrl-single,drive-strength : array of value that are used to configure
drive strength in the pinmux register. They're value of drive strength drive strength in the pinmux register. They're value of drive strength
......
* Renesas Pin Function Controller (GPIO and Pin Mux/Config)
The Pin Function Controller (PFC) is a Pin Mux/Config controller. On SH7372,
SH73A0, R8A73A4 and R8A7740 it also acts as a GPIO controller.
Pin Control
-----------
Required Properties:
- compatible: should be one of the following.
- "renesas,pfc-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible pin-controller.
- "renesas,pfc-r8a7740": for R8A7740 (R-Mobile A1) compatible pin-controller.
- "renesas,pfc-r8a7778": for R8A7778 (R-Mobile M1) compatible pin-controller.
- "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller.
- "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller.
- "renesas,pfc-sh7372": for SH7372 (SH-Mobile AP4) compatible pin-controller.
- "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller.
- reg: Base address and length of each memory resource used by the pin
controller hardware module.
Optional properties:
- #gpio-range-cells: Mandatory when the PFC doesn't handle GPIO, forbidden
otherwise. Should be 3.
The PFC node also acts as a container for pin configuration nodes. Please refer
to pinctrl-bindings.txt in this directory for the definition of the term "pin
configuration node" and for the common pinctrl bindings used by client devices.
Each pin configuration node represents a desired configuration for a pin, a
pin group, or a list of pins or pin groups. The configuration can include the
function to select on those pin(s) and pin configuration parameters (such as
pull-up and pull-down).
Pin configuration nodes contain pin configuration properties, either directly
or grouped in child subnodes. Both pin muxing and configuration parameters can
be grouped in that way and referenced as a single pin configuration node by
client devices.
A configuration node or subnode must reference at least one pin (through the
pins or pin groups properties) and contain at least a function or one
configuration parameter. When the function is present only pin groups can be
used to reference pins.
All pin configuration nodes and subnodes names are ignored. All of those nodes
are parsed through phandles and processed purely based on their content.
Pin Configuration Node Properties:
- renesas,pins : An array of strings, each string containing the name of a pin.
- renesas,groups : An array of strings, each string containing the name of a pin
group.
- renesas,function: A string containing the name of the function to mux to the
pin group(s) specified by the renesas,groups property
Valid values for pin, group and function names can be found in the group and
function arrays of the PFC data file corresponding to the SoC
(drivers/pinctrl/sh-pfc/pfc-*.c)
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 and bias-pull-down.
GPIO
----
On SH7372, SH73A0, R8A73A4 and R8A7740 the PFC node is also a GPIO controller
node.
Required Properties:
- gpio-controller: Marks the device node as a gpio controller.
- #gpio-cells: Should be 2. The first cell is the GPIO number and the second
cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
The syntax of the gpio specifier used by client nodes should be the following
with values derived from the SoC user manual.
<[phandle of the gpio controller node]
[pin number within the gpio controller]
[flags]>
On other mach-shmobile platforms GPIO is handled by the gpio-rcar driver.
Please refer to Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt
for documentation of the GPIO device tree bindings on those platforms.
Examples
--------
Example 1: SH73A0 (SH-Mobile AG5) pin controller node
pfc: pfc@e6050000 {
compatible = "renesas,pfc-sh73a0";
reg = <0xe6050000 0x8000>,
<0xe605801c 0x1c>;
gpio-controller;
#gpio-cells = <2>;
};
Example 2: A GPIO LED node that references a GPIO
#include <dt-bindings/gpio/gpio.h>
leds {
compatible = "gpio-leds";
led1 {
gpios = <&pfc 20 GPIO_ACTIVE_LOW>;
};
};
Example 3: KZM-A9-GT (SH-Mobile AG5) default pin state hog and pin control maps
for the MMCIF and SCIFA4 devices
&pfc {
pinctrl-0 = <&scifa4_pins>;
pinctrl-names = "default";
mmcif_pins: mmcif {
mux {
renesas,groups = "mmc0_data8_0", "mmc0_ctrl_0";
renesas,function = "mmc0";
};
cfg {
renesas,groups = "mmc0_data8_0";
renesas,pins = "PORT279";
bias-pull-up;
};
};
scifa4_pins: scifa4 {
renesas,groups = "scifa4_data", "scifa4_ctrl";
renesas,function = "scifa4";
};
};
Example 4: KZM-A9-GT (SH-Mobile AG5) default pin state for the MMCIF device
&mmcif {
pinctrl-0 = <&mmcif_pins>;
pinctrl-names = "default";
bus-width = <8>;
vmmc-supply = <&reg_1p8v>;
status = "okay";
};
* Rockchip Pinmux Controller
The Rockchip Pinmux Controller, enables the IC
to share one PAD to several functional blocks. The sharing is done by
multiplexing the PAD input/output signals. For each PAD there are up to
4 muxing options with option 0 being the use as a GPIO.
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 Rockchip pin configuration node is a node of a group of pins which can be
used for a specific device or function. This node represents both mux and
config of the pins in that group. The 'pins' selects the function mode(also
named pin mode) this pin can work on and the 'config' configures various pad
settings such as pull-up, etc.
The pins are grouped into up to 5 individual pin banks which need to be
defined as gpio sub-nodes of the pinmux controller.
Required properties for iomux controller:
- compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
"rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
Required properties for gpio sub nodes:
- compatible: "rockchip,gpio-bank"
- reg: register of the gpio bank (different than the iomux registerset)
- interrupts: base interrupt of the gpio bank in the interrupt controller
- clocks: clock that drives this bank
- gpio-controller: identifies the node as a gpio controller and pin bank.
- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
binding is used, the amount of cells must be specified as 2. See generic
GPIO binding documentation for description of particular cells.
- interrupt-controller: identifies the controller node as interrupt-parent.
- #interrupt-cells: the value of this property should be 2 and the interrupt
cells should use the standard two-cell scheme described in
bindings/interrupt-controller/interrupts.txt
Required properties for pin configuration node:
- rockchip,pins: 3 integers array, represents a group of pins mux and config
setting. The format is rockchip,pins = <PIN_BANK PIN_BANK_IDX MUX &phandle>.
The MUX 0 means gpio and MUX 1 to 3 mean the specific device function.
The phandle of a node containing the generic pinconfig options
to use, as described in pinctrl-bindings.txt in this directory.
Examples:
#include <dt-bindings/pinctrl/rockchip.h>
...
pinctrl@20008000 {
compatible = "rockchip,rk3066a-pinctrl";
reg = <0x20008000 0x150>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio0: gpio0@20034000 {
compatible = "rockchip,gpio-bank";
reg = <0x20034000 0x100>;
interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_gates8 9>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
...
pcfg_pull_default: pcfg_pull_default {
bias-pull-pin-default
};
uart2 {
uart2_xfer: uart2-xfer {
rockchip,pins = <RK_GPIO1 8 1 &pcfg_pull_default>,
<RK_GPIO1 9 1 &pcfg_pull_default>;
};
};
};
uart2: serial@20064000 {
compatible = "snps,dw-apb-uart";
reg = <0x20064000 0x400>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <1>;
clocks = <&mux_uart2>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&uart2_xfer>;
};
ST Ericsson abx500 pinmux controller
Required properties:
- compatible: "stericsson,ab8500-gpio", "stericsson,ab8540-gpio",
"stericsson,ab8505-gpio", "stericsson,ab9540-gpio",
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".
ST Ericsson's 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 input, output, pull up, pull down...
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Required subnode-properties:
- ste,pins : An array of strings. Each string contains the name of a pin or
group.
Optional subnode-properties:
- ste,function: A string containing the name of the function to mux to the
pin or group.
- generic pin configuration option to use. Example :
default_cfg {
ste,pins = "GPIO1";
bias-disable;
};
- ste,config: Handle of pin configuration node containing the generic
pinconfig options to use, as described in pinctrl-bindings.txt in
this directory. Example :
pcfg_bias_disable: pcfg_bias_disable {
bias-disable;
};
default_cfg {
ste,pins = "GPIO1";
ste.config = <&pcfg_bias_disable>;
};
Example board file extract:
&pinctrl_abx500 {
pinctrl-names = "default";
pinctrl-0 = <&sysclkreq2_default_mode>, <&sysclkreq3_default_mode>, <&gpio3_default_mode>, <&sysclkreq6_default_mode>, <&pwmout1_default_mode>, <&pwmout2_default_mode>, <&pwmout3_default_mode>, <&adi1_default_mode>, <&dmic12_default_mode>, <&dmic34_default_mode>, <&dmic56_default_mode>, <&sysclkreq5_default_mode>, <&batremn_default_mode>, <&service_default_mode>, <&pwrctrl0_default_mode>, <&pwrctrl1_default_mode>, <&pwmextvibra1_default_mode>, <&pwmextvibra2_default_mode>, <&gpio51_default_mode>, <&gpio52_default_mode>, <&gpio53_default_mode>, <&gpio54_default_mode>, <&pdmclkdat_default_mode>;
sysclkreq2 {
sysclkreq2_default_mode: sysclkreq2_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq2_d_1";
};
default_cfg {
ste,pins = "GPIO1";
bias-disable;
};
};
};
sysclkreq3 {
sysclkreq3_default_mode: sysclkreq3_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq3_d_1";
};
default_cfg {
ste,pins = "GPIO2";
output-low;
};
};
};
gpio3 {
gpio3_default_mode: gpio3_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio3_a_1";
};
default_cfg {
ste,pins = "GPIO3";
output-low;
};
};
};
sysclkreq6 {
sysclkreq6_default_mode: sysclkreq6_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq6_d_1";
};
default_cfg {
ste,pins = "GPIO4";
bias-disable;
};
};
};
pwmout1 {
pwmout1_default_mode: pwmout1_default {
default_mux {
ste,function = "pwmout";
ste,pins = "pwmout1_d_1";
};
default_cfg {
ste,pins = "GPIO14";
output-low;
};
};
};
pwmout2 {
pwmout2_default_mode: pwmout2_default {
pwmout2_default_mux {
ste,function = "pwmout";
ste,pins = "pwmout2_d_1";
};
pwmout2_default_cfg {
ste,pins = "GPIO15";
output-low;
};
};
};
pwmout3 {
pwmout3_default_mode: pwmout3_default {
pwmout3_default_mux {
ste,function = "pwmout";
ste,pins = "pwmout3_d_1";
};
pwmout3_default_cfg {
ste,pins = "GPIO16";
output-low;
};
};
};
adi1 {
adi1_default_mode: adi1_default {
adi1_default_mux {
ste,function = "adi1";
ste,pins = "adi1_d_1";
};
adi1_default_cfg1 {
ste,pins = "GPIO17","GPIO19","GPIO20";
bias-disable;
};
adi1_default_cfg2 {
ste,pins = "GPIO18";
output-low;
};
};
};
dmic12 {
dmic12_default_mode: dmic12_default {
dmic12_default_mux {
ste,function = "dmic";
ste,pins = "dmic12_d_1";
};
dmic12_default_cfg1 {
ste,pins = "GPIO27";
output-low;
};
dmic12_default_cfg2 {
ste,pins = "GPIO28";
bias-disable;
};
};
};
dmic34 {
dmic34_default_mode: dmic34_default {
dmic34_default_mux {
ste,function = "dmic";
ste,pins = "dmic34_d_1";
};
dmic34_default_cfg1 {
ste,pins = "GPIO29";
output-low;
};
dmic34_default_cfg2 {
ste,pins = "GPIO30";
bias-disable;{
};
};
};
dmic56 {
dmic56_default_mode: dmic56_default {
dmic56_default_mux {
ste,function = "dmic";
ste,pins = "dmic56_d_1";
};
dmic56_default_cfg1 {
ste,pins = "GPIO31";
output-low;
};
dmic56_default_cfg2 {
ste,pins = "GPIO32";
bias-disable;
};
};
};
sysclkreq5 {
sysclkreq5_default_mode: sysclkreq5_default {
sysclkreq5_default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq5_d_1";
};
sysclkreq5_default_cfg {
ste,pins = "GPIO42";
output-low;
};
};
};
batremn {
batremn_default_mode: batremn_default {
batremn_default_mux {
ste,function = "batremn";
ste,pins = "batremn_d_1";
};
batremn_default_cfg {
ste,pins = "GPIO43";
bias-disable;
};
};
};
service {
service_default_mode: service_default {
service_default_mux {
ste,function = "service";
ste,pins = "service_d_1";
};
service_default_cfg {
ste,pins = "GPIO44";
bias-disable;
};
};
};
pwrctrl0 {
pwrctrl0_default_mux: pwrctrl0_mux {
pwrctrl0_default_mux {
ste,function = "pwrctrl";
ste,pins = "pwrctrl0_d_1";
};
};
pwrctrl0_default_mode: pwrctrl0_default {
pwrctrl0_default_cfg {
ste,pins = "GPIO45";
bias-disable;
};
};
};
pwrctrl1 {
pwrctrl1_default_mux: pwrctrl1_mux {
pwrctrl1_default_mux {
ste,function = "pwrctrl";
ste,pins = "pwrctrl1_d_1";
};
};
pwrctrl1_default_mode: pwrctrl1_default {
pwrctrl1_default_cfg {
ste,pins = "GPIO46";
bias-disable;
};
};
};
pwmextvibra1 {
pwmextvibra1_default_mode: pwmextvibra1_default {
pwmextvibra1_default_mux {
ste,function = "pwmextvibra";
ste,pins = "pwmextvibra1_d_1";
};
pwmextvibra1_default_cfg {
ste,pins = "GPIO47";
bias-disable;
};
};
};
pwmextvibra2 {
pwmextvibra2_default_mode: pwmextvibra2_default {
pwmextvibra2_default_mux {
ste,function = "pwmextvibra";
ste,pins = "pwmextvibra2_d_1";
};
pwmextvibra1_default_cfg {
ste,pins = "GPIO48";
bias-disable;
};
};
};
gpio51 {
gpio51_default_mode: gpio51_default {
gpio51_default_mux {
ste,function = "gpio";
ste,pins = "gpio51_a_1";
};
gpio51_default_cfg {
ste,pins = "GPIO51";
output-low;
};
};
};
gpio52 {
gpio52_default_mode: gpio52_default {
gpio52_default_mux {
ste,function = "gpio";
ste,pins = "gpio52_a_1";
};
gpio52_default_cfg {
ste,pins = "GPIO52";
bias-pull-down;
};
};
};
gpio53 {
gpio53_default_mode: gpio53_default {
gpio53_default_mux {
ste,function = "gpio";
ste,pins = "gpio53_a_1";
};
gpio53_default_cfg {
ste,pins = "GPIO53";
bias-pull-down;
};
};
};
gpio54 {
gpio54_default_mode: gpio54_default {
gpio54_default_mux {
ste,function = "gpio";
ste,pins = "gpio54_a_1";
};
gpio54_default_cfg {
ste,pins = "GPIO54";
output-low;
};
};
};
pdmclkdat {
pdmclkdat_default_mode: pdmclkdat_default {
pdmclkdat_default_mux {
ste,function = "pdm";
ste,pins = "pdmclkdat_d_1";
};
pdmclkdat_default_cfg {
ste,pins = "GPIO55", "GPIO56";
bias-disable;
};
};
};
};
...@@ -203,15 +203,8 @@ using a certain resistor value - pull up and pull down - so that the pin has a ...@@ -203,15 +203,8 @@ using a certain resistor value - pull up and pull down - so that the pin has a
stable value when nothing is driving the rail it is connected to, or when it's stable value when nothing is driving the rail it is connected to, or when it's
unconnected. unconnected.
Pin configuration can be programmed either using the explicit APIs described Pin configuration can be programmed by adding configuration entries into the
immediately below, or by adding configuration entries into the mapping table; mapping table; see section "Board/machine configuration" below.
see section "Board/machine configuration" below.
For example, a platform may do the following to pull up a pin to VDD:
#include <linux/pinctrl/consumer.h>
ret = pin_config_set("foo-dev", "FOO_GPIO_PIN", PLATFORM_X_PULL_UP);
The format and meaning of the configuration parameter, PLATFORM_X_PULL_UP The format and meaning of the configuration parameter, PLATFORM_X_PULL_UP
above, is entirely defined by the pin controller driver. above, is entirely defined by the pin controller driver.
...@@ -350,6 +343,23 @@ chip b: ...@@ -350,6 +343,23 @@ chip b:
- GPIO range : [48 .. 55] - GPIO range : [48 .. 55]
- pin range : [64 .. 71] - pin range : [64 .. 71]
The above examples assume the mapping between the GPIOs and pins is
linear. If the mapping is sparse or haphazard, an array of arbitrary pin
numbers can be encoded in the range like this:
static const unsigned range_pins[] = { 14, 1, 22, 17, 10, 8, 6, 2 };
static struct pinctrl_gpio_range gpio_range = {
.name = "chip",
.id = 0,
.base = 32,
.pins = &range_pins,
.npins = ARRAY_SIZE(range_pins),
.gc = &chip;
};
In this case the pin_base property will be ignored.
When GPIO-specific functions in the pin control subsystem are called, these When GPIO-specific functions in the pin control subsystem are called, these
ranges will be used to look up the appropriate pin controller by inspecting ranges will be used to look up the appropriate pin controller by inspecting
and matching the pin to the pin ranges across all controllers. When a and matching the pin to the pin ranges across all controllers. When a
...@@ -357,9 +367,9 @@ pin controller handling the matching range is found, GPIO-specific functions ...@@ -357,9 +367,9 @@ pin controller handling the matching range is found, GPIO-specific functions
will be called on that specific pin controller. will be called on that specific pin controller.
For all functionalities dealing with pin biasing, pin muxing etc, the pin For all functionalities dealing with pin biasing, pin muxing etc, the pin
controller subsystem will subtract the range's .base offset from the passed controller subsystem will look up the corresponding pin number from the passed
in gpio number, and add the ranges's .pin_base offset to retrive a pin number. in gpio number, and use the range's internals to retrive a pin number. After
After that, the subsystem passes it on to the pin control driver, so the driver that, the subsystem passes it on to the pin control driver, so the driver
will get an pin number into its handled number range. Further it is also passed will get an pin number into its handled number range. Further it is also passed
the range ID value, so that the pin controller knows which range it should the range ID value, so that the pin controller knows which range it should
deal with. deal with.
...@@ -368,6 +378,7 @@ Calling pinctrl_add_gpio_range from pinctrl driver is DEPRECATED. Please see ...@@ -368,6 +378,7 @@ Calling pinctrl_add_gpio_range from pinctrl driver is DEPRECATED. Please see
section 2.1 of Documentation/devicetree/bindings/gpio/gpio.txt on how to bind section 2.1 of Documentation/devicetree/bindings/gpio/gpio.txt on how to bind
pinctrl and gpio drivers. pinctrl and gpio drivers.
PINMUX interfaces PINMUX interfaces
================= =================
...@@ -1226,8 +1237,8 @@ setting up the config and muxing for the pins right before the device is ...@@ -1226,8 +1237,8 @@ setting up the config and muxing for the pins right before the device is
probing, nevertheless orthogonal to the GPIO subsystem. probing, nevertheless orthogonal to the GPIO subsystem.
But there are also situations where it makes sense for the GPIO subsystem But there are also situations where it makes sense for the GPIO subsystem
to communicate directly with with the pinctrl subsystem, using the latter to communicate directly with the pinctrl subsystem, using the latter as a
as a back-end. This is when the GPIO driver may call out to the functions back-end. This is when the GPIO driver may call out to the functions
described in the section "Pin control interaction with the GPIO subsystem" described in the section "Pin control interaction with the GPIO subsystem"
above. This only involves per-pin multiplexing, and will be completely above. This only involves per-pin multiplexing, and will be completely
hidden behind the gpio_*() function namespace. In this case, the driver hidden behind the gpio_*() function namespace. In this case, the driver
......
...@@ -6295,6 +6295,16 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) ...@@ -6295,6 +6295,16 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained S: Maintained
F: drivers/pinctrl/pinctrl-at91.c F: drivers/pinctrl/pinctrl-at91.c
PIN CONTROLLER - SAMSUNG
M: Tomasz Figa <t.figa@samsung.com>
M: Thomas Abraham <thomas.abraham@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
S: Maintained
F: drivers/pinctrl/pinctrl-exynos.*
F: drivers/pinctrl/pinctrl-s3c*
F: drivers/pinctrl/pinctrl-samsung.*
PIN CONTROLLER - ST SPEAR PIN CONTROLLER - ST SPEAR
M: Viresh Kumar <viresh.linux@gmail.com> M: Viresh Kumar <viresh.linux@gmail.com>
L: spear-devel@list.st.com L: spear-devel@list.st.com
......
...@@ -48,6 +48,25 @@ int pinctrl_bind_pins(struct device *dev) ...@@ -48,6 +48,25 @@ int pinctrl_bind_pins(struct device *dev)
goto cleanup_get; goto cleanup_get;
} }
#ifdef CONFIG_PM
/*
* If power management is enabled, we also look for the optional
* sleep and idle pin states, with semantics as defined in
* <linux/pinctrl/pinctrl-state.h>
*/
dev->pins->sleep_state = pinctrl_lookup_state(dev->pins->p,
PINCTRL_STATE_SLEEP);
if (IS_ERR(dev->pins->sleep_state))
/* Not supplying this state is perfectly legal */
dev_dbg(dev, "no sleep pinctrl state\n");
dev->pins->idle_state = pinctrl_lookup_state(dev->pins->p,
PINCTRL_STATE_IDLE);
if (IS_ERR(dev->pins->idle_state))
/* Not supplying this state is perfectly legal */
dev_dbg(dev, "no idle pinctrl state\n");
#endif
return 0; return 0;
/* /*
......
...@@ -148,10 +148,6 @@ struct i2c_nmk_client { ...@@ -148,10 +148,6 @@ struct i2c_nmk_client {
* @stop: stop condition. * @stop: stop condition.
* @xfer_complete: acknowledge completion for a I2C message. * @xfer_complete: acknowledge completion for a I2C message.
* @result: controller propogated result. * @result: controller propogated result.
* @pinctrl: pinctrl handle.
* @pins_default: default state for the pins.
* @pins_idle: idle state for the pins.
* @pins_sleep: sleep state for the pins.
* @busy: Busy doing transfer. * @busy: Busy doing transfer.
*/ */
struct nmk_i2c_dev { struct nmk_i2c_dev {
...@@ -165,11 +161,6 @@ struct nmk_i2c_dev { ...@@ -165,11 +161,6 @@ struct nmk_i2c_dev {
int stop; int stop;
struct completion xfer_complete; struct completion xfer_complete;
int result; int result;
/* Three pin states - default, idle & sleep */
struct pinctrl *pinctrl;
struct pinctrl_state *pins_default;
struct pinctrl_state *pins_idle;
struct pinctrl_state *pins_sleep;
bool busy; bool busy;
}; };
...@@ -645,13 +636,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -645,13 +636,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
} }
/* Optionaly enable pins to be muxed in and configured */ /* Optionaly enable pins to be muxed in and configured */
if (!IS_ERR(dev->pins_default)) { pinctrl_pm_select_default_state(&dev->adev->dev);
status = pinctrl_select_state(dev->pinctrl,
dev->pins_default);
if (status)
dev_err(&dev->adev->dev,
"could not set default pins\n");
}
status = init_hw(dev); status = init_hw(dev);
if (status) if (status)
...@@ -681,13 +666,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -681,13 +666,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
clk_disable_unprepare(dev->clk); clk_disable_unprepare(dev->clk);
out_clk: out_clk:
/* Optionally let pins go into idle state */ /* Optionally let pins go into idle state */
if (!IS_ERR(dev->pins_idle)) { pinctrl_pm_select_idle_state(&dev->adev->dev);
status = pinctrl_select_state(dev->pinctrl,
dev->pins_idle);
if (status)
dev_err(&dev->adev->dev,
"could not set pins to idle state\n");
}
pm_runtime_put_sync(&dev->adev->dev); pm_runtime_put_sync(&dev->adev->dev);
...@@ -882,41 +861,22 @@ static int nmk_i2c_suspend(struct device *dev) ...@@ -882,41 +861,22 @@ static int nmk_i2c_suspend(struct device *dev)
{ {
struct amba_device *adev = to_amba_device(dev); struct amba_device *adev = to_amba_device(dev);
struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev); struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
int ret;
if (nmk_i2c->busy) if (nmk_i2c->busy)
return -EBUSY; return -EBUSY;
if (!IS_ERR(nmk_i2c->pins_sleep)) { pinctrl_pm_select_sleep_state(dev);
ret = pinctrl_select_state(nmk_i2c->pinctrl,
nmk_i2c->pins_sleep);
if (ret)
dev_err(dev, "could not set pins to sleep state\n");
}
return 0; return 0;
} }
static int nmk_i2c_resume(struct device *dev) static int nmk_i2c_resume(struct device *dev)
{ {
struct amba_device *adev = to_amba_device(dev);
struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
int ret;
/* First go to the default state */ /* First go to the default state */
if (!IS_ERR(nmk_i2c->pins_default)) { pinctrl_pm_select_default_state(dev);
ret = pinctrl_select_state(nmk_i2c->pinctrl,
nmk_i2c->pins_default);
if (ret)
dev_err(dev, "could not set pins to default state\n");
}
/* Then let's idle the pins until the next transfer happens */ /* Then let's idle the pins until the next transfer happens */
if (!IS_ERR(nmk_i2c->pins_idle)) { pinctrl_pm_select_idle_state(dev);
ret = pinctrl_select_state(nmk_i2c->pinctrl,
nmk_i2c->pins_idle);
if (ret)
dev_err(dev, "could not set pins to idle state\n");
}
return 0; return 0;
} }
#else #else
...@@ -1004,39 +964,10 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -1004,39 +964,10 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
dev->adev = adev; dev->adev = adev;
amba_set_drvdata(adev, dev); amba_set_drvdata(adev, dev);
dev->pinctrl = devm_pinctrl_get(&adev->dev); /* Select default pin state */
if (IS_ERR(dev->pinctrl)) { pinctrl_pm_select_default_state(&adev->dev);
ret = PTR_ERR(dev->pinctrl);
goto err_pinctrl;
}
dev->pins_default = pinctrl_lookup_state(dev->pinctrl,
PINCTRL_STATE_DEFAULT);
if (IS_ERR(dev->pins_default)) {
dev_err(&adev->dev, "could not get default pinstate\n");
} else {
ret = pinctrl_select_state(dev->pinctrl,
dev->pins_default);
if (ret)
dev_dbg(&adev->dev, "could not set default pinstate\n");
}
dev->pins_idle = pinctrl_lookup_state(dev->pinctrl,
PINCTRL_STATE_IDLE);
if (IS_ERR(dev->pins_idle)) {
dev_dbg(&adev->dev, "could not get idle pinstate\n");
} else {
/* If possible, let's go to idle until the first transfer */ /* If possible, let's go to idle until the first transfer */
ret = pinctrl_select_state(dev->pinctrl, pinctrl_pm_select_idle_state(&adev->dev);
dev->pins_idle);
if (ret)
dev_dbg(&adev->dev, "could not set idle pinstate\n");
}
dev->pins_sleep = pinctrl_lookup_state(dev->pinctrl,
PINCTRL_STATE_SLEEP);
if (IS_ERR(dev->pins_sleep))
dev_dbg(&adev->dev, "could not get sleep pinstate\n");
dev->virtbase = ioremap(adev->res.start, resource_size(&adev->res)); dev->virtbase = ioremap(adev->res.start, resource_size(&adev->res));
if (!dev->virtbase) { if (!dev->virtbase) {
...@@ -1106,7 +1037,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -1106,7 +1037,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
iounmap(dev->virtbase); iounmap(dev->virtbase);
err_no_ioremap: err_no_ioremap:
kfree(dev); kfree(dev);
err_pinctrl:
err_no_mem: err_no_mem:
return ret; return ret;
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/platform_data/cpsw.h> #include <linux/platform_data/cpsw.h>
#include <linux/pinctrl/consumer.h>
#include "cpsw_ale.h" #include "cpsw_ale.h"
#include "cpts.h" #include "cpts.h"
...@@ -1689,6 +1690,9 @@ static int cpsw_probe(struct platform_device *pdev) ...@@ -1689,6 +1690,9 @@ static int cpsw_probe(struct platform_device *pdev)
*/ */
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
/* Select default pin state */
pinctrl_pm_select_default_state(&pdev->dev);
if (cpsw_probe_dt(&priv->data, pdev)) { if (cpsw_probe_dt(&priv->data, pdev)) {
pr_err("cpsw: platform data missing\n"); pr_err("cpsw: platform data missing\n");
ret = -ENODEV; ret = -ENODEV;
...@@ -1981,6 +1985,9 @@ static int cpsw_suspend(struct device *dev) ...@@ -1981,6 +1985,9 @@ static int cpsw_suspend(struct device *dev)
soft_reset("sliver 1", &priv->slaves[1].sliver->soft_reset); soft_reset("sliver 1", &priv->slaves[1].sliver->soft_reset);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(&pdev->dev);
return 0; return 0;
} }
...@@ -1990,6 +1997,10 @@ static int cpsw_resume(struct device *dev) ...@@ -1990,6 +1997,10 @@ static int cpsw_resume(struct device *dev)
struct net_device *ndev = platform_get_drvdata(pdev); struct net_device *ndev = platform_get_drvdata(pdev);
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
/* Select default pin state */
pinctrl_pm_select_default_state(&pdev->dev);
if (netif_running(ndev)) if (netif_running(ndev))
cpsw_ndo_open(ndev); cpsw_ndo_open(ndev);
return 0; return 0;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/davinci_emac.h> #include <linux/davinci_emac.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
/* /*
* This timeout definition is a worst-case ultra defensive measure against * This timeout definition is a worst-case ultra defensive measure against
...@@ -347,6 +348,9 @@ static int davinci_mdio_probe(struct platform_device *pdev) ...@@ -347,6 +348,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)
data->bus->parent = dev; data->bus->parent = dev;
data->bus->priv = data; data->bus->priv = data;
/* Select default pin state */
pinctrl_pm_select_default_state(&pdev->dev);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
data->clk = clk_get(&pdev->dev, "fck"); data->clk = clk_get(&pdev->dev, "fck");
...@@ -453,6 +457,9 @@ static int davinci_mdio_suspend(struct device *dev) ...@@ -453,6 +457,9 @@ static int davinci_mdio_suspend(struct device *dev)
spin_unlock(&data->lock); spin_unlock(&data->lock);
pm_runtime_put_sync(data->dev); pm_runtime_put_sync(data->dev);
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(dev);
return 0; return 0;
} }
...@@ -460,6 +467,9 @@ static int davinci_mdio_resume(struct device *dev) ...@@ -460,6 +467,9 @@ static int davinci_mdio_resume(struct device *dev)
{ {
struct davinci_mdio_data *data = dev_get_drvdata(dev); struct davinci_mdio_data *data = dev_get_drvdata(dev);
/* Select default pin state */
pinctrl_pm_select_default_state(dev);
pm_runtime_get_sync(data->dev); pm_runtime_get_sync(data->dev);
spin_lock(&data->lock); spin_lock(&data->lock);
......
...@@ -58,6 +58,18 @@ config PINCTRL_AT91 ...@@ -58,6 +58,18 @@ config PINCTRL_AT91
help help
Say Y here to enable the at91 pinctrl driver Say Y here to enable the at91 pinctrl driver
config PINCTRL_BAYTRAIL
bool "Intel Baytrail GPIO pin control"
depends on GPIOLIB && ACPI && X86
select IRQ_DOMAIN
help
driver for memory mapped GPIO functionality on Intel Baytrail
platforms. Supports 3 banks with 102, 28 and 44 gpios.
Most pins are usually muxed to some other functionality by firmware,
so only a small amount is available for gpio use.
Requires ACPI device enumeration code to set up a platform device.
config PINCTRL_BCM2835 config PINCTRL_BCM2835
bool bool
select PINMUX select PINMUX
...@@ -108,6 +120,14 @@ config PINCTRL_IMX6SL ...@@ -108,6 +120,14 @@ config PINCTRL_IMX6SL
help help
Say Y here to enable the imx6sl pinctrl driver Say Y here to enable the imx6sl pinctrl driver
config PINCTRL_VF610
bool "Freescale Vybrid VF610 pinctrl driver"
depends on OF
depends on SOC_VF610
select PINCTRL_IMX
help
Say Y here to enable the Freescale Vybrid VF610 pinctrl driver
config PINCTRL_LANTIQ config PINCTRL_LANTIQ
bool bool
depends on LANTIQ depends on LANTIQ
...@@ -150,6 +170,12 @@ config PINCTRL_DB8540 ...@@ -150,6 +170,12 @@ config PINCTRL_DB8540
bool "DB8540 pin controller driver" bool "DB8540 pin controller driver"
depends on PINCTRL_NOMADIK && ARCH_U8500 depends on PINCTRL_NOMADIK && ARCH_U8500
config PINCTRL_ROCKCHIP
bool
select PINMUX
select GENERIC_PINCONF
select GENERIC_IRQ_CHIP
config PINCTRL_SINGLE config PINCTRL_SINGLE
tristate "One-register-per-pin type device tree based pinctrl driver" tristate "One-register-per-pin type device tree based pinctrl driver"
depends on OF depends on OF
...@@ -192,6 +218,18 @@ config PINCTRL_TEGRA114 ...@@ -192,6 +218,18 @@ config PINCTRL_TEGRA114
bool bool
select PINCTRL_TEGRA select PINCTRL_TEGRA
config PINCTRL_TZ1090
bool "Toumaz Xenif TZ1090 pin control driver"
depends on SOC_TZ1090
select PINMUX
select GENERIC_PINCONF
config PINCTRL_TZ1090_PDC
bool "Toumaz Xenif TZ1090 PDC pin control driver"
depends on SOC_TZ1090
select PINMUX
select PINCONF
config PINCTRL_U300 config PINCTRL_U300
bool "U300 pin controller driver" bool "U300 pin controller driver"
depends on ARCH_U300 depends on ARCH_U300
......
...@@ -16,12 +16,14 @@ obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o ...@@ -16,12 +16,14 @@ obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o
obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o
obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o
obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o
obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6q.o obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6q.o
obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6dl.o obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6dl.o
obj-$(CONFIG_PINCTRL_IMX6SL) += pinctrl-imx6sl.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
...@@ -30,13 +32,16 @@ obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o ...@@ -30,13 +32,16 @@ obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o obj-$(CONFIG_PINCTRL_SIRF) += sirf/
obj-$(CONFIG_PINCTRL_SUNXI) += pinctrl-sunxi.o obj-$(CONFIG_PINCTRL_SUNXI) += pinctrl-sunxi.o
obj-$(CONFIG_PINCTRL_TEGRA) += pinctrl-tegra.o obj-$(CONFIG_PINCTRL_TEGRA) += pinctrl-tegra.o
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_TEGRA114) += pinctrl-tegra114.o obj-$(CONFIG_PINCTRL_TEGRA114) += pinctrl-tegra114.o
obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o
obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
...@@ -47,6 +52,7 @@ obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o ...@@ -47,6 +52,7 @@ obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o
obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o
obj-$(CONFIG_PLAT_ORION) += mvebu/ obj-$(CONFIG_PLAT_ORION) += mvebu/
obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/ obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/
......
...@@ -41,13 +41,13 @@ ...@@ -41,13 +41,13 @@
static bool pinctrl_dummy_state; static bool pinctrl_dummy_state;
/* Mutex taken to protect pinctrl_list */ /* Mutex taken to protect pinctrl_list */
DEFINE_MUTEX(pinctrl_list_mutex); static DEFINE_MUTEX(pinctrl_list_mutex);
/* Mutex taken to protect pinctrl_maps */ /* Mutex taken to protect pinctrl_maps */
DEFINE_MUTEX(pinctrl_maps_mutex); DEFINE_MUTEX(pinctrl_maps_mutex);
/* Mutex taken to protect pinctrldev_list */ /* Mutex taken to protect pinctrldev_list */
DEFINE_MUTEX(pinctrldev_list_mutex); static DEFINE_MUTEX(pinctrldev_list_mutex);
/* Global list of pin control devices (struct pinctrl_dev) */ /* Global list of pin control devices (struct pinctrl_dev) */
static LIST_HEAD(pinctrldev_list); static LIST_HEAD(pinctrldev_list);
...@@ -101,20 +101,23 @@ EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata); ...@@ -101,20 +101,23 @@ EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata);
struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname)
{ {
struct pinctrl_dev *pctldev = NULL; struct pinctrl_dev *pctldev = NULL;
bool found = false;
if (!devname) if (!devname)
return NULL; return NULL;
mutex_lock(&pinctrldev_list_mutex);
list_for_each_entry(pctldev, &pinctrldev_list, node) { list_for_each_entry(pctldev, &pinctrldev_list, node) {
if (!strcmp(dev_name(pctldev->dev), devname)) { if (!strcmp(dev_name(pctldev->dev), devname)) {
/* Matched on device name */ /* Matched on device name */
found = true; mutex_unlock(&pinctrldev_list_mutex);
break; return pctldev;
} }
} }
return found ? pctldev : NULL; mutex_unlock(&pinctrldev_list_mutex);
return NULL;
} }
struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np) struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np)
...@@ -279,6 +282,29 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev, ...@@ -279,6 +282,29 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev,
return 0; return 0;
} }
/**
* gpio_to_pin() - GPIO range GPIO number to pin number translation
* @range: GPIO range used for the translation
* @gpio: gpio pin to translate to a pin number
*
* Finds the pin number for a given GPIO using the specified GPIO range
* as a base for translation. The distinction between linear GPIO ranges
* and pin list based GPIO ranges is managed correctly by this function.
*
* This function assumes the gpio is part of the specified GPIO range, use
* only after making sure this is the case (e.g. by calling it on the
* result of successful pinctrl_get_device_gpio_range calls)!
*/
static inline int gpio_to_pin(struct pinctrl_gpio_range *range,
unsigned int gpio)
{
unsigned int offset = gpio - range->base;
if (range->pins)
return range->pins[offset];
else
return range->pin_base + offset;
}
/** /**
* pinctrl_match_gpio_range() - check if a certain GPIO pin is in range * pinctrl_match_gpio_range() - check if a certain GPIO pin is in range
* @pctldev: pin controller device to check * @pctldev: pin controller device to check
...@@ -326,6 +352,8 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio) ...@@ -326,6 +352,8 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio)
struct pinctrl_gpio_range *range = NULL; struct pinctrl_gpio_range *range = NULL;
struct gpio_chip *chip = gpio_to_chip(gpio); struct gpio_chip *chip = gpio_to_chip(gpio);
mutex_lock(&pinctrldev_list_mutex);
/* Loop over the pin controllers */ /* Loop over the pin controllers */
list_for_each_entry(pctldev, &pinctrldev_list, node) { list_for_each_entry(pctldev, &pinctrldev_list, node) {
/* Loop over the ranges */ /* Loop over the ranges */
...@@ -334,9 +362,13 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio) ...@@ -334,9 +362,13 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio)
if (range->base + range->npins - 1 < chip->base || if (range->base + range->npins - 1 < chip->base ||
range->base > chip->base + chip->ngpio - 1) range->base > chip->base + chip->ngpio - 1)
continue; continue;
mutex_unlock(&pinctrldev_list_mutex);
return true; return true;
} }
} }
mutex_unlock(&pinctrldev_list_mutex);
return false; return false;
} }
#else #else
...@@ -408,8 +440,6 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, ...@@ -408,8 +440,6 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
{ {
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
mutex_lock(&pinctrldev_list_mutex);
pctldev = get_pinctrl_dev_from_devname(devname); pctldev = get_pinctrl_dev_from_devname(devname);
/* /*
...@@ -418,13 +448,10 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, ...@@ -418,13 +448,10 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
* range need to defer probing. * range need to defer probing.
*/ */
if (!pctldev) { if (!pctldev) {
mutex_unlock(&pinctrldev_list_mutex);
return ERR_PTR(-EPROBE_DEFER); return ERR_PTR(-EPROBE_DEFER);
} }
pinctrl_add_gpio_range(pctldev, range); pinctrl_add_gpio_range(pctldev, range);
mutex_unlock(&pinctrldev_list_mutex);
return pctldev; return pctldev;
} }
EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range); EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range);
...@@ -438,21 +465,26 @@ struct pinctrl_gpio_range * ...@@ -438,21 +465,26 @@ struct pinctrl_gpio_range *
pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
unsigned int pin) unsigned int pin)
{ {
struct pinctrl_gpio_range *range = NULL; struct pinctrl_gpio_range *range;
mutex_lock(&pctldev->mutex); mutex_lock(&pctldev->mutex);
/* Loop over the ranges */ /* Loop over the ranges */
list_for_each_entry(range, &pctldev->gpio_ranges, node) { list_for_each_entry(range, &pctldev->gpio_ranges, node) {
/* Check if we're in the valid range */ /* Check if we're in the valid range */
if (pin >= range->pin_base && if (range->pins) {
pin < range->pin_base + range->npins) { int a;
for (a = 0; a < range->npins; a++) {
if (range->pins[a] == pin)
goto out;
}
} else if (pin >= range->pin_base &&
pin < range->pin_base + range->npins)
goto out;
}
range = NULL;
out:
mutex_unlock(&pctldev->mutex); mutex_unlock(&pctldev->mutex);
return range; return range;
}
}
mutex_unlock(&pctldev->mutex);
return NULL;
} }
EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin); EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin);
...@@ -517,22 +549,18 @@ int pinctrl_request_gpio(unsigned gpio) ...@@ -517,22 +549,18 @@ int pinctrl_request_gpio(unsigned gpio)
int ret; int ret;
int pin; int pin;
mutex_lock(&pinctrldev_list_mutex);
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
if (ret) { if (ret) {
if (pinctrl_ready_for_gpio_range(gpio)) if (pinctrl_ready_for_gpio_range(gpio))
ret = 0; ret = 0;
mutex_unlock(&pinctrldev_list_mutex);
return ret; return ret;
} }
/* Convert to the pin controllers number space */ /* Convert to the pin controllers number space */
pin = gpio - range->base + range->pin_base; pin = gpio_to_pin(range, gpio);
ret = pinmux_request_gpio(pctldev, range, pin, gpio); ret = pinmux_request_gpio(pctldev, range, pin, gpio);
mutex_unlock(&pinctrldev_list_mutex);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(pinctrl_request_gpio); EXPORT_SYMBOL_GPL(pinctrl_request_gpio);
...@@ -552,22 +580,18 @@ void pinctrl_free_gpio(unsigned gpio) ...@@ -552,22 +580,18 @@ void pinctrl_free_gpio(unsigned gpio)
int ret; int ret;
int pin; int pin;
mutex_lock(&pinctrldev_list_mutex);
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
if (ret) { if (ret) {
mutex_unlock(&pinctrldev_list_mutex);
return; return;
} }
mutex_lock(&pctldev->mutex); mutex_lock(&pctldev->mutex);
/* Convert to the pin controllers number space */ /* Convert to the pin controllers number space */
pin = gpio - range->base + range->pin_base; pin = gpio_to_pin(range, gpio);
pinmux_free_gpio(pctldev, pin, range); pinmux_free_gpio(pctldev, pin, range);
mutex_unlock(&pctldev->mutex); mutex_unlock(&pctldev->mutex);
mutex_unlock(&pinctrldev_list_mutex);
} }
EXPORT_SYMBOL_GPL(pinctrl_free_gpio); EXPORT_SYMBOL_GPL(pinctrl_free_gpio);
...@@ -578,22 +602,18 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input) ...@@ -578,22 +602,18 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input)
int ret; int ret;
int pin; int pin;
mutex_lock(&pinctrldev_list_mutex);
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
if (ret) { if (ret) {
mutex_unlock(&pinctrldev_list_mutex);
return ret; return ret;
} }
mutex_lock(&pctldev->mutex); mutex_lock(&pctldev->mutex);
/* Convert to the pin controllers number space */ /* Convert to the pin controllers number space */
pin = gpio - range->base + range->pin_base; pin = gpio_to_pin(range, gpio);
ret = pinmux_gpio_direction(pctldev, range, pin, input); ret = pinmux_gpio_direction(pctldev, range, pin, input);
mutex_unlock(&pctldev->mutex); mutex_unlock(&pctldev->mutex);
mutex_unlock(&pinctrldev_list_mutex);
return ret; return ret;
} }
...@@ -1204,6 +1224,69 @@ int pinctrl_force_default(struct pinctrl_dev *pctldev) ...@@ -1204,6 +1224,69 @@ int pinctrl_force_default(struct pinctrl_dev *pctldev)
} }
EXPORT_SYMBOL_GPL(pinctrl_force_default); EXPORT_SYMBOL_GPL(pinctrl_force_default);
#ifdef CONFIG_PM
/**
* pinctrl_pm_select_default_state() - select default pinctrl state for PM
* @dev: device to select default state for
*/
int pinctrl_pm_select_default_state(struct device *dev)
{
struct dev_pin_info *pins = dev->pins;
int ret;
if (!pins)
return 0;
if (IS_ERR(pins->default_state))
return 0; /* No default state */
ret = pinctrl_select_state(pins->p, pins->default_state);
if (ret)
dev_err(dev, "failed to activate default pinctrl state\n");
return ret;
}
EXPORT_SYMBOL_GPL(pinctrl_pm_select_default_state);
/**
* pinctrl_pm_select_sleep_state() - select sleep pinctrl state for PM
* @dev: device to select sleep state for
*/
int pinctrl_pm_select_sleep_state(struct device *dev)
{
struct dev_pin_info *pins = dev->pins;
int ret;
if (!pins)
return 0;
if (IS_ERR(pins->sleep_state))
return 0; /* No sleep state */
ret = pinctrl_select_state(pins->p, pins->sleep_state);
if (ret)
dev_err(dev, "failed to activate pinctrl sleep state\n");
return ret;
}
EXPORT_SYMBOL_GPL(pinctrl_pm_select_sleep_state);
/**
* pinctrl_pm_select_idle_state() - select idle pinctrl state for PM
* @dev: device to select idle state for
*/
int pinctrl_pm_select_idle_state(struct device *dev)
{
struct dev_pin_info *pins = dev->pins;
int ret;
if (!pins)
return 0;
if (IS_ERR(pins->idle_state))
return 0; /* No idle state */
ret = pinctrl_select_state(pins->p, pins->idle_state);
if (ret)
dev_err(dev, "failed to activate pinctrl idle state\n");
return ret;
}
EXPORT_SYMBOL_GPL(pinctrl_pm_select_idle_state);
#endif
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
static int pinctrl_pins_show(struct seq_file *s, void *what) static int pinctrl_pins_show(struct seq_file *s, void *what)
...@@ -1296,6 +1379,16 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) ...@@ -1296,6 +1379,16 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
/* Loop over the ranges */ /* Loop over the ranges */
list_for_each_entry(range, &pctldev->gpio_ranges, node) { list_for_each_entry(range, &pctldev->gpio_ranges, node) {
if (range->pins) {
int a;
seq_printf(s, "%u: %s GPIOS [%u - %u] PINS {",
range->id, range->name,
range->base, (range->base + range->npins - 1));
for (a = 0; a < range->npins - 1; a++)
seq_printf(s, "%u, ", range->pins[a]);
seq_printf(s, "%u}\n", range->pins[a]);
}
else
seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n", seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n",
range->id, range->name, range->id, range->name,
range->base, (range->base + range->npins - 1), range->base, (range->base + range->npins - 1),
......
This diff is collapsed.
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h> #include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h> #include <linux/pinctrl/pinconf-generic.h>
#include <linux/of.h>
#include "core.h" #include "core.h"
#include "pinconf.h" #include "pinconf.h"
...@@ -37,14 +38,18 @@ struct pin_config_item { ...@@ -37,14 +38,18 @@ struct pin_config_item {
static struct pin_config_item conf_items[] = { static struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL), PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL), PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL), PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL), PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
"input bias pull to pin specific state", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL), PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_STRENGTH, "output drive strength", "mA"),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL), PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL), PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"), PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "usec"),
PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"), PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"),
PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL), PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL),
PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"), PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"),
...@@ -135,3 +140,100 @@ void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, ...@@ -135,3 +140,100 @@ void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
} }
EXPORT_SYMBOL_GPL(pinconf_generic_dump_config); EXPORT_SYMBOL_GPL(pinconf_generic_dump_config);
#endif #endif
#ifdef CONFIG_OF
struct pinconf_generic_dt_params {
const char * const property;
enum pin_config_param param;
u32 default_value;
};
static struct pinconf_generic_dt_params dt_params[] = {
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
{ "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
{ "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
{ "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
{ "output-low", PIN_CONFIG_OUTPUT, 0, },
{ "output-high", PIN_CONFIG_OUTPUT, 1, },
};
/**
* pinconf_generic_parse_dt_config()
* parse the config properties into generic pinconfig values.
* @np: node containing the pinconfig properties
* @configs: array with nconfigs entries containing the generic pinconf values
* @nconfigs: umber of configurations
*/
int pinconf_generic_parse_dt_config(struct device_node *np,
unsigned long **configs,
unsigned int *nconfigs)
{
unsigned long *cfg;
unsigned int ncfg = 0;
int ret;
int i;
u32 val;
if (!np)
return -EINVAL;
/* allocate a temporary array big enough to hold one of each option */
cfg = kzalloc(sizeof(*cfg) * ARRAY_SIZE(dt_params), GFP_KERNEL);
if (!cfg)
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
struct pinconf_generic_dt_params *par = &dt_params[i];
ret = of_property_read_u32(np, par->property, &val);
/* property not found */
if (ret == -EINVAL)
continue;
/* use default value, when no value is specified */
if (ret)
val = par->default_value;
pr_debug("found %s with value %u\n", par->property, val);
cfg[ncfg] = pinconf_to_config_packed(par->param, val);
ncfg++;
}
ret = 0;
/* no configs found at all */
if (ncfg == 0) {
*configs = NULL;
*nconfigs = 0;
goto out;
}
/*
* Now limit the number of configs to the real number of
* found properties.
*/
*configs = kzalloc(ncfg * sizeof(unsigned long), GFP_KERNEL);
if (!*configs) {
ret = -ENOMEM;
goto out;
}
memcpy(*configs, cfg, ncfg * sizeof(unsigned long));
*nconfigs = ncfg;
out:
kfree(cfg);
return ret;
}
#endif
...@@ -75,98 +75,6 @@ int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -75,98 +75,6 @@ int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
return ops->pin_config_get(pctldev, pin, config); return ops->pin_config_get(pctldev, pin, config);
} }
/**
* pin_config_get() - get the configuration of a single pin parameter
* @dev_name: name of the pin controller device for this pin
* @name: name of the pin to get the config for
* @config: the config pointed to by this argument will be filled in with the
* current pin state, it can be used directly by drivers as a numeral, or
* it can be dereferenced to any struct.
*/
int pin_config_get(const char *dev_name, const char *name,
unsigned long *config)
{
struct pinctrl_dev *pctldev;
int pin;
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
pin = -EINVAL;
return pin;
}
mutex_lock(&pctldev->mutex);
pin = pin_get_from_name(pctldev, name);
if (pin < 0)
goto unlock;
pin = pin_config_get_for_pin(pctldev, pin, config);
unlock:
mutex_unlock(&pctldev->mutex);
return pin;
}
EXPORT_SYMBOL(pin_config_get);
static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long config)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
int ret;
if (!ops || !ops->pin_config_set) {
dev_err(pctldev->dev, "cannot configure pin, missing "
"config function in driver\n");
return -EINVAL;
}
ret = ops->pin_config_set(pctldev, pin, config);
if (ret) {
dev_err(pctldev->dev,
"unable to set pin configuration on pin %d\n", pin);
return ret;
}
return 0;
}
/**
* pin_config_set() - set the configuration of a single pin parameter
* @dev_name: name of pin controller device for this pin
* @name: name of the pin to set the config for
* @config: the config in this argument will contain the desired pin state, it
* can be used directly by drivers as a numeral, or it can be dereferenced
* to any struct.
*/
int pin_config_set(const char *dev_name, const char *name,
unsigned long config)
{
struct pinctrl_dev *pctldev;
int pin, ret;
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
return ret;
}
mutex_lock(&pctldev->mutex);
pin = pin_get_from_name(pctldev, name);
if (pin < 0) {
ret = pin;
goto unlock;
}
ret = pin_config_set_for_pin(pctldev, pin, config);
unlock:
mutex_unlock(&pctldev->mutex);
return ret;
}
EXPORT_SYMBOL(pin_config_set);
int pin_config_group_get(const char *dev_name, const char *pin_group, int pin_config_group_get(const char *dev_name, const char *pin_group,
unsigned long *config) unsigned long *config)
{ {
...@@ -204,88 +112,6 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, ...@@ -204,88 +112,6 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
mutex_unlock(&pctldev->mutex); mutex_unlock(&pctldev->mutex);
return ret; return ret;
} }
EXPORT_SYMBOL(pin_config_group_get);
int pin_config_group_set(const char *dev_name, const char *pin_group,
unsigned long config)
{
struct pinctrl_dev *pctldev;
const struct pinconf_ops *ops;
const struct pinctrl_ops *pctlops;
int selector;
const unsigned *pins;
unsigned num_pins;
int ret;
int i;
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
return ret;
}
mutex_lock(&pctldev->mutex);
ops = pctldev->desc->confops;
pctlops = pctldev->desc->pctlops;
if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
dev_err(pctldev->dev, "cannot configure pin group, missing "
"config function in driver\n");
ret = -EINVAL;
goto unlock;
}
selector = pinctrl_get_group_selector(pctldev, pin_group);
if (selector < 0) {
ret = selector;
goto unlock;
}
ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
if (ret) {
dev_err(pctldev->dev, "cannot configure pin group, error "
"getting pins\n");
goto unlock;
}
/*
* If the pin controller supports handling entire groups we use that
* capability.
*/
if (ops->pin_config_group_set) {
ret = ops->pin_config_group_set(pctldev, selector, config);
/*
* If the pin controller prefer that a certain group be handled
* pin-by-pin as well, it returns -EAGAIN.
*/
if (ret != -EAGAIN)
goto unlock;
}
/*
* If the controller cannot handle entire groups, we configure each pin
* individually.
*/
if (!ops->pin_config_set) {
ret = 0;
goto unlock;
}
for (i = 0; i < num_pins; i++) {
ret = ops->pin_config_set(pctldev, pins[i], config);
if (ret < 0)
goto unlock;
}
ret = 0;
unlock:
mutex_unlock(&pctldev->mutex);
return ret;
}
EXPORT_SYMBOL(pin_config_group_set);
int pinconf_map_to_setting(struct pinctrl_map const *map, int pinconf_map_to_setting(struct pinctrl_map const *map,
struct pinctrl_setting *setting) struct pinctrl_setting *setting)
......
...@@ -123,3 +123,9 @@ static inline void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, ...@@ -123,3 +123,9 @@ static inline void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
return; return;
} }
#endif #endif
#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_OF)
int pinconf_generic_parse_dt_config(struct device_node *np,
unsigned long **configs,
unsigned int *nconfigs);
#endif
This diff is collapsed.
...@@ -1543,12 +1543,6 @@ static int at91_gpio_probe(struct platform_device *pdev) ...@@ -1543,12 +1543,6 @@ static int at91_gpio_probe(struct platform_device *pdev)
goto err; goto err;
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENOENT;
goto err;
}
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
ret = irq; ret = irq;
...@@ -1561,6 +1555,7 @@ static int at91_gpio_probe(struct platform_device *pdev) ...@@ -1561,6 +1555,7 @@ static int at91_gpio_probe(struct platform_device *pdev)
goto err; goto err;
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
at91_chip->regbase = devm_ioremap_resource(&pdev->dev, res); at91_chip->regbase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(at91_chip->regbase)) { if (IS_ERR(at91_chip->regbase)) {
ret = PTR_ERR(at91_chip->regbase); ret = PTR_ERR(at91_chip->regbase);
......
This diff is collapsed.
...@@ -113,7 +113,7 @@ static struct lock_class_key gpio_lock_class; ...@@ -113,7 +113,7 @@ static struct lock_class_key gpio_lock_class;
/* pins are just named GPIO0..GPIO53 */ /* pins are just named GPIO0..GPIO53 */
#define BCM2835_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a) #define BCM2835_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a)
struct pinctrl_pin_desc bcm2835_gpio_pins[] = { static struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
BCM2835_GPIO_PIN(0), BCM2835_GPIO_PIN(0),
BCM2835_GPIO_PIN(1), BCM2835_GPIO_PIN(1),
BCM2835_GPIO_PIN(2), BCM2835_GPIO_PIN(2),
......
...@@ -853,7 +853,6 @@ static int __exit u300_gpio_remove(struct platform_device *pdev) ...@@ -853,7 +853,6 @@ static int __exit u300_gpio_remove(struct platform_device *pdev)
} }
u300_gpio_free_ports(gpio); u300_gpio_free_ports(gpio);
clk_disable_unprepare(gpio->clk); clk_disable_unprepare(gpio->clk);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
...@@ -50,37 +50,58 @@ static const struct of_device_id exynos_wkup_irq_ids[] = { ...@@ -50,37 +50,58 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
{ } { }
}; };
static void exynos_gpio_irq_unmask(struct irq_data *irqd) static void exynos_gpio_irq_mask(struct irq_data *irqd)
{ {
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata; struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
unsigned long mask; unsigned long mask;
unsigned long flags;
spin_lock_irqsave(&bank->slock, flags);
mask = readl(d->virt_base + reg_mask); mask = readl(d->virt_base + reg_mask);
mask &= ~(1 << irqd->hwirq); mask |= 1 << irqd->hwirq;
writel(mask, d->virt_base + reg_mask); writel(mask, d->virt_base + reg_mask);
spin_unlock_irqrestore(&bank->slock, flags);
} }
static void exynos_gpio_irq_mask(struct irq_data *irqd) static void exynos_gpio_irq_ack(struct irq_data *irqd)
{ {
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata; struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
unsigned long mask;
mask = readl(d->virt_base + reg_mask); writel(1 << irqd->hwirq, d->virt_base + reg_pend);
mask |= 1 << irqd->hwirq;
writel(mask, d->virt_base + reg_mask);
} }
static void exynos_gpio_irq_ack(struct irq_data *irqd) static void exynos_gpio_irq_unmask(struct irq_data *irqd)
{ {
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata; struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset; unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
unsigned long mask;
unsigned long flags;
writel(1 << irqd->hwirq, d->virt_base + reg_pend); /*
* Ack level interrupts right before unmask
*
* If we don't do this we'll get a double-interrupt. Level triggered
* interrupts must not fire an interrupt if the level is not
* _currently_ active, even if it was active while the interrupt was
* masked.
*/
if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
exynos_gpio_irq_ack(irqd);
spin_lock_irqsave(&bank->slock, flags);
mask = readl(d->virt_base + reg_mask);
mask &= ~(1 << irqd->hwirq);
writel(mask, d->virt_base + reg_mask);
spin_unlock_irqrestore(&bank->slock, flags);
} }
static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
...@@ -258,37 +279,58 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) ...@@ -258,37 +279,58 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
return ret; return ret;
} }
static void exynos_wkup_irq_unmask(struct irq_data *irqd) static void exynos_wkup_irq_mask(struct irq_data *irqd)
{ {
struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = b->drvdata; struct samsung_pinctrl_drv_data *d = b->drvdata;
unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
unsigned long mask; unsigned long mask;
unsigned long flags;
spin_lock_irqsave(&b->slock, flags);
mask = readl(d->virt_base + reg_mask); mask = readl(d->virt_base + reg_mask);
mask &= ~(1 << irqd->hwirq); mask |= 1 << irqd->hwirq;
writel(mask, d->virt_base + reg_mask); writel(mask, d->virt_base + reg_mask);
spin_unlock_irqrestore(&b->slock, flags);
} }
static void exynos_wkup_irq_mask(struct irq_data *irqd) static void exynos_wkup_irq_ack(struct irq_data *irqd)
{ {
struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = b->drvdata; struct samsung_pinctrl_drv_data *d = b->drvdata;
unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
unsigned long mask;
mask = readl(d->virt_base + reg_mask); writel(1 << irqd->hwirq, d->virt_base + pend);
mask |= 1 << irqd->hwirq;
writel(mask, d->virt_base + reg_mask);
} }
static void exynos_wkup_irq_ack(struct irq_data *irqd) static void exynos_wkup_irq_unmask(struct irq_data *irqd)
{ {
struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = b->drvdata; struct samsung_pinctrl_drv_data *d = b->drvdata;
unsigned long pend = d->ctrl->weint_pend + b->eint_offset; unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
unsigned long mask;
unsigned long flags;
writel(1 << irqd->hwirq, d->virt_base + pend); /*
* Ack level interrupts right before unmask
*
* If we don't do this we'll get a double-interrupt. Level triggered
* interrupts must not fire an interrupt if the level is not
* _currently_ active, even if it was active while the interrupt was
* masked.
*/
if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
exynos_wkup_irq_ack(irqd);
spin_lock_irqsave(&b->slock, flags);
mask = readl(d->virt_base + reg_mask);
mask &= ~(1 << irqd->hwirq);
writel(mask, d->virt_base + reg_mask);
spin_unlock_irqrestore(&b->slock, flags);
} }
static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
......
...@@ -220,7 +220,7 @@ static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -220,7 +220,7 @@ static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev,
dev_err(dev, "failed to alloc memory for group name\n"); dev_err(dev, "failed to alloc memory for group name\n");
goto free_map; goto free_map;
} }
sprintf(gname, "%s%s", np->name, GROUP_SUFFIX); snprintf(gname, strlen(np->name) + 4, "%s%s", np->name, GROUP_SUFFIX);
/* /*
* don't have config options? then skip over to creating function * don't have config options? then skip over to creating function
...@@ -259,7 +259,8 @@ static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -259,7 +259,8 @@ static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev,
dev_err(dev, "failed to alloc memory for func name\n"); dev_err(dev, "failed to alloc memory for func name\n");
goto free_cfg; goto free_cfg;
} }
sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX); snprintf(fname, strlen(np->name) + 4, "%s%s", np->name,
FUNCTION_SUFFIX);
map[*nmaps].data.mux.group = gname; map[*nmaps].data.mux.group = gname;
map[*nmaps].data.mux.function = fname; map[*nmaps].data.mux.function = fname;
...@@ -713,7 +714,8 @@ static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev, ...@@ -713,7 +714,8 @@ static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev,
dev_err(dev, "failed to alloc memory for group name\n"); dev_err(dev, "failed to alloc memory for group name\n");
return -ENOMEM; return -ENOMEM;
} }
sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX); snprintf(gname, strlen(cfg_np->name) + 4, "%s%s", cfg_np->name,
GROUP_SUFFIX);
grp->name = gname; grp->name = gname;
grp->pins = pin_list; grp->pins = pin_list;
...@@ -733,7 +735,8 @@ static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev, ...@@ -733,7 +735,8 @@ static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev,
dev_err(dev, "failed to alloc memory for func name\n"); dev_err(dev, "failed to alloc memory for func name\n");
return -ENOMEM; return -ENOMEM;
} }
sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX); snprintf(fname, strlen(cfg_np->name) + 4, "%s%s", cfg_np->name,
FUNCTION_SUFFIX);
func->name = fname; func->name = fname;
func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL); func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
...@@ -806,7 +809,7 @@ static int exynos5440_pinctrl_register(struct platform_device *pdev, ...@@ -806,7 +809,7 @@ static int exynos5440_pinctrl_register(struct platform_device *pdev,
/* for each pin, set the name of the pin */ /* for each pin, set the name of the pin */
for (pin = 0; pin < ctrldesc->npins; pin++) { for (pin = 0; pin < ctrldesc->npins; pin++) {
sprintf(pin_names, "gpio%02d", pin); snprintf(pin_names, 6, "gpio%02d", pin);
pdesc = pindesc + pin; pdesc = pindesc + pin;
pdesc->name = pin_names; pdesc->name = pin_names;
pin_names += PIN_NAME_LENGTH; pin_names += PIN_NAME_LENGTH;
......
...@@ -221,13 +221,21 @@ static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -221,13 +221,21 @@ static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
pin_id = pins[i]; pin_id = pins[i];
pin_reg = &info->pin_regs[pin_id]; pin_reg = &info->pin_regs[pin_id];
if (!pin_reg->mux_reg) { if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->mux_reg) {
dev_err(ipctl->dev, "Pin(%s) does not support mux function\n", dev_err(ipctl->dev, "Pin(%s) does not support mux function\n",
info->pins[pin_id].name); info->pins[pin_id].name);
return -EINVAL; return -EINVAL;
} }
if (info->flags & SHARE_MUX_CONF_REG) {
u32 reg;
reg = readl(ipctl->base + pin_reg->mux_reg);
reg &= ~(0x7 << 20);
reg |= (mux[i] << 20);
writel(reg, ipctl->base + pin_reg->mux_reg);
} else {
writel(mux[i], ipctl->base + pin_reg->mux_reg); writel(mux[i], ipctl->base + pin_reg->mux_reg);
}
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
pin_reg->mux_reg, mux[i]); pin_reg->mux_reg, mux[i]);
...@@ -287,7 +295,7 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -287,7 +295,7 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
const struct imx_pinctrl_soc_info *info = ipctl->info; const struct imx_pinctrl_soc_info *info = ipctl->info;
const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
if (!pin_reg->conf_reg) { if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
dev_err(info->dev, "Pin(%s) does not support config function\n", dev_err(info->dev, "Pin(%s) does not support config function\n",
info->pins[pin_id].name); info->pins[pin_id].name);
return -EINVAL; return -EINVAL;
...@@ -295,6 +303,9 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -295,6 +303,9 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
*config = readl(ipctl->base + pin_reg->conf_reg); *config = readl(ipctl->base + pin_reg->conf_reg);
if (info->flags & SHARE_MUX_CONF_REG)
*config &= 0xffff;
return 0; return 0;
} }
...@@ -305,7 +316,7 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -305,7 +316,7 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
const struct imx_pinctrl_soc_info *info = ipctl->info; const struct imx_pinctrl_soc_info *info = ipctl->info;
const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
if (!pin_reg->conf_reg) { if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
dev_err(info->dev, "Pin(%s) does not support config function\n", dev_err(info->dev, "Pin(%s) does not support config function\n",
info->pins[pin_id].name); info->pins[pin_id].name);
return -EINVAL; return -EINVAL;
...@@ -314,7 +325,15 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -314,7 +325,15 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
dev_dbg(ipctl->dev, "pinconf set pin %s\n", dev_dbg(ipctl->dev, "pinconf set pin %s\n",
info->pins[pin_id].name); info->pins[pin_id].name);
if (info->flags & SHARE_MUX_CONF_REG) {
u32 reg;
reg = readl(ipctl->base + pin_reg->conf_reg);
reg &= ~0xffff;
reg |= config;
writel(reg, ipctl->base + pin_reg->conf_reg);
} else {
writel(config, ipctl->base + pin_reg->conf_reg); writel(config, ipctl->base + pin_reg->conf_reg);
}
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n", dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
pin_reg->conf_reg, config); pin_reg->conf_reg, config);
...@@ -381,19 +400,24 @@ static struct pinctrl_desc imx_pinctrl_desc = { ...@@ -381,19 +400,24 @@ static struct pinctrl_desc imx_pinctrl_desc = {
* 1 u32 CONFIG, so 24 types in total for each pin. * 1 u32 CONFIG, so 24 types in total for each pin.
*/ */
#define FSL_PIN_SIZE 24 #define FSL_PIN_SIZE 24
#define SHARE_FSL_PIN_SIZE 20
static int imx_pinctrl_parse_groups(struct device_node *np, static int imx_pinctrl_parse_groups(struct device_node *np,
struct imx_pin_group *grp, struct imx_pin_group *grp,
struct imx_pinctrl_soc_info *info, struct imx_pinctrl_soc_info *info,
u32 index) u32 index)
{ {
int size; int size, pin_size;
const __be32 *list; const __be32 *list;
int i; int i;
u32 config; u32 config;
dev_dbg(info->dev, "group(%d): %s\n", index, np->name); dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
if (info->flags & SHARE_MUX_CONF_REG)
pin_size = SHARE_FSL_PIN_SIZE;
else
pin_size = FSL_PIN_SIZE;
/* Initialise group */ /* Initialise group */
grp->name = np->name; grp->name = np->name;
...@@ -403,12 +427,12 @@ static int imx_pinctrl_parse_groups(struct device_node *np, ...@@ -403,12 +427,12 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
*/ */
list = of_get_property(np, "fsl,pins", &size); list = of_get_property(np, "fsl,pins", &size);
/* we do not check return since it's safe node passed down */ /* we do not check return since it's safe node passed down */
if (!size || size % FSL_PIN_SIZE) { if (!size || size % pin_size) {
dev_err(info->dev, "Invalid fsl,pins property\n"); dev_err(info->dev, "Invalid fsl,pins property\n");
return -EINVAL; return -EINVAL;
} }
grp->npins = size / FSL_PIN_SIZE; grp->npins = size / pin_size;
grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
GFP_KERNEL); GFP_KERNEL);
grp->mux_mode = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), grp->mux_mode = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
...@@ -421,10 +445,17 @@ static int imx_pinctrl_parse_groups(struct device_node *np, ...@@ -421,10 +445,17 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
GFP_KERNEL); GFP_KERNEL);
for (i = 0; i < grp->npins; i++) { for (i = 0; i < grp->npins; i++) {
u32 mux_reg = be32_to_cpu(*list++); u32 mux_reg = be32_to_cpu(*list++);
u32 conf_reg = be32_to_cpu(*list++); u32 conf_reg;
unsigned int pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4; unsigned int pin_id;
struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; struct imx_pin_reg *pin_reg;
if (info->flags & SHARE_MUX_CONF_REG)
conf_reg = mux_reg;
else
conf_reg = be32_to_cpu(*list++);
pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4;
pin_reg = &info->pin_regs[pin_id];
grp->pins[i] = pin_id; grp->pins[i] = pin_id;
pin_reg->mux_reg = mux_reg; pin_reg->mux_reg = mux_reg;
pin_reg->conf_reg = conf_reg; pin_reg->conf_reg = conf_reg;
......
...@@ -74,8 +74,12 @@ struct imx_pinctrl_soc_info { ...@@ -74,8 +74,12 @@ struct imx_pinctrl_soc_info {
unsigned int ngroups; unsigned int ngroups;
struct imx_pmx_func *functions; struct imx_pmx_func *functions;
unsigned int nfunctions; unsigned int nfunctions;
unsigned int flags;
}; };
#define ZERO_OFFSET_VALID 0x1
#define SHARE_MUX_CONF_REG 0x2
#define NO_MUX 0x0 #define NO_MUX 0x0
#define NO_PAD 0x0 #define NO_PAD 0x0
......
...@@ -515,7 +515,6 @@ int mxs_pinctrl_probe(struct platform_device *pdev, ...@@ -515,7 +515,6 @@ int mxs_pinctrl_probe(struct platform_device *pdev,
return 0; return 0;
err: err:
platform_set_drvdata(pdev, NULL);
iounmap(d->base); iounmap(d->base);
return ret; return ret;
} }
...@@ -525,7 +524,6 @@ int mxs_pinctrl_remove(struct platform_device *pdev) ...@@ -525,7 +524,6 @@ int mxs_pinctrl_remove(struct platform_device *pdev)
{ {
struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); struct mxs_pinctrl_data *d = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
pinctrl_unregister(d->pctl); pinctrl_unregister(d->pctl);
iounmap(d->base); iounmap(d->base);
......
...@@ -1309,7 +1309,7 @@ static int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq, ...@@ -1309,7 +1309,7 @@ static int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq,
return 0; return 0;
} }
const struct irq_domain_ops nmk_gpio_irq_simple_ops = { static const struct irq_domain_ops nmk_gpio_irq_simple_ops = {
.map = nmk_gpio_irq_map, .map = nmk_gpio_irq_map,
.xlate = irq_domain_xlate_twocell, .xlate = irq_domain_xlate_twocell,
}; };
...@@ -1681,7 +1681,7 @@ static bool nmk_pinctrl_dt_get_config(struct device_node *np, ...@@ -1681,7 +1681,7 @@ static bool nmk_pinctrl_dt_get_config(struct device_node *np,
return has_config; return has_config;
} }
int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np, struct device_node *np,
struct pinctrl_map **map, struct pinctrl_map **map,
unsigned *reserved_maps, unsigned *reserved_maps,
...@@ -1740,7 +1740,7 @@ int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -1740,7 +1740,7 @@ int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
return ret; return ret;
} }
int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np_config, struct device_node *np_config,
struct pinctrl_map **map, unsigned *num_maps) struct pinctrl_map **map, unsigned *num_maps)
{ {
......
This diff is collapsed.
...@@ -50,7 +50,7 @@ static struct pin_config { ...@@ -50,7 +50,7 @@ static struct pin_config {
}; };
/* Global list of devices (struct samsung_pinctrl_drv_data) */ /* Global list of devices (struct samsung_pinctrl_drv_data) */
LIST_HEAD(drvdata_list); static LIST_HEAD(drvdata_list);
static unsigned int pin_base; static unsigned int pin_base;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#define DRIVER_NAME "pinctrl-single" #define DRIVER_NAME "pinctrl-single"
#define PCS_MUX_PINS_NAME "pinctrl-single,pins" #define PCS_MUX_PINS_NAME "pinctrl-single,pins"
#define PCS_MUX_BITS_NAME "pinctrl-single,bits" #define PCS_MUX_BITS_NAME "pinctrl-single,bits"
#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) #define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 3)
#define PCS_OFF_DISABLED ~0U #define PCS_OFF_DISABLED ~0U
/** /**
...@@ -163,6 +163,7 @@ struct pcs_name { ...@@ -163,6 +163,7 @@ struct pcs_name {
* @foff: value to turn mux off * @foff: value to turn mux off
* @fmax: max number of functions in fmask * @fmax: max number of functions in fmask
* @is_pinconf: whether supports pinconf * @is_pinconf: whether supports pinconf
* @bits_per_pin:number of bits per pin
* @names: array of register names for pins * @names: array of register names for pins
* @pins: physical pins on the SoC * @pins: physical pins on the SoC
* @pgtree: pingroup index radix tree * @pgtree: pingroup index radix tree
...@@ -190,6 +191,7 @@ struct pcs_device { ...@@ -190,6 +191,7 @@ struct pcs_device {
unsigned fmax; unsigned fmax;
bool bits_per_mux; bool bits_per_mux;
bool is_pinconf; bool is_pinconf;
unsigned bits_per_pin;
struct pcs_name *names; struct pcs_name *names;
struct pcs_data pins; struct pcs_data pins;
struct radix_tree_root pgtree; struct radix_tree_root pgtree;
...@@ -431,10 +433,11 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector, ...@@ -431,10 +433,11 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
vals = &func->vals[i]; vals = &func->vals[i];
val = pcs->read(vals->reg); val = pcs->read(vals->reg);
if (!vals->mask)
mask = pcs->fmask; if (pcs->bits_per_mux)
mask = vals->mask;
else else
mask = pcs->fmask & vals->mask; mask = pcs->fmask;
val &= ~mask; val &= ~mask;
val |= (vals->val & mask); val |= (vals->val & mask);
...@@ -741,7 +744,8 @@ static const struct pinconf_ops pcs_pinconf_ops = { ...@@ -741,7 +744,8 @@ static const struct pinconf_ops pcs_pinconf_ops = {
* @pcs: pcs driver instance * @pcs: pcs driver instance
* @offset: register offset from base * @offset: register offset from base
*/ */
static int pcs_add_pin(struct pcs_device *pcs, unsigned offset) static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
unsigned pin_pos)
{ {
struct pinctrl_pin_desc *pin; struct pinctrl_pin_desc *pin;
struct pcs_name *pn; struct pcs_name *pn;
...@@ -756,8 +760,8 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset) ...@@ -756,8 +760,8 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset)
pin = &pcs->pins.pa[i]; pin = &pcs->pins.pa[i];
pn = &pcs->names[i]; pn = &pcs->names[i];
sprintf(pn->name, "%lx", sprintf(pn->name, "%lx.%d",
(unsigned long)pcs->res->start + offset); (unsigned long)pcs->res->start + offset, pin_pos);
pin->name = pn->name; pin->name = pn->name;
pin->number = i; pin->number = i;
pcs->pins.cur++; pcs->pins.cur++;
...@@ -777,9 +781,17 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset) ...@@ -777,9 +781,17 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset)
static int pcs_allocate_pin_table(struct pcs_device *pcs) static int pcs_allocate_pin_table(struct pcs_device *pcs)
{ {
int mux_bytes, nr_pins, i; int mux_bytes, nr_pins, i;
int num_pins_in_register = 0;
mux_bytes = pcs->width / BITS_PER_BYTE; mux_bytes = pcs->width / BITS_PER_BYTE;
if (pcs->bits_per_mux) {
pcs->bits_per_pin = fls(pcs->fmask);
nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin;
num_pins_in_register = pcs->width / pcs->bits_per_pin;
} else {
nr_pins = pcs->size / mux_bytes; nr_pins = pcs->size / mux_bytes;
}
dev_dbg(pcs->dev, "allocating %i pins\n", nr_pins); dev_dbg(pcs->dev, "allocating %i pins\n", nr_pins);
pcs->pins.pa = devm_kzalloc(pcs->dev, pcs->pins.pa = devm_kzalloc(pcs->dev,
...@@ -800,9 +812,17 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs) ...@@ -800,9 +812,17 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)
for (i = 0; i < pcs->desc.npins; i++) { for (i = 0; i < pcs->desc.npins; i++) {
unsigned offset; unsigned offset;
int res; int res;
int byte_num;
int pin_pos = 0;
if (pcs->bits_per_mux) {
byte_num = (pcs->bits_per_pin * i) / BITS_PER_BYTE;
offset = (byte_num / mux_bytes) * mux_bytes;
pin_pos = i % num_pins_in_register;
} else {
offset = i * mux_bytes; offset = i * mux_bytes;
res = pcs_add_pin(pcs, offset); }
res = pcs_add_pin(pcs, offset, pin_pos);
if (res < 0) { if (res < 0) {
dev_err(pcs->dev, "error adding pins: %i\n", res); dev_err(pcs->dev, "error adding pins: %i\n", res);
return res; return res;
...@@ -919,6 +939,9 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset) ...@@ -919,6 +939,9 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset)
return -EINVAL; return -EINVAL;
} }
if (pcs->bits_per_mux)
index = (offset * BITS_PER_BYTE) / pcs->bits_per_pin;
else
index = offset / (pcs->width / BITS_PER_BYTE); index = offset / (pcs->width / BITS_PER_BYTE);
return index; return index;
...@@ -1097,29 +1120,18 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, ...@@ -1097,29 +1120,18 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
{ {
struct pcs_func_vals *vals; struct pcs_func_vals *vals;
const __be32 *mux; const __be32 *mux;
int size, params, rows, *pins, index = 0, found = 0, res = -ENOMEM; int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
struct pcs_function *function; struct pcs_function *function;
if (pcs->bits_per_mux) {
params = 3;
mux = of_get_property(np, PCS_MUX_BITS_NAME, &size);
} else {
params = 2;
mux = of_get_property(np, PCS_MUX_PINS_NAME, &size); mux = of_get_property(np, PCS_MUX_PINS_NAME, &size);
} if ((!mux) || (size < sizeof(*mux) * 2)) {
dev_err(pcs->dev, "bad data for mux %s\n",
if (!mux) { np->name);
dev_err(pcs->dev, "no valid property for %s\n", np->name);
return -EINVAL;
}
if (size < (sizeof(*mux) * params)) {
dev_err(pcs->dev, "bad data for %s\n", np->name);
return -EINVAL; return -EINVAL;
} }
size /= sizeof(*mux); /* Number of elements in array */ size /= sizeof(*mux); /* Number of elements in array */
rows = size / params; rows = size / 2;
vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL); vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL);
if (!vals) if (!vals)
...@@ -1137,10 +1149,6 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, ...@@ -1137,10 +1149,6 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
val = be32_to_cpup(mux + index++); val = be32_to_cpup(mux + index++);
vals[found].reg = pcs->base + offset; vals[found].reg = pcs->base + offset;
vals[found].val = val; vals[found].val = val;
if (params == 3) {
val = be32_to_cpup(mux + index++);
vals[found].mask = val;
}
pin = pcs_get_pin_by_offset(pcs, offset); pin = pcs_get_pin_by_offset(pcs, offset);
if (pin < 0) { if (pin < 0) {
...@@ -1184,6 +1192,125 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, ...@@ -1184,6 +1192,125 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
free_pins: free_pins:
devm_kfree(pcs->dev, pins); devm_kfree(pcs->dev, pins);
free_vals:
devm_kfree(pcs->dev, vals);
return res;
}
#define PARAMS_FOR_BITS_PER_MUX 3
static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
struct device_node *np,
struct pinctrl_map **map,
unsigned *num_maps,
const char **pgnames)
{
struct pcs_func_vals *vals;
const __be32 *mux;
int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
int npins_in_row;
struct pcs_function *function;
mux = of_get_property(np, PCS_MUX_BITS_NAME, &size);
if (!mux) {
dev_err(pcs->dev, "no valid property for %s\n", np->name);
return -EINVAL;
}
if (size < (sizeof(*mux) * PARAMS_FOR_BITS_PER_MUX)) {
dev_err(pcs->dev, "bad data for %s\n", np->name);
return -EINVAL;
}
/* Number of elements in array */
size /= sizeof(*mux);
rows = size / PARAMS_FOR_BITS_PER_MUX;
npins_in_row = pcs->width / pcs->bits_per_pin;
vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows * npins_in_row,
GFP_KERNEL);
if (!vals)
return -ENOMEM;
pins = devm_kzalloc(pcs->dev, sizeof(*pins) * rows * npins_in_row,
GFP_KERNEL);
if (!pins)
goto free_vals;
while (index < size) {
unsigned offset, val;
unsigned mask, bit_pos, val_pos, mask_pos, submask;
unsigned pin_num_from_lsb;
int pin;
offset = be32_to_cpup(mux + index++);
val = be32_to_cpup(mux + index++);
mask = be32_to_cpup(mux + index++);
/* Parse pins in each row from LSB */
while (mask) {
bit_pos = ffs(mask);
pin_num_from_lsb = bit_pos / pcs->bits_per_pin;
mask_pos = ((pcs->fmask) << (bit_pos - 1));
val_pos = val & mask_pos;
submask = mask & mask_pos;
mask &= ~mask_pos;
if (submask != mask_pos) {
dev_warn(pcs->dev,
"Invalid submask 0x%x for %s at 0x%x\n",
submask, np->name, offset);
continue;
}
vals[found].mask = submask;
vals[found].reg = pcs->base + offset;
vals[found].val = val_pos;
pin = pcs_get_pin_by_offset(pcs, offset);
if (pin < 0) {
dev_err(pcs->dev,
"could not add functions for %s %ux\n",
np->name, offset);
break;
}
pins[found++] = pin + pin_num_from_lsb;
}
}
pgnames[0] = np->name;
function = pcs_add_function(pcs, np, np->name, vals, found, pgnames, 1);
if (!function)
goto free_pins;
res = pcs_add_pingroup(pcs, np, np->name, pins, found);
if (res < 0)
goto free_function;
(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
(*map)->data.mux.group = np->name;
(*map)->data.mux.function = np->name;
if (pcs->is_pinconf) {
dev_err(pcs->dev, "pinconf not supported\n");
goto free_pingroups;
}
*num_maps = 1;
return 0;
free_pingroups:
pcs_free_pingroups(pcs);
*num_maps = 1;
free_function:
pcs_remove_function(pcs, function);
free_pins:
devm_kfree(pcs->dev, pins);
free_vals: free_vals:
devm_kfree(pcs->dev, vals); devm_kfree(pcs->dev, vals);
...@@ -1219,13 +1346,23 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -1219,13 +1346,23 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
goto free_map; goto free_map;
} }
ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, num_maps, if (pcs->bits_per_mux) {
pgnames); ret = pcs_parse_bits_in_pinctrl_entry(pcs, np_config, map,
num_maps, pgnames);
if (ret < 0) {
dev_err(pcs->dev, "no pins entries for %s\n",
np_config->name);
goto free_pgnames;
}
} else {
ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map,
num_maps, pgnames);
if (ret < 0) { if (ret < 0) {
dev_err(pcs->dev, "no pins entries for %s\n", dev_err(pcs->dev, "no pins entries for %s\n",
np_config->name); np_config->name);
goto free_pgnames; goto free_pgnames;
} }
}
return 0; return 0;
...@@ -1346,6 +1483,29 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) ...@@ -1346,6 +1483,29 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
return ret; return ret;
} }
static int pinctrl_single_suspend(struct platform_device *pdev,
pm_message_t state)
{
struct pcs_device *pcs;
pcs = platform_get_drvdata(pdev);
if (!pcs)
return -EINVAL;
return pinctrl_force_sleep(pcs->pctl);
}
static int pinctrl_single_resume(struct platform_device *pdev)
{
struct pcs_device *pcs;
pcs = platform_get_drvdata(pdev);
if (!pcs)
return -EINVAL;
return pinctrl_force_default(pcs->pctl);
}
static int pcs_probe(struct platform_device *pdev) static int pcs_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
...@@ -1494,6 +1654,10 @@ static struct platform_driver pcs_driver = { ...@@ -1494,6 +1654,10 @@ static struct platform_driver pcs_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.of_match_table = pcs_of_match, .of_match_table = pcs_of_match,
}, },
#ifdef CONFIG_PM
.suspend = pinctrl_single_suspend,
.resume = pinctrl_single_resume,
#endif
}; };
module_platform_driver(pcs_driver); module_platform_driver(pcs_driver);
......
This diff is collapsed.
This diff is collapsed.
...@@ -344,9 +344,31 @@ ...@@ -344,9 +344,31 @@
#define PULL_PINS_BITS 2 #define PULL_PINS_BITS 2
#define PULL_PINS_MASK 0x03 #define PULL_PINS_MASK 0x03
#define SUNXI_IRQ_NUMBER 32
#define IRQ_CFG_REG 0x200
#define IRQ_CFG_IRQ_PER_REG 8
#define IRQ_CFG_IRQ_BITS 4
#define IRQ_CFG_IRQ_MASK ((1 << IRQ_CFG_IRQ_BITS) - 1)
#define IRQ_CTRL_REG 0x210
#define IRQ_CTRL_IRQ_PER_REG 32
#define IRQ_CTRL_IRQ_BITS 1
#define IRQ_CTRL_IRQ_MASK ((1 << IRQ_CTRL_IRQ_BITS) - 1)
#define IRQ_STATUS_REG 0x214
#define IRQ_STATUS_IRQ_PER_REG 32
#define IRQ_STATUS_IRQ_BITS 1
#define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1)
#define IRQ_EDGE_RISING 0x00
#define IRQ_EDGE_FALLING 0x01
#define IRQ_LEVEL_HIGH 0x02
#define IRQ_LEVEL_LOW 0x03
#define IRQ_EDGE_BOTH 0x04
struct sunxi_desc_function { struct sunxi_desc_function {
const char *name; const char *name;
u8 muxval; u8 muxval;
u8 irqnum;
}; };
struct sunxi_desc_pin { struct sunxi_desc_pin {
...@@ -378,10 +400,13 @@ struct sunxi_pinctrl { ...@@ -378,10 +400,13 @@ struct sunxi_pinctrl {
struct gpio_chip *chip; struct gpio_chip *chip;
struct sunxi_pinctrl_desc *desc; struct sunxi_pinctrl_desc *desc;
struct device *dev; struct device *dev;
struct irq_domain *domain;
struct sunxi_pinctrl_function *functions; struct sunxi_pinctrl_function *functions;
unsigned nfunctions; unsigned nfunctions;
struct sunxi_pinctrl_group *groups; struct sunxi_pinctrl_group *groups;
unsigned ngroups; unsigned ngroups;
int irq;
int irq_array[SUNXI_IRQ_NUMBER];
struct pinctrl_dev *pctl_dev; struct pinctrl_dev *pctl_dev;
}; };
...@@ -398,6 +423,13 @@ struct sunxi_pinctrl { ...@@ -398,6 +423,13 @@ struct sunxi_pinctrl {
.muxval = _val, \ .muxval = _val, \
} }
#define SUNXI_FUNCTION_IRQ(_val, _irq) \
{ \
.name = "irq", \
.muxval = _val, \
.irqnum = _irq, \
}
/* /*
* The sunXi PIO registers are organized as is: * The sunXi PIO registers are organized as is:
* 0x00 - 0x0c Muxing values. * 0x00 - 0x0c Muxing values.
...@@ -475,4 +507,40 @@ static inline u32 sunxi_pull_offset(u16 pin) ...@@ -475,4 +507,40 @@ static inline u32 sunxi_pull_offset(u16 pin)
return pin_num * PULL_PINS_BITS; return pin_num * PULL_PINS_BITS;
} }
static inline u32 sunxi_irq_cfg_reg(u16 irq)
{
u8 reg = irq / IRQ_CFG_IRQ_PER_REG;
return reg + IRQ_CFG_REG;
}
static inline u32 sunxi_irq_cfg_offset(u16 irq)
{
u32 irq_num = irq % IRQ_CFG_IRQ_PER_REG;
return irq_num * IRQ_CFG_IRQ_BITS;
}
static inline u32 sunxi_irq_ctrl_reg(u16 irq)
{
u8 reg = irq / IRQ_CTRL_IRQ_PER_REG;
return reg + IRQ_CTRL_REG;
}
static inline u32 sunxi_irq_ctrl_offset(u16 irq)
{
u32 irq_num = irq % IRQ_CTRL_IRQ_PER_REG;
return irq_num * IRQ_CTRL_IRQ_BITS;
}
static inline u32 sunxi_irq_status_reg(u16 irq)
{
u8 reg = irq / IRQ_STATUS_IRQ_PER_REG;
return reg + IRQ_STATUS_REG;
}
static inline u32 sunxi_irq_status_offset(u16 irq)
{
u32 irq_num = irq % IRQ_STATUS_IRQ_PER_REG;
return irq_num * IRQ_STATUS_IRQ_BITS;
}
#endif /* __PINCTRL_SUNXI_H */ #endif /* __PINCTRL_SUNXI_H */
This diff is collapsed.
This diff is collapsed.
...@@ -1100,7 +1100,6 @@ static int u300_pmx_remove(struct platform_device *pdev) ...@@ -1100,7 +1100,6 @@ static int u300_pmx_remove(struct platform_device *pdev)
struct u300_pmx *upmx = platform_get_drvdata(pdev); struct u300_pmx *upmx = platform_get_drvdata(pdev);
pinctrl_unregister(upmx->pctl); pinctrl_unregister(upmx->pctl);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
/*
* VF610 pinctrl driver based on imx pinmux and pinconf core
*
* Copyright 2013 Freescale Semiconductor, Inc.
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*/
#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>
#include "pinctrl-imx.h"
enum vf610_pads {
VF610_PAD_PTA6 = 0,
VF610_PAD_PTA8 = 1,
VF610_PAD_PTA9 = 2,
VF610_PAD_PTA10 = 3,
VF610_PAD_PTA11 = 4,
VF610_PAD_PTA12 = 5,
VF610_PAD_PTA16 = 6,
VF610_PAD_PTA17 = 7,
VF610_PAD_PTA18 = 8,
VF610_PAD_PTA19 = 9,
VF610_PAD_PTA20 = 10,
VF610_PAD_PTA21 = 11,
VF610_PAD_PTA22 = 12,
VF610_PAD_PTA23 = 13,
VF610_PAD_PTA24 = 14,
VF610_PAD_PTA25 = 15,
VF610_PAD_PTA26 = 16,
VF610_PAD_PTA27 = 17,
VF610_PAD_PTA28 = 18,
VF610_PAD_PTA29 = 19,
VF610_PAD_PTA30 = 20,
VF610_PAD_PTA31 = 21,
VF610_PAD_PTB0 = 22,
VF610_PAD_PTB1 = 23,
VF610_PAD_PTB2 = 24,
VF610_PAD_PTB3 = 25,
VF610_PAD_PTB4 = 26,
VF610_PAD_PTB5 = 27,
VF610_PAD_PTB6 = 28,
VF610_PAD_PTB7 = 29,
VF610_PAD_PTB8 = 30,
VF610_PAD_PTB9 = 31,
VF610_PAD_PTB10 = 32,
VF610_PAD_PTB11 = 33,
VF610_PAD_PTB12 = 34,
VF610_PAD_PTB13 = 35,
VF610_PAD_PTB14 = 36,
VF610_PAD_PTB15 = 37,
VF610_PAD_PTB16 = 38,
VF610_PAD_PTB17 = 39,
VF610_PAD_PTB18 = 40,
VF610_PAD_PTB19 = 41,
VF610_PAD_PTB20 = 42,
VF610_PAD_PTB21 = 43,
VF610_PAD_PTB22 = 44,
VF610_PAD_PTC0 = 45,
VF610_PAD_PTC1 = 46,
VF610_PAD_PTC2 = 47,
VF610_PAD_PTC3 = 48,
VF610_PAD_PTC4 = 49,
VF610_PAD_PTC5 = 50,
VF610_PAD_PTC6 = 51,
VF610_PAD_PTC7 = 52,
VF610_PAD_PTC8 = 53,
VF610_PAD_PTC9 = 54,
VF610_PAD_PTC10 = 55,
VF610_PAD_PTC11 = 56,
VF610_PAD_PTC12 = 57,
VF610_PAD_PTC13 = 58,
VF610_PAD_PTC14 = 59,
VF610_PAD_PTC15 = 60,
VF610_PAD_PTC16 = 61,
VF610_PAD_PTC17 = 62,
VF610_PAD_PTD31 = 63,
VF610_PAD_PTD30 = 64,
VF610_PAD_PTD29 = 65,
VF610_PAD_PTD28 = 66,
VF610_PAD_PTD27 = 67,
VF610_PAD_PTD26 = 68,
VF610_PAD_PTD25 = 69,
VF610_PAD_PTD24 = 70,
VF610_PAD_PTD23 = 71,
VF610_PAD_PTD22 = 72,
VF610_PAD_PTD21 = 73,
VF610_PAD_PTD20 = 74,
VF610_PAD_PTD19 = 75,
VF610_PAD_PTD18 = 76,
VF610_PAD_PTD17 = 77,
VF610_PAD_PTD16 = 78,
VF610_PAD_PTD0 = 79,
VF610_PAD_PTD1 = 80,
VF610_PAD_PTD2 = 81,
VF610_PAD_PTD3 = 82,
VF610_PAD_PTD4 = 83,
VF610_PAD_PTD5 = 84,
VF610_PAD_PTD6 = 85,
VF610_PAD_PTD7 = 86,
VF610_PAD_PTD8 = 87,
VF610_PAD_PTD9 = 88,
VF610_PAD_PTD10 = 89,
VF610_PAD_PTD11 = 90,
VF610_PAD_PTD12 = 91,
VF610_PAD_PTD13 = 92,
VF610_PAD_PTB23 = 93,
VF610_PAD_PTB24 = 94,
VF610_PAD_PTB25 = 95,
VF610_PAD_PTB26 = 96,
VF610_PAD_PTB27 = 97,
VF610_PAD_PTB28 = 98,
VF610_PAD_PTC26 = 99,
VF610_PAD_PTC27 = 100,
VF610_PAD_PTC28 = 101,
VF610_PAD_PTC29 = 102,
VF610_PAD_PTC30 = 103,
VF610_PAD_PTC31 = 104,
VF610_PAD_PTE0 = 105,
VF610_PAD_PTE1 = 106,
VF610_PAD_PTE2 = 107,
VF610_PAD_PTE3 = 108,
VF610_PAD_PTE4 = 109,
VF610_PAD_PTE5 = 110,
VF610_PAD_PTE6 = 111,
VF610_PAD_PTE7 = 112,
VF610_PAD_PTE8 = 113,
VF610_PAD_PTE9 = 114,
VF610_PAD_PTE10 = 115,
VF610_PAD_PTE11 = 116,
VF610_PAD_PTE12 = 117,
VF610_PAD_PTE13 = 118,
VF610_PAD_PTE14 = 119,
VF610_PAD_PTE15 = 120,
VF610_PAD_PTE16 = 121,
VF610_PAD_PTE17 = 122,
VF610_PAD_PTE18 = 123,
VF610_PAD_PTE19 = 124,
VF610_PAD_PTE20 = 125,
VF610_PAD_PTE21 = 126,
VF610_PAD_PTE22 = 127,
VF610_PAD_PTE23 = 128,
VF610_PAD_PTE24 = 129,
VF610_PAD_PTE25 = 130,
VF610_PAD_PTE26 = 131,
VF610_PAD_PTE27 = 132,
VF610_PAD_PTE28 = 133,
VF610_PAD_PTA7 = 134,
};
/* Pad names for the pinmux subsystem */
static const struct pinctrl_pin_desc vf610_pinctrl_pads[] = {
IMX_PINCTRL_PIN(VF610_PAD_PTA6),
IMX_PINCTRL_PIN(VF610_PAD_PTA8),
IMX_PINCTRL_PIN(VF610_PAD_PTA9),
IMX_PINCTRL_PIN(VF610_PAD_PTA10),
IMX_PINCTRL_PIN(VF610_PAD_PTA11),
IMX_PINCTRL_PIN(VF610_PAD_PTA12),
IMX_PINCTRL_PIN(VF610_PAD_PTA16),
IMX_PINCTRL_PIN(VF610_PAD_PTA17),
IMX_PINCTRL_PIN(VF610_PAD_PTA18),
IMX_PINCTRL_PIN(VF610_PAD_PTA19),
IMX_PINCTRL_PIN(VF610_PAD_PTA20),
IMX_PINCTRL_PIN(VF610_PAD_PTA21),
IMX_PINCTRL_PIN(VF610_PAD_PTA22),
IMX_PINCTRL_PIN(VF610_PAD_PTA23),
IMX_PINCTRL_PIN(VF610_PAD_PTA24),
IMX_PINCTRL_PIN(VF610_PAD_PTA25),
IMX_PINCTRL_PIN(VF610_PAD_PTA26),
IMX_PINCTRL_PIN(VF610_PAD_PTA27),
IMX_PINCTRL_PIN(VF610_PAD_PTA28),
IMX_PINCTRL_PIN(VF610_PAD_PTA29),
IMX_PINCTRL_PIN(VF610_PAD_PTA30),
IMX_PINCTRL_PIN(VF610_PAD_PTA31),
IMX_PINCTRL_PIN(VF610_PAD_PTB0),
IMX_PINCTRL_PIN(VF610_PAD_PTB1),
IMX_PINCTRL_PIN(VF610_PAD_PTB2),
IMX_PINCTRL_PIN(VF610_PAD_PTB3),
IMX_PINCTRL_PIN(VF610_PAD_PTB4),
IMX_PINCTRL_PIN(VF610_PAD_PTB5),
IMX_PINCTRL_PIN(VF610_PAD_PTB6),
IMX_PINCTRL_PIN(VF610_PAD_PTB7),
IMX_PINCTRL_PIN(VF610_PAD_PTB8),
IMX_PINCTRL_PIN(VF610_PAD_PTB9),
IMX_PINCTRL_PIN(VF610_PAD_PTB10),
IMX_PINCTRL_PIN(VF610_PAD_PTB11),
IMX_PINCTRL_PIN(VF610_PAD_PTB12),
IMX_PINCTRL_PIN(VF610_PAD_PTB13),
IMX_PINCTRL_PIN(VF610_PAD_PTB14),
IMX_PINCTRL_PIN(VF610_PAD_PTB15),
IMX_PINCTRL_PIN(VF610_PAD_PTB16),
IMX_PINCTRL_PIN(VF610_PAD_PTB17),
IMX_PINCTRL_PIN(VF610_PAD_PTB18),
IMX_PINCTRL_PIN(VF610_PAD_PTB19),
IMX_PINCTRL_PIN(VF610_PAD_PTB20),
IMX_PINCTRL_PIN(VF610_PAD_PTB21),
IMX_PINCTRL_PIN(VF610_PAD_PTB22),
IMX_PINCTRL_PIN(VF610_PAD_PTC0),
IMX_PINCTRL_PIN(VF610_PAD_PTC1),
IMX_PINCTRL_PIN(VF610_PAD_PTC2),
IMX_PINCTRL_PIN(VF610_PAD_PTC3),
IMX_PINCTRL_PIN(VF610_PAD_PTC4),
IMX_PINCTRL_PIN(VF610_PAD_PTC5),
IMX_PINCTRL_PIN(VF610_PAD_PTC6),
IMX_PINCTRL_PIN(VF610_PAD_PTC7),
IMX_PINCTRL_PIN(VF610_PAD_PTC8),
IMX_PINCTRL_PIN(VF610_PAD_PTC9),
IMX_PINCTRL_PIN(VF610_PAD_PTC10),
IMX_PINCTRL_PIN(VF610_PAD_PTC11),
IMX_PINCTRL_PIN(VF610_PAD_PTC12),
IMX_PINCTRL_PIN(VF610_PAD_PTC13),
IMX_PINCTRL_PIN(VF610_PAD_PTC14),
IMX_PINCTRL_PIN(VF610_PAD_PTC15),
IMX_PINCTRL_PIN(VF610_PAD_PTC16),
IMX_PINCTRL_PIN(VF610_PAD_PTC17),
IMX_PINCTRL_PIN(VF610_PAD_PTD31),
IMX_PINCTRL_PIN(VF610_PAD_PTD30),
IMX_PINCTRL_PIN(VF610_PAD_PTD29),
IMX_PINCTRL_PIN(VF610_PAD_PTD28),
IMX_PINCTRL_PIN(VF610_PAD_PTD27),
IMX_PINCTRL_PIN(VF610_PAD_PTD26),
IMX_PINCTRL_PIN(VF610_PAD_PTD25),
IMX_PINCTRL_PIN(VF610_PAD_PTD24),
IMX_PINCTRL_PIN(VF610_PAD_PTD23),
IMX_PINCTRL_PIN(VF610_PAD_PTD22),
IMX_PINCTRL_PIN(VF610_PAD_PTD21),
IMX_PINCTRL_PIN(VF610_PAD_PTD20),
IMX_PINCTRL_PIN(VF610_PAD_PTD19),
IMX_PINCTRL_PIN(VF610_PAD_PTD18),
IMX_PINCTRL_PIN(VF610_PAD_PTD17),
IMX_PINCTRL_PIN(VF610_PAD_PTD16),
IMX_PINCTRL_PIN(VF610_PAD_PTD0),
IMX_PINCTRL_PIN(VF610_PAD_PTD1),
IMX_PINCTRL_PIN(VF610_PAD_PTD2),
IMX_PINCTRL_PIN(VF610_PAD_PTD3),
IMX_PINCTRL_PIN(VF610_PAD_PTD4),
IMX_PINCTRL_PIN(VF610_PAD_PTD5),
IMX_PINCTRL_PIN(VF610_PAD_PTD6),
IMX_PINCTRL_PIN(VF610_PAD_PTD7),
IMX_PINCTRL_PIN(VF610_PAD_PTD8),
IMX_PINCTRL_PIN(VF610_PAD_PTD9),
IMX_PINCTRL_PIN(VF610_PAD_PTD10),
IMX_PINCTRL_PIN(VF610_PAD_PTD11),
IMX_PINCTRL_PIN(VF610_PAD_PTD12),
IMX_PINCTRL_PIN(VF610_PAD_PTD13),
IMX_PINCTRL_PIN(VF610_PAD_PTB23),
IMX_PINCTRL_PIN(VF610_PAD_PTB24),
IMX_PINCTRL_PIN(VF610_PAD_PTB25),
IMX_PINCTRL_PIN(VF610_PAD_PTB26),
IMX_PINCTRL_PIN(VF610_PAD_PTB27),
IMX_PINCTRL_PIN(VF610_PAD_PTB28),
IMX_PINCTRL_PIN(VF610_PAD_PTC26),
IMX_PINCTRL_PIN(VF610_PAD_PTC27),
IMX_PINCTRL_PIN(VF610_PAD_PTC28),
IMX_PINCTRL_PIN(VF610_PAD_PTC29),
IMX_PINCTRL_PIN(VF610_PAD_PTC30),
IMX_PINCTRL_PIN(VF610_PAD_PTC31),
IMX_PINCTRL_PIN(VF610_PAD_PTE0),
IMX_PINCTRL_PIN(VF610_PAD_PTE1),
IMX_PINCTRL_PIN(VF610_PAD_PTE2),
IMX_PINCTRL_PIN(VF610_PAD_PTE3),
IMX_PINCTRL_PIN(VF610_PAD_PTE4),
IMX_PINCTRL_PIN(VF610_PAD_PTE5),
IMX_PINCTRL_PIN(VF610_PAD_PTE6),
IMX_PINCTRL_PIN(VF610_PAD_PTE7),
IMX_PINCTRL_PIN(VF610_PAD_PTE8),
IMX_PINCTRL_PIN(VF610_PAD_PTE9),
IMX_PINCTRL_PIN(VF610_PAD_PTE10),
IMX_PINCTRL_PIN(VF610_PAD_PTE11),
IMX_PINCTRL_PIN(VF610_PAD_PTE12),
IMX_PINCTRL_PIN(VF610_PAD_PTE13),
IMX_PINCTRL_PIN(VF610_PAD_PTE14),
IMX_PINCTRL_PIN(VF610_PAD_PTE15),
IMX_PINCTRL_PIN(VF610_PAD_PTE16),
IMX_PINCTRL_PIN(VF610_PAD_PTE17),
IMX_PINCTRL_PIN(VF610_PAD_PTE18),
IMX_PINCTRL_PIN(VF610_PAD_PTE19),
IMX_PINCTRL_PIN(VF610_PAD_PTE20),
IMX_PINCTRL_PIN(VF610_PAD_PTE21),
IMX_PINCTRL_PIN(VF610_PAD_PTE22),
IMX_PINCTRL_PIN(VF610_PAD_PTE23),
IMX_PINCTRL_PIN(VF610_PAD_PTE24),
IMX_PINCTRL_PIN(VF610_PAD_PTE25),
IMX_PINCTRL_PIN(VF610_PAD_PTE26),
IMX_PINCTRL_PIN(VF610_PAD_PTE27),
IMX_PINCTRL_PIN(VF610_PAD_PTE28),
IMX_PINCTRL_PIN(VF610_PAD_PTA7),
};
static struct imx_pinctrl_soc_info vf610_pinctrl_info = {
.pins = vf610_pinctrl_pads,
.npins = ARRAY_SIZE(vf610_pinctrl_pads),
.flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG,
};
static struct of_device_id vf610_pinctrl_of_match[] = {
{ .compatible = "fsl,vf610-iomuxc", },
{ /* sentinel */ }
};
static int vf610_pinctrl_probe(struct platform_device *pdev)
{
return imx_pinctrl_probe(pdev, &vf610_pinctrl_info);
}
static struct platform_driver vf610_pinctrl_driver = {
.driver = {
.name = "vf610-pinctrl",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(vf610_pinctrl_of_match),
},
.probe = vf610_pinctrl_probe,
.remove = imx_pinctrl_remove,
};
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");
This diff is collapsed.
This diff is collapsed.
# CSR SiRFsoc pinmux support
obj-y += pinctrl-sirf.o
obj-y += pinctrl-prima2.o
obj-y += pinctrl-atlas6.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -569,11 +569,9 @@ int wmt_pinctrl_probe(struct platform_device *pdev, ...@@ -569,11 +569,9 @@ int wmt_pinctrl_probe(struct platform_device *pdev,
struct resource *res; struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->base = devm_request_and_ioremap(&pdev->dev, res); data->base = devm_ioremap_resource(&pdev->dev, res);
if (!data->base) { if (IS_ERR(data->base))
dev_err(&pdev->dev, "failed to map memory resource\n"); return PTR_ERR(data->base);
return -EBUSY;
}
wmt_desc.pins = data->pins; wmt_desc.pins = data->pins;
wmt_desc.npins = data->npins; wmt_desc.npins = data->npins;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -30,7 +30,7 @@ struct seq_file; ...@@ -30,7 +30,7 @@ struct seq_file;
* @pin_config_set: configure an individual pin * @pin_config_set: configure an individual pin
* @pin_config_group_get: get configurations for an entire pin group * @pin_config_group_get: get configurations for an entire pin group
* @pin_config_group_set: configure all pins in a group * @pin_config_group_set: configure all pins in a group
* @pin_config_group_dbg_set: optional debugfs to modify a pin configuration * @pin_config_dbg_parse_modify: optional debugfs to modify a pin configuration
* @pin_config_dbg_show: optional debugfs display hook that will provide * @pin_config_dbg_show: optional debugfs display hook that will provide
* per-device info for a certain pin in debugfs * per-device info for a certain pin in debugfs
* @pin_config_group_dbg_show: optional debugfs display hook that will provide * @pin_config_group_dbg_show: optional debugfs display hook that will provide
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment