Commit 2de68638 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull pin control updates from Linus Walleij:
 "Core changes:

   - Use DEFINE_SHOW_STORE_ATTRIBUTE() in debugfs entries

  New drivers:

   - Qualcomm PMIH0108, PMD8028, PMXR2230 and PM6450 pin control support

  Improvements:

   - Serious cleanup of the recently merged aw9523 driver

   - Fix PIN_CONFIG_BIAS_DISABLE handling in pinctrl-single

   - A slew of device tree binding cleanups

   - Support a bus clock in the Samsung driver"

* tag 'pinctrl-v6.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (48 commits)
  pinctrl: bcm2835: Make pin freeing behavior configurable
  dt-bindings: pinctrl: qcom,pmic-gpio: Fix "comptaible" typo for PMIH0108
  pinctrl: qcom: pinctrl-sm7150: Fix sdc1 and ufs special pins regs
  dt-bindings: pinctrl: mediatek: mt7622: add "antsel" function
  dt-bindings: pinctrl: mediatek: mt7622: fix array properties
  pinctrl: samsung: drop redundant drvdata assignment
  pinctrl: samsung: support a bus clock
  dt-bindings: pinctrl: samsung: google,gs101-pinctrl needs a clock
  pinctrl: renesas: rzg2l: Limit 2.5V power supply to Ethernet interfaces
  pinctrl: renesas: r8a779h0: Add INTC-EX pins, groups, and function
  pinctrl: renesas: r8a779h0: Fix IRQ suffixes
  pinctrl: renesas: rzg2l: Remove extra space in function parameter
  dt-bindings: pinctrl: qcom,pmic-mpp: add support for PM8901
  pinctrl: pinconf-generic: print hex value
  pinctrl: realtek: fix module autoloading
  pinctrl: qcom: sm7150: fix module autoloading
  pinctrl: loongson2: fix module autoloading
  pinctrl: mediatek: fix module autoloading
  pinctrl: freescale: imx8ulp: fix module autoloading
  dt-bindings: pinctrl: qcom,pmic-gpio: Allow gpio-hog nodes
  ...
parents 568c98a0 83906257
...@@ -34,6 +34,9 @@ properties: ...@@ -34,6 +34,9 @@ properties:
the amount of cells must be specified as 2. See the below mentioned gpio the amount of cells must be specified as 2. See the below mentioned gpio
binding representation for description of particular cells. binding representation for description of particular cells.
gpio-ranges:
maxItems: 1
interrupt-controller: true interrupt-controller: true
interrupts: interrupts:
...@@ -75,8 +78,8 @@ patternProperties: ...@@ -75,8 +78,8 @@ patternProperties:
function: function:
description: description:
A string containing the name of the function to mux to the group. A string containing the name of the function to mux to the group.
enum: [emmc, eth, i2c, i2s, ir, led, flash, pcie, pmic, pwm, sd, enum: [antsel, emmc, eth, i2c, i2s, ir, led, flash, pcie, pmic, pwm,
spi, tdm, uart, watchdog, wifi] sd, spi, tdm, uart, watchdog, wifi]
groups: groups:
description: description:
...@@ -90,6 +93,20 @@ patternProperties: ...@@ -90,6 +93,20 @@ patternProperties:
- function - function
allOf: allOf:
- if:
properties:
function:
const: antsel
then:
properties:
groups:
items:
enum: [antsel0, antsel1, antsel2, antsel3, antsel4, antsel5,
antsel6, antsel7, antsel8, antsel9, antsel10,
antsel11, antsel12, antsel13, antsel14, antsel15,
antsel16, antsel17, antsel18, antsel19, antsel20,
antsel21, antsel22, antsel23, antsel24, antsel25,
antsel26, antsel27, antsel28, antsel29]
- if: - if:
properties: properties:
function: function:
...@@ -97,6 +114,7 @@ patternProperties: ...@@ -97,6 +114,7 @@ patternProperties:
then: then:
properties: properties:
groups: groups:
items:
enum: [emmc, emmc_rst] enum: [emmc, emmc_rst]
- if: - if:
properties: properties:
...@@ -105,6 +123,7 @@ patternProperties: ...@@ -105,6 +123,7 @@ patternProperties:
then: then:
properties: properties:
groups: groups:
items:
enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw, enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio] rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio]
- if: - if:
...@@ -123,6 +142,7 @@ patternProperties: ...@@ -123,6 +142,7 @@ patternProperties:
then: then:
properties: properties:
groups: groups:
items:
enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data, enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data,
i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws, i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws,
i2s1_out_data, i2s2_out_data, i2s3_out_data, i2s1_out_data, i2s2_out_data, i2s3_out_data,
...@@ -159,6 +179,7 @@ patternProperties: ...@@ -159,6 +179,7 @@ patternProperties:
then: then:
properties: properties:
groups: groups:
items:
enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken, enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq, pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
pcie0_pad_perst, pcie1_pad_perst, pcie_pereset, pcie0_pad_perst, pcie1_pad_perst, pcie_pereset,
...@@ -178,6 +199,7 @@ patternProperties: ...@@ -178,6 +199,7 @@ patternProperties:
then: then:
properties: properties:
groups: groups:
items:
enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1, enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1,
pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0, pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0,
pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1, pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1,
...@@ -260,6 +282,7 @@ patternProperties: ...@@ -260,6 +282,7 @@ patternProperties:
pins: pins:
description: description:
An array of strings. Each string contains the name of a pin. An array of strings. Each string contains the name of a pin.
items:
enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0, enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0,
RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS, RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS,
I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT, I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT,
......
...@@ -24,6 +24,7 @@ properties: ...@@ -24,6 +24,7 @@ properties:
- qcom,pm6150-gpio - qcom,pm6150-gpio
- qcom,pm6150l-gpio - qcom,pm6150l-gpio
- qcom,pm6350-gpio - qcom,pm6350-gpio
- qcom,pm6450-gpio
- qcom,pm7250b-gpio - qcom,pm7250b-gpio
- qcom,pm7325-gpio - qcom,pm7325-gpio
- qcom,pm7550ba-gpio - qcom,pm7550ba-gpio
...@@ -56,10 +57,12 @@ properties: ...@@ -56,10 +57,12 @@ properties:
- qcom,pma8084-gpio - qcom,pma8084-gpio
- qcom,pmc8180-gpio - qcom,pmc8180-gpio
- qcom,pmc8180c-gpio - qcom,pmc8180c-gpio
- qcom,pmd8028-gpio
- qcom,pmi632-gpio - qcom,pmi632-gpio
- qcom,pmi8950-gpio - qcom,pmi8950-gpio
- qcom,pmi8994-gpio - qcom,pmi8994-gpio
- qcom,pmi8998-gpio - qcom,pmi8998-gpio
- qcom,pmih0108-gpio
- qcom,pmk8350-gpio - qcom,pmk8350-gpio
- qcom,pmk8550-gpio - qcom,pmk8550-gpio
- qcom,pmm8155au-gpio - qcom,pmm8155au-gpio
...@@ -72,6 +75,7 @@ properties: ...@@ -72,6 +75,7 @@ properties:
- qcom,pmx55-gpio - qcom,pmx55-gpio
- qcom,pmx65-gpio - qcom,pmx65-gpio
- qcom,pmx75-gpio - qcom,pmx75-gpio
- qcom,pmxr2230-gpio
- enum: - enum:
- qcom,spmi-gpio - qcom,spmi-gpio
...@@ -141,6 +145,7 @@ allOf: ...@@ -141,6 +145,7 @@ allOf:
- qcom,pm8005-gpio - qcom,pm8005-gpio
- qcom,pm8450-gpio - qcom,pm8450-gpio
- qcom,pm8916-gpio - qcom,pm8916-gpio
- qcom,pmd8028-gpio
- qcom,pmk8350-gpio - qcom,pmk8350-gpio
- qcom,pmr735a-gpio - qcom,pmr735a-gpio
- qcom,pmr735b-gpio - qcom,pmr735b-gpio
...@@ -198,6 +203,7 @@ allOf: ...@@ -198,6 +203,7 @@ allOf:
contains: contains:
enum: enum:
- qcom,pm6350-gpio - qcom,pm6350-gpio
- qcom,pm6450-gpio
- qcom,pm8350c-gpio - qcom,pm8350c-gpio
then: then:
properties: properties:
...@@ -261,6 +267,7 @@ allOf: ...@@ -261,6 +267,7 @@ allOf:
- qcom,pmc8180c-gpio - qcom,pmc8180c-gpio
- qcom,pmp8074-gpio - qcom,pmp8074-gpio
- qcom,pms405-gpio - qcom,pms405-gpio
- qcom,pmxr2230-gpio
then: then:
properties: properties:
gpio-line-names: gpio-line-names:
...@@ -300,6 +307,21 @@ allOf: ...@@ -300,6 +307,21 @@ allOf:
minItems: 1 minItems: 1
maxItems: 7 maxItems: 7
- if:
properties:
compatible:
contains:
enum:
- qcom,pmih0108-gpio
then:
properties:
gpio-line-names:
minItems: 18
maxItems: 18
gpio-reserved-ranges:
minItems: 1
maxItems: 9
- if: - if:
properties: properties:
compatible: compatible:
...@@ -402,6 +424,10 @@ patternProperties: ...@@ -402,6 +424,10 @@ patternProperties:
$ref: "#/$defs/qcom-pmic-gpio-state" $ref: "#/$defs/qcom-pmic-gpio-state"
additionalProperties: false additionalProperties: false
"-hog(-[0-9]+)?$":
required:
- gpio-hog
$defs: $defs:
qcom-pmic-gpio-state: qcom-pmic-gpio-state:
type: object type: object
...@@ -417,6 +443,7 @@ $defs: ...@@ -417,6 +443,7 @@ $defs:
- gpio1-gpio10 for pm6150 - gpio1-gpio10 for pm6150
- gpio1-gpio12 for pm6150l - gpio1-gpio12 for pm6150l
- gpio1-gpio9 for pm6350 - gpio1-gpio9 for pm6350
- gpio1-gpio9 for pm6450
- gpio1-gpio12 for pm7250b - gpio1-gpio12 for pm7250b
- gpio1-gpio10 for pm7325 - gpio1-gpio10 for pm7325
- gpio1-gpio8 for pm7550ba - gpio1-gpio8 for pm7550ba
...@@ -447,9 +474,11 @@ $defs: ...@@ -447,9 +474,11 @@ $defs:
- gpio1-gpio22 for pm8994 - gpio1-gpio22 for pm8994
- gpio1-gpio26 for pm8998 - gpio1-gpio26 for pm8998
- gpio1-gpio22 for pma8084 - gpio1-gpio22 for pma8084
- gpio1-gpio4 for pmd8028
- gpio1-gpio8 for pmi632 - gpio1-gpio8 for pmi632
- gpio1-gpio2 for pmi8950 - gpio1-gpio2 for pmi8950
- gpio1-gpio10 for pmi8994 - gpio1-gpio10 for pmi8994
- gpio1-gpio18 for pmih0108
- gpio1-gpio4 for pmk8350 - gpio1-gpio4 for pmk8350
- gpio1-gpio6 for pmk8550 - gpio1-gpio6 for pmk8550
- gpio1-gpio10 for pmm8155au - gpio1-gpio10 for pmm8155au
...@@ -464,6 +493,7 @@ $defs: ...@@ -464,6 +493,7 @@ $defs:
and gpio11) and gpio11)
- gpio1-gpio16 for pmx65 - gpio1-gpio16 for pmx65
- gpio1-gpio16 for pmx75 - gpio1-gpio16 for pmx75
- gpio1-gpio12 for pmxr2230
items: items:
pattern: "^gpio([0-9]+)$" pattern: "^gpio([0-9]+)$"
...@@ -545,6 +575,7 @@ $defs: ...@@ -545,6 +575,7 @@ $defs:
examples: examples:
- | - |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> #include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
pm8921_gpio: gpio@150 { pm8921_gpio: gpio@150 {
...@@ -568,5 +599,12 @@ examples: ...@@ -568,5 +599,12 @@ examples:
power-source = <PM8921_GPIO_S4>; power-source = <PM8921_GPIO_S4>;
}; };
}; };
otg-hog {
gpio-hog;
gpios = <35 GPIO_ACTIVE_HIGH>;
output-high;
line-name = "otg-gpio";
};
}; };
... ...
...@@ -35,6 +35,7 @@ properties: ...@@ -35,6 +35,7 @@ properties:
- qcom,pm8038-mpp - qcom,pm8038-mpp
- qcom,pm8058-mpp - qcom,pm8058-mpp
- qcom,pm8821-mpp - qcom,pm8821-mpp
- qcom,pm8901-mpp
- qcom,pm8917-mpp - qcom,pm8917-mpp
- qcom,pm8921-mpp - qcom,pm8921-mpp
- const: qcom,ssbi-mpp - const: qcom,ssbi-mpp
......
...@@ -72,40 +72,24 @@ $defs: ...@@ -72,40 +72,24 @@ $defs:
description: description:
Specify the alternative function to be configured for the specified Specify the alternative function to be configured for the specified
pins. pins.
enum: [ gpio, atest_char, atest_char0, atest_char1, atest_char2, enum: [ gpio, atest_char, atest_usb0, audio_ref_clk, cam_mclk,
atest_char3, atest_usb0, atest_usb00, atest_usb01, atest_usb02, cci_async_in0, cci_i2c, cci, cmu_rng, coex_uart1_rx,
atest_usb03, audio_ref, cam_mclk, cci_async, cci_i2c, coex_uart1_tx, cri_trng, dbg_out_clk, ddr_bist,
cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4, ddr_pxi0_test, ddr_pxi1_test, gcc_gp1_clk, gcc_gp2_clk,
cmu_rng0, cmu_rng1, cmu_rng2, cmu_rng3, coex_uart1, cri_trng, gcc_gp3_clk, host2wlan_sol, ibi_i3c_qup0, ibi_i3c_qup1,
cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1, jitter_bist_ref, mdp_vsync0_out, mdp_vsync1_out,
dp0_hot, gcc_gp1, gcc_gp2, gcc_gp3, host2wlan_sol, ibi_i3c, mdp_vsync2_out, mdp_vsync3_out, mdp_vsync, nav,
jitter_bist, mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2, pcie0_clk_req, phase_flag, pll_bist_sync, pll_clk_aux,
mdp_vsync3, mi2s0_data0, mi2s0_data1, mi2s0_sck, mi2s0_ws, prng_rosc, qdss_cti_trig0, qdss_cti_trig1, qdss_gpio,
mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, mi2s_mclk0, qlink0_enable, qlink0_request, qlink0_wmss_reset,
mi2s_mclk1, nav_gpio0, nav_gpio1, nav_gpio2, pcie0_clk, qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4,
phase_flag0, phase_flag1, phase_flag10, phase_flag11, qup1_se0, qup1_se1, qup1_se2, qup1_se2_l2, qup1_se3,
phase_flag12, phase_flag13, phase_flag14, phase_flag15, qup1_se4, sd_write_protect, tb_trig_sdc1, tb_trig_sdc2,
phase_flag16, phase_flag17, phase_flag18, phase_flag19, tgu_ch0_trigout, tgu_ch1_trigout, tgu_ch2_trigout,
phase_flag2, phase_flag20, phase_flag21, phase_flag22, tgu_ch3_trigout, tmess_prng, tsense_pwm1_out,
phase_flag23, phase_flag24, phase_flag25, phase_flag26, tsense_pwm2_out, uim0, uim1, usb0_hs_ac, usb0_phy_ps,
phase_flag27, phase_flag28, phase_flag29, phase_flag3, vfr_0_mira, vfr_0_mirb, vfr_1, vsense_trigger_mirnat,
phase_flag30, phase_flag31, phase_flag4, phase_flag5, wlan1_adc_dtest0, wlan1_adc_dtest1 ]
phase_flag6, phase_flag7, phase_flag8, phase_flag9,
pll_bist, pll_clk, prng_rosc0, prng_rosc1, prng_rosc2,
prng_rosc3, qdss_cti, qdss_gpio, qdss_gpio0, qdss_gpio1,
qdss_gpio10, qdss_gpio11, qdss_gpio12, qdss_gpio13, qdss_gpio14,
qdss_gpio15, qdss_gpio2, qdss_gpio3, qdss_gpio4, qdss_gpio5,
qdss_gpio6, qdss_gpio7, qdss_gpio8, qdss_gpio9, qlink0_enable,
qlink0_request, qlink0_wmss, qlink1_enable, qlink1_request,
qlink1_wmss, qlink2_enable, qlink2_request, qlink2_wmss,
qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, qup0_se5,
qup0_se6, qup0_se7, qup1_se0, qup1_se1, qup1_se2, qup1_se3,
qup1_se4, qup1_se5, qup1_se6, sd_write, tb_trig, tgu_ch0,
tgu_ch1, tgu_ch2, tgu_ch3, tmess_prng0, tmess_prng1,
tmess_prng2, tmess_prng3, tsense_pwm1, tsense_pwm2, uim0_clk,
uim0_data, uim0_present, uim0_reset, uim1_clk, uim1_data,
uim1_present, uim1_reset, usb0_hs, usb0_phy, vfr_0, vfr_1,
vsense_trigger ]
required: required:
- pins - pins
......
...@@ -73,6 +73,13 @@ properties: ...@@ -73,6 +73,13 @@ properties:
minItems: 1 minItems: 1
maxItems: 2 maxItems: 2
clocks:
maxItems: 1
clock-names:
items:
- const: pclk
wakeup-interrupt-controller: wakeup-interrupt-controller:
$ref: samsung,pinctrl-wakeup-interrupt.yaml $ref: samsung,pinctrl-wakeup-interrupt.yaml
...@@ -120,6 +127,20 @@ required: ...@@ -120,6 +127,20 @@ required:
allOf: allOf:
- $ref: pinctrl.yaml# - $ref: pinctrl.yaml#
- if:
properties:
compatible:
contains:
const: google,gs101-pinctrl
then:
required:
- clocks
- clock-names
else:
properties:
clocks: false
clock-names: false
- if: - if:
properties: properties:
compatible: compatible:
......
...@@ -17702,7 +17702,6 @@ C: irc://irc.libera.chat/linux-exynos ...@@ -17702,7 +17702,6 @@ C: irc://irc.libera.chat/linux-exynos
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
F: Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml F: Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml
F: drivers/pinctrl/samsung/ F: drivers/pinctrl/samsung/
F: include/dt-bindings/pinctrl/samsung.h
PIN CONTROLLER - SINGLE PIN CONTROLLER - SINGLE
M: Tony Lindgren <tony@atomide.com> M: Tony Lindgren <tony@atomide.com>
......
...@@ -244,6 +244,10 @@ static const char * const irq_type_names[] = { ...@@ -244,6 +244,10 @@ static const char * const irq_type_names[] = {
[IRQ_TYPE_LEVEL_LOW] = "level-low", [IRQ_TYPE_LEVEL_LOW] = "level-low",
}; };
static bool persist_gpio_outputs;
module_param(persist_gpio_outputs, bool, 0644);
MODULE_PARM_DESC(persist_gpio_outputs, "Enable GPIO_OUT persistence when pin is freed");
static inline u32 bcm2835_gpio_rd(struct bcm2835_pinctrl *pc, unsigned reg) static inline u32 bcm2835_gpio_rd(struct bcm2835_pinctrl *pc, unsigned reg)
{ {
return readl(pc->base + reg); return readl(pc->base + reg);
...@@ -926,6 +930,13 @@ static int bcm2835_pmx_free(struct pinctrl_dev *pctldev, ...@@ -926,6 +930,13 @@ static int bcm2835_pmx_free(struct pinctrl_dev *pctldev,
unsigned offset) unsigned offset)
{ {
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
if (fsel == BCM2835_FSEL_GPIO_IN)
return 0;
if (persist_gpio_outputs && fsel == BCM2835_FSEL_GPIO_OUT)
return 0;
/* disable by setting to GPIO_IN */ /* disable by setting to GPIO_IN */
bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN); bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
...@@ -970,10 +981,7 @@ static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, ...@@ -970,10 +981,7 @@ static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned offset) unsigned offset)
{ {
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); bcm2835_pmx_free(pctldev, offset);
/* disable by setting to GPIO_IN */
bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
} }
static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
...@@ -1003,8 +1011,27 @@ static const struct pinmux_ops bcm2835_pmx_ops = { ...@@ -1003,8 +1011,27 @@ static const struct pinmux_ops bcm2835_pmx_ops = {
static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev, static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long *config) unsigned pin, unsigned long *config)
{ {
/* No way to read back config in HW */ enum pin_config_param param = pinconf_to_config_param(*config);
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, pin);
u32 val;
/* No way to read back bias config in HW */
switch (param) {
case PIN_CONFIG_OUTPUT:
if (fsel != BCM2835_FSEL_GPIO_OUT)
return -EINVAL;
val = bcm2835_gpio_get_bit(pc, GPLEV0, pin);
*config = pinconf_to_config_packed(param, val);
break;
default:
return -ENOTSUPP; return -ENOTSUPP;
}
return 0;
} }
static void bcm2835_pull_config_set(struct bcm2835_pinctrl *pc, static void bcm2835_pull_config_set(struct bcm2835_pinctrl *pc,
...@@ -1079,6 +1106,45 @@ static const struct pinconf_ops bcm2835_pinconf_ops = { ...@@ -1079,6 +1106,45 @@ static const struct pinconf_ops bcm2835_pinconf_ops = {
.pin_config_set = bcm2835_pinconf_set, .pin_config_set = bcm2835_pinconf_set,
}; };
static int bcm2711_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config)
{
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
u32 offset, shift, val;
offset = PUD_2711_REG_OFFSET(pin);
shift = PUD_2711_REG_SHIFT(pin);
val = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (offset * 4));
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_NONE)
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_UP)
return -EINVAL;
*config = pinconf_to_config_packed(param, 50000);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_DOWN)
return -EINVAL;
*config = pinconf_to_config_packed(param, 50000);
break;
default:
return bcm2835_pinconf_get(pctldev, pin, config);
}
return 0;
}
static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc, static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc,
unsigned int pin, unsigned int arg) unsigned int pin, unsigned int arg)
{ {
...@@ -1146,7 +1212,7 @@ static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -1146,7 +1212,7 @@ static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev,
static const struct pinconf_ops bcm2711_pinconf_ops = { static const struct pinconf_ops bcm2711_pinconf_ops = {
.is_generic = true, .is_generic = true,
.pin_config_get = bcm2835_pinconf_get, .pin_config_get = bcm2711_pinconf_get,
.pin_config_set = bcm2711_pinconf_set, .pin_config_set = bcm2711_pinconf_set,
}; };
...@@ -1361,6 +1427,9 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) ...@@ -1361,6 +1427,9 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
goto out_remove; goto out_remove;
} }
dev_info(dev, "GPIO_OUT persistence: %s\n",
persist_gpio_outputs ? "yes" : "no");
return 0; return 0;
out_remove: out_remove:
......
...@@ -252,6 +252,7 @@ static const struct of_device_id imx8ulp_pinctrl_of_match[] = { ...@@ -252,6 +252,7 @@ static const struct of_device_id imx8ulp_pinctrl_of_match[] = {
{ .compatible = "fsl,imx8ulp-iomuxc1", }, { .compatible = "fsl,imx8ulp-iomuxc1", },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, imx8ulp_pinctrl_of_match);
static int imx8ulp_pinctrl_probe(struct platform_device *pdev) static int imx8ulp_pinctrl_probe(struct platform_device *pdev)
{ {
......
...@@ -1086,6 +1086,7 @@ static const struct of_device_id mt6765_pinctrl_of_match[] = { ...@@ -1086,6 +1086,7 @@ static const struct of_device_id mt6765_pinctrl_of_match[] = {
{ .compatible = "mediatek,mt6765-pinctrl", .data = &mt6765_data }, { .compatible = "mediatek,mt6765-pinctrl", .data = &mt6765_data },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, mt6765_pinctrl_of_match);
static struct platform_driver mt6765_pinctrl_driver = { static struct platform_driver mt6765_pinctrl_driver = {
.driver = { .driver = {
......
...@@ -762,6 +762,7 @@ static const struct of_device_id mt6779_pinctrl_of_match[] = { ...@@ -762,6 +762,7 @@ static const struct of_device_id mt6779_pinctrl_of_match[] = {
{ .compatible = "mediatek,mt6779-pinctrl", .data = &mt6779_data }, { .compatible = "mediatek,mt6779-pinctrl", .data = &mt6779_data },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, mt6779_pinctrl_of_match);
static struct platform_driver mt6779_pinctrl_driver = { static struct platform_driver mt6779_pinctrl_driver = {
.driver = { .driver = {
......
...@@ -834,8 +834,6 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev, ...@@ -834,8 +834,6 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs, static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
int *funcsize, const char *name) int *funcsize, const char *name)
{ {
int i = 0;
if (*funcsize <= 0) if (*funcsize <= 0)
return -EOVERFLOW; return -EOVERFLOW;
...@@ -847,7 +845,6 @@ static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs, ...@@ -847,7 +845,6 @@ static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
return -EEXIST; return -EEXIST;
} }
funcs++; funcs++;
i++;
} }
/* append new unique function */ /* append new unique function */
......
...@@ -88,7 +88,7 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev, ...@@ -88,7 +88,7 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
seq_puts(s, items[i].display); seq_puts(s, items[i].display);
/* Print unit if available */ /* Print unit if available */
if (items[i].has_arg) { if (items[i].has_arg) {
seq_printf(s, " (%u", seq_printf(s, " (0x%x",
pinconf_to_config_argument(config)); pinconf_to_config_argument(config));
if (items[i].format) if (items[i].format)
seq_printf(s, " %s)", items[i].format); seq_printf(s, " %s)", items[i].format);
......
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Awinic AW9523B i2c pin controller driver * Awinic AW9523B i2c pin controller driver
* Copyright (c) 2020, AngeloGioacchino Del Regno * Copyright (c) 2020, AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
* <angelogioacchino.delregno@somainline.org>
*/ */
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/mutex.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pinctrl/pinconf.h> #include <linux/mutex.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#define AW9523_MAX_FUNCS 2 #define AW9523_MAX_FUNCS 2
#define AW9523_NUM_PORTS 2 #define AW9523_NUM_PORTS 2
#define AW9523_PINS_PER_PORT 8 #define AW9523_PINS_PER_PORT 8
...@@ -56,27 +57,13 @@ ...@@ -56,27 +57,13 @@
/* /*
* struct aw9523_irq - Interrupt controller structure * struct aw9523_irq - Interrupt controller structure
* @lock: mutex locking for the irq bus * @lock: mutex locking for the irq bus
* @irqchip: structure holding irqchip params
* @cached_gpio: stores the previous gpio status for bit comparison * @cached_gpio: stores the previous gpio status for bit comparison
*/ */
struct aw9523_irq { struct aw9523_irq {
struct mutex lock; struct mutex lock;
struct irq_chip *irqchip;
u16 cached_gpio; u16 cached_gpio;
}; };
/*
* struct aw9523_pinmux - Pin mux params
* @name: Name of the mux
* @grps: Groups of the mux
* @num_grps: Number of groups (sizeof array grps)
*/
struct aw9523_pinmux {
const char *name;
const char * const *grps;
const u8 num_grps;
};
/* /*
* struct aw9523 - Main driver structure * struct aw9523 - Main driver structure
* @dev: device handle * @dev: device handle
...@@ -151,23 +138,16 @@ static const struct pinctrl_ops aw9523_pinctrl_ops = { ...@@ -151,23 +138,16 @@ static const struct pinctrl_ops aw9523_pinctrl_ops = {
}; };
static const char * const gpio_pwm_groups[] = { static const char * const gpio_pwm_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio0", "gpio1", "gpio2", "gpio3", /* 0-3 */
"gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", "gpio4", "gpio5", "gpio6", "gpio7", /* 4-7 */
"gpio12", "gpio13", "gpio14", "gpio15" "gpio8", "gpio9", "gpio10", "gpio11", /* 8-11 */
"gpio12", "gpio13", "gpio14", "gpio15", /* 11-15 */
}; };
/* Warning: Do NOT reorder this array */ /* Warning: Do NOT reorder this array */
static const struct aw9523_pinmux aw9523_pmx[] = { static const struct pinfunction aw9523_pmx[] = {
{ PINCTRL_PINFUNCTION("pwm", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)),
.name = "pwm", PINCTRL_PINFUNCTION("gpio", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)),
.grps = gpio_pwm_groups,
.num_grps = ARRAY_SIZE(gpio_pwm_groups),
},
{
.name = "gpio",
.grps = gpio_pwm_groups,
.num_grps = ARRAY_SIZE(gpio_pwm_groups),
},
}; };
static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl) static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl)
...@@ -183,10 +163,10 @@ static const char *aw9523_pmx_get_fname(struct pinctrl_dev *pctl, ...@@ -183,10 +163,10 @@ static const char *aw9523_pmx_get_fname(struct pinctrl_dev *pctl,
static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel, static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel,
const char * const **groups, const char * const **groups,
unsigned int * const num_groups) unsigned int * const ngroups)
{ {
*groups = aw9523_pmx[sel].grps; *groups = aw9523_pmx[sel].groups;
*num_groups = aw9523_pmx[sel].num_grps; *ngroups = aw9523_pmx[sel].ngroups;
return 0; return 0;
} }
...@@ -239,7 +219,7 @@ static int aw9523_pcfg_param_to_reg(enum pin_config_param pcp, int pin, u8 *r) ...@@ -239,7 +219,7 @@ static int aw9523_pcfg_param_to_reg(enum pin_config_param pcp, int pin, u8 *r)
reg = AW9523_REG_OUT_STATE(pin); reg = AW9523_REG_OUT_STATE(pin);
break; break;
default: default:
return -EOPNOTSUPP; return -ENOTSUPP;
} }
*r = reg; *r = reg;
...@@ -290,7 +270,7 @@ static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -290,7 +270,7 @@ static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val); val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
break; break;
default: default:
return -EOPNOTSUPP; return -ENOTSUPP;
} }
if (val < 1) if (val < 1)
return -EINVAL; return -EINVAL;
...@@ -344,7 +324,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -344,7 +324,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
case PIN_CONFIG_DRIVE_OPEN_DRAIN: case PIN_CONFIG_DRIVE_OPEN_DRAIN:
/* Open-Drain is supported only on port 0 */ /* Open-Drain is supported only on port 0 */
if (pin >= AW9523_PINS_PER_PORT) { if (pin >= AW9523_PINS_PER_PORT) {
rc = -EOPNOTSUPP; rc = -ENOTSUPP;
goto end; goto end;
} }
mask = AW9523_GCR_GPOMD_MASK; mask = AW9523_GCR_GPOMD_MASK;
...@@ -361,7 +341,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -361,7 +341,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
val = AW9523_GCR_GPOMD_MASK; val = AW9523_GCR_GPOMD_MASK;
break; break;
default: default:
rc = -EOPNOTSUPP; rc = -ENOTSUPP;
goto end; goto end;
} }
...@@ -408,8 +388,8 @@ static int aw9523_get_pin_direction(struct regmap *regmap, u8 pin, u8 n) ...@@ -408,8 +388,8 @@ static int aw9523_get_pin_direction(struct regmap *regmap, u8 pin, u8 n)
* *
* Return: Zero for success or negative number for error * Return: Zero for success or negative number for error
*/ */
static int aw9523_get_port_state(struct regmap *regmap, u8 pin, static int aw9523_get_port_state(struct regmap *regmap, u8 pin, u8 regbit,
u8 regbit, unsigned int *state) unsigned int *state)
{ {
u8 reg; u8 reg;
int dir; int dir;
...@@ -447,12 +427,12 @@ static int aw9523_gpio_irq_type(struct irq_data *d, unsigned int type) ...@@ -447,12 +427,12 @@ static int aw9523_gpio_irq_type(struct irq_data *d, unsigned int type)
static void aw9523_irq_mask(struct irq_data *d) static void aw9523_irq_mask(struct irq_data *d)
{ {
struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d)); struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
unsigned int n = d->hwirq % AW9523_PINS_PER_PORT; irq_hw_number_t hwirq = irqd_to_hwirq(d);
unsigned int n = hwirq % AW9523_PINS_PER_PORT;
regmap_update_bits(awi->regmap, regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq),
AW9523_REG_INTR_DIS(d->hwirq),
BIT(n), BIT(n)); BIT(n), BIT(n));
gpiochip_disable_irq(&awi->gpio, irqd_to_hwirq(d)); gpiochip_disable_irq(&awi->gpio, hwirq);
} }
/* /*
...@@ -465,11 +445,11 @@ static void aw9523_irq_mask(struct irq_data *d) ...@@ -465,11 +445,11 @@ static void aw9523_irq_mask(struct irq_data *d)
static void aw9523_irq_unmask(struct irq_data *d) static void aw9523_irq_unmask(struct irq_data *d)
{ {
struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d)); struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
unsigned int n = d->hwirq % AW9523_PINS_PER_PORT; irq_hw_number_t hwirq = irqd_to_hwirq(d);
unsigned int n = hwirq % AW9523_PINS_PER_PORT;
gpiochip_enable_irq(&awi->gpio, irqd_to_hwirq(d)); gpiochip_enable_irq(&awi->gpio, hwirq);
regmap_update_bits(awi->regmap, regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq),
AW9523_REG_INTR_DIS(d->hwirq),
BIT(n), 0); BIT(n), 0);
} }
...@@ -622,7 +602,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip, ...@@ -622,7 +602,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
mutex_lock(&awi->i2c_lock); mutex_lock(&awi->i2c_lock);
/* Port 0 (gpio 0-7) */ /* Port 0 (gpio 0-7) */
m = *mask & U8_MAX; m = *mask;
if (m) { if (m) {
ret = _aw9523_gpio_get_multiple(awi, 0, &state, m); ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
if (ret) if (ret)
...@@ -631,7 +611,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip, ...@@ -631,7 +611,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
*bits = state; *bits = state;
/* Port 1 (gpio 8-15) */ /* Port 1 (gpio 8-15) */
m = (*mask >> 8) & U8_MAX; m = *mask >> 8;
if (m) { if (m) {
ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT, ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
&state, m); &state, m);
...@@ -652,29 +632,26 @@ static void aw9523_gpio_set_multiple(struct gpio_chip *chip, ...@@ -652,29 +632,26 @@ static void aw9523_gpio_set_multiple(struct gpio_chip *chip,
struct aw9523 *awi = gpiochip_get_data(chip); struct aw9523 *awi = gpiochip_get_data(chip);
u8 mask_lo, mask_hi, bits_lo, bits_hi; u8 mask_lo, mask_hi, bits_lo, bits_hi;
unsigned int reg; unsigned int reg;
int ret = 0; int ret;
mask_lo = *mask;
mask_hi = *mask >> 8;
bits_lo = *bits;
bits_hi = *bits >> 8;
mask_lo = *mask & U8_MAX;
mask_hi = (*mask >> 8) & U8_MAX;
mutex_lock(&awi->i2c_lock); mutex_lock(&awi->i2c_lock);
if (mask_hi) { if (mask_hi) {
reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT); reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
bits_hi = (*bits >> 8) & U8_MAX;
ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi); ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
if (ret) { if (ret)
dev_warn(awi->dev, "Cannot write port1 out level\n"); dev_warn(awi->dev, "Cannot write port1 out level\n");
goto out;
}
} }
if (mask_lo) { if (mask_lo) {
reg = AW9523_REG_OUT_STATE(0); reg = AW9523_REG_OUT_STATE(0);
bits_lo = *bits & U8_MAX;
ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo); ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
if (ret) if (ret)
dev_warn(awi->dev, "Cannot write port0 out level\n"); dev_warn(awi->dev, "Cannot write port0 out level\n");
} }
out:
mutex_unlock(&awi->i2c_lock); mutex_unlock(&awi->i2c_lock);
} }
...@@ -827,29 +804,21 @@ static int aw9523_init_irq(struct aw9523 *awi, int irq) ...@@ -827,29 +804,21 @@ static int aw9523_init_irq(struct aw9523 *awi, int irq)
{ {
struct device *dev = awi->dev; struct device *dev = awi->dev;
struct gpio_irq_chip *girq; struct gpio_irq_chip *girq;
struct irq_chip *irqchip;
int ret; int ret;
if (!device_property_read_bool(dev, "interrupt-controller")) if (!device_property_read_bool(dev, "interrupt-controller"))
return 0; return 0;
irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL);
if (!irqchip)
return -ENOMEM;
awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL); awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL);
if (!awi->irq) if (!awi->irq)
return -ENOMEM; return -ENOMEM;
awi->irq->irqchip = irqchip;
mutex_init(&awi->irq->lock); mutex_init(&awi->irq->lock);
ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func, ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
IRQF_ONESHOT, dev_name(dev), awi); IRQF_ONESHOT, dev_name(dev), awi);
if (ret) { if (ret)
dev_err(dev, "Failed to request irq %d\n", irq); return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);
return ret;
}
girq = &awi->gpio.irq; girq = &awi->gpio.irq;
gpio_irq_chip_set_chip(girq, &aw9523_irq_chip); gpio_irq_chip_set_chip(girq, &aw9523_irq_chip);
...@@ -1015,8 +984,7 @@ static int aw9523_probe(struct i2c_client *client) ...@@ -1015,8 +984,7 @@ static int aw9523_probe(struct i2c_client *client)
} }
mutex_init(&awi->i2c_lock); mutex_init(&awi->i2c_lock);
lockdep_set_subclass(&awi->i2c_lock, lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter));
i2c_adapter_depth(client->adapter));
pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL);
if (!pdesc) if (!pdesc)
...@@ -1046,8 +1014,7 @@ static int aw9523_probe(struct i2c_client *client) ...@@ -1046,8 +1014,7 @@ static int aw9523_probe(struct i2c_client *client)
awi->pctl = devm_pinctrl_register(dev, pdesc, awi); awi->pctl = devm_pinctrl_register(dev, pdesc, awi);
if (IS_ERR(awi->pctl)) { if (IS_ERR(awi->pctl)) {
ret = PTR_ERR(awi->pctl); ret = dev_err_probe(dev, PTR_ERR(awi->pctl), "Cannot register pinctrl");
dev_err(dev, "Cannot register pinctrl: %d", ret);
goto err_disable_vregs; goto err_disable_vregs;
} }
...@@ -1067,10 +1034,6 @@ static int aw9523_probe(struct i2c_client *client) ...@@ -1067,10 +1034,6 @@ static int aw9523_probe(struct i2c_client *client)
static void aw9523_remove(struct i2c_client *client) static void aw9523_remove(struct i2c_client *client)
{ {
struct aw9523 *awi = i2c_get_clientdata(client); struct aw9523 *awi = i2c_get_clientdata(client);
int ret;
if (!awi)
return;
/* /*
* If the chip VIO is connected to a regulator that we can turn * If the chip VIO is connected to a regulator that we can turn
...@@ -1082,10 +1045,8 @@ static void aw9523_remove(struct i2c_client *client) ...@@ -1082,10 +1045,8 @@ static void aw9523_remove(struct i2c_client *client)
regulator_disable(awi->vio_vreg); regulator_disable(awi->vio_vreg);
} else { } else {
mutex_lock(&awi->i2c_lock); mutex_lock(&awi->i2c_lock);
ret = aw9523_hw_init(awi); aw9523_hw_init(awi);
mutex_unlock(&awi->i2c_lock); mutex_unlock(&awi->i2c_lock);
if (ret)
return;
} }
mutex_destroy(&awi->i2c_lock); mutex_destroy(&awi->i2c_lock);
......
...@@ -286,6 +286,7 @@ static const struct of_device_id loongson2_pinctrl_dt_match[] = { ...@@ -286,6 +286,7 @@ static const struct of_device_id loongson2_pinctrl_dt_match[] = {
}, },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, loongson2_pinctrl_dt_match);
static struct platform_driver loongson2_pinctrl_driver = { static struct platform_driver loongson2_pinctrl_driver = {
.probe = loongson2_pinctrl_probe, .probe = loongson2_pinctrl_probe,
......
...@@ -88,7 +88,6 @@ struct max77620_pingroup { ...@@ -88,7 +88,6 @@ struct max77620_pingroup {
struct max77620_pin_info { struct max77620_pin_info {
enum max77620_pin_ppdrv drv_type; enum max77620_pin_ppdrv drv_type;
int pull_config;
}; };
struct max77620_fps_config { struct max77620_fps_config {
...@@ -104,7 +103,6 @@ struct max77620_pctrl_info { ...@@ -104,7 +103,6 @@ struct max77620_pctrl_info {
struct device *dev; struct device *dev;
struct pinctrl_dev *pctl; struct pinctrl_dev *pctl;
struct regmap *rmap; struct regmap *rmap;
int pins_current_opt[MAX77620_GPIO_NR];
const struct max77620_pin_function *functions; const struct max77620_pin_function *functions;
unsigned int num_functions; unsigned int num_functions;
const struct max77620_pingroup *pin_groups; const struct max77620_pingroup *pin_groups;
......
...@@ -81,8 +81,6 @@ struct pcs_conf_type { ...@@ -81,8 +81,6 @@ struct pcs_conf_type {
* @name: pinctrl function name * @name: pinctrl function name
* @vals: register and vals array * @vals: register and vals array
* @nvals: number of entries in vals array * @nvals: number of entries in vals array
* @pgnames: array of pingroup names the function uses
* @npgnames: number of pingroup names the function uses
* @conf: array of pin configurations * @conf: array of pin configurations
* @nconfs: number of pin configurations available * @nconfs: number of pin configurations available
* @node: list node * @node: list node
...@@ -91,8 +89,6 @@ struct pcs_function { ...@@ -91,8 +89,6 @@ struct pcs_function {
const char *name; const char *name;
struct pcs_func_vals *vals; struct pcs_func_vals *vals;
unsigned nvals; unsigned nvals;
const char **pgnames;
int npgnames;
struct pcs_conf_vals *conf; struct pcs_conf_vals *conf;
int nconfs; int nconfs;
struct list_head node; struct list_head node;
...@@ -554,21 +550,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -554,21 +550,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
unsigned offset = 0, shift = 0, i, data, ret; unsigned offset = 0, shift = 0, i, data, ret;
u32 arg; u32 arg;
int j; int j;
enum pin_config_param param;
ret = pcs_get_function(pctldev, pin, &func); ret = pcs_get_function(pctldev, pin, &func);
if (ret) if (ret)
return ret; return ret;
for (j = 0; j < num_configs; j++) { for (j = 0; j < num_configs; j++) {
param = pinconf_to_config_param(configs[j]);
/* BIAS_DISABLE has no entry in the func->conf table */
if (param == PIN_CONFIG_BIAS_DISABLE) {
/* This just disables all bias entries */
pcs_pinconf_clear_bias(pctldev, pin);
continue;
}
for (i = 0; i < func->nconfs; i++) { for (i = 0; i < func->nconfs; i++) {
if (pinconf_to_config_param(configs[j]) if (param != func->conf[i].param)
!= func->conf[i].param)
continue; continue;
offset = pin * (pcs->width / BITS_PER_BYTE); offset = pin * (pcs->width / BITS_PER_BYTE);
data = pcs->read(pcs->base + offset); data = pcs->read(pcs->base + offset);
arg = pinconf_to_config_argument(configs[j]); arg = pinconf_to_config_argument(configs[j]);
switch (func->conf[i].param) { switch (param) {
/* 2 parameters */ /* 2 parameters */
case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_INPUT_SCHMITT:
case PIN_CONFIG_DRIVE_STRENGTH: case PIN_CONFIG_DRIVE_STRENGTH:
...@@ -580,9 +585,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -580,9 +585,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
data |= (arg << shift) & func->conf[i].mask; data |= (arg << shift) & func->conf[i].mask;
break; break;
/* 4 parameters */ /* 4 parameters */
case PIN_CONFIG_BIAS_DISABLE:
pcs_pinconf_clear_bias(pctldev, pin);
break;
case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_DOWN:
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
if (arg) if (arg)
...@@ -1625,7 +1627,6 @@ static int pcs_irq_init_chained_handler(struct pcs_device *pcs, ...@@ -1625,7 +1627,6 @@ static int pcs_irq_init_chained_handler(struct pcs_device *pcs,
return 0; return 0;
} }
#ifdef CONFIG_PM
static int pcs_save_context(struct pcs_device *pcs) static int pcs_save_context(struct pcs_device *pcs)
{ {
int i, mux_bytes; int i, mux_bytes;
...@@ -1690,14 +1691,9 @@ static void pcs_restore_context(struct pcs_device *pcs) ...@@ -1690,14 +1691,9 @@ static void pcs_restore_context(struct pcs_device *pcs)
} }
} }
static int pinctrl_single_suspend(struct platform_device *pdev, static int pinctrl_single_suspend_noirq(struct device *dev)
pm_message_t state)
{ {
struct pcs_device *pcs; struct pcs_device *pcs = dev_get_drvdata(dev);
pcs = platform_get_drvdata(pdev);
if (!pcs)
return -EINVAL;
if (pcs->flags & PCS_CONTEXT_LOSS_OFF) { if (pcs->flags & PCS_CONTEXT_LOSS_OFF) {
int ret; int ret;
...@@ -1710,20 +1706,19 @@ static int pinctrl_single_suspend(struct platform_device *pdev, ...@@ -1710,20 +1706,19 @@ static int pinctrl_single_suspend(struct platform_device *pdev,
return pinctrl_force_sleep(pcs->pctl); return pinctrl_force_sleep(pcs->pctl);
} }
static int pinctrl_single_resume(struct platform_device *pdev) static int pinctrl_single_resume_noirq(struct device *dev)
{ {
struct pcs_device *pcs; struct pcs_device *pcs = dev_get_drvdata(dev);
pcs = platform_get_drvdata(pdev);
if (!pcs)
return -EINVAL;
if (pcs->flags & PCS_CONTEXT_LOSS_OFF) if (pcs->flags & PCS_CONTEXT_LOSS_OFF)
pcs_restore_context(pcs); pcs_restore_context(pcs);
return pinctrl_force_default(pcs->pctl); return pinctrl_force_default(pcs->pctl);
} }
#endif
static DEFINE_NOIRQ_DEV_PM_OPS(pinctrl_single_pm_ops,
pinctrl_single_suspend_noirq,
pinctrl_single_resume_noirq);
/** /**
* pcs_quirk_missing_pinctrl_cells - handle legacy binding * pcs_quirk_missing_pinctrl_cells - handle legacy binding
...@@ -1986,11 +1981,8 @@ static struct platform_driver pcs_driver = { ...@@ -1986,11 +1981,8 @@ static struct platform_driver pcs_driver = {
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.of_match_table = pcs_of_match, .of_match_table = pcs_of_match,
.pm = pm_sleep_ptr(&pinctrl_single_pm_ops),
}, },
#ifdef CONFIG_PM
.suspend = pinctrl_single_suspend,
.resume = pinctrl_single_resume,
#endif
}; };
module_platform_driver(pcs_driver); module_platform_driver(pcs_driver);
......
...@@ -578,6 +578,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what) ...@@ -578,6 +578,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
return 0; return 0;
} }
DEFINE_SHOW_ATTRIBUTE(pinmux_functions);
static int pinmux_pins_show(struct seq_file *s, void *what) static int pinmux_pins_show(struct seq_file *s, void *what)
{ {
...@@ -650,6 +651,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what) ...@@ -650,6 +651,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
return 0; return 0;
} }
DEFINE_SHOW_ATTRIBUTE(pinmux_pins);
void pinmux_show_map(struct seq_file *s, const struct pinctrl_map *map) void pinmux_show_map(struct seq_file *s, const struct pinctrl_map *map)
{ {
...@@ -672,10 +674,12 @@ void pinmux_show_setting(struct seq_file *s, ...@@ -672,10 +674,12 @@ void pinmux_show_setting(struct seq_file *s,
setting->data.mux.func); setting->data.mux.func);
} }
DEFINE_SHOW_ATTRIBUTE(pinmux_functions); static int pinmux_select_show(struct seq_file *s, void *unused)
DEFINE_SHOW_ATTRIBUTE(pinmux_pins); {
return -EPERM;
}
static ssize_t pinmux_select(struct file *file, const char __user *user_buf, static ssize_t pinmux_select_write(struct file *file, const char __user *user_buf,
size_t len, loff_t *ppos) size_t len, loff_t *ppos)
{ {
struct seq_file *sfile = file->private_data; struct seq_file *sfile = file->private_data;
...@@ -749,19 +753,7 @@ static ssize_t pinmux_select(struct file *file, const char __user *user_buf, ...@@ -749,19 +753,7 @@ static ssize_t pinmux_select(struct file *file, const char __user *user_buf,
return ret; return ret;
} }
DEFINE_SHOW_STORE_ATTRIBUTE(pinmux_select);
static int pinmux_select_open(struct inode *inode, struct file *file)
{
return single_open(file, NULL, inode->i_private);
}
static const struct file_operations pinmux_select_ops = {
.owner = THIS_MODULE,
.open = pinmux_select_open,
.write = pinmux_select,
.llseek = no_llseek,
.release = single_release,
};
void pinmux_init_device_debugfs(struct dentry *devroot, void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev) struct pinctrl_dev *pctldev)
...@@ -771,7 +763,7 @@ void pinmux_init_device_debugfs(struct dentry *devroot, ...@@ -771,7 +763,7 @@ void pinmux_init_device_debugfs(struct dentry *devroot,
debugfs_create_file("pinmux-pins", 0444, debugfs_create_file("pinmux-pins", 0444,
devroot, pctldev, &pinmux_pins_fops); devroot, pctldev, &pinmux_pins_fops);
debugfs_create_file("pinmux-select", 0200, debugfs_create_file("pinmux-select", 0200,
devroot, pctldev, &pinmux_select_ops); devroot, pctldev, &pinmux_select_fops);
} }
#endif /* CONFIG_DEBUG_FS */ #endif /* CONFIG_DEBUG_FS */
......
...@@ -32,7 +32,7 @@ static const char *pxa2xx_pctrl_get_group_name(struct pinctrl_dev *pctldev, ...@@ -32,7 +32,7 @@ static const char *pxa2xx_pctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned tgroup) unsigned tgroup)
{ {
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *group = pctl->groups + tgroup; struct pingroup *group = pctl->groups + tgroup;
return group->name; return group->name;
} }
...@@ -43,10 +43,10 @@ static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev, ...@@ -43,10 +43,10 @@ static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
unsigned *num_pins) unsigned *num_pins)
{ {
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *group = pctl->groups + tgroup; struct pingroup *group = pctl->groups + tgroup;
*pins = (unsigned *)&group->pin; *pins = group->pins;
*num_pins = 1; *num_pins = group->npins;
return 0; return 0;
} }
...@@ -109,7 +109,7 @@ static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev, ...@@ -109,7 +109,7 @@ static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev,
unsigned function) unsigned function)
{ {
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_function *pf = pctl->functions + function; struct pinfunction *pf = pctl->functions + function;
return pf->name; return pf->name;
} }
...@@ -127,7 +127,7 @@ static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev, ...@@ -127,7 +127,7 @@ static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev,
unsigned * const num_groups) unsigned * const num_groups)
{ {
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_function *pf = pctl->functions + function; struct pinfunction *pf = pctl->functions + function;
*groups = pf->groups; *groups = pf->groups;
*num_groups = pf->ngroups; *num_groups = pf->ngroups;
...@@ -139,20 +139,18 @@ static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function, ...@@ -139,20 +139,18 @@ static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function,
unsigned tgroup) unsigned tgroup)
{ {
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *group = pctl->groups + tgroup; struct pingroup *g = pctl->groups + tgroup;
unsigned int pin = g->pins[0];
struct pxa_desc_function *df; struct pxa_desc_function *df;
int pin, shift;
unsigned long flags; unsigned long flags;
void __iomem *gafr, *gpdr; void __iomem *gafr, *gpdr;
int shift;
u32 val; u32 val;
df = pxa_desc_by_func_group(pctl, g->name, (pctl->functions + function)->name);
df = pxa_desc_by_func_group(pctl, group->name,
(pctl->functions + function)->name);
if (!df) if (!df)
return -EINVAL; return -EINVAL;
pin = group->pin;
gafr = pctl->base_gafr[pin / 16]; gafr = pctl->base_gafr[pin / 16];
gpdr = pctl->base_gpdr[pin / 32]; gpdr = pctl->base_gpdr[pin / 32];
shift = (pin % 16) << 1; shift = (pin % 16) << 1;
...@@ -186,9 +184,9 @@ static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev, ...@@ -186,9 +184,9 @@ static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev,
unsigned long *config) unsigned long *config)
{ {
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *g = pctl->groups + group; struct pingroup *g = pctl->groups + group;
unsigned int pin = g->pins[0];
unsigned long flags; unsigned long flags;
unsigned pin = g->pin;
void __iomem *pgsr = pctl->base_pgsr[pin / 32]; void __iomem *pgsr = pctl->base_pgsr[pin / 32];
u32 val; u32 val;
...@@ -208,9 +206,9 @@ static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev, ...@@ -208,9 +206,9 @@ static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev,
unsigned num_configs) unsigned num_configs)
{ {
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct pxa_pinctrl_group *g = pctl->groups + group; struct pingroup *g = pctl->groups + group;
unsigned int pin = g->pins[0];
unsigned long flags; unsigned long flags;
unsigned pin = g->pin;
void __iomem *pgsr = pctl->base_pgsr[pin / 32]; void __iomem *pgsr = pctl->base_pgsr[pin / 32];
int i, is_set = 0; int i, is_set = 0;
u32 val; u32 val;
...@@ -249,11 +247,11 @@ static struct pinctrl_desc pxa2xx_pinctrl_desc = { ...@@ -249,11 +247,11 @@ static struct pinctrl_desc pxa2xx_pinctrl_desc = {
.pmxops = &pxa2xx_pinmux_ops, .pmxops = &pxa2xx_pinmux_ops,
}; };
static const struct pxa_pinctrl_function * static const struct pinfunction *pxa2xx_find_function(struct pxa_pinctrl *pctl,
pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname, const char *fname,
const struct pxa_pinctrl_function *functions) const struct pinfunction *functions)
{ {
const struct pxa_pinctrl_function *func; const struct pinfunction *func;
for (func = functions; func->name; func++) for (func = functions; func->name; func++)
if (!strcmp(fname, func->name)) if (!strcmp(fname, func->name))
...@@ -264,8 +262,8 @@ pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname, ...@@ -264,8 +262,8 @@ pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname,
static int pxa2xx_build_functions(struct pxa_pinctrl *pctl) static int pxa2xx_build_functions(struct pxa_pinctrl *pctl)
{ {
struct pinfunction *functions;
int i; int i;
struct pxa_pinctrl_function *functions;
struct pxa_desc_function *df; struct pxa_desc_function *df;
/* /*
...@@ -296,9 +294,9 @@ static int pxa2xx_build_functions(struct pxa_pinctrl *pctl) ...@@ -296,9 +294,9 @@ static int pxa2xx_build_functions(struct pxa_pinctrl *pctl)
static int pxa2xx_build_groups(struct pxa_pinctrl *pctl) static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
{ {
int i, j, ngroups; int i, j, ngroups;
struct pxa_pinctrl_function *func;
struct pxa_desc_function *df; struct pxa_desc_function *df;
char **gtmp; struct pinfunction *func;
const char **gtmp;
gtmp = devm_kmalloc_array(pctl->dev, pctl->npins, sizeof(*gtmp), gtmp = devm_kmalloc_array(pctl->dev, pctl->npins, sizeof(*gtmp),
GFP_KERNEL); GFP_KERNEL);
...@@ -316,13 +314,9 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl) ...@@ -316,13 +314,9 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
pctl->ppins[j].pin.name; pctl->ppins[j].pin.name;
func = pctl->functions + i; func = pctl->functions + i;
func->ngroups = ngroups; func->ngroups = ngroups;
func->groups = func->groups = devm_kmemdup(pctl->dev, gtmp, ngroups * sizeof(*gtmp), GFP_KERNEL);
devm_kmalloc_array(pctl->dev, ngroups,
sizeof(char *), GFP_KERNEL);
if (!func->groups) if (!func->groups)
return -ENOMEM; return -ENOMEM;
memcpy(func->groups, gtmp, ngroups * sizeof(*gtmp));
} }
devm_kfree(pctl->dev, gtmp); devm_kfree(pctl->dev, gtmp);
...@@ -332,8 +326,8 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl) ...@@ -332,8 +326,8 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
static int pxa2xx_build_state(struct pxa_pinctrl *pctl, static int pxa2xx_build_state(struct pxa_pinctrl *pctl,
const struct pxa_desc_pin *ppins, int npins) const struct pxa_desc_pin *ppins, int npins)
{ {
struct pxa_pinctrl_group *group;
struct pinctrl_pin_desc *pins; struct pinctrl_pin_desc *pins;
struct pingroup *group;
int ret, i; int ret, i;
pctl->npins = npins; pctl->npins = npins;
...@@ -357,7 +351,8 @@ static int pxa2xx_build_state(struct pxa_pinctrl *pctl, ...@@ -357,7 +351,8 @@ static int pxa2xx_build_state(struct pxa_pinctrl *pctl,
for (i = 0; i < npins; i++) { for (i = 0; i < npins; i++) {
group = pctl->groups + i; group = pctl->groups + i;
group->name = ppins[i].pin.name; group->name = ppins[i].pin.name;
group->pin = ppins[i].pin.number; group->pins = &ppins[i].pin.number;
group->npins = 1;
} }
ret = pxa2xx_build_functions(pctl); ret = pxa2xx_build_functions(pctl);
......
...@@ -52,17 +52,6 @@ struct pxa_desc_pin { ...@@ -52,17 +52,6 @@ struct pxa_desc_pin {
struct pxa_desc_function *functions; struct pxa_desc_function *functions;
}; };
struct pxa_pinctrl_group {
const char *name;
unsigned pin;
};
struct pxa_pinctrl_function {
const char *name;
const char **groups;
unsigned ngroups;
};
struct pxa_pinctrl { struct pxa_pinctrl {
spinlock_t lock; spinlock_t lock;
void __iomem **base_gafr; void __iomem **base_gafr;
...@@ -74,9 +63,9 @@ struct pxa_pinctrl { ...@@ -74,9 +63,9 @@ struct pxa_pinctrl {
unsigned npins; unsigned npins;
const struct pxa_desc_pin *ppins; const struct pxa_desc_pin *ppins;
unsigned ngroups; unsigned ngroups;
struct pxa_pinctrl_group *groups; struct pingroup *groups;
unsigned nfuncs; unsigned nfuncs;
struct pxa_pinctrl_function *functions; struct pinfunction *functions;
char *name; char *name;
}; };
......
...@@ -65,7 +65,7 @@ enum { ...@@ -65,7 +65,7 @@ enum {
.intr_detection_width = 2, \ .intr_detection_width = 2, \
} }
#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \ #define SDC_QDSD_PINGROUP(pg_name, _tile, ctl, pull, drv) \
{ \ { \
.grp = PINCTRL_PINGROUP(#pg_name, \ .grp = PINCTRL_PINGROUP(#pg_name, \
pg_name##_pins, \ pg_name##_pins, \
...@@ -75,7 +75,7 @@ enum { ...@@ -75,7 +75,7 @@ enum {
.intr_cfg_reg = 0, \ .intr_cfg_reg = 0, \
.intr_status_reg = 0, \ .intr_status_reg = 0, \
.intr_target_reg = 0, \ .intr_target_reg = 0, \
.tile = SOUTH, \ .tile = _tile, \
.mux_bit = -1, \ .mux_bit = -1, \
.pull_bit = pull, \ .pull_bit = pull, \
.drv_bit = drv, \ .drv_bit = drv, \
...@@ -101,7 +101,7 @@ enum { ...@@ -101,7 +101,7 @@ enum {
.intr_cfg_reg = 0, \ .intr_cfg_reg = 0, \
.intr_status_reg = 0, \ .intr_status_reg = 0, \
.intr_target_reg = 0, \ .intr_target_reg = 0, \
.tile = SOUTH, \ .tile = WEST, \
.mux_bit = -1, \ .mux_bit = -1, \
.pull_bit = 3, \ .pull_bit = 3, \
.drv_bit = 0, \ .drv_bit = 0, \
...@@ -1199,13 +1199,13 @@ static const struct msm_pingroup sm7150_groups[] = { ...@@ -1199,13 +1199,13 @@ static const struct msm_pingroup sm7150_groups[] = {
[117] = PINGROUP(117, NORTH, _, _, _, _, _, _, _, _, _), [117] = PINGROUP(117, NORTH, _, _, _, _, _, _, _, _, _),
[118] = PINGROUP(118, NORTH, _, _, _, _, _, _, _, _, _), [118] = PINGROUP(118, NORTH, _, _, _, _, _, _, _, _, _),
[119] = UFS_RESET(ufs_reset, 0x9f000), [119] = UFS_RESET(ufs_reset, 0x9f000),
[120] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x9a000, 15, 0), [120] = SDC_QDSD_PINGROUP(sdc1_rclk, WEST, 0x9a000, 15, 0),
[121] = SDC_QDSD_PINGROUP(sdc1_clk, 0x9a000, 13, 6), [121] = SDC_QDSD_PINGROUP(sdc1_clk, WEST, 0x9a000, 13, 6),
[122] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x9a000, 11, 3), [122] = SDC_QDSD_PINGROUP(sdc1_cmd, WEST, 0x9a000, 11, 3),
[123] = SDC_QDSD_PINGROUP(sdc1_data, 0x9a000, 9, 0), [123] = SDC_QDSD_PINGROUP(sdc1_data, WEST, 0x9a000, 9, 0),
[124] = SDC_QDSD_PINGROUP(sdc2_clk, 0x98000, 14, 6), [124] = SDC_QDSD_PINGROUP(sdc2_clk, SOUTH, 0x98000, 14, 6),
[125] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x98000, 11, 3), [125] = SDC_QDSD_PINGROUP(sdc2_cmd, SOUTH, 0x98000, 11, 3),
[126] = SDC_QDSD_PINGROUP(sdc2_data, 0x98000, 9, 0), [126] = SDC_QDSD_PINGROUP(sdc2_data, SOUTH, 0x98000, 9, 0),
}; };
static const struct msm_gpio_wakeirq_map sm7150_pdc_map[] = { static const struct msm_gpio_wakeirq_map sm7150_pdc_map[] = {
...@@ -1246,6 +1246,7 @@ static const struct of_device_id sm7150_tlmm_of_match[] = { ...@@ -1246,6 +1246,7 @@ static const struct of_device_id sm7150_tlmm_of_match[] = {
{ .compatible = "qcom,sm7150-tlmm", }, { .compatible = "qcom,sm7150-tlmm", },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, sm7150_tlmm_of_match);
static struct platform_driver sm7150_tlmm_driver = { static struct platform_driver sm7150_tlmm_driver = {
.driver = { .driver = {
......
...@@ -1202,6 +1202,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { ...@@ -1202,6 +1202,7 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm6150-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm6150-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 }, { .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 },
{ .compatible = "qcom,pm6350-gpio", .data = (void *) 9 }, { .compatible = "qcom,pm6350-gpio", .data = (void *) 9 },
{ .compatible = "qcom,pm6450-gpio", .data = (void *) 9 },
{ .compatible = "qcom,pm7250b-gpio", .data = (void *) 12 }, { .compatible = "qcom,pm7250b-gpio", .data = (void *) 12 },
{ .compatible = "qcom,pm7325-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm7325-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pm7550ba-gpio", .data = (void *) 8}, { .compatible = "qcom,pm7550ba-gpio", .data = (void *) 8},
...@@ -1234,10 +1235,12 @@ static const struct of_device_id pmic_gpio_of_match[] = { ...@@ -1234,10 +1235,12 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm8994-gpio", .data = (void *) 22 }, { .compatible = "qcom,pm8994-gpio", .data = (void *) 22 },
{ .compatible = "qcom,pm8998-gpio", .data = (void *) 26 }, { .compatible = "qcom,pm8998-gpio", .data = (void *) 26 },
{ .compatible = "qcom,pma8084-gpio", .data = (void *) 22 }, { .compatible = "qcom,pma8084-gpio", .data = (void *) 22 },
{ .compatible = "qcom,pmd8028-gpio", .data = (void *) 4 },
{ .compatible = "qcom,pmi632-gpio", .data = (void *) 8 }, { .compatible = "qcom,pmi632-gpio", .data = (void *) 8 },
{ .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 }, { .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 },
{ .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 }, { .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 },
{ .compatible = "qcom,pmih0108-gpio", .data = (void *) 18 },
{ .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 }, { .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 },
{ .compatible = "qcom,pmk8550-gpio", .data = (void *) 6 }, { .compatible = "qcom,pmk8550-gpio", .data = (void *) 6 },
{ .compatible = "qcom,pmm8155au-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmm8155au-gpio", .data = (void *) 10 },
...@@ -1253,6 +1256,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { ...@@ -1253,6 +1256,7 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pmx55-gpio", .data = (void *) 11 }, { .compatible = "qcom,pmx55-gpio", .data = (void *) 11 },
{ .compatible = "qcom,pmx65-gpio", .data = (void *) 16 }, { .compatible = "qcom,pmx65-gpio", .data = (void *) 16 },
{ .compatible = "qcom,pmx75-gpio", .data = (void *) 16 }, { .compatible = "qcom,pmx75-gpio", .data = (void *) 16 },
{ .compatible = "qcom,pmxr2230-gpio", .data = (void *) 12 },
{ }, { },
}; };
......
...@@ -1414,6 +1414,7 @@ static const struct of_device_id rtd1315e_pinctrl_of_match[] = { ...@@ -1414,6 +1414,7 @@ static const struct of_device_id rtd1315e_pinctrl_of_match[] = {
{ .compatible = "realtek,rtd1315e-pinctrl", }, { .compatible = "realtek,rtd1315e-pinctrl", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, rtd1315e_pinctrl_of_match);
static struct platform_driver rtd1315e_pinctrl_driver = { static struct platform_driver rtd1315e_pinctrl_driver = {
.driver = { .driver = {
......
...@@ -1584,6 +1584,7 @@ static const struct of_device_id rtd1319d_pinctrl_of_match[] = { ...@@ -1584,6 +1584,7 @@ static const struct of_device_id rtd1319d_pinctrl_of_match[] = {
{ .compatible = "realtek,rtd1319d-pinctrl", }, { .compatible = "realtek,rtd1319d-pinctrl", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, rtd1319d_pinctrl_of_match);
static struct platform_driver rtd1319d_pinctrl_driver = { static struct platform_driver rtd1319d_pinctrl_driver = {
.driver = { .driver = {
......
...@@ -75,10 +75,10 @@ ...@@ -75,10 +75,10 @@
#define GPSR0_9 F_(MSIOF5_SYNC, IP1SR0_7_4) #define GPSR0_9 F_(MSIOF5_SYNC, IP1SR0_7_4)
#define GPSR0_8 F_(MSIOF5_SS1, IP1SR0_3_0) #define GPSR0_8 F_(MSIOF5_SS1, IP1SR0_3_0)
#define GPSR0_7 F_(MSIOF5_SS2, IP0SR0_31_28) #define GPSR0_7 F_(MSIOF5_SS2, IP0SR0_31_28)
#define GPSR0_6 F_(IRQ0, IP0SR0_27_24) #define GPSR0_6 F_(IRQ0_A, IP0SR0_27_24)
#define GPSR0_5 F_(IRQ1, IP0SR0_23_20) #define GPSR0_5 F_(IRQ1_A, IP0SR0_23_20)
#define GPSR0_4 F_(IRQ2, IP0SR0_19_16) #define GPSR0_4 F_(IRQ2_A, IP0SR0_19_16)
#define GPSR0_3 F_(IRQ3, IP0SR0_15_12) #define GPSR0_3 F_(IRQ3_A, IP0SR0_15_12)
#define GPSR0_2 F_(GP0_02, IP0SR0_11_8) #define GPSR0_2 F_(GP0_02, IP0SR0_11_8)
#define GPSR0_1 F_(GP0_01, IP0SR0_7_4) #define GPSR0_1 F_(GP0_01, IP0SR0_7_4)
#define GPSR0_0 F_(GP0_00, IP0SR0_3_0) #define GPSR0_0 F_(GP0_00, IP0SR0_3_0)
...@@ -265,10 +265,10 @@ ...@@ -265,10 +265,10 @@
#define IP0SR0_3_0 F_(0, 0) FM(ERROROUTC_N_B) FM(TCLK2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_3_0 F_(0, 0) FM(ERROROUTC_N_B) FM(TCLK2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_7_4 F_(0, 0) FM(MSIOF3_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_7_4 F_(0, 0) FM(MSIOF3_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_11_8 F_(0, 0) FM(MSIOF3_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_11_8 F_(0, 0) FM(MSIOF3_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_15_12 FM(IRQ3) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_15_12 FM(IRQ3_A) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_19_16 FM(IRQ2) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_19_16 FM(IRQ2_A) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_23_20 FM(IRQ1) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_23_20 FM(IRQ1_A) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_27_24 FM(IRQ0) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_27_24 FM(IRQ0_A) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP0SR0_31_28 FM(MSIOF5_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_31_28 FM(MSIOF5_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
/* IP1SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ /* IP1SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
...@@ -672,16 +672,16 @@ static const u16 pinmux_data[] = { ...@@ -672,16 +672,16 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_GPSR(IP0SR0_11_8, MSIOF3_SS2), PINMUX_IPSR_GPSR(IP0SR0_11_8, MSIOF3_SS2),
PINMUX_IPSR_GPSR(IP0SR0_15_12, IRQ3), PINMUX_IPSR_GPSR(IP0SR0_15_12, IRQ3_A),
PINMUX_IPSR_GPSR(IP0SR0_15_12, MSIOF3_SCK), PINMUX_IPSR_GPSR(IP0SR0_15_12, MSIOF3_SCK),
PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2), PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2_A),
PINMUX_IPSR_GPSR(IP0SR0_19_16, MSIOF3_TXD), PINMUX_IPSR_GPSR(IP0SR0_19_16, MSIOF3_TXD),
PINMUX_IPSR_GPSR(IP0SR0_23_20, IRQ1), PINMUX_IPSR_GPSR(IP0SR0_23_20, IRQ1_A),
PINMUX_IPSR_GPSR(IP0SR0_23_20, MSIOF3_RXD), PINMUX_IPSR_GPSR(IP0SR0_23_20, MSIOF3_RXD),
PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0), PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0_A),
PINMUX_IPSR_GPSR(IP0SR0_27_24, MSIOF3_SYNC), PINMUX_IPSR_GPSR(IP0SR0_27_24, MSIOF3_SYNC),
PINMUX_IPSR_GPSR(IP0SR0_31_28, MSIOF5_SS2), PINMUX_IPSR_GPSR(IP0SR0_31_28, MSIOF5_SS2),
...@@ -1660,6 +1660,90 @@ static const unsigned int i2c3_mux[] = { ...@@ -1660,6 +1660,90 @@ static const unsigned int i2c3_mux[] = {
SDA3_MARK, SCL3_MARK, SDA3_MARK, SCL3_MARK,
}; };
/* - INTC-EX ---------------------------------------------------------------- */
static const unsigned int intc_ex_irq0_a_pins[] = {
/* IRQ0_A */
RCAR_GP_PIN(0, 6),
};
static const unsigned int intc_ex_irq0_a_mux[] = {
IRQ0_A_MARK,
};
static const unsigned int intc_ex_irq0_b_pins[] = {
/* IRQ0_B */
RCAR_GP_PIN(1, 20),
};
static const unsigned int intc_ex_irq0_b_mux[] = {
IRQ0_B_MARK,
};
static const unsigned int intc_ex_irq1_a_pins[] = {
/* IRQ1_A */
RCAR_GP_PIN(0, 5),
};
static const unsigned int intc_ex_irq1_a_mux[] = {
IRQ1_A_MARK,
};
static const unsigned int intc_ex_irq1_b_pins[] = {
/* IRQ1_B */
RCAR_GP_PIN(1, 21),
};
static const unsigned int intc_ex_irq1_b_mux[] = {
IRQ1_B_MARK,
};
static const unsigned int intc_ex_irq2_a_pins[] = {
/* IRQ2_A */
RCAR_GP_PIN(0, 4),
};
static const unsigned int intc_ex_irq2_a_mux[] = {
IRQ2_A_MARK,
};
static const unsigned int intc_ex_irq2_b_pins[] = {
/* IRQ2_B */
RCAR_GP_PIN(0, 13),
};
static const unsigned int intc_ex_irq2_b_mux[] = {
IRQ2_B_MARK,
};
static const unsigned int intc_ex_irq3_a_pins[] = {
/* IRQ3_A */
RCAR_GP_PIN(0, 3),
};
static const unsigned int intc_ex_irq3_a_mux[] = {
IRQ3_A_MARK,
};
static const unsigned int intc_ex_irq3_b_pins[] = {
/* IRQ3_B */
RCAR_GP_PIN(1, 23),
};
static const unsigned int intc_ex_irq3_b_mux[] = {
IRQ3_B_MARK,
};
static const unsigned int intc_ex_irq4_a_pins[] = {
/* IRQ4_A */
RCAR_GP_PIN(1, 17),
};
static const unsigned int intc_ex_irq4_a_mux[] = {
IRQ4_A_MARK,
};
static const unsigned int intc_ex_irq4_b_pins[] = {
/* IRQ4_B */
RCAR_GP_PIN(2, 3),
};
static const unsigned int intc_ex_irq4_b_mux[] = {
IRQ4_B_MARK,
};
static const unsigned int intc_ex_irq5_pins[] = {
/* IRQ5 */
RCAR_GP_PIN(2, 2),
};
static const unsigned int intc_ex_irq5_mux[] = {
IRQ5_MARK,
};
/* - MMC -------------------------------------------------------------------- */ /* - MMC -------------------------------------------------------------------- */
static const unsigned int mmc_data_pins[] = { static const unsigned int mmc_data_pins[] = {
/* MMC_SD_D[0:3], MMC_D[4:7] */ /* MMC_SD_D[0:3], MMC_D[4:7] */
...@@ -2416,6 +2500,18 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { ...@@ -2416,6 +2500,18 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(i2c2), SH_PFC_PIN_GROUP(i2c2),
SH_PFC_PIN_GROUP(i2c3), SH_PFC_PIN_GROUP(i2c3),
SH_PFC_PIN_GROUP(intc_ex_irq0_a),
SH_PFC_PIN_GROUP(intc_ex_irq0_b),
SH_PFC_PIN_GROUP(intc_ex_irq1_a),
SH_PFC_PIN_GROUP(intc_ex_irq1_b),
SH_PFC_PIN_GROUP(intc_ex_irq2_a),
SH_PFC_PIN_GROUP(intc_ex_irq2_b),
SH_PFC_PIN_GROUP(intc_ex_irq3_a),
SH_PFC_PIN_GROUP(intc_ex_irq3_b),
SH_PFC_PIN_GROUP(intc_ex_irq4_a),
SH_PFC_PIN_GROUP(intc_ex_irq4_b),
SH_PFC_PIN_GROUP(intc_ex_irq5),
BUS_DATA_PIN_GROUP(mmc_data, 1), BUS_DATA_PIN_GROUP(mmc_data, 1),
BUS_DATA_PIN_GROUP(mmc_data, 4), BUS_DATA_PIN_GROUP(mmc_data, 4),
BUS_DATA_PIN_GROUP(mmc_data, 8), BUS_DATA_PIN_GROUP(mmc_data, 8),
...@@ -2629,6 +2725,20 @@ static const char * const i2c3_groups[] = { ...@@ -2629,6 +2725,20 @@ static const char * const i2c3_groups[] = {
"i2c3", "i2c3",
}; };
static const char * const intc_ex_groups[] = {
"intc_ex_irq0_a",
"intc_ex_irq0_b",
"intc_ex_irq1_a",
"intc_ex_irq1_b",
"intc_ex_irq2_a",
"intc_ex_irq2_b",
"intc_ex_irq3_a",
"intc_ex_irq3_b",
"intc_ex_irq4_a",
"intc_ex_irq4_b",
"intc_ex_irq5",
};
static const char * const mmc_groups[] = { static const char * const mmc_groups[] = {
"mmc_data1", "mmc_data1",
"mmc_data4", "mmc_data4",
...@@ -2813,6 +2923,8 @@ static const struct sh_pfc_function pinmux_functions[] = { ...@@ -2813,6 +2923,8 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(i2c2), SH_PFC_FUNCTION(i2c2),
SH_PFC_FUNCTION(i2c3), SH_PFC_FUNCTION(i2c3),
SH_PFC_FUNCTION(intc_ex),
SH_PFC_FUNCTION(mmc), SH_PFC_FUNCTION(mmc),
SH_PFC_FUNCTION(msiof0), SH_PFC_FUNCTION(msiof0),
......
...@@ -892,6 +892,8 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps ...@@ -892,6 +892,8 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps
val = PVDD_1800; val = PVDD_1800;
break; break;
case 2500: case 2500:
if (!(caps & (PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1)))
return -EINVAL;
val = PVDD_2500; val = PVDD_2500;
break; break;
case 3300: case 3300:
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
// the Samsung pinctrl/gpiolib driver. It also includes the implementation of // the Samsung pinctrl/gpiolib driver. It also includes the implementation of
// external gpio and wakeup interrupt support. // external gpio and wakeup interrupt support.
#include <linux/clk.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
...@@ -61,6 +62,12 @@ static void exynos_irq_mask(struct irq_data *irqd) ...@@ -61,6 +62,12 @@ static void exynos_irq_mask(struct irq_data *irqd)
else else
reg_mask = our_chip->eint_mask + bank->eint_offset; reg_mask = our_chip->eint_mask + bank->eint_offset;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for masking IRQ\n");
return;
}
raw_spin_lock_irqsave(&bank->slock, flags); raw_spin_lock_irqsave(&bank->slock, flags);
mask = readl(bank->eint_base + reg_mask); mask = readl(bank->eint_base + reg_mask);
...@@ -68,6 +75,8 @@ static void exynos_irq_mask(struct irq_data *irqd) ...@@ -68,6 +75,8 @@ static void exynos_irq_mask(struct irq_data *irqd)
writel(mask, bank->eint_base + reg_mask); writel(mask, bank->eint_base + reg_mask);
raw_spin_unlock_irqrestore(&bank->slock, flags); raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->drvdata->pclk);
} }
static void exynos_irq_ack(struct irq_data *irqd) static void exynos_irq_ack(struct irq_data *irqd)
...@@ -82,7 +91,15 @@ static void exynos_irq_ack(struct irq_data *irqd) ...@@ -82,7 +91,15 @@ static void exynos_irq_ack(struct irq_data *irqd)
else else
reg_pend = our_chip->eint_pend + bank->eint_offset; reg_pend = our_chip->eint_pend + bank->eint_offset;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock to ack IRQ\n");
return;
}
writel(1 << irqd->hwirq, bank->eint_base + reg_pend); writel(1 << irqd->hwirq, bank->eint_base + reg_pend);
clk_disable(bank->drvdata->pclk);
} }
static void exynos_irq_unmask(struct irq_data *irqd) static void exynos_irq_unmask(struct irq_data *irqd)
...@@ -110,6 +127,12 @@ static void exynos_irq_unmask(struct irq_data *irqd) ...@@ -110,6 +127,12 @@ static void exynos_irq_unmask(struct irq_data *irqd)
else else
reg_mask = our_chip->eint_mask + bank->eint_offset; reg_mask = our_chip->eint_mask + bank->eint_offset;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for unmasking IRQ\n");
return;
}
raw_spin_lock_irqsave(&bank->slock, flags); raw_spin_lock_irqsave(&bank->slock, flags);
mask = readl(bank->eint_base + reg_mask); mask = readl(bank->eint_base + reg_mask);
...@@ -117,6 +140,8 @@ static void exynos_irq_unmask(struct irq_data *irqd) ...@@ -117,6 +140,8 @@ static void exynos_irq_unmask(struct irq_data *irqd)
writel(mask, bank->eint_base + reg_mask); writel(mask, bank->eint_base + reg_mask);
raw_spin_unlock_irqrestore(&bank->slock, flags); raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->drvdata->pclk);
} }
static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
...@@ -127,6 +152,7 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) ...@@ -127,6 +152,7 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
unsigned int con, trig_type; unsigned int con, trig_type;
unsigned long reg_con; unsigned long reg_con;
int ret;
switch (type) { switch (type) {
case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_RISING:
...@@ -159,11 +185,20 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) ...@@ -159,11 +185,20 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
else else
reg_con = our_chip->eint_con + bank->eint_offset; reg_con = our_chip->eint_con + bank->eint_offset;
ret = clk_enable(bank->drvdata->pclk);
if (ret) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for configuring IRQ type\n");
return ret;
}
con = readl(bank->eint_base + reg_con); con = readl(bank->eint_base + reg_con);
con &= ~(EXYNOS_EINT_CON_MASK << shift); con &= ~(EXYNOS_EINT_CON_MASK << shift);
con |= trig_type << shift; con |= trig_type << shift;
writel(con, bank->eint_base + reg_con); writel(con, bank->eint_base + reg_con);
clk_disable(bank->drvdata->pclk);
return 0; return 0;
} }
...@@ -200,6 +235,14 @@ static int exynos_irq_request_resources(struct irq_data *irqd) ...@@ -200,6 +235,14 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
ret = clk_enable(bank->drvdata->pclk);
if (ret) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for configuring pin %s-%lu\n",
bank->name, irqd->hwirq);
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags); raw_spin_lock_irqsave(&bank->slock, flags);
con = readl(bank->pctl_base + reg_con); con = readl(bank->pctl_base + reg_con);
...@@ -209,6 +252,8 @@ static int exynos_irq_request_resources(struct irq_data *irqd) ...@@ -209,6 +252,8 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
raw_spin_unlock_irqrestore(&bank->slock, flags); raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->drvdata->pclk);
return 0; return 0;
} }
...@@ -223,6 +268,13 @@ static void exynos_irq_release_resources(struct irq_data *irqd) ...@@ -223,6 +268,13 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for deconfiguring pin %s-%lu\n",
bank->name, irqd->hwirq);
return;
}
raw_spin_lock_irqsave(&bank->slock, flags); raw_spin_lock_irqsave(&bank->slock, flags);
con = readl(bank->pctl_base + reg_con); con = readl(bank->pctl_base + reg_con);
...@@ -232,6 +284,8 @@ static void exynos_irq_release_resources(struct irq_data *irqd) ...@@ -232,6 +284,8 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
raw_spin_unlock_irqrestore(&bank->slock, flags); raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->drvdata->pclk);
gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq); gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq);
} }
...@@ -281,10 +335,19 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) ...@@ -281,10 +335,19 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
unsigned int svc, group, pin; unsigned int svc, group, pin;
int ret; int ret;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for handling IRQ\n");
return IRQ_NONE;
}
if (bank->eint_con_offset) if (bank->eint_con_offset)
svc = readl(bank->eint_base + EXYNOSAUTO_SVC_OFFSET); svc = readl(bank->eint_base + EXYNOSAUTO_SVC_OFFSET);
else else
svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET); svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET);
clk_disable(bank->drvdata->pclk);
group = EXYNOS_SVC_GROUP(svc); group = EXYNOS_SVC_GROUP(svc);
pin = svc & EXYNOS_SVC_NUM_MASK; pin = svc & EXYNOS_SVC_NUM_MASK;
...@@ -563,6 +626,20 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc) ...@@ -563,6 +626,20 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
/*
* just enable the clock once here, to avoid an enable/disable dance for
* each bank.
*/
if (eintd->nr_banks) {
struct samsung_pin_bank *b = eintd->banks[0];
if (clk_enable(b->drvdata->pclk)) {
dev_err(b->gpio_chip.parent,
"unable to enable clock for pending IRQs\n");
return;
}
}
for (i = 0; i < eintd->nr_banks; ++i) { for (i = 0; i < eintd->nr_banks; ++i) {
struct samsung_pin_bank *b = eintd->banks[i]; struct samsung_pin_bank *b = eintd->banks[i];
pend = readl(b->eint_base + b->irq_chip->eint_pend pend = readl(b->eint_base + b->irq_chip->eint_pend
...@@ -572,6 +649,9 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc) ...@@ -572,6 +649,9 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
exynos_irq_demux_eint(pend & ~mask, b->irq_domain); exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
} }
if (eintd->nr_banks)
clk_disable(eintd->banks[0]->drvdata->pclk);
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }
...@@ -695,6 +775,12 @@ static void exynos_pinctrl_suspend_bank( ...@@ -695,6 +775,12 @@ static void exynos_pinctrl_suspend_bank(
struct exynos_eint_gpio_save *save = bank->soc_priv; struct exynos_eint_gpio_save *save = bank->soc_priv;
const void __iomem *regs = bank->eint_base; const void __iomem *regs = bank->eint_base;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for saving state\n");
return;
}
save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ bank->eint_offset); + bank->eint_offset);
save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
...@@ -704,6 +790,8 @@ static void exynos_pinctrl_suspend_bank( ...@@ -704,6 +790,8 @@ static void exynos_pinctrl_suspend_bank(
save->eint_mask = readl(regs + bank->irq_chip->eint_mask save->eint_mask = readl(regs + bank->irq_chip->eint_mask
+ bank->eint_offset); + bank->eint_offset);
clk_disable(bank->drvdata->pclk);
pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0); pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1); pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
...@@ -716,9 +804,17 @@ static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drv ...@@ -716,9 +804,17 @@ static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drv
struct exynos_eint_gpio_save *save = bank->soc_priv; struct exynos_eint_gpio_save *save = bank->soc_priv;
const void __iomem *regs = bank->eint_base; const void __iomem *regs = bank->eint_base;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for saving state\n");
return;
}
save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset); save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset);
save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset); save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset);
clk_disable(bank->drvdata->pclk);
pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask); pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
} }
...@@ -753,6 +849,12 @@ static void exynos_pinctrl_resume_bank( ...@@ -753,6 +849,12 @@ static void exynos_pinctrl_resume_bank(
struct exynos_eint_gpio_save *save = bank->soc_priv; struct exynos_eint_gpio_save *save = bank->soc_priv;
void __iomem *regs = bank->eint_base; void __iomem *regs = bank->eint_base;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for restoring state\n");
return;
}
pr_debug("%s: con %#010x => %#010x\n", bank->name, pr_debug("%s: con %#010x => %#010x\n", bank->name,
readl(regs + EXYNOS_GPIO_ECON_OFFSET readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ bank->eint_offset), save->eint_con); + bank->eint_offset), save->eint_con);
...@@ -774,6 +876,8 @@ static void exynos_pinctrl_resume_bank( ...@@ -774,6 +876,8 @@ static void exynos_pinctrl_resume_bank(
+ 2 * bank->eint_offset + 4); + 2 * bank->eint_offset + 4);
writel(save->eint_mask, regs + bank->irq_chip->eint_mask writel(save->eint_mask, regs + bank->irq_chip->eint_mask
+ bank->eint_offset); + bank->eint_offset);
clk_disable(bank->drvdata->pclk);
} }
static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvdata, static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvdata,
...@@ -782,6 +886,12 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd ...@@ -782,6 +886,12 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd
struct exynos_eint_gpio_save *save = bank->soc_priv; struct exynos_eint_gpio_save *save = bank->soc_priv;
void __iomem *regs = bank->eint_base; void __iomem *regs = bank->eint_base;
if (clk_enable(bank->drvdata->pclk)) {
dev_err(bank->gpio_chip.parent,
"unable to enable clock for restoring state\n");
return;
}
pr_debug("%s: con %#010x => %#010x\n", bank->name, pr_debug("%s: con %#010x => %#010x\n", bank->name,
readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con); readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con);
pr_debug("%s: mask %#010x => %#010x\n", bank->name, pr_debug("%s: mask %#010x => %#010x\n", bank->name,
...@@ -789,6 +899,8 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd ...@@ -789,6 +899,8 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd
writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset); writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset);
writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset); writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset);
clk_disable(bank->drvdata->pclk);
} }
void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
// but provides extensions to which platform specific implementation of the gpio // but provides extensions to which platform specific implementation of the gpio
// and wakeup interrupts can be hooked to. // and wakeup interrupts can be hooked to.
#include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -371,7 +372,7 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, ...@@ -371,7 +372,7 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
} }
/* enable or disable a pinmux function */ /* enable or disable a pinmux function */
static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, static int samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group) unsigned group)
{ {
struct samsung_pinctrl_drv_data *drvdata; struct samsung_pinctrl_drv_data *drvdata;
...@@ -382,6 +383,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -382,6 +383,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
unsigned long flags; unsigned long flags;
const struct samsung_pmx_func *func; const struct samsung_pmx_func *func;
const struct samsung_pin_group *grp; const struct samsung_pin_group *grp;
int ret;
drvdata = pinctrl_dev_get_drvdata(pctldev); drvdata = pinctrl_dev_get_drvdata(pctldev);
func = &drvdata->pmx_functions[selector]; func = &drvdata->pmx_functions[selector];
...@@ -397,6 +399,12 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -397,6 +399,12 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
reg += 4; reg += 4;
} }
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(pctldev->dev, "failed to enable clock for setup\n");
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags); raw_spin_lock_irqsave(&bank->slock, flags);
data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
...@@ -405,6 +413,10 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -405,6 +413,10 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
raw_spin_unlock_irqrestore(&bank->slock, flags); raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
return 0;
} }
/* enable a specified pinmux by writing to registers */ /* enable a specified pinmux by writing to registers */
...@@ -412,8 +424,7 @@ static int samsung_pinmux_set_mux(struct pinctrl_dev *pctldev, ...@@ -412,8 +424,7 @@ static int samsung_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned selector, unsigned selector,
unsigned group) unsigned group)
{ {
samsung_pinmux_setup(pctldev, selector, group); return samsung_pinmux_setup(pctldev, selector, group);
return 0;
} }
/* list of pinmux callbacks for the pinmux vertical in pinctrl core */ /* list of pinmux callbacks for the pinmux vertical in pinctrl core */
...@@ -436,6 +447,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -436,6 +447,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
u32 data, width, pin_offset, mask, shift; u32 data, width, pin_offset, mask, shift;
u32 cfg_value, cfg_reg; u32 cfg_value, cfg_reg;
unsigned long flags; unsigned long flags;
int ret;
drvdata = pinctrl_dev_get_drvdata(pctldev); drvdata = pinctrl_dev_get_drvdata(pctldev);
pin_to_reg_bank(drvdata, pin, &reg_base, &pin_offset, &bank); pin_to_reg_bank(drvdata, pin, &reg_base, &pin_offset, &bank);
...@@ -447,6 +459,12 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -447,6 +459,12 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
width = type->fld_width[cfg_type]; width = type->fld_width[cfg_type];
cfg_reg = type->reg_offset[cfg_type]; cfg_reg = type->reg_offset[cfg_type];
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev, "failed to enable clock\n");
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags); raw_spin_lock_irqsave(&bank->slock, flags);
mask = (1 << width) - 1; mask = (1 << width) - 1;
...@@ -466,6 +484,8 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -466,6 +484,8 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
raw_spin_unlock_irqrestore(&bank->slock, flags); raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
return 0; return 0;
} }
...@@ -555,11 +575,19 @@ static void samsung_gpio_set_value(struct gpio_chip *gc, ...@@ -555,11 +575,19 @@ static void samsung_gpio_set_value(struct gpio_chip *gc,
static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
{ {
struct samsung_pin_bank *bank = gpiochip_get_data(gc); struct samsung_pin_bank *bank = gpiochip_get_data(gc);
struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;
unsigned long flags; unsigned long flags;
if (clk_enable(drvdata->pclk)) {
dev_err(drvdata->dev, "failed to enable clock\n");
return;
}
raw_spin_lock_irqsave(&bank->slock, flags); raw_spin_lock_irqsave(&bank->slock, flags);
samsung_gpio_set_value(gc, offset, value); samsung_gpio_set_value(gc, offset, value);
raw_spin_unlock_irqrestore(&bank->slock, flags); raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
} }
/* gpiolib gpio_get callback function */ /* gpiolib gpio_get callback function */
...@@ -569,12 +597,23 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) ...@@ -569,12 +597,23 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
u32 data; u32 data;
struct samsung_pin_bank *bank = gpiochip_get_data(gc); struct samsung_pin_bank *bank = gpiochip_get_data(gc);
const struct samsung_pin_bank_type *type = bank->type; const struct samsung_pin_bank_type *type = bank->type;
struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;
int ret;
reg = bank->pctl_base + bank->pctl_offset; reg = bank->pctl_base + bank->pctl_offset;
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev, "failed to enable clock\n");
return ret;
}
data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);
data >>= offset; data >>= offset;
data &= 1; data &= 1;
clk_disable(drvdata->pclk);
return data; return data;
} }
...@@ -619,12 +658,22 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc, ...@@ -619,12 +658,22 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc,
static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset) static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{ {
struct samsung_pin_bank *bank = gpiochip_get_data(gc); struct samsung_pin_bank *bank = gpiochip_get_data(gc);
struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;
unsigned long flags; unsigned long flags;
int ret; int ret;
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev, "failed to enable clock\n");
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags); raw_spin_lock_irqsave(&bank->slock, flags);
ret = samsung_gpio_set_direction(gc, offset, true); ret = samsung_gpio_set_direction(gc, offset, true);
raw_spin_unlock_irqrestore(&bank->slock, flags); raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
return ret; return ret;
} }
...@@ -633,14 +682,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, ...@@ -633,14 +682,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
int value) int value)
{ {
struct samsung_pin_bank *bank = gpiochip_get_data(gc); struct samsung_pin_bank *bank = gpiochip_get_data(gc);
struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;
unsigned long flags; unsigned long flags;
int ret; int ret;
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev, "failed to enable clock\n");
return ret;
}
raw_spin_lock_irqsave(&bank->slock, flags); raw_spin_lock_irqsave(&bank->slock, flags);
samsung_gpio_set_value(gc, offset, value); samsung_gpio_set_value(gc, offset, value);
ret = samsung_gpio_set_direction(gc, offset, false); ret = samsung_gpio_set_direction(gc, offset, false);
raw_spin_unlock_irqrestore(&bank->slock, flags); raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(drvdata->pclk);
return ret; return ret;
} }
...@@ -1164,6 +1222,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) ...@@ -1164,6 +1222,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
} }
} }
drvdata->pclk = devm_clk_get_optional_prepared(dev, "pclk");
if (IS_ERR(drvdata->pclk)) {
ret = PTR_ERR(drvdata->pclk);
goto err_put_banks;
}
ret = samsung_pinctrl_register(pdev, drvdata); ret = samsung_pinctrl_register(pdev, drvdata);
if (ret) if (ret)
goto err_put_banks; goto err_put_banks;
...@@ -1202,6 +1266,13 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) ...@@ -1202,6 +1266,13 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev); struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);
int i; int i;
i = clk_enable(drvdata->pclk);
if (i) {
dev_err(drvdata->dev,
"failed to enable clock for saving state\n");
return i;
}
for (i = 0; i < drvdata->nr_banks; i++) { for (i = 0; i < drvdata->nr_banks; i++) {
struct samsung_pin_bank *bank = &drvdata->pin_banks[i]; struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
const void __iomem *reg = bank->pctl_base + bank->pctl_offset; const void __iomem *reg = bank->pctl_base + bank->pctl_offset;
...@@ -1231,6 +1302,8 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) ...@@ -1231,6 +1302,8 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
} }
} }
clk_disable(drvdata->pclk);
if (drvdata->suspend) if (drvdata->suspend)
drvdata->suspend(drvdata); drvdata->suspend(drvdata);
if (drvdata->retention_ctrl && drvdata->retention_ctrl->enable) if (drvdata->retention_ctrl && drvdata->retention_ctrl->enable)
...@@ -1250,8 +1323,20 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) ...@@ -1250,8 +1323,20 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
static int __maybe_unused samsung_pinctrl_resume(struct device *dev) static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
{ {
struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev); struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);
int ret;
int i; int i;
/*
* enable clock before the callback, as we don't want to have to deal
* with callback cleanup on clock failures.
*/
ret = clk_enable(drvdata->pclk);
if (ret) {
dev_err(drvdata->dev,
"failed to enable clock for restoring state\n");
return ret;
}
if (drvdata->resume) if (drvdata->resume)
drvdata->resume(drvdata); drvdata->resume(drvdata);
...@@ -1286,6 +1371,8 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev) ...@@ -1286,6 +1371,8 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
writel(bank->pm_save[type], reg + offs[type]); writel(bank->pm_save[type], reg + offs[type]);
} }
clk_disable(drvdata->pclk);
if (drvdata->retention_ctrl && drvdata->retention_ctrl->disable) if (drvdata->retention_ctrl && drvdata->retention_ctrl->disable)
drvdata->retention_ctrl->disable(drvdata); drvdata->retention_ctrl->disable(drvdata);
......
...@@ -274,6 +274,7 @@ struct samsung_pin_ctrl { ...@@ -274,6 +274,7 @@ struct samsung_pin_ctrl {
* through samsung_pinctrl_drv_data, not samsung_pin_bank). * through samsung_pinctrl_drv_data, not samsung_pin_bank).
* @dev: device instance representing the controller. * @dev: device instance representing the controller.
* @irq: interrpt number used by the controller to notify gpio interrupts. * @irq: interrpt number used by the controller to notify gpio interrupts.
* @pclk: optional bus clock if required for accessing registers
* @ctrl: pin controller instance managed by the driver. * @ctrl: pin controller instance managed by the driver.
* @pctl: pin controller descriptor registered with the pinctrl subsystem. * @pctl: pin controller descriptor registered with the pinctrl subsystem.
* @pctl_dev: cookie representing pinctrl device instance. * @pctl_dev: cookie representing pinctrl device instance.
...@@ -293,6 +294,7 @@ struct samsung_pinctrl_drv_data { ...@@ -293,6 +294,7 @@ struct samsung_pinctrl_drv_data {
void __iomem *virt_base; void __iomem *virt_base;
struct device *dev; struct device *dev;
int irq; int irq;
struct clk *pclk;
struct pinctrl_desc pctl; struct pinctrl_desc pctl;
struct pinctrl_dev *pctl_dev; struct pinctrl_dev *pctl_dev;
......
...@@ -169,7 +169,6 @@ static struct platform_driver sun9i_a80_r_pinctrl_driver = { ...@@ -169,7 +169,6 @@ static struct platform_driver sun9i_a80_r_pinctrl_driver = {
.probe = sun9i_a80_r_pinctrl_probe, .probe = sun9i_a80_r_pinctrl_probe,
.driver = { .driver = {
.name = "sun9i-a80-r-pinctrl", .name = "sun9i-a80-r-pinctrl",
.owner = THIS_MODULE,
.of_match_table = sun9i_a80_r_pinctrl_match, .of_match_table = sun9i_a80_r_pinctrl_match,
}, },
}; };
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Samsung's Exynos pinctrl bindings
*
* Copyright (c) 2016 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Author: Krzysztof Kozlowski <krzk@kernel.org>
*/
#ifndef __DT_BINDINGS_PINCTRL_SAMSUNG_H__
#define __DT_BINDINGS_PINCTRL_SAMSUNG_H__
/*
* These bindings are deprecated, because they do not match the actual
* concept of bindings but rather contain pure register values.
* Instead include the header in the DTS source directory.
*/
#warning "These bindings are deprecated. Instead use the header in the DTS source directory."
#define EXYNOS_PIN_PULL_NONE 0
#define EXYNOS_PIN_PULL_DOWN 1
#define EXYNOS_PIN_PULL_UP 3
#define S3C64XX_PIN_PULL_NONE 0
#define S3C64XX_PIN_PULL_DOWN 1
#define S3C64XX_PIN_PULL_UP 2
/* Pin function in power down mode */
#define EXYNOS_PIN_PDN_OUT0 0
#define EXYNOS_PIN_PDN_OUT1 1
#define EXYNOS_PIN_PDN_INPUT 2
#define EXYNOS_PIN_PDN_PREV 3
/* Drive strengths for Exynos3250, Exynos4 (all) and Exynos5250 */
#define EXYNOS4_PIN_DRV_LV1 0
#define EXYNOS4_PIN_DRV_LV2 2
#define EXYNOS4_PIN_DRV_LV3 1
#define EXYNOS4_PIN_DRV_LV4 3
/* Drive strengths for Exynos5260 */
#define EXYNOS5260_PIN_DRV_LV1 0
#define EXYNOS5260_PIN_DRV_LV2 1
#define EXYNOS5260_PIN_DRV_LV4 2
#define EXYNOS5260_PIN_DRV_LV6 3
/*
* Drive strengths for Exynos5410, Exynos542x, Exynos5800 and Exynos850 (except
* GPIO_HSI block)
*/
#define EXYNOS5420_PIN_DRV_LV1 0
#define EXYNOS5420_PIN_DRV_LV2 1
#define EXYNOS5420_PIN_DRV_LV3 2
#define EXYNOS5420_PIN_DRV_LV4 3
/* Drive strengths for Exynos5433 */
#define EXYNOS5433_PIN_DRV_FAST_SR1 0
#define EXYNOS5433_PIN_DRV_FAST_SR2 1
#define EXYNOS5433_PIN_DRV_FAST_SR3 2
#define EXYNOS5433_PIN_DRV_FAST_SR4 3
#define EXYNOS5433_PIN_DRV_FAST_SR5 4
#define EXYNOS5433_PIN_DRV_FAST_SR6 5
#define EXYNOS5433_PIN_DRV_SLOW_SR1 8
#define EXYNOS5433_PIN_DRV_SLOW_SR2 9
#define EXYNOS5433_PIN_DRV_SLOW_SR3 0xa
#define EXYNOS5433_PIN_DRV_SLOW_SR4 0xb
#define EXYNOS5433_PIN_DRV_SLOW_SR5 0xc
#define EXYNOS5433_PIN_DRV_SLOW_SR6 0xf
/* Drive strengths for Exynos850 GPIO_HSI block */
#define EXYNOS850_HSI_PIN_DRV_LV1 0 /* 1x */
#define EXYNOS850_HSI_PIN_DRV_LV1_5 1 /* 1.5x */
#define EXYNOS850_HSI_PIN_DRV_LV2 2 /* 2x */
#define EXYNOS850_HSI_PIN_DRV_LV2_5 3 /* 2.5x */
#define EXYNOS850_HSI_PIN_DRV_LV3 4 /* 3x */
#define EXYNOS850_HSI_PIN_DRV_LV4 5 /* 4x */
#define EXYNOS_PIN_FUNC_INPUT 0
#define EXYNOS_PIN_FUNC_OUTPUT 1
#define EXYNOS_PIN_FUNC_2 2
#define EXYNOS_PIN_FUNC_3 3
#define EXYNOS_PIN_FUNC_4 4
#define EXYNOS_PIN_FUNC_5 5
#define EXYNOS_PIN_FUNC_6 6
#define EXYNOS_PIN_FUNC_EINT 0xf
#define EXYNOS_PIN_FUNC_F EXYNOS_PIN_FUNC_EINT
/* Drive strengths for Exynos7 FSYS1 block */
#define EXYNOS7_FSYS1_PIN_DRV_LV1 0
#define EXYNOS7_FSYS1_PIN_DRV_LV2 4
#define EXYNOS7_FSYS1_PIN_DRV_LV3 2
#define EXYNOS7_FSYS1_PIN_DRV_LV4 6
#define EXYNOS7_FSYS1_PIN_DRV_LV5 1
#define EXYNOS7_FSYS1_PIN_DRV_LV6 5
#endif /* __DT_BINDINGS_PINCTRL_SAMSUNG_H__ */
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