diff options
30 files changed, 679 insertions, 390 deletions
diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml index bd72a326e6e0..d74cae9d4d65 100644 --- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml @@ -34,6 +34,9 @@ properties: the amount of cells must be specified as 2. See the below mentioned gpio binding representation for description of particular cells. + gpio-ranges: + maxItems: 1 + interrupt-controller: true interrupts: @@ -75,8 +78,8 @@ patternProperties: function: description: 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, - spi, tdm, uart, watchdog, wifi] + enum: [antsel, emmc, eth, i2c, i2s, ir, led, flash, pcie, pmic, pwm, + sd, spi, tdm, uart, watchdog, wifi] groups: description: @@ -93,11 +96,26 @@ patternProperties: - 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: + properties: + function: const: emmc then: properties: groups: - enum: [emmc, emmc_rst] + items: + enum: [emmc, emmc_rst] - if: properties: function: @@ -105,8 +123,9 @@ patternProperties: then: properties: groups: - enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw, - rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio] + items: + enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw, + rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio] - if: properties: function: @@ -123,10 +142,11 @@ patternProperties: then: properties: groups: - enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data, - i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws, - i2s1_out_data, i2s2_out_data, i2s3_out_data, - i2s4_out_data] + items: + enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data, + i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws, + i2s1_out_data, i2s2_out_data, i2s3_out_data, + i2s4_out_data] - if: properties: function: @@ -159,10 +179,11 @@ patternProperties: then: properties: groups: - enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken, - pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq, - pcie0_pad_perst, pcie1_pad_perst, pcie_pereset, - pcie_wake, pcie_clkreq] + items: + enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken, + pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq, + pcie0_pad_perst, pcie1_pad_perst, pcie_pereset, + pcie_wake, pcie_clkreq] - if: properties: function: @@ -178,11 +199,12 @@ patternProperties: then: properties: groups: - 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_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1, - pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3, - pwm_ch7_0, pwm_0, pwm_1] + items: + 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_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1, + pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3, + pwm_ch7_0, pwm_0, pwm_1] - if: properties: function: @@ -260,33 +282,34 @@ patternProperties: pins: description: An array of strings. Each string contains the name of a pin. - 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, - I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT, - I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1, - G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2, - G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6, - NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0, - MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1, - MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2, - MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3, - MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL, - PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS, - GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N, - PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2, - AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4, - PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA, - WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4, - WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG, - EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS, - EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N, - WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD, - UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD, - UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N, - PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, - GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK, - TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3, - WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6] + items: + 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, + I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT, + I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1, + G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2, + G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6, + NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0, + MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1, + MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2, + MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3, + MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL, + PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS, + GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N, + PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2, + AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4, + PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA, + WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4, + WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG, + EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS, + EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N, + WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD, + UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD, + UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N, + PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, + GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK, + TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3, + WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6] bias-disable: true diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml index 3f8ad07c7cfd..50846a2d09c8 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml @@ -24,6 +24,7 @@ properties: - qcom,pm6150-gpio - qcom,pm6150l-gpio - qcom,pm6350-gpio + - qcom,pm6450-gpio - qcom,pm7250b-gpio - qcom,pm7325-gpio - qcom,pm7550ba-gpio @@ -56,10 +57,12 @@ properties: - qcom,pma8084-gpio - qcom,pmc8180-gpio - qcom,pmc8180c-gpio + - qcom,pmd8028-gpio - qcom,pmi632-gpio - qcom,pmi8950-gpio - qcom,pmi8994-gpio - qcom,pmi8998-gpio + - qcom,pmih0108-gpio - qcom,pmk8350-gpio - qcom,pmk8550-gpio - qcom,pmm8155au-gpio @@ -72,6 +75,7 @@ properties: - qcom,pmx55-gpio - qcom,pmx65-gpio - qcom,pmx75-gpio + - qcom,pmxr2230-gpio - enum: - qcom,spmi-gpio @@ -141,6 +145,7 @@ allOf: - qcom,pm8005-gpio - qcom,pm8450-gpio - qcom,pm8916-gpio + - qcom,pmd8028-gpio - qcom,pmk8350-gpio - qcom,pmr735a-gpio - qcom,pmr735b-gpio @@ -198,6 +203,7 @@ allOf: contains: enum: - qcom,pm6350-gpio + - qcom,pm6450-gpio - qcom,pm8350c-gpio then: properties: @@ -261,6 +267,7 @@ allOf: - qcom,pmc8180c-gpio - qcom,pmp8074-gpio - qcom,pms405-gpio + - qcom,pmxr2230-gpio then: properties: gpio-line-names: @@ -305,6 +312,21 @@ allOf: compatible: contains: enum: + - qcom,pmih0108-gpio + then: + properties: + gpio-line-names: + minItems: 18 + maxItems: 18 + gpio-reserved-ranges: + minItems: 1 + maxItems: 9 + + - if: + properties: + compatible: + contains: + enum: - qcom,pmx65-gpio - qcom,pmx75-gpio then: @@ -402,6 +424,10 @@ patternProperties: $ref: "#/$defs/qcom-pmic-gpio-state" additionalProperties: false + "-hog(-[0-9]+)?$": + required: + - gpio-hog + $defs: qcom-pmic-gpio-state: type: object @@ -417,6 +443,7 @@ $defs: - gpio1-gpio10 for pm6150 - gpio1-gpio12 for pm6150l - gpio1-gpio9 for pm6350 + - gpio1-gpio9 for pm6450 - gpio1-gpio12 for pm7250b - gpio1-gpio10 for pm7325 - gpio1-gpio8 for pm7550ba @@ -447,9 +474,11 @@ $defs: - gpio1-gpio22 for pm8994 - gpio1-gpio26 for pm8998 - gpio1-gpio22 for pma8084 + - gpio1-gpio4 for pmd8028 - gpio1-gpio8 for pmi632 - gpio1-gpio2 for pmi8950 - gpio1-gpio10 for pmi8994 + - gpio1-gpio18 for pmih0108 - gpio1-gpio4 for pmk8350 - gpio1-gpio6 for pmk8550 - gpio1-gpio10 for pmm8155au @@ -464,6 +493,7 @@ $defs: and gpio11) - gpio1-gpio16 for pmx65 - gpio1-gpio16 for pmx75 + - gpio1-gpio12 for pmxr2230 items: pattern: "^gpio([0-9]+)$" @@ -545,6 +575,7 @@ $defs: examples: - | + #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> pm8921_gpio: gpio@150 { @@ -568,5 +599,12 @@ examples: power-source = <PM8921_GPIO_S4>; }; }; + + otg-hog { + gpio-hog; + gpios = <35 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "otg-gpio"; + }; }; ... diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.yaml index fe717d8d4798..43146709e204 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.yaml @@ -35,6 +35,7 @@ properties: - qcom,pm8038-mpp - qcom,pm8058-mpp - qcom,pm8821-mpp + - qcom,pm8901-mpp - qcom,pm8917-mpp - qcom,pm8921-mpp - const: qcom,ssbi-mpp diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml index bb675c8ec220..1b941b276b3f 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml @@ -72,40 +72,24 @@ $defs: description: Specify the alternative function to be configured for the specified pins. - enum: [ gpio, atest_char, atest_char0, atest_char1, atest_char2, - atest_char3, atest_usb0, atest_usb00, atest_usb01, atest_usb02, - atest_usb03, audio_ref, cam_mclk, cci_async, cci_i2c, - cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4, - cmu_rng0, cmu_rng1, cmu_rng2, cmu_rng3, coex_uart1, cri_trng, - cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1, - dp0_hot, gcc_gp1, gcc_gp2, gcc_gp3, host2wlan_sol, ibi_i3c, - jitter_bist, mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2, - mdp_vsync3, mi2s0_data0, mi2s0_data1, mi2s0_sck, mi2s0_ws, - mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, mi2s_mclk0, - mi2s_mclk1, nav_gpio0, nav_gpio1, nav_gpio2, pcie0_clk, - phase_flag0, phase_flag1, phase_flag10, phase_flag11, - phase_flag12, phase_flag13, phase_flag14, phase_flag15, - phase_flag16, phase_flag17, phase_flag18, phase_flag19, - phase_flag2, phase_flag20, phase_flag21, phase_flag22, - phase_flag23, phase_flag24, phase_flag25, phase_flag26, - phase_flag27, phase_flag28, phase_flag29, phase_flag3, - phase_flag30, phase_flag31, phase_flag4, phase_flag5, - 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 ] + enum: [ gpio, atest_char, atest_usb0, audio_ref_clk, cam_mclk, + cci_async_in0, cci_i2c, cci, cmu_rng, coex_uart1_rx, + coex_uart1_tx, cri_trng, dbg_out_clk, ddr_bist, + ddr_pxi0_test, ddr_pxi1_test, gcc_gp1_clk, gcc_gp2_clk, + gcc_gp3_clk, host2wlan_sol, ibi_i3c_qup0, ibi_i3c_qup1, + jitter_bist_ref, mdp_vsync0_out, mdp_vsync1_out, + mdp_vsync2_out, mdp_vsync3_out, mdp_vsync, nav, + pcie0_clk_req, phase_flag, pll_bist_sync, pll_clk_aux, + prng_rosc, qdss_cti_trig0, qdss_cti_trig1, qdss_gpio, + qlink0_enable, qlink0_request, qlink0_wmss_reset, + qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, + qup1_se0, qup1_se1, qup1_se2, qup1_se2_l2, qup1_se3, + qup1_se4, sd_write_protect, tb_trig_sdc1, tb_trig_sdc2, + tgu_ch0_trigout, tgu_ch1_trigout, tgu_ch2_trigout, + tgu_ch3_trigout, tmess_prng, tsense_pwm1_out, + tsense_pwm2_out, uim0, uim1, usb0_hs_ac, usb0_phy_ps, + vfr_0_mira, vfr_0_mirb, vfr_1, vsense_trigger_mirnat, + wlan1_adc_dtest0, wlan1_adc_dtest1 ] required: - pins diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml index 118549c25976..242dd13c276b 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml @@ -73,6 +73,13 @@ properties: minItems: 1 maxItems: 2 + clocks: + maxItems: 1 + + clock-names: + items: + - const: pclk + wakeup-interrupt-controller: $ref: samsung,pinctrl-wakeup-interrupt.yaml @@ -124,6 +131,20 @@ allOf: properties: compatible: contains: + const: google,gs101-pinctrl + then: + required: + - clocks + - clock-names + else: + properties: + clocks: false + clock-names: false + + - if: + properties: + compatible: + contains: const: samsung,exynos5433-pinctrl then: properties: diff --git a/MAINTAINERS b/MAINTAINERS index 35ab336a6093..bce682699156 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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 F: Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml F: drivers/pinctrl/samsung/ -F: include/dt-bindings/pinctrl/samsung.h PIN CONTROLLER - SINGLE M: Tony Lindgren <tony@atomide.com> diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 1489191a213f..7178a38475cc 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -244,6 +244,10 @@ static const char * const irq_type_names[] = { [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) { return readl(pc->base + reg); @@ -926,6 +930,13 @@ static int bcm2835_pmx_free(struct pinctrl_dev *pctldev, unsigned offset) { 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 */ 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, struct pinctrl_gpio_range *range, unsigned offset) { - struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); - - /* disable by setting to GPIO_IN */ - bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN); + bcm2835_pmx_free(pctldev, offset); } static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, @@ -1003,8 +1011,27 @@ static const struct pinmux_ops bcm2835_pmx_ops = { static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { - /* No way to read back config in HW */ - return -ENOTSUPP; + 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 0; } static void bcm2835_pull_config_set(struct bcm2835_pinctrl *pc, @@ -1079,6 +1106,45 @@ static const struct pinconf_ops bcm2835_pinconf_ops = { .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, unsigned int pin, unsigned int arg) { @@ -1146,7 +1212,7 @@ static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev, static const struct pinconf_ops bcm2711_pinconf_ops = { .is_generic = true, - .pin_config_get = bcm2835_pinconf_get, + .pin_config_get = bcm2711_pinconf_get, .pin_config_set = bcm2711_pinconf_set, }; @@ -1361,6 +1427,9 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) goto out_remove; } + dev_info(dev, "GPIO_OUT persistence: %s\n", + persist_gpio_outputs ? "yes" : "no"); + return 0; out_remove: diff --git a/drivers/pinctrl/freescale/pinctrl-imx8ulp.c b/drivers/pinctrl/freescale/pinctrl-imx8ulp.c index 2e86ca9fc7ac..5632c7285147 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8ulp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8ulp.c @@ -252,6 +252,7 @@ static const struct of_device_id imx8ulp_pinctrl_of_match[] = { { .compatible = "fsl,imx8ulp-iomuxc1", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8ulp_pinctrl_of_match); static int imx8ulp_pinctrl_probe(struct platform_device *pdev) { diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c index f6ec41eb6e0c..72609cf74760 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1086,6 +1086,7 @@ static const struct of_device_id mt6765_pinctrl_of_match[] = { { .compatible = "mediatek,mt6765-pinctrl", .data = &mt6765_data }, { } }; +MODULE_DEVICE_TABLE(of, mt6765_pinctrl_of_match); static struct platform_driver mt6765_pinctrl_driver = { .driver = { diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6779.c b/drivers/pinctrl/mediatek/pinctrl-mt6779.c index 62d4f5ad6737..591905e4132a 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6779.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6779.c @@ -762,6 +762,7 @@ static const struct of_device_id mt6779_pinctrl_of_match[] = { { .compatible = "mediatek,mt6779-pinctrl", .data = &mt6779_data }, { } }; +MODULE_DEVICE_TABLE(of, mt6779_pinctrl_of_match); static struct platform_driver mt6779_pinctrl_driver = { .driver = { diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index c34719b7506d..4c4ada06423d 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -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, int *funcsize, const char *name) { - int i = 0; - if (*funcsize <= 0) return -EOVERFLOW; @@ -847,7 +845,6 @@ static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs, return -EEXIST; } funcs++; - i++; } /* append new unique function */ diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index cada5d18ffae..80de389199bd 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -88,7 +88,7 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev, seq_puts(s, items[i].display); /* Print unit if available */ if (items[i].has_arg) { - seq_printf(s, " (%u", + seq_printf(s, " (0x%x", pinconf_to_config_argument(config)); if (items[i].format) seq_printf(s, " %s)", items[i].format); diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index 4edd371c469f..b5e1c467625b 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -1,28 +1,29 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Awinic AW9523B i2c pin controller driver - * Copyright (c) 2020, AngeloGioacchino Del Regno - * <angelogioacchino.delregno@somainline.org> + * Copyright (c) 2020, AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org> */ #include <linux/bitfield.h> +#include <linux/errno.h> #include <linux/gpio/consumer.h> #include <linux/gpio/driver.h> #include <linux/i2c.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/mutex.h> #include <linux/module.h> -#include <linux/pinctrl/pinconf.h> -#include <linux/pinctrl/pinctrl.h> -#include <linux/pinctrl/pinmux.h> -#include <linux/pinctrl/pinconf-generic.h> +#include <linux/mutex.h> #include <linux/property.h> #include <linux/regmap.h> #include <linux/regulator/consumer.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_NUM_PORTS 2 #define AW9523_PINS_PER_PORT 8 @@ -56,28 +57,14 @@ /* * struct aw9523_irq - Interrupt controller structure * @lock: mutex locking for the irq bus - * @irqchip: structure holding irqchip params * @cached_gpio: stores the previous gpio status for bit comparison */ struct aw9523_irq { struct mutex lock; - struct irq_chip *irqchip; 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 * @dev: device handle * @regmap: regmap handle for current device @@ -151,23 +138,16 @@ static const struct pinctrl_ops aw9523_pinctrl_ops = { }; static const char * const gpio_pwm_groups[] = { - "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", - "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", - "gpio12", "gpio13", "gpio14", "gpio15" + "gpio0", "gpio1", "gpio2", "gpio3", /* 0-3 */ + "gpio4", "gpio5", "gpio6", "gpio7", /* 4-7 */ + "gpio8", "gpio9", "gpio10", "gpio11", /* 8-11 */ + "gpio12", "gpio13", "gpio14", "gpio15", /* 11-15 */ }; /* Warning: Do NOT reorder this array */ -static const struct aw9523_pinmux aw9523_pmx[] = { - { - .name = "pwm", - .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 const struct pinfunction aw9523_pmx[] = { + PINCTRL_PINFUNCTION("pwm", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)), + PINCTRL_PINFUNCTION("gpio", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)), }; 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, static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel, const char * const **groups, - unsigned int * const num_groups) + unsigned int * const ngroups) { - *groups = aw9523_pmx[sel].grps; - *num_groups = aw9523_pmx[sel].num_grps; + *groups = aw9523_pmx[sel].groups; + *ngroups = aw9523_pmx[sel].ngroups; return 0; } @@ -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); break; default: - return -EOPNOTSUPP; + return -ENOTSUPP; } *r = reg; @@ -290,7 +270,7 @@ static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin, val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val); break; default: - return -EOPNOTSUPP; + return -ENOTSUPP; } if (val < 1) return -EINVAL; @@ -344,7 +324,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, case PIN_CONFIG_DRIVE_OPEN_DRAIN: /* Open-Drain is supported only on port 0 */ if (pin >= AW9523_PINS_PER_PORT) { - rc = -EOPNOTSUPP; + rc = -ENOTSUPP; goto end; } mask = AW9523_GCR_GPOMD_MASK; @@ -361,7 +341,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, val = AW9523_GCR_GPOMD_MASK; break; default: - rc = -EOPNOTSUPP; + rc = -ENOTSUPP; goto end; } @@ -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 */ -static int aw9523_get_port_state(struct regmap *regmap, u8 pin, - u8 regbit, unsigned int *state) +static int aw9523_get_port_state(struct regmap *regmap, u8 pin, u8 regbit, + unsigned int *state) { u8 reg; int dir; @@ -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) { 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, - AW9523_REG_INTR_DIS(d->hwirq), + regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq), 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) static void aw9523_irq_unmask(struct irq_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)); - regmap_update_bits(awi->regmap, - AW9523_REG_INTR_DIS(d->hwirq), + gpiochip_enable_irq(&awi->gpio, hwirq); + regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq), BIT(n), 0); } @@ -622,7 +602,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip, mutex_lock(&awi->i2c_lock); /* Port 0 (gpio 0-7) */ - m = *mask & U8_MAX; + m = *mask; if (m) { ret = _aw9523_gpio_get_multiple(awi, 0, &state, m); if (ret) @@ -631,7 +611,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip, *bits = state; /* Port 1 (gpio 8-15) */ - m = (*mask >> 8) & U8_MAX; + m = *mask >> 8; if (m) { ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT, &state, m); @@ -652,29 +632,26 @@ static void aw9523_gpio_set_multiple(struct gpio_chip *chip, struct aw9523 *awi = gpiochip_get_data(chip); u8 mask_lo, mask_hi, bits_lo, bits_hi; 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); if (mask_hi) { 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); - if (ret) { + if (ret) dev_warn(awi->dev, "Cannot write port1 out level\n"); - goto out; - } } if (mask_lo) { reg = AW9523_REG_OUT_STATE(0); - bits_lo = *bits & U8_MAX; ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo); if (ret) dev_warn(awi->dev, "Cannot write port0 out level\n"); } -out: mutex_unlock(&awi->i2c_lock); } @@ -827,29 +804,21 @@ static int aw9523_init_irq(struct aw9523 *awi, int irq) { struct device *dev = awi->dev; struct gpio_irq_chip *girq; - struct irq_chip *irqchip; int ret; if (!device_property_read_bool(dev, "interrupt-controller")) return 0; - irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL); - if (!irqchip) - return -ENOMEM; - awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL); if (!awi->irq) return -ENOMEM; - awi->irq->irqchip = irqchip; mutex_init(&awi->irq->lock); ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func, IRQF_ONESHOT, dev_name(dev), awi); - if (ret) { - dev_err(dev, "Failed to request irq %d\n", irq); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq); girq = &awi->gpio.irq; gpio_irq_chip_set_chip(girq, &aw9523_irq_chip); @@ -1015,8 +984,7 @@ static int aw9523_probe(struct i2c_client *client) } mutex_init(&awi->i2c_lock); - lockdep_set_subclass(&awi->i2c_lock, - i2c_adapter_depth(client->adapter)); + lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter)); pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); if (!pdesc) @@ -1046,8 +1014,7 @@ static int aw9523_probe(struct i2c_client *client) awi->pctl = devm_pinctrl_register(dev, pdesc, awi); if (IS_ERR(awi->pctl)) { - ret = PTR_ERR(awi->pctl); - dev_err(dev, "Cannot register pinctrl: %d", ret); + ret = dev_err_probe(dev, PTR_ERR(awi->pctl), "Cannot register pinctrl"); goto err_disable_vregs; } @@ -1067,10 +1034,6 @@ err_disable_vregs: static void aw9523_remove(struct i2c_client *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 @@ -1082,10 +1045,8 @@ static void aw9523_remove(struct i2c_client *client) regulator_disable(awi->vio_vreg); } else { mutex_lock(&awi->i2c_lock); - ret = aw9523_hw_init(awi); + aw9523_hw_init(awi); mutex_unlock(&awi->i2c_lock); - if (ret) - return; } mutex_destroy(&awi->i2c_lock); diff --git a/drivers/pinctrl/pinctrl-loongson2.c b/drivers/pinctrl/pinctrl-loongson2.c index a72ffeca26fb..4d4fbeadafb7 100644 --- a/drivers/pinctrl/pinctrl-loongson2.c +++ b/drivers/pinctrl/pinctrl-loongson2.c @@ -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 = { .probe = loongson2_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-max77620.c b/drivers/pinctrl/pinctrl-max77620.c index ab723ab4ec1d..d236daa7c13e 100644 --- a/drivers/pinctrl/pinctrl-max77620.c +++ b/drivers/pinctrl/pinctrl-max77620.c @@ -88,7 +88,6 @@ struct max77620_pingroup { struct max77620_pin_info { enum max77620_pin_ppdrv drv_type; - int pull_config; }; struct max77620_fps_config { @@ -104,7 +103,6 @@ struct max77620_pctrl_info { struct device *dev; struct pinctrl_dev *pctl; struct regmap *rmap; - int pins_current_opt[MAX77620_GPIO_NR]; const struct max77620_pin_function *functions; unsigned int num_functions; const struct max77620_pingroup *pin_groups; diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 19cc0db771a5..a798f31d6954 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -81,8 +81,6 @@ struct pcs_conf_type { * @name: pinctrl function name * @vals: register and 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 * @nconfs: number of pin configurations available * @node: list node @@ -91,8 +89,6 @@ struct pcs_function { const char *name; struct pcs_func_vals *vals; unsigned nvals; - const char **pgnames; - int npgnames; struct pcs_conf_vals *conf; int nconfs; struct list_head node; @@ -554,21 +550,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned offset = 0, shift = 0, i, data, ret; u32 arg; int j; + enum pin_config_param param; ret = pcs_get_function(pctldev, pin, &func); if (ret) return ret; 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++) { - if (pinconf_to_config_param(configs[j]) - != func->conf[i].param) + if (param != func->conf[i].param) continue; offset = pin * (pcs->width / BITS_PER_BYTE); data = pcs->read(pcs->base + offset); arg = pinconf_to_config_argument(configs[j]); - switch (func->conf[i].param) { + switch (param) { /* 2 parameters */ case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_DRIVE_STRENGTH: @@ -580,9 +585,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, data |= (arg << shift) & func->conf[i].mask; break; /* 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_UP: if (arg) @@ -1625,7 +1627,6 @@ static int pcs_irq_init_chained_handler(struct pcs_device *pcs, return 0; } -#ifdef CONFIG_PM static int pcs_save_context(struct pcs_device *pcs) { int i, mux_bytes; @@ -1690,14 +1691,9 @@ static void pcs_restore_context(struct pcs_device *pcs) } } -static int pinctrl_single_suspend(struct platform_device *pdev, - pm_message_t state) +static int pinctrl_single_suspend_noirq(struct device *dev) { - struct pcs_device *pcs; - - pcs = platform_get_drvdata(pdev); - if (!pcs) - return -EINVAL; + struct pcs_device *pcs = dev_get_drvdata(dev); if (pcs->flags & PCS_CONTEXT_LOSS_OFF) { int ret; @@ -1710,20 +1706,19 @@ static int pinctrl_single_suspend(struct platform_device *pdev, 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; - - pcs = platform_get_drvdata(pdev); - if (!pcs) - return -EINVAL; + struct pcs_device *pcs = dev_get_drvdata(dev); if (pcs->flags & PCS_CONTEXT_LOSS_OFF) pcs_restore_context(pcs); 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 @@ -1986,11 +1981,8 @@ static struct platform_driver pcs_driver = { .driver = { .name = DRIVER_NAME, .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); diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index d924207d629b..addba55334d9 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -578,6 +578,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what) return 0; } +DEFINE_SHOW_ATTRIBUTE(pinmux_functions); 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; } +DEFINE_SHOW_ATTRIBUTE(pinmux_pins); 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, setting->data.mux.func); } -DEFINE_SHOW_ATTRIBUTE(pinmux_functions); -DEFINE_SHOW_ATTRIBUTE(pinmux_pins); +static int pinmux_select_show(struct seq_file *s, void *unused) +{ + 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) { struct seq_file *sfile = file->private_data; @@ -749,19 +753,7 @@ exit_free_buf: return ret; } - -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, -}; +DEFINE_SHOW_STORE_ATTRIBUTE(pinmux_select); void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev) @@ -771,7 +763,7 @@ void pinmux_init_device_debugfs(struct dentry *devroot, debugfs_create_file("pinmux-pins", 0444, devroot, pctldev, &pinmux_pins_fops); debugfs_create_file("pinmux-select", 0200, - devroot, pctldev, &pinmux_select_ops); + devroot, pctldev, &pinmux_select_fops); } #endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c index d2568dab8c78..9e34b92ff5f2 100644 --- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c +++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c @@ -32,7 +32,7 @@ static const char *pxa2xx_pctrl_get_group_name(struct pinctrl_dev *pctldev, unsigned tgroup) { 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; } @@ -43,10 +43,10 @@ static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned *num_pins) { 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; - *num_pins = 1; + *pins = group->pins; + *num_pins = group->npins; return 0; } @@ -109,7 +109,7 @@ static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev, unsigned function) { 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; } @@ -127,7 +127,7 @@ static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev, unsigned * const num_groups) { 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; *num_groups = pf->ngroups; @@ -139,20 +139,18 @@ static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function, unsigned tgroup) { 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; - int pin, shift; unsigned long flags; void __iomem *gafr, *gpdr; + int shift; u32 val; - - df = pxa_desc_by_func_group(pctl, group->name, - (pctl->functions + function)->name); + df = pxa_desc_by_func_group(pctl, g->name, (pctl->functions + function)->name); if (!df) return -EINVAL; - pin = group->pin; gafr = pctl->base_gafr[pin / 16]; gpdr = pctl->base_gpdr[pin / 32]; shift = (pin % 16) << 1; @@ -186,9 +184,9 @@ static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev, unsigned long *config) { 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 pin = g->pin; void __iomem *pgsr = pctl->base_pgsr[pin / 32]; u32 val; @@ -208,9 +206,9 @@ static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev, unsigned num_configs) { 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 pin = g->pin; void __iomem *pgsr = pctl->base_pgsr[pin / 32]; int i, is_set = 0; u32 val; @@ -249,11 +247,11 @@ static struct pinctrl_desc pxa2xx_pinctrl_desc = { .pmxops = &pxa2xx_pinmux_ops, }; -static const struct pxa_pinctrl_function * -pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname, - const struct pxa_pinctrl_function *functions) +static const struct pinfunction *pxa2xx_find_function(struct pxa_pinctrl *pctl, + const char *fname, + const struct pinfunction *functions) { - const struct pxa_pinctrl_function *func; + const struct pinfunction *func; for (func = functions; func->name; func++) if (!strcmp(fname, func->name)) @@ -264,8 +262,8 @@ pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname, static int pxa2xx_build_functions(struct pxa_pinctrl *pctl) { + struct pinfunction *functions; int i; - struct pxa_pinctrl_function *functions; struct pxa_desc_function *df; /* @@ -296,9 +294,9 @@ static int pxa2xx_build_functions(struct pxa_pinctrl *pctl) static int pxa2xx_build_groups(struct pxa_pinctrl *pctl) { int i, j, ngroups; - struct pxa_pinctrl_function *func; struct pxa_desc_function *df; - char **gtmp; + struct pinfunction *func; + const char **gtmp; gtmp = devm_kmalloc_array(pctl->dev, pctl->npins, sizeof(*gtmp), GFP_KERNEL); @@ -316,13 +314,9 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl) pctl->ppins[j].pin.name; func = pctl->functions + i; func->ngroups = ngroups; - func->groups = - devm_kmalloc_array(pctl->dev, ngroups, - sizeof(char *), GFP_KERNEL); + func->groups = devm_kmemdup(pctl->dev, gtmp, ngroups * sizeof(*gtmp), GFP_KERNEL); if (!func->groups) return -ENOMEM; - - memcpy(func->groups, gtmp, ngroups * sizeof(*gtmp)); } devm_kfree(pctl->dev, gtmp); @@ -332,8 +326,8 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl) static int pxa2xx_build_state(struct pxa_pinctrl *pctl, const struct pxa_desc_pin *ppins, int npins) { - struct pxa_pinctrl_group *group; struct pinctrl_pin_desc *pins; + struct pingroup *group; int ret, i; pctl->npins = npins; @@ -357,7 +351,8 @@ static int pxa2xx_build_state(struct pxa_pinctrl *pctl, for (i = 0; i < npins; i++) { group = pctl->groups + i; 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); diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.h b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h index d86d47dbbc94..b292b79efdf8 100644 --- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.h +++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h @@ -52,17 +52,6 @@ struct pxa_desc_pin { 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 { spinlock_t lock; void __iomem **base_gafr; @@ -74,9 +63,9 @@ struct pxa_pinctrl { unsigned npins; const struct pxa_desc_pin *ppins; unsigned ngroups; - struct pxa_pinctrl_group *groups; + struct pingroup *groups; unsigned nfuncs; - struct pxa_pinctrl_function *functions; + struct pinfunction *functions; char *name; }; diff --git a/drivers/pinctrl/qcom/pinctrl-sm7150.c b/drivers/pinctrl/qcom/pinctrl-sm7150.c index c25357ca1963..095a1ca75849 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm7150.c +++ b/drivers/pinctrl/qcom/pinctrl-sm7150.c @@ -65,7 +65,7 @@ enum { .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, \ pg_name##_pins, \ @@ -75,7 +75,7 @@ enum { .intr_cfg_reg = 0, \ .intr_status_reg = 0, \ .intr_target_reg = 0, \ - .tile = SOUTH, \ + .tile = _tile, \ .mux_bit = -1, \ .pull_bit = pull, \ .drv_bit = drv, \ @@ -101,7 +101,7 @@ enum { .intr_cfg_reg = 0, \ .intr_status_reg = 0, \ .intr_target_reg = 0, \ - .tile = SOUTH, \ + .tile = WEST, \ .mux_bit = -1, \ .pull_bit = 3, \ .drv_bit = 0, \ @@ -1199,13 +1199,13 @@ static const struct msm_pingroup sm7150_groups[] = { [117] = PINGROUP(117, NORTH, _, _, _, _, _, _, _, _, _), [118] = PINGROUP(118, NORTH, _, _, _, _, _, _, _, _, _), [119] = UFS_RESET(ufs_reset, 0x9f000), - [120] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x9a000, 15, 0), - [121] = SDC_QDSD_PINGROUP(sdc1_clk, 0x9a000, 13, 6), - [122] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x9a000, 11, 3), - [123] = SDC_QDSD_PINGROUP(sdc1_data, 0x9a000, 9, 0), - [124] = SDC_QDSD_PINGROUP(sdc2_clk, 0x98000, 14, 6), - [125] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x98000, 11, 3), - [126] = SDC_QDSD_PINGROUP(sdc2_data, 0x98000, 9, 0), + [120] = SDC_QDSD_PINGROUP(sdc1_rclk, WEST, 0x9a000, 15, 0), + [121] = SDC_QDSD_PINGROUP(sdc1_clk, WEST, 0x9a000, 13, 6), + [122] = SDC_QDSD_PINGROUP(sdc1_cmd, WEST, 0x9a000, 11, 3), + [123] = SDC_QDSD_PINGROUP(sdc1_data, WEST, 0x9a000, 9, 0), + [124] = SDC_QDSD_PINGROUP(sdc2_clk, SOUTH, 0x98000, 14, 6), + [125] = SDC_QDSD_PINGROUP(sdc2_cmd, SOUTH, 0x98000, 11, 3), + [126] = SDC_QDSD_PINGROUP(sdc2_data, SOUTH, 0x98000, 9, 0), }; static const struct msm_gpio_wakeirq_map sm7150_pdc_map[] = { @@ -1246,6 +1246,7 @@ static const struct of_device_id sm7150_tlmm_of_match[] = { { .compatible = "qcom,sm7150-tlmm", }, { }, }; +MODULE_DEVICE_TABLE(of, sm7150_tlmm_of_match); static struct platform_driver sm7150_tlmm_driver = { .driver = { diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index f4e2c88a7c82..4e80c7204e5f 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1202,6 +1202,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm6150-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 }, { .compatible = "qcom,pm6350-gpio", .data = (void *) 9 }, + { .compatible = "qcom,pm6450-gpio", .data = (void *) 9 }, { .compatible = "qcom,pm7250b-gpio", .data = (void *) 12 }, { .compatible = "qcom,pm7325-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm7550ba-gpio", .data = (void *) 8}, @@ -1234,10 +1235,12 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm8994-gpio", .data = (void *) 22 }, { .compatible = "qcom,pm8998-gpio", .data = (void *) 26 }, { .compatible = "qcom,pma8084-gpio", .data = (void *) 22 }, + { .compatible = "qcom,pmd8028-gpio", .data = (void *) 4 }, { .compatible = "qcom,pmi632-gpio", .data = (void *) 8 }, { .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 }, { .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 }, + { .compatible = "qcom,pmih0108-gpio", .data = (void *) 18 }, { .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 }, { .compatible = "qcom,pmk8550-gpio", .data = (void *) 6 }, { .compatible = "qcom,pmm8155au-gpio", .data = (void *) 10 }, @@ -1253,6 +1256,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pmx55-gpio", .data = (void *) 11 }, { .compatible = "qcom,pmx65-gpio", .data = (void *) 16 }, { .compatible = "qcom,pmx75-gpio", .data = (void *) 16 }, + { .compatible = "qcom,pmxr2230-gpio", .data = (void *) 12 }, { }, }; diff --git a/drivers/pinctrl/realtek/pinctrl-rtd1315e.c b/drivers/pinctrl/realtek/pinctrl-rtd1315e.c index 10afc736a52b..86f919122bed 100644 --- a/drivers/pinctrl/realtek/pinctrl-rtd1315e.c +++ b/drivers/pinctrl/realtek/pinctrl-rtd1315e.c @@ -1414,6 +1414,7 @@ static const struct of_device_id rtd1315e_pinctrl_of_match[] = { { .compatible = "realtek,rtd1315e-pinctrl", }, {}, }; +MODULE_DEVICE_TABLE(of, rtd1315e_pinctrl_of_match); static struct platform_driver rtd1315e_pinctrl_driver = { .driver = { diff --git a/drivers/pinctrl/realtek/pinctrl-rtd1319d.c b/drivers/pinctrl/realtek/pinctrl-rtd1319d.c index b1a654ac30dc..474c337d2d05 100644 --- a/drivers/pinctrl/realtek/pinctrl-rtd1319d.c +++ b/drivers/pinctrl/realtek/pinctrl-rtd1319d.c @@ -1584,6 +1584,7 @@ static const struct of_device_id rtd1319d_pinctrl_of_match[] = { { .compatible = "realtek,rtd1319d-pinctrl", }, {}, }; +MODULE_DEVICE_TABLE(of, rtd1319d_pinctrl_of_match); static struct platform_driver rtd1319d_pinctrl_driver = { .driver = { diff --git a/drivers/pinctrl/renesas/pfc-r8a779h0.c b/drivers/pinctrl/renesas/pfc-r8a779h0.c index afa8f06c85cf..438d1f2739dd 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779h0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779h0.c @@ -75,10 +75,10 @@ #define GPSR0_9 F_(MSIOF5_SYNC, IP1SR0_7_4) #define GPSR0_8 F_(MSIOF5_SS1, IP1SR0_3_0) #define GPSR0_7 F_(MSIOF5_SS2, IP0SR0_31_28) -#define GPSR0_6 F_(IRQ0, IP0SR0_27_24) -#define GPSR0_5 F_(IRQ1, IP0SR0_23_20) -#define GPSR0_4 F_(IRQ2, IP0SR0_19_16) -#define GPSR0_3 F_(IRQ3, IP0SR0_15_12) +#define GPSR0_6 F_(IRQ0_A, IP0SR0_27_24) +#define GPSR0_5 F_(IRQ1_A, IP0SR0_23_20) +#define GPSR0_4 F_(IRQ2_A, IP0SR0_19_16) +#define GPSR0_3 F_(IRQ3_A, IP0SR0_15_12) #define GPSR0_2 F_(GP0_02, IP0SR0_11_8) #define GPSR0_1 F_(GP0_01, IP0SR0_7_4) #define GPSR0_0 F_(GP0_00, IP0SR0_3_0) @@ -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_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_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_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_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_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_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_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_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_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) /* 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[] = { 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_19_16, IRQ2), + PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2_A), 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_27_24, IRQ0), + PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0_A), PINMUX_IPSR_GPSR(IP0SR0_27_24, MSIOF3_SYNC), PINMUX_IPSR_GPSR(IP0SR0_31_28, MSIOF5_SS2), @@ -1660,6 +1660,90 @@ static const unsigned int i2c3_mux[] = { 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 -------------------------------------------------------------------- */ static const unsigned int mmc_data_pins[] = { /* MMC_SD_D[0:3], MMC_D[4:7] */ @@ -2416,6 +2500,18 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(i2c2), 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, 4), BUS_DATA_PIN_GROUP(mmc_data, 8), @@ -2629,6 +2725,20 @@ static const char * const i2c3_groups[] = { "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[] = { "mmc_data1", "mmc_data4", @@ -2813,6 +2923,8 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(i2c2), SH_PFC_FUNCTION(i2c3), + SH_PFC_FUNCTION(intc_ex), + SH_PFC_FUNCTION(mmc), SH_PFC_FUNCTION(msiof0), diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index 20425afc6b33..c3256bfde502 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -892,6 +892,8 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps val = PVDD_1800; break; case 2500: + if (!(caps & (PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1))) + return -EINVAL; val = PVDD_2500; break; case 3300: @@ -2514,7 +2516,7 @@ static void rzg2l_pinctrl_pm_setup_dedicated_regs(struct rzg2l_pinctrl *pctrl, b } } -static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl) +static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl) { u32 nports = pctrl->data->n_port_pins / RZG2L_PINS_PER_PORT; const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 871c1eb46ddf..ce5e6783b5b9 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -13,6 +13,7 @@ // the Samsung pinctrl/gpiolib driver. It also includes the implementation of // external gpio and wakeup interrupt support. +#include <linux/clk.h> #include <linux/device.h> #include <linux/interrupt.h> #include <linux/irqdomain.h> @@ -61,6 +62,12 @@ static void exynos_irq_mask(struct irq_data *irqd) else 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); mask = readl(bank->eint_base + reg_mask); @@ -68,6 +75,8 @@ static void exynos_irq_mask(struct irq_data *irqd) writel(mask, bank->eint_base + reg_mask); raw_spin_unlock_irqrestore(&bank->slock, flags); + + clk_disable(bank->drvdata->pclk); } static void exynos_irq_ack(struct irq_data *irqd) @@ -82,7 +91,15 @@ static void exynos_irq_ack(struct irq_data *irqd) else 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); + + clk_disable(bank->drvdata->pclk); } static void exynos_irq_unmask(struct irq_data *irqd) @@ -110,6 +127,12 @@ static void exynos_irq_unmask(struct irq_data *irqd) else 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); mask = readl(bank->eint_base + reg_mask); @@ -117,6 +140,8 @@ static void exynos_irq_unmask(struct irq_data *irqd) writel(mask, bank->eint_base + reg_mask); 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) @@ -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 con, trig_type; unsigned long reg_con; + int ret; switch (type) { case IRQ_TYPE_EDGE_RISING: @@ -159,11 +185,20 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) else 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 &= ~(EXYNOS_EINT_CON_MASK << shift); con |= trig_type << shift; writel(con, bank->eint_base + reg_con); + clk_disable(bank->drvdata->pclk); + return 0; } @@ -200,6 +235,14 @@ static int exynos_irq_request_resources(struct irq_data *irqd) shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; 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); con = readl(bank->pctl_base + reg_con); @@ -209,6 +252,8 @@ static int exynos_irq_request_resources(struct irq_data *irqd) raw_spin_unlock_irqrestore(&bank->slock, flags); + clk_disable(bank->drvdata->pclk); + return 0; } @@ -223,6 +268,13 @@ static void exynos_irq_release_resources(struct irq_data *irqd) shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; 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); con = readl(bank->pctl_base + reg_con); @@ -232,6 +284,8 @@ static void exynos_irq_release_resources(struct irq_data *irqd) raw_spin_unlock_irqrestore(&bank->slock, flags); + clk_disable(bank->drvdata->pclk); + gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq); } @@ -281,10 +335,19 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) unsigned int svc, group, pin; 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) svc = readl(bank->eint_base + EXYNOSAUTO_SVC_OFFSET); else svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET); + + clk_disable(bank->drvdata->pclk); + group = EXYNOS_SVC_GROUP(svc); pin = svc & EXYNOS_SVC_NUM_MASK; @@ -563,6 +626,20 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *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) { struct samsung_pin_bank *b = eintd->banks[i]; 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) 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); } @@ -695,6 +775,12 @@ static void exynos_pinctrl_suspend_bank( struct exynos_eint_gpio_save *save = bank->soc_priv; 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 + bank->eint_offset); save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET @@ -704,6 +790,8 @@ static void exynos_pinctrl_suspend_bank( save->eint_mask = readl(regs + bank->irq_chip->eint_mask + bank->eint_offset); + clk_disable(bank->drvdata->pclk); + 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 fltcon1 %#010x\n", bank->name, save->eint_fltcon1); @@ -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; 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_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 mask %#010x\n", bank->name, save->eint_mask); } @@ -753,6 +849,12 @@ static void exynos_pinctrl_resume_bank( struct exynos_eint_gpio_save *save = bank->soc_priv; 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, readl(regs + EXYNOS_GPIO_ECON_OFFSET + bank->eint_offset), save->eint_con); @@ -774,6 +876,8 @@ static void exynos_pinctrl_resume_bank( + 2 * bank->eint_offset + 4); writel(save->eint_mask, regs + bank->irq_chip->eint_mask + bank->eint_offset); + + clk_disable(bank->drvdata->pclk); } 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 struct exynos_eint_gpio_save *save = bank->soc_priv; 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, readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con); 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 writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_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) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index ed07e23e0912..623df65a5d6f 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -15,6 +15,7 @@ // but provides extensions to which platform specific implementation of the gpio // and wakeup interrupts can be hooked to. +#include <linux/clk.h> #include <linux/err.h> #include <linux/gpio/driver.h> #include <linux/init.h> @@ -371,8 +372,8 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, } /* enable or disable a pinmux function */ -static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) +static int samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, + unsigned group) { struct samsung_pinctrl_drv_data *drvdata; const struct samsung_pin_bank_type *type; @@ -382,6 +383,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, unsigned long flags; const struct samsung_pmx_func *func; const struct samsung_pin_group *grp; + int ret; drvdata = pinctrl_dev_get_drvdata(pctldev); func = &drvdata->pmx_functions[selector]; @@ -397,6 +399,12 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, 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); data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); @@ -405,6 +413,10 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); raw_spin_unlock_irqrestore(&bank->slock, flags); + + clk_disable(drvdata->pclk); + + return 0; } /* enable a specified pinmux by writing to registers */ @@ -412,8 +424,7 @@ static int samsung_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { - samsung_pinmux_setup(pctldev, selector, group); - return 0; + return samsung_pinmux_setup(pctldev, selector, group); } /* 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, u32 data, width, pin_offset, mask, shift; u32 cfg_value, cfg_reg; unsigned long flags; + int ret; drvdata = pinctrl_dev_get_drvdata(pctldev); pin_to_reg_bank(drvdata, pin, ®_base, &pin_offset, &bank); @@ -447,6 +459,12 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, width = type->fld_width[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); mask = (1 << width) - 1; @@ -466,6 +484,8 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, raw_spin_unlock_irqrestore(&bank->slock, flags); + clk_disable(drvdata->pclk); + return 0; } @@ -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) { struct samsung_pin_bank *bank = gpiochip_get_data(gc); + struct samsung_pinctrl_drv_data *drvdata = bank->drvdata; 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); samsung_gpio_set_value(gc, offset, value); raw_spin_unlock_irqrestore(&bank->slock, flags); + + clk_disable(drvdata->pclk); } /* gpiolib gpio_get callback function */ @@ -569,12 +597,23 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) u32 data; struct samsung_pin_bank *bank = gpiochip_get_data(gc); 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; + 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 >>= offset; data &= 1; + + clk_disable(drvdata->pclk); + return data; } @@ -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) { struct samsung_pin_bank *bank = gpiochip_get_data(gc); + struct samsung_pinctrl_drv_data *drvdata = bank->drvdata; unsigned long flags; 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); ret = samsung_gpio_set_direction(gc, offset, true); raw_spin_unlock_irqrestore(&bank->slock, flags); + + clk_disable(drvdata->pclk); + return ret; } @@ -633,14 +682,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int value) { struct samsung_pin_bank *bank = gpiochip_get_data(gc); + struct samsung_pinctrl_drv_data *drvdata = bank->drvdata; unsigned long flags; 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); samsung_gpio_set_value(gc, offset, value); ret = samsung_gpio_set_direction(gc, offset, false); raw_spin_unlock_irqrestore(&bank->slock, flags); + clk_disable(drvdata->pclk); + return ret; } @@ -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); if (ret) goto err_put_banks; @@ -1202,6 +1266,13 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev); 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++) { struct samsung_pin_bank *bank = &drvdata->pin_banks[i]; const void __iomem *reg = bank->pctl_base + bank->pctl_offset; @@ -1231,6 +1302,8 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) } } + clk_disable(drvdata->pclk); + if (drvdata->suspend) drvdata->suspend(drvdata); if (drvdata->retention_ctrl && drvdata->retention_ctrl->enable) @@ -1250,8 +1323,20 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) static int __maybe_unused samsung_pinctrl_resume(struct device *dev) { struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev); + int ret; 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) drvdata->resume(drvdata); @@ -1286,6 +1371,8 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev) writel(bank->pm_save[type], reg + offs[type]); } + clk_disable(drvdata->pclk); + if (drvdata->retention_ctrl && drvdata->retention_ctrl->disable) drvdata->retention_ctrl->disable(drvdata); diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index ab791afaabf5..d50ba6f07d5d 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -274,6 +274,7 @@ struct samsung_pin_ctrl { * through samsung_pinctrl_drv_data, not samsung_pin_bank). * @dev: device instance representing the controller. * @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. * @pctl: pin controller descriptor registered with the pinctrl subsystem. * @pctl_dev: cookie representing pinctrl device instance. @@ -293,6 +294,7 @@ struct samsung_pinctrl_drv_data { void __iomem *virt_base; struct device *dev; int irq; + struct clk *pclk; struct pinctrl_desc pctl; struct pinctrl_dev *pctl_dev; diff --git a/drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c index 919b6a20af83..5b4822f77d2a 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c @@ -169,7 +169,6 @@ static struct platform_driver sun9i_a80_r_pinctrl_driver = { .probe = sun9i_a80_r_pinctrl_probe, .driver = { .name = "sun9i-a80-r-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun9i_a80_r_pinctrl_match, }, }; diff --git a/include/dt-bindings/pinctrl/samsung.h b/include/dt-bindings/pinctrl/samsung.h deleted file mode 100644 index d1da5ff68d0c..000000000000 --- a/include/dt-bindings/pinctrl/samsung.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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__ */ |