Commit 8a3a11f9 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull pinctrl changes from Linus Walleij:
 "These are the main pinctrl changes for the v3.9 merge window.  The
  most interesting change by far is how the device core grabs pinctrl
  default handles avoiding the need to stick boilerplate into driver
  consumers.

   - Grabbing of default pinctrl handles from the device core.  These
     are the hunks hitting drivers/base.  All is ACKed by Greg, after a
     long discussion about different alternatives.

   - Some stuff also touches the MFD and ARM SoC trees, this has been
     coordinated and ACKed.

   - New drivers for:
     - The Tegra 114 sub-SoC
     - Allwinner sunxi
     - New ABx500 driver and sub-SoC drivers for AB8500, AB8505, AB9540
       and AB8540.

   - Make it possible for hogged pins to enter a sleep mode, and make it
     possible for drivers to control that mode.

   - Various clean-up, extensions and device tree support to various pin
     controllers."

* tag 'pinctrl-for-v3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (68 commits)
  pinctrl: tegra: add clfvs function to Tegra114 support
  pinctrl: generic: rename input schmitt disable
  pinctrl/pinconfig: add debug interface
  pinctrl: samsung: remove duplicated line
  ARM: ux500: use real AB8500 IRQ numbers instead of virtual ones
  ARM: ux500: remove irq_base property from platform_data
  pinctrl/abx500: use direct IRQ defines
  pinctrl/abx500: replace IRQ offsets with table read-in values
  pinctrl/abx500: move IRQ handling to ab8500-core
  pinctrl: exynos5440: remove erroneous __init
  pinctrl/abx500: adjust offset for get_mode()
  pinctrl/abx500: add Device Tree support
  pinctrl/abx500: align GPIO cluster boundaries
  pinctrl/abx500: prevent error path from corrupting returning error
  pinctrl: sunxi: add of_xlate function
  pinctrl/lantiq: fix pin number in ltq_pmx_gpio_request_enable
  pinctrl/lantiq: add functionality to falcon_pinconf_dbg_show
  pinctrl/lantiq: fix pinconfig parameters
  pinctrl/lantiq: one of the boot leds was defined incorrectly
  pinctrl/lantiq: only probe available pad controllers
  ...
parents 8909ff65 ade158eb
* Allwinner A1X Pin Controller
The pins controlled by sunXi pin controller are organized in banks,
each bank has 32 pins. Each pin has 7 multiplexing functions, with
the first two functions being GPIO in and out. The configuration on
the pins includes drive strength and pull-up.
Required properties:
- compatible: "allwinner,<soc>-pinctrl". Supported SoCs for now are:
sun5i-a13.
- reg: Should contain the register physical address and length for the
pin controller.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices.
A pinctrl node should contain at least one subnodes representing the
pinctrl groups available on the machine. Each subnode will list the
pins it needs, and how they should be configured, with regard to muxer
configuration, drive strength and pullups. If one of these options is
not set, its actual value will be unspecified.
Required subnode-properties:
- allwinner,pins: List of strings containing the pin name.
- allwinner,function: Function to mux the pins listed above to.
Optional subnode-properties:
- allwinner,drive: Integer. Represents the current sent to the pin
0: 10 mA
1: 20 mA
2: 30 mA
3: 40 mA
- allwinner,pull: Integer.
0: No resistor
1: Pull-up resistor
2: Pull-down resistor
Examples:
pinctrl@01c20800 {
compatible = "allwinner,sun5i-a13-pinctrl";
reg = <0x01c20800 0x400>;
#address-cells = <1>;
#size-cells = <0>;
uart1_pins_a: uart1@0 {
allwinner,pins = "PE10", "PE11";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
uart1_pins_b: uart1@1 {
allwinner,pins = "PG3", "PG4";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
};
NVIDIA Tegra114 pinmux controller
The Tegra114 pinctrl binding is very similar to the Tegra20 and Tegra30
pinctrl binding, as described in nvidia,tegra20-pinmux.txt and
nvidia,tegra30-pinmux.txt. In fact, this document assumes that binding as
a baseline, and only documents the differences between the two bindings.
Required properties:
- compatible: "nvidia,tegra114-pinmux"
- reg: Should contain the register physical address and length for each of
the pad control and mux registers. The first bank of address must be the
driver strength pad control register address and second bank address must
be pinmux register address.
Tegra114 adds the following optional properties for pin configuration subnodes:
- nvidia,enable-input: Integer. Enable the pin's input path. 0: no, 1: yes.
- nvidia,open-drain: Integer. Enable open drain mode. 0: no, 1: yes.
- nvidia,lock: Integer. Lock the pin configuration against further changes
until reset. 0: no, 1: yes.
- nvidia,io-reset: Integer. Reset the IO path. 0: no, 1: yes.
- nvidia,rcv-sel: Integer. Select VIL/VIH receivers. 0: normal, 1: high.
- nvidia,drive-type: Integer. Valid range 0...3.
As with Tegra20 and Terga30, see the Tegra TRM for complete details regarding
which groups support which functionality.
Valid values for pin and group names are:
per-pin mux groups:
These all support nvidia,function, nvidia,tristate, nvidia,pull,
nvidia,enable-input, nvidia,lock. Some support nvidia,open-drain,
nvidia,io-reset and nvidia,rcv-sel.
ulpi_data0_po1, ulpi_data1_po2, ulpi_data2_po3, ulpi_data3_po4,
ulpi_data4_po5, ulpi_data5_po6, ulpi_data6_po7, ulpi_data7_po0,
ulpi_clk_py0, ulpi_dir_py1, ulpi_nxt_py2, ulpi_stp_py3, dap3_fs_pp0,
dap3_din_pp1, dap3_dout_pp2, dap3_sclk_pp3, pv0, pv1, sdmmc1_clk_pz0,
sdmmc1_cmd_pz1, sdmmc1_dat3_py4, sdmmc1_dat2_py5, sdmmc1_dat1_py6,
sdmmc1_dat0_py7, clk2_out_pw5, clk2_req_pcc5, hdmi_int_pn7, ddc_scl_pv4,
ddc_sda_pv5, uart2_rxd_pc3, uart2_txd_pc2, uart2_rts_n_pj6,
uart2_cts_n_pj5, uart3_txd_pw6, uart3_rxd_pw7, uart3_cts_n_pa1,
uart3_rts_n_pc0, pu0, pu1, pu2, pu3, pu4, pu5, pu6, gen1_i2c_sda_pc5,
gen1_i2c_scl_pc4, dap4_fs_pp4, dap4_din_pp5, dap4_dout_pp6, dap4_sclk_pp7,
clk3_out_pee0, clk3_req_pee1, gmi_wp_n_pc7, gmi_iordy_pi5, gmi_wait_pi7,
gmi_adv_n_pk0, gmi_clk_pk1, gmi_cs0_n_pj0, gmi_cs1_n_pj2, gmi_cs2_n_pk3,
gmi_cs3_n_pk4, gmi_cs4_n_pk2, gmi_cs6_n_pi3, gmi_cs7_n_pi6, gmi_ad0_pg0,
gmi_ad1_pg1, gmi_ad2_pg2, gmi_ad3_pg3, gmi_ad4_pg4, gmi_ad5_pg5,
gmi_ad6_pg6, gmi_ad7_pg7, gmi_ad8_ph0, gmi_ad9_ph1, gmi_ad10_ph2,
gmi_ad11_ph3, gmi_ad12_ph4, gmi_ad13_ph5, gmi_ad14_ph6, gmi_ad15_ph7,
gmi_a16_pj7, gmi_a17_pb0, gmi_a18_pb1, gmi_a19_pk7, gmi_wr_n_pi0,
gmi_oe_n_pi1, gmi_dqs_p_pj3, gmi_rst_n_pi4, gen2_i2c_scl_pt5,
gen2_i2c_sda_pt6, sdmmc4_clk_pcc4, sdmmc4_cmd_pt7, sdmmc4_dat0_paa0,
sdmmc4_dat1_paa1, sdmmc4_dat2_paa2, sdmmc4_dat3_paa3, sdmmc4_dat4_paa4,
sdmmc4_dat5_paa5, sdmmc4_dat6_paa6, sdmmc4_dat7_paa7, cam_mclk_pcc0,
pcc1, pbb0, cam_i2c_scl_pbb1, cam_i2c_sda_pbb2, pbb3, pbb4, pbb5, pbb6,
pbb7, pcc2, pwr_i2c_scl_pz6, pwr_i2c_sda_pz7, kb_row0_pr0, kb_row1_pr1,
kb_row2_pr2, kb_row3_pr3, kb_row4_pr4, kb_row5_pr5, kb_row6_pr6,
kb_row7_pr7, kb_row8_ps0, kb_row9_ps1, kb_row10_ps2, kb_col0_pq0,
kb_col1_pq1, kb_col2_pq2, kb_col3_pq3, kb_col4_pq4, kb_col5_pq5,
kb_col6_pq6, kb_col7_pq7, clk_32k_out_pa0, sys_clk_req_pz5, core_pwr_req,
cpu_pwr_req, pwr_int_n, owr, dap1_fs_pn0, dap1_din_pn1, dap1_dout_pn2,
dap1_sclk_pn3, clk1_req_pee2, clk1_out_pw4, spdif_in_pk6, spdif_out_pk5,
dap2_fs_pa2, dap2_din_pa4, dap2_dout_pa5, dap2_sclk_pa3, dvfs_pwm_px0,
gpio_x1_aud_px1, gpio_x3_aud_px3, dvfs_clk_px2, gpio_x4_aud_px4,
gpio_x5_aud_px5, gpio_x6_aud_px6, gpio_x7_aud_px7, sdmmc3_clk_pa6,
sdmmc3_cmd_pa7, sdmmc3_dat0_pb7, sdmmc3_dat1_pb6, sdmmc3_dat2_pb5,
sdmmc3_dat3_pb4, hdmi_cec_pee3, sdmmc1_wp_n_pv3, sdmmc3_cd_n_pv2,
gpio_w2_aud_pw2, gpio_w3_aud_pw3, usb_vbus_en0_pn4, usb_vbus_en1_pn5,
sdmmc3_clk_lb_in_pee5, sdmmc3_clk_lb_out_pee4, reset_out_n.
drive groups:
These all support nvidia,pull-down-strength, nvidia,pull-up-strength,
nvidia,slew-rate-rising, nvidia,slew-rate-falling. Most but not all
support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode
and nvidia,drive-type.
ao1, ao2, at1, at2, at3, at4, at5, cdev1, cdev2, dap1, dap2, dap3, dap4,
dbg, sdio3, spi, uaa, uab, uart2, uart3, sdio1, ddc, gma, gme, gmf, gmg,
gmh, owr, uda.
Example:
pinmux: pinmux {
compatible = "nvidia,tegra114-pinmux";
reg = <0x70000868 0x148 /* Pad control registers */
0x70003000 0x40c>; /* PinMux registers */
};
Example board file extract:
pinctrl {
sdmmc4_default: pinmux {
sdmmc4_clk_pcc4 {
nvidia,pins = "sdmmc4_clk_pcc4",
nvidia,function = "sdmmc4";
nvidia,pull = <0>;
nvidia,tristate = <0>;
};
sdmmc4_dat0_paa0 {
nvidia,pins = "sdmmc4_dat0_paa0",
"sdmmc4_dat1_paa1",
"sdmmc4_dat2_paa2",
"sdmmc4_dat3_paa3",
"sdmmc4_dat4_paa4",
"sdmmc4_dat5_paa5",
"sdmmc4_dat6_paa6",
"sdmmc4_dat7_paa7";
nvidia,function = "sdmmc4";
nvidia,pull = <2>;
nvidia,tristate = <0>;
};
};
};
sdhci@78000400 {
pinctrl-names = "default";
pinctrl-0 = <&sdmmc4_default>;
};
ST Ericsson Nomadik pinmux controller
Required properties:
- compatible: "stericsson,nmk-pinctrl", "stericsson,nmk-pinctrl-db8540",
"stericsson,nmk-pinctrl-stn8815"
- reg: Should contain the register physical address and length of the PRCMU.
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.
- ste,config: Handle of pin configuration node (e.g. ste,config = <&slpm_in_wkup_pdis>)
- ste,input : <0/1/2>
0: input with no pull
1: input with pull up,
2: input with pull down,
- ste,output: <0/1/2>
0: output low,
1: output high,
2: output (value is not specified).
- ste,sleep: <0/1>
0: sleep mode disable,
1: sleep mode enable.
- ste,sleep-input: <0/1/2/3>
0: sleep input with no pull,
1: sleep input with pull up,
2: sleep input with pull down.
3: sleep input and keep last input configuration (no pull, pull up or pull down).
- ste,sleep-output: <0/1/2>
0: sleep output low,
1: sleep output high,
2: sleep output (value is not specified).
- ste,sleep-gpio: <0/1>
0: disable sleep gpio mode,
1: enable sleep gpio mode.
- ste,sleep-wakeup: <0/1>
0: wake-up detection enabled,
1: wake-up detection disabled.
- ste,sleep-pull-disable: <0/1>
0: GPIO pull-up or pull-down resistor is enabled, when pin is an input,
1: GPIO pull-up and pull-down resistor are disabled.
Example board file extract:
pinctrl@80157000 {
compatible = "stericsson,nmk-pinctrl";
reg = <0x80157000 0x2000>;
pinctrl-names = "default";
slpm_in_wkup_pdis: slpm_in_wkup_pdis {
ste,sleep = <1>;
ste,sleep-input = <3>;
ste,sleep-wakeup = <1>;
ste,sleep-pull-disable = <0>;
};
slpm_out_hi_wkup_pdis: slpm_out_hi_wkup_pdis {
ste,sleep = <1>;
ste,sleep-output = <1>;
ste,sleep-wakeup = <1>;
ste,sleep-pull-disable = <0>;
};
slpm_out_wkup_pdis: slpm_out_wkup_pdis {
ste,sleep = <1>;
ste,sleep-output = <2>;
ste,sleep-wakeup = <1>;
ste,sleep-pull-disable = <0>;
};
uart0 {
uart0_default_mux: uart0_mux {
u0_default_mux {
ste,function = "u0";
ste,pins = "u0_a_1";
};
};
uart0_default_mode: uart0_default {
uart0_default_cfg1 {
ste,pins = "GPIO0", "GPIO2";
ste,input = <1>;
};
uart0_default_cfg2 {
ste,pins = "GPIO1", "GPIO3";
ste,output = <1>;
};
};
uart0_sleep_mode: uart0_sleep {
uart0_sleep_cfg1 {
ste,pins = "GPIO0", "GPIO2";
ste,config = <&slpm_in_wkup_pdis>;
};
uart0_sleep_cfg2 {
ste,pins = "GPIO1";
ste,config = <&slpm_out_hi_wkup_pdis>;
};
uart0_sleep_cfg3 {
ste,pins = "GPIO3";
ste,config = <&slpm_out_wkup_pdis>;
};
};
};
};
uart@80120000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x80120000 0x1000>;
interrupts = <0 11 0x4>;
pinctrl-names = "default","sleep";
pinctrl-0 = <&uart0_default_mux>, <&uart0_default_mode>;
pinctrl-1 = <&uart0_sleep_mode>;
};
...@@ -50,6 +50,7 @@ simtek ...@@ -50,6 +50,7 @@ simtek
sirf SiRF Technology, Inc. sirf SiRF Technology, Inc.
snps Synopsys, Inc. snps Synopsys, Inc.
st STMicroelectronics st STMicroelectronics
ste ST-Ericsson
stericsson ST-Ericsson stericsson ST-Ericsson
ti Texas Instruments ti Texas Instruments
via VIA Technologies, Inc. via VIA Technologies, Inc.
......
...@@ -972,6 +972,18 @@ pinmux core. ...@@ -972,6 +972,18 @@ pinmux core.
Pin control requests from drivers Pin control requests from drivers
================================= =================================
When a device driver is about to probe the device core will automatically
attempt to issue pinctrl_get_select_default() on these devices.
This way driver writers do not need to add any of the boilerplate code
of the type found below. However when doing fine-grained state selection
and not using the "default" state, you may have to do some device driver
handling of the pinctrl handles and states.
So if you just want to put the pins for a certain device into the default
state and be done with it, there is nothing you need to do besides
providing the proper mapping table. The device core will take care of
the rest.
Generally it is discouraged to let individual drivers get and enable pin Generally it is discouraged to let individual drivers get and enable pin
control. So if possible, handle the pin control in platform code or some other control. So if possible, handle the pin control in platform code or some other
place where you have access to all the affected struct device * pointers. In place where you have access to all the affected struct device * pointers. In
...@@ -1097,9 +1109,9 @@ situations that can be electrically unpleasant, you will certainly want to ...@@ -1097,9 +1109,9 @@ situations that can be electrically unpleasant, you will certainly want to
mux in and bias pins in a certain way before the GPIO subsystems starts to mux in and bias pins in a certain way before the GPIO subsystems starts to
deal with them. deal with them.
The above can be hidden: using pinctrl hogs, the pin control driver may be The above can be hidden: using the device core, the pinctrl core may be
setting up the config and muxing for the pins when it is probing, setting up the config and muxing for the pins right before the device is
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 with the pinctrl subsystem, using the latter
......
...@@ -1636,7 +1636,7 @@ config ARCH_NR_GPIO ...@@ -1636,7 +1636,7 @@ config ARCH_NR_GPIO
default 355 if ARCH_U8500 default 355 if ARCH_U8500
default 264 if MACH_H4700 default 264 if MACH_H4700
default 512 if SOC_OMAP5 default 512 if SOC_OMAP5
default 288 if ARCH_VT8500 default 288 if ARCH_VT8500 || ARCH_SUNXI
default 0 default 0
help help
Maximum number of GPIOs in the system. Maximum number of GPIOs in the system.
......
...@@ -170,10 +170,9 @@ gpio8: gpio@a03fe000 { ...@@ -170,10 +170,9 @@ gpio8: gpio@a03fe000 {
gpio-bank = <8>; gpio-bank = <8>;
}; };
pinctrl@80157000 { pinctrl {
// This is actually the PRCMU base address compatible = "stericsson,nmk-pinctrl";
reg = <0x80157000 0x2000>; prcm = <&prcmu>;
compatible = "stericsson,nmk_pinctrl";
}; };
usb@a03e0000 { usb@a03e0000 {
...@@ -190,9 +189,10 @@ dma-controller@801C0000 { ...@@ -190,9 +189,10 @@ dma-controller@801C0000 {
interrupts = <0 25 0x4>; interrupts = <0 25 0x4>;
}; };
prcmu@80157000 { prcmu: prcmu@80157000 {
compatible = "stericsson,db8500-prcmu"; compatible = "stericsson,db8500-prcmu";
reg = <0x80157000 0x1000>; reg = <0x80157000 0x1000>;
reg-names = "prcmu";
interrupts = <0 47 0x4>; interrupts = <0 47 0x4>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
......
...@@ -16,4 +16,34 @@ / { ...@@ -16,4 +16,34 @@ / {
memory { memory {
reg = <0x40000000 0x80000000>; reg = <0x40000000 0x80000000>;
}; };
soc {
pinctrl@01c20800 {
compatible = "allwinner,sun4i-a10-pinctrl";
reg = <0x01c20800 0x400>;
#address-cells = <1>;
#size-cells = <0>;
uart0_pins_a: uart0@0 {
allwinner,pins = "PB22", "PB23";
allwinner,function = "uart0";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
uart0_pins_b: uart0@1 {
allwinner,pins = "PF2", "PF4";
allwinner,function = "uart0";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
uart1_pins_a: uart1@0 {
allwinner,pins = "PA10", "PA11";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
};
};
}; };
...@@ -24,6 +24,8 @@ chosen { ...@@ -24,6 +24,8 @@ chosen {
soc { soc {
uart1: uart@01c28400 { uart1: uart@01c28400 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins_b>;
status = "okay"; status = "okay";
}; };
}; };
......
...@@ -17,4 +17,27 @@ / { ...@@ -17,4 +17,27 @@ / {
memory { memory {
reg = <0x40000000 0x20000000>; reg = <0x40000000 0x20000000>;
}; };
soc {
pinctrl@01c20800 {
compatible = "allwinner,sun5i-a13-pinctrl";
reg = <0x01c20800 0x400>;
#address-cells = <1>;
#size-cells = <0>;
uart1_pins_a: uart1@0 {
allwinner,pins = "PE10", "PE11";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
uart1_pins_b: uart1@1 {
allwinner,pins = "PG3", "PG4";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
};
};
}; };
...@@ -7,3 +7,4 @@ config ARCH_SUNXI ...@@ -7,3 +7,4 @@ config ARCH_SUNXI
select PINCTRL select PINCTRL
select SPARSE_IRQ select SPARSE_IRQ
select SUNXI_TIMER select SUNXI_TIMER
select PINCTRL_SUNXI
\ No newline at end of file
...@@ -11,6 +11,7 @@ config UX500_SOC_COMMON ...@@ -11,6 +11,7 @@ config UX500_SOC_COMMON
select COMMON_CLK select COMMON_CLK
select PINCTRL select PINCTRL
select PINCTRL_NOMADIK select PINCTRL_NOMADIK
select PINCTRL_ABX500
select PL310_ERRATA_753970 if CACHE_PL310 select PL310_ERRATA_753970 if CACHE_PL310
config UX500_SOC_DB8500 config UX500_SOC_DB8500
...@@ -18,6 +19,11 @@ config UX500_SOC_DB8500 ...@@ -18,6 +19,11 @@ config UX500_SOC_DB8500
select CPU_FREQ_TABLE if CPU_FREQ select CPU_FREQ_TABLE if CPU_FREQ
select MFD_DB8500_PRCMU select MFD_DB8500_PRCMU
select PINCTRL_DB8500 select PINCTRL_DB8500
select PINCTRL_DB8540
select PINCTRL_AB8500
select PINCTRL_AB8505
select PINCTRL_AB9540
select PINCTRL_AB8540
select REGULATOR select REGULATOR
select REGULATOR_DB8500_PRCMU select REGULATOR_DB8500_PRCMU
......
...@@ -90,26 +90,8 @@ static struct platform_device snowball_gpio_en_3v3_regulator_dev = { ...@@ -90,26 +90,8 @@ static struct platform_device snowball_gpio_en_3v3_regulator_dev = {
}, },
}; };
static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { static struct abx500_gpio_platform_data ab8500_gpio_pdata = {
.gpio_base = MOP500_AB8500_PIN_GPIO(1), .gpio_base = MOP500_AB8500_PIN_GPIO(1),
.irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE,
/* config_reg is the initial configuration of ab8500 pins.
* The pins can be configured as GPIO or alt functions based
* on value present in GpioSel1 to GpioSel6 and AlternatFunction
* register. This is the array of 7 configuration settings.
* One has to compile time decide these settings. Below is the
* explanation of these setting
* GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO
* GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO
* GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO
* GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO
* GpioSel5 = 0x7A => Pins GPIO34, GPIO36 to GPIO39 are conf as GPIO
* GpioSel6 = 0x00 => Pins GPIO41 & GPIo42 are not configured as GPIO
* AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured
* as GPIO then this register selectes the alternate fucntions
*/
.config_reg = {0x00, 0x1E, 0x80, 0x01,
0x7A, 0x00, 0x00},
}; };
/* ab8500-codec */ /* ab8500-codec */
......
...@@ -285,7 +285,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { ...@@ -285,7 +285,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL), OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL),
OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL), OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),
/* Requires device name bindings. */ /* Requires device name bindings. */
OF_DEV_AUXDATA("stericsson,nmk_pinctrl", U8500_PRCMU_BASE, OF_DEV_AUXDATA("stericsson,nmk-pinctrl", U8500_PRCMU_BASE,
"pinctrl-db8500", NULL), "pinctrl-db8500", NULL),
/* Requires clock name and DMA bindings. */ /* Requires clock name and DMA bindings. */
OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000, OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
......
...@@ -38,15 +38,7 @@ ...@@ -38,15 +38,7 @@
#define MOP500_STMPE1601_IRQ_END \ #define MOP500_STMPE1601_IRQ_END \
MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS) MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
/* AB8500 virtual gpio IRQ */ #define MOP500_NR_IRQS MOP500_STMPE1601_IRQ_END
#define AB8500_VIR_GPIO_NR_IRQS 16
#define MOP500_AB8500_VIR_GPIO_IRQ_BASE \
MOP500_STMPE1601_IRQ_END
#define MOP500_AB8500_VIR_GPIO_IRQ_END \
(MOP500_AB8500_VIR_GPIO_IRQ_BASE + AB8500_VIR_GPIO_NR_IRQS)
#define MOP500_NR_IRQS MOP500_AB8500_VIR_GPIO_IRQ_END
#define MOP500_IRQ_END MOP500_NR_IRQS #define MOP500_IRQ_END MOP500_NR_IRQS
......
...@@ -21,6 +21,7 @@ endif ...@@ -21,6 +21,7 @@ endif
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
obj-$(CONFIG_REGMAP) += regmap/ obj-$(CONFIG_REGMAP) += regmap/
obj-$(CONFIG_SOC_BUS) += soc.o obj-$(CONFIG_SOC_BUS) += soc.o
obj-$(CONFIG_PINCTRL) += pinctrl.o
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/async.h> #include <linux/async.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/pinctrl/devinfo.h>
#include "base.h" #include "base.h"
#include "power/power.h" #include "power/power.h"
...@@ -269,6 +270,12 @@ static int really_probe(struct device *dev, struct device_driver *drv) ...@@ -269,6 +270,12 @@ static int really_probe(struct device *dev, struct device_driver *drv)
WARN_ON(!list_empty(&dev->devres_head)); WARN_ON(!list_empty(&dev->devres_head));
dev->driver = drv; dev->driver = drv;
/* If using pinctrl, bind pins now before probing */
ret = pinctrl_bind_pins(dev);
if (ret)
goto probe_failed;
if (driver_sysfs_add(dev)) { if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n", printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev_name(dev)); __func__, dev_name(dev));
......
/*
* Driver core interface to the pinctrl subsystem.
*
* Copyright (C) 2012 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/device.h>
#include <linux/pinctrl/devinfo.h>
#include <linux/pinctrl/consumer.h>
#include <linux/slab.h>
/**
* pinctrl_bind_pins() - called by the device core before probe
* @dev: the device that is just about to probe
*/
int pinctrl_bind_pins(struct device *dev)
{
int ret;
dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
if (!dev->pins)
return -ENOMEM;
dev->pins->p = devm_pinctrl_get(dev);
if (IS_ERR(dev->pins->p)) {
dev_dbg(dev, "no pinctrl handle\n");
ret = PTR_ERR(dev->pins->p);
goto cleanup_alloc;
}
dev->pins->default_state = pinctrl_lookup_state(dev->pins->p,
PINCTRL_STATE_DEFAULT);
if (IS_ERR(dev->pins->default_state)) {
dev_dbg(dev, "no default pinctrl state\n");
ret = 0;
goto cleanup_get;
}
ret = pinctrl_select_state(dev->pins->p, dev->pins->default_state);
if (ret) {
dev_dbg(dev, "failed to activate default pinctrl state\n");
goto cleanup_get;
}
return 0;
/*
* If no pinctrl handle or default state was found for this device,
* let's explicitly free the pin container in the device, there is
* no point in keeping it around.
*/
cleanup_get:
devm_pinctrl_put(dev->pins->p);
cleanup_alloc:
devm_kfree(dev, dev->pins);
dev->pins = NULL;
/* Only return deferrals */
if (ret != -EPROBE_DEFER)
ret = 0;
return ret;
}
...@@ -657,12 +657,6 @@ config GPIO_JANZ_TTL ...@@ -657,12 +657,6 @@ config GPIO_JANZ_TTL
This driver provides support for driving the pins in output This driver provides support for driving the pins in output
mode only. Input mode is not supported. mode only. Input mode is not supported.
config GPIO_AB8500
bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions"
depends on AB8500_CORE && BROKEN
help
Select this to enable the AB8500 IC GPIO driver
config GPIO_TPS6586X config GPIO_TPS6586X
bool "TPS6586X GPIO" bool "TPS6586X GPIO"
depends on MFD_TPS6586X depends on MFD_TPS6586X
......
...@@ -10,7 +10,6 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o ...@@ -10,7 +10,6 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o
obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o
obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o
......
This diff is collapsed.
...@@ -250,7 +250,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) ...@@ -250,7 +250,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
* on the same GPIO chip. * on the same GPIO chip.
*/ */
ret = gpiochip_add_pin_range(chip, ret = gpiochip_add_pin_range(chip,
pinctrl_dev_get_name(pctldev), pinctrl_dev_get_devname(pctldev),
0, /* offset in gpiochip */ 0, /* offset in gpiochip */
pinspec.args[0], pinspec.args[0],
pinspec.args[1]); pinspec.args[1]);
......
...@@ -26,6 +26,29 @@ config DEBUG_PINCTRL ...@@ -26,6 +26,29 @@ config DEBUG_PINCTRL
help help
Say Y here to add some extra checks and diagnostics to PINCTRL calls. Say Y here to add some extra checks and diagnostics to PINCTRL calls.
config PINCTRL_ABX500
bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
depends on AB8500_CORE
select GENERIC_PINCONF
help
Select this to enable the ABx500 family IC GPIO driver
config PINCTRL_AB8500
bool "AB8500 pin controller driver"
depends on PINCTRL_ABX500 && ARCH_U8500
config PINCTRL_AB8540
bool "AB8540 pin controller driver"
depends on PINCTRL_ABX500 && ARCH_U8500
config PINCTRL_AB9540
bool "AB9540 pin controller driver"
depends on PINCTRL_ABX500 && ARCH_U8500
config PINCTRL_AB8505
bool "AB8505 pin controller driver"
depends on PINCTRL_ABX500 && ARCH_U8500
config PINCTRL_AT91 config PINCTRL_AT91
bool "AT91 pinctrl driver" bool "AT91 pinctrl driver"
depends on OF depends on OF
...@@ -151,6 +174,11 @@ config PINCTRL_SIRF ...@@ -151,6 +174,11 @@ config PINCTRL_SIRF
depends on ARCH_SIRF depends on ARCH_SIRF
select PINMUX select PINMUX
config PINCTRL_SUNXI
bool
select PINMUX
select GENERIC_PINCONF
config PINCTRL_TEGRA config PINCTRL_TEGRA
bool bool
select PINMUX select PINMUX
...@@ -164,6 +192,10 @@ config PINCTRL_TEGRA30 ...@@ -164,6 +192,10 @@ config PINCTRL_TEGRA30
bool bool
select PINCTRL_TEGRA select PINCTRL_TEGRA
config PINCTRL_TEGRA114
bool
select PINCTRL_TEGRA
config PINCTRL_U300 config PINCTRL_U300
bool "U300 pin controller driver" bool "U300 pin controller driver"
depends on ARCH_U300 depends on ARCH_U300
......
...@@ -9,6 +9,11 @@ ifeq ($(CONFIG_OF),y) ...@@ -9,6 +9,11 @@ ifeq ($(CONFIG_OF),y)
obj-$(CONFIG_PINCTRL) += devicetree.o obj-$(CONFIG_PINCTRL) += devicetree.o
endif endif
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o
obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o
obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o
obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.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_IMX) += pinctrl-imx.o obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
...@@ -30,9 +35,11 @@ obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o ...@@ -30,9 +35,11 @@ obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o
obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.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) += pinctrl-sirf.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_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
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#define pr_fmt(fmt) "pinctrl core: " fmt #define pr_fmt(fmt) "pinctrl core: " fmt
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -31,17 +32,6 @@ ...@@ -31,17 +32,6 @@
#include "pinmux.h" #include "pinmux.h"
#include "pinconf.h" #include "pinconf.h"
/**
* struct pinctrl_maps - a list item containing part of the mapping table
* @node: mapping table list node
* @maps: array of mapping table entries
* @num_maps: the number of entries in @maps
*/
struct pinctrl_maps {
struct list_head node;
struct pinctrl_map const *maps;
unsigned num_maps;
};
static bool pinctrl_dummy_state; static bool pinctrl_dummy_state;
...@@ -55,13 +45,8 @@ LIST_HEAD(pinctrldev_list); ...@@ -55,13 +45,8 @@ LIST_HEAD(pinctrldev_list);
static LIST_HEAD(pinctrl_list); static LIST_HEAD(pinctrl_list);
/* List of pinctrl maps (struct pinctrl_maps) */ /* List of pinctrl maps (struct pinctrl_maps) */
static LIST_HEAD(pinctrl_maps); LIST_HEAD(pinctrl_maps);
#define for_each_maps(_maps_node_, _i_, _map_) \
list_for_each_entry(_maps_node_, &pinctrl_maps, node) \
for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \
_i_ < _maps_node_->num_maps; \
_i_++, _map_ = &_maps_node_->maps[_i_])
/** /**
* pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support * pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support
...@@ -83,6 +68,12 @@ const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) ...@@ -83,6 +68,12 @@ const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev)
} }
EXPORT_SYMBOL_GPL(pinctrl_dev_get_name); EXPORT_SYMBOL_GPL(pinctrl_dev_get_name);
const char *pinctrl_dev_get_devname(struct pinctrl_dev *pctldev)
{
return dev_name(pctldev->dev);
}
EXPORT_SYMBOL_GPL(pinctrl_dev_get_devname);
void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev) void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev)
{ {
return pctldev->driver_data; return pctldev->driver_data;
...@@ -609,13 +600,16 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) ...@@ -609,13 +600,16 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
if (setting->pctldev == NULL) { if (setting->pctldev == NULL) {
dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe",
map->ctrl_dev_name);
kfree(setting); kfree(setting);
/* Do not defer probing of hogs (circular loop) */
if (!strcmp(map->ctrl_dev_name, map->dev_name))
return -ENODEV;
/* /*
* OK let us guess that the driver is not there yet, and * OK let us guess that the driver is not there yet, and
* let's defer obtaining this pinctrl handle to later... * let's defer obtaining this pinctrl handle to later...
*/ */
dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe",
map->ctrl_dev_name);
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }
...@@ -694,11 +688,31 @@ static struct pinctrl *create_pinctrl(struct device *dev) ...@@ -694,11 +688,31 @@ static struct pinctrl *create_pinctrl(struct device *dev)
continue; continue;
ret = add_setting(p, map); ret = add_setting(p, map);
if (ret < 0) { /*
* At this point the adding of a setting may:
*
* - Defer, if the pinctrl device is not yet available
* - Fail, if the pinctrl device is not yet available,
* AND the setting is a hog. We cannot defer that, since
* the hog will kick in immediately after the device
* is registered.
*
* If the error returned was not -EPROBE_DEFER then we
* accumulate the errors to see if we end up with
* an -EPROBE_DEFER later, as that is the worst case.
*/
if (ret == -EPROBE_DEFER) {
pinctrl_put_locked(p, false); pinctrl_put_locked(p, false);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
} }
if (ret < 0) {
/* If some other error than deferral occured, return here */
pinctrl_put_locked(p, false);
return ERR_PTR(ret);
}
kref_init(&p->users);
/* Add the pinctrl handle to the global list */ /* Add the pinctrl handle to the global list */
list_add_tail(&p->node, &pinctrl_list); list_add_tail(&p->node, &pinctrl_list);
...@@ -713,9 +727,17 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev) ...@@ -713,9 +727,17 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev)
if (WARN_ON(!dev)) if (WARN_ON(!dev))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
/*
* See if somebody else (such as the device core) has already
* obtained a handle to the pinctrl for this device. In that case,
* return another pointer to it.
*/
p = find_pinctrl(dev); p = find_pinctrl(dev);
if (p != NULL) if (p != NULL) {
return ERR_PTR(-EBUSY); dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n");
kref_get(&p->users);
return p;
}
return create_pinctrl(dev); return create_pinctrl(dev);
} }
...@@ -771,13 +793,24 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist) ...@@ -771,13 +793,24 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist)
} }
/** /**
* pinctrl_put() - release a previously claimed pinctrl handle * pinctrl_release() - release the pinctrl handle
* @kref: the kref in the pinctrl being released
*/
static void pinctrl_release(struct kref *kref)
{
struct pinctrl *p = container_of(kref, struct pinctrl, users);
pinctrl_put_locked(p, true);
}
/**
* pinctrl_put() - decrease use count on a previously claimed pinctrl handle
* @p: the pinctrl handle to release * @p: the pinctrl handle to release
*/ */
void pinctrl_put(struct pinctrl *p) void pinctrl_put(struct pinctrl *p)
{ {
mutex_lock(&pinctrl_mutex); mutex_lock(&pinctrl_mutex);
pinctrl_put_locked(p, true); kref_put(&p->users, pinctrl_release);
mutex_unlock(&pinctrl_mutex); mutex_unlock(&pinctrl_mutex);
} }
EXPORT_SYMBOL_GPL(pinctrl_put); EXPORT_SYMBOL_GPL(pinctrl_put);
...@@ -1055,6 +1088,30 @@ void pinctrl_unregister_map(struct pinctrl_map const *map) ...@@ -1055,6 +1088,30 @@ void pinctrl_unregister_map(struct pinctrl_map const *map)
} }
} }
/**
* pinctrl_force_sleep() - turn a given controller device into sleep state
* @pctldev: pin controller device
*/
int pinctrl_force_sleep(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep))
return pinctrl_select_state(pctldev->p, pctldev->hog_sleep);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
/**
* pinctrl_force_default() - turn a given controller device into default state
* @pctldev: pin controller device
*/
int pinctrl_force_default(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default))
return pinctrl_select_state(pctldev->p, pctldev->hog_default);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_default);
#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)
...@@ -1500,16 +1557,23 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, ...@@ -1500,16 +1557,23 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
pctldev->p = pinctrl_get_locked(pctldev->dev); pctldev->p = pinctrl_get_locked(pctldev->dev);
if (!IS_ERR(pctldev->p)) { if (!IS_ERR(pctldev->p)) {
struct pinctrl_state *s = pctldev->hog_default =
pinctrl_lookup_state_locked(pctldev->p, pinctrl_lookup_state_locked(pctldev->p,
PINCTRL_STATE_DEFAULT); PINCTRL_STATE_DEFAULT);
if (IS_ERR(s)) { if (IS_ERR(pctldev->hog_default)) {
dev_dbg(dev, "failed to lookup the default state\n"); dev_dbg(dev, "failed to lookup the default state\n");
} else { } else {
if (pinctrl_select_state_locked(pctldev->p, s)) if (pinctrl_select_state_locked(pctldev->p,
pctldev->hog_default))
dev_err(dev, dev_err(dev,
"failed to select default state\n"); "failed to select default state\n");
} }
pctldev->hog_sleep =
pinctrl_lookup_state_locked(pctldev->p,
PINCTRL_STATE_SLEEP);
if (IS_ERR(pctldev->hog_sleep))
dev_dbg(dev, "failed to lookup the sleep state\n");
} }
mutex_unlock(&pinctrl_mutex); mutex_unlock(&pinctrl_mutex);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* License terms: GNU General Public License (GPL) version 2 * License terms: GNU General Public License (GPL) version 2
*/ */
#include <linux/kref.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/radix-tree.h> #include <linux/radix-tree.h>
#include <linux/pinctrl/pinconf.h> #include <linux/pinctrl/pinconf.h>
...@@ -30,6 +31,8 @@ struct pinctrl_gpio_range; ...@@ -30,6 +31,8 @@ struct pinctrl_gpio_range;
* @driver_data: driver data for drivers registering to the pin controller * @driver_data: driver data for drivers registering to the pin controller
* subsystem * subsystem
* @p: result of pinctrl_get() for this device * @p: result of pinctrl_get() for this device
* @hog_default: default state for pins hogged by this device
* @hog_sleep: sleep state for pins hogged by this device
* @device_root: debugfs root for this device * @device_root: debugfs root for this device
*/ */
struct pinctrl_dev { struct pinctrl_dev {
...@@ -41,6 +44,8 @@ struct pinctrl_dev { ...@@ -41,6 +44,8 @@ struct pinctrl_dev {
struct module *owner; struct module *owner;
void *driver_data; void *driver_data;
struct pinctrl *p; struct pinctrl *p;
struct pinctrl_state *hog_default;
struct pinctrl_state *hog_sleep;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *device_root; struct dentry *device_root;
#endif #endif
...@@ -54,6 +59,7 @@ struct pinctrl_dev { ...@@ -54,6 +59,7 @@ struct pinctrl_dev {
* @state: the current state * @state: the current state
* @dt_maps: the mapping table chunks dynamically parsed from device tree for * @dt_maps: the mapping table chunks dynamically parsed from device tree for
* this device, if any * this device, if any
* @users: reference count
*/ */
struct pinctrl { struct pinctrl {
struct list_head node; struct list_head node;
...@@ -61,6 +67,7 @@ struct pinctrl { ...@@ -61,6 +67,7 @@ struct pinctrl {
struct list_head states; struct list_head states;
struct pinctrl_state *state; struct pinctrl_state *state;
struct list_head dt_maps; struct list_head dt_maps;
struct kref users;
}; };
/** /**
...@@ -148,6 +155,18 @@ struct pin_desc { ...@@ -148,6 +155,18 @@ struct pin_desc {
#endif #endif
}; };
/**
* struct pinctrl_maps - a list item containing part of the mapping table
* @node: mapping table list node
* @maps: array of mapping table entries
* @num_maps: the number of entries in @maps
*/
struct pinctrl_maps {
struct list_head node;
struct pinctrl_map const *maps;
unsigned num_maps;
};
struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin); const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin);
...@@ -164,5 +183,15 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, ...@@ -164,5 +183,15 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
bool dup, bool locked); bool dup, bool locked);
void pinctrl_unregister_map(struct pinctrl_map const *map); void pinctrl_unregister_map(struct pinctrl_map const *map);
extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev);
extern int pinctrl_force_default(struct pinctrl_dev *pctldev);
extern struct mutex pinctrl_mutex; extern struct mutex pinctrl_mutex;
extern struct list_head pinctrldev_list; extern struct list_head pinctrldev_list;
extern struct list_head pinctrl_maps;
#define for_each_maps(_maps_node_, _i_, _map_) \
list_for_each_entry(_maps_node_, &pinctrl_maps, node) \
for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \
_i_ < _maps_node_->num_maps; \
_i_++, _map_ = &_maps_node_->maps[_i_])
...@@ -141,6 +141,11 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename, ...@@ -141,6 +141,11 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename,
pctldev = find_pinctrl_by_of_node(np_pctldev); pctldev = find_pinctrl_by_of_node(np_pctldev);
if (pctldev) if (pctldev)
break; break;
/* Do not defer probing of hogs (circular loop) */
if (np_pctldev == p->dev->of_node) {
of_node_put(np_pctldev);
return -ENODEV;
}
} }
of_node_put(np_pctldev); of_node_put(np_pctldev);
......
...@@ -41,11 +41,13 @@ struct pin_config_item conf_items[] = { ...@@ -41,11 +41,13 @@ struct pin_config_item conf_items[] = {
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_INPUT_SCHMITT_DISABLE, "input schmitt disabled", 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", "time units"),
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_LOW_POWER_MODE, "pin low power", "mode"), PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"),
PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level"),
}; };
void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
......
...@@ -574,6 +574,207 @@ static const struct file_operations pinconf_groups_ops = { ...@@ -574,6 +574,207 @@ static const struct file_operations pinconf_groups_ops = {
.release = single_release, .release = single_release,
}; };
/* 32bit read/write ressources */
#define MAX_NAME_LEN 16
char dbg_pinname[MAX_NAME_LEN]; /* shared: name of the state of the pin*/
char dbg_state_name[MAX_NAME_LEN]; /* shared: state of the pin*/
static u32 dbg_config; /* shared: config to be read/set for the pin & state*/
static int pinconf_dbg_pinname_print(struct seq_file *s, void *d)
{
if (strlen(dbg_pinname))
seq_printf(s, "%s\n", dbg_pinname);
else
seq_printf(s, "No pin name set\n");
return 0;
}
static int pinconf_dbg_pinname_open(struct inode *inode, struct file *file)
{
return single_open(file, pinconf_dbg_pinname_print, inode->i_private);
}
static int pinconf_dbg_pinname_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
int err;
if (count > MAX_NAME_LEN)
return -EINVAL;
err = sscanf(user_buf, "%15s", dbg_pinname);
if (err != 1)
return -EINVAL;
return count;
}
static const struct file_operations pinconf_dbg_pinname_fops = {
.open = pinconf_dbg_pinname_open,
.write = pinconf_dbg_pinname_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
static int pinconf_dbg_state_print(struct seq_file *s, void *d)
{
if (strlen(dbg_state_name))
seq_printf(s, "%s\n", dbg_pinname);
else
seq_printf(s, "No pin state set\n");
return 0;
}
static int pinconf_dbg_state_open(struct inode *inode, struct file *file)
{
return single_open(file, pinconf_dbg_state_print, inode->i_private);
}
static int pinconf_dbg_state_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
int err;
if (count > MAX_NAME_LEN)
return -EINVAL;
err = sscanf(user_buf, "%15s", dbg_state_name);
if (err != 1)
return -EINVAL;
return count;
}
static const struct file_operations pinconf_dbg_pinstate_fops = {
.open = pinconf_dbg_state_open,
.write = pinconf_dbg_state_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
/**
* pinconf_dbg_config_print() - display the pinctrl config from the pinctrl
* map, of a pin/state pair based on pinname and state that have been
* selected with the debugfs entries pinconf-name and pinconf-state
* @s: contains the 32bits config to be written
* @d: not used
*/
static int pinconf_dbg_config_print(struct seq_file *s, void *d)
{
struct pinctrl_maps *maps_node;
struct pinctrl_map const *map;
struct pinctrl_dev *pctldev = NULL;
struct pinconf_ops *confops = NULL;
int i, j;
bool found = false;
mutex_lock(&pinctrl_mutex);
/* Parse the pinctrl map and look for the elected pin/state */
for_each_maps(maps_node, i, map) {
if (map->type != PIN_MAP_TYPE_CONFIGS_PIN)
continue;
if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0)
continue;
for (j = 0; j < map->data.configs.num_configs; j++) {
if (0 == strncmp(map->data.configs.group_or_pin,
dbg_pinname, MAX_NAME_LEN)) {
/* We found the right pin / state, read the
* config and store the pctldev */
dbg_config = map->data.configs.configs[j];
pctldev = get_pinctrl_dev_from_devname
(map->ctrl_dev_name);
found = true;
break;
}
}
}
mutex_unlock(&pinctrl_mutex);
if (found) {
seq_printf(s, "Config of %s in state %s: 0x%08X\n", dbg_pinname,
dbg_state_name, dbg_config);
if (pctldev)
confops = pctldev->desc->confops;
if (confops && confops->pin_config_config_dbg_show)
confops->pin_config_config_dbg_show(pctldev,
s, dbg_config);
} else {
seq_printf(s, "No pin found for defined name/state\n");
}
return 0;
}
static int pinconf_dbg_config_open(struct inode *inode, struct file *file)
{
return single_open(file, pinconf_dbg_config_print, inode->i_private);
}
/**
* pinconf_dbg_config_write() - overwrite the pinctrl config in thepinctrl
* map, of a pin/state pair based on pinname and state that have been
* selected with the debugfs entries pinconf-name and pinconf-state
*/
static int pinconf_dbg_config_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
int err;
unsigned long config;
struct pinctrl_maps *maps_node;
struct pinctrl_map const *map;
int i, j;
err = kstrtoul_from_user(user_buf, count, 0, &config);
if (err)
return err;
dbg_config = config;
mutex_lock(&pinctrl_mutex);
/* Parse the pinctrl map and look for the selected pin/state */
for_each_maps(maps_node, i, map) {
if (map->type != PIN_MAP_TYPE_CONFIGS_PIN)
continue;
if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0)
continue;
/* we found the right pin / state, so overwrite config */
for (j = 0; j < map->data.configs.num_configs; j++) {
if (strncmp(map->data.configs.group_or_pin, dbg_pinname,
MAX_NAME_LEN) == 0)
map->data.configs.configs[j] = dbg_config;
}
}
mutex_unlock(&pinctrl_mutex);
return count;
}
static const struct file_operations pinconf_dbg_pinconfig_fops = {
.open = pinconf_dbg_config_open,
.write = pinconf_dbg_config_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
void pinconf_init_device_debugfs(struct dentry *devroot, void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev) struct pinctrl_dev *pctldev)
{ {
...@@ -581,6 +782,12 @@ void pinconf_init_device_debugfs(struct dentry *devroot, ...@@ -581,6 +782,12 @@ void pinconf_init_device_debugfs(struct dentry *devroot,
devroot, pctldev, &pinconf_pins_ops); devroot, pctldev, &pinconf_pins_ops);
debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO, debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
devroot, pctldev, &pinconf_groups_ops); devroot, pctldev, &pinconf_groups_ops);
debugfs_create_file("pinconf-name", (S_IRUGO | S_IWUSR | S_IWGRP),
devroot, pctldev, &pinconf_dbg_pinname_fops);
debugfs_create_file("pinconf-state", (S_IRUGO | S_IWUSR | S_IWGRP),
devroot, pctldev, &pinconf_dbg_pinstate_fops);
debugfs_create_file("pinconf-config", (S_IRUGO | S_IWUSR | S_IWGRP),
devroot, pctldev, &pinconf_dbg_pinconfig_fops);
} }
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef PINCTRL_PINCTRL_ABx5O0_H
#define PINCTRL_PINCTRL_ABx500_H
/* Package definitions */
#define PINCTRL_AB8500 0
#define PINCTRL_AB8540 1
#define PINCTRL_AB9540 2
#define PINCTRL_AB8505 3
/* pins alternate function */
enum abx500_pin_func {
ABX500_DEFAULT,
ABX500_ALT_A,
ABX500_ALT_B,
ABX500_ALT_C,
};
/**
* struct abx500_function - ABx500 pinctrl mux function
* @name: The name of the function, exported to pinctrl core.
* @groups: An array of pin groups that may select this function.
* @ngroups: The number of entries in @groups.
*/
struct abx500_function {
const char *name;
const char * const *groups;
unsigned ngroups;
};
/**
* struct abx500_pingroup - describes a ABx500 pin group
* @name: the name of this specific pin group
* @pins: an array of discrete physical pins used in this group, taken
* from the driver-local pin enumeration space
* @num_pins: the number of pins in this group array, i.e. the number of
* elements in .pins so we can iterate over that array
* @altsetting: the altsetting to apply to all pins in this group to
* configure them to be used by a function
*/
struct abx500_pingroup {
const char *name;
const unsigned int *pins;
const unsigned npins;
int altsetting;
};
#define ALTERNATE_FUNCTIONS(pin, sel_bit, alt1, alt2, alta, altb, altc) \
{ \
.pin_number = pin, \
.gpiosel_bit = sel_bit, \
.alt_bit1 = alt1, \
.alt_bit2 = alt2, \
.alta_val = alta, \
.altb_val = altb, \
.altc_val = altc, \
}
#define UNUSED -1
/**
* struct alternate_functions
* @pin_number: The pin number
* @gpiosel_bit: Control bit in GPIOSEL register,
* @alt_bit1: First AlternateFunction bit used to select the
* alternate function
* @alt_bit2: Second AlternateFunction bit used to select the
* alternate function
*
* these 3 following fields are necessary due to none
* coherency on how to select the altA, altB and altC
* function between the ABx500 SOC family when using
* alternatfunc register.
* @alta_val: value to write in alternatfunc to select altA function
* @altb_val: value to write in alternatfunc to select altB function
* @altc_val: value to write in alternatfunc to select altC function
*/
struct alternate_functions {
unsigned pin_number;
s8 gpiosel_bit;
s8 alt_bit1;
s8 alt_bit2;
u8 alta_val;
u8 altb_val;
u8 altc_val;
};
/**
* struct pullud - specific pull up/down feature
* @first_pin: The pin number of the first pins which support
* specific pull up/down
* @last_pin: The pin number of the last pins
*/
struct pullud {
unsigned first_pin;
unsigned last_pin;
};
#define GPIO_IRQ_CLUSTER(a, b, c) \
{ \
.start = a, \
.end = b, \
.to_irq = c, \
}
/**
* struct abx500_gpio_irq_cluster - indicates GPIOs which are interrupt
* capable
* @start: The pin number of the first pin interrupt capable
* @end: The pin number of the last pin interrupt capable
* @to_irq: The ABx500 GPIO's associated IRQs are clustered
* together throughout the interrupt numbers at irregular
* intervals. To solve this quandary, we will place the
* read-in values into the cluster information table
*/
struct abx500_gpio_irq_cluster {
int start;
int end;
int to_irq;
};
/**
* struct abx500_pinrange - map pin numbers to GPIO offsets
* @offset: offset into the GPIO local numberspace, incidentally
* identical to the offset into the local pin numberspace
* @npins: number of pins to map from both offsets
* @altfunc: altfunc setting to be used to enable GPIO on a pin in
* this range (may vary)
*/
struct abx500_pinrange {
unsigned int offset;
unsigned int npins;
int altfunc;
};
#define ABX500_PINRANGE(a, b, c) { .offset = a, .npins = b, .altfunc = c }
/**
* struct abx500_pinctrl_soc_data - ABx500 pin controller per-SoC configuration
* @gpio_ranges: An array of GPIO ranges for this SoC
* @gpio_num_ranges: The number of GPIO ranges for this SoC
* @pins: An array describing all pins the pin controller affects.
* All pins which are also GPIOs must be listed first within the
* array, and be numbered identically to the GPIO controller's
* numbering.
* @npins: The number of entries in @pins.
* @functions: The functions supported on this SoC.
* @nfunction: The number of entries in @functions.
* @groups: An array describing all pin groups the pin SoC supports.
* @ngroups: The number of entries in @groups.
* @alternate_functions: array describing pins which supports alternate and
* how to set it.
* @pullud: array describing pins which supports pull up/down
* specific registers.
* @gpio_irq_cluster: An array of GPIO interrupt capable for this SoC
* @ngpio_irq_cluster: The number of GPIO inetrrupt capable for this SoC
* @irq_gpio_rising_offset: Interrupt offset used as base to compute specific
* setting strategy of the rising interrupt line
* @irq_gpio_falling_offset: Interrupt offset used as base to compute specific
* setting strategy of the falling interrupt line
* @irq_gpio_factor: Factor used to compute specific setting strategy of
* the interrupt line
*/
struct abx500_pinctrl_soc_data {
const struct abx500_pinrange *gpio_ranges;
unsigned gpio_num_ranges;
const struct pinctrl_pin_desc *pins;
unsigned npins;
const struct abx500_function *functions;
unsigned nfunctions;
const struct abx500_pingroup *groups;
unsigned ngroups;
struct alternate_functions *alternate_functions;
struct pullud *pullud;
struct abx500_gpio_irq_cluster *gpio_irq_cluster;
unsigned ngpio_irq_cluster;
int irq_gpio_rising_offset;
int irq_gpio_falling_offset;
int irq_gpio_factor;
};
#ifdef CONFIG_PINCTRL_AB8500
void abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc);
#else
static inline void
abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc)
{
}
#endif
#ifdef CONFIG_PINCTRL_AB8540
void abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc);
#else
static inline void
abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc)
{
}
#endif
#ifdef CONFIG_PINCTRL_AB9540
void abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc);
#else
static inline void
abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc)
{
}
#endif
#ifdef CONFIG_PINCTRL_AB8505
void abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc);
#else
static inline void
abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc)
{
}
#endif
#endif /* PINCTRL_PINCTRL_ABx500_H */
...@@ -170,7 +170,7 @@ static const unsigned pins_ntr[] = {GPIO4}; ...@@ -170,7 +170,7 @@ static const unsigned pins_ntr[] = {GPIO4};
static const unsigned pins_ntr8k[] = {GPIO5}; static const unsigned pins_ntr8k[] = {GPIO5};
static const unsigned pins_hrst[] = {GPIO6}; static const unsigned pins_hrst[] = {GPIO6};
static const unsigned pins_mdio[] = {GPIO7, GPIO8}; static const unsigned pins_mdio[] = {GPIO7, GPIO8};
static const unsigned pins_bled[] = {GPIO7, GPIO10, GPIO11, static const unsigned pins_bled[] = {GPIO9, GPIO10, GPIO11,
GPIO12, GPIO13, GPIO14}; GPIO12, GPIO13, GPIO14};
static const unsigned pins_asc0[] = {GPIO32, GPIO33}; static const unsigned pins_asc0[] = {GPIO32, GPIO33};
static const unsigned pins_spi[] = {GPIO34, GPIO35, GPIO36}; static const unsigned pins_spi[] = {GPIO34, GPIO35, GPIO36};
...@@ -315,6 +315,37 @@ static int falcon_pinconf_set(struct pinctrl_dev *pctrldev, ...@@ -315,6 +315,37 @@ static int falcon_pinconf_set(struct pinctrl_dev *pctrldev,
static void falcon_pinconf_dbg_show(struct pinctrl_dev *pctrldev, static void falcon_pinconf_dbg_show(struct pinctrl_dev *pctrldev,
struct seq_file *s, unsigned offset) struct seq_file *s, unsigned offset)
{ {
unsigned long config;
struct pin_desc *desc;
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
int port = PORT(offset);
seq_printf(s, " (port %d) mux %d -- ", port,
pad_r32(info->membase[port], LTQ_PADC_MUX(PORT_PIN(offset))));
config = LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_PULL, 0);
if (!falcon_pinconf_get(pctrldev, offset, &config))
seq_printf(s, "pull %d ",
(int)LTQ_PINCONF_UNPACK_ARG(config));
config = LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_DRIVE_CURRENT, 0);
if (!falcon_pinconf_get(pctrldev, offset, &config))
seq_printf(s, "drive-current %d ",
(int)LTQ_PINCONF_UNPACK_ARG(config));
config = LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_SLEW_RATE, 0);
if (!falcon_pinconf_get(pctrldev, offset, &config))
seq_printf(s, "slew-rate %d ",
(int)LTQ_PINCONF_UNPACK_ARG(config));
desc = pin_desc_get(pctrldev, offset);
if (desc) {
if (desc->gpio_owner)
seq_printf(s, " owner: %s", desc->gpio_owner);
} else {
seq_printf(s, " not registered");
}
} }
static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev, static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev,
...@@ -360,6 +391,8 @@ static const struct ltq_cfg_param falcon_cfg_params[] = { ...@@ -360,6 +391,8 @@ static const struct ltq_cfg_param falcon_cfg_params[] = {
static struct ltq_pinmux_info falcon_info = { static struct ltq_pinmux_info falcon_info = {
.desc = &falcon_pctrl_desc, .desc = &falcon_pctrl_desc,
.apply_mux = falcon_mux_apply, .apply_mux = falcon_mux_apply,
.params = falcon_cfg_params,
.num_params = ARRAY_SIZE(falcon_cfg_params),
}; };
...@@ -398,6 +431,9 @@ static int pinctrl_falcon_probe(struct platform_device *pdev) ...@@ -398,6 +431,9 @@ static int pinctrl_falcon_probe(struct platform_device *pdev)
u32 avail; u32 avail;
int pins; int pins;
if (!of_device_is_available(np))
continue;
if (!ppdev) { if (!ppdev) {
dev_err(&pdev->dev, "failed to find pad pdev\n"); dev_err(&pdev->dev, "failed to find pad pdev\n");
continue; continue;
......
...@@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, ...@@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(s, " %s", dev_name(pctldev->dev)); seq_printf(s, " %s", dev_name(pctldev->dev));
} }
static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, static void ltq_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)
{ {
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
struct property *pins = of_find_property(np, "lantiq,pins", NULL);
struct property *groups = of_find_property(np, "lantiq,groups", NULL);
unsigned long configs[3]; unsigned long configs[3];
unsigned num_configs = 0; unsigned num_configs = 0;
struct property *prop; struct property *prop;
...@@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
const char *function; const char *function;
int ret, i; int ret, i;
if (!pins && !groups) {
dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
np->name);
return;
}
if (pins && groups) {
dev_err(pctldev->dev, "%s defines both pins and groups\n",
np->name);
return;
}
ret = of_property_read_string(np, "lantiq,function", &function); ret = of_property_read_string(np, "lantiq,function", &function);
if (!ret) { if (groups && !ret) {
of_property_for_each_string(np, "lantiq,groups", prop, group) { of_property_for_each_string(np, "lantiq,groups", prop, group) {
(*map)->type = PIN_MAP_TYPE_MUX_GROUP; (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
(*map)->name = function; (*map)->name = function;
...@@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
(*map)->data.mux.function = function; (*map)->data.mux.function = function;
(*map)++; (*map)++;
} }
if (of_find_property(np, "lantiq,pins", NULL))
dev_err(pctldev->dev,
"%s mixes pins and groups settings\n",
np->name);
return 0;
} }
for (i = 0; i < info->num_params; i++) { for (i = 0; i < info->num_params; i++) {
...@@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
} }
if (!num_configs) if (!num_configs)
return -EINVAL; return;
of_property_for_each_string(np, "lantiq,pins", prop, pin) { of_property_for_each_string(np, "lantiq,pins", prop, pin) {
(*map)->data.configs.configs = kmemdup(configs, (*map)->data.configs.configs = kmemdup(configs,
...@@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
(*map)->data.configs.num_configs = num_configs; (*map)->data.configs.num_configs = num_configs;
(*map)++; (*map)++;
} }
return 0; of_property_for_each_string(np, "lantiq,groups", prop, group) {
(*map)->data.configs.configs = kmemdup(configs,
num_configs * sizeof(unsigned long),
GFP_KERNEL);
(*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
(*map)->name = group;
(*map)->data.configs.group_or_pin = group;
(*map)->data.configs.num_configs = num_configs;
(*map)++;
}
} }
static int ltq_pinctrl_dt_subnode_size(struct device_node *np) static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
...@@ -135,23 +153,19 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -135,23 +153,19 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
{ {
struct pinctrl_map *tmp; struct pinctrl_map *tmp;
struct device_node *np; struct device_node *np;
int ret; int max_maps = 0;
*num_maps = 0;
for_each_child_of_node(np_config, np) for_each_child_of_node(np_config, np)
*num_maps += ltq_pinctrl_dt_subnode_size(np); max_maps += ltq_pinctrl_dt_subnode_size(np);
*map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL); *map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL);
if (!*map) if (!*map)
return -ENOMEM; return -ENOMEM;
tmp = *map; tmp = *map;
for_each_child_of_node(np_config, np) { for_each_child_of_node(np_config, np)
ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp); ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
if (ret < 0) { *num_maps = ((int)(tmp - *map));
ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
return ret;
}
}
return 0; return 0;
} }
...@@ -280,7 +294,7 @@ static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev, ...@@ -280,7 +294,7 @@ static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev,
unsigned pin) unsigned pin)
{ {
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
int mfp = match_mfp(info, pin + (range->id * 32)); int mfp = match_mfp(info, pin);
int pin_func; int pin_func;
if (mfp < 0) { if (mfp < 0) {
......
...@@ -34,6 +34,7 @@ enum ltq_pinconf_param { ...@@ -34,6 +34,7 @@ enum ltq_pinconf_param {
LTQ_PINCONF_PARAM_OPEN_DRAIN, LTQ_PINCONF_PARAM_OPEN_DRAIN,
LTQ_PINCONF_PARAM_DRIVE_CURRENT, LTQ_PINCONF_PARAM_DRIVE_CURRENT,
LTQ_PINCONF_PARAM_SLEW_RATE, LTQ_PINCONF_PARAM_SLEW_RATE,
LTQ_PINCONF_PARAM_OUTPUT,
}; };
struct ltq_cfg_param { struct ltq_cfg_param {
......
This diff is collapsed.
...@@ -716,7 +716,6 @@ static int samsung_pinctrl_register(struct platform_device *pdev, ...@@ -716,7 +716,6 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
} }
ctrldesc->pins = pindesc; ctrldesc->pins = pindesc;
ctrldesc->npins = drvdata->ctrl->nr_pins; ctrldesc->npins = drvdata->ctrl->nr_pins;
ctrldesc->npins = drvdata->ctrl->nr_pins;
/* dynamically populate the pin number and pin name for pindesc */ /* dynamically populate the pin number and pin name for pindesc */
for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++) for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
......
This diff is collapsed.
This diff is collapsed.
...@@ -201,6 +201,7 @@ static const struct cfg_param { ...@@ -201,6 +201,7 @@ static const struct cfg_param {
{"nvidia,open-drain", TEGRA_PINCONF_PARAM_OPEN_DRAIN}, {"nvidia,open-drain", TEGRA_PINCONF_PARAM_OPEN_DRAIN},
{"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK}, {"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK},
{"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET}, {"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET},
{"nvidia,rcv-sel", TEGRA_PINCONF_PARAM_RCV_SEL},
{"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE}, {"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE},
{"nvidia,schmitt", TEGRA_PINCONF_PARAM_SCHMITT}, {"nvidia,schmitt", TEGRA_PINCONF_PARAM_SCHMITT},
{"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE}, {"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE},
...@@ -208,6 +209,7 @@ static const struct cfg_param { ...@@ -208,6 +209,7 @@ static const struct cfg_param {
{"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH}, {"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH},
{"nvidia,slew-rate-falling", TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING}, {"nvidia,slew-rate-falling", TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING},
{"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING}, {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
{"nvidia,drive-type", TEGRA_PINCONF_PARAM_DRIVE_TYPE},
}; };
static int tegra_pinctrl_dt_subnode_to_map(struct device *dev, static int tegra_pinctrl_dt_subnode_to_map(struct device *dev,
...@@ -450,6 +452,12 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx, ...@@ -450,6 +452,12 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
*bit = g->ioreset_bit; *bit = g->ioreset_bit;
*width = 1; *width = 1;
break; break;
case TEGRA_PINCONF_PARAM_RCV_SEL:
*bank = g->rcv_sel_bank;
*reg = g->rcv_sel_reg;
*bit = g->rcv_sel_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE: case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE:
*bank = g->drv_bank; *bank = g->drv_bank;
*reg = g->drv_reg; *reg = g->drv_reg;
...@@ -492,6 +500,12 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx, ...@@ -492,6 +500,12 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
*bit = g->slwr_bit; *bit = g->slwr_bit;
*width = g->slwr_width; *width = g->slwr_width;
break; break;
case TEGRA_PINCONF_PARAM_DRIVE_TYPE:
*bank = g->drvtype_bank;
*reg = g->drvtype_reg;
*bit = g->drvtype_bit;
*width = 2;
break;
default: default:
dev_err(pmx->dev, "Invalid config param %04x\n", param); dev_err(pmx->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP; return -ENOTSUPP;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -154,6 +154,7 @@ struct pinctrl_dev *of_pinctrl_get(struct device_node *np) ...@@ -154,6 +154,7 @@ struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
#endif /* CONFIG_OF */ #endif /* CONFIG_OF */
extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);
extern const char *pinctrl_dev_get_devname(struct pinctrl_dev *pctldev);
extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev); extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev);
#else #else
......
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