diff --git a/.gitignore b/.gitignore index bb65fa253e58..3af66272d6f1 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ *.so.dbg *.su *.symtypes +*.symversions *.tab.[ch] *.tar *.xz diff --git a/Documentation/devicetree/bindings/gpio/gpio-atlas7.txt b/Documentation/devicetree/bindings/gpio/gpio-atlas7.txt deleted file mode 100644 index d7e123fc90b5..000000000000 --- a/Documentation/devicetree/bindings/gpio/gpio-atlas7.txt +++ /dev/null @@ -1,50 +0,0 @@ -CSR SiRFatlas7 GPIO controller bindings - -Required properties: -- compatible : "sirf,atlas7-gpio" -- reg : Address range of the pinctrl registers -- interrupts : Interrupts used by every GPIO group -- gpio-banks : How many gpio banks on this controller -- gpio-controller : Indicates this device is a GPIO controller -- interrupt-controller : Marks the device node as an interrupt controller - -The GPIO controller also acts as an interrupt controller. It uses the default -two cells specifier as described in Documentation/devicetree/bindings/ -interrupt-controller/interrupts.txt. - -Example: - - gpio_0: gpio_mediam@17040000 { - compatible = "sirf,atlas7-gpio"; - reg = <0x17040000 0x1000>; - interrupts = <0 13 0>, <0 14 0>; - - #gpio-cells = <2>; - #interrupt-cells = <2>; - - gpio-controller; - interrupt-controller; - - gpio-banks = <2>; - gpio-ranges = <&pinctrl 0 0 0>, - <&pinctrl 32 0 0>; - gpio-ranges-group-names = "lvds_gpio_grp", - "uart_nand_gpio_grp"; - }; - - leds { - compatible = "gpio-leds"; - - led1 { - gpios = <&gpio_1 15 0>; - ... - }; - - led2 { - gpios = <&gpio_2 34 0>; - ... - }; - }; - -Please refer to gpio.txt in this directory for details of the common -gpio properties used by devices. diff --git a/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt b/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt deleted file mode 100644 index fd665b44d767..000000000000 --- a/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt +++ /dev/null @@ -1,7 +0,0 @@ -ST-Ericsson COH 901 571/3 GPIO controller - -Required properties: -- compatible: Compatible property value should be "stericsson,gpio-coh901" -- reg: Physical base address of the controller and length of memory mapped - region. -- interrupts: the 0...n interrupts assigned to the different GPIO ports/banks. diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml index 5240487dfe50..cce63c3cc463 100644 --- a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml @@ -53,6 +53,8 @@ properties: - allwinner,sun50i-h5-pinctrl - allwinner,sun50i-h6-pinctrl - allwinner,sun50i-h6-r-pinctrl + - allwinner,sun50i-h616-pinctrl + - allwinner,sun50i-h616-r-pinctrl - allwinner,suniv-f1c100s-pinctrl - nextthing,gr8-pinctrl @@ -61,7 +63,7 @@ properties: interrupts: minItems: 1 - maxItems: 7 + maxItems: 8 description: One interrupt per external interrupt bank supported on the controller, sorted by bank number ascending order. @@ -91,7 +93,7 @@ properties: bank found in the controller $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 1 - maxItems: 5 + maxItems: 8 patternProperties: # It's pretty scary, but the basic idea is that: @@ -145,6 +147,17 @@ allOf: # boards are defining it at the moment so it would generate a lot of # warnings. + - if: + properties: + compatible: + enum: + - allwinner,sun50i-h616-pinctrl + + then: + properties: + interrupts: + minItems: 8 + - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt index 265015bc0603..e2b861ce16d8 100644 --- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt @@ -35,9 +35,11 @@ ioset settings. Use the macros from boot/dts/-pinfunc.h file to get the right representation of the pin. Optional properties: -- GENERIC_PINCONFIG: generic pinconfig options to use, bias-disable, -bias-pull-down, bias-pull-up, drive-open-drain, input-schmitt-enable, -input-debounce, output-low, output-high. +- GENERIC_PINCONFIG: generic pinconfig options to use: + - bias-disable, bias-pull-down, bias-pull-up, drive-open-drain, + input-schmitt-enable, input-debounce, output-low, output-high. + - for microchip,sama7g5-pinctrl only: + - slew-rate: 0 - disabled, 1 - enabled (default) - atmel,drive-strength: 0 or 1 for low drive, 2 for medium drive and 3 for high drive. The default value is low drive. diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.txt index e295dda4bbba..40e0a9a19525 100644 --- a/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.txt +++ b/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.txt @@ -39,7 +39,7 @@ For example: <0x660009b0 0x40>; pinctrl-names = "default"; - pinctrl-0 = <&nand_sel &uart3_rx &sdio0_d4>; + pinctrl-0 = <&nand_sel>, <&uart3_rx>, <&sdio0_d4>; /* Select nand function */ nand_sel: nand_sel { diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,nsp-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/brcm,nsp-pinmux.txt index 603564e5fe6f..dede11e4ef78 100644 --- a/Documentation/devicetree/bindings/pinctrl/brcm,nsp-pinmux.txt +++ b/Documentation/devicetree/bindings/pinctrl/brcm,nsp-pinmux.txt @@ -30,7 +30,7 @@ For example: <0x1803f408 0x04>; pinctrl-names = "default"; - pinctrl-0 = <&pwm &gpio_b &nand_sel>; + pinctrl-0 = <&pwm>, <&gpio_b>, <&nand_sel>; pwm: pwm { function = "pwm"; diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt index 8ac1d0851a0f..bfab5ca49fd1 100644 --- a/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt @@ -60,7 +60,7 @@ iomuxc-lpsr controller and SDA pad from iomuxc controller as: i2c1: i2c@30a20000 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c1_1 &pinctrl_i2c1_2>; + pinctrl-0 = <&pinctrl_i2c1_1>, <&pinctrl_i2c1_2>; }; iomuxc-lpsr@302c0000 { diff --git a/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml b/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml index df0c83cb1c6e..4fe35e650909 100644 --- a/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml @@ -99,8 +99,8 @@ patternProperties: '#interrupt-cells': description: - Specifies the pin (port and bit) and flags, as defined in - defined in include/dt-bindings/interrupt-controller/irq.h + Specifies the pin (port and bit) and flags, as defined in + defined in include/dt-bindings/interrupt-controller/irq.h const: 3 ngpios: diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-atlas7.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-atlas7.txt deleted file mode 100644 index fbdd1a716a1e..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-atlas7.txt +++ /dev/null @@ -1,109 +0,0 @@ -CSR SiRFatlas7 pinmux controller - -Required properties: -- compatible : "sirf,atlas7-ioc" -- reg : Address range of the pinctrl registers - -For example, pinctrl might have properties like the following: - pinctrl: ioc@18880000 { - compatible = "sirf,atlas7-ioc"; - reg = <0x18880000 0x1000>; - - a_ac97_pmx: ac97@0 { - ac97 { - groups = "audio_ac97_grp"; - function = "audio_ac97"; - }; - }; - - ... - - sd2_pmx: sd2@0 { - sd2 { - groups = "sd2_grp0"; - function = "sd2"; - }; - }; - - ... - - - sample0_cfg: sample0@0 { - sample0 { - pins = "ldd_0", "ldd_1"; - bias-pull-up; - }; - }; - - sample1_cfg: sample1@0 { - sample1 { - pins = "ldd_2", "ldd_3"; - input-schmitt-enable; - }; - }; - - sample2_cfg: sample2@0 { - sample2 { - groups = "uart4_nopause_grp"; - bias-pull-down; - }; - }; - - sample3_cfg: sample3@0 { - sample3 { - pins = "ldd_4", "ldd_5"; - drive-strength = <2>; - }; - }; - }; - -Please refer to pinctrl-bindings.txt in this directory for details of the common -pinctrl bindings used by client devices. - -SiRFatlas7's pinmux nodes act as a container for an arbitrary number of subnodes. -Each of these subnodes represents some desired configuration for a group of pins. - -Required subnode-properties: -- groups : An array of strings. Each string contains the name of a group. -- function: A string containing the name of the function to mux to the - group. - - Valid values for group and function names can be found from looking at the - group and function arrays in driver files: - drivers/pinctrl/pinctrl-sirf.c - -For example, pinctrl might have subnodes like the following: - sd0_pmx: sd0@0 { - sd0 { - groups = "sd0_grp"; - function = "sd0"; - }; - }; - - sd1_pmx0: sd1@0 { - sd1 { - groups = "sd1_grp0"; - function = "sd1_m0"; - }; - }; - - sd1_pmx1: sd1@1 { - sd1 { - groups = "sd1_grp1"; - function = "sd1_m1"; - }; - }; - -For a specific board, if it wants to use sd1, -it can add the following to its board-specific .dts file. -sd1: sd@12340000 { - pinctrl-names = "default"; - pinctrl-0 = <&sd1_pmx0>; -} - -or - -sd1: sd@12340000 { - pinctrl-names = "default"; - pinctrl-0 = <&sd1_pmx1>; -} diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt index 4613bb17ace3..9dae60acf950 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt @@ -77,13 +77,13 @@ For example: device { pinctrl-names = "active", "idle"; pinctrl-0 = <&state_0_node_a>; - pinctrl-1 = <&state_1_node_a &state_1_node_b>; + pinctrl-1 = <&state_1_node_a>, <&state_1_node_b>; }; /* For the same device if using state IDs */ device { pinctrl-0 = <&state_0_node_a>; - pinctrl-1 = <&state_1_node_a &state_1_node_b>; + pinctrl-1 = <&state_1_node_a>, <&state_1_node_b>; }; /* diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mcp23s08.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mcp23s08.txt index 8b94aa8f5971..6ec3c8d79f49 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mcp23s08.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mcp23s08.txt @@ -134,7 +134,7 @@ gpio21: gpio@21 { #interrupt-cells = <0x2>; microchip,irq-mirror; pinctrl-names = "default"; - pinctrl-0 = <&i2cgpio0irq &gpio21pullups>; + pinctrl-0 = <&i2cgpio0irq>, <&gpio21pullups>; gpio21pullups: pinmux { pins = "gpio0", "gpio1", "gpio2", "gpio3", diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt index 931a18cd1e23..360e59c9301a 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt @@ -91,7 +91,7 @@ Examples: pinctrl@1c20800 { compatible = "mediatek,mt8135-pinctrl"; reg = <0 0x1000B000 0 0x1000>; - mediatek,pctl-regmap = <&syscfg_pctl_a &syscfg_pctl_b>; + mediatek,pctl-regmap = <&syscfg_pctl_a>, <&syscfg_pctl_b>; pins-are-numbered; gpio-controller; #gpio-cells = <2>; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt index f903eb4471f8..bfd222b05495 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt @@ -8,7 +8,7 @@ Required properties: - reg : offset and length of the register set for the mux registers - #pinctrl-cells : number of cells in addition to the index, set to 1 - for pinctrl-single,pins and 2 for pinctrl-single,bits + or 2 for pinctrl-single,pins and set to 2 for pinctrl-single,bits - pinctrl-single,register-width : pinmux register access width in bits @@ -80,7 +80,7 @@ Optional properties: property. /* pin base, nr pins & gpio function */ - pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1>; + pinctrl-single,gpio-range = <&range 0 3 0>, <&range 3 9 1>; - interrupt-controller : standard interrupt controller binding if using interrupts for wake-up events for example. In this case pinctrl-single @@ -185,10 +185,10 @@ pmx_gpio: pinmux@d401e000 { pinctrl-single,function-mask = <7>; /* sparse GPIO range could be supported */ - pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1 - &range 12 1 0 &range 13 29 1 - &range 43 1 0 &range 44 49 1 - &range 94 1 1 &range 96 2 1>; + pinctrl-single,gpio-range = <&range 0 3 0>, <&range 3 9 1>, + <&range 12 1 0>, <&range 13 29 1>, + <&range 43 1 0>, <&range 44 49 1>, + <&range 94 1 1>, <&range 96 2 1>; range: gpio-range { #pinctrl-single,gpio-range-cells = <3>; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt deleted file mode 100644 index 39170f372599..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt +++ /dev/null @@ -1,84 +0,0 @@ -* ZTE ZX Pin Controller - -The pin controller on ZTE ZX platforms is kinda of hybrid. It consists of -a main controller and an auxiliary one. For example, on ZX296718 SoC, the -main controller is TOP_PMM and the auxiliary one is AON_IOCFG. Both -controllers work together to control pin multiplexing and configuration in -the way illustrated as below. - - - GMII_RXD3 ---+ - | - DVI1_HS ---+----------------------------- GMII_RXD3 (TOP pin) - | - BGPIO16 ---+ ^ - | pinconf - ^ | - | pinmux | - | | - - TOP_PMM (main) AON_IOCFG (aux) - - | | | - | pinmux | | - | pinmux v | - v | pinconf - KEY_ROW2 ---+ v - PORT1_LCD_TE ---+ | - | AGPIO10 ---+------ KEY_ROW2 (AON pin) - I2S0_DOUT3 ---+ | - |-----------------------+ - PWM_OUT3 ---+ - | - VGA_VS1 ---+ - - -For most of pins like GMII_RXD3 in the figure, the pinmux function is -controlled by TOP_PMM block only, and this type of pins are meant by term -'TOP pins'. For pins like KEY_ROW2, the pinmux is controlled by both -TOP_PMM and AON_IOCFG blocks, as the available multiplexing functions for -the pin spread in both controllers. This type of pins are called 'AON pins'. -Though pinmux implementation is quite different, pinconf is same for both -types of pins. Both are controlled by auxiliary controller, i.e. AON_IOCFG -on ZX296718. - -Required properties: -- compatible: should be "zte,zx296718-pmm". -- reg: the register physical address and length. -- zte,auxiliary-controller: phandle to the auxiliary pin controller which - implements pinmux for AON pins and pinconf for all pins. - -The following pin configuration are supported. Please refer to -pinctrl-bindings.txt in this directory for more details of the common -pinctrl bindings used by client devices. - -- bias-pull-up -- bias-pull-down -- drive-strength -- input-enable -- slew-rate - -Examples: - -iocfg: pin-controller@119000 { - compatible = "zte,zx296718-iocfg"; - reg = <0x119000 0x1000>; -}; - -pmm: pin-controller@1462000 { - compatible = "zte,zx296718-pmm"; - reg = <0x1462000 0x1000>; - zte,auxiliary-controller = <&iocfg>; -}; - -&pmm { - vga_pins: vga { - pins = "KEY_COL1", "KEY_COL2", "KEY_ROW1", "KEY_ROW2"; - function = "VGA"; - }; -}; - -&vga { - pinctrl-names = "default"; - pinctrl-0 = <&vga_pins>; -}; diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt index 448d36a85730..0ba07bc96c55 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt @@ -8,6 +8,7 @@ of PMIC's from Qualcomm. Value type: Definition: Should contain one of: "qcom,pm8018-mpp", + "qcom,pm8019-mpp", "qcom,pm8038-mpp", "qcom,pm8058-mpp", "qcom,pm8821-mpp", diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml new file mode 100644 index 000000000000..a82dab898395 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml @@ -0,0 +1,152 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,sc8180x-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. SC8180X TLMM block + +maintainers: + - Bjorn Andersson + +description: | + This binding describes the Top Level Mode Multiplexer block found in the + SC8180X platform. + +allOf: + - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml# + +properties: + compatible: + const: qcom,sc8180x-tlmm + + reg: + maxItems: 3 + + reg-names: + items: + - const: "west" + - const: "east" + - const: "south" + + interrupts: true + interrupt-controller: true + '#interrupt-cells': true + gpio-controller: true + gpio-reserved-ranges: true + '#gpio-cells': true + gpio-ranges: true + wakeup-parent: true + +required: + - compatible + - reg + - reg-names + +additionalProperties: false + +patternProperties: + '-state$': + oneOf: + - $ref: "#/$defs/qcom-sc8180x-tlmm-state" + - patternProperties: + ".*": + $ref: "#/$defs/qcom-sc8180x-tlmm-state" + +'$defs': + qcom-sc8180x-tlmm-state: + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + + properties: + pins: + description: + List of gpio pins affected by the properties specified in this + subnode. + items: + oneOf: + - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-8][0-9])$" + - enum: [ sdc2_clk, sdc2_cmd, sdc2_data, ufs_reset ] + minItems: 1 + maxItems: 16 + + function: + description: + Specify the alternative function to be configured for the specified + pins. + + enum: [ adsp_ext, agera_pll, aoss_cti, atest_char, atest_tsens, + atest_tsens2, atest_usb0, atest_usb1, atest_usb2, atest_usb3, + atest_usb4, audio_ref, btfm_slimbus, cam_mclk, cci_async, + cci_i2c, cci_timer0, cci_timer1, cci_timer2, cci_timer3, + cci_timer4, cci_timer5, cci_timer6, cci_timer7, cci_timer8, + cci_timer9, cri_trng, dbg_out, ddr_bist, ddr_pxi, debug_hot, + dp_hot, edp_hot, edp_lcd, emac_phy, emac_pps, gcc_gp1, gcc_gp2, + gcc_gp3, gcc_gp4, gcc_gp5, gpio, gps, grfc, hs1_mi2s, hs2_mi2s, + hs3_mi2s, jitter_bist, lpass_slimbus, m_voc, mdp_vsync, + mdp_vsync0, mdp_vsync1, mdp_vsync2, mdp_vsync3, mdp_vsync4, + mdp_vsync5, mss_lte, nav_pps, pa_indicator, pci_e0, pci_e1, + pci_e2, pci_e3, phase_flag, pll_bist, pll_bypassnl, pll_reset, + pri_mi2s, pri_mi2s_ws, prng_rosc, qdss_cti, qdss_gpio, qlink, + qspi0, qspi0_clk, qspi0_cs, qspi1, qspi1_clk, qspi1_cs, + qua_mi2s, qup0, qup1, qup2, qup3, qup4, qup5, qup6, qup7, qup8, + qup9, qup10, qup11, qup12, qup13, qup14, qup15, qup16, qup17, + qup18, qup19, qup_l4, qup_l5, qup_l6, rgmii, sd_write, sdc4, + sdc4_clk, sdc4_cmd, sec_mi2s, sp_cmu, spkr_i2s, ter_mi2s, tgu, + tsense_pwm1, tsense_pwm2, tsif1, tsif2, uim1, uim2, uim_batt, + usb0_phy, usb1_phy, usb2phy_ac, vfr_1, vsense_trigger, + wlan1_adc, wlan2_adc, wmss_reset ] + + bias-disable: true + bias-pull-down: true + bias-pull-up: true + drive-strength: true + input-enable: true + output-high: true + output-low: true + + required: + - pins + - function + + additionalProperties: false + +examples: + - | + #include + pinctrl@3100000 { + compatible = "qcom,sc8180x-tlmm"; + reg = <0x03100000 0x300000>, + <0x03500000 0x700000>, + <0x03d00000 0x300000>; + reg-names = "west", "east", "south"; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 190>; + + gpio-wo-subnode-state { + pins = "gpio1"; + function = "gpio"; + }; + + uart-w-subnodes-state { + rx { + pins = "gpio4"; + function = "qup6"; + bias-pull-up; + }; + + tx { + pins = "gpio5"; + function = "qup6"; + bias-disable; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml new file mode 100644 index 000000000000..4f2667ea2805 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml @@ -0,0 +1,145 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,sm8350-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. SM8350 TLMM block + +maintainers: + - Vinod Koul + +description: | + This binding describes the Top Level Mode Multiplexer (TLMM) block found + in the SM8350 platform. + +allOf: + - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml# + +properties: + compatible: + const: qcom,sm8350-tlmm + + reg: + maxItems: 1 + + interrupts: true + interrupt-controller: true + '#interrupt-cells': true + gpio-controller: true + gpio-reserved-ranges: true + '#gpio-cells': true + gpio-ranges: true + wakeup-parent: true + +required: + - compatible + - reg + +additionalProperties: false + +patternProperties: + '-state$': + oneOf: + - $ref: "#/$defs/qcom-sm8350-tlmm-state" + - patternProperties: + ".*": + $ref: "#/$defs/qcom-sm8350-tlmm-state" + +$defs: + qcom-sm8350-tlmm-state: + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + + properties: + pins: + description: + List of gpio pins affected by the properties specified in this + subnode. + items: + oneOf: + - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|20[0-3])$" + - enum: [ sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data ] + minItems: 1 + maxItems: 36 + + function: + description: + Specify the alternative function to be configured for the specified + pins. + + enum: [ atest_char, atest_usb, audio_ref, cam_mclk, cci_async, + cci_i2c, cci_timer, cmu_rng, coex_uart1, coex_uart2, cri_trng, + cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1, + ddr_pxi2, ddr_pxi3, dp_hot, dp_lcd, gcc_gp1, gcc_gp2, gcc_gp3, + gpio, ibi_i3c, jitter_bist, lpass_slimbus, mdp_vsync, mdp_vsync0, + mdp_vsync1, mdp_vsync2, mdp_vsync3, mi2s0_data0, mi2s0_data1, + mi2s0_sck, mi2s0_ws, mi2s1_data0, mi2s1_data1, mi2s1_sck, + mi2s1_ws, mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, + mss_grfc0, mss_grfc1, mss_grfc10, mss_grfc11, mss_grfc12, + mss_grfc2, mss_grfc3, mss_grfc4, mss_grfc5, mss_grfc6, + mss_grfc7, mss_grfc8, mss_grfc9, nav_gpio, pa_indicator, + pcie0_clkreqn, pcie1_clkreqn, phase_flag, pll_bist, pll_clk, + pri_mi2s, prng_rosc, qdss_cti, qdss_gpio, qlink0_enable, + qlink0_request, qlink0_wmss, qlink1_enable, qlink1_request, + qlink1_wmss, qlink2_enable, qlink2_request, qlink2_wmss, qspi0, + qspi1, qspi2, qspi3, qspi_clk, qspi_cs, qup0, qup1, qup10, + qup11, qup12, qup13, qup14, qup15, qup16, qup17, qup18, qup19, + qup2, qup3, qup4, qup5, qup6, qup7, qup8, qup9, qup_l4, qup_l5, + qup_l6, sd_write, sdc40, sdc41, sdc42, sdc43, sdc4_clk, + sdc4_cmd, sec_mi2s, tb_trig, tgu_ch0, tgu_ch1, tgu_ch2, + tgu_ch3, tsense_pwm1, tsense_pwm2, uim0_clk, uim0_data, + uim0_present, uim0_reset, uim1_clk, uim1_data, uim1_present, + uim1_reset, usb2phy_ac, usb_phy, vfr_0, vfr_1, vsense_trigger ] + + + bias-disable: true + bias-pull-down: true + bias-pull-up: true + drive-strength: true + input-enable: true + output-high: true + output-low: true + + required: + - pins + - function + + additionalProperties: false + +examples: + - | + #include + pinctrl@f100000 { + compatible = "qcom,sm8350-tlmm"; + reg = <0x0f100000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 203>; + + gpio-wo-subnode-state { + pins = "gpio1"; + function = "gpio"; + }; + + uart-w-subnodes-state { + rx { + pins = "gpio18"; + function = "qup3"; + bias-pull-up; + }; + + tx { + pins = "gpio19"; + function = "qup3"; + bias-disable; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,tlmm-common.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,tlmm-common.yaml new file mode 100644 index 000000000000..3b37cf102d41 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,tlmm-common.yaml @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,tlmm-common.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. Top Level Mode Multiplexer (TLMM) definitions + +maintainers: + - Bjorn Andersson + +description: + This defines the common properties used to describe all Qualcomm Top Level + Mode Multiplexer bindings and pinconf/pinmux states for these. + +properties: + interrupts: + description: + Specifies the TLMM summary IRQ + maxItems: 1 + + interrupt-controller: true + + '#interrupt-cells': + description: + Specifies the PIN numbers and Flags, as defined in defined in + include/dt-bindings/interrupt-controller/irq.h + const: 2 + + gpio-controller: true + + '#gpio-cells': + description: + Specifying the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + gpio-ranges: + maxItems: 1 + + wakeup-parent: + description: + Specifying the interrupt-controller used to wake up the system when the + TLMM block has been powered down. + maxItems: 1 + + gpio-reserved-ranges: + description: + Pins can be reserved for trusted applications and thereby unaccessible + from the OS. This property can be used to mark the pins which resources + should not be accessed by the OS. Please see the ../gpio/gpio.txt for more + information. + +required: + - interrupts + - interrupt-controller + - '#interrupt-cells' + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: true + +$defs: + qcom-tlmm-state: + allOf: + - $ref: pincfg-node.yaml# + - $ref: pinmux-node.yaml# + + properties: + drive-strength: + enum: [2, 4, 6, 8, 10, 12, 14, 16] + default: 2 + description: + Selects the drive strength for the specified pins, in mA. + + bias-pull-down: true + bias-pull-up: true + bias-disable: true + input-enable: true + output-high: true + output-low: true + + additionalProperties: true +... diff --git a/Documentation/devicetree/bindings/pinctrl/ralink,rt2880-pinmux.yaml b/Documentation/devicetree/bindings/pinctrl/ralink,rt2880-pinmux.yaml index 7dea3e26d99e..b32f2676cab5 100644 --- a/Documentation/devicetree/bindings/pinctrl/ralink,rt2880-pinmux.yaml +++ b/Documentation/devicetree/bindings/pinctrl/ralink,rt2880-pinmux.yaml @@ -15,39 +15,38 @@ description: properties: compatible: - enum: - - ralink,rt2880-pinmux + const: ralink,rt2880-pinmux - pinctrl-0: - description: - A phandle to the node containing the subnodes containing default - configurations. This is for pinctrl hogs. +patternProperties: + '-pins$': + type: object + patternProperties: + '^(.*-)?pinmux$': + type: object + description: node for pinctrl. + $ref: pinmux-node.yaml# - pinctrl-names: - description: - A pinctrl state named "default" can be defined. - const: default + properties: + groups: + description: Name of the pin group to use for the functions. + enum: [i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, mdio, + pcie, sdhci] + function: + description: The mux function to select + enum: [gpio, i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, + mdio, nand1, nand2, sdhci] + + required: + - groups + - function + + additionalProperties: false + + additionalProperties: false required: - compatible -patternProperties: - '[a-z0-9_-]+': - if: - type: object - description: node for pinctrl. - $ref: "pinmux-node.yaml" - then: - properties: - groups: - description: Name of the pin group to use for the functions. - enum: [i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, mdio, - pcie, sdhci] - function: - description: The mux function to select - enum: [gpio, i2c, spi, uart1, uart2, uart3, rgmii1, rgmii2, - mdio, nand1, nand2, sdhci] - additionalProperties: false examples: @@ -55,14 +54,9 @@ examples: - | pinctrl { compatible = "ralink,rt2880-pinmux"; - pinctrl-names = "default"; - pinctrl-0 = <&state_default>; - state_default: pinctrl0 { - }; - - i2c_pins: i2c0 { - i2c0 { + i2c_pins: i2c0-pins { + pinmux { groups = "i2c"; function = "i2c"; }; diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml index 5d3947902f2d..ac4e068aa03f 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml @@ -43,11 +43,12 @@ properties: - renesas,pfc-r8a77980 # R-Car V3H - renesas,pfc-r8a77990 # R-Car E3 - renesas,pfc-r8a77995 # R-Car D3 + - renesas,pfc-r8a779a0 # R-Car V3U - renesas,pfc-sh73a0 # SH-Mobile AG5 reg: minItems: 1 - maxItems: 2 + maxItems: 10 gpio-controller: true diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt index 7734ab6fec44..38a1416fd2cd 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt @@ -336,7 +336,7 @@ Example 3: A uart client node that supports 'default' and 'flow-control' states. interrupts = <0 52 0>; pinctrl-names = "default", "flow-control; pinctrl-0 = <&uart0_data>; - pinctrl-1 = <&uart0_data &uart0_fctl>; + pinctrl-1 = <&uart0_data>, <&uart0_fctl>; }; Example 4: Set up the default pin state for uart controller. diff --git a/Makefile b/Makefile index 80307289c387..c628607bbceb 100644 --- a/Makefile +++ b/Makefile @@ -854,12 +854,8 @@ KBUILD_CFLAGS += $(DEBUG_CFLAGS) export DEBUG_CFLAGS ifdef CONFIG_FUNCTION_TRACER -ifdef CONFIG_FTRACE_MCOUNT_RECORD - # gcc 5 supports generating the mcount tables directly - ifeq ($(call cc-option-yn,-mrecord-mcount),y) - CC_FLAGS_FTRACE += -mrecord-mcount - export CC_USING_RECORD_MCOUNT := 1 - endif +ifdef CONFIG_FTRACE_MCOUNT_USE_CC + CC_FLAGS_FTRACE += -mrecord-mcount ifdef CONFIG_HAVE_NOP_MCOUNT ifeq ($(call cc-option-yn, -mnop-mcount),y) CC_FLAGS_FTRACE += -mnop-mcount @@ -867,6 +863,12 @@ ifdef CONFIG_FTRACE_MCOUNT_RECORD endif endif endif +ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT + ifdef CONFIG_HAVE_C_RECORDMCOUNT + BUILD_C_RECORDMCOUNT := y + export BUILD_C_RECORDMCOUNT + endif +endif ifdef CONFIG_HAVE_FENTRY ifeq ($(call cc-option-yn, -mfentry),y) CC_FLAGS_FTRACE += -mfentry @@ -876,12 +878,6 @@ endif export CC_FLAGS_FTRACE KBUILD_CFLAGS += $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING) KBUILD_AFLAGS += $(CC_FLAGS_USING) -ifdef CONFIG_DYNAMIC_FTRACE - ifdef CONFIG_HAVE_C_RECORDMCOUNT - BUILD_C_RECORDMCOUNT := y - export BUILD_C_RECORDMCOUNT - endif -endif endif # We trigger additional mismatches with less inlining @@ -900,6 +896,24 @@ KBUILD_CFLAGS += $(CC_FLAGS_SCS) export CC_FLAGS_SCS endif +ifdef CONFIG_LTO_CLANG +ifdef CONFIG_LTO_CLANG_THIN +CC_FLAGS_LTO := -flto=thin -fsplit-lto-unit +KBUILD_LDFLAGS += --thinlto-cache-dir=$(extmod-prefix).thinlto-cache +else +CC_FLAGS_LTO := -flto +endif +CC_FLAGS_LTO += -fvisibility=hidden + +# Limit inlining across translation units to reduce binary size +KBUILD_LDFLAGS += -mllvm -import-instr-limit=5 +endif + +ifdef CONFIG_LTO +KBUILD_CFLAGS += $(CC_FLAGS_LTO) +export CC_FLAGS_LTO +endif + ifdef CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B KBUILD_CFLAGS += -falign-functions=32 endif @@ -1509,7 +1523,7 @@ MRPROPER_FILES += include/config include/generated \ *.spec # Directories & files removed with 'make distclean' -DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS +DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS .thinlto-cache # clean - Delete most, but leave enough to build external modules # @@ -1755,7 +1769,7 @@ PHONY += compile_commands.json clean-dirs := $(KBUILD_EXTMOD) clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \ - $(KBUILD_EXTMOD)/compile_commands.json + $(KBUILD_EXTMOD)/compile_commands.json $(KBUILD_EXTMOD)/.thinlto-cache PHONY += help help: @@ -1854,7 +1868,8 @@ clean: $(clean-dirs) -o -name '.tmp_*.o.*' \ -o -name '*.c.[012]*.*' \ -o -name '*.ll' \ - -o -name '*.gcno' \) -type f -print | xargs rm -f + -o -name '*.gcno' \ + -o -name '*.*.symversions' \) -type f -print | xargs rm -f # Generate tags for editors # --------------------------------------------------------------------------- diff --git a/arch/Kconfig b/arch/Kconfig index 9fc4eb8bfdbc..207261f4879d 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -603,6 +603,96 @@ config SHADOW_CALL_STACK reading and writing arbitrary memory may be able to locate them and hijack control flow by modifying the stacks. +config LTO + bool + help + Selected if the kernel will be built using the compiler's LTO feature. + +config LTO_CLANG + bool + select LTO + help + Selected if the kernel will be built using Clang's LTO feature. + +config ARCH_SUPPORTS_LTO_CLANG + bool + help + An architecture should select this option if it supports: + - compiling with Clang, + - compiling inline assembly with Clang's integrated assembler, + - and linking with LLD. + +config ARCH_SUPPORTS_LTO_CLANG_THIN + bool + help + An architecture should select this option if it can support Clang's + ThinLTO mode. + +config HAS_LTO_CLANG + def_bool y + # Clang >= 11: https://github.com/ClangBuiltLinux/linux/issues/510 + depends on CC_IS_CLANG && CLANG_VERSION >= 110000 && LD_IS_LLD + depends on $(success,test $(LLVM) -eq 1) + depends on $(success,test $(LLVM_IAS) -eq 1) + depends on $(success,$(NM) --help | head -n 1 | grep -qi llvm) + depends on $(success,$(AR) --help | head -n 1 | grep -qi llvm) + depends on ARCH_SUPPORTS_LTO_CLANG + depends on !FTRACE_MCOUNT_USE_RECORDMCOUNT + depends on !KASAN + depends on !GCOV_KERNEL + help + The compiler and Kconfig options support building with Clang's + LTO. + +choice + prompt "Link Time Optimization (LTO)" + default LTO_NONE + help + This option enables Link Time Optimization (LTO), which allows the + compiler to optimize binaries globally. + + If unsure, select LTO_NONE. Note that LTO is very resource-intensive + so it's disabled by default. + +config LTO_NONE + bool "None" + help + Build the kernel normally, without Link Time Optimization (LTO). + +config LTO_CLANG_FULL + bool "Clang Full LTO (EXPERIMENTAL)" + depends on HAS_LTO_CLANG + depends on !COMPILE_TEST + select LTO_CLANG + help + This option enables Clang's full Link Time Optimization (LTO), which + allows the compiler to optimize the kernel globally. If you enable + this option, the compiler generates LLVM bitcode instead of ELF + object files, and the actual compilation from bitcode happens at + the LTO link step, which may take several minutes depending on the + kernel configuration. More information can be found from LLVM's + documentation: + + https://llvm.org/docs/LinkTimeOptimization.html + + During link time, this option can use a large amount of RAM, and + may take much longer than the ThinLTO option. + +config LTO_CLANG_THIN + bool "Clang ThinLTO (EXPERIMENTAL)" + depends on HAS_LTO_CLANG && ARCH_SUPPORTS_LTO_CLANG_THIN + select LTO_CLANG + help + This option enables Clang's ThinLTO, which allows for parallel + optimization and faster incremental compiles compared to the + CONFIG_LTO_CLANG_FULL option. More information can be found + from Clang's documentation: + + https://clang.llvm.org/docs/ThinLTO.html + + If unsure, say Y. +endchoice + config HAVE_ARCH_WITHIN_STACK_FRAMES bool help diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig index 1ef2bc4c7f69..383c632eba7b 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig @@ -176,7 +176,6 @@ CONFIG_BOOT_PRINTK_DELAY=y CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y # CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_LOCKUP_DETECTOR=y CONFIG_SCHED_TRACER=y diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index a9c6f32a9b1c..ca32446b187f 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -164,7 +164,6 @@ CONFIG_FONTS=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_WARN=2048 -CONFIG_UNUSED_SYMBOLS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_SOFTLOCKUP_DETECTOR=y diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1b8cecdc028e..fd8abf9cb312 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -73,6 +73,8 @@ config ARM64 select ARCH_SUPPORTS_DEBUG_PAGEALLOC select ARCH_SUPPORTS_MEMORY_FAILURE select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK + select ARCH_SUPPORTS_LTO_CLANG if CPU_LITTLE_ENDIAN + select ARCH_SUPPORTS_LTO_CLANG_THIN select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && (GCC_VERSION >= 50000 || CC_IS_CLANG) select ARCH_SUPPORTS_NUMA_BALANCING @@ -162,6 +164,8 @@ config ARM64 select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS \ if $(cc-option,-fpatchable-function-entry=2) + select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \ + if DYNAMIC_FTRACE_WITH_REGS select HAVE_EFFICIENT_UNALIGNED_ACCESS select HAVE_FAST_GUP select HAVE_FTRACE_MCOUNT_RECORD diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index 76c0255ecc91..945e6bb326e3 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -29,7 +29,8 @@ ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO -CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) +CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) \ + $(CC_FLAGS_LTO) KASAN_SANITIZE := n UBSAN_SANITIZE := n OBJECT_FILES_NON_STANDARD := y diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 25a5a3fb14aa..0660f47012bc 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -38,7 +38,6 @@ config MICROBLAZE select OF_EARLY_FLATTREE select PCI_DOMAINS_GENERIC if PCI select PCI_SYSCALL if PCI - select TRACING_SUPPORT select VIRT_TO_BUS select CPU_NO_EFFICIENT_FFS select MMU_GATHER_NO_RANGE diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c index 9f12e3c2bb42..e5db3a57b9e3 100644 --- a/arch/microblaze/kernel/module.c +++ b/arch/microblaze/kernel/module.c @@ -24,9 +24,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, Elf32_Sym *sym; unsigned long int *location; unsigned long int value; -#if __GNUC__ < 4 - unsigned long int old_value; -#endif pr_debug("Applying add relocation section %u to %u\n", relsec, sechdrs[relsec].sh_info); @@ -49,40 +46,17 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, */ case R_MICROBLAZE_32: -#if __GNUC__ < 4 - old_value = *location; - *location = value + old_value; - - pr_debug("R_MICROBLAZE_32 (%08lx->%08lx)\n", - old_value, value); -#else *location = value; -#endif break; case R_MICROBLAZE_64: -#if __GNUC__ < 4 - /* Split relocs only required/used pre gcc4.1.1 */ - old_value = ((location[0] & 0x0000FFFF) << 16) | - (location[1] & 0x0000FFFF); - value += old_value; -#endif location[0] = (location[0] & 0xFFFF0000) | (value >> 16); location[1] = (location[1] & 0xFFFF0000) | (value & 0xFFFF); -#if __GNUC__ < 4 - pr_debug("R_MICROBLAZE_64 (%08lx->%08lx)\n", - old_value, value); -#endif break; case R_MICROBLAZE_64_PCREL: -#if __GNUC__ < 4 - old_value = (location[0] & 0xFFFF) << 16 | - (location[1] & 0xFFFF); - value -= old_value; -#endif value -= (unsigned long int)(location) + 4; location[0] = (location[0] & 0xFFFF0000) | (value >> 16); diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index df07b3d06cd6..fb31747ec092 100644 --- a/arch/microblaze/kernel/vmlinux.lds.S +++ b/arch/microblaze/kernel/vmlinux.lds.S @@ -45,7 +45,7 @@ SECTIONS { _etext = . ; } - . = ALIGN (4) ; + . = ALIGN (8) ; __fdt_blob : AT(ADDR(__fdt_blob) - LOAD_OFFSET) { _fdt_start = . ; /* place for fdt blob */ *(__fdt_blob) ; /* Any link-placed DTB */ diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig index 72a211d2d556..32c290611723 100644 --- a/arch/mips/configs/nlm_xlp_defconfig +++ b/arch/mips/configs/nlm_xlp_defconfig @@ -549,7 +549,6 @@ CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 -CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DETECT_HUNG_TASK=y CONFIG_SCHEDSTATS=y diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig index 4ecb157e56d4..bf9b9244929e 100644 --- a/arch/mips/configs/nlm_xlr_defconfig +++ b/arch/mips/configs/nlm_xlr_defconfig @@ -500,7 +500,6 @@ CONFIG_CRC7=m CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y # CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DETECT_HUNG_TASK=y CONFIG_SCHEDSTATS=y diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig index 3cbcfad5f724..7611d48c599e 100644 --- a/arch/parisc/configs/generic-32bit_defconfig +++ b/arch/parisc/configs/generic-32bit_defconfig @@ -22,7 +22,6 @@ CONFIG_PCI_LBA=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_UNUSED_SYMBOLS=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index 8f81fcbf04c4..53054b81461a 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -31,7 +31,6 @@ CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y -CONFIG_UNUSED_SYMBOLS=y CONFIG_BLK_DEV_INTEGRITY=y CONFIG_BINFMT_MISC=m # CONFIG_COMPACTION is not set diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9141f03060ce..2ffb229d8d2d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -196,7 +196,6 @@ config PPC select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13) select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2) select HAVE_CONTEXT_TRACKING if PPC64 - select HAVE_TIF_NOHZ if PPC64 select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_STACKOVERFLOW select HAVE_DYNAMIC_FTRACE @@ -503,18 +502,14 @@ config HOTPLUG_CPU Say N if you are unsure. config PPC_QUEUED_SPINLOCKS - bool "Queued spinlocks" + bool "Queued spinlocks" if EXPERT depends on SMP + default PPC_BOOK3S_64 help Say Y here to use queued spinlocks which give better scalability and fairness on large SMP and NUMA systems without harming single threaded performance. - This option is currently experimental, the code is more complex and - less tested so it defaults to "N" for the moment. - - If unsure, say "N". - config ARCH_CPU_PROBE_RELEASE def_bool y depends on HOTPLUG_CPU @@ -718,18 +713,6 @@ config ARCH_MEMORY_PROBE def_bool y depends on MEMORY_HOTPLUG -config STDBINUTILS - bool "Using standard binutils settings" - depends on 44x - default y - help - Turning this option off allows you to select 256KB PAGE_SIZE on 44x. - Note, that kernel will be able to run only those applications, - which had been compiled using binutils later than 2.17.50.0.3 with - '-zmax-page-size' set to 256K (the default is 64K). Or, if using - the older binutils, you can patch them with a trivial patch, which - changes the ELF_MAXPAGESIZE definition from 0x10000 to 0x40000. - choice prompt "Page size" default PPC_4K_PAGES @@ -769,17 +752,15 @@ config PPC_64K_PAGES select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64 config PPC_256K_PAGES - bool "256k page size" - depends on 44x && !STDBINUTILS + bool "256k page size (Requires non-standard binutils settings)" + depends on 44x && !PPC_47x help Make the page size 256k. - As the ELF standard only requires alignment to support page - sizes up to 64k, you will need to compile all of your user - space applications with a non-standard binutils settings - (see the STDBINUTILS description for details). - - Say N unless you know what you are doing. + The kernel will only be able to run applications that have been + compiled with '-zmax-page-size' set to 256K (the default is 64K) using + binutils later than 2.17.50.0.3, or by patching the ELF_MAXPAGESIZE + definition from 0x10000 to 0x40000 in older versions. endchoice diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index b88900f4832f..ae084357994e 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -88,6 +88,7 @@ config PPC_IRQ_SOFT_MASK_DEBUG config XMON bool "Include xmon kernel debugger" depends on DEBUG_KERNEL + select CONSOLE_POLL if SERIAL_CPM_CONSOLE help Include in-kernel hooks for the xmon kernel monitor/debugger. Unless you are intending to debug the kernel, say N here. diff --git a/arch/powerpc/configs/44x/akebono_defconfig b/arch/powerpc/configs/44x/akebono_defconfig index 72b8f93a9bdd..4bc549c6edc5 100644 --- a/arch/powerpc/configs/44x/akebono_defconfig +++ b/arch/powerpc/configs/44x/akebono_defconfig @@ -20,6 +20,7 @@ CONFIG_IRQ_ALL_CPUS=y # CONFIG_COMPACTION is not set # CONFIG_SUSPEND is not set CONFIG_NET=y +CONFIG_NETDEVICES=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y @@ -40,7 +41,9 @@ CONFIG_BLK_DEV_RAM_SIZE=35000 # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set +CONFIG_ATA=y # CONFIG_SATA_PMP is not set +CONFIG_SATA_AHCI_PLATFORM=y # CONFIG_ATA_SFF is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_ADAPTEC is not set @@ -97,6 +100,8 @@ CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_HCD_PCI is not set CONFIG_USB_STORAGE=y CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_M41T80=y CONFIG_EXT2_FS=y diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 10c055eaebf0..6677ac0da45a 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -1071,7 +1071,6 @@ CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_DEBUG_INFO=y -CONFIG_UNUSED_SYMBOLS=y CONFIG_HEADERS_INSTALL=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h index d0b832cbbec8..939f3c94c8f3 100644 --- a/arch/powerpc/include/asm/asm-prototypes.h +++ b/arch/powerpc/include/asm/asm-prototypes.h @@ -56,35 +56,6 @@ int exit_vmx_usercopy(void); int enter_vmx_ops(void); void *exit_vmx_ops(void *dest); -/* Traps */ -long machine_check_early(struct pt_regs *regs); -long hmi_exception_realmode(struct pt_regs *regs); -void SMIException(struct pt_regs *regs); -void handle_hmi_exception(struct pt_regs *regs); -void instruction_breakpoint_exception(struct pt_regs *regs); -void RunModeException(struct pt_regs *regs); -void single_step_exception(struct pt_regs *regs); -void program_check_exception(struct pt_regs *regs); -void alignment_exception(struct pt_regs *regs); -void StackOverflow(struct pt_regs *regs); -void stack_overflow_exception(struct pt_regs *regs); -void kernel_fp_unavailable_exception(struct pt_regs *regs); -void altivec_unavailable_exception(struct pt_regs *regs); -void vsx_unavailable_exception(struct pt_regs *regs); -void fp_unavailable_tm(struct pt_regs *regs); -void altivec_unavailable_tm(struct pt_regs *regs); -void vsx_unavailable_tm(struct pt_regs *regs); -void facility_unavailable_exception(struct pt_regs *regs); -void TAUException(struct pt_regs *regs); -void altivec_assist_exception(struct pt_regs *regs); -void unrecoverable_exception(struct pt_regs *regs); -void kernel_bad_stack(struct pt_regs *regs); -void system_reset_exception(struct pt_regs *regs); -void machine_check_exception(struct pt_regs *regs); -void emulation_assist_interrupt(struct pt_regs *regs); -long do_slb_fault(struct pt_regs *regs, unsigned long ea); -void do_bad_slb_fault(struct pt_regs *regs, unsigned long ea, long err); - /* signals, syscalls and interrupts */ long sys_swapcontext(struct ucontext __user *old_ctx, struct ucontext __user *new_ctx, diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/include/asm/book3s/32/kup.h index a0117a9d5b06..73bc5d2c431d 100644 --- a/arch/powerpc/include/asm/book3s/32/kup.h +++ b/arch/powerpc/include/asm/book3s/32/kup.h @@ -95,12 +95,12 @@ static inline void kuap_update_sr(u32 sr, u32 addr, u32 end) addr &= 0xf0000000; /* align addr to start of segment */ barrier(); /* make sure thread.kuap is updated before playing with SRs */ while (addr < end) { - mtsrin(sr, addr); + mtsr(sr, addr); sr += 0x111; /* next VSID */ sr &= 0xf0ffffff; /* clear VSID overflow */ addr += 0x10000000; /* address of next segment */ } - isync(); /* Context sync required after mtsrin() */ + isync(); /* Context sync required after mtsr() */ } static __always_inline void allow_user_access(void __user *to, const void __user *from, @@ -122,7 +122,7 @@ static __always_inline void allow_user_access(void __user *to, const void __user end = min(addr + size, TASK_SIZE); current->thread.kuap = (addr & 0xf0000000) | ((((end - 1) >> 28) + 1) & 0xf); - kuap_update_sr(mfsrin(addr) & ~SR_KS, addr, end); /* Clear Ks */ + kuap_update_sr(mfsr(addr) & ~SR_KS, addr, end); /* Clear Ks */ } static __always_inline void prevent_user_access(void __user *to, const void __user *from, @@ -151,7 +151,7 @@ static __always_inline void prevent_user_access(void __user *to, const void __us } current->thread.kuap = 0; - kuap_update_sr(mfsrin(addr) | SR_KS, addr, end); /* set Ks */ + kuap_update_sr(mfsr(addr) | SR_KS, addr, end); /* set Ks */ } static inline unsigned long prevent_user_access_return(void) diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h index 685c589e723f..b85f8e114a9c 100644 --- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h @@ -94,7 +94,7 @@ typedef struct { } mm_context_t; void update_bats(void); -static inline void cleanup_cpu_mmu_context(void) { }; +static inline void cleanup_cpu_mmu_context(void) { } /* patch sites */ extern s32 patch__hash_page_A0, patch__hash_page_A1, patch__hash_page_A2; diff --git a/arch/powerpc/include/asm/book3s/64/kup.h b/arch/powerpc/include/asm/book3s/64/kup.h index 7d1ef7b9754e..8bd905050896 100644 --- a/arch/powerpc/include/asm/book3s/64/kup.h +++ b/arch/powerpc/include/asm/book3s/64/kup.h @@ -339,7 +339,7 @@ static inline unsigned long get_kuap(void) * This has no effect in terms of actually blocking things on hash, * so it doesn't break anything. */ - if (!early_mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) + if (!mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) return AMR_KUAP_BLOCKED; return mfspr(SPRN_AMR); @@ -347,7 +347,7 @@ static inline unsigned long get_kuap(void) static inline void set_kuap(unsigned long value) { - if (!early_mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) + if (!mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) return; /* diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 066b1d34c7bc..f911bdb68d8b 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -454,6 +454,8 @@ static inline unsigned long hpt_hash(unsigned long vpn, #define HPTE_NOHPTE_UPDATE 0x2 #define HPTE_USE_KERNEL_KEY 0x4 +long hpte_insert_repeating(unsigned long hash, unsigned long vpn, unsigned long pa, + unsigned long rlags, unsigned long vflags, int psize, int ssize); extern int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, pte_t *ptep, unsigned long trap, unsigned long flags, int ssize, int subpage_prot); @@ -467,6 +469,8 @@ extern int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long flags); extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap, unsigned long dsisr); +void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc); +int __hash_page(unsigned long trap, unsigned long ea, unsigned long dsisr, unsigned long msr); int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, pte_t *ptep, unsigned long trap, unsigned long flags, int ssize, unsigned int shift, unsigned int mmu_psize); @@ -521,6 +525,7 @@ void slb_dump_contents(struct slb_entry *slb_ptr); extern void slb_vmalloc_update(void); extern void slb_set_size(u16 size); +void preload_new_slb_context(unsigned long start, unsigned long sp); #endif /* __ASSEMBLY__ */ /* diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 995bbcdd0ef8..eace8c3f7b0a 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -239,7 +239,7 @@ static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base, #ifdef CONFIG_PPC_PSERIES extern void radix_init_pseries(void); #else -static inline void radix_init_pseries(void) { }; +static inline void radix_init_pseries(void) { } #endif #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index a39886681629..058601efbc8a 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -388,11 +388,28 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm, #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define ptep_test_and_clear_young(__vma, __addr, __ptep) \ ({ \ - int __r; \ - __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \ - __r; \ + __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \ }) +/* + * On Book3S CPUs, clearing the accessed bit without a TLB flush + * doesn't cause data corruption. [ It could cause incorrect + * page aging and the (mistaken) reclaim of hot pages, but the + * chance of that should be relatively low. ] + * + * So as a performance optimization don't flush the TLB when + * clearing the accessed bit, it will eventually be flushed by + * a context switch or a VM operation anyway. [ In the rare + * event of it not getting flushed for a long time the delay + * shouldn't really matter because there's no real memory + * pressure for swapout to react to. ] + */ +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH +#define ptep_clear_flush_young ptep_test_and_clear_young + +#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH +#define pmdp_clear_flush_young pmdp_test_and_clear_young + static inline int __pte_write(pte_t pte) { return !!(pte_raw(pte) & cpu_to_be64(_PAGE_WRITE)); diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h index 94439e0cefc9..8b33601cdb9d 100644 --- a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h +++ b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h @@ -35,7 +35,7 @@ extern void radix__flush_pwc_lpid(unsigned int lpid); extern void radix__flush_all_lpid(unsigned int lpid); extern void radix__flush_all_lpid_guest(unsigned int lpid); #else -static inline void radix__tlbiel_all(unsigned int action) { WARN_ON(1); }; +static inline void radix__tlbiel_all(unsigned int action) { WARN_ON(1); } static inline void radix__flush_tlb_lpid_page(unsigned int lpid, unsigned long addr, unsigned long page_size) diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush.h b/arch/powerpc/include/asm/book3s/64/tlbflush.h index dcb5c3839d2f..215973b4cb26 100644 --- a/arch/powerpc/include/asm/book3s/64/tlbflush.h +++ b/arch/powerpc/include/asm/book3s/64/tlbflush.h @@ -31,7 +31,7 @@ static inline void tlbiel_all(void) hash__tlbiel_all(TLB_INVAL_SCOPE_GLOBAL); } #else -static inline void tlbiel_all(void) { BUG(); }; +static inline void tlbiel_all(void) { BUG(); } #endif static inline void tlbiel_all_lpid(bool radix) diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index 464f8ca8a5c9..d1635ffbb179 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -111,12 +111,15 @@ #ifndef __ASSEMBLY__ struct pt_regs; -extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); -extern void bad_page_fault(struct pt_regs *, unsigned long, int); -void __bad_page_fault(struct pt_regs *regs, unsigned long address, int sig); +long do_page_fault(struct pt_regs *); +long hash__do_page_fault(struct pt_regs *); +void bad_page_fault(struct pt_regs *, int); +void __bad_page_fault(struct pt_regs *regs, int sig); +void do_bad_page_fault_segv(struct pt_regs *regs); extern void _exception(int, struct pt_regs *, int, unsigned long); extern void _exception_pkey(struct pt_regs *, unsigned long, int); extern void die(const char *, struct pt_regs *, long); +void die_mce(const char *str, struct pt_regs *regs, long err); extern bool die_will_crash(void); extern void panic_flush_kmsg_start(void); extern void panic_flush_kmsg_end(void); diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 138e46d8c04e..f63495109f63 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -8,6 +8,12 @@ #include #include +/* + * This flag is used to indicate that the page pointed to by a pte is clean + * and does not require cleaning before returning it to the user. + */ +#define PG_dcache_clean PG_arch_1 + #ifdef CONFIG_PPC_BOOK3S_64 /* * Book3s has no ptesync after setting a pte, so without this ptesync it's diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index ed75d1c318e3..504f7fe6711a 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -87,6 +87,17 @@ static notrace inline void account_cpu_user_exit(void) acct->starttime_user = tb; } +static notrace inline void account_stolen_time(void) +{ +#ifdef CONFIG_PPC_SPLPAR + if (firmware_has_feature(FW_FEATURE_SPLPAR)) { + struct lppaca *lp = local_paca->lppaca_ptr; + + if (unlikely(local_paca->dtl_ridx != be64_to_cpu(lp->dtl_idx))) + accumulate_stolen_time(); + } +#endif +} #endif /* __KERNEL__ */ #else /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ @@ -96,5 +107,8 @@ static inline void account_cpu_user_entry(void) static inline void account_cpu_user_exit(void) { } +static notrace inline void account_stolen_time(void) +{ +} #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ #endif /* __POWERPC_CPUTIME_H */ diff --git a/arch/powerpc/include/asm/debug.h b/arch/powerpc/include/asm/debug.h index ec57daf87f40..86a14736c76c 100644 --- a/arch/powerpc/include/asm/debug.h +++ b/arch/powerpc/include/asm/debug.h @@ -50,10 +50,6 @@ bool ppc_breakpoint_available(void); #ifdef CONFIG_PPC_ADV_DEBUG_REGS extern void do_send_trap(struct pt_regs *regs, unsigned long address, unsigned long error_code, int brkpt); -#else - -extern void do_break(struct pt_regs *regs, unsigned long address, - unsigned long error_code); #endif #endif /* _ASM_POWERPC_DEBUG_H */ diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index aa6a5ef5d483..7604673787d6 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h @@ -137,7 +137,7 @@ extern unsigned int __start___fw_ftr_fixup, __stop___fw_ftr_fixup; #ifdef CONFIG_PPC_PSERIES void pseries_probe_fw_features(void); #else -static inline void pseries_probe_fw_features(void) { }; +static inline void pseries_probe_fw_features(void) { } #endif #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 013165e62618..f18c543bc01d 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -17,8 +17,6 @@ extern bool hugetlb_disabled; void hugetlbpage_init_default(void); -void flush_dcache_icache_hugepage(struct page *page); - int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, unsigned long len); diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index 0363734ff56e..56a98936a6a9 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -38,6 +38,8 @@ #define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE) #endif +#endif /* CONFIG_PPC64 */ + /* * flags for paca->irq_soft_mask */ @@ -46,18 +48,56 @@ #define IRQS_PMI_DISABLED 2 #define IRQS_ALL_DISABLED (IRQS_DISABLED | IRQS_PMI_DISABLED) -#endif /* CONFIG_PPC64 */ - #ifndef __ASSEMBLY__ -extern void replay_system_reset(void); -extern void replay_soft_interrupts(void); +static inline void __hard_irq_enable(void) +{ + if (IS_ENABLED(CONFIG_BOOKE) || IS_ENABLED(CONFIG_40x)) + wrtee(MSR_EE); + else if (IS_ENABLED(CONFIG_PPC_8xx)) + wrtspr(SPRN_EIE); + else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) + __mtmsrd(MSR_EE | MSR_RI, 1); + else + mtmsr(mfmsr() | MSR_EE); +} -extern void timer_interrupt(struct pt_regs *); -extern void timer_broadcast_interrupt(void); -extern void performance_monitor_exception(struct pt_regs *regs); -extern void WatchdogException(struct pt_regs *regs); -extern void unknown_exception(struct pt_regs *regs); +static inline void __hard_irq_disable(void) +{ + if (IS_ENABLED(CONFIG_BOOKE) || IS_ENABLED(CONFIG_40x)) + wrtee(0); + else if (IS_ENABLED(CONFIG_PPC_8xx)) + wrtspr(SPRN_EID); + else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) + __mtmsrd(MSR_RI, 1); + else + mtmsr(mfmsr() & ~MSR_EE); +} + +static inline void __hard_EE_RI_disable(void) +{ + if (IS_ENABLED(CONFIG_BOOKE) || IS_ENABLED(CONFIG_40x)) + wrtee(0); + else if (IS_ENABLED(CONFIG_PPC_8xx)) + wrtspr(SPRN_NRI); + else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) + __mtmsrd(0, 1); + else + mtmsr(mfmsr() & ~(MSR_EE | MSR_RI)); +} + +static inline void __hard_RI_enable(void) +{ + if (IS_ENABLED(CONFIG_BOOKE) || IS_ENABLED(CONFIG_40x)) + return; + + if (IS_ENABLED(CONFIG_PPC_8xx)) + wrtspr(SPRN_EID); + else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) + __mtmsrd(MSR_RI, 1); + else + mtmsr(mfmsr() | MSR_RI); +} #ifdef CONFIG_PPC64 #include @@ -221,18 +261,6 @@ static inline bool arch_irqs_disabled(void) #endif /* CONFIG_PPC_BOOK3S */ -#ifdef CONFIG_PPC_BOOK3E -#define __hard_irq_enable() wrtee(MSR_EE) -#define __hard_irq_disable() wrtee(0) -#define __hard_EE_RI_disable() wrtee(0) -#define __hard_RI_enable() do { } while (0) -#else -#define __hard_irq_enable() __mtmsrd(MSR_EE|MSR_RI, 1) -#define __hard_irq_disable() __mtmsrd(MSR_RI, 1) -#define __hard_EE_RI_disable() __mtmsrd(0, 1) -#define __hard_RI_enable() __mtmsrd(MSR_RI, 1) -#endif - #define hard_irq_disable() do { \ unsigned long flags; \ __hard_irq_disable(); \ @@ -296,8 +324,17 @@ extern void irq_set_pending_from_srr1(unsigned long srr1); extern void force_external_irq_replay(void); +static inline void irq_soft_mask_regs_set_state(struct pt_regs *regs, unsigned long val) +{ + regs->softe = val; +} #else /* CONFIG_PPC64 */ +static inline notrace unsigned long irq_soft_mask_return(void) +{ + return 0; +} + static inline unsigned long arch_local_save_flags(void) { return mfmsr(); @@ -327,22 +364,12 @@ static inline unsigned long arch_local_irq_save(void) static inline void arch_local_irq_disable(void) { - if (IS_ENABLED(CONFIG_BOOKE)) - wrtee(0); - else if (IS_ENABLED(CONFIG_PPC_8xx)) - wrtspr(SPRN_EID); - else - mtmsr(mfmsr() & ~MSR_EE); + __hard_irq_disable(); } static inline void arch_local_irq_enable(void) { - if (IS_ENABLED(CONFIG_BOOKE)) - wrtee(MSR_EE); - else if (IS_ENABLED(CONFIG_PPC_8xx)) - wrtspr(SPRN_EIE); - else - mtmsr(mfmsr() | MSR_EE); + __hard_irq_enable(); } static inline bool arch_irqs_disabled_flags(unsigned long flags) @@ -364,6 +391,9 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs) static inline void may_hard_irq_enable(void) { } +static inline void irq_soft_mask_regs_set_state(struct pt_regs *regs, unsigned long val) +{ +} #endif /* CONFIG_PPC64 */ #define ARCH_IRQ_INIT_FLAGS IRQ_NOREQUEST diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h new file mode 100644 index 000000000000..aedfba29e43a --- /dev/null +++ b/arch/powerpc/include/asm/interrupt.h @@ -0,0 +1,449 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _ASM_POWERPC_INTERRUPT_H +#define _ASM_POWERPC_INTERRUPT_H + +#include +#include +#include +#include +#include +#include + +struct interrupt_state { +#ifdef CONFIG_PPC_BOOK3E_64 + enum ctx_state ctx_state; +#endif +}; + +static inline void booke_restore_dbcr0(void) +{ +#ifdef CONFIG_PPC_ADV_DEBUG_REGS + unsigned long dbcr0 = current->thread.debug.dbcr0; + + if (IS_ENABLED(CONFIG_PPC32) && unlikely(dbcr0 & DBCR0_IDM)) { + mtspr(SPRN_DBSR, -1); + mtspr(SPRN_DBCR0, global_dbcr0[smp_processor_id()]); + } +#endif +} + +static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrupt_state *state) +{ + /* + * Book3E reconciles irq soft mask in asm + */ +#ifdef CONFIG_PPC_BOOK3S_64 + if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED) + trace_hardirqs_off(); + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; + + if (user_mode(regs)) { + CT_WARN_ON(ct_state() != CONTEXT_USER); + user_exit_irqoff(); + + account_cpu_user_entry(); + account_stolen_time(); + } else { + /* + * CT_WARN_ON comes here via program_check_exception, + * so avoid recursion. + */ + if (TRAP(regs) != 0x700) + CT_WARN_ON(ct_state() != CONTEXT_KERNEL); + } +#endif + +#ifdef CONFIG_PPC_BOOK3E_64 + state->ctx_state = exception_enter(); + if (user_mode(regs)) + account_cpu_user_entry(); +#endif +} + +/* + * Care should be taken to note that interrupt_exit_prepare and + * interrupt_async_exit_prepare do not necessarily return immediately to + * regs context (e.g., if regs is usermode, we don't necessarily return to + * user mode). Other interrupts might be taken between here and return, + * context switch / preemption may occur in the exit path after this, or a + * signal may be delivered, etc. + * + * The real interrupt exit code is platform specific, e.g., + * interrupt_exit_user_prepare / interrupt_exit_kernel_prepare for 64s. + * + * However interrupt_nmi_exit_prepare does return directly to regs, because + * NMIs do not do "exit work" or replay soft-masked interrupts. + */ +static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interrupt_state *state) +{ +#ifdef CONFIG_PPC_BOOK3E_64 + exception_exit(state->ctx_state); +#endif + + /* + * Book3S exits to user via interrupt_exit_user_prepare(), which does + * context tracking, which is a cleaner way to handle PREEMPT=y + * and avoid context entry/exit in e.g., preempt_schedule_irq()), + * which is likely to be where the core code wants to end up. + * + * The above comment explains why we can't do the + * + * if (user_mode(regs)) + * user_exit_irqoff(); + * + * sequence here. + */ +} + +static inline void interrupt_async_enter_prepare(struct pt_regs *regs, struct interrupt_state *state) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + if (cpu_has_feature(CPU_FTR_CTRL) && + !test_thread_local_flags(_TLF_RUNLATCH)) + __ppc64_runlatch_on(); +#endif + + interrupt_enter_prepare(regs, state); + irq_enter(); +} + +static inline void interrupt_async_exit_prepare(struct pt_regs *regs, struct interrupt_state *state) +{ + irq_exit(); + interrupt_exit_prepare(regs, state); +} + +struct interrupt_nmi_state { +#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S_64 + u8 irq_soft_mask; + u8 irq_happened; +#endif + u8 ftrace_enabled; +#endif +}; + +static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct interrupt_nmi_state *state) +{ +#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S_64 + state->irq_soft_mask = local_paca->irq_soft_mask; + state->irq_happened = local_paca->irq_happened; + + /* + * Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does + * the right thing, and set IRQ_HARD_DIS. We do not want to reconcile + * because that goes through irq tracing which we don't want in NMI. + */ + local_paca->irq_soft_mask = IRQS_ALL_DISABLED; + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; + + /* Don't do any per-CPU operations until interrupt state is fixed */ +#endif + /* Allow DEC and PMI to be traced when they are soft-NMI */ + if (TRAP(regs) != 0x900 && TRAP(regs) != 0xf00 && TRAP(regs) != 0x260) { + state->ftrace_enabled = this_cpu_get_ftrace_enabled(); + this_cpu_set_ftrace_enabled(0); + } +#endif + + /* + * Do not use nmi_enter() for pseries hash guest taking a real-mode + * NMI because not everything it touches is within the RMA limit. + */ + if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) || + !firmware_has_feature(FW_FEATURE_LPAR) || + radix_enabled() || (mfmsr() & MSR_DR)) + nmi_enter(); +} + +static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct interrupt_nmi_state *state) +{ + if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) || + !firmware_has_feature(FW_FEATURE_LPAR) || + radix_enabled() || (mfmsr() & MSR_DR)) + nmi_exit(); + +#ifdef CONFIG_PPC64 + if (TRAP(regs) != 0x900 && TRAP(regs) != 0xf00 && TRAP(regs) != 0x260) + this_cpu_set_ftrace_enabled(state->ftrace_enabled); + +#ifdef CONFIG_PPC_BOOK3S_64 + /* Check we didn't change the pending interrupt mask. */ + WARN_ON_ONCE((state->irq_happened | PACA_IRQ_HARD_DIS) != local_paca->irq_happened); + local_paca->irq_happened = state->irq_happened; + local_paca->irq_soft_mask = state->irq_soft_mask; +#endif +#endif +} + +/* + * Don't use noinstr here like x86, but rather add NOKPROBE_SYMBOL to each + * function definition. The reason for this is the noinstr section is placed + * after the main text section, i.e., very far away from the interrupt entry + * asm. That creates problems with fitting linker stubs when building large + * kernels. + */ +#define interrupt_handler __visible noinline notrace __no_kcsan __no_sanitize_address + +/** + * DECLARE_INTERRUPT_HANDLER_RAW - Declare raw interrupt handler function + * @func: Function name of the entry point + * @returns: Returns a value back to asm caller + */ +#define DECLARE_INTERRUPT_HANDLER_RAW(func) \ + __visible long func(struct pt_regs *regs) + +/** + * DEFINE_INTERRUPT_HANDLER_RAW - Define raw interrupt handler function + * @func: Function name of the entry point + * @returns: Returns a value back to asm caller + * + * @func is called from ASM entry code. + * + * This is a plain function which does no tracing, reconciling, etc. + * The macro is written so it acts as function definition. Append the + * body with a pair of curly brackets. + * + * raw interrupt handlers must not enable or disable interrupts, or + * schedule, tracing and instrumentation (ftrace, lockdep, etc) would + * not be advisable either, although may be possible in a pinch, the + * trace will look odd at least. + * + * A raw handler may call one of the other interrupt handler functions + * to be converted into that interrupt context without these restrictions. + * + * On PPC64, _RAW handlers may return with fast_interrupt_return. + * + * Specific handlers may have additional restrictions. + */ +#define DEFINE_INTERRUPT_HANDLER_RAW(func) \ +static __always_inline long ____##func(struct pt_regs *regs); \ + \ +interrupt_handler long func(struct pt_regs *regs) \ +{ \ + long ret; \ + \ + ret = ____##func (regs); \ + \ + return ret; \ +} \ +NOKPROBE_SYMBOL(func); \ + \ +static __always_inline long ____##func(struct pt_regs *regs) + +/** + * DECLARE_INTERRUPT_HANDLER - Declare synchronous interrupt handler function + * @func: Function name of the entry point + */ +#define DECLARE_INTERRUPT_HANDLER(func) \ + __visible void func(struct pt_regs *regs) + +/** + * DEFINE_INTERRUPT_HANDLER - Define synchronous interrupt handler function + * @func: Function name of the entry point + * + * @func is called from ASM entry code. + * + * The macro is written so it acts as function definition. Append the + * body with a pair of curly brackets. + */ +#define DEFINE_INTERRUPT_HANDLER(func) \ +static __always_inline void ____##func(struct pt_regs *regs); \ + \ +interrupt_handler void func(struct pt_regs *regs) \ +{ \ + struct interrupt_state state; \ + \ + interrupt_enter_prepare(regs, &state); \ + \ + ____##func (regs); \ + \ + interrupt_exit_prepare(regs, &state); \ +} \ +NOKPROBE_SYMBOL(func); \ + \ +static __always_inline void ____##func(struct pt_regs *regs) + +/** + * DECLARE_INTERRUPT_HANDLER_RET - Declare synchronous interrupt handler function + * @func: Function name of the entry point + * @returns: Returns a value back to asm caller + */ +#define DECLARE_INTERRUPT_HANDLER_RET(func) \ + __visible long func(struct pt_regs *regs) + +/** + * DEFINE_INTERRUPT_HANDLER_RET - Define synchronous interrupt handler function + * @func: Function name of the entry point + * @returns: Returns a value back to asm caller + * + * @func is called from ASM entry code. + * + * The macro is written so it acts as function definition. Append the + * body with a pair of curly brackets. + */ +#define DEFINE_INTERRUPT_HANDLER_RET(func) \ +static __always_inline long ____##func(struct pt_regs *regs); \ + \ +interrupt_handler long func(struct pt_regs *regs) \ +{ \ + struct interrupt_state state; \ + long ret; \ + \ + interrupt_enter_prepare(regs, &state); \ + \ + ret = ____##func (regs); \ + \ + interrupt_exit_prepare(regs, &state); \ + \ + return ret; \ +} \ +NOKPROBE_SYMBOL(func); \ + \ +static __always_inline long ____##func(struct pt_regs *regs) + +/** + * DECLARE_INTERRUPT_HANDLER_ASYNC - Declare asynchronous interrupt handler function + * @func: Function name of the entry point + */ +#define DECLARE_INTERRUPT_HANDLER_ASYNC(func) \ + __visible void func(struct pt_regs *regs) + +/** + * DEFINE_INTERRUPT_HANDLER_ASYNC - Define asynchronous interrupt handler function + * @func: Function name of the entry point + * + * @func is called from ASM entry code. + * + * The macro is written so it acts as function definition. Append the + * body with a pair of curly brackets. + */ +#define DEFINE_INTERRUPT_HANDLER_ASYNC(func) \ +static __always_inline void ____##func(struct pt_regs *regs); \ + \ +interrupt_handler void func(struct pt_regs *regs) \ +{ \ + struct interrupt_state state; \ + \ + interrupt_async_enter_prepare(regs, &state); \ + \ + ____##func (regs); \ + \ + interrupt_async_exit_prepare(regs, &state); \ +} \ +NOKPROBE_SYMBOL(func); \ + \ +static __always_inline void ____##func(struct pt_regs *regs) + +/** + * DECLARE_INTERRUPT_HANDLER_NMI - Declare NMI interrupt handler function + * @func: Function name of the entry point + * @returns: Returns a value back to asm caller + */ +#define DECLARE_INTERRUPT_HANDLER_NMI(func) \ + __visible long func(struct pt_regs *regs) + +/** + * DEFINE_INTERRUPT_HANDLER_NMI - Define NMI interrupt handler function + * @func: Function name of the entry point + * @returns: Returns a value back to asm caller + * + * @func is called from ASM entry code. + * + * The macro is written so it acts as function definition. Append the + * body with a pair of curly brackets. + */ +#define DEFINE_INTERRUPT_HANDLER_NMI(func) \ +static __always_inline long ____##func(struct pt_regs *regs); \ + \ +interrupt_handler long func(struct pt_regs *regs) \ +{ \ + struct interrupt_nmi_state state; \ + long ret; \ + \ + interrupt_nmi_enter_prepare(regs, &state); \ + \ + ret = ____##func (regs); \ + \ + interrupt_nmi_exit_prepare(regs, &state); \ + \ + return ret; \ +} \ +NOKPROBE_SYMBOL(func); \ + \ +static __always_inline long ____##func(struct pt_regs *regs) + + +/* Interrupt handlers */ +/* kernel/traps.c */ +DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception); +#ifdef CONFIG_PPC_BOOK3S_64 +DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception); +#else +DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception); +#endif +DECLARE_INTERRUPT_HANDLER(SMIException); +DECLARE_INTERRUPT_HANDLER(handle_hmi_exception); +DECLARE_INTERRUPT_HANDLER(unknown_exception); +DECLARE_INTERRUPT_HANDLER_ASYNC(unknown_async_exception); +DECLARE_INTERRUPT_HANDLER(instruction_breakpoint_exception); +DECLARE_INTERRUPT_HANDLER(RunModeException); +DECLARE_INTERRUPT_HANDLER(single_step_exception); +DECLARE_INTERRUPT_HANDLER(program_check_exception); +DECLARE_INTERRUPT_HANDLER(emulation_assist_interrupt); +DECLARE_INTERRUPT_HANDLER(alignment_exception); +DECLARE_INTERRUPT_HANDLER(StackOverflow); +DECLARE_INTERRUPT_HANDLER(stack_overflow_exception); +DECLARE_INTERRUPT_HANDLER(kernel_fp_unavailable_exception); +DECLARE_INTERRUPT_HANDLER(altivec_unavailable_exception); +DECLARE_INTERRUPT_HANDLER(vsx_unavailable_exception); +DECLARE_INTERRUPT_HANDLER(facility_unavailable_exception); +DECLARE_INTERRUPT_HANDLER(fp_unavailable_tm); +DECLARE_INTERRUPT_HANDLER(altivec_unavailable_tm); +DECLARE_INTERRUPT_HANDLER(vsx_unavailable_tm); +DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi); +DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async); +DECLARE_INTERRUPT_HANDLER_RAW(performance_monitor_exception); +DECLARE_INTERRUPT_HANDLER(DebugException); +DECLARE_INTERRUPT_HANDLER(altivec_assist_exception); +DECLARE_INTERRUPT_HANDLER(CacheLockingException); +DECLARE_INTERRUPT_HANDLER(SPEFloatingPointException); +DECLARE_INTERRUPT_HANDLER(SPEFloatingPointRoundException); +DECLARE_INTERRUPT_HANDLER(unrecoverable_exception); +DECLARE_INTERRUPT_HANDLER(WatchdogException); +DECLARE_INTERRUPT_HANDLER(kernel_bad_stack); + +/* slb.c */ +DECLARE_INTERRUPT_HANDLER_RAW(do_slb_fault); +DECLARE_INTERRUPT_HANDLER(do_bad_slb_fault); + +/* hash_utils.c */ +DECLARE_INTERRUPT_HANDLER_RAW(do_hash_fault); + +/* fault.c */ +DECLARE_INTERRUPT_HANDLER_RET(do_page_fault); +DECLARE_INTERRUPT_HANDLER(do_bad_page_fault_segv); + +/* process.c */ +DECLARE_INTERRUPT_HANDLER(do_break); + +/* time.c */ +DECLARE_INTERRUPT_HANDLER_ASYNC(timer_interrupt); + +/* mce.c */ +DECLARE_INTERRUPT_HANDLER_NMI(machine_check_early); +DECLARE_INTERRUPT_HANDLER_NMI(hmi_exception_realmode); + +DECLARE_INTERRUPT_HANDLER_ASYNC(TAUException); + +void replay_system_reset(void); +void replay_soft_interrupts(void); + +static inline void interrupt_cond_local_irq_enable(struct pt_regs *regs) +{ + if (!arch_irq_disabled_regs(regs)) + local_irq_enable(); +} + +#endif /* _ASM_POWERPC_INTERRUPT_H */ diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index 55d6ede30c19..9ab344d29a54 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h @@ -136,6 +136,7 @@ int load_crashdump_segments_ppc64(struct kimage *image, int setup_purgatory_ppc64(struct kimage *image, const void *slave_code, const void *fdt, unsigned long kernel_load_addr, unsigned long fdt_load_addr); +unsigned int kexec_fdt_totalsize_ppc64(struct kimage *image); int setup_new_fdt_ppc64(const struct kimage *image, void *fdt, unsigned long initrd_load_addr, unsigned long initrd_len, const char *cmdline); diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h index bf221a2a523e..7ec21af49a45 100644 --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -91,6 +91,7 @@ static __always_inline void setup_kup(void) static inline void allow_read_from_user(const void __user *from, unsigned long size) { + barrier_nospec(); allow_user_access(NULL, from, size, KUAP_READ); } @@ -102,6 +103,7 @@ static inline void allow_write_to_user(void __user *to, unsigned long size) static inline void allow_read_write_user(void __user *to, const void __user *from, unsigned long size) { + barrier_nospec(); allow_user_access(to, from, size, KUAP_READ_WRITE); } diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index d32ec9ae73bd..2f5f919f6cd3 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -277,6 +277,13 @@ extern int kvmppc_hcall_impl_hv_realmode(unsigned long cmd); extern void kvmppc_copy_to_svcpu(struct kvm_vcpu *vcpu); extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu); +long kvmppc_read_intr(void); +void kvmppc_bad_interrupt(struct pt_regs *regs); +void kvmhv_p9_set_lpcr(struct kvm_split_mode *sip); +void kvmhv_p9_restore_lpcr(struct kvm_split_mode *sip); +void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr); +void kvmppc_inject_interrupt_hv(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags); + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM void kvmppc_save_tm_pr(struct kvm_vcpu *vcpu); void kvmppc_restore_tm_pr(struct kvm_vcpu *vcpu); diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index df4bda867bab..8aacd76bb702 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -629,9 +629,9 @@ extern int h_ipi_redirect; static inline struct kvmppc_passthru_irqmap *kvmppc_get_passthru_irqmap( struct kvm *kvm) { return NULL; } -static inline void kvmppc_alloc_host_rm_ops(void) {}; -static inline void kvmppc_free_host_rm_ops(void) {}; -static inline void kvmppc_free_pimap(struct kvm *kvm) {}; +static inline void kvmppc_alloc_host_rm_ops(void) {} +static inline void kvmppc_free_host_rm_ops(void) {} +static inline void kvmppc_free_pimap(struct kvm *kvm) {} static inline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall) { return 0; } static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu) @@ -883,9 +883,9 @@ static inline void kvmppc_mmu_flush_icache(kvm_pfn_t pfn) /* Clear i-cache for new pages */ page = pfn_to_page(pfn); - if (!test_bit(PG_arch_1, &page->flags)) { + if (!test_bit(PG_dcache_clean, &page->flags)) { flush_dcache_icache_page(page); - set_bit(PG_arch_1, &page->flags); + set_bit(PG_dcache_clean, &page->flags); } } diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index cf6ebbc16cb4..764f2732a821 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -59,6 +59,9 @@ struct machdep_calls { int (*pcibios_root_bridge_prepare)(struct pci_host_bridge *bridge); + /* finds all the pci_controllers present at boot */ + void (*discover_phbs)(void); + /* To setup PHBs when using automatic OF platform driver for PCI */ int (*pci_setup_phb)(struct pci_controller *host); diff --git a/arch/powerpc/include/asm/mce.h b/arch/powerpc/include/asm/mce.h index e6c27ae843dc..331d944280b8 100644 --- a/arch/powerpc/include/asm/mce.h +++ b/arch/powerpc/include/asm/mce.h @@ -204,7 +204,18 @@ struct mce_error_info { bool ignore_event; }; -#define MAX_MC_EVT 100 +#define MAX_MC_EVT 10 + +struct mce_info { + int mce_nest_count; + struct machine_check_event mce_event[MAX_MC_EVT]; + /* Queue for delayed MCE events. */ + int mce_queue_count; + struct machine_check_event mce_event_queue[MAX_MC_EVT]; + /* Queue for delayed MCE UE events. */ + int mce_ue_count; + struct machine_check_event mce_ue_event_queue[MAX_MC_EVT]; +}; /* Release flags for get_mce_event() */ #define MCE_EVENT_RELEASE true @@ -234,4 +245,11 @@ long __machine_check_early_realmode_p8(struct pt_regs *regs); long __machine_check_early_realmode_p9(struct pt_regs *regs); long __machine_check_early_realmode_p10(struct pt_regs *regs); #endif /* CONFIG_PPC_BOOK3S_64 */ + +#ifdef CONFIG_PPC_BOOK3S_64 +void mce_init(void); +#else +static inline void mce_init(void) { }; +#endif /* CONFIG_PPC_BOOK3S_64 */ + #endif /* __ASM_PPC64_MCE_H__ */ diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index d5821834dba9..652ce85f9410 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -282,9 +282,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, } #define pkey_mm_init(mm) -#define thread_pkey_regs_save(thread) -#define thread_pkey_regs_restore(new_thread, old_thread) -#define thread_pkey_regs_init(thread) #define arch_dup_pkeys(oldmm, mm) static inline u64 pte_to_hpte_pkey_bits(u64 pteflags, unsigned long flags) diff --git a/arch/powerpc/include/asm/nmi.h b/arch/powerpc/include/asm/nmi.h index 84b4cfe73edd..160abcb8e9fa 100644 --- a/arch/powerpc/include/asm/nmi.h +++ b/arch/powerpc/include/asm/nmi.h @@ -4,6 +4,7 @@ #ifdef CONFIG_PPC_WATCHDOG extern void arch_touch_nmi_watchdog(void); +long soft_nmi_interrupt(struct pt_regs *regs); #else static inline void arch_touch_nmi_watchdog(void) {} #endif diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 9454d29ff4b4..ec18ac818e3a 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -108,8 +109,7 @@ struct paca_struct { */ /* used for most interrupts/exceptions */ u64 exgen[EX_SIZE] __attribute__((aligned(0x80))); - u64 exslb[EX_SIZE]; /* used for SLB/segment table misses - * on the linear mapping */ + /* SLB related definitions */ u16 vmalloc_sllp; u8 slb_cache_ptr; @@ -273,6 +273,9 @@ struct paca_struct { #ifdef CONFIG_MMIOWB struct mmiowb_state mmiowb_state; #endif +#ifdef CONFIG_PPC_BOOK3S_64 + struct mce_info *mce_info; +#endif /* CONFIG_PPC_BOOK3S_64 */ } ____cacheline_aligned; extern void copy_mm_to_paca(struct mm_struct *mm); @@ -285,9 +288,9 @@ extern void free_unused_pacas(void); #else /* CONFIG_PPC64 */ -static inline void allocate_paca_ptrs(void) { }; -static inline void allocate_paca(int cpu) { }; -static inline void free_unused_pacas(void) { }; +static inline void allocate_paca_ptrs(void) { } +static inline void allocate_paca(int cpu) { } +static inline void free_unused_pacas(void) { } #endif /* CONFIG_PPC64 */ diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h index edc08f04aef7..5d1726bb28e7 100644 --- a/arch/powerpc/include/asm/paravirt.h +++ b/arch/powerpc/include/asm/paravirt.h @@ -10,6 +10,7 @@ #endif #ifdef CONFIG_PPC_SPLPAR +#include #include #include diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h index daec64d41b44..164e910bf654 100644 --- a/arch/powerpc/include/asm/perf_event.h +++ b/arch/powerpc/include/asm/perf_event.h @@ -14,6 +14,7 @@ #include #else static inline bool is_sier_available(void) { return false; } +static inline unsigned long get_pmcs_ext_regs(int idx) { return 0; } #endif #ifdef CONFIG_FSL_EMB_PERF_EVENT @@ -40,6 +41,7 @@ static inline bool is_sier_available(void) { return false; } /* To support perf_regs sier update */ extern bool is_sier_available(void); +extern unsigned long get_pmcs_ext_regs(int idx); /* To define perf extended regs mask value */ extern u64 PERF_REG_EXTENDED_MASK; #define PERF_REG_EXTENDED_MASK PERF_REG_EXTENDED_MASK diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index 3b7baba01c92..00e7e671bb4b 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h @@ -36,9 +36,9 @@ struct power_pmu { unsigned long test_adder; int (*compute_mmcr)(u64 events[], int n_ev, unsigned int hwc[], struct mmcr_regs *mmcr, - struct perf_event *pevents[]); + struct perf_event *pevents[], u32 flags); int (*get_constraint)(u64 event_id, unsigned long *mskp, - unsigned long *valp); + unsigned long *valp, u64 event_config1); int (*get_alternatives)(u64 event_id, unsigned int flags, u64 alt[]); void (*get_mem_data_src)(union perf_mem_data_src *dsrc, @@ -83,6 +83,7 @@ struct power_pmu { #define PPMU_NO_SIAR 0x00000100 /* Do not use SIAR */ #define PPMU_ARCH_31 0x00000200 /* Has MMCR3, SIER2 and SIER3 */ #define PPMU_P10_DD1 0x00000400 /* Is power10 DD1 processor version */ +#define PPMU_HAS_ATTR_CONFIG1 0x00000800 /* Using config1 attribute */ /* * Values for flags to get_alternatives() diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index f7613f43c9cf..4eed82172e33 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -162,6 +162,9 @@ static inline bool is_ioremap_addr(const void *x) return addr >= IOREMAP_BASE && addr < IOREMAP_END; } + +struct seq_file; +void arch_report_meminfo(struct seq_file *m); #endif /* CONFIG_PPC64 */ #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h index a7951049e129..59a2c7dbc78f 100644 --- a/arch/powerpc/include/asm/pkeys.h +++ b/arch/powerpc/include/asm/pkeys.h @@ -169,10 +169,4 @@ static inline bool arch_pkeys_enabled(void) } extern void pkey_mm_init(struct mm_struct *mm); -extern bool arch_supports_pkeys(int cap); -extern unsigned int arch_usable_pkeys(void); -extern void thread_pkey_regs_save(struct thread_struct *thread); -extern void thread_pkey_regs_restore(struct thread_struct *new_thread, - struct thread_struct *old_thread); -extern void thread_pkey_regs_init(struct thread_struct *thread); #endif /*_ASM_POWERPC_KEYS_H */ diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h index 7f4be5a05eb3..2b9edbf6e929 100644 --- a/arch/powerpc/include/asm/ppc-pci.h +++ b/arch/powerpc/include/asm/ppc-pci.h @@ -13,10 +13,6 @@ extern unsigned long isa_io_base; -extern void pci_setup_phb_io(struct pci_controller *hose, int primary); -extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary); - - extern struct list_head hose_list; extern struct pci_dev *isa_bridge_pcidev; /* may be NULL if no ISA bus */ @@ -32,9 +28,6 @@ struct pci_dn; void *pci_traverse_device_nodes(struct device_node *start, void *(*fn)(struct device_node *, void *), void *data); -void *traverse_pci_dn(struct pci_dn *root, - void *(*fn)(struct pci_dn *, void *), - void *data); extern void pci_devs_phb_init_dynamic(struct pci_controller *phb); /* From rtas_pci.h */ diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index cc1bca571332..3dceb64fc9af 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -25,7 +25,6 @@ #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE #define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb) #define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb) -#define ACCOUNT_STOLEN_TIME #else #define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb) \ MFTB(ra); /* get timebase */ \ @@ -44,29 +43,6 @@ PPC_LL ra, ACCOUNT_SYSTEM_TIME(ptr); \ add ra,ra,rb; /* add on to system time */ \ PPC_STL ra, ACCOUNT_SYSTEM_TIME(ptr) - -#ifdef CONFIG_PPC_SPLPAR -#define ACCOUNT_STOLEN_TIME \ -BEGIN_FW_FTR_SECTION; \ - beq 33f; \ - /* from user - see if there are any DTL entries to process */ \ - ld r10,PACALPPACAPTR(r13); /* get ptr to VPA */ \ - ld r11,PACA_DTL_RIDX(r13); /* get log read index */ \ - addi r10,r10,LPPACA_DTLIDX; \ - LDX_BE r10,0,r10; /* get log write index */ \ - cmpd cr1,r11,r10; \ - beq+ cr1,33f; \ - bl accumulate_stolen_time; \ - ld r12,_MSR(r1); \ - andi. r10,r12,MSR_PR; /* Restore cr0 (coming from user) */ \ -33: \ -END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) - -#else /* CONFIG_PPC_SPLPAR */ -#define ACCOUNT_STOLEN_TIME - -#endif /* CONFIG_PPC_SPLPAR */ - #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ /* diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 58f9dc060a7b..975ba260006a 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h @@ -70,6 +70,9 @@ struct pt_regs }; #endif + +#define STACK_FRAME_WITH_PT_REGS (STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)) + #ifdef __powerpc64__ /* @@ -229,6 +232,11 @@ static inline bool trap_is_scv(struct pt_regs *regs) return (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && TRAP(regs) == 0x3000); } +static inline bool trap_is_unsupported_scv(struct pt_regs *regs) +{ + return IS_ENABLED(CONFIG_PPC_BOOK3S_64) && TRAP(regs) == 0x7ff0; +} + static inline bool trap_is_syscall(struct pt_regs *regs) { return (trap_is_scv(regs) || TRAP(regs) == 0xc00); diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index e40a921d78f9..da103e92c112 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1375,6 +1375,7 @@ #define mtmsr(v) asm volatile("mtmsr %0" : \ : "r" ((unsigned long)(v)) \ : "memory") +#define __mtmsrd(v, l) BUILD_BUG() #define __MTMSR "mtmsr" #endif @@ -1413,13 +1414,24 @@ static inline void msr_check_and_clear(unsigned long bits) } #ifdef CONFIG_PPC32 -#define mfsrin(v) ({unsigned int rval; \ - asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \ - rval;}) - -static inline void mtsrin(u32 val, u32 idx) +static inline u32 mfsr(u32 idx) { - asm volatile("mtsrin %0, %1" : : "r" (val), "r" (idx)); + u32 val; + + if (__builtin_constant_p(idx)) + asm volatile("mfsr %0, %1" : "=r" (val): "i" (idx >> 28)); + else + asm volatile("mfsrin %0, %1" : "=r" (val): "r" (idx)); + + return val; +} + +static inline void mtsr(u32 val, u32 idx) +{ + if (__builtin_constant_p(idx)) + asm volatile("mtsr %1, %0" : : "r" (val), "i" (idx >> 28)); + else + asm volatile("mtsrin %0, %1" : : "r" (val), "r" (idx)); } #endif diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 262782f08fd4..17b8dcd9a40d 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -691,6 +691,9 @@ #define mttmr(rn, v) asm volatile(MTTMR(rn, %0) : \ : "r" ((unsigned long)(v)) \ : "memory") + +extern unsigned long global_dbcr0[]; + #endif /* !__ASSEMBLY__ */ #endif /* __ASM_POWERPC_REG_BOOKE_H__ */ diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 332e1000ca0f..658448ca5b8a 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -369,7 +369,7 @@ void rtas_initialize(void); #else static inline int page_is_rtas_user_buf(unsigned long pfn) { return 0;} static inline void pSeries_coalesce_init(void) { } -static inline void rtas_initialize(void) { }; +static inline void rtas_initialize(void) { } #endif extern int call_rtas(const char *, int, int, unsigned long *, ...); diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h index a466749703f1..e89bfebd4e00 100644 --- a/arch/powerpc/include/asm/setup.h +++ b/arch/powerpc/include/asm/setup.h @@ -58,7 +58,7 @@ void do_rfi_flush_fixups(enum l1d_flush_type types); #ifdef CONFIG_PPC_BARRIER_NOSPEC void setup_barrier_nospec(void); #else -static inline void setup_barrier_nospec(void) { }; +static inline void setup_barrier_nospec(void) { } #endif void do_uaccess_flush_fixups(enum l1d_flush_type types); void do_entry_flush_fixups(enum l1d_flush_type types); @@ -68,13 +68,13 @@ extern bool barrier_nospec_enabled; #ifdef CONFIG_PPC_BARRIER_NOSPEC void do_barrier_nospec_fixups_range(bool enable, void *start, void *end); #else -static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { }; +static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { } #endif #ifdef CONFIG_PPC_FSL_BOOK3E void setup_spectre_v2(void); #else -static inline void setup_spectre_v2(void) {}; +static inline void setup_spectre_v2(void) {} #endif void do_btb_flush_fixups(void); diff --git a/arch/powerpc/include/asm/simple_spinlock.h b/arch/powerpc/include/asm/simple_spinlock.h index 9c3c30534333..5b862de29dff 100644 --- a/arch/powerpc/include/asm/simple_spinlock.h +++ b/arch/powerpc/include/asm/simple_spinlock.h @@ -90,8 +90,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) void splpar_spin_yield(arch_spinlock_t *lock); void splpar_rw_yield(arch_rwlock_t *lock); #else /* SPLPAR */ -static inline void splpar_spin_yield(arch_spinlock_t *lock) {}; -static inline void splpar_rw_yield(arch_rwlock_t *lock) {}; +static inline void splpar_spin_yield(arch_spinlock_t *lock) {} +static inline void splpar_rw_yield(arch_rwlock_t *lock) {} #endif static inline void spin_yield(arch_spinlock_t *lock) diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index c4e2d53acd2b..7a13bc20f0a0 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -236,7 +236,7 @@ static inline void set_hard_smp_processor_id(int cpu, int phys) #if defined(CONFIG_PPC64) && (defined(CONFIG_SMP) || defined(CONFIG_KEXEC_CORE)) extern void smp_release_cpus(void); #else -static inline void smp_release_cpus(void) { }; +static inline void smp_release_cpus(void) { } #endif extern int smt_enabled_at_boot; diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index 3d8a47af7a25..386d576673a1 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -94,7 +94,6 @@ void arch_setup_new_exec(void); #define TIF_PATCH_PENDING 6 /* pending live patching update */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SINGLESTEP 8 /* singlestepping active */ -#define TIF_NOHZ 9 /* in adaptive nohz mode */ #define TIF_SECCOMP 10 /* secure computing */ #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ #define TIF_NOERROR 12 /* Force successful syscall return */ @@ -128,11 +127,10 @@ void arch_setup_new_exec(void); #define _TIF_UPROBE (1< #include +#include #include #include #include #ifdef CONFIG_SMP -void doorbell_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception) { struct pt_regs *old_regs = set_irq_regs(regs); - irq_enter(); trace_doorbell_entry(regs); ppc_msgsync(); @@ -35,13 +35,12 @@ void doorbell_exception(struct pt_regs *regs) smp_ipi_demux_relaxed(); /* already performed the barrier */ trace_doorbell_exit(regs); - irq_exit(); + set_irq_regs(old_regs); } #else /* CONFIG_SMP */ -void doorbell_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception) { printk(KERN_WARNING "Received doorbell on non-smp system\n"); } #endif /* CONFIG_SMP */ - diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 813713c9120c..cd60bc1c8701 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -1596,6 +1596,35 @@ static int proc_eeh_show(struct seq_file *m, void *v) } #ifdef CONFIG_DEBUG_FS + + +static struct pci_dev *eeh_debug_lookup_pdev(struct file *filp, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + uint32_t domain, bus, dev, fn; + struct pci_dev *pdev; + char buf[20]; + int ret; + + memset(buf, 0, sizeof(buf)); + ret = simple_write_to_buffer(buf, sizeof(buf)-1, ppos, user_buf, count); + if (!ret) + return ERR_PTR(-EFAULT); + + ret = sscanf(buf, "%x:%x:%x.%x", &domain, &bus, &dev, &fn); + if (ret != 4) { + pr_err("%s: expected 4 args, got %d\n", __func__, ret); + return ERR_PTR(-EINVAL); + } + + pdev = pci_get_domain_bus_and_slot(domain, bus, (dev << 3) | fn); + if (!pdev) + return ERR_PTR(-ENODEV); + + return pdev; +} + static int eeh_enable_dbgfs_set(void *data, u64 val) { if (val) @@ -1688,26 +1717,13 @@ static ssize_t eeh_dev_check_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *ppos) { - uint32_t domain, bus, dev, fn; struct pci_dev *pdev; struct eeh_dev *edev; - char buf[20]; int ret; - memset(buf, 0, sizeof(buf)); - ret = simple_write_to_buffer(buf, sizeof(buf)-1, ppos, user_buf, count); - if (!ret) - return -EFAULT; - - ret = sscanf(buf, "%x:%x:%x.%x", &domain, &bus, &dev, &fn); - if (ret != 4) { - pr_err("%s: expected 4 args, got %d\n", __func__, ret); - return -EINVAL; - } - - pdev = pci_get_domain_bus_and_slot(domain, bus, (dev << 3) | fn); - if (!pdev) - return -ENODEV; + pdev = eeh_debug_lookup_pdev(filp, user_buf, count, ppos); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); edev = pci_dev_to_eeh_dev(pdev); if (!edev) { @@ -1717,8 +1733,8 @@ static ssize_t eeh_dev_check_write(struct file *filp, } ret = eeh_dev_check_failure(edev); - pci_info(pdev, "eeh_dev_check_failure(%04x:%02x:%02x.%01x) = %d\n", - domain, bus, dev, fn, ret); + pci_info(pdev, "eeh_dev_check_failure(%s) = %d\n", + pci_name(pdev), ret); pci_dev_put(pdev); @@ -1829,25 +1845,12 @@ static ssize_t eeh_dev_break_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *ppos) { - uint32_t domain, bus, dev, fn; struct pci_dev *pdev; - char buf[20]; int ret; - memset(buf, 0, sizeof(buf)); - ret = simple_write_to_buffer(buf, sizeof(buf)-1, ppos, user_buf, count); - if (!ret) - return -EFAULT; - - ret = sscanf(buf, "%x:%x:%x.%x", &domain, &bus, &dev, &fn); - if (ret != 4) { - pr_err("%s: expected 4 args, got %d\n", __func__, ret); - return -EINVAL; - } - - pdev = pci_get_domain_bus_and_slot(domain, bus, (dev << 3) | fn); - if (!pdev) - return -ENODEV; + pdev = eeh_debug_lookup_pdev(filp, user_buf, count, ppos); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); ret = eeh_debugfs_break_device(pdev); pci_dev_put(pdev); @@ -1865,6 +1868,53 @@ static const struct file_operations eeh_dev_break_fops = { .read = eeh_debugfs_dev_usage, }; +static ssize_t eeh_dev_can_recover(struct file *filp, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct pci_driver *drv; + struct pci_dev *pdev; + size_t ret; + + pdev = eeh_debug_lookup_pdev(filp, user_buf, count, ppos); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + /* + * In order for error recovery to work the driver needs to implement + * .error_detected(), so it can quiesce IO to the device, and + * .slot_reset() so it can re-initialise the device after a reset. + * + * Ideally they'd implement .resume() too, but some drivers which + * we need to support (notably IPR) don't so I guess we can tolerate + * that. + * + * .mmio_enabled() is mostly there as a work-around for devices which + * take forever to re-init after a hot reset. Implementing that is + * strictly optional. + */ + drv = pci_dev_driver(pdev); + if (drv && + drv->err_handler && + drv->err_handler->error_detected && + drv->err_handler->slot_reset) { + ret = count; + } else { + ret = -EOPNOTSUPP; + } + + pci_dev_put(pdev); + + return ret; +} + +static const struct file_operations eeh_dev_can_recover_fops = { + .open = simple_open, + .llseek = no_llseek, + .write = eeh_dev_can_recover, + .read = eeh_debugfs_dev_usage, +}; + #endif static int __init eeh_init_proc(void) @@ -1889,6 +1939,9 @@ static int __init eeh_init_proc(void) debugfs_create_file_unsafe("eeh_force_recover", 0600, powerpc_debugfs_root, NULL, &eeh_force_recover_fops); + debugfs_create_file_unsafe("eeh_dev_can_recover", 0600, + powerpc_debugfs_root, NULL, + &eeh_dev_can_recover_fops); eeh_cache_debugfs_init(); #endif } diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 1c9b0ccc2172..78c430b7f9d9 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -175,14 +175,11 @@ transfer_to_handler: addi r11,r11,global_dbcr0@l #ifdef CONFIG_SMP lwz r9,TASK_CPU(r2) - slwi r9,r9,3 + slwi r9,r9,2 add r11,r11,r9 #endif lwz r12,0(r11) mtspr SPRN_DBCR0,r12 - lwz r12,4(r11) - addi r12,r12,-1 - stw r12,4(r11) #endif b 3f @@ -276,8 +273,7 @@ reenable_mmu: * We save a bunch of GPRs, * r3 can be different from GPR3(r1) at this point, r9 and r11 * contains the old MSR and handler address respectively, - * r4 & r5 can contain page fault arguments that need to be passed - * along as well. r0, r6-r8, r12, CCR, CTR, XER etc... are left + * r0, r4-r8, r12, CCR, CTR, XER etc... are left * clobbered as they aren't useful past this point. */ @@ -285,15 +281,11 @@ reenable_mmu: stw r9,8(r1) stw r11,12(r1) stw r3,16(r1) - stw r4,20(r1) - stw r5,24(r1) /* If we are disabling interrupts (normal case), simply log it with * lockdep */ 1: bl trace_hardirqs_off - lwz r5,24(r1) - lwz r4,20(r1) lwz r3,16(r1) lwz r11,12(r1) lwz r9,8(r1) @@ -334,132 +326,29 @@ stack_ovf: _ASM_NOKPROBE_SYMBOL(stack_ovf) #endif -#ifdef CONFIG_TRACE_IRQFLAGS -trace_syscall_entry_irq_off: - /* - * Syscall shouldn't happen while interrupts are disabled, - * so let's do a warning here. - */ -0: trap - EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING - bl trace_hardirqs_on - - /* Now enable for real */ - LOAD_REG_IMMEDIATE(r10, MSR_KERNEL | MSR_EE) - mtmsr r10 - - REST_GPR(0, r1) - REST_4GPRS(3, r1) - REST_2GPRS(7, r1) - b DoSyscall -#endif /* CONFIG_TRACE_IRQFLAGS */ - .globl transfer_to_syscall transfer_to_syscall: -#ifdef CONFIG_TRACE_IRQFLAGS - andi. r12,r9,MSR_EE - beq- trace_syscall_entry_irq_off -#endif /* CONFIG_TRACE_IRQFLAGS */ + SAVE_NVGPRS(r1) +#ifdef CONFIG_PPC_BOOK3S_32 + kuep_lock r11, r12 +#endif -/* - * Handle a system call. - */ - .stabs "arch/powerpc/kernel/",N_SO,0,0,0f - .stabs "entry_32.S",N_SO,0,0,0f -0: + /* Calling convention has r9 = orig r0, r10 = regs */ + addi r10,r1,STACK_FRAME_OVERHEAD + mr r9,r0 + stw r10,THREAD+PT_REGS(r2) + bl system_call_exception -_GLOBAL(DoSyscall) - stw r3,ORIG_GPR3(r1) - li r12,0 - stw r12,RESULT(r1) -#ifdef CONFIG_TRACE_IRQFLAGS - /* Make sure interrupts are enabled */ - mfmsr r11 - andi. r12,r11,MSR_EE - /* We came in with interrupts disabled, we WARN and mark them enabled - * for lockdep now */ -0: tweqi r12, 0 - EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING -#endif /* CONFIG_TRACE_IRQFLAGS */ - lwz r11,TI_FLAGS(r2) - andi. r11,r11,_TIF_SYSCALL_DOTRACE - bne- syscall_dotrace -syscall_dotrace_cont: - cmplwi 0,r0,NR_syscalls - lis r10,sys_call_table@h - ori r10,r10,sys_call_table@l - slwi r0,r0,2 - bge- 66f - - barrier_nospec_asm - /* - * Prevent the load of the handler below (based on the user-passed - * system call number) being speculatively executed until the test - * against NR_syscalls and branch to .66f above has - * committed. - */ - - lwzx r10,r10,r0 /* Fetch system call handler [ptr] */ - mtlr r10 - addi r9,r1,STACK_FRAME_OVERHEAD - PPC440EP_ERR42 - blrl /* Call handler */ - .globl ret_from_syscall ret_from_syscall: -#ifdef CONFIG_DEBUG_RSEQ - /* Check whether the syscall is issued inside a restartable sequence */ - stw r3,GPR3(r1) - addi r3,r1,STACK_FRAME_OVERHEAD - bl rseq_syscall - lwz r3,GPR3(r1) -#endif - mr r6,r3 - /* disable interrupts so current_thread_info()->flags can't change */ - LOAD_REG_IMMEDIATE(r10,MSR_KERNEL) /* doesn't include MSR_EE */ - /* Note: We don't bother telling lockdep about it */ - mtmsr r10 - lwz r9,TI_FLAGS(r2) - li r8,-MAX_ERRNO - andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) - bne- syscall_exit_work - cmplw 0,r3,r8 - blt+ syscall_exit_cont - lwz r11,_CCR(r1) /* Load CR */ - neg r3,r3 - oris r11,r11,0x1000 /* Set SO bit in CR */ - stw r11,_CCR(r1) -syscall_exit_cont: - lwz r8,_MSR(r1) -#ifdef CONFIG_TRACE_IRQFLAGS - /* If we are going to return from the syscall with interrupts - * off, we trace that here. It shouldn't normally happen. - */ - andi. r10,r8,MSR_EE - bne+ 1f - stw r3,GPR3(r1) - bl trace_hardirqs_off - lwz r3,GPR3(r1) -1: -#endif /* CONFIG_TRACE_IRQFLAGS */ -#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - /* If the process has its own DBCR0 value, load it up. The internal - debug mode bit tells us that dbcr0 should be loaded. */ - lwz r0,THREAD+THREAD_DBCR0(r2) - andis. r10,r0,DBCR0_IDM@h - bnel- load_dbcr0 -#endif + addi r4,r1,STACK_FRAME_OVERHEAD + li r5,0 + bl syscall_exit_prepare #ifdef CONFIG_PPC_47x lis r4,icache_44x_need_flush@ha lwz r5,icache_44x_need_flush@l(r4) cmplwi cr0,r5,0 bne- 2f #endif /* CONFIG_PPC_47x */ -1: -BEGIN_FTR_SECTION - lwarx r7,0,r1 -END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) - stwcx. r0,0,r1 /* to clear the reservation */ - ACCOUNT_CPU_USER_EXIT(r2, r5, r7) #ifdef CONFIG_PPC_BOOK3S_32 kuep_unlock r5, r7 #endif @@ -467,21 +356,36 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) lwz r4,_LINK(r1) lwz r5,_CCR(r1) mtlr r4 - mtcr r5 lwz r7,_NIP(r1) - lwz r2,GPR2(r1) - lwz r1,GPR1(r1) + lwz r8,_MSR(r1) + cmpwi r3,0 + lwz r3,GPR3(r1) syscall_exit_finish: -#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS) - mtspr SPRN_NRI, r0 -#endif mtspr SPRN_SRR0,r7 mtspr SPRN_SRR1,r8 + + bne 3f + mtcr r5 + +1: lwz r2,GPR2(r1) + lwz r1,GPR1(r1) rfi #ifdef CONFIG_40x b . /* Prevent prefetch past rfi */ #endif -_ASM_NOKPROBE_SYMBOL(syscall_exit_finish) + +3: mtcr r5 + lwz r4,_CTR(r1) + lwz r5,_XER(r1) + REST_NVGPRS(r1) + mtctr r4 + mtxer r5 + lwz r0,GPR0(r1) + lwz r3,GPR3(r1) + REST_8GPRS(4,r1) + lwz r12,GPR12(r1) + b 1b + #ifdef CONFIG_44x 2: li r7,0 iccci r0,r0 @@ -489,9 +393,6 @@ _ASM_NOKPROBE_SYMBOL(syscall_exit_finish) b 1b #endif /* CONFIG_44x */ -66: li r3,-ENOSYS - b ret_from_syscall - .globl ret_from_fork ret_from_fork: REST_NVGPRS(r1) @@ -510,157 +411,6 @@ ret_from_kernel_thread: li r3,0 b ret_from_syscall -/* Traced system call support */ -syscall_dotrace: - SAVE_NVGPRS(r1) - li r0,0xc00 - stw r0,_TRAP(r1) - addi r3,r1,STACK_FRAME_OVERHEAD - bl do_syscall_trace_enter - /* - * Restore argument registers possibly just changed. - * We use the return value of do_syscall_trace_enter - * for call number to look up in the table (r0). - */ - mr r0,r3 - lwz r3,GPR3(r1) - lwz r4,GPR4(r1) - lwz r5,GPR5(r1) - lwz r6,GPR6(r1) - lwz r7,GPR7(r1) - lwz r8,GPR8(r1) - REST_NVGPRS(r1) - - cmplwi r0,NR_syscalls - /* Return code is already in r3 thanks to do_syscall_trace_enter() */ - bge- ret_from_syscall - b syscall_dotrace_cont - -syscall_exit_work: - andi. r0,r9,_TIF_RESTOREALL - beq+ 0f - REST_NVGPRS(r1) - b 2f -0: cmplw 0,r3,r8 - blt+ 1f - andi. r0,r9,_TIF_NOERROR - bne- 1f - lwz r11,_CCR(r1) /* Load CR */ - neg r3,r3 - oris r11,r11,0x1000 /* Set SO bit in CR */ - stw r11,_CCR(r1) - -1: stw r6,RESULT(r1) /* Save result */ - stw r3,GPR3(r1) /* Update return value */ -2: andi. r0,r9,(_TIF_PERSYSCALL_MASK) - beq 4f - - /* Clear per-syscall TIF flags if any are set. */ - - li r11,_TIF_PERSYSCALL_MASK - addi r12,r2,TI_FLAGS -3: lwarx r8,0,r12 - andc r8,r8,r11 - stwcx. r8,0,r12 - bne- 3b - -4: /* Anything which requires enabling interrupts? */ - andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP) - beq ret_from_except - - /* Re-enable interrupts. There is no need to trace that with - * lockdep as we are supposed to have IRQs on at this point - */ - ori r10,r10,MSR_EE - mtmsr r10 - - /* Save NVGPRS if they're not saved already */ - lwz r4,_TRAP(r1) - andi. r4,r4,1 - beq 5f - SAVE_NVGPRS(r1) - li r4,0xc00 - stw r4,_TRAP(r1) -5: - addi r3,r1,STACK_FRAME_OVERHEAD - bl do_syscall_trace_leave - b ret_from_except_full - - /* - * System call was called from kernel. We get here with SRR1 in r9. - * Mark the exception as recoverable once we have retrieved SRR0, - * trap a warning and return ENOSYS with CR[SO] set. - */ - .globl ret_from_kernel_syscall -ret_from_kernel_syscall: - mfspr r9, SPRN_SRR0 - mfspr r10, SPRN_SRR1 -#if !defined(CONFIG_4xx) && !defined(CONFIG_BOOKE) - LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_IR|MSR_DR)) - mtmsr r11 -#endif - -0: trap - EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING - - li r3, ENOSYS - crset so -#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS) - mtspr SPRN_NRI, r0 -#endif - mtspr SPRN_SRR0, r9 - mtspr SPRN_SRR1, r10 - rfi -#ifdef CONFIG_40x - b . /* Prevent prefetch past rfi */ -#endif -_ASM_NOKPROBE_SYMBOL(ret_from_kernel_syscall) - -/* - * The fork/clone functions need to copy the full register set into - * the child process. Therefore we need to save all the nonvolatile - * registers (r13 - r31) before calling the C code. - */ - .globl ppc_fork -ppc_fork: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,_TRAP(r1) /* register set saved */ - b sys_fork - - .globl ppc_vfork -ppc_vfork: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,_TRAP(r1) /* register set saved */ - b sys_vfork - - .globl ppc_clone -ppc_clone: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,_TRAP(r1) /* register set saved */ - b sys_clone - - .globl ppc_clone3 -ppc_clone3: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,_TRAP(r1) /* register set saved */ - b sys_clone3 - - .globl ppc_swapcontext -ppc_swapcontext: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ - stw r0,_TRAP(r1) /* register set saved */ - b sys_swapcontext - /* * Top-level page fault handling. * This is in assembler because if do_page_fault tells us that @@ -670,10 +420,6 @@ ppc_swapcontext: .globl handle_page_fault handle_page_fault: addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef CONFIG_PPC_BOOK3S_32 - andis. r0,r5,DSISR_DABRMATCH@h - bne- handle_dabr_fault -#endif bl do_page_fault cmpwi r3,0 beq+ ret_from_except @@ -681,23 +427,11 @@ handle_page_fault: lwz r0,_TRAP(r1) clrrwi r0,r0,1 stw r0,_TRAP(r1) - mr r5,r3 + mr r4,r3 /* err arg for bad_page_fault */ addi r3,r1,STACK_FRAME_OVERHEAD - lwz r4,_DAR(r1) bl __bad_page_fault b ret_from_except_full -#ifdef CONFIG_PPC_BOOK3S_32 - /* We have a data breakpoint exception - handle it */ -handle_dabr_fault: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - clrrwi r0,r0,1 - stw r0,_TRAP(r1) - bl do_break - b ret_from_except_full -#endif - /* * This routine switches between two different tasks. The process * state of one is saved on its kernel stack. Then the state @@ -1237,14 +971,11 @@ load_dbcr0: addi r11,r11,global_dbcr0@l #ifdef CONFIG_SMP lwz r9,TASK_CPU(r2) - slwi r9,r9,3 + slwi r9,r9,2 add r11,r11,r9 #endif stw r10,0(r11) mtspr SPRN_DBCR0,r0 - lwz r10,4(r11) - addi r10,r10,1 - stw r10,4(r11) li r11,-1 mtspr SPRN_DBSR,r11 /* clear all pending debug events */ blr @@ -1253,7 +984,7 @@ load_dbcr0: .align 4 .global global_dbcr0 global_dbcr0: - .space 8*NR_CPUS + .space 4*NR_CPUS .previous #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 33ddfeef4fe9..6c4d9e276c4d 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -108,7 +108,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) li r11,\trapnr std r11,_TRAP(r1) std r12,_CCR(r1) - std r3,ORIG_GPR3(r1) addi r10,r1,STACK_FRAME_OVERHEAD ld r11,exception_marker@toc(r2) std r11,-16(r10) /* "regshere" marker */ @@ -225,6 +224,12 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_emulate) b system_call_vectored_common #endif + .balign IFETCH_ALIGN_BYTES + .globl system_call_common_real +system_call_common_real: + ld r10,PACAKMSR(r13) /* get MSR value for kernel */ + mtmsrd r10 + .balign IFETCH_ALIGN_BYTES .globl system_call_common system_call_common: @@ -278,7 +283,6 @@ END_BTB_FLUSH_SECTION std r10,_LINK(r1) std r11,_TRAP(r1) std r12,_CCR(r1) - std r3,ORIG_GPR3(r1) addi r10,r1,STACK_FRAME_OVERHEAD ld r11,exception_marker@toc(r2) std r11,-16(r10) /* "regshere" marker */ diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 74d07dc0bb48..e8eb9992a270 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -398,7 +398,6 @@ exc_##n##_common: \ std r10,_NIP(r1); /* save SRR0 to stackframe */ \ std r11,_MSR(r1); /* save SRR1 to stackframe */ \ beq 2f; /* if from kernel mode */ \ - ACCOUNT_CPU_USER_ENTRY(r13,r10,r11);/* accounting (uses cr0+eq) */ \ 2: ld r3,excf+EX_R10(r13); /* get back r10 */ \ ld r4,excf+EX_R11(r13); /* get back r11 */ \ mfspr r5,scratch; /* get back r13 */ \ @@ -791,7 +790,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) EXCEPTION_COMMON_CRIT(0xd00) std r14,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD - mr r4,r14 ld r14,PACA_EXCRIT+EX_R14(r13) ld r15,PACA_EXCRIT+EX_R15(r13) bl save_nvgprs @@ -864,7 +862,6 @@ kernel_dbg_exc: INTS_DISABLE std r14,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD - mr r4,r14 ld r14,PACA_EXDBG+EX_R14(r13) ld r15,PACA_EXDBG+EX_R15(r13) bl save_nvgprs @@ -1011,8 +1008,6 @@ storage_fault_common: std r14,_DAR(r1) std r15,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD - mr r4,r14 - mr r5,r15 ld r14,PACA_EXGEN+EX_R14(r13) ld r15,PACA_EXGEN+EX_R15(r13) bl do_page_fault @@ -1020,9 +1015,8 @@ storage_fault_common: bne- 1f b ret_from_except_lite 1: bl save_nvgprs - mr r5,r3 + mr r4,r3 addi r3,r1,STACK_FRAME_OVERHEAD - ld r4,_DAR(r1) bl __bad_page_fault b ret_from_except diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 6e53f7638737..60d3051a8bc8 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -139,7 +139,6 @@ name: #define IKVM_VIRT .L_IKVM_VIRT_\name\() /* Virt entry tests KVM */ #define ISTACK .L_ISTACK_\name\() /* Set regular kernel stack */ #define __ISTACK(name) .L_ISTACK_ ## name -#define IRECONCILE .L_IRECONCILE_\name\() /* Do RECONCILE_IRQ_STATE */ #define IKUAP .L_IKUAP_\name\() /* Do KUAP lock */ #define INT_DEFINE_BEGIN(n) \ @@ -203,9 +202,6 @@ do_define_int n .ifndef ISTACK ISTACK=1 .endif - .ifndef IRECONCILE - IRECONCILE=1 - .endif .ifndef IKUAP IKUAP=1 .endif @@ -581,7 +577,6 @@ DEFINE_FIXED_SYMBOL(\name\()_common_real) kuap_save_amr_and_lock r9, r10, cr1, cr0 .endif beq 101f /* if from kernel mode */ - ACCOUNT_CPU_USER_ENTRY(r13, r9, r10) BEGIN_FTR_SECTION ld r9,IAREA+EX_PPR(r13) /* Read PPR from paca */ std r9,_PPR(r1) @@ -649,14 +644,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) ld r11,exception_marker@toc(r2) std r10,RESULT(r1) /* clear regs->result */ std r11,STACK_FRAME_OVERHEAD-16(r1) /* mark the frame */ - - .if ISTACK - ACCOUNT_STOLEN_TIME - .endif - - .if IRECONCILE - RECONCILE_IRQ_STATE(r10, r11) - .endif .endm /* @@ -705,14 +692,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) ld r1,GPR1(r1) .endm -#define RUNLATCH_ON \ -BEGIN_FTR_SECTION \ - ld r3, PACA_THREAD_INFO(r13); \ - ld r4,TI_LOCAL_FLAGS(r3); \ - andi. r0,r4,_TLF_RUNLATCH; \ - beql ppc64_runlatch_on_trampoline; \ -END_FTR_SECTION_IFSET(CPU_FTR_CTRL) - /* * When the idle code in power4_idle puts the CPU into NAP mode, * it has to do so in a loop, and relies on the external interrupt @@ -935,7 +914,6 @@ INT_DEFINE_BEGIN(system_reset) */ ISET_RI=0 ISTACK=0 - IRECONCILE=0 IKVM_REAL=1 INT_DEFINE_END(system_reset) @@ -1022,20 +1000,6 @@ EXC_COMMON_BEGIN(system_reset_common) ld r1,PACA_NMI_EMERG_SP(r13) subi r1,r1,INT_FRAME_SIZE __GEN_COMMON_BODY system_reset - /* - * Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does - * the right thing. We do not want to reconcile because that goes - * through irq tracing which we don't want in NMI. - * - * Save PACAIRQHAPPENED to RESULT (otherwise unused), and set HARD_DIS - * as we are running with MSR[EE]=0. - */ - li r10,IRQS_ALL_DISABLED - stb r10,PACAIRQSOFTMASK(r13) - lbz r10,PACAIRQHAPPENED(r13) - std r10,RESULT(r1) - ori r10,r10,PACA_IRQ_HARD_DIS - stb r10,PACAIRQHAPPENED(r13) addi r3,r1,STACK_FRAME_OVERHEAD bl system_reset_exception @@ -1051,14 +1015,6 @@ EXC_COMMON_BEGIN(system_reset_common) subi r10,r10,1 sth r10,PACA_IN_NMI(r13) - /* - * Restore soft mask settings. - */ - ld r10,RESULT(r1) - stb r10,PACAIRQHAPPENED(r13) - ld r10,SOFTE(r1) - stb r10,PACAIRQSOFTMASK(r13) - kuap_kernel_restore r9, r10 EXCEPTION_RESTORE_REGS RFI_TO_USER_OR_KERNEL @@ -1123,7 +1079,6 @@ INT_DEFINE_BEGIN(machine_check_early) ISTACK=0 IDAR=1 IDSISR=1 - IRECONCILE=0 IKUAP=0 /* We don't touch AMR here, we never go to virtual mode */ INT_DEFINE_END(machine_check_early) @@ -1205,30 +1160,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) li r10,MSR_RI mtmsrd r10,1 - /* - * Set IRQS_ALL_DISABLED and save PACAIRQHAPPENED (see - * system_reset_common) - */ - li r10,IRQS_ALL_DISABLED - stb r10,PACAIRQSOFTMASK(r13) - lbz r10,PACAIRQHAPPENED(r13) - std r10,RESULT(r1) - ori r10,r10,PACA_IRQ_HARD_DIS - stb r10,PACAIRQHAPPENED(r13) - addi r3,r1,STACK_FRAME_OVERHEAD bl machine_check_early std r3,RESULT(r1) /* Save result */ ld r12,_MSR(r1) - /* - * Restore soft mask settings. - */ - ld r10,RESULT(r1) - stb r10,PACAIRQHAPPENED(r13) - ld r10,SOFTE(r1) - stb r10,PACAIRQSOFTMASK(r13) - #ifdef CONFIG_PPC_P7_NAP /* * Check if thread was in power saving mode. We come here when any @@ -1401,14 +1337,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) * * Handling: * - Hash MMU - * Go to do_hash_page first to see if the HPT can be filled from an entry in - * the Linux page table. Hash faults can hit in kernel mode in a fairly + * Go to do_hash_fault, which attempts to fill the HPT from an entry in the + * Linux page table. Hash faults can hit in kernel mode in a fairly * arbitrary state (e.g., interrupts disabled, locks held) when accessing * "non-bolted" regions, e.g., vmalloc space. However these should always be - * backed by Linux page tables. + * backed by Linux page table entries. * - * If none is found, do a Linux page fault. Linux page faults can happen in - * kernel mode due to user copy operations of course. + * If no entry is found the Linux page fault handler is invoked (by + * do_hash_fault). Linux page faults can happen in kernel mode due to user + * copy operations of course. * * KVM: The KVM HDSI handler may perform a load with MSR[DR]=1 in guest * MMU context, which may cause a DSI in the host, which must go to the @@ -1437,15 +1374,24 @@ EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) EXC_VIRT_END(data_access, 0x4300, 0x80) EXC_COMMON_BEGIN(data_access_common) GEN_COMMON data_access - ld r4,_DAR(r1) - ld r5,_DSISR(r1) + ld r4,_DSISR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + andis. r0,r4,DSISR_DABRMATCH@h + bne- 1f BEGIN_MMU_FTR_SECTION - ld r6,_MSR(r1) - li r3,0x300 - b do_hash_page /* Try to handle as hpte fault */ + bl do_hash_fault MMU_FTR_SECTION_ELSE - b handle_page_fault + bl do_page_fault ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) + b interrupt_return + +1: bl do_break + /* + * do_break() may have changed the NV GPRS while handling a breakpoint. + * If so, we need to restore them with their updated values. + */ + REST_NVGPRS(r1) + b interrupt_return GEN_KVM data_access @@ -1466,14 +1412,9 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) * on user-handler data structures. * * KVM: Same as 0x300, DSLB must test for KVM guest. - * - * A dedicated save area EXSLB is used (XXX: but it actually need not be - * these days, we could use EXGEN). */ INT_DEFINE_BEGIN(data_access_slb) IVEC=0x380 - IAREA=PACA_EXSLB - IRECONCILE=0 IDAR=1 IKVM_SKIP=1 IKVM_REAL=1 @@ -1487,10 +1428,9 @@ EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) EXC_VIRT_END(data_access_slb, 0x4380, 0x80) EXC_COMMON_BEGIN(data_access_slb_common) GEN_COMMON data_access_slb - ld r4,_DAR(r1) - addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION /* HPT case, do SLB fault */ + addi r3,r1,STACK_FRAME_OVERHEAD bl do_slb_fault cmpdi r3,0 bne- 1f @@ -1501,9 +1441,6 @@ MMU_FTR_SECTION_ELSE li r3,-EFAULT ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) std r3,RESULT(r1) - RECONCILE_IRQ_STATE(r10, r11) - ld r4,_DAR(r1) - ld r5,RESULT(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_bad_slb_fault b interrupt_return @@ -1538,15 +1475,13 @@ EXC_VIRT_BEGIN(instruction_access, 0x4400, 0x80) EXC_VIRT_END(instruction_access, 0x4400, 0x80) EXC_COMMON_BEGIN(instruction_access_common) GEN_COMMON instruction_access - ld r4,_DAR(r1) - ld r5,_DSISR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION - ld r6,_MSR(r1) - li r3,0x400 - b do_hash_page /* Try to handle as hpte fault */ + bl do_hash_fault MMU_FTR_SECTION_ELSE - b handle_page_fault + bl do_page_fault ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) + b interrupt_return GEN_KVM instruction_access @@ -1562,8 +1497,6 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) */ INT_DEFINE_BEGIN(instruction_access_slb) IVEC=0x480 - IAREA=PACA_EXSLB - IRECONCILE=0 IISIDE=1 IDAR=1 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE @@ -1579,10 +1512,9 @@ EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80) EXC_VIRT_END(instruction_access_slb, 0x4480, 0x80) EXC_COMMON_BEGIN(instruction_access_slb_common) GEN_COMMON instruction_access_slb - ld r4,_DAR(r1) - addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION /* HPT case, do SLB fault */ + addi r3,r1,STACK_FRAME_OVERHEAD bl do_slb_fault cmpdi r3,0 bne- 1f @@ -1593,9 +1525,6 @@ MMU_FTR_SECTION_ELSE li r3,-EFAULT ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) std r3,RESULT(r1) - RECONCILE_IRQ_STATE(r10, r11) - ld r4,_DAR(r1) - ld r5,RESULT(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_bad_slb_fault b interrupt_return @@ -1643,7 +1572,6 @@ EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100) EXC_COMMON_BEGIN(hardware_interrupt_common) GEN_COMMON hardware_interrupt FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl do_IRQ b interrupt_return @@ -1697,6 +1625,51 @@ INT_DEFINE_BEGIN(program_check) INT_DEFINE_END(program_check) EXC_REAL_BEGIN(program_check, 0x700, 0x100) + +#ifdef CONFIG_CPU_LITTLE_ENDIAN + /* + * There's a short window during boot where although the kernel is + * running little endian, any exceptions will cause the CPU to switch + * back to big endian. For example a WARN() boils down to a trap + * instruction, which will cause a program check, and we end up here but + * with the CPU in big endian mode. The first instruction of the program + * check handler (in GEN_INT_ENTRY below) is an mtsprg, which when + * executed in the wrong endian is an lhzu with a ~3GB displacement from + * r3. The content of r3 is random, so that is a load from some random + * location, and depending on the system can easily lead to a checkstop, + * or an infinitely recursive page fault. + * + * So to handle that case we have a trampoline here that can detect we + * are in the wrong endian and flip us back to the correct endian. We + * can't flip MSR[LE] using mtmsr, so we have to use rfid. That requires + * backing up SRR0/1 as well as a GPR. To do that we use SPRG0/2/3, as + * SPRG1 is already used for the paca. SPRG3 is user readable, but this + * trampoline is only active very early in boot, and SPRG3 will be + * reinitialised in vdso_getcpu_init() before userspace starts. + */ +BEGIN_FTR_SECTION + tdi 0,0,0x48 // Trap never, or in reverse endian: b . + 8 + b 1f // Skip trampoline if endian is correct + .long 0xa643707d // mtsprg 0, r11 Backup r11 + .long 0xa6027a7d // mfsrr0 r11 + .long 0xa643727d // mtsprg 2, r11 Backup SRR0 in SPRG2 + .long 0xa6027b7d // mfsrr1 r11 + .long 0xa643737d // mtsprg 3, r11 Backup SRR1 in SPRG3 + .long 0xa600607d // mfmsr r11 + .long 0x01006b69 // xori r11, r11, 1 Invert MSR[LE] + .long 0xa6037b7d // mtsrr1 r11 + .long 0x34076039 // li r11, 0x734 + .long 0xa6037a7d // mtsrr0 r11 + .long 0x2400004c // rfid + mfsprg r11, 3 + mtsrr1 r11 // Restore SRR1 + mfsprg r11, 2 + mtsrr0 r11 // Restore SRR0 + mfsprg r11, 0 // Restore r11 +1: +END_FTR_SECTION(0, 1) // nop out after boot +#endif /* CONFIG_CPU_LITTLE_ENDIAN */ + GEN_INT_ENTRY program_check, virt=0 EXC_REAL_END(program_check, 0x700, 0x100) EXC_VIRT_BEGIN(program_check, 0x4700, 0x100) @@ -1755,7 +1728,6 @@ EXC_COMMON_BEGIN(program_check_common) */ INT_DEFINE_BEGIN(fp_unavailable) IVEC=0x800 - IRECONCILE=0 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE IKVM_REAL=1 #endif @@ -1770,7 +1742,6 @@ EXC_VIRT_END(fp_unavailable, 0x4800, 0x100) EXC_COMMON_BEGIN(fp_unavailable_common) GEN_COMMON fp_unavailable bne 1f /* if from user, just load it up */ - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl kernel_fp_unavailable_exception 0: trap @@ -1789,7 +1760,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) b fast_interrupt_return #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 2: /* User process was in a transaction */ - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl fp_unavailable_tm b interrupt_return @@ -1832,7 +1802,6 @@ EXC_VIRT_END(decrementer, 0x4900, 0x80) EXC_COMMON_BEGIN(decrementer_common) GEN_COMMON decrementer FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl timer_interrupt b interrupt_return @@ -1854,7 +1823,6 @@ INT_DEFINE_BEGIN(hdecrementer) IVEC=0x980 IHSRR=1 ISTACK=0 - IRECONCILE=0 IKVM_REAL=1 IKVM_VIRT=1 INT_DEFINE_END(hdecrementer) @@ -1919,12 +1887,11 @@ EXC_VIRT_END(doorbell_super, 0x4a00, 0x100) EXC_COMMON_BEGIN(doorbell_super_common) GEN_COMMON doorbell_super FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD #ifdef CONFIG_PPC_DOORBELL bl doorbell_exception #else - bl unknown_exception + bl unknown_async_exception #endif b interrupt_return @@ -2001,12 +1968,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) HMT_MEDIUM .if ! \virt - __LOAD_HANDLER(r10, system_call_common) - mtspr SPRN_SRR0,r10 - ld r10,PACAKMSR(r13) - mtspr SPRN_SRR1,r10 - RFI_TO_KERNEL - b . /* prevent speculative execution */ + __LOAD_HANDLER(r10, system_call_common_real) + mtctr r10 + bctr .else li r10,MSR_RI mtmsrd r10,1 /* Set RI (EE=0) */ @@ -2137,9 +2101,7 @@ EXC_COMMON_BEGIN(h_data_storage_common) GEN_COMMON h_data_storage addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION - ld r4,_DAR(r1) - li r5,SIGSEGV - bl bad_page_fault + bl do_bad_page_fault_segv MMU_FTR_SECTION_ELSE bl unknown_exception ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_TYPE_RADIX) @@ -2230,7 +2192,6 @@ INT_DEFINE_BEGIN(hmi_exception_early) IHSRR=1 IREALMODE_COMMON=1 ISTACK=0 - IRECONCILE=0 IKUAP=0 /* We don't touch AMR here, we never go to virtual mode */ IKVM_REAL=1 INT_DEFINE_END(hmi_exception_early) @@ -2277,7 +2238,6 @@ EXC_COMMON_BEGIN(hmi_exception_early_common) EXC_COMMON_BEGIN(hmi_exception_common) GEN_COMMON hmi_exception FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl handle_hmi_exception b interrupt_return @@ -2307,12 +2267,11 @@ EXC_VIRT_END(h_doorbell, 0x4e80, 0x20) EXC_COMMON_BEGIN(h_doorbell_common) GEN_COMMON h_doorbell FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD #ifdef CONFIG_PPC_DOORBELL bl doorbell_exception #else - bl unknown_exception + bl unknown_async_exception #endif b interrupt_return @@ -2341,7 +2300,6 @@ EXC_VIRT_END(h_virt_irq, 0x4ea0, 0x20) EXC_COMMON_BEGIN(h_virt_irq_common) GEN_COMMON h_virt_irq FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl do_IRQ b interrupt_return @@ -2388,7 +2346,6 @@ EXC_VIRT_END(performance_monitor, 0x4f00, 0x20) EXC_COMMON_BEGIN(performance_monitor_common) GEN_COMMON performance_monitor FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl performance_monitor_exception b interrupt_return @@ -2404,7 +2361,6 @@ EXC_COMMON_BEGIN(performance_monitor_common) */ INT_DEFINE_BEGIN(altivec_unavailable) IVEC=0xf20 - IRECONCILE=0 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE IKVM_REAL=1 #endif @@ -2434,7 +2390,6 @@ BEGIN_FTR_SECTION b fast_interrupt_return #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 2: /* User process was in a transaction */ - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl altivec_unavailable_tm b interrupt_return @@ -2442,7 +2397,6 @@ BEGIN_FTR_SECTION 1: END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl altivec_unavailable_exception b interrupt_return @@ -2458,7 +2412,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) */ INT_DEFINE_BEGIN(vsx_unavailable) IVEC=0xf40 - IRECONCILE=0 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE IKVM_REAL=1 #endif @@ -2487,7 +2440,6 @@ BEGIN_FTR_SECTION b load_up_vsx #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 2: /* User process was in a transaction */ - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl vsx_unavailable_tm b interrupt_return @@ -2495,7 +2447,6 @@ BEGIN_FTR_SECTION 1: END_FTR_SECTION_IFSET(CPU_FTR_VSX) #endif - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl vsx_unavailable_exception b interrupt_return @@ -2830,7 +2781,6 @@ EXC_VIRT_NONE(0x5800, 0x100) INT_DEFINE_BEGIN(soft_nmi) IVEC=0x900 ISTACK=0 - IRECONCILE=0 /* Soft-NMI may fire under local_irq_disable */ INT_DEFINE_END(soft_nmi) /* @@ -2849,17 +2799,6 @@ EXC_COMMON_BEGIN(soft_nmi_common) subi r1,r1,INT_FRAME_SIZE __GEN_COMMON_BODY soft_nmi - /* - * Set IRQS_ALL_DISABLED and save PACAIRQHAPPENED (see - * system_reset_common) - */ - li r10,IRQS_ALL_DISABLED - stb r10,PACAIRQSOFTMASK(r13) - lbz r10,PACAIRQHAPPENED(r13) - std r10,RESULT(r1) - ori r10,r10,PACA_IRQ_HARD_DIS - stb r10,PACAIRQHAPPENED(r13) - addi r3,r1,STACK_FRAME_OVERHEAD bl soft_nmi_interrupt @@ -2867,14 +2806,6 @@ EXC_COMMON_BEGIN(soft_nmi_common) li r9,0 mtmsrd r9,1 - /* - * Restore soft mask settings. - */ - ld r10,RESULT(r1) - stb r10,PACAIRQHAPPENED(r13) - ld r10,SOFTE(r1) - stb r10,PACAIRQSOFTMASK(r13) - kuap_kernel_restore r9, r10 EXCEPTION_RESTORE_REGS hsrr=0 RFI_TO_KERNEL @@ -3148,9 +3079,6 @@ kvmppc_skip_Hinterrupt: * come here. */ -EXC_COMMON_BEGIN(ppc64_runlatch_on_trampoline) - b __ppc64_runlatch_on - USE_FIXED_SECTION(virt_trampolines) /* * All code below __end_interrupts is treated as soft-masked. If @@ -3221,99 +3149,3 @@ disable_machine_check: RFI_TO_KERNEL 1: mtlr r0 blr - -/* - * Hash table stuff - */ - .balign IFETCH_ALIGN_BYTES -do_hash_page: -#ifdef CONFIG_PPC_BOOK3S_64 - lis r0,(DSISR_BAD_FAULT_64S | DSISR_DABRMATCH | DSISR_KEYFAULT)@h - ori r0,r0,DSISR_BAD_FAULT_64S@l - and. r0,r5,r0 /* weird error? */ - bne- handle_page_fault /* if not, try to insert a HPTE */ - - /* - * If we are in an "NMI" (e.g., an interrupt when soft-disabled), then - * don't call hash_page, just fail the fault. This is required to - * prevent re-entrancy problems in the hash code, namely perf - * interrupts hitting while something holds H_PAGE_BUSY, and taking a - * hash fault. See the comment in hash_preload(). - */ - ld r11, PACA_THREAD_INFO(r13) - lwz r0,TI_PREEMPT(r11) - andis. r0,r0,NMI_MASK@h - bne 77f - - /* - * r3 contains the trap number - * r4 contains the faulting address - * r5 contains dsisr - * r6 msr - * - * at return r3 = 0 for success, 1 for page fault, negative for error - */ - bl __hash_page /* build HPTE if possible */ - cmpdi r3,0 /* see if __hash_page succeeded */ - - /* Success */ - beq interrupt_return /* Return from exception on success */ - - /* Error */ - blt- 13f - - /* Reload DAR/DSISR into r4/r5 for the DABR check below */ - ld r4,_DAR(r1) - ld r5,_DSISR(r1) -#endif /* CONFIG_PPC_BOOK3S_64 */ - -/* Here we have a page fault that hash_page can't handle. */ -handle_page_fault: -11: andis. r0,r5,DSISR_DABRMATCH@h - bne- handle_dabr_fault - addi r3,r1,STACK_FRAME_OVERHEAD - bl do_page_fault - cmpdi r3,0 - beq+ interrupt_return - mr r5,r3 - addi r3,r1,STACK_FRAME_OVERHEAD - ld r4,_DAR(r1) - bl __bad_page_fault - b interrupt_return - -/* We have a data breakpoint exception - handle it */ -handle_dabr_fault: - ld r4,_DAR(r1) - ld r5,_DSISR(r1) - addi r3,r1,STACK_FRAME_OVERHEAD - bl do_break - /* - * do_break() may have changed the NV GPRS while handling a breakpoint. - * If so, we need to restore them with their updated values. - */ - REST_NVGPRS(r1) - b interrupt_return - - -#ifdef CONFIG_PPC_BOOK3S_64 -/* We have a page fault that hash_page could handle but HV refused - * the PTE insertion - */ -13: mr r5,r3 - addi r3,r1,STACK_FRAME_OVERHEAD - ld r4,_DAR(r1) - bl low_hash_fault - b interrupt_return -#endif - -/* - * We come here as a result of a DSI at a point where we don't want - * to call hash_page, such as when we are accessing memory (possibly - * user memory) inside a PMU interrupt that occurred while interrupts - * were soft-disabled. We want to invoke the exception handler for - * the access, or panic if there isn't a handler. - */ -77: addi r3,r1,STACK_FRAME_OVERHEAD - li r5,SIGSEGV - bl bad_page_fault - b interrupt_return diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h index a2f72c966baf..5d4706c14572 100644 --- a/arch/powerpc/kernel/head_32.h +++ b/arch/powerpc/kernel/head_32.h @@ -47,7 +47,7 @@ lwz r1,TASK_STACK-THREAD(r1) addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 1: - mtcrf 0x7f, r1 + mtcrf 0x3f, r1 bt 32 - THREAD_ALIGN_SHIFT, stack_overflow #else subi r11, r1, INT_FRAME_SIZE /* use r1 if kernel */ @@ -116,114 +116,44 @@ .endm .macro SYSCALL_ENTRY trapno - mfspr r12,SPRN_SPRG_THREAD mfspr r9, SPRN_SRR1 -#ifdef CONFIG_VMAP_STACK - mfspr r11, SPRN_SRR0 - mtctr r11 - andi. r11, r9, MSR_PR + mfspr r10, SPRN_SRR0 + LOAD_REG_IMMEDIATE(r11, MSR_KERNEL) /* can take exceptions */ + lis r12, 1f@h + ori r12, r12, 1f@l + mtspr SPRN_SRR1, r11 + mtspr SPRN_SRR0, r12 + mfspr r12,SPRN_SPRG_THREAD mr r11, r1 lwz r1,TASK_STACK-THREAD(r12) - beq- 99f - addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE - li r10, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ - mtmsr r10 - isync tovirt(r12, r12) + addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE + rfi +1: stw r11,GPR1(r1) stw r11,0(r1) mr r11, r1 -#else - andi. r11, r9, MSR_PR - lwz r11,TASK_STACK-THREAD(r12) - beq- 99f - addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE - tophys(r11, r11) - stw r1,GPR1(r11) - stw r1,0(r11) - tovirt(r1, r11) /* set new kernel sp */ -#endif + stw r10,_NIP(r11) mflr r10 stw r10, _LINK(r11) -#ifdef CONFIG_VMAP_STACK - mfctr r10 -#else - mfspr r10,SPRN_SRR0 -#endif - stw r10,_NIP(r11) mfcr r10 rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */ stw r10,_CCR(r11) /* save registers */ #ifdef CONFIG_40x rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ -#else -#ifdef CONFIG_VMAP_STACK - LOAD_REG_IMMEDIATE(r10, MSR_KERNEL & ~MSR_IR) /* can take exceptions */ -#else - LOAD_REG_IMMEDIATE(r10, MSR_KERNEL & ~(MSR_IR|MSR_DR)) /* can take exceptions */ -#endif - mtmsr r10 /* (except for mach check in rtas) */ #endif lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */ stw r2,GPR2(r11) addi r10,r10,STACK_FRAME_REGS_MARKER@l stw r9,_MSR(r11) - li r2, \trapno + 1 + li r2, \trapno stw r10,8(r11) stw r2,_TRAP(r11) SAVE_GPR(0, r11) SAVE_4GPRS(3, r11) SAVE_2GPRS(7, r11) - addi r11,r1,STACK_FRAME_OVERHEAD addi r2,r12,-THREAD - stw r11,PT_REGS(r12) -#if defined(CONFIG_40x) - /* Check to see if the dbcr0 register is set up to debug. Use the - internal debug mode bit to do this. */ - lwz r12,THREAD_DBCR0(r12) - andis. r12,r12,DBCR0_IDM@h -#endif - ACCOUNT_CPU_USER_ENTRY(r2, r11, r12) -#if defined(CONFIG_40x) - beq+ 3f - /* From user and task is ptraced - load up global dbcr0 */ - li r12,-1 /* clear all pending debug events */ - mtspr SPRN_DBSR,r12 - lis r11,global_dbcr0@ha - tophys(r11,r11) - addi r11,r11,global_dbcr0@l - lwz r12,0(r11) - mtspr SPRN_DBCR0,r12 - lwz r12,4(r11) - addi r12,r12,-1 - stw r12,4(r11) -#endif - -3: - tovirt_novmstack r2, r2 /* set r2 to current */ - lis r11, transfer_to_syscall@h - ori r11, r11, transfer_to_syscall@l -#ifdef CONFIG_TRACE_IRQFLAGS - /* - * If MSR is changing we need to keep interrupts disabled at this point - * otherwise we might risk taking an interrupt before we tell lockdep - * they are enabled. - */ - LOAD_REG_IMMEDIATE(r10, MSR_KERNEL) - rlwimi r10, r9, 0, MSR_EE -#else - LOAD_REG_IMMEDIATE(r10, MSR_KERNEL | MSR_EE) -#endif -#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS) - mtspr SPRN_NRI, r0 -#endif - mtspr SPRN_SRR1,r10 - mtspr SPRN_SRR0,r11 - rfi /* jump to handler, enable MMU */ -#ifdef CONFIG_40x - b . /* Prevent prefetch past rfi */ -#endif -99: b ret_from_kernel_syscall + b transfer_to_syscall /* jump to handler */ .endm .macro save_dar_dsisr_on_stack reg1, reg2, sp diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S index a1ae00689e0f..24724a7dad49 100644 --- a/arch/powerpc/kernel/head_40x.S +++ b/arch/powerpc/kernel/head_40x.S @@ -179,9 +179,9 @@ _ENTRY(saved_ksp_limit) */ START_EXCEPTION(0x0300, DataStorage) EXCEPTION_PROLOG - mfspr r5, SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + mfspr r5, SPRN_ESR /* Grab the ESR, save it */ stw r5, _ESR(r11) - mfspr r4, SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + mfspr r4, SPRN_DEAR /* Grab the DEAR, save it */ stw r4, _DEAR(r11) EXC_XFER_LITE(0x300, handle_page_fault) @@ -191,9 +191,9 @@ _ENTRY(saved_ksp_limit) */ START_EXCEPTION(0x0400, InstructionAccess) EXCEPTION_PROLOG - mr r4,r12 /* Pass SRR0 as arg2 */ - stw r4, _DEAR(r11) - li r5,0 /* Pass zero as arg3 */ + li r5,0 + stw r5, _ESR(r11) /* Zero ESR */ + stw r12, _DEAR(r11) /* SRR0 as DEAR */ EXC_XFER_LITE(0x400, handle_page_fault) /* 0x0500 - External Interrupt Exception */ @@ -476,6 +476,7 @@ _ENTRY(saved_ksp_limit) /* continue normal handling for a critical exception... */ 2: mfspr r4,SPRN_DBSR + stw r4,_ESR(r11) /* DebugException takes DBSR in _ESR */ addi r3,r1,STACK_FRAME_OVERHEAD EXC_XFER_TEMPLATE(DebugException, 0x2002, \ (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 8e36718f3167..813fa305c33b 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -376,7 +376,7 @@ interrupt_base: /* Load the next available TLB index */ lwz r13,tlb_44x_index@l(r10) - bne 2f /* Bail if permission mismach */ + bne 2f /* Bail if permission mismatch */ /* Increment, rollover, and store TLB index */ addi r13,r13,1 @@ -471,7 +471,7 @@ interrupt_base: /* Load the next available TLB index */ lwz r13,tlb_44x_index@l(r10) - bne 2f /* Bail if permission mismach */ + bne 2f /* Bail if permission mismatch */ /* Increment, rollover, and store TLB index */ addi r13,r13,1 diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 52702f3db6df..46dff3f9c31f 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -165,7 +165,7 @@ SystemCall: /* On the MPC8xx, this is a software emulation interrupt. It occurs * for all unimplemented and illegal instructions. */ - EXCEPTION(0x1000, SoftEmu, program_check_exception, EXC_XFER_STD) + EXCEPTION(0x1000, SoftEmu, emulation_assist_interrupt, EXC_XFER_STD) . = 0x1100 /* @@ -312,14 +312,14 @@ DataStoreTLBMiss: . = 0x1300 InstructionTLBError: EXCEPTION_PROLOG - mr r4,r12 andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ andis. r10,r9,SRR1_ISI_NOPT@h beq+ .Litlbie - tlbie r4 + tlbie r12 /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */ .Litlbie: - stw r4, _DAR(r11) + stw r12, _DAR(r11) + stw r5, _DSISR(r11) EXC_XFER_LITE(0x400, handle_page_fault) /* This is the data TLB error on the MPC8xx. This could be due to @@ -364,10 +364,9 @@ do_databreakpoint: addi r3,r1,STACK_FRAME_OVERHEAD mfspr r4,SPRN_BAR stw r4,_DAR(r11) -#ifdef CONFIG_VMAP_STACK - lwz r5,_DSISR(r11) -#else +#ifndef CONFIG_VMAP_STACK mfspr r5,SPRN_DSISR + stw r5,_DSISR(r11) #endif EXC_XFER_STD(0x1c00, do_break) diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S index 858fbc8b19f3..727fdab557c9 100644 --- a/arch/powerpc/kernel/head_book3s_32.S +++ b/arch/powerpc/kernel/head_book3s_32.S @@ -238,8 +238,8 @@ __secondary_hold_acknowledge: /* System reset */ /* core99 pmac starts the seconary here by changing the vector, and - putting it back to what it was (unknown_exception) when done. */ - EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) + putting it back to what it was (unknown_async_exception) when done. */ + EXCEPTION(0x100, Reset, unknown_async_exception, EXC_XFER_STD) /* Machine check */ /* @@ -278,12 +278,6 @@ MachineCheck: 7: EXCEPTION_PROLOG_2 addi r3,r1,STACK_FRAME_OVERHEAD #ifdef CONFIG_PPC_CHRP -#ifdef CONFIG_VMAP_STACK - mfspr r4, SPRN_SPRG_THREAD - tovirt(r4, r4) - lwz r4, RTAS_SP(r4) - cmpwi cr1, r4, 0 -#endif beq cr1, machine_check_tramp twi 31, 0, 0 #else @@ -295,6 +289,7 @@ MachineCheck: DO_KVM 0x300 DataAccess: #ifdef CONFIG_VMAP_STACK +#ifdef CONFIG_PPC_BOOK3S_604 BEGIN_MMU_FTR_SECTION mtspr SPRN_SPRG_SCRATCH2,r10 mfspr r10, SPRN_SPRG_THREAD @@ -311,12 +306,14 @@ BEGIN_MMU_FTR_SECTION MMU_FTR_SECTION_ELSE b 1f ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE) +#endif 1: EXCEPTION_PROLOG_0 handle_dar_dsisr=1 EXCEPTION_PROLOG_1 b handle_page_fault_tramp_1 #else /* CONFIG_VMAP_STACK */ EXCEPTION_PROLOG handle_dar_dsisr=1 get_and_save_dar_dsisr_on_stack r4, r5, r11 +#ifdef CONFIG_PPC_BOOK3S_604 BEGIN_MMU_FTR_SECTION andis. r0, r5, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h bne handle_page_fault_tramp_2 /* if not, try to put a PTE */ @@ -324,8 +321,11 @@ BEGIN_MMU_FTR_SECTION bl hash_page b handle_page_fault_tramp_1 MMU_FTR_SECTION_ELSE +#endif b handle_page_fault_tramp_2 +#ifdef CONFIG_PPC_BOOK3S_604 ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE) +#endif #endif /* CONFIG_VMAP_STACK */ /* Instruction access exception. */ @@ -341,12 +341,14 @@ InstructionAccess: mfspr r11, SPRN_SRR1 /* check whether user or kernel */ stw r11, SRR1(r10) mfcr r10 +#ifdef CONFIG_PPC_BOOK3S_604 BEGIN_MMU_FTR_SECTION andis. r11, r11, SRR1_ISI_NOPT@h /* no pte found? */ bne hash_page_isi .Lhash_page_isi_cont: mfspr r11, SPRN_SRR1 /* check whether user or kernel */ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) +#endif andi. r11, r11, MSR_PR EXCEPTION_PROLOG_1 @@ -357,13 +359,15 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) beq 1f /* if so, try to put a PTE */ li r3,0 /* into the hash table */ mr r4,r12 /* SRR0 is fault address */ +#ifdef CONFIG_PPC_BOOK3S_604 BEGIN_MMU_FTR_SECTION bl hash_page END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) +#endif #endif /* CONFIG_VMAP_STACK */ -1: mr r4,r12 andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ - stw r4, _DAR(r11) + stw r5, _DSISR(r11) + stw r12, _DAR(r11) EXC_XFER_LITE(0x400, handle_page_fault) /* External interrupt */ @@ -640,7 +644,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) #endif #ifndef CONFIG_TAU_INT -#define TAUException unknown_exception +#define TAUException unknown_async_exception #endif EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_STD) @@ -685,13 +689,16 @@ handle_page_fault_tramp_1: #ifdef CONFIG_VMAP_STACK EXCEPTION_PROLOG_2 handle_dar_dsisr=1 #endif - lwz r4, _DAR(r11) lwz r5, _DSISR(r11) /* fall through */ handle_page_fault_tramp_2: + andis. r0, r5, DSISR_DABRMATCH@h + bne- 1f EXC_XFER_LITE(0x300, handle_page_fault) +1: EXC_XFER_STD(0x300, do_break) #ifdef CONFIG_VMAP_STACK +#ifdef CONFIG_PPC_BOOK3S_604 .macro save_regs_thread thread stw r0, THR0(\thread) stw r3, THR3(\thread) @@ -763,6 +770,7 @@ fast_hash_page_return: mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r10, SPRN_SPRG_SCRATCH0 rfi +#endif /* CONFIG_PPC_BOOK3S_604 */ stack_overflow: vmap_stack_overflow_exception diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 74e230c200fb..47857795f50a 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -106,10 +106,8 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) #endif mfspr r9, SPRN_SRR1 BOOKE_CLEAR_BTB(r11) - andi. r11, r9, MSR_PR lwz r11, TASK_STACK - THREAD(r10) rlwinm r12,r12,0,4,2 /* Clear SO bit in CR */ - beq- 99f ALLOC_STACK_FRAME(r11, THREAD_SIZE - INT_FRAME_SIZE) stw r12, _CCR(r11) /* save various registers */ mflr r12 @@ -124,60 +122,15 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) stw r2,GPR2(r11) addi r12, r12, STACK_FRAME_REGS_MARKER@l stw r9,_MSR(r11) - li r2, \trapno + 1 + li r2, \trapno stw r12, 8(r11) stw r2,_TRAP(r11) SAVE_GPR(0, r11) SAVE_4GPRS(3, r11) SAVE_2GPRS(7, r11) - addi r11,r1,STACK_FRAME_OVERHEAD addi r2,r10,-THREAD - stw r11,PT_REGS(r10) - /* Check to see if the dbcr0 register is set up to debug. Use the - internal debug mode bit to do this. */ - lwz r12,THREAD_DBCR0(r10) - andis. r12,r12,DBCR0_IDM@h - ACCOUNT_CPU_USER_ENTRY(r2, r11, r12) - beq+ 3f - /* From user and task is ptraced - load up global dbcr0 */ - li r12,-1 /* clear all pending debug events */ - mtspr SPRN_DBSR,r12 - lis r11,global_dbcr0@ha - tophys(r11,r11) - addi r11,r11,global_dbcr0@l -#ifdef CONFIG_SMP - lwz r10, TASK_CPU(r2) - slwi r10, r10, 3 - add r11, r11, r10 -#endif - lwz r12,0(r11) - mtspr SPRN_DBCR0,r12 - lwz r12,4(r11) - addi r12,r12,-1 - stw r12,4(r11) - -3: - tovirt(r2, r2) /* set r2 to current */ - lis r11, transfer_to_syscall@h - ori r11, r11, transfer_to_syscall@l -#ifdef CONFIG_TRACE_IRQFLAGS - /* - * If MSR is changing we need to keep interrupts disabled at this point - * otherwise we might risk taking an interrupt before we tell lockdep - * they are enabled. - */ - lis r10, MSR_KERNEL@h - ori r10, r10, MSR_KERNEL@l - rlwimi r10, r9, 0, MSR_EE -#else - lis r10, (MSR_KERNEL | MSR_EE)@h - ori r10, r10, (MSR_KERNEL | MSR_EE)@l -#endif - mtspr SPRN_SRR1,r10 - mtspr SPRN_SRR0,r11 - rfi /* jump to handler, enable MMU */ -99: b ret_from_kernel_syscall + b transfer_to_syscall /* jump to handler */ .endm /* To handle the additional exception priority levels on 40x and Book-E @@ -406,6 +359,7 @@ label: \ /* continue normal handling for a debug exception... */ \ 2: mfspr r4,SPRN_DBSR; \ + stw r4,_ESR(r11); /* DebugException takes DBSR in _ESR */\ addi r3,r1,STACK_FRAME_OVERHEAD; \ EXC_XFER_TEMPLATE(DebugException, 0x2008, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), debug_transfer_to_handler, ret_from_debug_exc) @@ -459,6 +413,7 @@ label: \ /* continue normal handling for a critical exception... */ \ 2: mfspr r4,SPRN_DBSR; \ + stw r4,_ESR(r11); /* DebugException takes DBSR in _ESR */\ addi r3,r1,STACK_FRAME_OVERHEAD; \ EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), crit_transfer_to_handler, ret_from_crit_exc) @@ -476,9 +431,7 @@ label: NORMAL_EXCEPTION_PROLOG(INST_STORAGE); \ mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ stw r5,_ESR(r11); \ - mr r4,r12; /* Pass SRR0 as arg2 */ \ - stw r4, _DEAR(r11); \ - li r5,0; /* Pass zero as arg3 */ \ + stw r12, _DEAR(r11); /* Pass SRR0 as arg2 */ \ EXC_XFER_LITE(0x0400, handle_page_fault) #define ALIGNMENT_EXCEPTION \ diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index fdd4d274c245..3f4a40cccef5 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -364,12 +364,12 @@ interrupt_base: /* Data Storage Interrupt */ START_EXCEPTION(DataStorage) NORMAL_EXCEPTION_PROLOG(DATA_STORAGE) - mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + mfspr r5,SPRN_ESR /* Grab the ESR, save it */ stw r5,_ESR(r11) - mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + mfspr r4,SPRN_DEAR /* Grab the DEAR, save it */ + stw r4, _DEAR(r11) andis. r10,r5,(ESR_ILK|ESR_DLK)@h bne 1f - stw r4, _DEAR(r11) EXC_XFER_LITE(0x0300, handle_page_fault) 1: addi r3,r1,STACK_FRAME_OVERHEAD diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 22f249b6f58d..f9e6d83e6720 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -52,28 +52,32 @@ _GLOBAL(isa300_idle_stop_mayloss) std r1,PACAR1(r13) mflr r4 mfcr r5 - /* use stack red zone rather than a new frame for saving regs */ - std r2,-8*0(r1) - std r14,-8*1(r1) - std r15,-8*2(r1) - std r16,-8*3(r1) - std r17,-8*4(r1) - std r18,-8*5(r1) - std r19,-8*6(r1) - std r20,-8*7(r1) - std r21,-8*8(r1) - std r22,-8*9(r1) - std r23,-8*10(r1) - std r24,-8*11(r1) - std r25,-8*12(r1) - std r26,-8*13(r1) - std r27,-8*14(r1) - std r28,-8*15(r1) - std r29,-8*16(r1) - std r30,-8*17(r1) - std r31,-8*18(r1) - std r4,-8*19(r1) - std r5,-8*20(r1) + /* + * Use the stack red zone rather than a new frame for saving regs since + * in the case of no GPR loss the wakeup code branches directly back to + * the caller without deallocating the stack frame first. + */ + std r2,-8*1(r1) + std r14,-8*2(r1) + std r15,-8*3(r1) + std r16,-8*4(r1) + std r17,-8*5(r1) + std r18,-8*6(r1) + std r19,-8*7(r1) + std r20,-8*8(r1) + std r21,-8*9(r1) + std r22,-8*10(r1) + std r23,-8*11(r1) + std r24,-8*12(r1) + std r25,-8*13(r1) + std r26,-8*14(r1) + std r27,-8*15(r1) + std r28,-8*16(r1) + std r29,-8*17(r1) + std r30,-8*18(r1) + std r31,-8*19(r1) + std r4,-8*20(r1) + std r5,-8*21(r1) /* 168 bytes */ PPC_STOP b . /* catch bugs */ @@ -89,8 +93,8 @@ _GLOBAL(isa300_idle_stop_mayloss) */ _GLOBAL(idle_return_gpr_loss) ld r1,PACAR1(r13) - ld r4,-8*19(r1) - ld r5,-8*20(r1) + ld r4,-8*20(r1) + ld r5,-8*21(r1) mtlr r4 mtcr r5 /* @@ -98,25 +102,25 @@ _GLOBAL(idle_return_gpr_loss) * from PACATOC. This could be avoided for that less common case * if KVM saved its r2. */ - ld r2,-8*0(r1) - ld r14,-8*1(r1) - ld r15,-8*2(r1) - ld r16,-8*3(r1) - ld r17,-8*4(r1) - ld r18,-8*5(r1) - ld r19,-8*6(r1) - ld r20,-8*7(r1) - ld r21,-8*8(r1) - ld r22,-8*9(r1) - ld r23,-8*10(r1) - ld r24,-8*11(r1) - ld r25,-8*12(r1) - ld r26,-8*13(r1) - ld r27,-8*14(r1) - ld r28,-8*15(r1) - ld r29,-8*16(r1) - ld r30,-8*17(r1) - ld r31,-8*18(r1) + ld r2,-8*1(r1) + ld r14,-8*2(r1) + ld r15,-8*3(r1) + ld r16,-8*4(r1) + ld r17,-8*5(r1) + ld r18,-8*6(r1) + ld r19,-8*7(r1) + ld r20,-8*8(r1) + ld r21,-8*9(r1) + ld r22,-8*10(r1) + ld r23,-8*11(r1) + ld r24,-8*12(r1) + ld r25,-8*13(r1) + ld r26,-8*14(r1) + ld r27,-8*15(r1) + ld r28,-8*16(r1) + ld r29,-8*17(r1) + ld r30,-8*18(r1) + ld r31,-8*19(r1) blr /* @@ -154,28 +158,32 @@ _GLOBAL(isa206_idle_insn_mayloss) std r1,PACAR1(r13) mflr r4 mfcr r5 - /* use stack red zone rather than a new frame for saving regs */ - std r2,-8*0(r1) - std r14,-8*1(r1) - std r15,-8*2(r1) - std r16,-8*3(r1) - std r17,-8*4(r1) - std r18,-8*5(r1) - std r19,-8*6(r1) - std r20,-8*7(r1) - std r21,-8*8(r1) - std r22,-8*9(r1) - std r23,-8*10(r1) - std r24,-8*11(r1) - std r25,-8*12(r1) - std r26,-8*13(r1) - std r27,-8*14(r1) - std r28,-8*15(r1) - std r29,-8*16(r1) - std r30,-8*17(r1) - std r31,-8*18(r1) - std r4,-8*19(r1) - std r5,-8*20(r1) + /* + * Use the stack red zone rather than a new frame for saving regs since + * in the case of no GPR loss the wakeup code branches directly back to + * the caller without deallocating the stack frame first. + */ + std r2,-8*1(r1) + std r14,-8*2(r1) + std r15,-8*3(r1) + std r16,-8*4(r1) + std r17,-8*5(r1) + std r18,-8*6(r1) + std r19,-8*7(r1) + std r20,-8*8(r1) + std r21,-8*9(r1) + std r22,-8*10(r1) + std r23,-8*11(r1) + std r24,-8*12(r1) + std r25,-8*13(r1) + std r26,-8*14(r1) + std r27,-8*15(r1) + std r28,-8*16(r1) + std r29,-8*17(r1) + std r30,-8*18(r1) + std r31,-8*19(r1) + std r4,-8*20(r1) + std r5,-8*21(r1) cmpwi r3,PNV_THREAD_NAP bne 1f IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP) diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/interrupt.c similarity index 69% rename from arch/powerpc/kernel/syscall_64.c rename to arch/powerpc/kernel/interrupt.c index 7c85ed04a164..398cd86b6ada 100644 --- a/arch/powerpc/kernel/syscall_64.c +++ b/arch/powerpc/kernel/interrupt.c @@ -1,10 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-or-later +#include #include +#include + #include #include #include +#include #include +#include #include #include #include @@ -24,16 +29,21 @@ notrace long system_call_exception(long r3, long r4, long r5, { syscall_fn f; + regs->orig_gpr3 = r3; + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED); + CT_WARN_ON(ct_state() == CONTEXT_KERNEL); + user_exit_irqoff(); + trace_hardirqs_off(); /* finish reconciling */ - if (IS_ENABLED(CONFIG_PPC_BOOK3S)) + if (!IS_ENABLED(CONFIG_BOOKE) && !IS_ENABLED(CONFIG_40x)) BUG_ON(!(regs->msr & MSR_RI)); BUG_ON(!(regs->msr & MSR_PR)); BUG_ON(!FULL_REGS(regs)); - BUG_ON(regs->softe != IRQS_ENABLED); + BUG_ON(arch_irq_disabled_regs(regs)); #ifdef CONFIG_PPC_PKEY if (mmu_has_feature(MMU_FTR_PKEY)) { @@ -59,19 +69,15 @@ notrace long system_call_exception(long r3, long r4, long r5, isync(); } else #endif +#ifdef CONFIG_PPC64 kuap_check_amr(); +#endif + + booke_restore_dbcr0(); account_cpu_user_entry(); -#ifdef CONFIG_PPC_SPLPAR - if (IS_ENABLED(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && - firmware_has_feature(FW_FEATURE_SPLPAR)) { - struct lppaca *lp = local_paca->lppaca_ptr; - - if (unlikely(local_paca->dtl_ridx != be64_to_cpu(lp->dtl_idx))) - accumulate_stolen_time(); - } -#endif + account_stolen_time(); /* * This is not required for the syscall exit path, but makes the @@ -79,12 +85,12 @@ notrace long system_call_exception(long r3, long r4, long r5, * frame, or if the unwinder was taught the first stack frame always * returns to user with IRQS_ENABLED, this store could be avoided! */ - regs->softe = IRQS_ENABLED; + irq_soft_mask_regs_set_state(regs, IRQS_ENABLED); local_irq_enable(); if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) { - if (unlikely(regs->trap == 0x7ff0)) { + if (unlikely(trap_is_unsupported_scv(regs))) { /* Unsupported scv vector */ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); return regs->gpr[3]; @@ -107,7 +113,7 @@ notrace long system_call_exception(long r3, long r4, long r5, r8 = regs->gpr[8]; } else if (unlikely(r0 >= NR_syscalls)) { - if (unlikely(regs->trap == 0x7ff0)) { + if (unlikely(trap_is_unsupported_scv(regs))) { /* Unsupported scv vector */ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); return regs->gpr[3]; @@ -118,7 +124,7 @@ notrace long system_call_exception(long r3, long r4, long r5, /* May be faster to do array_index_nospec? */ barrier_nospec(); - if (unlikely(is_32bit_task())) { + if (unlikely(is_compat_task())) { f = (void *)compat_sys_call_table[r0]; r3 &= 0x00000000ffffffffULL; @@ -138,8 +144,12 @@ notrace long system_call_exception(long r3, long r4, long r5, /* * local irqs must be disabled. Returns false if the caller must re-enable * them, check for new work, and try again. + * + * This should be called with local irqs disabled, but if they were previously + * enabled when the interrupt handler returns (indicating a process-context / + * synchronous interrupt) then irqs_enabled should be true. */ -static notrace inline bool prep_irq_for_enabled_exit(bool clear_ri) +static notrace inline bool __prep_irq_for_enabled_exit(bool clear_ri) { /* This must be done with RI=1 because tracing may touch vmaps */ trace_hardirqs_on(); @@ -149,6 +159,7 @@ static notrace inline bool prep_irq_for_enabled_exit(bool clear_ri) __hard_EE_RI_disable(); else __hard_irq_disable(); +#ifdef CONFIG_PPC64 if (unlikely(lazy_irq_pending_nocheck())) { /* Took an interrupt, may have more exit work to do. */ if (clear_ri) @@ -160,10 +171,63 @@ static notrace inline bool prep_irq_for_enabled_exit(bool clear_ri) } local_paca->irq_happened = 0; irq_soft_mask_set(IRQS_ENABLED); - +#endif return true; } +static notrace inline bool prep_irq_for_enabled_exit(bool clear_ri, bool irqs_enabled) +{ + if (__prep_irq_for_enabled_exit(clear_ri)) + return true; + + /* + * Must replay pending soft-masked interrupts now. Don't just + * local_irq_enabe(); local_irq_disable(); because if we are + * returning from an asynchronous interrupt here, another one + * might hit after irqs are enabled, and it would exit via this + * same path allowing another to fire, and so on unbounded. + * + * If interrupts were enabled when this interrupt exited, + * indicating a process context (synchronous) interrupt, + * local_irq_enable/disable can be used, which will enable + * interrupts rather than keeping them masked (unclear how + * much benefit this is over just replaying for all cases, + * because we immediately disable again, so all we're really + * doing is allowing hard interrupts to execute directly for + * a very small time, rather than being masked and replayed). + */ + if (irqs_enabled) { + local_irq_enable(); + local_irq_disable(); + } else { + replay_soft_interrupts(); + } + + return false; +} + +static notrace void booke_load_dbcr0(void) +{ +#ifdef CONFIG_PPC_ADV_DEBUG_REGS + unsigned long dbcr0 = current->thread.debug.dbcr0; + + if (likely(!(dbcr0 & DBCR0_IDM))) + return; + + /* + * Check to see if the dbcr0 register is set up to debug. + * Use the internal debug mode bit to do this. + */ + mtmsr(mfmsr() & ~MSR_DE); + if (IS_ENABLED(CONFIG_PPC32)) { + isync(); + global_dbcr0[smp_processor_id()] = mfspr(SPRN_DBCR0); + } + mtspr(SPRN_DBCR0, dbcr0); + mtspr(SPRN_DBSR, -1); +#endif +} + /* * This should be called after a syscall returns, with r3 the return value * from the syscall. If this function returns non-zero, the system call @@ -177,20 +241,24 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3, struct pt_regs *regs, long scv) { - unsigned long *ti_flagsp = ¤t_thread_info()->flags; unsigned long ti_flags; unsigned long ret = 0; + bool is_not_scv = !IS_ENABLED(CONFIG_PPC_BOOK3S_64) || !scv; + CT_WARN_ON(ct_state() == CONTEXT_USER); + +#ifdef CONFIG_PPC64 kuap_check_amr(); +#endif regs->result = r3; /* Check whether the syscall is issued inside a restartable sequence */ rseq_syscall(regs); - ti_flags = *ti_flagsp; + ti_flags = current_thread_info()->flags; - if (unlikely(r3 >= (unsigned long)-MAX_ERRNO) && !scv) { + if (unlikely(r3 >= (unsigned long)-MAX_ERRNO) && is_not_scv) { if (likely(!(ti_flags & (_TIF_NOERROR | _TIF_RESTOREALL)))) { r3 = -r3; regs->ccr |= 0x10000000; /* Set SO bit in CR */ @@ -202,7 +270,7 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3, ret = _TIF_RESTOREALL; else regs->gpr[3] = r3; - clear_bits(_TIF_PERSYSCALL_MASK, ti_flagsp); + clear_bits(_TIF_PERSYSCALL_MASK, ¤t_thread_info()->flags); } else { regs->gpr[3] = r3; } @@ -212,9 +280,10 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3, ret |= _TIF_RESTOREALL; } -again: local_irq_disable(); - ti_flags = READ_ONCE(*ti_flagsp); + +again: + ti_flags = READ_ONCE(current_thread_info()->flags); while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) { local_irq_enable(); if (ti_flags & _TIF_NEED_RESCHED) { @@ -230,7 +299,7 @@ again: do_notify_resume(regs, ti_flags); } local_irq_disable(); - ti_flags = READ_ONCE(*ti_flagsp); + ti_flags = READ_ONCE(current_thread_info()->flags); } if (IS_ENABLED(CONFIG_PPC_BOOK3S) && IS_ENABLED(CONFIG_PPC_FPU)) { @@ -257,9 +326,13 @@ again: } } + user_enter_irqoff(); + /* scv need not set RI=0 because SRRs are not used */ - if (unlikely(!prep_irq_for_enabled_exit(!scv))) { + if (unlikely(!__prep_irq_for_enabled_exit(is_not_scv))) { + user_exit_irqoff(); local_irq_enable(); + local_irq_disable(); goto again; } @@ -267,9 +340,11 @@ again: local_paca->tm_scratch = regs->msr; #endif + booke_load_dbcr0(); + account_cpu_user_exit(); -#ifdef CONFIG_PPC_BOOK3S /* BOOK3E not yet using this */ +#ifdef CONFIG_PPC_BOOK3S_64 /* BOOK3E and ppc32 not using this */ /* * We do this at the end so that we do context switch with KERNEL AMR */ @@ -278,33 +353,32 @@ again: return ret; } -#ifdef CONFIG_PPC_BOOK3S /* BOOK3E not yet using this */ +#ifndef CONFIG_PPC_BOOK3E_64 /* BOOK3E not yet using this */ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned long msr) { -#ifdef CONFIG_PPC_BOOK3E - struct thread_struct *ts = ¤t->thread; -#endif - unsigned long *ti_flagsp = ¤t_thread_info()->flags; unsigned long ti_flags; unsigned long flags; unsigned long ret = 0; - if (IS_ENABLED(CONFIG_PPC_BOOK3S)) + if (!IS_ENABLED(CONFIG_BOOKE) && !IS_ENABLED(CONFIG_40x)) BUG_ON(!(regs->msr & MSR_RI)); BUG_ON(!(regs->msr & MSR_PR)); BUG_ON(!FULL_REGS(regs)); - BUG_ON(regs->softe != IRQS_ENABLED); + BUG_ON(arch_irq_disabled_regs(regs)); + CT_WARN_ON(ct_state() == CONTEXT_USER); /* * We don't need to restore AMR on the way back to userspace for KUAP. * AMR can only have been unlocked if we interrupted the kernel. */ +#ifdef CONFIG_PPC64 kuap_check_amr(); +#endif local_irq_save(flags); again: - ti_flags = READ_ONCE(*ti_flagsp); + ti_flags = READ_ONCE(current_thread_info()->flags); while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) { local_irq_enable(); /* returning to user: may enable */ if (ti_flags & _TIF_NEED_RESCHED) { @@ -315,7 +389,7 @@ again: do_notify_resume(regs, ti_flags); } local_irq_disable(); - ti_flags = READ_ONCE(*ti_flagsp); + ti_flags = READ_ONCE(current_thread_info()->flags); } if (IS_ENABLED(CONFIG_PPC_BOOK3S) && IS_ENABLED(CONFIG_PPC_FPU)) { @@ -336,23 +410,16 @@ again: } } - if (unlikely(!prep_irq_for_enabled_exit(true))) { + user_enter_irqoff(); + + if (unlikely(!__prep_irq_for_enabled_exit(true))) { + user_exit_irqoff(); local_irq_enable(); local_irq_disable(); goto again; } -#ifdef CONFIG_PPC_BOOK3E - if (unlikely(ts->debug.dbcr0 & DBCR0_IDM)) { - /* - * Check to see if the dbcr0 register is set up to debug. - * Use the internal debug mode bit to do this. - */ - mtmsr(mfmsr() & ~MSR_DE); - mtspr(SPRN_DBCR0, ts->debug.dbcr0); - mtspr(SPRN_DBSR, -1); - } -#endif + booke_load_dbcr0(); #ifdef CONFIG_PPC_TRANSACTIONAL_MEM local_paca->tm_scratch = regs->msr; @@ -363,7 +430,9 @@ again: /* * We do this at the end so that we do context switch with KERNEL AMR */ +#ifdef CONFIG_PPC64 kuap_user_restore(regs); +#endif return ret; } @@ -372,56 +441,56 @@ void preempt_schedule_irq(void); notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsigned long msr) { - unsigned long *ti_flagsp = ¤t_thread_info()->flags; unsigned long flags; unsigned long ret = 0; +#ifdef CONFIG_PPC64 unsigned long amr; +#endif - if (IS_ENABLED(CONFIG_PPC_BOOK3S) && unlikely(!(regs->msr & MSR_RI))) + if (!IS_ENABLED(CONFIG_BOOKE) && !IS_ENABLED(CONFIG_40x) && + unlikely(!(regs->msr & MSR_RI))) unrecoverable_exception(regs); BUG_ON(regs->msr & MSR_PR); BUG_ON(!FULL_REGS(regs)); + /* + * CT_WARN_ON comes here via program_check_exception, + * so avoid recursion. + */ + if (TRAP(regs) != 0x700) + CT_WARN_ON(ct_state() == CONTEXT_USER); +#ifdef CONFIG_PPC64 amr = kuap_get_and_check_amr(); +#endif - if (unlikely(*ti_flagsp & _TIF_EMULATE_STACK_STORE)) { - clear_bits(_TIF_EMULATE_STACK_STORE, ti_flagsp); + if (unlikely(current_thread_info()->flags & _TIF_EMULATE_STACK_STORE)) { + clear_bits(_TIF_EMULATE_STACK_STORE, ¤t_thread_info()->flags); ret = 1; } local_irq_save(flags); - if (regs->softe == IRQS_ENABLED) { + if (!arch_irq_disabled_regs(regs)) { /* Returning to a kernel context with local irqs enabled. */ WARN_ON_ONCE(!(regs->msr & MSR_EE)); again: if (IS_ENABLED(CONFIG_PREEMPT)) { /* Return to preemptible kernel context */ - if (unlikely(*ti_flagsp & _TIF_NEED_RESCHED)) { + if (unlikely(current_thread_info()->flags & _TIF_NEED_RESCHED)) { if (preempt_count() == 0) preempt_schedule_irq(); } } - if (unlikely(!prep_irq_for_enabled_exit(true))) { - /* - * Can't local_irq_restore to replay if we were in - * interrupt context. Must replay directly. - */ - if (irqs_disabled_flags(flags)) { - replay_soft_interrupts(); - } else { - local_irq_restore(flags); - local_irq_save(flags); - } - /* Took an interrupt, may have more exit work to do. */ + if (unlikely(!prep_irq_for_enabled_exit(true, !irqs_disabled_flags(flags)))) goto again; - } } else { /* Returning to a kernel context with local irqs disabled. */ __hard_EE_RI_disable(); +#ifdef CONFIG_PPC64 if (regs->msr & MSR_EE) local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; +#endif } @@ -434,7 +503,9 @@ again: * which would cause Read-After-Write stalls. Hence, we take the AMR * value from the check above. */ +#ifdef CONFIG_PPC64 kuap_kernel_restore(regs, amr); +#endif return ret; } diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 5b69a6a72a0e..c00214a4355c 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,47 @@ #define DBG(...) +#ifdef CONFIG_IOMMU_DEBUGFS +static int iommu_debugfs_weight_get(void *data, u64 *val) +{ + struct iommu_table *tbl = data; + *val = bitmap_weight(tbl->it_map, tbl->it_size); + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(iommu_debugfs_fops_weight, iommu_debugfs_weight_get, NULL, "%llu\n"); + +static void iommu_debugfs_add(struct iommu_table *tbl) +{ + char name[10]; + struct dentry *liobn_entry; + + sprintf(name, "%08lx", tbl->it_index); + liobn_entry = debugfs_create_dir(name, iommu_debugfs_dir); + + debugfs_create_file_unsafe("weight", 0400, liobn_entry, tbl, &iommu_debugfs_fops_weight); + debugfs_create_ulong("it_size", 0400, liobn_entry, &tbl->it_size); + debugfs_create_ulong("it_page_shift", 0400, liobn_entry, &tbl->it_page_shift); + debugfs_create_ulong("it_reserved_start", 0400, liobn_entry, &tbl->it_reserved_start); + debugfs_create_ulong("it_reserved_end", 0400, liobn_entry, &tbl->it_reserved_end); + debugfs_create_ulong("it_indirect_levels", 0400, liobn_entry, &tbl->it_indirect_levels); + debugfs_create_ulong("it_level_size", 0400, liobn_entry, &tbl->it_level_size); +} + +static void iommu_debugfs_del(struct iommu_table *tbl) +{ + char name[10]; + struct dentry *liobn_entry; + + sprintf(name, "%08lx", tbl->it_index); + liobn_entry = debugfs_lookup(name, iommu_debugfs_dir); + if (liobn_entry) + debugfs_remove(liobn_entry); +} +#else +static void iommu_debugfs_add(struct iommu_table *tbl){} +static void iommu_debugfs_del(struct iommu_table *tbl){} +#endif + static int novmerge; static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int); @@ -725,6 +767,8 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid, welcomed = 1; } + iommu_debugfs_add(tbl); + return tbl; } @@ -744,6 +788,8 @@ static void iommu_table_free(struct kref *kref) return; } + iommu_debugfs_del(tbl); + iommu_table_release_pages(tbl); /* verify that table contains no entries */ diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index cc7a6271b6b4..086b0a743329 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -54,6 +54,7 @@ #include #include +#include #include #include #include @@ -269,6 +270,31 @@ again: } } +#if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_KUAP) +static inline void replay_soft_interrupts_irqrestore(void) +{ + unsigned long kuap_state = get_kuap(); + + /* + * Check if anything calls local_irq_enable/restore() when KUAP is + * disabled (user access enabled). We handle that case here by saving + * and re-locking AMR but we shouldn't get here in the first place, + * hence the warning. + */ + kuap_check_amr(); + + if (kuap_state != AMR_KUAP_BLOCKED) + set_kuap(AMR_KUAP_BLOCKED); + + replay_soft_interrupts(); + + if (kuap_state != AMR_KUAP_BLOCKED) + set_kuap(kuap_state); +} +#else +#define replay_soft_interrupts_irqrestore() replay_soft_interrupts() +#endif + notrace void arch_local_irq_restore(unsigned long mask) { unsigned char irq_happened; @@ -332,7 +358,7 @@ notrace void arch_local_irq_restore(unsigned long mask) irq_soft_mask_set(IRQS_ALL_DISABLED); trace_hardirqs_off(); - replay_soft_interrupts(); + replay_soft_interrupts_irqrestore(); local_paca->irq_happened = 0; trace_hardirqs_on(); @@ -644,8 +670,6 @@ void __do_irq(struct pt_regs *regs) { unsigned int irq; - irq_enter(); - trace_irq_entry(regs); /* @@ -665,11 +689,9 @@ void __do_irq(struct pt_regs *regs) generic_handle_irq(irq); trace_irq_exit(regs); - - irq_exit(); } -void do_IRQ(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_ASYNC(do_IRQ) { struct pt_regs *old_regs = set_irq_regs(regs); void *cursp, *irqsp, *sirqsp; diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index 9f3e133b57b7..11f0cae086ed 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -17,22 +17,15 @@ #include #include #include +#include +#include #include #include #include +#include -static DEFINE_PER_CPU(int, mce_nest_count); -static DEFINE_PER_CPU(struct machine_check_event[MAX_MC_EVT], mce_event); - -/* Queue for delayed MCE events. */ -static DEFINE_PER_CPU(int, mce_queue_count); -static DEFINE_PER_CPU(struct machine_check_event[MAX_MC_EVT], mce_event_queue); - -/* Queue for delayed MCE UE events. */ -static DEFINE_PER_CPU(int, mce_ue_count); -static DEFINE_PER_CPU(struct machine_check_event[MAX_MC_EVT], - mce_ue_event_queue); +#include "setup.h" static void machine_check_process_queued_event(struct irq_work *work); static void machine_check_ue_irq_work(struct irq_work *work); @@ -103,9 +96,10 @@ void save_mce_event(struct pt_regs *regs, long handled, struct mce_error_info *mce_err, uint64_t nip, uint64_t addr, uint64_t phys_addr) { - int index = __this_cpu_inc_return(mce_nest_count) - 1; - struct machine_check_event *mce = this_cpu_ptr(&mce_event[index]); + int index = local_paca->mce_info->mce_nest_count++; + struct machine_check_event *mce; + mce = &local_paca->mce_info->mce_event[index]; /* * Return if we don't have enough space to log mce event. * mce_nest_count may go beyond MAX_MC_EVT but that's ok, @@ -191,7 +185,7 @@ void save_mce_event(struct pt_regs *regs, long handled, */ int get_mce_event(struct machine_check_event *mce, bool release) { - int index = __this_cpu_read(mce_nest_count) - 1; + int index = local_paca->mce_info->mce_nest_count - 1; struct machine_check_event *mc_evt; int ret = 0; @@ -201,7 +195,7 @@ int get_mce_event(struct machine_check_event *mce, bool release) /* Check if we have MCE info to process. */ if (index < MAX_MC_EVT) { - mc_evt = this_cpu_ptr(&mce_event[index]); + mc_evt = &local_paca->mce_info->mce_event[index]; /* Copy the event structure and release the original */ if (mce) *mce = *mc_evt; @@ -211,7 +205,7 @@ int get_mce_event(struct machine_check_event *mce, bool release) } /* Decrement the count to free the slot. */ if (release) - __this_cpu_dec(mce_nest_count); + local_paca->mce_info->mce_nest_count--; return ret; } @@ -233,13 +227,14 @@ static void machine_check_ue_event(struct machine_check_event *evt) { int index; - index = __this_cpu_inc_return(mce_ue_count) - 1; + index = local_paca->mce_info->mce_ue_count++; /* If queue is full, just return for now. */ if (index >= MAX_MC_EVT) { - __this_cpu_dec(mce_ue_count); + local_paca->mce_info->mce_ue_count--; return; } - memcpy(this_cpu_ptr(&mce_ue_event_queue[index]), evt, sizeof(*evt)); + memcpy(&local_paca->mce_info->mce_ue_event_queue[index], + evt, sizeof(*evt)); /* Queue work to process this event later. */ irq_work_queue(&mce_ue_event_irq_work); @@ -256,13 +251,14 @@ void machine_check_queue_event(void) if (!get_mce_event(&evt, MCE_EVENT_RELEASE)) return; - index = __this_cpu_inc_return(mce_queue_count) - 1; + index = local_paca->mce_info->mce_queue_count++; /* If queue is full, just return for now. */ if (index >= MAX_MC_EVT) { - __this_cpu_dec(mce_queue_count); + local_paca->mce_info->mce_queue_count--; return; } - memcpy(this_cpu_ptr(&mce_event_queue[index]), &evt, sizeof(evt)); + memcpy(&local_paca->mce_info->mce_event_queue[index], + &evt, sizeof(evt)); /* Queue irq work to process this event later. */ irq_work_queue(&mce_event_process_work); @@ -289,9 +285,9 @@ static void machine_process_ue_event(struct work_struct *work) int index; struct machine_check_event *evt; - while (__this_cpu_read(mce_ue_count) > 0) { - index = __this_cpu_read(mce_ue_count) - 1; - evt = this_cpu_ptr(&mce_ue_event_queue[index]); + while (local_paca->mce_info->mce_ue_count > 0) { + index = local_paca->mce_info->mce_ue_count - 1; + evt = &local_paca->mce_info->mce_ue_event_queue[index]; blocking_notifier_call_chain(&mce_notifier_list, 0, evt); #ifdef CONFIG_MEMORY_FAILURE /* @@ -304,7 +300,7 @@ static void machine_process_ue_event(struct work_struct *work) */ if (evt->error_type == MCE_ERROR_TYPE_UE) { if (evt->u.ue_error.ignore_event) { - __this_cpu_dec(mce_ue_count); + local_paca->mce_info->mce_ue_count--; continue; } @@ -320,7 +316,7 @@ static void machine_process_ue_event(struct work_struct *work) "was generated\n"); } #endif - __this_cpu_dec(mce_ue_count); + local_paca->mce_info->mce_ue_count--; } } /* @@ -338,17 +334,17 @@ static void machine_check_process_queued_event(struct irq_work *work) * For now just print it to console. * TODO: log this error event to FSP or nvram. */ - while (__this_cpu_read(mce_queue_count) > 0) { - index = __this_cpu_read(mce_queue_count) - 1; - evt = this_cpu_ptr(&mce_event_queue[index]); + while (local_paca->mce_info->mce_queue_count > 0) { + index = local_paca->mce_info->mce_queue_count - 1; + evt = &local_paca->mce_info->mce_event_queue[index]; if (evt->error_type == MCE_ERROR_TYPE_UE && evt->u.ue_error.ignore_event) { - __this_cpu_dec(mce_queue_count); + local_paca->mce_info->mce_queue_count--; continue; } machine_check_print_event_info(evt, false, false); - __this_cpu_dec(mce_queue_count); + local_paca->mce_info->mce_queue_count--; } } @@ -588,15 +584,9 @@ EXPORT_SYMBOL_GPL(machine_check_print_event_info); * * regs->nip and regs->msr contains srr0 and ssr1. */ -long notrace machine_check_early(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_NMI(machine_check_early) { long handled = 0; - u8 ftrace_enabled = this_cpu_get_ftrace_enabled(); - - this_cpu_set_ftrace_enabled(0); - /* Do not use nmi_enter/exit for pseries hpte guest */ - if (radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) - nmi_enter(); hv_nmi_check_nonrecoverable(regs); @@ -606,11 +596,6 @@ long notrace machine_check_early(struct pt_regs *regs) if (ppc_md.machine_check_early) handled = ppc_md.machine_check_early(regs); - if (radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) - nmi_exit(); - - this_cpu_set_ftrace_enabled(ftrace_enabled); - return handled; } @@ -722,7 +707,7 @@ long hmi_handle_debugtrig(struct pt_regs *regs) /* * Return values: */ -long hmi_exception_realmode(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_NMI(hmi_exception_realmode) { int ret; @@ -741,3 +726,24 @@ long hmi_exception_realmode(struct pt_regs *regs) return 1; } + +void __init mce_init(void) +{ + struct mce_info *mce_info; + u64 limit; + int i; + + limit = min(ppc64_bolted_size(), ppc64_rma_size); + for_each_possible_cpu(i) { + mce_info = memblock_alloc_try_nid(sizeof(*mce_info), + __alignof__(*mce_info), + MEMBLOCK_LOW_LIMIT, + limit, cpu_to_node(i)); + if (!mce_info) + goto err; + paca_ptrs[i]->mce_info = mce_info; + } + return; +err: + panic("Failed to allocate memory for MCE event data\n"); +} diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index 69bfe96884e2..7f7cdbeacd1a 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -141,30 +141,11 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op) } } -/* - * emulate_step() requires insn to be emulated as - * second parameter. Load register 'r4' with the - * instruction. - */ -void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr) -{ - /* addis r4,0,(insn)@h */ - patch_instruction((struct ppc_inst *)addr, - ppc_inst(PPC_INST_ADDIS | ___PPC_RT(4) | - ((val >> 16) & 0xffff))); - addr++; - - /* ori r4,r4,(insn)@l */ - patch_instruction((struct ppc_inst *)addr, - ppc_inst(PPC_INST_ORI | ___PPC_RA(4) | - ___PPC_RS(4) | (val & 0xffff))); -} - /* * Generate instructions to load provided immediate 64-bit value * to register 'reg' and patch these instructions at 'addr'. */ -void patch_imm64_load_insns(unsigned long val, int reg, kprobe_opcode_t *addr) +static void patch_imm64_load_insns(unsigned long val, int reg, kprobe_opcode_t *addr) { /* lis reg,(op)@highest */ patch_instruction((struct ppc_inst *)addr, diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 2b555997b295..001e90cd8948 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1699,3 +1699,13 @@ static void fixup_hide_host_resource_fsl(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); + + +static int __init discover_phbs(void) +{ + if (ppc_md.discover_phbs) + ppc_md.discover_phbs(); + + return 0; +} +core_initcall(discover_phbs); diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index e99b7c547d7e..61571ae23953 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -443,46 +443,6 @@ void *pci_traverse_device_nodes(struct device_node *start, } EXPORT_SYMBOL_GPL(pci_traverse_device_nodes); -static struct pci_dn *pci_dn_next_one(struct pci_dn *root, - struct pci_dn *pdn) -{ - struct list_head *next = pdn->child_list.next; - - if (next != &pdn->child_list) - return list_entry(next, struct pci_dn, list); - - while (1) { - if (pdn == root) - return NULL; - - next = pdn->list.next; - if (next != &pdn->parent->child_list) - break; - - pdn = pdn->parent; - } - - return list_entry(next, struct pci_dn, list); -} - -void *traverse_pci_dn(struct pci_dn *root, - void *(*fn)(struct pci_dn *, void *), - void *data) -{ - struct pci_dn *pdn = root; - void *ret; - - /* Only scan the child nodes */ - for (pdn = pci_dn_next_one(root, pdn); pdn; - pdn = pci_dn_next_one(root, pdn)) { - ret = fn(pdn, data); - if (ret) - return ret; - } - - return NULL; -} - static void *add_pdn(struct device_node *dn, void *data) { struct pci_controller *hose = data; @@ -521,28 +481,6 @@ void pci_devs_phb_init_dynamic(struct pci_controller *phb) pci_traverse_device_nodes(dn, add_pdn, phb); } -/** - * pci_devs_phb_init - Initialize phbs and pci devs under them. - * - * This routine walks over all phb's (pci-host bridges) on the - * system, and sets up assorted pci-related structures - * (including pci info in the device node structs) for each - * pci device found underneath. This routine runs once, - * early in the boot sequence. - */ -static int __init pci_devs_phb_init(void) -{ - struct pci_controller *phb, *tmp; - - /* This must be done first so the device nodes have valid pci info! */ - list_for_each_entry_safe(phb, tmp, &hose_list, list_node) - pci_devs_phb_init_dynamic(phb); - - return 0; -} - -core_initcall(pci_devs_phb_init); - static void pci_dev_pdn_setup(struct pci_dev *pdev) { struct pci_dn *pdn; diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index a66f435dabbf..924d023dad0a 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -659,11 +660,10 @@ static void do_break_handler(struct pt_regs *regs) } } -void do_break (struct pt_regs *regs, unsigned long address, - unsigned long error_code) +DEFINE_INTERRUPT_HANDLER(do_break) { current->thread.trap_nr = TRAP_HWBKPT; - if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, + if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, regs->dsisr, 11, SIGSEGV) == NOTIFY_STOP) return; @@ -681,7 +681,7 @@ void do_break (struct pt_regs *regs, unsigned long address, do_break_handler(regs); /* Deliver the signal to userspace */ - force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address); + force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)regs->dar); } #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ @@ -2047,6 +2047,9 @@ static inline int valid_emergency_stack(unsigned long sp, struct task_struct *p, unsigned long stack_page; unsigned long cpu = task_cpu(p); + if (!paca_ptrs) + return 0; + stack_page = (unsigned long)paca_ptrs[cpu]->emergency_sp - THREAD_SIZE; if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes) return 1; @@ -2176,7 +2179,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack, * See if this is an exception frame. * We look for the "regshere" marker in the current frame. */ - if (validate_sp(sp, tsk, STACK_INT_FRAME_SIZE) + if (validate_sp(sp, tsk, STACK_FRAME_WITH_PT_REGS) && stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) { struct pt_regs *regs = (struct pt_regs *) (sp + STACK_FRAME_OVERHEAD); diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index ae3c41730367..9a4797d1d40d 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -707,7 +707,7 @@ static void __init save_fscr_to_task(void) init_task.thread.fscr = mfspr(SPRN_FSCR); } #else -static inline void save_fscr_to_task(void) {}; +static inline void save_fscr_to_task(void) {} #endif diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index e9d4eb6144e1..ccf77b985c8f 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1331,14 +1331,10 @@ static void __init prom_check_platform_support(void) if (prop_len > sizeof(vec)) prom_printf("WARNING: ibm,arch-vec-5-platform-support longer than expected (len: %d)\n", prop_len); - prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support", - &vec, sizeof(vec)); - for (i = 0; i < sizeof(vec); i += 2) { - prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2 - , vec[i] - , vec[i + 1]); - prom_parse_platform_support(vec[i], vec[i + 1], - &supported); + prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support", &vec, sizeof(vec)); + for (i = 0; i < prop_len; i += 2) { + prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2, vec[i], vec[i + 1]); + prom_parse_platform_support(vec[i], vec[i + 1], &supported); } } diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c index 3d44b73adb83..4f3d4ff3728c 100644 --- a/arch/powerpc/kernel/ptrace/ptrace.c +++ b/arch/powerpc/kernel/ptrace/ptrace.c @@ -262,8 +262,6 @@ long do_syscall_trace_enter(struct pt_regs *regs) { u32 flags; - user_exit(); - flags = READ_ONCE(current_thread_info()->flags) & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE); @@ -340,8 +338,6 @@ void do_syscall_trace_leave(struct pt_regs *regs) step = test_thread_flag(TIF_SINGLESTEP); if (step || test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, step); - - user_enter(); } void __init pt_regs_check(void); diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 71f38e9248be..bee984b1887b 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -64,6 +64,7 @@ #include #include #include +#include #include "setup.h" @@ -237,18 +238,17 @@ static int show_cpuinfo(struct seq_file *m, void *v) maj = (pvr >> 8) & 0xFF; min = pvr & 0xFF; - seq_printf(m, "processor\t: %lu\n", cpu_id); - seq_printf(m, "cpu\t\t: "); + seq_printf(m, "processor\t: %lu\ncpu\t\t: ", cpu_id); if (cur_cpu_spec->pvr_mask && cur_cpu_spec->cpu_name) - seq_printf(m, "%s", cur_cpu_spec->cpu_name); + seq_puts(m, cur_cpu_spec->cpu_name); else seq_printf(m, "unknown (%08x)", pvr); if (cpu_has_feature(CPU_FTR_ALTIVEC)) - seq_printf(m, ", altivec supported"); + seq_puts(m, ", altivec supported"); - seq_printf(m, "\n"); + seq_putc(m, '\n'); #ifdef CONFIG_TAU if (cpu_has_feature(CPU_FTR_TAU)) { @@ -327,7 +327,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "bogomips\t: %lu.%02lu\n", loops_per_jiffy / (500000 / HZ), (loops_per_jiffy / (5000 / HZ)) % 100); - seq_printf(m, "\n"); + seq_putc(m, '\n'); /* If this is the last cpu, print the summary */ if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids) @@ -938,6 +938,7 @@ void __init setup_arch(char **cmdline_p) exc_lvl_early_init(); emergency_stack_init(); + mce_init(); smp_release_cpus(); initmem_init(); diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h index 2dd0d9cb5a20..84058bbc8fe9 100644 --- a/arch/powerpc/kernel/setup.h +++ b/arch/powerpc/kernel/setup.h @@ -14,31 +14,31 @@ void irqstack_early_init(void); #ifdef CONFIG_PPC32 void setup_power_save(void); #else -static inline void setup_power_save(void) { }; +static inline void setup_power_save(void) { } #endif #if defined(CONFIG_PPC64) && defined(CONFIG_SMP) void check_smt_enabled(void); #else -static inline void check_smt_enabled(void) { }; +static inline void check_smt_enabled(void) { } #endif #if defined(CONFIG_PPC_BOOK3E) && defined(CONFIG_SMP) void setup_tlb_core_data(void); #else -static inline void setup_tlb_core_data(void) { }; +static inline void setup_tlb_core_data(void) { } #endif #if defined(CONFIG_PPC_BOOK3E) || defined(CONFIG_BOOKE) || defined(CONFIG_40x) void exc_lvl_early_init(void); #else -static inline void exc_lvl_early_init(void) { }; +static inline void exc_lvl_early_init(void) { } #endif #if defined(CONFIG_PPC64) || defined(CONFIG_VMAP_STACK) void emergency_stack_init(void); #else -static inline void emergency_stack_init(void) { }; +static inline void emergency_stack_init(void) { } #endif #ifdef CONFIG_PPC64 @@ -55,7 +55,7 @@ extern unsigned long spr_default_dscr; #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE void kvm_cma_reserve(void); #else -static inline void kvm_cma_reserve(void) { }; +static inline void kvm_cma_reserve(void) { } #endif #ifdef CONFIG_TAU diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index c28e949cc222..560ed8b975e7 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -67,6 +67,7 @@ #include #include #include +#include #include "setup.h" @@ -258,7 +259,7 @@ static void cpu_ready_for_interrupts(void) unsigned long spr_default_dscr = 0; -void __init record_spr_defaults(void) +static void __init record_spr_defaults(void) { if (early_cpu_has_feature(CPU_FTR_DSCR)) spr_default_dscr = mfspr(SPRN_DSCR); @@ -1008,7 +1009,7 @@ void rfi_flush_enable(bool enable) rfi_flush = enable; } -void entry_flush_enable(bool enable) +static void entry_flush_enable(bool enable) { if (enable) { do_entry_flush_fixups(enabled_flush_types); @@ -1020,7 +1021,7 @@ void entry_flush_enable(bool enable) entry_flush = enable; } -void uaccess_flush_enable(bool enable) +static void uaccess_flush_enable(bool enable) { if (enable) { do_uaccess_flush_fixups(enabled_flush_types); diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 53782aa60ade..9ded046edb0e 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -282,8 +282,6 @@ static void do_signal(struct task_struct *tsk) void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) { - user_exit(); - if (thread_info_flags & _TIF_UPROBE) uprobe_notify_resume(regs); @@ -299,8 +297,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) tracehook_notify_resume(regs); rseq_handle_notify_resume(NULL, regs); } - - user_enter(); } static unsigned long get_tm_stackpointer(struct task_struct *tsk) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 934cbdf6dd10..75ee918a120a 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -929,8 +929,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, regs->gpr[3] = ksig->sig; regs->gpr[4] = (unsigned long) sc; regs->nip = (unsigned long)ksig->ka.sa.sa_handler; - /* enter the signal handler in big-endian mode */ + /* enter the signal handler in native-endian mode */ regs->msr &= ~MSR_LE; + regs->msr |= (MSR_KERNEL & MSR_LE); return 0; failed: diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 9e2246e80efd..5a4d59a1070d 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -576,7 +577,7 @@ void tick_broadcast(const struct cpumask *mask) #endif #ifdef CONFIG_DEBUGGER -void debugger_ipi_callback(struct pt_regs *regs) +static void debugger_ipi_callback(struct pt_regs *regs) { debugger_ipi(regs); } diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index d36c6391eaf5..16ff0399a257 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -59,57 +59,64 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len, /* * long long munging: * The 32 bit ABI passes long longs in an odd even register pair. + * High and low parts are swapped depending on endian mode, + * so define a macro (similar to mips linux32) to handle that. */ +#ifdef __LITTLE_ENDIAN__ +#define merge_64(low, high) ((u64)high << 32) | low +#else +#define merge_64(high, low) ((u64)high << 32) | low +#endif compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, - u32 reg6, u32 poshi, u32 poslo) + u32 reg6, u32 pos1, u32 pos2) { - return ksys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); + return ksys_pread64(fd, ubuf, count, merge_64(pos1, pos2)); } compat_ssize_t compat_sys_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count, - u32 reg6, u32 poshi, u32 poslo) + u32 reg6, u32 pos1, u32 pos2) { - return ksys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); + return ksys_pwrite64(fd, ubuf, count, merge_64(pos1, pos2)); } -compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count) +compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offset1, u32 offset2, u32 count) { - return ksys_readahead(fd, ((loff_t)offhi << 32) | offlo, count); + return ksys_readahead(fd, merge_64(offset1, offset2), count); } asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4, - unsigned long high, unsigned long low) + unsigned long len1, unsigned long len2) { - return ksys_truncate(path, (high << 32) | low); + return ksys_truncate(path, merge_64(len1, len2)); } -asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, - u32 lenhi, u32 lenlo) +asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offset1, u32 offset2, + u32 len1, u32 len2) { - return ksys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, - ((loff_t)lenhi << 32) | lenlo); + return ksys_fallocate(fd, mode, ((loff_t)offset1 << 32) | offset2, + merge_64(len1, len2)); } -asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high, - unsigned long low) +asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long len1, + unsigned long len2) { - return ksys_ftruncate(fd, (high << 32) | low); + return ksys_ftruncate(fd, merge_64(len1, len2)); } -long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, +long ppc32_fadvise64(int fd, u32 unused, u32 offset1, u32 offset2, size_t len, int advice) { - return ksys_fadvise64_64(fd, (u64)offset_high << 32 | offset_low, len, + return ksys_fadvise64_64(fd, merge_64(offset1, offset2), len, advice); } asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, - unsigned offset_hi, unsigned offset_lo, - unsigned nbytes_hi, unsigned nbytes_lo) + unsigned offset1, unsigned offset2, + unsigned nbytes1, unsigned nbytes2) { - loff_t offset = ((loff_t)offset_hi << 32) | offset_lo; - loff_t nbytes = ((loff_t)nbytes_hi << 32) | nbytes_lo; + loff_t offset = merge_64(offset1, offset2); + loff_t nbytes = merge_64(nbytes1, nbytes2); return ksys_sync_file_range(fd, offset, nbytes, flags); } diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index f744eb5cba88..96b2157f0371 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -9,9 +9,7 @@ # 0 nospu restart_syscall sys_restart_syscall 1 nospu exit sys_exit -2 32 fork ppc_fork sys_fork -2 64 fork sys_fork -2 spu fork sys_ni_syscall +2 nospu fork sys_fork 3 common read sys_read 4 common write sys_write 5 common open sys_open compat_sys_open @@ -160,9 +158,7 @@ 119 32 sigreturn sys_sigreturn compat_sys_sigreturn 119 64 sigreturn sys_ni_syscall 119 spu sigreturn sys_ni_syscall -120 32 clone ppc_clone sys_clone -120 64 clone sys_clone -120 spu clone sys_ni_syscall +120 nospu clone sys_clone 121 common setdomainname sys_setdomainname 122 common uname sys_newuname 123 common modify_ldt sys_ni_syscall @@ -244,9 +240,7 @@ 186 spu sendfile sys_sendfile64 187 common getpmsg sys_ni_syscall 188 common putpmsg sys_ni_syscall -189 32 vfork ppc_vfork sys_vfork -189 64 vfork sys_vfork -189 spu vfork sys_ni_syscall +189 nospu vfork sys_vfork 190 common ugetrlimit sys_getrlimit compat_sys_getrlimit 191 common readahead sys_readahead compat_sys_readahead 192 32 mmap2 sys_mmap2 compat_sys_mmap2 @@ -322,9 +316,7 @@ 248 32 clock_nanosleep sys_clock_nanosleep_time32 248 64 clock_nanosleep sys_clock_nanosleep 248 spu clock_nanosleep sys_clock_nanosleep -249 32 swapcontext ppc_swapcontext compat_sys_swapcontext -249 64 swapcontext sys_swapcontext -249 spu swapcontext sys_ni_syscall +249 nospu swapcontext sys_swapcontext compat_sys_swapcontext 250 common tgkill sys_tgkill 251 32 utimes sys_utimes_time32 251 64 utimes sys_utimes @@ -522,9 +514,7 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open -435 32 clone3 ppc_clone3 sys_clone3 -435 64 clone3 sys_clone3 -435 spu clone3 sys_ni_syscall +435 nospu clone3 sys_clone3 436 common close_range sys_close_range 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c index 0b4694b8d248..6c31af7f4fa8 100644 --- a/arch/powerpc/kernel/tau_6xx.c +++ b/arch/powerpc/kernel/tau_6xx.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -100,16 +101,13 @@ static void TAUupdate(int cpu) * with interrupts disabled */ -void TAUException(struct pt_regs * regs) +DEFINE_INTERRUPT_HANDLER_ASYNC(TAUException) { int cpu = smp_processor_id(); - irq_enter(); tau[cpu].interrupts++; TAUupdate(cpu); - - irq_exit(); } #endif /* CONFIG_TAU_INT */ diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 67feb3524460..b67d93a609a2 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -53,9 +53,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -570,7 +572,7 @@ void arch_irq_work_raise(void) * timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. */ -void timer_interrupt(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt) { struct clock_event_device *evt = this_cpu_ptr(&decrementers); u64 *next_tb = this_cpu_ptr(&decrementers_next_tb); @@ -609,7 +611,7 @@ void timer_interrupt(struct pt_regs *regs) #endif old_regs = set_irq_regs(regs); - irq_enter(); + trace_timer_interrupt_entry(regs); if (test_irq_work_pending()) { @@ -634,7 +636,7 @@ void timer_interrupt(struct pt_regs *regs) } trace_timer_interrupt_exit(regs); - irq_exit(); + set_irq_regs(old_regs); } EXPORT_SYMBOL(timer_interrupt); @@ -1030,6 +1032,7 @@ void __init time_init(void) tick_setup_hrtimer_broadcast(); of_clk_init(NULL); + enable_sched_clock_irqtime(); } /* diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 3ec7b443fe6b..1583fd1c6010 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -342,8 +343,8 @@ static bool exception_common(int signr, struct pt_regs *regs, int code, show_signal_msg(signr, regs, code, addr); - if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs)) - local_irq_enable(); + if (arch_irqs_disabled()) + interrupt_cond_local_irq_enable(regs); current->thread.trap_nr = code; @@ -430,16 +431,10 @@ nonrecoverable: regs->msr &= ~MSR_RI; #endif } - -void system_reset_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_NMI(system_reset_exception) { unsigned long hsrr0, hsrr1; bool saved_hsrrs = false; - u8 ftrace_enabled = this_cpu_get_ftrace_enabled(); - - this_cpu_set_ftrace_enabled(0); - - nmi_enter(); /* * System reset can interrupt code where HSRRs are live and MSR[RI]=1. @@ -503,19 +498,20 @@ out: die("Unrecoverable nested System Reset", regs, SIGABRT); #endif /* Must die if the interrupt is not recoverable */ - if (!(regs->msr & MSR_RI)) + if (!(regs->msr & MSR_RI)) { + /* For the reason explained in die_mce, nmi_exit before die */ + nmi_exit(); die("Unrecoverable System Reset", regs, SIGABRT); + } if (saved_hsrrs) { mtspr(SPRN_HSRR0, hsrr0); mtspr(SPRN_HSRR1, hsrr1); } - nmi_exit(); - - this_cpu_set_ftrace_enabled(ftrace_enabled); - /* What should we do here? We could issue a shutdown or hard reset. */ + + return 0; } /* @@ -788,24 +784,34 @@ int machine_check_generic(struct pt_regs *regs) } #endif /* everything else */ -void machine_check_exception(struct pt_regs *regs) +void die_mce(const char *str, struct pt_regs *regs, long err) +{ + /* + * The machine check wants to kill the interrupted context, but + * do_exit() checks for in_interrupt() and panics in that case, so + * exit the irq/nmi before calling die. + */ + if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) + irq_exit(); + else + nmi_exit(); + die(str, regs, err); +} + +/* + * BOOK3S_64 does not call this handler as a non-maskable interrupt + * (it uses its own early real-mode handler to handle the MCE proper + * and then raises irq_work to call this handler when interrupts are + * enabled). + */ +#ifdef CONFIG_PPC_BOOK3S_64 +DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception) +#else +DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception) +#endif { int recover = 0; - /* - * BOOK3S_64 does not call this handler as a non-maskable interrupt - * (it uses its own early real-mode handler to handle the MCE proper - * and then raises irq_work to call this handler when interrupts are - * enabled). - * - * This is silly. The BOOK3S_64 should just call a different function - * rather than expecting semantics to magically change. Something - * like 'non_nmi_machine_check_exception()', perhaps? - */ - const bool nmi = !IS_ENABLED(CONFIG_PPC_BOOK3S_64); - - if (nmi) nmi_enter(); - __this_cpu_inc(irq_stat.mce_exceptions); add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); @@ -830,21 +836,21 @@ void machine_check_exception(struct pt_regs *regs) if (check_io_access(regs)) goto bail; - if (nmi) nmi_exit(); - - die("Machine check", regs, SIGBUS); - - /* Must die if the interrupt is not recoverable */ - if (!(regs->msr & MSR_RI)) - die("Unrecoverable Machine check", regs, SIGBUS); - - return; + die_mce("Machine check", regs, SIGBUS); bail: - if (nmi) nmi_exit(); + /* Must die if the interrupt is not recoverable */ + if (!(regs->msr & MSR_RI)) + die_mce("Unrecoverable Machine check", regs, SIGBUS); + +#ifdef CONFIG_PPC_BOOK3S_64 + return; +#else + return 0; +#endif } -void SMIException(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */ { die("System Management Interrupt", regs, SIGABRT); } @@ -1030,12 +1036,11 @@ static void p9_hmi_special_emu(struct pt_regs *regs) } #endif /* CONFIG_VSX */ -void handle_hmi_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_ASYNC(handle_hmi_exception) { struct pt_regs *old_regs; old_regs = set_irq_regs(regs); - irq_enter(); #ifdef CONFIG_VSX /* Real mode flagged P9 special emu is needed */ @@ -1055,46 +1060,42 @@ void handle_hmi_exception(struct pt_regs *regs) if (ppc_md.handle_hmi_exception) ppc_md.handle_hmi_exception(regs); - irq_exit(); set_irq_regs(old_regs); } -void unknown_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(unknown_exception) { - enum ctx_state prev_state = exception_enter(); - printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", regs->nip, regs->msr, regs->trap); _exception(SIGTRAP, regs, TRAP_UNK, 0); - - exception_exit(prev_state); } -void instruction_breakpoint_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_ASYNC(unknown_async_exception) { - enum ctx_state prev_state = exception_enter(); + printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", + regs->nip, regs->msr, regs->trap); + _exception(SIGTRAP, regs, TRAP_UNK, 0); +} + +DEFINE_INTERRUPT_HANDLER(instruction_breakpoint_exception) +{ if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) - goto bail; + return; if (debugger_iabr_match(regs)) - goto bail; + return; _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); - -bail: - exception_exit(prev_state); } -void RunModeException(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(RunModeException) { _exception(SIGTRAP, regs, TRAP_UNK, 0); } -void single_step_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(single_step_exception) { - enum ctx_state prev_state = exception_enter(); - clear_single_step(regs); clear_br_trace(regs); @@ -1103,16 +1104,12 @@ void single_step_exception(struct pt_regs *regs) if (notify_die(DIE_SSTEP, "single_step", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) - goto bail; + return; if (debugger_sstep(regs)) - goto bail; + return; _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); - -bail: - exception_exit(prev_state); } -NOKPROBE_SYMBOL(single_step_exception); /* * After we have successfully emulated an instruction, we have to @@ -1436,9 +1433,8 @@ static int emulate_math(struct pt_regs *regs) static inline int emulate_math(struct pt_regs *regs) { return -1; } #endif -void program_check_exception(struct pt_regs *regs) +static void do_program_check(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); unsigned int reason = get_reason(regs); /* We can now get here via a FP Unavailable exception if the core @@ -1447,22 +1443,22 @@ void program_check_exception(struct pt_regs *regs) if (reason & REASON_FP) { /* IEEE FP exception */ parse_fpe(regs); - goto bail; + return; } if (reason & REASON_TRAP) { unsigned long bugaddr; /* Debugger is first in line to stop recursive faults in * rcu_lock, notify_die, or atomic_notifier_call_chain */ if (debugger_bpt(regs)) - goto bail; + return; if (kprobe_handler(regs)) - goto bail; + return; /* trap exception */ if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) - goto bail; + return; bugaddr = regs->nip; /* @@ -1474,10 +1470,10 @@ void program_check_exception(struct pt_regs *regs) if (!(regs->msr & MSR_PR) && /* not user-mode */ report_bug(bugaddr, regs) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; - goto bail; + return; } _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); - goto bail; + return; } #ifdef CONFIG_PPC_TRANSACTIONAL_MEM if (reason & REASON_TM) { @@ -1498,7 +1494,7 @@ void program_check_exception(struct pt_regs *regs) */ if (user_mode(regs)) { _exception(SIGILL, regs, ILL_ILLOPN, regs->nip); - goto bail; + return; } else { printk(KERN_EMERG "Unexpected TM Bad Thing exception " "at %lx (msr 0x%lx) tm_scratch=%llx\n", @@ -1518,9 +1514,7 @@ void program_check_exception(struct pt_regs *regs) if (!user_mode(regs)) goto sigill; - /* We restore the interrupt state now */ - if (!arch_irq_disabled_regs(regs)) - local_irq_enable(); + interrupt_cond_local_irq_enable(regs); /* (reason & REASON_ILLEGAL) would be the obvious thing here, * but there seems to be a hardware bug on the 405GP (RevD) @@ -1531,7 +1525,7 @@ void program_check_exception(struct pt_regs *regs) * pattern to occurrences etc. -dgibson 31/Mar/2003 */ if (!emulate_math(regs)) - goto bail; + return; /* Try to emulate it if we should. */ if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { @@ -1539,10 +1533,10 @@ void program_check_exception(struct pt_regs *regs) case 0: regs->nip += 4; emulate_single_step(regs); - goto bail; + return; case -EFAULT: _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); - goto bail; + return; } } @@ -1552,34 +1546,31 @@ sigill: else _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); -bail: - exception_exit(prev_state); } -NOKPROBE_SYMBOL(program_check_exception); + +DEFINE_INTERRUPT_HANDLER(program_check_exception) +{ + do_program_check(regs); +} /* * This occurs when running in hypervisor mode on POWER6 or later * and an illegal instruction is encountered. */ -void emulation_assist_interrupt(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(emulation_assist_interrupt) { regs->msr |= REASON_ILLEGAL; - program_check_exception(regs); + do_program_check(regs); } -NOKPROBE_SYMBOL(emulation_assist_interrupt); -void alignment_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(alignment_exception) { - enum ctx_state prev_state = exception_enter(); int sig, code, fixed = 0; unsigned long reason; - /* We restore the interrupt state now */ - if (!arch_irq_disabled_regs(regs)) - local_irq_enable(); + interrupt_cond_local_irq_enable(regs); reason = get_reason(regs); - if (reason & REASON_BOUNDARY) { sig = SIGBUS; code = BUS_ADRALN; @@ -1587,7 +1578,7 @@ void alignment_exception(struct pt_regs *regs) } if (tm_abort_check(regs, TM_CAUSE_ALIGNMENT | TM_CAUSE_PERSISTENT)) - goto bail; + return; /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) @@ -1597,7 +1588,7 @@ void alignment_exception(struct pt_regs *regs) /* skip over emulated instruction */ regs->nip += inst_length(reason); emulate_single_step(regs); - goto bail; + return; } /* Operand address was bad */ @@ -1612,13 +1603,10 @@ bad: if (user_mode(regs)) _exception(sig, regs, code, regs->dar); else - bad_page_fault(regs, regs->dar, sig); - -bail: - exception_exit(prev_state); + bad_page_fault(regs, sig); } -void StackOverflow(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(StackOverflow) { pr_crit("Kernel stack overflow in process %s[%d], r1=%lx\n", current->comm, task_pid_nr(current), regs->gpr[1]); @@ -1627,46 +1615,33 @@ void StackOverflow(struct pt_regs *regs) panic("kernel stack overflow"); } -void stack_overflow_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(stack_overflow_exception) { - enum ctx_state prev_state = exception_enter(); - die("Kernel stack overflow", regs, SIGSEGV); - - exception_exit(prev_state); } -void kernel_fp_unavailable_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(kernel_fp_unavailable_exception) { - enum ctx_state prev_state = exception_enter(); - printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); - - exception_exit(prev_state); } -void altivec_unavailable_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(altivec_unavailable_exception) { - enum ctx_state prev_state = exception_enter(); - if (user_mode(regs)) { /* A user program has executed an altivec instruction, but this kernel doesn't support altivec. */ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - goto bail; + return; } printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); - -bail: - exception_exit(prev_state); } -void vsx_unavailable_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(vsx_unavailable_exception) { if (user_mode(regs)) { /* A user program has executed an vsx instruction, @@ -1697,7 +1672,7 @@ static void tm_unavailable(struct pt_regs *regs) die("Unrecoverable TM Unavailable Exception", regs, SIGABRT); } -void facility_unavailable_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(facility_unavailable_exception) { static char *facility_strings[] = { [FSCR_FP_LG] = "FPU", @@ -1737,9 +1712,7 @@ void facility_unavailable_exception(struct pt_regs *regs) die("Unexpected facility unavailable exception", regs, SIGABRT); } - /* We restore the interrupt state now */ - if (!arch_irq_disabled_regs(regs)) - local_irq_enable(); + interrupt_cond_local_irq_enable(regs); if (status == FSCR_DSCR_LG) { /* @@ -1817,7 +1790,7 @@ out: #ifdef CONFIG_PPC_TRANSACTIONAL_MEM -void fp_unavailable_tm(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(fp_unavailable_tm) { /* Note: This does not handle any kind of FP laziness. */ @@ -1850,7 +1823,7 @@ void fp_unavailable_tm(struct pt_regs *regs) tm_recheckpoint(¤t->thread); } -void altivec_unavailable_tm(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(altivec_unavailable_tm) { /* See the comments in fp_unavailable_tm(). This function operates * the same way. @@ -1865,7 +1838,7 @@ void altivec_unavailable_tm(struct pt_regs *regs) current->thread.used_vr = 1; } -void vsx_unavailable_tm(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(vsx_unavailable_tm) { /* See the comments in fp_unavailable_tm(). This works similarly, * though we're loading both FP and VEC registers in here. @@ -1890,11 +1863,40 @@ void vsx_unavailable_tm(struct pt_regs *regs) } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -void performance_monitor_exception(struct pt_regs *regs) +#ifdef CONFIG_PPC64 +DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi); +DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi) { __this_cpu_inc(irq_stat.pmu_irqs); perf_irq(regs); + + return 0; +} +#endif + +DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async); +DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async) +{ + __this_cpu_inc(irq_stat.pmu_irqs); + + perf_irq(regs); +} + +DEFINE_INTERRUPT_HANDLER_RAW(performance_monitor_exception) +{ + /* + * On 64-bit, if perf interrupts hit in a local_irq_disable + * (soft-masked) region, we consider them as NMIs. This is required to + * prevent hash faults on user addresses when reading callchains (and + * looks better from an irq tracing perspective). + */ + if (IS_ENABLED(CONFIG_PPC64) && unlikely(arch_irq_disabled_regs(regs))) + performance_monitor_exception_nmi(regs); + else + performance_monitor_exception_async(regs); + + return 0; } #ifdef CONFIG_PPC_ADV_DEBUG_REGS @@ -1957,8 +1959,10 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status) mtspr(SPRN_DBCR0, current->thread.debug.dbcr0); } -void DebugException(struct pt_regs *regs, unsigned long debug_status) +DEFINE_INTERRUPT_HANDLER(DebugException) { + unsigned long debug_status = regs->dsisr; + current->thread.debug.dbsr = debug_status; /* Hack alert: On BookE, Branch Taken stops on the branch itself, while @@ -2024,11 +2028,10 @@ void DebugException(struct pt_regs *regs, unsigned long debug_status) } else handle_debug(regs, debug_status); } -NOKPROBE_SYMBOL(DebugException); #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ #ifdef CONFIG_ALTIVEC -void altivec_assist_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(altivec_assist_exception) { int err; @@ -2062,9 +2065,10 @@ void altivec_assist_exception(struct pt_regs *regs) #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_FSL_BOOKE -void CacheLockingException(struct pt_regs *regs, unsigned long address, - unsigned long error_code) +DEFINE_INTERRUPT_HANDLER(CacheLockingException) { + unsigned long error_code = regs->dsisr; + /* We treat cache locking instructions from the user * as priv ops, in the future we could try to do * something smarter @@ -2076,7 +2080,7 @@ void CacheLockingException(struct pt_regs *regs, unsigned long address, #endif /* CONFIG_FSL_BOOKE */ #ifdef CONFIG_SPE -void SPEFloatingPointException(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(SPEFloatingPointException) { extern int do_spe_mathemu(struct pt_regs *regs); unsigned long spefscr; @@ -2084,9 +2088,7 @@ void SPEFloatingPointException(struct pt_regs *regs) int code = FPE_FLTUNK; int err; - /* We restore the interrupt state now */ - if (!arch_irq_disabled_regs(regs)) - local_irq_enable(); + interrupt_cond_local_irq_enable(regs); flush_spe_to_thread(current); @@ -2128,14 +2130,12 @@ void SPEFloatingPointException(struct pt_regs *regs) return; } -void SPEFloatingPointRoundException(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(SPEFloatingPointRoundException) { extern int speround_handler(struct pt_regs *regs); int err; - /* We restore the interrupt state now */ - if (!arch_irq_disabled_regs(regs)) - local_irq_enable(); + interrupt_cond_local_irq_enable(regs); preempt_disable(); if (regs->msr & MSR_SPE) @@ -2170,13 +2170,12 @@ void SPEFloatingPointRoundException(struct pt_regs *regs) * in the MSR is 0. This indicates that SRR0/1 are live, and that * we therefore lost state by taking this exception. */ -void unrecoverable_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(unrecoverable_exception) { pr_emerg("Unrecoverable exception %lx at %lx (msr=%lx)\n", regs->trap, regs->nip, regs->msr); die("Unrecoverable exception", regs, SIGABRT); } -NOKPROBE_SYMBOL(unrecoverable_exception); #if defined(CONFIG_BOOKE_WDT) || defined(CONFIG_40x) /* @@ -2190,7 +2189,7 @@ void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs) return; } -void WatchdogException(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(WatchdogException) /* XXX NMI? async? */ { printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n"); WatchdogHandler(regs); @@ -2201,13 +2200,12 @@ void WatchdogException(struct pt_regs *regs) * We enter here if we discover during exception entry that we are * running in supervisor mode with a userspace value in the stack pointer. */ -void kernel_bad_stack(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(kernel_bad_stack) { printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n", regs->gpr[1], regs->nip); die("Bad kernel stack pointer", regs, SIGABRT); } -NOKPROBE_SYMBOL(kernel_bad_stack); void __init trap_init(void) { diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c index af3c15a1d41e..c9a8f4781a10 100644 --- a/arch/powerpc/kernel/watchdog.c +++ b/arch/powerpc/kernel/watchdog.c @@ -26,7 +26,9 @@ #include #include +#include #include +#include /* * The powerpc watchdog ensures that each CPU is able to service timers. @@ -247,16 +249,17 @@ static void watchdog_timer_interrupt(int cpu) watchdog_smp_panic(cpu, tb); } -void soft_nmi_interrupt(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_NMI(soft_nmi_interrupt) { unsigned long flags; int cpu = raw_smp_processor_id(); u64 tb; - if (!cpumask_test_cpu(cpu, &wd_cpus_enabled)) - return; + /* should only arrive from kernel, with irqs disabled */ + WARN_ON_ONCE(!arch_irq_disabled_regs(regs)); - nmi_enter(); + if (!cpumask_test_cpu(cpu, &wd_cpus_enabled)) + return 0; __this_cpu_inc(irq_stat.soft_nmi_irqs); @@ -265,7 +268,7 @@ void soft_nmi_interrupt(struct pt_regs *regs) wd_smp_lock(&flags); if (cpumask_test_cpu(cpu, &wd_smp_cpus_stuck)) { wd_smp_unlock(&flags); - goto out; + return 0; } set_cpu_stuck(cpu, tb); @@ -289,8 +292,7 @@ void soft_nmi_interrupt(struct pt_regs *regs) if (wd_panic_timeout_tb < 0x7fffffff) mtspr(SPRN_DEC, wd_panic_timeout_tb); -out: - nmi_exit(); + return 0; } static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c index d0e459bb2f05..9842e33533df 100644 --- a/arch/powerpc/kexec/elf_64.c +++ b/arch/powerpc/kexec/elf_64.c @@ -102,7 +102,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, pr_debug("Loaded initrd at 0x%lx\n", initrd_load_addr); } - fdt_size = fdt_totalsize(initial_boot_params) * 2; + fdt_size = kexec_fdt_totalsize_ppc64(image); fdt = kmalloc(fdt_size, GFP_KERNEL); if (!fdt) { pr_err("Not enough memory for the device tree.\n"); diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c index c69bcf9b547a..02b9e4d0dc40 100644 --- a/arch/powerpc/kexec/file_load_64.c +++ b/arch/powerpc/kexec/file_load_64.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -925,6 +926,40 @@ out: return ret; } +/** + * kexec_fdt_totalsize_ppc64 - Return the estimated size needed to setup FDT + * for kexec/kdump kernel. + * @image: kexec image being loaded. + * + * Returns the estimated size needed for kexec/kdump kernel FDT. + */ +unsigned int kexec_fdt_totalsize_ppc64(struct kimage *image) +{ + unsigned int fdt_size; + u64 usm_entries; + + /* + * The below estimate more than accounts for a typical kexec case where + * the additional space is to accommodate things like kexec cmdline, + * chosen node with properties for initrd start & end addresses and + * a property to indicate kexec boot.. + */ + fdt_size = fdt_totalsize(initial_boot_params) + (2 * COMMAND_LINE_SIZE); + if (image->type != KEXEC_TYPE_CRASH) + return fdt_size; + + /* + * For kdump kernel, also account for linux,usable-memory and + * linux,drconf-usable-memory properties. Get an approximate on the + * number of usable memory entries and use for FDT size estimation. + */ + usm_entries = ((memblock_end_of_DRAM() / drmem_lmb_size()) + + (2 * (resource_size(&crashk_res) / drmem_lmb_size()))); + fdt_size += (unsigned int)(usm_entries * sizeof(u64)); + + return fdt_size; +} + /** * setup_new_fdt_ppc64 - Update the flattend device-tree of the kernel * being loaded. diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 549591d9aaa2..e45644657d49 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -54,6 +54,7 @@ config KVM_BOOK3S_32 select KVM select KVM_BOOK3S_32_HANDLER select KVM_BOOK3S_PR_POSSIBLE + select PPC_FPU help Support running unmodified book3s_32 guest kernels in virtual machines on book3s_32 host processors. diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 38ea396a23d6..c77f2d4f44ca 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -27,6 +27,7 @@ #include #include +#include "book3s.h" #include "trace_hv.h" //#define DEBUG_RESIZE_HPT 1 diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index b08cc15f31c7..fdb57be71aa6 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -61,10 +61,6 @@ #define SPRN_GQR6 918 #define SPRN_GQR7 919 -/* Book3S_32 defines mfsrin(v) - but that messes up our abstract - * function pointers, so let's just disable the define. */ -#undef mfsrin - enum priv_level { PRIV_PROBLEM = 0, PRIV_SUPER = 1, diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index f09708da216e..13bad6bf4c95 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -3408,8 +3409,9 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) kvmppc_set_host_core(pcpu); + guest_exit_irqoff(); + local_irq_enable(); - guest_exit(); /* Let secondaries go back to the offline loop */ for (i = 0; i < controlled_threads; ++i) { @@ -4236,8 +4238,9 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, kvmppc_set_host_core(pcpu); + guest_exit_irqoff(); + local_irq_enable(); - guest_exit(); cpumask_clear_cpu(pcpu, &kvm->arch.cpu_in_guest); diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index f3d3183249fe..158d309b42a3 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 30dfeac731c6..e7219b6f5f9a 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -1813,9 +1813,9 @@ int kvmppc_xive_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, return -EINVAL; if ((level == 1 && state->lsi) || level == KVM_INTERRUPT_SET_LEVEL) - state->asserted = 1; + state->asserted = true; else if (level == 0 || level == KVM_INTERRUPT_UNSET) { - state->asserted = 0; + state->asserted = false; return 0; } diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index f38ae3e54b37..7d5fe43f85c4 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 6c083a9b3545..a2a68a958fa0 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -1522,7 +1522,7 @@ int kvmppc_handle_vmx_load(struct kvm_vcpu *vcpu, return emulated; } -int kvmppc_get_vmx_dword(struct kvm_vcpu *vcpu, int index, u64 *val) +static int kvmppc_get_vmx_dword(struct kvm_vcpu *vcpu, int index, u64 *val) { union kvmppc_one_reg reg; int vmx_offset = 0; @@ -1540,7 +1540,7 @@ int kvmppc_get_vmx_dword(struct kvm_vcpu *vcpu, int index, u64 *val) return result; } -int kvmppc_get_vmx_word(struct kvm_vcpu *vcpu, int index, u64 *val) +static int kvmppc_get_vmx_word(struct kvm_vcpu *vcpu, int index, u64 *val) { union kvmppc_one_reg reg; int vmx_offset = 0; @@ -1558,7 +1558,7 @@ int kvmppc_get_vmx_word(struct kvm_vcpu *vcpu, int index, u64 *val) return result; } -int kvmppc_get_vmx_hword(struct kvm_vcpu *vcpu, int index, u64 *val) +static int kvmppc_get_vmx_hword(struct kvm_vcpu *vcpu, int index, u64 *val) { union kvmppc_one_reg reg; int vmx_offset = 0; @@ -1576,7 +1576,7 @@ int kvmppc_get_vmx_hword(struct kvm_vcpu *vcpu, int index, u64 *val) return result; } -int kvmppc_get_vmx_byte(struct kvm_vcpu *vcpu, int index, u64 *val) +static int kvmppc_get_vmx_byte(struct kvm_vcpu *vcpu, int index, u64 *val) { union kvmppc_one_reg reg; int vmx_offset = 0; diff --git a/arch/powerpc/lib/pmem.c b/arch/powerpc/lib/pmem.c index 1550e0d2513a..eb2919ddf9b9 100644 --- a/arch/powerpc/lib/pmem.c +++ b/arch/powerpc/lib/pmem.c @@ -6,6 +6,7 @@ #include #include #include +#include #include diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index ede093e96234..bb5c20d4ca91 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -1306,9 +1306,11 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, if ((word & 0xfe2) == 2) op->type = SYSCALL; else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && - (word & 0xfe3) == 1) + (word & 0xfe3) == 1) { /* scv */ op->type = SYSCALL_VECTORED_0; - else + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; + } else op->type = UNKNOWN; return 0; #endif @@ -1412,7 +1414,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #ifdef __powerpc64__ case 1: if (!cpu_has_feature(CPU_FTR_ARCH_31)) - return -1; + goto unknown_opcode; prefix_r = GET_PREFIX_R(word); ra = GET_PREFIX_RA(suffix); @@ -1445,8 +1447,13 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #ifdef __powerpc64__ case 4: + /* + * There are very many instructions with this primary opcode + * introduced in the ISA as early as v2.03. However, the ones + * we currently emulate were all introduced with ISA 3.0 + */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) - return -1; + goto unknown_opcode; switch (word & 0x3f) { case 48: /* maddhd */ @@ -1472,7 +1479,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, * There are other instructions from ISA 3.0 with the same * primary opcode which do not have emulation support yet. */ - return -1; + goto unknown_opcode; #endif case 7: /* mulli */ @@ -1532,6 +1539,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 19: if (((word >> 1) & 0x1f) == 2) { /* addpcis */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; imm = (short) (word & 0xffc1); /* d0 + d2 fields */ imm |= (word >> 15) & 0x3e; /* d1 field */ op->val = regs->nip + (imm << 16) + 4; @@ -1844,7 +1853,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #ifdef __powerpc64__ case 265: /* modud */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) - return -1; + goto unknown_opcode; op->val = regs->gpr[ra] % regs->gpr[rb]; goto compute_done; #endif @@ -1854,7 +1863,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 267: /* moduw */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) - return -1; + goto unknown_opcode; op->val = (unsigned int) regs->gpr[ra] % (unsigned int) regs->gpr[rb]; goto compute_done; @@ -1891,7 +1900,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #endif case 755: /* darn */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) - return -1; + goto unknown_opcode; switch (ra & 0x3) { case 0: /* 32-bit conditioned */ @@ -1909,18 +1918,18 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, goto compute_done; } - return -1; + goto unknown_opcode; #ifdef __powerpc64__ case 777: /* modsd */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) - return -1; + goto unknown_opcode; op->val = (long int) regs->gpr[ra] % (long int) regs->gpr[rb]; goto compute_done; #endif case 779: /* modsw */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) - return -1; + goto unknown_opcode; op->val = (int) regs->gpr[ra] % (int) regs->gpr[rb]; goto compute_done; @@ -1997,14 +2006,14 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #endif case 538: /* cnttzw */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) - return -1; + goto unknown_opcode; val = (unsigned int) regs->gpr[rd]; op->val = (val ? __builtin_ctz(val) : 32); goto logical_done; #ifdef __powerpc64__ case 570: /* cnttzd */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) - return -1; + goto unknown_opcode; val = regs->gpr[rd]; op->val = (val ? __builtin_ctzl(val) : 64); goto logical_done; @@ -2114,7 +2123,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 890: /* extswsli with sh_5 = 0 */ case 891: /* extswsli with sh_5 = 1 */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) - return -1; + goto unknown_opcode; op->type = COMPUTE + SETREG; sh = rb | ((word & 2) << 4); val = (signed int) regs->gpr[rd]; @@ -2441,6 +2450,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 268: /* lxvx */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 16); op->element_size = 16; @@ -2450,6 +2461,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 269: /* lxvl */ case 301: { /* lxvll */ int nb; + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->ea = ra ? regs->gpr[ra] : 0; nb = regs->gpr[rb] & 0xff; @@ -2470,13 +2483,15 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 333: /* lxvpx */ if (!cpu_has_feature(CPU_FTR_ARCH_31)) - return -1; + goto unknown_opcode; op->reg = VSX_REGISTER_XTP(rd); op->type = MKOP(LOAD_VSX, 0, 32); op->element_size = 32; break; case 364: /* lxvwsx */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 4); op->element_size = 4; @@ -2484,6 +2499,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 396: /* stxvx */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 16); op->element_size = 16; @@ -2493,6 +2510,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 397: /* stxvl */ case 429: { /* stxvll */ int nb; + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->ea = ra ? regs->gpr[ra] : 0; nb = regs->gpr[rb] & 0xff; @@ -2506,7 +2525,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, } case 461: /* stxvpx */ if (!cpu_has_feature(CPU_FTR_ARCH_31)) - return -1; + goto unknown_opcode; op->reg = VSX_REGISTER_XTP(rd); op->type = MKOP(STORE_VSX, 0, 32); op->element_size = 32; @@ -2544,6 +2563,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 781: /* lxsibzx */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 1); op->element_size = 8; @@ -2551,6 +2572,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 812: /* lxvh8x */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 16); op->element_size = 2; @@ -2558,6 +2581,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 813: /* lxsihzx */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 2); op->element_size = 8; @@ -2571,6 +2596,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 876: /* lxvb16x */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 16); op->element_size = 1; @@ -2584,6 +2611,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 909: /* stxsibx */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 1); op->element_size = 8; @@ -2591,6 +2620,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 940: /* stxvh8x */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 16); op->element_size = 2; @@ -2598,6 +2629,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 941: /* stxsihx */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 2); op->element_size = 8; @@ -2611,6 +2644,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 1004: /* stxvb16x */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 16); op->element_size = 1; @@ -2719,12 +2754,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->type = MKOP(LOAD_FP, 0, 16); break; case 2: /* lxsd */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd + 32; op->type = MKOP(LOAD_VSX, 0, 8); op->element_size = 8; op->vsx_flags = VSX_CHECK_VEC; break; case 3: /* lxssp */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->reg = rd + 32; op->type = MKOP(LOAD_VSX, 0, 4); op->element_size = 8; @@ -2754,7 +2793,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #ifdef CONFIG_VSX case 6: if (!cpu_has_feature(CPU_FTR_ARCH_31)) - return -1; + goto unknown_opcode; op->ea = dqform_ea(word, regs); op->reg = VSX_REGISTER_XTP(rd); op->element_size = 32; @@ -2777,6 +2816,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 1: /* lxv */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->ea = dqform_ea(word, regs); if (word & 8) op->reg = rd + 32; @@ -2787,6 +2828,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 2: /* stxsd with LSB of DS field = 0 */ case 6: /* stxsd with LSB of DS field = 1 */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->ea = dsform_ea(word, regs); op->reg = rd + 32; op->type = MKOP(STORE_VSX, 0, 8); @@ -2796,6 +2839,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 3: /* stxssp with LSB of DS field = 0 */ case 7: /* stxssp with LSB of DS field = 1 */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->ea = dsform_ea(word, regs); op->reg = rd + 32; op->type = MKOP(STORE_VSX, 0, 4); @@ -2804,6 +2849,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 5: /* stxv */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + goto unknown_opcode; op->ea = dqform_ea(word, regs); if (word & 8) op->reg = rd + 32; @@ -2833,7 +2880,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 1: /* Prefixed instructions */ if (!cpu_has_feature(CPU_FTR_ARCH_31)) - return -1; + goto unknown_opcode; prefix_r = GET_PREFIX_R(word); ra = GET_PREFIX_RA(suffix); @@ -2972,6 +3019,20 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, } + if (OP_IS_LOAD_STORE(op->type) && (op->type & UPDATE)) { + switch (GETTYPE(op->type)) { + case LOAD: + if (ra == rd) + goto unknown_opcode; + fallthrough; + case STORE: + case LOAD_FP: + case STORE_FP: + if (ra == 0) + goto unknown_opcode; + } + } + #ifdef CONFIG_VSX if ((GETTYPE(op->type) == LOAD_VSX || GETTYPE(op->type) == STORE_VSX) && @@ -2982,6 +3043,10 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, return 0; + unknown_opcode: + op->type = UNKNOWN; + return 0; + logical_done: if (word & 1) set_cr0(regs, op); diff --git a/arch/powerpc/mm/book3s32/Makefile b/arch/powerpc/mm/book3s32/Makefile index 3f972db17761..446d9de88ce4 100644 --- a/arch/powerpc/mm/book3s32/Makefile +++ b/arch/powerpc/mm/book3s32/Makefile @@ -6,4 +6,6 @@ ifdef CONFIG_KASAN CFLAGS_mmu.o += -DDISABLE_BRANCH_PROFILING endif -obj-y += mmu.o hash_low.o mmu_context.o tlb.o nohash_low.o +obj-y += mmu.o mmu_context.o +obj-$(CONFIG_PPC_BOOK3S_603) += nohash_low.o +obj-$(CONFIG_PPC_BOOK3S_604) += hash_low.o tlb.o diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c index 859e5bd603ac..d7eb266a3f7a 100644 --- a/arch/powerpc/mm/book3s32/mmu.c +++ b/arch/powerpc/mm/book3s32/mmu.c @@ -234,7 +234,7 @@ void mmu_mark_initmem_nx(void) if (is_module_segment(i << 28)) continue; - mtsrin(mfsrin(i << 28) | 0x10000000, i << 28); + mtsr(mfsr(i << 28) | 0x10000000, i << 28); } } diff --git a/arch/powerpc/mm/book3s64/hash_hugetlbpage.c b/arch/powerpc/mm/book3s64/hash_hugetlbpage.c index b5e9fff8c217..a688e1324ae5 100644 --- a/arch/powerpc/mm/book3s64/hash_hugetlbpage.c +++ b/arch/powerpc/mm/book3s64/hash_hugetlbpage.c @@ -16,10 +16,6 @@ unsigned int hpage_shift; EXPORT_SYMBOL(hpage_shift); -extern long hpte_insert_repeating(unsigned long hash, unsigned long vpn, - unsigned long pa, unsigned long rlags, - unsigned long vflags, int psize, int ssize); - int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, pte_t *ptep, unsigned long trap, unsigned long flags, int ssize, unsigned int shift, unsigned int mmu_psize) diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index 73b06adb6eeb..581b20a2feaf 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -1143,10 +1144,10 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap) page = pte_page(pte); /* page is dirty */ - if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) { + if (!test_bit(PG_dcache_clean, &page->flags) && !PageReserved(page)) { if (trap == 0x400) { flush_dcache_icache_page(page); - set_bit(PG_arch_1, &page->flags); + set_bit(PG_dcache_clean, &page->flags); } else pp |= HPTE_R_N; } @@ -1288,7 +1289,6 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long flags) { bool is_thp; - enum ctx_state prev_state = exception_enter(); pgd_t *pgdir; unsigned long vsid; pte_t *ptep; @@ -1490,7 +1490,6 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, DBG_LOW(" -> rc=%d\n", rc); bail: - exception_exit(prev_state); return rc; } EXPORT_SYMBOL_GPL(hash_page_mm); @@ -1512,16 +1511,22 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap, } EXPORT_SYMBOL_GPL(hash_page); -int __hash_page(unsigned long trap, unsigned long ea, unsigned long dsisr, - unsigned long msr) +DECLARE_INTERRUPT_HANDLER_RET(__do_hash_fault); +DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault) { + unsigned long ea = regs->dar; + unsigned long dsisr = regs->dsisr; unsigned long access = _PAGE_PRESENT | _PAGE_READ; unsigned long flags = 0; - struct mm_struct *mm = current->mm; - unsigned int region_id = get_region_id(ea); + struct mm_struct *mm; + unsigned int region_id; + long err; + region_id = get_region_id(ea); if ((region_id == VMALLOC_REGION_ID) || (region_id == IO_REGION_ID)) mm = &init_mm; + else + mm = current->mm; if (dsisr & DSISR_NOHPTE) flags |= HPTE_NOHPTE_UPDATE; @@ -1537,13 +1542,66 @@ int __hash_page(unsigned long trap, unsigned long ea, unsigned long dsisr, * 2) user space access kernel space. */ access |= _PAGE_PRIVILEGED; - if ((msr & MSR_PR) || (region_id == USER_REGION_ID)) + if (user_mode(regs) || (region_id == USER_REGION_ID)) access &= ~_PAGE_PRIVILEGED; - if (trap == 0x400) + if (regs->trap == 0x400) access |= _PAGE_EXEC; - return hash_page_mm(mm, ea, access, trap, flags); + err = hash_page_mm(mm, ea, access, regs->trap, flags); + if (unlikely(err < 0)) { + // failed to instert a hash PTE due to an hypervisor error + if (user_mode(regs)) { + if (IS_ENABLED(CONFIG_PPC_SUBPAGE_PROT) && err == -2) + _exception(SIGSEGV, regs, SEGV_ACCERR, ea); + else + _exception(SIGBUS, regs, BUS_ADRERR, ea); + } else { + bad_page_fault(regs, SIGBUS); + } + err = 0; + } + + return err; +} + +/* + * The _RAW interrupt entry checks for the in_nmi() case before + * running the full handler. + */ +DEFINE_INTERRUPT_HANDLER_RAW(do_hash_fault) +{ + unsigned long dsisr = regs->dsisr; + long err; + + if (unlikely(dsisr & (DSISR_BAD_FAULT_64S | DSISR_KEYFAULT))) + goto page_fault; + + /* + * If we are in an "NMI" (e.g., an interrupt when soft-disabled), then + * don't call hash_page, just fail the fault. This is required to + * prevent re-entrancy problems in the hash code, namely perf + * interrupts hitting while something holds H_PAGE_BUSY, and taking a + * hash fault. See the comment in hash_preload(). + * + * We come here as a result of a DSI at a point where we don't want + * to call hash_page, such as when we are accessing memory (possibly + * user memory) inside a PMU interrupt that occurred while interrupts + * were soft-disabled. We want to invoke the exception handler for + * the access, or panic if there isn't a handler. + */ + if (unlikely(in_nmi())) { + do_bad_page_fault_segv(regs); + return 0; + } + + err = __do_hash_fault(regs); + if (err) { +page_fault: + err = hash__do_page_fault(regs); + } + + return err; } #ifdef CONFIG_PPC_MM_SLICES @@ -1843,27 +1901,6 @@ void flush_hash_range(unsigned long number, int local) } } -/* - * low_hash_fault is called when we the low level hash code failed - * to instert a PTE due to an hypervisor error - */ -void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc) -{ - enum ctx_state prev_state = exception_enter(); - - if (user_mode(regs)) { -#ifdef CONFIG_PPC_SUBPAGE_PROT - if (rc == -2) - _exception(SIGSEGV, regs, SEGV_ACCERR, address); - else -#endif - _exception(SIGBUS, regs, BUS_ADRERR, address); - } else - bad_page_fault(regs, address, SIGBUS); - - exception_exit(prev_state); -} - long hpte_insert_repeating(unsigned long hash, unsigned long vpn, unsigned long pa, unsigned long rflags, unsigned long vflags, int psize, int ssize) diff --git a/arch/powerpc/mm/book3s64/internal.h b/arch/powerpc/mm/book3s64/internal.h index c12d78ee42f5..5045048ce244 100644 --- a/arch/powerpc/mm/book3s64/internal.h +++ b/arch/powerpc/mm/book3s64/internal.h @@ -15,4 +15,6 @@ static inline bool stress_slb(void) void slb_setup_new_exec(void); +void exit_lazy_flush_tlb(struct mm_struct *mm, bool always_flush); + #endif /* ARCH_POWERPC_MM_BOOK3S64_INTERNAL_H */ diff --git a/arch/powerpc/mm/book3s64/iommu_api.c b/arch/powerpc/mm/book3s64/iommu_api.c index 685d7bb3d26f..cd18e94d0843 100644 --- a/arch/powerpc/mm/book3s64/iommu_api.c +++ b/arch/powerpc/mm/book3s64/iommu_api.c @@ -129,7 +129,8 @@ good_exit: mutex_lock(&mem_list_mutex); - list_for_each_entry_rcu(mem2, &mm->context.iommu_group_mem_list, next) { + list_for_each_entry_rcu(mem2, &mm->context.iommu_group_mem_list, next, + lockdep_is_held(&mem_list_mutex)) { /* Overlap? */ if ((mem2->ua < (ua + (entries << PAGE_SHIFT))) && (ua < (mem2->ua + @@ -289,6 +290,7 @@ struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm, { struct mm_iommu_table_group_mem_t *mem, *ret = NULL; + rcu_read_lock(); list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) { if ((mem->ua <= ua) && (ua + size <= mem->ua + @@ -297,6 +299,7 @@ struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm, break; } } + rcu_read_unlock(); return ret; } @@ -327,7 +330,8 @@ struct mm_iommu_table_group_mem_t *mm_iommu_get(struct mm_struct *mm, mutex_lock(&mem_list_mutex); - list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) { + list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next, + lockdep_is_held(&mem_list_mutex)) { if ((mem->ua == ua) && (mem->entries == entries)) { ret = mem; ++mem->used; @@ -421,6 +425,7 @@ bool mm_iommu_is_devmem(struct mm_struct *mm, unsigned long hpa, struct mm_iommu_table_group_mem_t *mem; unsigned long end; + rcu_read_lock(); list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) { if (mem->dev_hpa == MM_IOMMU_TABLE_INVALID_HPA) continue; @@ -437,6 +442,7 @@ bool mm_iommu_is_devmem(struct mm_struct *mm, unsigned long hpa, return true; } } + rcu_read_unlock(); return false; } diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c index 5b3a3bae21aa..9ffa65074cb0 100644 --- a/arch/powerpc/mm/book3s64/pgtable.c +++ b/arch/powerpc/mm/book3s64/pgtable.c @@ -20,6 +20,8 @@ #include #include +#include "internal.h" + unsigned long __pmd_frag_nr; EXPORT_SYMBOL(__pmd_frag_nr); unsigned long __pmd_frag_size_shift; @@ -79,10 +81,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd)); } -static void do_nothing(void *unused) +static void do_serialize(void *arg) { - + /* We've taken the IPI, so try to trim the mask while here */ + if (radix_enabled()) { + struct mm_struct *mm = arg; + exit_lazy_flush_tlb(mm, false); + } } + /* * Serialize against find_current_mm_pte which does lock-less * lookup in page tables with local interrupts disabled. For huge pages @@ -96,7 +103,7 @@ static void do_nothing(void *unused) void serialize_against_pte_lookup(struct mm_struct *mm) { smp_mb(); - smp_call_function_many(mm_cpumask(mm), do_nothing, NULL, 1); + smp_call_function_many(mm_cpumask(mm), do_serialize, mm, 1); } /* diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index fb66d154b26c..409e61210789 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -18,6 +18,8 @@ #include #include +#include "internal.h" + #define RIC_FLUSH_TLB 0 #define RIC_FLUSH_PWC 1 #define RIC_FLUSH_ALL 2 @@ -627,15 +629,6 @@ void radix__local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmadd } EXPORT_SYMBOL(radix__local_flush_tlb_page); -static bool mm_is_singlethreaded(struct mm_struct *mm) -{ - if (atomic_read(&mm->context.copros) > 0) - return false; - if (atomic_read(&mm->mm_users) <= 1 && current->mm == mm) - return true; - return false; -} - static bool mm_needs_flush_escalation(struct mm_struct *mm) { /* @@ -648,21 +641,24 @@ static bool mm_needs_flush_escalation(struct mm_struct *mm) return false; } -#ifdef CONFIG_SMP -static void do_exit_flush_lazy_tlb(void *arg) +/* + * If always_flush is true, then flush even if this CPU can't be removed + * from mm_cpumask. + */ +void exit_lazy_flush_tlb(struct mm_struct *mm, bool always_flush) { - struct mm_struct *mm = arg; unsigned long pid = mm->context.id; + int cpu = smp_processor_id(); /* * A kthread could have done a mmget_not_zero() after the flushing CPU - * checked mm_is_singlethreaded, and be in the process of - * kthread_use_mm when interrupted here. In that case, current->mm will - * be set to mm, because kthread_use_mm() setting ->mm and switching to - * the mm is done with interrupts off. + * checked mm_cpumask, and be in the process of kthread_use_mm when + * interrupted here. In that case, current->mm will be set to mm, + * because kthread_use_mm() setting ->mm and switching to the mm is + * done with interrupts off. */ if (current->mm == mm) - goto out_flush; + goto out; if (current->active_mm == mm) { WARN_ON_ONCE(current->mm != NULL); @@ -673,11 +669,30 @@ static void do_exit_flush_lazy_tlb(void *arg) mmdrop(mm); } - atomic_dec(&mm->context.active_cpus); - cpumask_clear_cpu(smp_processor_id(), mm_cpumask(mm)); + /* + * This IPI may be initiated from any source including those not + * running the mm, so there may be a racing IPI that comes after + * this one which finds the cpumask already clear. Check and avoid + * underflowing the active_cpus count in that case. The race should + * not otherwise be a problem, but the TLB must be flushed because + * that's what the caller expects. + */ + if (cpumask_test_cpu(cpu, mm_cpumask(mm))) { + atomic_dec(&mm->context.active_cpus); + cpumask_clear_cpu(cpu, mm_cpumask(mm)); + always_flush = true; + } -out_flush: - _tlbiel_pid(pid, RIC_FLUSH_ALL); +out: + if (always_flush) + _tlbiel_pid(pid, RIC_FLUSH_ALL); +} + +#ifdef CONFIG_SMP +static void do_exit_flush_lazy_tlb(void *arg) +{ + struct mm_struct *mm = arg; + exit_lazy_flush_tlb(mm, true); } static void exit_flush_lazy_tlbs(struct mm_struct *mm) @@ -693,9 +708,110 @@ static void exit_flush_lazy_tlbs(struct mm_struct *mm) (void *)mm, 1); } +#else /* CONFIG_SMP */ +static inline void exit_flush_lazy_tlbs(struct mm_struct *mm) { } +#endif /* CONFIG_SMP */ + +static DEFINE_PER_CPU(unsigned int, mm_cpumask_trim_clock); + +/* + * Interval between flushes at which we send out IPIs to check whether the + * mm_cpumask can be trimmed for the case where it's not a single-threaded + * process flushing its own mm. The intent is to reduce the cost of later + * flushes. Don't want this to be so low that it adds noticable cost to TLB + * flushing, or so high that it doesn't help reduce global TLBIEs. + */ +static unsigned long tlb_mm_cpumask_trim_timer = 1073; + +static bool tick_and_test_trim_clock(void) +{ + if (__this_cpu_inc_return(mm_cpumask_trim_clock) == + tlb_mm_cpumask_trim_timer) { + __this_cpu_write(mm_cpumask_trim_clock, 0); + return true; + } + return false; +} + +enum tlb_flush_type { + FLUSH_TYPE_NONE, + FLUSH_TYPE_LOCAL, + FLUSH_TYPE_GLOBAL, +}; + +static enum tlb_flush_type flush_type_needed(struct mm_struct *mm, bool fullmm) +{ + int active_cpus = atomic_read(&mm->context.active_cpus); + int cpu = smp_processor_id(); + + if (active_cpus == 0) + return FLUSH_TYPE_NONE; + if (active_cpus == 1 && cpumask_test_cpu(cpu, mm_cpumask(mm))) { + if (current->mm != mm) { + /* + * Asynchronous flush sources may trim down to nothing + * if the process is not running, so occasionally try + * to trim. + */ + if (tick_and_test_trim_clock()) { + exit_lazy_flush_tlb(mm, true); + return FLUSH_TYPE_NONE; + } + } + return FLUSH_TYPE_LOCAL; + } + + /* Coprocessors require TLBIE to invalidate nMMU. */ + if (atomic_read(&mm->context.copros) > 0) + return FLUSH_TYPE_GLOBAL; + + /* + * In the fullmm case there's no point doing the exit_flush_lazy_tlbs + * because the mm is being taken down anyway, and a TLBIE tends to + * be faster than an IPI+TLBIEL. + */ + if (fullmm) + return FLUSH_TYPE_GLOBAL; + + /* + * If we are running the only thread of a single-threaded process, + * then we should almost always be able to trim off the rest of the + * CPU mask (except in the case of use_mm() races), so always try + * trimming the mask. + */ + if (atomic_read(&mm->mm_users) <= 1 && current->mm == mm) { + exit_flush_lazy_tlbs(mm); + /* + * use_mm() race could prevent IPIs from being able to clear + * the cpumask here, however those users are established + * after our first check (and so after the PTEs are removed), + * and the TLB still gets flushed by the IPI, so this CPU + * will only require a local flush. + */ + return FLUSH_TYPE_LOCAL; + } + + /* + * Occasionally try to trim down the cpumask. It's possible this can + * bring the mask to zero, which results in no flush. + */ + if (tick_and_test_trim_clock()) { + exit_flush_lazy_tlbs(mm); + if (current->mm == mm) + return FLUSH_TYPE_LOCAL; + if (cpumask_test_cpu(cpu, mm_cpumask(mm))) + exit_lazy_flush_tlb(mm, true); + return FLUSH_TYPE_NONE; + } + + return FLUSH_TYPE_GLOBAL; +} + +#ifdef CONFIG_SMP void radix__flush_tlb_mm(struct mm_struct *mm) { unsigned long pid; + enum tlb_flush_type type; pid = mm->context.id; if (unlikely(pid == MMU_NO_CONTEXT)) @@ -703,16 +819,15 @@ void radix__flush_tlb_mm(struct mm_struct *mm) preempt_disable(); /* - * Order loads of mm_cpumask vs previous stores to clear ptes before - * the invalidate. See barrier in switch_mm_irqs_off + * Order loads of mm_cpumask (in flush_type_needed) vs previous + * stores to clear ptes before the invalidate. See barrier in + * switch_mm_irqs_off */ smp_mb(); - if (!mm_is_thread_local(mm)) { - if (unlikely(mm_is_singlethreaded(mm))) { - exit_flush_lazy_tlbs(mm); - goto local; - } - + type = flush_type_needed(mm, false); + if (type == FLUSH_TYPE_LOCAL) { + _tlbiel_pid(pid, RIC_FLUSH_TLB); + } else if (type == FLUSH_TYPE_GLOBAL) { if (!mmu_has_feature(MMU_FTR_GTSE)) { unsigned long tgt = H_RPTI_TARGET_CMMU; @@ -728,9 +843,6 @@ void radix__flush_tlb_mm(struct mm_struct *mm) } else { _tlbiel_pid_multicast(mm, pid, RIC_FLUSH_TLB); } - } else { -local: - _tlbiel_pid(pid, RIC_FLUSH_TLB); } preempt_enable(); } @@ -739,6 +851,7 @@ EXPORT_SYMBOL(radix__flush_tlb_mm); static void __flush_all_mm(struct mm_struct *mm, bool fullmm) { unsigned long pid; + enum tlb_flush_type type; pid = mm->context.id; if (unlikely(pid == MMU_NO_CONTEXT)) @@ -746,13 +859,10 @@ static void __flush_all_mm(struct mm_struct *mm, bool fullmm) preempt_disable(); smp_mb(); /* see radix__flush_tlb_mm */ - if (!mm_is_thread_local(mm)) { - if (unlikely(mm_is_singlethreaded(mm))) { - if (!fullmm) { - exit_flush_lazy_tlbs(mm); - goto local; - } - } + type = flush_type_needed(mm, fullmm); + if (type == FLUSH_TYPE_LOCAL) { + _tlbiel_pid(pid, RIC_FLUSH_ALL); + } else if (type == FLUSH_TYPE_GLOBAL) { if (!mmu_has_feature(MMU_FTR_GTSE)) { unsigned long tgt = H_RPTI_TARGET_CMMU; unsigned long type = H_RPTI_TYPE_TLB | H_RPTI_TYPE_PWC | @@ -766,9 +876,6 @@ static void __flush_all_mm(struct mm_struct *mm, bool fullmm) _tlbie_pid(pid, RIC_FLUSH_ALL); else _tlbiel_pid_multicast(mm, pid, RIC_FLUSH_ALL); - } else { -local: - _tlbiel_pid(pid, RIC_FLUSH_ALL); } preempt_enable(); } @@ -783,6 +890,7 @@ void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, int psize) { unsigned long pid; + enum tlb_flush_type type; pid = mm->context.id; if (unlikely(pid == MMU_NO_CONTEXT)) @@ -790,11 +898,10 @@ void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, preempt_disable(); smp_mb(); /* see radix__flush_tlb_mm */ - if (!mm_is_thread_local(mm)) { - if (unlikely(mm_is_singlethreaded(mm))) { - exit_flush_lazy_tlbs(mm); - goto local; - } + type = flush_type_needed(mm, false); + if (type == FLUSH_TYPE_LOCAL) { + _tlbiel_va(vmaddr, pid, psize, RIC_FLUSH_TLB); + } else if (type == FLUSH_TYPE_GLOBAL) { if (!mmu_has_feature(MMU_FTR_GTSE)) { unsigned long tgt, pg_sizes, size; @@ -811,9 +918,6 @@ void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, _tlbie_va(vmaddr, pid, psize, RIC_FLUSH_TLB); else _tlbiel_va_multicast(mm, vmaddr, pid, psize, RIC_FLUSH_TLB); - } else { -local: - _tlbiel_va(vmaddr, pid, psize, RIC_FLUSH_TLB); } preempt_enable(); } @@ -828,8 +932,6 @@ void radix__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) } EXPORT_SYMBOL(radix__flush_tlb_page); -#else /* CONFIG_SMP */ -static inline void exit_flush_lazy_tlbs(struct mm_struct *mm) { } #endif /* CONFIG_SMP */ static void do_tlbiel_kernel(void *info) @@ -893,7 +995,9 @@ static inline void __radix__flush_tlb_range(struct mm_struct *mm, unsigned int page_shift = mmu_psize_defs[mmu_virtual_psize].shift; unsigned long page_size = 1UL << page_shift; unsigned long nr_pages = (end - start) >> page_shift; - bool local, full; + bool fullmm = (end == TLB_FLUSH_ALL); + bool flush_pid; + enum tlb_flush_type type; pid = mm->context.id; if (unlikely(pid == MMU_NO_CONTEXT)) @@ -901,24 +1005,18 @@ static inline void __radix__flush_tlb_range(struct mm_struct *mm, preempt_disable(); smp_mb(); /* see radix__flush_tlb_mm */ - if (!mm_is_thread_local(mm)) { - if (unlikely(mm_is_singlethreaded(mm))) { - if (end != TLB_FLUSH_ALL) { - exit_flush_lazy_tlbs(mm); - goto is_local; - } - } - local = false; - full = (end == TLB_FLUSH_ALL || - nr_pages > tlb_single_page_flush_ceiling); - } else { -is_local: - local = true; - full = (end == TLB_FLUSH_ALL || - nr_pages > tlb_local_single_page_flush_ceiling); - } + type = flush_type_needed(mm, fullmm); + if (type == FLUSH_TYPE_NONE) + goto out; - if (!mmu_has_feature(MMU_FTR_GTSE) && !local) { + if (fullmm) + flush_pid = true; + else if (type == FLUSH_TYPE_GLOBAL) + flush_pid = nr_pages > tlb_single_page_flush_ceiling; + else + flush_pid = nr_pages > tlb_local_single_page_flush_ceiling; + + if (!mmu_has_feature(MMU_FTR_GTSE) && type == FLUSH_TYPE_GLOBAL) { unsigned long tgt = H_RPTI_TARGET_CMMU; unsigned long pg_sizes = psize_to_rpti_pgsize(mmu_virtual_psize); @@ -928,8 +1026,8 @@ is_local: tgt |= H_RPTI_TARGET_NMMU; pseries_rpt_invalidate(pid, tgt, H_RPTI_TYPE_TLB, pg_sizes, start, end); - } else if (full) { - if (local) { + } else if (flush_pid) { + if (type == FLUSH_TYPE_LOCAL) { _tlbiel_pid(pid, RIC_FLUSH_TLB); } else { if (cputlb_use_tlbie()) { @@ -952,7 +1050,7 @@ is_local: hflush = true; } - if (local) { + if (type == FLUSH_TYPE_LOCAL) { asm volatile("ptesync": : :"memory"); __tlbiel_va_range(start, end, pid, page_size, mmu_virtual_psize); if (hflush) @@ -974,6 +1072,7 @@ is_local: hstart, hend, pid, PMD_SIZE, MMU_PAGE_2M, false); } } +out: preempt_enable(); } @@ -1085,32 +1184,30 @@ static __always_inline void __radix__flush_tlb_range_psize(struct mm_struct *mm, unsigned int page_shift = mmu_psize_defs[psize].shift; unsigned long page_size = 1UL << page_shift; unsigned long nr_pages = (end - start) >> page_shift; - bool local, full; + bool fullmm = (end == TLB_FLUSH_ALL); + bool flush_pid; + enum tlb_flush_type type; pid = mm->context.id; if (unlikely(pid == MMU_NO_CONTEXT)) return; + fullmm = (end == TLB_FLUSH_ALL); + preempt_disable(); smp_mb(); /* see radix__flush_tlb_mm */ - if (!mm_is_thread_local(mm)) { - if (unlikely(mm_is_singlethreaded(mm))) { - if (end != TLB_FLUSH_ALL) { - exit_flush_lazy_tlbs(mm); - goto is_local; - } - } - local = false; - full = (end == TLB_FLUSH_ALL || - nr_pages > tlb_single_page_flush_ceiling); - } else { -is_local: - local = true; - full = (end == TLB_FLUSH_ALL || - nr_pages > tlb_local_single_page_flush_ceiling); - } + type = flush_type_needed(mm, fullmm); + if (type == FLUSH_TYPE_NONE) + goto out; - if (!mmu_has_feature(MMU_FTR_GTSE) && !local) { + if (fullmm) + flush_pid = true; + else if (type == FLUSH_TYPE_GLOBAL) + flush_pid = nr_pages > tlb_single_page_flush_ceiling; + else + flush_pid = nr_pages > tlb_local_single_page_flush_ceiling; + + if (!mmu_has_feature(MMU_FTR_GTSE) && type == FLUSH_TYPE_GLOBAL) { unsigned long tgt = H_RPTI_TARGET_CMMU; unsigned long type = H_RPTI_TYPE_TLB; unsigned long pg_sizes = psize_to_rpti_pgsize(psize); @@ -1120,8 +1217,8 @@ is_local: if (atomic_read(&mm->context.copros) > 0) tgt |= H_RPTI_TARGET_NMMU; pseries_rpt_invalidate(pid, tgt, type, pg_sizes, start, end); - } else if (full) { - if (local) { + } else if (flush_pid) { + if (type == FLUSH_TYPE_LOCAL) { _tlbiel_pid(pid, also_pwc ? RIC_FLUSH_ALL : RIC_FLUSH_TLB); } else { if (cputlb_use_tlbie()) { @@ -1137,7 +1234,7 @@ is_local: } } else { - if (local) + if (type == FLUSH_TYPE_LOCAL) _tlbiel_va_range(start, end, pid, page_size, psize, also_pwc); else if (cputlb_use_tlbie()) _tlbie_va_range(start, end, pid, page_size, psize, also_pwc); @@ -1145,6 +1242,7 @@ is_local: _tlbiel_va_range_multicast(mm, start, end, pid, page_size, psize, also_pwc); } +out: preempt_enable(); } @@ -1164,6 +1262,7 @@ static void radix__flush_tlb_pwc_range_psize(struct mm_struct *mm, unsigned long void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr) { unsigned long pid, end; + enum tlb_flush_type type; pid = mm->context.id; if (unlikely(pid == MMU_NO_CONTEXT)) @@ -1180,11 +1279,10 @@ void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr) /* Otherwise first do the PWC, then iterate the pages. */ preempt_disable(); smp_mb(); /* see radix__flush_tlb_mm */ - if (!mm_is_thread_local(mm)) { - if (unlikely(mm_is_singlethreaded(mm))) { - exit_flush_lazy_tlbs(mm); - goto local; - } + type = flush_type_needed(mm, false); + if (type == FLUSH_TYPE_LOCAL) { + _tlbiel_va_range(addr, end, pid, PAGE_SIZE, mmu_virtual_psize, true); + } else if (type == FLUSH_TYPE_GLOBAL) { if (!mmu_has_feature(MMU_FTR_GTSE)) { unsigned long tgt, type, pg_sizes; @@ -1202,9 +1300,6 @@ void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr) else _tlbiel_va_range_multicast(mm, addr, end, pid, PAGE_SIZE, mmu_virtual_psize, true); - } else { -local: - _tlbiel_va_range(addr, end, pid, PAGE_SIZE, mmu_virtual_psize, true); } preempt_enable(); diff --git a/arch/powerpc/mm/book3s64/slb.c b/arch/powerpc/mm/book3s64/slb.c index 584567970c11..c91bd85eb90e 100644 --- a/arch/powerpc/mm/book3s64/slb.c +++ b/arch/powerpc/mm/book3s64/slb.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -813,8 +814,9 @@ static long slb_allocate_user(struct mm_struct *mm, unsigned long ea) return slb_insert_entry(ea, context, flags, ssize, false); } -long do_slb_fault(struct pt_regs *regs, unsigned long ea) +DEFINE_INTERRUPT_HANDLER_RAW(do_slb_fault) { + unsigned long ea = regs->dar; unsigned long id = get_region_id(ea); /* IRQs are not reconciled here, so can't check irqs_disabled */ @@ -824,19 +826,21 @@ long do_slb_fault(struct pt_regs *regs, unsigned long ea) return -EINVAL; /* - * SLB kernel faults must be very careful not to touch anything - * that is not bolted. E.g., PACA and global variables are okay, - * mm->context stuff is not. - * - * SLB user faults can access all of kernel memory, but must be - * careful not to touch things like IRQ state because it is not - * "reconciled" here. The difficulty is that we must use - * fast_exception_return to return from kernel SLB faults without - * looking at possible non-bolted memory. We could test user vs - * kernel faults in the interrupt handler asm and do a full fault, - * reconcile, ret_from_except for user faults which would make them - * first class kernel code. But for performance it's probably nicer - * if they go via fast_exception_return too. + * SLB kernel faults must be very careful not to touch anything that is + * not bolted. E.g., PACA and global variables are okay, mm->context + * stuff is not. SLB user faults may access all of memory (and induce + * one recursive SLB kernel fault), so the kernel fault must not + * trample on the user fault state at those points. + */ + + /* + * This is a raw interrupt handler, for performance, so that + * fast_interrupt_return can be used. The handler must not touch local + * irq state, or schedule. We could test for usermode and upgrade to a + * normal process context (synchronous) interrupt for those, which + * would make them first-class kernel code and able to be traced and + * instrumented, although performance would suffer a bit, it would + * probably be a good tradeoff. */ if (id >= LINEAR_MAP_REGION_ID) { long err; @@ -865,13 +869,15 @@ long do_slb_fault(struct pt_regs *regs, unsigned long ea) } } -void do_bad_slb_fault(struct pt_regs *regs, unsigned long ea, long err) +DEFINE_INTERRUPT_HANDLER(do_bad_slb_fault) { + int err = regs->result; + if (err == -EFAULT) { if (user_mode(regs)) - _exception(SIGSEGV, regs, SEGV_BNDERR, ea); + _exception(SIGSEGV, regs, SEGV_BNDERR, regs->dar); else - bad_page_fault(regs, ea, SIGSEGV); + bad_page_fault(regs, SIGSEGV); } else if (err == -EINVAL) { unrecoverable_exception(regs); } else { diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 8961b44f350c..bb368257b55c 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -377,18 +378,16 @@ static void sanity_check_fault(bool is_write, bool is_user, /* * For 600- and 800-family processors, the error_code parameter is DSISR - * for a data fault, SRR1 for an instruction fault. For 400-family processors - * the error_code parameter is ESR for a data fault, 0 for an instruction - * fault. - * For 64-bit processors, the error_code parameter is - * - DSISR for a non-SLB data access fault, - * - SRR1 & 0x08000000 for a non-SLB instruction access fault - * - 0 any SLB fault. + * for a data fault, SRR1 for an instruction fault. + * For 400-family processors the error_code parameter is ESR for a data fault, + * 0 for an instruction fault. + * For 64-bit processors, the error_code parameter is DSISR for a data access + * fault, SRR1 & 0x08000000 for an instruction access fault. * * The return value is 0 if the fault was handled, or the signal * number if this is a kernel fault that can't be handled here. */ -static int __do_page_fault(struct pt_regs *regs, unsigned long address, +static int ___do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code) { struct vm_area_struct * vma; @@ -435,9 +434,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address, return bad_area_nosemaphore(regs, address); } - /* We restore the interrupt state now */ - if (!arch_irq_disabled_regs(regs)) - local_irq_enable(); + interrupt_cond_local_irq_enable(regs); perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); @@ -540,34 +537,51 @@ retry: return 0; } -NOKPROBE_SYMBOL(__do_page_fault); +NOKPROBE_SYMBOL(___do_page_fault); -int do_page_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code) +static long __do_page_fault(struct pt_regs *regs) { const struct exception_table_entry *entry; - enum ctx_state prev_state = exception_enter(); - int rc = __do_page_fault(regs, address, error_code); - exception_exit(prev_state); - if (likely(!rc)) - return 0; + long err; + + err = ___do_page_fault(regs, regs->dar, regs->dsisr); + if (likely(!err)) + return err; entry = search_exception_tables(regs->nip); - if (unlikely(!entry)) - return rc; - - instruction_pointer_set(regs, extable_fixup(entry)); - - return 0; + if (likely(entry)) { + instruction_pointer_set(regs, extable_fixup(entry)); + return 0; + } else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) { + __bad_page_fault(regs, err); + return 0; + } else { + /* 32 and 64e handle the bad page fault in asm */ + return err; + } } -NOKPROBE_SYMBOL(do_page_fault); +NOKPROBE_SYMBOL(__do_page_fault); + +DEFINE_INTERRUPT_HANDLER_RET(do_page_fault) +{ + return __do_page_fault(regs); +} + +#ifdef CONFIG_PPC_BOOK3S_64 +/* Same as do_page_fault but interrupt entry has already run in do_hash_fault */ +long hash__do_page_fault(struct pt_regs *regs) +{ + return __do_page_fault(regs); +} +NOKPROBE_SYMBOL(hash__do_page_fault); +#endif /* * bad_page_fault is called when we have a bad access from the kernel. * It is called from the DSI and ISI handlers in head.S and from some * of the procedures in traps.c. */ -void __bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) +void __bad_page_fault(struct pt_regs *regs, int sig) { int is_write = page_fault_is_write(regs->dsisr); @@ -605,7 +619,7 @@ void __bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) die("Kernel access of bad area", regs, sig); } -void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) +void bad_page_fault(struct pt_regs *regs, int sig) { const struct exception_table_entry *entry; @@ -614,5 +628,12 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) if (entry) instruction_pointer_set(regs, extable_fixup(entry)); else - __bad_page_fault(regs, address, sig); + __bad_page_fault(regs, sig); } + +#ifdef CONFIG_PPC_BOOK3S_64 +DEFINE_INTERRUPT_HANDLER(do_bad_page_fault_segv) +{ + bad_page_fault(regs, SIGSEGV); +} +#endif diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 8b3cc4d688e8..d142b76d507d 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -217,7 +217,7 @@ void __init pseries_add_gpage(u64 addr, u64 page_size, unsigned long number_of_p } } -int __init pseries_alloc_bootmem_huge_page(struct hstate *hstate) +static int __init pseries_alloc_bootmem_huge_page(struct hstate *hstate) { struct huge_bootmem_page *m; if (nr_gpages == 0) @@ -663,24 +663,6 @@ static int __init hugetlbpage_init(void) arch_initcall(hugetlbpage_init); -void flush_dcache_icache_hugepage(struct page *page) -{ - int i; - void *start; - - BUG_ON(!PageCompound(page)); - - for (i = 0; i < compound_nr(page); i++) { - if (!PageHighMem(page)) { - __flush_dcache_icache(page_address(page+i)); - } else { - start = kmap_atomic(page+i); - __flush_dcache_icache(start); - kunmap_atomic(start); - } - } -} - void __init gigantic_hugetlb_cma_reserve(void) { unsigned long order = 0; diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index afab328d0887..4e8ce6d85232 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -91,27 +91,6 @@ int __weak remove_section_mapping(unsigned long start, unsigned long end) return -ENODEV; } -#define FLUSH_CHUNK_SIZE SZ_1G -/** - * flush_dcache_range_chunked(): Write any modified data cache blocks out to - * memory and invalidate them, in chunks of up to FLUSH_CHUNK_SIZE - * Does not invalidate the corresponding instruction cache blocks. - * - * @start: the start address - * @stop: the stop address (exclusive) - * @chunk: the max size of the chunks - */ -static void flush_dcache_range_chunked(unsigned long start, unsigned long stop, - unsigned long chunk) -{ - unsigned long i; - - for (i = start; i < stop; i += chunk) { - flush_dcache_range(i, min(stop, i + chunk)); - cond_resched(); - } -} - int __ref arch_create_linear_mapping(int nid, u64 start, u64 size, struct mhp_params *params) { @@ -136,7 +115,6 @@ void __ref arch_remove_linear_mapping(u64 start, u64 size) /* Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(start); - flush_dcache_range_chunked(start, start + size, FLUSH_CHUNK_SIZE); mutex_lock(&linear_mapping_mutex); ret = remove_section_mapping(start, start + size); @@ -489,19 +467,35 @@ void flush_dcache_page(struct page *page) if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) return; /* avoid an atomic op if possible */ - if (test_bit(PG_arch_1, &page->flags)) - clear_bit(PG_arch_1, &page->flags); + if (test_bit(PG_dcache_clean, &page->flags)) + clear_bit(PG_dcache_clean, &page->flags); } EXPORT_SYMBOL(flush_dcache_page); +static void flush_dcache_icache_hugepage(struct page *page) +{ + int i; + void *start; + + BUG_ON(!PageCompound(page)); + + for (i = 0; i < compound_nr(page); i++) { + if (!PageHighMem(page)) { + __flush_dcache_icache(page_address(page+i)); + } else { + start = kmap_atomic(page+i); + __flush_dcache_icache(start); + kunmap_atomic(start); + } + } +} + void flush_dcache_icache_page(struct page *page) { -#ifdef CONFIG_HUGETLB_PAGE - if (PageCompound(page)) { - flush_dcache_icache_hugepage(page); - return; - } -#endif + + if (PageCompound(page)) + return flush_dcache_icache_hugepage(page); + #if defined(CONFIG_PPC_8xx) || defined(CONFIG_PPC64) /* On 8xx there is no need to kmap since highmem is not supported */ __flush_dcache_icache(page_address(page)); diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index 15555c95cebc..354611940118 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c @@ -26,6 +26,7 @@ #include #include #include +#include static inline int is_exec_fault(void) { @@ -81,9 +82,9 @@ static pte_t set_pte_filter_hash(pte_t pte) struct page *pg = maybe_pte_to_page(pte); if (!pg) return pte; - if (!test_bit(PG_arch_1, &pg->flags)) { + if (!test_bit(PG_dcache_clean, &pg->flags)) { flush_dcache_icache_page(pg); - set_bit(PG_arch_1, &pg->flags); + set_bit(PG_dcache_clean, &pg->flags); } } return pte; @@ -116,13 +117,13 @@ static inline pte_t set_pte_filter(pte_t pte) return pte; /* If the page clean, we move on */ - if (test_bit(PG_arch_1, &pg->flags)) + if (test_bit(PG_dcache_clean, &pg->flags)) return pte; /* If it's an exec fault, we flush the cache and make it clean */ if (is_exec_fault()) { flush_dcache_icache_page(pg); - set_bit(PG_arch_1, &pg->flags); + set_bit(PG_dcache_clean, &pg->flags); return pte; } @@ -161,12 +162,12 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma, goto bail; /* If the page is already clean, we move on */ - if (test_bit(PG_arch_1, &pg->flags)) + if (test_bit(PG_dcache_clean, &pg->flags)) goto bail; - /* Clean the page and set PG_arch_1 */ + /* Clean the page and set PG_dcache_clean */ flush_dcache_icache_page(pg); - set_bit(PG_arch_1, &pg->flags); + set_bit(PG_dcache_clean, &pg->flags); bail: return pte_mkexec(pte); diff --git a/arch/powerpc/mm/ptdump/segment_regs.c b/arch/powerpc/mm/ptdump/segment_regs.c index dde2fe8de4b2..565048a0c9be 100644 --- a/arch/powerpc/mm/ptdump/segment_regs.c +++ b/arch/powerpc/mm/ptdump/segment_regs.c @@ -10,7 +10,7 @@ static void seg_show(struct seq_file *m, int i) { - u32 val = mfsrin(i << 28); + u32 val = mfsr(i << 28); seq_printf(m, "0x%01x0000000-0x%01xfffffff ", i, i); seq_printf(m, "Kern key %d ", (val >> 30) & 1); diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 869d999a836e..6817331e22ff 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -54,6 +54,9 @@ struct cpu_hw_events { struct perf_branch_stack bhrb_stack; struct perf_branch_entry bhrb_entries[BHRB_MAX_ENTRIES]; u64 ic_init; + + /* Store the PMC values */ + unsigned long pmcs[MAX_HWEVENTS]; }; static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); @@ -110,10 +113,6 @@ static inline void perf_read_regs(struct pt_regs *regs) { regs->result = 0; } -static inline int perf_intr_is_nmi(struct pt_regs *regs) -{ - return 0; -} static inline int siar_valid(struct pt_regs *regs) { @@ -147,6 +146,17 @@ bool is_sier_available(void) return false; } +/* + * Return PMC value corresponding to the + * index passed. + */ +unsigned long get_pmcs_ext_regs(int idx) +{ + struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); + + return cpuhw->pmcs[idx]; +} + static bool regs_use_siar(struct pt_regs *regs) { /* @@ -353,15 +363,6 @@ static inline void perf_read_regs(struct pt_regs *regs) regs->result = use_siar; } -/* - * If interrupts were soft-disabled when a PMU interrupt occurs, treat - * it as an NMI. - */ -static inline int perf_intr_is_nmi(struct pt_regs *regs) -{ - return (regs->softe & IRQS_DISABLED); -} - /* * On processors like P7+ that have the SIAR-Valid bit, marked instructions * must be sampled only if the SIAR-valid bit is set. @@ -915,7 +916,7 @@ void perf_event_print_debug(void) */ static int power_check_constraints(struct cpu_hw_events *cpuhw, u64 event_id[], unsigned int cflags[], - int n_ev) + int n_ev, struct perf_event **event) { unsigned long mask, value, nv; unsigned long smasks[MAX_HWEVENTS], svalues[MAX_HWEVENTS]; @@ -938,7 +939,7 @@ static int power_check_constraints(struct cpu_hw_events *cpuhw, event_id[i] = cpuhw->alternatives[i][0]; } if (ppmu->get_constraint(event_id[i], &cpuhw->amasks[i][0], - &cpuhw->avalues[i][0])) + &cpuhw->avalues[i][0], event[i]->attr.config1)) return -1; } value = mask = 0; @@ -973,7 +974,8 @@ static int power_check_constraints(struct cpu_hw_events *cpuhw, for (j = 1; j < n_alt[i]; ++j) ppmu->get_constraint(cpuhw->alternatives[i][j], &cpuhw->amasks[i][j], - &cpuhw->avalues[i][j]); + &cpuhw->avalues[i][j], + event[i]->attr.config1); } /* enumerate all possibilities and see if any will work */ @@ -1391,7 +1393,7 @@ static void power_pmu_enable(struct pmu *pmu) memset(&cpuhw->mmcr, 0, sizeof(cpuhw->mmcr)); if (ppmu->compute_mmcr(cpuhw->events, cpuhw->n_events, hwc_index, - &cpuhw->mmcr, cpuhw->event)) { + &cpuhw->mmcr, cpuhw->event, ppmu->flags)) { /* shouldn't ever get here */ printk(KERN_ERR "oops compute_mmcr failed\n"); goto out; @@ -1579,7 +1581,7 @@ static int power_pmu_add(struct perf_event *event, int ef_flags) if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1)) goto out; - if (power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n0 + 1)) + if (power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n0 + 1, cpuhw->event)) goto out; event->hw.config = cpuhw->events[n0]; @@ -1789,7 +1791,7 @@ static int power_pmu_commit_txn(struct pmu *pmu) n = cpuhw->n_events; if (check_excludes(cpuhw->event, cpuhw->flags, 0, n)) return -EAGAIN; - i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n); + i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n, cpuhw->event); if (i < 0) return -EAGAIN; @@ -2027,7 +2029,7 @@ static int power_pmu_event_init(struct perf_event *event) local_irq_save(irq_flags); cpuhw = this_cpu_ptr(&cpu_hw_events); - err = power_check_constraints(cpuhw, events, cflags, n + 1); + err = power_check_constraints(cpuhw, events, cflags, n + 1, ctrs); if (has_branch_stack(event)) { u64 bhrb_filter = -1; @@ -2149,7 +2151,17 @@ static void record_and_restart(struct perf_event *event, unsigned long val, left += period; if (left <= 0) left = period; - record = siar_valid(regs); + + /* + * If address is not requested in the sample via + * PERF_SAMPLE_IP, just record that sample irrespective + * of SIAR valid check. + */ + if (event->attr.sample_type & PERF_SAMPLE_IP) + record = siar_valid(regs); + else + record = 1; + event->hw.last_period = event->hw.sample_period; } if (left < 0x80000000LL) @@ -2167,9 +2179,10 @@ static void record_and_restart(struct perf_event *event, unsigned long val, * MMCR2. Check attr.exclude_kernel and address to drop the sample in * these cases. */ - if (event->attr.exclude_kernel && record) - if (is_kernel_addr(mfspr(SPRN_SIAR))) - record = 0; + if (event->attr.exclude_kernel && + (event->attr.sample_type & PERF_SAMPLE_IP) && + is_kernel_addr(mfspr(SPRN_SIAR))) + record = 0; /* * Finally record data if requested. @@ -2277,9 +2290,7 @@ static void __perf_event_interrupt(struct pt_regs *regs) int i, j; struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); struct perf_event *event; - unsigned long val[8]; int found, active; - int nmi; if (cpuhw->n_limited) freeze_limited_counters(cpuhw, mfspr(SPRN_PMC5), @@ -2287,26 +2298,14 @@ static void __perf_event_interrupt(struct pt_regs *regs) perf_read_regs(regs); - /* - * If perf interrupts hit in a local_irq_disable (soft-masked) region, - * we consider them as NMIs. This is required to prevent hash faults on - * user addresses when reading callchains. See the NMI test in - * do_hash_page. - */ - nmi = perf_intr_is_nmi(regs); - if (nmi) - nmi_enter(); - else - irq_enter(); - /* Read all the PMCs since we'll need them a bunch of times */ for (i = 0; i < ppmu->n_counter; ++i) - val[i] = read_pmc(i + 1); + cpuhw->pmcs[i] = read_pmc(i + 1); /* Try to find what caused the IRQ */ found = 0; for (i = 0; i < ppmu->n_counter; ++i) { - if (!pmc_overflow(val[i])) + if (!pmc_overflow(cpuhw->pmcs[i])) continue; if (is_limited_pmc(i + 1)) continue; /* these won't generate IRQs */ @@ -2321,7 +2320,7 @@ static void __perf_event_interrupt(struct pt_regs *regs) event = cpuhw->event[j]; if (event->hw.idx == (i + 1)) { active = 1; - record_and_restart(event, val[i], regs); + record_and_restart(event, cpuhw->pmcs[i], regs); break; } } @@ -2335,17 +2334,17 @@ static void __perf_event_interrupt(struct pt_regs *regs) event = cpuhw->event[i]; if (!event->hw.idx || is_limited_pmc(event->hw.idx)) continue; - if (pmc_overflow_power7(val[event->hw.idx - 1])) { + if (pmc_overflow_power7(cpuhw->pmcs[event->hw.idx - 1])) { /* event has overflowed in a buggy way*/ found = 1; record_and_restart(event, - val[event->hw.idx - 1], + cpuhw->pmcs[event->hw.idx - 1], regs); } } } - if (!found && !nmi && printk_ratelimit()) - printk(KERN_WARNING "Can't find PMC that caused IRQ\n"); + if (unlikely(!found) && !arch_irq_disabled_regs(regs)) + printk_ratelimited(KERN_WARNING "Can't find PMC that caused IRQ\n"); /* * Reset MMCR0 to its normal value. This will set PMXE and @@ -2356,10 +2355,9 @@ static void __perf_event_interrupt(struct pt_regs *regs) */ write_mmcr0(cpuhw, cpuhw->mmcr.mmcr0); - if (nmi) - nmi_exit(); - else - irq_exit(); + /* Clear the cpuhw->pmcs */ + memset(&cpuhw->pmcs, 0, sizeof(cpuhw->pmcs)); + } static void perf_event_interrupt(struct pt_regs *regs) diff --git a/arch/powerpc/perf/core-fsl-emb.c b/arch/powerpc/perf/core-fsl-emb.c index e0e7e276bfd2..ee721f420a7b 100644 --- a/arch/powerpc/perf/core-fsl-emb.c +++ b/arch/powerpc/perf/core-fsl-emb.c @@ -31,19 +31,6 @@ static atomic_t num_events; /* Used to avoid races in calling reserve/release_pmc_hardware */ static DEFINE_MUTEX(pmc_reserve_mutex); -/* - * If interrupts were soft-disabled when a PMU interrupt occurs, treat - * it as an NMI. - */ -static inline int perf_intr_is_nmi(struct pt_regs *regs) -{ -#ifdef __powerpc64__ - return (regs->softe & IRQS_DISABLED); -#else - return 0; -#endif -} - static void perf_event_interrupt(struct pt_regs *regs); /* @@ -659,13 +646,6 @@ static void perf_event_interrupt(struct pt_regs *regs) struct perf_event *event; unsigned long val; int found = 0; - int nmi; - - nmi = perf_intr_is_nmi(regs); - if (nmi) - nmi_enter(); - else - irq_enter(); for (i = 0; i < ppmu->n_counter; ++i) { event = cpuhw->event[i]; @@ -690,11 +670,6 @@ static void perf_event_interrupt(struct pt_regs *regs) mtmsr(mfmsr() | MSR_PMM); mtpmr(PMRN_PMGC0, PMGC0_PMIE | PMGC0_FCECE); isync(); - - if (nmi) - nmi_exit(); - else - irq_exit(); } void hw_perf_event_setup(int cpu) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 6e7e820508df..e5eb33255066 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -764,6 +764,14 @@ static ssize_t catalog_event_len_validate(struct hv_24x7_event_data *event, return ev_len; } +/* + * Return true incase of invalid or dummy events with names like RESERVED* + */ +static bool ignore_event(const char *name) +{ + return strncmp(name, "RESERVED", 8) == 0; +} + #define MAX_4K (SIZE_MAX / 4096) static int create_events_from_catalog(struct attribute ***events_, @@ -894,6 +902,10 @@ static int create_events_from_catalog(struct attribute ***events_, name = event_name(event, &nl); + if (ignore_event(name)) { + junk_events++; + continue; + } if (event->event_group_record_len == 0) { pr_devel("invalid event %zu (%.*s): group_record_len == 0, skipping\n", event_idx, nl, name); @@ -955,6 +967,9 @@ static int create_events_from_catalog(struct attribute ***events_, continue; name = event_name(event, &nl); + if (ignore_event(name)) + continue; + nonce = event_uniq_add(&ev_uniq, name, nl, event->domain); ct = event_data_to_attrs(event_idx, events + event_attr_ct, event, nonce); diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index 6ab5b272090a..e4f577da33d8 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -108,12 +108,57 @@ static void mmcra_sdar_mode(u64 event, unsigned long *mmcra) *mmcra |= MMCRA_SDAR_MODE_TLB; } +static u64 p10_thresh_cmp_val(u64 value) +{ + int exp = 0; + u64 result = value; + + if (!value) + return value; + + /* + * Incase of P10, thresh_cmp value is not part of raw event code + * and provided via attr.config1 parameter. To program threshold in MMCRA, + * take a 18 bit number N and shift right 2 places and increment + * the exponent E by 1 until the upper 10 bits of N are zero. + * Write E to the threshold exponent and write the lower 8 bits of N + * to the threshold mantissa. + * The max threshold that can be written is 261120. + */ + if (cpu_has_feature(CPU_FTR_ARCH_31)) { + if (value > 261120) + value = 261120; + while ((64 - __builtin_clzl(value)) > 8) { + exp++; + value >>= 2; + } + + /* + * Note that it is invalid to write a mantissa with the + * upper 2 bits of mantissa being zero, unless the + * exponent is also zero. + */ + if (!(value & 0xC0) && exp) + result = 0; + else + result = (exp << 8) | value; + } + return result; +} + static u64 thresh_cmp_val(u64 value) { + if (cpu_has_feature(CPU_FTR_ARCH_31)) + value = p10_thresh_cmp_val(value); + + /* + * Since location of threshold compare bits in MMCRA + * is different for p8, using different shift value. + */ if (cpu_has_feature(CPU_FTR_ARCH_300)) return value << p9_MMCRA_THR_CMP_SHIFT; - - return value << MMCRA_THR_CMP_SHIFT; + else + return value << MMCRA_THR_CMP_SHIFT; } static unsigned long combine_from_event(u64 event) @@ -141,13 +186,13 @@ static bool is_thresh_cmp_valid(u64 event) { unsigned int cmp, exp; + if (cpu_has_feature(CPU_FTR_ARCH_31)) + return p10_thresh_cmp_val(event) != 0; + /* * Check the mantissa upper two bits are not zero, unless the * exponent is also zero. See the THRESH_CMP_MANTISSA doc. - * Power10: thresh_cmp is replaced by l2_l3 event select. */ - if (cpu_has_feature(CPU_FTR_ARCH_31)) - return false; cmp = (event >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK; exp = cmp >> 7; @@ -256,7 +301,7 @@ void isa207_get_mem_weight(u64 *weight) *weight = mantissa << (2 * exp); } -int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp) +int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp, u64 event_config1) { unsigned int unit, pmc, cache, ebb; unsigned long mask, value; @@ -355,9 +400,11 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp) } if (cpu_has_feature(CPU_FTR_ARCH_31)) { - if (event_is_threshold(event)) { + if (event_is_threshold(event) && is_thresh_cmp_valid(event_config1)) { mask |= CNST_THRESH_CTL_SEL_MASK; value |= CNST_THRESH_CTL_SEL_VAL(event >> EVENT_THRESH_SHIFT); + mask |= p10_CNST_THRESH_CMP_MASK; + value |= p10_CNST_THRESH_CMP_VAL(p10_thresh_cmp_val(event_config1)); } } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { @@ -411,7 +458,7 @@ ebb_bhrb: int isa207_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[], struct mmcr_regs *mmcr, - struct perf_event *pevents[]) + struct perf_event *pevents[], u32 flags) { unsigned long mmcra, mmcr1, mmcr2, unit, combine, psel, cache, val; unsigned long mmcr3; @@ -504,6 +551,10 @@ int isa207_compute_mmcr(u64 event[], int n_ev, val = (event[i] >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK; mmcra |= thresh_cmp_val(val); + } else if (flags & PPMU_HAS_ATTR_CONFIG1) { + val = (pevents[i]->attr.config1 >> p10_EVENT_THR_CMP_SHIFT) & + p10_EVENT_THR_CMP_MASK; + mmcra |= thresh_cmp_val(val); } } diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h index 454b32c31440..1af0e8c97ac7 100644 --- a/arch/powerpc/perf/isa207-common.h +++ b/arch/powerpc/perf/isa207-common.h @@ -105,6 +105,10 @@ #define p10_EVENT_RADIX_SCOPE_QUAL_MASK 0x1 #define p10_MMCR1_RADIX_SCOPE_QUAL_SHIFT 45 +/* Event Threshold Compare bit constant for power10 in config1 attribute */ +#define p10_EVENT_THR_CMP_SHIFT 0 +#define p10_EVENT_THR_CMP_MASK 0x3FFFFull + #define p10_EVENT_VALID_MASK \ ((p10_SDAR_MODE_MASK << p10_SDAR_MODE_SHIFT | \ (p10_EVENT_THRESH_MASK << EVENT_THRESH_SHIFT) | \ @@ -124,8 +128,8 @@ * 60 56 52 48 44 40 36 32 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | * [ fab_match ] [ thresh_cmp ] [ thresh_ctl ] [ ] - * | - * thresh_sel -* + * | | + * [ thresh_cmp bits for p10] thresh_sel -* * * 28 24 20 16 12 8 4 0 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | @@ -152,6 +156,9 @@ #define CNST_THRESH_CTL_SEL_VAL(v) (((v) & 0x7ffull) << 32) #define CNST_THRESH_CTL_SEL_MASK CNST_THRESH_CTL_SEL_VAL(0x7ff) +#define p10_CNST_THRESH_CMP_VAL(v) (((v) & 0x7ffull) << 43) +#define p10_CNST_THRESH_CMP_MASK p10_CNST_THRESH_CMP_VAL(0x7ff) + #define CNST_EBB_VAL(v) (((v) & EVENT_EBB_MASK) << 24) #define CNST_EBB_MASK CNST_EBB_VAL(EVENT_EBB_MASK) @@ -262,10 +269,10 @@ #define PH(a, b) (P(LVL, HIT) | P(a, b)) #define PM(a, b) (P(LVL, MISS) | P(a, b)) -int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp); +int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp, u64 event_config1); int isa207_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[], struct mmcr_regs *mmcr, - struct perf_event *pevents[]); + struct perf_event *pevents[], u32 flags); void isa207_disable_pmc(unsigned int pmc, struct mmcr_regs *mmcr); int isa207_get_alternatives(u64 event, u64 alt[], int size, unsigned int flags, const unsigned int ev_alt[][MAX_ALT]); diff --git a/arch/powerpc/perf/mpc7450-pmu.c b/arch/powerpc/perf/mpc7450-pmu.c index 1919e9df9165..e39b15b79a83 100644 --- a/arch/powerpc/perf/mpc7450-pmu.c +++ b/arch/powerpc/perf/mpc7450-pmu.c @@ -148,7 +148,7 @@ static u32 classbits[N_CLASSES - 1][2] = { }; static int mpc7450_get_constraint(u64 event, unsigned long *maskp, - unsigned long *valp) + unsigned long *valp, u64 event_config1 __maybe_unused) { int pmc, class; u32 mask, value; @@ -258,7 +258,8 @@ static const u32 pmcsel_mask[N_COUNTER] = { */ static int mpc7450_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[], struct mmcr_regs *mmcr, - struct perf_event *pevents[]) + struct perf_event *pevents[], + u32 flags __maybe_unused) { u8 event_index[N_CLASSES][N_COUNTER]; int n_classevent[N_CLASSES]; diff --git a/arch/powerpc/perf/perf_regs.c b/arch/powerpc/perf/perf_regs.c index 6f681b105eec..b931eed482c9 100644 --- a/arch/powerpc/perf/perf_regs.c +++ b/arch/powerpc/perf/perf_regs.c @@ -75,6 +75,8 @@ static unsigned int pt_regs_offset[PERF_REG_POWERPC_MAX] = { static u64 get_ext_regs_value(int idx) { switch (idx) { + case PERF_REG_POWERPC_PMC1 ... PERF_REG_POWERPC_PMC6: + return get_pmcs_ext_regs(idx - PERF_REG_POWERPC_PMC1); case PERF_REG_POWERPC_MMCR0: return mfspr(SPRN_MMCR0); case PERF_REG_POWERPC_MMCR1: @@ -95,13 +97,6 @@ static u64 get_ext_regs_value(int idx) u64 perf_reg_value(struct pt_regs *regs, int idx) { - u64 perf_reg_extended_max = PERF_REG_POWERPC_MAX; - - if (cpu_has_feature(CPU_FTR_ARCH_31)) - perf_reg_extended_max = PERF_REG_MAX_ISA_31; - else if (cpu_has_feature(CPU_FTR_ARCH_300)) - perf_reg_extended_max = PERF_REG_MAX_ISA_300; - if (idx == PERF_REG_POWERPC_SIER && (IS_ENABLED(CONFIG_FSL_EMB_PERF_EVENT) || IS_ENABLED(CONFIG_PPC32) || @@ -113,14 +108,14 @@ u64 perf_reg_value(struct pt_regs *regs, int idx) IS_ENABLED(CONFIG_PPC32))) return 0; - if (idx >= PERF_REG_POWERPC_MAX && idx < perf_reg_extended_max) + if (idx >= PERF_REG_POWERPC_MAX && idx < PERF_REG_EXTENDED_MAX) return get_ext_regs_value(idx); /* * If the idx is referring to value beyond the * supported registers, return 0 with a warning */ - if (WARN_ON_ONCE(idx >= perf_reg_extended_max)) + if (WARN_ON_ONCE(idx >= PERF_REG_EXTENDED_MAX)) return 0; return regs_get_register(regs, pt_regs_offset[idx]); diff --git a/arch/powerpc/perf/power10-pmu.c b/arch/powerpc/perf/power10-pmu.c index 79e0206ca454..a901c1348cad 100644 --- a/arch/powerpc/perf/power10-pmu.c +++ b/arch/powerpc/perf/power10-pmu.c @@ -216,6 +216,7 @@ PMU_FORMAT_ATTR(invert_bit, "config:47"); PMU_FORMAT_ATTR(src_mask, "config:48-53"); PMU_FORMAT_ATTR(src_match, "config:54-59"); PMU_FORMAT_ATTR(radix_scope, "config:9"); +PMU_FORMAT_ATTR(thresh_cmp, "config1:0-17"); static struct attribute *power10_pmu_format_attr[] = { &format_attr_event.attr, @@ -236,6 +237,7 @@ static struct attribute *power10_pmu_format_attr[] = { &format_attr_src_mask.attr, &format_attr_src_match.attr, &format_attr_radix_scope.attr, + &format_attr_thresh_cmp.attr, NULL, }; @@ -550,7 +552,7 @@ static struct power_pmu power10_pmu = { .get_mem_weight = isa207_get_mem_weight, .disable_pmc = isa207_disable_pmc, .flags = PPMU_HAS_SIER | PPMU_ARCH_207S | - PPMU_ARCH_31, + PPMU_ARCH_31 | PPMU_HAS_ATTR_CONFIG1, .n_generic = ARRAY_SIZE(power10_generic_events), .generic_events = power10_generic_events, .cache_events = &power10_cache_events, diff --git a/arch/powerpc/perf/power5+-pmu.c b/arch/powerpc/perf/power5+-pmu.c index 3e64b4a1511f..18732267993a 100644 --- a/arch/powerpc/perf/power5+-pmu.c +++ b/arch/powerpc/perf/power5+-pmu.c @@ -132,7 +132,7 @@ static unsigned long unit_cons[PM_LASTUNIT+1][2] = { }; static int power5p_get_constraint(u64 event, unsigned long *maskp, - unsigned long *valp) + unsigned long *valp, u64 event_config1 __maybe_unused) { int pmc, byte, unit, sh; int bit, fmask; @@ -451,7 +451,8 @@ static int power5p_marked_instr_event(u64 event) static int power5p_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[], struct mmcr_regs *mmcr, - struct perf_event *pevents[]) + struct perf_event *pevents[], + u32 flags __maybe_unused) { unsigned long mmcr1 = 0; unsigned long mmcra = 0; diff --git a/arch/powerpc/perf/power5-pmu.c b/arch/powerpc/perf/power5-pmu.c index 017bb19b73fb..cb611c1e7abe 100644 --- a/arch/powerpc/perf/power5-pmu.c +++ b/arch/powerpc/perf/power5-pmu.c @@ -136,7 +136,7 @@ static unsigned long unit_cons[PM_LASTUNIT+1][2] = { }; static int power5_get_constraint(u64 event, unsigned long *maskp, - unsigned long *valp) + unsigned long *valp, u64 event_config1 __maybe_unused) { int pmc, byte, unit, sh; int bit, fmask; @@ -382,7 +382,8 @@ static int power5_marked_instr_event(u64 event) static int power5_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[], struct mmcr_regs *mmcr, - struct perf_event *pevents[]) + struct perf_event *pevents[], + u32 flags __maybe_unused) { unsigned long mmcr1 = 0; unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS; diff --git a/arch/powerpc/perf/power6-pmu.c b/arch/powerpc/perf/power6-pmu.c index 189974478e9f..69ef38216418 100644 --- a/arch/powerpc/perf/power6-pmu.c +++ b/arch/powerpc/perf/power6-pmu.c @@ -173,7 +173,8 @@ static int power6_marked_instr_event(u64 event) * Assign PMC numbers and compute MMCR1 value for a set of events */ static int p6_compute_mmcr(u64 event[], int n_ev, - unsigned int hwc[], struct mmcr_regs *mmcr, struct perf_event *pevents[]) + unsigned int hwc[], struct mmcr_regs *mmcr, struct perf_event *pevents[], + u32 flags __maybe_unused) { unsigned long mmcr1 = 0; unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS; @@ -266,7 +267,7 @@ static int p6_compute_mmcr(u64 event[], int n_ev, * 32-34 select field: nest (subunit) event selector */ static int p6_get_constraint(u64 event, unsigned long *maskp, - unsigned long *valp) + unsigned long *valp, u64 event_config1 __maybe_unused) { int pmc, byte, sh, subunit; unsigned long mask = 0, value = 0; diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c index bacfab104a1a..894c17f9a762 100644 --- a/arch/powerpc/perf/power7-pmu.c +++ b/arch/powerpc/perf/power7-pmu.c @@ -81,7 +81,7 @@ enum { */ static int power7_get_constraint(u64 event, unsigned long *maskp, - unsigned long *valp) + unsigned long *valp, u64 event_config1 __maybe_unused) { int pmc, sh, unit; unsigned long mask = 0, value = 0; @@ -245,7 +245,8 @@ static int power7_marked_instr_event(u64 event) static int power7_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[], struct mmcr_regs *mmcr, - struct perf_event *pevents[]) + struct perf_event *pevents[], + u32 flags __maybe_unused) { unsigned long mmcr1 = 0; unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS; diff --git a/arch/powerpc/perf/ppc970-pmu.c b/arch/powerpc/perf/ppc970-pmu.c index 7d78df97f272..1f8263785286 100644 --- a/arch/powerpc/perf/ppc970-pmu.c +++ b/arch/powerpc/perf/ppc970-pmu.c @@ -190,7 +190,7 @@ static unsigned long unit_cons[PM_LASTUNIT+1][2] = { }; static int p970_get_constraint(u64 event, unsigned long *maskp, - unsigned long *valp) + unsigned long *valp, u64 event_config1 __maybe_unused) { int pmc, byte, unit, sh, spcsel; unsigned long mask = 0, value = 0; @@ -256,7 +256,8 @@ static int p970_get_alternatives(u64 event, unsigned int flags, u64 alt[]) static int p970_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[], struct mmcr_regs *mmcr, - struct perf_event *pevents[]) + struct perf_event *pevents[], + u32 flags __maybe_unused) { unsigned long mmcr0 = 0, mmcr1 = 0, mmcra = 0; unsigned int pmc, unit, byte, psel; diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 78ac6d67a935..7d41e9264510 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -206,17 +206,10 @@ config AKEBONO select PPC4xx_HSTA_MSI select I2C select I2C_IBM_IIC - select NETDEVICES - select ETHERNET - select NET_VENDOR_IBM select IBM_EMAC_EMAC4 if IBM_EMAC select USB if USB_SUPPORT select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD - select MMC_SDHCI - select MMC_SDHCI_PLTFM - select ATA - select SATA_AHCI_PLATFORM help This option enables support for the IBM Akebono (476gtr) evaluation board diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c index 6303fbfc4e4f..9d030c2e0004 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads.c @@ -24,21 +24,23 @@ static void __init mpc5121_ads_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif printk(KERN_INFO "MPC5121 ADS board from Freescale Semiconductor\n"); /* * cpld regs are needed early */ mpc5121_ads_cpld_map(); + mpc512x_setup_arch(); +} + +static void __init mpc5121_ads_setup_pci(void) +{ #ifdef CONFIG_PCI + struct device_node *np; + for_each_compatible_node(np, "pci", "fsl,mpc5121-pci") mpc83xx_add_bridge(np); #endif - - mpc512x_setup_arch(); } static void __init mpc5121_ads_init_IRQ(void) @@ -64,6 +66,7 @@ define_machine(mpc5121_ads) { .name = "MPC5121 ADS", .probe = mpc5121_ads_probe, .setup_arch = mpc5121_ads_setup_arch, + .discover_phbs = mpc5121_ads_setup_pci, .init = mpc512x_init, .init_IRQ = mpc5121_ads_init_IRQ, .get_irq = ipic_get_irq, diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 4514a6f7458a..3b7d70d71692 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c @@ -185,8 +185,6 @@ static void __init efika_setup_arch(void) /* Map important registers from the internal memory map */ mpc52xx_map_common_devices(); - efika_pcisetup(); - #ifdef CONFIG_PM mpc52xx_suspend.board_suspend_prepare = efika_suspend_prepare; mpc52xx_pm_init(); @@ -218,6 +216,7 @@ define_machine(efika) .name = EFIKA_PLATFORM_NAME, .probe = efika_probe, .setup_arch = efika_setup_arch, + .discover_phbs = efika_pcisetup, .init = mpc52xx_declare_of_platform_devices, .show_cpuinfo = efika_show_cpuinfo, .init_IRQ = mpc52xx_init_irq, diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c index 3181aac08225..04cc97397095 100644 --- a/arch/powerpc/platforms/52xx/lite5200.c +++ b/arch/powerpc/platforms/52xx/lite5200.c @@ -165,8 +165,6 @@ static void __init lite5200_setup_arch(void) mpc52xx_suspend.board_resume_finish = lite5200_resume_finish; lite5200_pm_init(); #endif - - mpc52xx_setup_pci(); } static const char * const board[] __initconst = { @@ -187,6 +185,7 @@ define_machine(lite5200) { .name = "lite5200", .probe = lite5200_probe, .setup_arch = lite5200_setup_arch, + .discover_phbs = mpc52xx_setup_pci, .init = mpc52xx_declare_of_platform_devices, .init_IRQ = mpc52xx_init_irq, .get_irq = mpc52xx_get_irq, diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c index 07c5bc4ed0b5..efb8bdecbcc7 100644 --- a/arch/powerpc/platforms/52xx/media5200.c +++ b/arch/powerpc/platforms/52xx/media5200.c @@ -202,8 +202,6 @@ static void __init media5200_setup_arch(void) /* Some mpc5200 & mpc5200b related configuration */ mpc5200_setup_xlb_arbiter(); - mpc52xx_setup_pci(); - np = of_find_matching_node(NULL, mpc5200_gpio_ids); gpio = of_iomap(np, 0); of_node_put(np); @@ -244,6 +242,7 @@ define_machine(media5200_platform) { .name = "media5200-platform", .probe = media5200_probe, .setup_arch = media5200_setup_arch, + .discover_phbs = mpc52xx_setup_pci, .init = mpc52xx_declare_of_platform_devices, .init_IRQ = media5200_init_irq, .get_irq = mpc52xx_get_irq, diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c index 2d01e9b2e779..b9f5675b0a1d 100644 --- a/arch/powerpc/platforms/52xx/mpc5200_simple.c +++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c @@ -40,8 +40,6 @@ static void __init mpc5200_simple_setup_arch(void) /* Some mpc5200 & mpc5200b related configuration */ mpc5200_setup_xlb_arbiter(); - - mpc52xx_setup_pci(); } /* list of the supported boards */ @@ -73,6 +71,7 @@ define_machine(mpc5200_simple_platform) { .name = "mpc5200-simple-platform", .probe = mpc5200_simple_probe, .setup_arch = mpc5200_simple_setup_arch, + .discover_phbs = mpc52xx_setup_pci, .init = mpc52xx_declare_of_platform_devices, .init_IRQ = mpc52xx_init_irq, .get_irq = mpc52xx_get_irq, diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index 05e19470d523..b91ebebd9ff2 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -229,7 +229,7 @@ static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id) int dma, write, poll_dma; spin_lock_irqsave(&lpbfifo.lock, flags); - ts = get_tbl(); + ts = mftb(); req = lpbfifo.req; if (!req) { @@ -307,7 +307,7 @@ static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id) if (irq != 0) /* don't increment on polled case */ req->irq_count++; - req->irq_ticks += get_tbl() - ts; + req->irq_ticks += mftb() - ts; spin_unlock_irqrestore(&lpbfifo.lock, flags); /* Spinlock is released; it is now safe to call the callback */ @@ -330,7 +330,7 @@ static irqreturn_t mpc52xx_lpbfifo_bcom_irq(int irq, void *dev_id) u32 ts; spin_lock_irqsave(&lpbfifo.lock, flags); - ts = get_tbl(); + ts = mftb(); req = lpbfifo.req; if (!req || (req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA)) { @@ -361,7 +361,7 @@ static irqreturn_t mpc52xx_lpbfifo_bcom_irq(int irq, void *dev_id) lpbfifo.req = NULL; /* Release the lock before calling out to the callback. */ - req->irq_ticks += get_tbl() - ts; + req->irq_ticks += mftb() - ts; spin_unlock_irqrestore(&lpbfifo.lock, flags); if (req->callback) diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c index 3fe1a6593280..0b5b9dec16d5 100644 --- a/arch/powerpc/platforms/82xx/mpc8272_ads.c +++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c @@ -171,7 +171,6 @@ static void __init mpc8272_ads_setup_arch(void) iounmap(bcsr); init_ioports(); - pq2_init_pci(); if (ppc_md.progress) ppc_md.progress("mpc8272_ads_setup_arch(), finish", 0); @@ -205,6 +204,7 @@ define_machine(mpc8272_ads) .name = "Freescale MPC8272 ADS", .probe = mpc8272_ads_probe, .setup_arch = mpc8272_ads_setup_arch, + .discover_phbs = pq2_init_pci, .init_IRQ = mpc8272_ads_pic_init, .get_irq = cpm2_get_irq, .calibrate_decr = generic_calibrate_decr, diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c index 096cc0d59fd8..f82f75a6085c 100644 --- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c @@ -123,20 +123,17 @@ int __init pq2ads_pci_init_irq(void) np = of_find_compatible_node(NULL, NULL, "fsl,pq2ads-pci-pic"); if (!np) { printk(KERN_ERR "No pci pic node in device tree.\n"); - of_node_put(np); goto out; } irq = irq_of_parse_and_map(np, 0); if (!irq) { printk(KERN_ERR "No interrupt in pci pic node.\n"); - of_node_put(np); - goto out; + goto out_put_node; } priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { - of_node_put(np); ret = -ENOMEM; goto out_unmap_irq; } @@ -161,17 +158,17 @@ int __init pq2ads_pci_init_irq(void) priv->host = host; irq_set_handler_data(irq, priv); irq_set_chained_handler(irq, pq2ads_pci_irq_demux); - - of_node_put(np); - return 0; + ret = 0; + goto out_put_node; out_unmap_regs: iounmap(priv->regs); out_free_kmalloc: kfree(priv); - of_node_put(np); out_unmap_irq: irq_dispose_mapping(irq); +out_put_node: + of_node_put(np); out: return ret; } diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c index a74082140718..ac9113d524af 100644 --- a/arch/powerpc/platforms/82xx/pq2fads.c +++ b/arch/powerpc/platforms/82xx/pq2fads.c @@ -150,8 +150,6 @@ static void __init pq2fads_setup_arch(void) /* Enable external IRQs */ clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_siumcr, 0x0c000000); - pq2_init_pci(); - if (ppc_md.progress) ppc_md.progress("pq2fads_setup_arch(), finish", 0); } @@ -184,6 +182,7 @@ define_machine(pq2fads) .name = "Freescale PQ2FADS", .probe = pq2fads_probe, .setup_arch = pq2fads_setup_arch, + .discover_phbs = pq2_init_pci, .init_IRQ = pq2fads_pic_init, .get_irq = cpm2_get_irq, .calibrate_decr = generic_calibrate_decr, diff --git a/arch/powerpc/platforms/83xx/asp834x.c b/arch/powerpc/platforms/83xx/asp834x.c index 28474876f41b..68061c2a57c1 100644 --- a/arch/powerpc/platforms/83xx/asp834x.c +++ b/arch/powerpc/platforms/83xx/asp834x.c @@ -44,6 +44,7 @@ define_machine(asp834x) { .name = "ASP8347E", .probe = asp834x_probe, .setup_arch = asp834x_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index bcdc2c203ec9..108e1e4d2683 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c @@ -180,6 +180,7 @@ define_machine(mpc83xx_km) { .name = "mpc83xx-km-platform", .probe = mpc83xx_km_probe, .setup_arch = mpc83xx_km_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c index a952e91db3ee..3285dabcf923 100644 --- a/arch/powerpc/platforms/83xx/misc.c +++ b/arch/powerpc/platforms/83xx/misc.c @@ -132,8 +132,6 @@ void __init mpc83xx_setup_arch(void) setbat(-1, va, immrbase, immrsize, PAGE_KERNEL_NCG); update_bats(); } - - mpc83xx_setup_pci(); } int machine_check_83xx(struct pt_regs *regs) diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c index 51426e88ec67..956d4389effa 100644 --- a/arch/powerpc/platforms/83xx/mpc830x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c @@ -48,6 +48,7 @@ define_machine(mpc830x_rdb) { .name = "MPC830x RDB", .probe = mpc830x_rdb_probe, .setup_arch = mpc830x_rdb_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c index 5ccd57a48492..3b578f080e3b 100644 --- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c @@ -48,6 +48,7 @@ define_machine(mpc831x_rdb) { .name = "MPC831x RDB", .probe = mpc831x_rdb_probe, .setup_arch = mpc831x_rdb_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index 6fa5402ebf20..850d566ef900 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -101,6 +101,7 @@ define_machine(mpc832x_mds) { .name = "MPC832x MDS", .probe = mpc832x_sys_probe, .setup_arch = mpc832x_sys_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index 622c625d5ce4..b6133a237a70 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -219,6 +219,7 @@ define_machine(mpc832x_rdb) { .name = "MPC832x RDB", .probe = mpc832x_rdb_probe, .setup_arch = mpc832x_rdb_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index ebfd139bca20..9630f3aa4d9c 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -70,6 +70,7 @@ define_machine(mpc834x_itx) { .name = "MPC834x ITX", .probe = mpc834x_itx_probe, .setup_arch = mpc834x_itx_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c index 356228e35279..6d91bdce0a18 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c @@ -91,6 +91,7 @@ define_machine(mpc834x_mds) { .name = "MPC834x MDS", .probe = mpc834x_mds_probe, .setup_arch = mpc834x_mds_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index 90d9cbfae659..da4cf52cb55b 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -201,6 +201,7 @@ define_machine(mpc836x_mds) { .name = "MPC836x MDS", .probe = mpc836x_mds_probe, .setup_arch = mpc836x_mds_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c index b4aac2cde849..3427ad0d9d38 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c +++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c @@ -41,6 +41,7 @@ define_machine(mpc836x_rdk) { .name = "MPC836x RDK", .probe = mpc836x_rdk_probe, .setup_arch = mpc836x_rdk_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index 9d3721c965be..f28d166ea7db 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c @@ -93,6 +93,7 @@ define_machine(mpc837x_mds) { .name = "MPC837x MDS", .probe = mpc837x_mds_probe, .setup_arch = mpc837x_mds_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index 7c45f7ac2607..7fb7684c256b 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c @@ -73,6 +73,7 @@ define_machine(mpc837x_rdb) { .name = "MPC837x RDB/WLAN", .probe = mpc837x_rdb_probe, .setup_arch = mpc837x_rdb_setup_arch, + .discover_phbs = mpc83xx_setup_pci, .init_IRQ = mpc83xx_ipic_init_IRQ, .get_irq = ipic_get_irq, .restart = mpc83xx_restart, diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h index f37d04332fc7..a30d30588cf6 100644 --- a/arch/powerpc/platforms/83xx/mpc83xx.h +++ b/arch/powerpc/platforms/83xx/mpc83xx.h @@ -76,7 +76,7 @@ extern void mpc83xx_ipic_init_IRQ(void); #ifdef CONFIG_PCI extern void mpc83xx_setup_pci(void); #else -#define mpc83xx_setup_pci() do {} while (0) +#define mpc83xx_setup_pci NULL #endif extern int mpc83xx_declare_of_platform_devices(void); diff --git a/arch/powerpc/platforms/8xx/machine_check.c b/arch/powerpc/platforms/8xx/machine_check.c index 88dedf38eccd..656365975895 100644 --- a/arch/powerpc/platforms/8xx/machine_check.c +++ b/arch/powerpc/platforms/8xx/machine_check.c @@ -26,7 +26,7 @@ int machine_check_8xx(struct pt_regs *regs) * to deal with that than having a wart in the mcheck handler. * -- BenH */ - bad_page_fault(regs, regs->dar, SIGBUS); + bad_page_fault(regs, SIGBUS); return 1; #else return 0; diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c index f5d0bf999759..9d252c554f7f 100644 --- a/arch/powerpc/platforms/amigaone/setup.c +++ b/arch/powerpc/platforms/amigaone/setup.c @@ -65,6 +65,12 @@ static int __init amigaone_add_bridge(struct device_node *dev) } void __init amigaone_setup_arch(void) +{ + if (ppc_md.progress) + ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0); +} + +static void __init amigaone_discover_phbs(void) { struct device_node *np; int phb = -ENODEV; @@ -74,9 +80,6 @@ void __init amigaone_setup_arch(void) phb = amigaone_add_bridge(np); BUG_ON(phb != 0); - - if (ppc_md.progress) - ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0); } void __init amigaone_init_IRQ(void) @@ -159,6 +162,7 @@ define_machine(amigaone) { .name = "AmigaOne", .probe = amigaone_probe, .setup_arch = amigaone_setup_arch, + .discover_phbs = amigaone_discover_phbs, .show_cpuinfo = amigaone_show_cpuinfo, .init_IRQ = amigaone_init_IRQ, .restart = amigaone_restart, diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c index 9068edef71f7..5b9a7e9f144b 100644 --- a/arch/powerpc/platforms/cell/pervasive.c +++ b/arch/powerpc/platforms/cell/pervasive.c @@ -25,6 +25,7 @@ #include #include "pervasive.h" +#include "ras.h" static void cbe_power_save(void) { diff --git a/arch/powerpc/platforms/cell/pervasive.h b/arch/powerpc/platforms/cell/pervasive.h index c6fccad6caee..0da74ab10716 100644 --- a/arch/powerpc/platforms/cell/pervasive.h +++ b/arch/powerpc/platforms/cell/pervasive.h @@ -13,9 +13,6 @@ #define PERVASIVE_H extern void cbe_pervasive_init(void); -extern void cbe_system_error_exception(struct pt_regs *regs); -extern void cbe_maintenance_exception(struct pt_regs *regs); -extern void cbe_thermal_exception(struct pt_regs *regs); #ifdef CONFIG_PPC_IBM_CELL_RESETBUTTON extern int cbe_sysreset_hack(void); diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 6ea480539419..4325c05bedd9 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -49,7 +49,7 @@ static void dump_fir(int cpu) } -void cbe_system_error_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(cbe_system_error_exception) { int cpu = smp_processor_id(); @@ -58,7 +58,7 @@ void cbe_system_error_exception(struct pt_regs *regs) dump_stack(); } -void cbe_maintenance_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(cbe_maintenance_exception) { int cpu = smp_processor_id(); @@ -70,7 +70,7 @@ void cbe_maintenance_exception(struct pt_regs *regs) dump_stack(); } -void cbe_thermal_exception(struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER(cbe_thermal_exception) { int cpu = smp_processor_id(); diff --git a/arch/powerpc/platforms/cell/ras.h b/arch/powerpc/platforms/cell/ras.h index 6c2e6bc0062e..226dbd48efad 100644 --- a/arch/powerpc/platforms/cell/ras.h +++ b/arch/powerpc/platforms/cell/ras.h @@ -2,9 +2,12 @@ #ifndef RAS_H #define RAS_H -extern void cbe_system_error_exception(struct pt_regs *regs); -extern void cbe_maintenance_exception(struct pt_regs *regs); -extern void cbe_thermal_exception(struct pt_regs *regs); +#include + +DECLARE_INTERRUPT_HANDLER(cbe_system_error_exception); +DECLARE_INTERRUPT_HANDLER(cbe_maintenance_exception); +DECLARE_INTERRUPT_HANDLER(cbe_thermal_exception); + extern void cbe_ras_init(void); #endif /* RAS_H */ diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index b2c2bf35b76c..8c421dc78b28 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c @@ -314,6 +314,14 @@ chrp_find_bridges(void) } } of_node_put(root); + + /* + * "Temporary" fixes for PCI devices. + * -- Geert + */ + hydra_init(); /* Mac I/O */ + + pci_create_OF_bus_map(); } /* SL82C105 IDE Control/Status Register */ diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index c45435aa5e36..3cfc382841e5 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -334,22 +334,11 @@ static void __init chrp_setup_arch(void) /* On pegasos, enable the L2 cache if not already done by OF */ pegasos_set_l2cr(); - /* Lookup PCI host bridges */ - chrp_find_bridges(); - - /* - * Temporary fixes for PCI devices. - * -- Geert - */ - hydra_init(); /* Mac I/O */ - /* * Fix the Super I/O configuration */ sio_init(); - pci_create_OF_bus_map(); - /* * Print the banner, then scroll down so boot progress * can be printed. -- Cort @@ -582,6 +571,7 @@ define_machine(chrp) { .name = "CHRP", .probe = chrp_probe, .setup_arch = chrp_setup_arch, + .discover_phbs = chrp_find_bridges, .init = chrp_init2, .show_cpuinfo = chrp_show_cpuinfo, .init_IRQ = chrp_init_IRQ, diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c index d8f2e2c737bb..53065d564161 100644 --- a/arch/powerpc/platforms/embedded6xx/holly.c +++ b/arch/powerpc/platforms/embedded6xx/holly.c @@ -108,15 +108,13 @@ static void holly_remap_bridge(void) tsi108_write_reg(TSI108_PCI_P2O_BAR2, 0x0); } -static void __init holly_setup_arch(void) +static void __init holly_init_pci(void) { struct device_node *np; if (ppc_md.progress) ppc_md.progress("holly_setup_arch():set_bridge", 0); - tsi108_csr_vir_base = get_vir_csrbase(); - /* setup PCI host bridge */ holly_remap_bridge(); @@ -127,6 +125,11 @@ static void __init holly_setup_arch(void) ppc_md.pci_exclude_device = holly_exclude_device; if (ppc_md.progress) ppc_md.progress("tsi108: resources set", 0x100); +} + +static void __init holly_setup_arch(void) +{ + tsi108_csr_vir_base = get_vir_csrbase(); printk(KERN_INFO "PPC750GX/CL Platform\n"); } @@ -259,6 +262,7 @@ define_machine(holly){ .name = "PPC750 GX/CL TSI", .probe = holly_probe, .setup_arch = holly_setup_arch, + .discover_phbs = holly_init_pci, .init_IRQ = holly_init_IRQ, .show_cpuinfo = holly_show_cpuinfo, .get_irq = mpic_get_irq, diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c index f514d5d28cd4..eb8342e7f84e 100644 --- a/arch/powerpc/platforms/embedded6xx/linkstation.c +++ b/arch/powerpc/platforms/embedded6xx/linkstation.c @@ -63,15 +63,18 @@ static int __init linkstation_add_bridge(struct device_node *dev) } static void __init linkstation_setup_arch(void) +{ + printk(KERN_INFO "BUFFALO Network Attached Storage Series\n"); + printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n"); +} + +static void __init linkstation_setup_pci(void) { struct device_node *np; /* Lookup PCI host bridges */ for_each_compatible_node(np, "pci", "mpc10x-pci") linkstation_add_bridge(np); - - printk(KERN_INFO "BUFFALO Network Attached Storage Series\n"); - printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n"); } /* @@ -153,6 +156,7 @@ define_machine(linkstation){ .name = "Buffalo Linkstation", .probe = linkstation_probe, .setup_arch = linkstation_setup_arch, + .discover_phbs = linkstation_setup_pci, .init_IRQ = linkstation_init_IRQ, .show_cpuinfo = linkstation_show_cpuinfo, .get_irq = mpic_get_irq, diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index b95c3380d2b5..5565647dc879 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -58,16 +58,14 @@ int mpc7448_hpc2_exclude_device(struct pci_controller *hose, return PCIBIOS_SUCCESSFUL; } -static void __init mpc7448_hpc2_setup_arch(void) +static void __init mpc7448_hpc2_setup_pci(void) { +#ifdef CONFIG_PCI struct device_node *np; if (ppc_md.progress) - ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0); - - tsi108_csr_vir_base = get_vir_csrbase(); + ppc_md.progress("mpc7448_hpc2_setup_pci():set_bridge", 0); /* setup PCI host bridge */ -#ifdef CONFIG_PCI for_each_compatible_node(np, "pci", "tsi108-pci") tsi108_setup_pci(np, MPC7448HPC2_PCI_CFG_PHYS, 0); @@ -75,6 +73,11 @@ static void __init mpc7448_hpc2_setup_arch(void) if (ppc_md.progress) ppc_md.progress("tsi108: resources set", 0x100); #endif +} + +static void __init mpc7448_hpc2_setup_arch(void) +{ + tsi108_csr_vir_base = get_vir_csrbase(); printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n"); printk(KERN_INFO @@ -181,6 +184,7 @@ define_machine(mpc7448_hpc2){ .name = "MPC7448 HPC2", .probe = mpc7448_hpc2_probe, .setup_arch = mpc7448_hpc2_setup_arch, + .discover_phbs = mpc7448_hpc2_setup_pci, .init_IRQ = mpc7448_hpc2_init_IRQ, .show_cpuinfo = mpc7448_hpc2_show_cpuinfo, .get_irq = mpic_get_irq, diff --git a/arch/powerpc/platforms/embedded6xx/mvme5100.c b/arch/powerpc/platforms/embedded6xx/mvme5100.c index 1cd488daa0bf..c06a0490d157 100644 --- a/arch/powerpc/platforms/embedded6xx/mvme5100.c +++ b/arch/powerpc/platforms/embedded6xx/mvme5100.c @@ -154,17 +154,19 @@ static const struct of_device_id mvme5100_of_bus_ids[] __initconst = { */ static void __init mvme5100_setup_arch(void) { - struct device_node *np; - if (ppc_md.progress) ppc_md.progress("mvme5100_setup_arch()", 0); - for_each_compatible_node(np, "pci", "hawk-pci") - mvme5100_add_bridge(np); - restart = ioremap(BOARD_MODRST_REG, 4); } +static void __init mvme5100_setup_pci(void) +{ + struct device_node *np; + + for_each_compatible_node(np, "pci", "hawk-pci") + mvme5100_add_bridge(np); +} static void mvme5100_show_cpuinfo(struct seq_file *m) { @@ -205,6 +207,7 @@ define_machine(mvme5100) { .name = "MVME5100", .probe = mvme5100_probe, .setup_arch = mvme5100_setup_arch, + .discover_phbs = mvme5100_setup_pci, .init_IRQ = mvme5100_pic_init, .show_cpuinfo = mvme5100_show_cpuinfo, .get_irq = mpic_get_irq, diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c index e346ddcef45e..e188b90f7016 100644 --- a/arch/powerpc/platforms/embedded6xx/storcenter.c +++ b/arch/powerpc/platforms/embedded6xx/storcenter.c @@ -65,14 +65,17 @@ static int __init storcenter_add_bridge(struct device_node *dev) } static void __init storcenter_setup_arch(void) +{ + printk(KERN_INFO "IOMEGA StorCenter\n"); +} + +static void __init storcenter_setup_pci(void) { struct device_node *np; /* Lookup PCI host bridges */ for_each_compatible_node(np, "pci", "mpc10x-pci") storcenter_add_bridge(np); - - printk(KERN_INFO "IOMEGA StorCenter\n"); } /* @@ -117,6 +120,7 @@ define_machine(storcenter){ .name = "IOMEGA StorCenter", .probe = storcenter_probe, .setup_arch = storcenter_setup_arch, + .discover_phbs = storcenter_setup_pci, .init_IRQ = storcenter_init_IRQ, .get_irq = mpic_get_irq, .restart = storcenter_restart, diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index c86a66d5e998..a20b9576de22 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -536,6 +536,9 @@ static int __init maple_add_bridge(struct device_node *dev) /* Check for legacy IOs */ isa_bridge_find_early(hose); + /* create pci_dn's for DT nodes under this PHB */ + pci_devs_phb_init_dynamic(hose); + return 0; } diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index f7e66a2005b4..4e9ad5bf3efb 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -179,9 +179,6 @@ static void __init maple_setup_arch(void) #ifdef CONFIG_SMP smp_ops = &maple_smp_ops; #endif - /* Lookup PCI hosts */ - maple_pci_init(); - maple_use_rtas_reboot_and_halt_if_present(); printk(KERN_DEBUG "Using native/NAP idle loop\n"); @@ -351,6 +348,7 @@ define_machine(maple) { .name = "Maple", .probe = maple_probe, .setup_arch = maple_setup_arch, + .discover_phbs = maple_pci_init, .init_IRQ = maple_init_IRQ, .pci_irq_fixup = maple_pci_irq_fixup, .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index b612474f8f8e..376797eb7894 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -144,8 +144,6 @@ static void __init pas_setup_arch(void) /* Setup SMP callback */ smp_ops = &pas_smp_ops; #endif - /* Lookup PCI hosts */ - pas_pci_init(); /* Remap SDC register for doing reset */ /* XXXOJN This should maybe come out of the device tree */ @@ -446,6 +444,7 @@ define_machine(pasemi) { .name = "PA Semi PWRficient", .probe = pas_probe, .setup_arch = pas_setup_arch, + .discover_phbs = pas_pci_init, .init_IRQ = pas_init_IRQ, .get_irq = mpic_get_irq, .restart = pas_restart, diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index e35eaa9cf938..e9abe0f2e7f0 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -850,6 +850,10 @@ static int __init pmac_add_bridge(struct device_node *dev) /* Fixup "bus-range" OF property */ fixup_bus_range(dev); + /* create pci_dn's for DT nodes under this PHB */ + if (IS_ENABLED(CONFIG_PPC64)) + pci_devs_phb_init_dynamic(hose); + return 0; } diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 2e2cc0c75d87..86aee3f2483f 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -298,9 +298,6 @@ static void __init pmac_setup_arch(void) of_node_put(ic); } - /* Lookup PCI hosts */ - pmac_pci_init(); - #ifdef CONFIG_PPC32 ohare_init(); l2cr_init(); @@ -600,6 +597,7 @@ define_machine(powermac) { .name = "PowerMac", .probe = pmac_probe, .setup_arch = pmac_setup_arch, + .discover_phbs = pmac_pci_init, .show_cpuinfo = pmac_show_cpuinfo, .init_IRQ = pmac_pic_init, .get_irq = NULL, /* changed later */ diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index e6f461812856..999997d9e9a9 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c index 5fc9408bb0b3..019669eb21d2 100644 --- a/arch/powerpc/platforms/powernv/memtrace.c +++ b/arch/powerpc/platforms/powernv/memtrace.c @@ -19,6 +19,7 @@ #include #include #include +#include /* This enables us to keep track of the memory removed from each node. */ struct memtrace_entry { @@ -51,6 +52,27 @@ static const struct file_operations memtrace_fops = { .open = simple_open, }; +#define FLUSH_CHUNK_SIZE SZ_1G +/** + * flush_dcache_range_chunked(): Write any modified data cache blocks out to + * memory and invalidate them, in chunks of up to FLUSH_CHUNK_SIZE + * Does not invalidate the corresponding instruction cache blocks. + * + * @start: the start address + * @stop: the stop address (exclusive) + * @chunk: the max size of the chunks + */ +static void flush_dcache_range_chunked(unsigned long start, unsigned long stop, + unsigned long chunk) +{ + unsigned long i; + + for (i = start; i < stop; i += chunk) { + flush_dcache_range(i, min(stop, i + chunk)); + cond_resched(); + } +} + static void memtrace_clear_range(unsigned long start_pfn, unsigned long nr_pages) { @@ -62,6 +84,13 @@ static void memtrace_clear_range(unsigned long start_pfn, cond_resched(); clear_page(__va(PFN_PHYS(pfn))); } + /* + * Before we go ahead and use this range as cache inhibited range + * flush the cache. + */ + flush_dcache_range_chunked(PFN_PHYS(start_pfn), + PFN_PHYS(start_pfn + nr_pages), + FLUSH_CHUNK_SIZE); } static u64 memtrace_alloc_node(u32 nid, u64 size) diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index c61c3b62c8c6..303d7c775740 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -624,7 +624,7 @@ static int opal_recover_mce(struct pt_regs *regs, */ recovered = 0; } else { - die("Machine check", regs, SIGBUS); + die_mce("Machine check", regs, SIGBUS); recovered = 1; } } diff --git a/arch/powerpc/platforms/powernv/pci-cxl.c b/arch/powerpc/platforms/powernv/pci-cxl.c index 8c739c94ed28..53172862d23b 100644 --- a/arch/powerpc/platforms/powernv/pci-cxl.c +++ b/arch/powerpc/platforms/powernv/pci-cxl.c @@ -150,25 +150,3 @@ int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq, return 0; } EXPORT_SYMBOL(pnv_cxl_ioda_msi_setup); - -#if IS_MODULE(CONFIG_CXL) -static inline int get_cxl_module(void) -{ - struct module *cxl_module; - - mutex_lock(&module_mutex); - - cxl_module = find_module("cxl"); - if (cxl_module) - __module_get(cxl_module); - - mutex_unlock(&module_mutex); - - if (!cxl_module) - return -ENODEV; - - return 0; -} -#else -static inline int get_cxl_module(void) { return 0; } -#endif diff --git a/arch/powerpc/platforms/powernv/pci-ioda-tce.c b/arch/powerpc/platforms/powernv/pci-ioda-tce.c index 5218f5da2737..30551bbd7988 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda-tce.c +++ b/arch/powerpc/platforms/powernv/pci-ioda-tce.c @@ -380,6 +380,8 @@ void pnv_pci_unlink_table_and_group(struct iommu_table *tbl, /* Remove link to a group from table's list of attached groups */ found = false; + + rcu_read_lock(); list_for_each_entry_rcu(tgl, &tbl->it_group_list, next) { if (tgl->table_group == table_group) { list_del_rcu(&tgl->next); @@ -388,6 +390,8 @@ void pnv_pci_unlink_table_and_group(struct iommu_table *tbl, break; } } + rcu_read_unlock(); + if (WARN_ON(!found)) return; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index c4f72cdc9b51..f0f901683a2f 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2402,9 +2402,6 @@ static void pnv_pci_ioda_create_dbgfs(void) list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { phb = hose->private_data; - /* Notify initialization of PHB done */ - phb->initialized = 1; - sprintf(name, "PCI%04x", hose->global_number); phb->dbgfs = debugfs_create_dir(name, powerpc_debugfs_root); @@ -2601,17 +2598,8 @@ static resource_size_t pnv_pci_default_alignment(void) */ static bool pnv_pci_enable_device_hook(struct pci_dev *dev) { - struct pnv_phb *phb = pci_bus_to_pnvhb(dev->bus); struct pci_dn *pdn; - /* The function is probably called while the PEs have - * not be created yet. For example, resource reassignment - * during PCI probe period. We just skip the check if - * PEs isn't ready. - */ - if (!phb->initialized) - return true; - pdn = pci_get_pdn(dev); if (!pdn || pdn->pe_number == IODA_INVALID_PE) { pci_err(dev, "pci_enable_device() blocked, no PE assigned.\n"); @@ -2623,14 +2611,9 @@ static bool pnv_pci_enable_device_hook(struct pci_dev *dev) static bool pnv_ocapi_enable_device_hook(struct pci_dev *dev) { - struct pci_controller *hose = pci_bus_to_host(dev->bus); - struct pnv_phb *phb = hose->private_data; struct pci_dn *pdn; struct pnv_ioda_pe *pe; - if (!phb->initialized) - return true; - pdn = pci_get_pdn(dev); if (!pdn) return false; @@ -2938,7 +2921,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, phb_id = be64_to_cpup(prop64); pr_debug(" PHB-ID : 0x%016llx\n", phb_id); - phb = memblock_alloc(sizeof(*phb), SMP_CACHE_BYTES); + phb = kzalloc(sizeof(*phb), GFP_KERNEL); if (!phb) panic("%s: Failed to allocate %zu bytes\n", __func__, sizeof(*phb)); @@ -2987,7 +2970,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, else phb->diag_data_size = PNV_PCI_DIAG_BUF_SIZE; - phb->diag_data = memblock_alloc(phb->diag_data_size, SMP_CACHE_BYTES); + phb->diag_data = kzalloc(phb->diag_data_size, GFP_KERNEL); if (!phb->diag_data) panic("%s: Failed to allocate %u bytes\n", __func__, phb->diag_data_size); @@ -3049,9 +3032,10 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, } pemap_off = size; size += phb->ioda.total_pe_num * sizeof(struct pnv_ioda_pe); - aux = memblock_alloc(size, SMP_CACHE_BYTES); + aux = kzalloc(size, GFP_KERNEL); if (!aux) panic("%s: Failed to allocate %lu bytes\n", __func__, size); + phb->ioda.pe_alloc = aux; phb->ioda.m64_segmap = aux + m64map_off; phb->ioda.m32_segmap = aux + m32map_off; @@ -3178,6 +3162,9 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, /* Remove M64 resource if we can't configure it successfully */ if (!phb->init_m64 || phb->init_m64(phb)) hose->mem_resources[1].flags = 0; + + /* create pci_dn's for DT nodes under this PHB */ + pci_devs_phb_init_dynamic(hose); } void __init pnv_pci_init_ioda2_phb(struct device_node *np) diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 739a0b3b72e1..36d22920f5a3 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -119,7 +119,6 @@ struct pnv_phb { int flags; void __iomem *regs; u64 regs_phys; - int initialized; spinlock_t lock; #ifdef CONFIG_DEBUG_FS diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 4426a109ec2f..aadf932c4e61 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -180,9 +180,6 @@ static void __init pnv_setup_arch(void) /* Initialize SMP */ pnv_smp_init(); - /* Setup PCI */ - pnv_pci_init(); - /* Setup RTC and NVRAM callbacks */ if (firmware_has_feature(FW_FEATURE_OPAL)) opal_nvram_init(); @@ -547,6 +544,7 @@ define_machine(powernv) { .init_IRQ = pnv_init_IRQ, .show_cpuinfo = pnv_show_cpuinfo, .get_proc_freq = pnv_get_proc_freq, + .discover_phbs = pnv_pci_init, .progress = pnv_progress, .machine_shutdown = pnv_shutdown, .power_save = NULL, diff --git a/arch/powerpc/platforms/powernv/subcore.h b/arch/powerpc/platforms/powernv/subcore.h index c8f574d1c04a..77feee8436d4 100644 --- a/arch/powerpc/platforms/powernv/subcore.h +++ b/arch/powerpc/platforms/powernv/subcore.h @@ -15,7 +15,7 @@ void split_core_secondary_loop(u8 *state); extern void update_subcore_sibling_mask(void); #else -static inline void update_subcore_sibling_mask(void) { }; +static inline void update_subcore_sibling_mask(void) { } #endif /* CONFIG_SMP */ #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/platforms/powernv/vas.c b/arch/powerpc/platforms/powernv/vas.c index 598e4cd563fb..b65256a63e87 100644 --- a/arch/powerpc/platforms/powernv/vas.c +++ b/arch/powerpc/platforms/powernv/vas.c @@ -28,12 +28,10 @@ static DEFINE_PER_CPU(int, cpu_vas_id); static int vas_irq_fault_window_setup(struct vas_instance *vinst) { - char devname[64]; int rc = 0; - snprintf(devname, sizeof(devname), "vas-%d", vinst->vas_id); rc = request_threaded_irq(vinst->virq, vas_fault_handler, - vas_fault_thread_fn, 0, devname, vinst); + vas_fault_thread_fn, 0, vinst->name, vinst); if (rc) { pr_err("VAS[%d]: Request IRQ(%d) failed with %d\n", @@ -80,6 +78,12 @@ static int init_vas_instance(struct platform_device *pdev) if (!vinst) return -ENOMEM; + vinst->name = kasprintf(GFP_KERNEL, "vas-%d", vasid); + if (!vinst->name) { + kfree(vinst); + return -ENOMEM; + } + INIT_LIST_HEAD(&vinst->node); ida_init(&vinst->ida); mutex_init(&vinst->mutex); @@ -162,6 +166,7 @@ static int init_vas_instance(struct platform_device *pdev) return 0; free_vinst: + kfree(vinst->name); kfree(vinst); return -ENODEV; diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h index 70f793e8f6cc..c7db3190baca 100644 --- a/arch/powerpc/platforms/powernv/vas.h +++ b/arch/powerpc/platforms/powernv/vas.h @@ -340,6 +340,7 @@ struct vas_instance { struct vas_window *rxwin[VAS_COP_TYPE_MAX]; struct vas_window *windows[VAS_WINDOWS_PER_CHIP]; + char *name; char *dbgname; struct dentry *dbgdir; }; diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 16e86ba8aa20..233503fcf8f0 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -127,7 +127,6 @@ void dlpar_free_cc_nodes(struct device_node *dn) #define NEXT_PROPERTY 3 #define PREV_PARENT 4 #define MORE_MEMORY 5 -#define CALL_AGAIN -2 #define ERR_CFG_USE -9003 struct device_node *dlpar_configure_connector(__be32 drc_index, @@ -168,6 +167,9 @@ struct device_node *dlpar_configure_connector(__be32 drc_index, spin_unlock(&rtas_data_buf_lock); + if (rtas_busy_delay(rc)) + continue; + switch (rc) { case COMPLETE: break; @@ -216,9 +218,6 @@ struct device_node *dlpar_configure_connector(__be32 drc_index, last_dn = last_dn->parent; break; - case CALL_AGAIN: - break; - case MORE_MEMORY: case ERR_CFG_USE: default: @@ -521,11 +520,8 @@ static ssize_t dlpar_store(struct class *class, struct class_attribute *attr, int rc; args = argbuf = kstrdup(buf, GFP_KERNEL); - if (!argbuf) { - pr_info("Could not allocate resources for DLPAR operation\n"); - kfree(argbuf); + if (!argbuf) return -ENOMEM; - } /* * Parse out the request from the user, this will be in the form: diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index cf024fa37bda..bc15200852b7 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -43,7 +43,7 @@ static int ibm_get_config_addr_info; static int ibm_get_config_addr_info2; static int ibm_configure_pe; -void pseries_pcibios_bus_add_device(struct pci_dev *pdev) +static void pseries_pcibios_bus_add_device(struct pci_dev *pdev) { struct pci_dn *pdn = pci_get_pdn(pdev); @@ -694,8 +694,7 @@ static int pseries_eeh_write_config(struct eeh_dev *edev, int where, int size, u } #ifdef CONFIG_PCI_IOV -int pseries_send_allow_unfreeze(struct pci_dn *pdn, - u16 *vf_pe_array, int cur_vfs) +static int pseries_send_allow_unfreeze(struct pci_dn *pdn, u16 *vf_pe_array, int cur_vfs) { int rc; int ibm_allow_unfreeze = rtas_token("ibm,open-sriov-allow-unfreeze"); diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index 72a4d4167849..1bffbd1c9a94 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -55,9 +55,8 @@ struct pe_map_bar_entry { __be32 reserved; /* Reserved Space */ }; -int pseries_send_map_pe(struct pci_dev *pdev, - u16 num_vfs, - struct pe_map_bar_entry *vf_pe_array) +static int pseries_send_map_pe(struct pci_dev *pdev, u16 num_vfs, + struct pe_map_bar_entry *vf_pe_array) { struct pci_dn *pdn; int rc; @@ -88,7 +87,7 @@ int pseries_send_map_pe(struct pci_dev *pdev, return rc; } -void pseries_set_pe_num(struct pci_dev *pdev, u16 vf_index, __be16 pe_num) +static void pseries_set_pe_num(struct pci_dev *pdev, u16 vf_index, __be16 pe_num) { struct pci_dn *pdn; @@ -102,7 +101,7 @@ void pseries_set_pe_num(struct pci_dev *pdev, u16 vf_index, __be16 pe_num) pdn->pe_num_map[vf_index]); } -int pseries_associate_pes(struct pci_dev *pdev, u16 num_vfs) +static int pseries_associate_pes(struct pci_dev *pdev, u16 num_vfs) { struct pci_dn *pdn; int i, rc, vf_index; @@ -146,7 +145,7 @@ int pseries_associate_pes(struct pci_dev *pdev, u16 num_vfs) return rc; } -int pseries_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) +static int pseries_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) { struct pci_dn *pdn; int rc; @@ -189,14 +188,14 @@ int pseries_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) return rc; } -int pseries_pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs) +static int pseries_pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs) { /* Allocate PCI data */ add_sriov_vf_pdns(pdev); return pseries_pci_sriov_enable(pdev, num_vfs); } -int pseries_pcibios_sriov_disable(struct pci_dev *pdev) +static int pseries_pcibios_sriov_disable(struct pci_dev *pdev) { struct pci_dn *pdn; diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 593840847cd3..4fe48c04c6c2 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -33,7 +33,7 @@ int smp_query_cpu_stopped(unsigned int pcpu); #define QCSS_HARDWARE_ERROR -1 #define QCSS_HARDWARE_BUSY -2 #else -static inline void smp_init_pseries(void) { }; +static inline void smp_init_pseries(void) { } #endif extern void pseries_kexec_cpu_down(int crash_shutdown, int secondary); diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 149cec2212e6..f8b390a9d9fb 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -122,7 +122,7 @@ static inline u8 rtas_mc_error_sub_type(const struct pseries_mc_errorlog *mlog) * devices or systems (e.g. hugepages) that have not been initialized at the * subsys stage. */ -int __init init_ras_hotplug_IRQ(void) +static int __init init_ras_hotplug_IRQ(void) { struct device_node *np; @@ -315,12 +315,10 @@ static irqreturn_t ras_hotplug_interrupt(int irq, void *dev_id) /* Handle environmental and power warning (EPOW) interrupts. */ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id) { - int status; int state; int critical; - status = rtas_get_sensor_fast(EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX, - &state); + rtas_get_sensor_fast(EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX, &state); if (state > 3) critical = 1; /* Time Critical */ @@ -329,12 +327,9 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id) spin_lock(&ras_log_buf_lock); - status = rtas_call(ras_check_exception_token, 6, 1, NULL, - RTAS_VECTOR_EXTERNAL_INTERRUPT, - virq_to_hw(irq), - RTAS_EPOW_WARNING, - critical, __pa(&ras_log_buf), - rtas_get_error_log_max()); + rtas_call(ras_check_exception_token, 6, 1, NULL, RTAS_VECTOR_EXTERNAL_INTERRUPT, + virq_to_hw(irq), RTAS_EPOW_WARNING, critical, __pa(&ras_log_buf), + rtas_get_error_log_max()); log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, 0); @@ -722,6 +717,7 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) struct pseries_errorlog *pseries_log; struct pseries_mc_errorlog *mce_log = NULL; int disposition = rtas_error_disposition(errp); + unsigned long msr; u8 error_type; if (!rtas_error_extended(errp)) @@ -747,9 +743,21 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) * SLB multihit is done by now. */ out: - mtmsr(mfmsr() | MSR_IR | MSR_DR); + msr = mfmsr(); + mtmsr(msr | MSR_IR | MSR_DR); + disposition = mce_handle_err_virtmode(regs, errp, mce_log, disposition); + + /* + * Queue irq work to log this rtas event later. + * irq_work_queue uses per-cpu variables, so do this in virt + * mode as well. + */ + irq_work_queue(&mce_errlog_process_work); + + mtmsr(msr); + return disposition; } @@ -813,7 +821,7 @@ static int recover_mce(struct pt_regs *regs, struct machine_check_event *evt) */ recovered = 0; } else { - die("Machine check", regs, SIGBUS); + die_mce("Machine check", regs, SIGBUS); recovered = 1; } } @@ -865,10 +873,8 @@ long pseries_machine_check_realmode(struct pt_regs *regs) * virtual mode. */ disposition = mce_handle_error(regs, errp); - fwnmi_release_errinfo(); - /* Queue irq work to log this rtas event later. */ - irq_work_queue(&mce_errlog_process_work); + fwnmi_release_errinfo(); if (disposition == RTAS_DISP_FULLY_RECOVERED) return 1; diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 090c13f6c881..46e1540abc22 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -463,7 +463,7 @@ void pseries_little_endian_exceptions(void) } #endif -static void __init find_and_init_phbs(void) +static void __init pSeries_discover_phbs(void) { struct device_node *node; struct pci_controller *phb; @@ -481,6 +481,9 @@ static void __init find_and_init_phbs(void) pci_process_bridge_OF_ranges(phb, node, 0); isa_bridge_find_early(phb); phb->controller_ops = pseries_pci_controller_ops; + + /* create pci_dn's for DT nodes under this PHB */ + pci_devs_phb_init_dynamic(phb); } of_node_put(root); @@ -607,8 +610,8 @@ enum get_iov_fw_value_index { WDW_SIZE = 3 /* Get Window Size */ }; -resource_size_t pseries_get_iov_fw_value(struct pci_dev *dev, int resno, - enum get_iov_fw_value_index value) +static resource_size_t pseries_get_iov_fw_value(struct pci_dev *dev, int resno, + enum get_iov_fw_value_index value) { const int *indexes; struct device_node *dn = pci_device_to_OF_node(dev); @@ -643,7 +646,7 @@ resource_size_t pseries_get_iov_fw_value(struct pci_dev *dev, int resno, return ret; } -void of_pci_set_vf_bar_size(struct pci_dev *dev, const int *indexes) +static void of_pci_set_vf_bar_size(struct pci_dev *dev, const int *indexes) { struct resource *res; resource_size_t base, size; @@ -665,7 +668,7 @@ void of_pci_set_vf_bar_size(struct pci_dev *dev, const int *indexes) } } -void of_pci_parse_iov_addrs(struct pci_dev *dev, const int *indexes) +static void of_pci_parse_iov_addrs(struct pci_dev *dev, const int *indexes) { struct resource *res, *root, *conflict; resource_size_t base, size; @@ -786,7 +789,6 @@ static void __init pSeries_setup_arch(void) /* Find and initialize PCI host bridges */ init_pci_config_tokens(); - find_and_init_phbs(); of_reconfig_notifier_register(&pci_dn_reconfig_nb); pSeries_nvram_init(); @@ -1050,6 +1052,7 @@ define_machine(pseries) { .init_IRQ = pseries_init_irq, .show_cpuinfo = pSeries_show_cpuinfo, .log_error = pSeries_log_error, + .discover_phbs = pSeries_discover_phbs, .pcibios_fixup = pSeries_final_fixup, .restart = rtas_restart, .halt = rtas_halt, diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index dcd817ca2edf..3fe37495f63d 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -1383,7 +1383,6 @@ static long check_bp_loc(unsigned long addr) return 1; } -#ifndef CONFIG_PPC_8xx static int find_free_data_bpt(void) { int i; @@ -1395,7 +1394,6 @@ static int find_free_data_bpt(void) printf("Couldn't find free breakpoint register\n"); return -1; } -#endif static void print_data_bpts(void) { @@ -1435,7 +1433,6 @@ bpt_cmds(void) cmd = inchar(); switch (cmd) { -#ifndef CONFIG_PPC_8xx static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n"; int mode; case 'd': /* bd - hardware data breakpoint */ @@ -1497,7 +1494,6 @@ bpt_cmds(void) force_enable_xmon(); } break; -#endif case 'c': if (!scanhex(&a)) { @@ -3723,7 +3719,7 @@ void dump_segments(void) printf("sr0-15 ="); for (i = 0; i < 16; ++i) - printf(" %x", mfsrin(i << 28)); + printf(" %x", mfsr(i << 28)); printf("\n"); } #endif diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig index 6896b4213c49..02056b024091 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig @@ -71,7 +71,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_MODULE_SIG_SHA256=y -CONFIG_UNUSED_SYMBOLS=y CONFIG_BLK_DEV_INTEGRITY=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_BLK_WBT=y diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index ef4df9d60d6a..bac721a501da 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig @@ -66,7 +66,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_MODULE_SIG_SHA256=y -CONFIG_UNUSED_SYMBOLS=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_BLK_WBT=y CONFIG_BLK_CGROUP_IOLATENCY=y diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig index 02ba62298576..d77f54e906fd 100644 --- a/arch/sh/configs/edosk7760_defconfig +++ b/arch/sh/configs/edosk7760_defconfig @@ -102,7 +102,6 @@ CONFIG_NLS_UTF8=y CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y -CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig index d00376eb044f..6c719ab4332a 100644 --- a/arch/sh/configs/sdk7780_defconfig +++ b/arch/sh/configs/sdk7780_defconfig @@ -128,7 +128,6 @@ CONFIG_NLS_ISO8859_15=y CONFIG_NLS_UTF8=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y -CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 78210793d357..9c9c4a888b1d 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -50,7 +50,6 @@ CONFIG_JUMP_LABEL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_UNUSED_SYMBOLS is not set CONFIG_BINFMT_MISC=y CONFIG_NET=y CONFIG_PACKET=y diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 9936528e1939..b60bd2d86034 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -48,7 +48,6 @@ CONFIG_JUMP_LABEL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_UNUSED_SYMBOLS is not set CONFIG_BINFMT_MISC=y CONFIG_NET=y CONFIG_PACKET=y diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h index a8c3d284fa46..95a448fbb44c 100644 --- a/arch/x86/include/asm/insn.h +++ b/arch/x86/include/asm/insn.h @@ -7,9 +7,12 @@ * Copyright (C) IBM Corporation, 2009 */ +#include /* insn_attr_t is defined in inat.h */ #include +#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) + struct insn_field { union { insn_value_t value; @@ -20,6 +23,48 @@ struct insn_field { unsigned char nbytes; }; +static inline void insn_field_set(struct insn_field *p, insn_value_t v, + unsigned char n) +{ + p->value = v; + p->nbytes = n; +} + +static inline void insn_set_byte(struct insn_field *p, unsigned char n, + insn_byte_t v) +{ + p->bytes[n] = v; +} + +#else + +struct insn_field { + insn_value_t value; + union { + insn_value_t little; + insn_byte_t bytes[4]; + }; + /* !0 if we've run insn_get_xxx() for this field */ + unsigned char got; + unsigned char nbytes; +}; + +static inline void insn_field_set(struct insn_field *p, insn_value_t v, + unsigned char n) +{ + p->value = v; + p->little = __cpu_to_le32(v); + p->nbytes = n; +} + +static inline void insn_set_byte(struct insn_field *p, unsigned char n, + insn_byte_t v) +{ + p->bytes[n] = v; + p->value = __le32_to_cpu(p->little); +} +#endif + struct insn { struct insn_field prefixes; /* * Prefixes diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h index fdbffec4cfde..5a2baf28a1dc 100644 --- a/arch/x86/include/asm/orc_types.h +++ b/arch/x86/include/asm/orc_types.h @@ -40,6 +40,8 @@ #define ORC_REG_MAX 15 #ifndef __ASSEMBLY__ +#include + /* * This struct is more or less a vastly simplified version of the DWARF Call * Frame Information standard. It contains only the necessary parts of DWARF @@ -51,10 +53,18 @@ struct orc_entry { s16 sp_offset; s16 bp_offset; +#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned sp_reg:4; unsigned bp_reg:4; unsigned type:2; unsigned end:1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned bp_reg:4; + unsigned sp_reg:4; + unsigned unused:5; + unsigned end:1; + unsigned type:2; +#endif } __packed; #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h index 664d4610d700..8e574c0afef8 100644 --- a/arch/x86/include/asm/unwind_hints.h +++ b/arch/x86/include/asm/unwind_hints.h @@ -48,17 +48,8 @@ UNWIND_HINT_REGS base=\base offset=\offset partial=1 .endm -.macro UNWIND_HINT_FUNC sp_offset=8 - UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=\sp_offset type=UNWIND_HINT_TYPE_CALL -.endm - -/* - * RET_OFFSET: Used on instructions that terminate a function; mostly RETURN - * and sibling calls. On these, sp_offset denotes the expected offset from - * initial_func_cfi. - */ -.macro UNWIND_HINT_RET_OFFSET sp_offset=8 - UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_RET_OFFSET sp_offset=\sp_offset +.macro UNWIND_HINT_FUNC + UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC .endm #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile index f1bb57b0e41e..cf340d85946a 100644 --- a/arch/x86/kernel/acpi/Makefile +++ b/arch/x86/kernel/acpi/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -OBJECT_FILES_NON_STANDARD_wakeup_$(BITS).o := y obj-$(CONFIG_ACPI) += boot.o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 5d3a0b8fd379..56b6865afb2a 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -1,12 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0-only */ .text #include +#include #include #include #include #include #include #include +#include # Copyright 2003 Pavel Machek sp + orc->sp_offset; + sp = state->sp; indirect = true; break; @@ -521,6 +521,9 @@ bool unwind_next_frame(struct unwind_state *state) if (indirect) { if (!deref_stack_reg(state, sp, &sp)) goto err; + + if (orc->sp_reg == ORC_REG_SP_INDIRECT) + sp += orc->sp_offset; } /* Find IP, SP and possibly regs: */ diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c index 404279563891..435630a6ec97 100644 --- a/arch/x86/lib/insn.c +++ b/arch/x86/lib/insn.c @@ -5,6 +5,7 @@ * Copyright (C) IBM Corporation, 2002, 2004, 2009 */ +#include #ifdef __KERNEL__ #include #else @@ -15,15 +16,28 @@ #include +#define leXX_to_cpu(t, r) \ +({ \ + __typeof__(t) v; \ + switch (sizeof(t)) { \ + case 4: v = le32_to_cpu(r); break; \ + case 2: v = le16_to_cpu(r); break; \ + case 1: v = r; break; \ + default: \ + BUILD_BUG(); break; \ + } \ + v; \ +}) + /* Verify next sizeof(t) bytes can be on the same instruction */ #define validate_next(t, insn, n) \ ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) #define __get_next(t, insn) \ - ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) + ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); leXX_to_cpu(t, r); }) #define __peek_nbyte_next(t, insn, n) \ - ({ t r = *(t*)((insn)->next_byte + n); r; }) + ({ t r = *(t*)((insn)->next_byte + n); leXX_to_cpu(t, r); }) #define get_next(t, insn) \ ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) @@ -147,9 +161,9 @@ found: b = insn->prefixes.bytes[3]; for (i = 0; i < nb; i++) if (prefixes->bytes[i] == lb) - prefixes->bytes[i] = b; + insn_set_byte(prefixes, i, b); } - insn->prefixes.bytes[3] = lb; + insn_set_byte(&insn->prefixes, 3, lb); } /* Decode REX prefix */ @@ -157,8 +171,7 @@ found: b = peek_next(insn_byte_t, insn); attr = inat_get_opcode_attribute(b); if (inat_is_rex_prefix(attr)) { - insn->rex_prefix.value = b; - insn->rex_prefix.nbytes = 1; + insn_field_set(&insn->rex_prefix, b, 1); insn->next_byte++; if (X86_REX_W(b)) /* REX.W overrides opnd_size */ @@ -181,13 +194,13 @@ found: if (X86_MODRM_MOD(b2) != 3) goto vex_end; } - insn->vex_prefix.bytes[0] = b; - insn->vex_prefix.bytes[1] = b2; + insn_set_byte(&insn->vex_prefix, 0, b); + insn_set_byte(&insn->vex_prefix, 1, b2); if (inat_is_evex_prefix(attr)) { b2 = peek_nbyte_next(insn_byte_t, insn, 2); - insn->vex_prefix.bytes[2] = b2; + insn_set_byte(&insn->vex_prefix, 2, b2); b2 = peek_nbyte_next(insn_byte_t, insn, 3); - insn->vex_prefix.bytes[3] = b2; + insn_set_byte(&insn->vex_prefix, 3, b2); insn->vex_prefix.nbytes = 4; insn->next_byte += 4; if (insn->x86_64 && X86_VEX_W(b2)) @@ -195,7 +208,7 @@ found: insn->opnd_bytes = 8; } else if (inat_is_vex3_prefix(attr)) { b2 = peek_nbyte_next(insn_byte_t, insn, 2); - insn->vex_prefix.bytes[2] = b2; + insn_set_byte(&insn->vex_prefix, 2, b2); insn->vex_prefix.nbytes = 3; insn->next_byte += 3; if (insn->x86_64 && X86_VEX_W(b2)) @@ -207,7 +220,7 @@ found: * Makes it easier to decode vex.W, vex.vvvv, * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0. */ - insn->vex_prefix.bytes[2] = b2 & 0x7f; + insn_set_byte(&insn->vex_prefix, 2, b2 & 0x7f); insn->vex_prefix.nbytes = 2; insn->next_byte += 2; } @@ -243,7 +256,7 @@ void insn_get_opcode(struct insn *insn) /* Get first opcode */ op = get_next(insn_byte_t, insn); - opcode->bytes[0] = op; + insn_set_byte(opcode, 0, op); opcode->nbytes = 1; /* Check if there is VEX prefix or not */ @@ -295,8 +308,7 @@ void insn_get_modrm(struct insn *insn) if (inat_has_modrm(insn->attr)) { mod = get_next(insn_byte_t, insn); - modrm->value = mod; - modrm->nbytes = 1; + insn_field_set(modrm, mod, 1); if (inat_is_group(insn->attr)) { pfx_id = insn_last_prefix_id(insn); insn->attr = inat_get_group_attribute(mod, pfx_id, @@ -334,7 +346,7 @@ int insn_rip_relative(struct insn *insn) * For rip-relative instructions, the mod field (top 2 bits) * is zero and the r/m field (bottom 3 bits) is 0x5. */ - return (modrm->nbytes && (modrm->value & 0xc7) == 0x5); + return (modrm->nbytes && (modrm->bytes[0] & 0xc7) == 0x5); } /** @@ -353,11 +365,11 @@ void insn_get_sib(struct insn *insn) if (!insn->modrm.got) insn_get_modrm(insn); if (insn->modrm.nbytes) { - modrm = (insn_byte_t)insn->modrm.value; + modrm = insn->modrm.bytes[0]; if (insn->addr_bytes != 2 && X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) { - insn->sib.value = get_next(insn_byte_t, insn); - insn->sib.nbytes = 1; + insn_field_set(&insn->sib, + get_next(insn_byte_t, insn), 1); } } insn->sib.got = 1; @@ -407,19 +419,18 @@ void insn_get_displacement(struct insn *insn) if (mod == 3) goto out; if (mod == 1) { - insn->displacement.value = get_next(signed char, insn); - insn->displacement.nbytes = 1; + insn_field_set(&insn->displacement, + get_next(signed char, insn), 1); } else if (insn->addr_bytes == 2) { if ((mod == 0 && rm == 6) || mod == 2) { - insn->displacement.value = - get_next(short, insn); - insn->displacement.nbytes = 2; + insn_field_set(&insn->displacement, + get_next(short, insn), 2); } } else { if ((mod == 0 && rm == 5) || mod == 2 || (mod == 0 && base == 5)) { - insn->displacement.value = get_next(int, insn); - insn->displacement.nbytes = 4; + insn_field_set(&insn->displacement, + get_next(int, insn), 4); } } } @@ -435,18 +446,14 @@ static int __get_moffset(struct insn *insn) { switch (insn->addr_bytes) { case 2: - insn->moffset1.value = get_next(short, insn); - insn->moffset1.nbytes = 2; + insn_field_set(&insn->moffset1, get_next(short, insn), 2); break; case 4: - insn->moffset1.value = get_next(int, insn); - insn->moffset1.nbytes = 4; + insn_field_set(&insn->moffset1, get_next(int, insn), 4); break; case 8: - insn->moffset1.value = get_next(int, insn); - insn->moffset1.nbytes = 4; - insn->moffset2.value = get_next(int, insn); - insn->moffset2.nbytes = 4; + insn_field_set(&insn->moffset1, get_next(int, insn), 4); + insn_field_set(&insn->moffset2, get_next(int, insn), 4); break; default: /* opnd_bytes must be modified manually */ goto err_out; @@ -464,13 +471,11 @@ static int __get_immv32(struct insn *insn) { switch (insn->opnd_bytes) { case 2: - insn->immediate.value = get_next(short, insn); - insn->immediate.nbytes = 2; + insn_field_set(&insn->immediate, get_next(short, insn), 2); break; case 4: case 8: - insn->immediate.value = get_next(int, insn); - insn->immediate.nbytes = 4; + insn_field_set(&insn->immediate, get_next(int, insn), 4); break; default: /* opnd_bytes must be modified manually */ goto err_out; @@ -487,18 +492,15 @@ static int __get_immv(struct insn *insn) { switch (insn->opnd_bytes) { case 2: - insn->immediate1.value = get_next(short, insn); - insn->immediate1.nbytes = 2; + insn_field_set(&insn->immediate1, get_next(short, insn), 2); break; case 4: - insn->immediate1.value = get_next(int, insn); + insn_field_set(&insn->immediate1, get_next(int, insn), 4); insn->immediate1.nbytes = 4; break; case 8: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - insn->immediate2.value = get_next(int, insn); - insn->immediate2.nbytes = 4; + insn_field_set(&insn->immediate1, get_next(int, insn), 4); + insn_field_set(&insn->immediate2, get_next(int, insn), 4); break; default: /* opnd_bytes must be modified manually */ goto err_out; @@ -515,12 +517,10 @@ static int __get_immptr(struct insn *insn) { switch (insn->opnd_bytes) { case 2: - insn->immediate1.value = get_next(short, insn); - insn->immediate1.nbytes = 2; + insn_field_set(&insn->immediate1, get_next(short, insn), 2); break; case 4: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; + insn_field_set(&insn->immediate1, get_next(int, insn), 4); break; case 8: /* ptr16:64 is not exist (no segment) */ @@ -528,8 +528,7 @@ static int __get_immptr(struct insn *insn) default: /* opnd_bytes must be modified manually */ goto err_out; } - insn->immediate2.value = get_next(unsigned short, insn); - insn->immediate2.nbytes = 2; + insn_field_set(&insn->immediate2, get_next(unsigned short, insn), 2); insn->immediate1.got = insn->immediate2.got = 1; return 1; @@ -565,22 +564,17 @@ void insn_get_immediate(struct insn *insn) switch (inat_immediate_size(insn->attr)) { case INAT_IMM_BYTE: - insn->immediate.value = get_next(signed char, insn); - insn->immediate.nbytes = 1; + insn_field_set(&insn->immediate, get_next(signed char, insn), 1); break; case INAT_IMM_WORD: - insn->immediate.value = get_next(short, insn); - insn->immediate.nbytes = 2; + insn_field_set(&insn->immediate, get_next(short, insn), 2); break; case INAT_IMM_DWORD: - insn->immediate.value = get_next(int, insn); - insn->immediate.nbytes = 4; + insn_field_set(&insn->immediate, get_next(int, insn), 4); break; case INAT_IMM_QWORD: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - insn->immediate2.value = get_next(int, insn); - insn->immediate2.nbytes = 4; + insn_field_set(&insn->immediate1, get_next(int, insn), 4); + insn_field_set(&insn->immediate2, get_next(int, insn), 4); break; case INAT_IMM_PTR: if (!__get_immptr(insn)) @@ -599,8 +593,7 @@ void insn_get_immediate(struct insn *insn) goto err_out; } if (inat_has_second_immediate(insn->attr)) { - insn->immediate2.value = get_next(signed char, insn); - insn->immediate2.nbytes = 1; + insn_field_set(&insn->immediate2, get_next(signed char, insn), 1); } done: insn->immediate.got = 1; diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S index b4c43a9b1483..f6fb1d218dcc 100644 --- a/arch/x86/lib/retpoline.S +++ b/arch/x86/lib/retpoline.S @@ -28,7 +28,7 @@ SYM_FUNC_START_NOALIGN(__x86_retpoline_\reg) jmp .Lspec_trap_\@ .Ldo_rop_\@: mov %\reg, (%_ASM_SP) - UNWIND_HINT_RET_OFFSET + UNWIND_HINT_FUNC ret SYM_FUNC_END(__x86_retpoline_\reg) diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S index 43b4d864817e..d2ccadc247e6 100644 --- a/arch/x86/platform/pvh/head.S +++ b/arch/x86/platform/pvh/head.S @@ -16,6 +16,7 @@ #include #include #include +#include #include __HEAD @@ -105,6 +106,7 @@ SYM_CODE_START_LOCAL(pvh_start_xen) /* startup_64 expects boot_params in %rsi. */ mov $_pa(pvh_bootparams), %rsi mov $_pa(startup_64), %rax + ANNOTATE_RETPOLINE_SAFE jmp *%rax #else /* CONFIG_X86_64 */ diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile index 6907b523e856..3ff80156f21a 100644 --- a/arch/x86/power/Makefile +++ b/arch/x86/power/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -OBJECT_FILES_NON_STANDARD_hibernate_asm_$(BITS).o := y # __restore_processor_state() restores %gs after S3 resume and so should not # itself be stack-protected diff --git a/arch/x86/power/hibernate_asm_64.S b/arch/x86/power/hibernate_asm_64.S index 7918b8415f13..d9bed596d849 100644 --- a/arch/x86/power/hibernate_asm_64.S +++ b/arch/x86/power/hibernate_asm_64.S @@ -21,84 +21,7 @@ #include #include #include - -SYM_FUNC_START(swsusp_arch_suspend) - movq $saved_context, %rax - movq %rsp, pt_regs_sp(%rax) - movq %rbp, pt_regs_bp(%rax) - movq %rsi, pt_regs_si(%rax) - movq %rdi, pt_regs_di(%rax) - movq %rbx, pt_regs_bx(%rax) - movq %rcx, pt_regs_cx(%rax) - movq %rdx, pt_regs_dx(%rax) - movq %r8, pt_regs_r8(%rax) - movq %r9, pt_regs_r9(%rax) - movq %r10, pt_regs_r10(%rax) - movq %r11, pt_regs_r11(%rax) - movq %r12, pt_regs_r12(%rax) - movq %r13, pt_regs_r13(%rax) - movq %r14, pt_regs_r14(%rax) - movq %r15, pt_regs_r15(%rax) - pushfq - popq pt_regs_flags(%rax) - - /* save cr3 */ - movq %cr3, %rax - movq %rax, restore_cr3(%rip) - - FRAME_BEGIN - call swsusp_save - FRAME_END - ret -SYM_FUNC_END(swsusp_arch_suspend) - -SYM_CODE_START(restore_image) - /* prepare to jump to the image kernel */ - movq restore_jump_address(%rip), %r8 - movq restore_cr3(%rip), %r9 - - /* prepare to switch to temporary page tables */ - movq temp_pgt(%rip), %rax - movq mmu_cr4_features(%rip), %rbx - - /* prepare to copy image data to their original locations */ - movq restore_pblist(%rip), %rdx - - /* jump to relocated restore code */ - movq relocated_restore_code(%rip), %rcx - jmpq *%rcx -SYM_CODE_END(restore_image) - - /* code below has been relocated to a safe page */ -SYM_CODE_START(core_restore_code) - /* switch to temporary page tables */ - movq %rax, %cr3 - /* flush TLB */ - movq %rbx, %rcx - andq $~(X86_CR4_PGE), %rcx - movq %rcx, %cr4; # turn off PGE - movq %cr3, %rcx; # flush TLB - movq %rcx, %cr3; - movq %rbx, %cr4; # turn PGE back on -.Lloop: - testq %rdx, %rdx - jz .Ldone - - /* get addresses from the pbe and copy the page */ - movq pbe_address(%rdx), %rsi - movq pbe_orig_address(%rdx), %rdi - movq $(PAGE_SIZE >> 3), %rcx - rep - movsq - - /* progress to the next pbe */ - movq pbe_next(%rdx), %rdx - jmp .Lloop - -.Ldone: - /* jump to the restore_registers address from the image header */ - jmpq *%r8 -SYM_CODE_END(core_restore_code) +#include /* code below belongs to the image kernel */ .align PAGE_SIZE @@ -145,3 +68,83 @@ SYM_FUNC_START(restore_registers) ret SYM_FUNC_END(restore_registers) + +SYM_FUNC_START(swsusp_arch_suspend) + movq $saved_context, %rax + movq %rsp, pt_regs_sp(%rax) + movq %rbp, pt_regs_bp(%rax) + movq %rsi, pt_regs_si(%rax) + movq %rdi, pt_regs_di(%rax) + movq %rbx, pt_regs_bx(%rax) + movq %rcx, pt_regs_cx(%rax) + movq %rdx, pt_regs_dx(%rax) + movq %r8, pt_regs_r8(%rax) + movq %r9, pt_regs_r9(%rax) + movq %r10, pt_regs_r10(%rax) + movq %r11, pt_regs_r11(%rax) + movq %r12, pt_regs_r12(%rax) + movq %r13, pt_regs_r13(%rax) + movq %r14, pt_regs_r14(%rax) + movq %r15, pt_regs_r15(%rax) + pushfq + popq pt_regs_flags(%rax) + + /* save cr3 */ + movq %cr3, %rax + movq %rax, restore_cr3(%rip) + + FRAME_BEGIN + call swsusp_save + FRAME_END + ret +SYM_FUNC_END(swsusp_arch_suspend) + +SYM_FUNC_START(restore_image) + /* prepare to jump to the image kernel */ + movq restore_jump_address(%rip), %r8 + movq restore_cr3(%rip), %r9 + + /* prepare to switch to temporary page tables */ + movq temp_pgt(%rip), %rax + movq mmu_cr4_features(%rip), %rbx + + /* prepare to copy image data to their original locations */ + movq restore_pblist(%rip), %rdx + + /* jump to relocated restore code */ + movq relocated_restore_code(%rip), %rcx + ANNOTATE_RETPOLINE_SAFE + jmpq *%rcx +SYM_FUNC_END(restore_image) + + /* code below has been relocated to a safe page */ +SYM_FUNC_START(core_restore_code) + /* switch to temporary page tables */ + movq %rax, %cr3 + /* flush TLB */ + movq %rbx, %rcx + andq $~(X86_CR4_PGE), %rcx + movq %rcx, %cr4; # turn off PGE + movq %cr3, %rcx; # flush TLB + movq %rcx, %cr3; + movq %rbx, %cr4; # turn PGE back on +.Lloop: + testq %rdx, %rdx + jz .Ldone + + /* get addresses from the pbe and copy the page */ + movq pbe_address(%rdx), %rsi + movq pbe_orig_address(%rdx), %rdi + movq $(PAGE_SIZE >> 3), %rcx + rep + movsq + + /* progress to the next pbe */ + movq pbe_next(%rdx), %rdx + jmp .Lloop + +.Ldone: + /* jump to the restore_registers address from the image header */ + ANNOTATE_RETPOLINE_SAFE + jmpq *%r8 +SYM_FUNC_END(core_restore_code) diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile index 55b1ab378974..bddfc9a46645 100644 --- a/arch/x86/tools/Makefile +++ b/arch/x86/tools/Makefile @@ -29,14 +29,14 @@ posttest: $(obj)/insn_decoder_test vmlinux $(obj)/insn_sanity hostprogs += insn_decoder_test insn_sanity # -I needed for generated C source and C source which in the kernel tree. -HOSTCFLAGS_insn_decoder_test.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x86/include/uapi/ -I$(srctree)/arch/x86/include/ -I$(srctree)/arch/x86/lib/ -I$(srctree)/include/uapi/ +HOSTCFLAGS_insn_decoder_test.o := -Wall -I$(srctree)/tools/arch/x86/lib/ -I$(srctree)/tools/arch/x86/include/ -I$(objtree)/arch/x86/lib/ -HOSTCFLAGS_insn_sanity.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x86/include/ -I$(srctree)/arch/x86/lib/ -I$(srctree)/include/ +HOSTCFLAGS_insn_sanity.o := -Wall -I$(srctree)/tools/arch/x86/lib/ -I$(srctree)/tools/arch/x86/include/ -I$(objtree)/arch/x86/lib/ # Dependencies are also needed. -$(obj)/insn_decoder_test.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c +$(obj)/insn_decoder_test.o: $(srctree)/tools/arch/x86/lib/insn.c $(srctree)/tools/arch/x86/lib/inat.c $(srctree)/tools/arch/x86/include/asm/inat_types.h $(srctree)/tools/arch/x86/include/asm/inat.h $(srctree)/tools/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c -$(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c +$(obj)/insn_sanity.o: $(srctree)/tools/arch/x86/lib/insn.c $(srctree)/tools/arch/x86/lib/inat.c $(srctree)/tools/arch/x86/include/asm/inat_types.h $(srctree)/tools/arch/x86/include/asm/inat.h $(srctree)/tools/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c HOST_EXTRACFLAGS += -I$(srctree)/tools/include hostprogs += relocs diff --git a/arch/x86/tools/insn_sanity.c b/arch/x86/tools/insn_sanity.c index 185ceba9d289..c6a0000ae635 100644 --- a/arch/x86/tools/insn_sanity.c +++ b/arch/x86/tools/insn_sanity.c @@ -14,10 +14,6 @@ #include #include #include - -#define unlikely(cond) (cond) -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - #include #include #include diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c index 1c3a1962cade..04c5a44b9682 100644 --- a/arch/x86/tools/relocs.c +++ b/arch/x86/tools/relocs.c @@ -61,8 +61,8 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { "(__iommu_table|__apicdrivers|__smp_locks)(|_end)|" "__(start|end)_pci_.*|" "__(start|end)_builtin_fw|" - "__(start|stop)___ksymtab(|_gpl|_unused|_unused_gpl|_gpl_future)|" - "__(start|stop)___kcrctab(|_gpl|_unused|_unused_gpl|_gpl_future)|" + "__(start|stop)___ksymtab(|_gpl)|" + "__(start|stop)___kcrctab(|_gpl)|" "__(start|stop)___param|" "__(start|stop)___modver|" "__(start|stop)___bug_table|" diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index fc5c5ba4aacb..40b5779fce21 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -OBJECT_FILES_NON_STANDARD_xen-asm.o := y ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 02f31341e435..1e626444712b 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -118,6 +119,7 @@ SYM_FUNC_END(xen_read_cr2_direct); .macro xen_pv_trap name SYM_CODE_START(xen_\name) + UNWIND_HINT_EMPTY pop %rcx pop %r11 jmp \name @@ -157,6 +159,7 @@ xen_pv_trap asm_exc_xen_hypervisor_callback SYM_CODE_START(xen_early_idt_handler_array) i = 0 .rept NUM_EXCEPTION_VECTORS + UNWIND_HINT_EMPTY pop %rcx pop %r11 jmp early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE @@ -183,6 +186,7 @@ hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 * rsp->rax } */ SYM_CODE_START(xen_iret) + UNWIND_HINT_EMPTY pushq $0 jmp hypercall_iret SYM_CODE_END(xen_iret) @@ -203,7 +207,8 @@ SYM_CODE_END(xen_iret) */ /* Normal 64-bit system call target */ -SYM_FUNC_START(xen_syscall_target) +SYM_CODE_START(xen_syscall_target) + UNWIND_HINT_EMPTY popq %rcx popq %r11 @@ -216,12 +221,13 @@ SYM_FUNC_START(xen_syscall_target) movq $__USER_CS, 1*8(%rsp) jmp entry_SYSCALL_64_after_hwframe -SYM_FUNC_END(xen_syscall_target) +SYM_CODE_END(xen_syscall_target) #ifdef CONFIG_IA32_EMULATION /* 32-bit compat syscall target */ -SYM_FUNC_START(xen_syscall32_target) +SYM_CODE_START(xen_syscall32_target) + UNWIND_HINT_EMPTY popq %rcx popq %r11 @@ -234,10 +240,11 @@ SYM_FUNC_START(xen_syscall32_target) movq $__USER32_CS, 1*8(%rsp) jmp entry_SYSCALL_compat_after_hwframe -SYM_FUNC_END(xen_syscall32_target) +SYM_CODE_END(xen_syscall32_target) /* 32-bit compat sysenter target */ -SYM_FUNC_START(xen_sysenter_target) +SYM_CODE_START(xen_sysenter_target) + UNWIND_HINT_EMPTY /* * NB: Xen is polite and clears TF from EFLAGS for us. This means * that we don't need to guard against single step exceptions here. @@ -254,17 +261,18 @@ SYM_FUNC_START(xen_sysenter_target) movq $__USER32_CS, 1*8(%rsp) jmp entry_SYSENTER_compat_after_hwframe -SYM_FUNC_END(xen_sysenter_target) +SYM_CODE_END(xen_sysenter_target) #else /* !CONFIG_IA32_EMULATION */ -SYM_FUNC_START_ALIAS(xen_syscall32_target) -SYM_FUNC_START(xen_sysenter_target) +SYM_CODE_START(xen_syscall32_target) +SYM_CODE_START(xen_sysenter_target) + UNWIND_HINT_EMPTY lea 16(%rsp), %rsp /* strip %rcx, %r11 */ mov $-ENOSYS, %rax pushq $0 jmp hypercall_iret -SYM_FUNC_END(xen_sysenter_target) -SYM_FUNC_END_ALIAS(xen_syscall32_target) +SYM_CODE_END(xen_sysenter_target) +SYM_CODE_END(xen_syscall32_target) #endif /* CONFIG_IA32_EMULATION */ diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S index 2d7c8f34f56c..cb6538ae2fe0 100644 --- a/arch/x86/xen/xen-head.S +++ b/arch/x86/xen/xen-head.S @@ -68,8 +68,9 @@ SYM_CODE_END(asm_cpu_bringup_and_idle) .balign PAGE_SIZE SYM_CODE_START(hypercall_page) .rept (PAGE_SIZE / 32) - UNWIND_HINT_EMPTY - .skip 32 + UNWIND_HINT_FUNC + .skip 31, 0x90 + ret .endr #define HYPERCALL(n) \ diff --git a/drivers/char/ipmi/ipmb_dev_int.c b/drivers/char/ipmi/ipmb_dev_int.c index 382b28f1cf2f..49b8f22fdcf0 100644 --- a/drivers/char/ipmi/ipmb_dev_int.c +++ b/drivers/char/ipmi/ipmb_dev_int.c @@ -137,7 +137,7 @@ static ssize_t ipmb_write(struct file *file, const char __user *buf, { struct ipmb_dev *ipmb_dev = to_ipmb_dev(file); u8 rq_sa, netf_rq_lun, msg_len; - union i2c_smbus_data data; + struct i2c_client *temp_client; u8 msg[MAX_MSG_LEN]; ssize_t ret; @@ -160,21 +160,21 @@ static ssize_t ipmb_write(struct file *file, const char __user *buf, } /* - * subtract rq_sa and netf_rq_lun from the length of the msg passed to - * i2c_smbus_xfer + * subtract rq_sa and netf_rq_lun from the length of the msg. Fill the + * temporary client. Note that its use is an exception for IPMI. */ msg_len = msg[IPMB_MSG_LEN_IDX] - SMBUS_MSG_HEADER_LENGTH; - if (msg_len > I2C_SMBUS_BLOCK_MAX) - msg_len = I2C_SMBUS_BLOCK_MAX; + temp_client = kmemdup(ipmb_dev->client, sizeof(*temp_client), GFP_KERNEL); + if (!temp_client) + return -ENOMEM; - data.block[0] = msg_len; - memcpy(&data.block[1], msg + SMBUS_MSG_IDX_OFFSET, msg_len); - ret = i2c_smbus_xfer(ipmb_dev->client->adapter, rq_sa, - ipmb_dev->client->flags, - I2C_SMBUS_WRITE, netf_rq_lun, - I2C_SMBUS_BLOCK_DATA, &data); + temp_client->addr = rq_sa; - return ret ? : count; + ret = i2c_smbus_write_block_data(temp_client, netf_rq_lun, msg_len, + msg + SMBUS_MSG_IDX_OFFSET); + kfree(temp_client); + + return ret < 0 ? ret : count; } static __poll_t ipmb_poll(struct file *file, poll_table *wait) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 887ffca3f47f..869b9f5e8e03 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -31,9 +31,6 @@ #include #include #include -#include -#include -#include #ifdef CONFIG_IA64 # include @@ -829,42 +826,6 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig) return ret; } -static struct inode *devmem_inode; - -#ifdef CONFIG_IO_STRICT_DEVMEM -void revoke_devmem(struct resource *res) -{ - /* pairs with smp_store_release() in devmem_init_inode() */ - struct inode *inode = smp_load_acquire(&devmem_inode); - - /* - * Check that the initialization has completed. Losing the race - * is ok because it means drivers are claiming resources before - * the fs_initcall level of init and prevent /dev/mem from - * establishing mappings. - */ - if (!inode) - return; - - /* - * The expectation is that the driver has successfully marked - * the resource busy by this point, so devmem_is_allowed() - * should start returning false, however for performance this - * does not iterate the entire resource range. - */ - if (devmem_is_allowed(PHYS_PFN(res->start)) && - devmem_is_allowed(PHYS_PFN(res->end))) { - /* - * *cringe* iomem=relaxed says "go ahead, what's the - * worst that can happen?" - */ - return; - } - - unmap_mapping_range(inode->i_mapping, res->start, resource_size(res), 1); -} -#endif - static int open_port(struct inode *inode, struct file *filp) { int rc; @@ -884,8 +845,7 @@ static int open_port(struct inode *inode, struct file *filp) * revocations when drivers want to take over a /dev/mem mapped * range. */ - inode->i_mapping = devmem_inode->i_mapping; - filp->f_mapping = inode->i_mapping; + filp->f_mapping = iomem_get_mapping(); return 0; } @@ -1017,48 +977,6 @@ static char *mem_devnode(struct device *dev, umode_t *mode) static struct class *mem_class; -static int devmem_fs_init_fs_context(struct fs_context *fc) -{ - return init_pseudo(fc, DEVMEM_MAGIC) ? 0 : -ENOMEM; -} - -static struct file_system_type devmem_fs_type = { - .name = "devmem", - .owner = THIS_MODULE, - .init_fs_context = devmem_fs_init_fs_context, - .kill_sb = kill_anon_super, -}; - -static int devmem_init_inode(void) -{ - static struct vfsmount *devmem_vfs_mount; - static int devmem_fs_cnt; - struct inode *inode; - int rc; - - rc = simple_pin_fs(&devmem_fs_type, &devmem_vfs_mount, &devmem_fs_cnt); - if (rc < 0) { - pr_err("Cannot mount /dev/mem pseudo filesystem: %d\n", rc); - return rc; - } - - inode = alloc_anon_inode(devmem_vfs_mount->mnt_sb); - if (IS_ERR(inode)) { - rc = PTR_ERR(inode); - pr_err("Cannot allocate inode for /dev/mem: %d\n", rc); - simple_release_fs(&devmem_vfs_mount, &devmem_fs_cnt); - return rc; - } - - /* - * Publish /dev/mem initialized. - * Pairs with smp_load_acquire() in revoke_devmem(). - */ - smp_store_release(&devmem_inode, inode); - - return 0; -} - static int __init chr_dev_init(void) { int minor; @@ -1080,8 +998,6 @@ static int __init chr_dev_init(void) */ if ((minor == DEVPORT_MINOR) && !arch_has_dev_port()) continue; - if ((minor == DEVMEM_MINOR) && devmem_init_inode() != 0) - continue; device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor), NULL, devlist[minor].name); diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 8a94388e38b3..c23466e05e60 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -38,6 +38,8 @@ KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ # remove SCS flags from all objects in this directory KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS)) +# disable LTO +KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS)) GCOV_PROFILE := n # Sanitizer runtimes are unavailable and cannot be linked here. diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 8bf103de1594..e392a90ca687 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -15,6 +15,9 @@ menuconfig DRM select I2C_ALGOBIT select DMA_SHARED_BUFFER select SYNC_FILE +# gallium uses SYS_kcmp for os_same_file_description() to de-duplicate +# device and dmabuf fd. Let's make sure that is available for our userspace. + select KCMP help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select diff --git a/drivers/gpu/drm/drm_crtc_helper_internal.h b/drivers/gpu/drm/drm_crtc_helper_internal.h index 25ce42e79995..61e09f8a8d0f 100644 --- a/drivers/gpu/drm/drm_crtc_helper_internal.h +++ b/drivers/gpu/drm/drm_crtc_helper_internal.h @@ -32,16 +32,6 @@ #include #include -/* drm_fb_helper.c */ -#ifdef CONFIG_DRM_FBDEV_EMULATION -int drm_fb_helper_modinit(void); -#else -static inline int drm_fb_helper_modinit(void) -{ - return 0; -} -#endif - /* drm_dp_aux_dev.c */ #ifdef CONFIG_DRM_DP_AUX_CHARDEV int drm_dp_aux_dev_init(void); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index a44c3a438059..b9a616737c0e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2514,24 +2514,3 @@ void drm_fbdev_generic_setup(struct drm_device *dev, drm_client_register(&fb_helper->client); } EXPORT_SYMBOL(drm_fbdev_generic_setup); - -/* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT) - * but the module doesn't depend on any fb console symbols. At least - * attempt to load fbcon to avoid leaving the system without a usable console. - */ -int __init drm_fb_helper_modinit(void) -{ -#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT) - const char name[] = "fbcon"; - struct module *fbcon; - - mutex_lock(&module_mutex); - fbcon = find_module(name); - mutex_unlock(&module_mutex); - - if (!fbcon) - request_module_nowait(name); -#endif - return 0; -} -EXPORT_SYMBOL(drm_fb_helper_modinit); diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c index 221a8528c993..f933da1656eb 100644 --- a/drivers/gpu/drm/drm_kms_helper_common.c +++ b/drivers/gpu/drm/drm_kms_helper_common.c @@ -64,19 +64,18 @@ MODULE_PARM_DESC(edid_firmware, static int __init drm_kms_helper_init(void) { - int ret; + /* + * The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT) + * but the module doesn't depend on any fb console symbols. At least + * attempt to load fbcon to avoid leaving the system without a usable + * console. + */ + if (IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) && + IS_MODULE(CONFIG_FRAMEBUFFER_CONSOLE) && + !IS_ENABLED(CONFIG_EXPERT)) + request_module_nowait("fbcon"); - /* Call init functions from specific kms helpers here */ - ret = drm_fb_helper_modinit(); - if (ret < 0) - goto out; - - ret = drm_dp_aux_dev_init(); - if (ret < 0) - goto out; - -out: - return ret; + return drm_dp_aux_dev_init(); } static void __exit drm_kms_helper_exit(void) diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 951d5f708e92..6a251e3aa779 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -89,7 +89,6 @@ comment "Sub-drivers" config DRM_EXYNOS_G2D bool "G2D" depends on VIDEO_SAMSUNG_S5P_G2D=n || COMPILE_TEST - select FRAME_VECTOR help Choose this option if you want to use Exynos G2D for DRM. diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 967a5cdc120e..1e0c5a7f206e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -205,7 +205,8 @@ struct g2d_cmdlist_userptr { dma_addr_t dma_addr; unsigned long userptr; unsigned long size; - struct frame_vector *vec; + struct page **pages; + unsigned int npages; struct sg_table *sgt; atomic_t refcount; bool in_pool; @@ -378,7 +379,6 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d, bool force) { struct g2d_cmdlist_userptr *g2d_userptr = obj; - struct page **pages; if (!obj) return; @@ -398,15 +398,9 @@ out: dma_unmap_sgtable(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt, DMA_BIDIRECTIONAL, 0); - pages = frame_vector_pages(g2d_userptr->vec); - if (!IS_ERR(pages)) { - int i; - - for (i = 0; i < frame_vector_count(g2d_userptr->vec); i++) - set_page_dirty_lock(pages[i]); - } - put_vaddr_frames(g2d_userptr->vec); - frame_vector_destroy(g2d_userptr->vec); + unpin_user_pages_dirty_lock(g2d_userptr->pages, g2d_userptr->npages, + true); + kvfree(g2d_userptr->pages); if (!g2d_userptr->out_of_list) list_del_init(&g2d_userptr->list); @@ -474,35 +468,35 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, offset = userptr & ~PAGE_MASK; end = PAGE_ALIGN(userptr + size); npages = (end - start) >> PAGE_SHIFT; - g2d_userptr->vec = frame_vector_create(npages); - if (!g2d_userptr->vec) { + g2d_userptr->pages = kvmalloc_array(npages, sizeof(*g2d_userptr->pages), + GFP_KERNEL); + if (!g2d_userptr->pages) { ret = -ENOMEM; goto err_free; } - ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE, - g2d_userptr->vec); + ret = pin_user_pages_fast(start, npages, + FOLL_FORCE | FOLL_WRITE | FOLL_LONGTERM, + g2d_userptr->pages); if (ret != npages) { DRM_DEV_ERROR(g2d->dev, "failed to get user pages from userptr.\n"); if (ret < 0) - goto err_destroy_framevec; + goto err_destroy_pages; + npages = ret; ret = -EFAULT; - goto err_put_framevec; - } - if (frame_vector_to_pages(g2d_userptr->vec) < 0) { - ret = -EFAULT; - goto err_put_framevec; + goto err_unpin_pages; } + g2d_userptr->npages = npages; sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) { ret = -ENOMEM; - goto err_put_framevec; + goto err_unpin_pages; } ret = sg_alloc_table_from_pages(sgt, - frame_vector_pages(g2d_userptr->vec), + g2d_userptr->pages, npages, offset, size, GFP_KERNEL); if (ret < 0) { DRM_DEV_ERROR(g2d->dev, "failed to get sgt from pages.\n"); @@ -538,11 +532,11 @@ err_sg_free_table: err_free_sgt: kfree(sgt); -err_put_framevec: - put_vaddr_frames(g2d_userptr->vec); +err_unpin_pages: + unpin_user_pages(g2d_userptr->pages, npages); -err_destroy_framevec: - frame_vector_destroy(g2d_userptr->vec); +err_destroy_pages: + kvfree(g2d_userptr->pages); err_free: kfree(g2d_userptr); diff --git a/drivers/media/common/videobuf2/Kconfig b/drivers/media/common/videobuf2/Kconfig index edbc99ebba87..d2223a12c95f 100644 --- a/drivers/media/common/videobuf2/Kconfig +++ b/drivers/media/common/videobuf2/Kconfig @@ -9,7 +9,6 @@ config VIDEOBUF2_V4L2 config VIDEOBUF2_MEMOPS tristate - select FRAME_VECTOR config VIDEOBUF2_DMA_CONTIG tristate diff --git a/drivers/media/common/videobuf2/Makefile b/drivers/media/common/videobuf2/Makefile index 77bebe8b202f..54306f8d096c 100644 --- a/drivers/media/common/videobuf2/Makefile +++ b/drivers/media/common/videobuf2/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 videobuf2-common-objs := videobuf2-core.o +videobuf2-common-objs += frame_vector.o ifeq ($(CONFIG_TRACEPOINTS),y) videobuf2-common-objs += vb2-trace.o diff --git a/mm/frame_vector.c b/drivers/media/common/videobuf2/frame_vector.c similarity index 85% rename from mm/frame_vector.c rename to drivers/media/common/videobuf2/frame_vector.c index 10f82d5643b6..a0e65481a201 100644 --- a/mm/frame_vector.c +++ b/drivers/media/common/videobuf2/frame_vector.c @@ -8,6 +8,8 @@ #include #include +#include + /** * get_vaddr_frames() - map virtual addresses to pfns * @start: starting user address @@ -32,13 +34,12 @@ * This function takes care of grabbing mmap_lock as necessary. */ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, - unsigned int gup_flags, struct frame_vector *vec) + struct frame_vector *vec) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; int ret = 0; int err; - int locked; if (nr_frames == 0) return 0; @@ -48,40 +49,26 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, start = untagged_addr(start); - mmap_read_lock(mm); - locked = 1; - vma = find_vma_intersection(mm, start, start + 1); - if (!vma) { - ret = -EFAULT; - goto out; - } - - /* - * While get_vaddr_frames() could be used for transient (kernel - * controlled lifetime) pinning of memory pages all current - * users establish long term (userspace controlled lifetime) - * page pinning. Treat get_vaddr_frames() like - * get_user_pages_longterm() and disallow it for filesystem-dax - * mappings. - */ - if (vma_is_fsdax(vma)) { - ret = -EOPNOTSUPP; - goto out; - } - - if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) { + ret = pin_user_pages_fast(start, nr_frames, + FOLL_FORCE | FOLL_WRITE | FOLL_LONGTERM, + (struct page **)(vec->ptrs)); + if (ret > 0) { vec->got_ref = true; vec->is_pfns = false; - ret = pin_user_pages_locked(start, nr_frames, - gup_flags, (struct page **)(vec->ptrs), &locked); - goto out; + goto out_unlocked; } + mmap_read_lock(mm); vec->got_ref = false; vec->is_pfns = true; + ret = 0; do { unsigned long *nums = frame_vector_pfns(vec); + vma = find_vma_intersection(mm, start, start + 1); + if (!vma) + break; + while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) { err = follow_pfn(vma, start, &nums[ret]); if (err) { @@ -92,17 +79,13 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, start += PAGE_SIZE; ret++; } - /* - * We stop if we have enough pages or if VMA doesn't completely - * cover the tail page. - */ - if (ret >= nr_frames || start < vma->vm_end) + /* Bail out if VMA doesn't completely cover the tail page. */ + if (start < vma->vm_end) break; - vma = find_vma_intersection(mm, start, start + 1); - } while (vma && vma->vm_flags & (VM_IO | VM_PFNMAP)); + } while (ret < nr_frames); out: - if (locked) - mmap_read_unlock(mm); + mmap_read_unlock(mm); +out_unlocked: if (!ret) ret = -EFAULT; if (ret > 0) diff --git a/drivers/media/common/videobuf2/videobuf2-memops.c b/drivers/media/common/videobuf2/videobuf2-memops.c index 6e9e05153f4e..9dd6c27162f4 100644 --- a/drivers/media/common/videobuf2/videobuf2-memops.c +++ b/drivers/media/common/videobuf2/videobuf2-memops.c @@ -40,7 +40,6 @@ struct frame_vector *vb2_create_framevec(unsigned long start, unsigned long first, last; unsigned long nr; struct frame_vector *vec; - unsigned int flags = FOLL_FORCE | FOLL_WRITE; first = start >> PAGE_SHIFT; last = (start + length - 1) >> PAGE_SHIFT; @@ -48,7 +47,7 @@ struct frame_vector *vb2_create_framevec(unsigned long start, vec = frame_vector_create(nr); if (!vec) return ERR_PTR(-ENOMEM); - ret = get_vaddr_frames(start & PAGE_MASK, nr, flags, vec); + ret = get_vaddr_frames(start & PAGE_MASK, nr, vec); if (ret < 0) goto out_destroy; /* We accept only complete set of PFNs */ diff --git a/drivers/media/platform/omap/Kconfig b/drivers/media/platform/omap/Kconfig index f73b5893220d..de16de46c0f4 100644 --- a/drivers/media/platform/omap/Kconfig +++ b/drivers/media/platform/omap/Kconfig @@ -12,6 +12,5 @@ config VIDEO_OMAP2_VOUT depends on VIDEO_V4L2 select VIDEOBUF2_DMA_CONTIG select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 - select FRAME_VECTOR help V4L2 Display driver support for OMAP2/3 based boards. diff --git a/drivers/misc/cxl/cxllib.c b/drivers/misc/cxl/cxllib.c index 2a1783f32254..53b919856426 100644 --- a/drivers/misc/cxl/cxllib.c +++ b/drivers/misc/cxl/cxllib.c @@ -170,8 +170,6 @@ int cxllib_get_PE_attributes(struct task_struct *task, unsigned long translation_mode, struct cxllib_pe_attributes *attr) { - struct mm_struct *mm = NULL; - if (translation_mode != CXL_TRANSLATED_MODE && translation_mode != CXL_REAL_MODE) return -EINVAL; @@ -182,7 +180,7 @@ int cxllib_get_PE_attributes(struct task_struct *task, true); attr->lpid = mfspr(SPRN_LPID); if (task) { - mm = get_task_mm(task); + struct mm_struct *mm = get_task_mm(task); if (mm == NULL) return -EINVAL; /* diff --git a/drivers/misc/habanalabs/Kconfig b/drivers/misc/habanalabs/Kconfig index 1640340d3e62..293d79811372 100644 --- a/drivers/misc/habanalabs/Kconfig +++ b/drivers/misc/habanalabs/Kconfig @@ -6,7 +6,6 @@ config HABANA_AI tristate "HabanaAI accelerators (habanalabs)" depends on PCI && HAS_IOMEM - select FRAME_VECTOR select GENERIC_ALLOCATOR select HWMON help diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 60e16dc4bcac..41af347157e0 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -1089,7 +1089,8 @@ struct hl_ctx_mgr { * struct hl_userptr - memory mapping chunk information * @vm_type: type of the VM. * @job_node: linked-list node for hanging the object on the Job's list. - * @vec: pointer to the frame vector. + * @pages: pointer to struct page array + * @npages: size of @pages array * @sgt: pointer to the scatter-gather table that holds the pages. * @dir: for DMA unmapping, the direction must be supplied, so save it. * @debugfs_list: node in debugfs list of command submissions. @@ -1100,7 +1101,8 @@ struct hl_ctx_mgr { struct hl_userptr { enum vm_type_t vm_type; /* must be first */ struct list_head job_node; - struct frame_vector *vec; + struct page **pages; + unsigned int npages; struct sg_table *sgt; enum dma_data_direction dir; struct list_head debugfs_list; diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c index 5d4fbdcaefe3..245c0159159f 100644 --- a/drivers/misc/habanalabs/common/memory.c +++ b/drivers/misc/habanalabs/common/memory.c @@ -1436,45 +1436,40 @@ static int get_user_memory(struct hl_device *hdev, u64 addr, u64 size, return -EFAULT; } - userptr->vec = frame_vector_create(npages); - if (!userptr->vec) { - dev_err(hdev->dev, "Failed to create frame vector\n"); + userptr->pages = kvmalloc_array(npages, sizeof(*userptr->pages), + GFP_KERNEL); + if (!userptr->pages) return -ENOMEM; - } - rc = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE, - userptr->vec); + rc = pin_user_pages_fast(start, npages, + FOLL_FORCE | FOLL_WRITE | FOLL_LONGTERM, + userptr->pages); if (rc != npages) { dev_err(hdev->dev, "Failed to map host memory, user ptr probably wrong\n"); if (rc < 0) - goto destroy_framevec; + goto destroy_pages; + npages = rc; rc = -EFAULT; - goto put_framevec; - } - - if (frame_vector_to_pages(userptr->vec) < 0) { - dev_err(hdev->dev, - "Failed to translate frame vector to pages\n"); - rc = -EFAULT; - goto put_framevec; + goto put_pages; } + userptr->npages = npages; rc = sg_alloc_table_from_pages(userptr->sgt, - frame_vector_pages(userptr->vec), - npages, offset, size, GFP_ATOMIC); + userptr->pages, + npages, offset, size, GFP_ATOMIC); if (rc < 0) { dev_err(hdev->dev, "failed to create SG table from pages\n"); - goto put_framevec; + goto put_pages; } return 0; -put_framevec: - put_vaddr_frames(userptr->vec); -destroy_framevec: - frame_vector_destroy(userptr->vec); +put_pages: + unpin_user_pages(userptr->pages, npages); +destroy_pages: + kvfree(userptr->pages); return rc; } @@ -1560,8 +1555,6 @@ free_sgt: */ void hl_unpin_host_memory(struct hl_device *hdev, struct hl_userptr *userptr) { - struct page **pages; - hl_debugfs_remove_userptr(hdev, userptr); if (userptr->dma_mapped) @@ -1569,15 +1562,8 @@ void hl_unpin_host_memory(struct hl_device *hdev, struct hl_userptr *userptr) userptr->sgt->nents, userptr->dir); - pages = frame_vector_pages(userptr->vec); - if (!IS_ERR(pages)) { - int i; - - for (i = 0; i < frame_vector_count(userptr->vec); i++) - set_page_dirty_lock(pages[i]); - } - put_vaddr_frames(userptr->vec); - frame_vector_destroy(userptr->vec); + unpin_user_pages_dirty_lock(userptr->pages, userptr->npages, true); + kvfree(userptr->pages); list_del(&userptr->job_node); diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile index 6b888d04392d..aa12097668d3 100644 --- a/drivers/misc/lkdtm/Makefile +++ b/drivers/misc/lkdtm/Makefile @@ -16,6 +16,7 @@ lkdtm-$(CONFIG_PPC_BOOK3S_64) += powerpc.o KASAN_SANITIZE_rodata.o := n KASAN_SANITIZE_stackleak.o := n KCOV_INSTRUMENT_rodata.o := n +CFLAGS_REMOVE_rodata.o += $(CC_FLAGS_LTO) OBJCOPYFLAGS := OBJCOPYFLAGS_rodata_objcopy.o := \ diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index 4d1b44de1492..e70525eedaae 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -15,7 +15,7 @@ static dev_t ocxl_dev; static struct class *ocxl_class; -static struct mutex minors_idr_lock; +static DEFINE_MUTEX(minors_idr_lock); static struct idr minors_idr; static struct ocxl_file_info *find_and_get_file_info(dev_t devno) @@ -588,7 +588,6 @@ int ocxl_file_init(void) { int rc; - mutex_init(&minors_idr_lock); idr_init(&minors_idr); rc = alloc_chrdev_region(&ocxl_dev, 0, OCXL_NUM_MINORS, "ocxl"); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index fb072f4b3176..f8afd54ca3e1 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -927,6 +927,9 @@ void pci_create_legacy_files(struct pci_bus *b) { int error; + if (!sysfs_initialized) + return; + b->legacy_io = kcalloc(2, sizeof(struct bin_attribute), GFP_ATOMIC); if (!b->legacy_io) @@ -939,6 +942,7 @@ void pci_create_legacy_files(struct pci_bus *b) b->legacy_io->read = pci_read_legacy_io; b->legacy_io->write = pci_write_legacy_io; b->legacy_io->mmap = pci_mmap_legacy_io; + b->legacy_io->mapping = iomem_get_mapping(); pci_adjust_legacy_attr(b, pci_mmap_io); error = device_create_bin_file(&b->dev, b->legacy_io); if (error) @@ -951,6 +955,7 @@ void pci_create_legacy_files(struct pci_bus *b) b->legacy_mem->size = 1024*1024; b->legacy_mem->attr.mode = 0600; b->legacy_mem->mmap = pci_mmap_legacy_mem; + b->legacy_io->mapping = iomem_get_mapping(); pci_adjust_legacy_attr(b, pci_mmap_mem); error = device_create_bin_file(&b->dev, b->legacy_mem); if (error) @@ -1166,6 +1171,8 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) res_attr->mmap = pci_mmap_resource_uc; } } + if (res_attr->mmap) + res_attr->mapping = iomem_get_mapping(); res_attr->attr.name = res_attr_name; res_attr->attr.mode = 0600; res_attr->size = pci_resource_len(pdev, num); @@ -1448,6 +1455,7 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) static int __init pci_sysfs_init(void) { struct pci_dev *pdev = NULL; + struct pci_bus *pbus = NULL; int retval; sysfs_initialized = 1; @@ -1459,6 +1467,9 @@ static int __init pci_sysfs_init(void) } } + while ((pbus = pci_find_next_bus(pbus))) + pci_create_legacy_files(pbus); + return 0; } late_initcall(pci_sysfs_init); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index d35186b01d98..9bab07302bbf 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -274,6 +274,11 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) else return -EINVAL; } + + if (dev->resource[i].flags & IORESOURCE_MEM && + iomem_is_exclusive(dev->resource[i].start)) + return -EINVAL; + ret = pci_mmap_page_range(dev, i, vma, fpriv->mmap_state, write_combine); if (ret < 0) @@ -293,6 +298,7 @@ static int proc_bus_pci_open(struct inode *inode, struct file *file) fpriv->write_combine = 0; file->private_data = fpriv; + file->f_mapping = iomem_get_mapping(); return 0; } diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d4b2f2e2ed75..03c62e1cb395 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -226,14 +226,6 @@ config PINCTRL_SINGLE help This selects the device tree based generic pinctrl driver. -config PINCTRL_SIRF - bool "CSR SiRFprimaII pin controller driver" - depends on ARCH_SIRF - select PINMUX - select PINCONF - select GENERIC_PINCONF - select GPIOLIB_IRQCHIP - config PINCTRL_SX150X bool "Semtech SX150x I2C GPIO expander pinctrl driver" depends on I2C=y @@ -279,22 +271,6 @@ config PINCTRL_STMFX and configuring push-pull, open-drain, and can also be used as interrupt-controller. -config PINCTRL_U300 - bool "U300 pin controller driver" - depends on ARCH_U300 - select PINMUX - select GENERIC_PINCONF - -config PINCTRL_COH901 - bool "ST-Ericsson U300 COH 901 335/571 GPIO" - depends on GPIOLIB && ARCH_U300 && PINCTRL_U300 - select GPIOLIB_IRQCHIP - help - Say yes here to support GPIO interface on ST-Ericsson U300. - The names of the two IP block variants supported are - COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 - ports of 8 GPIO pins each. - config PINCTRL_MAX77620 tristate "MAX77620/MAX20024 Pincontrol support" depends on MFD_MAX77620 && OF @@ -417,7 +393,6 @@ source "drivers/pinctrl/ti/Kconfig" source "drivers/pinctrl/uniphier/Kconfig" source "drivers/pinctrl/vt8500/Kconfig" source "drivers/pinctrl/mediatek/Kconfig" -source "drivers/pinctrl/zte/Kconfig" source "drivers/pinctrl/meson/Kconfig" source "drivers/pinctrl/cirrus/Kconfig" source "drivers/pinctrl/visconti/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 5bb9bb6cc3ce..efc96f25c8db 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -31,11 +31,8 @@ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o -obj-$(CONFIG_PINCTRL_SIRF) += sirf/ obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o obj-$(CONFIG_ARCH_TEGRA) += tegra/ -obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o -obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o obj-$(CONFIG_PINCTRL_LPC18XX) += pinctrl-lpc18xx.o @@ -71,6 +68,5 @@ obj-y += ti/ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/ obj-$(CONFIG_ARCH_VT8500) += vt8500/ obj-y += mediatek/ -obj-$(CONFIG_PINCTRL_ZX) += zte/ obj-y += cirrus/ obj-$(CONFIG_PINCTRL_VISCONTI) += visconti/ diff --git a/drivers/pinctrl/actions/Kconfig b/drivers/pinctrl/actions/Kconfig index a1d16e8280e5..119f0e471efd 100644 --- a/drivers/pinctrl/actions/Kconfig +++ b/drivers/pinctrl/actions/Kconfig @@ -12,18 +12,21 @@ config PINCTRL_OWL config PINCTRL_S500 bool "Actions Semi S500 pinctrl driver" + depends on ARM || COMPILE_TEST depends on PINCTRL_OWL help Say Y here to enable Actions Semi S500 pinctrl driver config PINCTRL_S700 bool "Actions Semi S700 pinctrl driver" + depends on ARM64 || COMPILE_TEST depends on PINCTRL_OWL help Say Y here to enable Actions Semi S700 pinctrl driver config PINCTRL_S900 bool "Actions Semi S900 pinctrl driver" + depends on ARM64 || COMPILE_TEST depends on PINCTRL_OWL help Say Y here to enable Actions Semi S900 pinctrl driver diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c index 903a4baf3846..c8b3e396ea27 100644 --- a/drivers/pinctrl/actions/pinctrl-owl.c +++ b/drivers/pinctrl/actions/pinctrl-owl.c @@ -444,7 +444,6 @@ static int owl_group_config_get(struct pinctrl_dev *pctrldev, *config = pinconf_to_config_packed(param, arg); return ret; - } static int owl_group_config_set(struct pinctrl_dev *pctrldev, diff --git a/drivers/pinctrl/bcm/pinctrl-ns2-mux.c b/drivers/pinctrl/bcm/pinctrl-ns2-mux.c index 57044ab376d3..0fe4a1fcdf00 100644 --- a/drivers/pinctrl/bcm/pinctrl-ns2-mux.c +++ b/drivers/pinctrl/bcm/pinctrl-ns2-mux.c @@ -853,7 +853,7 @@ static int ns2_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, switch (param) { case PIN_CONFIG_BIAS_DISABLE: ns2_pin_get_pull(pctldev, pin, &pull_up, &pull_down); - if ((pull_up == false) && (pull_down == false)) + if (!pull_up && !pull_down) return 0; else return -EINVAL; diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 9fc4433fece4..7d3370289938 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -2117,7 +2117,6 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, return ERR_PTR(error); return pctldev; - } EXPORT_SYMBOL_GPL(pinctrl_register); diff --git a/drivers/pinctrl/freescale/pinctrl-imx1-core.c b/drivers/pinctrl/freescale/pinctrl-imx1-core.c index 08d110078c43..70186448d2f4 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx1-core.c +++ b/drivers/pinctrl/freescale/pinctrl-imx1-core.c @@ -290,7 +290,6 @@ static const struct pinctrl_ops imx1_pctrl_ops = { .pin_dbg_show = imx1_pin_dbg_show, .dt_node_to_map = imx1_dt_node_to_map, .dt_free_map = imx1_dt_free_map, - }; static int imx1_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index b6ef1911c1dd..8085782cd8f9 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -29,6 +29,16 @@ #define REVID_SHIFT 16 #define REVID_MASK GENMASK(31, 16) +#define CAPLIST 0x004 +#define CAPLIST_ID_SHIFT 16 +#define CAPLIST_ID_MASK GENMASK(23, 16) +#define CAPLIST_ID_GPIO_HW_INFO 1 +#define CAPLIST_ID_PWM 2 +#define CAPLIST_ID_BLINK 3 +#define CAPLIST_ID_EXP 4 +#define CAPLIST_NEXT_SHIFT 0 +#define CAPLIST_NEXT_MASK GENMASK(15, 0) + #define PADBAR 0x00c #define PADOWN_BITS 4 @@ -1321,34 +1331,19 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) return 0; } -static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl, - struct intel_community *community) +static int intel_pinctrl_add_padgroups_by_gpps(struct intel_pinctrl *pctrl, + struct intel_community *community) { struct intel_padgroup *gpps; - unsigned int npins = community->npins; unsigned int padown_num = 0; - size_t ngpps, i; - - if (community->gpps) - ngpps = community->ngpps; - else - ngpps = DIV_ROUND_UP(community->npins, community->gpp_size); + size_t i, ngpps = community->ngpps; gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL); if (!gpps) return -ENOMEM; for (i = 0; i < ngpps; i++) { - if (community->gpps) { - gpps[i] = community->gpps[i]; - } else { - unsigned int gpp_size = community->gpp_size; - - gpps[i].reg_num = i; - gpps[i].base = community->pin_base + i * gpp_size; - gpps[i].size = min(gpp_size, npins); - npins -= gpps[i].size; - } + gpps[i] = community->gpps[i]; if (gpps[i].size > 32) return -EINVAL; @@ -1366,6 +1361,38 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl, break; } + gpps[i].padown_num = padown_num; + padown_num += DIV_ROUND_UP(gpps[i].size * 4, 32); + } + + community->gpps = gpps; + + return 0; +} + +static int intel_pinctrl_add_padgroups_by_size(struct intel_pinctrl *pctrl, + struct intel_community *community) +{ + struct intel_padgroup *gpps; + unsigned int npins = community->npins; + unsigned int padown_num = 0; + size_t i, ngpps = DIV_ROUND_UP(npins, community->gpp_size); + + if (community->gpp_size > 32) + return -EINVAL; + + gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL); + if (!gpps) + return -ENOMEM; + + for (i = 0; i < ngpps; i++) { + unsigned int gpp_size = community->gpp_size; + + gpps[i].reg_num = i; + gpps[i].base = community->pin_base + i * gpp_size; + gpps[i].size = min(gpp_size, npins); + npins -= gpps[i].size; + gpps[i].padown_num = padown_num; /* @@ -1455,7 +1482,8 @@ static int intel_pinctrl_probe(struct platform_device *pdev, for (i = 0; i < pctrl->ncommunities; i++) { struct intel_community *community = &pctrl->communities[i]; void __iomem *regs; - u32 padbar; + u32 offset; + u32 value; *community = pctrl->soc->communities[i]; @@ -1463,27 +1491,48 @@ static int intel_pinctrl_probe(struct platform_device *pdev, if (IS_ERR(regs)) return PTR_ERR(regs); - /* - * Determine community features based on the revision if - * not specified already. - */ - if (!community->features) { - u32 rev; - - rev = (readl(regs + REVID) & REVID_MASK) >> REVID_SHIFT; - if (rev >= 0x94) { - community->features |= PINCTRL_FEATURE_DEBOUNCE; - community->features |= PINCTRL_FEATURE_1K_PD; - } + /* Determine community features based on the revision */ + value = readl(regs + REVID); + if (((value & REVID_MASK) >> REVID_SHIFT) >= 0x94) { + community->features |= PINCTRL_FEATURE_DEBOUNCE; + community->features |= PINCTRL_FEATURE_1K_PD; } + /* Determine community features based on the capabilities */ + offset = CAPLIST; + do { + value = readl(regs + offset); + switch ((value & CAPLIST_ID_MASK) >> CAPLIST_ID_SHIFT) { + case CAPLIST_ID_GPIO_HW_INFO: + community->features |= PINCTRL_FEATURE_GPIO_HW_INFO; + break; + case CAPLIST_ID_PWM: + community->features |= PINCTRL_FEATURE_PWM; + break; + case CAPLIST_ID_BLINK: + community->features |= PINCTRL_FEATURE_BLINK; + break; + case CAPLIST_ID_EXP: + community->features |= PINCTRL_FEATURE_EXP; + break; + default: + break; + } + offset = (value & CAPLIST_NEXT_MASK) >> CAPLIST_NEXT_SHIFT; + } while (offset); + + dev_dbg(&pdev->dev, "Community%d features: %#08x\n", i, community->features); + /* Read offset of the pad configuration registers */ - padbar = readl(regs + PADBAR); + offset = readl(regs + PADBAR); community->regs = regs; - community->pad_regs = regs + padbar; + community->pad_regs = regs + offset; - ret = intel_pinctrl_add_padgroups(pctrl, community); + if (community->gpps) + ret = intel_pinctrl_add_padgroups_by_gpps(pctrl, community); + else + ret = intel_pinctrl_add_padgroups_by_size(pctrl, community); if (ret) return ret; } diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index ad34b7a3f6ed..c4fef03b663f 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -143,6 +143,10 @@ struct intel_community { /* Additional features supported by the hardware */ #define PINCTRL_FEATURE_DEBOUNCE BIT(0) #define PINCTRL_FEATURE_1K_PD BIT(1) +#define PINCTRL_FEATURE_GPIO_HW_INFO BIT(2) +#define PINCTRL_FEATURE_PWM BIT(3) +#define PINCTRL_FEATURE_BLINK BIT(4) +#define PINCTRL_FEATURE_EXP BIT(5) /** * PIN_GROUP - Declare a pin group diff --git a/drivers/pinctrl/intel/pinctrl-tigerlake.c b/drivers/pinctrl/intel/pinctrl-tigerlake.c index 3e354e02f408..75b6d66955bf 100644 --- a/drivers/pinctrl/intel/pinctrl-tigerlake.c +++ b/drivers/pinctrl/intel/pinctrl-tigerlake.c @@ -748,6 +748,7 @@ static const struct intel_pinctrl_soc_data tglh_soc_data = { static const struct acpi_device_id tgl_pinctrl_acpi_match[] = { { "INT34C5", (kernel_ulong_t)&tgllp_soc_data }, { "INT34C6", (kernel_ulong_t)&tglh_soc_data }, + { "INTC1055", (kernel_ulong_t)&tgllp_soc_data }, { } }; MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match); diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c index 22736f60c16c..3b9b5dbd7968 100644 --- a/drivers/pinctrl/mediatek/mtk-eint.c +++ b/drivers/pinctrl/mediatek/mtk-eint.c @@ -157,6 +157,7 @@ static void mtk_eint_ack(struct irq_data *d) static int mtk_eint_set_type(struct irq_data *d, unsigned int type) { struct mtk_eint *eint = irq_data_get_irq_chip_data(d); + bool masked; u32 mask = BIT(d->hwirq & 0x1f); void __iomem *reg; @@ -173,6 +174,13 @@ static int mtk_eint_set_type(struct irq_data *d, unsigned int type) else eint->dual_edge[d->hwirq] = 0; + if (!mtk_eint_get_mask(eint, d->hwirq)) { + mtk_eint_mask(d); + masked = false; + } else { + masked = true; + } + if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) { reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_clr); writel(mask, reg); @@ -189,8 +197,9 @@ static int mtk_eint_set_type(struct irq_data *d, unsigned int type) writel(mask, reg); } - if (eint->dual_edge[d->hwirq]) - mtk_eint_flip_edge(eint, d->hwirq); + mtk_eint_ack(d); + if (!masked) + mtk_eint_unmask(d); return 0; } diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c index 5e00f93ac998..0fa7de43bc4c 100644 --- a/drivers/pinctrl/mediatek/pinctrl-moore.c +++ b/drivers/pinctrl/mediatek/pinctrl-moore.c @@ -514,8 +514,8 @@ static int mtk_build_gpiochip(struct mtk_pinctrl *hw, struct device_node *np) chip->direction_output = mtk_gpio_direction_output; chip->get = mtk_gpio_get; chip->set = mtk_gpio_set; - chip->to_irq = mtk_gpio_to_irq, - chip->set_config = mtk_gpio_set_config, + chip->to_irq = mtk_gpio_to_irq; + chip->set_config = mtk_gpio_set_config; chip->base = -1; chip->ngpio = hw->soc->npins; chip->of_node = np; diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 039ce9be19c5..da1f19288aa6 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -891,8 +891,8 @@ static int mtk_build_gpiochip(struct mtk_pinctrl *hw, struct device_node *np) chip->direction_output = mtk_gpio_direction_output; chip->get = mtk_gpio_get; chip->set = mtk_gpio_set; - chip->to_irq = mtk_gpio_to_irq, - chip->set_config = mtk_gpio_set_config, + chip->to_irq = mtk_gpio_to_irq; + chip->set_config = mtk_gpio_set_config; chip->base = -1; chip->ngpio = hw->soc->npins; chip->of_node = np; diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 68894e9e05d2..5a68e242f6b3 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -188,7 +188,6 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { PIN_GRP_GPIO_2("led1_od", 12, 1, BIT(21), BIT(21), 0, "led"), PIN_GRP_GPIO_2("led2_od", 13, 1, BIT(22), BIT(22), 0, "led"), PIN_GRP_GPIO_2("led3_od", 14, 1, BIT(23), BIT(23), 0, "led"), - }; static struct armada_37xx_pin_group armada_37xx_sb_groups[] = { diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c index 6de31b5ee358..2535ca720668 100644 --- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c +++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c @@ -923,7 +923,7 @@ struct npcm7xx_pincfg { }; static const struct npcm7xx_pincfg pincfg[] = { - /* PIN FUNCTION 1 FUNCTION 2 FUNCTION 3 FLAGS */ + /* PIN FUNCTION 1 FUNCTION 2 FUNCTION 3 FLAGS */ NPCM7XX_PINCFG(0, iox1, MFSEL1, 30, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(1, iox1, MFSEL1, 30, none, NONE, 0, none, NONE, 0, DS(8, 12)), NPCM7XX_PINCFG(2, iox1, MFSEL1, 30, none, NONE, 0, none, NONE, 0, DS(8, 12)), diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index 36c6078b93b3..e71ebccc479c 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -36,6 +36,7 @@ #define ATMEL_PIO_DIR_MASK BIT(8) #define ATMEL_PIO_PUEN_MASK BIT(9) #define ATMEL_PIO_PDEN_MASK BIT(10) +#define ATMEL_PIO_SR_MASK BIT(11) #define ATMEL_PIO_IFEN_MASK BIT(12) #define ATMEL_PIO_IFSCEN_MASK BIT(13) #define ATMEL_PIO_OPD_MASK BIT(14) @@ -76,10 +77,12 @@ * @nbanks: number of PIO banks * @last_bank_count: number of lines in the last bank (can be less than * the rest of the banks). + * @slew_rate_support: slew rate support */ struct atmel_pioctrl_data { - unsigned nbanks; - unsigned last_bank_count; + unsigned int nbanks; + unsigned int last_bank_count; + unsigned int slew_rate_support; }; struct atmel_group { @@ -88,11 +91,11 @@ struct atmel_group { }; struct atmel_pin { - unsigned pin_id; - unsigned mux; - unsigned ioset; - unsigned bank; - unsigned line; + unsigned int pin_id; + unsigned int mux; + unsigned int ioset; + unsigned int bank; + unsigned int line; const char *device; }; @@ -117,20 +120,21 @@ struct atmel_pin { * @pm_suspend_backup: backup/restore register values on suspend/resume * @dev: device entry for the Atmel PIO controller. * @node: node of the Atmel PIO controller. + * @slew_rate_support: slew rate support */ struct atmel_pioctrl { void __iomem *reg_base; struct clk *clk; - unsigned nbanks; + unsigned int nbanks; struct pinctrl_dev *pinctrl_dev; struct atmel_group *groups; const char * const *group_names; struct atmel_pin **pins; - unsigned npins; + unsigned int npins; struct gpio_chip *gpio_chip; struct irq_domain *irq_domain; int *irqs; - unsigned *pm_wakeup_sources; + unsigned int *pm_wakeup_sources; struct { u32 imr; u32 odsr; @@ -138,6 +142,7 @@ struct atmel_pioctrl { } *pm_suspend_backup; struct device *dev; struct device_node *node; + unsigned int slew_rate_support; }; static const char * const atmel_functions[] = { @@ -172,11 +177,11 @@ static void atmel_gpio_irq_ack(struct irq_data *d) */ } -static int atmel_gpio_irq_set_type(struct irq_data *d, unsigned type) +static int atmel_gpio_irq_set_type(struct irq_data *d, unsigned int type) { struct atmel_pioctrl *atmel_pioctrl = irq_data_get_irq_chip_data(d); struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq]; - unsigned reg; + unsigned int reg; atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_MSKR, BIT(pin->line)); @@ -263,7 +268,7 @@ static struct irq_chip atmel_gpio_irq_chip = { .irq_set_wake = atmel_gpio_irq_set_wake, }; -static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) { struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); @@ -311,11 +316,12 @@ static void atmel_gpio_irq_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } -static int atmel_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +static int atmel_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) { struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); struct atmel_pin *pin = atmel_pioctrl->pins[offset]; - unsigned reg; + unsigned int reg; atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_MSKR, BIT(pin->line)); @@ -326,11 +332,11 @@ static int atmel_gpio_direction_input(struct gpio_chip *chip, unsigned offset) return 0; } -static int atmel_gpio_get(struct gpio_chip *chip, unsigned offset) +static int atmel_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); struct atmel_pin *pin = atmel_pioctrl->pins[offset]; - unsigned reg; + unsigned int reg; reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_PDSR); @@ -364,12 +370,13 @@ static int atmel_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, return 0; } -static int atmel_gpio_direction_output(struct gpio_chip *chip, unsigned offset, +static int atmel_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) { struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); struct atmel_pin *pin = atmel_pioctrl->pins[offset]; - unsigned reg; + unsigned int reg; atmel_gpio_write(atmel_pioctrl, pin->bank, value ? ATMEL_PIO_SODR : ATMEL_PIO_CODR, @@ -384,7 +391,7 @@ static int atmel_gpio_direction_output(struct gpio_chip *chip, unsigned offset, return 0; } -static void atmel_gpio_set(struct gpio_chip *chip, unsigned offset, int val) +static void atmel_gpio_set(struct gpio_chip *chip, unsigned int offset, int val) { struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); struct atmel_pin *pin = atmel_pioctrl->pins[offset]; @@ -440,11 +447,11 @@ static struct gpio_chip atmel_gpio_chip = { /* --- PINCTRL --- */ static unsigned int atmel_pin_config_read(struct pinctrl_dev *pctldev, - unsigned pin_id) + unsigned int pin_id) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); - unsigned bank = atmel_pioctrl->pins[pin_id]->bank; - unsigned line = atmel_pioctrl->pins[pin_id]->line; + unsigned int bank = atmel_pioctrl->pins[pin_id]->bank; + unsigned int line = atmel_pioctrl->pins[pin_id]->line; void __iomem *addr = atmel_pioctrl->reg_base + bank * ATMEL_PIO_BANK_OFFSET; @@ -456,11 +463,11 @@ static unsigned int atmel_pin_config_read(struct pinctrl_dev *pctldev, } static void atmel_pin_config_write(struct pinctrl_dev *pctldev, - unsigned pin_id, u32 conf) + unsigned int pin_id, u32 conf) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); - unsigned bank = atmel_pioctrl->pins[pin_id]->bank; - unsigned line = atmel_pioctrl->pins[pin_id]->line; + unsigned int bank = atmel_pioctrl->pins[pin_id]->bank; + unsigned int line = atmel_pioctrl->pins[pin_id]->line; void __iomem *addr = atmel_pioctrl->reg_base + bank * ATMEL_PIO_BANK_OFFSET; @@ -478,7 +485,7 @@ static int atmel_pctl_get_groups_count(struct pinctrl_dev *pctldev) } static const char *atmel_pctl_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) + unsigned int selector) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); @@ -486,19 +493,20 @@ static const char *atmel_pctl_get_group_name(struct pinctrl_dev *pctldev, } static int atmel_pctl_get_group_pins(struct pinctrl_dev *pctldev, - unsigned selector, const unsigned **pins, - unsigned *num_pins) + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); - *pins = (unsigned *)&atmel_pioctrl->groups[selector].pin; + *pins = (unsigned int *)&atmel_pioctrl->groups[selector].pin; *num_pins = 1; return 0; } static struct atmel_group * -atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev, unsigned pin) +atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev, unsigned int pin) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); int i; @@ -519,7 +527,7 @@ static int atmel_pctl_xlate_pinfunc(struct pinctrl_dev *pctldev, const char **func_name) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); - unsigned pin_id, func_id; + unsigned int pin_id, func_id; struct atmel_group *grp; pin_id = ATMEL_GET_PIN_NO(pinfunc); @@ -549,10 +557,10 @@ static int atmel_pctl_xlate_pinfunc(struct pinctrl_dev *pctldev, static int atmel_pctl_dt_subnode_to_map(struct pinctrl_dev *pctldev, struct device_node *np, struct pinctrl_map **map, - unsigned *reserved_maps, - unsigned *num_maps) + unsigned int *reserved_maps, + unsigned int *num_maps) { - unsigned num_pins, num_configs, reserve; + unsigned int num_pins, num_configs, reserve; unsigned long *configs; struct property *pins; u32 pinfunc; @@ -623,10 +631,10 @@ exit: static int atmel_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config, struct pinctrl_map **map, - unsigned *num_maps) + unsigned int *num_maps) { struct device_node *np; - unsigned reserved_maps; + unsigned int reserved_maps; int ret; *map = NULL; @@ -674,13 +682,13 @@ static int atmel_pmx_get_functions_count(struct pinctrl_dev *pctldev) } static const char *atmel_pmx_get_function_name(struct pinctrl_dev *pctldev, - unsigned selector) + unsigned int selector) { return atmel_functions[selector]; } static int atmel_pmx_get_function_groups(struct pinctrl_dev *pctldev, - unsigned selector, + unsigned int selector, const char * const **groups, unsigned * const num_groups) { @@ -693,11 +701,11 @@ static int atmel_pmx_get_function_groups(struct pinctrl_dev *pctldev, } static int atmel_pmx_set_mux(struct pinctrl_dev *pctldev, - unsigned function, - unsigned group) + unsigned int function, + unsigned int group) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); - unsigned pin; + unsigned int pin; u32 conf; dev_dbg(pctldev->dev, "enable function %s group %s\n", @@ -721,13 +729,13 @@ static const struct pinmux_ops atmel_pmxops = { }; static int atmel_conf_pin_config_group_get(struct pinctrl_dev *pctldev, - unsigned group, + unsigned int group, unsigned long *config) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); - unsigned param = pinconf_to_config_param(*config), arg = 0; + unsigned int param = pinconf_to_config_param(*config), arg = 0; struct atmel_group *grp = atmel_pioctrl->groups + group; - unsigned pin_id = grp->pin; + unsigned int pin_id = grp->pin; u32 res; res = atmel_pin_config_read(pctldev, pin_id); @@ -760,6 +768,13 @@ static int atmel_conf_pin_config_group_get(struct pinctrl_dev *pctldev, return -EINVAL; arg = 1; break; + case PIN_CONFIG_SLEW_RATE: + if (!atmel_pioctrl->slew_rate_support) + return -EOPNOTSUPP; + if (!(res & ATMEL_PIO_SR_MASK)) + return -EINVAL; + arg = 1; + break; case ATMEL_PIN_CONFIG_DRIVE_STRENGTH: if (!(res & ATMEL_PIO_DRVSTR_MASK)) return -EINVAL; @@ -774,25 +789,29 @@ static int atmel_conf_pin_config_group_get(struct pinctrl_dev *pctldev, } static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, - unsigned group, + unsigned int group, unsigned long *configs, - unsigned num_configs) + unsigned int num_configs) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); struct atmel_group *grp = atmel_pioctrl->groups + group; - unsigned bank, pin, pin_id = grp->pin; + unsigned int bank, pin, pin_id = grp->pin; u32 mask, conf = 0; int i; conf = atmel_pin_config_read(pctldev, pin_id); for (i = 0; i < num_configs; i++) { - unsigned param = pinconf_to_config_param(configs[i]); - unsigned arg = pinconf_to_config_argument(configs[i]); + unsigned int param = pinconf_to_config_param(configs[i]); + unsigned int arg = pinconf_to_config_argument(configs[i]); dev_dbg(pctldev->dev, "%s: pin=%u, config=0x%lx\n", __func__, pin_id, configs[i]); + /* Keep slew rate enabled by default. */ + if (atmel_pioctrl->slew_rate_support) + conf |= ATMEL_PIO_SR_MASK; + switch (param) { case PIN_CONFIG_BIAS_DISABLE: conf &= (~ATMEL_PIO_PUEN_MASK); @@ -850,6 +869,13 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, ATMEL_PIO_SODR); } break; + case PIN_CONFIG_SLEW_RATE: + if (!atmel_pioctrl->slew_rate_support) + break; + /* And remove it if explicitly requested. */ + if (arg == 0) + conf &= ~ATMEL_PIO_SR_MASK; + break; case ATMEL_PIN_CONFIG_DRIVE_STRENGTH: switch (arg) { case ATMEL_PIO_DRVSTR_LO: @@ -877,7 +903,8 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, } static void atmel_conf_pin_config_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned pin_id) + struct seq_file *s, + unsigned int pin_id) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); u32 conf; @@ -901,6 +928,8 @@ static void atmel_conf_pin_config_dbg_show(struct pinctrl_dev *pctldev, seq_printf(s, "%s ", "open-drain"); if (conf & ATMEL_PIO_SCHMITT_MASK) seq_printf(s, "%s ", "schmitt"); + if (atmel_pioctrl->slew_rate_support && (conf & ATMEL_PIO_SR_MASK)) + seq_printf(s, "%s ", "slew-rate"); if (conf & ATMEL_PIO_DRVSTR_MASK) { switch ((conf & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET) { case ATMEL_PIO_DRVSTR_ME: @@ -994,6 +1023,7 @@ static const struct atmel_pioctrl_data atmel_sama5d2_pioctrl_data = { static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = { .nbanks = 5, .last_bank_count = 8, /* sama7g5 has only PE0 to PE7 */ + .slew_rate_support = 1, }; static const struct of_device_id atmel_pctrl_of_match[] = { @@ -1039,6 +1069,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) atmel_pioctrl->npins -= ATMEL_PIO_NPINS_PER_BANK; atmel_pioctrl->npins += atmel_pioctrl_data->last_bank_count; } + atmel_pioctrl->slew_rate_support = atmel_pioctrl_data->slew_rate_support; atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(atmel_pioctrl->reg_base)) @@ -1081,8 +1112,8 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) return -ENOMEM; for (i = 0 ; i < atmel_pioctrl->npins; i++) { struct atmel_group *group = atmel_pioctrl->groups + i; - unsigned bank = ATMEL_PIO_BANK(i); - unsigned line = ATMEL_PIO_LINE(i); + unsigned int bank = ATMEL_PIO_BANK(i); + unsigned int line = ATMEL_PIO_LINE(i); atmel_pioctrl->pins[i] = devm_kzalloc(dev, sizeof(**atmel_pioctrl->pins), GFP_KERNEL); diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 72edc675431c..8003d1bd1695 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -733,7 +733,6 @@ static const struct at91_pinctrl_mux_ops sam9x60_ops = { .get_slewrate = at91_mux_sam9x60_get_slewrate, .set_slewrate = at91_mux_sam9x60_set_slewrate, .irq_type = alt_gpio_irq_type, - }; static struct at91_pinctrl_mux_ops sama5d3_ops = { @@ -1742,7 +1741,7 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev, gpio_irqchip->irq_disable = gpio_irq_mask; gpio_irqchip->irq_mask = gpio_irq_mask; gpio_irqchip->irq_unmask = gpio_irq_unmask; - gpio_irqchip->irq_set_wake = gpio_irq_set_wake, + gpio_irqchip->irq_set_wake = gpio_irq_set_wake; gpio_irqchip->irq_set_type = at91_gpio->ops->irq_type; /* Disable irqs of this PIO controller */ diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c deleted file mode 100644 index 2905348ff430..000000000000 --- a/drivers/pinctrl/pinctrl-coh901.c +++ /dev/null @@ -1,774 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * U300 GPIO module. - * - * Copyright (C) 2007-2012 ST-Ericsson AB - * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) - * Author: Linus Walleij - * Author: Jonas Aaberg - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pinctrl-coh901.h" - -#define U300_GPIO_PORT_STRIDE (0x30) -/* - * Control Register 32bit (R/W) - * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores - * gives the number of GPIO pins. - * bit 8-2 (mask 0x000001FC) contains the core version ID. - */ -#define U300_GPIO_CR (0x00) -#define U300_GPIO_CR_SYNC_SEL_ENABLE (0x00000002UL) -#define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL) -#define U300_GPIO_PXPDIR (0x04) -#define U300_GPIO_PXPDOR (0x08) -#define U300_GPIO_PXPCR (0x0C) -#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL) -#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL) -#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL) -#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL) -#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL) -#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL) -#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL) -#define U300_GPIO_PXPER (0x10) -#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL) -#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL) -#define U300_GPIO_PXIEV (0x14) -#define U300_GPIO_PXIEN (0x18) -#define U300_GPIO_PXIFR (0x1C) -#define U300_GPIO_PXICR (0x20) -#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL) -#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL) -#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL) -#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) - -/* 8 bits per port, no version has more than 7 ports */ -#define U300_GPIO_NUM_PORTS 7 -#define U300_GPIO_PINS_PER_PORT 8 -#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS) - -struct u300_gpio_port { - struct u300_gpio *gpio; - char name[8]; - int irq; - int number; - u8 toggle_edge_mode; -}; - -struct u300_gpio { - struct gpio_chip chip; - struct u300_gpio_port ports[U300_GPIO_NUM_PORTS]; - struct clk *clk; - void __iomem *base; - struct device *dev; - u32 stride; - /* Register offsets */ - u32 pcr; - u32 dor; - u32 dir; - u32 per; - u32 icr; - u32 ien; - u32 iev; -}; - -/* - * Macro to expand to read a specific register found in the "gpio" - * struct. It requires the struct u300_gpio *gpio variable to exist in - * its context. It calculates the port offset from the given pin - * offset, muliplies by the port stride and adds the register offset - * so it provides a pointer to the desired register. - */ -#define U300_PIN_REG(pin, reg) \ - (gpio->base + (pin >> 3) * gpio->stride + gpio->reg) - -/* - * Provides a bitmask for a specific gpio pin inside an 8-bit GPIO - * register. - */ -#define U300_PIN_BIT(pin) \ - (1 << (pin & 0x07)) - -struct u300_gpio_confdata { - u16 bias_mode; - bool output; - int outval; -}; - -#define U300_FLOATING_INPUT { \ - .bias_mode = PIN_CONFIG_BIAS_HIGH_IMPEDANCE, \ - .output = false, \ -} - -#define U300_PULL_UP_INPUT { \ - .bias_mode = PIN_CONFIG_BIAS_PULL_UP, \ - .output = false, \ -} - -#define U300_OUTPUT_LOW { \ - .output = true, \ - .outval = 0, \ -} - -#define U300_OUTPUT_HIGH { \ - .output = true, \ - .outval = 1, \ -} - -/* Initial configuration */ -static const struct u300_gpio_confdata __initconst -bs335_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { - /* Port 0, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_OUTPUT_HIGH, - U300_FLOATING_INPUT, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - }, - /* Port 1, pins 0-7 */ - { - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - U300_FLOATING_INPUT, - U300_OUTPUT_HIGH, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - }, - /* Port 2, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - }, - /* Port 3, pins 0-7 */ - { - U300_PULL_UP_INPUT, - U300_OUTPUT_LOW, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 4, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 5, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 6, pind 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - } -}; - -static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - - return !!(readl(U300_PIN_REG(offset, dir)) & U300_PIN_BIT(offset)); -} - -static void u300_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - unsigned long flags; - u32 val; - - local_irq_save(flags); - - val = readl(U300_PIN_REG(offset, dor)); - if (value) - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); - else - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); - - local_irq_restore(flags); -} - -static int u300_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - unsigned long flags; - u32 val; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, pcr)); - /* Mask out this pin, note 2 bits per setting */ - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - local_irq_restore(flags); - return 0; -} - -static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - unsigned long flags; - u32 oldmode; - u32 val; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, pcr)); - /* - * Drive mode must be set by the special mode set function, set - * push/pull mode by default if no mode has been selected. - */ - oldmode = val & (U300_GPIO_PXPCR_PIN_MODE_MASK << - ((offset & 0x07) << 1)); - /* mode = 0 means input, else some mode is already set */ - if (oldmode == 0) { - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << - ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - } - u300_gpio_set(chip, offset, value); - local_irq_restore(flags); - return 0; -} - -/* Returning -EINVAL means "supported but not available" */ -int u300_gpio_config_get(struct gpio_chip *chip, - unsigned offset, - unsigned long *config) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - enum pin_config_param param = (enum pin_config_param) *config; - bool biasmode; - u32 drmode; - - /* One bit per pin, clamp to bool range */ - biasmode = !!(readl(U300_PIN_REG(offset, per)) & U300_PIN_BIT(offset)); - - /* Mask out the two bits for this pin and shift to bits 0,1 */ - drmode = readl(U300_PIN_REG(offset, pcr)); - drmode &= (U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1)); - drmode >>= ((offset & 0x07) << 1); - - switch (param) { - case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: - *config = 0; - if (biasmode) - return 0; - else - return -EINVAL; - break; - case PIN_CONFIG_BIAS_PULL_UP: - *config = 0; - if (!biasmode) - return 0; - else - return -EINVAL; - break; - case PIN_CONFIG_DRIVE_PUSH_PULL: - *config = 0; - if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL) - return 0; - else - return -EINVAL; - break; - case PIN_CONFIG_DRIVE_OPEN_DRAIN: - *config = 0; - if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN) - return 0; - else - return -EINVAL; - break; - case PIN_CONFIG_DRIVE_OPEN_SOURCE: - *config = 0; - if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE) - return 0; - else - return -EINVAL; - break; - default: - break; - } - return -ENOTSUPP; -} - -int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset, - enum pin_config_param param) -{ - struct u300_gpio *gpio = gpiochip_get_data(chip); - unsigned long flags; - u32 val; - - local_irq_save(flags); - switch (param) { - case PIN_CONFIG_BIAS_DISABLE: - case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: - val = readl(U300_PIN_REG(offset, per)); - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, per)); - break; - case PIN_CONFIG_BIAS_PULL_UP: - val = readl(U300_PIN_REG(offset, per)); - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, per)); - break; - case PIN_CONFIG_DRIVE_PUSH_PULL: - val = readl(U300_PIN_REG(offset, pcr)); - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK - << ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - break; - case PIN_CONFIG_DRIVE_OPEN_DRAIN: - val = readl(U300_PIN_REG(offset, pcr)); - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK - << ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - break; - case PIN_CONFIG_DRIVE_OPEN_SOURCE: - val = readl(U300_PIN_REG(offset, pcr)); - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK - << ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - break; - default: - local_irq_restore(flags); - dev_err(gpio->dev, "illegal configuration requested\n"); - return -EINVAL; - } - local_irq_restore(flags); - return 0; -} - -static const struct gpio_chip u300_gpio_chip = { - .label = "u300-gpio-chip", - .owner = THIS_MODULE, - .request = gpiochip_generic_request, - .free = gpiochip_generic_free, - .get = u300_gpio_get, - .set = u300_gpio_set, - .direction_input = u300_gpio_direction_input, - .direction_output = u300_gpio_direction_output, -}; - -static void u300_toggle_trigger(struct u300_gpio *gpio, unsigned offset) -{ - u32 val; - - val = readl(U300_PIN_REG(offset, icr)); - /* Set mode depending on state */ - if (u300_gpio_get(&gpio->chip, offset)) { - /* High now, let's trigger on falling edge next then */ - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - dev_dbg(gpio->dev, "next IRQ on falling edge on pin %d\n", - offset); - } else { - /* Low now, let's trigger on rising edge next then */ - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - dev_dbg(gpio->dev, "next IRQ on rising edge on pin %d\n", - offset); - } -} - -static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) -{ - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = gpiochip_get_data(chip); - struct u300_gpio_port *port = &gpio->ports[d->hwirq >> 3]; - int offset = d->hwirq; - u32 val; - - if ((trigger & IRQF_TRIGGER_RISING) && - (trigger & IRQF_TRIGGER_FALLING)) { - /* - * The GPIO block can only trigger on falling OR rising edges, - * not both. So we need to toggle the mode whenever the pin - * goes from one state to the other with a special state flag - */ - dev_dbg(gpio->dev, - "trigger on both rising and falling edge on pin %d\n", - offset); - port->toggle_edge_mode |= U300_PIN_BIT(offset); - u300_toggle_trigger(gpio, offset); - } else if (trigger & IRQF_TRIGGER_RISING) { - dev_dbg(gpio->dev, "trigger on rising edge on pin %d\n", - offset); - val = readl(U300_PIN_REG(offset, icr)); - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - port->toggle_edge_mode &= ~U300_PIN_BIT(offset); - } else if (trigger & IRQF_TRIGGER_FALLING) { - dev_dbg(gpio->dev, "trigger on falling edge on pin %d\n", - offset); - val = readl(U300_PIN_REG(offset, icr)); - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - port->toggle_edge_mode &= ~U300_PIN_BIT(offset); - } - - return 0; -} - -static void u300_gpio_irq_enable(struct irq_data *d) -{ - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = gpiochip_get_data(chip); - struct u300_gpio_port *port = &gpio->ports[d->hwirq >> 3]; - int offset = d->hwirq; - u32 val; - unsigned long flags; - - dev_dbg(gpio->dev, "enable IRQ for hwirq %lu on port %s, offset %d\n", - d->hwirq, port->name, offset); - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, ien)); - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); - local_irq_restore(flags); -} - -static void u300_gpio_irq_disable(struct irq_data *d) -{ - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = gpiochip_get_data(chip); - int offset = d->hwirq; - u32 val; - unsigned long flags; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, ien)); - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); - local_irq_restore(flags); -} - -static struct irq_chip u300_gpio_irqchip = { - .name = "u300-gpio-irqchip", - .irq_enable = u300_gpio_irq_enable, - .irq_disable = u300_gpio_irq_disable, - .irq_set_type = u300_gpio_irq_type, -}; - -static void u300_gpio_irq_handler(struct irq_desc *desc) -{ - unsigned int irq = irq_desc_get_irq(desc); - struct irq_chip *parent_chip = irq_desc_get_chip(desc); - struct gpio_chip *chip = irq_desc_get_handler_data(desc); - struct u300_gpio *gpio = gpiochip_get_data(chip); - struct u300_gpio_port *port = &gpio->ports[irq - chip->base]; - int pinoffset = port->number << 3; /* get the right stride */ - unsigned long val; - - chained_irq_enter(parent_chip, desc); - - /* Read event register */ - val = readl(U300_PIN_REG(pinoffset, iev)); - /* Mask relevant bits */ - val &= 0xFFU; /* 8 bits per port */ - /* ACK IRQ (clear event) */ - writel(val, U300_PIN_REG(pinoffset, iev)); - - /* Call IRQ handler */ - if (val != 0) { - int irqoffset; - - for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { - int offset = pinoffset + irqoffset; - int pin_irq = irq_find_mapping(chip->irq.domain, offset); - - dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", - pin_irq, offset); - generic_handle_irq(pin_irq); - /* - * Triggering IRQ on both rising and falling edge - * needs mockery - */ - if (port->toggle_edge_mode & U300_PIN_BIT(offset)) - u300_toggle_trigger(gpio, offset); - } - } - - chained_irq_exit(parent_chip, desc); -} - -static void __init u300_gpio_init_pin(struct u300_gpio *gpio, - int offset, - const struct u300_gpio_confdata *conf) -{ - /* Set mode: input or output */ - if (conf->output) { - u300_gpio_direction_output(&gpio->chip, offset, conf->outval); - - /* Deactivate bias mode for output */ - u300_gpio_config_set(&gpio->chip, offset, - PIN_CONFIG_BIAS_HIGH_IMPEDANCE); - - /* Set drive mode for output */ - u300_gpio_config_set(&gpio->chip, offset, - PIN_CONFIG_DRIVE_PUSH_PULL); - - dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n", - offset, conf->outval); - } else { - u300_gpio_direction_input(&gpio->chip, offset); - - /* Always set output low on input pins */ - u300_gpio_set(&gpio->chip, offset, 0); - - /* Set bias mode for input */ - u300_gpio_config_set(&gpio->chip, offset, conf->bias_mode); - - dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n", - offset, conf->bias_mode); - } -} - -static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio) -{ - int i, j; - - /* Write default config and values to all pins */ - for (i = 0; i < U300_GPIO_NUM_PORTS; i++) { - for (j = 0; j < 8; j++) { - const struct u300_gpio_confdata *conf; - int offset = (i*8) + j; - - conf = &bs335_gpio_config[i][j]; - u300_gpio_init_pin(gpio, offset, conf); - } - } -} - -/* - * Here we map a GPIO in the local gpio_chip pin space to a pin in - * the local pinctrl pin space. The pin controller used is - * pinctrl-u300. - */ -struct coh901_pinpair { - unsigned int offset; - unsigned int pin_base; -}; - -#define COH901_PINRANGE(a, b) { .offset = a, .pin_base = b } - -static struct coh901_pinpair coh901_pintable[] = { - COH901_PINRANGE(10, 426), - COH901_PINRANGE(11, 180), - COH901_PINRANGE(12, 165), /* MS/MMC card insertion */ - COH901_PINRANGE(13, 179), - COH901_PINRANGE(14, 178), - COH901_PINRANGE(16, 194), - COH901_PINRANGE(17, 193), - COH901_PINRANGE(18, 192), - COH901_PINRANGE(19, 191), - COH901_PINRANGE(20, 186), - COH901_PINRANGE(21, 185), - COH901_PINRANGE(22, 184), - COH901_PINRANGE(23, 183), - COH901_PINRANGE(24, 182), - COH901_PINRANGE(25, 181), -}; - -static int __init u300_gpio_probe(struct platform_device *pdev) -{ - struct u300_gpio *gpio; - struct gpio_irq_chip *girq; - int err = 0; - int portno; - u32 val; - u32 ifr; - int i; - - gpio = devm_kzalloc(&pdev->dev, sizeof(struct u300_gpio), GFP_KERNEL); - if (gpio == NULL) - return -ENOMEM; - - gpio->chip = u300_gpio_chip; - gpio->chip.ngpio = U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT; - gpio->chip.parent = &pdev->dev; - gpio->chip.base = 0; - gpio->dev = &pdev->dev; - - gpio->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(gpio->base)) - return PTR_ERR(gpio->base); - - gpio->clk = devm_clk_get(gpio->dev, NULL); - if (IS_ERR(gpio->clk)) { - err = PTR_ERR(gpio->clk); - dev_err(gpio->dev, "could not get GPIO clock\n"); - return err; - } - - err = clk_prepare_enable(gpio->clk); - if (err) { - dev_err(gpio->dev, "could not enable GPIO clock\n"); - return err; - } - - dev_info(gpio->dev, - "initializing GPIO Controller COH 901 571/3\n"); - gpio->stride = U300_GPIO_PORT_STRIDE; - gpio->pcr = U300_GPIO_PXPCR; - gpio->dor = U300_GPIO_PXPDOR; - gpio->dir = U300_GPIO_PXPDIR; - gpio->per = U300_GPIO_PXPER; - gpio->icr = U300_GPIO_PXICR; - gpio->ien = U300_GPIO_PXIEN; - gpio->iev = U300_GPIO_PXIEV; - ifr = U300_GPIO_PXIFR; - - val = readl(gpio->base + U300_GPIO_CR); - dev_info(gpio->dev, "COH901571/3 block version: %d, " \ - "number of cores: %d totalling %d pins\n", - ((val & 0x000001FC) >> 2), - ((val & 0x0000FE00) >> 9), - ((val & 0x0000FE00) >> 9) * 8); - writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, - gpio->base + U300_GPIO_CR); - u300_gpio_init_coh901571(gpio); - - girq = &gpio->chip.irq; - girq->chip = &u300_gpio_irqchip; - girq->parent_handler = u300_gpio_irq_handler; - girq->num_parents = U300_GPIO_NUM_PORTS; - girq->parents = devm_kcalloc(gpio->dev, U300_GPIO_NUM_PORTS, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) { - err = -ENOMEM; - goto err_dis_clk; - } - for (portno = 0 ; portno < U300_GPIO_NUM_PORTS; portno++) { - struct u300_gpio_port *port = &gpio->ports[portno]; - - snprintf(port->name, 8, "gpio%d", portno); - port->number = portno; - port->gpio = gpio; - - port->irq = platform_get_irq(pdev, portno); - girq->parents[portno] = port->irq; - - /* Turns off irq force (test register) for this port */ - writel(0x0, gpio->base + portno * gpio->stride + ifr); - } - girq->default_type = IRQ_TYPE_EDGE_FALLING; - girq->handler = handle_simple_irq; -#ifdef CONFIG_OF_GPIO - gpio->chip.of_node = pdev->dev.of_node; -#endif - err = gpiochip_add_data(&gpio->chip, gpio); - if (err) { - dev_err(gpio->dev, "unable to add gpiochip: %d\n", err); - goto err_dis_clk; - } - - /* - * Add pinctrl pin ranges, the pin controller must be registered - * at this point - */ - for (i = 0; i < ARRAY_SIZE(coh901_pintable); i++) { - struct coh901_pinpair *p = &coh901_pintable[i]; - - err = gpiochip_add_pin_range(&gpio->chip, "pinctrl-u300", - p->offset, p->pin_base, 1); - if (err) - goto err_no_range; - } - - platform_set_drvdata(pdev, gpio); - - return 0; - -err_no_range: - gpiochip_remove(&gpio->chip); -err_dis_clk: - clk_disable_unprepare(gpio->clk); - dev_err(&pdev->dev, "module ERROR:%d\n", err); - return err; -} - -static int __exit u300_gpio_remove(struct platform_device *pdev) -{ - struct u300_gpio *gpio = platform_get_drvdata(pdev); - - /* Turn off the GPIO block */ - writel(0x00000000U, gpio->base + U300_GPIO_CR); - - gpiochip_remove(&gpio->chip); - clk_disable_unprepare(gpio->clk); - return 0; -} - -static const struct of_device_id u300_gpio_match[] = { - { .compatible = "stericsson,gpio-coh901" }, - {}, -}; - -static struct platform_driver u300_gpio_driver = { - .driver = { - .name = "u300-gpio", - .of_match_table = u300_gpio_match, - }, - .remove = __exit_p(u300_gpio_remove), -}; - -static int __init u300_gpio_init(void) -{ - return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); -} - -static void __exit u300_gpio_exit(void) -{ - platform_driver_unregister(&u300_gpio_driver); -} - -arch_initcall(u300_gpio_init); -module_exit(u300_gpio_exit); - -MODULE_AUTHOR("Linus Walleij "); -MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335/COH 901 571/3 GPIO driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/pinctrl-coh901.h b/drivers/pinctrl/pinctrl-coh901.h deleted file mode 100644 index ba2678665168..000000000000 --- a/drivers/pinctrl/pinctrl-coh901.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -int u300_gpio_config_get(struct gpio_chip *chip, - unsigned offset, - unsigned long *config); -int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset, - enum pin_config_param param); diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 3ea163498647..f2746125b077 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -376,12 +376,21 @@ static int jz4760_cim_pins[] = { 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, }; -static int jz4760_lcd_24bit_pins[] = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, +static int jz4760_lcd_8bit_pins[] = { + 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x4c, + 0x4d, 0x52, 0x53, }; +static int jz4760_lcd_16bit_pins[] = { + 0x4e, 0x4f, 0x50, 0x51, 0x56, 0x57, 0x58, 0x59, +}; +static int jz4760_lcd_18bit_pins[] = { + 0x5a, 0x5b, +}; +static int jz4760_lcd_24bit_pins[] = { + 0x40, 0x41, 0x4a, 0x4b, 0x54, 0x55, +}; +static int jz4760_lcd_special_pins[] = { 0x40, 0x41, 0x4a, 0x54 }; +static int jz4760_lcd_generic_pins[] = { 0x49, }; static int jz4760_pwm_pwm0_pins[] = { 0x80, }; static int jz4760_pwm_pwm1_pins[] = { 0x81, }; static int jz4760_pwm_pwm2_pins[] = { 0x82, }; @@ -390,6 +399,7 @@ static int jz4760_pwm_pwm4_pins[] = { 0x84, }; static int jz4760_pwm_pwm5_pins[] = { 0x85, }; static int jz4760_pwm_pwm6_pins[] = { 0x6a, }; static int jz4760_pwm_pwm7_pins[] = { 0x6b, }; +static int jz4760_otg_pins[] = { 0x8a, }; static u8 jz4760_uart3_data_funcs[] = { 0, 1, }; static u8 jz4760_mmc0_1bit_a_funcs[] = { 1, 1, 0, }; @@ -436,8 +446,12 @@ static const struct group_desc jz4760_groups[] = { INGENIC_PIN_GROUP("i2c0-data", jz4760_i2c0, 0), INGENIC_PIN_GROUP("i2c1-data", jz4760_i2c1, 0), INGENIC_PIN_GROUP("cim-data", jz4760_cim, 0), + INGENIC_PIN_GROUP("lcd-8bit", jz4760_lcd_8bit, 0), + INGENIC_PIN_GROUP("lcd-16bit", jz4760_lcd_16bit, 0), + INGENIC_PIN_GROUP("lcd-18bit", jz4760_lcd_18bit, 0), INGENIC_PIN_GROUP("lcd-24bit", jz4760_lcd_24bit, 0), - { "lcd-no-pins", }, + INGENIC_PIN_GROUP("lcd-generic", jz4760_lcd_generic, 0), + INGENIC_PIN_GROUP("lcd-special", jz4760_lcd_special, 1), INGENIC_PIN_GROUP("pwm0", jz4760_pwm_pwm0, 0), INGENIC_PIN_GROUP("pwm1", jz4760_pwm_pwm1, 0), INGENIC_PIN_GROUP("pwm2", jz4760_pwm_pwm2, 0), @@ -446,6 +460,7 @@ static const struct group_desc jz4760_groups[] = { INGENIC_PIN_GROUP("pwm5", jz4760_pwm_pwm5, 0), INGENIC_PIN_GROUP("pwm6", jz4760_pwm_pwm6, 0), INGENIC_PIN_GROUP("pwm7", jz4760_pwm_pwm7, 0), + INGENIC_PIN_GROUP("otg-vbus", jz4760_otg, 0), }; static const char *jz4760_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; @@ -477,7 +492,10 @@ static const char *jz4760_cs6_groups[] = { "nemc-cs6", }; static const char *jz4760_i2c0_groups[] = { "i2c0-data", }; static const char *jz4760_i2c1_groups[] = { "i2c1-data", }; static const char *jz4760_cim_groups[] = { "cim-data", }; -static const char *jz4760_lcd_groups[] = { "lcd-24bit", "lcd-no-pins", }; +static const char *jz4760_lcd_groups[] = { + "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit", + "lcd-special", "lcd-generic", +}; static const char *jz4760_pwm0_groups[] = { "pwm0", }; static const char *jz4760_pwm1_groups[] = { "pwm1", }; static const char *jz4760_pwm2_groups[] = { "pwm2", }; @@ -486,6 +504,7 @@ static const char *jz4760_pwm4_groups[] = { "pwm4", }; static const char *jz4760_pwm5_groups[] = { "pwm5", }; static const char *jz4760_pwm6_groups[] = { "pwm6", }; static const char *jz4760_pwm7_groups[] = { "pwm7", }; +static const char *jz4760_otg_groups[] = { "otg-vbus", }; static const struct function_desc jz4760_functions[] = { { "uart0", jz4760_uart0_groups, ARRAY_SIZE(jz4760_uart0_groups), }, @@ -514,6 +533,7 @@ static const struct function_desc jz4760_functions[] = { { "pwm5", jz4760_pwm5_groups, ARRAY_SIZE(jz4760_pwm5_groups), }, { "pwm6", jz4760_pwm6_groups, ARRAY_SIZE(jz4760_pwm6_groups), }, { "pwm7", jz4760_pwm7_groups, ARRAY_SIZE(jz4760_pwm7_groups), }, + { "otg", jz4760_otg_groups, ARRAY_SIZE(jz4760_otg_groups), }, }; static const struct ingenic_chip_info jz4760_chip_info = { @@ -648,7 +668,6 @@ static int jz4770_mac_rmii_pins[] = { 0xa9, 0xab, 0xaa, 0xac, 0xa5, 0xa4, 0xad, 0xae, 0xa6, 0xa8, }; static int jz4770_mac_mii_pins[] = { 0xa7, 0xaf, }; -static int jz4770_otg_pins[] = { 0x8a, }; static const struct group_desc jz4770_groups[] = { INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data, 0), @@ -747,7 +766,7 @@ static const struct group_desc jz4770_groups[] = { INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7, 0), INGENIC_PIN_GROUP("mac-rmii", jz4770_mac_rmii, 0), INGENIC_PIN_GROUP("mac-mii", jz4770_mac_mii, 0), - INGENIC_PIN_GROUP("otg-vbus", jz4770_otg, 0), + INGENIC_PIN_GROUP("otg-vbus", jz4760_otg, 0), }; static const char *jz4770_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; @@ -808,7 +827,6 @@ static const char *jz4770_pwm5_groups[] = { "pwm5", }; static const char *jz4770_pwm6_groups[] = { "pwm6", }; static const char *jz4770_pwm7_groups[] = { "pwm7", }; static const char *jz4770_mac_groups[] = { "mac-rmii", "mac-mii", }; -static const char *jz4770_otg_groups[] = { "otg-vbus", }; static const struct function_desc jz4770_functions[] = { { "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), }, @@ -841,7 +859,7 @@ static const struct function_desc jz4770_functions[] = { { "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), }, { "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), }, { "mac", jz4770_mac_groups, ARRAY_SIZE(jz4770_mac_groups), }, - { "otg", jz4770_otg_groups, ARRAY_SIZE(jz4770_otg_groups), }, + { "otg", jz4760_otg_groups, ARRAY_SIZE(jz4760_otg_groups), }, }; static const struct ingenic_chip_info jz4770_chip_info = { @@ -2384,6 +2402,12 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) unsigned int i; int err; + chip_info = of_device_get_match_data(dev); + if (!chip_info) { + dev_err(dev, "Unsupported SoC\n"); + return -EINVAL; + } + jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL); if (!jzpc) return -ENOMEM; @@ -2400,7 +2424,7 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) } jzpc->dev = dev; - jzpc->info = chip_info = of_device_get_match_data(dev); + jzpc->info = chip_info; pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL); if (!pctl_desc) @@ -2470,17 +2494,47 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) } static const struct of_device_id ingenic_pinctrl_of_match[] = { - { .compatible = "ingenic,jz4740-pinctrl", .data = &jz4740_chip_info }, - { .compatible = "ingenic,jz4725b-pinctrl", .data = &jz4725b_chip_info }, - { .compatible = "ingenic,jz4760-pinctrl", .data = &jz4760_chip_info }, - { .compatible = "ingenic,jz4760b-pinctrl", .data = &jz4760_chip_info }, - { .compatible = "ingenic,jz4770-pinctrl", .data = &jz4770_chip_info }, - { .compatible = "ingenic,jz4780-pinctrl", .data = &jz4780_chip_info }, - { .compatible = "ingenic,x1000-pinctrl", .data = &x1000_chip_info }, - { .compatible = "ingenic,x1000e-pinctrl", .data = &x1000_chip_info }, - { .compatible = "ingenic,x1500-pinctrl", .data = &x1500_chip_info }, - { .compatible = "ingenic,x1830-pinctrl", .data = &x1830_chip_info }, - {}, + { + .compatible = "ingenic,jz4740-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4740, &jz4740_chip_info) + }, + { + .compatible = "ingenic,jz4725b-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4725B, &jz4725b_chip_info) + }, + { + .compatible = "ingenic,jz4760-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4760, &jz4760_chip_info) + }, + { + .compatible = "ingenic,jz4760b-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4760, &jz4760_chip_info) + }, + { + .compatible = "ingenic,jz4770-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4770, &jz4770_chip_info) + }, + { + .compatible = "ingenic,jz4780-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4780, &jz4780_chip_info) + }, + { + .compatible = "ingenic,x1000-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_X1000, &x1000_chip_info) + }, + { + .compatible = "ingenic,x1000e-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_X1000, &x1000_chip_info) + }, + { + .compatible = "ingenic,x1500-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_X1500, &x1500_chip_info) + }, + { + .compatible = "ingenic,x1830-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_X1830, &x1830_chip_info) + }, + { /* sentinel */ }, }; static struct platform_driver ingenic_pinctrl_driver = { diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index f3cd7e296712..7771316dfffa 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -777,6 +777,7 @@ static int pcs_add_function(struct pcs_device *pcs, function->vals = vals; function->nvals = nvals; + function->name = name; selector = pinmux_generic_add_function(pcs->pctl, name, pgnames, npgnames, diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 7b8c7a0b13de..43d9e6c7fd81 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -541,7 +541,6 @@ static void st_pinconf_set_retime_packed(struct st_pinctrl *info, st_regmap_field_bit_set_clear_pin(rt_p->delay_0, delay & 0x1, pin); /* 2 bit delay, msb */ st_regmap_field_bit_set_clear_pin(rt_p->delay_1, delay & 0x2, pin); - } static void st_pinconf_set_retime_dedicated(struct st_pinctrl *info, diff --git a/drivers/pinctrl/pinctrl-sx150x.c b/drivers/pinctrl/pinctrl-sx150x.c index c110f780407b..484a3b9e875c 100644 --- a/drivers/pinctrl/pinctrl-sx150x.c +++ b/drivers/pinctrl/pinctrl-sx150x.c @@ -443,7 +443,6 @@ static void sx150x_gpio_set(struct gpio_chip *chip, unsigned int offset, sx150x_gpio_oscio_set(pctl, value); else __sx150x_gpio_set(pctl, offset, value); - } static void sx150x_gpio_set_multiple(struct gpio_chip *chip, diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c deleted file mode 100644 index cc306448259e..000000000000 --- a/drivers/pinctrl/pinctrl-u300.c +++ /dev/null @@ -1,1111 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Driver for the U300 pin controller - * - * Based on the original U300 padmux functions - * Copyright (C) 2009-2011 ST-Ericsson AB - * Author: Martin Persson - * Author: Linus Walleij - * - * The DB3350 design and control registers are oriented around pads rather than - * pins, so we enumerate the pads we can mux rather than actual pins. The pads - * are connected to different pins in different packaging types, so it would - * be confusing. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pinctrl-coh901.h" - -/* - * Register definitions for the U300 Padmux control registers in the - * system controller - */ - -/* PAD MUX Control register 1 (LOW) 16bit (R/W) */ -#define U300_SYSCON_PMC1LR 0x007C -#define U300_SYSCON_PMC1LR_MASK 0xFFFF -#define U300_SYSCON_PMC1LR_CDI_MASK 0xC000 -#define U300_SYSCON_PMC1LR_CDI_CDI 0x0000 -#define U300_SYSCON_PMC1LR_CDI_EMIF 0x4000 -/* For BS335 */ -#define U300_SYSCON_PMC1LR_CDI_CDI2 0x8000 -#define U300_SYSCON_PMC1LR_CDI_WCDMA_APP_GPIO 0xC000 -/* For BS365 */ -#define U300_SYSCON_PMC1LR_CDI_GPIO 0x8000 -#define U300_SYSCON_PMC1LR_CDI_WCDMA 0xC000 -/* Common defs */ -#define U300_SYSCON_PMC1LR_PDI_MASK 0x3000 -#define U300_SYSCON_PMC1LR_PDI_PDI 0x0000 -#define U300_SYSCON_PMC1LR_PDI_EGG 0x1000 -#define U300_SYSCON_PMC1LR_PDI_WCDMA 0x3000 -#define U300_SYSCON_PMC1LR_MMCSD_MASK 0x0C00 -#define U300_SYSCON_PMC1LR_MMCSD_MMCSD 0x0000 -#define U300_SYSCON_PMC1LR_MMCSD_MSPRO 0x0400 -#define U300_SYSCON_PMC1LR_MMCSD_DSP 0x0800 -#define U300_SYSCON_PMC1LR_MMCSD_WCDMA 0x0C00 -#define U300_SYSCON_PMC1LR_ETM_MASK 0x0300 -#define U300_SYSCON_PMC1LR_ETM_ACC 0x0000 -#define U300_SYSCON_PMC1LR_ETM_APP 0x0100 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK 0x00C0 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC 0x0000 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_NFIF 0x0040 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM 0x0080 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC_2GB 0x00C0 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK 0x0030 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC 0x0000 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_NFIF 0x0010 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SDRAM 0x0020 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SEMI 0x0030 -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK 0x000C -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_STATIC 0x0000 -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF 0x0004 -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SDRAM 0x0008 -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SEMI 0x000C -#define U300_SYSCON_PMC1LR_EMIF_1_MASK 0x0003 -#define U300_SYSCON_PMC1LR_EMIF_1_STATIC 0x0000 -#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 0x0001 -#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM1 0x0002 -#define U300_SYSCON_PMC1LR_EMIF_1 0x0003 -/* PAD MUX Control register 2 (HIGH) 16bit (R/W) */ -#define U300_SYSCON_PMC1HR 0x007E -#define U300_SYSCON_PMC1HR_MASK 0xFFFF -#define U300_SYSCON_PMC1HR_MISC_2_MASK 0xC000 -#define U300_SYSCON_PMC1HR_MISC_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_MISC_2_MSPRO 0x4000 -#define U300_SYSCON_PMC1HR_MISC_2_DSP 0x8000 -#define U300_SYSCON_PMC1HR_MISC_2_AAIF 0xC000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_MASK 0x3000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_NFIF 0x1000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_DSP 0x2000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_AAIF 0x3000 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_MASK 0x0C00 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_MMC 0x0400 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_DSP 0x0800 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_AAIF 0x0C00 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK 0x0300 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI 0x0100 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_AAIF 0x0300 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK 0x00C0 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI 0x0040 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_AAIF 0x00C0 -#define U300_SYSCON_PMC1HR_APP_SPI_2_MASK 0x0030 -#define U300_SYSCON_PMC1HR_APP_SPI_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_SPI_2_SPI 0x0010 -#define U300_SYSCON_PMC1HR_APP_SPI_2_DSP 0x0020 -#define U300_SYSCON_PMC1HR_APP_SPI_2_AAIF 0x0030 -#define U300_SYSCON_PMC1HR_APP_UART0_2_MASK 0x000C -#define U300_SYSCON_PMC1HR_APP_UART0_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_UART0_2_UART0 0x0004 -#define U300_SYSCON_PMC1HR_APP_UART0_2_NFIF_CS 0x0008 -#define U300_SYSCON_PMC1HR_APP_UART0_2_AAIF 0x000C -#define U300_SYSCON_PMC1HR_APP_UART0_1_MASK 0x0003 -#define U300_SYSCON_PMC1HR_APP_UART0_1_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_UART0_1_UART0 0x0001 -#define U300_SYSCON_PMC1HR_APP_UART0_1_AAIF 0x0003 -/* Padmux 2 control */ -#define U300_SYSCON_PMC2R 0x100 -#define U300_SYSCON_PMC2R_APP_MISC_0_MASK 0x00C0 -#define U300_SYSCON_PMC2R_APP_MISC_0_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_0_EMIF_SDRAM 0x0040 -#define U300_SYSCON_PMC2R_APP_MISC_0_MMC 0x0080 -#define U300_SYSCON_PMC2R_APP_MISC_0_CDI2 0x00C0 -#define U300_SYSCON_PMC2R_APP_MISC_1_MASK 0x0300 -#define U300_SYSCON_PMC2R_APP_MISC_1_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_1_EMIF_SDRAM 0x0100 -#define U300_SYSCON_PMC2R_APP_MISC_1_MMC 0x0200 -#define U300_SYSCON_PMC2R_APP_MISC_1_CDI2 0x0300 -#define U300_SYSCON_PMC2R_APP_MISC_2_MASK 0x0C00 -#define U300_SYSCON_PMC2R_APP_MISC_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_2_EMIF_SDRAM 0x0400 -#define U300_SYSCON_PMC2R_APP_MISC_2_MMC 0x0800 -#define U300_SYSCON_PMC2R_APP_MISC_2_CDI2 0x0C00 -#define U300_SYSCON_PMC2R_APP_MISC_3_MASK 0x3000 -#define U300_SYSCON_PMC2R_APP_MISC_3_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_3_EMIF_SDRAM 0x1000 -#define U300_SYSCON_PMC2R_APP_MISC_3_MMC 0x2000 -#define U300_SYSCON_PMC2R_APP_MISC_3_CDI2 0x3000 -#define U300_SYSCON_PMC2R_APP_MISC_4_MASK 0xC000 -#define U300_SYSCON_PMC2R_APP_MISC_4_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_4_EMIF_SDRAM 0x4000 -#define U300_SYSCON_PMC2R_APP_MISC_4_MMC 0x8000 -#define U300_SYSCON_PMC2R_APP_MISC_4_ACC_GPIO 0xC000 -/* TODO: More SYSCON registers missing */ -#define U300_SYSCON_PMC3R 0x10C -#define U300_SYSCON_PMC3R_APP_MISC_11_MASK 0xC000 -#define U300_SYSCON_PMC3R_APP_MISC_11_SPI 0x4000 -#define U300_SYSCON_PMC3R_APP_MISC_10_MASK 0x3000 -#define U300_SYSCON_PMC3R_APP_MISC_10_SPI 0x1000 -/* TODO: Missing other configs */ -#define U300_SYSCON_PMC4R 0x168 -#define U300_SYSCON_PMC4R_APP_MISC_12_MASK 0x0003 -#define U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO 0x0000 -#define U300_SYSCON_PMC4R_APP_MISC_13_MASK 0x000C -#define U300_SYSCON_PMC4R_APP_MISC_13_CDI 0x0000 -#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA 0x0004 -#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA2 0x0008 -#define U300_SYSCON_PMC4R_APP_MISC_13_APP_GPIO 0x000C -#define U300_SYSCON_PMC4R_APP_MISC_14_MASK 0x0030 -#define U300_SYSCON_PMC4R_APP_MISC_14_CDI 0x0000 -#define U300_SYSCON_PMC4R_APP_MISC_14_SMIA 0x0010 -#define U300_SYSCON_PMC4R_APP_MISC_14_CDI2 0x0020 -#define U300_SYSCON_PMC4R_APP_MISC_14_APP_GPIO 0x0030 -#define U300_SYSCON_PMC4R_APP_MISC_16_MASK 0x0300 -#define U300_SYSCON_PMC4R_APP_MISC_16_APP_GPIO_13 0x0000 -#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS 0x0100 -#define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N 0x0200 - -#define DRIVER_NAME "pinctrl-u300" - -/* - * The DB3350 has 467 pads, I have enumerated the pads clockwise around the - * edges of the silicon, finger by finger. LTCORNER upper left is pad 0. - * Data taken from the PadRing chart, arranged like this: - * - * 0 ..... 104 - * 466 105 - * . . - * . . - * 358 224 - * 357 .... 225 - */ -#define U300_NUM_PADS 467 - -/* Pad names for the pinmux subsystem */ -static const struct pinctrl_pin_desc u300_pads[] = { - /* Pads along the top edge of the chip */ - PINCTRL_PIN(0, "P PAD VDD 28"), - PINCTRL_PIN(1, "P PAD GND 28"), - PINCTRL_PIN(2, "PO SIM RST N"), - PINCTRL_PIN(3, "VSSIO 25"), - PINCTRL_PIN(4, "VSSA ADDA ESDSUB"), - PINCTRL_PIN(5, "PWR VSSCOMMON"), - PINCTRL_PIN(6, "PI ADC I1 POS"), - PINCTRL_PIN(7, "PI ADC I1 NEG"), - PINCTRL_PIN(8, "PWR VSSAD0"), - PINCTRL_PIN(9, "PWR VCCAD0"), - PINCTRL_PIN(10, "PI ADC Q1 NEG"), - PINCTRL_PIN(11, "PI ADC Q1 POS"), - PINCTRL_PIN(12, "PWR VDDAD"), - PINCTRL_PIN(13, "PWR GNDAD"), - PINCTRL_PIN(14, "PI ADC I2 POS"), - PINCTRL_PIN(15, "PI ADC I2 NEG"), - PINCTRL_PIN(16, "PWR VSSAD1"), - PINCTRL_PIN(17, "PWR VCCAD1"), - PINCTRL_PIN(18, "PI ADC Q2 NEG"), - PINCTRL_PIN(19, "PI ADC Q2 POS"), - PINCTRL_PIN(20, "VSSA ADDA ESDSUB"), - PINCTRL_PIN(21, "PWR VCCGPAD"), - PINCTRL_PIN(22, "PI TX POW"), - PINCTRL_PIN(23, "PWR VSSGPAD"), - PINCTRL_PIN(24, "PO DAC I POS"), - PINCTRL_PIN(25, "PO DAC I NEG"), - PINCTRL_PIN(26, "PO DAC Q POS"), - PINCTRL_PIN(27, "PO DAC Q NEG"), - PINCTRL_PIN(28, "PWR VSSDA"), - PINCTRL_PIN(29, "PWR VCCDA"), - PINCTRL_PIN(30, "VSSA ADDA ESDSUB"), - PINCTRL_PIN(31, "P PAD VDDIO 11"), - PINCTRL_PIN(32, "PI PLL 26 FILTVDD"), - PINCTRL_PIN(33, "PI PLL 26 VCONT"), - PINCTRL_PIN(34, "PWR AGNDPLL2V5 32 13"), - PINCTRL_PIN(35, "PWR AVDDPLL2V5 32 13"), - PINCTRL_PIN(36, "VDDA PLL ESD"), - PINCTRL_PIN(37, "VSSA PLL ESD"), - PINCTRL_PIN(38, "VSS PLL"), - PINCTRL_PIN(39, "VDDC PLL"), - PINCTRL_PIN(40, "PWR AGNDPLL2V5 26 60"), - PINCTRL_PIN(41, "PWR AVDDPLL2V5 26 60"), - PINCTRL_PIN(42, "PWR AVDDPLL2V5 26 208"), - PINCTRL_PIN(43, "PWR AGNDPLL2V5 26 208"), - PINCTRL_PIN(44, "PWR AVDDPLL2V5 13 208"), - PINCTRL_PIN(45, "PWR AGNDPLL2V5 13 208"), - PINCTRL_PIN(46, "P PAD VSSIO 11"), - PINCTRL_PIN(47, "P PAD VSSIO 12"), - PINCTRL_PIN(48, "PI POW RST N"), - PINCTRL_PIN(49, "VDDC IO"), - PINCTRL_PIN(50, "P PAD VDDIO 16"), - PINCTRL_PIN(51, "PO RF WCDMA EN 4"), - PINCTRL_PIN(52, "PO RF WCDMA EN 3"), - PINCTRL_PIN(53, "PO RF WCDMA EN 2"), - PINCTRL_PIN(54, "PO RF WCDMA EN 1"), - PINCTRL_PIN(55, "PO RF WCDMA EN 0"), - PINCTRL_PIN(56, "PO GSM PA ENABLE"), - PINCTRL_PIN(57, "PO RF DATA STRB"), - PINCTRL_PIN(58, "PO RF DATA2"), - PINCTRL_PIN(59, "PIO RF DATA1"), - PINCTRL_PIN(60, "PIO RF DATA0"), - PINCTRL_PIN(61, "P PAD VDD 11"), - PINCTRL_PIN(62, "P PAD GND 11"), - PINCTRL_PIN(63, "P PAD VSSIO 16"), - PINCTRL_PIN(64, "P PAD VDDIO 18"), - PINCTRL_PIN(65, "PO RF CTRL STRB2"), - PINCTRL_PIN(66, "PO RF CTRL STRB1"), - PINCTRL_PIN(67, "PO RF CTRL STRB0"), - PINCTRL_PIN(68, "PIO RF CTRL DATA"), - PINCTRL_PIN(69, "PO RF CTRL CLK"), - PINCTRL_PIN(70, "PO TX ADC STRB"), - PINCTRL_PIN(71, "PO ANT SW 2"), - PINCTRL_PIN(72, "PO ANT SW 3"), - PINCTRL_PIN(73, "PO ANT SW 0"), - PINCTRL_PIN(74, "PO ANT SW 1"), - PINCTRL_PIN(75, "PO M CLKRQ"), - PINCTRL_PIN(76, "PI M CLK"), - PINCTRL_PIN(77, "PI RTC CLK"), - PINCTRL_PIN(78, "P PAD VDD 8"), - PINCTRL_PIN(79, "P PAD GND 8"), - PINCTRL_PIN(80, "P PAD VSSIO 13"), - PINCTRL_PIN(81, "P PAD VDDIO 13"), - PINCTRL_PIN(82, "PO SYS 1 CLK"), - PINCTRL_PIN(83, "PO SYS 2 CLK"), - PINCTRL_PIN(84, "PO SYS 0 CLK"), - PINCTRL_PIN(85, "PI SYS 0 CLKRQ"), - PINCTRL_PIN(86, "PO PWR MNGT CTRL 1"), - PINCTRL_PIN(87, "PO PWR MNGT CTRL 0"), - PINCTRL_PIN(88, "PO RESOUT2 RST N"), - PINCTRL_PIN(89, "PO RESOUT1 RST N"), - PINCTRL_PIN(90, "PO RESOUT0 RST N"), - PINCTRL_PIN(91, "PI SERVICE N"), - PINCTRL_PIN(92, "P PAD VDD 29"), - PINCTRL_PIN(93, "P PAD GND 29"), - PINCTRL_PIN(94, "P PAD VSSIO 8"), - PINCTRL_PIN(95, "P PAD VDDIO 8"), - PINCTRL_PIN(96, "PI EXT IRQ1 N"), - PINCTRL_PIN(97, "PI EXT IRQ0 N"), - PINCTRL_PIN(98, "PIO DC ON"), - PINCTRL_PIN(99, "PIO ACC APP I2C DATA"), - PINCTRL_PIN(100, "PIO ACC APP I2C CLK"), - PINCTRL_PIN(101, "P PAD VDD 12"), - PINCTRL_PIN(102, "P PAD GND 12"), - PINCTRL_PIN(103, "P PAD VSSIO 14"), - PINCTRL_PIN(104, "P PAD VDDIO 14"), - /* Pads along the right edge of the chip */ - PINCTRL_PIN(105, "PIO APP I2C1 DATA"), - PINCTRL_PIN(106, "PIO APP I2C1 CLK"), - PINCTRL_PIN(107, "PO KEY OUT0"), - PINCTRL_PIN(108, "PO KEY OUT1"), - PINCTRL_PIN(109, "PO KEY OUT2"), - PINCTRL_PIN(110, "PO KEY OUT3"), - PINCTRL_PIN(111, "PO KEY OUT4"), - PINCTRL_PIN(112, "PI KEY IN0"), - PINCTRL_PIN(113, "PI KEY IN1"), - PINCTRL_PIN(114, "PI KEY IN2"), - PINCTRL_PIN(115, "P PAD VDDIO 15"), - PINCTRL_PIN(116, "P PAD VSSIO 15"), - PINCTRL_PIN(117, "P PAD GND 13"), - PINCTRL_PIN(118, "P PAD VDD 13"), - PINCTRL_PIN(119, "PI KEY IN3"), - PINCTRL_PIN(120, "PI KEY IN4"), - PINCTRL_PIN(121, "PI KEY IN5"), - PINCTRL_PIN(122, "PIO APP PCM I2S1 DATA B"), - PINCTRL_PIN(123, "PIO APP PCM I2S1 DATA A"), - PINCTRL_PIN(124, "PIO APP PCM I2S1 WS"), - PINCTRL_PIN(125, "PIO APP PCM I2S1 CLK"), - PINCTRL_PIN(126, "PIO APP PCM I2S0 DATA B"), - PINCTRL_PIN(127, "PIO APP PCM I2S0 DATA A"), - PINCTRL_PIN(128, "PIO APP PCM I2S0 WS"), - PINCTRL_PIN(129, "PIO APP PCM I2S0 CLK"), - PINCTRL_PIN(130, "P PAD VDD 17"), - PINCTRL_PIN(131, "P PAD GND 17"), - PINCTRL_PIN(132, "P PAD VSSIO 19"), - PINCTRL_PIN(133, "P PAD VDDIO 19"), - PINCTRL_PIN(134, "UART0 RTS"), - PINCTRL_PIN(135, "UART0 CTS"), - PINCTRL_PIN(136, "UART0 TX"), - PINCTRL_PIN(137, "UART0 RX"), - PINCTRL_PIN(138, "PIO ACC SPI DO"), - PINCTRL_PIN(139, "PIO ACC SPI DI"), - PINCTRL_PIN(140, "PIO ACC SPI CS0 N"), - PINCTRL_PIN(141, "PIO ACC SPI CS1 N"), - PINCTRL_PIN(142, "PIO ACC SPI CS2 N"), - PINCTRL_PIN(143, "PIO ACC SPI CLK"), - PINCTRL_PIN(144, "PO PDI EXT RST N"), - PINCTRL_PIN(145, "P PAD VDDIO 22"), - PINCTRL_PIN(146, "P PAD VSSIO 22"), - PINCTRL_PIN(147, "P PAD GND 18"), - PINCTRL_PIN(148, "P PAD VDD 18"), - PINCTRL_PIN(149, "PIO PDI C0"), - PINCTRL_PIN(150, "PIO PDI C1"), - PINCTRL_PIN(151, "PIO PDI C2"), - PINCTRL_PIN(152, "PIO PDI C3"), - PINCTRL_PIN(153, "PIO PDI C4"), - PINCTRL_PIN(154, "PIO PDI C5"), - PINCTRL_PIN(155, "PIO PDI D0"), - PINCTRL_PIN(156, "PIO PDI D1"), - PINCTRL_PIN(157, "PIO PDI D2"), - PINCTRL_PIN(158, "PIO PDI D3"), - PINCTRL_PIN(159, "P PAD VDDIO 21"), - PINCTRL_PIN(160, "P PAD VSSIO 21"), - PINCTRL_PIN(161, "PIO PDI D4"), - PINCTRL_PIN(162, "PIO PDI D5"), - PINCTRL_PIN(163, "PIO PDI D6"), - PINCTRL_PIN(164, "PIO PDI D7"), - PINCTRL_PIN(165, "PIO MS INS"), - PINCTRL_PIN(166, "MMC DATA DIR LS"), - PINCTRL_PIN(167, "MMC DATA 3"), - PINCTRL_PIN(168, "MMC DATA 2"), - PINCTRL_PIN(169, "MMC DATA 1"), - PINCTRL_PIN(170, "MMC DATA 0"), - PINCTRL_PIN(171, "MMC CMD DIR LS"), - PINCTRL_PIN(172, "P PAD VDD 27"), - PINCTRL_PIN(173, "P PAD GND 27"), - PINCTRL_PIN(174, "P PAD VSSIO 20"), - PINCTRL_PIN(175, "P PAD VDDIO 20"), - PINCTRL_PIN(176, "MMC CMD"), - PINCTRL_PIN(177, "MMC CLK"), - PINCTRL_PIN(178, "PIO APP GPIO 14"), - PINCTRL_PIN(179, "PIO APP GPIO 13"), - PINCTRL_PIN(180, "PIO APP GPIO 11"), - PINCTRL_PIN(181, "PIO APP GPIO 25"), - PINCTRL_PIN(182, "PIO APP GPIO 24"), - PINCTRL_PIN(183, "PIO APP GPIO 23"), - PINCTRL_PIN(184, "PIO APP GPIO 22"), - PINCTRL_PIN(185, "PIO APP GPIO 21"), - PINCTRL_PIN(186, "PIO APP GPIO 20"), - PINCTRL_PIN(187, "P PAD VDD 19"), - PINCTRL_PIN(188, "P PAD GND 19"), - PINCTRL_PIN(189, "P PAD VSSIO 23"), - PINCTRL_PIN(190, "P PAD VDDIO 23"), - PINCTRL_PIN(191, "PIO APP GPIO 19"), - PINCTRL_PIN(192, "PIO APP GPIO 18"), - PINCTRL_PIN(193, "PIO APP GPIO 17"), - PINCTRL_PIN(194, "PIO APP GPIO 16"), - PINCTRL_PIN(195, "PI CI D1"), - PINCTRL_PIN(196, "PI CI D0"), - PINCTRL_PIN(197, "PI CI HSYNC"), - PINCTRL_PIN(198, "PI CI VSYNC"), - PINCTRL_PIN(199, "PI CI EXT CLK"), - PINCTRL_PIN(200, "PO CI EXT RST N"), - PINCTRL_PIN(201, "P PAD VSSIO 43"), - PINCTRL_PIN(202, "P PAD VDDIO 43"), - PINCTRL_PIN(203, "PI CI D6"), - PINCTRL_PIN(204, "PI CI D7"), - PINCTRL_PIN(205, "PI CI D2"), - PINCTRL_PIN(206, "PI CI D3"), - PINCTRL_PIN(207, "PI CI D4"), - PINCTRL_PIN(208, "PI CI D5"), - PINCTRL_PIN(209, "PI CI D8"), - PINCTRL_PIN(210, "PI CI D9"), - PINCTRL_PIN(211, "P PAD VDD 20"), - PINCTRL_PIN(212, "P PAD GND 20"), - PINCTRL_PIN(213, "P PAD VSSIO 24"), - PINCTRL_PIN(214, "P PAD VDDIO 24"), - PINCTRL_PIN(215, "P PAD VDDIO 26"), - PINCTRL_PIN(216, "PO EMIF 1 A26"), - PINCTRL_PIN(217, "PO EMIF 1 A25"), - PINCTRL_PIN(218, "P PAD VSSIO 26"), - PINCTRL_PIN(219, "PO EMIF 1 A24"), - PINCTRL_PIN(220, "PO EMIF 1 A23"), - /* Pads along the bottom edge of the chip */ - PINCTRL_PIN(221, "PO EMIF 1 A22"), - PINCTRL_PIN(222, "PO EMIF 1 A21"), - PINCTRL_PIN(223, "P PAD VDD 21"), - PINCTRL_PIN(224, "P PAD GND 21"), - PINCTRL_PIN(225, "P PAD VSSIO 27"), - PINCTRL_PIN(226, "P PAD VDDIO 27"), - PINCTRL_PIN(227, "PO EMIF 1 A20"), - PINCTRL_PIN(228, "PO EMIF 1 A19"), - PINCTRL_PIN(229, "PO EMIF 1 A18"), - PINCTRL_PIN(230, "PO EMIF 1 A17"), - PINCTRL_PIN(231, "P PAD VDDIO 28"), - PINCTRL_PIN(232, "P PAD VSSIO 28"), - PINCTRL_PIN(233, "PO EMIF 1 A16"), - PINCTRL_PIN(234, "PIO EMIF 1 D15"), - PINCTRL_PIN(235, "PO EMIF 1 A15"), - PINCTRL_PIN(236, "PIO EMIF 1 D14"), - PINCTRL_PIN(237, "P PAD VDD 22"), - PINCTRL_PIN(238, "P PAD GND 22"), - PINCTRL_PIN(239, "P PAD VSSIO 29"), - PINCTRL_PIN(240, "P PAD VDDIO 29"), - PINCTRL_PIN(241, "PO EMIF 1 A14"), - PINCTRL_PIN(242, "PIO EMIF 1 D13"), - PINCTRL_PIN(243, "PO EMIF 1 A13"), - PINCTRL_PIN(244, "PIO EMIF 1 D12"), - PINCTRL_PIN(245, "P PAD VSSIO 30"), - PINCTRL_PIN(246, "P PAD VDDIO 30"), - PINCTRL_PIN(247, "PO EMIF 1 A12"), - PINCTRL_PIN(248, "PIO EMIF 1 D11"), - PINCTRL_PIN(249, "PO EMIF 1 A11"), - PINCTRL_PIN(250, "PIO EMIF 1 D10"), - PINCTRL_PIN(251, "P PAD VSSIO 31"), - PINCTRL_PIN(252, "P PAD VDDIO 31"), - PINCTRL_PIN(253, "PO EMIF 1 A10"), - PINCTRL_PIN(254, "PIO EMIF 1 D09"), - PINCTRL_PIN(255, "PO EMIF 1 A09"), - PINCTRL_PIN(256, "P PAD VDDIO 32"), - PINCTRL_PIN(257, "P PAD VSSIO 32"), - PINCTRL_PIN(258, "P PAD GND 24"), - PINCTRL_PIN(259, "P PAD VDD 24"), - PINCTRL_PIN(260, "PIO EMIF 1 D08"), - PINCTRL_PIN(261, "PO EMIF 1 A08"), - PINCTRL_PIN(262, "PIO EMIF 1 D07"), - PINCTRL_PIN(263, "PO EMIF 1 A07"), - PINCTRL_PIN(264, "P PAD VDDIO 33"), - PINCTRL_PIN(265, "P PAD VSSIO 33"), - PINCTRL_PIN(266, "PIO EMIF 1 D06"), - PINCTRL_PIN(267, "PO EMIF 1 A06"), - PINCTRL_PIN(268, "PIO EMIF 1 D05"), - PINCTRL_PIN(269, "PO EMIF 1 A05"), - PINCTRL_PIN(270, "P PAD VDDIO 34"), - PINCTRL_PIN(271, "P PAD VSSIO 34"), - PINCTRL_PIN(272, "PIO EMIF 1 D04"), - PINCTRL_PIN(273, "PO EMIF 1 A04"), - PINCTRL_PIN(274, "PIO EMIF 1 D03"), - PINCTRL_PIN(275, "PO EMIF 1 A03"), - PINCTRL_PIN(276, "P PAD VDDIO 35"), - PINCTRL_PIN(277, "P PAD VSSIO 35"), - PINCTRL_PIN(278, "P PAD GND 23"), - PINCTRL_PIN(279, "P PAD VDD 23"), - PINCTRL_PIN(280, "PIO EMIF 1 D02"), - PINCTRL_PIN(281, "PO EMIF 1 A02"), - PINCTRL_PIN(282, "PIO EMIF 1 D01"), - PINCTRL_PIN(283, "PO EMIF 1 A01"), - PINCTRL_PIN(284, "P PAD VDDIO 36"), - PINCTRL_PIN(285, "P PAD VSSIO 36"), - PINCTRL_PIN(286, "PIO EMIF 1 D00"), - PINCTRL_PIN(287, "PO EMIF 1 BE1 N"), - PINCTRL_PIN(288, "PO EMIF 1 BE0 N"), - PINCTRL_PIN(289, "PO EMIF 1 ADV N"), - PINCTRL_PIN(290, "P PAD VDDIO 37"), - PINCTRL_PIN(291, "P PAD VSSIO 37"), - PINCTRL_PIN(292, "PO EMIF 1 SD CKE0"), - PINCTRL_PIN(293, "PO EMIF 1 OE N"), - PINCTRL_PIN(294, "PO EMIF 1 WE N"), - PINCTRL_PIN(295, "P PAD VDDIO 38"), - PINCTRL_PIN(296, "P PAD VSSIO 38"), - PINCTRL_PIN(297, "PO EMIF 1 CLK"), - PINCTRL_PIN(298, "PIO EMIF 1 SD CLK"), - PINCTRL_PIN(299, "P PAD VSSIO 45 (not bonded)"), - PINCTRL_PIN(300, "P PAD VDDIO 42"), - PINCTRL_PIN(301, "P PAD VSSIO 42"), - PINCTRL_PIN(302, "P PAD GND 31"), - PINCTRL_PIN(303, "P PAD VDD 31"), - PINCTRL_PIN(304, "PI EMIF 1 RET CLK"), - PINCTRL_PIN(305, "PI EMIF 1 WAIT N"), - PINCTRL_PIN(306, "PI EMIF 1 NFIF READY"), - PINCTRL_PIN(307, "PO EMIF 1 SD CKE1"), - PINCTRL_PIN(308, "PO EMIF 1 CS3 N"), - PINCTRL_PIN(309, "P PAD VDD 25"), - PINCTRL_PIN(310, "P PAD GND 25"), - PINCTRL_PIN(311, "P PAD VSSIO 39"), - PINCTRL_PIN(312, "P PAD VDDIO 39"), - PINCTRL_PIN(313, "PO EMIF 1 CS2 N"), - PINCTRL_PIN(314, "PO EMIF 1 CS1 N"), - PINCTRL_PIN(315, "PO EMIF 1 CS0 N"), - PINCTRL_PIN(316, "PO ETM TRACE PKT0"), - PINCTRL_PIN(317, "PO ETM TRACE PKT1"), - PINCTRL_PIN(318, "PO ETM TRACE PKT2"), - PINCTRL_PIN(319, "P PAD VDD 30"), - PINCTRL_PIN(320, "P PAD GND 30"), - PINCTRL_PIN(321, "P PAD VSSIO 44"), - PINCTRL_PIN(322, "P PAD VDDIO 44"), - PINCTRL_PIN(323, "PO ETM TRACE PKT3"), - PINCTRL_PIN(324, "PO ETM TRACE PKT4"), - PINCTRL_PIN(325, "PO ETM TRACE PKT5"), - PINCTRL_PIN(326, "PO ETM TRACE PKT6"), - PINCTRL_PIN(327, "PO ETM TRACE PKT7"), - PINCTRL_PIN(328, "PO ETM PIPE STAT0"), - PINCTRL_PIN(329, "P PAD VDD 26"), - PINCTRL_PIN(330, "P PAD GND 26"), - PINCTRL_PIN(331, "P PAD VSSIO 40"), - PINCTRL_PIN(332, "P PAD VDDIO 40"), - PINCTRL_PIN(333, "PO ETM PIPE STAT1"), - PINCTRL_PIN(334, "PO ETM PIPE STAT2"), - PINCTRL_PIN(335, "PO ETM TRACE CLK"), - PINCTRL_PIN(336, "PO ETM TRACE SYNC"), - PINCTRL_PIN(337, "PIO ACC GPIO 33"), - PINCTRL_PIN(338, "PIO ACC GPIO 32"), - PINCTRL_PIN(339, "PIO ACC GPIO 30"), - PINCTRL_PIN(340, "PIO ACC GPIO 29"), - PINCTRL_PIN(341, "P PAD VDDIO 17"), - PINCTRL_PIN(342, "P PAD VSSIO 17"), - PINCTRL_PIN(343, "P PAD GND 15"), - PINCTRL_PIN(344, "P PAD VDD 15"), - PINCTRL_PIN(345, "PIO ACC GPIO 28"), - PINCTRL_PIN(346, "PIO ACC GPIO 27"), - PINCTRL_PIN(347, "PIO ACC GPIO 16"), - PINCTRL_PIN(348, "PI TAP TMS"), - PINCTRL_PIN(349, "PI TAP TDI"), - PINCTRL_PIN(350, "PO TAP TDO"), - PINCTRL_PIN(351, "PI TAP RST N"), - /* Pads along the left edge of the chip */ - PINCTRL_PIN(352, "PI EMU MODE 0"), - PINCTRL_PIN(353, "PO TAP RET CLK"), - PINCTRL_PIN(354, "PI TAP CLK"), - PINCTRL_PIN(355, "PO EMIF 0 SD CS N"), - PINCTRL_PIN(356, "PO EMIF 0 SD CAS N"), - PINCTRL_PIN(357, "PO EMIF 0 SD WE N"), - PINCTRL_PIN(358, "P PAD VDDIO 1"), - PINCTRL_PIN(359, "P PAD VSSIO 1"), - PINCTRL_PIN(360, "P PAD GND 1"), - PINCTRL_PIN(361, "P PAD VDD 1"), - PINCTRL_PIN(362, "PO EMIF 0 SD CKE"), - PINCTRL_PIN(363, "PO EMIF 0 SD DQML"), - PINCTRL_PIN(364, "PO EMIF 0 SD DQMU"), - PINCTRL_PIN(365, "PO EMIF 0 SD RAS N"), - PINCTRL_PIN(366, "PIO EMIF 0 D15"), - PINCTRL_PIN(367, "PO EMIF 0 A15"), - PINCTRL_PIN(368, "PIO EMIF 0 D14"), - PINCTRL_PIN(369, "PO EMIF 0 A14"), - PINCTRL_PIN(370, "PIO EMIF 0 D13"), - PINCTRL_PIN(371, "PO EMIF 0 A13"), - PINCTRL_PIN(372, "P PAD VDDIO 2"), - PINCTRL_PIN(373, "P PAD VSSIO 2"), - PINCTRL_PIN(374, "P PAD GND 2"), - PINCTRL_PIN(375, "P PAD VDD 2"), - PINCTRL_PIN(376, "PIO EMIF 0 D12"), - PINCTRL_PIN(377, "PO EMIF 0 A12"), - PINCTRL_PIN(378, "PIO EMIF 0 D11"), - PINCTRL_PIN(379, "PO EMIF 0 A11"), - PINCTRL_PIN(380, "PIO EMIF 0 D10"), - PINCTRL_PIN(381, "PO EMIF 0 A10"), - PINCTRL_PIN(382, "PIO EMIF 0 D09"), - PINCTRL_PIN(383, "PO EMIF 0 A09"), - PINCTRL_PIN(384, "PIO EMIF 0 D08"), - PINCTRL_PIN(385, "PO EMIF 0 A08"), - PINCTRL_PIN(386, "PIO EMIF 0 D07"), - PINCTRL_PIN(387, "PO EMIF 0 A07"), - PINCTRL_PIN(388, "P PAD VDDIO 3"), - PINCTRL_PIN(389, "P PAD VSSIO 3"), - PINCTRL_PIN(390, "P PAD GND 3"), - PINCTRL_PIN(391, "P PAD VDD 3"), - PINCTRL_PIN(392, "PO EFUSE RDOUT1"), - PINCTRL_PIN(393, "PIO EMIF 0 D06"), - PINCTRL_PIN(394, "PO EMIF 0 A06"), - PINCTRL_PIN(395, "PIO EMIF 0 D05"), - PINCTRL_PIN(396, "PO EMIF 0 A05"), - PINCTRL_PIN(397, "PIO EMIF 0 D04"), - PINCTRL_PIN(398, "PO EMIF 0 A04"), - PINCTRL_PIN(399, "A PADS/A VDDCO1v82v5 GND 80U SF LIN VDDCO AF"), - PINCTRL_PIN(400, "PWR VDDCO AF"), - PINCTRL_PIN(401, "PWR EFUSE HV1"), - PINCTRL_PIN(402, "P PAD VSSIO 4"), - PINCTRL_PIN(403, "P PAD VDDIO 4"), - PINCTRL_PIN(404, "P PAD GND 4"), - PINCTRL_PIN(405, "P PAD VDD 4"), - PINCTRL_PIN(406, "PIO EMIF 0 D03"), - PINCTRL_PIN(407, "PO EMIF 0 A03"), - PINCTRL_PIN(408, "PWR EFUSE HV2"), - PINCTRL_PIN(409, "PWR EFUSE HV3"), - PINCTRL_PIN(410, "PIO EMIF 0 D02"), - PINCTRL_PIN(411, "PO EMIF 0 A02"), - PINCTRL_PIN(412, "PIO EMIF 0 D01"), - PINCTRL_PIN(413, "P PAD VDDIO 5"), - PINCTRL_PIN(414, "P PAD VSSIO 5"), - PINCTRL_PIN(415, "P PAD GND 5"), - PINCTRL_PIN(416, "P PAD VDD 5"), - PINCTRL_PIN(417, "PO EMIF 0 A01"), - PINCTRL_PIN(418, "PIO EMIF 0 D00"), - PINCTRL_PIN(419, "IF 0 SD CLK"), - PINCTRL_PIN(420, "APP SPI CLK"), - PINCTRL_PIN(421, "APP SPI DO"), - PINCTRL_PIN(422, "APP SPI DI"), - PINCTRL_PIN(423, "APP SPI CS0"), - PINCTRL_PIN(424, "APP SPI CS1"), - PINCTRL_PIN(425, "APP SPI CS2"), - PINCTRL_PIN(426, "PIO APP GPIO 10"), - PINCTRL_PIN(427, "P PAD VDDIO 41"), - PINCTRL_PIN(428, "P PAD VSSIO 41"), - PINCTRL_PIN(429, "P PAD GND 6"), - PINCTRL_PIN(430, "P PAD VDD 6"), - PINCTRL_PIN(431, "PIO ACC SDIO0 CMD"), - PINCTRL_PIN(432, "PIO ACC SDIO0 CK"), - PINCTRL_PIN(433, "PIO ACC SDIO0 D3"), - PINCTRL_PIN(434, "PIO ACC SDIO0 D2"), - PINCTRL_PIN(435, "PIO ACC SDIO0 D1"), - PINCTRL_PIN(436, "PIO ACC SDIO0 D0"), - PINCTRL_PIN(437, "PIO USB PU"), - PINCTRL_PIN(438, "PIO USB SP"), - PINCTRL_PIN(439, "PIO USB DAT VP"), - PINCTRL_PIN(440, "PIO USB SE0 VM"), - PINCTRL_PIN(441, "PIO USB OE"), - PINCTRL_PIN(442, "PIO USB SUSP"), - PINCTRL_PIN(443, "P PAD VSSIO 6"), - PINCTRL_PIN(444, "P PAD VDDIO 6"), - PINCTRL_PIN(445, "PIO USB PUEN"), - PINCTRL_PIN(446, "PIO ACC UART0 RX"), - PINCTRL_PIN(447, "PIO ACC UART0 TX"), - PINCTRL_PIN(448, "PIO ACC UART0 CTS"), - PINCTRL_PIN(449, "PIO ACC UART0 RTS"), - PINCTRL_PIN(450, "PIO ACC UART3 RX"), - PINCTRL_PIN(451, "PIO ACC UART3 TX"), - PINCTRL_PIN(452, "PIO ACC UART3 CTS"), - PINCTRL_PIN(453, "PIO ACC UART3 RTS"), - PINCTRL_PIN(454, "PIO ACC IRDA TX"), - PINCTRL_PIN(455, "P PAD VDDIO 7"), - PINCTRL_PIN(456, "P PAD VSSIO 7"), - PINCTRL_PIN(457, "P PAD GND 7"), - PINCTRL_PIN(458, "P PAD VDD 7"), - PINCTRL_PIN(459, "PIO ACC IRDA RX"), - PINCTRL_PIN(460, "PIO ACC PCM I2S CLK"), - PINCTRL_PIN(461, "PIO ACC PCM I2S WS"), - PINCTRL_PIN(462, "PIO ACC PCM I2S DATA A"), - PINCTRL_PIN(463, "PIO ACC PCM I2S DATA B"), - PINCTRL_PIN(464, "PO SIM CLK"), - PINCTRL_PIN(465, "PIO ACC IRDA SD"), - PINCTRL_PIN(466, "PIO SIM DATA"), -}; - -/** - * @dev: a pointer back to containing device - * @virtbase: the offset to the controller in virtual memory - */ -struct u300_pmx { - struct device *dev; - struct pinctrl_dev *pctl; - void __iomem *virtbase; -}; - -/** - * u300_pmx_registers - the array of registers read/written for each pinmux - * shunt setting - */ -static const u32 u300_pmx_registers[] = { - U300_SYSCON_PMC1LR, - U300_SYSCON_PMC1HR, - U300_SYSCON_PMC2R, - U300_SYSCON_PMC3R, - U300_SYSCON_PMC4R, -}; - -/** - * struct u300_pin_group - describes a U300 pin group - * @name: the name of this specific pin group - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @num_pins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array - */ -struct u300_pin_group { - const char *name; - const unsigned int *pins; - const unsigned num_pins; -}; - -/** - * struct pmx_onmask - mask bits to enable/disable padmux - * @mask: mask bits to disable - * @val: mask bits to enable - * - * onmask lazy dog: - * onmask = { - * {"PMC1LR" mask, "PMC1LR" value}, - * {"PMC1HR" mask, "PMC1HR" value}, - * {"PMC2R" mask, "PMC2R" value}, - * {"PMC3R" mask, "PMC3R" value}, - * {"PMC4R" mask, "PMC4R" value} - * } - */ -struct u300_pmx_mask { - u16 mask; - u16 bits; -}; - -/* The chip power pins are VDD, GND, VDDIO and VSSIO */ -static const unsigned power_pins[] = { 0, 1, 3, 31, 46, 47, 49, 50, 61, 62, 63, - 64, 78, 79, 80, 81, 92, 93, 94, 95, 101, 102, 103, 104, 115, 116, 117, - 118, 130, 131, 132, 133, 145, 146, 147, 148, 159, 160, 172, 173, 174, - 175, 187, 188, 189, 190, 201, 202, 211, 212, 213, 214, 215, 218, 223, - 224, 225, 226, 231, 232, 237, 238, 239, 240, 245, 246, 251, 252, 256, - 257, 258, 259, 264, 265, 270, 271, 276, 277, 278, 279, 284, 285, 290, - 291, 295, 296, 299, 300, 301, 302, 303, 309, 310, 311, 312, 319, 320, - 321, 322, 329, 330, 331, 332, 341, 342, 343, 344, 358, 359, 360, 361, - 372, 373, 374, 375, 388, 389, 390, 391, 402, 403, 404, 405, 413, 414, - 415, 416, 427, 428, 429, 430, 443, 444, 455, 456, 457, 458 }; -static const unsigned emif0_pins[] = { 355, 356, 357, 362, 363, 364, 365, 366, - 367, 368, 369, 370, 371, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 393, 394, 395, 396, 397, 398, 406, 407, 410, 411, 412, - 417, 418 }; -static const unsigned emif1_pins[] = { 216, 217, 219, 220, 221, 222, 227, 228, - 229, 230, 233, 234, 235, 236, 241, 242, 243, 244, 247, 248, 249, 250, - 253, 254, 255, 260, 261, 262, 263, 266, 267, 268, 269, 272, 273, 274, - 275, 280, 281, 282, 283, 286, 287, 288, 289, 292, 293, 294, 297, 298, - 304, 305, 306, 307, 308, 313, 314, 315 }; -static const unsigned uart0_pins[] = { 134, 135, 136, 137 }; -static const unsigned mmc0_pins[] = { 166, 167, 168, 169, 170, 171, 176, 177 }; -static const unsigned spi0_pins[] = { 420, 421, 422, 423, 424, 425 }; - -static const struct u300_pmx_mask emif0_mask[] = { - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, -}; - -static const struct u300_pmx_mask emif1_mask[] = { - /* - * This connects the SDRAM to CS2 and a NAND flash to - * CS0 on the EMIF. - */ - { - U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK | - U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK | - U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK | - U300_SYSCON_PMC1LR_EMIF_1_MASK, - U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM | - U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC | - U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF | - U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 - }, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, -}; - -static const struct u300_pmx_mask uart0_mask[] = { - {0, 0}, - { - U300_SYSCON_PMC1HR_APP_UART0_1_MASK | - U300_SYSCON_PMC1HR_APP_UART0_2_MASK, - U300_SYSCON_PMC1HR_APP_UART0_1_UART0 | - U300_SYSCON_PMC1HR_APP_UART0_2_UART0 - }, - {0, 0}, - {0, 0}, - {0, 0}, -}; - -static const struct u300_pmx_mask mmc0_mask[] = { - { U300_SYSCON_PMC1LR_MMCSD_MASK, U300_SYSCON_PMC1LR_MMCSD_MMCSD}, - {0, 0}, - {0, 0}, - {0, 0}, - { U300_SYSCON_PMC4R_APP_MISC_12_MASK, - U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO } -}; - -static const struct u300_pmx_mask spi0_mask[] = { - {0, 0}, - { - U300_SYSCON_PMC1HR_APP_SPI_2_MASK | - U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK | - U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK, - U300_SYSCON_PMC1HR_APP_SPI_2_SPI | - U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI | - U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI - }, - {0, 0}, - {0, 0}, - {0, 0} -}; - -static const struct u300_pin_group u300_pin_groups[] = { - { - .name = "powergrp", - .pins = power_pins, - .num_pins = ARRAY_SIZE(power_pins), - }, - { - .name = "emif0grp", - .pins = emif0_pins, - .num_pins = ARRAY_SIZE(emif0_pins), - }, - { - .name = "emif1grp", - .pins = emif1_pins, - .num_pins = ARRAY_SIZE(emif1_pins), - }, - { - .name = "uart0grp", - .pins = uart0_pins, - .num_pins = ARRAY_SIZE(uart0_pins), - }, - { - .name = "mmc0grp", - .pins = mmc0_pins, - .num_pins = ARRAY_SIZE(mmc0_pins), - }, - { - .name = "spi0grp", - .pins = spi0_pins, - .num_pins = ARRAY_SIZE(spi0_pins), - }, -}; - -static int u300_get_groups_count(struct pinctrl_dev *pctldev) -{ - return ARRAY_SIZE(u300_pin_groups); -} - -static const char *u300_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - return u300_pin_groups[selector].name; -} - -static int u300_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, - const unsigned **pins, - unsigned *num_pins) -{ - *pins = u300_pin_groups[selector].pins; - *num_pins = u300_pin_groups[selector].num_pins; - return 0; -} - -static void u300_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned offset) -{ - seq_printf(s, " " DRIVER_NAME); -} - -static const struct pinctrl_ops u300_pctrl_ops = { - .get_groups_count = u300_get_groups_count, - .get_group_name = u300_get_group_name, - .get_group_pins = u300_get_group_pins, - .pin_dbg_show = u300_pin_dbg_show, -}; - -/* - * Here we define the available functions and their corresponding pin groups - */ - -/** - * struct u300_pmx_func - describes U300 pinmux functions - * @name: the name of this specific function - * @groups: corresponding pin groups - * @onmask: bits to set to enable this when doing pin muxing - */ -struct u300_pmx_func { - const char *name; - const char * const *groups; - const unsigned num_groups; - const struct u300_pmx_mask *mask; -}; - -static const char * const powergrps[] = { "powergrp" }; -static const char * const emif0grps[] = { "emif0grp" }; -static const char * const emif1grps[] = { "emif1grp" }; -static const char * const uart0grps[] = { "uart0grp" }; -static const char * const mmc0grps[] = { "mmc0grp" }; -static const char * const spi0grps[] = { "spi0grp" }; - -static const struct u300_pmx_func u300_pmx_functions[] = { - { - .name = "power", - .groups = powergrps, - .num_groups = ARRAY_SIZE(powergrps), - /* Mask is N/A */ - }, - { - .name = "emif0", - .groups = emif0grps, - .num_groups = ARRAY_SIZE(emif0grps), - .mask = emif0_mask, - }, - { - .name = "emif1", - .groups = emif1grps, - .num_groups = ARRAY_SIZE(emif1grps), - .mask = emif1_mask, - }, - { - .name = "uart0", - .groups = uart0grps, - .num_groups = ARRAY_SIZE(uart0grps), - .mask = uart0_mask, - }, - { - .name = "mmc0", - .groups = mmc0grps, - .num_groups = ARRAY_SIZE(mmc0grps), - .mask = mmc0_mask, - }, - { - .name = "spi0", - .groups = spi0grps, - .num_groups = ARRAY_SIZE(spi0grps), - .mask = spi0_mask, - }, -}; - -static void u300_pmx_endisable(struct u300_pmx *upmx, unsigned selector, - bool enable) -{ - u16 regval, val, mask; - int i; - const struct u300_pmx_mask *upmx_mask; - - upmx_mask = u300_pmx_functions[selector].mask; - for (i = 0; i < ARRAY_SIZE(u300_pmx_registers); i++) { - if (enable) - val = upmx_mask->bits; - else - val = 0; - - mask = upmx_mask->mask; - if (mask != 0) { - regval = readw(upmx->virtbase + u300_pmx_registers[i]); - regval &= ~mask; - regval |= val; - writew(regval, upmx->virtbase + u300_pmx_registers[i]); - } - upmx_mask++; - } -} - -static int u300_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct u300_pmx *upmx; - - /* There is nothing to do with the power pins */ - if (selector == 0) - return 0; - - upmx = pinctrl_dev_get_drvdata(pctldev); - u300_pmx_endisable(upmx, selector, true); - - return 0; -} - -static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev) -{ - return ARRAY_SIZE(u300_pmx_functions); -} - -static const char *u300_pmx_get_func_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - return u300_pmx_functions[selector].name; -} - -static int u300_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, - const char * const **groups, - unsigned * const num_groups) -{ - *groups = u300_pmx_functions[selector].groups; - *num_groups = u300_pmx_functions[selector].num_groups; - return 0; -} - -static const struct pinmux_ops u300_pmx_ops = { - .get_functions_count = u300_pmx_get_funcs_count, - .get_function_name = u300_pmx_get_func_name, - .get_function_groups = u300_pmx_get_groups, - .set_mux = u300_pmx_set_mux, -}; - -static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long *config) -{ - struct pinctrl_gpio_range *range = - pinctrl_find_gpio_range_from_pin(pctldev, pin); - - /* We get config for those pins we CAN get it for and that's it */ - if (!range) - return -ENOTSUPP; - - return u300_gpio_config_get(range->gc, - (pin - range->pin_base + range->base), - config); -} - -static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long *configs, unsigned num_configs) -{ - struct pinctrl_gpio_range *range = - pinctrl_find_gpio_range_from_pin(pctldev, pin); - int ret, i; - - if (!range) - return -EINVAL; - - for (i = 0; i < num_configs; i++) { - /* Note: none of these configurations take any argument */ - ret = u300_gpio_config_set(range->gc, - (pin - range->pin_base + range->base), - pinconf_to_config_param(configs[i])); - if (ret) - return ret; - } /* for each config */ - - return 0; -} - -static const struct pinconf_ops u300_pconf_ops = { - .is_generic = true, - .pin_config_get = u300_pin_config_get, - .pin_config_set = u300_pin_config_set, -}; - -static struct pinctrl_desc u300_pmx_desc = { - .name = DRIVER_NAME, - .pins = u300_pads, - .npins = ARRAY_SIZE(u300_pads), - .pctlops = &u300_pctrl_ops, - .pmxops = &u300_pmx_ops, - .confops = &u300_pconf_ops, - .owner = THIS_MODULE, -}; - -static int u300_pmx_probe(struct platform_device *pdev) -{ - struct u300_pmx *upmx; - - /* Create state holders etc for this driver */ - upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); - if (!upmx) - return -ENOMEM; - - upmx->dev = &pdev->dev; - - upmx->virtbase = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(upmx->virtbase)) - return PTR_ERR(upmx->virtbase); - - upmx->pctl = devm_pinctrl_register(&pdev->dev, &u300_pmx_desc, upmx); - if (IS_ERR(upmx->pctl)) { - dev_err(&pdev->dev, "could not register U300 pinmux driver\n"); - return PTR_ERR(upmx->pctl); - } - - platform_set_drvdata(pdev, upmx); - - dev_info(&pdev->dev, "initialized U300 pin control driver\n"); - - return 0; -} - -static const struct of_device_id u300_pinctrl_match[] = { - { .compatible = "stericsson,pinctrl-u300" }, - {}, -}; - - -static struct platform_driver u300_pmx_driver = { - .driver = { - .name = DRIVER_NAME, - .of_match_table = u300_pinctrl_match, - }, - .probe = u300_pmx_probe, -}; - -static int __init u300_pmx_init(void) -{ - return platform_driver_register(&u300_pmx_driver); -} -arch_initcall(u300_pmx_init); - -static void __exit u300_pmx_exit(void) -{ - platform_driver_unregister(&u300_pmx_driver); -} -module_exit(u300_pmx_exit); - -MODULE_AUTHOR("Linus Walleij "); -MODULE_DESCRIPTION("U300 pin control driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index bab888fe3f8e..36a11c9e893a 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -564,7 +564,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what) continue; } - seq_printf(s, "function: %s, groups = [ ", func); + seq_printf(s, "function %d: %s, groups = [ ", func_selector, func); for (i = 0; i < num_groups; i++) seq_printf(s, "%s ", groups[i]); seq_puts(s, "]\n"); diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index a003776506d0..6853a896c476 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -220,6 +220,15 @@ config PINCTRL_SC7280 Qualcomm Technologies Inc TLMM block found on the Qualcomm Technologies Inc SC7280 platform. +config PINCTRL_SC8180X + tristate "Qualcomm Technologies Inc SC8180x pin controller driver" + depends on GPIOLIB && OF + select PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm Technologies Inc TLMM block found on the Qualcomm + Technologies Inc SC8180x platform. + config PINCTRL_SDM660 tristate "Qualcomm Technologies Inc SDM660 pin controller driver" depends on GPIOLIB && OF @@ -265,6 +274,15 @@ config PINCTRL_SM8250 Qualcomm Technologies Inc TLMM block found on the Qualcomm Technologies Inc SM8250 platform. +config PINCTRL_SM8350 + tristate "Qualcomm Technologies Inc SM8350 pin controller driver" + depends on GPIOLIB && OF + select PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm Technologies Inc TLMM block found on the Qualcomm + Technologies Inc SM8350 platform. + config PINCTRL_LPASS_LPI tristate "Qualcomm Technologies Inc LPASS LPI pin controller driver" select PINMUX diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 91875a3f5ac4..d4301fbb7274 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -26,9 +26,11 @@ obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-mpp.o obj-$(CONFIG_PINCTRL_SC7180) += pinctrl-sc7180.o obj-$(CONFIG_PINCTRL_SC7280) += pinctrl-sc7280.o +obj-$(CONFIG_PINCTRL_SC8180X) += pinctrl-sc8180x.o obj-$(CONFIG_PINCTRL_SDM660) += pinctrl-sdm660.o obj-$(CONFIG_PINCTRL_SDM845) += pinctrl-sdm845.o obj-$(CONFIG_PINCTRL_SDX55) += pinctrl-sdx55.o obj-$(CONFIG_PINCTRL_SM8150) += pinctrl-sm8150.o obj-$(CONFIG_PINCTRL_SM8250) += pinctrl-sm8250.o +obj-$(CONFIG_PINCTRL_SM8350) += pinctrl-sm8350.o obj-$(CONFIG_PINCTRL_LPASS_LPI) += pinctrl-lpass-lpi.o diff --git a/drivers/pinctrl/qcom/pinctrl-sc8180x.c b/drivers/pinctrl/qcom/pinctrl-sc8180x.c new file mode 100644 index 000000000000..b765bf667574 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-sc8180x.c @@ -0,0 +1,1624 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, Linaro Ltd. + */ + +#include +#include +#include +#include + +#include "pinctrl-msm.h" + +static const char * const sc8180x_tiles[] = { + "south", + "east", + "west" +}; + +enum { + SOUTH, + EAST, + WEST +}; + +#define FUNCTION(fname) \ + [msm_mux_##fname] = { \ + .name = #fname, \ + .groups = fname##_groups, \ + .ngroups = ARRAY_SIZE(fname##_groups), \ + } + +#define REG_SIZE 0x1000 +#define PINGROUP_OFFSET(id, _tile, offset, f1, f2, f3, f4, f5, f6, f7, f8, f9) \ + { \ + .name = "gpio" #id, \ + .pins = gpio##id##_pins, \ + .npins = (unsigned int)ARRAY_SIZE(gpio##id##_pins), \ + .funcs = (int[]){ \ + msm_mux_gpio, /* gpio mode */ \ + msm_mux_##f1, \ + msm_mux_##f2, \ + msm_mux_##f3, \ + msm_mux_##f4, \ + msm_mux_##f5, \ + msm_mux_##f6, \ + msm_mux_##f7, \ + msm_mux_##f8, \ + msm_mux_##f9 \ + }, \ + .nfuncs = 10, \ + .ctl_reg = REG_SIZE * id + offset, \ + .io_reg = REG_SIZE * id + 0x4 + offset, \ + .intr_cfg_reg = REG_SIZE * id + 0x8 + offset, \ + .intr_status_reg = REG_SIZE * id + 0xc + offset,\ + .intr_target_reg = REG_SIZE * id + 0x8 + offset,\ + .tile = _tile, \ + .mux_bit = 2, \ + .pull_bit = 0, \ + .drv_bit = 6, \ + .oe_bit = 9, \ + .in_bit = 0, \ + .out_bit = 1, \ + .intr_enable_bit = 0, \ + .intr_status_bit = 0, \ + .intr_target_bit = 5, \ + .intr_target_kpss_val = 3, \ + .intr_raw_status_bit = 4, \ + .intr_polarity_bit = 1, \ + .intr_detection_bit = 2, \ + .intr_detection_width = 2, \ + } + +#define PINGROUP(id, _tile, f1, f2, f3, f4, f5, f6, f7, f8, f9) \ + PINGROUP_OFFSET(id, _tile, 0x0, f1, f2, f3, f4, f5, f6, f7, f8, f9) + +#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .tile = EAST, \ + .mux_bit = -1, \ + .pull_bit = pull, \ + .drv_bit = drv, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + +#define UFS_RESET(pg_name) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \ + .ctl_reg = 0xb6000, \ + .io_reg = 0xb6004, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .tile = SOUTH, \ + .mux_bit = -1, \ + .pull_bit = 3, \ + .drv_bit = 0, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = 0, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } +static const struct pinctrl_pin_desc sc8180x_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "GPIO_34"), + PINCTRL_PIN(35, "GPIO_35"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GPIO_42"), + PINCTRL_PIN(43, "GPIO_43"), + PINCTRL_PIN(44, "GPIO_44"), + PINCTRL_PIN(45, "GPIO_45"), + PINCTRL_PIN(46, "GPIO_46"), + PINCTRL_PIN(47, "GPIO_47"), + PINCTRL_PIN(48, "GPIO_48"), + PINCTRL_PIN(49, "GPIO_49"), + PINCTRL_PIN(50, "GPIO_50"), + PINCTRL_PIN(51, "GPIO_51"), + PINCTRL_PIN(52, "GPIO_52"), + PINCTRL_PIN(53, "GPIO_53"), + PINCTRL_PIN(54, "GPIO_54"), + PINCTRL_PIN(55, "GPIO_55"), + PINCTRL_PIN(56, "GPIO_56"), + PINCTRL_PIN(57, "GPIO_57"), + PINCTRL_PIN(58, "GPIO_58"), + PINCTRL_PIN(59, "GPIO_59"), + PINCTRL_PIN(60, "GPIO_60"), + PINCTRL_PIN(61, "GPIO_61"), + PINCTRL_PIN(62, "GPIO_62"), + PINCTRL_PIN(63, "GPIO_63"), + PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), + PINCTRL_PIN(69, "GPIO_69"), + PINCTRL_PIN(70, "GPIO_70"), + PINCTRL_PIN(71, "GPIO_71"), + PINCTRL_PIN(72, "GPIO_72"), + PINCTRL_PIN(73, "GPIO_73"), + PINCTRL_PIN(74, "GPIO_74"), + PINCTRL_PIN(75, "GPIO_75"), + PINCTRL_PIN(76, "GPIO_76"), + PINCTRL_PIN(77, "GPIO_77"), + PINCTRL_PIN(78, "GPIO_78"), + PINCTRL_PIN(79, "GPIO_79"), + PINCTRL_PIN(80, "GPIO_80"), + PINCTRL_PIN(81, "GPIO_81"), + PINCTRL_PIN(82, "GPIO_82"), + PINCTRL_PIN(83, "GPIO_83"), + PINCTRL_PIN(84, "GPIO_84"), + PINCTRL_PIN(85, "GPIO_85"), + PINCTRL_PIN(86, "GPIO_86"), + PINCTRL_PIN(87, "GPIO_87"), + PINCTRL_PIN(88, "GPIO_88"), + PINCTRL_PIN(89, "GPIO_89"), + PINCTRL_PIN(90, "GPIO_90"), + PINCTRL_PIN(91, "GPIO_91"), + PINCTRL_PIN(92, "GPIO_92"), + PINCTRL_PIN(93, "GPIO_93"), + PINCTRL_PIN(94, "GPIO_94"), + PINCTRL_PIN(95, "GPIO_95"), + PINCTRL_PIN(96, "GPIO_96"), + PINCTRL_PIN(97, "GPIO_97"), + PINCTRL_PIN(98, "GPIO_98"), + PINCTRL_PIN(99, "GPIO_99"), + PINCTRL_PIN(100, "GPIO_100"), + PINCTRL_PIN(101, "GPIO_101"), + PINCTRL_PIN(102, "GPIO_102"), + PINCTRL_PIN(103, "GPIO_103"), + PINCTRL_PIN(104, "GPIO_104"), + PINCTRL_PIN(105, "GPIO_105"), + PINCTRL_PIN(106, "GPIO_106"), + PINCTRL_PIN(107, "GPIO_107"), + PINCTRL_PIN(108, "GPIO_108"), + PINCTRL_PIN(109, "GPIO_109"), + PINCTRL_PIN(110, "GPIO_110"), + PINCTRL_PIN(111, "GPIO_111"), + PINCTRL_PIN(112, "GPIO_112"), + PINCTRL_PIN(113, "GPIO_113"), + PINCTRL_PIN(114, "GPIO_114"), + PINCTRL_PIN(115, "GPIO_115"), + PINCTRL_PIN(116, "GPIO_116"), + PINCTRL_PIN(117, "GPIO_117"), + PINCTRL_PIN(118, "GPIO_118"), + PINCTRL_PIN(119, "GPIO_119"), + PINCTRL_PIN(120, "GPIO_120"), + PINCTRL_PIN(121, "GPIO_121"), + PINCTRL_PIN(122, "GPIO_122"), + PINCTRL_PIN(123, "GPIO_123"), + PINCTRL_PIN(124, "GPIO_124"), + PINCTRL_PIN(125, "GPIO_125"), + PINCTRL_PIN(126, "GPIO_126"), + PINCTRL_PIN(127, "GPIO_127"), + PINCTRL_PIN(128, "GPIO_128"), + PINCTRL_PIN(129, "GPIO_129"), + PINCTRL_PIN(130, "GPIO_130"), + PINCTRL_PIN(131, "GPIO_131"), + PINCTRL_PIN(132, "GPIO_132"), + PINCTRL_PIN(133, "GPIO_133"), + PINCTRL_PIN(134, "GPIO_134"), + PINCTRL_PIN(135, "GPIO_135"), + PINCTRL_PIN(136, "GPIO_136"), + PINCTRL_PIN(137, "GPIO_137"), + PINCTRL_PIN(138, "GPIO_138"), + PINCTRL_PIN(139, "GPIO_139"), + PINCTRL_PIN(140, "GPIO_140"), + PINCTRL_PIN(141, "GPIO_141"), + PINCTRL_PIN(142, "GPIO_142"), + PINCTRL_PIN(143, "GPIO_143"), + PINCTRL_PIN(144, "GPIO_144"), + PINCTRL_PIN(145, "GPIO_145"), + PINCTRL_PIN(146, "GPIO_146"), + PINCTRL_PIN(147, "GPIO_147"), + PINCTRL_PIN(148, "GPIO_148"), + PINCTRL_PIN(149, "GPIO_149"), + PINCTRL_PIN(150, "GPIO_150"), + PINCTRL_PIN(151, "GPIO_151"), + PINCTRL_PIN(152, "GPIO_152"), + PINCTRL_PIN(153, "GPIO_153"), + PINCTRL_PIN(154, "GPIO_154"), + PINCTRL_PIN(155, "GPIO_155"), + PINCTRL_PIN(156, "GPIO_156"), + PINCTRL_PIN(157, "GPIO_157"), + PINCTRL_PIN(158, "GPIO_158"), + PINCTRL_PIN(159, "GPIO_159"), + PINCTRL_PIN(160, "GPIO_160"), + PINCTRL_PIN(161, "GPIO_161"), + PINCTRL_PIN(162, "GPIO_162"), + PINCTRL_PIN(163, "GPIO_163"), + PINCTRL_PIN(164, "GPIO_164"), + PINCTRL_PIN(165, "GPIO_165"), + PINCTRL_PIN(166, "GPIO_166"), + PINCTRL_PIN(167, "GPIO_167"), + PINCTRL_PIN(168, "GPIO_168"), + PINCTRL_PIN(169, "GPIO_169"), + PINCTRL_PIN(170, "GPIO_170"), + PINCTRL_PIN(171, "GPIO_171"), + PINCTRL_PIN(172, "GPIO_172"), + PINCTRL_PIN(173, "GPIO_173"), + PINCTRL_PIN(174, "GPIO_174"), + PINCTRL_PIN(175, "GPIO_175"), + PINCTRL_PIN(176, "GPIO_176"), + PINCTRL_PIN(177, "GPIO_177"), + PINCTRL_PIN(178, "GPIO_178"), + PINCTRL_PIN(179, "GPIO_179"), + PINCTRL_PIN(180, "GPIO_180"), + PINCTRL_PIN(181, "GPIO_181"), + PINCTRL_PIN(182, "GPIO_182"), + PINCTRL_PIN(183, "GPIO_183"), + PINCTRL_PIN(184, "GPIO_184"), + PINCTRL_PIN(185, "GPIO_185"), + PINCTRL_PIN(186, "GPIO_186"), + PINCTRL_PIN(187, "GPIO_187"), + PINCTRL_PIN(188, "GPIO_188"), + PINCTRL_PIN(189, "GPIO_189"), + PINCTRL_PIN(190, "UFS_RESET"), + PINCTRL_PIN(191, "SDC2_CLK"), + PINCTRL_PIN(192, "SDC2_CMD"), + PINCTRL_PIN(193, "SDC2_DATA"), +}; + +#define DECLARE_MSM_GPIO_PINS(pin) \ + static const unsigned int gpio##pin##_pins[] = { pin } +DECLARE_MSM_GPIO_PINS(0); +DECLARE_MSM_GPIO_PINS(1); +DECLARE_MSM_GPIO_PINS(2); +DECLARE_MSM_GPIO_PINS(3); +DECLARE_MSM_GPIO_PINS(4); +DECLARE_MSM_GPIO_PINS(5); +DECLARE_MSM_GPIO_PINS(6); +DECLARE_MSM_GPIO_PINS(7); +DECLARE_MSM_GPIO_PINS(8); +DECLARE_MSM_GPIO_PINS(9); +DECLARE_MSM_GPIO_PINS(10); +DECLARE_MSM_GPIO_PINS(11); +DECLARE_MSM_GPIO_PINS(12); +DECLARE_MSM_GPIO_PINS(13); +DECLARE_MSM_GPIO_PINS(14); +DECLARE_MSM_GPIO_PINS(15); +DECLARE_MSM_GPIO_PINS(16); +DECLARE_MSM_GPIO_PINS(17); +DECLARE_MSM_GPIO_PINS(18); +DECLARE_MSM_GPIO_PINS(19); +DECLARE_MSM_GPIO_PINS(20); +DECLARE_MSM_GPIO_PINS(21); +DECLARE_MSM_GPIO_PINS(22); +DECLARE_MSM_GPIO_PINS(23); +DECLARE_MSM_GPIO_PINS(24); +DECLARE_MSM_GPIO_PINS(25); +DECLARE_MSM_GPIO_PINS(26); +DECLARE_MSM_GPIO_PINS(27); +DECLARE_MSM_GPIO_PINS(28); +DECLARE_MSM_GPIO_PINS(29); +DECLARE_MSM_GPIO_PINS(30); +DECLARE_MSM_GPIO_PINS(31); +DECLARE_MSM_GPIO_PINS(32); +DECLARE_MSM_GPIO_PINS(33); +DECLARE_MSM_GPIO_PINS(34); +DECLARE_MSM_GPIO_PINS(35); +DECLARE_MSM_GPIO_PINS(36); +DECLARE_MSM_GPIO_PINS(37); +DECLARE_MSM_GPIO_PINS(38); +DECLARE_MSM_GPIO_PINS(39); +DECLARE_MSM_GPIO_PINS(40); +DECLARE_MSM_GPIO_PINS(41); +DECLARE_MSM_GPIO_PINS(42); +DECLARE_MSM_GPIO_PINS(43); +DECLARE_MSM_GPIO_PINS(44); +DECLARE_MSM_GPIO_PINS(45); +DECLARE_MSM_GPIO_PINS(46); +DECLARE_MSM_GPIO_PINS(47); +DECLARE_MSM_GPIO_PINS(48); +DECLARE_MSM_GPIO_PINS(49); +DECLARE_MSM_GPIO_PINS(50); +DECLARE_MSM_GPIO_PINS(51); +DECLARE_MSM_GPIO_PINS(52); +DECLARE_MSM_GPIO_PINS(53); +DECLARE_MSM_GPIO_PINS(54); +DECLARE_MSM_GPIO_PINS(55); +DECLARE_MSM_GPIO_PINS(56); +DECLARE_MSM_GPIO_PINS(57); +DECLARE_MSM_GPIO_PINS(58); +DECLARE_MSM_GPIO_PINS(59); +DECLARE_MSM_GPIO_PINS(60); +DECLARE_MSM_GPIO_PINS(61); +DECLARE_MSM_GPIO_PINS(62); +DECLARE_MSM_GPIO_PINS(63); +DECLARE_MSM_GPIO_PINS(64); +DECLARE_MSM_GPIO_PINS(65); +DECLARE_MSM_GPIO_PINS(66); +DECLARE_MSM_GPIO_PINS(67); +DECLARE_MSM_GPIO_PINS(68); +DECLARE_MSM_GPIO_PINS(69); +DECLARE_MSM_GPIO_PINS(70); +DECLARE_MSM_GPIO_PINS(71); +DECLARE_MSM_GPIO_PINS(72); +DECLARE_MSM_GPIO_PINS(73); +DECLARE_MSM_GPIO_PINS(74); +DECLARE_MSM_GPIO_PINS(75); +DECLARE_MSM_GPIO_PINS(76); +DECLARE_MSM_GPIO_PINS(77); +DECLARE_MSM_GPIO_PINS(78); +DECLARE_MSM_GPIO_PINS(79); +DECLARE_MSM_GPIO_PINS(80); +DECLARE_MSM_GPIO_PINS(81); +DECLARE_MSM_GPIO_PINS(82); +DECLARE_MSM_GPIO_PINS(83); +DECLARE_MSM_GPIO_PINS(84); +DECLARE_MSM_GPIO_PINS(85); +DECLARE_MSM_GPIO_PINS(86); +DECLARE_MSM_GPIO_PINS(87); +DECLARE_MSM_GPIO_PINS(88); +DECLARE_MSM_GPIO_PINS(89); +DECLARE_MSM_GPIO_PINS(90); +DECLARE_MSM_GPIO_PINS(91); +DECLARE_MSM_GPIO_PINS(92); +DECLARE_MSM_GPIO_PINS(93); +DECLARE_MSM_GPIO_PINS(94); +DECLARE_MSM_GPIO_PINS(95); +DECLARE_MSM_GPIO_PINS(96); +DECLARE_MSM_GPIO_PINS(97); +DECLARE_MSM_GPIO_PINS(98); +DECLARE_MSM_GPIO_PINS(99); +DECLARE_MSM_GPIO_PINS(100); +DECLARE_MSM_GPIO_PINS(101); +DECLARE_MSM_GPIO_PINS(102); +DECLARE_MSM_GPIO_PINS(103); +DECLARE_MSM_GPIO_PINS(104); +DECLARE_MSM_GPIO_PINS(105); +DECLARE_MSM_GPIO_PINS(106); +DECLARE_MSM_GPIO_PINS(107); +DECLARE_MSM_GPIO_PINS(108); +DECLARE_MSM_GPIO_PINS(109); +DECLARE_MSM_GPIO_PINS(110); +DECLARE_MSM_GPIO_PINS(111); +DECLARE_MSM_GPIO_PINS(112); +DECLARE_MSM_GPIO_PINS(113); +DECLARE_MSM_GPIO_PINS(114); +DECLARE_MSM_GPIO_PINS(115); +DECLARE_MSM_GPIO_PINS(116); +DECLARE_MSM_GPIO_PINS(117); +DECLARE_MSM_GPIO_PINS(118); +DECLARE_MSM_GPIO_PINS(119); +DECLARE_MSM_GPIO_PINS(120); +DECLARE_MSM_GPIO_PINS(121); +DECLARE_MSM_GPIO_PINS(122); +DECLARE_MSM_GPIO_PINS(123); +DECLARE_MSM_GPIO_PINS(124); +DECLARE_MSM_GPIO_PINS(125); +DECLARE_MSM_GPIO_PINS(126); +DECLARE_MSM_GPIO_PINS(127); +DECLARE_MSM_GPIO_PINS(128); +DECLARE_MSM_GPIO_PINS(129); +DECLARE_MSM_GPIO_PINS(130); +DECLARE_MSM_GPIO_PINS(131); +DECLARE_MSM_GPIO_PINS(132); +DECLARE_MSM_GPIO_PINS(133); +DECLARE_MSM_GPIO_PINS(134); +DECLARE_MSM_GPIO_PINS(135); +DECLARE_MSM_GPIO_PINS(136); +DECLARE_MSM_GPIO_PINS(137); +DECLARE_MSM_GPIO_PINS(138); +DECLARE_MSM_GPIO_PINS(139); +DECLARE_MSM_GPIO_PINS(140); +DECLARE_MSM_GPIO_PINS(141); +DECLARE_MSM_GPIO_PINS(142); +DECLARE_MSM_GPIO_PINS(143); +DECLARE_MSM_GPIO_PINS(144); +DECLARE_MSM_GPIO_PINS(145); +DECLARE_MSM_GPIO_PINS(146); +DECLARE_MSM_GPIO_PINS(147); +DECLARE_MSM_GPIO_PINS(148); +DECLARE_MSM_GPIO_PINS(149); +DECLARE_MSM_GPIO_PINS(150); +DECLARE_MSM_GPIO_PINS(151); +DECLARE_MSM_GPIO_PINS(152); +DECLARE_MSM_GPIO_PINS(153); +DECLARE_MSM_GPIO_PINS(154); +DECLARE_MSM_GPIO_PINS(155); +DECLARE_MSM_GPIO_PINS(156); +DECLARE_MSM_GPIO_PINS(157); +DECLARE_MSM_GPIO_PINS(158); +DECLARE_MSM_GPIO_PINS(159); +DECLARE_MSM_GPIO_PINS(160); +DECLARE_MSM_GPIO_PINS(161); +DECLARE_MSM_GPIO_PINS(162); +DECLARE_MSM_GPIO_PINS(163); +DECLARE_MSM_GPIO_PINS(164); +DECLARE_MSM_GPIO_PINS(165); +DECLARE_MSM_GPIO_PINS(166); +DECLARE_MSM_GPIO_PINS(167); +DECLARE_MSM_GPIO_PINS(168); +DECLARE_MSM_GPIO_PINS(169); +DECLARE_MSM_GPIO_PINS(170); +DECLARE_MSM_GPIO_PINS(171); +DECLARE_MSM_GPIO_PINS(172); +DECLARE_MSM_GPIO_PINS(173); +DECLARE_MSM_GPIO_PINS(174); +DECLARE_MSM_GPIO_PINS(175); +DECLARE_MSM_GPIO_PINS(176); +DECLARE_MSM_GPIO_PINS(177); +DECLARE_MSM_GPIO_PINS(178); +DECLARE_MSM_GPIO_PINS(179); +DECLARE_MSM_GPIO_PINS(180); +DECLARE_MSM_GPIO_PINS(181); +DECLARE_MSM_GPIO_PINS(182); +DECLARE_MSM_GPIO_PINS(183); +DECLARE_MSM_GPIO_PINS(184); +DECLARE_MSM_GPIO_PINS(185); +DECLARE_MSM_GPIO_PINS(186); +DECLARE_MSM_GPIO_PINS(187); +DECLARE_MSM_GPIO_PINS(188); +DECLARE_MSM_GPIO_PINS(189); + +static const unsigned int sdc2_clk_pins[] = { 190 }; +static const unsigned int sdc2_cmd_pins[] = { 191 }; +static const unsigned int sdc2_data_pins[] = { 192 }; +static const unsigned int ufs_reset_pins[] = { 193 }; + +enum sc8180x_functions { + msm_mux_adsp_ext, + msm_mux_agera_pll, + msm_mux_aoss_cti, + msm_mux_atest_char, + msm_mux_atest_tsens, + msm_mux_atest_tsens2, + msm_mux_atest_usb0, + msm_mux_atest_usb1, + msm_mux_atest_usb2, + msm_mux_atest_usb3, + msm_mux_atest_usb4, + msm_mux_audio_ref, + msm_mux_btfm_slimbus, + msm_mux_cam_mclk, + msm_mux_cci_async, + msm_mux_cci_i2c, + msm_mux_cci_timer0, + msm_mux_cci_timer1, + msm_mux_cci_timer2, + msm_mux_cci_timer3, + msm_mux_cci_timer4, + msm_mux_cci_timer5, + msm_mux_cci_timer6, + msm_mux_cci_timer7, + msm_mux_cci_timer8, + msm_mux_cci_timer9, + msm_mux_cri_trng, + msm_mux_dbg_out, + msm_mux_ddr_bist, + msm_mux_ddr_pxi, + msm_mux_debug_hot, + msm_mux_dp_hot, + msm_mux_edp_hot, + msm_mux_edp_lcd, + msm_mux_emac_phy, + msm_mux_emac_pps, + msm_mux_gcc_gp1, + msm_mux_gcc_gp2, + msm_mux_gcc_gp3, + msm_mux_gcc_gp4, + msm_mux_gcc_gp5, + msm_mux_gpio, + msm_mux_gps, + msm_mux_grfc, + msm_mux_hs1_mi2s, + msm_mux_hs2_mi2s, + msm_mux_hs3_mi2s, + msm_mux_jitter_bist, + msm_mux_lpass_slimbus, + msm_mux_m_voc, + msm_mux_mdp_vsync, + msm_mux_mdp_vsync0, + msm_mux_mdp_vsync1, + msm_mux_mdp_vsync2, + msm_mux_mdp_vsync3, + msm_mux_mdp_vsync4, + msm_mux_mdp_vsync5, + msm_mux_mss_lte, + msm_mux_nav_pps, + msm_mux_pa_indicator, + msm_mux_pci_e0, + msm_mux_pci_e1, + msm_mux_pci_e2, + msm_mux_pci_e3, + msm_mux_phase_flag, + msm_mux_pll_bist, + msm_mux_pll_bypassnl, + msm_mux_pll_reset, + msm_mux_pri_mi2s, + msm_mux_pri_mi2s_ws, + msm_mux_prng_rosc, + msm_mux_qdss_cti, + msm_mux_qdss_gpio, + msm_mux_qlink, + msm_mux_qspi0, + msm_mux_qspi0_clk, + msm_mux_qspi0_cs, + msm_mux_qspi1, + msm_mux_qspi1_clk, + msm_mux_qspi1_cs, + msm_mux_qua_mi2s, + msm_mux_qup0, + msm_mux_qup1, + msm_mux_qup2, + msm_mux_qup3, + msm_mux_qup4, + msm_mux_qup5, + msm_mux_qup6, + msm_mux_qup7, + msm_mux_qup8, + msm_mux_qup9, + msm_mux_qup10, + msm_mux_qup11, + msm_mux_qup12, + msm_mux_qup13, + msm_mux_qup14, + msm_mux_qup15, + msm_mux_qup16, + msm_mux_qup17, + msm_mux_qup18, + msm_mux_qup19, + msm_mux_qup_l4, + msm_mux_qup_l5, + msm_mux_qup_l6, + msm_mux_rgmii, + msm_mux_sd_write, + msm_mux_sdc4, + msm_mux_sdc4_clk, + msm_mux_sdc4_cmd, + msm_mux_sec_mi2s, + msm_mux_sp_cmu, + msm_mux_spkr_i2s, + msm_mux_ter_mi2s, + msm_mux_tgu, + msm_mux_tsense_pwm1, + msm_mux_tsense_pwm2, + msm_mux_tsif1, + msm_mux_tsif2, + msm_mux_uim1, + msm_mux_uim2, + msm_mux_uim_batt, + msm_mux_usb0_phy, + msm_mux_usb1_phy, + msm_mux_usb2phy_ac, + msm_mux_vfr_1, + msm_mux_vsense_trigger, + msm_mux_wlan1_adc, + msm_mux_wlan2_adc, + msm_mux_wmss_reset, + msm_mux__, +}; + +static const char * const adsp_ext_groups[] = { + "gpio115", +}; + +static const char * const agera_pll_groups[] = { + "gpio37", +}; + +static const char * const aoss_cti_groups[] = { + "gpio113", +}; + +static const char * const atest_char_groups[] = { + "gpio133", "gpio134", "gpio135", "gpio140", "gpio142", +}; + +static const char * const atest_tsens2_groups[] = { + "gpio62", +}; + +static const char * const atest_tsens_groups[] = { + "gpio93", +}; + +static const char * const atest_usb0_groups[] = { + "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", +}; + +static const char * const atest_usb1_groups[] = { + "gpio60", "gpio62", "gpio63", "gpio64", "gpio65", +}; + +static const char * const atest_usb2_groups[] = { + "gpio34", "gpio95", "gpio102", "gpio121", "gpio122", +}; + +static const char * const atest_usb3_groups[] = { + "gpio68", "gpio71", "gpio72", "gpio73", "gpio74", +}; + +static const char * const atest_usb4_groups[] = { + "gpio75", "gpio76", "gpio77", "gpio78", "gpio88", +}; + +static const char * const audio_ref_groups[] = { + "gpio148", +}; + +static const char * const btfm_slimbus_groups[] = { + "gpio153", "gpio154", +}; + +static const char * const cam_mclk_groups[] = { + "gpio13", "gpio14", "gpio15", "gpio16", "gpio25", "gpio179", "gpio180", + "gpio181", +}; + +static const char * const cci_async_groups[] = { + "gpio24", "gpio25", "gpio26", "gpio176", "gpio185", "gpio186", +}; + +static const char * const cci_i2c_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio17", "gpio18", "gpio19", + "gpio20", "gpio31", "gpio32", "gpio33", "gpio34", "gpio39", "gpio40", + "gpio41", "gpio42", +}; + +static const char * const cci_timer0_groups[] = { + "gpio21", +}; + +static const char * const cci_timer1_groups[] = { + "gpio22", +}; + +static const char * const cci_timer2_groups[] = { + "gpio23", +}; + +static const char * const cci_timer3_groups[] = { + "gpio24", +}; + +static const char * const cci_timer4_groups[] = { + "gpio178", +}; + +static const char * const cci_timer5_groups[] = { + "gpio182", +}; + +static const char * const cci_timer6_groups[] = { + "gpio183", +}; + +static const char * const cci_timer7_groups[] = { + "gpio184", +}; + +static const char * const cci_timer8_groups[] = { + "gpio185", +}; + +static const char * const cci_timer9_groups[] = { + "gpio186", +}; + +static const char * const cri_trng_groups[] = { + "gpio159", + "gpio160", + "gpio161", +}; + +static const char * const dbg_out_groups[] = { + "gpio34", +}; + +static const char * const ddr_bist_groups[] = { + "gpio98", "gpio99", "gpio145", "gpio146", +}; + +static const char * const ddr_pxi_groups[] = { + "gpio60", "gpio62", "gpio63", "gpio64", "gpio65", "gpio68", "gpio71", + "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", "gpio78", + "gpio88", "gpio90", +}; + +static const char * const debug_hot_groups[] = { + "gpio7", +}; + +static const char * const dp_hot_groups[] = { + "gpio189", +}; + +static const char * const edp_hot_groups[] = { + "gpio10", +}; + +static const char * const edp_lcd_groups[] = { + "gpio11", +}; + +static const char * const emac_phy_groups[] = { + "gpio124", +}; + +static const char * const emac_pps_groups[] = { + "gpio81", +}; + +static const char * const gcc_gp1_groups[] = { + "gpio131", "gpio136", +}; + +static const char * const gcc_gp2_groups[] = { + "gpio21", "gpio137", +}; + +static const char * const gcc_gp3_groups[] = { + "gpio22", "gpio138", +}; + +static const char * const gcc_gp4_groups[] = { + "gpio139", "gpio182", +}; + +static const char * const gcc_gp5_groups[] = { + "gpio140", "gpio183", +}; + +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio12", "gpio13", + "gpio14", "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", + "gpio21", "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", + "gpio28", "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", + "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", + "gpio42", "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", + "gpio49", "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", + "gpio56", "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", + "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", + "gpio70", "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", + "gpio77", "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", + "gpio84", "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", + "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", + "gpio98", "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", + "gpio104", "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", + "gpio110", "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", + "gpio116", "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", + "gpio122", "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", + "gpio128", "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", + "gpio134", "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", + "gpio140", "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", + "gpio146", "gpio147", "gpio148", "gpio149", "gpio150", "gpio151", + "gpio152", "gpio153", "gpio154", "gpio155", "gpio156", "gpio157", + "gpio158", "gpio159", "gpio160", "gpio161", "gpio162", "gpio163", + "gpio164", "gpio165", "gpio166", "gpio167", "gpio168", "gpio169", + "gpio170", "gpio171", "gpio172", "gpio173", "gpio174", "gpio175", + "gpio176", "gpio177", "gpio177", "gpio178", "gpio179", "gpio180", + "gpio181", "gpio182", "gpio183", "gpio184", "gpio185", "gpio186", + "gpio186", "gpio187", "gpio187", "gpio188", "gpio188", "gpio189", +}; + +static const char * const gps_groups[] = { + "gpio60", "gpio76", "gpio77", "gpio81", "gpio82", +}; + +static const char * const grfc_groups[] = { + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio71", "gpio72", + "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", "gpio78", "gpio79", + "gpio80", "gpio81", "gpio82", +}; + +static const char * const hs1_mi2s_groups[] = { + "gpio155", "gpio156", "gpio157", "gpio158", "gpio159", +}; + +static const char * const hs2_mi2s_groups[] = { + "gpio160", "gpio161", "gpio162", "gpio163", "gpio164", +}; + +static const char * const hs3_mi2s_groups[] = { + "gpio125", "gpio165", "gpio166", "gpio167", "gpio168", +}; + +static const char * const jitter_bist_groups[] = { + "gpio129", +}; + +static const char * const lpass_slimbus_groups[] = { + "gpio149", "gpio150", "gpio151", "gpio152", +}; + +static const char * const m_voc_groups[] = { + "gpio10", +}; + +static const char * const mdp_vsync0_groups[] = { + "gpio89", +}; + +static const char * const mdp_vsync1_groups[] = { + "gpio89", +}; + +static const char * const mdp_vsync2_groups[] = { + "gpio89", +}; + +static const char * const mdp_vsync3_groups[] = { + "gpio89", +}; + +static const char * const mdp_vsync4_groups[] = { + "gpio89", +}; + +static const char * const mdp_vsync5_groups[] = { + "gpio89", +}; + +static const char * const mdp_vsync_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio60", "gpio82", +}; + +static const char * const mss_lte_groups[] = { + "gpio69", "gpio70", +}; + +static const char * const nav_pps_groups[] = { + "gpio60", "gpio60", "gpio76", "gpio76", "gpio77", "gpio77", "gpio81", + "gpio81", "gpio82", "gpio82", +}; + +static const char * const pa_indicator_groups[] = { + "gpio68", +}; + +static const char * const pci_e0_groups[] = { + "gpio35", "gpio36", +}; + +static const char * const pci_e1_groups[] = { + "gpio102", "gpio103", +}; + +static const char * const pci_e2_groups[] = { + "gpio175", "gpio176", +}; + +static const char * const pci_e3_groups[] = { + "gpio178", "gpio179", +}; + +static const char * const phase_flag_groups[] = { + "gpio4", "gpio5", "gpio6", "gpio7", "gpio33", "gpio53", "gpio54", + "gpio102", "gpio120", "gpio121", "gpio122", "gpio123", "gpio125", + "gpio148", "gpio149", "gpio150", "gpio151", "gpio152", "gpio155", + "gpio156", "gpio157", "gpio158", "gpio159", "gpio160", "gpio161", + "gpio162", "gpio163", "gpio164", "gpio165", "gpio166", "gpio167", + "gpio168", +}; + +static const char * const pll_bist_groups[] = { + "gpio130", +}; + +static const char * const pll_bypassnl_groups[] = { + "gpio100", +}; + +static const char * const pll_reset_groups[] = { + "gpio101", +}; + +static const char * const pri_mi2s_groups[] = { + "gpio143", "gpio144", "gpio146", "gpio147", +}; + +static const char * const pri_mi2s_ws_groups[] = { + "gpio145", +}; + +static const char * const prng_rosc_groups[] = { + "gpio163", +}; + +static const char * const qdss_cti_groups[] = { + "gpio49", "gpio50", "gpio81", "gpio82", "gpio89", "gpio90", "gpio141", + "gpio142", +}; + +static const char * const qdss_gpio_groups[] = { + "gpio13", "gpio14", "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", + "gpio20", "gpio21", "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", + "gpio27", "gpio28", "gpio29", "gpio30", "gpio39", "gpio40", "gpio41", + "gpio42", "gpio92", "gpio114", "gpio115", "gpio116", "gpio117", + "gpio118", "gpio119", "gpio120", "gpio121", "gpio130", "gpio132", + "gpio133", "gpio134", "gpio135", +}; + +static const char * const qlink_groups[] = { + "gpio61", "gpio62", +}; + +static const char * const qspi0_groups[] = { + "gpio89", "gpio90", "gpio91", "gpio93", +}; + +static const char * const qspi0_clk_groups[] = { + "gpio92", +}; + +static const char * const qspi0_cs_groups[] = { + "gpio88", "gpio94", +}; + +static const char * const qspi1_groups[] = { + "gpio56", "gpio57", "gpio161", "gpio162", +}; + +static const char * const qspi1_clk_groups[] = { + "gpio163", +}; + +static const char * const qspi1_cs_groups[] = { + "gpio55", "gpio164", +}; + +static const char * const qua_mi2s_groups[] = { + "gpio136", "gpio137", "gpio138", "gpio139", "gpio140", "gpio141", + "gpio142", +}; + +static const char * const qup0_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", +}; + +static const char * const qup10_groups[] = { + "gpio9", "gpio10", "gpio11", "gpio12", +}; + +static const char * const qup11_groups[] = { + "gpio92", "gpio93", "gpio94", "gpio95", +}; + +static const char * const qup12_groups[] = { + "gpio83", "gpio84", "gpio85", "gpio86", +}; + +static const char * const qup13_groups[] = { + "gpio43", "gpio44", "gpio45", "gpio46", +}; + +static const char * const qup14_groups[] = { + "gpio47", "gpio48", "gpio49", "gpio50", +}; + +static const char * const qup15_groups[] = { + "gpio27", "gpio28", "gpio29", "gpio30", +}; + +static const char * const qup16_groups[] = { + "gpio83", "gpio84", "gpio85", "gpio86", +}; + +static const char * const qup17_groups[] = { + "gpio55", "gpio56", "gpio57", "gpio58", +}; + +static const char * const qup18_groups[] = { + "gpio23", "gpio24", "gpio25", "gpio26", +}; + +static const char * const qup19_groups[] = { + "gpio181", "gpio182", "gpio183", "gpio184", +}; + +static const char * const qup1_groups[] = { + "gpio114", "gpio115", "gpio116", "gpio117", +}; + +static const char * const qup2_groups[] = { + "gpio126", "gpio127", "gpio128", "gpio129", +}; + +static const char * const qup3_groups[] = { + "gpio144", "gpio145", "gpio146", "gpio147", +}; + +static const char * const qup4_groups[] = { + "gpio51", "gpio52", "gpio53", "gpio54", +}; + +static const char * const qup5_groups[] = { + "gpio119", "gpio120", "gpio121", "gpio122", +}; + +static const char * const qup6_groups[] = { + "gpio4", "gpio5", "gpio6", "gpio7", +}; + +static const char * const qup7_groups[] = { + "gpio98", "gpio99", "gpio100", "gpio101", +}; + +static const char * const qup8_groups[] = { + "gpio88", "gpio89", "gpio90", "gpio91", +}; + +static const char * const qup9_groups[] = { + "gpio39", "gpio40", "gpio41", "gpio42", +}; + +static const char * const qup_l4_groups[] = { + "gpio35", "gpio59", "gpio60", "gpio95", +}; + +static const char * const qup_l5_groups[] = { + "gpio7", "gpio33", "gpio36", "gpio96", +}; + +static const char * const qup_l6_groups[] = { + "gpio6", "gpio34", "gpio37", "gpio97", +}; + +static const char * const rgmii_groups[] = { + "gpio4", "gpio5", "gpio6", "gpio7", "gpio59", "gpio114", "gpio115", + "gpio116", "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", + "gpio122", +}; + +static const char * const sd_write_groups[] = { + "gpio97", +}; + +static const char * const sdc4_groups[] = { + "gpio91", "gpio93", "gpio94", "gpio95", +}; + +static const char * const sdc4_clk_groups[] = { + "gpio92", +}; + +static const char * const sdc4_cmd_groups[] = { + "gpio90", +}; + +static const char * const sec_mi2s_groups[] = { + "gpio126", "gpio127", "gpio128", "gpio129", "gpio130", +}; + +static const char * const sp_cmu_groups[] = { + "gpio162", +}; + +static const char * const spkr_i2s_groups[] = { + "gpio148", "gpio149", "gpio150", "gpio151", "gpio152", +}; + +static const char * const ter_mi2s_groups[] = { + "gpio131", "gpio132", "gpio133", "gpio134", "gpio135", +}; + +static const char * const tgu_groups[] = { + "gpio89", "gpio90", "gpio91", "gpio88", "gpio74", "gpio77", "gpio76", + "gpio75", +}; + +static const char * const tsense_pwm1_groups[] = { + "gpio150", +}; + +static const char * const tsense_pwm2_groups[] = { + "gpio150", +}; + +static const char * const tsif1_groups[] = { + "gpio88", "gpio89", "gpio90", "gpio91", "gpio97", +}; + +static const char * const tsif2_groups[] = { + "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", +}; + +static const char * const uim1_groups[] = { + "gpio109", "gpio110", "gpio111", "gpio112", +}; + +static const char * const uim2_groups[] = { + "gpio105", "gpio106", "gpio107", "gpio108", +}; + +static const char * const uim_batt_groups[] = { + "gpio113", +}; + +static const char * const usb0_phy_groups[] = { + "gpio38", +}; + +static const char * const usb1_phy_groups[] = { + "gpio58", +}; + +static const char * const usb2phy_ac_groups[] = { + "gpio47", "gpio48", "gpio113", "gpio123", +}; + +static const char * const vfr_1_groups[] = { + "gpio91", +}; + +static const char * const vsense_trigger_groups[] = { + "gpio62", +}; + +static const char * const wlan1_adc_groups[] = { + "gpio64", "gpio63", +}; + +static const char * const wlan2_adc_groups[] = { + "gpio68", "gpio65", +}; + +static const char * const wmss_reset_groups[] = { + "gpio63", +}; + +static const struct msm_function sc8180x_functions[] = { + FUNCTION(adsp_ext), + FUNCTION(agera_pll), + FUNCTION(aoss_cti), + FUNCTION(atest_char), + FUNCTION(atest_tsens), + FUNCTION(atest_tsens2), + FUNCTION(atest_usb0), + FUNCTION(atest_usb1), + FUNCTION(atest_usb2), + FUNCTION(atest_usb3), + FUNCTION(atest_usb4), + FUNCTION(audio_ref), + FUNCTION(btfm_slimbus), + FUNCTION(cam_mclk), + FUNCTION(cci_async), + FUNCTION(cci_i2c), + FUNCTION(cci_timer0), + FUNCTION(cci_timer1), + FUNCTION(cci_timer2), + FUNCTION(cci_timer3), + FUNCTION(cci_timer4), + FUNCTION(cci_timer5), + FUNCTION(cci_timer6), + FUNCTION(cci_timer7), + FUNCTION(cci_timer8), + FUNCTION(cci_timer9), + FUNCTION(cri_trng), + FUNCTION(dbg_out), + FUNCTION(ddr_bist), + FUNCTION(ddr_pxi), + FUNCTION(debug_hot), + FUNCTION(dp_hot), + FUNCTION(edp_hot), + FUNCTION(edp_lcd), + FUNCTION(emac_phy), + FUNCTION(emac_pps), + FUNCTION(gcc_gp1), + FUNCTION(gcc_gp2), + FUNCTION(gcc_gp3), + FUNCTION(gcc_gp4), + FUNCTION(gcc_gp5), + FUNCTION(gpio), + FUNCTION(gps), + FUNCTION(grfc), + FUNCTION(hs1_mi2s), + FUNCTION(hs2_mi2s), + FUNCTION(hs3_mi2s), + FUNCTION(jitter_bist), + FUNCTION(lpass_slimbus), + FUNCTION(m_voc), + FUNCTION(mdp_vsync), + FUNCTION(mdp_vsync0), + FUNCTION(mdp_vsync1), + FUNCTION(mdp_vsync2), + FUNCTION(mdp_vsync3), + FUNCTION(mdp_vsync4), + FUNCTION(mdp_vsync5), + FUNCTION(mss_lte), + FUNCTION(nav_pps), + FUNCTION(pa_indicator), + FUNCTION(pci_e0), + FUNCTION(pci_e1), + FUNCTION(pci_e2), + FUNCTION(pci_e3), + FUNCTION(phase_flag), + FUNCTION(pll_bist), + FUNCTION(pll_bypassnl), + FUNCTION(pll_reset), + FUNCTION(pri_mi2s), + FUNCTION(pri_mi2s_ws), + FUNCTION(prng_rosc), + FUNCTION(qdss_cti), + FUNCTION(qdss_gpio), + FUNCTION(qlink), + FUNCTION(qspi0), + FUNCTION(qspi0_clk), + FUNCTION(qspi0_cs), + FUNCTION(qspi1), + FUNCTION(qspi1_clk), + FUNCTION(qspi1_cs), + FUNCTION(qua_mi2s), + FUNCTION(qup0), + FUNCTION(qup1), + FUNCTION(qup2), + FUNCTION(qup3), + FUNCTION(qup4), + FUNCTION(qup5), + FUNCTION(qup6), + FUNCTION(qup7), + FUNCTION(qup8), + FUNCTION(qup9), + FUNCTION(qup10), + FUNCTION(qup11), + FUNCTION(qup12), + FUNCTION(qup13), + FUNCTION(qup14), + FUNCTION(qup15), + FUNCTION(qup16), + FUNCTION(qup17), + FUNCTION(qup18), + FUNCTION(qup19), + FUNCTION(qup_l4), + FUNCTION(qup_l5), + FUNCTION(qup_l6), + FUNCTION(rgmii), + FUNCTION(sd_write), + FUNCTION(sdc4), + FUNCTION(sdc4_clk), + FUNCTION(sdc4_cmd), + FUNCTION(sec_mi2s), + FUNCTION(sp_cmu), + FUNCTION(spkr_i2s), + FUNCTION(ter_mi2s), + FUNCTION(tgu), + FUNCTION(tsense_pwm1), + FUNCTION(tsense_pwm2), + FUNCTION(tsif1), + FUNCTION(tsif2), + FUNCTION(uim1), + FUNCTION(uim2), + FUNCTION(uim_batt), + FUNCTION(usb0_phy), + FUNCTION(usb1_phy), + FUNCTION(usb2phy_ac), + FUNCTION(vfr_1), + FUNCTION(vsense_trigger), + FUNCTION(wlan1_adc), + FUNCTION(wlan2_adc), + FUNCTION(wmss_reset), +}; + +/* Every pin is maintained as a single group, and missing or non-existing pin + * would be maintained as dummy group to synchronize pin group index with + * pin descriptor registered with pinctrl core. + * Clients would not be able to request these dummy pin groups. + */ +static const struct msm_pingroup sc8180x_groups[] = { + [0] = PINGROUP(0, WEST, qup0, cci_i2c, _, _, _, _, _, _, _), + [1] = PINGROUP(1, WEST, qup0, cci_i2c, _, _, _, _, _, _, _), + [2] = PINGROUP(2, WEST, qup0, cci_i2c, _, _, _, _, _, _, _), + [3] = PINGROUP(3, WEST, qup0, cci_i2c, _, _, _, _, _, _, _), + [4] = PINGROUP(4, WEST, qup6, rgmii, _, phase_flag, _, _, _, _, _), + [5] = PINGROUP(5, WEST, qup6, rgmii, _, phase_flag, _, _, _, _, _), + [6] = PINGROUP(6, WEST, qup6, rgmii, qup_l6, _, phase_flag, _, _, _, _), + [7] = PINGROUP(7, WEST, qup6, debug_hot, rgmii, qup_l5, _, phase_flag, _, _, _), + [8] = PINGROUP(8, EAST, mdp_vsync, _, _, _, _, _, _, _, _), + [9] = PINGROUP(9, EAST, mdp_vsync, qup10, _, _, _, _, _, _, _), + [10] = PINGROUP(10, EAST, edp_hot, m_voc, mdp_vsync, qup10, _, _, _, _, _), + [11] = PINGROUP(11, EAST, edp_lcd, qup10, _, _, _, _, _, _, _), + [12] = PINGROUP(12, EAST, qup10, _, _, _, _, _, _, _, _), + [13] = PINGROUP(13, EAST, cam_mclk, qdss_gpio, _, _, _, _, _, _, _), + [14] = PINGROUP(14, EAST, cam_mclk, qdss_gpio, _, _, _, _, _, _, _), + [15] = PINGROUP(15, EAST, cam_mclk, qdss_gpio, _, _, _, _, _, _, _), + [16] = PINGROUP(16, EAST, cam_mclk, qdss_gpio, _, _, _, _, _, _, _), + [17] = PINGROUP(17, EAST, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [18] = PINGROUP(18, EAST, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [19] = PINGROUP(19, EAST, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [20] = PINGROUP(20, EAST, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [21] = PINGROUP(21, EAST, cci_timer0, gcc_gp2, qdss_gpio, _, _, _, _, _, _), + [22] = PINGROUP(22, EAST, cci_timer1, gcc_gp3, qdss_gpio, _, _, _, _, _, _), + [23] = PINGROUP(23, EAST, cci_timer2, qup18, qdss_gpio, _, _, _, _, _, _), + [24] = PINGROUP(24, EAST, cci_timer3, cci_async, qup18, qdss_gpio, _, _, _, _, _), + [25] = PINGROUP(25, EAST, cam_mclk, cci_async, qup18, qdss_gpio, _, _, _, _, _), + [26] = PINGROUP(26, EAST, cci_async, qup18, qdss_gpio, _, _, _, _, _, _), + [27] = PINGROUP(27, EAST, qup15, _, qdss_gpio, _, _, _, _, _, _), + [28] = PINGROUP(28, EAST, qup15, qdss_gpio, _, _, _, _, _, _, _), + [29] = PINGROUP(29, EAST, qup15, qdss_gpio, _, _, _, _, _, _, _), + [30] = PINGROUP(30, EAST, qup15, qdss_gpio, _, _, _, _, _, _, _), + [31] = PINGROUP(31, EAST, cci_i2c, _, _, _, _, _, _, _, _), + [32] = PINGROUP(32, EAST, cci_i2c, _, _, _, _, _, _, _, _), + [33] = PINGROUP(33, EAST, cci_i2c, qup_l5, _, phase_flag, _, _, _, _, _), + [34] = PINGROUP(34, EAST, cci_i2c, qup_l6, dbg_out, atest_usb2, _, _, _, _, _), + [35] = PINGROUP(35, SOUTH, pci_e0, qup_l4, _, _, _, _, _, _, _), + [36] = PINGROUP(36, SOUTH, pci_e0, qup_l5, _, _, _, _, _, _, _), + [37] = PINGROUP(37, SOUTH, qup_l6, agera_pll, _, _, _, _, _, _, _), + [38] = PINGROUP(38, SOUTH, usb0_phy, _, _, _, _, _, _, _, _), + [39] = PINGROUP(39, EAST, qup9, cci_i2c, qdss_gpio, _, _, _, _, _, _), + [40] = PINGROUP(40, EAST, qup9, cci_i2c, qdss_gpio, _, _, _, _, _, _), + [41] = PINGROUP(41, EAST, qup9, cci_i2c, qdss_gpio, _, _, _, _, _, _), + [42] = PINGROUP(42, EAST, qup9, cci_i2c, qdss_gpio, _, _, _, _, _, _), + [43] = PINGROUP(43, EAST, qup13, _, _, _, _, _, _, _, _), + [44] = PINGROUP(44, EAST, qup13, _, _, _, _, _, _, _, _), + [45] = PINGROUP(45, EAST, qup13, _, _, _, _, _, _, _, _), + [46] = PINGROUP(46, EAST, qup13, _, _, _, _, _, _, _, _), + [47] = PINGROUP(47, EAST, qup14, usb2phy_ac, _, _, _, _, _, _, _), + [48] = PINGROUP(48, EAST, qup14, usb2phy_ac, _, _, _, _, _, _, _), + [49] = PINGROUP(49, EAST, qup14, qdss_cti, _, _, _, _, _, _, _), + [50] = PINGROUP(50, EAST, qup14, qdss_cti, _, _, _, _, _, _, _), + [51] = PINGROUP(51, WEST, qup4, _, _, _, _, _, _, _, _), + [52] = PINGROUP(52, WEST, qup4, _, _, _, _, _, _, _, _), + [53] = PINGROUP(53, WEST, qup4, _, phase_flag, _, _, _, _, _, _), + [54] = PINGROUP(54, WEST, qup4, _, _, phase_flag, _, _, _, _, _), + [55] = PINGROUP(55, WEST, qup17, qspi1_cs, _, _, _, _, _, _, _), + [56] = PINGROUP(56, WEST, qup17, qspi1, _, _, _, _, _, _, _), + [57] = PINGROUP(57, WEST, qup17, qspi1, _, _, _, _, _, _, _), + [58] = PINGROUP(58, WEST, usb1_phy, qup17, _, _, _, _, _, _, _), + [59] = PINGROUP(59, WEST, rgmii, qup_l4, _, _, _, _, _, _, _), + [60] = PINGROUP(60, EAST, gps, nav_pps, nav_pps, qup_l4, mdp_vsync, atest_usb1, ddr_pxi, _, _), + [61] = PINGROUP(61, EAST, qlink, _, _, _, _, _, _, _, _), + [62] = PINGROUP(62, EAST, qlink, atest_tsens2, atest_usb1, ddr_pxi, vsense_trigger, _, _, _, _), + [63] = PINGROUP(63, EAST, wmss_reset, _, atest_usb1, ddr_pxi, wlan1_adc, _, _, _, _), + [64] = PINGROUP(64, EAST, grfc, _, atest_usb1, ddr_pxi, wlan1_adc, _, _, _, _), + [65] = PINGROUP(65, EAST, grfc, atest_usb1, ddr_pxi, wlan2_adc, _, _, _, _, _), + [66] = PINGROUP(66, EAST, grfc, _, _, _, _, _, _, _, _), + [67] = PINGROUP(67, EAST, grfc, _, _, _, _, _, _, _, _), + [68] = PINGROUP(68, EAST, grfc, pa_indicator, atest_usb3, ddr_pxi, wlan2_adc, _, _, _, _), + [69] = PINGROUP(69, EAST, mss_lte, _, _, _, _, _, _, _, _), + [70] = PINGROUP(70, EAST, mss_lte, _, _, _, _, _, _, _, _), + [71] = PINGROUP(71, EAST, _, grfc, atest_usb3, ddr_pxi, _, _, _, _, _), + [72] = PINGROUP(72, EAST, _, grfc, atest_usb3, ddr_pxi, _, _, _, _, _), + [73] = PINGROUP(73, EAST, _, grfc, atest_usb3, ddr_pxi, _, _, _, _, _), + [74] = PINGROUP(74, EAST, _, grfc, tgu, atest_usb3, ddr_pxi, _, _, _, _), + [75] = PINGROUP(75, EAST, _, grfc, tgu, atest_usb4, ddr_pxi, _, _, _, _), + [76] = PINGROUP(76, EAST, _, grfc, gps, nav_pps, nav_pps, tgu, atest_usb4, ddr_pxi, _), + [77] = PINGROUP(77, EAST, _, grfc, gps, nav_pps, nav_pps, tgu, atest_usb4, ddr_pxi, _), + [78] = PINGROUP(78, EAST, _, grfc, _, atest_usb4, ddr_pxi, _, _, _, _), + [79] = PINGROUP(79, EAST, _, grfc, _, _, _, _, _, _, _), + [80] = PINGROUP(80, EAST, _, grfc, _, _, _, _, _, _, _), + [81] = PINGROUP(81, EAST, _, grfc, gps, nav_pps, nav_pps, qdss_cti, _, emac_pps, _), + [82] = PINGROUP(82, EAST, _, grfc, gps, nav_pps, nav_pps, mdp_vsync, qdss_cti, _, _), + [83] = PINGROUP(83, EAST, qup12, qup16, _, _, _, _, _, _, _), + [84] = PINGROUP(84, EAST, qup12, qup16, _, _, _, _, _, _, _), + [85] = PINGROUP(85, EAST, qup12, qup16, _, _, _, _, _, _, _), + [86] = PINGROUP(86, EAST, qup12, qup16, _, _, _, _, _, _, _), + [87] = PINGROUP(87, SOUTH, _, _, _, _, _, _, _, _, _), + [88] = PINGROUP(88, EAST, tsif1, qup8, qspi0_cs, tgu, atest_usb4, ddr_pxi, _, _, _), + [89] = PINGROUP(89, EAST, tsif1, qup8, qspi0, mdp_vsync0, mdp_vsync1, mdp_vsync2, mdp_vsync3, mdp_vsync4, mdp_vsync5), + [90] = PINGROUP(90, EAST, tsif1, qup8, qspi0, sdc4_cmd, tgu, qdss_cti, atest_usb0, ddr_pxi, _), + [91] = PINGROUP(91, EAST, tsif1, qup8, qspi0, sdc4, vfr_1, tgu, atest_usb0, _, _), + [92] = PINGROUP(92, EAST, tsif2, qup11, qspi0_clk, sdc4_clk, qdss_gpio, atest_usb0, _, _, _), + [93] = PINGROUP(93, EAST, tsif2, qup11, qspi0, sdc4, atest_tsens, atest_usb0, _, _, _), + [94] = PINGROUP(94, EAST, tsif2, qup11, qspi0_cs, sdc4, _, atest_usb0, _, _, _), + [95] = PINGROUP(95, EAST, tsif2, qup11, sdc4, qup_l4, atest_usb2, _, _, _, _), + [96] = PINGROUP(96, WEST, tsif2, qup_l5, _, _, _, _, _, _, _), + [97] = PINGROUP(97, WEST, sd_write, tsif1, qup_l6, _, _, _, _, _, _), + [98] = PINGROUP(98, WEST, qup7, ddr_bist, _, _, _, _, _, _, _), + [99] = PINGROUP(99, WEST, qup7, ddr_bist, _, _, _, _, _, _, _), + [100] = PINGROUP(100, WEST, qup7, pll_bypassnl, _, _, _, _, _, _, _), + [101] = PINGROUP(101, WEST, qup7, pll_reset, _, _, _, _, _, _, _), + [102] = PINGROUP(102, SOUTH, pci_e1, _, phase_flag, atest_usb2, _, _, _, _, _), + [103] = PINGROUP(103, SOUTH, pci_e1, _, _, _, _, _, _, _, _), + [104] = PINGROUP(104, SOUTH, _, _, _, _, _, _, _, _, _), + [105] = PINGROUP(105, WEST, uim2, _, _, _, _, _, _, _, _), + [106] = PINGROUP(106, WEST, uim2, _, _, _, _, _, _, _, _), + [107] = PINGROUP(107, WEST, uim2, _, _, _, _, _, _, _, _), + [108] = PINGROUP(108, WEST, uim2, _, _, _, _, _, _, _, _), + [109] = PINGROUP(109, WEST, uim1, _, _, _, _, _, _, _, _), + [110] = PINGROUP(110, WEST, uim1, _, _, _, _, _, _, _, _), + [111] = PINGROUP(111, WEST, uim1, _, _, _, _, _, _, _, _), + [112] = PINGROUP(112, WEST, uim1, _, _, _, _, _, _, _, _), + [113] = PINGROUP(113, WEST, uim_batt, usb2phy_ac, aoss_cti, _, _, _, _, _, _), + [114] = PINGROUP(114, WEST, qup1, rgmii, _, qdss_gpio, _, _, _, _, _), + [115] = PINGROUP(115, WEST, qup1, rgmii, adsp_ext, _, qdss_gpio, _, _, _, _), + [116] = PINGROUP(116, WEST, qup1, rgmii, _, qdss_gpio, _, _, _, _, _), + [117] = PINGROUP(117, WEST, qup1, rgmii, _, qdss_gpio, _, _, _, _, _), + [118] = PINGROUP(118, WEST, rgmii, _, qdss_gpio, _, _, _, _, _, _), + [119] = PINGROUP(119, WEST, qup5, rgmii, _, qdss_gpio, _, _, _, _, _), + [120] = PINGROUP(120, WEST, qup5, rgmii, _, phase_flag, qdss_gpio, _, _, _, _), + [121] = PINGROUP(121, WEST, qup5, rgmii, _, phase_flag, qdss_gpio, atest_usb2, _, _, _), + [122] = PINGROUP(122, WEST, qup5, rgmii, _, phase_flag, atest_usb2, _, _, _, _), + [123] = PINGROUP(123, SOUTH, usb2phy_ac, _, phase_flag, _, _, _, _, _, _), + [124] = PINGROUP(124, SOUTH, emac_phy, _, _, _, _, _, _, _, _), + [125] = PINGROUP(125, WEST, hs3_mi2s, _, phase_flag, _, _, _, _, _, _), + [126] = PINGROUP(126, WEST, sec_mi2s, qup2, _, _, _, _, _, _, _), + [127] = PINGROUP(127, WEST, sec_mi2s, qup2, _, _, _, _, _, _, _), + [128] = PINGROUP(128, WEST, sec_mi2s, qup2, _, _, _, _, _, _, _), + [129] = PINGROUP(129, WEST, sec_mi2s, qup2, jitter_bist, _, _, _, _, _, _), + [130] = PINGROUP(130, WEST, sec_mi2s, pll_bist, _, qdss_gpio, _, _, _, _, _), + [131] = PINGROUP(131, WEST, ter_mi2s, gcc_gp1, _, _, _, _, _, _, _), + [132] = PINGROUP(132, WEST, ter_mi2s, _, qdss_gpio, _, _, _, _, _, _), + [133] = PINGROUP(133, WEST, ter_mi2s, _, qdss_gpio, atest_char, _, _, _, _, _), + [134] = PINGROUP(134, WEST, ter_mi2s, _, qdss_gpio, atest_char, _, _, _, _, _), + [135] = PINGROUP(135, WEST, ter_mi2s, _, qdss_gpio, atest_char, _, _, _, _, _), + [136] = PINGROUP(136, WEST, qua_mi2s, gcc_gp1, _, _, _, _, _, _, _), + [137] = PINGROUP(137, WEST, qua_mi2s, gcc_gp2, _, _, _, _, _, _, _), + [138] = PINGROUP(138, WEST, qua_mi2s, gcc_gp3, _, _, _, _, _, _, _), + [139] = PINGROUP(139, WEST, qua_mi2s, gcc_gp4, _, _, _, _, _, _, _), + [140] = PINGROUP(140, WEST, qua_mi2s, gcc_gp5, _, atest_char, _, _, _, _, _), + [141] = PINGROUP(141, WEST, qua_mi2s, qdss_cti, _, _, _, _, _, _, _), + [142] = PINGROUP(142, WEST, qua_mi2s, _, _, qdss_cti, atest_char, _, _, _, _), + [143] = PINGROUP(143, WEST, pri_mi2s, _, _, _, _, _, _, _, _), + [144] = PINGROUP(144, WEST, pri_mi2s, qup3, _, _, _, _, _, _, _), + [145] = PINGROUP(145, WEST, pri_mi2s_ws, qup3, ddr_bist, _, _, _, _, _, _), + [146] = PINGROUP(146, WEST, pri_mi2s, qup3, ddr_bist, _, _, _, _, _, _), + [147] = PINGROUP(147, WEST, pri_mi2s, qup3, _, _, _, _, _, _, _), + [148] = PINGROUP(148, WEST, spkr_i2s, audio_ref, _, phase_flag, _, _, _, _, _), + [149] = PINGROUP(149, WEST, lpass_slimbus, spkr_i2s, _, phase_flag, _, _, _, _, _), + [150] = PINGROUP(150, WEST, lpass_slimbus, spkr_i2s, _, phase_flag, tsense_pwm1, tsense_pwm2, _, _, _), + [151] = PINGROUP(151, WEST, lpass_slimbus, spkr_i2s, _, phase_flag, _, _, _, _, _), + [152] = PINGROUP(152, WEST, lpass_slimbus, spkr_i2s, _, phase_flag, _, _, _, _, _), + [153] = PINGROUP(153, WEST, btfm_slimbus, _, _, _, _, _, _, _, _), + [154] = PINGROUP(154, WEST, btfm_slimbus, _, _, _, _, _, _, _, _), + [155] = PINGROUP(155, WEST, hs1_mi2s, _, phase_flag, _, _, _, _, _, _), + [156] = PINGROUP(156, WEST, hs1_mi2s, _, phase_flag, _, _, _, _, _, _), + [157] = PINGROUP(157, WEST, hs1_mi2s, _, phase_flag, _, _, _, _, _, _), + [158] = PINGROUP(158, WEST, hs1_mi2s, _, phase_flag, _, _, _, _, _, _), + [159] = PINGROUP(159, WEST, hs1_mi2s, cri_trng, _, phase_flag, _, _, _, _, _), + [160] = PINGROUP(160, WEST, hs2_mi2s, cri_trng, _, phase_flag, _, _, _, _, _), + [161] = PINGROUP(161, WEST, hs2_mi2s, qspi1, cri_trng, _, phase_flag, _, _, _, _), + [162] = PINGROUP(162, WEST, hs2_mi2s, qspi1, sp_cmu, _, phase_flag, _, _, _, _), + [163] = PINGROUP(163, WEST, hs2_mi2s, qspi1_clk, prng_rosc, _, phase_flag, _, _, _, _), + [164] = PINGROUP(164, WEST, hs2_mi2s, qspi1_cs, _, phase_flag, _, _, _, _, _), + [165] = PINGROUP(165, WEST, hs3_mi2s, _, phase_flag, _, _, _, _, _, _), + [166] = PINGROUP(166, WEST, hs3_mi2s, _, phase_flag, _, _, _, _, _, _), + [167] = PINGROUP(167, WEST, hs3_mi2s, _, phase_flag, _, _, _, _, _, _), + [168] = PINGROUP(168, WEST, hs3_mi2s, _, phase_flag, _, _, _, _, _, _), + [169] = PINGROUP(169, SOUTH, _, _, _, _, _, _, _, _, _), + [170] = PINGROUP(170, SOUTH, _, _, _, _, _, _, _, _, _), + [171] = PINGROUP(171, SOUTH, _, _, _, _, _, _, _, _, _), + [172] = PINGROUP(172, SOUTH, _, _, _, _, _, _, _, _, _), + [173] = PINGROUP(173, SOUTH, _, _, _, _, _, _, _, _, _), + [174] = PINGROUP(174, SOUTH, _, _, _, _, _, _, _, _, _), + [175] = PINGROUP(175, SOUTH, pci_e2, _, _, _, _, _, _, _, _), + [176] = PINGROUP(176, SOUTH, pci_e2, cci_async, _, _, _, _, _, _, _), + [177] = PINGROUP_OFFSET(177, SOUTH, 0x1e000, _, _, _, _, _, _, _, _, _), + [178] = PINGROUP_OFFSET(178, SOUTH, 0x1e000, pci_e3, cci_timer4, _, _, _, _, _, _, _), + [179] = PINGROUP_OFFSET(179, SOUTH, 0x1e000, pci_e3, cam_mclk, _, _, _, _, _, _, _), + [180] = PINGROUP_OFFSET(180, SOUTH, 0x1e000, cam_mclk, _, _, _, _, _, _, _, _), + [181] = PINGROUP_OFFSET(181, SOUTH, 0x1e000, qup19, cam_mclk, _, _, _, _, _, _, _), + [182] = PINGROUP_OFFSET(182, SOUTH, 0x1e000, qup19, cci_timer5, gcc_gp4, _, _, _, _, _, _), + [183] = PINGROUP_OFFSET(183, SOUTH, 0x1e000, qup19, cci_timer6, gcc_gp5, _, _, _, _, _, _), + [184] = PINGROUP_OFFSET(184, SOUTH, 0x1e000, qup19, cci_timer7, _, _, _, _, _, _, _), + [185] = PINGROUP_OFFSET(185, SOUTH, 0x1e000, cci_timer8, cci_async, _, _, _, _, _, _, _), + [186] = PINGROUP_OFFSET(186, SOUTH, 0x1e000, cci_timer9, cci_async, _, _, _, _, _, _, _), + [187] = PINGROUP_OFFSET(187, SOUTH, 0x1e000, _, _, _, _, _, _, _, _, _), + [188] = PINGROUP_OFFSET(188, SOUTH, 0x1e000, _, _, _, _, _, _, _, _, _), + [189] = PINGROUP_OFFSET(189, SOUTH, 0x1e000, dp_hot, _, _, _, _, _, _, _, _), + [190] = UFS_RESET(ufs_reset), + [191] = SDC_QDSD_PINGROUP(sdc2_clk, 0x4b2000, 14, 6), + [192] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x4b2000, 11, 3), + [193] = SDC_QDSD_PINGROUP(sdc2_data, 0x4b2000, 9, 0), +}; + +static const struct msm_gpio_wakeirq_map sc8180x_pdc_map[] = { + { 3, 31 }, { 5, 32 }, { 8, 33 }, { 9, 34 }, { 10, 100 }, { 12, 104 }, + { 24, 37 }, { 26, 38 }, { 27, 41 }, { 28, 42 }, { 30, 39 }, { 36, 43 }, + { 37, 43 }, { 38, 45 }, { 39, 118 }, { 39, 125 }, { 41, 47 }, + { 42, 48 }, { 46, 50 }, { 47, 49 }, { 48, 51 }, { 49, 53 }, { 50, 52 }, + { 51, 116 }, { 51, 123 }, { 53, 54 }, { 54, 55 }, { 55, 56 }, + { 56, 57 }, { 58, 58 }, { 60, 60 }, { 68, 62 }, { 70, 63 }, { 76, 86 }, + { 77, 36 }, { 81, 64 }, { 83, 65 }, { 86, 67 }, { 87, 84 }, { 88, 117 }, + { 88, 124 }, { 90, 69 }, { 91, 70 }, { 93, 75 }, { 95, 72 }, { 97, 74 }, + { 101, 76 }, { 103, 77 }, { 104, 78 }, { 114, 82 }, { 117, 85 }, + { 118, 101 }, { 119, 87 }, { 120, 88 }, { 121, 89 }, { 122, 90 }, + { 123, 91 }, { 124, 92 }, { 125, 93 }, { 129, 94 }, { 132, 105 }, + { 133, 35 }, { 134, 36 }, { 136, 97 }, { 142, 103 }, { 144, 115 }, + { 144, 122 }, { 147, 106 }, { 150, 107 }, { 152, 108 }, { 153, 109 }, + { 177, 111 }, { 180, 112 }, { 184, 113 }, { 189, 114 } +}; + +static struct msm_pinctrl_soc_data sc8180x_pinctrl = { + .tiles = sc8180x_tiles, + .ntiles = ARRAY_SIZE(sc8180x_tiles), + .pins = sc8180x_pins, + .npins = ARRAY_SIZE(sc8180x_pins), + .functions = sc8180x_functions, + .nfunctions = ARRAY_SIZE(sc8180x_functions), + .groups = sc8180x_groups, + .ngroups = ARRAY_SIZE(sc8180x_groups), + .ngpios = 191, + .wakeirq_map = sc8180x_pdc_map, + .nwakeirq_map = ARRAY_SIZE(sc8180x_pdc_map), +}; + +static int sc8180x_pinctrl_probe(struct platform_device *pdev) +{ + return msm_pinctrl_probe(pdev, &sc8180x_pinctrl); +} + +static const struct of_device_id sc8180x_pinctrl_of_match[] = { + { .compatible = "qcom,sc8180x-tlmm", }, + { }, +}; +MODULE_DEVICE_TABLE(of, sc8180x_pinctrl_of_match); + +static struct platform_driver sc8180x_pinctrl_driver = { + .driver = { + .name = "sc8180x-pinctrl", + .of_match_table = sc8180x_pinctrl_of_match, + }, + .probe = sc8180x_pinctrl_probe, + .remove = msm_pinctrl_remove, +}; + +static int __init sc8180x_pinctrl_init(void) +{ + return platform_driver_register(&sc8180x_pinctrl_driver); +} +arch_initcall(sc8180x_pinctrl_init); + +static void __exit sc8180x_pinctrl_exit(void) +{ + platform_driver_unregister(&sc8180x_pinctrl_driver); +} +module_exit(sc8180x_pinctrl_exit); + +MODULE_DESCRIPTION("QTI SC8180x pinctrl driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845.c b/drivers/pinctrl/qcom/pinctrl-sdm845.c index 2834d2c1338c..c51793f6546f 100644 --- a/drivers/pinctrl/qcom/pinctrl-sdm845.c +++ b/drivers/pinctrl/qcom/pinctrl-sdm845.c @@ -1310,7 +1310,6 @@ static const struct msm_pinctrl_soc_data sdm845_pinctrl = { .ngpios = 151, .wakeirq_map = sdm845_pdc_map, .nwakeirq_map = ARRAY_SIZE(sdm845_pdc_map), - }; static const struct msm_pinctrl_soc_data sdm845_acpi_pinctrl = { diff --git a/drivers/pinctrl/qcom/pinctrl-sm8350.c b/drivers/pinctrl/qcom/pinctrl-sm8350.c new file mode 100644 index 000000000000..a406ed0ec7d3 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-sm8350.c @@ -0,0 +1,1649 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, Linaro Limited + */ + +#include +#include +#include +#include + +#include "pinctrl-msm.h" + +#define FUNCTION(fname) \ + [msm_mux_##fname] = { \ + .name = #fname, \ + .groups = fname##_groups, \ + .ngroups = ARRAY_SIZE(fname##_groups), \ + } + +#define REG_SIZE 0x1000 + +#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9) \ + { \ + .name = "gpio" #id, \ + .pins = gpio##id##_pins, \ + .npins = (unsigned int)ARRAY_SIZE(gpio##id##_pins), \ + .funcs = (int[]){ \ + msm_mux_gpio, /* gpio mode */ \ + msm_mux_##f1, \ + msm_mux_##f2, \ + msm_mux_##f3, \ + msm_mux_##f4, \ + msm_mux_##f5, \ + msm_mux_##f6, \ + msm_mux_##f7, \ + msm_mux_##f8, \ + msm_mux_##f9 \ + }, \ + .nfuncs = 10, \ + .ctl_reg = REG_SIZE * id, \ + .io_reg = REG_SIZE * id + 0x4, \ + .intr_cfg_reg = REG_SIZE * id + 0x8, \ + .intr_status_reg = REG_SIZE * id + 0xc, \ + .intr_target_reg = REG_SIZE * id + 0x8, \ + .mux_bit = 2, \ + .pull_bit = 0, \ + .drv_bit = 6, \ + .oe_bit = 9, \ + .in_bit = 0, \ + .out_bit = 1, \ + .intr_enable_bit = 0, \ + .intr_status_bit = 0, \ + .intr_target_bit = 5, \ + .intr_target_kpss_val = 3, \ + .intr_raw_status_bit = 4, \ + .intr_polarity_bit = 1, \ + .intr_detection_bit = 2, \ + .intr_detection_width = 2, \ + } + +#define SDC_PINGROUP(pg_name, ctl, pull, drv) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .mux_bit = -1, \ + .pull_bit = pull, \ + .drv_bit = drv, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + +#define UFS_RESET(pg_name, offset) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \ + .ctl_reg = offset, \ + .io_reg = offset + 0x4, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .mux_bit = -1, \ + .pull_bit = 3, \ + .drv_bit = 0, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = 0, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + +static const struct pinctrl_pin_desc sm8350_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "GPIO_34"), + PINCTRL_PIN(35, "GPIO_35"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GPIO_42"), + PINCTRL_PIN(43, "GPIO_43"), + PINCTRL_PIN(44, "GPIO_44"), + PINCTRL_PIN(45, "GPIO_45"), + PINCTRL_PIN(46, "GPIO_46"), + PINCTRL_PIN(47, "GPIO_47"), + PINCTRL_PIN(48, "GPIO_48"), + PINCTRL_PIN(49, "GPIO_49"), + PINCTRL_PIN(50, "GPIO_50"), + PINCTRL_PIN(51, "GPIO_51"), + PINCTRL_PIN(52, "GPIO_52"), + PINCTRL_PIN(53, "GPIO_53"), + PINCTRL_PIN(54, "GPIO_54"), + PINCTRL_PIN(55, "GPIO_55"), + PINCTRL_PIN(56, "GPIO_56"), + PINCTRL_PIN(57, "GPIO_57"), + PINCTRL_PIN(58, "GPIO_58"), + PINCTRL_PIN(59, "GPIO_59"), + PINCTRL_PIN(60, "GPIO_60"), + PINCTRL_PIN(61, "GPIO_61"), + PINCTRL_PIN(62, "GPIO_62"), + PINCTRL_PIN(63, "GPIO_63"), + PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), + PINCTRL_PIN(69, "GPIO_69"), + PINCTRL_PIN(70, "GPIO_70"), + PINCTRL_PIN(71, "GPIO_71"), + PINCTRL_PIN(72, "GPIO_72"), + PINCTRL_PIN(73, "GPIO_73"), + PINCTRL_PIN(74, "GPIO_74"), + PINCTRL_PIN(75, "GPIO_75"), + PINCTRL_PIN(76, "GPIO_76"), + PINCTRL_PIN(77, "GPIO_77"), + PINCTRL_PIN(78, "GPIO_78"), + PINCTRL_PIN(79, "GPIO_79"), + PINCTRL_PIN(80, "GPIO_80"), + PINCTRL_PIN(81, "GPIO_81"), + PINCTRL_PIN(82, "GPIO_82"), + PINCTRL_PIN(83, "GPIO_83"), + PINCTRL_PIN(84, "GPIO_84"), + PINCTRL_PIN(85, "GPIO_85"), + PINCTRL_PIN(86, "GPIO_86"), + PINCTRL_PIN(87, "GPIO_87"), + PINCTRL_PIN(88, "GPIO_88"), + PINCTRL_PIN(89, "GPIO_89"), + PINCTRL_PIN(90, "GPIO_90"), + PINCTRL_PIN(91, "GPIO_91"), + PINCTRL_PIN(92, "GPIO_92"), + PINCTRL_PIN(93, "GPIO_93"), + PINCTRL_PIN(94, "GPIO_94"), + PINCTRL_PIN(95, "GPIO_95"), + PINCTRL_PIN(96, "GPIO_96"), + PINCTRL_PIN(97, "GPIO_97"), + PINCTRL_PIN(98, "GPIO_98"), + PINCTRL_PIN(99, "GPIO_99"), + PINCTRL_PIN(100, "GPIO_100"), + PINCTRL_PIN(101, "GPIO_101"), + PINCTRL_PIN(102, "GPIO_102"), + PINCTRL_PIN(103, "GPIO_103"), + PINCTRL_PIN(104, "GPIO_104"), + PINCTRL_PIN(105, "GPIO_105"), + PINCTRL_PIN(106, "GPIO_106"), + PINCTRL_PIN(107, "GPIO_107"), + PINCTRL_PIN(108, "GPIO_108"), + PINCTRL_PIN(109, "GPIO_109"), + PINCTRL_PIN(110, "GPIO_110"), + PINCTRL_PIN(111, "GPIO_111"), + PINCTRL_PIN(112, "GPIO_112"), + PINCTRL_PIN(113, "GPIO_113"), + PINCTRL_PIN(114, "GPIO_114"), + PINCTRL_PIN(115, "GPIO_115"), + PINCTRL_PIN(116, "GPIO_116"), + PINCTRL_PIN(117, "GPIO_117"), + PINCTRL_PIN(118, "GPIO_118"), + PINCTRL_PIN(119, "GPIO_119"), + PINCTRL_PIN(120, "GPIO_120"), + PINCTRL_PIN(121, "GPIO_121"), + PINCTRL_PIN(122, "GPIO_122"), + PINCTRL_PIN(123, "GPIO_123"), + PINCTRL_PIN(124, "GPIO_124"), + PINCTRL_PIN(125, "GPIO_125"), + PINCTRL_PIN(126, "GPIO_126"), + PINCTRL_PIN(127, "GPIO_127"), + PINCTRL_PIN(128, "GPIO_128"), + PINCTRL_PIN(129, "GPIO_129"), + PINCTRL_PIN(130, "GPIO_130"), + PINCTRL_PIN(131, "GPIO_131"), + PINCTRL_PIN(132, "GPIO_132"), + PINCTRL_PIN(133, "GPIO_133"), + PINCTRL_PIN(134, "GPIO_134"), + PINCTRL_PIN(135, "GPIO_135"), + PINCTRL_PIN(136, "GPIO_136"), + PINCTRL_PIN(137, "GPIO_137"), + PINCTRL_PIN(138, "GPIO_138"), + PINCTRL_PIN(139, "GPIO_139"), + PINCTRL_PIN(140, "GPIO_140"), + PINCTRL_PIN(141, "GPIO_141"), + PINCTRL_PIN(142, "GPIO_142"), + PINCTRL_PIN(143, "GPIO_143"), + PINCTRL_PIN(144, "GPIO_144"), + PINCTRL_PIN(145, "GPIO_145"), + PINCTRL_PIN(146, "GPIO_146"), + PINCTRL_PIN(147, "GPIO_147"), + PINCTRL_PIN(148, "GPIO_148"), + PINCTRL_PIN(149, "GPIO_149"), + PINCTRL_PIN(150, "GPIO_150"), + PINCTRL_PIN(151, "GPIO_151"), + PINCTRL_PIN(152, "GPIO_152"), + PINCTRL_PIN(153, "GPIO_153"), + PINCTRL_PIN(154, "GPIO_154"), + PINCTRL_PIN(155, "GPIO_155"), + PINCTRL_PIN(156, "GPIO_156"), + PINCTRL_PIN(157, "GPIO_157"), + PINCTRL_PIN(158, "GPIO_158"), + PINCTRL_PIN(159, "GPIO_159"), + PINCTRL_PIN(160, "GPIO_160"), + PINCTRL_PIN(161, "GPIO_161"), + PINCTRL_PIN(162, "GPIO_162"), + PINCTRL_PIN(163, "GPIO_163"), + PINCTRL_PIN(164, "GPIO_164"), + PINCTRL_PIN(165, "GPIO_165"), + PINCTRL_PIN(166, "GPIO_166"), + PINCTRL_PIN(167, "GPIO_167"), + PINCTRL_PIN(168, "GPIO_168"), + PINCTRL_PIN(169, "GPIO_169"), + PINCTRL_PIN(170, "GPIO_170"), + PINCTRL_PIN(171, "GPIO_171"), + PINCTRL_PIN(172, "GPIO_172"), + PINCTRL_PIN(173, "GPIO_173"), + PINCTRL_PIN(174, "GPIO_174"), + PINCTRL_PIN(175, "GPIO_175"), + PINCTRL_PIN(176, "GPIO_176"), + PINCTRL_PIN(177, "GPIO_177"), + PINCTRL_PIN(178, "GPIO_178"), + PINCTRL_PIN(179, "GPIO_179"), + PINCTRL_PIN(180, "GPIO_180"), + PINCTRL_PIN(181, "GPIO_181"), + PINCTRL_PIN(182, "GPIO_182"), + PINCTRL_PIN(183, "GPIO_183"), + PINCTRL_PIN(184, "GPIO_184"), + PINCTRL_PIN(185, "GPIO_185"), + PINCTRL_PIN(186, "GPIO_186"), + PINCTRL_PIN(187, "GPIO_187"), + PINCTRL_PIN(188, "GPIO_188"), + PINCTRL_PIN(189, "GPIO_189"), + PINCTRL_PIN(190, "GPIO_190"), + PINCTRL_PIN(191, "GPIO_191"), + PINCTRL_PIN(192, "GPIO_192"), + PINCTRL_PIN(193, "GPIO_193"), + PINCTRL_PIN(194, "GPIO_194"), + PINCTRL_PIN(195, "GPIO_195"), + PINCTRL_PIN(196, "GPIO_196"), + PINCTRL_PIN(197, "GPIO_197"), + PINCTRL_PIN(198, "GPIO_198"), + PINCTRL_PIN(199, "GPIO_199"), + PINCTRL_PIN(200, "GPIO_200"), + PINCTRL_PIN(201, "GPIO_201"), + PINCTRL_PIN(202, "GPIO_202"), + PINCTRL_PIN(203, "UFS_RESET"), + PINCTRL_PIN(204, "SDC2_CLK"), + PINCTRL_PIN(205, "SDC2_CMD"), + PINCTRL_PIN(206, "SDC2_DATA"), +}; + +#define DECLARE_MSM_GPIO_PINS(pin) \ + static const unsigned int gpio##pin##_pins[] = { pin } +DECLARE_MSM_GPIO_PINS(0); +DECLARE_MSM_GPIO_PINS(1); +DECLARE_MSM_GPIO_PINS(2); +DECLARE_MSM_GPIO_PINS(3); +DECLARE_MSM_GPIO_PINS(4); +DECLARE_MSM_GPIO_PINS(5); +DECLARE_MSM_GPIO_PINS(6); +DECLARE_MSM_GPIO_PINS(7); +DECLARE_MSM_GPIO_PINS(8); +DECLARE_MSM_GPIO_PINS(9); +DECLARE_MSM_GPIO_PINS(10); +DECLARE_MSM_GPIO_PINS(11); +DECLARE_MSM_GPIO_PINS(12); +DECLARE_MSM_GPIO_PINS(13); +DECLARE_MSM_GPIO_PINS(14); +DECLARE_MSM_GPIO_PINS(15); +DECLARE_MSM_GPIO_PINS(16); +DECLARE_MSM_GPIO_PINS(17); +DECLARE_MSM_GPIO_PINS(18); +DECLARE_MSM_GPIO_PINS(19); +DECLARE_MSM_GPIO_PINS(20); +DECLARE_MSM_GPIO_PINS(21); +DECLARE_MSM_GPIO_PINS(22); +DECLARE_MSM_GPIO_PINS(23); +DECLARE_MSM_GPIO_PINS(24); +DECLARE_MSM_GPIO_PINS(25); +DECLARE_MSM_GPIO_PINS(26); +DECLARE_MSM_GPIO_PINS(27); +DECLARE_MSM_GPIO_PINS(28); +DECLARE_MSM_GPIO_PINS(29); +DECLARE_MSM_GPIO_PINS(30); +DECLARE_MSM_GPIO_PINS(31); +DECLARE_MSM_GPIO_PINS(32); +DECLARE_MSM_GPIO_PINS(33); +DECLARE_MSM_GPIO_PINS(34); +DECLARE_MSM_GPIO_PINS(35); +DECLARE_MSM_GPIO_PINS(36); +DECLARE_MSM_GPIO_PINS(37); +DECLARE_MSM_GPIO_PINS(38); +DECLARE_MSM_GPIO_PINS(39); +DECLARE_MSM_GPIO_PINS(40); +DECLARE_MSM_GPIO_PINS(41); +DECLARE_MSM_GPIO_PINS(42); +DECLARE_MSM_GPIO_PINS(43); +DECLARE_MSM_GPIO_PINS(44); +DECLARE_MSM_GPIO_PINS(45); +DECLARE_MSM_GPIO_PINS(46); +DECLARE_MSM_GPIO_PINS(47); +DECLARE_MSM_GPIO_PINS(48); +DECLARE_MSM_GPIO_PINS(49); +DECLARE_MSM_GPIO_PINS(50); +DECLARE_MSM_GPIO_PINS(51); +DECLARE_MSM_GPIO_PINS(52); +DECLARE_MSM_GPIO_PINS(53); +DECLARE_MSM_GPIO_PINS(54); +DECLARE_MSM_GPIO_PINS(55); +DECLARE_MSM_GPIO_PINS(56); +DECLARE_MSM_GPIO_PINS(57); +DECLARE_MSM_GPIO_PINS(58); +DECLARE_MSM_GPIO_PINS(59); +DECLARE_MSM_GPIO_PINS(60); +DECLARE_MSM_GPIO_PINS(61); +DECLARE_MSM_GPIO_PINS(62); +DECLARE_MSM_GPIO_PINS(63); +DECLARE_MSM_GPIO_PINS(64); +DECLARE_MSM_GPIO_PINS(65); +DECLARE_MSM_GPIO_PINS(66); +DECLARE_MSM_GPIO_PINS(67); +DECLARE_MSM_GPIO_PINS(68); +DECLARE_MSM_GPIO_PINS(69); +DECLARE_MSM_GPIO_PINS(70); +DECLARE_MSM_GPIO_PINS(71); +DECLARE_MSM_GPIO_PINS(72); +DECLARE_MSM_GPIO_PINS(73); +DECLARE_MSM_GPIO_PINS(74); +DECLARE_MSM_GPIO_PINS(75); +DECLARE_MSM_GPIO_PINS(76); +DECLARE_MSM_GPIO_PINS(77); +DECLARE_MSM_GPIO_PINS(78); +DECLARE_MSM_GPIO_PINS(79); +DECLARE_MSM_GPIO_PINS(80); +DECLARE_MSM_GPIO_PINS(81); +DECLARE_MSM_GPIO_PINS(82); +DECLARE_MSM_GPIO_PINS(83); +DECLARE_MSM_GPIO_PINS(84); +DECLARE_MSM_GPIO_PINS(85); +DECLARE_MSM_GPIO_PINS(86); +DECLARE_MSM_GPIO_PINS(87); +DECLARE_MSM_GPIO_PINS(88); +DECLARE_MSM_GPIO_PINS(89); +DECLARE_MSM_GPIO_PINS(90); +DECLARE_MSM_GPIO_PINS(91); +DECLARE_MSM_GPIO_PINS(92); +DECLARE_MSM_GPIO_PINS(93); +DECLARE_MSM_GPIO_PINS(94); +DECLARE_MSM_GPIO_PINS(95); +DECLARE_MSM_GPIO_PINS(96); +DECLARE_MSM_GPIO_PINS(97); +DECLARE_MSM_GPIO_PINS(98); +DECLARE_MSM_GPIO_PINS(99); +DECLARE_MSM_GPIO_PINS(100); +DECLARE_MSM_GPIO_PINS(101); +DECLARE_MSM_GPIO_PINS(102); +DECLARE_MSM_GPIO_PINS(103); +DECLARE_MSM_GPIO_PINS(104); +DECLARE_MSM_GPIO_PINS(105); +DECLARE_MSM_GPIO_PINS(106); +DECLARE_MSM_GPIO_PINS(107); +DECLARE_MSM_GPIO_PINS(108); +DECLARE_MSM_GPIO_PINS(109); +DECLARE_MSM_GPIO_PINS(110); +DECLARE_MSM_GPIO_PINS(111); +DECLARE_MSM_GPIO_PINS(112); +DECLARE_MSM_GPIO_PINS(113); +DECLARE_MSM_GPIO_PINS(114); +DECLARE_MSM_GPIO_PINS(115); +DECLARE_MSM_GPIO_PINS(116); +DECLARE_MSM_GPIO_PINS(117); +DECLARE_MSM_GPIO_PINS(118); +DECLARE_MSM_GPIO_PINS(119); +DECLARE_MSM_GPIO_PINS(120); +DECLARE_MSM_GPIO_PINS(121); +DECLARE_MSM_GPIO_PINS(122); +DECLARE_MSM_GPIO_PINS(123); +DECLARE_MSM_GPIO_PINS(124); +DECLARE_MSM_GPIO_PINS(125); +DECLARE_MSM_GPIO_PINS(126); +DECLARE_MSM_GPIO_PINS(127); +DECLARE_MSM_GPIO_PINS(128); +DECLARE_MSM_GPIO_PINS(129); +DECLARE_MSM_GPIO_PINS(130); +DECLARE_MSM_GPIO_PINS(131); +DECLARE_MSM_GPIO_PINS(132); +DECLARE_MSM_GPIO_PINS(133); +DECLARE_MSM_GPIO_PINS(134); +DECLARE_MSM_GPIO_PINS(135); +DECLARE_MSM_GPIO_PINS(136); +DECLARE_MSM_GPIO_PINS(137); +DECLARE_MSM_GPIO_PINS(138); +DECLARE_MSM_GPIO_PINS(139); +DECLARE_MSM_GPIO_PINS(140); +DECLARE_MSM_GPIO_PINS(141); +DECLARE_MSM_GPIO_PINS(142); +DECLARE_MSM_GPIO_PINS(143); +DECLARE_MSM_GPIO_PINS(144); +DECLARE_MSM_GPIO_PINS(145); +DECLARE_MSM_GPIO_PINS(146); +DECLARE_MSM_GPIO_PINS(147); +DECLARE_MSM_GPIO_PINS(148); +DECLARE_MSM_GPIO_PINS(149); +DECLARE_MSM_GPIO_PINS(150); +DECLARE_MSM_GPIO_PINS(151); +DECLARE_MSM_GPIO_PINS(152); +DECLARE_MSM_GPIO_PINS(153); +DECLARE_MSM_GPIO_PINS(154); +DECLARE_MSM_GPIO_PINS(155); +DECLARE_MSM_GPIO_PINS(156); +DECLARE_MSM_GPIO_PINS(157); +DECLARE_MSM_GPIO_PINS(158); +DECLARE_MSM_GPIO_PINS(159); +DECLARE_MSM_GPIO_PINS(160); +DECLARE_MSM_GPIO_PINS(161); +DECLARE_MSM_GPIO_PINS(162); +DECLARE_MSM_GPIO_PINS(163); +DECLARE_MSM_GPIO_PINS(164); +DECLARE_MSM_GPIO_PINS(165); +DECLARE_MSM_GPIO_PINS(166); +DECLARE_MSM_GPIO_PINS(167); +DECLARE_MSM_GPIO_PINS(168); +DECLARE_MSM_GPIO_PINS(169); +DECLARE_MSM_GPIO_PINS(170); +DECLARE_MSM_GPIO_PINS(171); +DECLARE_MSM_GPIO_PINS(172); +DECLARE_MSM_GPIO_PINS(173); +DECLARE_MSM_GPIO_PINS(174); +DECLARE_MSM_GPIO_PINS(175); +DECLARE_MSM_GPIO_PINS(176); +DECLARE_MSM_GPIO_PINS(177); +DECLARE_MSM_GPIO_PINS(178); +DECLARE_MSM_GPIO_PINS(179); +DECLARE_MSM_GPIO_PINS(180); +DECLARE_MSM_GPIO_PINS(181); +DECLARE_MSM_GPIO_PINS(182); +DECLARE_MSM_GPIO_PINS(183); +DECLARE_MSM_GPIO_PINS(184); +DECLARE_MSM_GPIO_PINS(185); +DECLARE_MSM_GPIO_PINS(186); +DECLARE_MSM_GPIO_PINS(187); +DECLARE_MSM_GPIO_PINS(188); +DECLARE_MSM_GPIO_PINS(189); +DECLARE_MSM_GPIO_PINS(190); +DECLARE_MSM_GPIO_PINS(191); +DECLARE_MSM_GPIO_PINS(192); +DECLARE_MSM_GPIO_PINS(193); +DECLARE_MSM_GPIO_PINS(194); +DECLARE_MSM_GPIO_PINS(195); +DECLARE_MSM_GPIO_PINS(196); +DECLARE_MSM_GPIO_PINS(197); +DECLARE_MSM_GPIO_PINS(198); +DECLARE_MSM_GPIO_PINS(199); +DECLARE_MSM_GPIO_PINS(200); +DECLARE_MSM_GPIO_PINS(201); +DECLARE_MSM_GPIO_PINS(202); + +static const unsigned int ufs_reset_pins[] = { 203 }; +static const unsigned int sdc2_clk_pins[] = { 204 }; +static const unsigned int sdc2_cmd_pins[] = { 205 }; +static const unsigned int sdc2_data_pins[] = { 206 }; + +enum sm8350_functions { + msm_mux_atest_char, + msm_mux_atest_usb, + msm_mux_audio_ref, + msm_mux_cam_mclk, + msm_mux_cci_async, + msm_mux_cci_i2c, + msm_mux_cci_timer, + msm_mux_cmu_rng, + msm_mux_coex_uart1, + msm_mux_coex_uart2, + msm_mux_cri_trng, + msm_mux_cri_trng0, + msm_mux_cri_trng1, + msm_mux_dbg_out, + msm_mux_ddr_bist, + msm_mux_ddr_pxi0, + msm_mux_ddr_pxi1, + msm_mux_ddr_pxi2, + msm_mux_ddr_pxi3, + msm_mux_dp_hot, + msm_mux_dp_lcd, + msm_mux_gcc_gp1, + msm_mux_gcc_gp2, + msm_mux_gcc_gp3, + msm_mux_gpio, + msm_mux_ibi_i3c, + msm_mux_jitter_bist, + msm_mux_lpass_slimbus, + msm_mux_mdp_vsync, + msm_mux_mdp_vsync0, + msm_mux_mdp_vsync1, + msm_mux_mdp_vsync2, + msm_mux_mdp_vsync3, + msm_mux_mi2s0_data0, + msm_mux_mi2s0_data1, + msm_mux_mi2s0_sck, + msm_mux_mi2s0_ws, + msm_mux_mi2s1_data0, + msm_mux_mi2s1_data1, + msm_mux_mi2s1_sck, + msm_mux_mi2s1_ws, + msm_mux_mi2s2_data0, + msm_mux_mi2s2_data1, + msm_mux_mi2s2_sck, + msm_mux_mi2s2_ws, + msm_mux_mss_grfc0, + msm_mux_mss_grfc1, + msm_mux_mss_grfc10, + msm_mux_mss_grfc11, + msm_mux_mss_grfc12, + msm_mux_mss_grfc2, + msm_mux_mss_grfc3, + msm_mux_mss_grfc4, + msm_mux_mss_grfc5, + msm_mux_mss_grfc6, + msm_mux_mss_grfc7, + msm_mux_mss_grfc8, + msm_mux_mss_grfc9, + msm_mux_nav_gpio, + msm_mux_pa_indicator, + msm_mux_pcie0_clkreqn, + msm_mux_pcie1_clkreqn, + msm_mux_phase_flag, + msm_mux_pll_bist, + msm_mux_pll_clk, + msm_mux_pri_mi2s, + msm_mux_prng_rosc, + msm_mux_qdss_cti, + msm_mux_qdss_gpio, + msm_mux_qlink0_enable, + msm_mux_qlink0_request, + msm_mux_qlink0_wmss, + msm_mux_qlink1_enable, + msm_mux_qlink1_request, + msm_mux_qlink1_wmss, + msm_mux_qlink2_enable, + msm_mux_qlink2_request, + msm_mux_qlink2_wmss, + msm_mux_qspi0, + msm_mux_qspi1, + msm_mux_qspi2, + msm_mux_qspi3, + msm_mux_qspi_clk, + msm_mux_qspi_cs, + msm_mux_qup0, + msm_mux_qup1, + msm_mux_qup10, + msm_mux_qup11, + msm_mux_qup12, + msm_mux_qup13, + msm_mux_qup14, + msm_mux_qup15, + msm_mux_qup16, + msm_mux_qup17, + msm_mux_qup18, + msm_mux_qup19, + msm_mux_qup2, + msm_mux_qup3, + msm_mux_qup4, + msm_mux_qup5, + msm_mux_qup6, + msm_mux_qup7, + msm_mux_qup8, + msm_mux_qup9, + msm_mux_qup_l4, + msm_mux_qup_l5, + msm_mux_qup_l6, + msm_mux_sd_write, + msm_mux_sdc40, + msm_mux_sdc41, + msm_mux_sdc42, + msm_mux_sdc43, + msm_mux_sdc4_clk, + msm_mux_sdc4_cmd, + msm_mux_sec_mi2s, + msm_mux_tb_trig, + msm_mux_tgu_ch0, + msm_mux_tgu_ch1, + msm_mux_tgu_ch2, + msm_mux_tgu_ch3, + msm_mux_tsense_pwm1, + msm_mux_tsense_pwm2, + msm_mux_uim0_clk, + msm_mux_uim0_data, + msm_mux_uim0_present, + msm_mux_uim0_reset, + msm_mux_uim1_clk, + msm_mux_uim1_data, + msm_mux_uim1_present, + msm_mux_uim1_reset, + msm_mux_usb2phy_ac, + msm_mux_usb_phy, + msm_mux_vfr_0, + msm_mux_vfr_1, + msm_mux_vsense_trigger, + msm_mux__, +}; + +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", + "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84", + "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91", + "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98", + "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104", + "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110", + "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116", + "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122", + "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128", + "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134", + "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140", + "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "gpio146", + "gpio147", "gpio148", "gpio149", "gpio150", "gpio151", "gpio152", + "gpio153", "gpio154", "gpio155", "gpio156", "gpio157", "gpio158", + "gpio159", "gpio160", "gpio161", "gpio162", "gpio163", "gpio164", + "gpio165", "gpio166", "gpio167", "gpio168", "gpio169", "gpio170", + "gpio171", "gpio172", "gpio173", "gpio174", "gpio175", "gpio176", + "gpio177", "gpio178", "gpio179", "gpio180", "gpio181", "gpio182", + "gpio183", "gpio184", "gpio185", "gpio186", "gpio187", "gpio188", + "gpio189", "gpio190", "gpio191", "gpio192", "gpio193", "gpio194", + "gpio195", "gpio196", "gpio197", "gpio198", "gpio199", "gpio200", + "gpio201", "gpio202", +}; + +static const char * const atest_char_groups[] = { + "gpio85", "gpio86", "gpio87", "gpio115", "gpio117", +}; + +static const char * const atest_usb_groups[] = { + "gpio55", "gpio80", "gpio81", "gpio151", "gpio152", + "gpio153", "gpio154", "gpio158", "gpio159", "gpio161", +}; + +static const char * const audio_ref_groups[] = { + "gpio124", +}; + +static const char * const cam_mclk_groups[] = { + "gpio100", "gpio101", "gpio102", "gpio103", "gpio104", "gpio105", +}; + +static const char * const cci_async_groups[] = { + "gpio106", "gpio118", "gpio119", +}; + +static const char * const cci_i2c_groups[] = { + "gpio107", "gpio108", "gpio109", "gpio110", "gpio111", "gpio112", + "gpio113", "gpio114", +}; + +static const char * const cci_timer_groups[] = { + "gpio115", "gpio116", "gpio117", "gpio118", "gpio119", +}; + +static const char * const cmu_rng_groups[] = { + "gpio174", "gpio175", "gpio176", "gpio177", +}; + +static const char * const coex_uart1_groups[] = { + "gpio151", "gpio152", +}; + +static const char * const coex_uart2_groups[] = { + "gpio153", "gpio154", +}; + +static const char * const cri_trng_groups[] = { + "gpio186", +}; + +static const char * const cri_trng0_groups[] = { + "gpio183", +}; + +static const char * const cri_trng1_groups[] = { + "gpio184", +}; + +static const char * const dbg_out_groups[] = { + "gpio14", +}; + +static const char * const ddr_bist_groups[] = { + "gpio36", "gpio37", "gpio40", "gpio41", +}; + +static const char * const ddr_pxi0_groups[] = { + "gpio51", "gpio52", +}; + +static const char * const ddr_pxi1_groups[] = { + "gpio48", "gpio49", +}; + +static const char * const ddr_pxi2_groups[] = { + "gpio45", "gpio47", +}; + +static const char * const ddr_pxi3_groups[] = { + "gpio43", "gpio44", +}; + +static const char * const dp_hot_groups[] = { + "gpio87", +}; + +static const char * const dp_lcd_groups[] = { + "gpio83", +}; + +static const char * const gcc_gp1_groups[] = { + "gpio115", "gpio129", +}; + +static const char * const gcc_gp2_groups[] = { + "gpio116", "gpio130", +}; + +static const char * const gcc_gp3_groups[] = { + "gpio117", "gpio131", +}; + +static const char * const ibi_i3c_groups[] = { + "gpio36", "gpio37", "gpio56", "gpio57", "gpio60", "gpio61", +}; + +static const char * const jitter_bist_groups[] = { + "gpio80", +}; + +static const char * const lpass_slimbus_groups[] = { + "gpio129", "gpio130", +}; + +static const char * const mdp_vsync_groups[] = { + "gpio15", "gpio26", "gpio82", "gpio83", "gpio84", +}; + +static const char * const mdp_vsync0_groups[] = { + "gpio86", +}; + +static const char * const mdp_vsync1_groups[] = { + "gpio86", +}; + +static const char * const mdp_vsync2_groups[] = { + "gpio87", +}; + +static const char * const mdp_vsync3_groups[] = { + "gpio87", +}; + +static const char * const mi2s0_data0_groups[] = { + "gpio126", +}; + +static const char * const mi2s0_data1_groups[] = { + "gpio127", +}; + +static const char * const mi2s0_sck_groups[] = { + "gpio125", +}; + +static const char * const mi2s0_ws_groups[] = { + "gpio128", +}; + +static const char * const mi2s1_data0_groups[] = { + "gpio130", +}; + +static const char * const mi2s1_data1_groups[] = { + "gpio131", +}; + +static const char * const mi2s1_sck_groups[] = { + "gpio129", +}; + +static const char * const mi2s1_ws_groups[] = { + "gpio132", +}; + +static const char * const mi2s2_data0_groups[] = { + "gpio121", +}; + +static const char * const mi2s2_data1_groups[] = { + "gpio124", +}; + +static const char * const mi2s2_sck_groups[] = { + "gpio120", +}; + +static const char * const mi2s2_ws_groups[] = { + "gpio122", +}; + +static const char * const mss_grfc0_groups[] = { + "gpio141", "gpio158", +}; + +static const char * const mss_grfc1_groups[] = { + "gpio142", +}; + +static const char * const mss_grfc10_groups[] = { + "gpio153", +}; + +static const char * const mss_grfc11_groups[] = { + "gpio154", +}; + +static const char * const mss_grfc12_groups[] = { + "gpio157", +}; + +static const char * const mss_grfc2_groups[] = { + "gpio143", +}; + +static const char * const mss_grfc3_groups[] = { + "gpio144", +}; + +static const char * const mss_grfc4_groups[] = { + "gpio145", +}; + +static const char * const mss_grfc5_groups[] = { + "gpio146", +}; + +static const char * const mss_grfc6_groups[] = { + "gpio147", +}; + +static const char * const mss_grfc7_groups[] = { + "gpio148", +}; + +static const char * const mss_grfc8_groups[] = { + "gpio149", +}; + +static const char * const mss_grfc9_groups[] = { + "gpio150", +}; + +static const char * const nav_gpio_groups[] = { + "gpio155", "gpio156", "gpio157", +}; + +static const char * const pa_indicator_groups[] = { + "gpio157", +}; + +static const char * const pcie0_clkreqn_groups[] = { + "gpio95", +}; + +static const char * const pcie1_clkreqn_groups[] = { + "gpio98", +}; + +static const char * const phase_flag_groups[] = { + "gpio12", "gpio13", "gpio16", "gpio17", "gpio28", "gpio29", "gpio30", + "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", "gpio72", "gpio73", + "gpio74", "gpio75", "gpio76", "gpio77", "gpio78", "gpio79", "gpio103", + "gpio104", "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", + "gpio110", "gpio111", "gpio112", "gpio113", "gpio114", +}; + +static const char * const pll_bist_groups[] = { + "gpio81", +}; + +static const char * const pll_clk_groups[] = { + "gpio81", +}; + +static const char * const pri_mi2s_groups[] = { + "gpio123", +}; + +static const char * const prng_rosc_groups[] = { + "gpio185", +}; + +static const char * const qdss_cti_groups[] = { + "gpio14", "gpio27", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91", "gpio92", +}; + +static const char * const qdss_gpio_groups[] = { + "gpio100", "gpio101", "gpio102", "gpio103", "gpio104", "gpio105", "gpio106", "gpio107", + "gpio108", "gpio109", "gpio110", "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", + "gpio116", "gpio117", "gpio183", "gpio184", "gpio185", "gpio186", "gpio187", "gpio188", + "gpio189", "gpio190", "gpio191", "gpio192", "gpio193", "gpio194", "gpio195", "gpio196", + "gpio197", "gpio198", "gpio199", "gpio200", +}; + +static const char * const qlink0_enable_groups[] = { + "gpio160", +}; + +static const char * const qlink0_request_groups[] = { + "gpio159", +}; + +static const char * const qlink0_wmss_groups[] = { + "gpio161", +}; + +static const char * const qlink1_enable_groups[] = { + "gpio163", +}; + +static const char * const qlink1_request_groups[] = { + "gpio162", +}; + +static const char * const qlink1_wmss_groups[] = { + "gpio164", +}; + +static const char * const qlink2_enable_groups[] = { + "gpio166", +}; + +static const char * const qlink2_request_groups[] = { + "gpio165", +}; + +static const char * const qlink2_wmss_groups[] = { + "gpio167", +}; + +static const char * const qspi0_groups[] = { + "gpio44", +}; + +static const char * const qspi1_groups[] = { + "gpio45", +}; + +static const char * const qspi2_groups[] = { + "gpio48", +}; + +static const char * const qspi3_groups[] = { + "gpio49", +}; + +static const char * const qspi_clk_groups[] = { + "gpio50", +}; + +static const char * const qspi_cs_groups[] = { + "gpio47", "gpio51", +}; + +static const char * const qup0_groups[] = { + "gpio4", "gpio5", "gpio6", "gpio7", +}; + +static const char * const qup1_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11", +}; + +static const char * const qup10_groups[] = { + "gpio44", "gpio45", "gpio46", "gpio47", +}; + +static const char * const qup11_groups[] = { + "gpio48", "gpio49", "gpio50", "gpio51", +}; + +static const char * const qup12_groups[] = { + "gpio52", "gpio53", "gpio54", "gpio55", +}; + +static const char * const qup13_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", +}; + +static const char * const qup14_groups[] = { + "gpio56", "gpio57", "gpio58", "gpio59", +}; + +static const char * const qup15_groups[] = { + "gpio60", "gpio61", "gpio62", "gpio63", +}; + +static const char * const qup16_groups[] = { + "gpio64", "gpio65", "gpio66", "gpio67", +}; + +static const char * const qup17_groups[] = { + "gpio72", "gpio73", "gpio74", "gpio75", +}; + +static const char * const qup18_groups[] = { + "gpio68", "gpio69", "gpio70", "gpio71", +}; + +static const char * const qup19_groups[] = { + "gpio76", "gpio77", "gpio78", "gpio79", +}; + +static const char * const qup2_groups[] = { + "gpio12", "gpio13", "gpio14", "gpio15", +}; + +static const char * const qup3_groups[] = { + "gpio16", "gpio17", "gpio18", "gpio19", +}; + +static const char * const qup4_groups[] = { + "gpio20", "gpio21", "gpio22", "gpio23", +}; + +static const char * const qup5_groups[] = { + "gpio24", "gpio25", "gpio26", "gpio27", +}; + +static const char * const qup6_groups[] = { + "gpio28", "gpio29", "gpio30", "gpio31", +}; + +static const char * const qup7_groups[] = { + "gpio32", "gpio33", "gpio34", "gpio35", +}; + +static const char * const qup8_groups[] = { + "gpio36", "gpio37", "gpio38", "gpio39", +}; + +static const char * const qup9_groups[] = { + "gpio40", "gpio41", "gpio42", "gpio43", +}; + +static const char * const qup_l4_groups[] = { + "gpio2", "gpio6", "gpio58", "gpio63", +}; + +static const char * const qup_l5_groups[] = { + "gpio3", "gpio7", "gpio59", "gpio66", +}; + +static const char * const qup_l6_groups[] = { + "gpio10", "gpio42", "gpio62", "gpio67", +}; + +static const char * const sd_write_groups[] = { + "gpio93", +}; + +static const char * const sdc40_groups[] = { + "gpio44", +}; + +static const char * const sdc41_groups[] = { + "gpio45", +}; + +static const char * const sdc42_groups[] = { + "gpio48", +}; + +static const char * const sdc43_groups[] = { + "gpio49", +}; + +static const char * const sdc4_clk_groups[] = { + "gpio50", +}; + +static const char * const sdc4_cmd_groups[] = { + "gpio51", +}; + +static const char * const sec_mi2s_groups[] = { + "gpio124", +}; + +static const char * const tb_trig_groups[] = { + "gpio64", "gpio136", +}; + +static const char * const tgu_ch0_groups[] = { + "gpio99", +}; + +static const char * const tgu_ch1_groups[] = { + "gpio100", +}; + +static const char * const tgu_ch2_groups[] = { + "gpio101", +}; + +static const char * const tgu_ch3_groups[] = { + "gpio102", +}; + +static const char * const tsense_pwm1_groups[] = { + "gpio88", +}; + +static const char * const tsense_pwm2_groups[] = { + "gpio88", +}; + +static const char * const uim0_clk_groups[] = { + "gpio138", +}; + +static const char * const uim0_data_groups[] = { + "gpio137", +}; + +static const char * const uim0_present_groups[] = { + "gpio140", +}; + +static const char * const uim0_reset_groups[] = { + "gpio139", +}; + +static const char * const uim1_clk_groups[] = { + "gpio134", +}; + +static const char * const uim1_data_groups[] = { + "gpio133", +}; + +static const char * const uim1_present_groups[] = { + "gpio136", +}; + +static const char * const uim1_reset_groups[] = { + "gpio135", +}; + +static const char * const usb2phy_ac_groups[] = { + "gpio39", "gpio80", +}; + +static const char * const usb_phy_groups[] = { + "gpio81", +}; + +static const char * const vfr_0_groups[] = { + "gpio84", +}; + +static const char * const vfr_1_groups[] = { + "gpio90", +}; + +static const char * const vsense_trigger_groups[] = { + "gpio78", +}; + +static const struct msm_function sm8350_functions[] = { + FUNCTION(atest_char), + FUNCTION(atest_usb), + FUNCTION(audio_ref), + FUNCTION(cam_mclk), + FUNCTION(cci_async), + FUNCTION(cci_i2c), + FUNCTION(cci_timer), + FUNCTION(cmu_rng), + FUNCTION(coex_uart1), + FUNCTION(coex_uart2), + FUNCTION(cri_trng), + FUNCTION(cri_trng0), + FUNCTION(cri_trng1), + FUNCTION(dbg_out), + FUNCTION(ddr_bist), + FUNCTION(ddr_pxi0), + FUNCTION(ddr_pxi1), + FUNCTION(ddr_pxi2), + FUNCTION(ddr_pxi3), + FUNCTION(dp_hot), + FUNCTION(dp_lcd), + FUNCTION(gcc_gp1), + FUNCTION(gcc_gp2), + FUNCTION(gcc_gp3), + FUNCTION(gpio), + FUNCTION(ibi_i3c), + FUNCTION(jitter_bist), + FUNCTION(lpass_slimbus), + FUNCTION(mdp_vsync), + FUNCTION(mdp_vsync0), + FUNCTION(mdp_vsync1), + FUNCTION(mdp_vsync2), + FUNCTION(mdp_vsync3), + FUNCTION(mi2s0_data0), + FUNCTION(mi2s0_data1), + FUNCTION(mi2s0_sck), + FUNCTION(mi2s0_ws), + FUNCTION(mi2s1_data0), + FUNCTION(mi2s1_data1), + FUNCTION(mi2s1_sck), + FUNCTION(mi2s1_ws), + FUNCTION(mi2s2_data0), + FUNCTION(mi2s2_data1), + FUNCTION(mi2s2_sck), + FUNCTION(mi2s2_ws), + FUNCTION(mss_grfc0), + FUNCTION(mss_grfc1), + FUNCTION(mss_grfc10), + FUNCTION(mss_grfc11), + FUNCTION(mss_grfc12), + FUNCTION(mss_grfc2), + FUNCTION(mss_grfc3), + FUNCTION(mss_grfc4), + FUNCTION(mss_grfc5), + FUNCTION(mss_grfc6), + FUNCTION(mss_grfc7), + FUNCTION(mss_grfc8), + FUNCTION(mss_grfc9), + FUNCTION(nav_gpio), + FUNCTION(pa_indicator), + FUNCTION(pcie0_clkreqn), + FUNCTION(pcie1_clkreqn), + FUNCTION(phase_flag), + FUNCTION(pll_bist), + FUNCTION(pll_clk), + FUNCTION(pri_mi2s), + FUNCTION(prng_rosc), + FUNCTION(qdss_cti), + FUNCTION(qdss_gpio), + FUNCTION(qlink0_enable), + FUNCTION(qlink0_request), + FUNCTION(qlink0_wmss), + FUNCTION(qlink1_enable), + FUNCTION(qlink1_request), + FUNCTION(qlink1_wmss), + FUNCTION(qlink2_enable), + FUNCTION(qlink2_request), + FUNCTION(qlink2_wmss), + FUNCTION(qspi0), + FUNCTION(qspi1), + FUNCTION(qspi2), + FUNCTION(qspi3), + FUNCTION(qspi_clk), + FUNCTION(qspi_cs), + FUNCTION(qup0), + FUNCTION(qup1), + FUNCTION(qup10), + FUNCTION(qup11), + FUNCTION(qup12), + FUNCTION(qup13), + FUNCTION(qup14), + FUNCTION(qup15), + FUNCTION(qup16), + FUNCTION(qup17), + FUNCTION(qup18), + FUNCTION(qup19), + FUNCTION(qup2), + FUNCTION(qup3), + FUNCTION(qup4), + FUNCTION(qup5), + FUNCTION(qup6), + FUNCTION(qup7), + FUNCTION(qup8), + FUNCTION(qup9), + FUNCTION(qup_l4), + FUNCTION(qup_l5), + FUNCTION(qup_l6), + FUNCTION(sd_write), + FUNCTION(sdc40), + FUNCTION(sdc41), + FUNCTION(sdc42), + FUNCTION(sdc43), + FUNCTION(sdc4_clk), + FUNCTION(sdc4_cmd), + FUNCTION(sec_mi2s), + FUNCTION(tb_trig), + FUNCTION(tgu_ch0), + FUNCTION(tgu_ch1), + FUNCTION(tgu_ch2), + FUNCTION(tgu_ch3), + FUNCTION(tsense_pwm1), + FUNCTION(tsense_pwm2), + FUNCTION(uim0_clk), + FUNCTION(uim0_data), + FUNCTION(uim0_present), + FUNCTION(uim0_reset), + FUNCTION(uim1_clk), + FUNCTION(uim1_data), + FUNCTION(uim1_present), + FUNCTION(uim1_reset), + FUNCTION(usb2phy_ac), + FUNCTION(usb_phy), + FUNCTION(vfr_0), + FUNCTION(vfr_1), + FUNCTION(vsense_trigger), +}; + +/* Every pin is maintained as a single group, and missing or non-existing pin + * would be maintained as dummy group to synchronize pin group index with + * pin descriptor registered with pinctrl core. + * Clients would not be able to request these dummy pin groups. + */ +static const struct msm_pingroup sm8350_groups[] = { + [0] = PINGROUP(0, qup13, _, _, _, _, _, _, _, _), + [1] = PINGROUP(1, qup13, _, _, _, _, _, _, _, _), + [2] = PINGROUP(2, qup13, qup_l4, _, _, _, _, _, _, _), + [3] = PINGROUP(3, qup13, qup_l5, _, _, _, _, _, _, _), + [4] = PINGROUP(4, qup0, _, _, _, _, _, _, _, _), + [5] = PINGROUP(5, qup0, _, _, _, _, _, _, _, _), + [6] = PINGROUP(6, qup0, qup_l4, _, _, _, _, _, _, _), + [7] = PINGROUP(7, qup0, qup_l5, _, _, _, _, _, _, _), + [8] = PINGROUP(8, qup1, _, _, _, _, _, _, _, _), + [9] = PINGROUP(9, qup1, _, _, _, _, _, _, _, _), + [10] = PINGROUP(10, qup1, qup_l6, _, _, _, _, _, _, _), + [11] = PINGROUP(11, qup1, _, _, _, _, _, _, _, _), + [12] = PINGROUP(12, qup2, phase_flag, _, _, _, _, _, _, _), + [13] = PINGROUP(13, qup2, phase_flag, _, _, _, _, _, _, _), + [14] = PINGROUP(14, qup2, qdss_cti, dbg_out, _, _, _, _, _, _), + [15] = PINGROUP(15, qup2, mdp_vsync, _, _, _, _, _, _, _), + [16] = PINGROUP(16, qup3, phase_flag, _, _, _, _, _, _, _), + [17] = PINGROUP(17, qup3, phase_flag, _, _, _, _, _, _, _), + [18] = PINGROUP(18, qup3, _, _, _, _, _, _, _, _), + [19] = PINGROUP(19, qup3, _, _, _, _, _, _, _, _), + [20] = PINGROUP(20, qup4, _, _, _, _, _, _, _, _), + [21] = PINGROUP(21, qup4, _, _, _, _, _, _, _, _), + [22] = PINGROUP(22, qup4, _, _, _, _, _, _, _, _), + [23] = PINGROUP(23, qup4, _, _, _, _, _, _, _, _), + [24] = PINGROUP(24, qup5, _, _, _, _, _, _, _, _), + [25] = PINGROUP(25, qup5, _, _, _, _, _, _, _, _), + [26] = PINGROUP(26, qup5, mdp_vsync, _, _, _, _, _, _, _), + [27] = PINGROUP(27, qup5, qdss_cti, _, _, _, _, _, _, _), + [28] = PINGROUP(28, qup6, phase_flag, _, _, _, _, _, _, _), + [29] = PINGROUP(29, qup6, phase_flag, _, _, _, _, _, _, _), + [30] = PINGROUP(30, qup6, phase_flag, _, _, _, _, _, _, _), + [31] = PINGROUP(31, qup6, phase_flag, _, _, _, _, _, _, _), + [32] = PINGROUP(32, qup7, phase_flag, _, _, _, _, _, _, _), + [33] = PINGROUP(33, qup7, phase_flag, _, _, _, _, _, _, _), + [34] = PINGROUP(34, qup7, phase_flag, _, _, _, _, _, _, _), + [35] = PINGROUP(35, qup7, phase_flag, _, _, _, _, _, _, _), + [36] = PINGROUP(36, qup8, ibi_i3c, ddr_bist, _, _, _, _, _, _), + [37] = PINGROUP(37, qup8, ibi_i3c, ddr_bist, _, _, _, _, _, _), + [38] = PINGROUP(38, qup8, _, _, _, _, _, _, _, _), + [39] = PINGROUP(39, qup8, usb2phy_ac, _, _, _, _, _, _, _), + [40] = PINGROUP(40, qup9, ddr_bist, _, _, _, _, _, _, _), + [41] = PINGROUP(41, qup9, ddr_bist, _, _, _, _, _, _, _), + [42] = PINGROUP(42, qup9, qup_l6, _, _, _, _, _, _, _), + [43] = PINGROUP(43, qup9, ddr_pxi3, _, _, _, _, _, _, _), + [44] = PINGROUP(44, qup10, qspi0, sdc40, ddr_pxi3, _, _, _, _, _), + [45] = PINGROUP(45, qup10, qspi1, sdc41, ddr_pxi2, _, _, _, _, _), + [46] = PINGROUP(46, qup10, _, _, _, _, _, _, _, _), + [47] = PINGROUP(47, qup10, qspi_cs, ddr_pxi2, _, _, _, _, _, _), + [48] = PINGROUP(48, qup11, qspi2, sdc42, ddr_pxi1, _, _, _, _, _), + [49] = PINGROUP(49, qup11, qspi3, sdc43, ddr_pxi1, _, _, _, _, _), + [50] = PINGROUP(50, qup11, qspi_clk, sdc4_clk, _, _, _, _, _, _), + [51] = PINGROUP(51, qup11, qspi_cs, sdc4_cmd, ddr_pxi0, _, _, _, _, _), + [52] = PINGROUP(52, qup12, ddr_pxi0, _, _, _, _, _, _, _), + [53] = PINGROUP(53, qup12, _, _, _, _, _, _, _, _), + [54] = PINGROUP(54, qup12, _, _, _, _, _, _, _, _), + [55] = PINGROUP(55, qup12, atest_usb, _, _, _, _, _, _, _), + [56] = PINGROUP(56, qup14, ibi_i3c, _, _, _, _, _, _, _), + [57] = PINGROUP(57, qup14, ibi_i3c, _, _, _, _, _, _, _), + [58] = PINGROUP(58, qup14, qup_l4, _, _, _, _, _, _, _), + [59] = PINGROUP(59, qup14, qup_l5, _, _, _, _, _, _, _), + [60] = PINGROUP(60, qup15, ibi_i3c, _, _, _, _, _, _, _), + [61] = PINGROUP(61, qup15, ibi_i3c, _, _, _, _, _, _, _), + [62] = PINGROUP(62, qup15, qup_l6, _, _, _, _, _, _, _), + [63] = PINGROUP(63, qup15, qup_l4, _, _, _, _, _, _, _), + [64] = PINGROUP(64, qup16, tb_trig, _, _, _, _, _, _, _), + [65] = PINGROUP(65, qup16, _, _, _, _, _, _, _, _), + [66] = PINGROUP(66, qup16, qup_l5, _, _, _, _, _, _, _), + [67] = PINGROUP(67, qup16, qup_l6, _, _, _, _, _, _, _), + [68] = PINGROUP(68, qup18, _, _, _, _, _, _, _, _), + [69] = PINGROUP(69, qup18, _, _, _, _, _, _, _, _), + [70] = PINGROUP(70, qup18, _, _, _, _, _, _, _, _), + [71] = PINGROUP(71, qup18, _, _, _, _, _, _, _, _), + [72] = PINGROUP(72, qup17, phase_flag, _, _, _, _, _, _, _), + [73] = PINGROUP(73, qup17, phase_flag, _, _, _, _, _, _, _), + [74] = PINGROUP(74, qup17, phase_flag, _, _, _, _, _, _, _), + [75] = PINGROUP(75, qup17, phase_flag, _, _, _, _, _, _, _), + [76] = PINGROUP(76, qup19, phase_flag, _, _, _, _, _, _, _), + [77] = PINGROUP(77, qup19, phase_flag, _, _, _, _, _, _, _), + [78] = PINGROUP(78, qup19, phase_flag, _, vsense_trigger, _, _, _, _, _), + [79] = PINGROUP(79, qup19, phase_flag, _, _, _, _, _, _, _), + [80] = PINGROUP(80, usb2phy_ac, jitter_bist, atest_usb, _, _, _, _, _, _), + [81] = PINGROUP(81, usb_phy, pll_bist, pll_clk, atest_usb, _, _, _, _, _), + [82] = PINGROUP(82, mdp_vsync, _, _, _, _, _, _, _, _), + [83] = PINGROUP(83, mdp_vsync, dp_lcd, _, _, _, _, _, _, _), + [84] = PINGROUP(84, mdp_vsync, vfr_0, _, _, _, _, _, _, _), + [85] = PINGROUP(85, atest_char, _, _, _, _, _, _, _, _), + [86] = PINGROUP(86, mdp_vsync0, mdp_vsync1, atest_char, _, _, _, _, _, _), + [87] = PINGROUP(87, dp_hot, mdp_vsync2, mdp_vsync3, qdss_cti, atest_char, _, _, _, _), + [88] = PINGROUP(88, qdss_cti, tsense_pwm1, tsense_pwm2, _, _, _, _, _, _), + [89] = PINGROUP(89, qdss_cti, _, _, _, _, _, _, _, _), + [90] = PINGROUP(90, vfr_1, qdss_cti, _, _, _, _, _, _, _), + [91] = PINGROUP(91, qdss_cti, _, _, _, _, _, _, _, _), + [92] = PINGROUP(92, qdss_cti, _, _, _, _, _, _, _, _), + [93] = PINGROUP(93, sd_write, _, _, _, _, _, _, _, _), + [94] = PINGROUP(94, _, _, _, _, _, _, _, _, _), + [95] = PINGROUP(95, pcie0_clkreqn, _, _, _, _, _, _, _, _), + [96] = PINGROUP(96, _, _, _, _, _, _, _, _, _), + [97] = PINGROUP(97, _, _, _, _, _, _, _, _, _), + [98] = PINGROUP(98, pcie1_clkreqn, _, _, _, _, _, _, _, _), + [99] = PINGROUP(99, tgu_ch0, _, _, _, _, _, _, _, _), + [100] = PINGROUP(100, cam_mclk, tgu_ch1, qdss_gpio, _, _, _, _, _, _), + [101] = PINGROUP(101, cam_mclk, tgu_ch2, qdss_gpio, _, _, _, _, _, _), + [102] = PINGROUP(102, cam_mclk, tgu_ch3, qdss_gpio, _, _, _, _, _, _), + [103] = PINGROUP(103, cam_mclk, phase_flag, _, qdss_gpio, _, _, _, _, _), + [104] = PINGROUP(104, cam_mclk, phase_flag, _, qdss_gpio, _, _, _, _, _), + [105] = PINGROUP(105, cam_mclk, phase_flag, _, qdss_gpio, _, _, _, _, _), + [106] = PINGROUP(106, cci_async, phase_flag, _, qdss_gpio, _, _, _, _, _), + [107] = PINGROUP(107, cci_i2c, phase_flag, _, qdss_gpio, _, _, _, _, _), + [108] = PINGROUP(108, cci_i2c, phase_flag, _, qdss_gpio, _, _, _, _, _), + [109] = PINGROUP(109, cci_i2c, phase_flag, _, qdss_gpio, _, _, _, _, _), + [110] = PINGROUP(110, cci_i2c, phase_flag, _, qdss_gpio, _, _, _, _, _), + [111] = PINGROUP(111, cci_i2c, phase_flag, _, qdss_gpio, _, _, _, _, _), + [112] = PINGROUP(112, cci_i2c, phase_flag, _, qdss_gpio, _, _, _, _, _), + [113] = PINGROUP(113, cci_i2c, phase_flag, _, qdss_gpio, _, _, _, _, _), + [114] = PINGROUP(114, cci_i2c, phase_flag, _, qdss_gpio, _, _, _, _, _), + [115] = PINGROUP(115, cci_timer, gcc_gp1, qdss_gpio, atest_char, _, _, _, _, _), + [116] = PINGROUP(116, cci_timer, gcc_gp2, qdss_gpio, _, _, _, _, _, _), + [117] = PINGROUP(117, cci_timer, gcc_gp3, qdss_gpio, atest_char, _, _, _, _, _), + [118] = PINGROUP(118, cci_timer, cci_async, _, _, _, _, _, _, _), + [119] = PINGROUP(119, cci_timer, cci_async, _, _, _, _, _, _, _), + [120] = PINGROUP(120, mi2s2_sck, _, _, _, _, _, _, _, _), + [121] = PINGROUP(121, mi2s2_data0, _, _, _, _, _, _, _, _), + [122] = PINGROUP(122, mi2s2_ws, _, _, _, _, _, _, _, _), + [123] = PINGROUP(123, pri_mi2s, _, _, _, _, _, _, _, _), + [124] = PINGROUP(124, sec_mi2s, audio_ref, mi2s2_data1, _, _, _, _, _, _), + [125] = PINGROUP(125, mi2s0_sck, _, _, _, _, _, _, _, _), + [126] = PINGROUP(126, mi2s0_data0, _, _, _, _, _, _, _, _), + [127] = PINGROUP(127, mi2s0_data1, _, _, _, _, _, _, _, _), + [128] = PINGROUP(128, mi2s0_ws, _, _, _, _, _, _, _, _), + [129] = PINGROUP(129, lpass_slimbus, mi2s1_sck, gcc_gp1, _, _, _, _, _, _), + [130] = PINGROUP(130, lpass_slimbus, mi2s1_data0, gcc_gp2, _, _, _, _, _, _), + [131] = PINGROUP(131, mi2s1_data1, gcc_gp3, _, _, _, _, _, _, _), + [132] = PINGROUP(132, mi2s1_ws, _, _, _, _, _, _, _, _), + [133] = PINGROUP(133, uim1_data, _, _, _, _, _, _, _, _), + [134] = PINGROUP(134, uim1_clk, _, _, _, _, _, _, _, _), + [135] = PINGROUP(135, uim1_reset, _, _, _, _, _, _, _, _), + [136] = PINGROUP(136, uim1_present, tb_trig, _, _, _, _, _, _, _), + [137] = PINGROUP(137, uim0_data, _, _, _, _, _, _, _, _), + [138] = PINGROUP(138, uim0_clk, _, _, _, _, _, _, _, _), + [139] = PINGROUP(139, uim0_reset, _, _, _, _, _, _, _, _), + [140] = PINGROUP(140, uim0_present, _, _, _, _, _, _, _, _), + [141] = PINGROUP(141, _, mss_grfc0, _, _, _, _, _, _, _), + [142] = PINGROUP(142, _, mss_grfc1, _, _, _, _, _, _, _), + [143] = PINGROUP(143, _, mss_grfc2, _, _, _, _, _, _, _), + [144] = PINGROUP(144, _, mss_grfc3, _, _, _, _, _, _, _), + [145] = PINGROUP(145, _, mss_grfc4, _, _, _, _, _, _, _), + [146] = PINGROUP(146, _, mss_grfc5, _, _, _, _, _, _, _), + [147] = PINGROUP(147, _, mss_grfc6, _, _, _, _, _, _, _), + [148] = PINGROUP(148, _, mss_grfc7, _, _, _, _, _, _, _), + [149] = PINGROUP(149, _, mss_grfc8, _, _, _, _, _, _, _), + [150] = PINGROUP(150, _, mss_grfc9, _, _, _, _, _, _, _), + [151] = PINGROUP(151, coex_uart1, atest_usb, _, _, _, _, _, _, _), + [152] = PINGROUP(152, coex_uart1, atest_usb, _, _, _, _, _, _, _), + [153] = PINGROUP(153, coex_uart2, mss_grfc10, atest_usb, _, _, _, _, _, _), + [154] = PINGROUP(154, coex_uart2, mss_grfc11, atest_usb, _, _, _, _, _, _), + [155] = PINGROUP(155, nav_gpio, _, _, _, _, _, _, _, _), + [156] = PINGROUP(156, nav_gpio, _, _, _, _, _, _, _, _), + [157] = PINGROUP(157, mss_grfc12, pa_indicator, nav_gpio, _, _, _, _, _, _), + [158] = PINGROUP(158, mss_grfc0, atest_usb, _, _, _, _, _, _, _), + [159] = PINGROUP(159, qlink0_request, atest_usb, _, _, _, _, _, _, _), + [160] = PINGROUP(160, qlink0_enable, _, _, _, _, _, _, _, _), + [161] = PINGROUP(161, qlink0_wmss, atest_usb, _, _, _, _, _, _, _), + [162] = PINGROUP(162, qlink1_request, _, _, _, _, _, _, _, _), + [163] = PINGROUP(163, qlink1_enable, _, _, _, _, _, _, _, _), + [164] = PINGROUP(164, qlink1_wmss, _, _, _, _, _, _, _, _), + [165] = PINGROUP(165, qlink2_request, _, _, _, _, _, _, _, _), + [166] = PINGROUP(166, qlink2_enable, _, _, _, _, _, _, _, _), + [167] = PINGROUP(167, qlink2_wmss, _, _, _, _, _, _, _, _), + [168] = PINGROUP(168, _, _, _, _, _, _, _, _, _), + [169] = PINGROUP(169, _, _, _, _, _, _, _, _, _), + [170] = PINGROUP(170, _, _, _, _, _, _, _, _, _), + [171] = PINGROUP(171, _, _, _, _, _, _, _, _, _), + [172] = PINGROUP(172, _, _, _, _, _, _, _, _, _), + [173] = PINGROUP(173, _, _, _, _, _, _, _, _, _), + [174] = PINGROUP(174, cmu_rng, _, _, _, _, _, _, _, _), + [175] = PINGROUP(175, cmu_rng, _, _, _, _, _, _, _, _), + [176] = PINGROUP(176, cmu_rng, _, _, _, _, _, _, _, _), + [177] = PINGROUP(177, cmu_rng, _, _, _, _, _, _, _, _), + [178] = PINGROUP(178, _, _, _, _, _, _, _, _, _), + [179] = PINGROUP(179, _, _, _, _, _, _, _, _, _), + [180] = PINGROUP(180, _, _, _, _, _, _, _, _, _), + [181] = PINGROUP(181, _, _, _, _, _, _, _, _, _), + [182] = PINGROUP(182, _, _, _, _, _, _, _, _, _), + [183] = PINGROUP(183, cri_trng0, qdss_gpio, _, _, _, _, _, _, _), + [184] = PINGROUP(184, cri_trng1, qdss_gpio, _, _, _, _, _, _, _), + [185] = PINGROUP(185, prng_rosc, qdss_gpio, _, _, _, _, _, _, _), + [186] = PINGROUP(186, cri_trng, qdss_gpio, _, _, _, _, _, _, _), + [187] = PINGROUP(187, qdss_gpio, _, _, _, _, _, _, _, _), + [188] = PINGROUP(188, qdss_gpio, _, _, _, _, _, _, _, _), + [189] = PINGROUP(189, qdss_gpio, _, _, _, _, _, _, _, _), + [190] = PINGROUP(190, qdss_gpio, _, _, _, _, _, _, _, _), + [191] = PINGROUP(191, qdss_gpio, _, _, _, _, _, _, _, _), + [192] = PINGROUP(192, qdss_gpio, _, _, _, _, _, _, _, _), + [193] = PINGROUP(193, qdss_gpio, _, _, _, _, _, _, _, _), + [194] = PINGROUP(194, qdss_gpio, _, _, _, _, _, _, _, _), + [195] = PINGROUP(195, qdss_gpio, _, _, _, _, _, _, _, _), + [196] = PINGROUP(196, qdss_gpio, _, _, _, _, _, _, _, _), + [197] = PINGROUP(197, qdss_gpio, _, _, _, _, _, _, _, _), + [198] = PINGROUP(198, qdss_gpio, _, _, _, _, _, _, _, _), + [199] = PINGROUP(199, qdss_gpio, _, _, _, _, _, _, _, _), + [200] = PINGROUP(200, qdss_gpio, _, _, _, _, _, _, _, _), + [201] = PINGROUP(201, _, _, _, _, _, _, _, _, _), + [202] = PINGROUP(202, _, _, _, _, _, _, _, _, _), + [203] = UFS_RESET(ufs_reset, 0x1d8000), + [204] = SDC_PINGROUP(sdc2_clk, 0x1cf000, 14, 6), + [205] = SDC_PINGROUP(sdc2_cmd, 0x1cf000, 11, 3), + [206] = SDC_PINGROUP(sdc2_data, 0x1cf000, 9, 0), +}; + +static const struct msm_pinctrl_soc_data sm8350_tlmm = { + .pins = sm8350_pins, + .npins = ARRAY_SIZE(sm8350_pins), + .functions = sm8350_functions, + .nfunctions = ARRAY_SIZE(sm8350_functions), + .groups = sm8350_groups, + .ngroups = ARRAY_SIZE(sm8350_groups), + .ngpios = 204, +}; + +static int sm8350_tlmm_probe(struct platform_device *pdev) +{ + return msm_pinctrl_probe(pdev, &sm8350_tlmm); +} + +static const struct of_device_id sm8350_tlmm_of_match[] = { + { .compatible = "qcom,sm8350-tlmm", }, + { }, +}; + +static struct platform_driver sm8350_tlmm_driver = { + .driver = { + .name = "sm8350-tlmm", + .of_match_table = sm8350_tlmm_of_match, + }, + .probe = sm8350_tlmm_probe, + .remove = msm_pinctrl_remove, +}; + +static int __init sm8350_tlmm_init(void) +{ + return platform_driver_register(&sm8350_tlmm_driver); +} +arch_initcall(sm8350_tlmm_init); + +static void __exit sm8350_tlmm_exit(void) +{ + platform_driver_unregister(&sm8350_tlmm_driver); +} +module_exit(sm8350_tlmm_exit); + +MODULE_DESCRIPTION("QTI SM8350 TLMM driver"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, sm8350_tlmm_of_match); diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c index 48602dba4967..3c213f799feb 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c @@ -912,6 +912,7 @@ static int pmic_mpp_remove(struct platform_device *pdev) } static const struct of_device_id pmic_mpp_of_match[] = { + { .compatible = "qcom,pm8019-mpp" }, /* 6 MPP's */ { .compatible = "qcom,pm8841-mpp" }, /* 4 MPP's */ { .compatible = "qcom,pm8916-mpp" }, /* 4 MPP's */ { .compatible = "qcom,pm8941-mpp" }, /* 8 MPP's */ diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c index 681d8dcf37e3..92e7f2602847 100644 --- a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c @@ -617,7 +617,6 @@ static void pm8xxx_mpp_dbg_show_one(struct seq_file *s, } break; } - } static void pm8xxx_mpp_dbg_show(struct seq_file *s, struct gpio_chip *chip) diff --git a/drivers/pinctrl/ralink/pinctrl-rt2880.c b/drivers/pinctrl/ralink/pinctrl-rt2880.c index 42b1c6cecb57..1f4bca854add 100644 --- a/drivers/pinctrl/ralink/pinctrl-rt2880.c +++ b/drivers/pinctrl/ralink/pinctrl-rt2880.c @@ -193,7 +193,6 @@ static struct rt2880_pmx_func gpio_func = { static int rt2880_pinmux_index(struct rt2880_priv *p) { - struct rt2880_pmx_func **f; struct rt2880_pmx_group *mux = p->groups; int i, j, c = 0; @@ -207,7 +206,7 @@ static int rt2880_pinmux_index(struct rt2880_priv *p) p->group_names = devm_kcalloc(p->dev, p->group_count, sizeof(char *), GFP_KERNEL); if (!p->group_names) - return -1; + return -ENOMEM; for (i = 0; i < p->group_count; i++) { p->group_names[i] = p->groups[i].name; @@ -218,31 +217,31 @@ static int rt2880_pinmux_index(struct rt2880_priv *p) p->func_count++; /* allocate our function and group mapping index buffers */ - f = p->func = devm_kcalloc(p->dev, - p->func_count, - sizeof(*p->func), - GFP_KERNEL); + p->func = devm_kcalloc(p->dev, p->func_count, + sizeof(*p->func), GFP_KERNEL); gpio_func.groups = devm_kcalloc(p->dev, p->group_count, sizeof(int), GFP_KERNEL); - if (!f || !gpio_func.groups) - return -1; + if (!p->func || !gpio_func.groups) + return -ENOMEM; /* add a backpointer to the function so it knows its group */ gpio_func.group_count = p->group_count; for (i = 0; i < gpio_func.group_count; i++) gpio_func.groups[i] = i; - f[c] = &gpio_func; + p->func[c] = &gpio_func; c++; /* add remaining functions */ for (i = 0; i < p->group_count; i++) { for (j = 0; j < p->groups[i].func_count; j++) { - f[c] = &p->groups[i].func[j]; - f[c]->groups = devm_kzalloc(p->dev, sizeof(int), + p->func[c] = &p->groups[i].func[j]; + p->func[c]->groups = devm_kzalloc(p->dev, sizeof(int), GFP_KERNEL); - f[c]->groups[0] = i; - f[c]->group_count = 1; + if (!p->func[c]->groups) + return -ENOMEM; + p->func[c]->groups[0] = i; + p->func[c]->group_count = 1; c++; } } @@ -280,10 +279,8 @@ static int rt2880_pinmux_pins(struct rt2880_priv *p) /* the pads needed to tell pinctrl about our pins */ p->pads = devm_kcalloc(p->dev, p->max_pins, sizeof(struct pinctrl_pin_desc), GFP_KERNEL); - if (!p->pads || !p->gpio) { - dev_err(p->dev, "Failed to allocate gpio data\n"); + if (!p->pads || !p->gpio) return -ENOMEM; - } memset(p->gpio, 1, sizeof(u8) * p->max_pins); for (i = 0; i < p->func_count; i++) { @@ -318,6 +315,7 @@ static int rt2880_pinmux_probe(struct platform_device *pdev) { struct rt2880_priv *p; struct pinctrl_dev *dev; + int err; if (!rt2880_pinmux_data) return -ENOTSUPP; @@ -333,19 +331,20 @@ static int rt2880_pinmux_probe(struct platform_device *pdev) platform_set_drvdata(pdev, p); /* init the device */ - if (rt2880_pinmux_index(p)) { + err = rt2880_pinmux_index(p); + if (err) { dev_err(&pdev->dev, "failed to load index\n"); - return -EINVAL; + return err; } - if (rt2880_pinmux_pins(p)) { + + err = rt2880_pinmux_pins(p); + if (err) { dev_err(&pdev->dev, "failed to load pins\n"); - return -EINVAL; + return err; } dev = pinctrl_register(p->desc, &pdev->dev, p); - if (IS_ERR(dev)) - return PTR_ERR(dev); - return 0; + return PTR_ERR_OR_ZERO(dev); } static const struct of_device_id rt2880_pinmux_match[] = { @@ -362,7 +361,7 @@ static struct platform_driver rt2880_pinmux_driver = { }, }; -int __init rt2880_pinmux_init(void) +static int __init rt2880_pinmux_init(void) { return platform_driver_register(&rt2880_pinmux_driver); } diff --git a/drivers/pinctrl/renesas/Kconfig b/drivers/pinctrl/renesas/Kconfig index e941b8440dbc..4b84a744ae87 100644 --- a/drivers/pinctrl/renesas/Kconfig +++ b/drivers/pinctrl/renesas/Kconfig @@ -36,6 +36,7 @@ config PINCTRL_RENESAS select PINCTRL_PFC_R8A77980 if ARCH_R8A77980 select PINCTRL_PFC_R8A77990 if ARCH_R8A77990 select PINCTRL_PFC_R8A77995 if ARCH_R8A77995 + select PINCTRL_PFC_R8A779A0 if ARCH_R8A779A0 select PINCTRL_PFC_SH7203 if CPU_SUBTYPE_SH7203 select PINCTRL_PFC_SH7264 if CPU_SUBTYPE_SH7264 select PINCTRL_PFC_SH7269 if CPU_SUBTYPE_SH7269 @@ -142,6 +143,10 @@ config PINCTRL_PFC_R8A77970 bool "pin control support for R-Car V3M" if COMPILE_TEST select PINCTRL_SH_PFC +config PINCTRL_PFC_R8A779A0 + bool "pin control support for R-Car V3U" if COMPILE_TEST + select PINCTRL_SH_PFC + config PINCTRL_PFC_R8A7740 bool "pin control support for R-Mobile A1" if COMPILE_TEST select PINCTRL_SH_PFC_GPIO diff --git a/drivers/pinctrl/renesas/Makefile b/drivers/pinctrl/renesas/Makefile index 1f6d7dd019d8..353563228dc2 100644 --- a/drivers/pinctrl/renesas/Makefile +++ b/drivers/pinctrl/renesas/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A77970) += pfc-r8a77970.o obj-$(CONFIG_PINCTRL_PFC_R8A77980) += pfc-r8a77980.o obj-$(CONFIG_PINCTRL_PFC_R8A77990) += pfc-r8a77990.o obj-$(CONFIG_PINCTRL_PFC_R8A77995) += pfc-r8a77995.o +obj-$(CONFIG_PINCTRL_PFC_R8A779A0) += pfc-r8a779a0.o obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o diff --git a/drivers/pinctrl/renesas/core.c b/drivers/pinctrl/renesas/core.c index 2cc457279345..2bfd3006f6fd 100644 --- a/drivers/pinctrl/renesas/core.c +++ b/drivers/pinctrl/renesas/core.c @@ -175,13 +175,25 @@ u32 sh_pfc_read(struct sh_pfc *pfc, u32 reg) return sh_pfc_read_raw_reg(sh_pfc_phys_to_virt(pfc, reg), 32); } +static void sh_pfc_unlock_reg(struct sh_pfc *pfc, u32 reg, u32 data) +{ + u32 unlock; + + if (!pfc->info->unlock_reg) + return; + + if (pfc->info->unlock_reg >= 0x80000000UL) + unlock = pfc->info->unlock_reg; + else + /* unlock_reg is a mask */ + unlock = reg & ~pfc->info->unlock_reg; + + sh_pfc_write_raw_reg(sh_pfc_phys_to_virt(pfc, unlock), 32, ~data); +} + void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data) { - if (pfc->info->unlock_reg) - sh_pfc_write_raw_reg( - sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32, - ~data); - + sh_pfc_unlock_reg(pfc, reg, data); sh_pfc_write_raw_reg(sh_pfc_phys_to_virt(pfc, reg), 32, data); } @@ -227,11 +239,7 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc, data &= mask; data |= value; - if (pfc->info->unlock_reg) - sh_pfc_write_raw_reg( - sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32, - ~data); - + sh_pfc_unlock_reg(pfc, crp->reg, data); sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data); } @@ -638,6 +646,12 @@ static const struct of_device_id sh_pfc_of_table[] = { .data = &r8a77995_pinmux_info, }, #endif +#ifdef CONFIG_PINCTRL_PFC_R8A779A0 + { + .compatible = "renesas,pfc-r8a779a0", + .data = &r8a779a0_pinmux_info, + }, +#endif #ifdef CONFIG_PINCTRL_PFC_SH73A0 { .compatible = "renesas,pfc-sh73a0", @@ -1052,6 +1066,10 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) { unsigned int i; + if (!IS_ENABLED(CONFIG_SUPERH) && + !of_find_matching_node(NULL, pdrv->driver.of_match_table)) + return; + sh_pfc_regs = kcalloc(SH_PFC_MAX_REGS, sizeof(*sh_pfc_regs), GFP_KERNEL); if (!sh_pfc_regs) diff --git a/drivers/pinctrl/renesas/pfc-r8a77950.c b/drivers/pinctrl/renesas/pfc-r8a77950.c index 32b66b9999b8..32fe8caca70a 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77950.c +++ b/drivers/pinctrl/renesas/pfc-r8a77950.c @@ -1668,7 +1668,6 @@ static const unsigned int avb_mii_pins[] = { PIN_AVB_RX_CTL, PIN_AVB_RXC, PIN_AVB_RD0, PIN_AVB_RD1, PIN_AVB_RD2, PIN_AVB_RD3, PIN_AVB_TXCREFCLK, - }; static const unsigned int avb_mii_mux[] = { AVB_TX_CTL_MARK, AVB_TXC_MARK, AVB_TD0_MARK, diff --git a/drivers/pinctrl/renesas/pfc-r8a77951.c b/drivers/pinctrl/renesas/pfc-r8a77951.c index cf14420794c7..bdd605e41303 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77951.c +++ b/drivers/pinctrl/renesas/pfc-r8a77951.c @@ -1727,7 +1727,6 @@ static const unsigned int avb_mii_pins[] = { PIN_AVB_RX_CTL, PIN_AVB_RXC, PIN_AVB_RD0, PIN_AVB_RD1, PIN_AVB_RD2, PIN_AVB_RD3, PIN_AVB_TXCREFCLK, - }; static const unsigned int avb_mii_mux[] = { AVB_TX_CTL_MARK, AVB_TXC_MARK, AVB_TD0_MARK, diff --git a/drivers/pinctrl/renesas/pfc-r8a7796.c b/drivers/pinctrl/renesas/pfc-r8a7796.c index 38d963561b5f..96b5b1509bb7 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7796.c +++ b/drivers/pinctrl/renesas/pfc-r8a7796.c @@ -1731,7 +1731,6 @@ static const unsigned int avb_mii_pins[] = { PIN_AVB_RX_CTL, PIN_AVB_RXC, PIN_AVB_RD0, PIN_AVB_RD1, PIN_AVB_RD2, PIN_AVB_RD3, PIN_AVB_TXCREFCLK, - }; static const unsigned int avb_mii_mux[] = { AVB_TX_CTL_MARK, AVB_TXC_MARK, AVB_TD0_MARK, diff --git a/drivers/pinctrl/renesas/pfc-r8a77965.c b/drivers/pinctrl/renesas/pfc-r8a77965.c index 92f231baff7d..f15e29383d9b 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77965.c +++ b/drivers/pinctrl/renesas/pfc-r8a77965.c @@ -1736,7 +1736,6 @@ static const unsigned int avb_mii_pins[] = { PIN_AVB_RX_CTL, PIN_AVB_RXC, PIN_AVB_RD0, PIN_AVB_RD1, PIN_AVB_RD2, PIN_AVB_RD3, PIN_AVB_TXCREFCLK, - }; static const unsigned int avb_mii_mux[] = { AVB_TX_CTL_MARK, AVB_TXC_MARK, AVB_TD0_MARK, diff --git a/drivers/pinctrl/renesas/pfc-r8a779a0.c b/drivers/pinctrl/renesas/pfc-r8a779a0.c new file mode 100644 index 000000000000..2250ccd0470a --- /dev/null +++ b/drivers/pinctrl/renesas/pfc-r8a779a0.c @@ -0,0 +1,4460 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R8A779A0 processor support - PFC hardware block. + * + * Copyright (C) 2020 Renesas Electronics Corp. + * + * This file is based on the drivers/pinctrl/renesas/pfc-r8a7795.c + */ + +#include +#include +#include + +#include "core.h" +#include "sh_pfc.h" + +#define CFG_FLAGS (SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_PULL_UP_DOWN) + +#define CPU_ALL_GP(fn, sfx) \ + PORT_GP_CFG_15(0, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(0, 15, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 16, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 17, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 18, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 19, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 20, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 21, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 22, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 23, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 24, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 25, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 26, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(0, 27, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_31(1, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_2(2, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 2, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 3, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 4, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 5, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 6, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 7, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 8, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 9, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 10, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 11, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 12, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 13, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 14, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 15, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_18_33), \ + PORT_GP_CFG_1(2, 16, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 17, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 18, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 19, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 20, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 21, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 22, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 23, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(2, 24, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_17(3, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_18(4, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_25_33),\ + PORT_GP_CFG_1(4, 18, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 19, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 20, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 21, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 22, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 23, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 24, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 25, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(4, 26, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_18(5, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_25_33),\ + PORT_GP_CFG_1(5, 18, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(5, 19, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(5, 20, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_18(6, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_25_33),\ + PORT_GP_CFG_1(6, 18, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(6, 19, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(6, 20, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_18(7, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_25_33),\ + PORT_GP_CFG_1(7, 18, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(7, 19, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(7, 20, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_18(8, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_25_33),\ + PORT_GP_CFG_1(8, 18, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(8, 19, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(8, 20, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_18(9, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE_25_33),\ + PORT_GP_CFG_1(9, 18, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(9, 19, fn, sfx, CFG_FLAGS), \ + PORT_GP_CFG_1(9, 20, fn, sfx, CFG_FLAGS) + +#define CPU_ALL_NOGP(fn) \ + PIN_NOGP_CFG(PRESETOUT_N, "PRESETOUT#", fn, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PIN_NOGP_CFG(EXTALR, "EXTALR", fn, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PIN_NOGP_CFG(DCUTRST_N_LPDRST_N, "DCUTRST#_LPDRST#", fn, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PIN_NOGP_CFG(DCUTCK_LPDCLK, "DCUTCK_LPDCLK", fn, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PIN_NOGP_CFG(DCUTMS, "DCUTMS", fn, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PIN_NOGP_CFG(DCUTDI_LPDI, "DCUTDI_LPDI", fn, SH_PFC_PIN_CFG_PULL_UP_DOWN) + +/* + * F_() : just information + * FM() : macro for FN_xxx / xxx_MARK + */ + +/* GPSR0 */ +#define GPSR0_27 FM(MMC_D7) +#define GPSR0_26 FM(MMC_D6) +#define GPSR0_25 FM(MMC_D5) +#define GPSR0_24 FM(MMC_D4) +#define GPSR0_23 FM(MMC_SD_CLK) +#define GPSR0_22 FM(MMC_SD_D3) +#define GPSR0_21 FM(MMC_SD_D2) +#define GPSR0_20 FM(MMC_SD_D1) +#define GPSR0_19 FM(MMC_SD_D0) +#define GPSR0_18 FM(MMC_SD_CMD) +#define GPSR0_17 FM(MMC_DS) +#define GPSR0_16 FM(SD_CD) +#define GPSR0_15 FM(SD_WP) +#define GPSR0_14 FM(RPC_INT_N) +#define GPSR0_13 FM(RPC_WP_N) +#define GPSR0_12 FM(RPC_RESET_N) +#define GPSR0_11 FM(QSPI1_SSL) +#define GPSR0_10 FM(QSPI1_IO3) +#define GPSR0_9 FM(QSPI1_IO2) +#define GPSR0_8 FM(QSPI1_MISO_IO1) +#define GPSR0_7 FM(QSPI1_MOSI_IO0) +#define GPSR0_6 FM(QSPI1_SPCLK) +#define GPSR0_5 FM(QSPI0_SSL) +#define GPSR0_4 FM(QSPI0_IO3) +#define GPSR0_3 FM(QSPI0_IO2) +#define GPSR0_2 FM(QSPI0_MISO_IO1) +#define GPSR0_1 FM(QSPI0_MOSI_IO0) +#define GPSR0_0 FM(QSPI0_SPCLK) + +/* GPSR1 */ +#define GPSR1_30 F_(GP1_30, IP3SR1_27_24) +#define GPSR1_29 F_(GP1_29, IP3SR1_23_20) +#define GPSR1_28 F_(GP1_28, IP3SR1_19_16) +#define GPSR1_27 F_(IRQ3, IP3SR1_15_12) +#define GPSR1_26 F_(IRQ2, IP3SR1_11_8) +#define GPSR1_25 F_(IRQ1, IP3SR1_7_4) +#define GPSR1_24 F_(IRQ0, IP3SR1_3_0) +#define GPSR1_23 F_(MSIOF2_SS2, IP2SR1_31_28) +#define GPSR1_22 F_(MSIOF2_SS1, IP2SR1_27_24) +#define GPSR1_21 F_(MSIOF2_SYNC, IP2SR1_23_20) +#define GPSR1_20 F_(MSIOF2_SCK, IP2SR1_19_16) +#define GPSR1_19 F_(MSIOF2_TXD, IP2SR1_15_12) +#define GPSR1_18 F_(MSIOF2_RXD, IP2SR1_11_8) +#define GPSR1_17 F_(MSIOF1_SS2, IP2SR1_7_4) +#define GPSR1_16 F_(MSIOF1_SS1, IP2SR1_3_0) +#define GPSR1_15 F_(MSIOF1_SYNC, IP1SR1_31_28) +#define GPSR1_14 F_(MSIOF1_SCK, IP1SR1_27_24) +#define GPSR1_13 F_(MSIOF1_TXD, IP1SR1_23_20) +#define GPSR1_12 F_(MSIOF1_RXD, IP1SR1_19_16) +#define GPSR1_11 F_(MSIOF0_SS2, IP1SR1_15_12) +#define GPSR1_10 F_(MSIOF0_SS1, IP1SR1_11_8) +#define GPSR1_9 F_(MSIOF0_SYNC, IP1SR1_7_4) +#define GPSR1_8 F_(MSIOF0_SCK, IP1SR1_3_0) +#define GPSR1_7 F_(MSIOF0_TXD, IP0SR1_31_28) +#define GPSR1_6 F_(MSIOF0_RXD, IP0SR1_27_24) +#define GPSR1_5 F_(HTX0, IP0SR1_23_20) +#define GPSR1_4 F_(HCTS0_N, IP0SR1_19_16) +#define GPSR1_3 F_(HRTS0_N, IP0SR1_15_12) +#define GPSR1_2 F_(HSCK0, IP0SR1_11_8) +#define GPSR1_1 F_(HRX0, IP0SR1_7_4) +#define GPSR1_0 F_(SCIF_CLK, IP0SR1_3_0) + +/* GPSR2 */ +#define GPSR2_24 FM(TCLK2_A) +#define GPSR2_23 F_(TCLK1_A, IP2SR2_31_28) +#define GPSR2_22 F_(TPU0TO1, IP2SR2_27_24) +#define GPSR2_21 F_(TPU0TO0, IP2SR2_23_20) +#define GPSR2_20 F_(CLK_EXTFXR, IP2SR2_19_16) +#define GPSR2_19 F_(RXDB_EXTFXR, IP2SR2_15_12) +#define GPSR2_18 F_(FXR_TXDB, IP2SR2_11_8) +#define GPSR2_17 F_(RXDA_EXTFXR_A, IP2SR2_7_4) +#define GPSR2_16 F_(FXR_TXDA_A, IP2SR2_3_0) +#define GPSR2_15 F_(GP2_15, IP1SR2_31_28) +#define GPSR2_14 F_(GP2_14, IP1SR2_27_24) +#define GPSR2_13 F_(GP2_13, IP1SR2_23_20) +#define GPSR2_12 F_(GP2_12, IP1SR2_19_16) +#define GPSR2_11 F_(GP2_11, IP1SR2_15_12) +#define GPSR2_10 F_(GP2_10, IP1SR2_11_8) +#define GPSR2_9 F_(GP2_09, IP1SR2_7_4) +#define GPSR2_8 F_(GP2_08, IP1SR2_3_0) +#define GPSR2_7 F_(GP2_07, IP0SR2_31_28) +#define GPSR2_6 F_(GP2_06, IP0SR2_27_24) +#define GPSR2_5 F_(GP2_05, IP0SR2_23_20) +#define GPSR2_4 F_(GP2_04, IP0SR2_19_16) +#define GPSR2_3 F_(GP2_03, IP0SR2_15_12) +#define GPSR2_2 F_(GP2_02, IP0SR2_11_8) +#define GPSR2_1 F_(IPC_CLKOUT, IP0SR2_7_4) +#define GPSR2_0 F_(IPC_CLKIN, IP0SR2_3_0) + +/* GPSR3 */ +#define GPSR3_16 FM(CANFD7_RX) +#define GPSR3_15 FM(CANFD7_TX) +#define GPSR3_14 FM(CANFD6_RX) +#define GPSR3_13 F_(CANFD6_TX, IP1SR3_23_20) +#define GPSR3_12 F_(CANFD5_RX, IP1SR3_19_16) +#define GPSR3_11 F_(CANFD5_TX, IP1SR3_15_12) +#define GPSR3_10 F_(CANFD4_RX, IP1SR3_11_8) +#define GPSR3_9 F_(CANFD4_TX, IP1SR3_7_4) +#define GPSR3_8 F_(CANFD3_RX, IP1SR3_3_0) +#define GPSR3_7 F_(CANFD3_TX, IP0SR3_31_28) +#define GPSR3_6 F_(CANFD2_RX, IP0SR3_27_24) +#define GPSR3_5 F_(CANFD2_TX, IP0SR3_23_20) +#define GPSR3_4 FM(CANFD1_RX) +#define GPSR3_3 FM(CANFD1_TX) +#define GPSR3_2 F_(CANFD0_RX, IP0SR3_11_8) +#define GPSR3_1 F_(CANFD0_TX, IP0SR3_7_4) +#define GPSR3_0 FM(CAN_CLK) + +/* GPSR4 */ +#define GPSR4_26 FM(AVS1) +#define GPSR4_25 FM(AVS0) +#define GPSR4_24 FM(PCIE3_CLKREQ_N) +#define GPSR4_23 FM(PCIE2_CLKREQ_N) +#define GPSR4_22 FM(PCIE1_CLKREQ_N) +#define GPSR4_21 FM(PCIE0_CLKREQ_N) +#define GPSR4_20 F_(AVB0_AVTP_PPS, IP2SR4_19_16) +#define GPSR4_19 F_(AVB0_AVTP_CAPTURE, IP2SR4_15_12) +#define GPSR4_18 F_(AVB0_AVTP_MATCH, IP2SR4_11_8) +#define GPSR4_17 F_(AVB0_LINK, IP2SR4_7_4) +#define GPSR4_16 FM(AVB0_PHY_INT) +#define GPSR4_15 F_(AVB0_MAGIC, IP1SR4_31_28) +#define GPSR4_14 F_(AVB0_MDC, IP1SR4_27_24) +#define GPSR4_13 F_(AVB0_MDIO, IP1SR4_23_20) +#define GPSR4_12 F_(AVB0_TXCREFCLK, IP1SR4_19_16) +#define GPSR4_11 F_(AVB0_TD3, IP1SR4_15_12) +#define GPSR4_10 F_(AVB0_TD2, IP1SR4_11_8) +#define GPSR4_9 F_(AVB0_TD1, IP1SR4_7_4) +#define GPSR4_8 F_(AVB0_TD0, IP1SR4_3_0) +#define GPSR4_7 F_(AVB0_TXC, IP0SR4_31_28) +#define GPSR4_6 F_(AVB0_TX_CTL, IP0SR4_27_24) +#define GPSR4_5 F_(AVB0_RD3, IP0SR4_23_20) +#define GPSR4_4 F_(AVB0_RD2, IP0SR4_19_16) +#define GPSR4_3 F_(AVB0_RD1, IP0SR4_15_12) +#define GPSR4_2 F_(AVB0_RD0, IP0SR4_11_8) +#define GPSR4_1 F_(AVB0_RXC, IP0SR4_7_4) +#define GPSR4_0 F_(AVB0_RX_CTL, IP0SR4_3_0) + +/* GPSR5 */ +#define GPSR5_20 F_(AVB1_AVTP_PPS, IP2SR5_19_16) +#define GPSR5_19 F_(AVB1_AVTP_CAPTURE, IP2SR5_15_12) +#define GPSR5_18 F_(AVB1_AVTP_MATCH, IP2SR5_11_8) +#define GPSR5_17 F_(AVB1_LINK, IP2SR5_7_4) +#define GPSR5_16 FM(AVB1_PHY_INT) +#define GPSR5_15 F_(AVB1_MAGIC, IP1SR5_31_28) +#define GPSR5_14 F_(AVB1_MDC, IP1SR5_27_24) +#define GPSR5_13 F_(AVB1_MDIO, IP1SR5_23_20) +#define GPSR5_12 F_(AVB1_TXCREFCLK, IP1SR5_19_16) +#define GPSR5_11 F_(AVB1_TD3, IP1SR5_15_12) +#define GPSR5_10 F_(AVB1_TD2, IP1SR5_11_8) +#define GPSR5_9 F_(AVB1_TD1, IP1SR5_7_4) +#define GPSR5_8 F_(AVB1_TD0, IP1SR5_3_0) +#define GPSR5_7 F_(AVB1_TXC, IP0SR5_31_28) +#define GPSR5_6 F_(AVB1_TX_CTL, IP0SR5_27_24) +#define GPSR5_5 F_(AVB1_RD3, IP0SR5_23_20) +#define GPSR5_4 F_(AVB1_RD2, IP0SR5_19_16) +#define GPSR5_3 F_(AVB1_RD1, IP0SR5_15_12) +#define GPSR5_2 F_(AVB1_RD0, IP0SR5_11_8) +#define GPSR5_1 F_(AVB1_RXC, IP0SR5_7_4) +#define GPSR5_0 F_(AVB1_RX_CTL, IP0SR5_3_0) + +/* GPSR6 */ +#define GPSR6_20 FM(AVB2_AVTP_PPS) +#define GPSR6_19 FM(AVB2_AVTP_CAPTURE) +#define GPSR6_18 FM(AVB2_AVTP_MATCH) +#define GPSR6_17 FM(AVB2_LINK) +#define GPSR6_16 FM(AVB2_PHY_INT) +#define GPSR6_15 FM(AVB2_MAGIC) +#define GPSR6_14 FM(AVB2_MDC) +#define GPSR6_13 FM(AVB2_MDIO) +#define GPSR6_12 FM(AVB2_TXCREFCLK) +#define GPSR6_11 FM(AVB2_TD3) +#define GPSR6_10 FM(AVB2_TD2) +#define GPSR6_9 FM(AVB2_TD1) +#define GPSR6_8 FM(AVB2_TD0) +#define GPSR6_7 FM(AVB2_TXC) +#define GPSR6_6 FM(AVB2_TX_CTL) +#define GPSR6_5 FM(AVB2_RD3) +#define GPSR6_4 FM(AVB2_RD2) +#define GPSR6_3 FM(AVB2_RD1) +#define GPSR6_2 FM(AVB2_RD0) +#define GPSR6_1 FM(AVB2_RXC) +#define GPSR6_0 FM(AVB2_RX_CTL) + +/* GPSR7 */ +#define GPSR7_20 FM(AVB3_AVTP_PPS) +#define GPSR7_19 FM(AVB3_AVTP_CAPTURE) +#define GPSR7_18 FM(AVB3_AVTP_MATCH) +#define GPSR7_17 FM(AVB3_LINK) +#define GPSR7_16 FM(AVB3_PHY_INT) +#define GPSR7_15 FM(AVB3_MAGIC) +#define GPSR7_14 FM(AVB3_MDC) +#define GPSR7_13 FM(AVB3_MDIO) +#define GPSR7_12 FM(AVB3_TXCREFCLK) +#define GPSR7_11 FM(AVB3_TD3) +#define GPSR7_10 FM(AVB3_TD2) +#define GPSR7_9 FM(AVB3_TD1) +#define GPSR7_8 FM(AVB3_TD0) +#define GPSR7_7 FM(AVB3_TXC) +#define GPSR7_6 FM(AVB3_TX_CTL) +#define GPSR7_5 FM(AVB3_RD3) +#define GPSR7_4 FM(AVB3_RD2) +#define GPSR7_3 FM(AVB3_RD1) +#define GPSR7_2 FM(AVB3_RD0) +#define GPSR7_1 FM(AVB3_RXC) +#define GPSR7_0 FM(AVB3_RX_CTL) + +/* GPSR8 */ +#define GPSR8_20 FM(AVB4_AVTP_PPS) +#define GPSR8_19 FM(AVB4_AVTP_CAPTURE) +#define GPSR8_18 FM(AVB4_AVTP_MATCH) +#define GPSR8_17 FM(AVB4_LINK) +#define GPSR8_16 FM(AVB4_PHY_INT) +#define GPSR8_15 FM(AVB4_MAGIC) +#define GPSR8_14 FM(AVB4_MDC) +#define GPSR8_13 FM(AVB4_MDIO) +#define GPSR8_12 FM(AVB4_TXCREFCLK) +#define GPSR8_11 FM(AVB4_TD3) +#define GPSR8_10 FM(AVB4_TD2) +#define GPSR8_9 FM(AVB4_TD1) +#define GPSR8_8 FM(AVB4_TD0) +#define GPSR8_7 FM(AVB4_TXC) +#define GPSR8_6 FM(AVB4_TX_CTL) +#define GPSR8_5 FM(AVB4_RD3) +#define GPSR8_4 FM(AVB4_RD2) +#define GPSR8_3 FM(AVB4_RD1) +#define GPSR8_2 FM(AVB4_RD0) +#define GPSR8_1 FM(AVB4_RXC) +#define GPSR8_0 FM(AVB4_RX_CTL) + +/* GPSR9 */ +#define GPSR9_20 FM(AVB5_AVTP_PPS) +#define GPSR9_19 FM(AVB5_AVTP_CAPTURE) +#define GPSR9_18 FM(AVB5_AVTP_MATCH) +#define GPSR9_17 FM(AVB5_LINK) +#define GPSR9_16 FM(AVB5_PHY_INT) +#define GPSR9_15 FM(AVB5_MAGIC) +#define GPSR9_14 FM(AVB5_MDC) +#define GPSR9_13 FM(AVB5_MDIO) +#define GPSR9_12 FM(AVB5_TXCREFCLK) +#define GPSR9_11 FM(AVB5_TD3) +#define GPSR9_10 FM(AVB5_TD2) +#define GPSR9_9 FM(AVB5_TD1) +#define GPSR9_8 FM(AVB5_TD0) +#define GPSR9_7 FM(AVB5_TXC) +#define GPSR9_6 FM(AVB5_TX_CTL) +#define GPSR9_5 FM(AVB5_RD3) +#define GPSR9_4 FM(AVB5_RD2) +#define GPSR9_3 FM(AVB5_RD1) +#define GPSR9_2 FM(AVB5_RD0) +#define GPSR9_1 FM(AVB5_RXC) +#define GPSR9_0 FM(AVB5_RX_CTL) + +/* IP0SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP0SR1_3_0 FM(SCIF_CLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) FM(A0) 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 IP0SR1_7_4 FM(HRX0) FM(RX0) F_(0, 0) F_(0, 0) F_(0, 0) FM(A1) 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 IP0SR1_11_8 FM(HSCK0) FM(SCK0) F_(0, 0) F_(0, 0) F_(0, 0) FM(A2) 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 IP0SR1_15_12 FM(HRTS0_N) FM(RTS0_N) F_(0, 0) F_(0, 0) F_(0, 0) FM(A3) 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 IP0SR1_19_16 FM(HCTS0_N) FM(CTS0_N) F_(0, 0) F_(0, 0) F_(0, 0) FM(A4) 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 IP0SR1_23_20 FM(HTX0) FM(TX0) F_(0, 0) F_(0, 0) F_(0, 0) FM(A5) 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 IP0SR1_27_24 FM(MSIOF0_RXD) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_DR2) FM(A6) 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 IP0SR1_31_28 FM(MSIOF0_TXD) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_DR3) FM(A7) 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) +/* IP1SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP1SR1_3_0 FM(MSIOF0_SCK) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_DR4) FM(A8) 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 IP1SR1_7_4 FM(MSIOF0_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_DR5) FM(A9) 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 IP1SR1_11_8 FM(MSIOF0_SS1) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_DR6) FM(A10) 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 IP1SR1_15_12 FM(MSIOF0_SS2) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_DR7) FM(A11) 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 IP1SR1_19_16 FM(MSIOF1_RXD) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_DG2) FM(A12) 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 IP1SR1_23_20 FM(MSIOF1_TXD) FM(HRX3) FM(SCK3) F_(0, 0) FM(DU_DG3) FM(A13) 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 IP1SR1_27_24 FM(MSIOF1_SCK) FM(HSCK3) FM(CTS3_N) F_(0, 0) FM(DU_DG4) FM(A14) 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 IP1SR1_31_28 FM(MSIOF1_SYNC) FM(HRTS3_N) FM(RTS3_N) F_(0, 0) FM(DU_DG5) FM(A15) 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) +/* IP2SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP2SR1_3_0 FM(MSIOF1_SS1) FM(HCTS3_N) FM(RX3) F_(0, 0) FM(DU_DG6) FM(A16) 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 IP2SR1_7_4 FM(MSIOF1_SS2) FM(HTX3) FM(TX3) F_(0, 0) FM(DU_DG7) FM(A17) 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 IP2SR1_11_8 FM(MSIOF2_RXD) FM(HSCK1) FM(SCK1) F_(0, 0) FM(DU_DB2) FM(A18) 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 IP2SR1_15_12 FM(MSIOF2_TXD) FM(HCTS1_N) FM(CTS1_N) F_(0, 0) FM(DU_DB3) FM(A19) 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 IP2SR1_19_16 FM(MSIOF2_SCK) FM(HRTS1_N) FM(RTS1_N) F_(0, 0) FM(DU_DB4) FM(A20) 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 IP2SR1_23_20 FM(MSIOF2_SYNC) FM(HRX1) FM(RX1_A) F_(0, 0) FM(DU_DB5) FM(A21) 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 IP2SR1_27_24 FM(MSIOF2_SS1) FM(HTX1) FM(TX1_A) F_(0, 0) FM(DU_DB6) FM(A22) 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 IP2SR1_31_28 FM(MSIOF2_SS2) FM(TCLK1_B) F_(0, 0) F_(0, 0) FM(DU_DB7) FM(A23) 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) + +/* IP3SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP3SR1_3_0 FM(IRQ0) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_DOTCLKOUT) FM(A24) 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 IP3SR1_7_4 FM(IRQ1) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_HSYNC) FM(A25) 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 IP3SR1_11_8 FM(IRQ2) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_VSYNC) FM(CS1_N_A26) 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 IP3SR1_15_12 FM(IRQ3) F_(0, 0) F_(0, 0) F_(0, 0) FM(DU_ODDF_DISP_CDE) FM(CS0_N) 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 IP3SR1_19_16 FM(GP1_28) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) FM(D0) 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 IP3SR1_23_20 FM(GP1_29) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) FM(D1) 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 IP3SR1_27_24 FM(GP1_30) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) FM(D2) 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 IP3SR1_31_28 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) F_(0, 0) + +/* IP0SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP0SR2_3_0 FM(IPC_CLKIN) FM(IPC_CLKEN_IN) F_(0, 0) F_(0, 0) FM(DU_DOTCLKIN) 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 IP0SR2_7_4 FM(IPC_CLKOUT) FM(IPC_CLKEN_OUT) 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 IP0SR2_11_8 FM(GP2_02) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) FM(D3) 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 IP0SR2_15_12 FM(GP2_03) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) FM(D4) 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 IP0SR2_19_16 FM(GP2_04) F_(0, 0) FM(MSIOF4_RXD) F_(0, 0) F_(0, 0) FM(D5) 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 IP0SR2_23_20 FM(GP2_05) FM(HSCK2) FM(MSIOF4_TXD) FM(SCK4) F_(0, 0) FM(D6) 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 IP0SR2_27_24 FM(GP2_06) FM(HCTS2_N) FM(MSIOF4_SCK) FM(CTS4_N) F_(0, 0) FM(D7) 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 IP0SR2_31_28 FM(GP2_07) FM(HRTS2_N) FM(MSIOF4_SYNC) FM(RTS4_N) F_(0, 0) FM(D8) 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) +/* IP1SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP1SR2_3_0 FM(GP2_08) FM(HRX2) FM(MSIOF4_SS1) FM(RX4) F_(0, 0) FM(D9) 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 IP1SR2_7_4 FM(GP2_09) FM(HTX2) FM(MSIOF4_SS2) FM(TX4) F_(0, 0) FM(D10) 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 IP1SR2_11_8 FM(GP2_10) FM(TCLK2_B) FM(MSIOF5_RXD) F_(0, 0) F_(0, 0) FM(D11) 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 IP1SR2_15_12 FM(GP2_11) FM(TCLK3) FM(MSIOF5_TXD) F_(0, 0) F_(0, 0) FM(D12) 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 IP1SR2_19_16 FM(GP2_12) FM(TCLK4) FM(MSIOF5_SCK) F_(0, 0) F_(0, 0) FM(D13) 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 IP1SR2_23_20 FM(GP2_13) F_(0, 0) FM(MSIOF5_SYNC) F_(0, 0) F_(0, 0) FM(D14) 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 IP1SR2_27_24 FM(GP2_14) FM(IRQ4) FM(MSIOF5_SS1) F_(0, 0) F_(0, 0) FM(D15) 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 IP1SR2_31_28 FM(GP2_15) FM(IRQ5) FM(MSIOF5_SS2) FM(CPG_CPCKOUT) 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) +/* IP2SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP2SR2_3_0 FM(FXR_TXDA_A) 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 IP2SR2_7_4 FM(RXDA_EXTFXR_A) FM(MSIOF3_SS2) F_(0, 0) F_(0, 0) F_(0, 0) FM(BS_N) 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 IP2SR2_11_8 FM(FXR_TXDB) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) FM(RD_N) 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 IP2SR2_15_12 FM(RXDB_EXTFXR) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) FM(WE0_N) 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 IP2SR2_19_16 FM(CLK_EXTFXR) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) FM(WE1_N) 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 IP2SR2_23_20 FM(TPU0TO0) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) FM(RD_WR_N) 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 IP2SR2_27_24 FM(TPU0TO1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) FM(CLKOUT) 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 IP2SR2_31_28 FM(TCLK1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) FM(EX_WAIT0) 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) + +/* IP0SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP0SR3_3_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) F_(0, 0) F_(0, 0) +#define IP0SR3_7_4 FM(CANFD0_TX) FM(FXR_TXDA_B) FM(TX1_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 IP0SR3_11_8 FM(CANFD0_RX) FM(RXDA_EXTFXR_B) FM(RX1_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 IP0SR3_15_12 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) F_(0, 0) +#define IP0SR3_19_16 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) F_(0, 0) +#define IP0SR3_23_20 FM(CANFD2_TX) FM(TPU0TO2) FM(PWM0) 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 IP0SR3_27_24 FM(CANFD2_RX) FM(TPU0TO3) FM(PWM1) 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 IP0SR3_31_28 FM(CANFD3_TX) F_(0, 0) FM(PWM2) 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) +/* IP1SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP1SR3_3_0 FM(CANFD3_RX) F_(0, 0) FM(PWM3) 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 IP1SR3_7_4 FM(CANFD4_TX) F_(0, 0) FM(PWM4) FM(FXR_CLKOUT1) 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 IP1SR3_11_8 FM(CANFD4_RX) F_(0, 0) F_(0, 0) FM(FXR_CLKOUT2) 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 IP1SR3_15_12 FM(CANFD5_TX) F_(0, 0) F_(0, 0) FM(FXR_TXENA_N) 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 IP1SR3_19_16 FM(CANFD5_RX) F_(0, 0) F_(0, 0) FM(FXR_TXENB_N) 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 IP1SR3_23_20 FM(CANFD6_TX) F_(0, 0) F_(0, 0) FM(STPWT_EXTFXR) 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 IP1SR3_27_24 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) F_(0, 0) +#define IP1SR3_31_28 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) F_(0, 0) + +/* IP0SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP0SR4_3_0 FM(AVB0_RX_CTL) FM(AVB0_MII_RX_DV) 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 IP0SR4_7_4 FM(AVB0_RXC) FM(AVB0_MII_RXC) 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 IP0SR4_11_8 FM(AVB0_RD0) FM(AVB0_MII_RD0) 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 IP0SR4_15_12 FM(AVB0_RD1) FM(AVB0_MII_RD1) 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 IP0SR4_19_16 FM(AVB0_RD2) FM(AVB0_MII_RD2) 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 IP0SR4_23_20 FM(AVB0_RD3) FM(AVB0_MII_RD3) 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 IP0SR4_27_24 FM(AVB0_TX_CTL) FM(AVB0_MII_TX_EN) 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 IP0SR4_31_28 FM(AVB0_TXC) FM(AVB0_MII_TXC) 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) +/* IP1SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP1SR4_3_0 FM(AVB0_TD0) FM(AVB0_MII_TD0) 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 IP1SR4_7_4 FM(AVB0_TD1) FM(AVB0_MII_TD1) 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 IP1SR4_11_8 FM(AVB0_TD2) FM(AVB0_MII_TD2) 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 IP1SR4_15_12 FM(AVB0_TD3) FM(AVB0_MII_TD3) 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 IP1SR4_19_16 FM(AVB0_TXCREFCLK) 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 IP1SR4_23_20 FM(AVB0_MDIO) 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 IP1SR4_27_24 FM(AVB0_MDC) 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 IP1SR4_31_28 FM(AVB0_MAGIC) 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) +/* IP2SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP2SR4_3_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) F_(0, 0) F_(0, 0) +#define IP2SR4_7_4 FM(AVB0_LINK) FM(AVB0_MII_TX_ER) 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 IP2SR4_11_8 FM(AVB0_AVTP_MATCH) FM(AVB0_MII_RX_ER) FM(CC5_OSCOUT) 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 IP2SR4_15_12 FM(AVB0_AVTP_CAPTURE) FM(AVB0_MII_CRS) 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 IP2SR4_19_16 FM(AVB0_AVTP_PPS) FM(AVB0_MII_COL) 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 IP2SR4_23_20 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) F_(0, 0) +#define IP2SR4_27_24 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) F_(0, 0) +#define IP2SR4_31_28 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) F_(0, 0) + +/* IP0SR5 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP0SR5_3_0 FM(AVB1_RX_CTL) FM(AVB1_MII_RX_DV) 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 IP0SR5_7_4 FM(AVB1_RXC) FM(AVB1_MII_RXC) 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 IP0SR5_11_8 FM(AVB1_RD0) FM(AVB1_MII_RD0) 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 IP0SR5_15_12 FM(AVB1_RD1) FM(AVB1_MII_RD1) 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 IP0SR5_19_16 FM(AVB1_RD2) FM(AVB1_MII_RD2) 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 IP0SR5_23_20 FM(AVB1_RD3) FM(AVB1_MII_RD3) 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 IP0SR5_27_24 FM(AVB1_TX_CTL) FM(AVB1_MII_TX_EN) 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 IP0SR5_31_28 FM(AVB1_TXC) FM(AVB1_MII_TXC) 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) +/* IP1SR5 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP1SR5_3_0 FM(AVB1_TD0) FM(AVB1_MII_TD0) 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 IP1SR5_7_4 FM(AVB1_TD1) FM(AVB1_MII_TD1) 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 IP1SR5_11_8 FM(AVB1_TD2) FM(AVB1_MII_TD2) 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 IP1SR5_15_12 FM(AVB1_TD3) FM(AVB1_MII_TD3) 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 IP1SR5_19_16 FM(AVB1_TXCREFCLK) 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 IP1SR5_23_20 FM(AVB1_MDIO) 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 IP1SR5_27_24 FM(AVB1_MDC) 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 IP1SR5_31_28 FM(AVB1_MAGIC) 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) +/* IP2SR5 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 - F */ +#define IP2SR5_3_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) F_(0, 0) F_(0, 0) +#define IP2SR5_7_4 FM(AVB1_LINK) FM(AVB1_MII_TX_ER) 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 IP2SR5_11_8 FM(AVB1_AVTP_MATCH) FM(AVB1_MII_RX_ER) 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 IP2SR5_15_12 FM(AVB1_AVTP_CAPTURE) FM(AVB1_MII_CRS) 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 IP2SR5_19_16 FM(AVB1_AVTP_PPS) FM(AVB1_MII_COL) 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 IP2SR5_23_20 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) F_(0, 0) +#define IP2SR5_27_24 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) F_(0, 0) +#define IP2SR5_31_28 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) F_(0, 0) + +#define PINMUX_GPSR \ + \ + GPSR1_30 \ + GPSR1_29 \ + GPSR1_28 \ +GPSR0_27 GPSR1_27 \ +GPSR0_26 GPSR1_26 GPSR4_26 \ +GPSR0_25 GPSR1_25 GPSR4_25 \ +GPSR0_24 GPSR1_24 GPSR2_24 GPSR4_24 \ +GPSR0_23 GPSR1_23 GPSR2_23 GPSR4_23 \ +GPSR0_22 GPSR1_22 GPSR2_22 GPSR4_22 \ +GPSR0_21 GPSR1_21 GPSR2_21 GPSR4_21 \ +GPSR0_20 GPSR1_20 GPSR2_20 GPSR4_20 GPSR5_20 GPSR6_20 GPSR7_20 GPSR8_20 GPSR9_20 \ +GPSR0_19 GPSR1_19 GPSR2_19 GPSR4_19 GPSR5_19 GPSR6_19 GPSR7_19 GPSR8_19 GPSR9_19 \ +GPSR0_18 GPSR1_18 GPSR2_18 GPSR4_18 GPSR5_18 GPSR6_18 GPSR7_18 GPSR8_18 GPSR9_18 \ +GPSR0_17 GPSR1_17 GPSR2_17 GPSR4_17 GPSR5_17 GPSR6_17 GPSR7_17 GPSR8_17 GPSR9_17 \ +GPSR0_16 GPSR1_16 GPSR2_16 GPSR3_16 GPSR4_16 GPSR5_16 GPSR6_16 GPSR7_16 GPSR8_16 GPSR9_16 \ +GPSR0_15 GPSR1_15 GPSR2_15 GPSR3_15 GPSR4_15 GPSR5_15 GPSR6_15 GPSR7_15 GPSR8_15 GPSR9_15 \ +GPSR0_14 GPSR1_14 GPSR2_14 GPSR3_14 GPSR4_14 GPSR5_14 GPSR6_14 GPSR7_14 GPSR8_14 GPSR9_14 \ +GPSR0_13 GPSR1_13 GPSR2_13 GPSR3_13 GPSR4_13 GPSR5_13 GPSR6_13 GPSR7_13 GPSR8_13 GPSR9_13 \ +GPSR0_12 GPSR1_12 GPSR2_12 GPSR3_12 GPSR4_12 GPSR5_12 GPSR6_12 GPSR7_12 GPSR8_12 GPSR9_12 \ +GPSR0_11 GPSR1_11 GPSR2_11 GPSR3_11 GPSR4_11 GPSR5_11 GPSR6_11 GPSR7_11 GPSR8_11 GPSR9_11 \ +GPSR0_10 GPSR1_10 GPSR2_10 GPSR3_10 GPSR4_10 GPSR5_10 GPSR6_10 GPSR7_10 GPSR8_10 GPSR9_10 \ +GPSR0_9 GPSR1_9 GPSR2_9 GPSR3_9 GPSR4_9 GPSR5_9 GPSR6_9 GPSR7_9 GPSR8_9 GPSR9_9 \ +GPSR0_8 GPSR1_8 GPSR2_8 GPSR3_8 GPSR4_8 GPSR5_8 GPSR6_8 GPSR7_8 GPSR8_8 GPSR9_8 \ +GPSR0_7 GPSR1_7 GPSR2_7 GPSR3_7 GPSR4_7 GPSR5_7 GPSR6_7 GPSR7_7 GPSR8_7 GPSR9_7 \ +GPSR0_6 GPSR1_6 GPSR2_6 GPSR3_6 GPSR4_6 GPSR5_6 GPSR6_6 GPSR7_6 GPSR8_6 GPSR9_6 \ +GPSR0_5 GPSR1_5 GPSR2_5 GPSR3_5 GPSR4_5 GPSR5_5 GPSR6_5 GPSR7_5 GPSR8_5 GPSR9_5 \ +GPSR0_4 GPSR1_4 GPSR2_4 GPSR3_4 GPSR4_4 GPSR5_4 GPSR6_4 GPSR7_4 GPSR8_4 GPSR9_4 \ +GPSR0_3 GPSR1_3 GPSR2_3 GPSR3_3 GPSR4_3 GPSR5_3 GPSR6_3 GPSR7_3 GPSR8_3 GPSR9_3 \ +GPSR0_2 GPSR1_2 GPSR2_2 GPSR3_2 GPSR4_2 GPSR5_2 GPSR6_2 GPSR7_2 GPSR8_2 GPSR9_2 \ +GPSR0_1 GPSR1_1 GPSR2_1 GPSR3_1 GPSR4_1 GPSR5_1 GPSR6_1 GPSR7_1 GPSR8_1 GPSR9_1 \ +GPSR0_0 GPSR1_0 GPSR2_0 GPSR3_0 GPSR4_0 GPSR5_0 GPSR6_0 GPSR7_0 GPSR8_0 GPSR9_0 + +#define PINMUX_IPSR \ +\ +FM(IP0SR1_3_0) IP0SR1_3_0 FM(IP1SR1_3_0) IP1SR1_3_0 FM(IP2SR1_3_0) IP2SR1_3_0 FM(IP3SR1_3_0) IP3SR1_3_0 \ +FM(IP0SR1_7_4) IP0SR1_7_4 FM(IP1SR1_7_4) IP1SR1_7_4 FM(IP2SR1_7_4) IP2SR1_7_4 FM(IP3SR1_7_4) IP3SR1_7_4 \ +FM(IP0SR1_11_8) IP0SR1_11_8 FM(IP1SR1_11_8) IP1SR1_11_8 FM(IP2SR1_11_8) IP2SR1_11_8 FM(IP3SR1_11_8) IP3SR1_11_8 \ +FM(IP0SR1_15_12) IP0SR1_15_12 FM(IP1SR1_15_12) IP1SR1_15_12 FM(IP2SR1_15_12) IP2SR1_15_12 FM(IP3SR1_15_12) IP3SR1_15_12 \ +FM(IP0SR1_19_16) IP0SR1_19_16 FM(IP1SR1_19_16) IP1SR1_19_16 FM(IP2SR1_19_16) IP2SR1_19_16 FM(IP3SR1_19_16) IP3SR1_19_16 \ +FM(IP0SR1_23_20) IP0SR1_23_20 FM(IP1SR1_23_20) IP1SR1_23_20 FM(IP2SR1_23_20) IP2SR1_23_20 FM(IP3SR1_23_20) IP3SR1_23_20 \ +FM(IP0SR1_27_24) IP0SR1_27_24 FM(IP1SR1_27_24) IP1SR1_27_24 FM(IP2SR1_27_24) IP2SR1_27_24 FM(IP3SR1_27_24) IP3SR1_27_24 \ +FM(IP0SR1_31_28) IP0SR1_31_28 FM(IP1SR1_31_28) IP1SR1_31_28 FM(IP2SR1_31_28) IP2SR1_31_28 FM(IP3SR1_31_28) IP3SR1_31_28 \ +\ +FM(IP0SR2_3_0) IP0SR2_3_0 FM(IP1SR2_3_0) IP1SR2_3_0 FM(IP2SR2_3_0) IP2SR2_3_0 \ +FM(IP0SR2_7_4) IP0SR2_7_4 FM(IP1SR2_7_4) IP1SR2_7_4 FM(IP2SR2_7_4) IP2SR2_7_4 \ +FM(IP0SR2_11_8) IP0SR2_11_8 FM(IP1SR2_11_8) IP1SR2_11_8 FM(IP2SR2_11_8) IP2SR2_11_8 \ +FM(IP0SR2_15_12) IP0SR2_15_12 FM(IP1SR2_15_12) IP1SR2_15_12 FM(IP2SR2_15_12) IP2SR2_15_12 \ +FM(IP0SR2_19_16) IP0SR2_19_16 FM(IP1SR2_19_16) IP1SR2_19_16 FM(IP2SR2_19_16) IP2SR2_19_16 \ +FM(IP0SR2_23_20) IP0SR2_23_20 FM(IP1SR2_23_20) IP1SR2_23_20 FM(IP2SR2_23_20) IP2SR2_23_20 \ +FM(IP0SR2_27_24) IP0SR2_27_24 FM(IP1SR2_27_24) IP1SR2_27_24 FM(IP2SR2_27_24) IP2SR2_27_24 \ +FM(IP0SR2_31_28) IP0SR2_31_28 FM(IP1SR2_31_28) IP1SR2_31_28 FM(IP2SR2_31_28) IP2SR2_31_28 \ +\ +FM(IP0SR3_3_0) IP0SR3_3_0 FM(IP1SR3_3_0) IP1SR3_3_0 \ +FM(IP0SR3_7_4) IP0SR3_7_4 FM(IP1SR3_7_4) IP1SR3_7_4 \ +FM(IP0SR3_11_8) IP0SR3_11_8 FM(IP1SR3_11_8) IP1SR3_11_8 \ +FM(IP0SR3_15_12) IP0SR3_15_12 FM(IP1SR3_15_12) IP1SR3_15_12 \ +FM(IP0SR3_19_16) IP0SR3_19_16 FM(IP1SR3_19_16) IP1SR3_19_16 \ +FM(IP0SR3_23_20) IP0SR3_23_20 FM(IP1SR3_23_20) IP1SR3_23_20 \ +FM(IP0SR3_27_24) IP0SR3_27_24 FM(IP1SR3_27_24) IP1SR3_27_24 \ +FM(IP0SR3_31_28) IP0SR3_31_28 FM(IP1SR3_31_28) IP1SR3_31_28 \ +\ +FM(IP0SR4_3_0) IP0SR4_3_0 FM(IP1SR4_3_0) IP1SR4_3_0 FM(IP2SR4_3_0) IP2SR4_3_0 \ +FM(IP0SR4_7_4) IP0SR4_7_4 FM(IP1SR4_7_4) IP1SR4_7_4 FM(IP2SR4_7_4) IP2SR4_7_4 \ +FM(IP0SR4_11_8) IP0SR4_11_8 FM(IP1SR4_11_8) IP1SR4_11_8 FM(IP2SR4_11_8) IP2SR4_11_8 \ +FM(IP0SR4_15_12) IP0SR4_15_12 FM(IP1SR4_15_12) IP1SR4_15_12 FM(IP2SR4_15_12) IP2SR4_15_12 \ +FM(IP0SR4_19_16) IP0SR4_19_16 FM(IP1SR4_19_16) IP1SR4_19_16 FM(IP2SR4_19_16) IP2SR4_19_16 \ +FM(IP0SR4_23_20) IP0SR4_23_20 FM(IP1SR4_23_20) IP1SR4_23_20 FM(IP2SR4_23_20) IP2SR4_23_20 \ +FM(IP0SR4_27_24) IP0SR4_27_24 FM(IP1SR4_27_24) IP1SR4_27_24 FM(IP2SR4_27_24) IP2SR4_27_24 \ +FM(IP0SR4_31_28) IP0SR4_31_28 FM(IP1SR4_31_28) IP1SR4_31_28 FM(IP2SR4_31_28) IP2SR4_31_28 \ +\ +FM(IP0SR5_3_0) IP0SR5_3_0 FM(IP1SR5_3_0) IP1SR5_3_0 FM(IP2SR5_3_0) IP2SR5_3_0 \ +FM(IP0SR5_7_4) IP0SR5_7_4 FM(IP1SR5_7_4) IP1SR5_7_4 FM(IP2SR5_7_4) IP2SR5_7_4 \ +FM(IP0SR5_11_8) IP0SR5_11_8 FM(IP1SR5_11_8) IP1SR5_11_8 FM(IP2SR5_11_8) IP2SR5_11_8 \ +FM(IP0SR5_15_12) IP0SR5_15_12 FM(IP1SR5_15_12) IP1SR5_15_12 FM(IP2SR5_15_12) IP2SR5_15_12 \ +FM(IP0SR5_19_16) IP0SR5_19_16 FM(IP1SR5_19_16) IP1SR5_19_16 FM(IP2SR5_19_16) IP2SR5_19_16 \ +FM(IP0SR5_23_20) IP0SR5_23_20 FM(IP1SR5_23_20) IP1SR5_23_20 FM(IP2SR5_23_20) IP2SR5_23_20 \ +FM(IP0SR5_27_24) IP0SR5_27_24 FM(IP1SR5_27_24) IP1SR5_27_24 FM(IP2SR5_27_24) IP2SR5_27_24 \ +FM(IP0SR5_31_28) IP0SR5_31_28 FM(IP1SR5_31_28) IP1SR5_31_28 FM(IP2SR5_31_28) IP2SR5_31_28 + +/* MOD_SEL2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ +#define MOD_SEL2_14_15 FM(SEL_I2C6_0) F_(0, 0) F_(0, 0) FM(SEL_I2C6_3) +#define MOD_SEL2_12_13 FM(SEL_I2C5_0) F_(0, 0) F_(0, 0) FM(SEL_I2C5_3) +#define MOD_SEL2_10_11 FM(SEL_I2C4_0) F_(0, 0) F_(0, 0) FM(SEL_I2C4_3) +#define MOD_SEL2_8_9 FM(SEL_I2C3_0) F_(0, 0) F_(0, 0) FM(SEL_I2C3_3) +#define MOD_SEL2_6_7 FM(SEL_I2C2_0) F_(0, 0) F_(0, 0) FM(SEL_I2C2_3) +#define MOD_SEL2_4_5 FM(SEL_I2C1_0) F_(0, 0) F_(0, 0) FM(SEL_I2C1_3) +#define MOD_SEL2_2_3 FM(SEL_I2C0_0) F_(0, 0) F_(0, 0) FM(SEL_I2C0_3) + +#define PINMUX_MOD_SELS \ +\ +MOD_SEL2_14_15 \ +MOD_SEL2_12_13 \ +MOD_SEL2_10_11 \ +MOD_SEL2_8_9 \ +MOD_SEL2_6_7 \ +MOD_SEL2_4_5 \ +MOD_SEL2_2_3 + +#define PINMUX_PHYS \ + FM(SCL0) FM(SDA0) FM(SCL1) FM(SDA1) FM(SCL2) FM(SDA2) FM(SCL3) FM(SDA3) \ + FM(SCL4) FM(SDA4) FM(SCL5) FM(SDA5) FM(SCL6) FM(SDA6) + +enum { + PINMUX_RESERVED = 0, + + PINMUX_DATA_BEGIN, + GP_ALL(DATA), + PINMUX_DATA_END, + +#define F_(x, y) +#define FM(x) FN_##x, + PINMUX_FUNCTION_BEGIN, + GP_ALL(FN), + PINMUX_GPSR + PINMUX_IPSR + PINMUX_MOD_SELS + PINMUX_FUNCTION_END, +#undef F_ +#undef FM + +#define F_(x, y) +#define FM(x) x##_MARK, + PINMUX_MARK_BEGIN, + PINMUX_GPSR + PINMUX_IPSR + PINMUX_MOD_SELS + PINMUX_PHYS + PINMUX_MARK_END, +#undef F_ +#undef FM +}; + +static const u16 pinmux_data[] = { + PINMUX_DATA_GP_ALL(), + + PINMUX_SINGLE(MMC_D7), + PINMUX_SINGLE(MMC_D6), + PINMUX_SINGLE(MMC_D5), + PINMUX_SINGLE(MMC_D4), + PINMUX_SINGLE(MMC_SD_CLK), + PINMUX_SINGLE(MMC_SD_D3), + PINMUX_SINGLE(MMC_SD_D2), + PINMUX_SINGLE(MMC_SD_D1), + PINMUX_SINGLE(MMC_SD_D0), + PINMUX_SINGLE(MMC_SD_CMD), + PINMUX_SINGLE(MMC_DS), + + PINMUX_SINGLE(SD_CD), + PINMUX_SINGLE(SD_WP), + + PINMUX_SINGLE(RPC_INT_N), + PINMUX_SINGLE(RPC_WP_N), + PINMUX_SINGLE(RPC_RESET_N), + + PINMUX_SINGLE(QSPI1_SSL), + PINMUX_SINGLE(QSPI1_IO3), + PINMUX_SINGLE(QSPI1_IO2), + PINMUX_SINGLE(QSPI1_MISO_IO1), + PINMUX_SINGLE(QSPI1_MOSI_IO0), + PINMUX_SINGLE(QSPI1_SPCLK), + PINMUX_SINGLE(QSPI0_SSL), + PINMUX_SINGLE(QSPI0_IO3), + PINMUX_SINGLE(QSPI0_IO2), + PINMUX_SINGLE(QSPI0_MISO_IO1), + PINMUX_SINGLE(QSPI0_MOSI_IO0), + PINMUX_SINGLE(QSPI0_SPCLK), + + PINMUX_SINGLE(TCLK2_A), + + PINMUX_SINGLE(CANFD7_RX), + PINMUX_SINGLE(CANFD7_TX), + PINMUX_SINGLE(CANFD6_RX), + PINMUX_SINGLE(CANFD1_RX), + PINMUX_SINGLE(CANFD1_TX), + PINMUX_SINGLE(CAN_CLK), + + PINMUX_SINGLE(AVS1), + PINMUX_SINGLE(AVS0), + + PINMUX_SINGLE(PCIE3_CLKREQ_N), + PINMUX_SINGLE(PCIE2_CLKREQ_N), + PINMUX_SINGLE(PCIE1_CLKREQ_N), + PINMUX_SINGLE(PCIE0_CLKREQ_N), + + PINMUX_SINGLE(AVB0_PHY_INT), + PINMUX_SINGLE(AVB0_MAGIC), + PINMUX_SINGLE(AVB0_MDC), + PINMUX_SINGLE(AVB0_MDIO), + PINMUX_SINGLE(AVB0_TXCREFCLK), + + PINMUX_SINGLE(AVB1_PHY_INT), + PINMUX_SINGLE(AVB1_MAGIC), + PINMUX_SINGLE(AVB1_MDC), + PINMUX_SINGLE(AVB1_MDIO), + PINMUX_SINGLE(AVB1_TXCREFCLK), + + PINMUX_SINGLE(AVB2_AVTP_PPS), + PINMUX_SINGLE(AVB2_AVTP_CAPTURE), + PINMUX_SINGLE(AVB2_AVTP_MATCH), + PINMUX_SINGLE(AVB2_LINK), + PINMUX_SINGLE(AVB2_PHY_INT), + PINMUX_SINGLE(AVB2_MAGIC), + PINMUX_SINGLE(AVB2_MDC), + PINMUX_SINGLE(AVB2_MDIO), + PINMUX_SINGLE(AVB2_TXCREFCLK), + PINMUX_SINGLE(AVB2_TD3), + PINMUX_SINGLE(AVB2_TD2), + PINMUX_SINGLE(AVB2_TD1), + PINMUX_SINGLE(AVB2_TD0), + PINMUX_SINGLE(AVB2_TXC), + PINMUX_SINGLE(AVB2_TX_CTL), + PINMUX_SINGLE(AVB2_RD3), + PINMUX_SINGLE(AVB2_RD2), + PINMUX_SINGLE(AVB2_RD1), + PINMUX_SINGLE(AVB2_RD0), + PINMUX_SINGLE(AVB2_RXC), + PINMUX_SINGLE(AVB2_RX_CTL), + + PINMUX_SINGLE(AVB3_AVTP_PPS), + PINMUX_SINGLE(AVB3_AVTP_CAPTURE), + PINMUX_SINGLE(AVB3_AVTP_MATCH), + PINMUX_SINGLE(AVB3_LINK), + PINMUX_SINGLE(AVB3_PHY_INT), + PINMUX_SINGLE(AVB3_MAGIC), + PINMUX_SINGLE(AVB3_MDC), + PINMUX_SINGLE(AVB3_MDIO), + PINMUX_SINGLE(AVB3_TXCREFCLK), + PINMUX_SINGLE(AVB3_TD3), + PINMUX_SINGLE(AVB3_TD2), + PINMUX_SINGLE(AVB3_TD1), + PINMUX_SINGLE(AVB3_TD0), + PINMUX_SINGLE(AVB3_TXC), + PINMUX_SINGLE(AVB3_TX_CTL), + PINMUX_SINGLE(AVB3_RD3), + PINMUX_SINGLE(AVB3_RD2), + PINMUX_SINGLE(AVB3_RD1), + PINMUX_SINGLE(AVB3_RD0), + PINMUX_SINGLE(AVB3_RXC), + PINMUX_SINGLE(AVB3_RX_CTL), + + PINMUX_SINGLE(AVB4_AVTP_PPS), + PINMUX_SINGLE(AVB4_AVTP_CAPTURE), + PINMUX_SINGLE(AVB4_AVTP_MATCH), + PINMUX_SINGLE(AVB4_LINK), + PINMUX_SINGLE(AVB4_PHY_INT), + PINMUX_SINGLE(AVB4_MAGIC), + PINMUX_SINGLE(AVB4_MDC), + PINMUX_SINGLE(AVB4_MDIO), + PINMUX_SINGLE(AVB4_TXCREFCLK), + PINMUX_SINGLE(AVB4_TD3), + PINMUX_SINGLE(AVB4_TD2), + PINMUX_SINGLE(AVB4_TD1), + PINMUX_SINGLE(AVB4_TD0), + PINMUX_SINGLE(AVB4_TXC), + PINMUX_SINGLE(AVB4_TX_CTL), + PINMUX_SINGLE(AVB4_RD3), + PINMUX_SINGLE(AVB4_RD2), + PINMUX_SINGLE(AVB4_RD1), + PINMUX_SINGLE(AVB4_RD0), + PINMUX_SINGLE(AVB4_RXC), + PINMUX_SINGLE(AVB4_RX_CTL), + + PINMUX_SINGLE(AVB5_AVTP_PPS), + PINMUX_SINGLE(AVB5_AVTP_CAPTURE), + PINMUX_SINGLE(AVB5_AVTP_MATCH), + PINMUX_SINGLE(AVB5_LINK), + PINMUX_SINGLE(AVB5_PHY_INT), + PINMUX_SINGLE(AVB5_MAGIC), + PINMUX_SINGLE(AVB5_MDC), + PINMUX_SINGLE(AVB5_MDIO), + PINMUX_SINGLE(AVB5_TXCREFCLK), + PINMUX_SINGLE(AVB5_TD3), + PINMUX_SINGLE(AVB5_TD2), + PINMUX_SINGLE(AVB5_TD1), + PINMUX_SINGLE(AVB5_TD0), + PINMUX_SINGLE(AVB5_TXC), + PINMUX_SINGLE(AVB5_TX_CTL), + PINMUX_SINGLE(AVB5_RD3), + PINMUX_SINGLE(AVB5_RD2), + PINMUX_SINGLE(AVB5_RD1), + PINMUX_SINGLE(AVB5_RD0), + PINMUX_SINGLE(AVB5_RXC), + PINMUX_SINGLE(AVB5_RX_CTL), + + /* IP0SR1 */ + PINMUX_IPSR_GPSR(IP0SR1_3_0, SCIF_CLK), + PINMUX_IPSR_GPSR(IP0SR1_3_0, A0), + + PINMUX_IPSR_GPSR(IP0SR1_7_4, HRX0), + PINMUX_IPSR_GPSR(IP0SR1_7_4, RX0), + PINMUX_IPSR_GPSR(IP0SR1_7_4, A1), + + PINMUX_IPSR_GPSR(IP0SR1_11_8, HSCK0), + PINMUX_IPSR_GPSR(IP0SR1_11_8, SCK0), + PINMUX_IPSR_GPSR(IP0SR1_11_8, A2), + + PINMUX_IPSR_GPSR(IP0SR1_15_12, HRTS0_N), + PINMUX_IPSR_GPSR(IP0SR1_15_12, RTS0_N), + PINMUX_IPSR_GPSR(IP0SR1_15_12, A3), + + PINMUX_IPSR_GPSR(IP0SR1_19_16, HCTS0_N), + PINMUX_IPSR_GPSR(IP0SR1_19_16, CTS0_N), + PINMUX_IPSR_GPSR(IP0SR1_19_16, A4), + + PINMUX_IPSR_GPSR(IP0SR1_23_20, HTX0), + PINMUX_IPSR_GPSR(IP0SR1_23_20, TX0), + PINMUX_IPSR_GPSR(IP0SR1_23_20, A5), + + PINMUX_IPSR_GPSR(IP0SR1_27_24, MSIOF0_RXD), + PINMUX_IPSR_GPSR(IP0SR1_27_24, DU_DR2), + PINMUX_IPSR_GPSR(IP0SR1_27_24, A6), + + PINMUX_IPSR_GPSR(IP0SR1_31_28, MSIOF0_TXD), + PINMUX_IPSR_GPSR(IP0SR1_31_28, DU_DR3), + PINMUX_IPSR_GPSR(IP0SR1_31_28, A7), + + /* IP1SR1 */ + PINMUX_IPSR_GPSR(IP1SR1_3_0, MSIOF0_SCK), + PINMUX_IPSR_GPSR(IP1SR1_3_0, DU_DR4), + PINMUX_IPSR_GPSR(IP1SR1_3_0, A8), + + PINMUX_IPSR_GPSR(IP1SR1_7_4, MSIOF0_SYNC), + PINMUX_IPSR_GPSR(IP1SR1_7_4, DU_DR5), + PINMUX_IPSR_GPSR(IP1SR1_7_4, A9), + + PINMUX_IPSR_GPSR(IP1SR1_11_8, MSIOF0_SS1), + PINMUX_IPSR_GPSR(IP1SR1_11_8, DU_DR6), + PINMUX_IPSR_GPSR(IP1SR1_11_8, A10), + + PINMUX_IPSR_GPSR(IP1SR1_15_12, MSIOF0_SS2), + PINMUX_IPSR_GPSR(IP1SR1_15_12, DU_DR7), + PINMUX_IPSR_GPSR(IP1SR1_15_12, A11), + + PINMUX_IPSR_GPSR(IP1SR1_19_16, MSIOF1_RXD), + PINMUX_IPSR_GPSR(IP1SR1_19_16, DU_DG2), + PINMUX_IPSR_GPSR(IP1SR1_19_16, A12), + + PINMUX_IPSR_GPSR(IP1SR1_23_20, MSIOF1_TXD), + PINMUX_IPSR_GPSR(IP1SR1_23_20, HRX3), + PINMUX_IPSR_GPSR(IP1SR1_23_20, SCK3), + PINMUX_IPSR_GPSR(IP1SR1_23_20, DU_DG3), + PINMUX_IPSR_GPSR(IP1SR1_23_20, A13), + + PINMUX_IPSR_GPSR(IP1SR1_27_24, MSIOF1_SCK), + PINMUX_IPSR_GPSR(IP1SR1_27_24, HSCK3), + PINMUX_IPSR_GPSR(IP1SR1_27_24, CTS3_N), + PINMUX_IPSR_GPSR(IP1SR1_27_24, DU_DG4), + PINMUX_IPSR_GPSR(IP1SR1_27_24, A14), + + PINMUX_IPSR_GPSR(IP1SR1_31_28, MSIOF1_SYNC), + PINMUX_IPSR_GPSR(IP1SR1_31_28, HRTS3_N), + PINMUX_IPSR_GPSR(IP1SR1_31_28, RTS3_N), + PINMUX_IPSR_GPSR(IP1SR1_31_28, DU_DG5), + PINMUX_IPSR_GPSR(IP1SR1_31_28, A15), + + /* IP2SR1 */ + PINMUX_IPSR_GPSR(IP2SR1_3_0, MSIOF1_SS1), + PINMUX_IPSR_GPSR(IP2SR1_3_0, HCTS3_N), + PINMUX_IPSR_GPSR(IP2SR1_3_0, RX3), + PINMUX_IPSR_GPSR(IP2SR1_3_0, DU_DG6), + PINMUX_IPSR_GPSR(IP2SR1_3_0, A16), + + PINMUX_IPSR_GPSR(IP2SR1_7_4, MSIOF1_SS2), + PINMUX_IPSR_GPSR(IP2SR1_7_4, HTX3), + PINMUX_IPSR_GPSR(IP2SR1_7_4, TX3), + PINMUX_IPSR_GPSR(IP2SR1_7_4, DU_DG7), + PINMUX_IPSR_GPSR(IP2SR1_7_4, A17), + + PINMUX_IPSR_GPSR(IP2SR1_11_8, MSIOF2_RXD), + PINMUX_IPSR_GPSR(IP2SR1_11_8, HSCK1), + PINMUX_IPSR_GPSR(IP2SR1_11_8, SCK1), + PINMUX_IPSR_GPSR(IP2SR1_11_8, DU_DB2), + PINMUX_IPSR_GPSR(IP2SR1_11_8, A18), + + PINMUX_IPSR_GPSR(IP2SR1_15_12, MSIOF2_TXD), + PINMUX_IPSR_GPSR(IP2SR1_15_12, HCTS1_N), + PINMUX_IPSR_GPSR(IP2SR1_15_12, CTS1_N), + PINMUX_IPSR_GPSR(IP2SR1_15_12, DU_DB3), + PINMUX_IPSR_GPSR(IP2SR1_15_12, A19), + + PINMUX_IPSR_GPSR(IP2SR1_19_16, MSIOF2_SCK), + PINMUX_IPSR_GPSR(IP2SR1_19_16, HRTS1_N), + PINMUX_IPSR_GPSR(IP2SR1_19_16, RTS1_N), + PINMUX_IPSR_GPSR(IP2SR1_19_16, DU_DB4), + PINMUX_IPSR_GPSR(IP2SR1_19_16, A20), + + PINMUX_IPSR_GPSR(IP2SR1_23_20, MSIOF2_SYNC), + PINMUX_IPSR_GPSR(IP2SR1_23_20, HRX1), + PINMUX_IPSR_GPSR(IP2SR1_23_20, RX1_A), + PINMUX_IPSR_GPSR(IP2SR1_23_20, DU_DB5), + PINMUX_IPSR_GPSR(IP2SR1_23_20, A21), + + PINMUX_IPSR_GPSR(IP2SR1_27_24, MSIOF2_SS1), + PINMUX_IPSR_GPSR(IP2SR1_27_24, HTX1), + PINMUX_IPSR_GPSR(IP2SR1_27_24, TX1_A), + PINMUX_IPSR_GPSR(IP2SR1_27_24, DU_DB6), + PINMUX_IPSR_GPSR(IP2SR1_27_24, A22), + + PINMUX_IPSR_GPSR(IP2SR1_31_28, MSIOF2_SS2), + PINMUX_IPSR_GPSR(IP2SR1_31_28, TCLK1_B), + PINMUX_IPSR_GPSR(IP2SR1_31_28, DU_DB7), + PINMUX_IPSR_GPSR(IP2SR1_31_28, A23), + + /* IP3SR1 */ + PINMUX_IPSR_GPSR(IP3SR1_3_0, IRQ0), + PINMUX_IPSR_GPSR(IP3SR1_3_0, DU_DOTCLKOUT), + PINMUX_IPSR_GPSR(IP3SR1_3_0, A24), + + PINMUX_IPSR_GPSR(IP3SR1_7_4, IRQ1), + PINMUX_IPSR_GPSR(IP3SR1_7_4, DU_HSYNC), + PINMUX_IPSR_GPSR(IP3SR1_7_4, A25), + + PINMUX_IPSR_GPSR(IP3SR1_11_8, IRQ2), + PINMUX_IPSR_GPSR(IP3SR1_11_8, DU_VSYNC), + PINMUX_IPSR_GPSR(IP3SR1_11_8, CS1_N_A26), + + PINMUX_IPSR_GPSR(IP3SR1_15_12, IRQ3), + PINMUX_IPSR_GPSR(IP3SR1_15_12, DU_ODDF_DISP_CDE), + PINMUX_IPSR_GPSR(IP3SR1_15_12, CS0_N), + + PINMUX_IPSR_GPSR(IP3SR1_19_16, GP1_28), + PINMUX_IPSR_GPSR(IP3SR1_19_16, D0), + + PINMUX_IPSR_GPSR(IP3SR1_23_20, GP1_29), + PINMUX_IPSR_GPSR(IP3SR1_23_20, D1), + + PINMUX_IPSR_GPSR(IP3SR1_27_24, GP1_30), + PINMUX_IPSR_GPSR(IP3SR1_27_24, D2), + + /* IP0SR2 */ + PINMUX_IPSR_GPSR(IP0SR2_3_0, IPC_CLKIN), + PINMUX_IPSR_GPSR(IP0SR2_3_0, IPC_CLKEN_IN), + PINMUX_IPSR_GPSR(IP0SR2_3_0, DU_DOTCLKIN), + + PINMUX_IPSR_GPSR(IP0SR2_7_4, IPC_CLKOUT), + PINMUX_IPSR_GPSR(IP0SR2_7_4, IPC_CLKEN_OUT), + + /* GP2_02 = SCL0 */ + PINMUX_IPSR_MSEL(IP0SR2_11_8, GP2_02, SEL_I2C0_0), + PINMUX_IPSR_MSEL(IP0SR2_11_8, D3, SEL_I2C0_0), + PINMUX_IPSR_PHYS(IP0SR2_11_8, SCL0, SEL_I2C0_3), + + /* GP2_03 = SDA0 */ + PINMUX_IPSR_MSEL(IP0SR2_15_12, GP2_03, SEL_I2C0_0), + PINMUX_IPSR_MSEL(IP0SR2_15_12, D4, SEL_I2C0_0), + PINMUX_IPSR_PHYS(IP0SR2_15_12, SDA0, SEL_I2C0_3), + + /* GP2_04 = SCL1 */ + PINMUX_IPSR_MSEL(IP0SR2_19_16, GP2_04, SEL_I2C1_0), + PINMUX_IPSR_MSEL(IP0SR2_19_16, MSIOF4_RXD, SEL_I2C1_0), + PINMUX_IPSR_MSEL(IP0SR2_19_16, D5, SEL_I2C1_0), + PINMUX_IPSR_PHYS(IP0SR2_19_16, SCL1, SEL_I2C1_3), + + /* GP2_05 = SDA1 */ + PINMUX_IPSR_MSEL(IP0SR2_23_20, GP2_05, SEL_I2C1_0), + PINMUX_IPSR_MSEL(IP0SR2_23_20, HSCK2, SEL_I2C1_0), + PINMUX_IPSR_MSEL(IP0SR2_23_20, MSIOF4_TXD, SEL_I2C1_0), + PINMUX_IPSR_MSEL(IP0SR2_23_20, SCK4, SEL_I2C1_0), + PINMUX_IPSR_MSEL(IP0SR2_23_20, D6, SEL_I2C1_0), + PINMUX_IPSR_PHYS(IP0SR2_23_20, SDA1, SEL_I2C1_3), + + /* GP2_06 = SCL2 */ + PINMUX_IPSR_MSEL(IP0SR2_27_24, GP2_06, SEL_I2C2_0), + PINMUX_IPSR_MSEL(IP0SR2_27_24, HCTS2_N, SEL_I2C2_0), + PINMUX_IPSR_MSEL(IP0SR2_27_24, MSIOF4_SCK, SEL_I2C2_0), + PINMUX_IPSR_MSEL(IP0SR2_27_24, CTS4_N, SEL_I2C2_0), + PINMUX_IPSR_MSEL(IP0SR2_27_24, D7, SEL_I2C2_0), + PINMUX_IPSR_PHYS(IP0SR2_27_24, SCL2, SEL_I2C2_3), + + /* GP2_07 = SDA2 */ + PINMUX_IPSR_MSEL(IP0SR2_31_28, GP2_07, SEL_I2C2_0), + PINMUX_IPSR_MSEL(IP0SR2_31_28, HRTS2_N, SEL_I2C2_0), + PINMUX_IPSR_MSEL(IP0SR2_31_28, MSIOF4_SYNC, SEL_I2C2_0), + PINMUX_IPSR_MSEL(IP0SR2_31_28, RTS4_N, SEL_I2C2_0), + PINMUX_IPSR_MSEL(IP0SR2_31_28, D8, SEL_I2C2_0), + PINMUX_IPSR_PHYS(IP0SR2_31_28, SDA2, SEL_I2C2_3), + + /* GP2_08 = SCL3 */ + PINMUX_IPSR_MSEL(IP1SR2_3_0, GP2_08, SEL_I2C3_0), + PINMUX_IPSR_MSEL(IP1SR2_3_0, HRX2, SEL_I2C3_0), + PINMUX_IPSR_MSEL(IP1SR2_3_0, MSIOF4_SS1, SEL_I2C3_0), + PINMUX_IPSR_MSEL(IP1SR2_3_0, RX4, SEL_I2C3_0), + PINMUX_IPSR_MSEL(IP1SR2_3_0, D9, SEL_I2C3_0), + PINMUX_IPSR_PHYS(IP1SR2_3_0, SCL3, SEL_I2C3_3), + + /* GP2_09 = SDA3 */ + PINMUX_IPSR_MSEL(IP1SR2_7_4, GP2_09, SEL_I2C3_0), + PINMUX_IPSR_MSEL(IP1SR2_7_4, HTX2, SEL_I2C3_0), + PINMUX_IPSR_MSEL(IP1SR2_7_4, MSIOF4_SS2, SEL_I2C3_0), + PINMUX_IPSR_MSEL(IP1SR2_7_4, TX4, SEL_I2C3_0), + PINMUX_IPSR_MSEL(IP1SR2_7_4, D10, SEL_I2C3_0), + PINMUX_IPSR_PHYS(IP1SR2_7_4, SDA3, SEL_I2C3_3), + + /* GP2_10 = SCL4 */ + PINMUX_IPSR_MSEL(IP1SR2_11_8, GP2_10, SEL_I2C4_0), + PINMUX_IPSR_MSEL(IP1SR2_11_8, TCLK2_B, SEL_I2C4_0), + PINMUX_IPSR_MSEL(IP1SR2_11_8, MSIOF5_RXD, SEL_I2C4_0), + PINMUX_IPSR_MSEL(IP1SR2_11_8, D11, SEL_I2C4_0), + PINMUX_IPSR_PHYS(IP1SR2_11_8, SCL4, SEL_I2C4_3), + + /* GP2_11 = SDA4 */ + PINMUX_IPSR_MSEL(IP1SR2_15_12, GP2_11, SEL_I2C4_0), + PINMUX_IPSR_MSEL(IP1SR2_15_12, TCLK3, SEL_I2C4_0), + PINMUX_IPSR_MSEL(IP1SR2_15_12, MSIOF5_TXD, SEL_I2C4_0), + PINMUX_IPSR_MSEL(IP1SR2_15_12, D12, SEL_I2C4_0), + PINMUX_IPSR_PHYS(IP1SR2_15_12, SDA4, SEL_I2C4_3), + + /* GP2_12 = SCL5 */ + PINMUX_IPSR_MSEL(IP1SR2_19_16, GP2_12, SEL_I2C5_0), + PINMUX_IPSR_MSEL(IP1SR2_19_16, TCLK4, SEL_I2C5_0), + PINMUX_IPSR_MSEL(IP1SR2_19_16, MSIOF5_SCK, SEL_I2C5_0), + PINMUX_IPSR_MSEL(IP1SR2_19_16, D13, SEL_I2C5_0), + PINMUX_IPSR_PHYS(IP1SR2_19_16, SCL5, SEL_I2C5_3), + + /* GP2_13 = SDA5 */ + PINMUX_IPSR_MSEL(IP1SR2_23_20, GP2_13, SEL_I2C5_0), + PINMUX_IPSR_MSEL(IP1SR2_23_20, MSIOF5_SYNC, SEL_I2C5_0), + PINMUX_IPSR_MSEL(IP1SR2_23_20, D14, SEL_I2C5_0), + PINMUX_IPSR_PHYS(IP1SR2_23_20, SDA5, SEL_I2C5_3), + + /* GP2_14 = SCL6 */ + PINMUX_IPSR_MSEL(IP1SR2_27_24, GP2_14, SEL_I2C6_0), + PINMUX_IPSR_MSEL(IP1SR2_27_24, IRQ4, SEL_I2C6_0), + PINMUX_IPSR_MSEL(IP1SR2_27_24, MSIOF5_SS1, SEL_I2C6_0), + PINMUX_IPSR_MSEL(IP1SR2_27_24, D15, SEL_I2C6_0), + PINMUX_IPSR_PHYS(IP1SR2_27_24, SCL6, SEL_I2C6_3), + + /* GP2_15 = SDA6 */ + PINMUX_IPSR_MSEL(IP1SR2_31_28, GP2_15, SEL_I2C6_0), + PINMUX_IPSR_MSEL(IP1SR2_31_28, IRQ5, SEL_I2C6_0), + PINMUX_IPSR_MSEL(IP1SR2_31_28, MSIOF5_SS2, SEL_I2C6_0), + PINMUX_IPSR_MSEL(IP1SR2_31_28, CPG_CPCKOUT, SEL_I2C6_0), + PINMUX_IPSR_PHYS(IP1SR2_31_28, SDA6, SEL_I2C6_3), + + /* IP2SR2 */ + PINMUX_IPSR_GPSR(IP2SR2_3_0, FXR_TXDA_A), + PINMUX_IPSR_GPSR(IP2SR2_3_0, MSIOF3_SS1), + + PINMUX_IPSR_GPSR(IP2SR2_7_4, RXDA_EXTFXR_A), + PINMUX_IPSR_GPSR(IP2SR2_7_4, MSIOF3_SS2), + PINMUX_IPSR_GPSR(IP2SR2_7_4, BS_N), + + PINMUX_IPSR_GPSR(IP2SR2_11_8, FXR_TXDB), + PINMUX_IPSR_GPSR(IP2SR2_11_8, MSIOF3_RXD), + PINMUX_IPSR_GPSR(IP2SR2_11_8, RD_N), + + PINMUX_IPSR_GPSR(IP2SR2_15_12, RXDB_EXTFXR), + PINMUX_IPSR_GPSR(IP2SR2_15_12, MSIOF3_TXD), + PINMUX_IPSR_GPSR(IP2SR2_15_12, WE0_N), + + PINMUX_IPSR_GPSR(IP2SR2_19_16, CLK_EXTFXR), + PINMUX_IPSR_GPSR(IP2SR2_19_16, MSIOF3_SCK), + PINMUX_IPSR_GPSR(IP2SR2_19_16, WE1_N), + + PINMUX_IPSR_GPSR(IP2SR2_23_20, TPU0TO0), + PINMUX_IPSR_GPSR(IP2SR2_23_20, MSIOF3_SYNC), + PINMUX_IPSR_GPSR(IP2SR2_23_20, RD_WR_N), + + PINMUX_IPSR_GPSR(IP2SR2_27_24, TPU0TO1), + PINMUX_IPSR_GPSR(IP2SR2_27_24, CLKOUT), + + PINMUX_IPSR_GPSR(IP2SR2_31_28, TCLK1_A), + PINMUX_IPSR_GPSR(IP2SR2_31_28, EX_WAIT0), + + /* IP0SR3 */ + PINMUX_IPSR_GPSR(IP0SR3_7_4, CANFD0_TX), + PINMUX_IPSR_GPSR(IP0SR3_7_4, FXR_TXDA_B), + PINMUX_IPSR_GPSR(IP0SR3_7_4, TX1_B), + + PINMUX_IPSR_GPSR(IP0SR3_11_8, CANFD0_RX), + PINMUX_IPSR_GPSR(IP0SR3_11_8, RXDA_EXTFXR_B), + PINMUX_IPSR_GPSR(IP0SR3_11_8, RX1_B), + + PINMUX_IPSR_GPSR(IP0SR3_23_20, CANFD2_TX), + PINMUX_IPSR_GPSR(IP0SR3_23_20, TPU0TO2), + PINMUX_IPSR_GPSR(IP0SR3_23_20, PWM0), + + PINMUX_IPSR_GPSR(IP0SR3_27_24, CANFD2_RX), + PINMUX_IPSR_GPSR(IP0SR3_27_24, TPU0TO3), + PINMUX_IPSR_GPSR(IP0SR3_27_24, PWM1), + + PINMUX_IPSR_GPSR(IP0SR3_31_28, CANFD3_TX), + PINMUX_IPSR_GPSR(IP0SR3_31_28, PWM2), + + /* IP1SR3 */ + PINMUX_IPSR_GPSR(IP1SR3_3_0, CANFD3_RX), + PINMUX_IPSR_GPSR(IP1SR3_3_0, PWM3), + + PINMUX_IPSR_GPSR(IP1SR3_7_4, CANFD4_TX), + PINMUX_IPSR_GPSR(IP1SR3_7_4, PWM4), + PINMUX_IPSR_GPSR(IP1SR3_7_4, FXR_CLKOUT1), + + PINMUX_IPSR_GPSR(IP1SR3_11_8, CANFD4_RX), + PINMUX_IPSR_GPSR(IP1SR3_11_8, FXR_CLKOUT2), + + PINMUX_IPSR_GPSR(IP1SR3_15_12, CANFD5_TX), + PINMUX_IPSR_GPSR(IP1SR3_15_12, FXR_TXENA_N), + + PINMUX_IPSR_GPSR(IP1SR3_19_16, CANFD5_RX), + PINMUX_IPSR_GPSR(IP1SR3_19_16, FXR_TXENB_N), + + PINMUX_IPSR_GPSR(IP1SR3_23_20, CANFD6_TX), + PINMUX_IPSR_GPSR(IP1SR3_23_20, STPWT_EXTFXR), + + /* IP0SR4 */ + PINMUX_IPSR_GPSR(IP0SR4_3_0, AVB0_RX_CTL), + PINMUX_IPSR_GPSR(IP0SR4_3_0, AVB0_MII_RX_DV), + + PINMUX_IPSR_GPSR(IP0SR4_7_4, AVB0_RXC), + PINMUX_IPSR_GPSR(IP0SR4_7_4, AVB0_MII_RXC), + + PINMUX_IPSR_GPSR(IP0SR4_11_8, AVB0_RD0), + PINMUX_IPSR_GPSR(IP0SR4_11_8, AVB0_MII_RD0), + + PINMUX_IPSR_GPSR(IP0SR4_15_12, AVB0_RD1), + PINMUX_IPSR_GPSR(IP0SR4_15_12, AVB0_MII_RD1), + + PINMUX_IPSR_GPSR(IP0SR4_19_16, AVB0_RD2), + PINMUX_IPSR_GPSR(IP0SR4_19_16, AVB0_MII_RD2), + + PINMUX_IPSR_GPSR(IP0SR4_23_20, AVB0_RD3), + PINMUX_IPSR_GPSR(IP0SR4_23_20, AVB0_MII_RD3), + + PINMUX_IPSR_GPSR(IP0SR4_27_24, AVB0_TX_CTL), + PINMUX_IPSR_GPSR(IP0SR4_27_24, AVB0_MII_TX_EN), + + PINMUX_IPSR_GPSR(IP0SR4_31_28, AVB0_TXC), + PINMUX_IPSR_GPSR(IP0SR4_31_28, AVB0_MII_TXC), + + /* IP1SR4 */ + PINMUX_IPSR_GPSR(IP1SR4_3_0, AVB0_TD0), + PINMUX_IPSR_GPSR(IP1SR4_3_0, AVB0_MII_TD0), + + PINMUX_IPSR_GPSR(IP1SR4_7_4, AVB0_TD1), + PINMUX_IPSR_GPSR(IP1SR4_7_4, AVB0_MII_TD1), + + PINMUX_IPSR_GPSR(IP1SR4_11_8, AVB0_TD2), + PINMUX_IPSR_GPSR(IP1SR4_11_8, AVB0_MII_TD2), + + PINMUX_IPSR_GPSR(IP1SR4_15_12, AVB0_TD3), + PINMUX_IPSR_GPSR(IP1SR4_15_12, AVB0_MII_TD3), + + PINMUX_IPSR_GPSR(IP1SR4_19_16, AVB0_TXCREFCLK), + + PINMUX_IPSR_GPSR(IP1SR4_23_20, AVB0_MDIO), + + PINMUX_IPSR_GPSR(IP1SR4_27_24, AVB0_MDC), + + PINMUX_IPSR_GPSR(IP1SR4_31_28, AVB0_MAGIC), + + /* IP2SR4 */ + PINMUX_IPSR_GPSR(IP2SR4_7_4, AVB0_LINK), + PINMUX_IPSR_GPSR(IP2SR4_7_4, AVB0_MII_TX_ER), + + PINMUX_IPSR_GPSR(IP2SR4_11_8, AVB0_AVTP_MATCH), + PINMUX_IPSR_GPSR(IP2SR4_11_8, AVB0_MII_RX_ER), + PINMUX_IPSR_GPSR(IP2SR4_11_8, CC5_OSCOUT), + + PINMUX_IPSR_GPSR(IP2SR4_15_12, AVB0_AVTP_CAPTURE), + PINMUX_IPSR_GPSR(IP2SR4_15_12, AVB0_MII_CRS), + + PINMUX_IPSR_GPSR(IP2SR4_19_16, AVB0_AVTP_PPS), + PINMUX_IPSR_GPSR(IP2SR4_19_16, AVB0_MII_COL), + + /* IP0SR5 */ + PINMUX_IPSR_GPSR(IP0SR5_3_0, AVB1_RX_CTL), + PINMUX_IPSR_GPSR(IP0SR5_3_0, AVB1_MII_RX_DV), + + PINMUX_IPSR_GPSR(IP0SR5_7_4, AVB1_RXC), + PINMUX_IPSR_GPSR(IP0SR5_7_4, AVB1_MII_RXC), + + PINMUX_IPSR_GPSR(IP0SR5_11_8, AVB1_RD0), + PINMUX_IPSR_GPSR(IP0SR5_11_8, AVB1_MII_RD0), + + PINMUX_IPSR_GPSR(IP0SR5_15_12, AVB1_RD1), + PINMUX_IPSR_GPSR(IP0SR5_15_12, AVB1_MII_RD1), + + PINMUX_IPSR_GPSR(IP0SR5_19_16, AVB1_RD2), + PINMUX_IPSR_GPSR(IP0SR5_19_16, AVB1_MII_RD2), + + PINMUX_IPSR_GPSR(IP0SR5_23_20, AVB1_RD3), + PINMUX_IPSR_GPSR(IP0SR5_23_20, AVB1_MII_RD3), + + PINMUX_IPSR_GPSR(IP0SR5_27_24, AVB1_TX_CTL), + PINMUX_IPSR_GPSR(IP0SR5_27_24, AVB1_MII_TX_EN), + + PINMUX_IPSR_GPSR(IP0SR5_31_28, AVB1_TXC), + PINMUX_IPSR_GPSR(IP0SR5_31_28, AVB1_MII_TXC), + + /* IP1SR5 */ + PINMUX_IPSR_GPSR(IP1SR5_3_0, AVB1_TD0), + PINMUX_IPSR_GPSR(IP1SR5_3_0, AVB1_MII_TD0), + + PINMUX_IPSR_GPSR(IP1SR5_7_4, AVB1_TD1), + PINMUX_IPSR_GPSR(IP1SR5_7_4, AVB1_MII_TD1), + + PINMUX_IPSR_GPSR(IP1SR5_11_8, AVB1_TD2), + PINMUX_IPSR_GPSR(IP1SR5_11_8, AVB1_MII_TD2), + + PINMUX_IPSR_GPSR(IP1SR5_15_12, AVB1_TD3), + PINMUX_IPSR_GPSR(IP1SR5_15_12, AVB1_MII_TD3), + + PINMUX_IPSR_GPSR(IP1SR5_19_16, AVB1_TXCREFCLK), + + PINMUX_IPSR_GPSR(IP1SR5_23_20, AVB1_MDIO), + + PINMUX_IPSR_GPSR(IP1SR5_27_24, AVB1_MDC), + + PINMUX_IPSR_GPSR(IP1SR5_31_28, AVB1_MAGIC), + + /* IP2SR5 */ + PINMUX_IPSR_GPSR(IP2SR5_7_4, AVB1_LINK), + PINMUX_IPSR_GPSR(IP2SR5_7_4, AVB1_MII_TX_ER), + + PINMUX_IPSR_GPSR(IP2SR5_11_8, AVB1_AVTP_MATCH), + PINMUX_IPSR_GPSR(IP2SR5_11_8, AVB1_MII_RX_ER), + + PINMUX_IPSR_GPSR(IP2SR5_15_12, AVB1_AVTP_CAPTURE), + PINMUX_IPSR_GPSR(IP2SR5_15_12, AVB1_MII_CRS), + + PINMUX_IPSR_GPSR(IP2SR5_19_16, AVB1_AVTP_PPS), + PINMUX_IPSR_GPSR(IP2SR5_19_16, AVB1_MII_COL), +}; + +/* + * Pins not associated with a GPIO port. + */ +enum { + GP_ASSIGN_LAST(), + NOGP_ALL(), +}; + +static const struct sh_pfc_pin pinmux_pins[] = { + PINMUX_GPIO_GP_ALL(), +}; + +/* - AVB0 ------------------------------------------------ */ +static const unsigned int avb0_link_pins[] = { + /* AVB0_LINK */ + RCAR_GP_PIN(4, 17), +}; +static const unsigned int avb0_link_mux[] = { + AVB0_LINK_MARK, +}; +static const unsigned int avb0_magic_pins[] = { + /* AVB0_MAGIC */ + RCAR_GP_PIN(4, 15), +}; +static const unsigned int avb0_magic_mux[] = { + AVB0_MAGIC_MARK, +}; +static const unsigned int avb0_phy_int_pins[] = { + /* AVB0_PHY_INT */ + RCAR_GP_PIN(4, 16), +}; +static const unsigned int avb0_phy_int_mux[] = { + AVB0_PHY_INT_MARK, +}; +static const unsigned int avb0_mdio_pins[] = { + /* AVB0_MDC, AVB0_MDIO */ + RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 13), +}; +static const unsigned int avb0_mdio_mux[] = { + AVB0_MDC_MARK, AVB0_MDIO_MARK, +}; +static const unsigned int avb0_rgmii_pins[] = { + /* + * AVB0_TX_CTL, AVB0_TXC, AVB0_TD0, AVB0_TD1, AVB0_TD2, AVB0_TD3, + * AVB0_RX_CTL, AVB0_RXC, AVB0_RD0, AVB0_RD1, AVB0_RD2, AVB0_RD3, + */ + RCAR_GP_PIN(4, 6), RCAR_GP_PIN(4, 7), + RCAR_GP_PIN(4, 8), RCAR_GP_PIN(4, 9), + RCAR_GP_PIN(4, 10), RCAR_GP_PIN(4, 11), + RCAR_GP_PIN(4, 0), RCAR_GP_PIN(4, 1), + RCAR_GP_PIN(4, 2), RCAR_GP_PIN(4, 3), + RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 5), +}; +static const unsigned int avb0_rgmii_mux[] = { + AVB0_TX_CTL_MARK, AVB0_TXC_MARK, + AVB0_TD0_MARK, AVB0_TD1_MARK, AVB0_TD2_MARK, AVB0_TD3_MARK, + AVB0_RX_CTL_MARK, AVB0_RXC_MARK, + AVB0_RD0_MARK, AVB0_RD1_MARK, AVB0_RD2_MARK, AVB0_RD3_MARK, +}; +static const unsigned int avb0_txcrefclk_pins[] = { + /* AVB0_TXCREFCLK */ + RCAR_GP_PIN(4, 12), +}; +static const unsigned int avb0_txcrefclk_mux[] = { + AVB0_TXCREFCLK_MARK, +}; +static const unsigned int avb0_avtp_pps_pins[] = { + /* AVB0_AVTP_PPS */ + RCAR_GP_PIN(4, 20), +}; +static const unsigned int avb0_avtp_pps_mux[] = { + AVB0_AVTP_PPS_MARK, +}; +static const unsigned int avb0_avtp_capture_pins[] = { + /* AVB0_AVTP_CAPTURE */ + RCAR_GP_PIN(4, 19), +}; +static const unsigned int avb0_avtp_capture_mux[] = { + AVB0_AVTP_CAPTURE_MARK, +}; +static const unsigned int avb0_avtp_match_pins[] = { + /* AVB0_AVTP_MATCH */ + RCAR_GP_PIN(4, 18), +}; +static const unsigned int avb0_avtp_match_mux[] = { + AVB0_AVTP_MATCH_MARK, +}; + +/* - AVB1 ------------------------------------------------ */ +static const unsigned int avb1_link_pins[] = { + /* AVB1_LINK */ + RCAR_GP_PIN(5, 17), +}; +static const unsigned int avb1_link_mux[] = { + AVB1_LINK_MARK, +}; +static const unsigned int avb1_magic_pins[] = { + /* AVB1_MAGIC */ + RCAR_GP_PIN(5, 15), +}; +static const unsigned int avb1_magic_mux[] = { + AVB1_MAGIC_MARK, +}; +static const unsigned int avb1_phy_int_pins[] = { + /* AVB1_PHY_INT */ + RCAR_GP_PIN(5, 16), +}; +static const unsigned int avb1_phy_int_mux[] = { + AVB1_PHY_INT_MARK, +}; +static const unsigned int avb1_mdio_pins[] = { + /* AVB1_MDC, AVB1_MDIO */ + RCAR_GP_PIN(5, 14), RCAR_GP_PIN(5, 13), +}; +static const unsigned int avb1_mdio_mux[] = { + AVB1_MDC_MARK, AVB1_MDIO_MARK, +}; +static const unsigned int avb1_rgmii_pins[] = { + /* + * AVB1_TX_CTL, AVB1_TXC, AVB1_TD0, AVB1_TD1, AVB1_TD2, AVB1_TD3, + * AVB1_RX_CTL, AVB1_RXC, AVB1_RD0, AVB1_RD1, AVB1_RD2, AVB1_RD3, + */ + RCAR_GP_PIN(5, 6), RCAR_GP_PIN(5, 7), + RCAR_GP_PIN(5, 8), RCAR_GP_PIN(5, 9), + RCAR_GP_PIN(5, 10), RCAR_GP_PIN(5, 11), + RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 1), + RCAR_GP_PIN(5, 2), RCAR_GP_PIN(5, 3), + RCAR_GP_PIN(5, 4), RCAR_GP_PIN(5, 5), +}; +static const unsigned int avb1_rgmii_mux[] = { + AVB1_TX_CTL_MARK, AVB1_TXC_MARK, + AVB1_TD0_MARK, AVB1_TD1_MARK, AVB1_TD2_MARK, AVB1_TD3_MARK, + AVB1_RX_CTL_MARK, AVB1_RXC_MARK, + AVB1_RD0_MARK, AVB1_RD1_MARK, AVB1_RD2_MARK, AVB1_RD3_MARK, +}; +static const unsigned int avb1_txcrefclk_pins[] = { + /* AVB1_TXCREFCLK */ + RCAR_GP_PIN(5, 12), +}; +static const unsigned int avb1_txcrefclk_mux[] = { + AVB1_TXCREFCLK_MARK, +}; +static const unsigned int avb1_avtp_pps_pins[] = { + /* AVB1_AVTP_PPS */ + RCAR_GP_PIN(5, 20), +}; +static const unsigned int avb1_avtp_pps_mux[] = { + AVB1_AVTP_PPS_MARK, +}; +static const unsigned int avb1_avtp_capture_pins[] = { + /* AVB1_AVTP_CAPTURE */ + RCAR_GP_PIN(5, 19), +}; +static const unsigned int avb1_avtp_capture_mux[] = { + AVB1_AVTP_CAPTURE_MARK, +}; +static const unsigned int avb1_avtp_match_pins[] = { + /* AVB1_AVTP_MATCH */ + RCAR_GP_PIN(5, 18), +}; +static const unsigned int avb1_avtp_match_mux[] = { + AVB1_AVTP_MATCH_MARK, +}; + +/* - AVB2 ------------------------------------------------ */ +static const unsigned int avb2_link_pins[] = { + /* AVB2_LINK */ + RCAR_GP_PIN(6, 17), +}; +static const unsigned int avb2_link_mux[] = { + AVB2_LINK_MARK, +}; +static const unsigned int avb2_magic_pins[] = { + /* AVB2_MAGIC */ + RCAR_GP_PIN(6, 15), +}; +static const unsigned int avb2_magic_mux[] = { + AVB2_MAGIC_MARK, +}; +static const unsigned int avb2_phy_int_pins[] = { + /* AVB2_PHY_INT */ + RCAR_GP_PIN(6, 16), +}; +static const unsigned int avb2_phy_int_mux[] = { + AVB2_PHY_INT_MARK, +}; +static const unsigned int avb2_mdio_pins[] = { + /* AVB2_MDC, AVB2_MDIO */ + RCAR_GP_PIN(6, 14), RCAR_GP_PIN(6, 13), +}; +static const unsigned int avb2_mdio_mux[] = { + AVB2_MDC_MARK, AVB2_MDIO_MARK, +}; +static const unsigned int avb2_rgmii_pins[] = { + /* + * AVB2_TX_CTL, AVB2_TXC, AVB2_TD0, AVB2_TD1, AVB2_TD2, AVB2_TD3, + * AVB2_RX_CTL, AVB2_RXC, AVB2_RD0, AVB2_RD1, AVB2_RD2, AVB2_RD3, + */ + RCAR_GP_PIN(6, 6), RCAR_GP_PIN(6, 7), + RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9), + RCAR_GP_PIN(6, 10), RCAR_GP_PIN(6, 11), + RCAR_GP_PIN(6, 0), RCAR_GP_PIN(6, 1), + RCAR_GP_PIN(6, 2), RCAR_GP_PIN(6, 3), + RCAR_GP_PIN(6, 4), RCAR_GP_PIN(6, 5), +}; +static const unsigned int avb2_rgmii_mux[] = { + AVB2_TX_CTL_MARK, AVB2_TXC_MARK, + AVB2_TD0_MARK, AVB2_TD1_MARK, AVB2_TD2_MARK, AVB2_TD3_MARK, + AVB2_RX_CTL_MARK, AVB2_RXC_MARK, + AVB2_RD0_MARK, AVB2_RD1_MARK, AVB2_RD2_MARK, AVB2_RD3_MARK, +}; +static const unsigned int avb2_txcrefclk_pins[] = { + /* AVB2_TXCREFCLK */ + RCAR_GP_PIN(6, 12), +}; +static const unsigned int avb2_txcrefclk_mux[] = { + AVB2_TXCREFCLK_MARK, +}; +static const unsigned int avb2_avtp_pps_pins[] = { + /* AVB2_AVTP_PPS */ + RCAR_GP_PIN(6, 20), +}; +static const unsigned int avb2_avtp_pps_mux[] = { + AVB2_AVTP_PPS_MARK, +}; +static const unsigned int avb2_avtp_capture_pins[] = { + /* AVB2_AVTP_CAPTURE */ + RCAR_GP_PIN(6, 19), +}; +static const unsigned int avb2_avtp_capture_mux[] = { + AVB2_AVTP_CAPTURE_MARK, +}; +static const unsigned int avb2_avtp_match_pins[] = { + /* AVB2_AVTP_MATCH */ + RCAR_GP_PIN(6, 18), +}; +static const unsigned int avb2_avtp_match_mux[] = { + AVB2_AVTP_MATCH_MARK, +}; + +/* - AVB3 ------------------------------------------------ */ +static const unsigned int avb3_link_pins[] = { + /* AVB3_LINK */ + RCAR_GP_PIN(7, 17), +}; +static const unsigned int avb3_link_mux[] = { + AVB3_LINK_MARK, +}; +static const unsigned int avb3_magic_pins[] = { + /* AVB3_MAGIC */ + RCAR_GP_PIN(7, 15), +}; +static const unsigned int avb3_magic_mux[] = { + AVB3_MAGIC_MARK, +}; +static const unsigned int avb3_phy_int_pins[] = { + /* AVB3_PHY_INT */ + RCAR_GP_PIN(7, 16), +}; +static const unsigned int avb3_phy_int_mux[] = { + AVB3_PHY_INT_MARK, +}; +static const unsigned int avb3_mdio_pins[] = { + /* AVB3_MDC, AVB3_MDIO */ + RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 13), +}; +static const unsigned int avb3_mdio_mux[] = { + AVB3_MDC_MARK, AVB3_MDIO_MARK, +}; +static const unsigned int avb3_rgmii_pins[] = { + /* + * AVB3_TX_CTL, AVB3_TXC, AVB3_TD0, AVB3_TD1, AVB3_TD2, AVB3_TD3, + * AVB3_RX_CTL, AVB3_RXC, AVB3_RD0, AVB3_RD1, AVB3_RD2, AVB3_RD3, + */ + RCAR_GP_PIN(7, 6), RCAR_GP_PIN(7, 7), + RCAR_GP_PIN(7, 8), RCAR_GP_PIN(7, 9), + RCAR_GP_PIN(7, 10), RCAR_GP_PIN(7, 11), + RCAR_GP_PIN(7, 0), RCAR_GP_PIN(7, 1), + RCAR_GP_PIN(7, 2), RCAR_GP_PIN(7, 3), + RCAR_GP_PIN(7, 4), RCAR_GP_PIN(7, 5), +}; +static const unsigned int avb3_rgmii_mux[] = { + AVB3_TX_CTL_MARK, AVB3_TXC_MARK, + AVB3_TD0_MARK, AVB3_TD1_MARK, AVB3_TD2_MARK, AVB3_TD3_MARK, + AVB3_RX_CTL_MARK, AVB3_RXC_MARK, + AVB3_RD0_MARK, AVB3_RD1_MARK, AVB3_RD2_MARK, AVB3_RD3_MARK, +}; +static const unsigned int avb3_txcrefclk_pins[] = { + /* AVB3_TXCREFCLK */ + RCAR_GP_PIN(7, 12), +}; +static const unsigned int avb3_txcrefclk_mux[] = { + AVB3_TXCREFCLK_MARK, +}; +static const unsigned int avb3_avtp_pps_pins[] = { + /* AVB3_AVTP_PPS */ + RCAR_GP_PIN(7, 20), +}; +static const unsigned int avb3_avtp_pps_mux[] = { + AVB3_AVTP_PPS_MARK, +}; +static const unsigned int avb3_avtp_capture_pins[] = { + /* AVB3_AVTP_CAPTURE */ + RCAR_GP_PIN(7, 19), +}; +static const unsigned int avb3_avtp_capture_mux[] = { + AVB3_AVTP_CAPTURE_MARK, +}; +static const unsigned int avb3_avtp_match_pins[] = { + /* AVB3_AVTP_MATCH */ + RCAR_GP_PIN(7, 18), +}; +static const unsigned int avb3_avtp_match_mux[] = { + AVB3_AVTP_MATCH_MARK, +}; + +/* - AVB4 ------------------------------------------------ */ +static const unsigned int avb4_link_pins[] = { + /* AVB4_LINK */ + RCAR_GP_PIN(8, 17), +}; +static const unsigned int avb4_link_mux[] = { + AVB4_LINK_MARK, +}; +static const unsigned int avb4_magic_pins[] = { + /* AVB4_MAGIC */ + RCAR_GP_PIN(8, 15), +}; +static const unsigned int avb4_magic_mux[] = { + AVB4_MAGIC_MARK, +}; +static const unsigned int avb4_phy_int_pins[] = { + /* AVB4_PHY_INT */ + RCAR_GP_PIN(8, 16), +}; +static const unsigned int avb4_phy_int_mux[] = { + AVB4_PHY_INT_MARK, +}; +static const unsigned int avb4_mdio_pins[] = { + /* AVB4_MDC, AVB4_MDIO */ + RCAR_GP_PIN(8, 14), RCAR_GP_PIN(8, 13), +}; +static const unsigned int avb4_mdio_mux[] = { + AVB4_MDC_MARK, AVB4_MDIO_MARK, +}; +static const unsigned int avb4_rgmii_pins[] = { + /* + * AVB4_TX_CTL, AVB4_TXC, AVB4_TD0, AVB4_TD1, AVB4_TD2, AVB4_TD3, + * AVB4_RX_CTL, AVB4_RXC, AVB4_RD0, AVB4_RD1, AVB4_RD2, AVB4_RD3, + */ + RCAR_GP_PIN(8, 6), RCAR_GP_PIN(8, 7), + RCAR_GP_PIN(8, 8), RCAR_GP_PIN(8, 9), + RCAR_GP_PIN(8, 10), RCAR_GP_PIN(8, 11), + RCAR_GP_PIN(8, 0), RCAR_GP_PIN(8, 1), + RCAR_GP_PIN(8, 2), RCAR_GP_PIN(8, 3), + RCAR_GP_PIN(8, 4), RCAR_GP_PIN(8, 5), +}; +static const unsigned int avb4_rgmii_mux[] = { + AVB4_TX_CTL_MARK, AVB4_TXC_MARK, + AVB4_TD0_MARK, AVB4_TD1_MARK, AVB4_TD2_MARK, AVB4_TD3_MARK, + AVB4_RX_CTL_MARK, AVB4_RXC_MARK, + AVB4_RD0_MARK, AVB4_RD1_MARK, AVB4_RD2_MARK, AVB4_RD3_MARK, +}; +static const unsigned int avb4_txcrefclk_pins[] = { + /* AVB4_TXCREFCLK */ + RCAR_GP_PIN(8, 12), +}; +static const unsigned int avb4_txcrefclk_mux[] = { + AVB4_TXCREFCLK_MARK, +}; +static const unsigned int avb4_avtp_pps_pins[] = { + /* AVB4_AVTP_PPS */ + RCAR_GP_PIN(8, 20), +}; +static const unsigned int avb4_avtp_pps_mux[] = { + AVB4_AVTP_PPS_MARK, +}; +static const unsigned int avb4_avtp_capture_pins[] = { + /* AVB4_AVTP_CAPTURE */ + RCAR_GP_PIN(8, 19), +}; +static const unsigned int avb4_avtp_capture_mux[] = { + AVB4_AVTP_CAPTURE_MARK, +}; +static const unsigned int avb4_avtp_match_pins[] = { + /* AVB4_AVTP_MATCH */ + RCAR_GP_PIN(8, 18), +}; +static const unsigned int avb4_avtp_match_mux[] = { + AVB4_AVTP_MATCH_MARK, +}; + +/* - AVB5 ------------------------------------------------ */ +static const unsigned int avb5_link_pins[] = { + /* AVB5_LINK */ + RCAR_GP_PIN(9, 17), +}; +static const unsigned int avb5_link_mux[] = { + AVB5_LINK_MARK, +}; +static const unsigned int avb5_magic_pins[] = { + /* AVB5_MAGIC */ + RCAR_GP_PIN(9, 15), +}; +static const unsigned int avb5_magic_mux[] = { + AVB5_MAGIC_MARK, +}; +static const unsigned int avb5_phy_int_pins[] = { + /* AVB5_PHY_INT */ + RCAR_GP_PIN(9, 16), +}; +static const unsigned int avb5_phy_int_mux[] = { + AVB5_PHY_INT_MARK, +}; +static const unsigned int avb5_mdio_pins[] = { + /* AVB5_MDC, AVB5_MDIO */ + RCAR_GP_PIN(9, 14), RCAR_GP_PIN(9, 13), +}; +static const unsigned int avb5_mdio_mux[] = { + AVB5_MDC_MARK, AVB5_MDIO_MARK, +}; +static const unsigned int avb5_rgmii_pins[] = { + /* + * AVB5_TX_CTL, AVB5_TXC, AVB5_TD0, AVB5_TD1, AVB5_TD2, AVB5_TD3, + * AVB5_RX_CTL, AVB5_RXC, AVB5_RD0, AVB5_RD1, AVB5_RD2, AVB5_RD3, + */ + RCAR_GP_PIN(9, 6), RCAR_GP_PIN(9, 7), + RCAR_GP_PIN(9, 8), RCAR_GP_PIN(9, 9), + RCAR_GP_PIN(9, 10), RCAR_GP_PIN(9, 11), + RCAR_GP_PIN(9, 0), RCAR_GP_PIN(9, 1), + RCAR_GP_PIN(9, 2), RCAR_GP_PIN(9, 3), + RCAR_GP_PIN(9, 4), RCAR_GP_PIN(9, 5), +}; +static const unsigned int avb5_rgmii_mux[] = { + AVB5_TX_CTL_MARK, AVB5_TXC_MARK, + AVB5_TD0_MARK, AVB5_TD1_MARK, AVB5_TD2_MARK, AVB5_TD3_MARK, + AVB5_RX_CTL_MARK, AVB5_RXC_MARK, + AVB5_RD0_MARK, AVB5_RD1_MARK, AVB5_RD2_MARK, AVB5_RD3_MARK, +}; +static const unsigned int avb5_txcrefclk_pins[] = { + /* AVB5_TXCREFCLK */ + RCAR_GP_PIN(9, 12), +}; +static const unsigned int avb5_txcrefclk_mux[] = { + AVB5_TXCREFCLK_MARK, +}; +static const unsigned int avb5_avtp_pps_pins[] = { + /* AVB5_AVTP_PPS */ + RCAR_GP_PIN(9, 20), +}; +static const unsigned int avb5_avtp_pps_mux[] = { + AVB5_AVTP_PPS_MARK, +}; +static const unsigned int avb5_avtp_capture_pins[] = { + /* AVB5_AVTP_CAPTURE */ + RCAR_GP_PIN(9, 19), +}; +static const unsigned int avb5_avtp_capture_mux[] = { + AVB5_AVTP_CAPTURE_MARK, +}; +static const unsigned int avb5_avtp_match_pins[] = { + /* AVB5_AVTP_MATCH */ + RCAR_GP_PIN(9, 18), +}; +static const unsigned int avb5_avtp_match_mux[] = { + AVB5_AVTP_MATCH_MARK, +}; + +/* - CANFD0 ----------------------------------------------------------------- */ +static const unsigned int canfd0_data_pins[] = { + /* CANFD0_TX, CANFD0_RX */ + RCAR_GP_PIN(3, 1), RCAR_GP_PIN(3, 2), +}; +static const unsigned int canfd0_data_mux[] = { + CANFD0_TX_MARK, CANFD0_RX_MARK, +}; + +/* - CANFD1 ----------------------------------------------------------------- */ +static const unsigned int canfd1_data_pins[] = { + /* CANFD1_TX, CANFD1_RX */ + RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 4), +}; +static const unsigned int canfd1_data_mux[] = { + CANFD1_TX_MARK, CANFD1_RX_MARK, +}; + +/* - CANFD2 ----------------------------------------------------------------- */ +static const unsigned int canfd2_data_pins[] = { + /* CANFD2_TX, CANFD2_RX */ + RCAR_GP_PIN(3, 5), RCAR_GP_PIN(3, 6), +}; +static const unsigned int canfd2_data_mux[] = { + CANFD2_TX_MARK, CANFD2_RX_MARK, +}; + +/* - CANFD3 ----------------------------------------------------------------- */ +static const unsigned int canfd3_data_pins[] = { + /* CANFD3_TX, CANFD3_RX */ + RCAR_GP_PIN(3, 7), RCAR_GP_PIN(3, 8), +}; +static const unsigned int canfd3_data_mux[] = { + CANFD3_TX_MARK, CANFD3_RX_MARK, +}; + +/* - CANFD4 ----------------------------------------------------------------- */ +static const unsigned int canfd4_data_pins[] = { + /* CANFD4_TX, CANFD4_RX */ + RCAR_GP_PIN(3, 9), RCAR_GP_PIN(3, 10), +}; +static const unsigned int canfd4_data_mux[] = { + CANFD4_TX_MARK, CANFD4_RX_MARK, +}; + +/* - CANFD5 ----------------------------------------------------------------- */ +static const unsigned int canfd5_data_pins[] = { + /* CANFD5_TX, CANFD5_RX */ + RCAR_GP_PIN(3, 11), RCAR_GP_PIN(3, 12), +}; +static const unsigned int canfd5_data_mux[] = { + CANFD5_TX_MARK, CANFD5_RX_MARK, +}; + +/* - CANFD6 ----------------------------------------------------------------- */ +static const unsigned int canfd6_data_pins[] = { + /* CANFD6_TX, CANFD6_RX */ + RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 14), +}; +static const unsigned int canfd6_data_mux[] = { + CANFD6_TX_MARK, CANFD6_RX_MARK, +}; + +/* - CANFD7 ----------------------------------------------------------------- */ +static const unsigned int canfd7_data_pins[] = { + /* CANFD7_TX, CANFD7_RX */ + RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 16), +}; +static const unsigned int canfd7_data_mux[] = { + CANFD7_TX_MARK, CANFD7_RX_MARK, +}; + +/* - CANFD Clock ------------------------------------------------------------ */ +static const unsigned int can_clk_pins[] = { + /* CAN_CLK */ + RCAR_GP_PIN(3, 0), +}; +static const unsigned int can_clk_mux[] = { + CAN_CLK_MARK, +}; + +/* - DU --------------------------------------------------------------------- */ +static const unsigned int du_rgb888_pins[] = { + /* DU_DR[7:2], DU_DG[7:2], DU_DB[7:2] */ + RCAR_GP_PIN(1, 11), RCAR_GP_PIN(1, 10), RCAR_GP_PIN(1, 9), + RCAR_GP_PIN(1, 8), RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), + RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 16), RCAR_GP_PIN(1, 15), + RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13), RCAR_GP_PIN(1, 12), + RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 21), + RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18), +}; +static const unsigned int du_rgb888_mux[] = { + DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, + DU_DR4_MARK, DU_DR3_MARK, DU_DR2_MARK, + DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, + DU_DG4_MARK, DU_DG3_MARK, DU_DG2_MARK, + DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, + DU_DB4_MARK, DU_DB3_MARK, DU_DB2_MARK, +}; +static const unsigned int du_clk_out_pins[] = { + /* DU_DOTCLKOUT */ + RCAR_GP_PIN(1, 24), +}; +static const unsigned int du_clk_out_mux[] = { + DU_DOTCLKOUT_MARK, +}; +static const unsigned int du_sync_pins[] = { + /* DU_HSYNC, DU_VSYNC */ + RCAR_GP_PIN(1, 25), RCAR_GP_PIN(1, 26), +}; +static const unsigned int du_sync_mux[] = { + DU_HSYNC_MARK, DU_VSYNC_MARK, +}; +static const unsigned int du_oddf_pins[] = { + /* DU_EXODDF/DU_ODDF/DISP/CDE */ + RCAR_GP_PIN(1, 27), +}; +static const unsigned int du_oddf_mux[] = { + DU_ODDF_DISP_CDE_MARK, +}; + +/* - HSCIF0 ----------------------------------------------------------------- */ +static const unsigned int hscif0_data_pins[] = { + /* HRX0, HTX0 */ + RCAR_GP_PIN(1, 1), RCAR_GP_PIN(1, 5), +}; +static const unsigned int hscif0_data_mux[] = { + HRX0_MARK, HTX0_MARK, +}; +static const unsigned int hscif0_clk_pins[] = { + /* HSCK0 */ + RCAR_GP_PIN(1, 2), +}; +static const unsigned int hscif0_clk_mux[] = { + HSCK0_MARK, +}; +static const unsigned int hscif0_ctrl_pins[] = { + /* HRTS0#, HCTS0# */ + RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 4), +}; +static const unsigned int hscif0_ctrl_mux[] = { + HRTS0_N_MARK, HCTS0_N_MARK, +}; + +/* - HSCIF1 ----------------------------------------------------------------- */ +static const unsigned int hscif1_data_pins[] = { + /* HRX1, HTX1 */ + RCAR_GP_PIN(1, 21), RCAR_GP_PIN(1, 22), +}; +static const unsigned int hscif1_data_mux[] = { + HRX1_MARK, HTX1_MARK, +}; +static const unsigned int hscif1_clk_pins[] = { + /* HSCK1 */ + RCAR_GP_PIN(1, 18), +}; +static const unsigned int hscif1_clk_mux[] = { + HSCK1_MARK, +}; +static const unsigned int hscif1_ctrl_pins[] = { + /* HRTS1#, HCTS1# */ + RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 19), +}; +static const unsigned int hscif1_ctrl_mux[] = { + HRTS1_N_MARK, HCTS1_N_MARK, +}; + +/* - HSCIF2 ----------------------------------------------------------------- */ +static const unsigned int hscif2_data_pins[] = { + /* HRX2, HTX2 */ + RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), +}; +static const unsigned int hscif2_data_mux[] = { + HRX2_MARK, HTX2_MARK, +}; +static const unsigned int hscif2_clk_pins[] = { + /* HSCK2 */ + RCAR_GP_PIN(2, 5), +}; +static const unsigned int hscif2_clk_mux[] = { + HSCK2_MARK, +}; +static const unsigned int hscif2_ctrl_pins[] = { + /* HRTS2#, HCTS2# */ + RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 6), +}; +static const unsigned int hscif2_ctrl_mux[] = { + HRTS2_N_MARK, HCTS2_N_MARK, +}; + +/* - HSCIF3 ----------------------------------------------------------------- */ +static const unsigned int hscif3_data_pins[] = { + /* HRX3, HTX3 */ + RCAR_GP_PIN(1, 13), RCAR_GP_PIN(1, 17), +}; +static const unsigned int hscif3_data_mux[] = { + HRX3_MARK, HTX3_MARK, +}; +static const unsigned int hscif3_clk_pins[] = { + /* HSCK3 */ + RCAR_GP_PIN(1, 14), +}; +static const unsigned int hscif3_clk_mux[] = { + HSCK3_MARK, +}; +static const unsigned int hscif3_ctrl_pins[] = { + /* HRTS3#, HCTS3# */ + RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 16), +}; +static const unsigned int hscif3_ctrl_mux[] = { + HRTS3_N_MARK, HCTS3_N_MARK, +}; + +/* - I2C0 ------------------------------------------------------------------- */ +static const unsigned int i2c0_pins[] = { + /* SDA0, SCL0 */ + RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 2), +}; +static const unsigned int i2c0_mux[] = { + SDA0_MARK, SCL0_MARK, +}; + +/* - I2C1 ------------------------------------------------------------------- */ +static const unsigned int i2c1_pins[] = { + /* SDA1, SCL1 */ + RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 4), +}; +static const unsigned int i2c1_mux[] = { + SDA1_MARK, SCL1_MARK, +}; + +/* - I2C2 ------------------------------------------------------------------- */ +static const unsigned int i2c2_pins[] = { + /* SDA2, SCL2 */ + RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 6), +}; +static const unsigned int i2c2_mux[] = { + SDA2_MARK, SCL2_MARK, +}; + +/* - I2C3 ------------------------------------------------------------------- */ +static const unsigned int i2c3_pins[] = { + /* SDA3, SCL3 */ + RCAR_GP_PIN(2, 9), RCAR_GP_PIN(2, 8), +}; +static const unsigned int i2c3_mux[] = { + SDA3_MARK, SCL3_MARK, +}; + +/* - I2C4 ------------------------------------------------------------------- */ +static const unsigned int i2c4_pins[] = { + /* SDA4, SCL4 */ + RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 10), +}; +static const unsigned int i2c4_mux[] = { + SDA4_MARK, SCL4_MARK, +}; + +/* - I2C5 ------------------------------------------------------------------- */ +static const unsigned int i2c5_pins[] = { + /* SDA5, SCL5 */ + RCAR_GP_PIN(2, 13), RCAR_GP_PIN(2, 12), +}; +static const unsigned int i2c5_mux[] = { + SDA5_MARK, SCL5_MARK, +}; + +/* - I2C6 ------------------------------------------------------------------- */ +static const unsigned int i2c6_pins[] = { + /* SDA6, SCL6 */ + RCAR_GP_PIN(2, 15), RCAR_GP_PIN(2, 14), +}; +static const unsigned int i2c6_mux[] = { + SDA6_MARK, SCL6_MARK, +}; + +/* - INTC-EX ---------------------------------------------------------------- */ +static const unsigned int intc_ex_irq0_pins[] = { + /* IRQ0 */ + RCAR_GP_PIN(1, 24), +}; +static const unsigned int intc_ex_irq0_mux[] = { + IRQ0_MARK, +}; +static const unsigned int intc_ex_irq1_pins[] = { + /* IRQ1 */ + RCAR_GP_PIN(1, 25), +}; +static const unsigned int intc_ex_irq1_mux[] = { + IRQ1_MARK, +}; +static const unsigned int intc_ex_irq2_pins[] = { + /* IRQ2 */ + RCAR_GP_PIN(1, 26), +}; +static const unsigned int intc_ex_irq2_mux[] = { + IRQ2_MARK, +}; +static const unsigned int intc_ex_irq3_pins[] = { + /* IRQ3 */ + RCAR_GP_PIN(1, 27), +}; +static const unsigned int intc_ex_irq3_mux[] = { + IRQ3_MARK, +}; +static const unsigned int intc_ex_irq4_pins[] = { + /* IRQ4 */ + RCAR_GP_PIN(2, 14), +}; +static const unsigned int intc_ex_irq4_mux[] = { + IRQ4_MARK, +}; +static const unsigned int intc_ex_irq5_pins[] = { + /* IRQ5 */ + RCAR_GP_PIN(2, 15), +}; +static const unsigned int intc_ex_irq5_mux[] = { + IRQ5_MARK, +}; + +/* - MMC -------------------------------------------------------------------- */ +static const unsigned int mmc_data1_pins[] = { + /* MMC_SD_D0 */ + RCAR_GP_PIN(0, 19), +}; +static const unsigned int mmc_data1_mux[] = { + MMC_SD_D0_MARK, +}; +static const unsigned int mmc_data4_pins[] = { + /* MMC_SD_D[0:3] */ + RCAR_GP_PIN(0, 19), RCAR_GP_PIN(0, 20), + RCAR_GP_PIN(0, 21), RCAR_GP_PIN(0, 22), +}; +static const unsigned int mmc_data4_mux[] = { + MMC_SD_D0_MARK, MMC_SD_D1_MARK, + MMC_SD_D2_MARK, MMC_SD_D3_MARK, +}; +static const unsigned int mmc_data8_pins[] = { + /* MMC_SD_D[0:3], MMC_D[4:7] */ + RCAR_GP_PIN(0, 19), RCAR_GP_PIN(0, 20), + RCAR_GP_PIN(0, 21), RCAR_GP_PIN(0, 22), + RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25), + RCAR_GP_PIN(0, 26), RCAR_GP_PIN(0, 27), +}; +static const unsigned int mmc_data8_mux[] = { + MMC_SD_D0_MARK, MMC_SD_D1_MARK, + MMC_SD_D2_MARK, MMC_SD_D3_MARK, + MMC_D4_MARK, MMC_D5_MARK, + MMC_D6_MARK, MMC_D7_MARK, +}; +static const unsigned int mmc_ctrl_pins[] = { + /* MMC_SD_CLK, MMC_SD_CMD */ + RCAR_GP_PIN(0, 23), RCAR_GP_PIN(0, 18), +}; +static const unsigned int mmc_ctrl_mux[] = { + MMC_SD_CLK_MARK, MMC_SD_CMD_MARK, +}; +static const unsigned int mmc_cd_pins[] = { + /* SD_CD */ + RCAR_GP_PIN(0, 16), +}; +static const unsigned int mmc_cd_mux[] = { + SD_CD_MARK, +}; +static const unsigned int mmc_wp_pins[] = { + /* SD_WP */ + RCAR_GP_PIN(0, 15), +}; +static const unsigned int mmc_wp_mux[] = { + SD_WP_MARK, +}; +static const unsigned int mmc_ds_pins[] = { + /* MMC_DS */ + RCAR_GP_PIN(0, 17), +}; +static const unsigned int mmc_ds_mux[] = { + MMC_DS_MARK, +}; + +/* - MSIOF0 ----------------------------------------------------------------- */ +static const unsigned int msiof0_clk_pins[] = { + /* MSIOF0_SCK */ + RCAR_GP_PIN(1, 8), +}; +static const unsigned int msiof0_clk_mux[] = { + MSIOF0_SCK_MARK, +}; +static const unsigned int msiof0_sync_pins[] = { + /* MSIOF0_SYNC */ + RCAR_GP_PIN(1, 9), +}; +static const unsigned int msiof0_sync_mux[] = { + MSIOF0_SYNC_MARK, +}; +static const unsigned int msiof0_ss1_pins[] = { + /* MSIOF0_SS1 */ + RCAR_GP_PIN(1, 10), +}; +static const unsigned int msiof0_ss1_mux[] = { + MSIOF0_SS1_MARK, +}; +static const unsigned int msiof0_ss2_pins[] = { + /* MSIOF0_SS2 */ + RCAR_GP_PIN(1, 11), +}; +static const unsigned int msiof0_ss2_mux[] = { + MSIOF0_SS2_MARK, +}; +static const unsigned int msiof0_txd_pins[] = { + /* MSIOF0_TXD */ + RCAR_GP_PIN(1, 7), +}; +static const unsigned int msiof0_txd_mux[] = { + MSIOF0_TXD_MARK, +}; +static const unsigned int msiof0_rxd_pins[] = { + /* MSIOF0_RXD */ + RCAR_GP_PIN(1, 6), +}; +static const unsigned int msiof0_rxd_mux[] = { + MSIOF0_RXD_MARK, +}; + +/* - MSIOF1 ----------------------------------------------------------------- */ +static const unsigned int msiof1_clk_pins[] = { + /* MSIOF1_SCK */ + RCAR_GP_PIN(1, 14), +}; +static const unsigned int msiof1_clk_mux[] = { + MSIOF1_SCK_MARK, +}; +static const unsigned int msiof1_sync_pins[] = { + /* MSIOF1_SYNC */ + RCAR_GP_PIN(1, 15), +}; +static const unsigned int msiof1_sync_mux[] = { + MSIOF1_SYNC_MARK, +}; +static const unsigned int msiof1_ss1_pins[] = { + /* MSIOF1_SS1 */ + RCAR_GP_PIN(1, 16), +}; +static const unsigned int msiof1_ss1_mux[] = { + MSIOF1_SS1_MARK, +}; +static const unsigned int msiof1_ss2_pins[] = { + /* MSIOF1_SS2 */ + RCAR_GP_PIN(1, 17), +}; +static const unsigned int msiof1_ss2_mux[] = { + MSIOF1_SS2_MARK, +}; +static const unsigned int msiof1_txd_pins[] = { + /* MSIOF1_TXD */ + RCAR_GP_PIN(1, 13), +}; +static const unsigned int msiof1_txd_mux[] = { + MSIOF1_TXD_MARK, +}; +static const unsigned int msiof1_rxd_pins[] = { + /* MSIOF1_RXD */ + RCAR_GP_PIN(1, 12), +}; +static const unsigned int msiof1_rxd_mux[] = { + MSIOF1_RXD_MARK, +}; + +/* - MSIOF2 ----------------------------------------------------------------- */ +static const unsigned int msiof2_clk_pins[] = { + /* MSIOF2_SCK */ + RCAR_GP_PIN(1, 20), +}; +static const unsigned int msiof2_clk_mux[] = { + MSIOF2_SCK_MARK, +}; +static const unsigned int msiof2_sync_pins[] = { + /* MSIOF2_SYNC */ + RCAR_GP_PIN(1, 21), +}; +static const unsigned int msiof2_sync_mux[] = { + MSIOF2_SYNC_MARK, +}; +static const unsigned int msiof2_ss1_pins[] = { + /* MSIOF2_SS1 */ + RCAR_GP_PIN(1, 22), +}; +static const unsigned int msiof2_ss1_mux[] = { + MSIOF2_SS1_MARK, +}; +static const unsigned int msiof2_ss2_pins[] = { + /* MSIOF2_SS2 */ + RCAR_GP_PIN(1, 23), +}; +static const unsigned int msiof2_ss2_mux[] = { + MSIOF2_SS2_MARK, +}; +static const unsigned int msiof2_txd_pins[] = { + /* MSIOF2_TXD */ + RCAR_GP_PIN(1, 19), +}; +static const unsigned int msiof2_txd_mux[] = { + MSIOF2_TXD_MARK, +}; +static const unsigned int msiof2_rxd_pins[] = { + /* MSIOF2_RXD */ + RCAR_GP_PIN(1, 18), +}; +static const unsigned int msiof2_rxd_mux[] = { + MSIOF2_RXD_MARK, +}; + +/* - MSIOF3 ----------------------------------------------------------------- */ +static const unsigned int msiof3_clk_pins[] = { + /* MSIOF3_SCK */ + RCAR_GP_PIN(2, 20), +}; +static const unsigned int msiof3_clk_mux[] = { + MSIOF3_SCK_MARK, +}; +static const unsigned int msiof3_sync_pins[] = { + /* MSIOF3_SYNC */ + RCAR_GP_PIN(2, 21), +}; +static const unsigned int msiof3_sync_mux[] = { + MSIOF3_SYNC_MARK, +}; +static const unsigned int msiof3_ss1_pins[] = { + /* MSIOF3_SS1 */ + RCAR_GP_PIN(2, 16), +}; +static const unsigned int msiof3_ss1_mux[] = { + MSIOF3_SS1_MARK, +}; +static const unsigned int msiof3_ss2_pins[] = { + /* MSIOF3_SS2 */ + RCAR_GP_PIN(2, 17), +}; +static const unsigned int msiof3_ss2_mux[] = { + MSIOF3_SS2_MARK, +}; +static const unsigned int msiof3_txd_pins[] = { + /* MSIOF3_TXD */ + RCAR_GP_PIN(2, 19), +}; +static const unsigned int msiof3_txd_mux[] = { + MSIOF3_TXD_MARK, +}; +static const unsigned int msiof3_rxd_pins[] = { + /* MSIOF3_RXD */ + RCAR_GP_PIN(2, 18), +}; +static const unsigned int msiof3_rxd_mux[] = { + MSIOF3_RXD_MARK, +}; + +/* - MSIOF4 ----------------------------------------------------------------- */ +static const unsigned int msiof4_clk_pins[] = { + /* MSIOF4_SCK */ + RCAR_GP_PIN(2, 6), +}; +static const unsigned int msiof4_clk_mux[] = { + MSIOF4_SCK_MARK, +}; +static const unsigned int msiof4_sync_pins[] = { + /* MSIOF4_SYNC */ + RCAR_GP_PIN(2, 7), +}; +static const unsigned int msiof4_sync_mux[] = { + MSIOF4_SYNC_MARK, +}; +static const unsigned int msiof4_ss1_pins[] = { + /* MSIOF4_SS1 */ + RCAR_GP_PIN(2, 8), +}; +static const unsigned int msiof4_ss1_mux[] = { + MSIOF4_SS1_MARK, +}; +static const unsigned int msiof4_ss2_pins[] = { + /* MSIOF4_SS2 */ + RCAR_GP_PIN(2, 9), +}; +static const unsigned int msiof4_ss2_mux[] = { + MSIOF4_SS2_MARK, +}; +static const unsigned int msiof4_txd_pins[] = { + /* MSIOF4_TXD */ + RCAR_GP_PIN(2, 5), +}; +static const unsigned int msiof4_txd_mux[] = { + MSIOF4_TXD_MARK, +}; +static const unsigned int msiof4_rxd_pins[] = { + /* MSIOF4_RXD */ + RCAR_GP_PIN(2, 4), +}; +static const unsigned int msiof4_rxd_mux[] = { + MSIOF4_RXD_MARK, +}; + +/* - MSIOF5 ----------------------------------------------------------------- */ +static const unsigned int msiof5_clk_pins[] = { + /* MSIOF5_SCK */ + RCAR_GP_PIN(2, 12), +}; +static const unsigned int msiof5_clk_mux[] = { + MSIOF5_SCK_MARK, +}; +static const unsigned int msiof5_sync_pins[] = { + /* MSIOF5_SYNC */ + RCAR_GP_PIN(2, 13), +}; +static const unsigned int msiof5_sync_mux[] = { + MSIOF5_SYNC_MARK, +}; +static const unsigned int msiof5_ss1_pins[] = { + /* MSIOF5_SS1 */ + RCAR_GP_PIN(2, 14), +}; +static const unsigned int msiof5_ss1_mux[] = { + MSIOF5_SS1_MARK, +}; +static const unsigned int msiof5_ss2_pins[] = { + /* MSIOF5_SS2 */ + RCAR_GP_PIN(2, 15), +}; +static const unsigned int msiof5_ss2_mux[] = { + MSIOF5_SS2_MARK, +}; +static const unsigned int msiof5_txd_pins[] = { + /* MSIOF5_TXD */ + RCAR_GP_PIN(2, 11), +}; +static const unsigned int msiof5_txd_mux[] = { + MSIOF5_TXD_MARK, +}; +static const unsigned int msiof5_rxd_pins[] = { + /* MSIOF5_RXD */ + RCAR_GP_PIN(2, 10), +}; +static const unsigned int msiof5_rxd_mux[] = { + MSIOF5_RXD_MARK, +}; + +/* - PWM0 ------------------------------------------------------------------- */ +static const unsigned int pwm0_pins[] = { + /* PWM0 */ + RCAR_GP_PIN(3, 5), +}; +static const unsigned int pwm0_mux[] = { + PWM0_MARK, +}; + +/* - PWM1 ------------------------------------------------------------------- */ +static const unsigned int pwm1_pins[] = { + /* PWM1 */ + RCAR_GP_PIN(3, 6), +}; +static const unsigned int pwm1_mux[] = { + PWM1_MARK, +}; + +/* - PWM2 ------------------------------------------------------------------- */ +static const unsigned int pwm2_pins[] = { + /* PWM2 */ + RCAR_GP_PIN(3, 7), +}; +static const unsigned int pwm2_mux[] = { + PWM2_MARK, +}; + +/* - PWM3 ------------------------------------------------------------------- */ +static const unsigned int pwm3_pins[] = { + /* PWM3 */ + RCAR_GP_PIN(3, 8), +}; +static const unsigned int pwm3_mux[] = { + PWM3_MARK, +}; + +/* - PWM4 ------------------------------------------------------------------- */ +static const unsigned int pwm4_pins[] = { + /* PWM4 */ + RCAR_GP_PIN(3, 9), +}; +static const unsigned int pwm4_mux[] = { + PWM4_MARK, +}; + +/* - QSPI0 ------------------------------------------------------------------ */ +static const unsigned int qspi0_ctrl_pins[] = { + /* SPCLK, SSL */ + RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 5), +}; +static const unsigned int qspi0_ctrl_mux[] = { + QSPI0_SPCLK_MARK, QSPI0_SSL_MARK, +}; +static const unsigned int qspi0_data2_pins[] = { + /* MOSI_IO0, MISO_IO1 */ + RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 2), +}; +static const unsigned int qspi0_data2_mux[] = { + QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, +}; +static const unsigned int qspi0_data4_pins[] = { + /* MOSI_IO0, MISO_IO1, IO2, IO3 */ + RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 2), + RCAR_GP_PIN(0, 3), RCAR_GP_PIN(0, 4), +}; +static const unsigned int qspi0_data4_mux[] = { + QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, + QSPI0_IO2_MARK, QSPI0_IO3_MARK +}; + +/* - QSPI1 ------------------------------------------------------------------ */ +static const unsigned int qspi1_ctrl_pins[] = { + /* SPCLK, SSL */ + RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 11), +}; +static const unsigned int qspi1_ctrl_mux[] = { + QSPI1_SPCLK_MARK, QSPI1_SSL_MARK, +}; +static const unsigned int qspi1_data2_pins[] = { + /* MOSI_IO0, MISO_IO1 */ + RCAR_GP_PIN(0, 7), RCAR_GP_PIN(0, 8), +}; +static const unsigned int qspi1_data2_mux[] = { + QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, +}; +static const unsigned int qspi1_data4_pins[] = { + /* MOSI_IO0, MISO_IO1, IO2, IO3 */ + RCAR_GP_PIN(0, 7), RCAR_GP_PIN(0, 8), + RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 10), +}; +static const unsigned int qspi1_data4_mux[] = { + QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, + QSPI1_IO2_MARK, QSPI1_IO3_MARK +}; + +/* - SCIF0 ------------------------------------------------------------------ */ +static const unsigned int scif0_data_pins[] = { + /* RX0, TX0 */ + RCAR_GP_PIN(1, 1), RCAR_GP_PIN(1, 5), +}; +static const unsigned int scif0_data_mux[] = { + RX0_MARK, TX0_MARK, +}; +static const unsigned int scif0_clk_pins[] = { + /* SCK0 */ + RCAR_GP_PIN(1, 2), +}; +static const unsigned int scif0_clk_mux[] = { + SCK0_MARK, +}; +static const unsigned int scif0_ctrl_pins[] = { + /* RTS0#, CTS0# */ + RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 4), +}; +static const unsigned int scif0_ctrl_mux[] = { + RTS0_N_MARK, CTS0_N_MARK, +}; + +/* - SCIF1 ------------------------------------------------------------------ */ +static const unsigned int scif1_data_a_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(1, 21), RCAR_GP_PIN(1, 22), +}; +static const unsigned int scif1_data_a_mux[] = { + RX1_A_MARK, TX1_A_MARK, +}; +static const unsigned int scif1_data_b_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(3, 2), RCAR_GP_PIN(3, 1), +}; +static const unsigned int scif1_data_b_mux[] = { + RX1_B_MARK, TX1_B_MARK, +}; +static const unsigned int scif1_clk_pins[] = { + /* SCK1 */ + RCAR_GP_PIN(1, 18), +}; +static const unsigned int scif1_clk_mux[] = { + SCK1_MARK, +}; +static const unsigned int scif1_ctrl_pins[] = { + /* RTS1#, CTS1# */ + RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 19), +}; +static const unsigned int scif1_ctrl_mux[] = { + RTS1_N_MARK, CTS1_N_MARK, +}; + +/* - SCIF3 ------------------------------------------------------------------ */ +static const unsigned int scif3_data_pins[] = { + /* RX3, TX3 */ + RCAR_GP_PIN(1, 16), RCAR_GP_PIN(1, 17), +}; +static const unsigned int scif3_data_mux[] = { + RX3_MARK, TX3_MARK, +}; +static const unsigned int scif3_clk_pins[] = { + /* SCK3 */ + RCAR_GP_PIN(1, 13), +}; +static const unsigned int scif3_clk_mux[] = { + SCK3_MARK, +}; +static const unsigned int scif3_ctrl_pins[] = { + /* RTS3#, CTS3# */ + RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), +}; +static const unsigned int scif3_ctrl_mux[] = { + RTS3_N_MARK, CTS3_N_MARK, +}; + +/* - SCIF4 ------------------------------------------------------------------ */ +static const unsigned int scif4_data_pins[] = { + /* RX4, TX4 */ + RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), +}; +static const unsigned int scif4_data_mux[] = { + RX4_MARK, TX4_MARK, +}; +static const unsigned int scif4_clk_pins[] = { + /* SCK4 */ + RCAR_GP_PIN(2, 5), +}; +static const unsigned int scif4_clk_mux[] = { + SCK4_MARK, +}; +static const unsigned int scif4_ctrl_pins[] = { + /* RTS4#, CTS4# */ + RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 6), +}; +static const unsigned int scif4_ctrl_mux[] = { + RTS4_N_MARK, CTS4_N_MARK, +}; + +/* - SCIF Clock ------------------------------------------------------------- */ +static const unsigned int scif_clk_pins[] = { + /* SCIF_CLK */ + RCAR_GP_PIN(1, 0), +}; +static const unsigned int scif_clk_mux[] = { + SCIF_CLK_MARK, +}; + +/* - TMU -------------------------------------------------------------------- */ +static const unsigned int tmu_tclk1_a_pins[] = { + /* TCLK1 */ + RCAR_GP_PIN(2, 23), +}; +static const unsigned int tmu_tclk1_a_mux[] = { + TCLK1_A_MARK, +}; +static const unsigned int tmu_tclk1_b_pins[] = { + /* TCLK1 */ + RCAR_GP_PIN(1, 23), +}; +static const unsigned int tmu_tclk1_b_mux[] = { + TCLK1_B_MARK, +}; + +static const unsigned int tmu_tclk2_a_pins[] = { + /* TCLK2 */ + RCAR_GP_PIN(2, 24), +}; +static const unsigned int tmu_tclk2_a_mux[] = { + TCLK2_A_MARK, +}; +static const unsigned int tmu_tclk2_b_pins[] = { + /* TCLK2 */ + RCAR_GP_PIN(2, 10), +}; +static const unsigned int tmu_tclk2_b_mux[] = { + TCLK2_B_MARK, +}; + +static const unsigned int tmu_tclk3_pins[] = { + /* TCLK3 */ + RCAR_GP_PIN(2, 11), +}; +static const unsigned int tmu_tclk3_mux[] = { + TCLK3_MARK, +}; + +static const unsigned int tmu_tclk4_pins[] = { + /* TCLK4 */ + RCAR_GP_PIN(2, 12), +}; +static const unsigned int tmu_tclk4_mux[] = { + TCLK4_MARK, +}; + +/* - TPU ------------------------------------------------------------------- */ +static const unsigned int tpu_to0_pins[] = { + /* TPU0TO0 */ + RCAR_GP_PIN(2, 21), +}; +static const unsigned int tpu_to0_mux[] = { + TPU0TO0_MARK, +}; +static const unsigned int tpu_to1_pins[] = { + /* TPU0TO1 */ + RCAR_GP_PIN(2, 22), +}; +static const unsigned int tpu_to1_mux[] = { + TPU0TO1_MARK, +}; +static const unsigned int tpu_to2_pins[] = { + /* TPU0TO2 */ + RCAR_GP_PIN(3, 5), +}; +static const unsigned int tpu_to2_mux[] = { + TPU0TO2_MARK, +}; +static const unsigned int tpu_to3_pins[] = { + /* TPU0TO3 */ + RCAR_GP_PIN(3, 6), +}; +static const unsigned int tpu_to3_mux[] = { + TPU0TO3_MARK, +}; + +static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(avb0_link), + SH_PFC_PIN_GROUP(avb0_magic), + SH_PFC_PIN_GROUP(avb0_phy_int), + SH_PFC_PIN_GROUP(avb0_mdio), + SH_PFC_PIN_GROUP(avb0_rgmii), + SH_PFC_PIN_GROUP(avb0_txcrefclk), + SH_PFC_PIN_GROUP(avb0_avtp_pps), + SH_PFC_PIN_GROUP(avb0_avtp_capture), + SH_PFC_PIN_GROUP(avb0_avtp_match), + + SH_PFC_PIN_GROUP(avb1_link), + SH_PFC_PIN_GROUP(avb1_magic), + SH_PFC_PIN_GROUP(avb1_phy_int), + SH_PFC_PIN_GROUP(avb1_mdio), + SH_PFC_PIN_GROUP(avb1_rgmii), + SH_PFC_PIN_GROUP(avb1_txcrefclk), + SH_PFC_PIN_GROUP(avb1_avtp_pps), + SH_PFC_PIN_GROUP(avb1_avtp_capture), + SH_PFC_PIN_GROUP(avb1_avtp_match), + + SH_PFC_PIN_GROUP(avb2_link), + SH_PFC_PIN_GROUP(avb2_magic), + SH_PFC_PIN_GROUP(avb2_phy_int), + SH_PFC_PIN_GROUP(avb2_mdio), + SH_PFC_PIN_GROUP(avb2_rgmii), + SH_PFC_PIN_GROUP(avb2_txcrefclk), + SH_PFC_PIN_GROUP(avb2_avtp_pps), + SH_PFC_PIN_GROUP(avb2_avtp_capture), + SH_PFC_PIN_GROUP(avb2_avtp_match), + + SH_PFC_PIN_GROUP(avb3_link), + SH_PFC_PIN_GROUP(avb3_magic), + SH_PFC_PIN_GROUP(avb3_phy_int), + SH_PFC_PIN_GROUP(avb3_mdio), + SH_PFC_PIN_GROUP(avb3_rgmii), + SH_PFC_PIN_GROUP(avb3_txcrefclk), + SH_PFC_PIN_GROUP(avb3_avtp_pps), + SH_PFC_PIN_GROUP(avb3_avtp_capture), + SH_PFC_PIN_GROUP(avb3_avtp_match), + + SH_PFC_PIN_GROUP(avb4_link), + SH_PFC_PIN_GROUP(avb4_magic), + SH_PFC_PIN_GROUP(avb4_phy_int), + SH_PFC_PIN_GROUP(avb4_mdio), + SH_PFC_PIN_GROUP(avb4_rgmii), + SH_PFC_PIN_GROUP(avb4_txcrefclk), + SH_PFC_PIN_GROUP(avb4_avtp_pps), + SH_PFC_PIN_GROUP(avb4_avtp_capture), + SH_PFC_PIN_GROUP(avb4_avtp_match), + + SH_PFC_PIN_GROUP(avb5_link), + SH_PFC_PIN_GROUP(avb5_magic), + SH_PFC_PIN_GROUP(avb5_phy_int), + SH_PFC_PIN_GROUP(avb5_mdio), + SH_PFC_PIN_GROUP(avb5_rgmii), + SH_PFC_PIN_GROUP(avb5_txcrefclk), + SH_PFC_PIN_GROUP(avb5_avtp_pps), + SH_PFC_PIN_GROUP(avb5_avtp_capture), + SH_PFC_PIN_GROUP(avb5_avtp_match), + + SH_PFC_PIN_GROUP(canfd0_data), + SH_PFC_PIN_GROUP(canfd1_data), + SH_PFC_PIN_GROUP(canfd2_data), + SH_PFC_PIN_GROUP(canfd3_data), + SH_PFC_PIN_GROUP(canfd4_data), + SH_PFC_PIN_GROUP(canfd5_data), + SH_PFC_PIN_GROUP(canfd6_data), + SH_PFC_PIN_GROUP(canfd7_data), + SH_PFC_PIN_GROUP(can_clk), + + SH_PFC_PIN_GROUP(du_rgb888), + SH_PFC_PIN_GROUP(du_clk_out), + SH_PFC_PIN_GROUP(du_sync), + SH_PFC_PIN_GROUP(du_oddf), + + SH_PFC_PIN_GROUP(hscif0_data), + SH_PFC_PIN_GROUP(hscif0_clk), + SH_PFC_PIN_GROUP(hscif0_ctrl), + SH_PFC_PIN_GROUP(hscif1_data), + SH_PFC_PIN_GROUP(hscif1_clk), + SH_PFC_PIN_GROUP(hscif1_ctrl), + SH_PFC_PIN_GROUP(hscif2_data), + SH_PFC_PIN_GROUP(hscif2_clk), + SH_PFC_PIN_GROUP(hscif2_ctrl), + SH_PFC_PIN_GROUP(hscif3_data), + SH_PFC_PIN_GROUP(hscif3_clk), + SH_PFC_PIN_GROUP(hscif3_ctrl), + + SH_PFC_PIN_GROUP(i2c0), + SH_PFC_PIN_GROUP(i2c1), + SH_PFC_PIN_GROUP(i2c2), + SH_PFC_PIN_GROUP(i2c3), + SH_PFC_PIN_GROUP(i2c4), + SH_PFC_PIN_GROUP(i2c5), + SH_PFC_PIN_GROUP(i2c6), + + SH_PFC_PIN_GROUP(intc_ex_irq0), + SH_PFC_PIN_GROUP(intc_ex_irq1), + SH_PFC_PIN_GROUP(intc_ex_irq2), + SH_PFC_PIN_GROUP(intc_ex_irq3), + SH_PFC_PIN_GROUP(intc_ex_irq4), + SH_PFC_PIN_GROUP(intc_ex_irq5), + + SH_PFC_PIN_GROUP(mmc_data1), + SH_PFC_PIN_GROUP(mmc_data4), + SH_PFC_PIN_GROUP(mmc_data8), + SH_PFC_PIN_GROUP(mmc_ctrl), + SH_PFC_PIN_GROUP(mmc_cd), + SH_PFC_PIN_GROUP(mmc_wp), + SH_PFC_PIN_GROUP(mmc_ds), + + SH_PFC_PIN_GROUP(msiof0_clk), + SH_PFC_PIN_GROUP(msiof0_sync), + SH_PFC_PIN_GROUP(msiof0_ss1), + SH_PFC_PIN_GROUP(msiof0_ss2), + SH_PFC_PIN_GROUP(msiof0_txd), + SH_PFC_PIN_GROUP(msiof0_rxd), + SH_PFC_PIN_GROUP(msiof1_clk), + SH_PFC_PIN_GROUP(msiof1_sync), + SH_PFC_PIN_GROUP(msiof1_ss1), + SH_PFC_PIN_GROUP(msiof1_ss2), + SH_PFC_PIN_GROUP(msiof1_txd), + SH_PFC_PIN_GROUP(msiof1_rxd), + SH_PFC_PIN_GROUP(msiof2_clk), + SH_PFC_PIN_GROUP(msiof2_sync), + SH_PFC_PIN_GROUP(msiof2_ss1), + SH_PFC_PIN_GROUP(msiof2_ss2), + SH_PFC_PIN_GROUP(msiof2_txd), + SH_PFC_PIN_GROUP(msiof2_rxd), + SH_PFC_PIN_GROUP(msiof3_clk), + SH_PFC_PIN_GROUP(msiof3_sync), + SH_PFC_PIN_GROUP(msiof3_ss1), + SH_PFC_PIN_GROUP(msiof3_ss2), + SH_PFC_PIN_GROUP(msiof3_txd), + SH_PFC_PIN_GROUP(msiof3_rxd), + SH_PFC_PIN_GROUP(msiof4_clk), + SH_PFC_PIN_GROUP(msiof4_sync), + SH_PFC_PIN_GROUP(msiof4_ss1), + SH_PFC_PIN_GROUP(msiof4_ss2), + SH_PFC_PIN_GROUP(msiof4_txd), + SH_PFC_PIN_GROUP(msiof4_rxd), + SH_PFC_PIN_GROUP(msiof5_clk), + SH_PFC_PIN_GROUP(msiof5_sync), + SH_PFC_PIN_GROUP(msiof5_ss1), + SH_PFC_PIN_GROUP(msiof5_ss2), + SH_PFC_PIN_GROUP(msiof5_txd), + SH_PFC_PIN_GROUP(msiof5_rxd), + + SH_PFC_PIN_GROUP(pwm0), + SH_PFC_PIN_GROUP(pwm1), + SH_PFC_PIN_GROUP(pwm2), + SH_PFC_PIN_GROUP(pwm3), + SH_PFC_PIN_GROUP(pwm4), + + SH_PFC_PIN_GROUP(qspi0_ctrl), + SH_PFC_PIN_GROUP(qspi0_data2), + SH_PFC_PIN_GROUP(qspi0_data4), + SH_PFC_PIN_GROUP(qspi1_ctrl), + SH_PFC_PIN_GROUP(qspi1_data2), + SH_PFC_PIN_GROUP(qspi1_data4), + + SH_PFC_PIN_GROUP(scif0_data), + SH_PFC_PIN_GROUP(scif0_clk), + SH_PFC_PIN_GROUP(scif0_ctrl), + SH_PFC_PIN_GROUP(scif1_data_a), + SH_PFC_PIN_GROUP(scif1_data_b), + SH_PFC_PIN_GROUP(scif1_clk), + SH_PFC_PIN_GROUP(scif1_ctrl), + SH_PFC_PIN_GROUP(scif3_data), + SH_PFC_PIN_GROUP(scif3_clk), + SH_PFC_PIN_GROUP(scif3_ctrl), + SH_PFC_PIN_GROUP(scif4_data), + SH_PFC_PIN_GROUP(scif4_clk), + SH_PFC_PIN_GROUP(scif4_ctrl), + SH_PFC_PIN_GROUP(scif_clk), + + SH_PFC_PIN_GROUP(tmu_tclk1_a), + SH_PFC_PIN_GROUP(tmu_tclk1_b), + SH_PFC_PIN_GROUP(tmu_tclk2_a), + SH_PFC_PIN_GROUP(tmu_tclk2_b), + SH_PFC_PIN_GROUP(tmu_tclk3), + SH_PFC_PIN_GROUP(tmu_tclk4), + + SH_PFC_PIN_GROUP(tpu_to0), + SH_PFC_PIN_GROUP(tpu_to1), + SH_PFC_PIN_GROUP(tpu_to2), + SH_PFC_PIN_GROUP(tpu_to3), +}; + +static const char * const avb0_groups[] = { + "avb0_link", + "avb0_magic", + "avb0_phy_int", + "avb0_mdio", + "avb0_rgmii", + "avb0_txcrefclk", + "avb0_avtp_pps", + "avb0_avtp_capture", + "avb0_avtp_match", +}; + +static const char * const avb1_groups[] = { + "avb1_link", + "avb1_magic", + "avb1_phy_int", + "avb1_mdio", + "avb1_rgmii", + "avb1_txcrefclk", + "avb1_avtp_pps", + "avb1_avtp_capture", + "avb1_avtp_match", +}; + +static const char * const avb2_groups[] = { + "avb2_link", + "avb2_magic", + "avb2_phy_int", + "avb2_mdio", + "avb2_rgmii", + "avb2_txcrefclk", + "avb2_avtp_pps", + "avb2_avtp_capture", + "avb2_avtp_match", +}; + +static const char * const avb3_groups[] = { + "avb3_link", + "avb3_magic", + "avb3_phy_int", + "avb3_mdio", + "avb3_rgmii", + "avb3_txcrefclk", + "avb3_avtp_pps", + "avb3_avtp_capture", + "avb3_avtp_match", +}; + +static const char * const avb4_groups[] = { + "avb4_link", + "avb4_magic", + "avb4_phy_int", + "avb4_mdio", + "avb4_rgmii", + "avb4_txcrefclk", + "avb4_avtp_pps", + "avb4_avtp_capture", + "avb4_avtp_match", +}; + +static const char * const avb5_groups[] = { + "avb5_link", + "avb5_magic", + "avb5_phy_int", + "avb5_mdio", + "avb5_rgmii", + "avb5_txcrefclk", + "avb5_avtp_pps", + "avb5_avtp_capture", + "avb5_avtp_match", +}; + +static const char * const canfd0_groups[] = { + "canfd0_data", +}; + +static const char * const canfd1_groups[] = { + "canfd1_data", +}; + +static const char * const canfd2_groups[] = { + "canfd2_data", +}; + +static const char * const canfd3_groups[] = { + "canfd3_data", +}; + +static const char * const canfd4_groups[] = { + "canfd4_data", +}; + +static const char * const canfd5_groups[] = { + "canfd5_data", +}; + +static const char * const canfd6_groups[] = { + "canfd6_data", +}; + +static const char * const canfd7_groups[] = { + "canfd7_data", +}; + +static const char * const can_clk_groups[] = { + "can_clk", +}; + +static const char * const du_groups[] = { + "du_rgb888", + "du_clk_out", + "du_sync", + "du_oddf", +}; + +static const char * const hscif0_groups[] = { + "hscif0_data", + "hscif0_clk", + "hscif0_ctrl", +}; + +static const char * const hscif1_groups[] = { + "hscif1_data", + "hscif1_clk", + "hscif1_ctrl", +}; + +static const char * const hscif2_groups[] = { + "hscif2_data", + "hscif2_clk", + "hscif2_ctrl", +}; + +static const char * const hscif3_groups[] = { + "hscif3_data", + "hscif3_clk", + "hscif3_ctrl", +}; + +static const char * const i2c0_groups[] = { + "i2c0", +}; + +static const char * const i2c1_groups[] = { + "i2c1", +}; + +static const char * const i2c2_groups[] = { + "i2c2", +}; + +static const char * const i2c3_groups[] = { + "i2c3", +}; + +static const char * const i2c4_groups[] = { + "i2c4", +}; + +static const char * const i2c5_groups[] = { + "i2c5", +}; + +static const char * const i2c6_groups[] = { + "i2c6", +}; + +static const char * const intc_ex_groups[] = { + "intc_ex_irq0", + "intc_ex_irq1", + "intc_ex_irq2", + "intc_ex_irq3", + "intc_ex_irq4", + "intc_ex_irq5", +}; + +static const char * const mmc_groups[] = { + "mmc_data1", + "mmc_data4", + "mmc_data8", + "mmc_ctrl", + "mmc_cd", + "mmc_wp", + "mmc_ds", +}; + +static const char * const msiof0_groups[] = { + "msiof0_clk", + "msiof0_sync", + "msiof0_ss1", + "msiof0_ss2", + "msiof0_txd", + "msiof0_rxd", +}; + +static const char * const msiof1_groups[] = { + "msiof1_clk", + "msiof1_sync", + "msiof1_ss1", + "msiof1_ss2", + "msiof1_txd", + "msiof1_rxd", +}; + +static const char * const msiof2_groups[] = { + "msiof2_clk", + "msiof2_sync", + "msiof2_ss1", + "msiof2_ss2", + "msiof2_txd", + "msiof2_rxd", +}; + +static const char * const msiof3_groups[] = { + "msiof3_clk", + "msiof3_sync", + "msiof3_ss1", + "msiof3_ss2", + "msiof3_txd", + "msiof3_rxd", +}; + +static const char * const msiof4_groups[] = { + "msiof4_clk", + "msiof4_sync", + "msiof4_ss1", + "msiof4_ss2", + "msiof4_txd", + "msiof4_rxd", +}; + +static const char * const msiof5_groups[] = { + "msiof5_clk", + "msiof5_sync", + "msiof5_ss1", + "msiof5_ss2", + "msiof5_txd", + "msiof5_rxd", +}; + +static const char * const pwm0_groups[] = { + "pwm0", +}; + +static const char * const pwm1_groups[] = { + "pwm1", +}; + +static const char * const pwm2_groups[] = { + "pwm2", +}; + +static const char * const pwm3_groups[] = { + "pwm3", +}; + +static const char * const pwm4_groups[] = { + "pwm4", +}; + +static const char * const qspi0_groups[] = { + "qspi0_ctrl", + "qspi0_data2", + "qspi0_data4", +}; + +static const char * const qspi1_groups[] = { + "qspi1_ctrl", + "qspi1_data2", + "qspi1_data4", +}; + +static const char * const scif0_groups[] = { + "scif0_data", + "scif0_clk", + "scif0_ctrl", +}; + +static const char * const scif1_groups[] = { + "scif1_data_a", + "scif1_data_b", + "scif1_clk", + "scif1_ctrl", +}; + +static const char * const scif3_groups[] = { + "scif3_data", + "scif3_clk", + "scif3_ctrl", +}; + +static const char * const scif4_groups[] = { + "scif4_data", + "scif4_clk", + "scif4_ctrl", +}; + +static const char * const scif_clk_groups[] = { + "scif_clk", +}; + +static const char * const tmu_groups[] = { + "tmu_tclk1_a", + "tmu_tclk1_b", + "tmu_tclk2_a", + "tmu_tclk2_b", + "tmu_tclk3", + "tmu_tclk4", +}; + +static const char * const tpu_groups[] = { + "tpu_to0", + "tpu_to1", + "tpu_to2", + "tpu_to3", +}; + +static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(avb0), + SH_PFC_FUNCTION(avb1), + SH_PFC_FUNCTION(avb2), + SH_PFC_FUNCTION(avb3), + SH_PFC_FUNCTION(avb4), + SH_PFC_FUNCTION(avb5), + + SH_PFC_FUNCTION(canfd0), + SH_PFC_FUNCTION(canfd1), + SH_PFC_FUNCTION(canfd2), + SH_PFC_FUNCTION(canfd3), + SH_PFC_FUNCTION(canfd4), + SH_PFC_FUNCTION(canfd5), + SH_PFC_FUNCTION(canfd6), + SH_PFC_FUNCTION(canfd7), + SH_PFC_FUNCTION(can_clk), + + SH_PFC_FUNCTION(du), + + SH_PFC_FUNCTION(hscif0), + SH_PFC_FUNCTION(hscif1), + SH_PFC_FUNCTION(hscif2), + SH_PFC_FUNCTION(hscif3), + + SH_PFC_FUNCTION(i2c0), + SH_PFC_FUNCTION(i2c1), + SH_PFC_FUNCTION(i2c2), + SH_PFC_FUNCTION(i2c3), + SH_PFC_FUNCTION(i2c4), + SH_PFC_FUNCTION(i2c5), + SH_PFC_FUNCTION(i2c6), + + SH_PFC_FUNCTION(intc_ex), + + SH_PFC_FUNCTION(mmc), + + SH_PFC_FUNCTION(msiof0), + SH_PFC_FUNCTION(msiof1), + SH_PFC_FUNCTION(msiof2), + SH_PFC_FUNCTION(msiof3), + SH_PFC_FUNCTION(msiof4), + SH_PFC_FUNCTION(msiof5), + + SH_PFC_FUNCTION(pwm0), + SH_PFC_FUNCTION(pwm1), + SH_PFC_FUNCTION(pwm2), + SH_PFC_FUNCTION(pwm3), + SH_PFC_FUNCTION(pwm4), + + SH_PFC_FUNCTION(qspi0), + SH_PFC_FUNCTION(qspi1), + + SH_PFC_FUNCTION(scif0), + SH_PFC_FUNCTION(scif1), + SH_PFC_FUNCTION(scif3), + SH_PFC_FUNCTION(scif4), + SH_PFC_FUNCTION(scif_clk), + + SH_PFC_FUNCTION(tmu), + + SH_PFC_FUNCTION(tpu), +}; + +static const struct pinmux_cfg_reg pinmux_config_regs[] = { +#define F_(x, y) FN_##y +#define FM(x) FN_##x + { PINMUX_CFG_REG("GPSR0", 0xe6058040, 32, 1, GROUP( + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_0_27_FN, GPSR0_27, + GP_0_26_FN, GPSR0_26, + GP_0_25_FN, GPSR0_25, + GP_0_24_FN, GPSR0_24, + GP_0_23_FN, GPSR0_23, + GP_0_22_FN, GPSR0_22, + GP_0_21_FN, GPSR0_21, + GP_0_20_FN, GPSR0_20, + GP_0_19_FN, GPSR0_19, + GP_0_18_FN, GPSR0_18, + GP_0_17_FN, GPSR0_17, + GP_0_16_FN, GPSR0_16, + GP_0_15_FN, GPSR0_15, + GP_0_14_FN, GPSR0_14, + GP_0_13_FN, GPSR0_13, + GP_0_12_FN, GPSR0_12, + GP_0_11_FN, GPSR0_11, + GP_0_10_FN, GPSR0_10, + GP_0_9_FN, GPSR0_9, + GP_0_8_FN, GPSR0_8, + GP_0_7_FN, GPSR0_7, + GP_0_6_FN, GPSR0_6, + GP_0_5_FN, GPSR0_5, + GP_0_4_FN, GPSR0_4, + GP_0_3_FN, GPSR0_3, + GP_0_2_FN, GPSR0_2, + GP_0_1_FN, GPSR0_1, + GP_0_0_FN, GPSR0_0, )) + }, + { PINMUX_CFG_REG("GPSR1", 0xe6050040, 32, 1, GROUP( + 0, 0, + GP_1_30_FN, GPSR1_30, + GP_1_29_FN, GPSR1_29, + GP_1_28_FN, GPSR1_28, + GP_1_27_FN, GPSR1_27, + GP_1_26_FN, GPSR1_26, + GP_1_25_FN, GPSR1_25, + GP_1_24_FN, GPSR1_24, + GP_1_23_FN, GPSR1_23, + GP_1_22_FN, GPSR1_22, + GP_1_21_FN, GPSR1_21, + GP_1_20_FN, GPSR1_20, + GP_1_19_FN, GPSR1_19, + GP_1_18_FN, GPSR1_18, + GP_1_17_FN, GPSR1_17, + GP_1_16_FN, GPSR1_16, + GP_1_15_FN, GPSR1_15, + GP_1_14_FN, GPSR1_14, + GP_1_13_FN, GPSR1_13, + GP_1_12_FN, GPSR1_12, + GP_1_11_FN, GPSR1_11, + GP_1_10_FN, GPSR1_10, + GP_1_9_FN, GPSR1_9, + GP_1_8_FN, GPSR1_8, + GP_1_7_FN, GPSR1_7, + GP_1_6_FN, GPSR1_6, + GP_1_5_FN, GPSR1_5, + GP_1_4_FN, GPSR1_4, + GP_1_3_FN, GPSR1_3, + GP_1_2_FN, GPSR1_2, + GP_1_1_FN, GPSR1_1, + GP_1_0_FN, GPSR1_0, )) + }, + { PINMUX_CFG_REG("GPSR2", 0xe6050840, 32, 1, GROUP( + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_2_24_FN, GPSR2_24, + GP_2_23_FN, GPSR2_23, + GP_2_22_FN, GPSR2_22, + GP_2_21_FN, GPSR2_21, + GP_2_20_FN, GPSR2_20, + GP_2_19_FN, GPSR2_19, + GP_2_18_FN, GPSR2_18, + GP_2_17_FN, GPSR2_17, + GP_2_16_FN, GPSR2_16, + GP_2_15_FN, GPSR2_15, + GP_2_14_FN, GPSR2_14, + GP_2_13_FN, GPSR2_13, + GP_2_12_FN, GPSR2_12, + GP_2_11_FN, GPSR2_11, + GP_2_10_FN, GPSR2_10, + GP_2_9_FN, GPSR2_9, + GP_2_8_FN, GPSR2_8, + GP_2_7_FN, GPSR2_7, + GP_2_6_FN, GPSR2_6, + GP_2_5_FN, GPSR2_5, + GP_2_4_FN, GPSR2_4, + GP_2_3_FN, GPSR2_3, + GP_2_2_FN, GPSR2_2, + GP_2_1_FN, GPSR2_1, + GP_2_0_FN, GPSR2_0, )) + }, + { PINMUX_CFG_REG("GPSR3", 0xe6058840, 32, 1, GROUP( + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_3_16_FN, GPSR3_16, + GP_3_15_FN, GPSR3_15, + GP_3_14_FN, GPSR3_14, + GP_3_13_FN, GPSR3_13, + GP_3_12_FN, GPSR3_12, + GP_3_11_FN, GPSR3_11, + GP_3_10_FN, GPSR3_10, + GP_3_9_FN, GPSR3_9, + GP_3_8_FN, GPSR3_8, + GP_3_7_FN, GPSR3_7, + GP_3_6_FN, GPSR3_6, + GP_3_5_FN, GPSR3_5, + GP_3_4_FN, GPSR3_4, + GP_3_3_FN, GPSR3_3, + GP_3_2_FN, GPSR3_2, + GP_3_1_FN, GPSR3_1, + GP_3_0_FN, GPSR3_0, )) + }, + { PINMUX_CFG_REG("GPSR4", 0xe6060040, 32, 1, GROUP( + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_4_26_FN, GPSR4_26, + GP_4_25_FN, GPSR4_25, + GP_4_24_FN, GPSR4_24, + GP_4_23_FN, GPSR4_23, + GP_4_22_FN, GPSR4_22, + GP_4_21_FN, GPSR4_21, + GP_4_20_FN, GPSR4_20, + GP_4_19_FN, GPSR4_19, + GP_4_18_FN, GPSR4_18, + GP_4_17_FN, GPSR4_17, + GP_4_16_FN, GPSR4_16, + GP_4_15_FN, GPSR4_15, + GP_4_14_FN, GPSR4_14, + GP_4_13_FN, GPSR4_13, + GP_4_12_FN, GPSR4_12, + GP_4_11_FN, GPSR4_11, + GP_4_10_FN, GPSR4_10, + GP_4_9_FN, GPSR4_9, + GP_4_8_FN, GPSR4_8, + GP_4_7_FN, GPSR4_7, + GP_4_6_FN, GPSR4_6, + GP_4_5_FN, GPSR4_5, + GP_4_4_FN, GPSR4_4, + GP_4_3_FN, GPSR4_3, + GP_4_2_FN, GPSR4_2, + GP_4_1_FN, GPSR4_1, + GP_4_0_FN, GPSR4_0, )) + }, + { PINMUX_CFG_REG("GPSR5", 0xe6060840, 32, 1, GROUP( + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_5_20_FN, GPSR5_20, + GP_5_19_FN, GPSR5_19, + GP_5_18_FN, GPSR5_18, + GP_5_17_FN, GPSR5_17, + GP_5_16_FN, GPSR5_16, + GP_5_15_FN, GPSR5_15, + GP_5_14_FN, GPSR5_14, + GP_5_13_FN, GPSR5_13, + GP_5_12_FN, GPSR5_12, + GP_5_11_FN, GPSR5_11, + GP_5_10_FN, GPSR5_10, + GP_5_9_FN, GPSR5_9, + GP_5_8_FN, GPSR5_8, + GP_5_7_FN, GPSR5_7, + GP_5_6_FN, GPSR5_6, + GP_5_5_FN, GPSR5_5, + GP_5_4_FN, GPSR5_4, + GP_5_3_FN, GPSR5_3, + GP_5_2_FN, GPSR5_2, + GP_5_1_FN, GPSR5_1, + GP_5_0_FN, GPSR5_0, )) + }, + { PINMUX_CFG_REG("GPSR6", 0xe6068040, 32, 1, GROUP( + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_6_20_FN, GPSR6_20, + GP_6_19_FN, GPSR6_19, + GP_6_18_FN, GPSR6_18, + GP_6_17_FN, GPSR6_17, + GP_6_16_FN, GPSR6_16, + GP_6_15_FN, GPSR6_15, + GP_6_14_FN, GPSR6_14, + GP_6_13_FN, GPSR6_13, + GP_6_12_FN, GPSR6_12, + GP_6_11_FN, GPSR6_11, + GP_6_10_FN, GPSR6_10, + GP_6_9_FN, GPSR6_9, + GP_6_8_FN, GPSR6_8, + GP_6_7_FN, GPSR6_7, + GP_6_6_FN, GPSR6_6, + GP_6_5_FN, GPSR6_5, + GP_6_4_FN, GPSR6_4, + GP_6_3_FN, GPSR6_3, + GP_6_2_FN, GPSR6_2, + GP_6_1_FN, GPSR6_1, + GP_6_0_FN, GPSR6_0, )) + }, + { PINMUX_CFG_REG("GPSR7", 0xe6068840, 32, 1, GROUP( + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_7_20_FN, GPSR7_20, + GP_7_19_FN, GPSR7_19, + GP_7_18_FN, GPSR7_18, + GP_7_17_FN, GPSR7_17, + GP_7_16_FN, GPSR7_16, + GP_7_15_FN, GPSR7_15, + GP_7_14_FN, GPSR7_14, + GP_7_13_FN, GPSR7_13, + GP_7_12_FN, GPSR7_12, + GP_7_11_FN, GPSR7_11, + GP_7_10_FN, GPSR7_10, + GP_7_9_FN, GPSR7_9, + GP_7_8_FN, GPSR7_8, + GP_7_7_FN, GPSR7_7, + GP_7_6_FN, GPSR7_6, + GP_7_5_FN, GPSR7_5, + GP_7_4_FN, GPSR7_4, + GP_7_3_FN, GPSR7_3, + GP_7_2_FN, GPSR7_2, + GP_7_1_FN, GPSR7_1, + GP_7_0_FN, GPSR7_0, )) + }, + { PINMUX_CFG_REG("GPSR8", 0xe6069040, 32, 1, GROUP( + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_8_20_FN, GPSR8_20, + GP_8_19_FN, GPSR8_19, + GP_8_18_FN, GPSR8_18, + GP_8_17_FN, GPSR8_17, + GP_8_16_FN, GPSR8_16, + GP_8_15_FN, GPSR8_15, + GP_8_14_FN, GPSR8_14, + GP_8_13_FN, GPSR8_13, + GP_8_12_FN, GPSR8_12, + GP_8_11_FN, GPSR8_11, + GP_8_10_FN, GPSR8_10, + GP_8_9_FN, GPSR8_9, + GP_8_8_FN, GPSR8_8, + GP_8_7_FN, GPSR8_7, + GP_8_6_FN, GPSR8_6, + GP_8_5_FN, GPSR8_5, + GP_8_4_FN, GPSR8_4, + GP_8_3_FN, GPSR8_3, + GP_8_2_FN, GPSR8_2, + GP_8_1_FN, GPSR8_1, + GP_8_0_FN, GPSR8_0, )) + }, + { PINMUX_CFG_REG("GPSR9", 0xe6069840, 32, 1, GROUP( + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_9_20_FN, GPSR9_20, + GP_9_19_FN, GPSR9_19, + GP_9_18_FN, GPSR9_18, + GP_9_17_FN, GPSR9_17, + GP_9_16_FN, GPSR9_16, + GP_9_15_FN, GPSR9_15, + GP_9_14_FN, GPSR9_14, + GP_9_13_FN, GPSR9_13, + GP_9_12_FN, GPSR9_12, + GP_9_11_FN, GPSR9_11, + GP_9_10_FN, GPSR9_10, + GP_9_9_FN, GPSR9_9, + GP_9_8_FN, GPSR9_8, + GP_9_7_FN, GPSR9_7, + GP_9_6_FN, GPSR9_6, + GP_9_5_FN, GPSR9_5, + GP_9_4_FN, GPSR9_4, + GP_9_3_FN, GPSR9_3, + GP_9_2_FN, GPSR9_2, + GP_9_1_FN, GPSR9_1, + GP_9_0_FN, GPSR9_0, )) + }, +#undef F_ +#undef FM + +#define F_(x, y) x, +#define FM(x) FN_##x, + { PINMUX_CFG_REG("IP0SR1", 0xe6050060, 32, 4, GROUP( + IP0SR1_31_28 + IP0SR1_27_24 + IP0SR1_23_20 + IP0SR1_19_16 + IP0SR1_15_12 + IP0SR1_11_8 + IP0SR1_7_4 + IP0SR1_3_0)) + }, + { PINMUX_CFG_REG("IP1SR1", 0xe6050064, 32, 4, GROUP( + IP1SR1_31_28 + IP1SR1_27_24 + IP1SR1_23_20 + IP1SR1_19_16 + IP1SR1_15_12 + IP1SR1_11_8 + IP1SR1_7_4 + IP1SR1_3_0)) + }, + { PINMUX_CFG_REG("IP2SR1", 0xe6050068, 32, 4, GROUP( + IP2SR1_31_28 + IP2SR1_27_24 + IP2SR1_23_20 + IP2SR1_19_16 + IP2SR1_15_12 + IP2SR1_11_8 + IP2SR1_7_4 + IP2SR1_3_0)) + }, + { PINMUX_CFG_REG("IP3SR1", 0xe605006c, 32, 4, GROUP( + IP3SR1_31_28 + IP3SR1_27_24 + IP3SR1_23_20 + IP3SR1_19_16 + IP3SR1_15_12 + IP3SR1_11_8 + IP3SR1_7_4 + IP3SR1_3_0)) + }, + { PINMUX_CFG_REG("IP0SR2", 0xe6050860, 32, 4, GROUP( + IP0SR2_31_28 + IP0SR2_27_24 + IP0SR2_23_20 + IP0SR2_19_16 + IP0SR2_15_12 + IP0SR2_11_8 + IP0SR2_7_4 + IP0SR2_3_0)) + }, + { PINMUX_CFG_REG("IP1SR2", 0xe6050864, 32, 4, GROUP( + IP1SR2_31_28 + IP1SR2_27_24 + IP1SR2_23_20 + IP1SR2_19_16 + IP1SR2_15_12 + IP1SR2_11_8 + IP1SR2_7_4 + IP1SR2_3_0)) + }, + { PINMUX_CFG_REG("IP2SR2", 0xe6050868, 32, 4, GROUP( + IP2SR2_31_28 + IP2SR2_27_24 + IP2SR2_23_20 + IP2SR2_19_16 + IP2SR2_15_12 + IP2SR2_11_8 + IP2SR2_7_4 + IP2SR2_3_0)) + }, + { PINMUX_CFG_REG("IP0SR3", 0xe6058860, 32, 4, GROUP( + IP0SR3_31_28 + IP0SR3_27_24 + IP0SR3_23_20 + IP0SR3_19_16 + IP0SR3_15_12 + IP0SR3_11_8 + IP0SR3_7_4 + IP0SR3_3_0)) + }, + { PINMUX_CFG_REG("IP1SR3", 0xe6058864, 32, 4, GROUP( + IP1SR3_31_28 + IP1SR3_27_24 + IP1SR3_23_20 + IP1SR3_19_16 + IP1SR3_15_12 + IP1SR3_11_8 + IP1SR3_7_4 + IP1SR3_3_0)) + }, + { PINMUX_CFG_REG("IP0SR4", 0xe6060060, 32, 4, GROUP( + IP0SR4_31_28 + IP0SR4_27_24 + IP0SR4_23_20 + IP0SR4_19_16 + IP0SR4_15_12 + IP0SR4_11_8 + IP0SR4_7_4 + IP0SR4_3_0)) + }, + { PINMUX_CFG_REG("IP1SR4", 0xe6060064, 32, 4, GROUP( + IP1SR4_31_28 + IP1SR4_27_24 + IP1SR4_23_20 + IP1SR4_19_16 + IP1SR4_15_12 + IP1SR4_11_8 + IP1SR4_7_4 + IP1SR4_3_0)) + }, + { PINMUX_CFG_REG("IP2SR4", 0xe6060068, 32, 4, GROUP( + IP2SR4_31_28 + IP2SR4_27_24 + IP2SR4_23_20 + IP2SR4_19_16 + IP2SR4_15_12 + IP2SR4_11_8 + IP2SR4_7_4 + IP2SR4_3_0)) + }, + { PINMUX_CFG_REG("IP0SR5", 0xe6060860, 32, 4, GROUP( + IP0SR5_31_28 + IP0SR5_27_24 + IP0SR5_23_20 + IP0SR5_19_16 + IP0SR5_15_12 + IP0SR5_11_8 + IP0SR5_7_4 + IP0SR5_3_0)) + }, + { PINMUX_CFG_REG("IP1SR5", 0xe6060864, 32, 4, GROUP( + IP1SR5_31_28 + IP1SR5_27_24 + IP1SR5_23_20 + IP1SR5_19_16 + IP1SR5_15_12 + IP1SR5_11_8 + IP1SR5_7_4 + IP1SR5_3_0)) + }, + { PINMUX_CFG_REG("IP2SR5", 0xe6060868, 32, 4, GROUP( + IP2SR5_31_28 + IP2SR5_27_24 + IP2SR5_23_20 + IP2SR5_19_16 + IP2SR5_15_12 + IP2SR5_11_8 + IP2SR5_7_4 + IP2SR5_3_0)) + }, +#undef F_ +#undef FM + +#define F_(x, y) x, +#define FM(x) FN_##x, + { PINMUX_CFG_REG_VAR("MOD_SEL2", 0xe6050900, 32, + GROUP(4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1), + GROUP( + /* RESERVED 31, 30, 29, 28 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* RESERVED 27, 26, 25, 24 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* RESERVED 23, 22, 21, 20 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* RESERVED 19, 18, 17, 16 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + MOD_SEL2_14_15 + MOD_SEL2_12_13 + MOD_SEL2_10_11 + MOD_SEL2_8_9 + MOD_SEL2_6_7 + MOD_SEL2_4_5 + MOD_SEL2_2_3 + 0, 0, + 0, 0, )) + }, + { }, +}; + +static const struct pinmux_drive_reg pinmux_drive_regs[] = { + { PINMUX_DRIVE_REG("DRV0CTRL0", 0xe6058080) { + { RCAR_GP_PIN(0, 7), 28, 2 }, /* QSPI1_MOSI_IO0 */ + { RCAR_GP_PIN(0, 6), 24, 2 }, /* QSPI1_SPCLK */ + { RCAR_GP_PIN(0, 5), 20, 2 }, /* QSPI0_SSL */ + { RCAR_GP_PIN(0, 4), 16, 2 }, /* QSPI0_IO3 */ + { RCAR_GP_PIN(0, 3), 12, 2 }, /* QSPI0_IO2 */ + { RCAR_GP_PIN(0, 2), 8, 2 }, /* QSPI0_MISO_IO1 */ + { RCAR_GP_PIN(0, 1), 4, 2 }, /* QSPI0_MOSI_IO0 */ + { RCAR_GP_PIN(0, 0), 0, 2 }, /* QSPI0_SPCLK */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL0", 0xe6058084) { + { RCAR_GP_PIN(0, 15), 28, 3 }, /* SD_WP */ + { RCAR_GP_PIN(0, 14), 24, 2 }, /* RPC_INT_N */ + { RCAR_GP_PIN(0, 13), 20, 2 }, /* RPC_WP_N */ + { RCAR_GP_PIN(0, 12), 16, 2 }, /* RPC_RESET_N */ + { RCAR_GP_PIN(0, 11), 12, 2 }, /* QSPI1_SSL */ + { RCAR_GP_PIN(0, 10), 8, 2 }, /* QSPI1_IO3 */ + { RCAR_GP_PIN(0, 9), 4, 2 }, /* QSPI1_IO2 */ + { RCAR_GP_PIN(0, 8), 0, 2 }, /* QSPI1_MISO_IO1 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL0", 0xe6058088) { + { RCAR_GP_PIN(0, 23), 28, 3 }, /* MMC_SD_CLK */ + { RCAR_GP_PIN(0, 22), 24, 3 }, /* MMC_SD_D3 */ + { RCAR_GP_PIN(0, 21), 20, 3 }, /* MMC_SD_D2 */ + { RCAR_GP_PIN(0, 20), 16, 3 }, /* MMC_SD_D1 */ + { RCAR_GP_PIN(0, 19), 12, 3 }, /* MMC_SD_D0 */ + { RCAR_GP_PIN(0, 18), 8, 3 }, /* MMC_SD_CMD */ + { RCAR_GP_PIN(0, 17), 4, 3 }, /* MMC_DS */ + { RCAR_GP_PIN(0, 16), 0, 3 }, /* SD_CD */ + } }, + { PINMUX_DRIVE_REG("DRV3CTRL0", 0xe605808c) { + { RCAR_GP_PIN(0, 27), 12, 3 }, /* MMC_D7 */ + { RCAR_GP_PIN(0, 26), 8, 3 }, /* MMC_D6 */ + { RCAR_GP_PIN(0, 25), 4, 3 }, /* MMC_D5 */ + { RCAR_GP_PIN(0, 24), 0, 3 }, /* MMC_D4 */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL1", 0xe6050080) { + { RCAR_GP_PIN(1, 7), 28, 3 }, /* MSIOF0_TXD */ + { RCAR_GP_PIN(1, 6), 24, 3 }, /* MSIOF0_RXD */ + { RCAR_GP_PIN(1, 5), 20, 3 }, /* HTX0 */ + { RCAR_GP_PIN(1, 4), 16, 3 }, /* HCTS0_N */ + { RCAR_GP_PIN(1, 3), 12, 3 }, /* HRTS0_N */ + { RCAR_GP_PIN(1, 2), 8, 3 }, /* HSCK0 */ + { RCAR_GP_PIN(1, 1), 4, 3 }, /* HRX0 */ + { RCAR_GP_PIN(1, 0), 0, 3 }, /* SCIF_CLK */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL1", 0xe6050084) { + { RCAR_GP_PIN(1, 15), 28, 3 }, /* MSIOF1_SYNC */ + { RCAR_GP_PIN(1, 14), 24, 3 }, /* MSIOF1_SCK */ + { RCAR_GP_PIN(1, 13), 20, 3 }, /* MSIOF1_TXD */ + { RCAR_GP_PIN(1, 12), 16, 3 }, /* MSIOF1_RXD */ + { RCAR_GP_PIN(1, 11), 12, 3 }, /* MSIOF0_SS2 */ + { RCAR_GP_PIN(1, 10), 8, 3 }, /* MSIOF0_SS1 */ + { RCAR_GP_PIN(1, 9), 4, 3 }, /* MSIOF0_SYNC */ + { RCAR_GP_PIN(1, 8), 0, 3 }, /* MSIOF0_SCK */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL1", 0xe6050088) { + { RCAR_GP_PIN(1, 23), 28, 3 }, /* MSIOF2_SS2 */ + { RCAR_GP_PIN(1, 22), 24, 3 }, /* MSIOF2_SS1 */ + { RCAR_GP_PIN(1, 21), 20, 3 }, /* MSIOF2_SYNC */ + { RCAR_GP_PIN(1, 20), 16, 3 }, /* MSIOF2_SCK */ + { RCAR_GP_PIN(1, 19), 12, 3 }, /* MSIOF2_TXD */ + { RCAR_GP_PIN(1, 18), 8, 3 }, /* MSIOF2_RXD */ + { RCAR_GP_PIN(1, 17), 4, 3 }, /* MSIOF1_SS2 */ + { RCAR_GP_PIN(1, 16), 0, 3 }, /* MSIOF1_SS1 */ + } }, + { PINMUX_DRIVE_REG("DRV3CTRL1", 0xe605008c) { + { RCAR_GP_PIN(1, 30), 24, 3 }, /* GP1_30 */ + { RCAR_GP_PIN(1, 29), 20, 3 }, /* GP1_29 */ + { RCAR_GP_PIN(1, 28), 16, 3 }, /* GP1_28 */ + { RCAR_GP_PIN(1, 27), 12, 3 }, /* IRQ3 */ + { RCAR_GP_PIN(1, 26), 8, 3 }, /* IRQ2 */ + { RCAR_GP_PIN(1, 25), 4, 3 }, /* IRQ1 */ + { RCAR_GP_PIN(1, 24), 0, 3 }, /* IRQ0 */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL2", 0xe6050880) { + { RCAR_GP_PIN(2, 7), 28, 3 }, /* GP2_07 */ + { RCAR_GP_PIN(2, 6), 24, 3 }, /* GP2_06 */ + { RCAR_GP_PIN(2, 5), 20, 3 }, /* GP2_05 */ + { RCAR_GP_PIN(2, 4), 16, 3 }, /* GP2_04 */ + { RCAR_GP_PIN(2, 3), 12, 3 }, /* GP2_03 */ + { RCAR_GP_PIN(2, 2), 8, 3 }, /* GP2_02 */ + { RCAR_GP_PIN(2, 1), 4, 2 }, /* IPC_CLKOUT */ + { RCAR_GP_PIN(2, 0), 0, 2 }, /* IPC_CLKIN */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL2", 0xe6050884) { + { RCAR_GP_PIN(2, 15), 28, 3 }, /* GP2_15 */ + { RCAR_GP_PIN(2, 14), 24, 3 }, /* GP2_14 */ + { RCAR_GP_PIN(2, 13), 20, 3 }, /* GP2_13 */ + { RCAR_GP_PIN(2, 12), 16, 3 }, /* GP2_12 */ + { RCAR_GP_PIN(2, 11), 12, 3 }, /* GP2_11 */ + { RCAR_GP_PIN(2, 10), 8, 3 }, /* GP2_10 */ + { RCAR_GP_PIN(2, 9), 4, 3 }, /* GP2_9 */ + { RCAR_GP_PIN(2, 8), 0, 3 }, /* GP2_8 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL2", 0xe6050888) { + { RCAR_GP_PIN(2, 23), 28, 3 }, /* TCLK1_A */ + { RCAR_GP_PIN(2, 22), 24, 3 }, /* TPU0TO1 */ + { RCAR_GP_PIN(2, 21), 20, 3 }, /* TPU0TO0 */ + { RCAR_GP_PIN(2, 20), 16, 3 }, /* CLK_EXTFXR */ + { RCAR_GP_PIN(2, 19), 12, 3 }, /* RXDB_EXTFXR */ + { RCAR_GP_PIN(2, 18), 8, 3 }, /* FXR_TXDB */ + { RCAR_GP_PIN(2, 17), 4, 3 }, /* RXDA_EXTFXR_A */ + { RCAR_GP_PIN(2, 16), 0, 3 }, /* FXR_TXDA_A */ + } }, + { PINMUX_DRIVE_REG("DRV3CTRL2", 0xe605088c) { + { RCAR_GP_PIN(2, 24), 0, 3 }, /* TCLK2_A */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL3", 0xe6058880) { + { RCAR_GP_PIN(3, 7), 28, 3 }, /* CANFD3_TX */ + { RCAR_GP_PIN(3, 6), 24, 3 }, /* CANFD2_RX */ + { RCAR_GP_PIN(3, 5), 20, 3 }, /* CANFD2_TX */ + { RCAR_GP_PIN(3, 4), 16, 3 }, /* CANFD1_RX */ + { RCAR_GP_PIN(3, 3), 12, 3 }, /* CANFD1_TX */ + { RCAR_GP_PIN(3, 2), 8, 3 }, /* CANFD0_RX */ + { RCAR_GP_PIN(3, 1), 4, 2 }, /* CANFD0_TX */ + { RCAR_GP_PIN(3, 0), 0, 2 }, /* CAN_CLK */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL3", 0xe6058884) { + { RCAR_GP_PIN(3, 15), 28, 3 }, /* CANFD7_TX */ + { RCAR_GP_PIN(3, 14), 24, 3 }, /* CANFD6_RX */ + { RCAR_GP_PIN(3, 13), 20, 3 }, /* CANFD6_TX */ + { RCAR_GP_PIN(3, 12), 16, 3 }, /* CANFD5_RX */ + { RCAR_GP_PIN(3, 11), 12, 3 }, /* CANFD5_TX */ + { RCAR_GP_PIN(3, 10), 8, 3 }, /* CANFD4_RX */ + { RCAR_GP_PIN(3, 9), 4, 3 }, /* CANFD4_TX*/ + { RCAR_GP_PIN(3, 8), 0, 3 }, /* CANFD3_RX */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL3", 0xe6058888) { + { RCAR_GP_PIN(3, 16), 0, 3 }, /* CANFD7_RX */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL4", 0xe6060080) { + { RCAR_GP_PIN(4, 7), 28, 3 }, /* AVB0_TXC */ + { RCAR_GP_PIN(4, 6), 24, 3 }, /* AVB0_TX_CTL */ + { RCAR_GP_PIN(4, 5), 20, 3 }, /* AVB0_RD3 */ + { RCAR_GP_PIN(4, 4), 16, 3 }, /* AVB0_RD2 */ + { RCAR_GP_PIN(4, 3), 12, 3 }, /* AVB0_RD1 */ + { RCAR_GP_PIN(4, 2), 8, 3 }, /* AVB0_RD0 */ + { RCAR_GP_PIN(4, 1), 4, 3 }, /* AVB0_RXC */ + { RCAR_GP_PIN(4, 0), 0, 3 }, /* AVB0_RX_CTL */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL4", 0xe6060084) { + { RCAR_GP_PIN(4, 15), 28, 3 }, /* AVB0_MAGIC */ + { RCAR_GP_PIN(4, 14), 24, 3 }, /* AVB0_MDC */ + { RCAR_GP_PIN(4, 13), 20, 3 }, /* AVB0_MDIO */ + { RCAR_GP_PIN(4, 12), 16, 3 }, /* AVB0_TXCREFCLK */ + { RCAR_GP_PIN(4, 11), 12, 3 }, /* AVB0_TD3 */ + { RCAR_GP_PIN(4, 10), 8, 3 }, /* AVB0_TD2 */ + { RCAR_GP_PIN(4, 9), 4, 3 }, /* AVB0_TD1*/ + { RCAR_GP_PIN(4, 8), 0, 3 }, /* AVB0_TD0 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL4", 0xe6060088) { + { RCAR_GP_PIN(4, 23), 28, 3 }, /* PCIE2_CLKREQ_N */ + { RCAR_GP_PIN(4, 22), 24, 3 }, /* PCIE1_CLKREQ_N */ + { RCAR_GP_PIN(4, 21), 20, 3 }, /* PCIE0_CLKREQ_N */ + { RCAR_GP_PIN(4, 20), 16, 3 }, /* AVB0_AVTP_PPS */ + { RCAR_GP_PIN(4, 19), 12, 3 }, /* AVB0_AVTP_CAPTURE */ + { RCAR_GP_PIN(4, 18), 8, 3 }, /* AVB0_AVTP_MATCH */ + { RCAR_GP_PIN(4, 17), 4, 3 }, /* AVB0_LINK */ + { RCAR_GP_PIN(4, 16), 0, 3 }, /* AVB0_PHY_INT */ + } }, + { PINMUX_DRIVE_REG("DRV3CTRL4", 0xe606008c) { + { RCAR_GP_PIN(4, 26), 8, 3 }, /* AVS1 */ + { RCAR_GP_PIN(4, 25), 4, 3 }, /* AVS0 */ + { RCAR_GP_PIN(4, 24), 0, 3 }, /* PCIE3_CLKREQ_N */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL5", 0xe6060880) { + { RCAR_GP_PIN(5, 7), 28, 3 }, /* AVB1_TXC */ + { RCAR_GP_PIN(5, 6), 24, 3 }, /* AVB1_TX_CTL */ + { RCAR_GP_PIN(5, 5), 20, 3 }, /* AVB1_RD3 */ + { RCAR_GP_PIN(5, 4), 16, 3 }, /* AVB1_RD2 */ + { RCAR_GP_PIN(5, 3), 12, 3 }, /* AVB1_RD1 */ + { RCAR_GP_PIN(5, 2), 8, 3 }, /* AVB1_RD0 */ + { RCAR_GP_PIN(5, 1), 4, 3 }, /* AVB1_RXC */ + { RCAR_GP_PIN(5, 0), 0, 3 }, /* AVB1_RX_CTL */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL5", 0xe6060884) { + { RCAR_GP_PIN(5, 15), 28, 3 }, /* AVB1_MAGIC */ + { RCAR_GP_PIN(5, 14), 24, 3 }, /* AVB1_MDC */ + { RCAR_GP_PIN(5, 13), 20, 3 }, /* AVB1_MDIO */ + { RCAR_GP_PIN(5, 12), 16, 3 }, /* AVB1_TXCREFCLK */ + { RCAR_GP_PIN(5, 11), 12, 3 }, /* AVB1_TD3 */ + { RCAR_GP_PIN(5, 10), 8, 3 }, /* AVB1_TD2 */ + { RCAR_GP_PIN(5, 9), 4, 3 }, /* AVB1_TD1*/ + { RCAR_GP_PIN(5, 8), 0, 3 }, /* AVB1_TD0 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL5", 0xe6060888) { + { RCAR_GP_PIN(5, 20), 16, 3 }, /* AVB1_AVTP_PPS */ + { RCAR_GP_PIN(5, 19), 12, 3 }, /* AVB1_AVTP_CAPTURE */ + { RCAR_GP_PIN(5, 18), 8, 3 }, /* AVB1_AVTP_MATCH */ + { RCAR_GP_PIN(5, 17), 4, 3 }, /* AVB1_LINK */ + { RCAR_GP_PIN(5, 16), 0, 3 }, /* AVB1_PHY_INT */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL6", 0xe6068080) { + { RCAR_GP_PIN(6, 7), 28, 3 }, /* AVB2_TXC */ + { RCAR_GP_PIN(6, 6), 24, 3 }, /* AVB2_TX_CTL */ + { RCAR_GP_PIN(6, 5), 20, 3 }, /* AVB2_RD3 */ + { RCAR_GP_PIN(6, 4), 16, 3 }, /* AVB2_RD2 */ + { RCAR_GP_PIN(6, 3), 12, 3 }, /* AVB2_RD1 */ + { RCAR_GP_PIN(6, 2), 8, 3 }, /* AVB2_RD0 */ + { RCAR_GP_PIN(6, 1), 4, 3 }, /* AVB2_RXC */ + { RCAR_GP_PIN(6, 0), 0, 3 }, /* AVB2_RX_CTL */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL6", 0xe6068084) { + { RCAR_GP_PIN(6, 15), 28, 3 }, /* AVB2_MAGIC */ + { RCAR_GP_PIN(6, 14), 24, 3 }, /* AVB2_MDC */ + { RCAR_GP_PIN(6, 13), 20, 3 }, /* AVB2_MDIO */ + { RCAR_GP_PIN(6, 12), 16, 3 }, /* AVB2_TXCREFCLK */ + { RCAR_GP_PIN(6, 11), 12, 3 }, /* AVB2_TD3 */ + { RCAR_GP_PIN(6, 10), 8, 3 }, /* AVB2_TD2 */ + { RCAR_GP_PIN(6, 9), 4, 3 }, /* AVB2_TD1*/ + { RCAR_GP_PIN(6, 8), 0, 3 }, /* AVB2_TD0 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL6", 0xe6068088) { + { RCAR_GP_PIN(6, 20), 16, 3 }, /* AVB2_AVTP_PPS */ + { RCAR_GP_PIN(6, 19), 12, 3 }, /* AVB2_AVTP_CAPTURE */ + { RCAR_GP_PIN(6, 18), 8, 3 }, /* AVB2_AVTP_MATCH */ + { RCAR_GP_PIN(6, 17), 4, 3 }, /* AVB2_LINK */ + { RCAR_GP_PIN(6, 16), 0, 3 }, /* AVB2_PHY_INT */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL7", 0xe6068880) { + { RCAR_GP_PIN(7, 7), 28, 3 }, /* AVB3_TXC */ + { RCAR_GP_PIN(7, 6), 24, 3 }, /* AVB3_TX_CTL */ + { RCAR_GP_PIN(7, 5), 20, 3 }, /* AVB3_RD3 */ + { RCAR_GP_PIN(7, 4), 16, 3 }, /* AVB3_RD2 */ + { RCAR_GP_PIN(7, 3), 12, 3 }, /* AVB3_RD1 */ + { RCAR_GP_PIN(7, 2), 8, 3 }, /* AVB3_RD0 */ + { RCAR_GP_PIN(7, 1), 4, 3 }, /* AVB3_RXC */ + { RCAR_GP_PIN(7, 0), 0, 3 }, /* AVB3_RX_CTL */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL7", 0xe6068884) { + { RCAR_GP_PIN(7, 15), 28, 3 }, /* AVB3_MAGIC */ + { RCAR_GP_PIN(7, 14), 24, 3 }, /* AVB3_MDC */ + { RCAR_GP_PIN(7, 13), 20, 3 }, /* AVB3_MDIO */ + { RCAR_GP_PIN(7, 12), 16, 3 }, /* AVB3_TXCREFCLK */ + { RCAR_GP_PIN(7, 11), 12, 3 }, /* AVB3_TD3 */ + { RCAR_GP_PIN(7, 10), 8, 3 }, /* AVB3_TD2 */ + { RCAR_GP_PIN(7, 9), 4, 3 }, /* AVB3_TD1*/ + { RCAR_GP_PIN(7, 8), 0, 3 }, /* AVB3_TD0 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL7", 0xe6068888) { + { RCAR_GP_PIN(7, 20), 16, 3 }, /* AVB3_AVTP_PPS */ + { RCAR_GP_PIN(7, 19), 12, 3 }, /* AVB3_AVTP_CAPTURE */ + { RCAR_GP_PIN(7, 18), 8, 3 }, /* AVB3_AVTP_MATCH */ + { RCAR_GP_PIN(7, 17), 4, 3 }, /* AVB3_LINK */ + { RCAR_GP_PIN(7, 16), 0, 3 }, /* AVB3_PHY_INT */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL8", 0xe6069080) { + { RCAR_GP_PIN(8, 7), 28, 3 }, /* AVB4_TXC */ + { RCAR_GP_PIN(8, 6), 24, 3 }, /* AVB4_TX_CTL */ + { RCAR_GP_PIN(8, 5), 20, 3 }, /* AVB4_RD3 */ + { RCAR_GP_PIN(8, 4), 16, 3 }, /* AVB4_RD2 */ + { RCAR_GP_PIN(8, 3), 12, 3 }, /* AVB4_RD1 */ + { RCAR_GP_PIN(8, 2), 8, 3 }, /* AVB4_RD0 */ + { RCAR_GP_PIN(8, 1), 4, 3 }, /* AVB4_RXC */ + { RCAR_GP_PIN(8, 0), 0, 3 }, /* AVB4_RX_CTL */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL8", 0xe6069084) { + { RCAR_GP_PIN(8, 15), 28, 3 }, /* AVB4_MAGIC */ + { RCAR_GP_PIN(8, 14), 24, 3 }, /* AVB4_MDC */ + { RCAR_GP_PIN(8, 13), 20, 3 }, /* AVB4_MDIO */ + { RCAR_GP_PIN(8, 12), 16, 3 }, /* AVB4_TXCREFCLK */ + { RCAR_GP_PIN(8, 11), 12, 3 }, /* AVB4_TD3 */ + { RCAR_GP_PIN(8, 10), 8, 3 }, /* AVB4_TD2 */ + { RCAR_GP_PIN(8, 9), 4, 3 }, /* AVB4_TD1*/ + { RCAR_GP_PIN(8, 8), 0, 3 }, /* AVB4_TD0 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL8", 0xe6069088) { + { RCAR_GP_PIN(8, 20), 16, 3 }, /* AVB4_AVTP_PPS */ + { RCAR_GP_PIN(8, 19), 12, 3 }, /* AVB4_AVTP_CAPTURE */ + { RCAR_GP_PIN(8, 18), 8, 3 }, /* AVB4_AVTP_MATCH */ + { RCAR_GP_PIN(8, 17), 4, 3 }, /* AVB4_LINK */ + { RCAR_GP_PIN(8, 16), 0, 3 }, /* AVB4_PHY_INT */ + } }, + { PINMUX_DRIVE_REG("DRV0CTRL9", 0xe6069880) { + { RCAR_GP_PIN(9, 7), 28, 3 }, /* AVB5_TXC */ + { RCAR_GP_PIN(9, 6), 24, 3 }, /* AVB5_TX_CTL */ + { RCAR_GP_PIN(9, 5), 20, 3 }, /* AVB5_RD3 */ + { RCAR_GP_PIN(9, 4), 16, 3 }, /* AVB5_RD2 */ + { RCAR_GP_PIN(9, 3), 12, 3 }, /* AVB5_RD1 */ + { RCAR_GP_PIN(9, 2), 8, 3 }, /* AVB5_RD0 */ + { RCAR_GP_PIN(9, 1), 4, 3 }, /* AVB5_RXC */ + { RCAR_GP_PIN(9, 0), 0, 3 }, /* AVB5_RX_CTL */ + } }, + { PINMUX_DRIVE_REG("DRV1CTRL9", 0xe6069884) { + { RCAR_GP_PIN(9, 15), 28, 3 }, /* AVB5_MAGIC */ + { RCAR_GP_PIN(9, 14), 24, 3 }, /* AVB5_MDC */ + { RCAR_GP_PIN(9, 13), 20, 3 }, /* AVB5_MDIO */ + { RCAR_GP_PIN(9, 12), 16, 3 }, /* AVB5_TXCREFCLK */ + { RCAR_GP_PIN(9, 11), 12, 3 }, /* AVB5_TD3 */ + { RCAR_GP_PIN(9, 10), 8, 3 }, /* AVB5_TD2 */ + { RCAR_GP_PIN(9, 9), 4, 3 }, /* AVB5_TD1*/ + { RCAR_GP_PIN(9, 8), 0, 3 }, /* AVB5_TD0 */ + } }, + { PINMUX_DRIVE_REG("DRV2CTRL9", 0xe6069888) { + { RCAR_GP_PIN(9, 20), 16, 3 }, /* AVB5_AVTP_PPS */ + { RCAR_GP_PIN(9, 19), 12, 3 }, /* AVB5_AVTP_CAPTURE */ + { RCAR_GP_PIN(9, 18), 8, 3 }, /* AVB5_AVTP_MATCH */ + { RCAR_GP_PIN(9, 17), 4, 3 }, /* AVB5_LINK */ + { RCAR_GP_PIN(9, 16), 0, 3 }, /* AVB5_PHY_INT */ + } }, + { }, +}; + +enum ioctrl_regs { + POC0, + POC1, + POC2, + POC4, + POC5, + POC6, + POC7, + POC8, + POC9, + TD1SEL0, +}; + +static const struct pinmux_ioctrl_reg pinmux_ioctrl_regs[] = { + [POC0] = { 0xe60580a0, }, + [POC1] = { 0xe60500a0, }, + [POC2] = { 0xe60508a0, }, + [POC4] = { 0xe60600a0, }, + [POC5] = { 0xe60608a0, }, + [POC6] = { 0xe60680a0, }, + [POC7] = { 0xe60688a0, }, + [POC8] = { 0xe60690a0, }, + [POC9] = { 0xe60698a0, }, + [TD1SEL0] = { 0xe6058124, }, + { /* sentinel */ }, +}; + +static int r8a779a0_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, + u32 *pocctrl) +{ + int bit = pin & 0x1f; + + *pocctrl = pinmux_ioctrl_regs[POC0].reg; + if (pin >= RCAR_GP_PIN(0, 15) && pin <= RCAR_GP_PIN(0, 27)) + return bit; + + *pocctrl = pinmux_ioctrl_regs[POC1].reg; + if (pin >= RCAR_GP_PIN(1, 0) && pin <= RCAR_GP_PIN(1, 30)) + return bit; + + *pocctrl = pinmux_ioctrl_regs[POC2].reg; + if (pin >= RCAR_GP_PIN(2, 2) && pin <= RCAR_GP_PIN(2, 15)) + return bit; + + *pocctrl = pinmux_ioctrl_regs[POC4].reg; + if (pin >= RCAR_GP_PIN(4, 0) && pin <= RCAR_GP_PIN(4, 17)) + return bit; + + *pocctrl = pinmux_ioctrl_regs[POC5].reg; + if (pin >= RCAR_GP_PIN(5, 0) && pin <= RCAR_GP_PIN(5, 17)) + return bit; + + *pocctrl = pinmux_ioctrl_regs[POC6].reg; + if (pin >= RCAR_GP_PIN(6, 0) && pin <= RCAR_GP_PIN(6, 17)) + return bit; + + *pocctrl = pinmux_ioctrl_regs[POC7].reg; + if (pin >= RCAR_GP_PIN(7, 0) && pin <= RCAR_GP_PIN(7, 17)) + return bit; + + *pocctrl = pinmux_ioctrl_regs[POC8].reg; + if (pin >= RCAR_GP_PIN(8, 0) && pin <= RCAR_GP_PIN(8, 17)) + return bit; + + *pocctrl = pinmux_ioctrl_regs[POC9].reg; + if (pin >= RCAR_GP_PIN(9, 0) && pin <= RCAR_GP_PIN(9, 17)) + return bit; + + return -EINVAL; +} + +static const struct pinmux_bias_reg pinmux_bias_regs[] = { + { PINMUX_BIAS_REG("PUEN0", 0xe60580c0, "PUD0", 0xe60580e0) { + [ 0] = RCAR_GP_PIN(0, 0), /* QSPI0_SPCLK */ + [ 1] = RCAR_GP_PIN(0, 1), /* QSPI0_MOSI_IO0 */ + [ 2] = RCAR_GP_PIN(0, 2), /* QSPI0_MISO_IO1 */ + [ 3] = RCAR_GP_PIN(0, 3), /* QSPI0_IO2 */ + [ 4] = RCAR_GP_PIN(0, 4), /* QSPI0_IO3 */ + [ 5] = RCAR_GP_PIN(0, 5), /* QSPI0_SSL */ + [ 6] = RCAR_GP_PIN(0, 6), /* QSPI1_SPCLK */ + [ 7] = RCAR_GP_PIN(0, 7), /* QSPI1_MOSI_IO0 */ + [ 8] = RCAR_GP_PIN(0, 8), /* QSPI1_MISO_IO1 */ + [ 9] = RCAR_GP_PIN(0, 9), /* QSPI1_IO2 */ + [10] = RCAR_GP_PIN(0, 10), /* QSPI1_IO3 */ + [11] = RCAR_GP_PIN(0, 11), /* QSPI1_SSL */ + [12] = RCAR_GP_PIN(0, 12), /* RPC_RESET_N */ + [13] = RCAR_GP_PIN(0, 13), /* RPC_WP_N */ + [14] = RCAR_GP_PIN(0, 14), /* RPC_INT_N */ + [15] = RCAR_GP_PIN(0, 15), /* SD_WP */ + [16] = RCAR_GP_PIN(0, 16), /* SD_CD */ + [17] = RCAR_GP_PIN(0, 17), /* MMC_DS */ + [18] = RCAR_GP_PIN(0, 18), /* MMC_SD_CMD */ + [19] = RCAR_GP_PIN(0, 19), /* MMC_SD_D0 */ + [20] = RCAR_GP_PIN(0, 20), /* MMC_SD_D1 */ + [21] = RCAR_GP_PIN(0, 21), /* MMC_SD_D2 */ + [22] = RCAR_GP_PIN(0, 22), /* MMC_SD_D3 */ + [23] = RCAR_GP_PIN(0, 23), /* MMC_SD_CLK */ + [24] = RCAR_GP_PIN(0, 24), /* MMC_D4 */ + [25] = RCAR_GP_PIN(0, 25), /* MMC_D5 */ + [26] = RCAR_GP_PIN(0, 26), /* MMC_D6 */ + [27] = RCAR_GP_PIN(0, 27), /* MMC_D7 */ + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN1", 0xe60500c0, "PUD1", 0xe60500e0) { + [ 0] = RCAR_GP_PIN(1, 0), /* SCIF_CLK */ + [ 1] = RCAR_GP_PIN(1, 1), /* HRX0 */ + [ 2] = RCAR_GP_PIN(1, 2), /* HSCK0 */ + [ 3] = RCAR_GP_PIN(1, 3), /* HRTS0_N */ + [ 4] = RCAR_GP_PIN(1, 4), /* HCTS0_N */ + [ 5] = RCAR_GP_PIN(1, 5), /* HTX0 */ + [ 6] = RCAR_GP_PIN(1, 6), /* MSIOF0_RXD */ + [ 7] = RCAR_GP_PIN(1, 7), /* MSIOF0_TXD */ + [ 8] = RCAR_GP_PIN(1, 8), /* MSIOF0_SCK */ + [ 9] = RCAR_GP_PIN(1, 9), /* MSIOF0_SYNC */ + [10] = RCAR_GP_PIN(1, 10), /* MSIOF0_SS1 */ + [11] = RCAR_GP_PIN(1, 11), /* MSIOF0_SS2 */ + [12] = RCAR_GP_PIN(1, 12), /* MSIOF1_RXD */ + [13] = RCAR_GP_PIN(1, 13), /* MSIOF1_TXD */ + [14] = RCAR_GP_PIN(1, 14), /* MSIOF1_SCK */ + [15] = RCAR_GP_PIN(1, 15), /* MSIOF1_SYNC */ + [16] = RCAR_GP_PIN(1, 16), /* MSIOF1_SS1 */ + [17] = RCAR_GP_PIN(1, 17), /* MSIOF1_SS2 */ + [18] = RCAR_GP_PIN(1, 18), /* MSIOF2_RXD */ + [19] = RCAR_GP_PIN(1, 19), /* MSIOF2_TXD */ + [20] = RCAR_GP_PIN(1, 20), /* MSIOF2_SCK */ + [21] = RCAR_GP_PIN(1, 21), /* MSIOF2_SYNC */ + [22] = RCAR_GP_PIN(1, 22), /* MSIOF2_SS1 */ + [23] = RCAR_GP_PIN(1, 23), /* MSIOF2_SS2 */ + [24] = RCAR_GP_PIN(1, 24), /* IRQ0 */ + [25] = RCAR_GP_PIN(1, 25), /* IRQ1 */ + [26] = RCAR_GP_PIN(1, 26), /* IRQ2 */ + [27] = RCAR_GP_PIN(1, 27), /* IRQ3 */ + [28] = RCAR_GP_PIN(1, 28), /* GP1_28 */ + [29] = RCAR_GP_PIN(1, 29), /* GP1_29 */ + [30] = RCAR_GP_PIN(1, 30), /* GP1_30 */ + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN2", 0xe60508c0, "PUD2", 0xe60508e0) { + [ 0] = RCAR_GP_PIN(2, 0), /* IPC_CLKIN */ + [ 1] = RCAR_GP_PIN(2, 1), /* IPC_CLKOUT */ + [ 2] = RCAR_GP_PIN(2, 2), /* GP2_02 */ + [ 3] = RCAR_GP_PIN(2, 3), /* GP2_03 */ + [ 4] = RCAR_GP_PIN(2, 4), /* GP2_04 */ + [ 5] = RCAR_GP_PIN(2, 5), /* GP2_05 */ + [ 6] = RCAR_GP_PIN(2, 6), /* GP2_06 */ + [ 7] = RCAR_GP_PIN(2, 7), /* GP2_07 */ + [ 8] = RCAR_GP_PIN(2, 8), /* GP2_08 */ + [ 9] = RCAR_GP_PIN(2, 9), /* GP2_09 */ + [10] = RCAR_GP_PIN(2, 10), /* GP2_10 */ + [11] = RCAR_GP_PIN(2, 11), /* GP2_11 */ + [12] = RCAR_GP_PIN(2, 12), /* GP2_12 */ + [13] = RCAR_GP_PIN(2, 13), /* GP2_13 */ + [14] = RCAR_GP_PIN(2, 14), /* GP2_14 */ + [15] = RCAR_GP_PIN(2, 15), /* GP2_15 */ + [16] = RCAR_GP_PIN(2, 16), /* FXR_TXDA_A */ + [17] = RCAR_GP_PIN(2, 17), /* RXDA_EXTFXR_A */ + [18] = RCAR_GP_PIN(2, 18), /* FXR_TXDB */ + [19] = RCAR_GP_PIN(2, 19), /* RXDB_EXTFXR */ + [20] = RCAR_GP_PIN(2, 20), /* CLK_EXTFXR */ + [21] = RCAR_GP_PIN(2, 21), /* TPU0TO0 */ + [22] = RCAR_GP_PIN(2, 22), /* TPU0TO1 */ + [23] = RCAR_GP_PIN(2, 23), /* TCLK1_A */ + [24] = RCAR_GP_PIN(2, 24), /* TCLK2_A */ + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN3", 0xe60588c0, "PUD3", 0xe60588e0) { + [ 0] = RCAR_GP_PIN(3, 0), /* CAN_CLK */ + [ 1] = RCAR_GP_PIN(3, 1), /* CANFD0_TX */ + [ 2] = RCAR_GP_PIN(3, 2), /* CANFD0_RX */ + [ 3] = RCAR_GP_PIN(3, 3), /* CANFD1_TX */ + [ 4] = RCAR_GP_PIN(3, 4), /* CANFD1_RX */ + [ 5] = RCAR_GP_PIN(3, 5), /* CANFD2_TX */ + [ 6] = RCAR_GP_PIN(3, 6), /* CANFD2_RX */ + [ 7] = RCAR_GP_PIN(3, 7), /* CANFD3_TX */ + [ 8] = RCAR_GP_PIN(3, 8), /* CANFD3_RX */ + [ 9] = RCAR_GP_PIN(3, 9), /* CANFD4_TX */ + [10] = RCAR_GP_PIN(3, 10), /* CANFD4_RX */ + [11] = RCAR_GP_PIN(3, 11), /* CANFD5_TX */ + [12] = RCAR_GP_PIN(3, 12), /* CANFD5_RX */ + [13] = RCAR_GP_PIN(3, 13), /* CANFD6_TX */ + [14] = RCAR_GP_PIN(3, 14), /* CANFD6_RX */ + [15] = RCAR_GP_PIN(3, 15), /* CANFD7_TX */ + [16] = RCAR_GP_PIN(3, 16), /* CANFD7_RX */ + [17] = SH_PFC_PIN_NONE, + [18] = SH_PFC_PIN_NONE, + [19] = SH_PFC_PIN_NONE, + [20] = SH_PFC_PIN_NONE, + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN4", 0xe60600c0, "PUD4", 0xe60600e0) { + [ 0] = RCAR_GP_PIN(4, 0), /* AVB0_RX_CTL */ + [ 1] = RCAR_GP_PIN(4, 1), /* AVB0_RXC */ + [ 2] = RCAR_GP_PIN(4, 2), /* AVB0_RD0 */ + [ 3] = RCAR_GP_PIN(4, 3), /* AVB0_RD1 */ + [ 4] = RCAR_GP_PIN(4, 4), /* AVB0_RD2 */ + [ 5] = RCAR_GP_PIN(4, 5), /* AVB0_RD3 */ + [ 6] = RCAR_GP_PIN(4, 6), /* AVB0_TX_CTL */ + [ 7] = RCAR_GP_PIN(4, 7), /* AVB0_TXC */ + [ 8] = RCAR_GP_PIN(4, 8), /* AVB0_TD0 */ + [ 9] = RCAR_GP_PIN(4, 9), /* AVB0_TD1 */ + [10] = RCAR_GP_PIN(4, 10), /* AVB0_TD2 */ + [11] = RCAR_GP_PIN(4, 11), /* AVB0_TD3 */ + [12] = RCAR_GP_PIN(4, 12), /* AVB0_TXREFCLK */ + [13] = RCAR_GP_PIN(4, 13), /* AVB0_MDIO */ + [14] = RCAR_GP_PIN(4, 14), /* AVB0_MDC */ + [15] = RCAR_GP_PIN(4, 15), /* AVB0_MAGIC */ + [16] = RCAR_GP_PIN(4, 16), /* AVB0_PHY_INT */ + [17] = RCAR_GP_PIN(4, 17), /* AVB0_LINK */ + [18] = RCAR_GP_PIN(4, 18), /* AVB0_AVTP_MATCH */ + [19] = RCAR_GP_PIN(4, 19), /* AVB0_AVTP_CAPTURE */ + [20] = RCAR_GP_PIN(4, 20), /* AVB0_AVTP_PPS */ + [21] = RCAR_GP_PIN(4, 21), /* PCIE0_CLKREQ_N */ + [22] = RCAR_GP_PIN(4, 22), /* PCIE1_CLKREQ_N */ + [23] = RCAR_GP_PIN(4, 23), /* PCIE2_CLKREQ_N */ + [24] = RCAR_GP_PIN(4, 24), /* PCIE3_CLKREQ_N */ + [25] = RCAR_GP_PIN(4, 25), /* AVS0 */ + [26] = RCAR_GP_PIN(4, 26), /* AVS1 */ + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN5", 0xe60608c0, "PUD5", 0xe60608e0) { + [ 0] = RCAR_GP_PIN(5, 0), /* AVB1_RX_CTL */ + [ 1] = RCAR_GP_PIN(5, 1), /* AVB1_RXC */ + [ 2] = RCAR_GP_PIN(5, 2), /* AVB1_RD0 */ + [ 3] = RCAR_GP_PIN(5, 3), /* AVB1_RD1 */ + [ 4] = RCAR_GP_PIN(5, 4), /* AVB1_RD2 */ + [ 5] = RCAR_GP_PIN(5, 5), /* AVB1_RD3 */ + [ 6] = RCAR_GP_PIN(5, 6), /* AVB1_TX_CTL */ + [ 7] = RCAR_GP_PIN(5, 7), /* AVB1_TXC */ + [ 8] = RCAR_GP_PIN(5, 8), /* AVB1_TD0 */ + [ 9] = RCAR_GP_PIN(5, 9), /* AVB1_TD1 */ + [10] = RCAR_GP_PIN(5, 10), /* AVB1_TD2 */ + [11] = RCAR_GP_PIN(5, 11), /* AVB1_TD3 */ + [12] = RCAR_GP_PIN(5, 12), /* AVB1_TXCREFCLK */ + [13] = RCAR_GP_PIN(5, 13), /* AVB1_MDIO */ + [14] = RCAR_GP_PIN(5, 14), /* AVB1_MDC */ + [15] = RCAR_GP_PIN(5, 15), /* AVB1_MAGIC */ + [16] = RCAR_GP_PIN(5, 16), /* AVB1_PHY_INT */ + [17] = RCAR_GP_PIN(5, 17), /* AVB1_LINK */ + [18] = RCAR_GP_PIN(5, 18), /* AVB1_AVTP_MATCH */ + [19] = RCAR_GP_PIN(5, 19), /* AVB1_AVTP_CAPTURE */ + [20] = RCAR_GP_PIN(5, 20), /* AVB1_AVTP_PPS */ + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN6", 0xe60680c0, "PUD6", 0xe60680e0) { + [ 0] = RCAR_GP_PIN(6, 0), /* AVB2_RX_CTL */ + [ 1] = RCAR_GP_PIN(6, 1), /* AVB2_RXC */ + [ 2] = RCAR_GP_PIN(6, 2), /* AVB2_RD0 */ + [ 3] = RCAR_GP_PIN(6, 3), /* AVB2_RD1 */ + [ 4] = RCAR_GP_PIN(6, 4), /* AVB2_RD2 */ + [ 5] = RCAR_GP_PIN(6, 5), /* AVB2_RD3 */ + [ 6] = RCAR_GP_PIN(6, 6), /* AVB2_TX_CTL */ + [ 7] = RCAR_GP_PIN(6, 7), /* AVB2_TXC */ + [ 8] = RCAR_GP_PIN(6, 8), /* AVB2_TD0 */ + [ 9] = RCAR_GP_PIN(6, 9), /* AVB2_TD1 */ + [10] = RCAR_GP_PIN(6, 10), /* AVB2_TD2 */ + [11] = RCAR_GP_PIN(6, 11), /* AVB2_TD3 */ + [12] = RCAR_GP_PIN(6, 12), /* AVB2_TXCREFCLK */ + [13] = RCAR_GP_PIN(6, 13), /* AVB2_MDIO */ + [14] = RCAR_GP_PIN(6, 14), /* AVB2_MDC*/ + [15] = RCAR_GP_PIN(6, 15), /* AVB2_MAGIC */ + [16] = RCAR_GP_PIN(6, 16), /* AVB2_PHY_INT */ + [17] = RCAR_GP_PIN(6, 17), /* AVB2_LINK */ + [18] = RCAR_GP_PIN(6, 18), /* AVB2_AVTP_MATCH */ + [19] = RCAR_GP_PIN(6, 19), /* AVB2_AVTP_CAPTURE */ + [20] = RCAR_GP_PIN(6, 20), /* AVB2_AVTP_PPS */ + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN7", 0xe60688c0, "PUD7", 0xe60688e0) { + [ 0] = RCAR_GP_PIN(7, 0), /* AVB3_RX_CTL */ + [ 1] = RCAR_GP_PIN(7, 1), /* AVB3_RXC */ + [ 2] = RCAR_GP_PIN(7, 2), /* AVB3_RD0 */ + [ 3] = RCAR_GP_PIN(7, 3), /* AVB3_RD1 */ + [ 4] = RCAR_GP_PIN(7, 4), /* AVB3_RD2 */ + [ 5] = RCAR_GP_PIN(7, 5), /* AVB3_RD3 */ + [ 6] = RCAR_GP_PIN(7, 6), /* AVB3_TX_CTL */ + [ 7] = RCAR_GP_PIN(7, 7), /* AVB3_TXC */ + [ 8] = RCAR_GP_PIN(7, 8), /* AVB3_TD0 */ + [ 9] = RCAR_GP_PIN(7, 9), /* AVB3_TD1 */ + [10] = RCAR_GP_PIN(7, 10), /* AVB3_TD2 */ + [11] = RCAR_GP_PIN(7, 11), /* AVB3_TD3 */ + [12] = RCAR_GP_PIN(7, 12), /* AVB3_TXCREFCLK */ + [13] = RCAR_GP_PIN(7, 13), /* AVB3_MDIO */ + [14] = RCAR_GP_PIN(7, 14), /* AVB3_MDC */ + [15] = RCAR_GP_PIN(7, 15), /* AVB3_MAGIC */ + [16] = RCAR_GP_PIN(7, 16), /* AVB3_PHY_INT */ + [17] = RCAR_GP_PIN(7, 17), /* AVB3_LINK */ + [18] = RCAR_GP_PIN(7, 18), /* AVB3_AVTP_MATCH */ + [19] = RCAR_GP_PIN(7, 19), /* AVB3_AVTP_CAPTURE */ + [20] = RCAR_GP_PIN(7, 20), /* AVB3_AVTP_PPS */ + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN8", 0xe60690c0, "PUD8", 0xe60690e0) { + [ 0] = RCAR_GP_PIN(8, 0), /* AVB4_RX_CTL */ + [ 1] = RCAR_GP_PIN(8, 1), /* AVB4_RXC */ + [ 2] = RCAR_GP_PIN(8, 2), /* AVB4_RD0 */ + [ 3] = RCAR_GP_PIN(8, 3), /* AVB4_RD1 */ + [ 4] = RCAR_GP_PIN(8, 4), /* AVB4_RD2 */ + [ 5] = RCAR_GP_PIN(8, 5), /* AVB4_RD3 */ + [ 6] = RCAR_GP_PIN(8, 6), /* AVB4_TX_CTL */ + [ 7] = RCAR_GP_PIN(8, 7), /* AVB4_TXC */ + [ 8] = RCAR_GP_PIN(8, 8), /* AVB4_TD0 */ + [ 9] = RCAR_GP_PIN(8, 9), /* AVB4_TD1 */ + [10] = RCAR_GP_PIN(8, 10), /* AVB4_TD2 */ + [11] = RCAR_GP_PIN(8, 11), /* AVB4_TD3 */ + [12] = RCAR_GP_PIN(8, 12), /* AVB4_TXCREFCLK */ + [13] = RCAR_GP_PIN(8, 13), /* AVB4_MDIO */ + [14] = RCAR_GP_PIN(8, 14), /* AVB4_MDC */ + [15] = RCAR_GP_PIN(8, 15), /* AVB4_MAGIC */ + [16] = RCAR_GP_PIN(8, 16), /* AVB4_PHY_INT */ + [17] = RCAR_GP_PIN(8, 17), /* AVB4_LINK */ + [18] = RCAR_GP_PIN(8, 18), /* AVB4_AVTP_MATCH */ + [19] = RCAR_GP_PIN(8, 19), /* AVB4_AVTP_CAPTURE */ + [20] = RCAR_GP_PIN(8, 20), /* AVB4_AVTP_PPS */ + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("PUEN9", 0xe60698c0, "PUD9", 0xe60698e0) { + [ 0] = RCAR_GP_PIN(9, 0), /* AVB5_RX_CTL */ + [ 1] = RCAR_GP_PIN(9, 1), /* AVB5_RXC */ + [ 2] = RCAR_GP_PIN(9, 2), /* AVB5_RD0 */ + [ 3] = RCAR_GP_PIN(9, 3), /* AVB5_RD1 */ + [ 4] = RCAR_GP_PIN(9, 4), /* AVB5_RD2 */ + [ 5] = RCAR_GP_PIN(9, 5), /* AVB5_RD3 */ + [ 6] = RCAR_GP_PIN(9, 6), /* AVB5_TX_CTL */ + [ 7] = RCAR_GP_PIN(9, 7), /* AVB5_TXC */ + [ 8] = RCAR_GP_PIN(9, 8), /* AVB5_TD0 */ + [ 9] = RCAR_GP_PIN(9, 9), /* AVB5_TD1 */ + [10] = RCAR_GP_PIN(9, 10), /* AVB5_TD2 */ + [11] = RCAR_GP_PIN(9, 11), /* AVB5_TD3 */ + [12] = RCAR_GP_PIN(9, 12), /* AVB5_TXCREFCLK */ + [13] = RCAR_GP_PIN(9, 13), /* AVB5_MDIO */ + [14] = RCAR_GP_PIN(9, 14), /* AVB5_MDC */ + [15] = RCAR_GP_PIN(9, 15), /* AVB5_MAGIC */ + [16] = RCAR_GP_PIN(9, 16), /* AVB5_PHY_INT */ + [17] = RCAR_GP_PIN(9, 17), /* AVB5_LINK */ + [18] = RCAR_GP_PIN(9, 18), /* AVB5_AVTP_MATCH */ + [19] = RCAR_GP_PIN(9, 19), /* AVB5_AVTP_CAPTURE */ + [20] = RCAR_GP_PIN(9, 20), /* AVB5_AVTP_PPS */ + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { /* sentinel */ }, +}; + +static const struct sh_pfc_soc_operations pinmux_ops = { + .pin_to_pocctrl = r8a779a0_pin_to_pocctrl, + .get_bias = rcar_pinmux_get_bias, + .set_bias = rcar_pinmux_set_bias, +}; + +const struct sh_pfc_soc_info r8a779a0_pinmux_info = { + .name = "r8a779a0_pfc", + .ops = &pinmux_ops, + .unlock_reg = 0x1ff, /* PMMRn mask */ + + .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, + + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .groups = pinmux_groups, + .nr_groups = ARRAY_SIZE(pinmux_groups), + .functions = pinmux_functions, + .nr_functions = ARRAY_SIZE(pinmux_functions), + + .cfg_regs = pinmux_config_regs, + .drive_regs = pinmux_drive_regs, + .bias_regs = pinmux_bias_regs, + .ioctrl_regs = pinmux_ioctrl_regs, + + .pinmux_data = pinmux_data, + .pinmux_data_size = ARRAY_SIZE(pinmux_data), +}; diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c index ac542d278a38..a49f74730272 100644 --- a/drivers/pinctrl/renesas/pinctrl.c +++ b/drivers/pinctrl/renesas/pinctrl.c @@ -634,6 +634,9 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, } case PIN_CONFIG_POWER_SOURCE: { + int idx = sh_pfc_get_pin_index(pfc, _pin); + const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; + unsigned int lower_voltage; u32 pocctrl, val; int bit; @@ -648,7 +651,10 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, val = sh_pfc_read(pfc, pocctrl); spin_unlock_irqrestore(&pfc->lock, flags); - arg = (val & BIT(bit)) ? 3300 : 1800; + lower_voltage = (pin->configs & SH_PFC_PIN_VOLTAGE_25_33) ? + 2500 : 1800; + + arg = (val & BIT(bit)) ? 3300 : lower_voltage; break; } @@ -702,6 +708,9 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin, case PIN_CONFIG_POWER_SOURCE: { unsigned int mV = pinconf_to_config_argument(configs[i]); + int idx = sh_pfc_get_pin_index(pfc, _pin); + const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; + unsigned int lower_voltage; u32 pocctrl, val; int bit; @@ -712,7 +721,10 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin, if (WARN(bit < 0, "invalid pin %#x", _pin)) return bit; - if (mV != 1800 && mV != 3300) + lower_voltage = (pin->configs & SH_PFC_PIN_VOLTAGE_25_33) ? + 2500 : 1800; + + if (mV != lower_voltage && mV != 3300) return -EINVAL; spin_lock_irqsave(&pfc->lock, flags); diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index dc484c13f59c..5934faeb23d7 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -31,6 +31,15 @@ enum { SH_PFC_PIN_CFG_PULL_DOWN) #define SH_PFC_PIN_CFG_IO_VOLTAGE (1 << 4) #define SH_PFC_PIN_CFG_DRIVE_STRENGTH (1 << 5) + +#define SH_PFC_PIN_VOLTAGE_18_33 (0 << 6) +#define SH_PFC_PIN_VOLTAGE_25_33 (1 << 6) + +#define SH_PFC_PIN_CFG_IO_VOLTAGE_18_33 (SH_PFC_PIN_CFG_IO_VOLTAGE | \ + SH_PFC_PIN_VOLTAGE_18_33) +#define SH_PFC_PIN_CFG_IO_VOLTAGE_25_33 (SH_PFC_PIN_CFG_IO_VOLTAGE | \ + SH_PFC_PIN_VOLTAGE_25_33) + #define SH_PFC_PIN_CFG_NO_GPIO (1 << 31) struct sh_pfc_pin { @@ -300,7 +309,7 @@ struct sh_pfc_soc_info { const u16 *pinmux_data; unsigned int pinmux_data_size; - u32 unlock_reg; + u32 unlock_reg; /* can be literal address or mask */ }; extern const struct sh_pfc_soc_info emev2_pinmux_info; @@ -331,6 +340,7 @@ extern const struct sh_pfc_soc_info r8a77970_pinmux_info; extern const struct sh_pfc_soc_info r8a77980_pinmux_info; extern const struct sh_pfc_soc_info r8a77990_pinmux_info; extern const struct sh_pfc_soc_info r8a77995_pinmux_info; +extern const struct sh_pfc_soc_info r8a779a0_pinmux_info; extern const struct sh_pfc_soc_info sh7203_pinmux_info; extern const struct sh_pfc_soc_info sh7264_pinmux_info; extern const struct sh_pfc_soc_info sh7269_pinmux_info; @@ -451,9 +461,13 @@ extern const struct sh_pfc_soc_info shx3_pinmux_info; fn(bank, pin, GP_##bank##_##pin, sfx, cfg) #define PORT_GP_1(bank, pin, fn, sfx) PORT_GP_CFG_1(bank, pin, fn, sfx, 0) -#define PORT_GP_CFG_4(bank, fn, sfx, cfg) \ +#define PORT_GP_CFG_2(bank, fn, sfx, cfg) \ PORT_GP_CFG_1(bank, 0, fn, sfx, cfg), \ - PORT_GP_CFG_1(bank, 1, fn, sfx, cfg), \ + PORT_GP_CFG_1(bank, 1, fn, sfx, cfg) +#define PORT_GP_2(bank, fn, sfx) PORT_GP_CFG_2(bank, fn, sfx, 0) + +#define PORT_GP_CFG_4(bank, fn, sfx, cfg) \ + PORT_GP_CFG_2(bank, fn, sfx, cfg), \ PORT_GP_CFG_1(bank, 2, fn, sfx, cfg), \ PORT_GP_CFG_1(bank, 3, fn, sfx, cfg) #define PORT_GP_4(bank, fn, sfx) PORT_GP_CFG_4(bank, fn, sfx, 0) @@ -572,9 +586,13 @@ extern const struct sh_pfc_soc_info shx3_pinmux_info; PORT_GP_CFG_1(bank, 29, fn, sfx, cfg) #define PORT_GP_30(bank, fn, sfx) PORT_GP_CFG_30(bank, fn, sfx, 0) -#define PORT_GP_CFG_32(bank, fn, sfx, cfg) \ +#define PORT_GP_CFG_31(bank, fn, sfx, cfg) \ PORT_GP_CFG_30(bank, fn, sfx, cfg), \ - PORT_GP_CFG_1(bank, 30, fn, sfx, cfg), \ + PORT_GP_CFG_1(bank, 30, fn, sfx, cfg) +#define PORT_GP_31(bank, fn, sfx) PORT_GP_CFG_31(bank, fn, sfx, 0) + +#define PORT_GP_CFG_32(bank, fn, sfx, cfg) \ + PORT_GP_CFG_31(bank, fn, sfx, cfg), \ PORT_GP_CFG_1(bank, 31, fn, sfx, cfg) #define PORT_GP_32(bank, fn, sfx) PORT_GP_CFG_32(bank, fn, sfx, 0) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index b9ea09fabf84..0cd7f33cdf25 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -58,13 +58,13 @@ static void exynos_irq_mask(struct irq_data *irqd) unsigned long mask; unsigned long flags; - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); mask = readl(bank->eint_base + reg_mask); mask |= 1 << irqd->hwirq; writel(mask, bank->eint_base + reg_mask); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); } static void exynos_irq_ack(struct irq_data *irqd) @@ -97,13 +97,13 @@ static void exynos_irq_unmask(struct irq_data *irqd) if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK) exynos_irq_ack(irqd); - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); mask = readl(bank->eint_base + reg_mask); mask &= ~(1 << irqd->hwirq); writel(mask, bank->eint_base + reg_mask); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); } static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) @@ -169,14 +169,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; - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); con = readl(bank->pctl_base + reg_con); con &= ~(mask << shift); con |= EXYNOS_PIN_FUNC_EINT << shift; writel(con, bank->pctl_base + reg_con); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); return 0; } @@ -192,14 +192,14 @@ 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; - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); con = readl(bank->pctl_base + reg_con); con &= ~(mask << shift); con |= EXYNOS_PIN_FUNC_INPUT << shift; writel(con, bank->pctl_base + reg_con); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq); } diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index 2223ead5bd72..00d77d6946b5 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -145,14 +145,14 @@ static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d, shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); val = readl(reg); val &= ~(mask << shift); val |= bank->eint_func << shift; writel(val, reg); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); } static int s3c24xx_eint_type(struct irq_data *data, unsigned int type) diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index b8166e3fe4ce..53e2a6412add 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -286,14 +286,14 @@ static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, shift = shift * bank_type->fld_width[PINCFG_TYPE_FUNC]; mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); val = readl(reg); val &= ~(mask << shift); val |= bank->eint_func << shift; writel(val, reg); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); } /* diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 608eb5a07248..376876bd6605 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -400,14 +400,14 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, reg += 4; } - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); data &= ~(mask << shift); data |= func->val << shift; writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); } /* enable a specified pinmux by writing to registers */ @@ -451,7 +451,7 @@ 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]; - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); mask = (1 << width) - 1; shift = pin_offset * width; @@ -468,7 +468,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, *config = PINCFG_PACK(cfg_type, data); } - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); return 0; } @@ -561,9 +561,9 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) struct samsung_pin_bank *bank = gpiochip_get_data(gc); unsigned long flags; - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); samsung_gpio_set_value(gc, offset, value); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); } /* gpiolib gpio_get callback function */ @@ -626,9 +626,9 @@ static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset) unsigned long flags; int ret; - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); ret = samsung_gpio_set_direction(gc, offset, true); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); return ret; } @@ -640,10 +640,10 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, unsigned long flags; int ret; - spin_lock_irqsave(&bank->slock, flags); + raw_spin_lock_irqsave(&bank->slock, flags); samsung_gpio_set_value(gc, offset, value); ret = samsung_gpio_set_direction(gc, offset, false); - spin_unlock_irqrestore(&bank->slock, flags); + raw_spin_unlock_irqrestore(&bank->slock, flags); return ret; } @@ -1057,7 +1057,7 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, bank->eint_offset = bdata->eint_offset; bank->name = bdata->name; - spin_lock_init(&bank->slock); + raw_spin_lock_init(&bank->slock); bank->drvdata = d; bank->pin_base = d->nr_pins; d->nr_pins += bank->nr_pins; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 379f34a9a482..de44f8ec330b 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -171,7 +171,7 @@ struct samsung_pin_bank { struct gpio_chip gpio_chip; struct pinctrl_gpio_range grange; struct exynos_irq_chip *irq_chip; - spinlock_t slock; + raw_spinlock_t slock; u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/ }; diff --git a/drivers/pinctrl/sirf/Makefile b/drivers/pinctrl/sirf/Makefile deleted file mode 100644 index 1ab0742075f6..000000000000 --- a/drivers/pinctrl/sirf/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# CSR SiRFsoc pinmux support - -obj-y += pinctrl-sirf.o -obj-y += pinctrl-prima2.o -obj-y += pinctrl-atlas6.o -obj-y += pinctrl-atlas7.o diff --git a/drivers/pinctrl/sirf/pinctrl-atlas6.c b/drivers/pinctrl/sirf/pinctrl-atlas6.c deleted file mode 100644 index ab35d59bfa04..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-atlas6.c +++ /dev/null @@ -1,1137 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pinctrl pads, groups, functions for CSR SiRFatlasVI - * - * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group - * company. - */ - -#include -#include - -#include "pinctrl-sirf.h" - -/* - * pad list for the pinmux subsystem - * refer to atlasVI_io_table_v0.93.xls - */ -static const struct pinctrl_pin_desc sirfsoc_pads[] = { - PINCTRL_PIN(0, "gpio0-0"), - PINCTRL_PIN(1, "gpio0-1"), - PINCTRL_PIN(2, "gpio0-2"), - PINCTRL_PIN(3, "gpio0-3"), - PINCTRL_PIN(4, "pwm0"), - PINCTRL_PIN(5, "pwm1"), - PINCTRL_PIN(6, "pwm2"), - PINCTRL_PIN(7, "pwm3"), - PINCTRL_PIN(8, "warm_rst_b"), - PINCTRL_PIN(9, "odo_0"), - PINCTRL_PIN(10, "odo_1"), - PINCTRL_PIN(11, "dr_dir"), - PINCTRL_PIN(12, "rts_0"), - PINCTRL_PIN(13, "scl_1"), - PINCTRL_PIN(14, "ntrst"), - PINCTRL_PIN(15, "sda_1"), - PINCTRL_PIN(16, "x_ldd[16]"), - PINCTRL_PIN(17, "x_ldd[17]"), - PINCTRL_PIN(18, "x_ldd[18]"), - PINCTRL_PIN(19, "x_ldd[19]"), - PINCTRL_PIN(20, "x_ldd[20]"), - PINCTRL_PIN(21, "x_ldd[21]"), - PINCTRL_PIN(22, "x_ldd[22]"), - PINCTRL_PIN(23, "x_ldd[23]"), - PINCTRL_PIN(24, "gps_sgn"), - PINCTRL_PIN(25, "gps_mag"), - PINCTRL_PIN(26, "gps_clk"), - PINCTRL_PIN(27, "sd_cd_b_2"), - PINCTRL_PIN(28, "sd_vcc_on_2"), - PINCTRL_PIN(29, "sd_wp_b_2"), - PINCTRL_PIN(30, "sd_clk_3"), - PINCTRL_PIN(31, "sd_cmd_3"), - - PINCTRL_PIN(32, "x_sd_dat_3[0]"), - PINCTRL_PIN(33, "x_sd_dat_3[1]"), - PINCTRL_PIN(34, "x_sd_dat_3[2]"), - PINCTRL_PIN(35, "x_sd_dat_3[3]"), - PINCTRL_PIN(36, "usb_clk"), - PINCTRL_PIN(37, "usb_dir"), - PINCTRL_PIN(38, "usb_nxt"), - PINCTRL_PIN(39, "usb_stp"), - PINCTRL_PIN(40, "usb_dat[7]"), - PINCTRL_PIN(41, "usb_dat[6]"), - PINCTRL_PIN(42, "x_cko_1"), - PINCTRL_PIN(43, "spi_clk_1"), - PINCTRL_PIN(44, "spi_dout_1"), - PINCTRL_PIN(45, "spi_din_1"), - PINCTRL_PIN(46, "spi_en_1"), - PINCTRL_PIN(47, "x_txd_1"), - PINCTRL_PIN(48, "x_txd_2"), - PINCTRL_PIN(49, "x_rxd_1"), - PINCTRL_PIN(50, "x_rxd_2"), - PINCTRL_PIN(51, "x_usclk_0"), - PINCTRL_PIN(52, "x_utxd_0"), - PINCTRL_PIN(53, "x_urxd_0"), - PINCTRL_PIN(54, "x_utfs_0"), - PINCTRL_PIN(55, "x_urfs_0"), - PINCTRL_PIN(56, "usb_dat5"), - PINCTRL_PIN(57, "usb_dat4"), - PINCTRL_PIN(58, "usb_dat3"), - PINCTRL_PIN(59, "usb_dat2"), - PINCTRL_PIN(60, "usb_dat1"), - PINCTRL_PIN(61, "usb_dat0"), - PINCTRL_PIN(62, "x_ldd[14]"), - PINCTRL_PIN(63, "x_ldd[15]"), - - PINCTRL_PIN(64, "x_gps_gpio"), - PINCTRL_PIN(65, "x_ldd[13]"), - PINCTRL_PIN(66, "x_df_we_b"), - PINCTRL_PIN(67, "x_df_re_b"), - PINCTRL_PIN(68, "x_txd_0"), - PINCTRL_PIN(69, "x_rxd_0"), - PINCTRL_PIN(70, "x_l_lck"), - PINCTRL_PIN(71, "x_l_fck"), - PINCTRL_PIN(72, "x_l_de"), - PINCTRL_PIN(73, "x_ldd[0]"), - PINCTRL_PIN(74, "x_ldd[1]"), - PINCTRL_PIN(75, "x_ldd[2]"), - PINCTRL_PIN(76, "x_ldd[3]"), - PINCTRL_PIN(77, "x_ldd[4]"), - PINCTRL_PIN(78, "x_cko_0"), - PINCTRL_PIN(79, "x_ldd[5]"), - PINCTRL_PIN(80, "x_ldd[6]"), - PINCTRL_PIN(81, "x_ldd[7]"), - PINCTRL_PIN(82, "x_ldd[8]"), - PINCTRL_PIN(83, "x_ldd[9]"), - PINCTRL_PIN(84, "x_ldd[10]"), - PINCTRL_PIN(85, "x_ldd[11]"), - PINCTRL_PIN(86, "x_ldd[12]"), - PINCTRL_PIN(87, "x_vip_vsync"), - PINCTRL_PIN(88, "x_vip_hsync"), - PINCTRL_PIN(89, "x_vip_pxclk"), - PINCTRL_PIN(90, "x_sda_0"), - PINCTRL_PIN(91, "x_scl_0"), - PINCTRL_PIN(92, "x_df_ry_by"), - PINCTRL_PIN(93, "x_df_cs_b[1]"), - PINCTRL_PIN(94, "x_df_cs_b[0]"), - PINCTRL_PIN(95, "x_l_pclk"), - - PINCTRL_PIN(96, "x_df_dqs"), - PINCTRL_PIN(97, "x_df_wp_b"), - PINCTRL_PIN(98, "ac97_sync"), - PINCTRL_PIN(99, "ac97_bit_clk "), - PINCTRL_PIN(100, "ac97_dout"), - PINCTRL_PIN(101, "ac97_din"), - PINCTRL_PIN(102, "x_rtc_io"), - - PINCTRL_PIN(103, "x_usb1_dp"), - PINCTRL_PIN(104, "x_usb1_dn"), -}; - -static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = { - { - .group = 1, - .mask = BIT(30) | BIT(31), - }, { - .group = 2, - .mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | - BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(15) | - BIT(16) | BIT(17) | BIT(18) | BIT(19) | - BIT(20) | BIT(21) | BIT(22) | BIT(31), - }, -}; - -static const struct sirfsoc_padmux lcd_16bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask), - .muxmask = lcd_16bits_sirfsoc_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_16bits_pins[] = { 62, 63, 65, 70, 71, 72, 73, 74, 75, - 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 95 }; - -static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = { - { - .group = 2, - .mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | - BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(15) | - BIT(16) | BIT(17) | BIT(18) | BIT(19) | - BIT(20) | BIT(21) | BIT(22) | BIT(31), - }, { - .group = 1, - .mask = BIT(30) | BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux lcd_18bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask), - .muxmask = lcd_18bits_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4) | BIT(15), - .funcval = 0, -}; - -static const unsigned lcd_18bits_pins[] = { 16, 17, 62, 63, 65, 70, 71, 72, 73, - 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 95 }; - -static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = { - { - .group = 2, - .mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | - BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(15) | - BIT(16) | BIT(17) | BIT(18) | BIT(19) | - BIT(20) | BIT(21) | BIT(22) | BIT(31), - }, { - .group = 1, - .mask = BIT(30) | BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | - BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux lcd_24bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask), - .muxmask = lcd_24bits_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4) | BIT(15), - .funcval = 0, -}; - -static const unsigned lcd_24bits_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 62, - 63, 65, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, - 85, 86, 95}; - -static const struct sirfsoc_muxmask lcdrom_muxmask[] = { - { - .group = 2, - .mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | - BIT(11) | BIT(12) | BIT(13) | BIT(15) | BIT(16) | - BIT(17) | BIT(18) | BIT(19) | - BIT(20) | BIT(21) | BIT(22) | BIT(31), - }, { - .group = 1, - .mask = BIT(30) | BIT(31), - }, { - .group = 0, - .mask = BIT(8), - }, -}; - -static const struct sirfsoc_padmux lcdrom_padmux = { - .muxmask_counts = ARRAY_SIZE(lcdrom_muxmask), - .muxmask = lcdrom_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = BIT(4), -}; - -static const unsigned lcdrom_pins[] = { 8, 62, 63, 65, 70, 71, 72, 73, 74, 75, - 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 95}; - -static const struct sirfsoc_muxmask uart0_muxmask[] = { - { - .group = 0, - .mask = BIT(12), - }, { - .group = 1, - .mask = BIT(23), - }, { - .group = 2, - .mask = BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux uart0_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_muxmask), - .muxmask = uart0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(9), - .funcval = BIT(9), -}; - -static const unsigned uart0_pins[] = { 12, 55, 68, 69 }; - -static const struct sirfsoc_muxmask uart0_nostreamctrl_muxmask[] = { - { - .group = 2, - .mask = BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux uart0_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask), - .muxmask = uart0_nostreamctrl_muxmask, -}; - -static const unsigned uart0_nostreamctrl_pins[] = { 68, 69 }; - -static const struct sirfsoc_muxmask uart1_muxmask[] = { - { - .group = 1, - .mask = BIT(15) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux uart1_padmux = { - .muxmask_counts = ARRAY_SIZE(uart1_muxmask), - .muxmask = uart1_muxmask, -}; - -static const unsigned uart1_pins[] = { 47, 49 }; - -static const struct sirfsoc_muxmask uart2_muxmask[] = { - { - .group = 0, - .mask = BIT(10) | BIT(14), - }, { - .group = 1, - .mask = BIT(16) | BIT(18), - }, -}; - -static const struct sirfsoc_padmux uart2_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_muxmask), - .muxmask = uart2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(10), - .funcval = BIT(10), -}; - -static const unsigned uart2_pins[] = { 10, 14, 48, 50 }; - -static const struct sirfsoc_muxmask uart2_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(16) | BIT(18), - }, -}; - -static const struct sirfsoc_padmux uart2_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask), - .muxmask = uart2_nostreamctrl_muxmask, -}; - -static const unsigned uart2_nostreamctrl_pins[] = { 48, 50 }; - -static const struct sirfsoc_muxmask sdmmc3_muxmask[] = { - { - .group = 0, - .mask = BIT(30) | BIT(31), - }, { - .group = 1, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc3_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask), - .muxmask = sdmmc3_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(7), - .funcval = 0, -}; - -static const unsigned sdmmc3_pins[] = { 30, 31, 32, 33, 34, 35 }; - -static const struct sirfsoc_muxmask spi0_muxmask[] = { - { - .group = 0, - .mask = BIT(30), - }, { - .group = 1, - .mask = BIT(0) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux spi0_padmux = { - .muxmask_counts = ARRAY_SIZE(spi0_muxmask), - .muxmask = spi0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(7), - .funcval = BIT(7), -}; - -static const unsigned spi0_pins[] = { 30, 32, 34, 35 }; - -static const struct sirfsoc_muxmask cko1_muxmask[] = { - { - .group = 1, - .mask = BIT(10), - }, -}; - -static const struct sirfsoc_padmux cko1_padmux = { - .muxmask_counts = ARRAY_SIZE(cko1_muxmask), - .muxmask = cko1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(3), - .funcval = 0, -}; - -static const unsigned cko1_pins[] = { 42 }; - -static const struct sirfsoc_muxmask i2s_mclk_muxmask[] = { - { - .group = 1, - .mask = BIT(10), - }, -}; - -static const struct sirfsoc_padmux i2s_mclk_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_mclk_muxmask), - .muxmask = i2s_mclk_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(3), - .funcval = BIT(3), -}; - -static const unsigned i2s_mclk_pins[] = { 42 }; - -static const struct sirfsoc_muxmask i2s_ext_clk_input_muxmask[] = { - { - .group = 1, - .mask = BIT(19), - }, -}; - -static const struct sirfsoc_padmux i2s_ext_clk_input_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_ext_clk_input_muxmask), - .muxmask = i2s_ext_clk_input_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(2), - .funcval = BIT(2), -}; - -static const unsigned i2s_ext_clk_input_pins[] = { 51 }; - -static const struct sirfsoc_muxmask i2s_muxmask[] = { - { - .group = 3, - .mask = BIT(2) | BIT(3) | BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux i2s_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_muxmask), - .muxmask = i2s_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, -}; - -static const unsigned i2s_pins[] = { 98, 99, 100, 101 }; - -static const struct sirfsoc_muxmask i2s_no_din_muxmask[] = { - { - .group = 3, - .mask = BIT(2) | BIT(3) | BIT(4), - }, -}; - -static const struct sirfsoc_padmux i2s_no_din_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_no_din_muxmask), - .muxmask = i2s_no_din_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, -}; - -static const unsigned i2s_no_din_pins[] = { 98, 99, 100 }; - -static const struct sirfsoc_muxmask i2s_6chn_muxmask[] = { - { - .group = 3, - .mask = BIT(2) | BIT(3) | BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux i2s_6chn_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_6chn_muxmask), - .muxmask = i2s_6chn_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(9), - .funcval = BIT(1) | BIT(9), -}; - -static const unsigned i2s_6chn_pins[] = { 52, 55, 98, 99, 100, 101 }; - -static const struct sirfsoc_muxmask ac97_muxmask[] = { - { - .group = 3, - .mask = BIT(2) | BIT(3) | BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux ac97_padmux = { - .muxmask_counts = ARRAY_SIZE(ac97_muxmask), - .muxmask = ac97_muxmask, -}; - -static const unsigned ac97_pins[] = { 98, 99, 100, 101 }; - -static const struct sirfsoc_muxmask spi1_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux spi1_padmux = { - .muxmask_counts = ARRAY_SIZE(spi1_muxmask), - .muxmask = spi1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(16), - .funcval = 0, -}; - -static const unsigned spi1_pins[] = { 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask sdmmc1_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc1_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask), - .muxmask = sdmmc1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5), - .funcval = BIT(5), -}; - -static const unsigned sdmmc1_pins[] = { 66, 67 }; - -static const struct sirfsoc_muxmask gps_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux gps_padmux = { - .muxmask_counts = ARRAY_SIZE(gps_muxmask), - .muxmask = gps_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(13), - .funcval = 0, -}; - -static const unsigned gps_pins[] = { 24, 25, 26 }; - -static const struct sirfsoc_muxmask sdmmc5_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux sdmmc5_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask), - .muxmask = sdmmc5_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(13), - .funcval = BIT(13), -}; - -static const unsigned sdmmc5_pins[] = { 24, 25, 26 }; - -static const struct sirfsoc_muxmask usp0_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux usp0_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_muxmask), - .muxmask = usp0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(9), - .funcval = 0, -}; - -static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 }; - -static const struct sirfsoc_muxmask usp0_only_utfs_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22), - }, -}; - -static const struct sirfsoc_padmux usp0_only_utfs_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_only_utfs_muxmask), - .muxmask = usp0_only_utfs_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(6), - .funcval = 0, -}; - -static const unsigned usp0_only_utfs_pins[] = { 51, 52, 53, 54 }; - -static const struct sirfsoc_muxmask usp0_only_urfs_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux usp0_only_urfs_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_only_urfs_muxmask), - .muxmask = usp0_only_urfs_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(9), - .funcval = 0, -}; - -static const unsigned usp0_only_urfs_pins[] = { 51, 52, 53, 55 }; - -static const struct sirfsoc_muxmask usp0_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(20) | BIT(21), - }, -}; - -static const struct sirfsoc_padmux usp0_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_uart_nostreamctrl_muxmask), - .muxmask = usp0_uart_nostreamctrl_muxmask, -}; - -static const unsigned usp0_uart_nostreamctrl_pins[] = { 52, 53 }; -static const struct sirfsoc_muxmask usp1_muxmask[] = { - { - .group = 0, - .mask = BIT(15), - }, { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux usp1_padmux = { - .muxmask_counts = ARRAY_SIZE(usp1_muxmask), - .muxmask = usp1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(16), - .funcval = BIT(16), -}; - -static const unsigned usp1_pins[] = { 15, 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask usp1_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(12) | BIT(13), - }, -}; - -static const struct sirfsoc_padmux usp1_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp1_uart_nostreamctrl_muxmask), - .muxmask = usp1_uart_nostreamctrl_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(16), - .funcval = BIT(16), -}; - -static const unsigned usp1_uart_nostreamctrl_pins[] = { 44, 45 }; - -static const struct sirfsoc_muxmask nand_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3) | BIT(28) | BIT(29) | BIT(30), - }, { - .group = 3, - .mask = BIT(0) | BIT(1), - }, -}; - -static const struct sirfsoc_padmux nand_padmux = { - .muxmask_counts = ARRAY_SIZE(nand_muxmask), - .muxmask = nand_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5) | BIT(19), - .funcval = 0, -}; - -static const unsigned nand_pins[] = { 66, 67, 92, 93, 94, 96, 97 }; - -static const struct sirfsoc_muxmask sdmmc0_muxmask[] = { - { - .group = 3, - .mask = BIT(1), - }, -}; - -static const struct sirfsoc_padmux sdmmc0_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc0_muxmask), - .muxmask = sdmmc0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5) | BIT(19), - .funcval = BIT(19), -}; - -static const unsigned sdmmc0_pins[] = { 97 }; - -static const struct sirfsoc_muxmask sdmmc2_muxmask[] = { - { - .group = 0, - .mask = BIT(27) | BIT(28) | BIT(29), - }, -}; - -static const struct sirfsoc_padmux sdmmc2_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask), - .muxmask = sdmmc2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(11), - .funcval = 0, -}; - -static const unsigned sdmmc2_pins[] = { 27, 28, 29 }; - -static const struct sirfsoc_muxmask sdmmc2_nowp_muxmask[] = { - { - .group = 0, - .mask = BIT(27) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux sdmmc2_nowp_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc2_nowp_muxmask), - .muxmask = sdmmc2_nowp_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(11), - .funcval = 0, -}; - -static const unsigned sdmmc2_nowp_pins[] = { 27, 28 }; - -static const struct sirfsoc_muxmask cko0_muxmask[] = { - { - .group = 2, - .mask = BIT(14), - }, -}; - -static const struct sirfsoc_padmux cko0_padmux = { - .muxmask_counts = ARRAY_SIZE(cko0_muxmask), - .muxmask = cko0_muxmask, -}; - -static const unsigned cko0_pins[] = { 78 }; - -static const struct sirfsoc_muxmask vip_muxmask[] = { - { - .group = 1, - .mask = BIT(4) | BIT(5) | BIT(6) | BIT(8) | BIT(9) - | BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28) | - BIT(29), - }, -}; - -static const struct sirfsoc_padmux vip_padmux = { - .muxmask_counts = ARRAY_SIZE(vip_muxmask), - .muxmask = vip_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(18), - .funcval = BIT(18), -}; - -static const unsigned vip_pins[] = { 36, 37, 38, 40, 41, 56, 57, 58, 59, - 60, 61 }; - -static const struct sirfsoc_muxmask vip_noupli_muxmask[] = { - { - .group = 0, - .mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) - | BIT(21) | BIT(22) | BIT(23), - }, { - .group = 2, - .mask = BIT(23) | BIT(24) | BIT(25), - }, -}; - -static const struct sirfsoc_padmux vip_noupli_padmux = { - .muxmask_counts = ARRAY_SIZE(vip_noupli_muxmask), - .muxmask = vip_noupli_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(15), - .funcval = BIT(15), -}; - -static const unsigned vip_noupli_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, - 87, 88, 89 }; - -static const struct sirfsoc_muxmask i2c0_muxmask[] = { - { - .group = 2, - .mask = BIT(26) | BIT(27), - }, -}; - -static const struct sirfsoc_padmux i2c0_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c0_muxmask), - .muxmask = i2c0_muxmask, -}; - -static const unsigned i2c0_pins[] = { 90, 91 }; - -static const struct sirfsoc_muxmask i2c1_muxmask[] = { - { - .group = 0, - .mask = BIT(13) | BIT(15), - }, -}; - -static const struct sirfsoc_padmux i2c1_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c1_muxmask), - .muxmask = i2c1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(16), - .funcval = 0, -}; - -static const unsigned i2c1_pins[] = { 13, 15 }; - -static const struct sirfsoc_muxmask pwm0_muxmask[] = { - { - .group = 0, - .mask = BIT(4), - }, -}; - -static const struct sirfsoc_padmux pwm0_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm0_muxmask), - .muxmask = pwm0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(12), - .funcval = 0, -}; - -static const unsigned pwm0_pins[] = { 4 }; - -static const struct sirfsoc_muxmask pwm1_muxmask[] = { - { - .group = 0, - .mask = BIT(5), - }, -}; - -static const struct sirfsoc_padmux pwm1_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm1_muxmask), - .muxmask = pwm1_muxmask, -}; - -static const unsigned pwm1_pins[] = { 5 }; - -static const struct sirfsoc_muxmask pwm2_muxmask[] = { - { - .group = 0, - .mask = BIT(6), - }, -}; - -static const struct sirfsoc_padmux pwm2_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm2_muxmask), - .muxmask = pwm2_muxmask, -}; - -static const unsigned pwm2_pins[] = { 6 }; - -static const struct sirfsoc_muxmask pwm3_muxmask[] = { - { - .group = 0, - .mask = BIT(7), - }, -}; - -static const struct sirfsoc_padmux pwm3_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm3_muxmask), - .muxmask = pwm3_muxmask, -}; - -static const unsigned pwm3_pins[] = { 7 }; - -static const struct sirfsoc_muxmask pwm4_muxmask[] = { - { - .group = 2, - .mask = BIT(14), - }, -}; - -static const struct sirfsoc_padmux pwm4_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm4_muxmask), - .muxmask = pwm4_muxmask, -}; - -static const unsigned pwm4_pins[] = { 78 }; - -static const struct sirfsoc_muxmask warm_rst_muxmask[] = { - { - .group = 0, - .mask = BIT(8), - }, -}; - -static const struct sirfsoc_padmux warm_rst_padmux = { - .muxmask_counts = ARRAY_SIZE(warm_rst_muxmask), - .muxmask = warm_rst_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned warm_rst_pins[] = { 8 }; - -static const struct sirfsoc_muxmask usb0_upli_drvbus_muxmask[] = { - { - .group = 1, - .mask = BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) - | BIT(9) | BIT(24) | BIT(25) | BIT(26) | - BIT(27) | BIT(28) | BIT(29), - }, -}; -static const struct sirfsoc_padmux usb0_upli_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb0_upli_drvbus_muxmask), - .muxmask = usb0_upli_drvbus_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(18), - .funcval = 0, -}; - -static const unsigned usb0_upli_drvbus_pins[] = { 36, 37, 38, 39, 40, - 41, 56, 57, 58, 59, 60, 61 }; - -static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = { - { - .group = 0, - .mask = BIT(28), - }, -}; - -static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask), - .muxmask = usb1_utmi_drvbus_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(11), - .funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */ -}; - -static const unsigned usb1_utmi_drvbus_pins[] = { 28 }; - -static const struct sirfsoc_padmux usb1_dp_dn_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE, - .funcmask = BIT(2), - .funcval = BIT(2), -}; - -static const unsigned usb1_dp_dn_pins[] = { 103, 104 }; - -static const struct sirfsoc_padmux uart1_route_io_usb1_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE, - .funcmask = BIT(2), - .funcval = 0, -}; - -static const unsigned uart1_route_io_usb1_pins[] = { 103, 104 }; - -static const struct sirfsoc_muxmask pulse_count_muxmask[] = { - { - .group = 0, - .mask = BIT(9) | BIT(10) | BIT(11), - }, -}; - -static const struct sirfsoc_padmux pulse_count_padmux = { - .muxmask_counts = ARRAY_SIZE(pulse_count_muxmask), - .muxmask = pulse_count_muxmask, -}; - -static const unsigned pulse_count_pins[] = { 9, 10, 11 }; - -static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = { - SIRFSOC_PIN_GROUP("lcd_16bitsgrp", lcd_16bits_pins), - SIRFSOC_PIN_GROUP("lcd_18bitsgrp", lcd_18bits_pins), - SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins), - SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins), - SIRFSOC_PIN_GROUP("uart0grp", uart0_pins), - SIRFSOC_PIN_GROUP("uart0_nostreamctrlgrp", uart0_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("uart1grp", uart1_pins), - SIRFSOC_PIN_GROUP("uart2grp", uart2_pins), - SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp0grp", usp0_pins), - SIRFSOC_PIN_GROUP("usp0_uart_nostreamctrl_grp", - usp0_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp0_only_utfs_grp", usp0_only_utfs_pins), - SIRFSOC_PIN_GROUP("usp0_only_urfs_grp", usp0_only_urfs_pins), - SIRFSOC_PIN_GROUP("usp1grp", usp1_pins), - SIRFSOC_PIN_GROUP("usp1_uart_nostreamctrl_grp", - usp1_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins), - SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins), - SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins), - SIRFSOC_PIN_GROUP("pwm1grp", pwm1_pins), - SIRFSOC_PIN_GROUP("pwm2grp", pwm2_pins), - SIRFSOC_PIN_GROUP("pwm3grp", pwm3_pins), - SIRFSOC_PIN_GROUP("pwm4grp", pwm4_pins), - SIRFSOC_PIN_GROUP("vipgrp", vip_pins), - SIRFSOC_PIN_GROUP("vip_noupligrp", vip_noupli_pins), - SIRFSOC_PIN_GROUP("warm_rstgrp", warm_rst_pins), - SIRFSOC_PIN_GROUP("cko0grp", cko0_pins), - SIRFSOC_PIN_GROUP("cko1grp", cko1_pins), - SIRFSOC_PIN_GROUP("sdmmc0grp", sdmmc0_pins), - SIRFSOC_PIN_GROUP("sdmmc1grp", sdmmc1_pins), - SIRFSOC_PIN_GROUP("sdmmc2grp", sdmmc2_pins), - SIRFSOC_PIN_GROUP("sdmmc2_nowpgrp", sdmmc2_nowp_pins), - SIRFSOC_PIN_GROUP("sdmmc3grp", sdmmc3_pins), - SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins), - SIRFSOC_PIN_GROUP("usb0_upli_drvbusgrp", usb0_upli_drvbus_pins), - SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins), - SIRFSOC_PIN_GROUP("usb1_dp_dngrp", usb1_dp_dn_pins), - SIRFSOC_PIN_GROUP("uart1_route_io_usb1grp", uart1_route_io_usb1_pins), - SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins), - SIRFSOC_PIN_GROUP("i2smclkgrp", i2s_mclk_pins), - SIRFSOC_PIN_GROUP("i2s_ext_clk_inputgrp", i2s_ext_clk_input_pins), - SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins), - SIRFSOC_PIN_GROUP("i2s_no_dingrp", i2s_no_din_pins), - SIRFSOC_PIN_GROUP("i2s_6chngrp", i2s_6chn_pins), - SIRFSOC_PIN_GROUP("ac97grp", ac97_pins), - SIRFSOC_PIN_GROUP("nandgrp", nand_pins), - SIRFSOC_PIN_GROUP("spi0grp", spi0_pins), - SIRFSOC_PIN_GROUP("spi1grp", spi1_pins), - SIRFSOC_PIN_GROUP("gpsgrp", gps_pins), -}; - -static const char * const lcd_16bitsgrp[] = { "lcd_16bitsgrp" }; -static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" }; -static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" }; -static const char * const lcdromgrp[] = { "lcdromgrp" }; -static const char * const uart0grp[] = { "uart0grp" }; -static const char * const uart0_nostreamctrlgrp[] = { "uart0_nostreamctrlgrp" }; -static const char * const uart1grp[] = { "uart1grp" }; -static const char * const uart2grp[] = { "uart2grp" }; -static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" }; -static const char * const usp0_uart_nostreamctrl_grp[] = { - "usp0_uart_nostreamctrl_grp" }; -static const char * const usp0grp[] = { "usp0grp" }; -static const char * const usp0_only_utfs_grp[] = { "usp0_only_utfs_grp" }; -static const char * const usp0_only_urfs_grp[] = { "usp0_only_urfs_grp" }; - -static const char * const usp1grp[] = { "usp1grp" }; -static const char * const usp1_uart_nostreamctrl_grp[] = { - "usp1_uart_nostreamctrl_grp" }; -static const char * const i2c0grp[] = { "i2c0grp" }; -static const char * const i2c1grp[] = { "i2c1grp" }; -static const char * const pwm0grp[] = { "pwm0grp" }; -static const char * const pwm1grp[] = { "pwm1grp" }; -static const char * const pwm2grp[] = { "pwm2grp" }; -static const char * const pwm3grp[] = { "pwm3grp" }; -static const char * const pwm4grp[] = { "pwm4grp" }; -static const char * const vipgrp[] = { "vipgrp" }; -static const char * const vip_noupligrp[] = { "vip_noupligrp" }; -static const char * const warm_rstgrp[] = { "warm_rstgrp" }; -static const char * const cko0grp[] = { "cko0grp" }; -static const char * const cko1grp[] = { "cko1grp" }; -static const char * const sdmmc0grp[] = { "sdmmc0grp" }; -static const char * const sdmmc1grp[] = { "sdmmc1grp" }; -static const char * const sdmmc2grp[] = { "sdmmc2grp" }; -static const char * const sdmmc3grp[] = { "sdmmc3grp" }; -static const char * const sdmmc5grp[] = { "sdmmc5grp" }; -static const char * const sdmmc2_nowpgrp[] = { "sdmmc2_nowpgrp" }; -static const char * const usb0_upli_drvbusgrp[] = { "usb0_upli_drvbusgrp" }; -static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" }; -static const char * const usb1_dp_dngrp[] = { "usb1_dp_dngrp" }; -static const char * const - uart1_route_io_usb1grp[] = { "uart1_route_io_usb1grp" }; -static const char * const pulse_countgrp[] = { "pulse_countgrp" }; -static const char * const i2smclkgrp[] = { "i2smclkgrp" }; -static const char * const i2s_ext_clk_inputgrp[] = { "i2s_ext_clk_inputgrp" }; -static const char * const i2sgrp[] = { "i2sgrp" }; -static const char * const i2s_no_dingrp[] = { "i2s_no_dingrp" }; -static const char * const i2s_6chngrp[] = { "i2s_6chngrp" }; -static const char * const ac97grp[] = { "ac97grp" }; -static const char * const nandgrp[] = { "nandgrp" }; -static const char * const spi0grp[] = { "spi0grp" }; -static const char * const spi1grp[] = { "spi1grp" }; -static const char * const gpsgrp[] = { "gpsgrp" }; - -static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = { - SIRFSOC_PMX_FUNCTION("lcd_16bits", lcd_16bitsgrp, lcd_16bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_18bits", lcd_18bitsgrp, lcd_18bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux), - SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux), - SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux), - SIRFSOC_PMX_FUNCTION("uart0_nostreamctrl", uart0_nostreamctrlgrp, - uart0_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux), - SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux), - SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", - uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux), - SIRFSOC_PMX_FUNCTION("usp0_uart_nostreamctrl", - usp0_uart_nostreamctrl_grp, - usp0_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp0_only_utfs", usp0_only_utfs_grp, - usp0_only_utfs_padmux), - SIRFSOC_PMX_FUNCTION("usp0_only_urfs", usp0_only_urfs_grp, - usp0_only_urfs_padmux), - SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux), - SIRFSOC_PMX_FUNCTION("usp1_uart_nostreamctrl", - usp1_uart_nostreamctrl_grp, - usp1_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux), - SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux), - SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux), - SIRFSOC_PMX_FUNCTION("pwm1", pwm1grp, pwm1_padmux), - SIRFSOC_PMX_FUNCTION("pwm2", pwm2grp, pwm2_padmux), - SIRFSOC_PMX_FUNCTION("pwm3", pwm3grp, pwm3_padmux), - SIRFSOC_PMX_FUNCTION("pwm4", pwm4grp, pwm4_padmux), - SIRFSOC_PMX_FUNCTION("vip", vipgrp, vip_padmux), - SIRFSOC_PMX_FUNCTION("vip_noupli", vip_noupligrp, vip_noupli_padmux), - SIRFSOC_PMX_FUNCTION("warm_rst", warm_rstgrp, warm_rst_padmux), - SIRFSOC_PMX_FUNCTION("cko0", cko0grp, cko0_padmux), - SIRFSOC_PMX_FUNCTION("cko1", cko1grp, cko1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc0", sdmmc0grp, sdmmc0_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc1", sdmmc1grp, sdmmc1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc2", sdmmc2grp, sdmmc2_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc3", sdmmc3grp, sdmmc3_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc2_nowp", - sdmmc2_nowpgrp, sdmmc2_nowp_padmux), - SIRFSOC_PMX_FUNCTION("usb0_upli_drvbus", - usb0_upli_drvbusgrp, usb0_upli_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", - usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("usb1_dp_dn", usb1_dp_dngrp, usb1_dp_dn_padmux), - SIRFSOC_PMX_FUNCTION("uart1_route_io_usb1", - uart1_route_io_usb1grp, uart1_route_io_usb1_padmux), - SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux), - SIRFSOC_PMX_FUNCTION("i2s_mclk", i2smclkgrp, i2s_mclk_padmux), - SIRFSOC_PMX_FUNCTION("i2s_ext_clk_input", i2s_ext_clk_inputgrp, - i2s_ext_clk_input_padmux), - SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux), - SIRFSOC_PMX_FUNCTION("i2s_no_din", i2s_no_dingrp, i2s_no_din_padmux), - SIRFSOC_PMX_FUNCTION("i2s_6chn", i2s_6chngrp, i2s_6chn_padmux), - SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux), - SIRFSOC_PMX_FUNCTION("nand", nandgrp, nand_padmux), - SIRFSOC_PMX_FUNCTION("spi0", spi0grp, spi0_padmux), - SIRFSOC_PMX_FUNCTION("spi1", spi1grp, spi1_padmux), - SIRFSOC_PMX_FUNCTION("gps", gpsgrp, gps_padmux), -}; - -struct sirfsoc_pinctrl_data atlas6_pinctrl_data = { - (struct pinctrl_pin_desc *)sirfsoc_pads, - ARRAY_SIZE(sirfsoc_pads), - (struct sirfsoc_pin_group *)sirfsoc_pin_groups, - ARRAY_SIZE(sirfsoc_pin_groups), - (struct sirfsoc_pmx_func *)sirfsoc_pmx_functions, - ARRAY_SIZE(sirfsoc_pmx_functions), -}; - diff --git a/drivers/pinctrl/sirf/pinctrl-atlas7.c b/drivers/pinctrl/sirf/pinctrl-atlas7.c deleted file mode 100644 index e54a6e3cafd2..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-atlas7.c +++ /dev/null @@ -1,6157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pinctrl pads, groups, functions for CSR SiRFatlasVII - * - * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group - * company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Definition of Pad&Mux Properties */ -#define N 0 - -/* The Bank contains input-disable regisgers */ -#define BANK_DS 0 - -/* Clear Register offset */ -#define CLR_REG(r) ((r) + 0x04) - -/* Definition of multiple function select register */ -#define FUNC_CLEAR_MASK 0x7 -#define FUNC_GPIO 0 -#define FUNC_ANALOGUE 0x8 -#define ANA_CLEAR_MASK 0x1 - -/* The Atlas7's Pad Type List */ -enum altas7_pad_type { - PAD_T_4WE_PD = 0, /* ZIO_PAD3V_4WE_PD */ - PAD_T_4WE_PU, /* ZIO_PAD3V_4WE_PD */ - PAD_T_16ST, /* ZIO_PAD3V_SDCLK_PD */ - PAD_T_M31_0204_PD, /* PRDW0204SDGZ_M311311_PD */ - PAD_T_M31_0204_PU, /* PRDW0204SDGZ_M311311_PU */ - PAD_T_M31_0610_PD, /* PRUW0610SDGZ_M311311_PD */ - PAD_T_M31_0610_PU, /* PRUW0610SDGZ_M311311_PU */ - PAD_T_AD, /* PRDWUWHW08SCDG_HZ */ -}; - -/* Raw value of Driver-Strength Bits */ -#define DS3 BIT(3) -#define DS2 BIT(2) -#define DS1 BIT(1) -#define DS0 BIT(0) -#define DSZ 0 - -/* Drive-Strength Intermediate Values */ -#define DS_NULL -1 -#define DS_1BIT_IM_VAL DS0 -#define DS_1BIT_MASK 0x1 -#define DS_2BIT_IM_VAL (DS1 | DS0) -#define DS_2BIT_MASK 0x3 -#define DS_4BIT_IM_VAL (DS3 | DS2 | DS1 | DS0) -#define DS_4BIT_MASK 0xf - -/* The Drive-Strength of 4WE Pad DS1 0 CO */ -#define DS_4WE_3 (DS1 | DS0) /* 1 1 3 */ -#define DS_4WE_2 (DS1) /* 1 0 2 */ -#define DS_4WE_1 (DS0) /* 0 1 1 */ -#define DS_4WE_0 (DSZ) /* 0 0 0 */ - -/* The Drive-Strength of 16st Pad DS3 2 1 0 CO */ -#define DS_16ST_15 (DS3 | DS2 | DS1 | DS0) /* 1 1 1 1 15 */ -#define DS_16ST_14 (DS3 | DS2 | DS0) /* 1 1 0 1 13 */ -#define DS_16ST_13 (DS3 | DS2 | DS1) /* 1 1 1 0 14 */ -#define DS_16ST_12 (DS2 | DS1 | DS0) /* 0 1 1 1 7 */ -#define DS_16ST_11 (DS2 | DS0) /* 0 1 0 1 5 */ -#define DS_16ST_10 (DS3 | DS1 | DS0) /* 1 0 1 1 11 */ -#define DS_16ST_9 (DS3 | DS0) /* 1 0 0 1 9 */ -#define DS_16ST_8 (DS1 | DS0) /* 0 0 1 1 3 */ -#define DS_16ST_7 (DS2 | DS1) /* 0 1 1 0 6 */ -#define DS_16ST_6 (DS3 | DS2) /* 1 1 0 0 12 */ -#define DS_16ST_5 (DS2) /* 0 1 0 0 4 */ -#define DS_16ST_4 (DS3 | DS1) /* 1 0 1 0 10 */ -#define DS_16ST_3 (DS1) /* 0 0 1 0 2 */ -#define DS_16ST_2 (DS0) /* 0 0 0 1 1 */ -#define DS_16ST_1 (DSZ) /* 0 0 0 0 0 */ -#define DS_16ST_0 (DS3) /* 1 0 0 0 8 */ - -/* The Drive-Strength of M31 Pad DS0 CO */ -#define DS_M31_0 (DSZ) /* 0 0 */ -#define DS_M31_1 (DS0) /* 1 1 */ - -/* Raw values of Pull Option Bits */ -#define PUN BIT(1) -#define PD BIT(0) -#define PE BIT(0) -#define PZ 0 - -/* Definition of Pull Types */ -#define PULL_UP 0 -#define HIGH_HYSTERESIS 1 -#define HIGH_Z 2 -#define PULL_DOWN 3 -#define PULL_DISABLE 4 -#define PULL_ENABLE 5 -#define PULL_UNKNOWN -1 - -/* Pull Options for 4WE Pad PUN PD CO */ -#define P4WE_PULL_MASK 0x3 -#define P4WE_PULL_DOWN (PUN | PD) /* 1 1 3 */ -#define P4WE_HIGH_Z (PUN) /* 1 0 2 */ -#define P4WE_HIGH_HYSTERESIS (PD) /* 0 1 1 */ -#define P4WE_PULL_UP (PZ) /* 0 0 0 */ - -/* Pull Options for 16ST Pad PUN PD CO */ -#define P16ST_PULL_MASK 0x3 -#define P16ST_PULL_DOWN (PUN | PD) /* 1 1 3 */ -#define P16ST_HIGH_Z (PUN) /* 1 0 2 */ -#define P16ST_PULL_UP (PZ) /* 0 0 0 */ - -/* Pull Options for M31 Pad PE */ -#define PM31_PULL_MASK 0x1 -#define PM31_PULL_ENABLED (PE) /* 1 */ -#define PM31_PULL_DISABLED (PZ) /* 0 */ - -/* Pull Options for A/D Pad PUN PD CO */ -#define PANGD_PULL_MASK 0x3 -#define PANGD_PULL_DOWN (PUN | PD) /* 1 1 3 */ -#define PANGD_HIGH_Z (PUN) /* 1 0 2 */ -#define PANGD_PULL_UP (PZ) /* 0 0 0 */ - -/* Definition of Input Disable */ -#define DI_MASK 0x1 -#define DI_DISABLE 0x1 -#define DI_ENABLE 0x0 - -/* Definition of Input Disable Value */ -#define DIV_MASK 0x1 -#define DIV_DISABLE 0x1 -#define DIV_ENABLE 0x0 - -/* Number of Function input disable registers */ -#define NUM_OF_IN_DISABLE_REG 0x2 - -/* Offset of Function input disable registers */ -#define IN_DISABLE_0_REG_SET 0x0A00 -#define IN_DISABLE_0_REG_CLR 0x0A04 -#define IN_DISABLE_1_REG_SET 0x0A08 -#define IN_DISABLE_1_REG_CLR 0x0A0C -#define IN_DISABLE_VAL_0_REG_SET 0x0A80 -#define IN_DISABLE_VAL_0_REG_CLR 0x0A84 -#define IN_DISABLE_VAL_1_REG_SET 0x0A88 -#define IN_DISABLE_VAL_1_REG_CLR 0x0A8C - -/* Offset of the SDIO9SEL*/ -#define SYS2PCI_SDIO9SEL 0x14 - -struct dt_params { - const char *property; - int value; -}; - -/** - * struct atlas7_pad_conf - Atlas7 Pad Configuration - * @id: The ID of this Pad. - * @type: The type of this Pad. - * @mux_reg: The mux register offset. - * This register contains the mux. - * @pupd_reg: The pull-up/down register offset. - * @drvstr_reg: The drive-strength register offset. - * @ad_ctrl_reg: The Analogue/Digital Control register. - * - * @mux_bit: The start bit of mux register. - * @pupd_bit: The start bit of pull-up/down register. - * @drvstr_bit: The start bit of drive-strength register. - * @ad_ctrl_bit: The start bit of analogue/digital register. - */ -struct atlas7_pad_config { - const u32 id; - u32 type; - u32 mux_reg; - u32 pupd_reg; - u32 drvstr_reg; - u32 ad_ctrl_reg; - /* bits in register */ - u8 mux_bit; - u8 pupd_bit; - u8 drvstr_bit; - u8 ad_ctrl_bit; -}; - -#define PADCONF(pad, t, mr, pr, dsr, adr, mb, pb, dsb, adb) \ - { \ - .id = pad, \ - .type = t, \ - .mux_reg = mr, \ - .pupd_reg = pr, \ - .drvstr_reg = dsr, \ - .ad_ctrl_reg = adr, \ - .mux_bit = mb, \ - .pupd_bit = pb, \ - .drvstr_bit = dsb, \ - .ad_ctrl_bit = adb, \ - } - -/* - * struct atlas7_pad_status - Atlas7 Pad status - */ -struct atlas7_pad_status { - u8 func; - u8 pull; - u8 dstr; - u8 reserved; -}; - -/** - * struct atlas7_pad_mux - Atlas7 mux - * @bank: The bank of this pad's registers on. - * @pin : The ID of this Pad. - * @func: The mux func on this Pad. - * @dinput_reg: The Input-Disable register offset. - * @dinput_bit: The start bit of Input-Disable register. - * @dinput_val_reg: The Input-Disable-value register offset. - * This register is used to set the value of this pad - * if this pad was disabled. - * @dinput_val_bit: The start bit of Input-Disable Value register. - */ -struct atlas7_pad_mux { - u32 bank; - u32 pin; - u32 func; - u32 dinput_reg; - u32 dinput_bit; - u32 dinput_val_reg; - u32 dinput_val_bit; -}; - -#define MUX(b, pad, f, dr, db, dvr, dvb) \ - { \ - .bank = b, \ - .pin = pad, \ - .func = f, \ - .dinput_reg = dr, \ - .dinput_bit = db, \ - .dinput_val_reg = dvr, \ - .dinput_val_bit = dvb, \ - } - -struct atlas7_grp_mux { - unsigned int group; - unsigned int pad_mux_count; - const struct atlas7_pad_mux *pad_mux_list; -}; - - /** - * struct sirfsoc_pin_group - describes a SiRFprimaII pin group - * @name: the name of this specific pin group - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @num_pins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array - */ -struct atlas7_pin_group { - const char *name; - const unsigned int *pins; - const unsigned num_pins; -}; - -#define GROUP(n, p) \ - { \ - .name = n, \ - .pins = p, \ - .num_pins = ARRAY_SIZE(p), \ - } - -struct atlas7_pmx_func { - const char *name; - const char * const *groups; - const unsigned num_groups; - const struct atlas7_grp_mux *grpmux; -}; - -#define FUNCTION(n, g, m) \ - { \ - .name = n, \ - .groups = g, \ - .num_groups = ARRAY_SIZE(g), \ - .grpmux = m, \ - } - -struct atlas7_pinctrl_data { - struct pinctrl_pin_desc *pads; - int pads_cnt; - struct atlas7_pin_group *grps; - int grps_cnt; - struct atlas7_pmx_func *funcs; - int funcs_cnt; - struct atlas7_pad_config *confs; - int confs_cnt; -}; - -/* Platform info of atlas7 pinctrl */ -#define ATLAS7_PINCTRL_REG_BANKS 2 -#define ATLAS7_PINCTRL_BANK_0_PINS 18 -#define ATLAS7_PINCTRL_BANK_1_PINS 141 -#define ATLAS7_PINCTRL_TOTAL_PINS \ - (ATLAS7_PINCTRL_BANK_0_PINS + ATLAS7_PINCTRL_BANK_1_PINS) - -/** - * Atlas7 GPIO Chip - */ - -#define NGPIO_OF_BANK 32 -#define GPIO_TO_BANK(gpio) ((gpio) / NGPIO_OF_BANK) - -/* Registers of GPIO Controllers */ -#define ATLAS7_GPIO_BASE(g, b) ((g)->reg + 0x100 * (b)) -#define ATLAS7_GPIO_CTRL(b, i) ((b)->base + 4 * (i)) -#define ATLAS7_GPIO_INT_STATUS(b) ((b)->base + 0x8C) - -/* Definition bits of GPIO Control Registers */ -#define ATLAS7_GPIO_CTL_INTR_LOW_MASK BIT(0) -#define ATLAS7_GPIO_CTL_INTR_HIGH_MASK BIT(1) -#define ATLAS7_GPIO_CTL_INTR_TYPE_MASK BIT(2) -#define ATLAS7_GPIO_CTL_INTR_EN_MASK BIT(3) -#define ATLAS7_GPIO_CTL_INTR_STATUS_MASK BIT(4) -#define ATLAS7_GPIO_CTL_OUT_EN_MASK BIT(5) -#define ATLAS7_GPIO_CTL_DATAOUT_MASK BIT(6) -#define ATLAS7_GPIO_CTL_DATAIN_MASK BIT(7) - -struct atlas7_gpio_bank { - int id; - int irq; - void __iomem *base; - unsigned int gpio_offset; - unsigned int ngpio; - const unsigned int *gpio_pins; - u32 sleep_data[NGPIO_OF_BANK]; -}; - -struct atlas7_gpio_chip { - const char *name; - void __iomem *reg; - struct clk *clk; - int nbank; - raw_spinlock_t lock; - struct gpio_chip chip; - struct atlas7_gpio_bank banks[]; -}; - -struct atlas7_pmx { - struct device *dev; - struct pinctrl_dev *pctl; - struct pinctrl_desc pctl_desc; - struct atlas7_pinctrl_data *pctl_data; - void __iomem *regs[ATLAS7_PINCTRL_REG_BANKS]; - void __iomem *sys2pci_base; - u32 status_ds[NUM_OF_IN_DISABLE_REG]; - u32 status_dsv[NUM_OF_IN_DISABLE_REG]; - struct atlas7_pad_status sleep_data[ATLAS7_PINCTRL_TOTAL_PINS]; -}; - -/* - * Pad list for the pinmux subsystem - * refer to A7DA IO Summary - CS-314158-DD-4E.xls - */ - -/* Pads in IOC RTC & TOP */ -static const struct pinctrl_pin_desc atlas7_ioc_pads[] = { - /* RTC PADs */ - PINCTRL_PIN(0, "rtc_gpio_0"), - PINCTRL_PIN(1, "rtc_gpio_1"), - PINCTRL_PIN(2, "rtc_gpio_2"), - PINCTRL_PIN(3, "rtc_gpio_3"), - PINCTRL_PIN(4, "low_bat_ind_b"), - PINCTRL_PIN(5, "on_key_b"), - PINCTRL_PIN(6, "ext_on"), - PINCTRL_PIN(7, "mem_on"), - PINCTRL_PIN(8, "core_on"), - PINCTRL_PIN(9, "io_on"), - PINCTRL_PIN(10, "can0_tx"), - PINCTRL_PIN(11, "can0_rx"), - PINCTRL_PIN(12, "spi0_clk"), - PINCTRL_PIN(13, "spi0_cs_b"), - PINCTRL_PIN(14, "spi0_io_0"), - PINCTRL_PIN(15, "spi0_io_1"), - PINCTRL_PIN(16, "spi0_io_2"), - PINCTRL_PIN(17, "spi0_io_3"), - - /* TOP PADs */ - PINCTRL_PIN(18, "spi1_en"), - PINCTRL_PIN(19, "spi1_clk"), - PINCTRL_PIN(20, "spi1_din"), - PINCTRL_PIN(21, "spi1_dout"), - PINCTRL_PIN(22, "trg_spi_clk"), - PINCTRL_PIN(23, "trg_spi_di"), - PINCTRL_PIN(24, "trg_spi_do"), - PINCTRL_PIN(25, "trg_spi_cs_b"), - PINCTRL_PIN(26, "trg_acq_d1"), - PINCTRL_PIN(27, "trg_irq_b"), - PINCTRL_PIN(28, "trg_acq_d0"), - PINCTRL_PIN(29, "trg_acq_clk"), - PINCTRL_PIN(30, "trg_shutdown_b_out"), - PINCTRL_PIN(31, "sdio2_clk"), - PINCTRL_PIN(32, "sdio2_cmd"), - PINCTRL_PIN(33, "sdio2_dat_0"), - PINCTRL_PIN(34, "sdio2_dat_1"), - PINCTRL_PIN(35, "sdio2_dat_2"), - PINCTRL_PIN(36, "sdio2_dat_3"), - PINCTRL_PIN(37, "df_ad_7"), - PINCTRL_PIN(38, "df_ad_6"), - PINCTRL_PIN(39, "df_ad_5"), - PINCTRL_PIN(40, "df_ad_4"), - PINCTRL_PIN(41, "df_ad_3"), - PINCTRL_PIN(42, "df_ad_2"), - PINCTRL_PIN(43, "df_ad_1"), - PINCTRL_PIN(44, "df_ad_0"), - PINCTRL_PIN(45, "df_dqs"), - PINCTRL_PIN(46, "df_cle"), - PINCTRL_PIN(47, "df_ale"), - PINCTRL_PIN(48, "df_we_b"), - PINCTRL_PIN(49, "df_re_b"), - PINCTRL_PIN(50, "df_ry_by"), - PINCTRL_PIN(51, "df_cs_b_1"), - PINCTRL_PIN(52, "df_cs_b_0"), - PINCTRL_PIN(53, "l_pclk"), - PINCTRL_PIN(54, "l_lck"), - PINCTRL_PIN(55, "l_fck"), - PINCTRL_PIN(56, "l_de"), - PINCTRL_PIN(57, "ldd_0"), - PINCTRL_PIN(58, "ldd_1"), - PINCTRL_PIN(59, "ldd_2"), - PINCTRL_PIN(60, "ldd_3"), - PINCTRL_PIN(61, "ldd_4"), - PINCTRL_PIN(62, "ldd_5"), - PINCTRL_PIN(63, "ldd_6"), - PINCTRL_PIN(64, "ldd_7"), - PINCTRL_PIN(65, "ldd_8"), - PINCTRL_PIN(66, "ldd_9"), - PINCTRL_PIN(67, "ldd_10"), - PINCTRL_PIN(68, "ldd_11"), - PINCTRL_PIN(69, "ldd_12"), - PINCTRL_PIN(70, "ldd_13"), - PINCTRL_PIN(71, "ldd_14"), - PINCTRL_PIN(72, "ldd_15"), - PINCTRL_PIN(73, "lcd_gpio_20"), - PINCTRL_PIN(74, "vip_0"), - PINCTRL_PIN(75, "vip_1"), - PINCTRL_PIN(76, "vip_2"), - PINCTRL_PIN(77, "vip_3"), - PINCTRL_PIN(78, "vip_4"), - PINCTRL_PIN(79, "vip_5"), - PINCTRL_PIN(80, "vip_6"), - PINCTRL_PIN(81, "vip_7"), - PINCTRL_PIN(82, "vip_pxclk"), - PINCTRL_PIN(83, "vip_hsync"), - PINCTRL_PIN(84, "vip_vsync"), - PINCTRL_PIN(85, "sdio3_clk"), - PINCTRL_PIN(86, "sdio3_cmd"), - PINCTRL_PIN(87, "sdio3_dat_0"), - PINCTRL_PIN(88, "sdio3_dat_1"), - PINCTRL_PIN(89, "sdio3_dat_2"), - PINCTRL_PIN(90, "sdio3_dat_3"), - PINCTRL_PIN(91, "sdio5_clk"), - PINCTRL_PIN(92, "sdio5_cmd"), - PINCTRL_PIN(93, "sdio5_dat_0"), - PINCTRL_PIN(94, "sdio5_dat_1"), - PINCTRL_PIN(95, "sdio5_dat_2"), - PINCTRL_PIN(96, "sdio5_dat_3"), - PINCTRL_PIN(97, "rgmii_txd_0"), - PINCTRL_PIN(98, "rgmii_txd_1"), - PINCTRL_PIN(99, "rgmii_txd_2"), - PINCTRL_PIN(100, "rgmii_txd_3"), - PINCTRL_PIN(101, "rgmii_txclk"), - PINCTRL_PIN(102, "rgmii_tx_ctl"), - PINCTRL_PIN(103, "rgmii_rxd_0"), - PINCTRL_PIN(104, "rgmii_rxd_1"), - PINCTRL_PIN(105, "rgmii_rxd_2"), - PINCTRL_PIN(106, "rgmii_rxd_3"), - PINCTRL_PIN(107, "rgmii_rx_clk"), - PINCTRL_PIN(108, "rgmii_rxc_ctl"), - PINCTRL_PIN(109, "rgmii_mdio"), - PINCTRL_PIN(110, "rgmii_mdc"), - PINCTRL_PIN(111, "rgmii_intr_n"), - PINCTRL_PIN(112, "i2s_mclk"), - PINCTRL_PIN(113, "i2s_bclk"), - PINCTRL_PIN(114, "i2s_ws"), - PINCTRL_PIN(115, "i2s_dout0"), - PINCTRL_PIN(116, "i2s_dout1"), - PINCTRL_PIN(117, "i2s_dout2"), - PINCTRL_PIN(118, "i2s_din"), - PINCTRL_PIN(119, "gpio_0"), - PINCTRL_PIN(120, "gpio_1"), - PINCTRL_PIN(121, "gpio_2"), - PINCTRL_PIN(122, "gpio_3"), - PINCTRL_PIN(123, "gpio_4"), - PINCTRL_PIN(124, "gpio_5"), - PINCTRL_PIN(125, "gpio_6"), - PINCTRL_PIN(126, "gpio_7"), - PINCTRL_PIN(127, "sda_0"), - PINCTRL_PIN(128, "scl_0"), - PINCTRL_PIN(129, "coex_pio_0"), - PINCTRL_PIN(130, "coex_pio_1"), - PINCTRL_PIN(131, "coex_pio_2"), - PINCTRL_PIN(132, "coex_pio_3"), - PINCTRL_PIN(133, "uart0_tx"), - PINCTRL_PIN(134, "uart0_rx"), - PINCTRL_PIN(135, "uart1_tx"), - PINCTRL_PIN(136, "uart1_rx"), - PINCTRL_PIN(137, "uart3_tx"), - PINCTRL_PIN(138, "uart3_rx"), - PINCTRL_PIN(139, "uart4_tx"), - PINCTRL_PIN(140, "uart4_rx"), - PINCTRL_PIN(141, "usp0_clk"), - PINCTRL_PIN(142, "usp0_tx"), - PINCTRL_PIN(143, "usp0_rx"), - PINCTRL_PIN(144, "usp0_fs"), - PINCTRL_PIN(145, "usp1_clk"), - PINCTRL_PIN(146, "usp1_tx"), - PINCTRL_PIN(147, "usp1_rx"), - PINCTRL_PIN(148, "usp1_fs"), - PINCTRL_PIN(149, "lvds_tx0d4p"), - PINCTRL_PIN(150, "lvds_tx0d4n"), - PINCTRL_PIN(151, "lvds_tx0d3p"), - PINCTRL_PIN(152, "lvds_tx0d3n"), - PINCTRL_PIN(153, "lvds_tx0d2p"), - PINCTRL_PIN(154, "lvds_tx0d2n"), - PINCTRL_PIN(155, "lvds_tx0d1p"), - PINCTRL_PIN(156, "lvds_tx0d1n"), - PINCTRL_PIN(157, "lvds_tx0d0p"), - PINCTRL_PIN(158, "lvds_tx0d0n"), - PINCTRL_PIN(159, "jtag_tdo"), - PINCTRL_PIN(160, "jtag_tms"), - PINCTRL_PIN(161, "jtag_tck"), - PINCTRL_PIN(162, "jtag_tdi"), - PINCTRL_PIN(163, "jtag_trstn"), -}; - -static struct atlas7_pad_config atlas7_ioc_pad_confs[] = { - /* The Configuration of IOC_RTC Pads */ - PADCONF(0, 3, 0x0, 0x100, 0x200, -1, 0, 0, 0, 0), - PADCONF(1, 3, 0x0, 0x100, 0x200, -1, 4, 2, 2, 0), - PADCONF(2, 3, 0x0, 0x100, 0x200, -1, 8, 4, 4, 0), - PADCONF(3, 5, 0x0, 0x100, 0x200, -1, 12, 6, 6, 0), - PADCONF(4, 4, 0x0, 0x100, 0x200, -1, 16, 8, 8, 0), - PADCONF(5, 4, 0x0, 0x100, 0x200, -1, 20, 10, 10, 0), - PADCONF(6, 3, 0x0, 0x100, 0x200, -1, 24, 12, 12, 0), - PADCONF(7, 3, 0x0, 0x100, 0x200, -1, 28, 14, 14, 0), - PADCONF(8, 3, 0x8, 0x100, 0x200, -1, 0, 16, 16, 0), - PADCONF(9, 3, 0x8, 0x100, 0x200, -1, 4, 18, 18, 0), - PADCONF(10, 4, 0x8, 0x100, 0x200, -1, 8, 20, 20, 0), - PADCONF(11, 4, 0x8, 0x100, 0x200, -1, 12, 22, 22, 0), - PADCONF(12, 5, 0x8, 0x100, 0x200, -1, 16, 24, 24, 0), - PADCONF(13, 6, 0x8, 0x100, 0x200, -1, 20, 26, 26, 0), - PADCONF(14, 5, 0x8, 0x100, 0x200, -1, 24, 28, 28, 0), - PADCONF(15, 5, 0x8, 0x100, 0x200, -1, 28, 30, 30, 0), - PADCONF(16, 5, 0x10, 0x108, 0x208, -1, 0, 0, 0, 0), - PADCONF(17, 5, 0x10, 0x108, 0x208, -1, 4, 2, 2, 0), - /* The Configuration of IOC_TOP Pads */ - PADCONF(18, 5, 0x80, 0x180, 0x300, -1, 0, 0, 0, 0), - PADCONF(19, 5, 0x80, 0x180, 0x300, -1, 4, 2, 2, 0), - PADCONF(20, 5, 0x80, 0x180, 0x300, -1, 8, 4, 4, 0), - PADCONF(21, 5, 0x80, 0x180, 0x300, -1, 12, 6, 6, 0), - PADCONF(22, 5, 0x88, 0x188, 0x308, -1, 0, 0, 0, 0), - PADCONF(23, 5, 0x88, 0x188, 0x308, -1, 4, 2, 2, 0), - PADCONF(24, 5, 0x88, 0x188, 0x308, -1, 8, 4, 4, 0), - PADCONF(25, 6, 0x88, 0x188, 0x308, -1, 12, 6, 6, 0), - PADCONF(26, 5, 0x88, 0x188, 0x308, -1, 16, 8, 8, 0), - PADCONF(27, 6, 0x88, 0x188, 0x308, -1, 20, 10, 10, 0), - PADCONF(28, 5, 0x88, 0x188, 0x308, -1, 24, 12, 12, 0), - PADCONF(29, 5, 0x88, 0x188, 0x308, -1, 28, 14, 14, 0), - PADCONF(30, 5, 0x90, 0x188, 0x308, -1, 0, 16, 16, 0), - PADCONF(31, 2, 0x98, 0x190, 0x310, -1, 0, 0, 0, 0), - PADCONF(32, 1, 0x98, 0x190, 0x310, -1, 4, 2, 4, 0), - PADCONF(33, 1, 0x98, 0x190, 0x310, -1, 8, 4, 6, 0), - PADCONF(34, 1, 0x98, 0x190, 0x310, -1, 12, 6, 8, 0), - PADCONF(35, 1, 0x98, 0x190, 0x310, -1, 16, 8, 10, 0), - PADCONF(36, 1, 0x98, 0x190, 0x310, -1, 20, 10, 12, 0), - PADCONF(37, 1, 0xa0, 0x198, 0x318, -1, 0, 0, 0, 0), - PADCONF(38, 1, 0xa0, 0x198, 0x318, -1, 4, 2, 2, 0), - PADCONF(39, 1, 0xa0, 0x198, 0x318, -1, 8, 4, 4, 0), - PADCONF(40, 1, 0xa0, 0x198, 0x318, -1, 12, 6, 6, 0), - PADCONF(41, 1, 0xa0, 0x198, 0x318, -1, 16, 8, 8, 0), - PADCONF(42, 1, 0xa0, 0x198, 0x318, -1, 20, 10, 10, 0), - PADCONF(43, 1, 0xa0, 0x198, 0x318, -1, 24, 12, 12, 0), - PADCONF(44, 1, 0xa0, 0x198, 0x318, -1, 28, 14, 14, 0), - PADCONF(45, 0, 0xa8, 0x198, 0x318, -1, 0, 16, 16, 0), - PADCONF(46, 0, 0xa8, 0x198, 0x318, -1, 4, 18, 18, 0), - PADCONF(47, 1, 0xa8, 0x198, 0x318, -1, 8, 20, 20, 0), - PADCONF(48, 1, 0xa8, 0x198, 0x318, -1, 12, 22, 22, 0), - PADCONF(49, 1, 0xa8, 0x198, 0x318, -1, 16, 24, 24, 0), - PADCONF(50, 1, 0xa8, 0x198, 0x318, -1, 20, 26, 26, 0), - PADCONF(51, 1, 0xa8, 0x198, 0x318, -1, 24, 28, 28, 0), - PADCONF(52, 1, 0xa8, 0x198, 0x318, -1, 28, 30, 30, 0), - PADCONF(53, 0, 0xb0, 0x1a0, 0x320, -1, 0, 0, 0, 0), - PADCONF(54, 0, 0xb0, 0x1a0, 0x320, -1, 4, 2, 2, 0), - PADCONF(55, 0, 0xb0, 0x1a0, 0x320, -1, 8, 4, 4, 0), - PADCONF(56, 0, 0xb0, 0x1a0, 0x320, -1, 12, 6, 6, 0), - PADCONF(57, 0, 0xb0, 0x1a0, 0x320, -1, 16, 8, 8, 0), - PADCONF(58, 0, 0xb0, 0x1a0, 0x320, -1, 20, 10, 10, 0), - PADCONF(59, 0, 0xb0, 0x1a0, 0x320, -1, 24, 12, 12, 0), - PADCONF(60, 0, 0xb0, 0x1a0, 0x320, -1, 28, 14, 14, 0), - PADCONF(61, 0, 0xb8, 0x1a0, 0x320, -1, 0, 16, 16, 0), - PADCONF(62, 0, 0xb8, 0x1a0, 0x320, -1, 4, 18, 18, 0), - PADCONF(63, 0, 0xb8, 0x1a0, 0x320, -1, 8, 20, 20, 0), - PADCONF(64, 0, 0xb8, 0x1a0, 0x320, -1, 12, 22, 22, 0), - PADCONF(65, 0, 0xb8, 0x1a0, 0x320, -1, 16, 24, 24, 0), - PADCONF(66, 0, 0xb8, 0x1a0, 0x320, -1, 20, 26, 26, 0), - PADCONF(67, 0, 0xb8, 0x1a0, 0x320, -1, 24, 28, 28, 0), - PADCONF(68, 0, 0xb8, 0x1a0, 0x320, -1, 28, 30, 30, 0), - PADCONF(69, 0, 0xc0, 0x1a8, 0x328, -1, 0, 0, 0, 0), - PADCONF(70, 0, 0xc0, 0x1a8, 0x328, -1, 4, 2, 2, 0), - PADCONF(71, 0, 0xc0, 0x1a8, 0x328, -1, 8, 4, 4, 0), - PADCONF(72, 0, 0xc0, 0x1a8, 0x328, -1, 12, 6, 6, 0), - PADCONF(73, 0, 0xc0, 0x1a8, 0x328, -1, 16, 8, 8, 0), - PADCONF(74, 0, 0xc8, 0x1b0, 0x330, -1, 0, 0, 0, 0), - PADCONF(75, 0, 0xc8, 0x1b0, 0x330, -1, 4, 2, 2, 0), - PADCONF(76, 0, 0xc8, 0x1b0, 0x330, -1, 8, 4, 4, 0), - PADCONF(77, 0, 0xc8, 0x1b0, 0x330, -1, 12, 6, 6, 0), - PADCONF(78, 0, 0xc8, 0x1b0, 0x330, -1, 16, 8, 8, 0), - PADCONF(79, 0, 0xc8, 0x1b0, 0x330, -1, 20, 10, 10, 0), - PADCONF(80, 0, 0xc8, 0x1b0, 0x330, -1, 24, 12, 12, 0), - PADCONF(81, 0, 0xc8, 0x1b0, 0x330, -1, 28, 14, 14, 0), - PADCONF(82, 0, 0xd0, 0x1b0, 0x330, -1, 0, 16, 16, 0), - PADCONF(83, 0, 0xd0, 0x1b0, 0x330, -1, 4, 18, 18, 0), - PADCONF(84, 0, 0xd0, 0x1b0, 0x330, -1, 8, 20, 20, 0), - PADCONF(85, 2, 0xd8, 0x1b8, 0x338, -1, 0, 0, 0, 0), - PADCONF(86, 1, 0xd8, 0x1b8, 0x338, -1, 4, 4, 4, 0), - PADCONF(87, 1, 0xd8, 0x1b8, 0x338, -1, 8, 6, 6, 0), - PADCONF(88, 1, 0xd8, 0x1b8, 0x338, -1, 12, 8, 8, 0), - PADCONF(89, 1, 0xd8, 0x1b8, 0x338, -1, 16, 10, 10, 0), - PADCONF(90, 1, 0xd8, 0x1b8, 0x338, -1, 20, 12, 12, 0), - PADCONF(91, 2, 0xe0, 0x1c0, 0x340, -1, 0, 0, 0, 0), - PADCONF(92, 1, 0xe0, 0x1c0, 0x340, -1, 4, 4, 4, 0), - PADCONF(93, 1, 0xe0, 0x1c0, 0x340, -1, 8, 6, 6, 0), - PADCONF(94, 1, 0xe0, 0x1c0, 0x340, -1, 12, 8, 8, 0), - PADCONF(95, 1, 0xe0, 0x1c0, 0x340, -1, 16, 10, 10, 0), - PADCONF(96, 1, 0xe0, 0x1c0, 0x340, -1, 20, 12, 12, 0), - PADCONF(97, 0, 0xe8, 0x1c8, 0x348, -1, 0, 0, 0, 0), - PADCONF(98, 0, 0xe8, 0x1c8, 0x348, -1, 4, 2, 2, 0), - PADCONF(99, 0, 0xe8, 0x1c8, 0x348, -1, 8, 4, 4, 0), - PADCONF(100, 0, 0xe8, 0x1c8, 0x348, -1, 12, 6, 6, 0), - PADCONF(101, 2, 0xe8, 0x1c8, 0x348, -1, 16, 8, 8, 0), - PADCONF(102, 0, 0xe8, 0x1c8, 0x348, -1, 20, 12, 12, 0), - PADCONF(103, 0, 0xe8, 0x1c8, 0x348, -1, 24, 14, 14, 0), - PADCONF(104, 0, 0xe8, 0x1c8, 0x348, -1, 28, 16, 16, 0), - PADCONF(105, 0, 0xf0, 0x1c8, 0x348, -1, 0, 18, 18, 0), - PADCONF(106, 0, 0xf0, 0x1c8, 0x348, -1, 4, 20, 20, 0), - PADCONF(107, 0, 0xf0, 0x1c8, 0x348, -1, 8, 22, 22, 0), - PADCONF(108, 0, 0xf0, 0x1c8, 0x348, -1, 12, 24, 24, 0), - PADCONF(109, 1, 0xf0, 0x1c8, 0x348, -1, 16, 26, 26, 0), - PADCONF(110, 0, 0xf0, 0x1c8, 0x348, -1, 20, 28, 28, 0), - PADCONF(111, 1, 0xf0, 0x1c8, 0x348, -1, 24, 30, 30, 0), - PADCONF(112, 5, 0xf8, 0x200, 0x350, -1, 0, 0, 0, 0), - PADCONF(113, 5, 0xf8, 0x200, 0x350, -1, 4, 2, 2, 0), - PADCONF(114, 5, 0xf8, 0x200, 0x350, -1, 8, 4, 4, 0), - PADCONF(115, 5, 0xf8, 0x200, 0x350, -1, 12, 6, 6, 0), - PADCONF(116, 5, 0xf8, 0x200, 0x350, -1, 16, 8, 8, 0), - PADCONF(117, 5, 0xf8, 0x200, 0x350, -1, 20, 10, 10, 0), - PADCONF(118, 5, 0xf8, 0x200, 0x350, -1, 24, 12, 12, 0), - PADCONF(119, 5, 0x100, 0x250, 0x358, -1, 0, 0, 0, 0), - PADCONF(120, 5, 0x100, 0x250, 0x358, -1, 4, 2, 2, 0), - PADCONF(121, 5, 0x100, 0x250, 0x358, -1, 8, 4, 4, 0), - PADCONF(122, 5, 0x100, 0x250, 0x358, -1, 12, 6, 6, 0), - PADCONF(123, 6, 0x100, 0x250, 0x358, -1, 16, 8, 8, 0), - PADCONF(124, 6, 0x100, 0x250, 0x358, -1, 20, 10, 10, 0), - PADCONF(125, 6, 0x100, 0x250, 0x358, -1, 24, 12, 12, 0), - PADCONF(126, 6, 0x100, 0x250, 0x358, -1, 28, 14, 14, 0), - PADCONF(127, 6, 0x108, 0x250, 0x358, -1, 16, 24, 24, 0), - PADCONF(128, 6, 0x108, 0x250, 0x358, -1, 20, 26, 26, 0), - PADCONF(129, 0, 0x110, 0x258, 0x360, -1, 0, 0, 0, 0), - PADCONF(130, 0, 0x110, 0x258, 0x360, -1, 4, 2, 2, 0), - PADCONF(131, 0, 0x110, 0x258, 0x360, -1, 8, 4, 4, 0), - PADCONF(132, 0, 0x110, 0x258, 0x360, -1, 12, 6, 6, 0), - PADCONF(133, 6, 0x118, 0x260, 0x368, -1, 0, 0, 0, 0), - PADCONF(134, 6, 0x118, 0x260, 0x368, -1, 4, 2, 2, 0), - PADCONF(135, 6, 0x118, 0x260, 0x368, -1, 16, 8, 8, 0), - PADCONF(136, 6, 0x118, 0x260, 0x368, -1, 20, 10, 10, 0), - PADCONF(137, 6, 0x118, 0x260, 0x368, -1, 24, 12, 12, 0), - PADCONF(138, 6, 0x118, 0x260, 0x368, -1, 28, 14, 14, 0), - PADCONF(139, 6, 0x120, 0x260, 0x368, -1, 0, 16, 16, 0), - PADCONF(140, 6, 0x120, 0x260, 0x368, -1, 4, 18, 18, 0), - PADCONF(141, 5, 0x128, 0x268, 0x378, -1, 0, 0, 0, 0), - PADCONF(142, 5, 0x128, 0x268, 0x378, -1, 4, 2, 2, 0), - PADCONF(143, 5, 0x128, 0x268, 0x378, -1, 8, 4, 4, 0), - PADCONF(144, 5, 0x128, 0x268, 0x378, -1, 12, 6, 6, 0), - PADCONF(145, 5, 0x128, 0x268, 0x378, -1, 16, 8, 8, 0), - PADCONF(146, 5, 0x128, 0x268, 0x378, -1, 20, 10, 10, 0), - PADCONF(147, 5, 0x128, 0x268, 0x378, -1, 24, 12, 12, 0), - PADCONF(148, 5, 0x128, 0x268, 0x378, -1, 28, 14, 14, 0), - PADCONF(149, 7, 0x130, 0x270, -1, 0x480, 0, 0, 0, 0), - PADCONF(150, 7, 0x130, 0x270, -1, 0x480, 4, 2, 0, 1), - PADCONF(151, 7, 0x130, 0x270, -1, 0x480, 8, 4, 0, 2), - PADCONF(152, 7, 0x130, 0x270, -1, 0x480, 12, 6, 0, 3), - PADCONF(153, 7, 0x130, 0x270, -1, 0x480, 16, 8, 0, 4), - PADCONF(154, 7, 0x130, 0x270, -1, 0x480, 20, 10, 0, 5), - PADCONF(155, 7, 0x130, 0x270, -1, 0x480, 24, 12, 0, 6), - PADCONF(156, 7, 0x130, 0x270, -1, 0x480, 28, 14, 0, 7), - PADCONF(157, 7, 0x138, 0x278, -1, 0x480, 0, 0, 0, 8), - PADCONF(158, 7, 0x138, 0x278, -1, 0x480, 4, 2, 0, 9), - PADCONF(159, 5, 0x140, 0x280, 0x380, -1, 0, 0, 0, 0), - PADCONF(160, 6, 0x140, 0x280, 0x380, -1, 4, 2, 2, 0), - PADCONF(161, 5, 0x140, 0x280, 0x380, -1, 8, 4, 4, 0), - PADCONF(162, 6, 0x140, 0x280, 0x380, -1, 12, 6, 6, 0), - PADCONF(163, 6, 0x140, 0x280, 0x380, -1, 16, 8, 8, 0), -}; - -/* pin list of each pin group */ -static const unsigned int gnss_gpio_pins[] = { 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 22, 23, 24, 25, 26, 27, 28, 29, 30, }; -static const unsigned int lcd_vip_gpio_pins[] = { 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, }; -static const unsigned int sdio_i2s_gpio_pins[] = { 31, 32, 33, 34, 35, 36, - 85, 86, 87, 88, 89, 90, 129, 130, 131, 132, 91, 92, 93, 94, - 95, 96, 112, 113, 114, 115, 116, 117, 118, }; -static const unsigned int sp_rgmii_gpio_pins[] = { 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 18, 19, 20, 21, - 141, 142, 143, 144, 145, 146, 147, 148, }; -static const unsigned int lvds_gpio_pins[] = { 157, 158, 155, 156, 153, 154, - 151, 152, 149, 150, }; -static const unsigned int jtag_uart_nand_gpio_pins[] = { 44, 43, 42, 41, 40, - 39, 38, 37, 46, 47, 48, 49, 50, 52, 51, 45, 133, 134, 135, - 136, 137, 138, 139, 140, 159, 160, 161, 162, 163, }; -static const unsigned int rtc_gpio_pins[] = { 0, 1, 2, 3, 4, 10, 11, 12, 13, - 14, 15, 16, 17, 9, }; -static const unsigned int audio_ac97_pins[] = { 113, 118, 115, 114, }; -static const unsigned int audio_digmic_pins0[] = { 51, }; -static const unsigned int audio_digmic_pins1[] = { 122, }; -static const unsigned int audio_digmic_pins2[] = { 161, }; -static const unsigned int audio_func_dbg_pins[] = { 141, 144, 44, 43, 42, 41, - 40, 39, 38, 37, 74, 75, 76, 77, 78, 79, 81, 113, 114, 118, - 115, 49, 50, 142, 143, 80, }; -static const unsigned int audio_i2s_pins[] = { 118, 115, 116, 117, 112, 113, - 114, }; -static const unsigned int audio_i2s_2ch_pins[] = { 118, 115, 112, 113, 114, }; -static const unsigned int audio_i2s_extclk_pins[] = { 112, }; -static const unsigned int audio_spdif_out_pins0[] = { 112, }; -static const unsigned int audio_spdif_out_pins1[] = { 116, }; -static const unsigned int audio_spdif_out_pins2[] = { 142, }; -static const unsigned int audio_uart0_basic_pins[] = { 143, 142, 141, 144, }; -static const unsigned int audio_uart0_urfs_pins0[] = { 117, }; -static const unsigned int audio_uart0_urfs_pins1[] = { 139, }; -static const unsigned int audio_uart0_urfs_pins2[] = { 163, }; -static const unsigned int audio_uart0_urfs_pins3[] = { 162, }; -static const unsigned int audio_uart1_basic_pins[] = { 147, 146, 145, 148, }; -static const unsigned int audio_uart1_urfs_pins0[] = { 117, }; -static const unsigned int audio_uart1_urfs_pins1[] = { 140, }; -static const unsigned int audio_uart1_urfs_pins2[] = { 163, }; -static const unsigned int audio_uart2_urfs_pins0[] = { 139, }; -static const unsigned int audio_uart2_urfs_pins1[] = { 163, }; -static const unsigned int audio_uart2_urfs_pins2[] = { 96, }; -static const unsigned int audio_uart2_urxd_pins0[] = { 20, }; -static const unsigned int audio_uart2_urxd_pins1[] = { 109, }; -static const unsigned int audio_uart2_urxd_pins2[] = { 93, }; -static const unsigned int audio_uart2_usclk_pins0[] = { 19, }; -static const unsigned int audio_uart2_usclk_pins1[] = { 101, }; -static const unsigned int audio_uart2_usclk_pins2[] = { 91, }; -static const unsigned int audio_uart2_utfs_pins0[] = { 18, }; -static const unsigned int audio_uart2_utfs_pins1[] = { 111, }; -static const unsigned int audio_uart2_utfs_pins2[] = { 94, }; -static const unsigned int audio_uart2_utxd_pins0[] = { 21, }; -static const unsigned int audio_uart2_utxd_pins1[] = { 110, }; -static const unsigned int audio_uart2_utxd_pins2[] = { 92, }; -static const unsigned int c_can_trnsvr_en_pins0[] = { 2, }; -static const unsigned int c_can_trnsvr_en_pins1[] = { 0, }; -static const unsigned int c_can_trnsvr_intr_pins[] = { 1, }; -static const unsigned int c_can_trnsvr_stb_n_pins[] = { 3, }; -static const unsigned int c0_can_rxd_trnsv0_pins[] = { 11, }; -static const unsigned int c0_can_rxd_trnsv1_pins[] = { 2, }; -static const unsigned int c0_can_txd_trnsv0_pins[] = { 10, }; -static const unsigned int c0_can_txd_trnsv1_pins[] = { 3, }; -static const unsigned int c1_can_rxd_pins0[] = { 138, }; -static const unsigned int c1_can_rxd_pins1[] = { 147, }; -static const unsigned int c1_can_rxd_pins2[] = { 2, }; -static const unsigned int c1_can_rxd_pins3[] = { 162, }; -static const unsigned int c1_can_txd_pins0[] = { 137, }; -static const unsigned int c1_can_txd_pins1[] = { 146, }; -static const unsigned int c1_can_txd_pins2[] = { 3, }; -static const unsigned int c1_can_txd_pins3[] = { 161, }; -static const unsigned int ca_audio_lpc_pins[] = { 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, }; -static const unsigned int ca_bt_lpc_pins[] = { 85, 86, 87, 88, 89, 90, }; -static const unsigned int ca_coex_pins[] = { 129, 130, 131, 132, }; -static const unsigned int ca_curator_lpc_pins[] = { 57, 58, 59, 60, }; -static const unsigned int ca_pcm_debug_pins[] = { 91, 93, 94, 92, }; -static const unsigned int ca_pio_pins[] = { 121, 122, 125, 126, 38, 37, 47, - 49, 50, 54, 55, 56, }; -static const unsigned int ca_sdio_debug_pins[] = { 40, 39, 44, 43, 42, 41, }; -static const unsigned int ca_spi_pins[] = { 82, 79, 80, 81, }; -static const unsigned int ca_trb_pins[] = { 91, 93, 94, 95, 96, 78, 74, 75, - 76, 77, }; -static const unsigned int ca_uart_debug_pins[] = { 136, 135, 134, 133, }; -static const unsigned int clkc_pins0[] = { 30, 47, }; -static const unsigned int clkc_pins1[] = { 78, 54, }; -static const unsigned int gn_gnss_i2c_pins[] = { 128, 127, }; -static const unsigned int gn_gnss_uart_nopause_pins[] = { 134, 133, }; -static const unsigned int gn_gnss_uart_pins[] = { 134, 133, 136, 135, }; -static const unsigned int gn_trg_spi_pins0[] = { 22, 25, 23, 24, }; -static const unsigned int gn_trg_spi_pins1[] = { 82, 79, 80, 81, }; -static const unsigned int cvbs_dbg_pins[] = { 54, 53, 82, 74, 75, 76, 77, 78, - 79, 80, 81, 83, 84, 73, 55, 56, }; -static const unsigned int cvbs_dbg_test_pins0[] = { 57, }; -static const unsigned int cvbs_dbg_test_pins1[] = { 58, }; -static const unsigned int cvbs_dbg_test_pins2[] = { 59, }; -static const unsigned int cvbs_dbg_test_pins3[] = { 60, }; -static const unsigned int cvbs_dbg_test_pins4[] = { 61, }; -static const unsigned int cvbs_dbg_test_pins5[] = { 62, }; -static const unsigned int cvbs_dbg_test_pins6[] = { 63, }; -static const unsigned int cvbs_dbg_test_pins7[] = { 64, }; -static const unsigned int cvbs_dbg_test_pins8[] = { 65, }; -static const unsigned int cvbs_dbg_test_pins9[] = { 66, }; -static const unsigned int cvbs_dbg_test_pins10[] = { 67, }; -static const unsigned int cvbs_dbg_test_pins11[] = { 68, }; -static const unsigned int cvbs_dbg_test_pins12[] = { 69, }; -static const unsigned int cvbs_dbg_test_pins13[] = { 70, }; -static const unsigned int cvbs_dbg_test_pins14[] = { 71, }; -static const unsigned int cvbs_dbg_test_pins15[] = { 72, }; -static const unsigned int gn_gnss_power_pins[] = { 123, 124, 121, 122, 125, - 120, }; -static const unsigned int gn_gnss_sw_status_pins[] = { 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 53, 55, 56, 54, }; -static const unsigned int gn_gnss_eclk_pins[] = { 113, }; -static const unsigned int gn_gnss_irq1_pins0[] = { 112, }; -static const unsigned int gn_gnss_irq2_pins0[] = { 118, }; -static const unsigned int gn_gnss_tm_pins[] = { 115, }; -static const unsigned int gn_gnss_tsync_pins[] = { 114, }; -static const unsigned int gn_io_gnsssys_sw_cfg_pins[] = { 44, 43, 42, 41, 40, - 39, 38, 37, 49, 50, 91, 92, 93, 94, 95, 96, }; -static const unsigned int gn_trg_pins0[] = { 29, 28, 26, 27, }; -static const unsigned int gn_trg_pins1[] = { 77, 76, 74, 75, }; -static const unsigned int gn_trg_shutdown_pins0[] = { 30, }; -static const unsigned int gn_trg_shutdown_pins1[] = { 83, }; -static const unsigned int gn_trg_shutdown_pins2[] = { 117, }; -static const unsigned int gn_trg_shutdown_pins3[] = { 123, }; -static const unsigned int i2c0_pins[] = { 128, 127, }; -static const unsigned int i2c1_pins[] = { 126, 125, }; -static const unsigned int i2s0_pins[] = { 91, 93, 94, 92, }; -static const unsigned int i2s1_basic_pins[] = { 95, 96, }; -static const unsigned int i2s1_rxd0_pins0[] = { 61, }; -static const unsigned int i2s1_rxd0_pins1[] = { 131, }; -static const unsigned int i2s1_rxd0_pins2[] = { 129, }; -static const unsigned int i2s1_rxd0_pins3[] = { 117, }; -static const unsigned int i2s1_rxd0_pins4[] = { 83, }; -static const unsigned int i2s1_rxd1_pins0[] = { 72, }; -static const unsigned int i2s1_rxd1_pins1[] = { 132, }; -static const unsigned int i2s1_rxd1_pins2[] = { 130, }; -static const unsigned int i2s1_rxd1_pins3[] = { 118, }; -static const unsigned int i2s1_rxd1_pins4[] = { 84, }; -static const unsigned int jtag_jt_dbg_nsrst_pins[] = { 125, }; -static const unsigned int jtag_ntrst_pins0[] = { 4, }; -static const unsigned int jtag_ntrst_pins1[] = { 163, }; -static const unsigned int jtag_swdiotms_pins0[] = { 2, }; -static const unsigned int jtag_swdiotms_pins1[] = { 160, }; -static const unsigned int jtag_tck_pins0[] = { 0, }; -static const unsigned int jtag_tck_pins1[] = { 161, }; -static const unsigned int jtag_tdi_pins0[] = { 1, }; -static const unsigned int jtag_tdi_pins1[] = { 162, }; -static const unsigned int jtag_tdo_pins0[] = { 3, }; -static const unsigned int jtag_tdo_pins1[] = { 159, }; -static const unsigned int ks_kas_spi_pins0[] = { 141, 144, 143, 142, }; -static const unsigned int ld_ldd_pins[] = { 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, - 81, 56, 53, }; -static const unsigned int ld_ldd_16bit_pins[] = { 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 56, 53, }; -static const unsigned int ld_ldd_fck_pins[] = { 55, }; -static const unsigned int ld_ldd_lck_pins[] = { 54, }; -static const unsigned int lr_lcdrom_pins[] = { 73, 54, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 56, 53, 55, }; -static const unsigned int lvds_analog_pins[] = { 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, }; -static const unsigned int nd_df_basic_pins[] = { 44, 43, 42, 41, 40, 39, 38, - 37, 47, 46, 52, 45, 49, 50, 48, }; -static const unsigned int nd_df_wp_pins[] = { 124, }; -static const unsigned int nd_df_cs_pins[] = { 51, }; -static const unsigned int ps_pins[] = { 120, 119, 121, }; -static const unsigned int ps_no_dir_pins[] = { 119, }; -static const unsigned int pwc_core_on_pins[] = { 8, }; -static const unsigned int pwc_ext_on_pins[] = { 6, }; -static const unsigned int pwc_gpio3_clk_pins[] = { 3, }; -static const unsigned int pwc_io_on_pins[] = { 9, }; -static const unsigned int pwc_lowbatt_b_pins0[] = { 4, }; -static const unsigned int pwc_mem_on_pins[] = { 7, }; -static const unsigned int pwc_on_key_b_pins0[] = { 5, }; -static const unsigned int pwc_wakeup_src0_pins[] = { 0, }; -static const unsigned int pwc_wakeup_src1_pins[] = { 1, }; -static const unsigned int pwc_wakeup_src2_pins[] = { 2, }; -static const unsigned int pwc_wakeup_src3_pins[] = { 3, }; -static const unsigned int pw_cko0_pins0[] = { 123, }; -static const unsigned int pw_cko0_pins1[] = { 101, }; -static const unsigned int pw_cko0_pins2[] = { 82, }; -static const unsigned int pw_cko0_pins3[] = { 162, }; -static const unsigned int pw_cko1_pins0[] = { 124, }; -static const unsigned int pw_cko1_pins1[] = { 110, }; -static const unsigned int pw_cko1_pins2[] = { 163, }; -static const unsigned int pw_i2s01_clk_pins0[] = { 125, }; -static const unsigned int pw_i2s01_clk_pins1[] = { 117, }; -static const unsigned int pw_i2s01_clk_pins2[] = { 132, }; -static const unsigned int pw_pwm0_pins0[] = { 119, }; -static const unsigned int pw_pwm0_pins1[] = { 159, }; -static const unsigned int pw_pwm1_pins0[] = { 120, }; -static const unsigned int pw_pwm1_pins1[] = { 160, }; -static const unsigned int pw_pwm1_pins2[] = { 131, }; -static const unsigned int pw_pwm2_pins0[] = { 121, }; -static const unsigned int pw_pwm2_pins1[] = { 98, }; -static const unsigned int pw_pwm2_pins2[] = { 161, }; -static const unsigned int pw_pwm3_pins0[] = { 122, }; -static const unsigned int pw_pwm3_pins1[] = { 73, }; -static const unsigned int pw_pwm_cpu_vol_pins0[] = { 121, }; -static const unsigned int pw_pwm_cpu_vol_pins1[] = { 98, }; -static const unsigned int pw_pwm_cpu_vol_pins2[] = { 161, }; -static const unsigned int pw_backlight_pins0[] = { 122, }; -static const unsigned int pw_backlight_pins1[] = { 73, }; -static const unsigned int rg_eth_mac_pins[] = { 108, 103, 104, 105, 106, 107, - 102, 97, 98, 99, 100, 101, }; -static const unsigned int rg_gmac_phy_intr_n_pins[] = { 111, }; -static const unsigned int rg_rgmii_mac_pins[] = { 109, 110, }; -static const unsigned int rg_rgmii_phy_ref_clk_pins0[] = { 111, }; -static const unsigned int rg_rgmii_phy_ref_clk_pins1[] = { 53, }; -static const unsigned int sd0_pins[] = { 46, 47, 44, 43, 42, 41, 40, 39, 38, - 37, }; -static const unsigned int sd0_4bit_pins[] = { 46, 47, 44, 43, 42, 41, }; -static const unsigned int sd1_pins[] = { 48, 49, 44, 43, 42, 41, 40, 39, 38, - 37, }; -static const unsigned int sd1_4bit_pins0[] = { 48, 49, 44, 43, 42, 41, }; -static const unsigned int sd1_4bit_pins1[] = { 48, 49, 40, 39, 38, 37, }; -static const unsigned int sd2_basic_pins[] = { 31, 32, 33, 34, 35, 36, }; -static const unsigned int sd2_cdb_pins0[] = { 124, }; -static const unsigned int sd2_cdb_pins1[] = { 161, }; -static const unsigned int sd2_wpb_pins0[] = { 123, }; -static const unsigned int sd2_wpb_pins1[] = { 163, }; -static const unsigned int sd3_9_pins[] = { 85, 86, 87, 88, 89, 90, }; -static const unsigned int sd5_pins[] = { 91, 92, 93, 94, 95, 96, }; -static const unsigned int sd6_pins0[] = { 79, 78, 74, 75, 76, 77, }; -static const unsigned int sd6_pins1[] = { 101, 99, 100, 110, 109, 111, }; -static const unsigned int sp0_ext_ldo_on_pins[] = { 4, }; -static const unsigned int sp0_qspi_pins[] = { 12, 13, 14, 15, 16, 17, }; -static const unsigned int sp1_spi_pins[] = { 19, 20, 21, 18, }; -static const unsigned int tpiu_trace_pins[] = { 53, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, }; -static const unsigned int uart0_pins[] = { 121, 120, 134, 133, }; -static const unsigned int uart0_nopause_pins[] = { 134, 133, }; -static const unsigned int uart1_pins[] = { 136, 135, }; -static const unsigned int uart2_cts_pins0[] = { 132, }; -static const unsigned int uart2_cts_pins1[] = { 162, }; -static const unsigned int uart2_rts_pins0[] = { 131, }; -static const unsigned int uart2_rts_pins1[] = { 161, }; -static const unsigned int uart2_rxd_pins0[] = { 11, }; -static const unsigned int uart2_rxd_pins1[] = { 160, }; -static const unsigned int uart2_rxd_pins2[] = { 130, }; -static const unsigned int uart2_txd_pins0[] = { 10, }; -static const unsigned int uart2_txd_pins1[] = { 159, }; -static const unsigned int uart2_txd_pins2[] = { 129, }; -static const unsigned int uart3_cts_pins0[] = { 125, }; -static const unsigned int uart3_cts_pins1[] = { 111, }; -static const unsigned int uart3_cts_pins2[] = { 140, }; -static const unsigned int uart3_rts_pins0[] = { 126, }; -static const unsigned int uart3_rts_pins1[] = { 109, }; -static const unsigned int uart3_rts_pins2[] = { 139, }; -static const unsigned int uart3_rxd_pins0[] = { 138, }; -static const unsigned int uart3_rxd_pins1[] = { 84, }; -static const unsigned int uart3_rxd_pins2[] = { 162, }; -static const unsigned int uart3_txd_pins0[] = { 137, }; -static const unsigned int uart3_txd_pins1[] = { 83, }; -static const unsigned int uart3_txd_pins2[] = { 161, }; -static const unsigned int uart4_basic_pins[] = { 140, 139, }; -static const unsigned int uart4_cts_pins0[] = { 122, }; -static const unsigned int uart4_cts_pins1[] = { 100, }; -static const unsigned int uart4_cts_pins2[] = { 117, }; -static const unsigned int uart4_rts_pins0[] = { 123, }; -static const unsigned int uart4_rts_pins1[] = { 99, }; -static const unsigned int uart4_rts_pins2[] = { 116, }; -static const unsigned int usb0_drvvbus_pins0[] = { 51, }; -static const unsigned int usb0_drvvbus_pins1[] = { 162, }; -static const unsigned int usb1_drvvbus_pins0[] = { 134, }; -static const unsigned int usb1_drvvbus_pins1[] = { 163, }; -static const unsigned int visbus_dout_pins[] = { 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 53, 54, 55, 56, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, }; -static const unsigned int vi_vip1_pins[] = { 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 103, 104, 105, 106, 107, 102, 97, 98, }; -static const unsigned int vi_vip1_ext_pins[] = { 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 108, 103, 104, 105, 106, 107, 102, 97, 98, - 99, 100, }; -static const unsigned int vi_vip1_low8bit_pins[] = { 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, }; -static const unsigned int vi_vip1_high8bit_pins[] = { 82, 83, 84, 103, 104, - 105, 106, 107, 102, 97, 98, }; - -/* definition of pin group table */ -static struct atlas7_pin_group altas7_pin_groups[] = { - GROUP("gnss_gpio_grp", gnss_gpio_pins), - GROUP("lcd_vip_gpio_grp", lcd_vip_gpio_pins), - GROUP("sdio_i2s_gpio_grp", sdio_i2s_gpio_pins), - GROUP("sp_rgmii_gpio_grp", sp_rgmii_gpio_pins), - GROUP("lvds_gpio_grp", lvds_gpio_pins), - GROUP("jtag_uart_nand_gpio_grp", jtag_uart_nand_gpio_pins), - GROUP("rtc_gpio_grp", rtc_gpio_pins), - GROUP("audio_ac97_grp", audio_ac97_pins), - GROUP("audio_digmic_grp0", audio_digmic_pins0), - GROUP("audio_digmic_grp1", audio_digmic_pins1), - GROUP("audio_digmic_grp2", audio_digmic_pins2), - GROUP("audio_func_dbg_grp", audio_func_dbg_pins), - GROUP("audio_i2s_grp", audio_i2s_pins), - GROUP("audio_i2s_2ch_grp", audio_i2s_2ch_pins), - GROUP("audio_i2s_extclk_grp", audio_i2s_extclk_pins), - GROUP("audio_spdif_out_grp0", audio_spdif_out_pins0), - GROUP("audio_spdif_out_grp1", audio_spdif_out_pins1), - GROUP("audio_spdif_out_grp2", audio_spdif_out_pins2), - GROUP("audio_uart0_basic_grp", audio_uart0_basic_pins), - GROUP("audio_uart0_urfs_grp0", audio_uart0_urfs_pins0), - GROUP("audio_uart0_urfs_grp1", audio_uart0_urfs_pins1), - GROUP("audio_uart0_urfs_grp2", audio_uart0_urfs_pins2), - GROUP("audio_uart0_urfs_grp3", audio_uart0_urfs_pins3), - GROUP("audio_uart1_basic_grp", audio_uart1_basic_pins), - GROUP("audio_uart1_urfs_grp0", audio_uart1_urfs_pins0), - GROUP("audio_uart1_urfs_grp1", audio_uart1_urfs_pins1), - GROUP("audio_uart1_urfs_grp2", audio_uart1_urfs_pins2), - GROUP("audio_uart2_urfs_grp0", audio_uart2_urfs_pins0), - GROUP("audio_uart2_urfs_grp1", audio_uart2_urfs_pins1), - GROUP("audio_uart2_urfs_grp2", audio_uart2_urfs_pins2), - GROUP("audio_uart2_urxd_grp0", audio_uart2_urxd_pins0), - GROUP("audio_uart2_urxd_grp1", audio_uart2_urxd_pins1), - GROUP("audio_uart2_urxd_grp2", audio_uart2_urxd_pins2), - GROUP("audio_uart2_usclk_grp0", audio_uart2_usclk_pins0), - GROUP("audio_uart2_usclk_grp1", audio_uart2_usclk_pins1), - GROUP("audio_uart2_usclk_grp2", audio_uart2_usclk_pins2), - GROUP("audio_uart2_utfs_grp0", audio_uart2_utfs_pins0), - GROUP("audio_uart2_utfs_grp1", audio_uart2_utfs_pins1), - GROUP("audio_uart2_utfs_grp2", audio_uart2_utfs_pins2), - GROUP("audio_uart2_utxd_grp0", audio_uart2_utxd_pins0), - GROUP("audio_uart2_utxd_grp1", audio_uart2_utxd_pins1), - GROUP("audio_uart2_utxd_grp2", audio_uart2_utxd_pins2), - GROUP("c_can_trnsvr_en_grp0", c_can_trnsvr_en_pins0), - GROUP("c_can_trnsvr_en_grp1", c_can_trnsvr_en_pins1), - GROUP("c_can_trnsvr_intr_grp", c_can_trnsvr_intr_pins), - GROUP("c_can_trnsvr_stb_n_grp", c_can_trnsvr_stb_n_pins), - GROUP("c0_can_rxd_trnsv0_grp", c0_can_rxd_trnsv0_pins), - GROUP("c0_can_rxd_trnsv1_grp", c0_can_rxd_trnsv1_pins), - GROUP("c0_can_txd_trnsv0_grp", c0_can_txd_trnsv0_pins), - GROUP("c0_can_txd_trnsv1_grp", c0_can_txd_trnsv1_pins), - GROUP("c1_can_rxd_grp0", c1_can_rxd_pins0), - GROUP("c1_can_rxd_grp1", c1_can_rxd_pins1), - GROUP("c1_can_rxd_grp2", c1_can_rxd_pins2), - GROUP("c1_can_rxd_grp3", c1_can_rxd_pins3), - GROUP("c1_can_txd_grp0", c1_can_txd_pins0), - GROUP("c1_can_txd_grp1", c1_can_txd_pins1), - GROUP("c1_can_txd_grp2", c1_can_txd_pins2), - GROUP("c1_can_txd_grp3", c1_can_txd_pins3), - GROUP("ca_audio_lpc_grp", ca_audio_lpc_pins), - GROUP("ca_bt_lpc_grp", ca_bt_lpc_pins), - GROUP("ca_coex_grp", ca_coex_pins), - GROUP("ca_curator_lpc_grp", ca_curator_lpc_pins), - GROUP("ca_pcm_debug_grp", ca_pcm_debug_pins), - GROUP("ca_pio_grp", ca_pio_pins), - GROUP("ca_sdio_debug_grp", ca_sdio_debug_pins), - GROUP("ca_spi_grp", ca_spi_pins), - GROUP("ca_trb_grp", ca_trb_pins), - GROUP("ca_uart_debug_grp", ca_uart_debug_pins), - GROUP("clkc_grp0", clkc_pins0), - GROUP("clkc_grp1", clkc_pins1), - GROUP("gn_gnss_i2c_grp", gn_gnss_i2c_pins), - GROUP("gn_gnss_uart_nopause_grp", gn_gnss_uart_nopause_pins), - GROUP("gn_gnss_uart_grp", gn_gnss_uart_pins), - GROUP("gn_trg_spi_grp0", gn_trg_spi_pins0), - GROUP("gn_trg_spi_grp1", gn_trg_spi_pins1), - GROUP("cvbs_dbg_grp", cvbs_dbg_pins), - GROUP("cvbs_dbg_test_grp0", cvbs_dbg_test_pins0), - GROUP("cvbs_dbg_test_grp1", cvbs_dbg_test_pins1), - GROUP("cvbs_dbg_test_grp2", cvbs_dbg_test_pins2), - GROUP("cvbs_dbg_test_grp3", cvbs_dbg_test_pins3), - GROUP("cvbs_dbg_test_grp4", cvbs_dbg_test_pins4), - GROUP("cvbs_dbg_test_grp5", cvbs_dbg_test_pins5), - GROUP("cvbs_dbg_test_grp6", cvbs_dbg_test_pins6), - GROUP("cvbs_dbg_test_grp7", cvbs_dbg_test_pins7), - GROUP("cvbs_dbg_test_grp8", cvbs_dbg_test_pins8), - GROUP("cvbs_dbg_test_grp9", cvbs_dbg_test_pins9), - GROUP("cvbs_dbg_test_grp10", cvbs_dbg_test_pins10), - GROUP("cvbs_dbg_test_grp11", cvbs_dbg_test_pins11), - GROUP("cvbs_dbg_test_grp12", cvbs_dbg_test_pins12), - GROUP("cvbs_dbg_test_grp13", cvbs_dbg_test_pins13), - GROUP("cvbs_dbg_test_grp14", cvbs_dbg_test_pins14), - GROUP("cvbs_dbg_test_grp15", cvbs_dbg_test_pins15), - GROUP("gn_gnss_power_grp", gn_gnss_power_pins), - GROUP("gn_gnss_sw_status_grp", gn_gnss_sw_status_pins), - GROUP("gn_gnss_eclk_grp", gn_gnss_eclk_pins), - GROUP("gn_gnss_irq1_grp0", gn_gnss_irq1_pins0), - GROUP("gn_gnss_irq2_grp0", gn_gnss_irq2_pins0), - GROUP("gn_gnss_tm_grp", gn_gnss_tm_pins), - GROUP("gn_gnss_tsync_grp", gn_gnss_tsync_pins), - GROUP("gn_io_gnsssys_sw_cfg_grp", gn_io_gnsssys_sw_cfg_pins), - GROUP("gn_trg_grp0", gn_trg_pins0), - GROUP("gn_trg_grp1", gn_trg_pins1), - GROUP("gn_trg_shutdown_grp0", gn_trg_shutdown_pins0), - GROUP("gn_trg_shutdown_grp1", gn_trg_shutdown_pins1), - GROUP("gn_trg_shutdown_grp2", gn_trg_shutdown_pins2), - GROUP("gn_trg_shutdown_grp3", gn_trg_shutdown_pins3), - GROUP("i2c0_grp", i2c0_pins), - GROUP("i2c1_grp", i2c1_pins), - GROUP("i2s0_grp", i2s0_pins), - GROUP("i2s1_basic_grp", i2s1_basic_pins), - GROUP("i2s1_rxd0_grp0", i2s1_rxd0_pins0), - GROUP("i2s1_rxd0_grp1", i2s1_rxd0_pins1), - GROUP("i2s1_rxd0_grp2", i2s1_rxd0_pins2), - GROUP("i2s1_rxd0_grp3", i2s1_rxd0_pins3), - GROUP("i2s1_rxd0_grp4", i2s1_rxd0_pins4), - GROUP("i2s1_rxd1_grp0", i2s1_rxd1_pins0), - GROUP("i2s1_rxd1_grp1", i2s1_rxd1_pins1), - GROUP("i2s1_rxd1_grp2", i2s1_rxd1_pins2), - GROUP("i2s1_rxd1_grp3", i2s1_rxd1_pins3), - GROUP("i2s1_rxd1_grp4", i2s1_rxd1_pins4), - GROUP("jtag_jt_dbg_nsrst_grp", jtag_jt_dbg_nsrst_pins), - GROUP("jtag_ntrst_grp0", jtag_ntrst_pins0), - GROUP("jtag_ntrst_grp1", jtag_ntrst_pins1), - GROUP("jtag_swdiotms_grp0", jtag_swdiotms_pins0), - GROUP("jtag_swdiotms_grp1", jtag_swdiotms_pins1), - GROUP("jtag_tck_grp0", jtag_tck_pins0), - GROUP("jtag_tck_grp1", jtag_tck_pins1), - GROUP("jtag_tdi_grp0", jtag_tdi_pins0), - GROUP("jtag_tdi_grp1", jtag_tdi_pins1), - GROUP("jtag_tdo_grp0", jtag_tdo_pins0), - GROUP("jtag_tdo_grp1", jtag_tdo_pins1), - GROUP("ks_kas_spi_grp0", ks_kas_spi_pins0), - GROUP("ld_ldd_grp", ld_ldd_pins), - GROUP("ld_ldd_16bit_grp", ld_ldd_16bit_pins), - GROUP("ld_ldd_fck_grp", ld_ldd_fck_pins), - GROUP("ld_ldd_lck_grp", ld_ldd_lck_pins), - GROUP("lr_lcdrom_grp", lr_lcdrom_pins), - GROUP("lvds_analog_grp", lvds_analog_pins), - GROUP("nd_df_basic_grp", nd_df_basic_pins), - GROUP("nd_df_wp_grp", nd_df_wp_pins), - GROUP("nd_df_cs_grp", nd_df_cs_pins), - GROUP("ps_grp", ps_pins), - GROUP("ps_no_dir_grp", ps_no_dir_pins), - GROUP("pwc_core_on_grp", pwc_core_on_pins), - GROUP("pwc_ext_on_grp", pwc_ext_on_pins), - GROUP("pwc_gpio3_clk_grp", pwc_gpio3_clk_pins), - GROUP("pwc_io_on_grp", pwc_io_on_pins), - GROUP("pwc_lowbatt_b_grp0", pwc_lowbatt_b_pins0), - GROUP("pwc_mem_on_grp", pwc_mem_on_pins), - GROUP("pwc_on_key_b_grp0", pwc_on_key_b_pins0), - GROUP("pwc_wakeup_src0_grp", pwc_wakeup_src0_pins), - GROUP("pwc_wakeup_src1_grp", pwc_wakeup_src1_pins), - GROUP("pwc_wakeup_src2_grp", pwc_wakeup_src2_pins), - GROUP("pwc_wakeup_src3_grp", pwc_wakeup_src3_pins), - GROUP("pw_cko0_grp0", pw_cko0_pins0), - GROUP("pw_cko0_grp1", pw_cko0_pins1), - GROUP("pw_cko0_grp2", pw_cko0_pins2), - GROUP("pw_cko0_grp3", pw_cko0_pins3), - GROUP("pw_cko1_grp0", pw_cko1_pins0), - GROUP("pw_cko1_grp1", pw_cko1_pins1), - GROUP("pw_cko1_grp2", pw_cko1_pins2), - GROUP("pw_i2s01_clk_grp0", pw_i2s01_clk_pins0), - GROUP("pw_i2s01_clk_grp1", pw_i2s01_clk_pins1), - GROUP("pw_i2s01_clk_grp2", pw_i2s01_clk_pins2), - GROUP("pw_pwm0_grp0", pw_pwm0_pins0), - GROUP("pw_pwm0_grp1", pw_pwm0_pins1), - GROUP("pw_pwm1_grp0", pw_pwm1_pins0), - GROUP("pw_pwm1_grp1", pw_pwm1_pins1), - GROUP("pw_pwm1_grp2", pw_pwm1_pins2), - GROUP("pw_pwm2_grp0", pw_pwm2_pins0), - GROUP("pw_pwm2_grp1", pw_pwm2_pins1), - GROUP("pw_pwm2_grp2", pw_pwm2_pins2), - GROUP("pw_pwm3_grp0", pw_pwm3_pins0), - GROUP("pw_pwm3_grp1", pw_pwm3_pins1), - GROUP("pw_pwm_cpu_vol_grp0", pw_pwm_cpu_vol_pins0), - GROUP("pw_pwm_cpu_vol_grp1", pw_pwm_cpu_vol_pins1), - GROUP("pw_pwm_cpu_vol_grp2", pw_pwm_cpu_vol_pins2), - GROUP("pw_backlight_grp0", pw_backlight_pins0), - GROUP("pw_backlight_grp1", pw_backlight_pins1), - GROUP("rg_eth_mac_grp", rg_eth_mac_pins), - GROUP("rg_gmac_phy_intr_n_grp", rg_gmac_phy_intr_n_pins), - GROUP("rg_rgmii_mac_grp", rg_rgmii_mac_pins), - GROUP("rg_rgmii_phy_ref_clk_grp0", rg_rgmii_phy_ref_clk_pins0), - GROUP("rg_rgmii_phy_ref_clk_grp1", rg_rgmii_phy_ref_clk_pins1), - GROUP("sd0_grp", sd0_pins), - GROUP("sd0_4bit_grp", sd0_4bit_pins), - GROUP("sd1_grp", sd1_pins), - GROUP("sd1_4bit_grp0", sd1_4bit_pins0), - GROUP("sd1_4bit_grp1", sd1_4bit_pins1), - GROUP("sd2_basic_grp", sd2_basic_pins), - GROUP("sd2_cdb_grp0", sd2_cdb_pins0), - GROUP("sd2_cdb_grp1", sd2_cdb_pins1), - GROUP("sd2_wpb_grp0", sd2_wpb_pins0), - GROUP("sd2_wpb_grp1", sd2_wpb_pins1), - GROUP("sd3_9_grp", sd3_9_pins), - GROUP("sd5_grp", sd5_pins), - GROUP("sd6_grp0", sd6_pins0), - GROUP("sd6_grp1", sd6_pins1), - GROUP("sp0_ext_ldo_on_grp", sp0_ext_ldo_on_pins), - GROUP("sp0_qspi_grp", sp0_qspi_pins), - GROUP("sp1_spi_grp", sp1_spi_pins), - GROUP("tpiu_trace_grp", tpiu_trace_pins), - GROUP("uart0_grp", uart0_pins), - GROUP("uart0_nopause_grp", uart0_nopause_pins), - GROUP("uart1_grp", uart1_pins), - GROUP("uart2_cts_grp0", uart2_cts_pins0), - GROUP("uart2_cts_grp1", uart2_cts_pins1), - GROUP("uart2_rts_grp0", uart2_rts_pins0), - GROUP("uart2_rts_grp1", uart2_rts_pins1), - GROUP("uart2_rxd_grp0", uart2_rxd_pins0), - GROUP("uart2_rxd_grp1", uart2_rxd_pins1), - GROUP("uart2_rxd_grp2", uart2_rxd_pins2), - GROUP("uart2_txd_grp0", uart2_txd_pins0), - GROUP("uart2_txd_grp1", uart2_txd_pins1), - GROUP("uart2_txd_grp2", uart2_txd_pins2), - GROUP("uart3_cts_grp0", uart3_cts_pins0), - GROUP("uart3_cts_grp1", uart3_cts_pins1), - GROUP("uart3_cts_grp2", uart3_cts_pins2), - GROUP("uart3_rts_grp0", uart3_rts_pins0), - GROUP("uart3_rts_grp1", uart3_rts_pins1), - GROUP("uart3_rts_grp2", uart3_rts_pins2), - GROUP("uart3_rxd_grp0", uart3_rxd_pins0), - GROUP("uart3_rxd_grp1", uart3_rxd_pins1), - GROUP("uart3_rxd_grp2", uart3_rxd_pins2), - GROUP("uart3_txd_grp0", uart3_txd_pins0), - GROUP("uart3_txd_grp1", uart3_txd_pins1), - GROUP("uart3_txd_grp2", uart3_txd_pins2), - GROUP("uart4_basic_grp", uart4_basic_pins), - GROUP("uart4_cts_grp0", uart4_cts_pins0), - GROUP("uart4_cts_grp1", uart4_cts_pins1), - GROUP("uart4_cts_grp2", uart4_cts_pins2), - GROUP("uart4_rts_grp0", uart4_rts_pins0), - GROUP("uart4_rts_grp1", uart4_rts_pins1), - GROUP("uart4_rts_grp2", uart4_rts_pins2), - GROUP("usb0_drvvbus_grp0", usb0_drvvbus_pins0), - GROUP("usb0_drvvbus_grp1", usb0_drvvbus_pins1), - GROUP("usb1_drvvbus_grp0", usb1_drvvbus_pins0), - GROUP("usb1_drvvbus_grp1", usb1_drvvbus_pins1), - GROUP("visbus_dout_grp", visbus_dout_pins), - GROUP("vi_vip1_grp", vi_vip1_pins), - GROUP("vi_vip1_ext_grp", vi_vip1_ext_pins), - GROUP("vi_vip1_low8bit_grp", vi_vip1_low8bit_pins), - GROUP("vi_vip1_high8bit_grp", vi_vip1_high8bit_pins), -}; - -/* How many groups that a function can use */ -static const char * const gnss_gpio_grp[] = { "gnss_gpio_grp", }; -static const char * const lcd_vip_gpio_grp[] = { "lcd_vip_gpio_grp", }; -static const char * const sdio_i2s_gpio_grp[] = { "sdio_i2s_gpio_grp", }; -static const char * const sp_rgmii_gpio_grp[] = { "sp_rgmii_gpio_grp", }; -static const char * const lvds_gpio_grp[] = { "lvds_gpio_grp", }; -static const char * const jtag_uart_nand_gpio_grp[] = { - "jtag_uart_nand_gpio_grp", }; -static const char * const rtc_gpio_grp[] = { "rtc_gpio_grp", }; -static const char * const audio_ac97_grp[] = { "audio_ac97_grp", }; -static const char * const audio_digmic_grp0[] = { "audio_digmic_grp0", }; -static const char * const audio_digmic_grp1[] = { "audio_digmic_grp1", }; -static const char * const audio_digmic_grp2[] = { "audio_digmic_grp2", }; -static const char * const audio_func_dbg_grp[] = { "audio_func_dbg_grp", }; -static const char * const audio_i2s_grp[] = { "audio_i2s_grp", }; -static const char * const audio_i2s_2ch_grp[] = { "audio_i2s_2ch_grp", }; -static const char * const audio_i2s_extclk_grp[] = { "audio_i2s_extclk_grp", }; -static const char * const audio_spdif_out_grp0[] = { "audio_spdif_out_grp0", }; -static const char * const audio_spdif_out_grp1[] = { "audio_spdif_out_grp1", }; -static const char * const audio_spdif_out_grp2[] = { "audio_spdif_out_grp2", }; -static const char * const audio_uart0_basic_grp[] = { - "audio_uart0_basic_grp", }; -static const char * const audio_uart0_urfs_grp0[] = { - "audio_uart0_urfs_grp0", }; -static const char * const audio_uart0_urfs_grp1[] = { - "audio_uart0_urfs_grp1", }; -static const char * const audio_uart0_urfs_grp2[] = { - "audio_uart0_urfs_grp2", }; -static const char * const audio_uart0_urfs_grp3[] = { - "audio_uart0_urfs_grp3", }; -static const char * const audio_uart1_basic_grp[] = { - "audio_uart1_basic_grp", }; -static const char * const audio_uart1_urfs_grp0[] = { - "audio_uart1_urfs_grp0", }; -static const char * const audio_uart1_urfs_grp1[] = { - "audio_uart1_urfs_grp1", }; -static const char * const audio_uart1_urfs_grp2[] = { - "audio_uart1_urfs_grp2", }; -static const char * const audio_uart2_urfs_grp0[] = { - "audio_uart2_urfs_grp0", }; -static const char * const audio_uart2_urfs_grp1[] = { - "audio_uart2_urfs_grp1", }; -static const char * const audio_uart2_urfs_grp2[] = { - "audio_uart2_urfs_grp2", }; -static const char * const audio_uart2_urxd_grp0[] = { - "audio_uart2_urxd_grp0", }; -static const char * const audio_uart2_urxd_grp1[] = { - "audio_uart2_urxd_grp1", }; -static const char * const audio_uart2_urxd_grp2[] = { - "audio_uart2_urxd_grp2", }; -static const char * const audio_uart2_usclk_grp0[] = { - "audio_uart2_usclk_grp0", }; -static const char * const audio_uart2_usclk_grp1[] = { - "audio_uart2_usclk_grp1", }; -static const char * const audio_uart2_usclk_grp2[] = { - "audio_uart2_usclk_grp2", }; -static const char * const audio_uart2_utfs_grp0[] = { - "audio_uart2_utfs_grp0", }; -static const char * const audio_uart2_utfs_grp1[] = { - "audio_uart2_utfs_grp1", }; -static const char * const audio_uart2_utfs_grp2[] = { - "audio_uart2_utfs_grp2", }; -static const char * const audio_uart2_utxd_grp0[] = { - "audio_uart2_utxd_grp0", }; -static const char * const audio_uart2_utxd_grp1[] = { - "audio_uart2_utxd_grp1", }; -static const char * const audio_uart2_utxd_grp2[] = { - "audio_uart2_utxd_grp2", }; -static const char * const c_can_trnsvr_en_grp0[] = { "c_can_trnsvr_en_grp0", }; -static const char * const c_can_trnsvr_en_grp1[] = { "c_can_trnsvr_en_grp1", }; -static const char * const c_can_trnsvr_intr_grp[] = { - "c_can_trnsvr_intr_grp", }; -static const char * const c_can_trnsvr_stb_n_grp[] = { - "c_can_trnsvr_stb_n_grp", }; -static const char * const c0_can_rxd_trnsv0_grp[] = { - "c0_can_rxd_trnsv0_grp", }; -static const char * const c0_can_rxd_trnsv1_grp[] = { - "c0_can_rxd_trnsv1_grp", }; -static const char * const c0_can_txd_trnsv0_grp[] = { - "c0_can_txd_trnsv0_grp", }; -static const char * const c0_can_txd_trnsv1_grp[] = { - "c0_can_txd_trnsv1_grp", }; -static const char * const c1_can_rxd_grp0[] = { "c1_can_rxd_grp0", }; -static const char * const c1_can_rxd_grp1[] = { "c1_can_rxd_grp1", }; -static const char * const c1_can_rxd_grp2[] = { "c1_can_rxd_grp2", }; -static const char * const c1_can_rxd_grp3[] = { "c1_can_rxd_grp3", }; -static const char * const c1_can_txd_grp0[] = { "c1_can_txd_grp0", }; -static const char * const c1_can_txd_grp1[] = { "c1_can_txd_grp1", }; -static const char * const c1_can_txd_grp2[] = { "c1_can_txd_grp2", }; -static const char * const c1_can_txd_grp3[] = { "c1_can_txd_grp3", }; -static const char * const ca_audio_lpc_grp[] = { "ca_audio_lpc_grp", }; -static const char * const ca_bt_lpc_grp[] = { "ca_bt_lpc_grp", }; -static const char * const ca_coex_grp[] = { "ca_coex_grp", }; -static const char * const ca_curator_lpc_grp[] = { "ca_curator_lpc_grp", }; -static const char * const ca_pcm_debug_grp[] = { "ca_pcm_debug_grp", }; -static const char * const ca_pio_grp[] = { "ca_pio_grp", }; -static const char * const ca_sdio_debug_grp[] = { "ca_sdio_debug_grp", }; -static const char * const ca_spi_grp[] = { "ca_spi_grp", }; -static const char * const ca_trb_grp[] = { "ca_trb_grp", }; -static const char * const ca_uart_debug_grp[] = { "ca_uart_debug_grp", }; -static const char * const clkc_grp0[] = { "clkc_grp0", }; -static const char * const clkc_grp1[] = { "clkc_grp1", }; -static const char * const gn_gnss_i2c_grp[] = { "gn_gnss_i2c_grp", }; -static const char * const gn_gnss_uart_nopause_grp[] = { - "gn_gnss_uart_nopause_grp", }; -static const char * const gn_gnss_uart_grp[] = { "gn_gnss_uart_grp", }; -static const char * const gn_trg_spi_grp0[] = { "gn_trg_spi_grp0", }; -static const char * const gn_trg_spi_grp1[] = { "gn_trg_spi_grp1", }; -static const char * const cvbs_dbg_grp[] = { "cvbs_dbg_grp", }; -static const char * const cvbs_dbg_test_grp0[] = { "cvbs_dbg_test_grp0", }; -static const char * const cvbs_dbg_test_grp1[] = { "cvbs_dbg_test_grp1", }; -static const char * const cvbs_dbg_test_grp2[] = { "cvbs_dbg_test_grp2", }; -static const char * const cvbs_dbg_test_grp3[] = { "cvbs_dbg_test_grp3", }; -static const char * const cvbs_dbg_test_grp4[] = { "cvbs_dbg_test_grp4", }; -static const char * const cvbs_dbg_test_grp5[] = { "cvbs_dbg_test_grp5", }; -static const char * const cvbs_dbg_test_grp6[] = { "cvbs_dbg_test_grp6", }; -static const char * const cvbs_dbg_test_grp7[] = { "cvbs_dbg_test_grp7", }; -static const char * const cvbs_dbg_test_grp8[] = { "cvbs_dbg_test_grp8", }; -static const char * const cvbs_dbg_test_grp9[] = { "cvbs_dbg_test_grp9", }; -static const char * const cvbs_dbg_test_grp10[] = { "cvbs_dbg_test_grp10", }; -static const char * const cvbs_dbg_test_grp11[] = { "cvbs_dbg_test_grp11", }; -static const char * const cvbs_dbg_test_grp12[] = { "cvbs_dbg_test_grp12", }; -static const char * const cvbs_dbg_test_grp13[] = { "cvbs_dbg_test_grp13", }; -static const char * const cvbs_dbg_test_grp14[] = { "cvbs_dbg_test_grp14", }; -static const char * const cvbs_dbg_test_grp15[] = { "cvbs_dbg_test_grp15", }; -static const char * const gn_gnss_power_grp[] = { "gn_gnss_power_grp", }; -static const char * const gn_gnss_sw_status_grp[] = { - "gn_gnss_sw_status_grp", }; -static const char * const gn_gnss_eclk_grp[] = { "gn_gnss_eclk_grp", }; -static const char * const gn_gnss_irq1_grp0[] = { "gn_gnss_irq1_grp0", }; -static const char * const gn_gnss_irq2_grp0[] = { "gn_gnss_irq2_grp0", }; -static const char * const gn_gnss_tm_grp[] = { "gn_gnss_tm_grp", }; -static const char * const gn_gnss_tsync_grp[] = { "gn_gnss_tsync_grp", }; -static const char * const gn_io_gnsssys_sw_cfg_grp[] = { - "gn_io_gnsssys_sw_cfg_grp", }; -static const char * const gn_trg_grp0[] = { "gn_trg_grp0", }; -static const char * const gn_trg_grp1[] = { "gn_trg_grp1", }; -static const char * const gn_trg_shutdown_grp0[] = { "gn_trg_shutdown_grp0", }; -static const char * const gn_trg_shutdown_grp1[] = { "gn_trg_shutdown_grp1", }; -static const char * const gn_trg_shutdown_grp2[] = { "gn_trg_shutdown_grp2", }; -static const char * const gn_trg_shutdown_grp3[] = { "gn_trg_shutdown_grp3", }; -static const char * const i2c0_grp[] = { "i2c0_grp", }; -static const char * const i2c1_grp[] = { "i2c1_grp", }; -static const char * const i2s0_grp[] = { "i2s0_grp", }; -static const char * const i2s1_basic_grp[] = { "i2s1_basic_grp", }; -static const char * const i2s1_rxd0_grp0[] = { "i2s1_rxd0_grp0", }; -static const char * const i2s1_rxd0_grp1[] = { "i2s1_rxd0_grp1", }; -static const char * const i2s1_rxd0_grp2[] = { "i2s1_rxd0_grp2", }; -static const char * const i2s1_rxd0_grp3[] = { "i2s1_rxd0_grp3", }; -static const char * const i2s1_rxd0_grp4[] = { "i2s1_rxd0_grp4", }; -static const char * const i2s1_rxd1_grp0[] = { "i2s1_rxd1_grp0", }; -static const char * const i2s1_rxd1_grp1[] = { "i2s1_rxd1_grp1", }; -static const char * const i2s1_rxd1_grp2[] = { "i2s1_rxd1_grp2", }; -static const char * const i2s1_rxd1_grp3[] = { "i2s1_rxd1_grp3", }; -static const char * const i2s1_rxd1_grp4[] = { "i2s1_rxd1_grp4", }; -static const char * const jtag_jt_dbg_nsrst_grp[] = { - "jtag_jt_dbg_nsrst_grp", }; -static const char * const jtag_ntrst_grp0[] = { "jtag_ntrst_grp0", }; -static const char * const jtag_ntrst_grp1[] = { "jtag_ntrst_grp1", }; -static const char * const jtag_swdiotms_grp0[] = { "jtag_swdiotms_grp0", }; -static const char * const jtag_swdiotms_grp1[] = { "jtag_swdiotms_grp1", }; -static const char * const jtag_tck_grp0[] = { "jtag_tck_grp0", }; -static const char * const jtag_tck_grp1[] = { "jtag_tck_grp1", }; -static const char * const jtag_tdi_grp0[] = { "jtag_tdi_grp0", }; -static const char * const jtag_tdi_grp1[] = { "jtag_tdi_grp1", }; -static const char * const jtag_tdo_grp0[] = { "jtag_tdo_grp0", }; -static const char * const jtag_tdo_grp1[] = { "jtag_tdo_grp1", }; -static const char * const ks_kas_spi_grp0[] = { "ks_kas_spi_grp0", }; -static const char * const ld_ldd_grp[] = { "ld_ldd_grp", }; -static const char * const ld_ldd_16bit_grp[] = { "ld_ldd_16bit_grp", }; -static const char * const ld_ldd_fck_grp[] = { "ld_ldd_fck_grp", }; -static const char * const ld_ldd_lck_grp[] = { "ld_ldd_lck_grp", }; -static const char * const lr_lcdrom_grp[] = { "lr_lcdrom_grp", }; -static const char * const lvds_analog_grp[] = { "lvds_analog_grp", }; -static const char * const nd_df_basic_grp[] = { "nd_df_basic_grp", }; -static const char * const nd_df_wp_grp[] = { "nd_df_wp_grp", }; -static const char * const nd_df_cs_grp[] = { "nd_df_cs_grp", }; -static const char * const ps_grp[] = { "ps_grp", }; -static const char * const ps_no_dir_grp[] = { "ps_no_dir_grp", }; -static const char * const pwc_core_on_grp[] = { "pwc_core_on_grp", }; -static const char * const pwc_ext_on_grp[] = { "pwc_ext_on_grp", }; -static const char * const pwc_gpio3_clk_grp[] = { "pwc_gpio3_clk_grp", }; -static const char * const pwc_io_on_grp[] = { "pwc_io_on_grp", }; -static const char * const pwc_lowbatt_b_grp0[] = { "pwc_lowbatt_b_grp0", }; -static const char * const pwc_mem_on_grp[] = { "pwc_mem_on_grp", }; -static const char * const pwc_on_key_b_grp0[] = { "pwc_on_key_b_grp0", }; -static const char * const pwc_wakeup_src0_grp[] = { "pwc_wakeup_src0_grp", }; -static const char * const pwc_wakeup_src1_grp[] = { "pwc_wakeup_src1_grp", }; -static const char * const pwc_wakeup_src2_grp[] = { "pwc_wakeup_src2_grp", }; -static const char * const pwc_wakeup_src3_grp[] = { "pwc_wakeup_src3_grp", }; -static const char * const pw_cko0_grp0[] = { "pw_cko0_grp0", }; -static const char * const pw_cko0_grp1[] = { "pw_cko0_grp1", }; -static const char * const pw_cko0_grp2[] = { "pw_cko0_grp2", }; -static const char * const pw_cko0_grp3[] = { "pw_cko0_grp3", }; -static const char * const pw_cko1_grp0[] = { "pw_cko1_grp0", }; -static const char * const pw_cko1_grp1[] = { "pw_cko1_grp1", }; -static const char * const pw_cko1_grp2[] = { "pw_cko1_grp2", }; -static const char * const pw_i2s01_clk_grp0[] = { "pw_i2s01_clk_grp0", }; -static const char * const pw_i2s01_clk_grp1[] = { "pw_i2s01_clk_grp1", }; -static const char * const pw_i2s01_clk_grp2[] = { "pw_i2s01_clk_grp2", }; -static const char * const pw_pwm0_grp0[] = { "pw_pwm0_grp0", }; -static const char * const pw_pwm0_grp1[] = { "pw_pwm0_grp1", }; -static const char * const pw_pwm1_grp0[] = { "pw_pwm1_grp0", }; -static const char * const pw_pwm1_grp1[] = { "pw_pwm1_grp1", }; -static const char * const pw_pwm1_grp2[] = { "pw_pwm1_grp2", }; -static const char * const pw_pwm2_grp0[] = { "pw_pwm2_grp0", }; -static const char * const pw_pwm2_grp1[] = { "pw_pwm2_grp1", }; -static const char * const pw_pwm2_grp2[] = { "pw_pwm2_grp2", }; -static const char * const pw_pwm3_grp0[] = { "pw_pwm3_grp0", }; -static const char * const pw_pwm3_grp1[] = { "pw_pwm3_grp1", }; -static const char * const pw_pwm_cpu_vol_grp0[] = { "pw_pwm_cpu_vol_grp0", }; -static const char * const pw_pwm_cpu_vol_grp1[] = { "pw_pwm_cpu_vol_grp1", }; -static const char * const pw_pwm_cpu_vol_grp2[] = { "pw_pwm_cpu_vol_grp2", }; -static const char * const pw_backlight_grp0[] = { "pw_backlight_grp0", }; -static const char * const pw_backlight_grp1[] = { "pw_backlight_grp1", }; -static const char * const rg_eth_mac_grp[] = { "rg_eth_mac_grp", }; -static const char * const rg_gmac_phy_intr_n_grp[] = { - "rg_gmac_phy_intr_n_grp", }; -static const char * const rg_rgmii_mac_grp[] = { "rg_rgmii_mac_grp", }; -static const char * const rg_rgmii_phy_ref_clk_grp0[] = { - "rg_rgmii_phy_ref_clk_grp0", }; -static const char * const rg_rgmii_phy_ref_clk_grp1[] = { - "rg_rgmii_phy_ref_clk_grp1", }; -static const char * const sd0_grp[] = { "sd0_grp", }; -static const char * const sd0_4bit_grp[] = { "sd0_4bit_grp", }; -static const char * const sd1_grp[] = { "sd1_grp", }; -static const char * const sd1_4bit_grp0[] = { "sd1_4bit_grp0", }; -static const char * const sd1_4bit_grp1[] = { "sd1_4bit_grp1", }; -static const char * const sd2_basic_grp[] = { "sd2_basic_grp", }; -static const char * const sd2_cdb_grp0[] = { "sd2_cdb_grp0", }; -static const char * const sd2_cdb_grp1[] = { "sd2_cdb_grp1", }; -static const char * const sd2_wpb_grp0[] = { "sd2_wpb_grp0", }; -static const char * const sd2_wpb_grp1[] = { "sd2_wpb_grp1", }; -static const char * const sd3_9_grp[] = { "sd3_9_grp", }; -static const char * const sd5_grp[] = { "sd5_grp", }; -static const char * const sd6_grp0[] = { "sd6_grp0", }; -static const char * const sd6_grp1[] = { "sd6_grp1", }; -static const char * const sp0_ext_ldo_on_grp[] = { "sp0_ext_ldo_on_grp", }; -static const char * const sp0_qspi_grp[] = { "sp0_qspi_grp", }; -static const char * const sp1_spi_grp[] = { "sp1_spi_grp", }; -static const char * const tpiu_trace_grp[] = { "tpiu_trace_grp", }; -static const char * const uart0_grp[] = { "uart0_grp", }; -static const char * const uart0_nopause_grp[] = { "uart0_nopause_grp", }; -static const char * const uart1_grp[] = { "uart1_grp", }; -static const char * const uart2_cts_grp0[] = { "uart2_cts_grp0", }; -static const char * const uart2_cts_grp1[] = { "uart2_cts_grp1", }; -static const char * const uart2_rts_grp0[] = { "uart2_rts_grp0", }; -static const char * const uart2_rts_grp1[] = { "uart2_rts_grp1", }; -static const char * const uart2_rxd_grp0[] = { "uart2_rxd_grp0", }; -static const char * const uart2_rxd_grp1[] = { "uart2_rxd_grp1", }; -static const char * const uart2_rxd_grp2[] = { "uart2_rxd_grp2", }; -static const char * const uart2_txd_grp0[] = { "uart2_txd_grp0", }; -static const char * const uart2_txd_grp1[] = { "uart2_txd_grp1", }; -static const char * const uart2_txd_grp2[] = { "uart2_txd_grp2", }; -static const char * const uart3_cts_grp0[] = { "uart3_cts_grp0", }; -static const char * const uart3_cts_grp1[] = { "uart3_cts_grp1", }; -static const char * const uart3_cts_grp2[] = { "uart3_cts_grp2", }; -static const char * const uart3_rts_grp0[] = { "uart3_rts_grp0", }; -static const char * const uart3_rts_grp1[] = { "uart3_rts_grp1", }; -static const char * const uart3_rts_grp2[] = { "uart3_rts_grp2", }; -static const char * const uart3_rxd_grp0[] = { "uart3_rxd_grp0", }; -static const char * const uart3_rxd_grp1[] = { "uart3_rxd_grp1", }; -static const char * const uart3_rxd_grp2[] = { "uart3_rxd_grp2", }; -static const char * const uart3_txd_grp0[] = { "uart3_txd_grp0", }; -static const char * const uart3_txd_grp1[] = { "uart3_txd_grp1", }; -static const char * const uart3_txd_grp2[] = { "uart3_txd_grp2", }; -static const char * const uart4_basic_grp[] = { "uart4_basic_grp", }; -static const char * const uart4_cts_grp0[] = { "uart4_cts_grp0", }; -static const char * const uart4_cts_grp1[] = { "uart4_cts_grp1", }; -static const char * const uart4_cts_grp2[] = { "uart4_cts_grp2", }; -static const char * const uart4_rts_grp0[] = { "uart4_rts_grp0", }; -static const char * const uart4_rts_grp1[] = { "uart4_rts_grp1", }; -static const char * const uart4_rts_grp2[] = { "uart4_rts_grp2", }; -static const char * const usb0_drvvbus_grp0[] = { "usb0_drvvbus_grp0", }; -static const char * const usb0_drvvbus_grp1[] = { "usb0_drvvbus_grp1", }; -static const char * const usb1_drvvbus_grp0[] = { "usb1_drvvbus_grp0", }; -static const char * const usb1_drvvbus_grp1[] = { "usb1_drvvbus_grp1", }; -static const char * const visbus_dout_grp[] = { "visbus_dout_grp", }; -static const char * const vi_vip1_grp[] = { "vi_vip1_grp", }; -static const char * const vi_vip1_ext_grp[] = { "vi_vip1_ext_grp", }; -static const char * const vi_vip1_low8bit_grp[] = { "vi_vip1_low8bit_grp", }; -static const char * const vi_vip1_high8bit_grp[] = { "vi_vip1_high8bit_grp", }; - -static struct atlas7_pad_mux gnss_gpio_grp_pad_mux[] = { - MUX(1, 119, 0, N, N, N, N), - MUX(1, 120, 0, N, N, N, N), - MUX(1, 121, 0, N, N, N, N), - MUX(1, 122, 0, N, N, N, N), - MUX(1, 123, 0, N, N, N, N), - MUX(1, 124, 0, N, N, N, N), - MUX(1, 125, 0, N, N, N, N), - MUX(1, 126, 0, N, N, N, N), - MUX(1, 127, 0, N, N, N, N), - MUX(1, 128, 0, N, N, N, N), - MUX(1, 22, 0, N, N, N, N), - MUX(1, 23, 0, N, N, N, N), - MUX(1, 24, 0, N, N, N, N), - MUX(1, 25, 0, N, N, N, N), - MUX(1, 26, 0, N, N, N, N), - MUX(1, 27, 0, N, N, N, N), - MUX(1, 28, 0, N, N, N, N), - MUX(1, 29, 0, N, N, N, N), - MUX(1, 30, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux gnss_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gnss_gpio_grp_pad_mux), - .pad_mux_list = gnss_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux lcd_vip_gpio_grp_pad_mux[] = { - MUX(1, 74, 0, N, N, N, N), - MUX(1, 75, 0, N, N, N, N), - MUX(1, 76, 0, N, N, N, N), - MUX(1, 77, 0, N, N, N, N), - MUX(1, 78, 0, N, N, N, N), - MUX(1, 79, 0, N, N, N, N), - MUX(1, 80, 0, N, N, N, N), - MUX(1, 81, 0, N, N, N, N), - MUX(1, 82, 0, N, N, N, N), - MUX(1, 83, 0, N, N, N, N), - MUX(1, 84, 0, N, N, N, N), - MUX(1, 53, 0, N, N, N, N), - MUX(1, 54, 0, N, N, N, N), - MUX(1, 55, 0, N, N, N, N), - MUX(1, 56, 0, N, N, N, N), - MUX(1, 57, 0, N, N, N, N), - MUX(1, 58, 0, N, N, N, N), - MUX(1, 59, 0, N, N, N, N), - MUX(1, 60, 0, N, N, N, N), - MUX(1, 61, 0, N, N, N, N), - MUX(1, 62, 0, N, N, N, N), - MUX(1, 63, 0, N, N, N, N), - MUX(1, 64, 0, N, N, N, N), - MUX(1, 65, 0, N, N, N, N), - MUX(1, 66, 0, N, N, N, N), - MUX(1, 67, 0, N, N, N, N), - MUX(1, 68, 0, N, N, N, N), - MUX(1, 69, 0, N, N, N, N), - MUX(1, 70, 0, N, N, N, N), - MUX(1, 71, 0, N, N, N, N), - MUX(1, 72, 0, N, N, N, N), - MUX(1, 73, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux lcd_vip_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(lcd_vip_gpio_grp_pad_mux), - .pad_mux_list = lcd_vip_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux sdio_i2s_gpio_grp_pad_mux[] = { - MUX(1, 31, 0, N, N, N, N), - MUX(1, 32, 0, N, N, N, N), - MUX(1, 33, 0, N, N, N, N), - MUX(1, 34, 0, N, N, N, N), - MUX(1, 35, 0, N, N, N, N), - MUX(1, 36, 0, N, N, N, N), - MUX(1, 85, 0, N, N, N, N), - MUX(1, 86, 0, N, N, N, N), - MUX(1, 87, 0, N, N, N, N), - MUX(1, 88, 0, N, N, N, N), - MUX(1, 89, 0, N, N, N, N), - MUX(1, 90, 0, N, N, N, N), - MUX(1, 129, 0, N, N, N, N), - MUX(1, 130, 0, N, N, N, N), - MUX(1, 131, 0, N, N, N, N), - MUX(1, 132, 0, N, N, N, N), - MUX(1, 91, 0, N, N, N, N), - MUX(1, 92, 0, N, N, N, N), - MUX(1, 93, 0, N, N, N, N), - MUX(1, 94, 0, N, N, N, N), - MUX(1, 95, 0, N, N, N, N), - MUX(1, 96, 0, N, N, N, N), - MUX(1, 112, 0, N, N, N, N), - MUX(1, 113, 0, N, N, N, N), - MUX(1, 114, 0, N, N, N, N), - MUX(1, 115, 0, N, N, N, N), - MUX(1, 116, 0, N, N, N, N), - MUX(1, 117, 0, N, N, N, N), - MUX(1, 118, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux sdio_i2s_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sdio_i2s_gpio_grp_pad_mux), - .pad_mux_list = sdio_i2s_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux sp_rgmii_gpio_grp_pad_mux[] = { - MUX(1, 97, 0, N, N, N, N), - MUX(1, 98, 0, N, N, N, N), - MUX(1, 99, 0, N, N, N, N), - MUX(1, 100, 0, N, N, N, N), - MUX(1, 101, 0, N, N, N, N), - MUX(1, 102, 0, N, N, N, N), - MUX(1, 103, 0, N, N, N, N), - MUX(1, 104, 0, N, N, N, N), - MUX(1, 105, 0, N, N, N, N), - MUX(1, 106, 0, N, N, N, N), - MUX(1, 107, 0, N, N, N, N), - MUX(1, 108, 0, N, N, N, N), - MUX(1, 109, 0, N, N, N, N), - MUX(1, 110, 0, N, N, N, N), - MUX(1, 111, 0, N, N, N, N), - MUX(1, 18, 0, N, N, N, N), - MUX(1, 19, 0, N, N, N, N), - MUX(1, 20, 0, N, N, N, N), - MUX(1, 21, 0, N, N, N, N), - MUX(1, 141, 0, N, N, N, N), - MUX(1, 142, 0, N, N, N, N), - MUX(1, 143, 0, N, N, N, N), - MUX(1, 144, 0, N, N, N, N), - MUX(1, 145, 0, N, N, N, N), - MUX(1, 146, 0, N, N, N, N), - MUX(1, 147, 0, N, N, N, N), - MUX(1, 148, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux sp_rgmii_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sp_rgmii_gpio_grp_pad_mux), - .pad_mux_list = sp_rgmii_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux lvds_gpio_grp_pad_mux[] = { - MUX(1, 157, 0, N, N, N, N), - MUX(1, 158, 0, N, N, N, N), - MUX(1, 155, 0, N, N, N, N), - MUX(1, 156, 0, N, N, N, N), - MUX(1, 153, 0, N, N, N, N), - MUX(1, 154, 0, N, N, N, N), - MUX(1, 151, 0, N, N, N, N), - MUX(1, 152, 0, N, N, N, N), - MUX(1, 149, 0, N, N, N, N), - MUX(1, 150, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux lvds_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(lvds_gpio_grp_pad_mux), - .pad_mux_list = lvds_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux jtag_uart_nand_gpio_grp_pad_mux[] = { - MUX(1, 44, 0, N, N, N, N), - MUX(1, 43, 0, N, N, N, N), - MUX(1, 42, 0, N, N, N, N), - MUX(1, 41, 0, N, N, N, N), - MUX(1, 40, 0, N, N, N, N), - MUX(1, 39, 0, N, N, N, N), - MUX(1, 38, 0, N, N, N, N), - MUX(1, 37, 0, N, N, N, N), - MUX(1, 46, 0, N, N, N, N), - MUX(1, 47, 0, N, N, N, N), - MUX(1, 48, 0, N, N, N, N), - MUX(1, 49, 0, N, N, N, N), - MUX(1, 50, 0, N, N, N, N), - MUX(1, 52, 0, N, N, N, N), - MUX(1, 51, 0, N, N, N, N), - MUX(1, 45, 0, N, N, N, N), - MUX(1, 133, 0, N, N, N, N), - MUX(1, 134, 0, N, N, N, N), - MUX(1, 135, 0, N, N, N, N), - MUX(1, 136, 0, N, N, N, N), - MUX(1, 137, 0, N, N, N, N), - MUX(1, 138, 0, N, N, N, N), - MUX(1, 139, 0, N, N, N, N), - MUX(1, 140, 0, N, N, N, N), - MUX(1, 159, 0, N, N, N, N), - MUX(1, 160, 0, N, N, N, N), - MUX(1, 161, 0, N, N, N, N), - MUX(1, 162, 0, N, N, N, N), - MUX(1, 163, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux jtag_uart_nand_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_uart_nand_gpio_grp_pad_mux), - .pad_mux_list = jtag_uart_nand_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux rtc_gpio_grp_pad_mux[] = { - MUX(0, 0, 0, N, N, N, N), - MUX(0, 1, 0, N, N, N, N), - MUX(0, 2, 0, N, N, N, N), - MUX(0, 3, 0, N, N, N, N), - MUX(0, 4, 0, N, N, N, N), - MUX(0, 10, 0, N, N, N, N), - MUX(0, 11, 0, N, N, N, N), - MUX(0, 12, 0, N, N, N, N), - MUX(0, 13, 0, N, N, N, N), - MUX(0, 14, 0, N, N, N, N), - MUX(0, 15, 0, N, N, N, N), - MUX(0, 16, 0, N, N, N, N), - MUX(0, 17, 0, N, N, N, N), - MUX(0, 9, 0, N, N, N, N), -}; - -static struct atlas7_grp_mux rtc_gpio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(rtc_gpio_grp_pad_mux), - .pad_mux_list = rtc_gpio_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_ac97_grp_pad_mux[] = { - MUX(1, 113, 2, N, N, N, N), - MUX(1, 118, 2, N, N, N, N), - MUX(1, 115, 2, N, N, N, N), - MUX(1, 114, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_ac97_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_ac97_grp_pad_mux), - .pad_mux_list = audio_ac97_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_digmic_grp0_pad_mux[] = { - MUX(1, 51, 3, 0xa10, 20, 0xa90, 20), -}; - -static struct atlas7_grp_mux audio_digmic_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_digmic_grp0_pad_mux), - .pad_mux_list = audio_digmic_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_digmic_grp1_pad_mux[] = { - MUX(1, 122, 5, 0xa10, 20, 0xa90, 20), -}; - -static struct atlas7_grp_mux audio_digmic_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_digmic_grp1_pad_mux), - .pad_mux_list = audio_digmic_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_digmic_grp2_pad_mux[] = { - MUX(1, 161, 7, 0xa10, 20, 0xa90, 20), -}; - -static struct atlas7_grp_mux audio_digmic_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_digmic_grp2_pad_mux), - .pad_mux_list = audio_digmic_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_func_dbg_grp_pad_mux[] = { - MUX(1, 141, 4, N, N, N, N), - MUX(1, 144, 4, N, N, N, N), - MUX(1, 44, 6, N, N, N, N), - MUX(1, 43, 6, N, N, N, N), - MUX(1, 42, 6, N, N, N, N), - MUX(1, 41, 6, N, N, N, N), - MUX(1, 40, 6, N, N, N, N), - MUX(1, 39, 6, N, N, N, N), - MUX(1, 38, 6, N, N, N, N), - MUX(1, 37, 6, N, N, N, N), - MUX(1, 74, 6, N, N, N, N), - MUX(1, 75, 6, N, N, N, N), - MUX(1, 76, 6, N, N, N, N), - MUX(1, 77, 6, N, N, N, N), - MUX(1, 78, 6, N, N, N, N), - MUX(1, 79, 6, N, N, N, N), - MUX(1, 81, 6, N, N, N, N), - MUX(1, 113, 6, N, N, N, N), - MUX(1, 114, 6, N, N, N, N), - MUX(1, 118, 6, N, N, N, N), - MUX(1, 115, 6, N, N, N, N), - MUX(1, 49, 6, N, N, N, N), - MUX(1, 50, 6, N, N, N, N), - MUX(1, 142, 4, N, N, N, N), - MUX(1, 143, 4, N, N, N, N), - MUX(1, 80, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_func_dbg_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_func_dbg_grp_pad_mux), - .pad_mux_list = audio_func_dbg_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_i2s_grp_pad_mux[] = { - MUX(1, 118, 1, N, N, N, N), - MUX(1, 115, 1, N, N, N, N), - MUX(1, 116, 1, N, N, N, N), - MUX(1, 117, 1, N, N, N, N), - MUX(1, 112, 1, N, N, N, N), - MUX(1, 113, 1, N, N, N, N), - MUX(1, 114, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_i2s_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_i2s_grp_pad_mux), - .pad_mux_list = audio_i2s_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_i2s_2ch_grp_pad_mux[] = { - MUX(1, 118, 1, N, N, N, N), - MUX(1, 115, 1, N, N, N, N), - MUX(1, 112, 1, N, N, N, N), - MUX(1, 113, 1, N, N, N, N), - MUX(1, 114, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_i2s_2ch_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_i2s_2ch_grp_pad_mux), - .pad_mux_list = audio_i2s_2ch_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_i2s_extclk_grp_pad_mux[] = { - MUX(1, 112, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_i2s_extclk_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_i2s_extclk_grp_pad_mux), - .pad_mux_list = audio_i2s_extclk_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_spdif_out_grp0_pad_mux[] = { - MUX(1, 112, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_spdif_out_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_spdif_out_grp0_pad_mux), - .pad_mux_list = audio_spdif_out_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_spdif_out_grp1_pad_mux[] = { - MUX(1, 116, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_spdif_out_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_spdif_out_grp1_pad_mux), - .pad_mux_list = audio_spdif_out_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_spdif_out_grp2_pad_mux[] = { - MUX(1, 142, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_spdif_out_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_spdif_out_grp2_pad_mux), - .pad_mux_list = audio_spdif_out_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_basic_grp_pad_mux[] = { - MUX(1, 143, 1, N, N, N, N), - MUX(1, 142, 1, N, N, N, N), - MUX(1, 141, 1, N, N, N, N), - MUX(1, 144, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux audio_uart0_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_basic_grp_pad_mux), - .pad_mux_list = audio_uart0_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_urfs_grp0_pad_mux[] = { - MUX(1, 117, 5, 0xa10, 28, 0xa90, 28), -}; - -static struct atlas7_grp_mux audio_uart0_urfs_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_urfs_grp0_pad_mux), - .pad_mux_list = audio_uart0_urfs_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_urfs_grp1_pad_mux[] = { - MUX(1, 139, 3, 0xa10, 28, 0xa90, 28), -}; - -static struct atlas7_grp_mux audio_uart0_urfs_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_urfs_grp1_pad_mux), - .pad_mux_list = audio_uart0_urfs_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_urfs_grp2_pad_mux[] = { - MUX(1, 163, 3, 0xa10, 28, 0xa90, 28), -}; - -static struct atlas7_grp_mux audio_uart0_urfs_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_urfs_grp2_pad_mux), - .pad_mux_list = audio_uart0_urfs_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart0_urfs_grp3_pad_mux[] = { - MUX(1, 162, 6, 0xa10, 28, 0xa90, 28), -}; - -static struct atlas7_grp_mux audio_uart0_urfs_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart0_urfs_grp3_pad_mux), - .pad_mux_list = audio_uart0_urfs_grp3_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart1_basic_grp_pad_mux[] = { - MUX(1, 147, 1, 0xa10, 24, 0xa90, 24), - MUX(1, 146, 1, 0xa10, 25, 0xa90, 25), - MUX(1, 145, 1, 0xa10, 23, 0xa90, 23), - MUX(1, 148, 1, 0xa10, 22, 0xa90, 22), -}; - -static struct atlas7_grp_mux audio_uart1_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart1_basic_grp_pad_mux), - .pad_mux_list = audio_uart1_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart1_urfs_grp0_pad_mux[] = { - MUX(1, 117, 6, 0xa10, 29, 0xa90, 29), -}; - -static struct atlas7_grp_mux audio_uart1_urfs_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart1_urfs_grp0_pad_mux), - .pad_mux_list = audio_uart1_urfs_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart1_urfs_grp1_pad_mux[] = { - MUX(1, 140, 3, 0xa10, 29, 0xa90, 29), -}; - -static struct atlas7_grp_mux audio_uart1_urfs_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart1_urfs_grp1_pad_mux), - .pad_mux_list = audio_uart1_urfs_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart1_urfs_grp2_pad_mux[] = { - MUX(1, 163, 4, 0xa10, 29, 0xa90, 29), -}; - -static struct atlas7_grp_mux audio_uart1_urfs_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart1_urfs_grp2_pad_mux), - .pad_mux_list = audio_uart1_urfs_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urfs_grp0_pad_mux[] = { - MUX(1, 139, 4, 0xa10, 30, 0xa90, 30), -}; - -static struct atlas7_grp_mux audio_uart2_urfs_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urfs_grp0_pad_mux), - .pad_mux_list = audio_uart2_urfs_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urfs_grp1_pad_mux[] = { - MUX(1, 163, 6, 0xa10, 30, 0xa90, 30), -}; - -static struct atlas7_grp_mux audio_uart2_urfs_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urfs_grp1_pad_mux), - .pad_mux_list = audio_uart2_urfs_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urfs_grp2_pad_mux[] = { - MUX(1, 96, 3, 0xa10, 30, 0xa90, 30), -}; - -static struct atlas7_grp_mux audio_uart2_urfs_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urfs_grp2_pad_mux), - .pad_mux_list = audio_uart2_urfs_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urxd_grp0_pad_mux[] = { - MUX(1, 20, 2, 0xa00, 24, 0xa80, 24), -}; - -static struct atlas7_grp_mux audio_uart2_urxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urxd_grp0_pad_mux), - .pad_mux_list = audio_uart2_urxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urxd_grp1_pad_mux[] = { - MUX(1, 109, 2, 0xa00, 24, 0xa80, 24), -}; - -static struct atlas7_grp_mux audio_uart2_urxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urxd_grp1_pad_mux), - .pad_mux_list = audio_uart2_urxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_urxd_grp2_pad_mux[] = { - MUX(1, 93, 3, 0xa00, 24, 0xa80, 24), -}; - -static struct atlas7_grp_mux audio_uart2_urxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_urxd_grp2_pad_mux), - .pad_mux_list = audio_uart2_urxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_usclk_grp0_pad_mux[] = { - MUX(1, 19, 2, 0xa00, 23, 0xa80, 23), -}; - -static struct atlas7_grp_mux audio_uart2_usclk_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_usclk_grp0_pad_mux), - .pad_mux_list = audio_uart2_usclk_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_usclk_grp1_pad_mux[] = { - MUX(1, 101, 2, 0xa00, 23, 0xa80, 23), -}; - -static struct atlas7_grp_mux audio_uart2_usclk_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_usclk_grp1_pad_mux), - .pad_mux_list = audio_uart2_usclk_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_usclk_grp2_pad_mux[] = { - MUX(1, 91, 3, 0xa00, 23, 0xa80, 23), -}; - -static struct atlas7_grp_mux audio_uart2_usclk_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_usclk_grp2_pad_mux), - .pad_mux_list = audio_uart2_usclk_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utfs_grp0_pad_mux[] = { - MUX(1, 18, 2, 0xa00, 22, 0xa80, 22), -}; - -static struct atlas7_grp_mux audio_uart2_utfs_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utfs_grp0_pad_mux), - .pad_mux_list = audio_uart2_utfs_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utfs_grp1_pad_mux[] = { - MUX(1, 111, 2, 0xa00, 22, 0xa80, 22), -}; - -static struct atlas7_grp_mux audio_uart2_utfs_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utfs_grp1_pad_mux), - .pad_mux_list = audio_uart2_utfs_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utfs_grp2_pad_mux[] = { - MUX(1, 94, 3, 0xa00, 22, 0xa80, 22), -}; - -static struct atlas7_grp_mux audio_uart2_utfs_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utfs_grp2_pad_mux), - .pad_mux_list = audio_uart2_utfs_grp2_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utxd_grp0_pad_mux[] = { - MUX(1, 21, 2, 0xa00, 25, 0xa80, 25), -}; - -static struct atlas7_grp_mux audio_uart2_utxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utxd_grp0_pad_mux), - .pad_mux_list = audio_uart2_utxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utxd_grp1_pad_mux[] = { - MUX(1, 110, 2, 0xa00, 25, 0xa80, 25), -}; - -static struct atlas7_grp_mux audio_uart2_utxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utxd_grp1_pad_mux), - .pad_mux_list = audio_uart2_utxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux audio_uart2_utxd_grp2_pad_mux[] = { - MUX(1, 92, 3, 0xa00, 25, 0xa80, 25), -}; - -static struct atlas7_grp_mux audio_uart2_utxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(audio_uart2_utxd_grp2_pad_mux), - .pad_mux_list = audio_uart2_utxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux c_can_trnsvr_en_grp0_pad_mux[] = { - MUX(0, 2, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux c_can_trnsvr_en_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(c_can_trnsvr_en_grp0_pad_mux), - .pad_mux_list = c_can_trnsvr_en_grp0_pad_mux, -}; - -static struct atlas7_pad_mux c_can_trnsvr_en_grp1_pad_mux[] = { - MUX(0, 0, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c_can_trnsvr_en_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(c_can_trnsvr_en_grp1_pad_mux), - .pad_mux_list = c_can_trnsvr_en_grp1_pad_mux, -}; - -static struct atlas7_pad_mux c_can_trnsvr_intr_grp_pad_mux[] = { - MUX(0, 1, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c_can_trnsvr_intr_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c_can_trnsvr_intr_grp_pad_mux), - .pad_mux_list = c_can_trnsvr_intr_grp_pad_mux, -}; - -static struct atlas7_pad_mux c_can_trnsvr_stb_n_grp_pad_mux[] = { - MUX(0, 3, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux c_can_trnsvr_stb_n_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c_can_trnsvr_stb_n_grp_pad_mux), - .pad_mux_list = c_can_trnsvr_stb_n_grp_pad_mux, -}; - -static struct atlas7_pad_mux c0_can_rxd_trnsv0_grp_pad_mux[] = { - MUX(0, 11, 1, 0xa08, 9, 0xa88, 9), -}; - -static struct atlas7_grp_mux c0_can_rxd_trnsv0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c0_can_rxd_trnsv0_grp_pad_mux), - .pad_mux_list = c0_can_rxd_trnsv0_grp_pad_mux, -}; - -static struct atlas7_pad_mux c0_can_rxd_trnsv1_grp_pad_mux[] = { - MUX(0, 2, 5, 0xa10, 9, 0xa90, 9), -}; - -static struct atlas7_grp_mux c0_can_rxd_trnsv1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c0_can_rxd_trnsv1_grp_pad_mux), - .pad_mux_list = c0_can_rxd_trnsv1_grp_pad_mux, -}; - -static struct atlas7_pad_mux c0_can_txd_trnsv0_grp_pad_mux[] = { - MUX(0, 10, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux c0_can_txd_trnsv0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c0_can_txd_trnsv0_grp_pad_mux), - .pad_mux_list = c0_can_txd_trnsv0_grp_pad_mux, -}; - -static struct atlas7_pad_mux c0_can_txd_trnsv1_grp_pad_mux[] = { - MUX(0, 3, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux c0_can_txd_trnsv1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(c0_can_txd_trnsv1_grp_pad_mux), - .pad_mux_list = c0_can_txd_trnsv1_grp_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_rxd_grp0_pad_mux[] = { - MUX(1, 138, 2, 0xa00, 4, 0xa80, 4), -}; - -static struct atlas7_grp_mux c1_can_rxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_rxd_grp0_pad_mux), - .pad_mux_list = c1_can_rxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_rxd_grp1_pad_mux[] = { - MUX(1, 147, 2, 0xa00, 4, 0xa80, 4), -}; - -static struct atlas7_grp_mux c1_can_rxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_rxd_grp1_pad_mux), - .pad_mux_list = c1_can_rxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_rxd_grp2_pad_mux[] = { - MUX(0, 2, 2, 0xa00, 4, 0xa80, 4), -}; - -static struct atlas7_grp_mux c1_can_rxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_rxd_grp2_pad_mux), - .pad_mux_list = c1_can_rxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_rxd_grp3_pad_mux[] = { - MUX(1, 162, 4, 0xa00, 4, 0xa80, 4), -}; - -static struct atlas7_grp_mux c1_can_rxd_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_rxd_grp3_pad_mux), - .pad_mux_list = c1_can_rxd_grp3_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_txd_grp0_pad_mux[] = { - MUX(1, 137, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c1_can_txd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_txd_grp0_pad_mux), - .pad_mux_list = c1_can_txd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_txd_grp1_pad_mux[] = { - MUX(1, 146, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c1_can_txd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_txd_grp1_pad_mux), - .pad_mux_list = c1_can_txd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_txd_grp2_pad_mux[] = { - MUX(0, 3, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux c1_can_txd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_txd_grp2_pad_mux), - .pad_mux_list = c1_can_txd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux c1_can_txd_grp3_pad_mux[] = { - MUX(1, 161, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux c1_can_txd_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(c1_can_txd_grp3_pad_mux), - .pad_mux_list = c1_can_txd_grp3_pad_mux, -}; - -static struct atlas7_pad_mux ca_audio_lpc_grp_pad_mux[] = { - MUX(1, 62, 4, N, N, N, N), - MUX(1, 63, 4, N, N, N, N), - MUX(1, 64, 4, N, N, N, N), - MUX(1, 65, 4, N, N, N, N), - MUX(1, 66, 4, N, N, N, N), - MUX(1, 67, 4, N, N, N, N), - MUX(1, 68, 4, N, N, N, N), - MUX(1, 69, 4, N, N, N, N), - MUX(1, 70, 4, N, N, N, N), - MUX(1, 71, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_audio_lpc_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_audio_lpc_grp_pad_mux), - .pad_mux_list = ca_audio_lpc_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_bt_lpc_grp_pad_mux[] = { - MUX(1, 85, 5, N, N, N, N), - MUX(1, 86, 5, N, N, N, N), - MUX(1, 87, 5, N, N, N, N), - MUX(1, 88, 5, N, N, N, N), - MUX(1, 89, 5, N, N, N, N), - MUX(1, 90, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_bt_lpc_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_bt_lpc_grp_pad_mux), - .pad_mux_list = ca_bt_lpc_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_coex_grp_pad_mux[] = { - MUX(1, 129, 1, N, N, N, N), - MUX(1, 130, 1, N, N, N, N), - MUX(1, 131, 1, N, N, N, N), - MUX(1, 132, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_coex_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_coex_grp_pad_mux), - .pad_mux_list = ca_coex_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_curator_lpc_grp_pad_mux[] = { - MUX(1, 57, 4, N, N, N, N), - MUX(1, 58, 4, N, N, N, N), - MUX(1, 59, 4, N, N, N, N), - MUX(1, 60, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_curator_lpc_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_curator_lpc_grp_pad_mux), - .pad_mux_list = ca_curator_lpc_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_pcm_debug_grp_pad_mux[] = { - MUX(1, 91, 5, N, N, N, N), - MUX(1, 93, 5, N, N, N, N), - MUX(1, 94, 5, N, N, N, N), - MUX(1, 92, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_pcm_debug_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_pcm_debug_grp_pad_mux), - .pad_mux_list = ca_pcm_debug_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_pio_grp_pad_mux[] = { - MUX(1, 121, 2, N, N, N, N), - MUX(1, 122, 2, N, N, N, N), - MUX(1, 125, 6, N, N, N, N), - MUX(1, 126, 6, N, N, N, N), - MUX(1, 38, 5, N, N, N, N), - MUX(1, 37, 5, N, N, N, N), - MUX(1, 47, 5, N, N, N, N), - MUX(1, 49, 5, N, N, N, N), - MUX(1, 50, 5, N, N, N, N), - MUX(1, 54, 4, N, N, N, N), - MUX(1, 55, 4, N, N, N, N), - MUX(1, 56, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_pio_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_pio_grp_pad_mux), - .pad_mux_list = ca_pio_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_sdio_debug_grp_pad_mux[] = { - MUX(1, 40, 5, N, N, N, N), - MUX(1, 39, 5, N, N, N, N), - MUX(1, 44, 5, N, N, N, N), - MUX(1, 43, 5, N, N, N, N), - MUX(1, 42, 5, N, N, N, N), - MUX(1, 41, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_sdio_debug_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_sdio_debug_grp_pad_mux), - .pad_mux_list = ca_sdio_debug_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_spi_grp_pad_mux[] = { - MUX(1, 82, 5, N, N, N, N), - MUX(1, 79, 5, 0xa08, 6, 0xa88, 6), - MUX(1, 80, 5, N, N, N, N), - MUX(1, 81, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_spi_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_spi_grp_pad_mux), - .pad_mux_list = ca_spi_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_trb_grp_pad_mux[] = { - MUX(1, 91, 4, N, N, N, N), - MUX(1, 93, 4, N, N, N, N), - MUX(1, 94, 4, N, N, N, N), - MUX(1, 95, 4, N, N, N, N), - MUX(1, 96, 4, N, N, N, N), - MUX(1, 78, 5, N, N, N, N), - MUX(1, 74, 5, N, N, N, N), - MUX(1, 75, 5, N, N, N, N), - MUX(1, 76, 5, N, N, N, N), - MUX(1, 77, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_trb_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_trb_grp_pad_mux), - .pad_mux_list = ca_trb_grp_pad_mux, -}; - -static struct atlas7_pad_mux ca_uart_debug_grp_pad_mux[] = { - MUX(1, 136, 3, N, N, N, N), - MUX(1, 135, 3, N, N, N, N), - MUX(1, 134, 3, N, N, N, N), - MUX(1, 133, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux ca_uart_debug_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ca_uart_debug_grp_pad_mux), - .pad_mux_list = ca_uart_debug_grp_pad_mux, -}; - -static struct atlas7_pad_mux clkc_grp0_pad_mux[] = { - MUX(1, 30, 2, 0xa08, 14, 0xa88, 14), - MUX(1, 47, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux clkc_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(clkc_grp0_pad_mux), - .pad_mux_list = clkc_grp0_pad_mux, -}; - -static struct atlas7_pad_mux clkc_grp1_pad_mux[] = { - MUX(1, 78, 3, 0xa08, 14, 0xa88, 14), - MUX(1, 54, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux clkc_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(clkc_grp1_pad_mux), - .pad_mux_list = clkc_grp1_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_i2c_grp_pad_mux[] = { - MUX(1, 128, 2, N, N, N, N), - MUX(1, 127, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_i2c_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_i2c_grp_pad_mux), - .pad_mux_list = gn_gnss_i2c_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_uart_nopause_grp_pad_mux[] = { - MUX(1, 134, 4, N, N, N, N), - MUX(1, 133, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_uart_nopause_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_uart_nopause_grp_pad_mux), - .pad_mux_list = gn_gnss_uart_nopause_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_uart_grp_pad_mux[] = { - MUX(1, 134, 4, N, N, N, N), - MUX(1, 133, 4, N, N, N, N), - MUX(1, 136, 4, N, N, N, N), - MUX(1, 135, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_uart_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_uart_grp_pad_mux), - .pad_mux_list = gn_gnss_uart_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_spi_grp0_pad_mux[] = { - MUX(1, 22, 1, N, N, N, N), - MUX(1, 25, 1, N, N, N, N), - MUX(1, 23, 1, 0xa00, 10, 0xa80, 10), - MUX(1, 24, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_spi_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_spi_grp0_pad_mux), - .pad_mux_list = gn_trg_spi_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_spi_grp1_pad_mux[] = { - MUX(1, 82, 3, N, N, N, N), - MUX(1, 79, 3, N, N, N, N), - MUX(1, 80, 3, 0xa00, 10, 0xa80, 10), - MUX(1, 81, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_spi_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_spi_grp1_pad_mux), - .pad_mux_list = gn_trg_spi_grp1_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_grp_pad_mux[] = { - MUX(1, 54, 3, N, N, N, N), - MUX(1, 53, 3, N, N, N, N), - MUX(1, 82, 7, N, N, N, N), - MUX(1, 74, 7, N, N, N, N), - MUX(1, 75, 7, N, N, N, N), - MUX(1, 76, 7, N, N, N, N), - MUX(1, 77, 7, N, N, N, N), - MUX(1, 78, 7, N, N, N, N), - MUX(1, 79, 7, N, N, N, N), - MUX(1, 80, 7, N, N, N, N), - MUX(1, 81, 7, N, N, N, N), - MUX(1, 83, 7, N, N, N, N), - MUX(1, 84, 7, N, N, N, N), - MUX(1, 73, 3, N, N, N, N), - MUX(1, 55, 3, N, N, N, N), - MUX(1, 56, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_grp_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_grp_pad_mux), - .pad_mux_list = cvbs_dbg_grp_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp0_pad_mux[] = { - MUX(1, 57, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp0_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp0_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp1_pad_mux[] = { - MUX(1, 58, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp1_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp1_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp2_pad_mux[] = { - MUX(1, 59, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp2_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp2_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp3_pad_mux[] = { - MUX(1, 60, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp3_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp3_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp4_pad_mux[] = { - MUX(1, 61, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp4_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp4_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp4_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp5_pad_mux[] = { - MUX(1, 62, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp5_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp5_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp5_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp6_pad_mux[] = { - MUX(1, 63, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp6_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp6_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp6_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp7_pad_mux[] = { - MUX(1, 64, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp7_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp7_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp7_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp8_pad_mux[] = { - MUX(1, 65, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp8_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp8_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp8_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp9_pad_mux[] = { - MUX(1, 66, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp9_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp9_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp9_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp10_pad_mux[] = { - MUX(1, 67, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp10_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp10_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp10_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp11_pad_mux[] = { - MUX(1, 68, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp11_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp11_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp11_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp12_pad_mux[] = { - MUX(1, 69, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp12_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp12_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp12_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp13_pad_mux[] = { - MUX(1, 70, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp13_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp13_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp13_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp14_pad_mux[] = { - MUX(1, 71, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp14_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp14_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp14_pad_mux, -}; - -static struct atlas7_pad_mux cvbs_dbg_test_grp15_pad_mux[] = { - MUX(1, 72, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux cvbs_dbg_test_grp15_mux = { - .pad_mux_count = ARRAY_SIZE(cvbs_dbg_test_grp15_pad_mux), - .pad_mux_list = cvbs_dbg_test_grp15_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_power_grp_pad_mux[] = { - MUX(1, 123, 7, N, N, N, N), - MUX(1, 124, 7, N, N, N, N), - MUX(1, 121, 7, N, N, N, N), - MUX(1, 122, 7, N, N, N, N), - MUX(1, 125, 7, N, N, N, N), - MUX(1, 120, 7, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_power_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_power_grp_pad_mux), - .pad_mux_list = gn_gnss_power_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_sw_status_grp_pad_mux[] = { - MUX(1, 57, 7, N, N, N, N), - MUX(1, 58, 7, N, N, N, N), - MUX(1, 59, 7, N, N, N, N), - MUX(1, 60, 7, N, N, N, N), - MUX(1, 61, 7, N, N, N, N), - MUX(1, 62, 7, N, N, N, N), - MUX(1, 63, 7, N, N, N, N), - MUX(1, 64, 7, N, N, N, N), - MUX(1, 65, 7, N, N, N, N), - MUX(1, 66, 7, N, N, N, N), - MUX(1, 67, 7, N, N, N, N), - MUX(1, 68, 7, N, N, N, N), - MUX(1, 69, 7, N, N, N, N), - MUX(1, 70, 7, N, N, N, N), - MUX(1, 71, 7, N, N, N, N), - MUX(1, 72, 7, N, N, N, N), - MUX(1, 53, 7, N, N, N, N), - MUX(1, 55, 7, N, N, N, N), - MUX(1, 56, 7, 0xa08, 12, 0xa88, 12), - MUX(1, 54, 7, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_sw_status_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_sw_status_grp_pad_mux), - .pad_mux_list = gn_gnss_sw_status_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_eclk_grp_pad_mux[] = { - MUX(1, 113, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_eclk_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_eclk_grp_pad_mux), - .pad_mux_list = gn_gnss_eclk_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_irq1_grp0_pad_mux[] = { - MUX(1, 112, 4, 0xa08, 10, 0xa88, 10), -}; - -static struct atlas7_grp_mux gn_gnss_irq1_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_irq1_grp0_pad_mux), - .pad_mux_list = gn_gnss_irq1_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_irq2_grp0_pad_mux[] = { - MUX(1, 118, 4, 0xa08, 11, 0xa88, 11), -}; - -static struct atlas7_grp_mux gn_gnss_irq2_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_irq2_grp0_pad_mux), - .pad_mux_list = gn_gnss_irq2_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_tm_grp_pad_mux[] = { - MUX(1, 115, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_tm_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_tm_grp_pad_mux), - .pad_mux_list = gn_gnss_tm_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_gnss_tsync_grp_pad_mux[] = { - MUX(1, 114, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_gnss_tsync_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_gnss_tsync_grp_pad_mux), - .pad_mux_list = gn_gnss_tsync_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_io_gnsssys_sw_cfg_grp_pad_mux[] = { - MUX(1, 44, 7, N, N, N, N), - MUX(1, 43, 7, N, N, N, N), - MUX(1, 42, 7, N, N, N, N), - MUX(1, 41, 7, N, N, N, N), - MUX(1, 40, 7, N, N, N, N), - MUX(1, 39, 7, N, N, N, N), - MUX(1, 38, 7, N, N, N, N), - MUX(1, 37, 7, N, N, N, N), - MUX(1, 49, 7, N, N, N, N), - MUX(1, 50, 7, N, N, N, N), - MUX(1, 91, 7, N, N, N, N), - MUX(1, 92, 7, N, N, N, N), - MUX(1, 93, 7, N, N, N, N), - MUX(1, 94, 7, N, N, N, N), - MUX(1, 95, 7, N, N, N, N), - MUX(1, 96, 7, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_io_gnsssys_sw_cfg_grp_mux = { - .pad_mux_count = ARRAY_SIZE(gn_io_gnsssys_sw_cfg_grp_pad_mux), - .pad_mux_list = gn_io_gnsssys_sw_cfg_grp_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_grp0_pad_mux[] = { - MUX(1, 29, 1, 0xa00, 6, 0xa80, 6), - MUX(1, 28, 1, 0xa00, 7, 0xa80, 7), - MUX(1, 26, 1, 0xa00, 8, 0xa80, 8), - MUX(1, 27, 1, 0xa00, 9, 0xa80, 9), -}; - -static struct atlas7_grp_mux gn_trg_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_grp0_pad_mux), - .pad_mux_list = gn_trg_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_grp1_pad_mux[] = { - MUX(1, 77, 3, 0xa00, 6, 0xa80, 6), - MUX(1, 76, 3, 0xa00, 7, 0xa80, 7), - MUX(1, 74, 3, 0xa00, 8, 0xa80, 8), - MUX(1, 75, 3, 0xa00, 9, 0xa80, 9), -}; - -static struct atlas7_grp_mux gn_trg_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_grp1_pad_mux), - .pad_mux_list = gn_trg_grp1_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_shutdown_grp0_pad_mux[] = { - MUX(1, 30, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_shutdown_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_shutdown_grp0_pad_mux), - .pad_mux_list = gn_trg_shutdown_grp0_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_shutdown_grp1_pad_mux[] = { - MUX(1, 83, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_shutdown_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_shutdown_grp1_pad_mux), - .pad_mux_list = gn_trg_shutdown_grp1_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_shutdown_grp2_pad_mux[] = { - MUX(1, 117, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_shutdown_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_shutdown_grp2_pad_mux), - .pad_mux_list = gn_trg_shutdown_grp2_pad_mux, -}; - -static struct atlas7_pad_mux gn_trg_shutdown_grp3_pad_mux[] = { - MUX(1, 123, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux gn_trg_shutdown_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(gn_trg_shutdown_grp3_pad_mux), - .pad_mux_list = gn_trg_shutdown_grp3_pad_mux, -}; - -static struct atlas7_pad_mux i2c0_grp_pad_mux[] = { - MUX(1, 128, 1, N, N, N, N), - MUX(1, 127, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux i2c0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(i2c0_grp_pad_mux), - .pad_mux_list = i2c0_grp_pad_mux, -}; - -static struct atlas7_pad_mux i2c1_grp_pad_mux[] = { - MUX(1, 126, 4, N, N, N, N), - MUX(1, 125, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux i2c1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(i2c1_grp_pad_mux), - .pad_mux_list = i2c1_grp_pad_mux, -}; - -static struct atlas7_pad_mux i2s0_grp_pad_mux[] = { - MUX(1, 91, 2, 0xa10, 12, 0xa90, 12), - MUX(1, 93, 2, 0xa10, 13, 0xa90, 13), - MUX(1, 94, 2, 0xa10, 14, 0xa90, 14), - MUX(1, 92, 2, 0xa10, 15, 0xa90, 15), -}; - -static struct atlas7_grp_mux i2s0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(i2s0_grp_pad_mux), - .pad_mux_list = i2s0_grp_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_basic_grp_pad_mux[] = { - MUX(1, 95, 2, 0xa10, 16, 0xa90, 16), - MUX(1, 96, 2, 0xa10, 19, 0xa90, 19), -}; - -static struct atlas7_grp_mux i2s1_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_basic_grp_pad_mux), - .pad_mux_list = i2s1_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp0_pad_mux[] = { - MUX(1, 61, 4, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp0_pad_mux), - .pad_mux_list = i2s1_rxd0_grp0_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp1_pad_mux[] = { - MUX(1, 131, 4, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp1_pad_mux), - .pad_mux_list = i2s1_rxd0_grp1_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp2_pad_mux[] = { - MUX(1, 129, 2, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp2_pad_mux), - .pad_mux_list = i2s1_rxd0_grp2_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp3_pad_mux[] = { - MUX(1, 117, 7, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp3_pad_mux), - .pad_mux_list = i2s1_rxd0_grp3_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd0_grp4_pad_mux[] = { - MUX(1, 83, 4, 0xa10, 17, 0xa90, 17), -}; - -static struct atlas7_grp_mux i2s1_rxd0_grp4_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd0_grp4_pad_mux), - .pad_mux_list = i2s1_rxd0_grp4_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp0_pad_mux[] = { - MUX(1, 72, 4, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp0_pad_mux), - .pad_mux_list = i2s1_rxd1_grp0_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp1_pad_mux[] = { - MUX(1, 132, 4, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp1_pad_mux), - .pad_mux_list = i2s1_rxd1_grp1_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp2_pad_mux[] = { - MUX(1, 130, 2, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp2_pad_mux), - .pad_mux_list = i2s1_rxd1_grp2_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp3_pad_mux[] = { - MUX(1, 118, 7, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp3_pad_mux), - .pad_mux_list = i2s1_rxd1_grp3_pad_mux, -}; - -static struct atlas7_pad_mux i2s1_rxd1_grp4_pad_mux[] = { - MUX(1, 84, 4, 0xa10, 18, 0xa90, 18), -}; - -static struct atlas7_grp_mux i2s1_rxd1_grp4_mux = { - .pad_mux_count = ARRAY_SIZE(i2s1_rxd1_grp4_pad_mux), - .pad_mux_list = i2s1_rxd1_grp4_pad_mux, -}; - -static struct atlas7_pad_mux jtag_jt_dbg_nsrst_grp_pad_mux[] = { - MUX(1, 125, 5, 0xa08, 2, 0xa88, 2), -}; - -static struct atlas7_grp_mux jtag_jt_dbg_nsrst_grp_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_jt_dbg_nsrst_grp_pad_mux), - .pad_mux_list = jtag_jt_dbg_nsrst_grp_pad_mux, -}; - -static struct atlas7_pad_mux jtag_ntrst_grp0_pad_mux[] = { - MUX(0, 4, 3, 0xa08, 3, 0xa88, 3), -}; - -static struct atlas7_grp_mux jtag_ntrst_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_ntrst_grp0_pad_mux), - .pad_mux_list = jtag_ntrst_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_ntrst_grp1_pad_mux[] = { - MUX(1, 163, 1, 0xa08, 3, 0xa88, 3), -}; - -static struct atlas7_grp_mux jtag_ntrst_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_ntrst_grp1_pad_mux), - .pad_mux_list = jtag_ntrst_grp1_pad_mux, -}; - -static struct atlas7_pad_mux jtag_swdiotms_grp0_pad_mux[] = { - MUX(0, 2, 3, 0xa10, 10, 0xa90, 10), -}; - -static struct atlas7_grp_mux jtag_swdiotms_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_swdiotms_grp0_pad_mux), - .pad_mux_list = jtag_swdiotms_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_swdiotms_grp1_pad_mux[] = { - MUX(1, 160, 1, 0xa10, 10, 0xa90, 10), -}; - -static struct atlas7_grp_mux jtag_swdiotms_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_swdiotms_grp1_pad_mux), - .pad_mux_list = jtag_swdiotms_grp1_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tck_grp0_pad_mux[] = { - MUX(0, 0, 3, 0xa10, 11, 0xa90, 11), -}; - -static struct atlas7_grp_mux jtag_tck_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tck_grp0_pad_mux), - .pad_mux_list = jtag_tck_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tck_grp1_pad_mux[] = { - MUX(1, 161, 1, 0xa10, 11, 0xa90, 11), -}; - -static struct atlas7_grp_mux jtag_tck_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tck_grp1_pad_mux), - .pad_mux_list = jtag_tck_grp1_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tdi_grp0_pad_mux[] = { - MUX(0, 1, 3, 0xa10, 31, 0xa90, 31), -}; - -static struct atlas7_grp_mux jtag_tdi_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tdi_grp0_pad_mux), - .pad_mux_list = jtag_tdi_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tdi_grp1_pad_mux[] = { - MUX(1, 162, 1, 0xa10, 31, 0xa90, 31), -}; - -static struct atlas7_grp_mux jtag_tdi_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tdi_grp1_pad_mux), - .pad_mux_list = jtag_tdi_grp1_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tdo_grp0_pad_mux[] = { - MUX(0, 3, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux jtag_tdo_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tdo_grp0_pad_mux), - .pad_mux_list = jtag_tdo_grp0_pad_mux, -}; - -static struct atlas7_pad_mux jtag_tdo_grp1_pad_mux[] = { - MUX(1, 159, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux jtag_tdo_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(jtag_tdo_grp1_pad_mux), - .pad_mux_list = jtag_tdo_grp1_pad_mux, -}; - -static struct atlas7_pad_mux ks_kas_spi_grp0_pad_mux[] = { - MUX(1, 141, 2, N, N, N, N), - MUX(1, 144, 2, 0xa08, 8, 0xa88, 8), - MUX(1, 143, 2, N, N, N, N), - MUX(1, 142, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux ks_kas_spi_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(ks_kas_spi_grp0_pad_mux), - .pad_mux_list = ks_kas_spi_grp0_pad_mux, -}; - -static struct atlas7_pad_mux ld_ldd_grp_pad_mux[] = { - MUX(1, 57, 1, N, N, N, N), - MUX(1, 58, 1, N, N, N, N), - MUX(1, 59, 1, N, N, N, N), - MUX(1, 60, 1, N, N, N, N), - MUX(1, 61, 1, N, N, N, N), - MUX(1, 62, 1, N, N, N, N), - MUX(1, 63, 1, N, N, N, N), - MUX(1, 64, 1, N, N, N, N), - MUX(1, 65, 1, N, N, N, N), - MUX(1, 66, 1, N, N, N, N), - MUX(1, 67, 1, N, N, N, N), - MUX(1, 68, 1, N, N, N, N), - MUX(1, 69, 1, N, N, N, N), - MUX(1, 70, 1, N, N, N, N), - MUX(1, 71, 1, N, N, N, N), - MUX(1, 72, 1, N, N, N, N), - MUX(1, 74, 2, N, N, N, N), - MUX(1, 75, 2, N, N, N, N), - MUX(1, 76, 2, N, N, N, N), - MUX(1, 77, 2, N, N, N, N), - MUX(1, 78, 2, N, N, N, N), - MUX(1, 79, 2, N, N, N, N), - MUX(1, 80, 2, N, N, N, N), - MUX(1, 81, 2, N, N, N, N), - MUX(1, 56, 1, N, N, N, N), - MUX(1, 53, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ld_ldd_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ld_ldd_grp_pad_mux), - .pad_mux_list = ld_ldd_grp_pad_mux, -}; - -static struct atlas7_pad_mux ld_ldd_16bit_grp_pad_mux[] = { - MUX(1, 57, 1, N, N, N, N), - MUX(1, 58, 1, N, N, N, N), - MUX(1, 59, 1, N, N, N, N), - MUX(1, 60, 1, N, N, N, N), - MUX(1, 61, 1, N, N, N, N), - MUX(1, 62, 1, N, N, N, N), - MUX(1, 63, 1, N, N, N, N), - MUX(1, 64, 1, N, N, N, N), - MUX(1, 65, 1, N, N, N, N), - MUX(1, 66, 1, N, N, N, N), - MUX(1, 67, 1, N, N, N, N), - MUX(1, 68, 1, N, N, N, N), - MUX(1, 69, 1, N, N, N, N), - MUX(1, 70, 1, N, N, N, N), - MUX(1, 71, 1, N, N, N, N), - MUX(1, 72, 1, N, N, N, N), - MUX(1, 56, 1, N, N, N, N), - MUX(1, 53, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ld_ldd_16bit_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ld_ldd_16bit_grp_pad_mux), - .pad_mux_list = ld_ldd_16bit_grp_pad_mux, -}; - -static struct atlas7_pad_mux ld_ldd_fck_grp_pad_mux[] = { - MUX(1, 55, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ld_ldd_fck_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ld_ldd_fck_grp_pad_mux), - .pad_mux_list = ld_ldd_fck_grp_pad_mux, -}; - -static struct atlas7_pad_mux ld_ldd_lck_grp_pad_mux[] = { - MUX(1, 54, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux ld_ldd_lck_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ld_ldd_lck_grp_pad_mux), - .pad_mux_list = ld_ldd_lck_grp_pad_mux, -}; - -static struct atlas7_pad_mux lr_lcdrom_grp_pad_mux[] = { - MUX(1, 73, 2, N, N, N, N), - MUX(1, 54, 2, N, N, N, N), - MUX(1, 57, 2, N, N, N, N), - MUX(1, 58, 2, N, N, N, N), - MUX(1, 59, 2, N, N, N, N), - MUX(1, 60, 2, N, N, N, N), - MUX(1, 61, 2, N, N, N, N), - MUX(1, 62, 2, N, N, N, N), - MUX(1, 63, 2, N, N, N, N), - MUX(1, 64, 2, N, N, N, N), - MUX(1, 65, 2, N, N, N, N), - MUX(1, 66, 2, N, N, N, N), - MUX(1, 67, 2, N, N, N, N), - MUX(1, 68, 2, N, N, N, N), - MUX(1, 69, 2, N, N, N, N), - MUX(1, 70, 2, N, N, N, N), - MUX(1, 71, 2, N, N, N, N), - MUX(1, 72, 2, N, N, N, N), - MUX(1, 56, 2, N, N, N, N), - MUX(1, 53, 2, N, N, N, N), - MUX(1, 55, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux lr_lcdrom_grp_mux = { - .pad_mux_count = ARRAY_SIZE(lr_lcdrom_grp_pad_mux), - .pad_mux_list = lr_lcdrom_grp_pad_mux, -}; - -static struct atlas7_pad_mux lvds_analog_grp_pad_mux[] = { - MUX(1, 149, 8, N, N, N, N), - MUX(1, 150, 8, N, N, N, N), - MUX(1, 151, 8, N, N, N, N), - MUX(1, 152, 8, N, N, N, N), - MUX(1, 153, 8, N, N, N, N), - MUX(1, 154, 8, N, N, N, N), - MUX(1, 155, 8, N, N, N, N), - MUX(1, 156, 8, N, N, N, N), - MUX(1, 157, 8, N, N, N, N), - MUX(1, 158, 8, N, N, N, N), -}; - -static struct atlas7_grp_mux lvds_analog_grp_mux = { - .pad_mux_count = ARRAY_SIZE(lvds_analog_grp_pad_mux), - .pad_mux_list = lvds_analog_grp_pad_mux, -}; - -static struct atlas7_pad_mux nd_df_basic_grp_pad_mux[] = { - MUX(1, 44, 1, N, N, N, N), - MUX(1, 43, 1, N, N, N, N), - MUX(1, 42, 1, N, N, N, N), - MUX(1, 41, 1, N, N, N, N), - MUX(1, 40, 1, N, N, N, N), - MUX(1, 39, 1, N, N, N, N), - MUX(1, 38, 1, N, N, N, N), - MUX(1, 37, 1, N, N, N, N), - MUX(1, 47, 1, N, N, N, N), - MUX(1, 46, 1, N, N, N, N), - MUX(1, 52, 1, N, N, N, N), - MUX(1, 45, 1, N, N, N, N), - MUX(1, 49, 1, N, N, N, N), - MUX(1, 50, 1, N, N, N, N), - MUX(1, 48, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux nd_df_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(nd_df_basic_grp_pad_mux), - .pad_mux_list = nd_df_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux nd_df_wp_grp_pad_mux[] = { - MUX(1, 124, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux nd_df_wp_grp_mux = { - .pad_mux_count = ARRAY_SIZE(nd_df_wp_grp_pad_mux), - .pad_mux_list = nd_df_wp_grp_pad_mux, -}; - -static struct atlas7_pad_mux nd_df_cs_grp_pad_mux[] = { - MUX(1, 51, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux nd_df_cs_grp_mux = { - .pad_mux_count = ARRAY_SIZE(nd_df_cs_grp_pad_mux), - .pad_mux_list = nd_df_cs_grp_pad_mux, -}; - -static struct atlas7_pad_mux ps_grp_pad_mux[] = { - MUX(1, 120, 2, N, N, N, N), - MUX(1, 119, 2, N, N, N, N), - MUX(1, 121, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux ps_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ps_grp_pad_mux), - .pad_mux_list = ps_grp_pad_mux, -}; - -static struct atlas7_pad_mux ps_no_dir_grp_pad_mux[] = { - MUX(1, 119, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux ps_no_dir_grp_mux = { - .pad_mux_count = ARRAY_SIZE(ps_no_dir_grp_pad_mux), - .pad_mux_list = ps_no_dir_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_core_on_grp_pad_mux[] = { - MUX(0, 8, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_core_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_core_on_grp_pad_mux), - .pad_mux_list = pwc_core_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_ext_on_grp_pad_mux[] = { - MUX(0, 6, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_ext_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_ext_on_grp_pad_mux), - .pad_mux_list = pwc_ext_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_gpio3_clk_grp_pad_mux[] = { - MUX(0, 3, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_gpio3_clk_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_gpio3_clk_grp_pad_mux), - .pad_mux_list = pwc_gpio3_clk_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_io_on_grp_pad_mux[] = { - MUX(0, 9, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_io_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_io_on_grp_pad_mux), - .pad_mux_list = pwc_io_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_lowbatt_b_grp0_pad_mux[] = { - MUX(0, 4, 1, 0xa08, 4, 0xa88, 4), -}; - -static struct atlas7_grp_mux pwc_lowbatt_b_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_lowbatt_b_grp0_pad_mux), - .pad_mux_list = pwc_lowbatt_b_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pwc_mem_on_grp_pad_mux[] = { - MUX(0, 7, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_mem_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_mem_on_grp_pad_mux), - .pad_mux_list = pwc_mem_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_on_key_b_grp0_pad_mux[] = { - MUX(0, 5, 1, 0xa08, 5, 0xa88, 5), -}; - -static struct atlas7_grp_mux pwc_on_key_b_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_on_key_b_grp0_pad_mux), - .pad_mux_list = pwc_on_key_b_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pwc_wakeup_src0_grp_pad_mux[] = { - MUX(0, 0, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_wakeup_src0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_wakeup_src0_grp_pad_mux), - .pad_mux_list = pwc_wakeup_src0_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_wakeup_src1_grp_pad_mux[] = { - MUX(0, 1, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_wakeup_src1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_wakeup_src1_grp_pad_mux), - .pad_mux_list = pwc_wakeup_src1_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_wakeup_src2_grp_pad_mux[] = { - MUX(0, 2, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_wakeup_src2_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_wakeup_src2_grp_pad_mux), - .pad_mux_list = pwc_wakeup_src2_grp_pad_mux, -}; - -static struct atlas7_pad_mux pwc_wakeup_src3_grp_pad_mux[] = { - MUX(0, 3, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux pwc_wakeup_src3_grp_mux = { - .pad_mux_count = ARRAY_SIZE(pwc_wakeup_src3_grp_pad_mux), - .pad_mux_list = pwc_wakeup_src3_grp_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko0_grp0_pad_mux[] = { - MUX(1, 123, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko0_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko0_grp0_pad_mux), - .pad_mux_list = pw_cko0_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko0_grp1_pad_mux[] = { - MUX(1, 101, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko0_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko0_grp1_pad_mux), - .pad_mux_list = pw_cko0_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko0_grp2_pad_mux[] = { - MUX(1, 82, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko0_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko0_grp2_pad_mux), - .pad_mux_list = pw_cko0_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko0_grp3_pad_mux[] = { - MUX(1, 162, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko0_grp3_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko0_grp3_pad_mux), - .pad_mux_list = pw_cko0_grp3_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko1_grp0_pad_mux[] = { - MUX(1, 124, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko1_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko1_grp0_pad_mux), - .pad_mux_list = pw_cko1_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko1_grp1_pad_mux[] = { - MUX(1, 110, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko1_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko1_grp1_pad_mux), - .pad_mux_list = pw_cko1_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_cko1_grp2_pad_mux[] = { - MUX(1, 163, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_cko1_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_cko1_grp2_pad_mux), - .pad_mux_list = pw_cko1_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_i2s01_clk_grp0_pad_mux[] = { - MUX(1, 125, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_i2s01_clk_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_i2s01_clk_grp0_pad_mux), - .pad_mux_list = pw_i2s01_clk_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_i2s01_clk_grp1_pad_mux[] = { - MUX(1, 117, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_i2s01_clk_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_i2s01_clk_grp1_pad_mux), - .pad_mux_list = pw_i2s01_clk_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_i2s01_clk_grp2_pad_mux[] = { - MUX(1, 132, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_i2s01_clk_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_i2s01_clk_grp2_pad_mux), - .pad_mux_list = pw_i2s01_clk_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm0_grp0_pad_mux[] = { - MUX(1, 119, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm0_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm0_grp0_pad_mux), - .pad_mux_list = pw_pwm0_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm0_grp1_pad_mux[] = { - MUX(1, 159, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm0_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm0_grp1_pad_mux), - .pad_mux_list = pw_pwm0_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm1_grp0_pad_mux[] = { - MUX(1, 120, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm1_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm1_grp0_pad_mux), - .pad_mux_list = pw_pwm1_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm1_grp1_pad_mux[] = { - MUX(1, 160, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm1_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm1_grp1_pad_mux), - .pad_mux_list = pw_pwm1_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm1_grp2_pad_mux[] = { - MUX(1, 131, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm1_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm1_grp2_pad_mux), - .pad_mux_list = pw_pwm1_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm2_grp0_pad_mux[] = { - MUX(1, 121, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm2_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm2_grp0_pad_mux), - .pad_mux_list = pw_pwm2_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm2_grp1_pad_mux[] = { - MUX(1, 98, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm2_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm2_grp1_pad_mux), - .pad_mux_list = pw_pwm2_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm2_grp2_pad_mux[] = { - MUX(1, 161, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm2_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm2_grp2_pad_mux), - .pad_mux_list = pw_pwm2_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm3_grp0_pad_mux[] = { - MUX(1, 122, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm3_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm3_grp0_pad_mux), - .pad_mux_list = pw_pwm3_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm3_grp1_pad_mux[] = { - MUX(1, 73, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm3_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm3_grp1_pad_mux), - .pad_mux_list = pw_pwm3_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm_cpu_vol_grp0_pad_mux[] = { - MUX(1, 121, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm_cpu_vol_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm_cpu_vol_grp0_pad_mux), - .pad_mux_list = pw_pwm_cpu_vol_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm_cpu_vol_grp1_pad_mux[] = { - MUX(1, 98, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm_cpu_vol_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm_cpu_vol_grp1_pad_mux), - .pad_mux_list = pw_pwm_cpu_vol_grp1_pad_mux, -}; - -static struct atlas7_pad_mux pw_pwm_cpu_vol_grp2_pad_mux[] = { - MUX(1, 161, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_pwm_cpu_vol_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(pw_pwm_cpu_vol_grp2_pad_mux), - .pad_mux_list = pw_pwm_cpu_vol_grp2_pad_mux, -}; - -static struct atlas7_pad_mux pw_backlight_grp0_pad_mux[] = { - MUX(1, 122, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_backlight_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(pw_backlight_grp0_pad_mux), - .pad_mux_list = pw_backlight_grp0_pad_mux, -}; - -static struct atlas7_pad_mux pw_backlight_grp1_pad_mux[] = { - MUX(1, 73, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux pw_backlight_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(pw_backlight_grp1_pad_mux), - .pad_mux_list = pw_backlight_grp1_pad_mux, -}; - -static struct atlas7_pad_mux rg_eth_mac_grp_pad_mux[] = { - MUX(1, 108, 1, N, N, N, N), - MUX(1, 103, 1, N, N, N, N), - MUX(1, 104, 1, N, N, N, N), - MUX(1, 105, 1, N, N, N, N), - MUX(1, 106, 1, N, N, N, N), - MUX(1, 107, 1, N, N, N, N), - MUX(1, 102, 1, N, N, N, N), - MUX(1, 97, 1, N, N, N, N), - MUX(1, 98, 1, N, N, N, N), - MUX(1, 99, 1, N, N, N, N), - MUX(1, 100, 1, N, N, N, N), - MUX(1, 101, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux rg_eth_mac_grp_mux = { - .pad_mux_count = ARRAY_SIZE(rg_eth_mac_grp_pad_mux), - .pad_mux_list = rg_eth_mac_grp_pad_mux, -}; - -static struct atlas7_pad_mux rg_gmac_phy_intr_n_grp_pad_mux[] = { - MUX(1, 111, 1, 0xa08, 13, 0xa88, 13), -}; - -static struct atlas7_grp_mux rg_gmac_phy_intr_n_grp_mux = { - .pad_mux_count = ARRAY_SIZE(rg_gmac_phy_intr_n_grp_pad_mux), - .pad_mux_list = rg_gmac_phy_intr_n_grp_pad_mux, -}; - -static struct atlas7_pad_mux rg_rgmii_mac_grp_pad_mux[] = { - MUX(1, 109, 1, N, N, N, N), - MUX(1, 110, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux rg_rgmii_mac_grp_mux = { - .pad_mux_count = ARRAY_SIZE(rg_rgmii_mac_grp_pad_mux), - .pad_mux_list = rg_rgmii_mac_grp_pad_mux, -}; - -static struct atlas7_pad_mux rg_rgmii_phy_ref_clk_grp0_pad_mux[] = { - MUX(1, 111, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux rg_rgmii_phy_ref_clk_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(rg_rgmii_phy_ref_clk_grp0_pad_mux), - .pad_mux_list = rg_rgmii_phy_ref_clk_grp0_pad_mux, -}; - -static struct atlas7_pad_mux rg_rgmii_phy_ref_clk_grp1_pad_mux[] = { - MUX(1, 53, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux rg_rgmii_phy_ref_clk_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(rg_rgmii_phy_ref_clk_grp1_pad_mux), - .pad_mux_list = rg_rgmii_phy_ref_clk_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sd0_grp_pad_mux[] = { - MUX(1, 46, 2, N, N, N, N), - MUX(1, 47, 2, N, N, N, N), - MUX(1, 44, 2, N, N, N, N), - MUX(1, 43, 2, N, N, N, N), - MUX(1, 42, 2, N, N, N, N), - MUX(1, 41, 2, N, N, N, N), - MUX(1, 40, 2, N, N, N, N), - MUX(1, 39, 2, N, N, N, N), - MUX(1, 38, 2, N, N, N, N), - MUX(1, 37, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux sd0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd0_grp_pad_mux), - .pad_mux_list = sd0_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd0_4bit_grp_pad_mux[] = { - MUX(1, 46, 2, N, N, N, N), - MUX(1, 47, 2, N, N, N, N), - MUX(1, 44, 2, N, N, N, N), - MUX(1, 43, 2, N, N, N, N), - MUX(1, 42, 2, N, N, N, N), - MUX(1, 41, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux sd0_4bit_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd0_4bit_grp_pad_mux), - .pad_mux_list = sd0_4bit_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd1_grp_pad_mux[] = { - MUX(1, 48, 3, N, N, N, N), - MUX(1, 49, 3, N, N, N, N), - MUX(1, 44, 3, 0xa00, 0, 0xa80, 0), - MUX(1, 43, 3, 0xa00, 1, 0xa80, 1), - MUX(1, 42, 3, 0xa00, 2, 0xa80, 2), - MUX(1, 41, 3, 0xa00, 3, 0xa80, 3), - MUX(1, 40, 3, N, N, N, N), - MUX(1, 39, 3, N, N, N, N), - MUX(1, 38, 3, N, N, N, N), - MUX(1, 37, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux sd1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd1_grp_pad_mux), - .pad_mux_list = sd1_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd1_4bit_grp0_pad_mux[] = { - MUX(1, 48, 3, N, N, N, N), - MUX(1, 49, 3, N, N, N, N), - MUX(1, 44, 3, 0xa00, 0, 0xa80, 0), - MUX(1, 43, 3, 0xa00, 1, 0xa80, 1), - MUX(1, 42, 3, 0xa00, 2, 0xa80, 2), - MUX(1, 41, 3, 0xa00, 3, 0xa80, 3), -}; - -static struct atlas7_grp_mux sd1_4bit_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(sd1_4bit_grp0_pad_mux), - .pad_mux_list = sd1_4bit_grp0_pad_mux, -}; - -static struct atlas7_pad_mux sd1_4bit_grp1_pad_mux[] = { - MUX(1, 48, 3, N, N, N, N), - MUX(1, 49, 3, N, N, N, N), - MUX(1, 40, 4, 0xa00, 0, 0xa80, 0), - MUX(1, 39, 4, 0xa00, 1, 0xa80, 1), - MUX(1, 38, 4, 0xa00, 2, 0xa80, 2), - MUX(1, 37, 4, 0xa00, 3, 0xa80, 3), -}; - -static struct atlas7_grp_mux sd1_4bit_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(sd1_4bit_grp1_pad_mux), - .pad_mux_list = sd1_4bit_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sd2_basic_grp_pad_mux[] = { - MUX(1, 31, 1, N, N, N, N), - MUX(1, 32, 1, N, N, N, N), - MUX(1, 33, 1, N, N, N, N), - MUX(1, 34, 1, N, N, N, N), - MUX(1, 35, 1, N, N, N, N), - MUX(1, 36, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sd2_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_basic_grp_pad_mux), - .pad_mux_list = sd2_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd2_cdb_grp0_pad_mux[] = { - MUX(1, 124, 2, 0xa08, 7, 0xa88, 7), -}; - -static struct atlas7_grp_mux sd2_cdb_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_cdb_grp0_pad_mux), - .pad_mux_list = sd2_cdb_grp0_pad_mux, -}; - -static struct atlas7_pad_mux sd2_cdb_grp1_pad_mux[] = { - MUX(1, 161, 6, 0xa08, 7, 0xa88, 7), -}; - -static struct atlas7_grp_mux sd2_cdb_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_cdb_grp1_pad_mux), - .pad_mux_list = sd2_cdb_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sd2_wpb_grp0_pad_mux[] = { - MUX(1, 123, 2, 0xa10, 6, 0xa90, 6), -}; - -static struct atlas7_grp_mux sd2_wpb_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_wpb_grp0_pad_mux), - .pad_mux_list = sd2_wpb_grp0_pad_mux, -}; - -static struct atlas7_pad_mux sd2_wpb_grp1_pad_mux[] = { - MUX(1, 163, 7, 0xa10, 6, 0xa90, 6), -}; - -static struct atlas7_grp_mux sd2_wpb_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(sd2_wpb_grp1_pad_mux), - .pad_mux_list = sd2_wpb_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sd3_9_grp_pad_mux[] = { - MUX(1, 85, 1, N, N, N, N), - MUX(1, 86, 1, N, N, N, N), - MUX(1, 87, 1, N, N, N, N), - MUX(1, 88, 1, N, N, N, N), - MUX(1, 89, 1, N, N, N, N), - MUX(1, 90, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sd3_9_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd3_9_grp_pad_mux), - .pad_mux_list = sd3_9_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd5_grp_pad_mux[] = { - MUX(1, 91, 1, N, N, N, N), - MUX(1, 92, 1, N, N, N, N), - MUX(1, 93, 1, N, N, N, N), - MUX(1, 94, 1, N, N, N, N), - MUX(1, 95, 1, N, N, N, N), - MUX(1, 96, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sd5_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sd5_grp_pad_mux), - .pad_mux_list = sd5_grp_pad_mux, -}; - -static struct atlas7_pad_mux sd6_grp0_pad_mux[] = { - MUX(1, 79, 4, 0xa00, 27, 0xa80, 27), - MUX(1, 78, 4, 0xa00, 26, 0xa80, 26), - MUX(1, 74, 4, 0xa00, 28, 0xa80, 28), - MUX(1, 75, 4, 0xa00, 29, 0xa80, 29), - MUX(1, 76, 4, 0xa00, 30, 0xa80, 30), - MUX(1, 77, 4, 0xa00, 31, 0xa80, 31), -}; - -static struct atlas7_grp_mux sd6_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(sd6_grp0_pad_mux), - .pad_mux_list = sd6_grp0_pad_mux, -}; - -static struct atlas7_pad_mux sd6_grp1_pad_mux[] = { - MUX(1, 101, 3, 0xa00, 27, 0xa80, 27), - MUX(1, 99, 3, 0xa00, 26, 0xa80, 26), - MUX(1, 100, 3, 0xa00, 28, 0xa80, 28), - MUX(1, 110, 3, 0xa00, 29, 0xa80, 29), - MUX(1, 109, 3, 0xa00, 30, 0xa80, 30), - MUX(1, 111, 3, 0xa00, 31, 0xa80, 31), -}; - -static struct atlas7_grp_mux sd6_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(sd6_grp1_pad_mux), - .pad_mux_list = sd6_grp1_pad_mux, -}; - -static struct atlas7_pad_mux sp0_ext_ldo_on_grp_pad_mux[] = { - MUX(0, 4, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux sp0_ext_ldo_on_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sp0_ext_ldo_on_grp_pad_mux), - .pad_mux_list = sp0_ext_ldo_on_grp_pad_mux, -}; - -static struct atlas7_pad_mux sp0_qspi_grp_pad_mux[] = { - MUX(0, 12, 1, N, N, N, N), - MUX(0, 13, 1, N, N, N, N), - MUX(0, 14, 1, N, N, N, N), - MUX(0, 15, 1, N, N, N, N), - MUX(0, 16, 1, N, N, N, N), - MUX(0, 17, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sp0_qspi_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sp0_qspi_grp_pad_mux), - .pad_mux_list = sp0_qspi_grp_pad_mux, -}; - -static struct atlas7_pad_mux sp1_spi_grp_pad_mux[] = { - MUX(1, 19, 1, N, N, N, N), - MUX(1, 20, 1, N, N, N, N), - MUX(1, 21, 1, N, N, N, N), - MUX(1, 18, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux sp1_spi_grp_mux = { - .pad_mux_count = ARRAY_SIZE(sp1_spi_grp_pad_mux), - .pad_mux_list = sp1_spi_grp_pad_mux, -}; - -static struct atlas7_pad_mux tpiu_trace_grp_pad_mux[] = { - MUX(1, 53, 5, N, N, N, N), - MUX(1, 56, 5, N, N, N, N), - MUX(1, 57, 5, N, N, N, N), - MUX(1, 58, 5, N, N, N, N), - MUX(1, 59, 5, N, N, N, N), - MUX(1, 60, 5, N, N, N, N), - MUX(1, 61, 5, N, N, N, N), - MUX(1, 62, 5, N, N, N, N), - MUX(1, 63, 5, N, N, N, N), - MUX(1, 64, 5, N, N, N, N), - MUX(1, 65, 5, N, N, N, N), - MUX(1, 66, 5, N, N, N, N), - MUX(1, 67, 5, N, N, N, N), - MUX(1, 68, 5, N, N, N, N), - MUX(1, 69, 5, N, N, N, N), - MUX(1, 70, 5, N, N, N, N), - MUX(1, 71, 5, N, N, N, N), - MUX(1, 72, 5, N, N, N, N), -}; - -static struct atlas7_grp_mux tpiu_trace_grp_mux = { - .pad_mux_count = ARRAY_SIZE(tpiu_trace_grp_pad_mux), - .pad_mux_list = tpiu_trace_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart0_grp_pad_mux[] = { - MUX(1, 121, 4, N, N, N, N), - MUX(1, 120, 4, N, N, N, N), - MUX(1, 134, 1, N, N, N, N), - MUX(1, 133, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart0_grp_mux = { - .pad_mux_count = ARRAY_SIZE(uart0_grp_pad_mux), - .pad_mux_list = uart0_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart0_nopause_grp_pad_mux[] = { - MUX(1, 134, 1, N, N, N, N), - MUX(1, 133, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart0_nopause_grp_mux = { - .pad_mux_count = ARRAY_SIZE(uart0_nopause_grp_pad_mux), - .pad_mux_list = uart0_nopause_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart1_grp_pad_mux[] = { - MUX(1, 136, 1, N, N, N, N), - MUX(1, 135, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(uart1_grp_pad_mux), - .pad_mux_list = uart1_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart2_cts_grp0_pad_mux[] = { - MUX(1, 132, 3, 0xa10, 2, 0xa90, 2), -}; - -static struct atlas7_grp_mux uart2_cts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_cts_grp0_pad_mux), - .pad_mux_list = uart2_cts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart2_cts_grp1_pad_mux[] = { - MUX(1, 162, 2, 0xa10, 2, 0xa90, 2), -}; - -static struct atlas7_grp_mux uart2_cts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_cts_grp1_pad_mux), - .pad_mux_list = uart2_cts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rts_grp0_pad_mux[] = { - MUX(1, 131, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_rts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rts_grp0_pad_mux), - .pad_mux_list = uart2_rts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rts_grp1_pad_mux[] = { - MUX(1, 161, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_rts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rts_grp1_pad_mux), - .pad_mux_list = uart2_rts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rxd_grp0_pad_mux[] = { - MUX(0, 11, 2, 0xa10, 5, 0xa90, 5), -}; - -static struct atlas7_grp_mux uart2_rxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rxd_grp0_pad_mux), - .pad_mux_list = uart2_rxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rxd_grp1_pad_mux[] = { - MUX(1, 160, 2, 0xa10, 5, 0xa90, 5), -}; - -static struct atlas7_grp_mux uart2_rxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rxd_grp1_pad_mux), - .pad_mux_list = uart2_rxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart2_rxd_grp2_pad_mux[] = { - MUX(1, 130, 3, 0xa10, 5, 0xa90, 5), -}; - -static struct atlas7_grp_mux uart2_rxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_rxd_grp2_pad_mux), - .pad_mux_list = uart2_rxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart2_txd_grp0_pad_mux[] = { - MUX(0, 10, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_txd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_txd_grp0_pad_mux), - .pad_mux_list = uart2_txd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart2_txd_grp1_pad_mux[] = { - MUX(1, 159, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_txd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_txd_grp1_pad_mux), - .pad_mux_list = uart2_txd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart2_txd_grp2_pad_mux[] = { - MUX(1, 129, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux uart2_txd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart2_txd_grp2_pad_mux), - .pad_mux_list = uart2_txd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart3_cts_grp0_pad_mux[] = { - MUX(1, 125, 2, 0xa08, 0, 0xa88, 0), -}; - -static struct atlas7_grp_mux uart3_cts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_cts_grp0_pad_mux), - .pad_mux_list = uart3_cts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart3_cts_grp1_pad_mux[] = { - MUX(1, 111, 4, 0xa08, 0, 0xa88, 0), -}; - -static struct atlas7_grp_mux uart3_cts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_cts_grp1_pad_mux), - .pad_mux_list = uart3_cts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart3_cts_grp2_pad_mux[] = { - MUX(1, 140, 2, 0xa08, 0, 0xa88, 0), -}; - -static struct atlas7_grp_mux uart3_cts_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_cts_grp2_pad_mux), - .pad_mux_list = uart3_cts_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rts_grp0_pad_mux[] = { - MUX(1, 126, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_rts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rts_grp0_pad_mux), - .pad_mux_list = uart3_rts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rts_grp1_pad_mux[] = { - MUX(1, 109, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_rts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rts_grp1_pad_mux), - .pad_mux_list = uart3_rts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rts_grp2_pad_mux[] = { - MUX(1, 139, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_rts_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rts_grp2_pad_mux), - .pad_mux_list = uart3_rts_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rxd_grp0_pad_mux[] = { - MUX(1, 138, 1, 0xa00, 5, 0xa80, 5), -}; - -static struct atlas7_grp_mux uart3_rxd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rxd_grp0_pad_mux), - .pad_mux_list = uart3_rxd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rxd_grp1_pad_mux[] = { - MUX(1, 84, 2, 0xa00, 5, 0xa80, 5), -}; - -static struct atlas7_grp_mux uart3_rxd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rxd_grp1_pad_mux), - .pad_mux_list = uart3_rxd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart3_rxd_grp2_pad_mux[] = { - MUX(1, 162, 3, 0xa00, 5, 0xa80, 5), -}; - -static struct atlas7_grp_mux uart3_rxd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_rxd_grp2_pad_mux), - .pad_mux_list = uart3_rxd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart3_txd_grp0_pad_mux[] = { - MUX(1, 137, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_txd_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_txd_grp0_pad_mux), - .pad_mux_list = uart3_txd_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart3_txd_grp1_pad_mux[] = { - MUX(1, 83, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_txd_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_txd_grp1_pad_mux), - .pad_mux_list = uart3_txd_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart3_txd_grp2_pad_mux[] = { - MUX(1, 161, 3, N, N, N, N), -}; - -static struct atlas7_grp_mux uart3_txd_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart3_txd_grp2_pad_mux), - .pad_mux_list = uart3_txd_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart4_basic_grp_pad_mux[] = { - MUX(1, 140, 1, N, N, N, N), - MUX(1, 139, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux uart4_basic_grp_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_basic_grp_pad_mux), - .pad_mux_list = uart4_basic_grp_pad_mux, -}; - -static struct atlas7_pad_mux uart4_cts_grp0_pad_mux[] = { - MUX(1, 122, 4, 0xa08, 1, 0xa88, 1), -}; - -static struct atlas7_grp_mux uart4_cts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_cts_grp0_pad_mux), - .pad_mux_list = uart4_cts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart4_cts_grp1_pad_mux[] = { - MUX(1, 100, 4, 0xa08, 1, 0xa88, 1), -}; - -static struct atlas7_grp_mux uart4_cts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_cts_grp1_pad_mux), - .pad_mux_list = uart4_cts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart4_cts_grp2_pad_mux[] = { - MUX(1, 117, 2, 0xa08, 1, 0xa88, 1), -}; - -static struct atlas7_grp_mux uart4_cts_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_cts_grp2_pad_mux), - .pad_mux_list = uart4_cts_grp2_pad_mux, -}; - -static struct atlas7_pad_mux uart4_rts_grp0_pad_mux[] = { - MUX(1, 123, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux uart4_rts_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_rts_grp0_pad_mux), - .pad_mux_list = uart4_rts_grp0_pad_mux, -}; - -static struct atlas7_pad_mux uart4_rts_grp1_pad_mux[] = { - MUX(1, 99, 4, N, N, N, N), -}; - -static struct atlas7_grp_mux uart4_rts_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_rts_grp1_pad_mux), - .pad_mux_list = uart4_rts_grp1_pad_mux, -}; - -static struct atlas7_pad_mux uart4_rts_grp2_pad_mux[] = { - MUX(1, 116, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux uart4_rts_grp2_mux = { - .pad_mux_count = ARRAY_SIZE(uart4_rts_grp2_pad_mux), - .pad_mux_list = uart4_rts_grp2_pad_mux, -}; - -static struct atlas7_pad_mux usb0_drvvbus_grp0_pad_mux[] = { - MUX(1, 51, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux usb0_drvvbus_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(usb0_drvvbus_grp0_pad_mux), - .pad_mux_list = usb0_drvvbus_grp0_pad_mux, -}; - -static struct atlas7_pad_mux usb0_drvvbus_grp1_pad_mux[] = { - MUX(1, 162, 7, N, N, N, N), -}; - -static struct atlas7_grp_mux usb0_drvvbus_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(usb0_drvvbus_grp1_pad_mux), - .pad_mux_list = usb0_drvvbus_grp1_pad_mux, -}; - -static struct atlas7_pad_mux usb1_drvvbus_grp0_pad_mux[] = { - MUX(1, 134, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux usb1_drvvbus_grp0_mux = { - .pad_mux_count = ARRAY_SIZE(usb1_drvvbus_grp0_pad_mux), - .pad_mux_list = usb1_drvvbus_grp0_pad_mux, -}; - -static struct atlas7_pad_mux usb1_drvvbus_grp1_pad_mux[] = { - MUX(1, 163, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux usb1_drvvbus_grp1_mux = { - .pad_mux_count = ARRAY_SIZE(usb1_drvvbus_grp1_pad_mux), - .pad_mux_list = usb1_drvvbus_grp1_pad_mux, -}; - -static struct atlas7_pad_mux visbus_dout_grp_pad_mux[] = { - MUX(1, 57, 6, N, N, N, N), - MUX(1, 58, 6, N, N, N, N), - MUX(1, 59, 6, N, N, N, N), - MUX(1, 60, 6, N, N, N, N), - MUX(1, 61, 6, N, N, N, N), - MUX(1, 62, 6, N, N, N, N), - MUX(1, 63, 6, N, N, N, N), - MUX(1, 64, 6, N, N, N, N), - MUX(1, 65, 6, N, N, N, N), - MUX(1, 66, 6, N, N, N, N), - MUX(1, 67, 6, N, N, N, N), - MUX(1, 68, 6, N, N, N, N), - MUX(1, 69, 6, N, N, N, N), - MUX(1, 70, 6, N, N, N, N), - MUX(1, 71, 6, N, N, N, N), - MUX(1, 72, 6, N, N, N, N), - MUX(1, 53, 6, N, N, N, N), - MUX(1, 54, 6, N, N, N, N), - MUX(1, 55, 6, N, N, N, N), - MUX(1, 56, 6, N, N, N, N), - MUX(1, 85, 6, N, N, N, N), - MUX(1, 86, 6, N, N, N, N), - MUX(1, 87, 6, N, N, N, N), - MUX(1, 88, 6, N, N, N, N), - MUX(1, 89, 6, N, N, N, N), - MUX(1, 90, 6, N, N, N, N), - MUX(1, 91, 6, N, N, N, N), - MUX(1, 92, 6, N, N, N, N), - MUX(1, 93, 6, N, N, N, N), - MUX(1, 94, 6, N, N, N, N), - MUX(1, 95, 6, N, N, N, N), - MUX(1, 96, 6, N, N, N, N), -}; - -static struct atlas7_grp_mux visbus_dout_grp_mux = { - .pad_mux_count = ARRAY_SIZE(visbus_dout_grp_pad_mux), - .pad_mux_list = visbus_dout_grp_pad_mux, -}; - -static struct atlas7_pad_mux vi_vip1_grp_pad_mux[] = { - MUX(1, 74, 1, N, N, N, N), - MUX(1, 75, 1, N, N, N, N), - MUX(1, 76, 1, N, N, N, N), - MUX(1, 77, 1, N, N, N, N), - MUX(1, 78, 1, N, N, N, N), - MUX(1, 79, 1, N, N, N, N), - MUX(1, 80, 1, N, N, N, N), - MUX(1, 81, 1, N, N, N, N), - MUX(1, 82, 1, N, N, N, N), - MUX(1, 83, 1, N, N, N, N), - MUX(1, 84, 1, N, N, N, N), - MUX(1, 103, 2, N, N, N, N), - MUX(1, 104, 2, N, N, N, N), - MUX(1, 105, 2, N, N, N, N), - MUX(1, 106, 2, N, N, N, N), - MUX(1, 107, 2, N, N, N, N), - MUX(1, 102, 2, N, N, N, N), - MUX(1, 97, 2, N, N, N, N), - MUX(1, 98, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux vi_vip1_grp_mux = { - .pad_mux_count = ARRAY_SIZE(vi_vip1_grp_pad_mux), - .pad_mux_list = vi_vip1_grp_pad_mux, -}; - -static struct atlas7_pad_mux vi_vip1_ext_grp_pad_mux[] = { - MUX(1, 74, 1, N, N, N, N), - MUX(1, 75, 1, N, N, N, N), - MUX(1, 76, 1, N, N, N, N), - MUX(1, 77, 1, N, N, N, N), - MUX(1, 78, 1, N, N, N, N), - MUX(1, 79, 1, N, N, N, N), - MUX(1, 80, 1, N, N, N, N), - MUX(1, 81, 1, N, N, N, N), - MUX(1, 82, 1, N, N, N, N), - MUX(1, 83, 1, N, N, N, N), - MUX(1, 84, 1, N, N, N, N), - MUX(1, 108, 2, N, N, N, N), - MUX(1, 103, 2, N, N, N, N), - MUX(1, 104, 2, N, N, N, N), - MUX(1, 105, 2, N, N, N, N), - MUX(1, 106, 2, N, N, N, N), - MUX(1, 107, 2, N, N, N, N), - MUX(1, 102, 2, N, N, N, N), - MUX(1, 97, 2, N, N, N, N), - MUX(1, 98, 2, N, N, N, N), - MUX(1, 99, 2, N, N, N, N), - MUX(1, 100, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux vi_vip1_ext_grp_mux = { - .pad_mux_count = ARRAY_SIZE(vi_vip1_ext_grp_pad_mux), - .pad_mux_list = vi_vip1_ext_grp_pad_mux, -}; - -static struct atlas7_pad_mux vi_vip1_low8bit_grp_pad_mux[] = { - MUX(1, 74, 1, N, N, N, N), - MUX(1, 75, 1, N, N, N, N), - MUX(1, 76, 1, N, N, N, N), - MUX(1, 77, 1, N, N, N, N), - MUX(1, 78, 1, N, N, N, N), - MUX(1, 79, 1, N, N, N, N), - MUX(1, 80, 1, N, N, N, N), - MUX(1, 81, 1, N, N, N, N), - MUX(1, 82, 1, N, N, N, N), - MUX(1, 83, 1, N, N, N, N), - MUX(1, 84, 1, N, N, N, N), -}; - -static struct atlas7_grp_mux vi_vip1_low8bit_grp_mux = { - .pad_mux_count = ARRAY_SIZE(vi_vip1_low8bit_grp_pad_mux), - .pad_mux_list = vi_vip1_low8bit_grp_pad_mux, -}; - -static struct atlas7_pad_mux vi_vip1_high8bit_grp_pad_mux[] = { - MUX(1, 82, 1, N, N, N, N), - MUX(1, 83, 1, N, N, N, N), - MUX(1, 84, 1, N, N, N, N), - MUX(1, 103, 2, N, N, N, N), - MUX(1, 104, 2, N, N, N, N), - MUX(1, 105, 2, N, N, N, N), - MUX(1, 106, 2, N, N, N, N), - MUX(1, 107, 2, N, N, N, N), - MUX(1, 102, 2, N, N, N, N), - MUX(1, 97, 2, N, N, N, N), - MUX(1, 98, 2, N, N, N, N), -}; - -static struct atlas7_grp_mux vi_vip1_high8bit_grp_mux = { - .pad_mux_count = ARRAY_SIZE(vi_vip1_high8bit_grp_pad_mux), - .pad_mux_list = vi_vip1_high8bit_grp_pad_mux, -}; - -static struct atlas7_pmx_func atlas7_pmx_functions[] = { - FUNCTION("gnss_gpio", gnss_gpio_grp, &gnss_gpio_grp_mux), - FUNCTION("lcd_vip_gpio", lcd_vip_gpio_grp, &lcd_vip_gpio_grp_mux), - FUNCTION("sdio_i2s_gpio", sdio_i2s_gpio_grp, &sdio_i2s_gpio_grp_mux), - FUNCTION("sp_rgmii_gpio", sp_rgmii_gpio_grp, &sp_rgmii_gpio_grp_mux), - FUNCTION("lvds_gpio", lvds_gpio_grp, &lvds_gpio_grp_mux), - FUNCTION("jtag_uart_nand_gpio", - jtag_uart_nand_gpio_grp, - &jtag_uart_nand_gpio_grp_mux), - FUNCTION("rtc_gpio", rtc_gpio_grp, &rtc_gpio_grp_mux), - FUNCTION("audio_ac97", audio_ac97_grp, &audio_ac97_grp_mux), - FUNCTION("audio_digmic_m0", - audio_digmic_grp0, - &audio_digmic_grp0_mux), - FUNCTION("audio_digmic_m1", - audio_digmic_grp1, - &audio_digmic_grp1_mux), - FUNCTION("audio_digmic_m2", - audio_digmic_grp2, - &audio_digmic_grp2_mux), - FUNCTION("audio_func_dbg", - audio_func_dbg_grp, - &audio_func_dbg_grp_mux), - FUNCTION("audio_i2s", audio_i2s_grp, &audio_i2s_grp_mux), - FUNCTION("audio_i2s_2ch", audio_i2s_2ch_grp, &audio_i2s_2ch_grp_mux), - FUNCTION("audio_i2s_extclk", - audio_i2s_extclk_grp, - &audio_i2s_extclk_grp_mux), - FUNCTION("audio_spdif_out_m0", - audio_spdif_out_grp0, - &audio_spdif_out_grp0_mux), - FUNCTION("audio_spdif_out_m1", - audio_spdif_out_grp1, - &audio_spdif_out_grp1_mux), - FUNCTION("audio_spdif_out_m2", - audio_spdif_out_grp2, - &audio_spdif_out_grp2_mux), - FUNCTION("audio_uart0_basic", - audio_uart0_basic_grp, - &audio_uart0_basic_grp_mux), - FUNCTION("audio_uart0_urfs_m0", - audio_uart0_urfs_grp0, - &audio_uart0_urfs_grp0_mux), - FUNCTION("audio_uart0_urfs_m1", - audio_uart0_urfs_grp1, - &audio_uart0_urfs_grp1_mux), - FUNCTION("audio_uart0_urfs_m2", - audio_uart0_urfs_grp2, - &audio_uart0_urfs_grp2_mux), - FUNCTION("audio_uart0_urfs_m3", - audio_uart0_urfs_grp3, - &audio_uart0_urfs_grp3_mux), - FUNCTION("audio_uart1_basic", - audio_uart1_basic_grp, - &audio_uart1_basic_grp_mux), - FUNCTION("audio_uart1_urfs_m0", - audio_uart1_urfs_grp0, - &audio_uart1_urfs_grp0_mux), - FUNCTION("audio_uart1_urfs_m1", - audio_uart1_urfs_grp1, - &audio_uart1_urfs_grp1_mux), - FUNCTION("audio_uart1_urfs_m2", - audio_uart1_urfs_grp2, - &audio_uart1_urfs_grp2_mux), - FUNCTION("audio_uart2_urfs_m0", - audio_uart2_urfs_grp0, - &audio_uart2_urfs_grp0_mux), - FUNCTION("audio_uart2_urfs_m1", - audio_uart2_urfs_grp1, - &audio_uart2_urfs_grp1_mux), - FUNCTION("audio_uart2_urfs_m2", - audio_uart2_urfs_grp2, - &audio_uart2_urfs_grp2_mux), - FUNCTION("audio_uart2_urxd_m0", - audio_uart2_urxd_grp0, - &audio_uart2_urxd_grp0_mux), - FUNCTION("audio_uart2_urxd_m1", - audio_uart2_urxd_grp1, - &audio_uart2_urxd_grp1_mux), - FUNCTION("audio_uart2_urxd_m2", - audio_uart2_urxd_grp2, - &audio_uart2_urxd_grp2_mux), - FUNCTION("audio_uart2_usclk_m0", - audio_uart2_usclk_grp0, - &audio_uart2_usclk_grp0_mux), - FUNCTION("audio_uart2_usclk_m1", - audio_uart2_usclk_grp1, - &audio_uart2_usclk_grp1_mux), - FUNCTION("audio_uart2_usclk_m2", - audio_uart2_usclk_grp2, - &audio_uart2_usclk_grp2_mux), - FUNCTION("audio_uart2_utfs_m0", - audio_uart2_utfs_grp0, - &audio_uart2_utfs_grp0_mux), - FUNCTION("audio_uart2_utfs_m1", - audio_uart2_utfs_grp1, - &audio_uart2_utfs_grp1_mux), - FUNCTION("audio_uart2_utfs_m2", - audio_uart2_utfs_grp2, - &audio_uart2_utfs_grp2_mux), - FUNCTION("audio_uart2_utxd_m0", - audio_uart2_utxd_grp0, - &audio_uart2_utxd_grp0_mux), - FUNCTION("audio_uart2_utxd_m1", - audio_uart2_utxd_grp1, - &audio_uart2_utxd_grp1_mux), - FUNCTION("audio_uart2_utxd_m2", - audio_uart2_utxd_grp2, - &audio_uart2_utxd_grp2_mux), - FUNCTION("c_can_trnsvr_en_m0", - c_can_trnsvr_en_grp0, - &c_can_trnsvr_en_grp0_mux), - FUNCTION("c_can_trnsvr_en_m1", - c_can_trnsvr_en_grp1, - &c_can_trnsvr_en_grp1_mux), - FUNCTION("c_can_trnsvr_intr", - c_can_trnsvr_intr_grp, - &c_can_trnsvr_intr_grp_mux), - FUNCTION("c_can_trnsvr_stb_n", - c_can_trnsvr_stb_n_grp, - &c_can_trnsvr_stb_n_grp_mux), - FUNCTION("c0_can_rxd_trnsv0", - c0_can_rxd_trnsv0_grp, - &c0_can_rxd_trnsv0_grp_mux), - FUNCTION("c0_can_rxd_trnsv1", - c0_can_rxd_trnsv1_grp, - &c0_can_rxd_trnsv1_grp_mux), - FUNCTION("c0_can_txd_trnsv0", - c0_can_txd_trnsv0_grp, - &c0_can_txd_trnsv0_grp_mux), - FUNCTION("c0_can_txd_trnsv1", - c0_can_txd_trnsv1_grp, - &c0_can_txd_trnsv1_grp_mux), - FUNCTION("c1_can_rxd_m0", c1_can_rxd_grp0, &c1_can_rxd_grp0_mux), - FUNCTION("c1_can_rxd_m1", c1_can_rxd_grp1, &c1_can_rxd_grp1_mux), - FUNCTION("c1_can_rxd_m2", c1_can_rxd_grp2, &c1_can_rxd_grp2_mux), - FUNCTION("c1_can_rxd_m3", c1_can_rxd_grp3, &c1_can_rxd_grp3_mux), - FUNCTION("c1_can_txd_m0", c1_can_txd_grp0, &c1_can_txd_grp0_mux), - FUNCTION("c1_can_txd_m1", c1_can_txd_grp1, &c1_can_txd_grp1_mux), - FUNCTION("c1_can_txd_m2", c1_can_txd_grp2, &c1_can_txd_grp2_mux), - FUNCTION("c1_can_txd_m3", c1_can_txd_grp3, &c1_can_txd_grp3_mux), - FUNCTION("ca_audio_lpc", ca_audio_lpc_grp, &ca_audio_lpc_grp_mux), - FUNCTION("ca_bt_lpc", ca_bt_lpc_grp, &ca_bt_lpc_grp_mux), - FUNCTION("ca_coex", ca_coex_grp, &ca_coex_grp_mux), - FUNCTION("ca_curator_lpc", - ca_curator_lpc_grp, - &ca_curator_lpc_grp_mux), - FUNCTION("ca_pcm_debug", ca_pcm_debug_grp, &ca_pcm_debug_grp_mux), - FUNCTION("ca_pio", ca_pio_grp, &ca_pio_grp_mux), - FUNCTION("ca_sdio_debug", ca_sdio_debug_grp, &ca_sdio_debug_grp_mux), - FUNCTION("ca_spi", ca_spi_grp, &ca_spi_grp_mux), - FUNCTION("ca_trb", ca_trb_grp, &ca_trb_grp_mux), - FUNCTION("ca_uart_debug", ca_uart_debug_grp, &ca_uart_debug_grp_mux), - FUNCTION("clkc_m0", clkc_grp0, &clkc_grp0_mux), - FUNCTION("clkc_m1", clkc_grp1, &clkc_grp1_mux), - FUNCTION("gn_gnss_i2c", gn_gnss_i2c_grp, &gn_gnss_i2c_grp_mux), - FUNCTION("gn_gnss_uart_nopause", - gn_gnss_uart_nopause_grp, - &gn_gnss_uart_nopause_grp_mux), - FUNCTION("gn_gnss_uart", gn_gnss_uart_grp, &gn_gnss_uart_grp_mux), - FUNCTION("gn_trg_spi_m0", gn_trg_spi_grp0, &gn_trg_spi_grp0_mux), - FUNCTION("gn_trg_spi_m1", gn_trg_spi_grp1, &gn_trg_spi_grp1_mux), - FUNCTION("cvbs_dbg", cvbs_dbg_grp, &cvbs_dbg_grp_mux), - FUNCTION("cvbs_dbg_test_m0", - cvbs_dbg_test_grp0, - &cvbs_dbg_test_grp0_mux), - FUNCTION("cvbs_dbg_test_m1", - cvbs_dbg_test_grp1, - &cvbs_dbg_test_grp1_mux), - FUNCTION("cvbs_dbg_test_m2", - cvbs_dbg_test_grp2, - &cvbs_dbg_test_grp2_mux), - FUNCTION("cvbs_dbg_test_m3", - cvbs_dbg_test_grp3, - &cvbs_dbg_test_grp3_mux), - FUNCTION("cvbs_dbg_test_m4", - cvbs_dbg_test_grp4, - &cvbs_dbg_test_grp4_mux), - FUNCTION("cvbs_dbg_test_m5", - cvbs_dbg_test_grp5, - &cvbs_dbg_test_grp5_mux), - FUNCTION("cvbs_dbg_test_m6", - cvbs_dbg_test_grp6, - &cvbs_dbg_test_grp6_mux), - FUNCTION("cvbs_dbg_test_m7", - cvbs_dbg_test_grp7, - &cvbs_dbg_test_grp7_mux), - FUNCTION("cvbs_dbg_test_m8", - cvbs_dbg_test_grp8, - &cvbs_dbg_test_grp8_mux), - FUNCTION("cvbs_dbg_test_m9", - cvbs_dbg_test_grp9, - &cvbs_dbg_test_grp9_mux), - FUNCTION("cvbs_dbg_test_m10", - cvbs_dbg_test_grp10, - &cvbs_dbg_test_grp10_mux), - FUNCTION("cvbs_dbg_test_m11", - cvbs_dbg_test_grp11, - &cvbs_dbg_test_grp11_mux), - FUNCTION("cvbs_dbg_test_m12", - cvbs_dbg_test_grp12, - &cvbs_dbg_test_grp12_mux), - FUNCTION("cvbs_dbg_test_m13", - cvbs_dbg_test_grp13, - &cvbs_dbg_test_grp13_mux), - FUNCTION("cvbs_dbg_test_m14", - cvbs_dbg_test_grp14, - &cvbs_dbg_test_grp14_mux), - FUNCTION("cvbs_dbg_test_m15", - cvbs_dbg_test_grp15, - &cvbs_dbg_test_grp15_mux), - FUNCTION("gn_gnss_power", gn_gnss_power_grp, &gn_gnss_power_grp_mux), - FUNCTION("gn_gnss_sw_status", - gn_gnss_sw_status_grp, - &gn_gnss_sw_status_grp_mux), - FUNCTION("gn_gnss_eclk", gn_gnss_eclk_grp, &gn_gnss_eclk_grp_mux), - FUNCTION("gn_gnss_irq1_m0", - gn_gnss_irq1_grp0, - &gn_gnss_irq1_grp0_mux), - FUNCTION("gn_gnss_irq2_m0", - gn_gnss_irq2_grp0, - &gn_gnss_irq2_grp0_mux), - FUNCTION("gn_gnss_tm", gn_gnss_tm_grp, &gn_gnss_tm_grp_mux), - FUNCTION("gn_gnss_tsync", gn_gnss_tsync_grp, &gn_gnss_tsync_grp_mux), - FUNCTION("gn_io_gnsssys_sw_cfg", - gn_io_gnsssys_sw_cfg_grp, - &gn_io_gnsssys_sw_cfg_grp_mux), - FUNCTION("gn_trg_m0", gn_trg_grp0, &gn_trg_grp0_mux), - FUNCTION("gn_trg_m1", gn_trg_grp1, &gn_trg_grp1_mux), - FUNCTION("gn_trg_shutdown_m0", - gn_trg_shutdown_grp0, - &gn_trg_shutdown_grp0_mux), - FUNCTION("gn_trg_shutdown_m1", - gn_trg_shutdown_grp1, - &gn_trg_shutdown_grp1_mux), - FUNCTION("gn_trg_shutdown_m2", - gn_trg_shutdown_grp2, - &gn_trg_shutdown_grp2_mux), - FUNCTION("gn_trg_shutdown_m3", - gn_trg_shutdown_grp3, - &gn_trg_shutdown_grp3_mux), - FUNCTION("i2c0", i2c0_grp, &i2c0_grp_mux), - FUNCTION("i2c1", i2c1_grp, &i2c1_grp_mux), - FUNCTION("i2s0", i2s0_grp, &i2s0_grp_mux), - FUNCTION("i2s1_basic", i2s1_basic_grp, &i2s1_basic_grp_mux), - FUNCTION("i2s1_rxd0_m0", i2s1_rxd0_grp0, &i2s1_rxd0_grp0_mux), - FUNCTION("i2s1_rxd0_m1", i2s1_rxd0_grp1, &i2s1_rxd0_grp1_mux), - FUNCTION("i2s1_rxd0_m2", i2s1_rxd0_grp2, &i2s1_rxd0_grp2_mux), - FUNCTION("i2s1_rxd0_m3", i2s1_rxd0_grp3, &i2s1_rxd0_grp3_mux), - FUNCTION("i2s1_rxd0_m4", i2s1_rxd0_grp4, &i2s1_rxd0_grp4_mux), - FUNCTION("i2s1_rxd1_m0", i2s1_rxd1_grp0, &i2s1_rxd1_grp0_mux), - FUNCTION("i2s1_rxd1_m1", i2s1_rxd1_grp1, &i2s1_rxd1_grp1_mux), - FUNCTION("i2s1_rxd1_m2", i2s1_rxd1_grp2, &i2s1_rxd1_grp2_mux), - FUNCTION("i2s1_rxd1_m3", i2s1_rxd1_grp3, &i2s1_rxd1_grp3_mux), - FUNCTION("i2s1_rxd1_m4", i2s1_rxd1_grp4, &i2s1_rxd1_grp4_mux), - FUNCTION("jtag_jt_dbg_nsrst", - jtag_jt_dbg_nsrst_grp, - &jtag_jt_dbg_nsrst_grp_mux), - FUNCTION("jtag_ntrst_m0", jtag_ntrst_grp0, &jtag_ntrst_grp0_mux), - FUNCTION("jtag_ntrst_m1", jtag_ntrst_grp1, &jtag_ntrst_grp1_mux), - FUNCTION("jtag_swdiotms_m0", - jtag_swdiotms_grp0, - &jtag_swdiotms_grp0_mux), - FUNCTION("jtag_swdiotms_m1", - jtag_swdiotms_grp1, - &jtag_swdiotms_grp1_mux), - FUNCTION("jtag_tck_m0", jtag_tck_grp0, &jtag_tck_grp0_mux), - FUNCTION("jtag_tck_m1", jtag_tck_grp1, &jtag_tck_grp1_mux), - FUNCTION("jtag_tdi_m0", jtag_tdi_grp0, &jtag_tdi_grp0_mux), - FUNCTION("jtag_tdi_m1", jtag_tdi_grp1, &jtag_tdi_grp1_mux), - FUNCTION("jtag_tdo_m0", jtag_tdo_grp0, &jtag_tdo_grp0_mux), - FUNCTION("jtag_tdo_m1", jtag_tdo_grp1, &jtag_tdo_grp1_mux), - FUNCTION("ks_kas_spi_m0", ks_kas_spi_grp0, &ks_kas_spi_grp0_mux), - FUNCTION("ld_ldd", ld_ldd_grp, &ld_ldd_grp_mux), - FUNCTION("ld_ldd_16bit", ld_ldd_16bit_grp, &ld_ldd_16bit_grp_mux), - FUNCTION("ld_ldd_fck", ld_ldd_fck_grp, &ld_ldd_fck_grp_mux), - FUNCTION("ld_ldd_lck", ld_ldd_lck_grp, &ld_ldd_lck_grp_mux), - FUNCTION("lr_lcdrom", lr_lcdrom_grp, &lr_lcdrom_grp_mux), - FUNCTION("lvds_analog", lvds_analog_grp, &lvds_analog_grp_mux), - FUNCTION("nd_df_basic", nd_df_basic_grp, &nd_df_basic_grp_mux), - FUNCTION("nd_df_wp", nd_df_wp_grp, &nd_df_wp_grp_mux), - FUNCTION("nd_df_cs", nd_df_cs_grp, &nd_df_cs_grp_mux), - FUNCTION("ps", ps_grp, &ps_grp_mux), - FUNCTION("ps_no_dir", ps_no_dir_grp, &ps_no_dir_grp_mux), - FUNCTION("pwc_core_on", pwc_core_on_grp, &pwc_core_on_grp_mux), - FUNCTION("pwc_ext_on", pwc_ext_on_grp, &pwc_ext_on_grp_mux), - FUNCTION("pwc_gpio3_clk", pwc_gpio3_clk_grp, &pwc_gpio3_clk_grp_mux), - FUNCTION("pwc_io_on", pwc_io_on_grp, &pwc_io_on_grp_mux), - FUNCTION("pwc_lowbatt_b_m0", - pwc_lowbatt_b_grp0, - &pwc_lowbatt_b_grp0_mux), - FUNCTION("pwc_mem_on", pwc_mem_on_grp, &pwc_mem_on_grp_mux), - FUNCTION("pwc_on_key_b_m0", - pwc_on_key_b_grp0, - &pwc_on_key_b_grp0_mux), - FUNCTION("pwc_wakeup_src0", - pwc_wakeup_src0_grp, - &pwc_wakeup_src0_grp_mux), - FUNCTION("pwc_wakeup_src1", - pwc_wakeup_src1_grp, - &pwc_wakeup_src1_grp_mux), - FUNCTION("pwc_wakeup_src2", - pwc_wakeup_src2_grp, - &pwc_wakeup_src2_grp_mux), - FUNCTION("pwc_wakeup_src3", - pwc_wakeup_src3_grp, - &pwc_wakeup_src3_grp_mux), - FUNCTION("pw_cko0_m0", pw_cko0_grp0, &pw_cko0_grp0_mux), - FUNCTION("pw_cko0_m1", pw_cko0_grp1, &pw_cko0_grp1_mux), - FUNCTION("pw_cko0_m2", pw_cko0_grp2, &pw_cko0_grp2_mux), - FUNCTION("pw_cko0_m3", pw_cko0_grp3, &pw_cko0_grp3_mux), - FUNCTION("pw_cko1_m0", pw_cko1_grp0, &pw_cko1_grp0_mux), - FUNCTION("pw_cko1_m1", pw_cko1_grp1, &pw_cko1_grp1_mux), - FUNCTION("pw_cko1_m2", pw_cko1_grp2, &pw_cko1_grp2_mux), - FUNCTION("pw_i2s01_clk_m0", - pw_i2s01_clk_grp0, - &pw_i2s01_clk_grp0_mux), - FUNCTION("pw_i2s01_clk_m1", - pw_i2s01_clk_grp1, - &pw_i2s01_clk_grp1_mux), - FUNCTION("pw_i2s01_clk_m2", - pw_i2s01_clk_grp2, - &pw_i2s01_clk_grp2_mux), - FUNCTION("pw_pwm0_m0", pw_pwm0_grp0, &pw_pwm0_grp0_mux), - FUNCTION("pw_pwm0_m1", pw_pwm0_grp1, &pw_pwm0_grp1_mux), - FUNCTION("pw_pwm1_m0", pw_pwm1_grp0, &pw_pwm1_grp0_mux), - FUNCTION("pw_pwm1_m1", pw_pwm1_grp1, &pw_pwm1_grp1_mux), - FUNCTION("pw_pwm1_m2", pw_pwm1_grp2, &pw_pwm1_grp2_mux), - FUNCTION("pw_pwm2_m0", pw_pwm2_grp0, &pw_pwm2_grp0_mux), - FUNCTION("pw_pwm2_m1", pw_pwm2_grp1, &pw_pwm2_grp1_mux), - FUNCTION("pw_pwm2_m2", pw_pwm2_grp2, &pw_pwm2_grp2_mux), - FUNCTION("pw_pwm3_m0", pw_pwm3_grp0, &pw_pwm3_grp0_mux), - FUNCTION("pw_pwm3_m1", pw_pwm3_grp1, &pw_pwm3_grp1_mux), - FUNCTION("pw_pwm_cpu_vol_m0", - pw_pwm_cpu_vol_grp0, - &pw_pwm_cpu_vol_grp0_mux), - FUNCTION("pw_pwm_cpu_vol_m1", - pw_pwm_cpu_vol_grp1, - &pw_pwm_cpu_vol_grp1_mux), - FUNCTION("pw_pwm_cpu_vol_m2", - pw_pwm_cpu_vol_grp2, - &pw_pwm_cpu_vol_grp2_mux), - FUNCTION("pw_backlight_m0", - pw_backlight_grp0, - &pw_backlight_grp0_mux), - FUNCTION("pw_backlight_m1", - pw_backlight_grp1, - &pw_backlight_grp1_mux), - FUNCTION("rg_eth_mac", rg_eth_mac_grp, &rg_eth_mac_grp_mux), - FUNCTION("rg_gmac_phy_intr_n", - rg_gmac_phy_intr_n_grp, - &rg_gmac_phy_intr_n_grp_mux), - FUNCTION("rg_rgmii_mac", rg_rgmii_mac_grp, &rg_rgmii_mac_grp_mux), - FUNCTION("rg_rgmii_phy_ref_clk_m0", - rg_rgmii_phy_ref_clk_grp0, - &rg_rgmii_phy_ref_clk_grp0_mux), - FUNCTION("rg_rgmii_phy_ref_clk_m1", - rg_rgmii_phy_ref_clk_grp1, - &rg_rgmii_phy_ref_clk_grp1_mux), - FUNCTION("sd0", sd0_grp, &sd0_grp_mux), - FUNCTION("sd0_4bit", sd0_4bit_grp, &sd0_4bit_grp_mux), - FUNCTION("sd1", sd1_grp, &sd1_grp_mux), - FUNCTION("sd1_4bit_m0", sd1_4bit_grp0, &sd1_4bit_grp0_mux), - FUNCTION("sd1_4bit_m1", sd1_4bit_grp1, &sd1_4bit_grp1_mux), - FUNCTION("sd2_basic", sd2_basic_grp, &sd2_basic_grp_mux), - FUNCTION("sd2_cdb_m0", sd2_cdb_grp0, &sd2_cdb_grp0_mux), - FUNCTION("sd2_cdb_m1", sd2_cdb_grp1, &sd2_cdb_grp1_mux), - FUNCTION("sd2_wpb_m0", sd2_wpb_grp0, &sd2_wpb_grp0_mux), - FUNCTION("sd2_wpb_m1", sd2_wpb_grp1, &sd2_wpb_grp1_mux), - FUNCTION("sd3", sd3_9_grp, &sd3_9_grp_mux), - FUNCTION("sd5", sd5_grp, &sd5_grp_mux), - FUNCTION("sd6_m0", sd6_grp0, &sd6_grp0_mux), - FUNCTION("sd6_m1", sd6_grp1, &sd6_grp1_mux), - FUNCTION("sd9", sd3_9_grp, &sd3_9_grp_mux), - FUNCTION("sp0_ext_ldo_on", - sp0_ext_ldo_on_grp, - &sp0_ext_ldo_on_grp_mux), - FUNCTION("sp0_qspi", sp0_qspi_grp, &sp0_qspi_grp_mux), - FUNCTION("sp1_spi", sp1_spi_grp, &sp1_spi_grp_mux), - FUNCTION("tpiu_trace", tpiu_trace_grp, &tpiu_trace_grp_mux), - FUNCTION("uart0", uart0_grp, &uart0_grp_mux), - FUNCTION("uart0_nopause", uart0_nopause_grp, &uart0_nopause_grp_mux), - FUNCTION("uart1", uart1_grp, &uart1_grp_mux), - FUNCTION("uart2_cts_m0", uart2_cts_grp0, &uart2_cts_grp0_mux), - FUNCTION("uart2_cts_m1", uart2_cts_grp1, &uart2_cts_grp1_mux), - FUNCTION("uart2_rts_m0", uart2_rts_grp0, &uart2_rts_grp0_mux), - FUNCTION("uart2_rts_m1", uart2_rts_grp1, &uart2_rts_grp1_mux), - FUNCTION("uart2_rxd_m0", uart2_rxd_grp0, &uart2_rxd_grp0_mux), - FUNCTION("uart2_rxd_m1", uart2_rxd_grp1, &uart2_rxd_grp1_mux), - FUNCTION("uart2_rxd_m2", uart2_rxd_grp2, &uart2_rxd_grp2_mux), - FUNCTION("uart2_txd_m0", uart2_txd_grp0, &uart2_txd_grp0_mux), - FUNCTION("uart2_txd_m1", uart2_txd_grp1, &uart2_txd_grp1_mux), - FUNCTION("uart2_txd_m2", uart2_txd_grp2, &uart2_txd_grp2_mux), - FUNCTION("uart3_cts_m0", uart3_cts_grp0, &uart3_cts_grp0_mux), - FUNCTION("uart3_cts_m1", uart3_cts_grp1, &uart3_cts_grp1_mux), - FUNCTION("uart3_cts_m2", uart3_cts_grp2, &uart3_cts_grp2_mux), - FUNCTION("uart3_rts_m0", uart3_rts_grp0, &uart3_rts_grp0_mux), - FUNCTION("uart3_rts_m1", uart3_rts_grp1, &uart3_rts_grp1_mux), - FUNCTION("uart3_rts_m2", uart3_rts_grp2, &uart3_rts_grp2_mux), - FUNCTION("uart3_rxd_m0", uart3_rxd_grp0, &uart3_rxd_grp0_mux), - FUNCTION("uart3_rxd_m1", uart3_rxd_grp1, &uart3_rxd_grp1_mux), - FUNCTION("uart3_rxd_m2", uart3_rxd_grp2, &uart3_rxd_grp2_mux), - FUNCTION("uart3_txd_m0", uart3_txd_grp0, &uart3_txd_grp0_mux), - FUNCTION("uart3_txd_m1", uart3_txd_grp1, &uart3_txd_grp1_mux), - FUNCTION("uart3_txd_m2", uart3_txd_grp2, &uart3_txd_grp2_mux), - FUNCTION("uart4_basic", uart4_basic_grp, &uart4_basic_grp_mux), - FUNCTION("uart4_cts_m0", uart4_cts_grp0, &uart4_cts_grp0_mux), - FUNCTION("uart4_cts_m1", uart4_cts_grp1, &uart4_cts_grp1_mux), - FUNCTION("uart4_cts_m2", uart4_cts_grp2, &uart4_cts_grp2_mux), - FUNCTION("uart4_rts_m0", uart4_rts_grp0, &uart4_rts_grp0_mux), - FUNCTION("uart4_rts_m1", uart4_rts_grp1, &uart4_rts_grp1_mux), - FUNCTION("uart4_rts_m2", uart4_rts_grp2, &uart4_rts_grp2_mux), - FUNCTION("usb0_drvvbus_m0", - usb0_drvvbus_grp0, - &usb0_drvvbus_grp0_mux), - FUNCTION("usb0_drvvbus_m1", - usb0_drvvbus_grp1, - &usb0_drvvbus_grp1_mux), - FUNCTION("usb1_drvvbus_m0", - usb1_drvvbus_grp0, - &usb1_drvvbus_grp0_mux), - FUNCTION("usb1_drvvbus_m1", - usb1_drvvbus_grp1, - &usb1_drvvbus_grp1_mux), - FUNCTION("visbus_dout", visbus_dout_grp, &visbus_dout_grp_mux), - FUNCTION("vi_vip1", vi_vip1_grp, &vi_vip1_grp_mux), - FUNCTION("vi_vip1_ext", vi_vip1_ext_grp, &vi_vip1_ext_grp_mux), - FUNCTION("vi_vip1_low8bit", - vi_vip1_low8bit_grp, - &vi_vip1_low8bit_grp_mux), - FUNCTION("vi_vip1_high8bit", - vi_vip1_high8bit_grp, - &vi_vip1_high8bit_grp_mux), -}; - -static struct atlas7_pinctrl_data atlas7_ioc_data = { - .pads = (struct pinctrl_pin_desc *)atlas7_ioc_pads, - .pads_cnt = ARRAY_SIZE(atlas7_ioc_pads), - .grps = (struct atlas7_pin_group *)altas7_pin_groups, - .grps_cnt = ARRAY_SIZE(altas7_pin_groups), - .funcs = (struct atlas7_pmx_func *)atlas7_pmx_functions, - .funcs_cnt = ARRAY_SIZE(atlas7_pmx_functions), - .confs = (struct atlas7_pad_config *)atlas7_ioc_pad_confs, - .confs_cnt = ARRAY_SIZE(atlas7_ioc_pad_confs), -}; - -/* Simple map data structure */ -struct map_data { - u8 idx; - u8 data; -}; - -/** - * struct atlas7_pull_info - Atlas7 Pad pull info - * @pad_type: The type of this Pad. - * @mask: The mas value of this pin's pull bits. - * @v2s: The map of pull register value to pull status. - * @s2v: The map of pull status to pull register value. - */ -struct atlas7_pull_info { - u8 pad_type; - u8 mask; - const struct map_data *v2s; - const struct map_data *s2v; -}; - -/* Pull Register value map to status */ -static const struct map_data p4we_pull_v2s[] = { - { P4WE_PULL_UP, PULL_UP }, - { P4WE_HIGH_HYSTERESIS, HIGH_HYSTERESIS }, - { P4WE_HIGH_Z, HIGH_Z }, - { P4WE_PULL_DOWN, PULL_DOWN }, -}; - -static const struct map_data p16st_pull_v2s[] = { - { P16ST_PULL_UP, PULL_UP }, - { PD, PULL_UNKNOWN }, - { P16ST_HIGH_Z, HIGH_Z }, - { P16ST_PULL_DOWN, PULL_DOWN }, -}; - -static const struct map_data pm31_pull_v2s[] = { - { PM31_PULL_DISABLED, PULL_DOWN }, - { PM31_PULL_ENABLED, PULL_UP }, -}; - -static const struct map_data pangd_pull_v2s[] = { - { PANGD_PULL_UP, PULL_UP }, - { PD, PULL_UNKNOWN }, - { PANGD_HIGH_Z, HIGH_Z }, - { PANGD_PULL_DOWN, PULL_DOWN }, -}; - -/* Pull status map to register value */ -static const struct map_data p4we_pull_s2v[] = { - { PULL_UP, P4WE_PULL_UP }, - { HIGH_HYSTERESIS, P4WE_HIGH_HYSTERESIS }, - { HIGH_Z, P4WE_HIGH_Z }, - { PULL_DOWN, P4WE_PULL_DOWN }, - { PULL_DISABLE, -1 }, - { PULL_ENABLE, -1 }, -}; - -static const struct map_data p16st_pull_s2v[] = { - { PULL_UP, P16ST_PULL_UP }, - { HIGH_HYSTERESIS, -1 }, - { HIGH_Z, P16ST_HIGH_Z }, - { PULL_DOWN, P16ST_PULL_DOWN }, - { PULL_DISABLE, -1 }, - { PULL_ENABLE, -1 }, -}; - -static const struct map_data pm31_pull_s2v[] = { - { PULL_UP, PM31_PULL_ENABLED }, - { HIGH_HYSTERESIS, -1 }, - { HIGH_Z, -1 }, - { PULL_DOWN, PM31_PULL_DISABLED }, - { PULL_DISABLE, -1 }, - { PULL_ENABLE, -1 }, -}; - -static const struct map_data pangd_pull_s2v[] = { - { PULL_UP, PANGD_PULL_UP }, - { HIGH_HYSTERESIS, -1 }, - { HIGH_Z, PANGD_HIGH_Z }, - { PULL_DOWN, PANGD_PULL_DOWN }, - { PULL_DISABLE, -1 }, - { PULL_ENABLE, -1 }, -}; - -static const struct atlas7_pull_info atlas7_pull_map[] = { - { PAD_T_4WE_PD, P4WE_PULL_MASK, p4we_pull_v2s, p4we_pull_s2v }, - { PAD_T_4WE_PU, P4WE_PULL_MASK, p4we_pull_v2s, p4we_pull_s2v }, - { PAD_T_16ST, P16ST_PULL_MASK, p16st_pull_v2s, p16st_pull_s2v }, - { PAD_T_M31_0204_PD, PM31_PULL_MASK, pm31_pull_v2s, pm31_pull_s2v }, - { PAD_T_M31_0204_PU, PM31_PULL_MASK, pm31_pull_v2s, pm31_pull_s2v }, - { PAD_T_M31_0610_PD, PM31_PULL_MASK, pm31_pull_v2s, pm31_pull_s2v }, - { PAD_T_M31_0610_PU, PM31_PULL_MASK, pm31_pull_v2s, pm31_pull_s2v }, - { PAD_T_AD, PANGD_PULL_MASK, pangd_pull_v2s, pangd_pull_s2v }, -}; - -/** - * struct atlas7_ds_ma_info - Atlas7 Pad DriveStrength & currents info - * @ma: The Drive Strength in current value . - * @ds_16st: The correspond raw value of 16st pad. - * @ds_4we: The correspond raw value of 4we pad. - * @ds_0204m31: The correspond raw value of 0204m31 pad. - * @ds_0610m31: The correspond raw value of 0610m31 pad. - */ -struct atlas7_ds_ma_info { - u32 ma; - u32 ds_16st; - u32 ds_4we; - u32 ds_0204m31; - u32 ds_0610m31; -}; - -static const struct atlas7_ds_ma_info atlas7_ma2ds_map[] = { - { 2, DS_16ST_0, DS_4WE_0, DS_M31_0, DS_NULL }, - { 4, DS_16ST_1, DS_NULL, DS_M31_1, DS_NULL }, - { 6, DS_16ST_2, DS_NULL, DS_NULL, DS_M31_0 }, - { 8, DS_16ST_3, DS_4WE_1, DS_NULL, DS_NULL }, - { 10, DS_16ST_4, DS_NULL, DS_NULL, DS_M31_1 }, - { 12, DS_16ST_5, DS_NULL, DS_NULL, DS_NULL }, - { 14, DS_16ST_6, DS_NULL, DS_NULL, DS_NULL }, - { 16, DS_16ST_7, DS_4WE_2, DS_NULL, DS_NULL }, - { 18, DS_16ST_8, DS_NULL, DS_NULL, DS_NULL }, - { 20, DS_16ST_9, DS_NULL, DS_NULL, DS_NULL }, - { 22, DS_16ST_10, DS_NULL, DS_NULL, DS_NULL }, - { 24, DS_16ST_11, DS_NULL, DS_NULL, DS_NULL }, - { 26, DS_16ST_12, DS_NULL, DS_NULL, DS_NULL }, - { 28, DS_16ST_13, DS_4WE_3, DS_NULL, DS_NULL }, - { 30, DS_16ST_14, DS_NULL, DS_NULL, DS_NULL }, - { 32, DS_16ST_15, DS_NULL, DS_NULL, DS_NULL }, -}; - -/** - * struct atlas7_ds_info - Atlas7 Pad DriveStrength info - * @type: The type of this Pad. - * @mask: The mask value of this pin's pull bits. - * @imval: The immediate value of drives trength register. - * @reserved: Reserved space - */ -struct atlas7_ds_info { - u8 type; - u8 mask; - u8 imval; - u8 reserved; -}; - -static const struct atlas7_ds_info atlas7_ds_map[] = { - { PAD_T_4WE_PD, DS_2BIT_MASK, DS_2BIT_IM_VAL }, - { PAD_T_4WE_PU, DS_2BIT_MASK, DS_2BIT_IM_VAL }, - { PAD_T_16ST, DS_4BIT_MASK, DS_4BIT_IM_VAL }, - { PAD_T_M31_0204_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL }, - { PAD_T_M31_0204_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL }, - { PAD_T_M31_0610_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL }, - { PAD_T_M31_0610_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL }, - { PAD_T_AD, DS_NULL, DS_NULL }, -}; - -static inline u32 atlas7_pin_to_bank(u32 pin) -{ - return (pin >= ATLAS7_PINCTRL_BANK_0_PINS) ? 1 : 0; -} - -static int atlas7_pmx_get_funcs_count(struct pinctrl_dev *pctldev) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - return pmx->pctl_data->funcs_cnt; -} - -static const char *atlas7_pmx_get_func_name(struct pinctrl_dev *pctldev, - u32 selector) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - return pmx->pctl_data->funcs[selector].name; -} - -static int atlas7_pmx_get_func_groups(struct pinctrl_dev *pctldev, - u32 selector, const char * const **groups, - u32 * const num_groups) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - *groups = pmx->pctl_data->funcs[selector].groups; - *num_groups = pmx->pctl_data->funcs[selector].num_groups; - - return 0; -} - -static void __atlas7_pmx_pin_input_disable_set(struct atlas7_pmx *pmx, - const struct atlas7_pad_mux *mux) -{ - /* Set Input Disable to avoid input glitches - * - * All Input-Disable Control registers are located on IOCRTC. - * So the regs bank is always 0. - * - */ - if (mux->dinput_reg && mux->dinput_val_reg) { - writel(DI_MASK << mux->dinput_bit, - pmx->regs[BANK_DS] + CLR_REG(mux->dinput_reg)); - writel(DI_DISABLE << mux->dinput_bit, - pmx->regs[BANK_DS] + mux->dinput_reg); - - - writel(DIV_MASK << mux->dinput_val_bit, - pmx->regs[BANK_DS] + CLR_REG(mux->dinput_val_reg)); - writel(DIV_DISABLE << mux->dinput_val_bit, - pmx->regs[BANK_DS] + mux->dinput_val_reg); - } -} - -static void __atlas7_pmx_pin_input_disable_clr(struct atlas7_pmx *pmx, - const struct atlas7_pad_mux *mux) -{ - /* Clear Input Disable to avoid input glitches */ - if (mux->dinput_reg && mux->dinput_val_reg) { - writel(DI_MASK << mux->dinput_bit, - pmx->regs[BANK_DS] + CLR_REG(mux->dinput_reg)); - writel(DI_ENABLE << mux->dinput_bit, - pmx->regs[BANK_DS] + mux->dinput_reg); - - writel(DIV_MASK << mux->dinput_val_bit, - pmx->regs[BANK_DS] + CLR_REG(mux->dinput_val_reg)); - writel(DIV_ENABLE << mux->dinput_val_bit, - pmx->regs[BANK_DS] + mux->dinput_val_reg); - } -} - -static int __atlas7_pmx_pin_ad_sel(struct atlas7_pmx *pmx, - struct atlas7_pad_config *conf, - u32 bank, u32 ad_sel) -{ - unsigned long regv; - - /* Write to clear register to clear A/D selector */ - writel(ANA_CLEAR_MASK << conf->ad_ctrl_bit, - pmx->regs[bank] + CLR_REG(conf->ad_ctrl_reg)); - - /* Set target pad A/D selector */ - regv = readl(pmx->regs[bank] + conf->ad_ctrl_reg); - regv &= ~(ANA_CLEAR_MASK << conf->ad_ctrl_bit); - writel(regv | (ad_sel << conf->ad_ctrl_bit), - pmx->regs[bank] + conf->ad_ctrl_reg); - - regv = readl(pmx->regs[bank] + conf->ad_ctrl_reg); - pr_debug("bank:%d reg:0x%04x val:0x%08lx\n", - bank, conf->ad_ctrl_reg, regv); - return 0; -} - -static int __atlas7_pmx_pin_analog_enable(struct atlas7_pmx *pmx, - struct atlas7_pad_config *conf, u32 bank) -{ - /* Only PAD_T_AD pins can change between Analogue&Digital */ - if (conf->type != PAD_T_AD) - return -EINVAL; - - return __atlas7_pmx_pin_ad_sel(pmx, conf, bank, 0); -} - -static int __atlas7_pmx_pin_digital_enable(struct atlas7_pmx *pmx, - struct atlas7_pad_config *conf, u32 bank) -{ - /* Other type pads are always digital */ - if (conf->type != PAD_T_AD) - return 0; - - return __atlas7_pmx_pin_ad_sel(pmx, conf, bank, 1); -} - -static int __atlas7_pmx_pin_enable(struct atlas7_pmx *pmx, - u32 pin, u32 func) -{ - struct atlas7_pad_config *conf; - u32 bank; - int ret; - unsigned long regv; - - pr_debug("PMX DUMP ### pin#%d func:%d #### START >>>\n", - pin, func); - - /* Get this Pad's descriptor from PINCTRL */ - conf = &pmx->pctl_data->confs[pin]; - bank = atlas7_pin_to_bank(pin); - - /* Just enable the analog function of this pad */ - if (FUNC_ANALOGUE == func) { - ret = __atlas7_pmx_pin_analog_enable(pmx, conf, bank); - if (ret) - dev_err(pmx->dev, - "Convert pad#%d to analog failed, ret=%d\n", - pin, ret); - return ret; - } - - /* Set Pads from analog to digital */ - ret = __atlas7_pmx_pin_digital_enable(pmx, conf, bank); - if (ret) { - dev_err(pmx->dev, - "Convert pad#%d to digital failed, ret=%d\n", - pin, ret); - return ret; - } - - /* Write to clear register to clear current function */ - writel(FUNC_CLEAR_MASK << conf->mux_bit, - pmx->regs[bank] + CLR_REG(conf->mux_reg)); - - /* Set target pad mux function */ - regv = readl(pmx->regs[bank] + conf->mux_reg); - regv &= ~(FUNC_CLEAR_MASK << conf->mux_bit); - writel(regv | (func << conf->mux_bit), - pmx->regs[bank] + conf->mux_reg); - - regv = readl(pmx->regs[bank] + conf->mux_reg); - pr_debug("bank:%d reg:0x%04x val:0x%08lx\n", - bank, conf->mux_reg, regv); - - return 0; -} - -static int atlas7_pmx_set_mux(struct pinctrl_dev *pctldev, - u32 func_selector, u32 group_selector) -{ - int idx, ret; - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct atlas7_pmx_func *pmx_func; - struct atlas7_pin_group *pin_grp; - const struct atlas7_grp_mux *grp_mux; - const struct atlas7_pad_mux *mux; - - pmx_func = &pmx->pctl_data->funcs[func_selector]; - pin_grp = &pmx->pctl_data->grps[group_selector]; - - pr_debug("PMX DUMP ### Function:[%s] Group:[%s] #### START >>>\n", - pmx_func->name, pin_grp->name); - - /* the sd3 and sd9 pin select by SYS2PCI_SDIO9SEL register */ - if (pin_grp->pins == (unsigned int *)&sd3_9_pins) { - if (!strcmp(pmx_func->name, "sd9")) - writel(1, pmx->sys2pci_base + SYS2PCI_SDIO9SEL); - else - writel(0, pmx->sys2pci_base + SYS2PCI_SDIO9SEL); - } - - grp_mux = pmx_func->grpmux; - - for (idx = 0; idx < grp_mux->pad_mux_count; idx++) { - mux = &grp_mux->pad_mux_list[idx]; - __atlas7_pmx_pin_input_disable_set(pmx, mux); - ret = __atlas7_pmx_pin_enable(pmx, mux->pin, mux->func); - if (ret) { - dev_err(pmx->dev, - "FUNC:%s GRP:%s PIN#%d.%d failed, ret=%d\n", - pmx_func->name, pin_grp->name, - mux->pin, mux->func, ret); - BUG_ON(1); - } - __atlas7_pmx_pin_input_disable_clr(pmx, mux); - } - pr_debug("PMX DUMP ### Function:[%s] Group:[%s] #### END <<<\n", - pmx_func->name, pin_grp->name); - - return 0; -} - -static u32 convert_current_to_drive_strength(u32 type, u32 ma) -{ - int idx; - - for (idx = 0; idx < ARRAY_SIZE(atlas7_ma2ds_map); idx++) { - if (atlas7_ma2ds_map[idx].ma != ma) - continue; - - if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU) - return atlas7_ma2ds_map[idx].ds_4we; - else if (type == PAD_T_16ST) - return atlas7_ma2ds_map[idx].ds_16st; - else if (type == PAD_T_M31_0204_PD || type == PAD_T_M31_0204_PU) - return atlas7_ma2ds_map[idx].ds_0204m31; - else if (type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU) - return atlas7_ma2ds_map[idx].ds_0610m31; - } - - return DS_NULL; -} - -static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev, - u32 pin, u32 sel) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin]; - const struct atlas7_pull_info *pull_info; - u32 bank; - unsigned long regv; - void __iomem *pull_sel_reg; - - bank = atlas7_pin_to_bank(pin); - pull_info = &atlas7_pull_map[conf->type]; - pull_sel_reg = pmx->regs[bank] + conf->pupd_reg; - - /* Retrieve correspond register value from table by sel */ - regv = pull_info->s2v[sel].data & pull_info->mask; - - /* Clear & Set new value to pull register */ - writel(pull_info->mask << conf->pupd_bit, CLR_REG(pull_sel_reg)); - writel(regv << conf->pupd_bit, pull_sel_reg); - - pr_debug("PIN_CFG ### SET PIN#%d PULL SELECTOR:%d == OK ####\n", - pin, sel); - return 0; -} - -static int __altas7_pinctrl_set_drive_strength_sel(struct pinctrl_dev *pctldev, - u32 pin, u32 sel) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin]; - const struct atlas7_ds_info *ds_info; - u32 bank; - void __iomem *ds_sel_reg; - - ds_info = &atlas7_ds_map[conf->type]; - if (sel & (~(ds_info->mask))) - goto unsupport; - - bank = atlas7_pin_to_bank(pin); - ds_sel_reg = pmx->regs[bank] + conf->drvstr_reg; - - writel(ds_info->imval << conf->drvstr_bit, CLR_REG(ds_sel_reg)); - writel(sel << conf->drvstr_bit, ds_sel_reg); - - return 0; - -unsupport: - pr_err("Pad#%d type[%d] doesn't support ds code[%d]!\n", - pin, conf->type, sel); - return -ENOTSUPP; -} - -static int altas7_pinctrl_set_drive_strength_sel(struct pinctrl_dev *pctldev, - u32 pin, u32 ma) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin]; - u32 type = conf->type; - u32 sel; - int ret; - - sel = convert_current_to_drive_strength(conf->type, ma); - if (DS_NULL == sel) { - pr_err("Pad#%d type[%d] doesn't support ds current[%d]!\n", - pin, type, ma); - return -ENOTSUPP; - } - - ret = __altas7_pinctrl_set_drive_strength_sel(pctldev, - pin, sel); - pr_debug("PIN_CFG ### SET PIN#%d DS:%d MA:%d == %s ####\n", - pin, sel, ma, ret?"FAILED":"OK"); - return ret; -} - -static int atlas7_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, u32 pin) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - u32 idx; - - dev_dbg(pmx->dev, - "atlas7_pmx_gpio_request_enable: pin=%d\n", pin); - for (idx = 0; idx < range->npins; idx++) { - if (pin == range->pins[idx]) - break; - } - - if (idx >= range->npins) { - dev_err(pmx->dev, - "The pin#%d could not be requested as GPIO!!\n", - pin); - return -EPERM; - } - - __atlas7_pmx_pin_enable(pmx, pin, FUNC_GPIO); - - return 0; -} - -static const struct pinmux_ops atlas7_pinmux_ops = { - .get_functions_count = atlas7_pmx_get_funcs_count, - .get_function_name = atlas7_pmx_get_func_name, - .get_function_groups = atlas7_pmx_get_func_groups, - .set_mux = atlas7_pmx_set_mux, - .gpio_request_enable = atlas7_pmx_gpio_request_enable, -}; - -static int atlas7_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - return pmx->pctl_data->grps_cnt; -} - -static const char *atlas7_pinctrl_get_group_name(struct pinctrl_dev *pctldev, - u32 group) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - return pmx->pctl_data->grps[group].name; -} - -static int atlas7_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, - u32 group, const u32 **pins, u32 *num_pins) -{ - struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - - *num_pins = pmx->pctl_data->grps[group].num_pins; - *pins = pmx->pctl_data->grps[group].pins; - - return 0; -} - -static int atlas7_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, - u32 *num_maps) -{ - return pinconf_generic_dt_node_to_map(pctldev, np_config, map, - num_maps, PIN_MAP_TYPE_INVALID); -} - -static void atlas7_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, u32 num_maps) -{ - kfree(map); -} - -static const struct pinctrl_ops atlas7_pinctrl_ops = { - .get_groups_count = atlas7_pinctrl_get_groups_count, - .get_group_name = atlas7_pinctrl_get_group_name, - .get_group_pins = atlas7_pinctrl_get_group_pins, - .dt_node_to_map = atlas7_pinctrl_dt_node_to_map, - .dt_free_map = atlas7_pinctrl_dt_free_map, -}; - -static int atlas7_pin_config_set(struct pinctrl_dev *pctldev, - unsigned pin, unsigned long *configs, - unsigned num_configs) -{ - u16 param; - u32 arg; - int idx, err; - - for (idx = 0; idx < num_configs; idx++) { - param = pinconf_to_config_param(configs[idx]); - arg = pinconf_to_config_argument(configs[idx]); - - pr_debug("PMX CFG###### ATLAS7 PIN#%d [%s] CONFIG PARAM:%d ARG:%d >>>>>\n", - pin, atlas7_ioc_pads[pin].name, param, arg); - switch (param) { - case PIN_CONFIG_BIAS_PULL_UP: - err = altas7_pinctrl_set_pull_sel(pctldev, - pin, PULL_UP); - if (err) - return err; - break; - - case PIN_CONFIG_BIAS_PULL_DOWN: - err = altas7_pinctrl_set_pull_sel(pctldev, - pin, PULL_DOWN); - if (err) - return err; - break; - - case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - err = altas7_pinctrl_set_pull_sel(pctldev, - pin, HIGH_HYSTERESIS); - if (err) - return err; - break; - case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: - err = altas7_pinctrl_set_pull_sel(pctldev, - pin, HIGH_Z); - if (err) - return err; - break; - - case PIN_CONFIG_DRIVE_STRENGTH: - err = altas7_pinctrl_set_drive_strength_sel(pctldev, - pin, arg); - if (err) - return err; - break; - default: - return -ENOTSUPP; - } - pr_debug("PMX CFG###### ATLAS7 PIN#%d [%s] CONFIG PARAM:%d ARG:%d <<<<\n", - pin, atlas7_ioc_pads[pin].name, param, arg); - } - - return 0; -} - -static int atlas7_pin_config_group_set(struct pinctrl_dev *pctldev, - unsigned group, unsigned long *configs, - unsigned num_configs) -{ - const unsigned *pins; - unsigned npins; - int i, ret; - - ret = atlas7_pinctrl_get_group_pins(pctldev, group, &pins, &npins); - if (ret) - return ret; - for (i = 0; i < npins; i++) { - if (atlas7_pin_config_set(pctldev, pins[i], - configs, num_configs)) - return -ENOTSUPP; - } - return 0; -} - -static const struct pinconf_ops atlas7_pinconf_ops = { - .pin_config_set = atlas7_pin_config_set, - .pin_config_group_set = atlas7_pin_config_group_set, - .is_generic = true, -}; - -static int atlas7_pinmux_probe(struct platform_device *pdev) -{ - int ret, idx; - struct atlas7_pmx *pmx; - struct device_node *np = pdev->dev.of_node; - u32 banks = ATLAS7_PINCTRL_REG_BANKS; - struct device_node *sys2pci_np; - struct resource res; - - /* Create state holders etc for this driver */ - pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL); - if (!pmx) - return -ENOMEM; - - /* The sd3 and sd9 shared all pins, and the function select by - * SYS2PCI_SDIO9SEL register - */ - sys2pci_np = of_find_node_by_name(NULL, "sys2pci"); - if (!sys2pci_np) - return -EINVAL; - - ret = of_address_to_resource(sys2pci_np, 0, &res); - of_node_put(sys2pci_np); - if (ret) - return ret; - - pmx->sys2pci_base = devm_ioremap_resource(&pdev->dev, &res); - if (IS_ERR(pmx->sys2pci_base)) - return -ENOMEM; - - pmx->dev = &pdev->dev; - - pmx->pctl_data = &atlas7_ioc_data; - pmx->pctl_desc.name = "pinctrl-atlas7"; - pmx->pctl_desc.pins = pmx->pctl_data->pads; - pmx->pctl_desc.npins = pmx->pctl_data->pads_cnt; - pmx->pctl_desc.pctlops = &atlas7_pinctrl_ops; - pmx->pctl_desc.pmxops = &atlas7_pinmux_ops; - pmx->pctl_desc.confops = &atlas7_pinconf_ops; - - for (idx = 0; idx < banks; idx++) { - pmx->regs[idx] = of_iomap(np, idx); - if (!pmx->regs[idx]) { - dev_err(&pdev->dev, - "can't map ioc bank#%d registers\n", idx); - ret = -ENOMEM; - goto unmap_io; - } - } - - /* Now register the pin controller and all pins it handles */ - pmx->pctl = pinctrl_register(&pmx->pctl_desc, &pdev->dev, pmx); - if (IS_ERR(pmx->pctl)) { - dev_err(&pdev->dev, "could not register atlas7 pinmux driver\n"); - ret = PTR_ERR(pmx->pctl); - goto unmap_io; - } - - platform_set_drvdata(pdev, pmx); - - dev_info(&pdev->dev, "initialized atlas7 pinmux driver\n"); - - return 0; - -unmap_io: - for (idx = 0; idx < banks; idx++) { - if (!pmx->regs[idx]) - break; - iounmap(pmx->regs[idx]); - } - - return ret; -} - -#ifdef CONFIG_PM_SLEEP -static int atlas7_pinmux_suspend_noirq(struct device *dev) -{ - struct atlas7_pmx *pmx = dev_get_drvdata(dev); - struct atlas7_pad_status *status; - struct atlas7_pad_config *conf; - const struct atlas7_ds_info *ds_info; - const struct atlas7_pull_info *pull_info; - int idx; - u32 bank; - unsigned long regv; - - for (idx = 0; idx < pmx->pctl_desc.npins; idx++) { - /* Get this Pad's descriptor from PINCTRL */ - conf = &pmx->pctl_data->confs[idx]; - bank = atlas7_pin_to_bank(idx); - status = &pmx->sleep_data[idx]; - - /* Save Function selector */ - regv = readl(pmx->regs[bank] + conf->mux_reg); - status->func = (regv >> conf->mux_bit) & FUNC_CLEAR_MASK; - - /* Check if Pad is in Analogue selector */ - if (conf->ad_ctrl_reg == -1) - goto save_ds_sel; - - regv = readl(pmx->regs[bank] + conf->ad_ctrl_reg); - if (!(regv & (conf->ad_ctrl_bit << ANA_CLEAR_MASK))) - status->func = FUNC_ANALOGUE; - -save_ds_sel: - if (conf->drvstr_reg == -1) - goto save_pull_sel; - - /* Save Drive Strength selector */ - ds_info = &atlas7_ds_map[conf->type]; - regv = readl(pmx->regs[bank] + conf->drvstr_reg); - status->dstr = (regv >> conf->drvstr_bit) & ds_info->mask; - -save_pull_sel: - /* Save Pull selector */ - pull_info = &atlas7_pull_map[conf->type]; - regv = readl(pmx->regs[bank] + conf->pupd_reg); - regv = (regv >> conf->pupd_bit) & pull_info->mask; - status->pull = pull_info->v2s[regv].data; - } - - /* - * Save disable input selector, this selector is not for Pin, - * but for Mux function. - */ - for (idx = 0; idx < NUM_OF_IN_DISABLE_REG; idx++) { - pmx->status_ds[idx] = readl(pmx->regs[BANK_DS] + - IN_DISABLE_0_REG_SET + 0x8 * idx); - pmx->status_dsv[idx] = readl(pmx->regs[BANK_DS] + - IN_DISABLE_VAL_0_REG_SET + 0x8 * idx); - } - - return 0; -} - -static int atlas7_pinmux_resume_noirq(struct device *dev) -{ - struct atlas7_pmx *pmx = dev_get_drvdata(dev); - struct atlas7_pad_status *status; - int idx; - - for (idx = 0; idx < pmx->pctl_desc.npins; idx++) { - /* Get this Pad's descriptor from PINCTRL */ - status = &pmx->sleep_data[idx]; - - /* Restore Function selector */ - __atlas7_pmx_pin_enable(pmx, idx, (u32)status->func & 0xff); - - if (FUNC_ANALOGUE == status->func) - goto restore_pull_sel; - - /* Restore Drive Strength selector */ - __altas7_pinctrl_set_drive_strength_sel(pmx->pctl, idx, - (u32)status->dstr & 0xff); - -restore_pull_sel: - /* Restore Pull selector */ - altas7_pinctrl_set_pull_sel(pmx->pctl, idx, - (u32)status->pull & 0xff); - } - - /* - * Restore disable input selector, this selector is not for Pin, - * but for Mux function - */ - for (idx = 0; idx < NUM_OF_IN_DISABLE_REG; idx++) { - writel(~0, pmx->regs[BANK_DS] + - IN_DISABLE_0_REG_CLR + 0x8 * idx); - writel(pmx->status_ds[idx], pmx->regs[BANK_DS] + - IN_DISABLE_0_REG_SET + 0x8 * idx); - writel(~0, pmx->regs[BANK_DS] + - IN_DISABLE_VAL_0_REG_CLR + 0x8 * idx); - writel(pmx->status_dsv[idx], pmx->regs[BANK_DS] + - IN_DISABLE_VAL_0_REG_SET + 0x8 * idx); - } - - return 0; -} - -static const struct dev_pm_ops atlas7_pinmux_pm_ops = { - .suspend_noirq = atlas7_pinmux_suspend_noirq, - .resume_noirq = atlas7_pinmux_resume_noirq, - .freeze_noirq = atlas7_pinmux_suspend_noirq, - .restore_noirq = atlas7_pinmux_resume_noirq, -}; -#endif - -static const struct of_device_id atlas7_pinmux_ids[] = { - { .compatible = "sirf,atlas7-ioc",}, - {}, -}; - -static struct platform_driver atlas7_pinmux_driver = { - .driver = { - .name = "atlas7-ioc", - .of_match_table = atlas7_pinmux_ids, -#ifdef CONFIG_PM_SLEEP - .pm = &atlas7_pinmux_pm_ops, -#endif - }, - .probe = atlas7_pinmux_probe, -}; - -static int __init atlas7_pinmux_init(void) -{ - return platform_driver_register(&atlas7_pinmux_driver); -} -arch_initcall(atlas7_pinmux_init); - - -/* - * The Following is GPIO Code - */ -static inline struct -atlas7_gpio_bank *atlas7_gpio_to_bank(struct atlas7_gpio_chip *a7gc, u32 gpio) -{ - return &a7gc->banks[GPIO_TO_BANK(gpio)]; -} - -static int __atlas7_gpio_to_pin(struct atlas7_gpio_chip *a7gc, u32 gpio) -{ - struct atlas7_gpio_bank *bank; - u32 ofs; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - ofs = gpio - bank->gpio_offset; - if (ofs >= bank->ngpio) - return -ENODEV; - - return bank->gpio_pins[ofs]; -} - -static void atlas7_gpio_irq_ack(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, d->hwirq); - pin_in_bank = d->hwirq - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - val = readl(ctrl_reg); - /* clear interrupt status */ - writel(val, ctrl_reg); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); -} - -static void __atlas7_gpio_irq_mask(struct atlas7_gpio_chip *a7gc, int idx) -{ - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - - bank = atlas7_gpio_to_bank(a7gc, idx); - pin_in_bank = idx - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - val = readl(ctrl_reg); - val &= ~(ATLAS7_GPIO_CTL_INTR_EN_MASK | - ATLAS7_GPIO_CTL_INTR_STATUS_MASK); - writel(val, ctrl_reg); -} - -static void atlas7_gpio_irq_mask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - unsigned long flags; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - __atlas7_gpio_irq_mask(a7gc, d->hwirq); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); -} - -static void atlas7_gpio_irq_unmask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, d->hwirq); - pin_in_bank = d->hwirq - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - val = readl(ctrl_reg); - val &= ~ATLAS7_GPIO_CTL_INTR_STATUS_MASK; - val |= ATLAS7_GPIO_CTL_INTR_EN_MASK; - writel(val, ctrl_reg); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); -} - -static int atlas7_gpio_irq_type(struct irq_data *d, - unsigned int type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, d->hwirq); - pin_in_bank = d->hwirq - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - val = readl(ctrl_reg); - val &= ~(ATLAS7_GPIO_CTL_INTR_STATUS_MASK | - ATLAS7_GPIO_CTL_INTR_EN_MASK); - - switch (type) { - case IRQ_TYPE_NONE: - break; - - case IRQ_TYPE_EDGE_RISING: - val |= ATLAS7_GPIO_CTL_INTR_HIGH_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK; - val &= ~ATLAS7_GPIO_CTL_INTR_LOW_MASK; - break; - - case IRQ_TYPE_EDGE_FALLING: - val &= ~ATLAS7_GPIO_CTL_INTR_HIGH_MASK; - val |= ATLAS7_GPIO_CTL_INTR_LOW_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK; - break; - - case IRQ_TYPE_EDGE_BOTH: - val |= ATLAS7_GPIO_CTL_INTR_HIGH_MASK | - ATLAS7_GPIO_CTL_INTR_LOW_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK; - break; - - case IRQ_TYPE_LEVEL_LOW: - val &= ~(ATLAS7_GPIO_CTL_INTR_HIGH_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK); - val |= ATLAS7_GPIO_CTL_INTR_LOW_MASK; - break; - - case IRQ_TYPE_LEVEL_HIGH: - val |= ATLAS7_GPIO_CTL_INTR_HIGH_MASK; - val &= ~(ATLAS7_GPIO_CTL_INTR_LOW_MASK | - ATLAS7_GPIO_CTL_INTR_TYPE_MASK); - break; - } - - writel(val, ctrl_reg); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return 0; -} - -static struct irq_chip atlas7_gpio_irq_chip = { - .name = "atlas7-gpio-irq", - .irq_ack = atlas7_gpio_irq_ack, - .irq_mask = atlas7_gpio_irq_mask, - .irq_unmask = atlas7_gpio_irq_unmask, - .irq_set_type = atlas7_gpio_irq_type, -}; - -static void atlas7_gpio_handle_irq(struct irq_desc *desc) -{ - struct gpio_chip *gc = irq_desc_get_handler_data(desc); - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc); - struct atlas7_gpio_bank *bank = NULL; - u32 status, ctrl; - int pin_in_bank = 0, idx; - struct irq_chip *chip = irq_desc_get_chip(desc); - unsigned int irq = irq_desc_get_irq(desc); - - for (idx = 0; idx < a7gc->nbank; idx++) { - bank = &a7gc->banks[idx]; - if (bank->irq == irq) - break; - } - BUG_ON(idx == a7gc->nbank); - - chained_irq_enter(chip, desc); - - status = readl(ATLAS7_GPIO_INT_STATUS(bank)); - if (!status) { - pr_warn("%s: gpio [%s] status %#x no interrupt is flagged\n", - __func__, gc->label, status); - handle_bad_irq(desc); - return; - } - - while (status) { - ctrl = readl(ATLAS7_GPIO_CTRL(bank, pin_in_bank)); - - /* - * Here we must check whether the corresponding GPIO's - * interrupt has been enabled, otherwise just skip it - */ - if ((status & 0x1) && (ctrl & ATLAS7_GPIO_CTL_INTR_EN_MASK)) { - pr_debug("%s: chip[%s] gpio:%d happens\n", - __func__, gc->label, - bank->gpio_offset + pin_in_bank); - generic_handle_irq( - irq_find_mapping(gc->irq.domain, - bank->gpio_offset + pin_in_bank)); - } - - if (++pin_in_bank >= bank->ngpio) - break; - - status = status >> 1; - } - - chained_irq_exit(chip, desc); -} - -static void __atlas7_gpio_set_input(struct atlas7_gpio_chip *a7gc, - unsigned int gpio) -{ - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 val, pin_in_bank; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - pin_in_bank = gpio - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - val = readl(ctrl_reg); - val &= ~ATLAS7_GPIO_CTL_OUT_EN_MASK; - writel(val, ctrl_reg); -} - -static int atlas7_gpio_request(struct gpio_chip *chip, - unsigned int gpio) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - int ret; - unsigned long flags; - - ret = __atlas7_gpio_to_pin(a7gc, gpio); - if (ret < 0) - return ret; - - if (pinctrl_gpio_request(chip->base + gpio)) - return -ENODEV; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - /* - * default status: - * set direction as input and mask irq - */ - __atlas7_gpio_set_input(a7gc, gpio); - __atlas7_gpio_irq_mask(a7gc, gpio); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return 0; -} - -static void atlas7_gpio_free(struct gpio_chip *chip, - unsigned int gpio) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - unsigned long flags; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - __atlas7_gpio_irq_mask(a7gc, gpio); - __atlas7_gpio_set_input(a7gc, gpio); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - pinctrl_gpio_free(chip->base + gpio); -} - -static int atlas7_gpio_direction_input(struct gpio_chip *chip, - unsigned int gpio) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - unsigned long flags; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - __atlas7_gpio_set_input(a7gc, gpio); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return 0; -} - -static void __atlas7_gpio_set_output(struct atlas7_gpio_chip *a7gc, - unsigned int gpio, int value) -{ - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 out_ctrl, pin_in_bank; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - pin_in_bank = gpio - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - out_ctrl = readl(ctrl_reg); - if (value) - out_ctrl |= ATLAS7_GPIO_CTL_DATAOUT_MASK; - else - out_ctrl &= ~ATLAS7_GPIO_CTL_DATAOUT_MASK; - - out_ctrl &= ~ATLAS7_GPIO_CTL_INTR_EN_MASK; - out_ctrl |= ATLAS7_GPIO_CTL_OUT_EN_MASK; - writel(out_ctrl, ctrl_reg); -} - -static int atlas7_gpio_direction_output(struct gpio_chip *chip, - unsigned int gpio, int value) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - unsigned long flags; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - __atlas7_gpio_set_output(a7gc, gpio, value); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return 0; -} - -static int atlas7_gpio_get_value(struct gpio_chip *chip, - unsigned int gpio) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - struct atlas7_gpio_bank *bank; - u32 val, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - pin_in_bank = gpio - bank->gpio_offset; - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - val = readl(ATLAS7_GPIO_CTRL(bank, pin_in_bank)); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); - - return !!(val & ATLAS7_GPIO_CTL_DATAIN_MASK); -} - -static void atlas7_gpio_set_value(struct gpio_chip *chip, - unsigned int gpio, int value) -{ - struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 ctrl, pin_in_bank; - unsigned long flags; - - bank = atlas7_gpio_to_bank(a7gc, gpio); - pin_in_bank = gpio - bank->gpio_offset; - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank); - - raw_spin_lock_irqsave(&a7gc->lock, flags); - - ctrl = readl(ctrl_reg); - if (value) - ctrl |= ATLAS7_GPIO_CTL_DATAOUT_MASK; - else - ctrl &= ~ATLAS7_GPIO_CTL_DATAOUT_MASK; - writel(ctrl, ctrl_reg); - - raw_spin_unlock_irqrestore(&a7gc->lock, flags); -} - -static const struct of_device_id atlas7_gpio_ids[] = { - { .compatible = "sirf,atlas7-gpio", }, - {}, -}; - -static int atlas7_gpio_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct atlas7_gpio_chip *a7gc; - struct gpio_chip *chip; - u32 nbank; - int ret, idx; - struct gpio_irq_chip *girq; - - ret = of_property_read_u32(np, "gpio-banks", &nbank); - if (ret) { - dev_err(&pdev->dev, - "Could not find GPIO bank info,ret=%d!\n", - ret); - return ret; - } - - /* retrieve gpio descriptor data */ - a7gc = devm_kzalloc(&pdev->dev, struct_size(a7gc, banks, nbank), - GFP_KERNEL); - if (!a7gc) - return -ENOMEM; - - /* Get Gpio clk */ - a7gc->clk = of_clk_get(np, 0); - if (!IS_ERR(a7gc->clk)) { - ret = clk_prepare_enable(a7gc->clk); - if (ret) { - dev_err(&pdev->dev, - "Could not enable clock!\n"); - return ret; - } - } - - /* Get Gpio Registers */ - a7gc->reg = of_iomap(np, 0); - if (!a7gc->reg) { - dev_err(&pdev->dev, "Could not map GPIO Registers!\n"); - return -ENOMEM; - } - - a7gc->nbank = nbank; - raw_spin_lock_init(&a7gc->lock); - - /* Setup GPIO Chip */ - chip = &a7gc->chip; - chip->request = atlas7_gpio_request; - chip->free = atlas7_gpio_free; - chip->direction_input = atlas7_gpio_direction_input; - chip->get = atlas7_gpio_get_value; - chip->direction_output = atlas7_gpio_direction_output; - chip->set = atlas7_gpio_set_value; - chip->base = -1; - /* Each chip can support 32 pins at one bank */ - chip->ngpio = NGPIO_OF_BANK * nbank; - chip->label = kstrdup(np->name, GFP_KERNEL); - chip->of_node = np; - chip->of_gpio_n_cells = 2; - chip->parent = &pdev->dev; - - girq = &chip->irq; - girq->chip = &atlas7_gpio_irq_chip; - girq->parent_handler = atlas7_gpio_handle_irq; - girq->num_parents = nbank; - girq->parents = devm_kcalloc(&pdev->dev, nbank, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) - return -ENOMEM; - for (idx = 0; idx < nbank; idx++) { - struct atlas7_gpio_bank *bank; - - bank = &a7gc->banks[idx]; - /* Set ctrl registers' base of this bank */ - bank->base = ATLAS7_GPIO_BASE(a7gc, idx); - bank->gpio_offset = idx * NGPIO_OF_BANK; - - /* Get interrupt number from DTS */ - ret = of_irq_get(np, idx); - if (ret <= 0) { - dev_err(&pdev->dev, - "Unable to find IRQ number. ret=%d\n", ret); - if (!ret) - ret = -ENXIO; - goto failed; - } - bank->irq = ret; - girq->parents[idx] = ret; - } - girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_level_irq; - - /* Add gpio chip to system */ - ret = gpiochip_add_data(chip, a7gc); - if (ret) { - dev_err(&pdev->dev, - "%pOF: error in probe function with status %d\n", - np, ret); - goto failed; - } - - platform_set_drvdata(pdev, a7gc); - dev_info(&pdev->dev, "add to system.\n"); - return 0; -failed: - return ret; -} - -#ifdef CONFIG_PM_SLEEP -static int atlas7_gpio_suspend_noirq(struct device *dev) -{ - struct atlas7_gpio_chip *a7gc = dev_get_drvdata(dev); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 idx, pin; - - for (idx = 0; idx < a7gc->nbank; idx++) { - bank = &a7gc->banks[idx]; - for (pin = 0; pin < bank->ngpio; pin++) { - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin); - bank->sleep_data[pin] = readl(ctrl_reg); - } - } - - return 0; -} - -static int atlas7_gpio_resume_noirq(struct device *dev) -{ - struct atlas7_gpio_chip *a7gc = dev_get_drvdata(dev); - struct atlas7_gpio_bank *bank; - void __iomem *ctrl_reg; - u32 idx, pin; - - for (idx = 0; idx < a7gc->nbank; idx++) { - bank = &a7gc->banks[idx]; - for (pin = 0; pin < bank->ngpio; pin++) { - ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin); - writel(bank->sleep_data[pin], ctrl_reg); - } - } - - return 0; -} - -static const struct dev_pm_ops atlas7_gpio_pm_ops = { - .suspend_noirq = atlas7_gpio_suspend_noirq, - .resume_noirq = atlas7_gpio_resume_noirq, - .freeze_noirq = atlas7_gpio_suspend_noirq, - .restore_noirq = atlas7_gpio_resume_noirq, -}; -#endif - -static struct platform_driver atlas7_gpio_driver = { - .driver = { - .name = "atlas7-gpio", - .of_match_table = atlas7_gpio_ids, -#ifdef CONFIG_PM_SLEEP - .pm = &atlas7_gpio_pm_ops, -#endif - }, - .probe = atlas7_gpio_probe, -}; - -static int __init atlas7_gpio_init(void) -{ - return platform_driver_register(&atlas7_gpio_driver); -} -subsys_initcall(atlas7_gpio_init); diff --git a/drivers/pinctrl/sirf/pinctrl-prima2.c b/drivers/pinctrl/sirf/pinctrl-prima2.c deleted file mode 100644 index 49da2a7eba1f..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-prima2.c +++ /dev/null @@ -1,1131 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pinctrl pads, groups, functions for CSR SiRFprimaII - * - * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group - * company. - */ - -#include -#include - -#include "pinctrl-sirf.h" - -/* - * pad list for the pinmux subsystem - * refer to CS-131858-DC-6A.xls - */ -static const struct pinctrl_pin_desc sirfsoc_pads[] = { - PINCTRL_PIN(0, "gpio0-0"), - PINCTRL_PIN(1, "gpio0-1"), - PINCTRL_PIN(2, "gpio0-2"), - PINCTRL_PIN(3, "gpio0-3"), - PINCTRL_PIN(4, "pwm0"), - PINCTRL_PIN(5, "pwm1"), - PINCTRL_PIN(6, "pwm2"), - PINCTRL_PIN(7, "pwm3"), - PINCTRL_PIN(8, "warm_rst_b"), - PINCTRL_PIN(9, "odo_0"), - PINCTRL_PIN(10, "odo_1"), - PINCTRL_PIN(11, "dr_dir"), - PINCTRL_PIN(12, "viprom_fa"), - PINCTRL_PIN(13, "scl_1"), - PINCTRL_PIN(14, "ntrst"), - PINCTRL_PIN(15, "sda_1"), - PINCTRL_PIN(16, "x_ldd[16]"), - PINCTRL_PIN(17, "x_ldd[17]"), - PINCTRL_PIN(18, "x_ldd[18]"), - PINCTRL_PIN(19, "x_ldd[19]"), - PINCTRL_PIN(20, "x_ldd[20]"), - PINCTRL_PIN(21, "x_ldd[21]"), - PINCTRL_PIN(22, "x_ldd[22]"), - PINCTRL_PIN(23, "x_ldd[23], lcdrom_frdy"), - PINCTRL_PIN(24, "gps_sgn"), - PINCTRL_PIN(25, "gps_mag"), - PINCTRL_PIN(26, "gps_clk"), - PINCTRL_PIN(27, "sd_cd_b_1"), - PINCTRL_PIN(28, "sd_vcc_on_1"), - PINCTRL_PIN(29, "sd_wp_b_1"), - PINCTRL_PIN(30, "sd_clk_3"), - PINCTRL_PIN(31, "sd_cmd_3"), - - PINCTRL_PIN(32, "x_sd_dat_3[0]"), - PINCTRL_PIN(33, "x_sd_dat_3[1]"), - PINCTRL_PIN(34, "x_sd_dat_3[2]"), - PINCTRL_PIN(35, "x_sd_dat_3[3]"), - PINCTRL_PIN(36, "x_sd_clk_4"), - PINCTRL_PIN(37, "x_sd_cmd_4"), - PINCTRL_PIN(38, "x_sd_dat_4[0]"), - PINCTRL_PIN(39, "x_sd_dat_4[1]"), - PINCTRL_PIN(40, "x_sd_dat_4[2]"), - PINCTRL_PIN(41, "x_sd_dat_4[3]"), - PINCTRL_PIN(42, "x_cko_1"), - PINCTRL_PIN(43, "x_ac97_bit_clk"), - PINCTRL_PIN(44, "x_ac97_dout"), - PINCTRL_PIN(45, "x_ac97_din"), - PINCTRL_PIN(46, "x_ac97_sync"), - PINCTRL_PIN(47, "x_txd_1"), - PINCTRL_PIN(48, "x_txd_2"), - PINCTRL_PIN(49, "x_rxd_1"), - PINCTRL_PIN(50, "x_rxd_2"), - PINCTRL_PIN(51, "x_usclk_0"), - PINCTRL_PIN(52, "x_utxd_0"), - PINCTRL_PIN(53, "x_urxd_0"), - PINCTRL_PIN(54, "x_utfs_0"), - PINCTRL_PIN(55, "x_urfs_0"), - PINCTRL_PIN(56, "x_usclk_1"), - PINCTRL_PIN(57, "x_utxd_1"), - PINCTRL_PIN(58, "x_urxd_1"), - PINCTRL_PIN(59, "x_utfs_1"), - PINCTRL_PIN(60, "x_urfs_1"), - PINCTRL_PIN(61, "x_usclk_2"), - PINCTRL_PIN(62, "x_utxd_2"), - PINCTRL_PIN(63, "x_urxd_2"), - - PINCTRL_PIN(64, "x_utfs_2"), - PINCTRL_PIN(65, "x_urfs_2"), - PINCTRL_PIN(66, "x_df_we_b"), - PINCTRL_PIN(67, "x_df_re_b"), - PINCTRL_PIN(68, "x_txd_0"), - PINCTRL_PIN(69, "x_rxd_0"), - PINCTRL_PIN(78, "x_cko_0"), - PINCTRL_PIN(79, "x_vip_pxd[7]"), - PINCTRL_PIN(80, "x_vip_pxd[6]"), - PINCTRL_PIN(81, "x_vip_pxd[5]"), - PINCTRL_PIN(82, "x_vip_pxd[4]"), - PINCTRL_PIN(83, "x_vip_pxd[3]"), - PINCTRL_PIN(84, "x_vip_pxd[2]"), - PINCTRL_PIN(85, "x_vip_pxd[1]"), - PINCTRL_PIN(86, "x_vip_pxd[0]"), - PINCTRL_PIN(87, "x_vip_vsync"), - PINCTRL_PIN(88, "x_vip_hsync"), - PINCTRL_PIN(89, "x_vip_pxclk"), - PINCTRL_PIN(90, "x_sda_0"), - PINCTRL_PIN(91, "x_scl_0"), - PINCTRL_PIN(92, "x_df_ry_by"), - PINCTRL_PIN(93, "x_df_cs_b[1]"), - PINCTRL_PIN(94, "x_df_cs_b[0]"), - PINCTRL_PIN(95, "x_l_pclk"), - - PINCTRL_PIN(96, "x_l_lck"), - PINCTRL_PIN(97, "x_l_fck"), - PINCTRL_PIN(98, "x_l_de"), - PINCTRL_PIN(99, "x_ldd[0]"), - PINCTRL_PIN(100, "x_ldd[1]"), - PINCTRL_PIN(101, "x_ldd[2]"), - PINCTRL_PIN(102, "x_ldd[3]"), - PINCTRL_PIN(103, "x_ldd[4]"), - PINCTRL_PIN(104, "x_ldd[5]"), - PINCTRL_PIN(105, "x_ldd[6]"), - PINCTRL_PIN(106, "x_ldd[7]"), - PINCTRL_PIN(107, "x_ldd[8]"), - PINCTRL_PIN(108, "x_ldd[9]"), - PINCTRL_PIN(109, "x_ldd[10]"), - PINCTRL_PIN(110, "x_ldd[11]"), - PINCTRL_PIN(111, "x_ldd[12]"), - PINCTRL_PIN(112, "x_ldd[13]"), - PINCTRL_PIN(113, "x_ldd[14]"), - PINCTRL_PIN(114, "x_ldd[15]"), - - PINCTRL_PIN(115, "x_usb1_dp"), - PINCTRL_PIN(116, "x_usb1_dn"), -}; - -static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | - BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | - BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, -}; - -static const struct sirfsoc_padmux lcd_16bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask), - .muxmask = lcd_16bits_sirfsoc_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_16bits_pins[] = { 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; - -static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | - BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | - BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux lcd_18bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask), - .muxmask = lcd_18bits_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_18bits_pins[] = { 16, 17, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114}; - -static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | - BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | - BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | - BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux lcd_24bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask), - .muxmask = lcd_24bits_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_24bits_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114 }; - -static const struct sirfsoc_muxmask lcdrom_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | - BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | - BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, { - .group = 0, - .mask = BIT(23), - }, -}; - -static const struct sirfsoc_padmux lcdrom_padmux = { - .muxmask_counts = ARRAY_SIZE(lcdrom_muxmask), - .muxmask = lcdrom_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(4), - .funcval = BIT(4), -}; - -static const unsigned lcdrom_pins[] = { 23, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; - -static const struct sirfsoc_muxmask uart0_muxmask[] = { - { - .group = 2, - .mask = BIT(4) | BIT(5), - }, { - .group = 1, - .mask = BIT(23) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux uart0_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_muxmask), - .muxmask = uart0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(9), - .funcval = BIT(9), -}; - -static const unsigned uart0_pins[] = { 55, 60, 68, 69 }; - -static const struct sirfsoc_muxmask uart0_nostreamctrl_muxmask[] = { - { - .group = 2, - .mask = BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux uart0_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask), - .muxmask = uart0_nostreamctrl_muxmask, -}; - -static const unsigned uart0_nostreamctrl_pins[] = { 68, 69 }; - -static const struct sirfsoc_muxmask uart1_muxmask[] = { - { - .group = 1, - .mask = BIT(15) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux uart1_padmux = { - .muxmask_counts = ARRAY_SIZE(uart1_muxmask), - .muxmask = uart1_muxmask, -}; - -static const unsigned uart1_pins[] = { 47, 49 }; - -static const struct sirfsoc_muxmask uart2_muxmask[] = { - { - .group = 1, - .mask = BIT(16) | BIT(18) | BIT(24) | BIT(27), - }, -}; - -static const struct sirfsoc_padmux uart2_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_muxmask), - .muxmask = uart2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(10), - .funcval = BIT(10), -}; - -static const unsigned uart2_pins[] = { 48, 50, 56, 59 }; - -static const struct sirfsoc_muxmask uart2_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(16) | BIT(18), - }, -}; - -static const struct sirfsoc_padmux uart2_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask), - .muxmask = uart2_nostreamctrl_muxmask, -}; - -static const unsigned uart2_nostreamctrl_pins[] = { 48, 50 }; - -static const struct sirfsoc_muxmask sdmmc3_muxmask[] = { - { - .group = 0, - .mask = BIT(30) | BIT(31), - }, { - .group = 1, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc3_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask), - .muxmask = sdmmc3_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(7), - .funcval = 0, -}; - -static const unsigned sdmmc3_pins[] = { 30, 31, 32, 33, 34, 35 }; - -static const struct sirfsoc_muxmask spi0_muxmask[] = { - { - .group = 1, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux spi0_padmux = { - .muxmask_counts = ARRAY_SIZE(spi0_muxmask), - .muxmask = spi0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(7), - .funcval = BIT(7), -}; - -static const unsigned spi0_pins[] = { 32, 33, 34, 35 }; - -static const struct sirfsoc_muxmask sdmmc4_muxmask[] = { - { - .group = 1, - .mask = BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9), - }, -}; - -static const struct sirfsoc_padmux sdmmc4_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc4_muxmask), - .muxmask = sdmmc4_muxmask, -}; - -static const unsigned sdmmc4_pins[] = { 36, 37, 38, 39, 40, 41 }; - -static const struct sirfsoc_muxmask cko1_muxmask[] = { - { - .group = 1, - .mask = BIT(10), - }, -}; - -static const struct sirfsoc_padmux cko1_padmux = { - .muxmask_counts = ARRAY_SIZE(cko1_muxmask), - .muxmask = cko1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(3), - .funcval = 0, -}; - -static const unsigned cko1_pins[] = { 42 }; - -static const struct sirfsoc_muxmask i2s_mclk_muxmask[] = { - { - .group = 1, - .mask = BIT(10), - }, -}; - -static const struct sirfsoc_padmux i2s_mclk_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_mclk_muxmask), - .muxmask = i2s_mclk_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(3), - .funcval = BIT(3), -}; - -static const unsigned i2s_mclk_pins[] = { 42 }; - -static const struct sirfsoc_muxmask i2s_ext_clk_input_muxmask[] = { - { - .group = 1, - .mask = BIT(19), - }, -}; - -static const struct sirfsoc_padmux i2s_ext_clk_input_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_ext_clk_input_muxmask), - .muxmask = i2s_ext_clk_input_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(2), - .funcval = BIT(2), -}; - -static const unsigned i2s_ext_clk_input_pins[] = { 51 }; - -static const struct sirfsoc_muxmask i2s_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux i2s_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_muxmask), - .muxmask = i2s_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, -}; - -static const unsigned i2s_pins[] = { 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask i2s_no_din_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux i2s_no_din_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_no_din_muxmask), - .muxmask = i2s_no_din_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, -}; - -static const unsigned i2s_no_din_pins[] = { 43, 44, 46 }; - -static const struct sirfsoc_muxmask i2s_6chn_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14) - | BIT(23) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux i2s_6chn_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_6chn_muxmask), - .muxmask = i2s_6chn_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(9), - .funcval = BIT(1) | BIT(9), -}; - -static const unsigned i2s_6chn_pins[] = { 43, 44, 45, 46, 55, 60 }; - -static const struct sirfsoc_muxmask ac97_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux ac97_padmux = { - .muxmask_counts = ARRAY_SIZE(ac97_muxmask), - .muxmask = ac97_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(8), - .funcval = 0, -}; - -static const unsigned ac97_pins[] = { 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask spi1_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux spi1_padmux = { - .muxmask_counts = ARRAY_SIZE(spi1_muxmask), - .muxmask = spi1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(8), - .funcval = BIT(8), -}; - -static const unsigned spi1_pins[] = { 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask sdmmc1_muxmask[] = { - { - .group = 0, - .mask = BIT(27) | BIT(28) | BIT(29), - }, -}; - -static const struct sirfsoc_padmux sdmmc1_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask), - .muxmask = sdmmc1_muxmask, -}; - -static const unsigned sdmmc1_pins[] = { 27, 28, 29 }; - -static const struct sirfsoc_muxmask gps_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux gps_padmux = { - .muxmask_counts = ARRAY_SIZE(gps_muxmask), - .muxmask = gps_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(12) | BIT(13) | BIT(14), - .funcval = BIT(12), -}; - -static const unsigned gps_pins[] = { 24, 25, 26 }; - -static const struct sirfsoc_muxmask sdmmc5_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux sdmmc5_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask), - .muxmask = sdmmc5_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(13) | BIT(14), - .funcval = BIT(13) | BIT(14), -}; - -static const unsigned sdmmc5_pins[] = { 24, 25, 26 }; - -static const struct sirfsoc_muxmask usp0_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux usp0_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_muxmask), - .muxmask = usp0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(6) | BIT(9), - .funcval = 0, -}; - -static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 }; - -static const struct sirfsoc_muxmask usp0_only_utfs_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22), - }, -}; - -static const struct sirfsoc_padmux usp0_only_utfs_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_only_utfs_muxmask), - .muxmask = usp0_only_utfs_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(6), - .funcval = 0, -}; - -static const unsigned usp0_only_utfs_pins[] = { 51, 52, 53, 54 }; - -static const struct sirfsoc_muxmask usp0_only_urfs_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux usp0_only_urfs_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_only_urfs_muxmask), - .muxmask = usp0_only_urfs_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(2) | BIT(9), - .funcval = 0, -}; - -static const unsigned usp0_only_urfs_pins[] = { 51, 52, 53, 55 }; - -static const struct sirfsoc_muxmask usp0_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(20) | BIT(21), - }, -}; - -static const struct sirfsoc_padmux usp0_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_uart_nostreamctrl_muxmask), - .muxmask = usp0_uart_nostreamctrl_muxmask, -}; - -static const unsigned usp0_uart_nostreamctrl_pins[] = { 52, 53 }; - -static const struct sirfsoc_muxmask usp1_muxmask[] = { - { - .group = 1, - .mask = BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux usp1_padmux = { - .muxmask_counts = ARRAY_SIZE(usp1_muxmask), - .muxmask = usp1_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(1) | BIT(9) | BIT(10) | BIT(11), - .funcval = 0, -}; - -static const unsigned usp1_pins[] = { 56, 57, 58, 59, 60 }; - -static const struct sirfsoc_muxmask usp1_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux usp1_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp1_uart_nostreamctrl_muxmask), - .muxmask = usp1_uart_nostreamctrl_muxmask, -}; - -static const unsigned usp1_uart_nostreamctrl_pins[] = { 57, 58 }; - -static const struct sirfsoc_muxmask usp2_muxmask[] = { - { - .group = 1, - .mask = BIT(29) | BIT(30) | BIT(31), - }, { - .group = 2, - .mask = BIT(0) | BIT(1), - }, -}; - -static const struct sirfsoc_padmux usp2_padmux = { - .muxmask_counts = ARRAY_SIZE(usp2_muxmask), - .muxmask = usp2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(13) | BIT(14), - .funcval = 0, -}; - -static const unsigned usp2_pins[] = { 61, 62, 63, 64, 65 }; - -static const struct sirfsoc_muxmask usp2_uart_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(30) | BIT(31), - }, -}; - -static const struct sirfsoc_padmux usp2_uart_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(usp2_uart_nostreamctrl_muxmask), - .muxmask = usp2_uart_nostreamctrl_muxmask, -}; - -static const unsigned usp2_uart_nostreamctrl_pins[] = { 62, 63 }; - -static const struct sirfsoc_muxmask nand_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3) | BIT(28) | BIT(29) | BIT(30), - }, -}; - -static const struct sirfsoc_padmux nand_padmux = { - .muxmask_counts = ARRAY_SIZE(nand_muxmask), - .muxmask = nand_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5), - .funcval = 0, -}; - -static const unsigned nand_pins[] = { 64, 65, 92, 93, 94 }; - -static const struct sirfsoc_padmux sdmmc0_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5), - .funcval = 0, -}; - -static const unsigned sdmmc0_pins[] = { }; - -static const struct sirfsoc_muxmask sdmmc2_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc2_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask), - .muxmask = sdmmc2_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(5), - .funcval = BIT(5), -}; - -static const unsigned sdmmc2_pins[] = { 66, 67 }; - -static const struct sirfsoc_muxmask cko0_muxmask[] = { - { - .group = 2, - .mask = BIT(14), - }, -}; - -static const struct sirfsoc_padmux cko0_padmux = { - .muxmask_counts = ARRAY_SIZE(cko0_muxmask), - .muxmask = cko0_muxmask, -}; - -static const unsigned cko0_pins[] = { 78 }; - -static const struct sirfsoc_muxmask vip_muxmask[] = { - { - .group = 2, - .mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) - | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | - BIT(25), - }, -}; - -static const struct sirfsoc_padmux vip_padmux = { - .muxmask_counts = ARRAY_SIZE(vip_muxmask), - .muxmask = vip_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(0), - .funcval = 0, -}; - -static const unsigned vip_pins[] = { 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89 }; - -static const struct sirfsoc_muxmask i2c0_muxmask[] = { - { - .group = 2, - .mask = BIT(26) | BIT(27), - }, -}; - -static const struct sirfsoc_padmux i2c0_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c0_muxmask), - .muxmask = i2c0_muxmask, -}; - -static const unsigned i2c0_pins[] = { 90, 91 }; - -static const struct sirfsoc_muxmask i2c1_muxmask[] = { - { - .group = 0, - .mask = BIT(13) | BIT(15), - }, -}; - -static const struct sirfsoc_padmux i2c1_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c1_muxmask), - .muxmask = i2c1_muxmask, -}; - -static const unsigned i2c1_pins[] = { 13, 15 }; - -static const struct sirfsoc_muxmask viprom_muxmask[] = { - { - .group = 2, - .mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) - | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | - BIT(25), - }, { - .group = 0, - .mask = BIT(12), - }, -}; - -static const struct sirfsoc_padmux viprom_padmux = { - .muxmask_counts = ARRAY_SIZE(viprom_muxmask), - .muxmask = viprom_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(0), - .funcval = BIT(0), -}; - -static const unsigned viprom_pins[] = { 12, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89 }; - -static const struct sirfsoc_muxmask pwm0_muxmask[] = { - { - .group = 0, - .mask = BIT(4), - }, -}; - -static const struct sirfsoc_padmux pwm0_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm0_muxmask), - .muxmask = pwm0_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(12), - .funcval = 0, -}; - -static const unsigned pwm0_pins[] = { 4 }; - -static const struct sirfsoc_muxmask pwm1_muxmask[] = { - { - .group = 0, - .mask = BIT(5), - }, -}; - -static const struct sirfsoc_padmux pwm1_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm1_muxmask), - .muxmask = pwm1_muxmask, -}; - -static const unsigned pwm1_pins[] = { 5 }; - -static const struct sirfsoc_muxmask pwm2_muxmask[] = { - { - .group = 0, - .mask = BIT(6), - }, -}; - -static const struct sirfsoc_padmux pwm2_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm2_muxmask), - .muxmask = pwm2_muxmask, -}; - -static const unsigned pwm2_pins[] = { 6 }; - -static const struct sirfsoc_muxmask pwm3_muxmask[] = { - { - .group = 0, - .mask = BIT(7), - }, -}; - -static const struct sirfsoc_padmux pwm3_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm3_muxmask), - .muxmask = pwm3_muxmask, -}; - -static const unsigned pwm3_pins[] = { 7 }; - -static const struct sirfsoc_muxmask warm_rst_muxmask[] = { - { - .group = 0, - .mask = BIT(8), - }, -}; - -static const struct sirfsoc_padmux warm_rst_padmux = { - .muxmask_counts = ARRAY_SIZE(warm_rst_muxmask), - .muxmask = warm_rst_muxmask, -}; - -static const unsigned warm_rst_pins[] = { 8 }; - -static const struct sirfsoc_muxmask usb0_utmi_drvbus_muxmask[] = { - { - .group = 1, - .mask = BIT(22), - }, -}; -static const struct sirfsoc_padmux usb0_utmi_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb0_utmi_drvbus_muxmask), - .muxmask = usb0_utmi_drvbus_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(6), - .funcval = BIT(6), /* refer to PAD_UTMI_DRVVBUS0_ENABLE */ -}; - -static const unsigned usb0_utmi_drvbus_pins[] = { 54 }; - -static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = { - { - .group = 1, - .mask = BIT(27), - }, -}; - -static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask), - .muxmask = usb1_utmi_drvbus_muxmask, - .ctrlreg = SIRFSOC_RSC_PIN_MUX, - .funcmask = BIT(11), - .funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */ -}; - -static const unsigned usb1_utmi_drvbus_pins[] = { 59 }; - -static const struct sirfsoc_padmux usb1_dp_dn_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE, - .funcmask = BIT(2), - .funcval = BIT(2), -}; - -static const unsigned usb1_dp_dn_pins[] = { 115, 116 }; - -static const struct sirfsoc_padmux uart1_route_io_usb1_padmux = { - .muxmask_counts = 0, - .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE, - .funcmask = BIT(2), - .funcval = 0, -}; - -static const unsigned uart1_route_io_usb1_pins[] = { 115, 116 }; - -static const struct sirfsoc_muxmask pulse_count_muxmask[] = { - { - .group = 0, - .mask = BIT(9) | BIT(10) | BIT(11), - }, -}; - -static const struct sirfsoc_padmux pulse_count_padmux = { - .muxmask_counts = ARRAY_SIZE(pulse_count_muxmask), - .muxmask = pulse_count_muxmask, -}; - -static const unsigned pulse_count_pins[] = { 9, 10, 11 }; - -static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = { - SIRFSOC_PIN_GROUP("lcd_16bitsgrp", lcd_16bits_pins), - SIRFSOC_PIN_GROUP("lcd_18bitsgrp", lcd_18bits_pins), - SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins), - SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins), - SIRFSOC_PIN_GROUP("uart0grp", uart0_pins), - SIRFSOC_PIN_GROUP("uart0_nostreamctrlgrp", uart0_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("uart1grp", uart1_pins), - SIRFSOC_PIN_GROUP("uart2grp", uart2_pins), - SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp0grp", usp0_pins), - SIRFSOC_PIN_GROUP("usp0_uart_nostreamctrl_grp", - usp0_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp0_only_utfs_grp", usp0_only_utfs_pins), - SIRFSOC_PIN_GROUP("usp0_only_urfs_grp", usp0_only_urfs_pins), - SIRFSOC_PIN_GROUP("usp1grp", usp1_pins), - SIRFSOC_PIN_GROUP("usp1_uart_nostreamctrl_grp", - usp1_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp2grp", usp2_pins), - SIRFSOC_PIN_GROUP("usp2_uart_nostreamctrl_grp", - usp2_uart_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins), - SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins), - SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins), - SIRFSOC_PIN_GROUP("pwm1grp", pwm1_pins), - SIRFSOC_PIN_GROUP("pwm2grp", pwm2_pins), - SIRFSOC_PIN_GROUP("pwm3grp", pwm3_pins), - SIRFSOC_PIN_GROUP("vipgrp", vip_pins), - SIRFSOC_PIN_GROUP("vipromgrp", viprom_pins), - SIRFSOC_PIN_GROUP("warm_rstgrp", warm_rst_pins), - SIRFSOC_PIN_GROUP("cko0grp", cko0_pins), - SIRFSOC_PIN_GROUP("cko1grp", cko1_pins), - SIRFSOC_PIN_GROUP("sdmmc0grp", sdmmc0_pins), - SIRFSOC_PIN_GROUP("sdmmc1grp", sdmmc1_pins), - SIRFSOC_PIN_GROUP("sdmmc2grp", sdmmc2_pins), - SIRFSOC_PIN_GROUP("sdmmc3grp", sdmmc3_pins), - SIRFSOC_PIN_GROUP("sdmmc4grp", sdmmc4_pins), - SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins), - SIRFSOC_PIN_GROUP("usb0_utmi_drvbusgrp", usb0_utmi_drvbus_pins), - SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins), - SIRFSOC_PIN_GROUP("usb1_dp_dngrp", usb1_dp_dn_pins), - SIRFSOC_PIN_GROUP("uart1_route_io_usb1grp", uart1_route_io_usb1_pins), - SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins), - SIRFSOC_PIN_GROUP("i2smclkgrp", i2s_mclk_pins), - SIRFSOC_PIN_GROUP("i2s_ext_clk_inputgrp", i2s_ext_clk_input_pins), - SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins), - SIRFSOC_PIN_GROUP("i2s_no_dingrp", i2s_no_din_pins), - SIRFSOC_PIN_GROUP("i2s_6chngrp", i2s_6chn_pins), - SIRFSOC_PIN_GROUP("ac97grp", ac97_pins), - SIRFSOC_PIN_GROUP("nandgrp", nand_pins), - SIRFSOC_PIN_GROUP("spi0grp", spi0_pins), - SIRFSOC_PIN_GROUP("spi1grp", spi1_pins), - SIRFSOC_PIN_GROUP("gpsgrp", gps_pins), -}; - -static const char * const lcd_16bitsgrp[] = { "lcd_16bitsgrp" }; -static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" }; -static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" }; -static const char * const lcdromgrp[] = { "lcdromgrp" }; -static const char * const uart0grp[] = { "uart0grp" }; -static const char * const uart0_nostreamctrlgrp[] = { "uart0_nostreamctrlgrp" }; -static const char * const uart1grp[] = { "uart1grp" }; -static const char * const uart2grp[] = { "uart2grp" }; -static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" }; -static const char * const usp0grp[] = { "usp0grp" }; -static const char * const usp0_uart_nostreamctrl_grp[] = { - "usp0_uart_nostreamctrl_grp" -}; -static const char * const usp0_only_utfs_grp[] = { "usp0_only_utfs_grp" }; -static const char * const usp0_only_urfs_grp[] = { "usp0_only_urfs_grp" }; -static const char * const usp1grp[] = { "usp1grp" }; -static const char * const usp1_uart_nostreamctrl_grp[] = { - "usp1_uart_nostreamctrl_grp" -}; -static const char * const usp2grp[] = { "usp2grp" }; -static const char * const usp2_uart_nostreamctrl_grp[] = { - "usp2_uart_nostreamctrl_grp" -}; -static const char * const i2c0grp[] = { "i2c0grp" }; -static const char * const i2c1grp[] = { "i2c1grp" }; -static const char * const pwm0grp[] = { "pwm0grp" }; -static const char * const pwm1grp[] = { "pwm1grp" }; -static const char * const pwm2grp[] = { "pwm2grp" }; -static const char * const pwm3grp[] = { "pwm3grp" }; -static const char * const vipgrp[] = { "vipgrp" }; -static const char * const vipromgrp[] = { "vipromgrp" }; -static const char * const warm_rstgrp[] = { "warm_rstgrp" }; -static const char * const cko0grp[] = { "cko0grp" }; -static const char * const cko1grp[] = { "cko1grp" }; -static const char * const sdmmc0grp[] = { "sdmmc0grp" }; -static const char * const sdmmc1grp[] = { "sdmmc1grp" }; -static const char * const sdmmc2grp[] = { "sdmmc2grp" }; -static const char * const sdmmc3grp[] = { "sdmmc3grp" }; -static const char * const sdmmc4grp[] = { "sdmmc4grp" }; -static const char * const sdmmc5grp[] = { "sdmmc5grp" }; -static const char * const usb0_utmi_drvbusgrp[] = { "usb0_utmi_drvbusgrp" }; -static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" }; -static const char * const usb1_dp_dngrp[] = { "usb1_dp_dngrp" }; -static const char * const - uart1_route_io_usb1grp[] = { "uart1_route_io_usb1grp" }; -static const char * const pulse_countgrp[] = { "pulse_countgrp" }; -static const char * const i2smclkgrp[] = { "i2smclkgrp" }; -static const char * const i2s_ext_clk_inputgrp[] = { "i2s_ext_clk_inputgrp" }; -static const char * const i2sgrp[] = { "i2sgrp" }; -static const char * const i2s_no_dingrp[] = { "i2s_no_dingrp" }; -static const char * const i2s_6chngrp[] = { "i2s_6chngrp" }; -static const char * const ac97grp[] = { "ac97grp" }; -static const char * const nandgrp[] = { "nandgrp" }; -static const char * const spi0grp[] = { "spi0grp" }; -static const char * const spi1grp[] = { "spi1grp" }; -static const char * const gpsgrp[] = { "gpsgrp" }; - -static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = { - SIRFSOC_PMX_FUNCTION("lcd_16bits", lcd_16bitsgrp, lcd_16bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_18bits", lcd_18bitsgrp, lcd_18bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux), - SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux), - SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux), - SIRFSOC_PMX_FUNCTION("uart0_nostreamctrl", - uart0_nostreamctrlgrp, uart0_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux), - SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux), - SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", - uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux), - SIRFSOC_PMX_FUNCTION("usp0_uart_nostreamctrl", - usp0_uart_nostreamctrl_grp, usp0_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp0_only_utfs", - usp0_only_utfs_grp, usp0_only_utfs_padmux), - SIRFSOC_PMX_FUNCTION("usp0_only_urfs", - usp0_only_urfs_grp, usp0_only_urfs_padmux), - SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux), - SIRFSOC_PMX_FUNCTION("usp1_uart_nostreamctrl", - usp1_uart_nostreamctrl_grp, usp1_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp2", usp2grp, usp2_padmux), - SIRFSOC_PMX_FUNCTION("usp2_uart_nostreamctrl", - usp2_uart_nostreamctrl_grp, usp2_uart_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux), - SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux), - SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux), - SIRFSOC_PMX_FUNCTION("pwm1", pwm1grp, pwm1_padmux), - SIRFSOC_PMX_FUNCTION("pwm2", pwm2grp, pwm2_padmux), - SIRFSOC_PMX_FUNCTION("pwm3", pwm3grp, pwm3_padmux), - SIRFSOC_PMX_FUNCTION("vip", vipgrp, vip_padmux), - SIRFSOC_PMX_FUNCTION("viprom", vipromgrp, viprom_padmux), - SIRFSOC_PMX_FUNCTION("warm_rst", warm_rstgrp, warm_rst_padmux), - SIRFSOC_PMX_FUNCTION("cko0", cko0grp, cko0_padmux), - SIRFSOC_PMX_FUNCTION("cko1", cko1grp, cko1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc0", sdmmc0grp, sdmmc0_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc1", sdmmc1grp, sdmmc1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc2", sdmmc2grp, sdmmc2_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc3", sdmmc3grp, sdmmc3_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc4", sdmmc4grp, sdmmc4_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux), - SIRFSOC_PMX_FUNCTION("usb0_utmi_drvbus", - usb0_utmi_drvbusgrp, usb0_utmi_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", - usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("usb1_dp_dn", usb1_dp_dngrp, usb1_dp_dn_padmux), - SIRFSOC_PMX_FUNCTION("uart1_route_io_usb1", - uart1_route_io_usb1grp, uart1_route_io_usb1_padmux), - SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux), - SIRFSOC_PMX_FUNCTION("i2s_mclk", i2smclkgrp, i2s_mclk_padmux), - SIRFSOC_PMX_FUNCTION("i2s_ext_clk_input", i2s_ext_clk_inputgrp, - i2s_ext_clk_input_padmux), - SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux), - SIRFSOC_PMX_FUNCTION("i2s_no_din", i2s_no_dingrp, i2s_no_din_padmux), - SIRFSOC_PMX_FUNCTION("i2s_6chn", i2s_6chngrp, i2s_6chn_padmux), - SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux), - SIRFSOC_PMX_FUNCTION("nand", nandgrp, nand_padmux), - SIRFSOC_PMX_FUNCTION("spi0", spi0grp, spi0_padmux), - SIRFSOC_PMX_FUNCTION("spi1", spi1grp, spi1_padmux), - SIRFSOC_PMX_FUNCTION("gps", gpsgrp, gps_padmux), -}; - -struct sirfsoc_pinctrl_data prima2_pinctrl_data = { - (struct pinctrl_pin_desc *)sirfsoc_pads, - ARRAY_SIZE(sirfsoc_pads), - (struct sirfsoc_pin_group *)sirfsoc_pin_groups, - ARRAY_SIZE(sirfsoc_pin_groups), - (struct sirfsoc_pmx_func *)sirfsoc_pmx_functions, - ARRAY_SIZE(sirfsoc_pmx_functions), -}; - diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c deleted file mode 100644 index 63a287d5795f..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ /dev/null @@ -1,894 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pinmux driver for CSR SiRFprimaII - * - * Authors: - * Rongjun Ying - * Yuping Luo - * Barry Song - * - * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group - * company. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-sirf.h" - -#define DRIVER_NAME "pinmux-sirf" - -struct sirfsoc_gpio_bank { - int id; - int parent_irq; - spinlock_t lock; -}; - -struct sirfsoc_gpio_chip { - struct of_mm_gpio_chip chip; - struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; - spinlock_t lock; -}; - -static struct sirfsoc_pin_group *sirfsoc_pin_groups; -static int sirfsoc_pingrp_cnt; - -static int sirfsoc_get_groups_count(struct pinctrl_dev *pctldev) -{ - return sirfsoc_pingrp_cnt; -} - -static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - return sirfsoc_pin_groups[selector].name; -} - -static int sirfsoc_get_group_pins(struct pinctrl_dev *pctldev, - unsigned selector, - const unsigned **pins, - unsigned *num_pins) -{ - *pins = sirfsoc_pin_groups[selector].pins; - *num_pins = sirfsoc_pin_groups[selector].num_pins; - return 0; -} - -static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned offset) -{ - seq_printf(s, " " DRIVER_NAME); -} - -static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, unsigned *num_maps) -{ - struct sirfsoc_pmx *spmx = pinctrl_dev_get_drvdata(pctldev); - struct device_node *np; - struct property *prop; - const char *function, *group; - int ret, index = 0, count = 0; - - /* calculate number of maps required */ - for_each_child_of_node(np_config, np) { - ret = of_property_read_string(np, "sirf,function", &function); - if (ret < 0) { - of_node_put(np); - return ret; - } - - ret = of_property_count_strings(np, "sirf,pins"); - if (ret < 0) { - of_node_put(np); - return ret; - } - - count += ret; - } - - if (!count) { - dev_err(spmx->dev, "No child nodes passed via DT\n"); - return -ENODEV; - } - - *map = kcalloc(count, sizeof(**map), GFP_KERNEL); - if (!*map) - return -ENOMEM; - - for_each_child_of_node(np_config, np) { - of_property_read_string(np, "sirf,function", &function); - of_property_for_each_string(np, "sirf,pins", prop, group) { - (*map)[index].type = PIN_MAP_TYPE_MUX_GROUP; - (*map)[index].data.mux.group = group; - (*map)[index].data.mux.function = function; - index++; - } - } - - *num_maps = count; - - return 0; -} - -static void sirfsoc_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ - kfree(map); -} - -static const struct pinctrl_ops sirfsoc_pctrl_ops = { - .get_groups_count = sirfsoc_get_groups_count, - .get_group_name = sirfsoc_get_group_name, - .get_group_pins = sirfsoc_get_group_pins, - .pin_dbg_show = sirfsoc_pin_dbg_show, - .dt_node_to_map = sirfsoc_dt_node_to_map, - .dt_free_map = sirfsoc_dt_free_map, -}; - -static struct sirfsoc_pmx_func *sirfsoc_pmx_functions; -static int sirfsoc_pmxfunc_cnt; - -static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, - unsigned selector, bool enable) -{ - int i; - const struct sirfsoc_padmux *mux = - sirfsoc_pmx_functions[selector].padmux; - const struct sirfsoc_muxmask *mask = mux->muxmask; - - for (i = 0; i < mux->muxmask_counts; i++) { - u32 muxval; - muxval = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(mask[i].group)); - if (enable) - muxval = muxval & ~mask[i].mask; - else - muxval = muxval | mask[i].mask; - writel(muxval, spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(mask[i].group)); - } - - if (mux->funcmask && enable) { - u32 func_en_val; - - func_en_val = - readl(spmx->rsc_virtbase + mux->ctrlreg); - func_en_val = - (func_en_val & ~mux->funcmask) | (mux->funcval); - writel(func_en_val, spmx->rsc_virtbase + mux->ctrlreg); - } -} - -static int sirfsoc_pinmux_set_mux(struct pinctrl_dev *pmxdev, - unsigned selector, - unsigned group) -{ - struct sirfsoc_pmx *spmx; - - spmx = pinctrl_dev_get_drvdata(pmxdev); - sirfsoc_pinmux_endisable(spmx, selector, true); - - return 0; -} - -static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev) -{ - return sirfsoc_pmxfunc_cnt; -} - -static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - return sirfsoc_pmx_functions[selector].name; -} - -static int sirfsoc_pinmux_get_groups(struct pinctrl_dev *pctldev, - unsigned selector, - const char * const **groups, - unsigned * const num_groups) -{ - *groups = sirfsoc_pmx_functions[selector].groups; - *num_groups = sirfsoc_pmx_functions[selector].num_groups; - return 0; -} - -static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, - struct pinctrl_gpio_range *range, unsigned offset) -{ - struct sirfsoc_pmx *spmx; - - int group = range->id; - - u32 muxval; - - spmx = pinctrl_dev_get_drvdata(pmxdev); - - muxval = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(group)); - muxval = muxval | (1 << (offset - range->pin_base)); - writel(muxval, spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(group)); - - return 0; -} - -static const struct pinmux_ops sirfsoc_pinmux_ops = { - .set_mux = sirfsoc_pinmux_set_mux, - .get_functions_count = sirfsoc_pinmux_get_funcs_count, - .get_function_name = sirfsoc_pinmux_get_func_name, - .get_function_groups = sirfsoc_pinmux_get_groups, - .gpio_request_enable = sirfsoc_pinmux_request_gpio, -}; - -static struct pinctrl_desc sirfsoc_pinmux_desc = { - .name = DRIVER_NAME, - .pctlops = &sirfsoc_pctrl_ops, - .pmxops = &sirfsoc_pinmux_ops, - .owner = THIS_MODULE, -}; - -static void __iomem *sirfsoc_rsc_of_iomap(void) -{ - const struct of_device_id rsc_ids[] = { - { .compatible = "sirf,prima2-rsc" }, - {} - }; - struct device_node *np; - - np = of_find_matching_node(NULL, rsc_ids); - if (!np) - panic("unable to find compatible rsc node in dtb\n"); - - return of_iomap(np, 0); -} - -static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc, - const struct of_phandle_args *gpiospec, - u32 *flags) -{ - if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE) - return -EINVAL; - - if (flags) - *flags = gpiospec->args[1]; - - return gpiospec->args[0]; -} - -static const struct of_device_id pinmux_ids[] = { - { .compatible = "sirf,prima2-pinctrl", .data = &prima2_pinctrl_data, }, - { .compatible = "sirf,atlas6-pinctrl", .data = &atlas6_pinctrl_data, }, - {} -}; - -static int sirfsoc_pinmux_probe(struct platform_device *pdev) -{ - int ret; - struct sirfsoc_pmx *spmx; - struct device_node *np = pdev->dev.of_node; - const struct sirfsoc_pinctrl_data *pdata; - - /* Create state holders etc for this driver */ - spmx = devm_kzalloc(&pdev->dev, sizeof(*spmx), GFP_KERNEL); - if (!spmx) - return -ENOMEM; - - spmx->dev = &pdev->dev; - - platform_set_drvdata(pdev, spmx); - - spmx->gpio_virtbase = of_iomap(np, 0); - if (!spmx->gpio_virtbase) { - dev_err(&pdev->dev, "can't map gpio registers\n"); - return -ENOMEM; - } - - spmx->rsc_virtbase = sirfsoc_rsc_of_iomap(); - if (!spmx->rsc_virtbase) { - ret = -ENOMEM; - dev_err(&pdev->dev, "can't map rsc registers\n"); - goto out_no_rsc_remap; - } - - pdata = of_match_node(pinmux_ids, np)->data; - sirfsoc_pin_groups = pdata->grps; - sirfsoc_pingrp_cnt = pdata->grps_cnt; - sirfsoc_pmx_functions = pdata->funcs; - sirfsoc_pmxfunc_cnt = pdata->funcs_cnt; - sirfsoc_pinmux_desc.pins = pdata->pads; - sirfsoc_pinmux_desc.npins = pdata->pads_cnt; - - - /* Now register the pin controller and all pins it handles */ - spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); - if (IS_ERR(spmx->pmx)) { - dev_err(&pdev->dev, "could not register SIRFSOC pinmux driver\n"); - ret = PTR_ERR(spmx->pmx); - goto out_no_pmx; - } - - dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n"); - - return 0; - -out_no_pmx: - iounmap(spmx->rsc_virtbase); -out_no_rsc_remap: - iounmap(spmx->gpio_virtbase); - return ret; -} - -#ifdef CONFIG_PM_SLEEP -static int sirfsoc_pinmux_suspend_noirq(struct device *dev) -{ - int i, j; - struct sirfsoc_pmx *spmx = dev_get_drvdata(dev); - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for (j = 0; j < SIRFSOC_GPIO_BANK_SIZE; j++) { - spmx->gpio_regs[i][j] = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_CTRL(i, j)); - } - spmx->ints_regs[i] = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_INT_STATUS(i)); - spmx->paden_regs[i] = readl(spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(i)); - } - spmx->dspen_regs = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_DSP_EN0); - - for (i = 0; i < 3; i++) - spmx->rsc_regs[i] = readl(spmx->rsc_virtbase + 4 * i); - - return 0; -} - -static int sirfsoc_pinmux_resume_noirq(struct device *dev) -{ - int i, j; - struct sirfsoc_pmx *spmx = dev_get_drvdata(dev); - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for (j = 0; j < SIRFSOC_GPIO_BANK_SIZE; j++) { - writel(spmx->gpio_regs[i][j], spmx->gpio_virtbase + - SIRFSOC_GPIO_CTRL(i, j)); - } - writel(spmx->ints_regs[i], spmx->gpio_virtbase + - SIRFSOC_GPIO_INT_STATUS(i)); - writel(spmx->paden_regs[i], spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(i)); - } - writel(spmx->dspen_regs, spmx->gpio_virtbase + SIRFSOC_GPIO_DSP_EN0); - - for (i = 0; i < 3; i++) - writel(spmx->rsc_regs[i], spmx->rsc_virtbase + 4 * i); - - return 0; -} - -static const struct dev_pm_ops sirfsoc_pinmux_pm_ops = { - .suspend_noirq = sirfsoc_pinmux_suspend_noirq, - .resume_noirq = sirfsoc_pinmux_resume_noirq, - .freeze_noirq = sirfsoc_pinmux_suspend_noirq, - .restore_noirq = sirfsoc_pinmux_resume_noirq, -}; -#endif - -static struct platform_driver sirfsoc_pinmux_driver = { - .driver = { - .name = DRIVER_NAME, - .of_match_table = pinmux_ids, -#ifdef CONFIG_PM_SLEEP - .pm = &sirfsoc_pinmux_pm_ops, -#endif - }, - .probe = sirfsoc_pinmux_probe, -}; - -static int __init sirfsoc_pinmux_init(void) -{ - return platform_driver_register(&sirfsoc_pinmux_driver); -} -arch_initcall(sirfsoc_pinmux_init); - -static inline struct sirfsoc_gpio_bank * -sirfsoc_gpio_to_bank(struct sirfsoc_gpio_chip *sgpio, unsigned int offset) -{ - return &sgpio->sgpio_bank[offset / SIRFSOC_GPIO_BANK_SIZE]; -} - -static inline int sirfsoc_gpio_to_bankoff(unsigned int offset) -{ - return offset % SIRFSOC_GPIO_BANK_SIZE; -} - -static void sirfsoc_gpio_irq_ack(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); - int idx = sirfsoc_gpio_to_bankoff(d->hwirq); - u32 val, offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - val = readl(sgpio->chip.regs + offset); - - writel(val, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&sgpio->lock, flags); -} - -static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_chip *sgpio, - struct sirfsoc_gpio_bank *bank, - int idx) -{ - u32 val, offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - val = readl(sgpio->chip.regs + offset); - val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; - val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; - writel(val, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&sgpio->lock, flags); -} - -static void sirfsoc_gpio_irq_mask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); - - __sirfsoc_gpio_irq_mask(sgpio, bank, d->hwirq % SIRFSOC_GPIO_BANK_SIZE); -} - -static void sirfsoc_gpio_irq_unmask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); - int idx = sirfsoc_gpio_to_bankoff(d->hwirq); - u32 val, offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - val = readl(sgpio->chip.regs + offset); - val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; - val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK; - writel(val, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&sgpio->lock, flags); -} - -static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq); - int idx = sirfsoc_gpio_to_bankoff(d->hwirq); - u32 val, offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - val = readl(sgpio->chip.regs + offset); - val &= ~(SIRFSOC_GPIO_CTL_INTR_STS_MASK | SIRFSOC_GPIO_CTL_OUT_EN_MASK); - - switch (type) { - case IRQ_TYPE_NONE: - break; - case IRQ_TYPE_EDGE_RISING: - val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK; - val &= ~SIRFSOC_GPIO_CTL_INTR_LOW_MASK; - break; - case IRQ_TYPE_EDGE_FALLING: - val &= ~SIRFSOC_GPIO_CTL_INTR_HIGH_MASK; - val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK; - break; - case IRQ_TYPE_EDGE_BOTH: - val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | - SIRFSOC_GPIO_CTL_INTR_LOW_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK; - break; - case IRQ_TYPE_LEVEL_LOW: - val &= ~(SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK); - val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK; - break; - case IRQ_TYPE_LEVEL_HIGH: - val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK; - val &= ~(SIRFSOC_GPIO_CTL_INTR_LOW_MASK | - SIRFSOC_GPIO_CTL_INTR_TYPE_MASK); - break; - } - - writel(val, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&sgpio->lock, flags); - - return 0; -} - -static struct irq_chip sirfsoc_irq_chip = { - .name = "sirf-gpio-irq", - .irq_ack = sirfsoc_gpio_irq_ack, - .irq_mask = sirfsoc_gpio_irq_mask, - .irq_unmask = sirfsoc_gpio_irq_unmask, - .irq_set_type = sirfsoc_gpio_irq_type, -}; - -static void sirfsoc_gpio_handle_irq(struct irq_desc *desc) -{ - unsigned int irq = irq_desc_get_irq(desc); - struct gpio_chip *gc = irq_desc_get_handler_data(desc); - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(gc); - struct sirfsoc_gpio_bank *bank; - u32 status, ctrl; - int idx = 0; - struct irq_chip *chip = irq_desc_get_chip(desc); - int i; - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - bank = &sgpio->sgpio_bank[i]; - if (bank->parent_irq == irq) - break; - } - BUG_ON(i == SIRFSOC_GPIO_NO_OF_BANKS); - - chained_irq_enter(chip, desc); - - status = readl(sgpio->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id)); - if (!status) { - printk(KERN_WARNING - "%s: gpio id %d status %#x no interrupt is flagged\n", - __func__, bank->id, status); - handle_bad_irq(desc); - return; - } - - while (status) { - ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, idx)); - - /* - * Here we must check whether the corresponding GPIO's interrupt - * has been enabled, otherwise just skip it - */ - if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) { - pr_debug("%s: gpio id %d idx %d happens\n", - __func__, bank->id, idx); - generic_handle_irq(irq_find_mapping(gc->irq.domain, idx + - bank->id * SIRFSOC_GPIO_BANK_SIZE)); - } - - idx++; - status = status >> 1; - } - - chained_irq_exit(chip, desc); -} - -static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_chip *sgpio, - unsigned ctrl_offset) -{ - u32 val; - - val = readl(sgpio->chip.regs + ctrl_offset); - val &= ~SIRFSOC_GPIO_CTL_OUT_EN_MASK; - writel(val, sgpio->chip.regs + ctrl_offset); -} - -static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); - unsigned long flags; - - if (pinctrl_gpio_request(chip->base + offset)) - return -ENODEV; - - spin_lock_irqsave(&bank->lock, flags); - - /* - * default status: - * set direction as input and mask irq - */ - sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset)); - __sirfsoc_gpio_irq_mask(sgpio, bank, offset); - - spin_unlock_irqrestore(&bank->lock, flags); - - return 0; -} - -static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); - unsigned long flags; - - spin_lock_irqsave(&bank->lock, flags); - - __sirfsoc_gpio_irq_mask(sgpio, bank, offset); - sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset)); - - spin_unlock_irqrestore(&bank->lock, flags); - - pinctrl_gpio_free(chip->base + offset); -} - -static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio); - int idx = sirfsoc_gpio_to_bankoff(gpio); - unsigned long flags; - unsigned offset; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&bank->lock, flags); - - sirfsoc_gpio_set_input(sgpio, offset); - - spin_unlock_irqrestore(&bank->lock, flags); - - return 0; -} - -static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_chip *sgpio, - struct sirfsoc_gpio_bank *bank, - unsigned offset, - int value) -{ - u32 out_ctrl; - unsigned long flags; - - spin_lock_irqsave(&bank->lock, flags); - - out_ctrl = readl(sgpio->chip.regs + offset); - if (value) - out_ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; - else - out_ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK; - - out_ctrl &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; - out_ctrl |= SIRFSOC_GPIO_CTL_OUT_EN_MASK; - writel(out_ctrl, sgpio->chip.regs + offset); - - spin_unlock_irqrestore(&bank->lock, flags); -} - -static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, - unsigned gpio, int value) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio); - int idx = sirfsoc_gpio_to_bankoff(gpio); - u32 offset; - unsigned long flags; - - offset = SIRFSOC_GPIO_CTRL(bank->id, idx); - - spin_lock_irqsave(&sgpio->lock, flags); - - sirfsoc_gpio_set_output(sgpio, bank, offset, value); - - spin_unlock_irqrestore(&sgpio->lock, flags); - - return 0; -} - -static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); - u32 val; - unsigned long flags; - - spin_lock_irqsave(&bank->lock, flags); - - val = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); - - spin_unlock_irqrestore(&bank->lock, flags); - - return !!(val & SIRFSOC_GPIO_CTL_DATAIN_MASK); -} - -static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct sirfsoc_gpio_chip *sgpio = gpiochip_get_data(chip); - struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset); - u32 ctrl; - unsigned long flags; - - spin_lock_irqsave(&bank->lock, flags); - - ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); - if (value) - ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK; - else - ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK; - writel(ctrl, sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset)); - - spin_unlock_irqrestore(&bank->lock, flags); -} - -static void sirfsoc_gpio_set_pullup(struct sirfsoc_gpio_chip *sgpio, - const u32 *pullups) -{ - int i, n; - const unsigned long *p = (const unsigned long *)pullups; - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for_each_set_bit(n, p + i, BITS_PER_LONG) { - u32 offset = SIRFSOC_GPIO_CTRL(i, n); - u32 val = readl(sgpio->chip.regs + offset); - val |= SIRFSOC_GPIO_CTL_PULL_MASK; - val |= SIRFSOC_GPIO_CTL_PULL_HIGH; - writel(val, sgpio->chip.regs + offset); - } - } -} - -static void sirfsoc_gpio_set_pulldown(struct sirfsoc_gpio_chip *sgpio, - const u32 *pulldowns) -{ - int i, n; - const unsigned long *p = (const unsigned long *)pulldowns; - - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - for_each_set_bit(n, p + i, BITS_PER_LONG) { - u32 offset = SIRFSOC_GPIO_CTRL(i, n); - u32 val = readl(sgpio->chip.regs + offset); - val |= SIRFSOC_GPIO_CTL_PULL_MASK; - val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH; - writel(val, sgpio->chip.regs + offset); - } - } -} - -static int sirfsoc_gpio_probe(struct device_node *np) -{ - int i, err = 0; - struct sirfsoc_gpio_chip *sgpio; - struct sirfsoc_gpio_bank *bank; - void __iomem *regs; - struct platform_device *pdev; - struct gpio_irq_chip *girq; - - u32 pullups[SIRFSOC_GPIO_NO_OF_BANKS], pulldowns[SIRFSOC_GPIO_NO_OF_BANKS]; - - pdev = of_find_device_by_node(np); - if (!pdev) - return -ENODEV; - - sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL); - if (!sgpio) { - err = -ENOMEM; - goto out_put_device; - } - spin_lock_init(&sgpio->lock); - - regs = of_iomap(np, 0); - if (!regs) { - err = -ENOMEM; - goto out_put_device; - } - - sgpio->chip.gc.request = sirfsoc_gpio_request; - sgpio->chip.gc.free = sirfsoc_gpio_free; - sgpio->chip.gc.direction_input = sirfsoc_gpio_direction_input; - sgpio->chip.gc.get = sirfsoc_gpio_get_value; - sgpio->chip.gc.direction_output = sirfsoc_gpio_direction_output; - sgpio->chip.gc.set = sirfsoc_gpio_set_value; - sgpio->chip.gc.base = 0; - sgpio->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS; - sgpio->chip.gc.label = kasprintf(GFP_KERNEL, "%pOF", np); - sgpio->chip.gc.of_node = np; - sgpio->chip.gc.of_xlate = sirfsoc_gpio_of_xlate; - sgpio->chip.gc.of_gpio_n_cells = 2; - sgpio->chip.gc.parent = &pdev->dev; - sgpio->chip.regs = regs; - - girq = &sgpio->chip.gc.irq; - girq->chip = &sirfsoc_irq_chip; - girq->parent_handler = sirfsoc_gpio_handle_irq; - girq->num_parents = SIRFSOC_GPIO_NO_OF_BANKS; - girq->parents = devm_kcalloc(&pdev->dev, SIRFSOC_GPIO_NO_OF_BANKS, - sizeof(*girq->parents), - GFP_KERNEL); - if (!girq->parents) { - err = -ENOMEM; - goto out_put_device; - } - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { - bank = &sgpio->sgpio_bank[i]; - spin_lock_init(&bank->lock); - bank->parent_irq = platform_get_irq(pdev, i); - if (bank->parent_irq < 0) { - err = bank->parent_irq; - goto out; - } - girq->parents[i] = bank->parent_irq; - } - girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_level_irq; - - err = gpiochip_add_data(&sgpio->chip.gc, sgpio); - if (err) { - dev_err(&pdev->dev, "%pOF: error in probe function with status %d\n", - np, err); - goto out; - } - - err = gpiochip_add_pin_range(&sgpio->chip.gc, dev_name(&pdev->dev), - 0, 0, SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS); - if (err) { - dev_err(&pdev->dev, - "could not add gpiochip pin range\n"); - goto out_no_range; - } - - if (!of_property_read_u32_array(np, "sirf,pullups", pullups, - SIRFSOC_GPIO_NO_OF_BANKS)) - sirfsoc_gpio_set_pullup(sgpio, pullups); - - if (!of_property_read_u32_array(np, "sirf,pulldowns", pulldowns, - SIRFSOC_GPIO_NO_OF_BANKS)) - sirfsoc_gpio_set_pulldown(sgpio, pulldowns); - - return 0; - -out_no_range: - gpiochip_remove(&sgpio->chip.gc); -out: - iounmap(regs); -out_put_device: - put_device(&pdev->dev); - return err; -} - -static int __init sirfsoc_gpio_init(void) -{ - - struct device_node *np; - - np = of_find_matching_node(NULL, pinmux_ids); - - if (!np) - return -ENODEV; - - return sirfsoc_gpio_probe(np); -} -subsys_initcall(sirfsoc_gpio_init); diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.h b/drivers/pinctrl/sirf/pinctrl-sirf.h deleted file mode 100644 index d7125b8773cc..000000000000 --- a/drivers/pinctrl/sirf/pinctrl-sirf.h +++ /dev/null @@ -1,116 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * pinmux driver shared headfile for CSR SiRFsoc - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#ifndef __PINMUX_SIRF_H__ -#define __PINMUX_SIRF_H__ - -#define SIRFSOC_NUM_PADS 622 -#define SIRFSOC_RSC_USB_UART_SHARE 0 -#define SIRFSOC_RSC_PIN_MUX 0x4 - -#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) -#define SIRFSOC_GPIO_PAD_EN_CLR(g) ((g)*0x100 + 0x90) -#define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4) -#define SIRFSOC_GPIO_DSP_EN0 (0x80) -#define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C) - -#define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1 -#define SIRFSOC_GPIO_CTL_INTR_HIGH_MASK 0x2 -#define SIRFSOC_GPIO_CTL_INTR_TYPE_MASK 0x4 -#define SIRFSOC_GPIO_CTL_INTR_EN_MASK 0x8 -#define SIRFSOC_GPIO_CTL_INTR_STS_MASK 0x10 -#define SIRFSOC_GPIO_CTL_OUT_EN_MASK 0x20 -#define SIRFSOC_GPIO_CTL_DATAOUT_MASK 0x40 -#define SIRFSOC_GPIO_CTL_DATAIN_MASK 0x80 -#define SIRFSOC_GPIO_CTL_PULL_MASK 0x100 -#define SIRFSOC_GPIO_CTL_PULL_HIGH 0x200 -#define SIRFSOC_GPIO_CTL_DSP_INT 0x400 - -#define SIRFSOC_GPIO_NO_OF_BANKS 5 -#define SIRFSOC_GPIO_BANK_SIZE 32 -#define SIRFSOC_GPIO_NUM(bank, index) (((bank)*(32)) + (index)) - -/** - * @dev: a pointer back to containing device - * @virtbase: the offset to the controller in virtual memory - */ -struct sirfsoc_pmx { - struct device *dev; - struct pinctrl_dev *pmx; - void __iomem *gpio_virtbase; - void __iomem *rsc_virtbase; - u32 gpio_regs[SIRFSOC_GPIO_NO_OF_BANKS][SIRFSOC_GPIO_BANK_SIZE]; - u32 ints_regs[SIRFSOC_GPIO_NO_OF_BANKS]; - u32 paden_regs[SIRFSOC_GPIO_NO_OF_BANKS]; - u32 dspen_regs; - u32 rsc_regs[3]; -}; - -/* SIRFSOC_GPIO_PAD_EN set */ -struct sirfsoc_muxmask { - unsigned long group; - unsigned long mask; -}; - -struct sirfsoc_padmux { - unsigned long muxmask_counts; - const struct sirfsoc_muxmask *muxmask; - /* RSC_PIN_MUX set */ - unsigned long ctrlreg; - unsigned long funcmask; - unsigned long funcval; -}; - - /** - * struct sirfsoc_pin_group - describes a SiRFprimaII pin group - * @name: the name of this specific pin group - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @num_pins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array - */ -struct sirfsoc_pin_group { - const char *name; - const unsigned int *pins; - const unsigned num_pins; -}; - -#define SIRFSOC_PIN_GROUP(n, p) \ - { \ - .name = n, \ - .pins = p, \ - .num_pins = ARRAY_SIZE(p), \ - } - -struct sirfsoc_pmx_func { - const char *name; - const char * const *groups; - const unsigned num_groups; - const struct sirfsoc_padmux *padmux; -}; - -#define SIRFSOC_PMX_FUNCTION(n, g, m) \ - { \ - .name = n, \ - .groups = g, \ - .num_groups = ARRAY_SIZE(g), \ - .padmux = &m, \ - } - -struct sirfsoc_pinctrl_data { - struct pinctrl_pin_desc *pads; - int pads_cnt; - struct sirfsoc_pin_group *grps; - int grps_cnt; - struct sirfsoc_pmx_func *funcs; - int funcs_cnt; -}; - -extern struct sirfsoc_pinctrl_data prima2_pinctrl_data; -extern struct sirfsoc_pinctrl_data atlas6_pinctrl_data; - -#endif diff --git a/drivers/pinctrl/sprd/pinctrl-sprd.c b/drivers/pinctrl/sprd/pinctrl-sprd.c index 08dc1931b358..dca7a505d413 100644 --- a/drivers/pinctrl/sprd/pinctrl-sprd.c +++ b/drivers/pinctrl/sprd/pinctrl-sprd.c @@ -687,7 +687,7 @@ static int sprd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin_id, shift = INPUT_SCHMITT_SHIFT; break; case PIN_CONFIG_BIAS_PULL_UP: - if (is_sleep_config == true) { + if (is_sleep_config) { val |= SLEEP_PULL_UP; mask = SLEEP_PULL_UP_MASK; shift = SLEEP_PULL_UP_SHIFT; diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index 593293584ecc..33751a6a0757 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig @@ -119,4 +119,14 @@ config PINCTRL_SUN50I_H6_R default ARM64 && ARCH_SUNXI select PINCTRL_SUNXI +config PINCTRL_SUN50I_H616 + bool "Support for the Allwinner H616 PIO" + default ARM64 && ARCH_SUNXI + select PINCTRL_SUNXI + +config PINCTRL_SUN50I_H616_R + bool "Support for the Allwinner H616 R-PIO" + default ARM64 && ARCH_SUNXI + select PINCTRL_SUNXI + endif diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile index 8b7ff0dc3bdf..d3440c42b9d6 100644 --- a/drivers/pinctrl/sunxi/Makefile +++ b/drivers/pinctrl/sunxi/Makefile @@ -23,5 +23,7 @@ obj-$(CONFIG_PINCTRL_SUN8I_V3S) += pinctrl-sun8i-v3s.o obj-$(CONFIG_PINCTRL_SUN50I_H5) += pinctrl-sun50i-h5.o obj-$(CONFIG_PINCTRL_SUN50I_H6) += pinctrl-sun50i-h6.o obj-$(CONFIG_PINCTRL_SUN50I_H6_R) += pinctrl-sun50i-h6-r.o +obj-$(CONFIG_PINCTRL_SUN50I_H616) += pinctrl-sun50i-h616.o +obj-$(CONFIG_PINCTRL_SUN50I_H616_R) += pinctrl-sun50i-h616-r.o obj-$(CONFIG_PINCTRL_SUN9I_A80) += pinctrl-sun9i-a80.o obj-$(CONFIG_PINCTRL_SUN9I_A80_R) += pinctrl-sun9i-a80-r.o diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-h6-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-h6-r.c index 4557e18d5989..c7d90c44e87a 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun50i-h6-r.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-h6-r.c @@ -24,11 +24,13 @@ static const struct sunxi_desc_pin sun50i_h6_r_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */ SUNXI_FUNCTION(0x3, "s_i2c"), /* SCK */ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PL_EINT0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */ SUNXI_FUNCTION(0x3, "s_i2c"), /* SDA */ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PL_EINT1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2), diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-h616-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-h616-r.c new file mode 100644 index 000000000000..8e4f10ab96ce --- /dev/null +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-h616-r.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Allwinner H616 R_PIO pin controller driver + * + * Copyright (C) 2020 Arm Ltd. + * Based on former work, which is: + * Copyright (C) 2017 Icenowy Zheng + */ + +#include +#include +#include +#include +#include +#include + +#include "pinctrl-sunxi.h" + +static const struct sunxi_desc_pin sun50i_h616_r_pins[] = { + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */ + SUNXI_FUNCTION(0x3, "s_i2c")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */ + SUNXI_FUNCTION(0x3, "s_i2c")), /* SDA */ +}; + +static const struct sunxi_pinctrl_desc sun50i_h616_r_pinctrl_data = { + .pins = sun50i_h616_r_pins, + .npins = ARRAY_SIZE(sun50i_h616_r_pins), + .pin_base = PL_BASE, +}; + +static int sun50i_h616_r_pinctrl_probe(struct platform_device *pdev) +{ + return sunxi_pinctrl_init(pdev, + &sun50i_h616_r_pinctrl_data); +} + +static const struct of_device_id sun50i_h616_r_pinctrl_match[] = { + { .compatible = "allwinner,sun50i-h616-r-pinctrl", }, + {} +}; + +static struct platform_driver sun50i_h616_r_pinctrl_driver = { + .probe = sun50i_h616_r_pinctrl_probe, + .driver = { + .name = "sun50i-h616-r-pinctrl", + .of_match_table = sun50i_h616_r_pinctrl_match, + }, +}; +builtin_platform_driver(sun50i_h616_r_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c new file mode 100644 index 000000000000..ce1917e230f4 --- /dev/null +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c @@ -0,0 +1,548 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Allwinner H616 SoC pinctrl driver. + * + * Copyright (C) 2020 Arm Ltd. + * based on the H6 pinctrl driver + * Copyright (C) 2017 Icenowy Zheng + */ + +#include +#include +#include +#include +#include + +#include "pinctrl-sunxi.h" + +static const struct sunxi_desc_pin h616_pins[] = { + /* Internal connection to the AC200 part */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0), + SUNXI_FUNCTION(0x2, "emac1")), /* ERXD1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1), + SUNXI_FUNCTION(0x2, "emac1")), /* ERXD0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2), + SUNXI_FUNCTION(0x2, "emac1")), /* ECRS_DV */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3), + SUNXI_FUNCTION(0x2, "emac1")), /* ERXERR */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4), + SUNXI_FUNCTION(0x2, "emac1")), /* ETXD1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5), + SUNXI_FUNCTION(0x2, "emac1")), /* ETXD0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6), + SUNXI_FUNCTION(0x2, "emac1")), /* ETXCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7), + SUNXI_FUNCTION(0x2, "emac1")), /* ETXEN */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8), + SUNXI_FUNCTION(0x2, "emac1")), /* EMDC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9), + SUNXI_FUNCTION(0x2, "emac1")), /* EMDIO */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10), + SUNXI_FUNCTION(0x2, "i2c3")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11), + SUNXI_FUNCTION(0x2, "i2c3")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12), + SUNXI_FUNCTION(0x2, "pwm5")), + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* WE */ + SUNXI_FUNCTION(0x3, "mmc2"), /* DS */ + SUNXI_FUNCTION(0x4, "spi0"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)), /* PC_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* ALE */ + SUNXI_FUNCTION(0x3, "mmc2"), /* RST */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)), /* PC_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* CLE */ + SUNXI_FUNCTION(0x4, "spi0"), /* MOSI */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)), /* PC_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* CE1 */ + SUNXI_FUNCTION(0x4, "spi0"), /* CS0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)), /* PC_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* CE0 */ + SUNXI_FUNCTION(0x4, "spi0"), /* MISO */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)), /* PC_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* RE */ + SUNXI_FUNCTION(0x3, "mmc2"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PC_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */ + SUNXI_FUNCTION(0x3, "mmc2"), /* CMD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PC_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* RB1 */ + SUNXI_FUNCTION(0x4, "spi0"), /* CS1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 7)), /* PC_EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */ + SUNXI_FUNCTION(0x3, "mmc2"), /* D3 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 8)), /* PC_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */ + SUNXI_FUNCTION(0x3, "mmc2"), /* D4 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 9)), /* PC_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */ + SUNXI_FUNCTION(0x3, "mmc2"), /* D0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 10)), /* PC_EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */ + SUNXI_FUNCTION(0x3, "mmc2"), /* D5 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 11)), /* PC_EINT11 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 12)), /* PC_EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */ + SUNXI_FUNCTION(0x3, "mmc2"), /* D1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 13)), /* PC_EINT13 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */ + SUNXI_FUNCTION(0x3, "mmc2"), /* D6 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 14)), /* PC_EINT14 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */ + SUNXI_FUNCTION(0x3, "mmc2"), /* D2 */ + SUNXI_FUNCTION(0x4, "spi0"), /* WP */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 15)), /* PC_EINT15 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */ + SUNXI_FUNCTION(0x3, "mmc2"), /* D7 */ + SUNXI_FUNCTION(0x4, "spi0"), /* HOLD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 16)), /* PC_EINT16 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */ + SUNXI_FUNCTION(0x3, "jtag"), /* MS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 0)), /* PF_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */ + SUNXI_FUNCTION(0x3, "jtag"), /* DI */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 1)), /* PF_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */ + SUNXI_FUNCTION(0x3, "uart0"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 2)), /* PF_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */ + SUNXI_FUNCTION(0x3, "jtag"), /* DO */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 3)), /* PF_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */ + SUNXI_FUNCTION(0x3, "uart0"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 4)), /* PF_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */ + SUNXI_FUNCTION(0x3, "jtag"), /* CK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 5)), /* PF_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 6)), /* PF_EINT6 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 0)), /* PG_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 1)), /* PG_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 2)), /* PG_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 3)), /* PG_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 4)), /* PG_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 5)), /* PG_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart1"), /* TX */ + SUNXI_FUNCTION(0x4, "jtag"), /* MS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 6)), /* PG_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart1"), /* RX */ + SUNXI_FUNCTION(0x4, "jtag"), /* CK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 7)), /* PG_EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart1"), /* RTS */ + SUNXI_FUNCTION(0x3, "clock"), /* PLL_LOCK_DEBUG */ + SUNXI_FUNCTION(0x4, "jtag"), /* DO */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 8)), /* PG_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart1"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 9)), /* PG_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s2"), /* MCLK */ + SUNXI_FUNCTION(0x3, "clock"), /* X32KFOUT */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 10)), /* PG_EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s2"), /* BCLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 11)), /* PG_EINT11 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s2"), /* SYNC */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 12)), /* PG_EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s2"), /* DOUT */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 13)), /* PG_EINT13 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s2"), /* DIN */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 14)), /* PG_EINT14 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* TX */ + SUNXI_FUNCTION(0x5, "i2c4"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 15)), /* PG_EINT15 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RX */ + SUNXI_FUNCTION(0x5, "i2c4"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 16)), /* PG_EINT16 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ + SUNXI_FUNCTION(0x5, "i2c3"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 17)), /* PG_EINT17 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 18), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ + SUNXI_FUNCTION(0x5, "i2c3"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 18)), /* PG_EINT18 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 19), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "pwm1"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 5, 19)), /* PG_EINT19 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart0"), /* TX */ + SUNXI_FUNCTION(0x4, "pwm3"), + SUNXI_FUNCTION(0x5, "i2c1"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 0)), /* PH_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart0"), /* RX */ + SUNXI_FUNCTION(0x4, "pwm4"), + SUNXI_FUNCTION(0x5, "i2c1"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 1)), /* PH_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart5"), /* TX */ + SUNXI_FUNCTION(0x3, "spdif"), /* MCLK */ + SUNXI_FUNCTION(0x4, "pwm2"), + SUNXI_FUNCTION(0x5, "i2c2"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 2)), /* PH_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart5"), /* RX */ + SUNXI_FUNCTION(0x4, "pwm1"), + SUNXI_FUNCTION(0x5, "i2c2"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 3)), /* PH_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "spdif"), /* OUT */ + SUNXI_FUNCTION(0x5, "i2c3"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 4)), /* PH_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* TX */ + SUNXI_FUNCTION(0x3, "i2s3"), /* MCLK */ + SUNXI_FUNCTION(0x4, "spi1"), /* CS0 */ + SUNXI_FUNCTION(0x5, "i2c3"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 5)), /* PH_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RX */ + SUNXI_FUNCTION(0x3, "i2s3"), /* BCLK */ + SUNXI_FUNCTION(0x4, "spi1"), /* CLK */ + SUNXI_FUNCTION(0x5, "i2c4"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 6)), /* PH_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ + SUNXI_FUNCTION(0x3, "i2s3"), /* SYNC */ + SUNXI_FUNCTION(0x4, "spi1"), /* MOSI */ + SUNXI_FUNCTION(0x5, "i2c4"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 7)), /* PH_EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ + SUNXI_FUNCTION(0x3, "i2s3"), /* DO0 */ + SUNXI_FUNCTION(0x4, "spi1"), /* MISO */ + SUNXI_FUNCTION(0x5, "i2s3"), /* DI1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 8)), /* PH_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "i2s3"), /* DI0 */ + SUNXI_FUNCTION(0x4, "spi1"), /* CS1 */ + SUNXI_FUNCTION(0x3, "i2s3"), /* DO1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 9)), /* PH_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "ir_rx"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 10)), /* PH_EINT10 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ERXD3 */ + SUNXI_FUNCTION(0x3, "dmic"), /* CLK */ + SUNXI_FUNCTION(0x4, "i2s0"), /* MCLK */ + SUNXI_FUNCTION(0x5, "hdmi"), /* HSCL */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 0)), /* PI_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ERXD2 */ + SUNXI_FUNCTION(0x3, "dmic"), /* DATA0 */ + SUNXI_FUNCTION(0x4, "i2s0"), /* BCLK */ + SUNXI_FUNCTION(0x5, "hdmi"), /* HSDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 1)), /* PI_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ERXD1 */ + SUNXI_FUNCTION(0x3, "dmic"), /* DATA1 */ + SUNXI_FUNCTION(0x4, "i2s0"), /* SYNC */ + SUNXI_FUNCTION(0x5, "hdmi"), /* HCEC */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 2)), /* PI_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ERXD0 */ + SUNXI_FUNCTION(0x3, "dmic"), /* DATA2 */ + SUNXI_FUNCTION(0x4, "i2s0_dout0"), /* DO0 */ + SUNXI_FUNCTION(0x5, "i2s0_din1"), /* DI1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 3)), /* PI_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ERXCK */ + SUNXI_FUNCTION(0x3, "dmic"), /* DATA3 */ + SUNXI_FUNCTION(0x4, "i2s0_din0"), /* DI0 */ + SUNXI_FUNCTION(0x5, "i2s0_dout1"), /* DO1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 4)), /* PI_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ERXCTL */ + SUNXI_FUNCTION(0x3, "uart2"), /* TX */ + SUNXI_FUNCTION(0x4, "ts0"), /* CLK */ + SUNXI_FUNCTION(0x5, "i2c0"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 5)), /* PI_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ENULL */ + SUNXI_FUNCTION(0x3, "uart2"), /* RX */ + SUNXI_FUNCTION(0x4, "ts0"), /* ERR */ + SUNXI_FUNCTION(0x5, "i2c0"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 6)), /* PI_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ETXD3 */ + SUNXI_FUNCTION(0x3, "uart2"), /* RTS */ + SUNXI_FUNCTION(0x4, "ts0"), /* SYNC */ + SUNXI_FUNCTION(0x5, "i2c1"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 7)), /* PI_EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ETXD2 */ + SUNXI_FUNCTION(0x3, "uart2"), /* CTS */ + SUNXI_FUNCTION(0x4, "ts0"), /* DVLD */ + SUNXI_FUNCTION(0x5, "i2c1"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 8)), /* PI_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ETXD1 */ + SUNXI_FUNCTION(0x3, "uart3"), /* TX */ + SUNXI_FUNCTION(0x4, "ts0"), /* D0 */ + SUNXI_FUNCTION(0x5, "i2c2"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 9)), /* PI_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ETXD0 */ + SUNXI_FUNCTION(0x3, "uart3"), /* RX */ + SUNXI_FUNCTION(0x4, "ts0"), /* D1 */ + SUNXI_FUNCTION(0x5, "i2c2"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 10)), /* PI_EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ETXCK */ + SUNXI_FUNCTION(0x3, "uart3"), /* RTS */ + SUNXI_FUNCTION(0x4, "ts0"), /* D2 */ + SUNXI_FUNCTION(0x5, "pwm1"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 11)), /* PI_EINT11 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ETXCTL */ + SUNXI_FUNCTION(0x3, "uart3"), /* CTS */ + SUNXI_FUNCTION(0x4, "ts0"), /* D3 */ + SUNXI_FUNCTION(0x5, "pwm2"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 12)), /* PI_EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* ECLKIN */ + SUNXI_FUNCTION(0x3, "uart4"), /* TX */ + SUNXI_FUNCTION(0x4, "ts0"), /* D4 */ + SUNXI_FUNCTION(0x5, "pwm3"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 13)), /* PI_EINT13 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* MDC */ + SUNXI_FUNCTION(0x3, "uart4"), /* RX */ + SUNXI_FUNCTION(0x4, "ts0"), /* D5 */ + SUNXI_FUNCTION(0x5, "pwm4"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 14)), /* PI_EINT14 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* MDIO */ + SUNXI_FUNCTION(0x3, "uart4"), /* RTS */ + SUNXI_FUNCTION(0x4, "ts0"), /* D6 */ + SUNXI_FUNCTION(0x5, "clock"), /* CLK_FANOUT0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 15)), /* PI_EINT15 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(I, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "emac0"), /* EPHY_CLK */ + SUNXI_FUNCTION(0x3, "uart4"), /* CTS */ + SUNXI_FUNCTION(0x4, "ts0"), /* D7 */ + SUNXI_FUNCTION(0x5, "clock"), /* CLK_FANOUT1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 7, 16)), /* PI_EINT16 */ +}; +static const unsigned int h616_irq_bank_map[] = { 0, 2, 3, 4, 5, 6, 7, 8 }; + +static const struct sunxi_pinctrl_desc h616_pinctrl_data = { + .pins = h616_pins, + .npins = ARRAY_SIZE(h616_pins), + .irq_banks = ARRAY_SIZE(h616_irq_bank_map), + .irq_bank_map = h616_irq_bank_map, + .irq_read_needs_mux = true, + .io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL, +}; + +static int h616_pinctrl_probe(struct platform_device *pdev) +{ + return sunxi_pinctrl_init(pdev, &h616_pinctrl_data); +} + +static const struct of_device_id h616_pinctrl_match[] = { + { .compatible = "allwinner,sun50i-h616-pinctrl", }, + {} +}; + +static struct platform_driver h616_pinctrl_driver = { + .probe = h616_pinctrl_probe, + .driver = { + .name = "sun50i-h616-pinctrl", + .of_match_table = h616_pinctrl_match, + }, +}; +builtin_platform_driver(h616_pinctrl_driver); diff --git a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c index cfb924228d87..60a67139ff0a 100644 --- a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c +++ b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c @@ -704,10 +704,9 @@ static void ti_iodelay_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, u32 reg = 0; cfg = &group->cfg[i]; - regmap_read(iod->regmap, cfg->offset, ®), - seq_printf(s, "\n\t0x%08x = 0x%08x (%3d, %3d)", - cfg->offset, reg, cfg->a_delay, - cfg->g_delay); + regmap_read(iod->regmap, cfg->offset, ®); + seq_printf(s, "\n\t0x%08x = 0x%08x (%3d, %3d)", + cfg->offset, reg, cfg->a_delay, cfg->g_delay); } } #endif diff --git a/drivers/pinctrl/zte/Kconfig b/drivers/pinctrl/zte/Kconfig deleted file mode 100644 index 4fdc70511034..000000000000 --- a/drivers/pinctrl/zte/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config PINCTRL_ZX - bool - select PINMUX - select GENERIC_PINCONF - select GENERIC_PINCTRL_GROUPS - select GENERIC_PINMUX_FUNCTIONS - -config PINCTRL_ZX296718 - bool "ZTE ZX296718 pinctrl driver" - depends on OF && ARCH_ZX - select PINCTRL_ZX - help - Say Y here to enable the ZX296718 pinctrl driver diff --git a/drivers/pinctrl/zte/Makefile b/drivers/pinctrl/zte/Makefile deleted file mode 100644 index 2084c7810f96..000000000000 --- a/drivers/pinctrl/zte/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_PINCTRL_ZX) += pinctrl-zx.o -obj-$(CONFIG_PINCTRL_ZX296718) += pinctrl-zx296718.o diff --git a/drivers/pinctrl/zte/pinctrl-zx.c b/drivers/pinctrl/zte/pinctrl-zx.c deleted file mode 100644 index 80d00ab8c110..000000000000 --- a/drivers/pinctrl/zte/pinctrl-zx.c +++ /dev/null @@ -1,445 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../core.h" -#include "../pinctrl-utils.h" -#include "../pinmux.h" -#include "pinctrl-zx.h" - -#define ZX_PULL_DOWN BIT(0) -#define ZX_PULL_UP BIT(1) -#define ZX_INPUT_ENABLE BIT(3) -#define ZX_DS_SHIFT 4 -#define ZX_DS_MASK (0x7 << ZX_DS_SHIFT) -#define ZX_DS_VALUE(x) (((x) << ZX_DS_SHIFT) & ZX_DS_MASK) -#define ZX_SLEW BIT(8) - -struct zx_pinctrl { - struct pinctrl_dev *pctldev; - struct device *dev; - void __iomem *base; - void __iomem *aux_base; - spinlock_t lock; - struct zx_pinctrl_soc_info *info; -}; - -static int zx_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, u32 *num_maps) -{ - return pinconf_generic_dt_node_to_map(pctldev, np_config, map, - num_maps, PIN_MAP_TYPE_INVALID); -} - -static const struct pinctrl_ops zx_pinctrl_ops = { - .dt_node_to_map = zx_dt_node_to_map, - .dt_free_map = pinctrl_utils_free_map, - .get_groups_count = pinctrl_generic_get_group_count, - .get_group_name = pinctrl_generic_get_group_name, - .get_group_pins = pinctrl_generic_get_group_pins, -}; - -#define NONAON_MVAL 2 - -static int zx_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, - unsigned int group_selector) -{ - struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev); - struct zx_pinctrl_soc_info *info = zpctl->info; - const struct pinctrl_pin_desc *pindesc = info->pins + group_selector; - struct zx_pin_data *data = pindesc->drv_data; - struct zx_mux_desc *mux; - u32 mask, offset, bitpos; - struct function_desc *func; - unsigned long flags; - u32 val, mval; - - /* Skip reserved pin */ - if (!data) - return -EINVAL; - - mux = data->muxes; - mask = (1 << data->width) - 1; - offset = data->offset; - bitpos = data->bitpos; - - func = pinmux_generic_get_function(pctldev, func_selector); - if (!func) - return -EINVAL; - - while (mux->name) { - if (strcmp(mux->name, func->name) == 0) - break; - mux++; - } - - /* Found mux value to be written */ - mval = mux->muxval; - - spin_lock_irqsave(&zpctl->lock, flags); - - if (data->aon_pin) { - /* - * It's an AON pin, whose mux register offset and bit position - * can be calculated from pin number. Each register covers 16 - * pins, and each pin occupies 2 bits. - */ - u16 aoffset = pindesc->number / 16 * 4; - u16 abitpos = (pindesc->number % 16) * 2; - - if (mval & AON_MUX_FLAG) { - /* - * This is a mux value that needs to be written into - * AON pinmux register. Write it and then we're done. - */ - val = readl(zpctl->aux_base + aoffset); - val &= ~(0x3 << abitpos); - val |= (mval & 0x3) << abitpos; - writel(val, zpctl->aux_base + aoffset); - } else { - /* - * It's a mux value that needs to be written into TOP - * pinmux register. - */ - val = readl(zpctl->base + offset); - val &= ~(mask << bitpos); - val |= (mval & mask) << bitpos; - writel(val, zpctl->base + offset); - - /* - * In this case, the AON pinmux register needs to be - * set up to select non-AON function. - */ - val = readl(zpctl->aux_base + aoffset); - val &= ~(0x3 << abitpos); - val |= NONAON_MVAL << abitpos; - writel(val, zpctl->aux_base + aoffset); - } - - } else { - /* - * This is a TOP pin, and we only need to set up TOP pinmux - * register and then we're done with it. - */ - val = readl(zpctl->base + offset); - val &= ~(mask << bitpos); - val |= (mval & mask) << bitpos; - writel(val, zpctl->base + offset); - } - - spin_unlock_irqrestore(&zpctl->lock, flags); - - return 0; -} - -static const struct pinmux_ops zx_pinmux_ops = { - .get_functions_count = pinmux_generic_get_function_count, - .get_function_name = pinmux_generic_get_function_name, - .get_function_groups = pinmux_generic_get_function_groups, - .set_mux = zx_set_mux, -}; - -static int zx_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *config) -{ - struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev); - struct zx_pinctrl_soc_info *info = zpctl->info; - const struct pinctrl_pin_desc *pindesc = info->pins + pin; - struct zx_pin_data *data = pindesc->drv_data; - enum pin_config_param param = pinconf_to_config_param(*config); - u32 val; - - /* Skip reserved pin */ - if (!data) - return -EINVAL; - - val = readl(zpctl->aux_base + data->coffset); - val = val >> data->cbitpos; - - switch (param) { - case PIN_CONFIG_BIAS_PULL_DOWN: - val &= ZX_PULL_DOWN; - val = !!val; - if (val == 0) - return -EINVAL; - break; - case PIN_CONFIG_BIAS_PULL_UP: - val &= ZX_PULL_UP; - val = !!val; - if (val == 0) - return -EINVAL; - break; - case PIN_CONFIG_INPUT_ENABLE: - val &= ZX_INPUT_ENABLE; - val = !!val; - if (val == 0) - return -EINVAL; - break; - case PIN_CONFIG_DRIVE_STRENGTH: - val &= ZX_DS_MASK; - val = val >> ZX_DS_SHIFT; - break; - case PIN_CONFIG_SLEW_RATE: - val &= ZX_SLEW; - val = !!val; - break; - default: - return -ENOTSUPP; - } - - *config = pinconf_to_config_packed(param, val); - - return 0; -} - -static int zx_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *configs, unsigned int num_configs) -{ - struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev); - struct zx_pinctrl_soc_info *info = zpctl->info; - const struct pinctrl_pin_desc *pindesc = info->pins + pin; - struct zx_pin_data *data = pindesc->drv_data; - enum pin_config_param param; - u32 val, arg; - int i; - - /* Skip reserved pin */ - if (!data) - return -EINVAL; - - val = readl(zpctl->aux_base + data->coffset); - - for (i = 0; i < num_configs; i++) { - param = pinconf_to_config_param(configs[i]); - arg = pinconf_to_config_argument(configs[i]); - - switch (param) { - case PIN_CONFIG_BIAS_PULL_DOWN: - val |= ZX_PULL_DOWN << data->cbitpos; - break; - case PIN_CONFIG_BIAS_PULL_UP: - val |= ZX_PULL_UP << data->cbitpos; - break; - case PIN_CONFIG_INPUT_ENABLE: - val |= ZX_INPUT_ENABLE << data->cbitpos; - break; - case PIN_CONFIG_DRIVE_STRENGTH: - val &= ~(ZX_DS_MASK << data->cbitpos); - val |= ZX_DS_VALUE(arg) << data->cbitpos; - break; - case PIN_CONFIG_SLEW_RATE: - if (arg) - val |= ZX_SLEW << data->cbitpos; - else - val &= ~ZX_SLEW << data->cbitpos; - break; - default: - return -ENOTSUPP; - } - } - - writel(val, zpctl->aux_base + data->coffset); - return 0; -} - -static const struct pinconf_ops zx_pinconf_ops = { - .pin_config_set = zx_pin_config_set, - .pin_config_get = zx_pin_config_get, - .is_generic = true, -}; - -static int zx_pinctrl_build_state(struct platform_device *pdev) -{ - struct zx_pinctrl *zpctl = platform_get_drvdata(pdev); - struct zx_pinctrl_soc_info *info = zpctl->info; - struct pinctrl_dev *pctldev = zpctl->pctldev; - struct function_desc *functions; - int nfunctions; - struct group_desc *groups; - int ngroups; - int i; - - /* Every single pin composes a group */ - ngroups = info->npins; - groups = devm_kcalloc(&pdev->dev, ngroups, sizeof(*groups), - GFP_KERNEL); - if (!groups) - return -ENOMEM; - - for (i = 0; i < ngroups; i++) { - const struct pinctrl_pin_desc *pindesc = info->pins + i; - struct group_desc *group = groups + i; - - group->name = pindesc->name; - group->pins = (int *) &pindesc->number; - group->num_pins = 1; - radix_tree_insert(&pctldev->pin_group_tree, i, group); - } - - pctldev->num_groups = ngroups; - - /* Build function list from pin mux functions */ - functions = kcalloc(info->npins, sizeof(*functions), GFP_KERNEL); - if (!functions) - return -ENOMEM; - - nfunctions = 0; - for (i = 0; i < info->npins; i++) { - const struct pinctrl_pin_desc *pindesc = info->pins + i; - struct zx_pin_data *data = pindesc->drv_data; - struct zx_mux_desc *mux; - - /* Reserved pins do not have a drv_data at all */ - if (!data) - continue; - - /* Loop over all muxes for the pin */ - mux = data->muxes; - while (mux->name) { - struct function_desc *func = functions; - - /* Search function list for given mux */ - while (func->name) { - if (strcmp(mux->name, func->name) == 0) { - /* Function exists */ - func->num_group_names++; - break; - } - func++; - } - - if (!func->name) { - /* New function */ - func->name = mux->name; - func->num_group_names = 1; - radix_tree_insert(&pctldev->pin_function_tree, - nfunctions++, func); - } - - mux++; - } - } - - pctldev->num_functions = nfunctions; - functions = krealloc(functions, nfunctions * sizeof(*functions), - GFP_KERNEL); - - /* Find pin groups for every single function */ - for (i = 0; i < info->npins; i++) { - const struct pinctrl_pin_desc *pindesc = info->pins + i; - struct zx_pin_data *data = pindesc->drv_data; - struct zx_mux_desc *mux; - - if (!data) - continue; - - mux = data->muxes; - while (mux->name) { - struct function_desc *func; - const char **group; - int j; - - /* Find function for given mux */ - for (j = 0; j < nfunctions; j++) - if (strcmp(functions[j].name, mux->name) == 0) - break; - - func = functions + j; - if (!func->group_names) { - func->group_names = devm_kcalloc(&pdev->dev, - func->num_group_names, - sizeof(*func->group_names), - GFP_KERNEL); - if (!func->group_names) { - kfree(functions); - return -ENOMEM; - } - } - - group = func->group_names; - while (*group) - group++; - *group = pindesc->name; - - mux++; - } - } - - return 0; -} - -int zx_pinctrl_init(struct platform_device *pdev, - struct zx_pinctrl_soc_info *info) -{ - struct pinctrl_desc *pctldesc; - struct zx_pinctrl *zpctl; - struct device_node *np; - int ret; - - zpctl = devm_kzalloc(&pdev->dev, sizeof(*zpctl), GFP_KERNEL); - if (!zpctl) - return -ENOMEM; - - spin_lock_init(&zpctl->lock); - - zpctl->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(zpctl->base)) - return PTR_ERR(zpctl->base); - - np = of_parse_phandle(pdev->dev.of_node, "zte,auxiliary-controller", 0); - if (!np) { - dev_err(&pdev->dev, "failed to find auxiliary controller\n"); - return -ENODEV; - } - - zpctl->aux_base = of_iomap(np, 0); - of_node_put(np); - if (!zpctl->aux_base) - return -ENOMEM; - - zpctl->dev = &pdev->dev; - zpctl->info = info; - - pctldesc = devm_kzalloc(&pdev->dev, sizeof(*pctldesc), GFP_KERNEL); - if (!pctldesc) - return -ENOMEM; - - pctldesc->name = dev_name(&pdev->dev); - pctldesc->owner = THIS_MODULE; - pctldesc->pins = info->pins; - pctldesc->npins = info->npins; - pctldesc->pctlops = &zx_pinctrl_ops; - pctldesc->pmxops = &zx_pinmux_ops; - pctldesc->confops = &zx_pinconf_ops; - - zpctl->pctldev = devm_pinctrl_register(&pdev->dev, pctldesc, zpctl); - if (IS_ERR(zpctl->pctldev)) { - ret = PTR_ERR(zpctl->pctldev); - dev_err(&pdev->dev, "failed to register pinctrl: %d\n", ret); - return ret; - } - - platform_set_drvdata(pdev, zpctl); - - ret = zx_pinctrl_build_state(pdev); - if (ret) { - dev_err(&pdev->dev, "failed to build state: %d\n", ret); - return ret; - } - - dev_info(&pdev->dev, "initialized pinctrl driver\n"); - return 0; -} diff --git a/drivers/pinctrl/zte/pinctrl-zx.h b/drivers/pinctrl/zte/pinctrl-zx.h deleted file mode 100644 index a0692e2e9012..000000000000 --- a/drivers/pinctrl/zte/pinctrl-zx.h +++ /dev/null @@ -1,102 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#ifndef __PINCTRL_ZX_H -#define __PINCTRL_ZX_H - -/** - * struct zx_mux_desc - hardware mux descriptor - * @name: mux function name - * @muxval: mux register bit value - */ -struct zx_mux_desc { - const char *name; - u8 muxval; -}; - -/** - * struct zx_pin_data - hardware per-pin data - * @aon_pin: whether it's an AON pin - * @offset: register offset within TOP pinmux controller - * @bitpos: bit position within TOP pinmux register - * @width: bit width within TOP pinmux register - * @coffset: pinconf register offset within AON controller - * @cbitpos: pinconf bit position within AON register - * @muxes: available mux function names and corresponding register values - * - * Unlike TOP pinmux and AON pinconf registers which are arranged pretty - * arbitrarily, AON pinmux register bits are well organized per pin id, and - * each pin occupies two bits, so that we can calculate the AON register offset - * and bit position from pin id. Thus, we only need to define TOP pinmux and - * AON pinconf register data for the pin. - */ -struct zx_pin_data { - bool aon_pin; - u16 offset; - u16 bitpos; - u16 width; - u16 coffset; - u16 cbitpos; - struct zx_mux_desc *muxes; -}; - -struct zx_pinctrl_soc_info { - const struct pinctrl_pin_desc *pins; - unsigned int npins; -}; - -#define TOP_PIN(pin, off, bp, wd, coff, cbp, ...) { \ - .number = pin, \ - .name = #pin, \ - .drv_data = &(struct zx_pin_data) { \ - .aon_pin = false, \ - .offset = off, \ - .bitpos = bp, \ - .width = wd, \ - .coffset = coff, \ - .cbitpos = cbp, \ - .muxes = (struct zx_mux_desc[]) { \ - __VA_ARGS__, { } }, \ - }, \ -} - -#define AON_PIN(pin, off, bp, wd, coff, cbp, ...) { \ - .number = pin, \ - .name = #pin, \ - .drv_data = &(struct zx_pin_data) { \ - .aon_pin = true, \ - .offset = off, \ - .bitpos = bp, \ - .width = wd, \ - .coffset = coff, \ - .cbitpos = cbp, \ - .muxes = (struct zx_mux_desc[]) { \ - __VA_ARGS__, { } }, \ - }, \ -} - -#define ZX_RESERVED(pin) PINCTRL_PIN(pin, #pin) - -#define TOP_MUX(_val, _name) { \ - .name = _name, \ - .muxval = _val, \ -} - -/* - * When the flag is set, it's a mux configuration for an AON pin that sits in - * AON register. Otherwise, it's one for AON pin but sitting in TOP register. - */ -#define AON_MUX_FLAG BIT(7) - -#define AON_MUX(_val, _name) { \ - .name = _name, \ - .muxval = _val | AON_MUX_FLAG, \ -} - -int zx_pinctrl_init(struct platform_device *pdev, - struct zx_pinctrl_soc_info *info); - -#endif /* __PINCTRL_ZX_H */ diff --git a/drivers/pinctrl/zte/pinctrl-zx296718.c b/drivers/pinctrl/zte/pinctrl-zx296718.c deleted file mode 100644 index c980aecb6f2f..000000000000 --- a/drivers/pinctrl/zte/pinctrl-zx296718.c +++ /dev/null @@ -1,1024 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#include -#include -#include -#include -#include -#include - -#include "pinctrl-zx.h" - -#define TOP_REG0 0x00 -#define TOP_REG1 0x04 -#define TOP_REG2 0x08 -#define TOP_REG3 0x0c -#define TOP_REG4 0x10 -#define TOP_REG5 0x14 -#define TOP_REG6 0x18 -#define TOP_REG7 0x1c -#define TOP_REG8 0x20 - -/* - * The pin numbering starts from AON pins with reserved ones included, - * so that register data like offset and bit position for AON pins can - * be calculated from pin number. - */ -enum zx296718_pin { - /* aon_pmm_reg_0 */ - I2C3_SCL = 0, - I2C3_SDA = 1, - AON_RESERVED0 = 2, - AON_RESERVED1 = 3, - SEC_EN = 4, - UART0_RXD = 5, - UART0_TXD = 6, - IR_IN = 7, - SPI0_CLK = 8, - SPI0_CS = 9, - SPI0_TXD = 10, - SPI0_RXD = 11, - KEY_COL0 = 12, - KEY_COL1 = 13, - KEY_COL2 = 14, - KEY_ROW0 = 15, - - /* aon_pmm_reg_1 */ - KEY_ROW1 = 16, - KEY_ROW2 = 17, - HDMI_SCL = 18, - HDMI_SDA = 19, - JTAG_TCK = 20, - JTAG_TRSTN = 21, - JTAG_TMS = 22, - JTAG_TDI = 23, - JTAG_TDO = 24, - I2C0_SCL = 25, - I2C0_SDA = 26, - I2C1_SCL = 27, - I2C1_SDA = 28, - AON_RESERVED2 = 29, - AON_RESERVED3 = 30, - AON_RESERVED4 = 31, - - /* aon_pmm_reg_2 */ - SPI1_CLK = 32, - SPI1_CS = 33, - SPI1_TXD = 34, - SPI1_RXD = 35, - AON_RESERVED5 = 36, - AON_RESERVED6 = 37, - AUDIO_DET = 38, - SPDIF_OUT = 39, - HDMI_CEC = 40, - HDMI_HPD = 41, - GMAC_25M_OUT = 42, - BOOT_SEL0 = 43, - BOOT_SEL1 = 44, - BOOT_SEL2 = 45, - DEEP_SLEEP_OUT_N = 46, - AON_RESERVED7 = 47, - - /* top_pmm_reg_0 */ - GMII_GTX_CLK = 48, - GMII_TX_CLK = 49, - GMII_TXD0 = 50, - GMII_TXD1 = 51, - GMII_TXD2 = 52, - GMII_TXD3 = 53, - GMII_TXD4 = 54, - GMII_TXD5 = 55, - GMII_TXD6 = 56, - GMII_TXD7 = 57, - GMII_TX_ER = 58, - GMII_TX_EN = 59, - GMII_RX_CLK = 60, - GMII_RXD0 = 61, - GMII_RXD1 = 62, - GMII_RXD2 = 63, - - /* top_pmm_reg_1 */ - GMII_RXD3 = 64, - GMII_RXD4 = 65, - GMII_RXD5 = 66, - GMII_RXD6 = 67, - GMII_RXD7 = 68, - GMII_RX_ER = 69, - GMII_RX_DV = 70, - GMII_COL = 71, - GMII_CRS = 72, - GMII_MDC = 73, - GMII_MDIO = 74, - SDIO1_CLK = 75, - SDIO1_CMD = 76, - SDIO1_DATA0 = 77, - SDIO1_DATA1 = 78, - SDIO1_DATA2 = 79, - - /* top_pmm_reg_2 */ - SDIO1_DATA3 = 80, - SDIO1_CD = 81, - SDIO1_WP = 82, - USIM1_CD = 83, - USIM1_CLK = 84, - USIM1_RST = 85, - - /* top_pmm_reg_3 */ - USIM1_DATA = 86, - SDIO0_CLK = 87, - SDIO0_CMD = 88, - SDIO0_DATA0 = 89, - SDIO0_DATA1 = 90, - SDIO0_DATA2 = 91, - SDIO0_DATA3 = 92, - SDIO0_CD = 93, - SDIO0_WP = 94, - - /* top_pmm_reg_4 */ - TSI0_DATA0 = 95, - SPINOR_CLK = 96, - TSI2_DATA = 97, - TSI2_CLK = 98, - TSI2_SYNC = 99, - TSI2_VALID = 100, - SPINOR_CS = 101, - SPINOR_DQ0 = 102, - SPINOR_DQ1 = 103, - SPINOR_DQ2 = 104, - SPINOR_DQ3 = 105, - VGA_HS = 106, - VGA_VS = 107, - TSI3_DATA = 108, - - /* top_pmm_reg_5 */ - TSI3_CLK = 109, - TSI3_SYNC = 110, - TSI3_VALID = 111, - I2S1_WS = 112, - I2S1_BCLK = 113, - I2S1_MCLK = 114, - I2S1_DIN0 = 115, - I2S1_DOUT0 = 116, - SPI3_CLK = 117, - SPI3_CS = 118, - SPI3_TXD = 119, - NAND_LDO_MS18_SEL = 120, - - /* top_pmm_reg_6 */ - SPI3_RXD = 121, - I2S0_MCLK = 122, - I2S0_BCLK = 123, - I2S0_WS = 124, - I2S0_DIN0 = 125, - I2S0_DOUT0 = 126, - I2C5_SCL = 127, - I2C5_SDA = 128, - SPI2_CLK = 129, - SPI2_CS = 130, - SPI2_TXD = 131, - - /* top_pmm_reg_7 */ - SPI2_RXD = 132, - NAND_WP_N = 133, - NAND_PAGE_SIZE0 = 134, - NAND_PAGE_SIZE1 = 135, - NAND_ADDR_CYCLE = 136, - NAND_RB0 = 137, - NAND_RB1 = 138, - NAND_RB2 = 139, - NAND_RB3 = 140, - - /* top_pmm_reg_8 */ - GMAC_125M_IN = 141, - GMAC_50M_OUT = 142, - SPINOR_SSCLK_LOOPBACK = 143, - SPINOR_SDIO1CLK_LOOPBACK = 144, -}; - -static const struct pinctrl_pin_desc zx296718_pins[] = { - /* aon_pmm_reg_0 */ - AON_PIN(I2C3_SCL, TOP_REG2, 18, 2, 0x48, 0, - AON_MUX(0x0, "ANMI"), /* anmi */ - AON_MUX(0x1, "AGPIO"), /* agpio29 */ - AON_MUX(0x2, "nonAON"), /* pin0 */ - AON_MUX(0x3, "EXT_INT"), /* int4 */ - TOP_MUX(0x0, "I2C3"), /* scl */ - TOP_MUX(0x1, "SPI2"), /* txd */ - TOP_MUX(0x2, "I2S1")), /* din0 */ - AON_PIN(I2C3_SDA, TOP_REG2, 20, 2, 0x48, 9, - AON_MUX(0x0, "WD"), /* rst_b */ - AON_MUX(0x1, "AGPIO"), /* agpio30 */ - AON_MUX(0x2, "nonAON"), /* pin1 */ - AON_MUX(0x3, "EXT_INT"), /* int5 */ - TOP_MUX(0x0, "I2C3"), /* sda */ - TOP_MUX(0x1, "SPI2"), /* rxd */ - TOP_MUX(0x2, "I2S0")), /* mclk */ - ZX_RESERVED(AON_RESERVED0), - ZX_RESERVED(AON_RESERVED1), - AON_PIN(SEC_EN, TOP_REG3, 5, 1, 0x50, 0, - AON_MUX(0x0, "SEC"), /* en */ - AON_MUX(0x1, "AGPIO"), /* agpio28 */ - AON_MUX(0x2, "nonAON"), /* pin3 */ - AON_MUX(0x3, "EXT_INT"), /* int7 */ - TOP_MUX(0x0, "I2C2"), /* sda */ - TOP_MUX(0x1, "SPI2")), /* cs */ - AON_PIN(UART0_RXD, 0, 0, 0, 0x50, 9, - AON_MUX(0x0, "UART0"), /* rxd */ - AON_MUX(0x1, "AGPIO"), /* agpio20 */ - AON_MUX(0x2, "nonAON")), /* pin34 */ - AON_PIN(UART0_TXD, 0, 0, 0, 0x50, 18, - AON_MUX(0x0, "UART0"), /* txd */ - AON_MUX(0x1, "AGPIO"), /* agpio21 */ - AON_MUX(0x2, "nonAON")), /* pin32 */ - AON_PIN(IR_IN, 0, 0, 0, 0x64, 0, - AON_MUX(0x0, "IR"), /* in */ - AON_MUX(0x1, "AGPIO"), /* agpio0 */ - AON_MUX(0x2, "nonAON")), /* pin27 */ - AON_PIN(SPI0_CLK, TOP_REG3, 16, 1, 0x64, 9, - AON_MUX(0x0, "EXT_INT"), /* int0 */ - AON_MUX(0x1, "AGPIO"), /* agpio23 */ - AON_MUX(0x2, "nonAON"), /* pin5 */ - AON_MUX(0x3, "PCU"), /* test6 */ - TOP_MUX(0x0, "SPI0"), /* clk */ - TOP_MUX(0x1, "ISP")), /* flash_trig */ - AON_PIN(SPI0_CS, TOP_REG3, 17, 1, 0x64, 18, - AON_MUX(0x0, "EXT_INT"), /* int1 */ - AON_MUX(0x1, "AGPIO"), /* agpio24 */ - AON_MUX(0x2, "nonAON"), /* pin6 */ - AON_MUX(0x3, "PCU"), /* test0 */ - TOP_MUX(0x0, "SPI0"), /* cs */ - TOP_MUX(0x1, "ISP")), /* prelight_trig */ - AON_PIN(SPI0_TXD, TOP_REG3, 18, 1, 0x68, 0, - AON_MUX(0x0, "EXT_INT"), /* int2 */ - AON_MUX(0x1, "AGPIO"), /* agpio25 */ - AON_MUX(0x2, "nonAON"), /* pin7 */ - AON_MUX(0x3, "PCU"), /* test1 */ - TOP_MUX(0x0, "SPI0"), /* txd */ - TOP_MUX(0x1, "ISP")), /* shutter_trig */ - AON_PIN(SPI0_RXD, TOP_REG3, 19, 1, 0x68, 9, - AON_MUX(0x0, "EXT_INT"), /* int3 */ - AON_MUX(0x1, "AGPIO"), /* agpio26 */ - AON_MUX(0x2, "nonAON"), /* pin8 */ - AON_MUX(0x3, "PCU"), /* test2 */ - TOP_MUX(0x0, "SPI0"), /* rxd */ - TOP_MUX(0x1, "ISP")), /* shutter_open */ - AON_PIN(KEY_COL0, TOP_REG3, 20, 1, 0x68, 18, - AON_MUX(0x0, "KEY"), /* col0 */ - AON_MUX(0x1, "AGPIO"), /* agpio5 */ - AON_MUX(0x2, "nonAON"), /* pin9 */ - AON_MUX(0x3, "PCU"), /* test3 */ - TOP_MUX(0x0, "UART3"), /* rxd */ - TOP_MUX(0x1, "I2S0")), /* din1 */ - AON_PIN(KEY_COL1, TOP_REG3, 21, 2, 0x6c, 0, - AON_MUX(0x0, "KEY"), /* col1 */ - AON_MUX(0x1, "AGPIO"), /* agpio6 */ - AON_MUX(0x2, "nonAON"), /* pin10 */ - TOP_MUX(0x0, "UART3"), /* txd */ - TOP_MUX(0x1, "I2S0"), /* din2 */ - TOP_MUX(0x2, "VGA")), /* scl */ - AON_PIN(KEY_COL2, TOP_REG3, 23, 2, 0x6c, 9, - AON_MUX(0x0, "KEY"), /* col2 */ - AON_MUX(0x1, "AGPIO"), /* agpio7 */ - AON_MUX(0x2, "nonAON"), /* pin11 */ - TOP_MUX(0x0, "PWM"), /* out1 */ - TOP_MUX(0x1, "I2S0"), /* din3 */ - TOP_MUX(0x2, "VGA")), /* sda */ - AON_PIN(KEY_ROW0, 0, 0, 0, 0x6c, 18, - AON_MUX(0x0, "KEY"), /* row0 */ - AON_MUX(0x1, "AGPIO"), /* agpio8 */ - AON_MUX(0x2, "nonAON"), /* pin33 */ - AON_MUX(0x3, "WD")), /* rst_b */ - - /* aon_pmm_reg_1 */ - AON_PIN(KEY_ROW1, TOP_REG3, 25, 2, 0x70, 0, - AON_MUX(0x0, "KEY"), /* row1 */ - AON_MUX(0x1, "AGPIO"), /* agpio9 */ - AON_MUX(0x2, "nonAON"), /* pin12 */ - TOP_MUX(0x0, "LCD"), /* port0 lcd_te */ - TOP_MUX(0x1, "I2S0"), /* dout2 */ - TOP_MUX(0x2, "PWM"), /* out2 */ - TOP_MUX(0x3, "VGA")), /* hs1 */ - AON_PIN(KEY_ROW2, TOP_REG3, 27, 2, 0x70, 9, - AON_MUX(0x0, "KEY"), /* row2 */ - AON_MUX(0x1, "AGPIO"), /* agpio10 */ - AON_MUX(0x2, "nonAON"), /* pin13 */ - TOP_MUX(0x0, "LCD"), /* port1 lcd_te */ - TOP_MUX(0x1, "I2S0"), /* dout3 */ - TOP_MUX(0x2, "PWM"), /* out3 */ - TOP_MUX(0x3, "VGA")), /* vs1 */ - AON_PIN(HDMI_SCL, TOP_REG3, 29, 1, 0x70, 18, - AON_MUX(0x0, "PCU"), /* test7 */ - AON_MUX(0x1, "AGPIO"), /* agpio3 */ - AON_MUX(0x2, "nonAON"), /* pin14 */ - TOP_MUX(0x0, "HDMI"), /* scl */ - TOP_MUX(0x1, "UART3")), /* rxd */ - AON_PIN(HDMI_SDA, TOP_REG3, 30, 1, 0x74, 0, - AON_MUX(0x0, "PCU"), /* test8 */ - AON_MUX(0x1, "AGPIO"), /* agpio4 */ - AON_MUX(0x2, "nonAON"), /* pin15 */ - TOP_MUX(0x0, "HDMI"), /* sda */ - TOP_MUX(0x1, "UART3")), /* txd */ - AON_PIN(JTAG_TCK, TOP_REG7, 3, 1, 0x78, 18, - AON_MUX(0x0, "JTAG"), /* tck */ - AON_MUX(0x1, "AGPIO"), /* agpio11 */ - AON_MUX(0x2, "nonAON"), /* pin22 */ - AON_MUX(0x3, "EXT_INT"), /* int4 */ - TOP_MUX(0x0, "SPI4"), /* clk */ - TOP_MUX(0x1, "UART1")), /* rxd */ - AON_PIN(JTAG_TRSTN, TOP_REG7, 4, 1, 0xac, 0, - AON_MUX(0x0, "JTAG"), /* trstn */ - AON_MUX(0x1, "AGPIO"), /* agpio12 */ - AON_MUX(0x2, "nonAON"), /* pin23 */ - AON_MUX(0x3, "EXT_INT"), /* int5 */ - TOP_MUX(0x0, "SPI4"), /* cs */ - TOP_MUX(0x1, "UART1")), /* txd */ - AON_PIN(JTAG_TMS, TOP_REG7, 5, 1, 0xac, 9, - AON_MUX(0x0, "JTAG"), /* tms */ - AON_MUX(0x1, "AGPIO"), /* agpio13 */ - AON_MUX(0x2, "nonAON"), /* pin24 */ - AON_MUX(0x3, "EXT_INT"), /* int6 */ - TOP_MUX(0x0, "SPI4"), /* txd */ - TOP_MUX(0x1, "UART2")), /* rxd */ - AON_PIN(JTAG_TDI, TOP_REG7, 6, 1, 0xac, 18, - AON_MUX(0x0, "JTAG"), /* tdi */ - AON_MUX(0x1, "AGPIO"), /* agpio14 */ - AON_MUX(0x2, "nonAON"), /* pin25 */ - AON_MUX(0x3, "EXT_INT"), /* int7 */ - TOP_MUX(0x0, "SPI4"), /* rxd */ - TOP_MUX(0x1, "UART2")), /* txd */ - AON_PIN(JTAG_TDO, 0, 0, 0, 0xb0, 0, - AON_MUX(0x0, "JTAG"), /* tdo */ - AON_MUX(0x1, "AGPIO"), /* agpio15 */ - AON_MUX(0x2, "nonAON")), /* pin26 */ - AON_PIN(I2C0_SCL, 0, 0, 0, 0xb0, 9, - AON_MUX(0x0, "I2C0"), /* scl */ - AON_MUX(0x1, "AGPIO"), /* agpio16 */ - AON_MUX(0x2, "nonAON")), /* pin28 */ - AON_PIN(I2C0_SDA, 0, 0, 0, 0xb0, 18, - AON_MUX(0x0, "I2C0"), /* sda */ - AON_MUX(0x1, "AGPIO"), /* agpio17 */ - AON_MUX(0x2, "nonAON")), /* pin29 */ - AON_PIN(I2C1_SCL, TOP_REG8, 4, 1, 0xb4, 0, - AON_MUX(0x0, "I2C1"), /* scl */ - AON_MUX(0x1, "AGPIO"), /* agpio18 */ - AON_MUX(0x2, "nonAON"), /* pin30 */ - TOP_MUX(0x0, "LCD")), /* port0 lcd_te */ - AON_PIN(I2C1_SDA, TOP_REG8, 5, 1, 0xb4, 9, - AON_MUX(0x0, "I2C1"), /* sda */ - AON_MUX(0x1, "AGPIO"), /* agpio19 */ - AON_MUX(0x2, "nonAON"), /* pin31 */ - TOP_MUX(0x0, "LCD")), /* port1 lcd_te */ - ZX_RESERVED(AON_RESERVED2), - ZX_RESERVED(AON_RESERVED3), - ZX_RESERVED(AON_RESERVED4), - - /* aon_pmm_reg_2 */ - AON_PIN(SPI1_CLK, TOP_REG2, 6, 3, 0x40, 9, - AON_MUX(0x0, "EXT_INT"), /* int0 */ - AON_MUX(0x1, "PCU"), /* test12 */ - AON_MUX(0x2, "nonAON"), /* pin39 */ - TOP_MUX(0x0, "SPI1"), /* clk */ - TOP_MUX(0x1, "PCM"), /* clk */ - TOP_MUX(0x2, "BGPIO"), /* gpio35 */ - TOP_MUX(0x3, "I2C4"), /* scl */ - TOP_MUX(0x4, "I2S1"), /* mclk */ - TOP_MUX(0x5, "ISP")), /* flash_trig */ - AON_PIN(SPI1_CS, TOP_REG2, 9, 3, 0x40, 18, - AON_MUX(0x0, "EXT_INT"), /* int1 */ - AON_MUX(0x1, "PCU"), /* test13 */ - AON_MUX(0x2, "nonAON"), /* pin40 */ - TOP_MUX(0x0, "SPI1"), /* cs */ - TOP_MUX(0x1, "PCM"), /* fs */ - TOP_MUX(0x2, "BGPIO"), /* gpio36 */ - TOP_MUX(0x3, "I2C4"), /* sda */ - TOP_MUX(0x4, "I2S1"), /* bclk */ - TOP_MUX(0x5, "ISP")), /* prelight_trig */ - AON_PIN(SPI1_TXD, TOP_REG2, 12, 3, 0x44, 0, - AON_MUX(0x0, "EXT_INT"), /* int2 */ - AON_MUX(0x1, "PCU"), /* test14 */ - AON_MUX(0x2, "nonAON"), /* pin41 */ - TOP_MUX(0x0, "SPI1"), /* txd */ - TOP_MUX(0x1, "PCM"), /* txd */ - TOP_MUX(0x2, "BGPIO"), /* gpio37 */ - TOP_MUX(0x3, "UART5"), /* rxd */ - TOP_MUX(0x4, "I2S1"), /* ws */ - TOP_MUX(0x5, "ISP")), /* shutter_trig */ - AON_PIN(SPI1_RXD, TOP_REG2, 15, 3, 0x44, 9, - AON_MUX(0x0, "EXT_INT"), /* int3 */ - AON_MUX(0x1, "PCU"), /* test15 */ - AON_MUX(0x2, "nonAON"), /* pin42 */ - TOP_MUX(0x0, "SPI1"), /* rxd */ - TOP_MUX(0x1, "PCM"), /* rxd */ - TOP_MUX(0x2, "BGPIO"), /* gpio38 */ - TOP_MUX(0x3, "UART5"), /* txd */ - TOP_MUX(0x4, "I2S1"), /* dout0 */ - TOP_MUX(0x5, "ISP")), /* shutter_open */ - ZX_RESERVED(AON_RESERVED5), - ZX_RESERVED(AON_RESERVED6), - AON_PIN(AUDIO_DET, TOP_REG3, 3, 2, 0x48, 18, - AON_MUX(0x0, "PCU"), /* test4 */ - AON_MUX(0x1, "AGPIO"), /* agpio27 */ - AON_MUX(0x2, "nonAON"), /* pin2 */ - AON_MUX(0x3, "EXT_INT"), /* int16 */ - TOP_MUX(0x0, "AUDIO"), /* detect */ - TOP_MUX(0x1, "I2C2"), /* scl */ - TOP_MUX(0x2, "SPI2")), /* clk */ - AON_PIN(SPDIF_OUT, TOP_REG3, 14, 2, 0x78, 9, - AON_MUX(0x0, "PCU"), /* test5 */ - AON_MUX(0x1, "AGPIO"), /* agpio22 */ - AON_MUX(0x2, "nonAON"), /* pin4 */ - TOP_MUX(0x0, "SPDIF"), /* out */ - TOP_MUX(0x1, "PWM"), /* out0 */ - TOP_MUX(0x2, "ISP")), /* fl_trig */ - AON_PIN(HDMI_CEC, 0, 0, 0, 0x74, 9, - AON_MUX(0x0, "PCU"), /* test9 */ - AON_MUX(0x1, "AGPIO"), /* agpio1 */ - AON_MUX(0x2, "nonAON")), /* pin16 */ - AON_PIN(HDMI_HPD, 0, 0, 0, 0x74, 18, - AON_MUX(0x0, "PCU"), /* test10 */ - AON_MUX(0x1, "AGPIO"), /* agpio2 */ - AON_MUX(0x2, "nonAON")), /* pin17 */ - AON_PIN(GMAC_25M_OUT, 0, 0, 0, 0x78, 0, - AON_MUX(0x0, "PCU"), /* test11 */ - AON_MUX(0x1, "AGPIO"), /* agpio31 */ - AON_MUX(0x2, "nonAON")), /* pin43 */ - AON_PIN(BOOT_SEL0, 0, 0, 0, 0xc0, 9, - AON_MUX(0x0, "BOOT"), /* sel0 */ - AON_MUX(0x1, "AGPIO"), /* agpio18 */ - AON_MUX(0x2, "nonAON")), /* pin18 */ - AON_PIN(BOOT_SEL1, 0, 0, 0, 0xc0, 18, - AON_MUX(0x0, "BOOT"), /* sel1 */ - AON_MUX(0x1, "AGPIO"), /* agpio19 */ - AON_MUX(0x2, "nonAON")), /* pin19 */ - AON_PIN(BOOT_SEL2, 0, 0, 0, 0xc4, 0, - AON_MUX(0x0, "BOOT"), /* sel2 */ - AON_MUX(0x1, "AGPIO"), /* agpio20 */ - AON_MUX(0x2, "nonAON")), /* pin20 */ - AON_PIN(DEEP_SLEEP_OUT_N, 0, 0, 0, 0xc4, 9, - AON_MUX(0x0, "DEEPSLP"), /* deep sleep out_n */ - AON_MUX(0x1, "AGPIO"), /* agpio21 */ - AON_MUX(0x2, "nonAON")), /* pin21 */ - ZX_RESERVED(AON_RESERVED7), - - /* top_pmm_reg_0 */ - TOP_PIN(GMII_GTX_CLK, TOP_REG0, 0, 2, 0x10, 0, - TOP_MUX(0x0, "GMII"), /* gtx_clk */ - TOP_MUX(0x1, "DVI0"), /* clk */ - TOP_MUX(0x2, "BGPIO")), /* gpio0 */ - TOP_PIN(GMII_TX_CLK, TOP_REG0, 2, 2, 0x10, 9, - TOP_MUX(0x0, "GMII"), /* tx_clk */ - TOP_MUX(0x1, "DVI0"), /* vs */ - TOP_MUX(0x2, "BGPIO")), /* gpio1 */ - TOP_PIN(GMII_TXD0, TOP_REG0, 4, 2, 0x10, 18, - TOP_MUX(0x0, "GMII"), /* txd0 */ - TOP_MUX(0x1, "DVI0"), /* hs */ - TOP_MUX(0x2, "BGPIO")), /* gpio2 */ - TOP_PIN(GMII_TXD1, TOP_REG0, 6, 2, 0x14, 0, - TOP_MUX(0x0, "GMII"), /* txd1 */ - TOP_MUX(0x1, "DVI0"), /* d0 */ - TOP_MUX(0x2, "BGPIO")), /* gpio3 */ - TOP_PIN(GMII_TXD2, TOP_REG0, 8, 2, 0x14, 9, - TOP_MUX(0x0, "GMII"), /* txd2 */ - TOP_MUX(0x1, "DVI0"), /* d1 */ - TOP_MUX(0x2, "BGPIO")), /* gpio4 */ - TOP_PIN(GMII_TXD3, TOP_REG0, 10, 2, 0x14, 18, - TOP_MUX(0x0, "GMII"), /* txd3 */ - TOP_MUX(0x1, "DVI0"), /* d2 */ - TOP_MUX(0x2, "BGPIO")), /* gpio5 */ - TOP_PIN(GMII_TXD4, TOP_REG0, 12, 2, 0x18, 0, - TOP_MUX(0x0, "GMII"), /* txd4 */ - TOP_MUX(0x1, "DVI0"), /* d3 */ - TOP_MUX(0x2, "BGPIO")), /* gpio6 */ - TOP_PIN(GMII_TXD5, TOP_REG0, 14, 2, 0x18, 9, - TOP_MUX(0x0, "GMII"), /* txd5 */ - TOP_MUX(0x1, "DVI0"), /* d4 */ - TOP_MUX(0x2, "BGPIO")), /* gpio7 */ - TOP_PIN(GMII_TXD6, TOP_REG0, 16, 2, 0x18, 18, - TOP_MUX(0x0, "GMII"), /* txd6 */ - TOP_MUX(0x1, "DVI0"), /* d5 */ - TOP_MUX(0x2, "BGPIO")), /* gpio8 */ - TOP_PIN(GMII_TXD7, TOP_REG0, 18, 2, 0x1c, 0, - TOP_MUX(0x0, "GMII"), /* txd7 */ - TOP_MUX(0x1, "DVI0"), /* d6 */ - TOP_MUX(0x2, "BGPIO")), /* gpio9 */ - TOP_PIN(GMII_TX_ER, TOP_REG0, 20, 2, 0x1c, 9, - TOP_MUX(0x0, "GMII"), /* tx_er */ - TOP_MUX(0x1, "DVI0"), /* d7 */ - TOP_MUX(0x2, "BGPIO")), /* gpio10 */ - TOP_PIN(GMII_TX_EN, TOP_REG0, 22, 2, 0x1c, 18, - TOP_MUX(0x0, "GMII"), /* tx_en */ - TOP_MUX(0x1, "DVI0"), /* d8 */ - TOP_MUX(0x3, "BGPIO")), /* gpio11 */ - TOP_PIN(GMII_RX_CLK, TOP_REG0, 24, 2, 0x20, 0, - TOP_MUX(0x0, "GMII"), /* rx_clk */ - TOP_MUX(0x1, "DVI0"), /* d9 */ - TOP_MUX(0x3, "BGPIO")), /* gpio12 */ - TOP_PIN(GMII_RXD0, TOP_REG0, 26, 2, 0x20, 9, - TOP_MUX(0x0, "GMII"), /* rxd0 */ - TOP_MUX(0x1, "DVI0"), /* d10 */ - TOP_MUX(0x3, "BGPIO")), /* gpio13 */ - TOP_PIN(GMII_RXD1, TOP_REG0, 28, 2, 0x20, 18, - TOP_MUX(0x0, "GMII"), /* rxd1 */ - TOP_MUX(0x1, "DVI0"), /* d11 */ - TOP_MUX(0x2, "BGPIO")), /* gpio14 */ - TOP_PIN(GMII_RXD2, TOP_REG0, 30, 2, 0x24, 0, - TOP_MUX(0x0, "GMII"), /* rxd2 */ - TOP_MUX(0x1, "DVI1"), /* clk */ - TOP_MUX(0x2, "BGPIO")), /* gpio15 */ - - /* top_pmm_reg_1 */ - TOP_PIN(GMII_RXD3, TOP_REG1, 0, 2, 0x24, 9, - TOP_MUX(0x0, "GMII"), /* rxd3 */ - TOP_MUX(0x1, "DVI1"), /* hs */ - TOP_MUX(0x2, "BGPIO")), /* gpio16 */ - TOP_PIN(GMII_RXD4, TOP_REG1, 2, 2, 0x24, 18, - TOP_MUX(0x0, "GMII"), /* rxd4 */ - TOP_MUX(0x1, "DVI1"), /* vs */ - TOP_MUX(0x2, "BGPIO")), /* gpio17 */ - TOP_PIN(GMII_RXD5, TOP_REG1, 4, 2, 0x28, 0, - TOP_MUX(0x0, "GMII"), /* rxd5 */ - TOP_MUX(0x1, "DVI1"), /* d0 */ - TOP_MUX(0x2, "BGPIO"), /* gpio18 */ - TOP_MUX(0x3, "TSI0")), /* dat0 */ - TOP_PIN(GMII_RXD6, TOP_REG1, 6, 2, 0x28, 9, - TOP_MUX(0x0, "GMII"), /* rxd6 */ - TOP_MUX(0x1, "DVI1"), /* d1 */ - TOP_MUX(0x2, "BGPIO"), /* gpio19 */ - TOP_MUX(0x3, "TSI0")), /* clk */ - TOP_PIN(GMII_RXD7, TOP_REG1, 8, 2, 0x28, 18, - TOP_MUX(0x0, "GMII"), /* rxd7 */ - TOP_MUX(0x1, "DVI1"), /* d2 */ - TOP_MUX(0x2, "BGPIO"), /* gpio20 */ - TOP_MUX(0x3, "TSI0")), /* sync */ - TOP_PIN(GMII_RX_ER, TOP_REG1, 10, 2, 0x2c, 0, - TOP_MUX(0x0, "GMII"), /* rx_er */ - TOP_MUX(0x1, "DVI1"), /* d3 */ - TOP_MUX(0x2, "BGPIO"), /* gpio21 */ - TOP_MUX(0x3, "TSI0")), /* valid */ - TOP_PIN(GMII_RX_DV, TOP_REG1, 12, 2, 0x2c, 9, - TOP_MUX(0x0, "GMII"), /* rx_dv */ - TOP_MUX(0x1, "DVI1"), /* d4 */ - TOP_MUX(0x2, "BGPIO"), /* gpio22 */ - TOP_MUX(0x3, "TSI1")), /* dat0 */ - TOP_PIN(GMII_COL, TOP_REG1, 14, 2, 0x2c, 18, - TOP_MUX(0x0, "GMII"), /* col */ - TOP_MUX(0x1, "DVI1"), /* d5 */ - TOP_MUX(0x2, "BGPIO"), /* gpio23 */ - TOP_MUX(0x3, "TSI1")), /* clk */ - TOP_PIN(GMII_CRS, TOP_REG1, 16, 2, 0x30, 0, - TOP_MUX(0x0, "GMII"), /* crs */ - TOP_MUX(0x1, "DVI1"), /* d6 */ - TOP_MUX(0x2, "BGPIO"), /* gpio24 */ - TOP_MUX(0x3, "TSI1")), /* sync */ - TOP_PIN(GMII_MDC, TOP_REG1, 18, 2, 0x30, 9, - TOP_MUX(0x0, "GMII"), /* mdc */ - TOP_MUX(0x1, "DVI1"), /* d7 */ - TOP_MUX(0x2, "BGPIO"), /* gpio25 */ - TOP_MUX(0x3, "TSI1")), /* valid */ - TOP_PIN(GMII_MDIO, TOP_REG1, 20, 1, 0x30, 18, - TOP_MUX(0x0, "GMII"), /* mdio */ - TOP_MUX(0x2, "BGPIO")), /* gpio26 */ - TOP_PIN(SDIO1_CLK, TOP_REG1, 21, 2, 0x34, 18, - TOP_MUX(0x0, "SDIO1"), /* clk */ - TOP_MUX(0x1, "USIM0"), /* clk */ - TOP_MUX(0x2, "BGPIO"), /* gpio27 */ - TOP_MUX(0x3, "SPINOR")), /* clk */ - TOP_PIN(SDIO1_CMD, TOP_REG1, 23, 2, 0x38, 0, - TOP_MUX(0x0, "SDIO1"), /* cmd */ - TOP_MUX(0x1, "USIM0"), /* cd */ - TOP_MUX(0x2, "BGPIO"), /* gpio28 */ - TOP_MUX(0x3, "SPINOR")), /* cs */ - TOP_PIN(SDIO1_DATA0, TOP_REG1, 25, 2, 0x38, 9, - TOP_MUX(0x0, "SDIO1"), /* dat0 */ - TOP_MUX(0x1, "USIM0"), /* rst */ - TOP_MUX(0x2, "BGPIO"), /* gpio29 */ - TOP_MUX(0x3, "SPINOR")), /* dq0 */ - TOP_PIN(SDIO1_DATA1, TOP_REG1, 27, 2, 0x38, 18, - TOP_MUX(0x0, "SDIO1"), /* dat1 */ - TOP_MUX(0x1, "USIM0"), /* data */ - TOP_MUX(0x2, "BGPIO"), /* gpio30 */ - TOP_MUX(0x3, "SPINOR")), /* dq1 */ - TOP_PIN(SDIO1_DATA2, TOP_REG1, 29, 2, 0x3c, 0, - TOP_MUX(0x0, "SDIO1"), /* dat2 */ - TOP_MUX(0x1, "BGPIO"), /* gpio31 */ - TOP_MUX(0x2, "SPINOR")), /* dq2 */ - - /* top_pmm_reg_2 */ - TOP_PIN(SDIO1_DATA3, TOP_REG2, 0, 2, 0x3c, 9, - TOP_MUX(0x0, "SDIO1"), /* dat3 */ - TOP_MUX(0x1, "BGPIO"), /* gpio32 */ - TOP_MUX(0x2, "SPINOR")), /* dq3 */ - TOP_PIN(SDIO1_CD, TOP_REG2, 2, 2, 0x3c, 18, - TOP_MUX(0x0, "SDIO1"), /* cd */ - TOP_MUX(0x1, "BGPIO"), /* gpio33 */ - TOP_MUX(0x2, "ISP")), /* fl_trig */ - TOP_PIN(SDIO1_WP, TOP_REG2, 4, 2, 0x40, 0, - TOP_MUX(0x0, "SDIO1"), /* wp */ - TOP_MUX(0x1, "BGPIO"), /* gpio34 */ - TOP_MUX(0x2, "ISP")), /* ref_clk */ - TOP_PIN(USIM1_CD, TOP_REG2, 22, 3, 0x44, 18, - TOP_MUX(0x0, "USIM1"), /* cd */ - TOP_MUX(0x1, "UART4"), /* rxd */ - TOP_MUX(0x2, "BGPIO"), /* gpio39 */ - TOP_MUX(0x3, "SPI3"), /* clk */ - TOP_MUX(0x4, "I2S0"), /* bclk */ - TOP_MUX(0x5, "B_DVI0")), /* d8 */ - TOP_PIN(USIM1_CLK, TOP_REG2, 25, 3, 0x4c, 18, - TOP_MUX(0x0, "USIM1"), /* clk */ - TOP_MUX(0x1, "UART4"), /* txd */ - TOP_MUX(0x2, "BGPIO"), /* gpio40 */ - TOP_MUX(0x3, "SPI3"), /* cs */ - TOP_MUX(0x4, "I2S0"), /* ws */ - TOP_MUX(0x5, "B_DVI0")), /* d9 */ - TOP_PIN(USIM1_RST, TOP_REG2, 28, 3, 0x4c, 0, - TOP_MUX(0x0, "USIM1"), /* rst */ - TOP_MUX(0x1, "UART4"), /* cts */ - TOP_MUX(0x2, "BGPIO"), /* gpio41 */ - TOP_MUX(0x3, "SPI3"), /* txd */ - TOP_MUX(0x4, "I2S0"), /* dout0 */ - TOP_MUX(0x5, "B_DVI0")), /* d10 */ - - /* top_pmm_reg_3 */ - TOP_PIN(USIM1_DATA, TOP_REG3, 0, 3, 0x4c, 9, - TOP_MUX(0x0, "USIM1"), /* dat */ - TOP_MUX(0x1, "UART4"), /* rst */ - TOP_MUX(0x2, "BGPIO"), /* gpio42 */ - TOP_MUX(0x3, "SPI3"), /* rxd */ - TOP_MUX(0x4, "I2S0"), /* din0 */ - TOP_MUX(0x5, "B_DVI0")), /* d11 */ - TOP_PIN(SDIO0_CLK, TOP_REG3, 6, 1, 0x58, 0, - TOP_MUX(0x0, "SDIO0"), /* clk */ - TOP_MUX(0x1, "GPIO")), /* gpio43 */ - TOP_PIN(SDIO0_CMD, TOP_REG3, 7, 1, 0x58, 9, - TOP_MUX(0x0, "SDIO0"), /* cmd */ - TOP_MUX(0x1, "GPIO")), /* gpio44 */ - TOP_PIN(SDIO0_DATA0, TOP_REG3, 8, 1, 0x58, 18, - TOP_MUX(0x0, "SDIO0"), /* dat0 */ - TOP_MUX(0x1, "GPIO")), /* gpio45 */ - TOP_PIN(SDIO0_DATA1, TOP_REG3, 9, 1, 0x5c, 0, - TOP_MUX(0x0, "SDIO0"), /* dat1 */ - TOP_MUX(0x1, "GPIO")), /* gpio46 */ - TOP_PIN(SDIO0_DATA2, TOP_REG3, 10, 1, 0x5c, 9, - TOP_MUX(0x0, "SDIO0"), /* dat2 */ - TOP_MUX(0x1, "GPIO")), /* gpio47 */ - TOP_PIN(SDIO0_DATA3, TOP_REG3, 11, 1, 0x5c, 18, - TOP_MUX(0x0, "SDIO0"), /* dat3 */ - TOP_MUX(0x1, "GPIO")), /* gpio48 */ - TOP_PIN(SDIO0_CD, TOP_REG3, 12, 1, 0x60, 0, - TOP_MUX(0x0, "SDIO0"), /* cd */ - TOP_MUX(0x1, "GPIO")), /* gpio49 */ - TOP_PIN(SDIO0_WP, TOP_REG3, 13, 1, 0x60, 9, - TOP_MUX(0x0, "SDIO0"), /* wp */ - TOP_MUX(0x1, "GPIO")), /* gpio50 */ - - /* top_pmm_reg_4 */ - TOP_PIN(TSI0_DATA0, TOP_REG4, 0, 2, 0x60, 18, - TOP_MUX(0x0, "TSI0"), /* dat0 */ - TOP_MUX(0x1, "LCD"), /* clk */ - TOP_MUX(0x2, "BGPIO")), /* gpio51 */ - TOP_PIN(SPINOR_CLK, TOP_REG4, 2, 2, 0xa8, 18, - TOP_MUX(0x0, "SPINOR"), /* clk */ - TOP_MUX(0x1, "TSI0"), /* dat1 */ - TOP_MUX(0x2, "LCD"), /* dat0 */ - TOP_MUX(0x3, "BGPIO")), /* gpio52 */ - TOP_PIN(TSI2_DATA, TOP_REG4, 4, 2, 0x7c, 0, - TOP_MUX(0x0, "TSI2"), /* dat */ - TOP_MUX(0x1, "TSI0"), /* dat2 */ - TOP_MUX(0x2, "LCD"), /* dat1 */ - TOP_MUX(0x3, "BGPIO")), /* gpio53 */ - TOP_PIN(TSI2_CLK, TOP_REG4, 6, 2, 0x7c, 9, - TOP_MUX(0x0, "TSI2"), /* clk */ - TOP_MUX(0x1, "TSI0"), /* dat3 */ - TOP_MUX(0x2, "LCD"), /* dat2 */ - TOP_MUX(0x3, "BGPIO")), /* gpio54 */ - TOP_PIN(TSI2_SYNC, TOP_REG4, 8, 2, 0x7c, 18, - TOP_MUX(0x0, "TSI2"), /* sync */ - TOP_MUX(0x1, "TSI0"), /* dat4 */ - TOP_MUX(0x2, "LCD"), /* dat3 */ - TOP_MUX(0x3, "BGPIO")), /* gpio55 */ - TOP_PIN(TSI2_VALID, TOP_REG4, 10, 2, 0x80, 0, - TOP_MUX(0x0, "TSI2"), /* valid */ - TOP_MUX(0x1, "TSI0"), /* dat5 */ - TOP_MUX(0x2, "LCD"), /* dat4 */ - TOP_MUX(0x3, "BGPIO")), /* gpio56 */ - TOP_PIN(SPINOR_CS, TOP_REG4, 12, 2, 0x80, 9, - TOP_MUX(0x0, "SPINOR"), /* cs */ - TOP_MUX(0x1, "TSI0"), /* dat6 */ - TOP_MUX(0x2, "LCD"), /* dat5 */ - TOP_MUX(0x3, "BGPIO")), /* gpio57 */ - TOP_PIN(SPINOR_DQ0, TOP_REG4, 14, 2, 0x80, 18, - TOP_MUX(0x0, "SPINOR"), /* dq0 */ - TOP_MUX(0x1, "TSI0"), /* dat7 */ - TOP_MUX(0x2, "LCD"), /* dat6 */ - TOP_MUX(0x3, "BGPIO")), /* gpio58 */ - TOP_PIN(SPINOR_DQ1, TOP_REG4, 16, 2, 0x84, 0, - TOP_MUX(0x0, "SPINOR"), /* dq1 */ - TOP_MUX(0x1, "TSI0"), /* clk */ - TOP_MUX(0x2, "LCD"), /* dat7 */ - TOP_MUX(0x3, "BGPIO")), /* gpio59 */ - TOP_PIN(SPINOR_DQ2, TOP_REG4, 18, 2, 0x84, 9, - TOP_MUX(0x0, "SPINOR"), /* dq2 */ - TOP_MUX(0x1, "TSI0"), /* sync */ - TOP_MUX(0x2, "LCD"), /* dat8 */ - TOP_MUX(0x3, "BGPIO")), /* gpio60 */ - TOP_PIN(SPINOR_DQ3, TOP_REG4, 20, 2, 0x84, 18, - TOP_MUX(0x0, "SPINOR"), /* dq3 */ - TOP_MUX(0x1, "TSI0"), /* valid */ - TOP_MUX(0x2, "LCD"), /* dat9 */ - TOP_MUX(0x3, "BGPIO")), /* gpio61 */ - TOP_PIN(VGA_HS, TOP_REG4, 22, 3, 0x88, 0, - TOP_MUX(0x0, "VGA"), /* hs */ - TOP_MUX(0x1, "TSI1"), /* dat0 */ - TOP_MUX(0x2, "LCD"), /* dat10 */ - TOP_MUX(0x3, "BGPIO"), /* gpio62 */ - TOP_MUX(0x4, "I2S1"), /* din1 */ - TOP_MUX(0x5, "B_DVI0")), /* clk */ - TOP_PIN(VGA_VS, TOP_REG4, 25, 3, 0x88, 9, - TOP_MUX(0x0, "VGA"), /* vs0 */ - TOP_MUX(0x1, "TSI1"), /* dat1 */ - TOP_MUX(0x2, "LCD"), /* dat11 */ - TOP_MUX(0x3, "BGPIO"), /* gpio63 */ - TOP_MUX(0x4, "I2S1"), /* din2 */ - TOP_MUX(0x5, "B_DVI0")), /* vs */ - TOP_PIN(TSI3_DATA, TOP_REG4, 28, 3, 0x88, 18, - TOP_MUX(0x0, "TSI3"), /* dat */ - TOP_MUX(0x1, "TSI1"), /* dat2 */ - TOP_MUX(0x2, "LCD"), /* dat12 */ - TOP_MUX(0x3, "BGPIO"), /* gpio64 */ - TOP_MUX(0x4, "I2S1"), /* din3 */ - TOP_MUX(0x5, "B_DVI0")), /* hs */ - - /* top_pmm_reg_5 */ - TOP_PIN(TSI3_CLK, TOP_REG5, 0, 3, 0x8c, 0, - TOP_MUX(0x0, "TSI3"), /* clk */ - TOP_MUX(0x1, "TSI1"), /* dat3 */ - TOP_MUX(0x2, "LCD"), /* dat13 */ - TOP_MUX(0x3, "BGPIO"), /* gpio65 */ - TOP_MUX(0x4, "I2S1"), /* dout1 */ - TOP_MUX(0x5, "B_DVI0")), /* d0 */ - TOP_PIN(TSI3_SYNC, TOP_REG5, 3, 3, 0x8c, 9, - TOP_MUX(0x0, "TSI3"), /* sync */ - TOP_MUX(0x1, "TSI1"), /* dat4 */ - TOP_MUX(0x2, "LCD"), /* dat14 */ - TOP_MUX(0x3, "BGPIO"), /* gpio66 */ - TOP_MUX(0x4, "I2S1"), /* dout2 */ - TOP_MUX(0x5, "B_DVI0")), /* d1 */ - TOP_PIN(TSI3_VALID, TOP_REG5, 6, 3, 0x8c, 18, - TOP_MUX(0x0, "TSI3"), /* valid */ - TOP_MUX(0x1, "TSI1"), /* dat5 */ - TOP_MUX(0x2, "LCD"), /* dat15 */ - TOP_MUX(0x3, "BGPIO"), /* gpio67 */ - TOP_MUX(0x4, "I2S1"), /* dout3 */ - TOP_MUX(0x5, "B_DVI0")), /* d2 */ - TOP_PIN(I2S1_WS, TOP_REG5, 9, 3, 0x90, 0, - TOP_MUX(0x0, "I2S1"), /* ws */ - TOP_MUX(0x1, "TSI1"), /* dat6 */ - TOP_MUX(0x2, "LCD"), /* dat16 */ - TOP_MUX(0x3, "BGPIO"), /* gpio68 */ - TOP_MUX(0x4, "VGA"), /* scl */ - TOP_MUX(0x5, "B_DVI0")), /* d3 */ - TOP_PIN(I2S1_BCLK, TOP_REG5, 12, 3, 0x90, 9, - TOP_MUX(0x0, "I2S1"), /* bclk */ - TOP_MUX(0x1, "TSI1"), /* dat7 */ - TOP_MUX(0x2, "LCD"), /* dat17 */ - TOP_MUX(0x3, "BGPIO"), /* gpio69 */ - TOP_MUX(0x4, "VGA"), /* sda */ - TOP_MUX(0x5, "B_DVI0")), /* d4 */ - TOP_PIN(I2S1_MCLK, TOP_REG5, 15, 2, 0x90, 18, - TOP_MUX(0x0, "I2S1"), /* mclk */ - TOP_MUX(0x1, "TSI1"), /* clk */ - TOP_MUX(0x2, "LCD"), /* dat18 */ - TOP_MUX(0x3, "BGPIO")), /* gpio70 */ - TOP_PIN(I2S1_DIN0, TOP_REG5, 17, 2, 0x94, 0, - TOP_MUX(0x0, "I2S1"), /* din0 */ - TOP_MUX(0x1, "TSI1"), /* sync */ - TOP_MUX(0x2, "LCD"), /* dat19 */ - TOP_MUX(0x3, "BGPIO")), /* gpio71 */ - TOP_PIN(I2S1_DOUT0, TOP_REG5, 19, 2, 0x94, 9, - TOP_MUX(0x0, "I2S1"), /* dout0 */ - TOP_MUX(0x1, "TSI1"), /* valid */ - TOP_MUX(0x2, "LCD"), /* dat20 */ - TOP_MUX(0x3, "BGPIO")), /* gpio72 */ - TOP_PIN(SPI3_CLK, TOP_REG5, 21, 3, 0x94, 18, - TOP_MUX(0x0, "SPI3"), /* clk */ - TOP_MUX(0x1, "TSO1"), /* clk */ - TOP_MUX(0x2, "LCD"), /* dat21 */ - TOP_MUX(0x3, "BGPIO"), /* gpio73 */ - TOP_MUX(0x4, "UART5"), /* rxd */ - TOP_MUX(0x5, "PCM"), /* fs */ - TOP_MUX(0x6, "I2S0"), /* din1 */ - TOP_MUX(0x7, "B_DVI0")), /* d5 */ - TOP_PIN(SPI3_CS, TOP_REG5, 24, 3, 0x98, 0, - TOP_MUX(0x0, "SPI3"), /* cs */ - TOP_MUX(0x1, "TSO1"), /* dat0 */ - TOP_MUX(0x2, "LCD"), /* dat22 */ - TOP_MUX(0x3, "BGPIO"), /* gpio74 */ - TOP_MUX(0x4, "UART5"), /* txd */ - TOP_MUX(0x5, "PCM"), /* clk */ - TOP_MUX(0x6, "I2S0"), /* din2 */ - TOP_MUX(0x7, "B_DVI0")), /* d6 */ - TOP_PIN(SPI3_TXD, TOP_REG5, 27, 3, 0x98, 9, - TOP_MUX(0x0, "SPI3"), /* txd */ - TOP_MUX(0x1, "TSO1"), /* dat1 */ - TOP_MUX(0x2, "LCD"), /* dat23 */ - TOP_MUX(0x3, "BGPIO"), /* gpio75 */ - TOP_MUX(0x4, "UART5"), /* cts */ - TOP_MUX(0x5, "PCM"), /* txd */ - TOP_MUX(0x6, "I2S0"), /* din3 */ - TOP_MUX(0x7, "B_DVI0")), /* d7 */ - TOP_PIN(NAND_LDO_MS18_SEL, TOP_REG5, 30, 1, 0xe4, 0, - TOP_MUX(0x0, "NAND"), /* ldo_ms18_sel */ - TOP_MUX(0x1, "BGPIO")), /* gpio99 */ - - /* top_pmm_reg_6 */ - TOP_PIN(SPI3_RXD, TOP_REG6, 0, 3, 0x98, 18, - TOP_MUX(0x0, "SPI3"), /* rxd */ - TOP_MUX(0x1, "TSO1"), /* dat2 */ - TOP_MUX(0x2, "LCD"), /* stvu_vsync */ - TOP_MUX(0x3, "BGPIO"), /* gpio76 */ - TOP_MUX(0x4, "UART5"), /* rts */ - TOP_MUX(0x5, "PCM"), /* rxd */ - TOP_MUX(0x6, "I2S0"), /* dout1 */ - TOP_MUX(0x7, "B_DVI1")), /* clk */ - TOP_PIN(I2S0_MCLK, TOP_REG6, 3, 3, 0x9c, 0, - TOP_MUX(0x0, "I2S0"), /* mclk */ - TOP_MUX(0x1, "TSO1"), /* dat3 */ - TOP_MUX(0x2, "LCD"), /* stvd */ - TOP_MUX(0x3, "BGPIO"), /* gpio77 */ - TOP_MUX(0x4, "USIM0"), /* cd */ - TOP_MUX(0x5, "B_DVI1")), /* vs */ - TOP_PIN(I2S0_BCLK, TOP_REG6, 6, 3, 0x9c, 9, - TOP_MUX(0x0, "I2S0"), /* bclk */ - TOP_MUX(0x1, "TSO1"), /* dat4 */ - TOP_MUX(0x2, "LCD"), /* sthl_hsync */ - TOP_MUX(0x3, "BGPIO"), /* gpio78 */ - TOP_MUX(0x4, "USIM0"), /* clk */ - TOP_MUX(0x5, "B_DVI1")), /* hs */ - TOP_PIN(I2S0_WS, TOP_REG6, 9, 3, 0x9c, 18, - TOP_MUX(0x0, "I2S0"), /* ws */ - TOP_MUX(0x1, "TSO1"), /* dat5 */ - TOP_MUX(0x2, "LCD"), /* sthr */ - TOP_MUX(0x3, "BGPIO"), /* gpio79 */ - TOP_MUX(0x4, "USIM0"), /* rst */ - TOP_MUX(0x5, "B_DVI1")), /* d0 */ - TOP_PIN(I2S0_DIN0, TOP_REG6, 12, 3, 0xa0, 0, - TOP_MUX(0x0, "I2S0"), /* din0 */ - TOP_MUX(0x1, "TSO1"), /* dat6 */ - TOP_MUX(0x2, "LCD"), /* oev_dataen */ - TOP_MUX(0x3, "BGPIO"), /* gpio80 */ - TOP_MUX(0x4, "USIM0"), /* dat */ - TOP_MUX(0x5, "B_DVI1")), /* d1 */ - TOP_PIN(I2S0_DOUT0, TOP_REG6, 15, 2, 0xa0, 9, - TOP_MUX(0x0, "I2S0"), /* dout0 */ - TOP_MUX(0x1, "TSO1"), /* dat7 */ - TOP_MUX(0x2, "LCD"), /* ckv */ - TOP_MUX(0x3, "BGPIO")), /* gpio81 */ - TOP_PIN(I2C5_SCL, TOP_REG6, 17, 3, 0xa0, 18, - TOP_MUX(0x0, "I2C5"), /* scl */ - TOP_MUX(0x1, "TSO1"), /* sync */ - TOP_MUX(0x2, "LCD"), /* ld */ - TOP_MUX(0x3, "BGPIO"), /* gpio82 */ - TOP_MUX(0x4, "PWM"), /* out2 */ - TOP_MUX(0x5, "I2S0"), /* dout2 */ - TOP_MUX(0x6, "B_DVI1")), /* d2 */ - TOP_PIN(I2C5_SDA, TOP_REG6, 20, 3, 0xa4, 0, - TOP_MUX(0x0, "I2C5"), /* sda */ - TOP_MUX(0x1, "TSO1"), /* vld */ - TOP_MUX(0x2, "LCD"), /* pol */ - TOP_MUX(0x3, "BGPIO"), /* gpio83 */ - TOP_MUX(0x4, "PWM"), /* out3 */ - TOP_MUX(0x5, "I2S0"), /* dout3 */ - TOP_MUX(0x6, "B_DVI1")), /* d3 */ - TOP_PIN(SPI2_CLK, TOP_REG6, 23, 3, 0xa4, 9, - TOP_MUX(0x0, "SPI2"), /* clk */ - TOP_MUX(0x1, "TSO0"), /* clk */ - TOP_MUX(0x2, "LCD"), /* degsl */ - TOP_MUX(0x3, "BGPIO"), /* gpio84 */ - TOP_MUX(0x4, "I2C4"), /* scl */ - TOP_MUX(0x5, "B_DVI1")), /* d4 */ - TOP_PIN(SPI2_CS, TOP_REG6, 26, 3, 0xa4, 18, - TOP_MUX(0x0, "SPI2"), /* cs */ - TOP_MUX(0x1, "TSO0"), /* data */ - TOP_MUX(0x2, "LCD"), /* rev */ - TOP_MUX(0x3, "BGPIO"), /* gpio85 */ - TOP_MUX(0x4, "I2C4"), /* sda */ - TOP_MUX(0x5, "B_DVI1")), /* d5 */ - TOP_PIN(SPI2_TXD, TOP_REG6, 29, 3, 0xa8, 0, - TOP_MUX(0x0, "SPI2"), /* txd */ - TOP_MUX(0x1, "TSO0"), /* sync */ - TOP_MUX(0x2, "LCD"), /* u_d */ - TOP_MUX(0x3, "BGPIO"), /* gpio86 */ - TOP_MUX(0x4, "I2C4"), /* scl */ - TOP_MUX(0x5, "B_DVI1")), /* d6 */ - - /* top_pmm_reg_7 */ - TOP_PIN(SPI2_RXD, TOP_REG7, 0, 3, 0xa8, 9, - TOP_MUX(0x0, "SPI2"), /* rxd */ - TOP_MUX(0x1, "TSO0"), /* vld */ - TOP_MUX(0x2, "LCD"), /* r_l */ - TOP_MUX(0x3, "BGPIO"), /* gpio87 */ - TOP_MUX(0x4, "I2C3"), /* sda */ - TOP_MUX(0x5, "B_DVI1")), /* d7 */ - TOP_PIN(NAND_WP_N, TOP_REG7, 7, 3, 0x54, 9, - TOP_MUX(0x0, "NAND"), /* wp */ - TOP_MUX(0x1, "PWM"), /* out2 */ - TOP_MUX(0x2, "SPI2"), /* clk */ - TOP_MUX(0x3, "BGPIO"), /* gpio88 */ - TOP_MUX(0x4, "TSI0"), /* dat0 */ - TOP_MUX(0x5, "I2S1")), /* din1 */ - TOP_PIN(NAND_PAGE_SIZE0, TOP_REG7, 10, 3, 0xb8, 0, - TOP_MUX(0x0, "NAND"), /* boot_pagesize0 */ - TOP_MUX(0x1, "PWM"), /* out3 */ - TOP_MUX(0x2, "SPI2"), /* cs */ - TOP_MUX(0x3, "BGPIO"), /* gpio89 */ - TOP_MUX(0x4, "TSI0"), /* clk */ - TOP_MUX(0x5, "I2S1")), /* din2 */ - TOP_PIN(NAND_PAGE_SIZE1, TOP_REG7, 13, 3, 0xb8, 9, - TOP_MUX(0x0, "NAND"), /* boot_pagesize1 */ - TOP_MUX(0x1, "I2C4"), /* scl */ - TOP_MUX(0x2, "SPI2"), /* txd */ - TOP_MUX(0x3, "BGPIO"), /* gpio90 */ - TOP_MUX(0x4, "TSI0"), /* sync */ - TOP_MUX(0x5, "I2S1")), /* din3 */ - TOP_PIN(NAND_ADDR_CYCLE, TOP_REG7, 16, 3, 0xb8, 18, - TOP_MUX(0x0, "NAND"), /* boot_addr_cycles */ - TOP_MUX(0x1, "I2C4"), /* sda */ - TOP_MUX(0x2, "SPI2"), /* rxd */ - TOP_MUX(0x3, "BGPIO"), /* gpio91 */ - TOP_MUX(0x4, "TSI0"), /* valid */ - TOP_MUX(0x5, "I2S1")), /* dout1 */ - TOP_PIN(NAND_RB0, TOP_REG7, 19, 3, 0xbc, 0, - TOP_MUX(0x0, "NAND"), /* rdy_busy0 */ - TOP_MUX(0x1, "I2C2"), /* scl */ - TOP_MUX(0x2, "USIM0"), /* cd */ - TOP_MUX(0x3, "BGPIO"), /* gpio92 */ - TOP_MUX(0x4, "TSI1")), /* data0 */ - TOP_PIN(NAND_RB1, TOP_REG7, 22, 3, 0xbc, 9, - TOP_MUX(0x0, "NAND"), /* rdy_busy1 */ - TOP_MUX(0x1, "I2C2"), /* sda */ - TOP_MUX(0x2, "USIM0"), /* clk */ - TOP_MUX(0x3, "BGPIO"), /* gpio93 */ - TOP_MUX(0x4, "TSI1")), /* clk */ - TOP_PIN(NAND_RB2, TOP_REG7, 25, 3, 0xbc, 18, - TOP_MUX(0x0, "NAND"), /* rdy_busy2 */ - TOP_MUX(0x1, "UART5"), /* rxd */ - TOP_MUX(0x2, "USIM0"), /* rst */ - TOP_MUX(0x3, "BGPIO"), /* gpio94 */ - TOP_MUX(0x4, "TSI1"), /* sync */ - TOP_MUX(0x4, "I2S1")), /* dout2 */ - TOP_PIN(NAND_RB3, TOP_REG7, 28, 3, 0x54, 18, - TOP_MUX(0x0, "NAND"), /* rdy_busy3 */ - TOP_MUX(0x1, "UART5"), /* txd */ - TOP_MUX(0x2, "USIM0"), /* dat */ - TOP_MUX(0x3, "BGPIO"), /* gpio95 */ - TOP_MUX(0x4, "TSI1"), /* valid */ - TOP_MUX(0x4, "I2S1")), /* dout3 */ - - /* top_pmm_reg_8 */ - TOP_PIN(GMAC_125M_IN, TOP_REG8, 0, 2, 0x34, 0, - TOP_MUX(0x0, "GMII"), /* 125m_in */ - TOP_MUX(0x1, "USB2"), /* 0_drvvbus */ - TOP_MUX(0x2, "ISP"), /* ref_clk */ - TOP_MUX(0x3, "BGPIO")), /* gpio96 */ - TOP_PIN(GMAC_50M_OUT, TOP_REG8, 2, 2, 0x34, 9, - TOP_MUX(0x0, "GMII"), /* 50m_out */ - TOP_MUX(0x1, "USB2"), /* 1_drvvbus */ - TOP_MUX(0x2, "BGPIO"), /* gpio97 */ - TOP_MUX(0x3, "USB2")), /* 0_drvvbus */ - TOP_PIN(SPINOR_SSCLK_LOOPBACK, TOP_REG8, 6, 1, 0xc8, 9, - TOP_MUX(0x0, "SPINOR")), /* sdio1_clk_i */ - TOP_PIN(SPINOR_SDIO1CLK_LOOPBACK, TOP_REG8, 7, 1, 0xc8, 18, - TOP_MUX(0x0, "SPINOR")), /* ssclk_i */ -}; - -static struct zx_pinctrl_soc_info zx296718_pinctrl_info = { - .pins = zx296718_pins, - .npins = ARRAY_SIZE(zx296718_pins), -}; - -static int zx296718_pinctrl_probe(struct platform_device *pdev) -{ - return zx_pinctrl_init(pdev, &zx296718_pinctrl_info); -} - -static const struct of_device_id zx296718_pinctrl_match[] = { - { .compatible = "zte,zx296718-pmm", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx296718_pinctrl_match); - -static struct platform_driver zx296718_pinctrl_driver = { - .probe = zx296718_pinctrl_probe, - .driver = { - .name = "zx296718-pinctrl", - .of_match_table = zx296718_pinctrl_match, - }, -}; -builtin_platform_driver(zx296718_pinctrl_driver); - -MODULE_DESCRIPTION("ZTE ZX296718 pinctrl driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 36f941500676..124cba7213f1 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -120,7 +120,7 @@ static void mpc52xx_spi_start_transfer(struct mpc52xx_spi *ms) ms->cs_change = ms->transfer->cs_change; /* Write out the first byte */ - ms->wcol_tx_timestamp = get_tbl(); + ms->wcol_tx_timestamp = mftb(); if (ms->tx_buf) out_8(ms->regs + SPI_DATA, *ms->tx_buf++); else @@ -221,8 +221,8 @@ static int mpc52xx_spi_fsmstate_transfer(int irq, struct mpc52xx_spi *ms, * but it can also be worked around simply by retrying the * transfer which is what we do here. */ ms->wcol_count++; - ms->wcol_ticks += get_tbl() - ms->wcol_tx_timestamp; - ms->wcol_tx_timestamp = get_tbl(); + ms->wcol_ticks += mftb() - ms->wcol_tx_timestamp; + ms->wcol_tx_timestamp = mftb(); data = 0; if (ms->tx_buf) data = *(ms->tx_buf - 1); @@ -247,7 +247,7 @@ static int mpc52xx_spi_fsmstate_transfer(int irq, struct mpc52xx_spi *ms, /* Is the transfer complete? */ ms->len--; if (ms->len == 0) { - ms->timestamp = get_tbl(); + ms->timestamp = mftb(); if (ms->transfer->delay.unit == SPI_DELAY_UNIT_USECS) ms->timestamp += ms->transfer->delay.value * tb_ticks_per_usec; @@ -256,7 +256,7 @@ static int mpc52xx_spi_fsmstate_transfer(int irq, struct mpc52xx_spi *ms, } /* Write out the next byte */ - ms->wcol_tx_timestamp = get_tbl(); + ms->wcol_tx_timestamp = mftb(); if (ms->tx_buf) out_8(ms->regs + SPI_DATA, *ms->tx_buf++); else @@ -278,7 +278,7 @@ mpc52xx_spi_fsmstate_wait(int irq, struct mpc52xx_spi *ms, u8 status, u8 data) dev_err(&ms->master->dev, "spurious irq, status=0x%.2x\n", status); - if (((int)get_tbl()) - ms->timestamp < 0) + if (((int)mftb()) - ms->timestamp < 0) return FSM_POLL; ms->message->actual_length += ms->transfer->len; diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 1e470030f918..f081d6634acb 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -980,7 +980,7 @@ static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd) return epir; } -#ifdef CONFIG_CHECKPOINT_RESTORE +#ifdef CONFIG_KCMP static struct epitem *ep_find_tfd(struct eventpoll *ep, int tfd, unsigned long toff) { struct rb_node *rbp; @@ -1022,7 +1022,7 @@ struct file *get_epoll_tfile_raw_ptr(struct file *file, int tfd, return file_raw; } -#endif /* CONFIG_CHECKPOINT_RESTORE */ +#endif /* CONFIG_KCMP */ /** * Adds a new entry to the tail of the list in a lockless way, i.e. diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 96d0da65e088..9aefa7779b29 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -170,6 +170,16 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of, return battr->mmap(of->file, kobj, battr, vma); } +static int sysfs_kf_bin_open(struct kernfs_open_file *of) +{ + struct bin_attribute *battr = of->kn->priv; + + if (battr->mapping) + of->file->f_mapping = battr->mapping; + + return 0; +} + void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr) { struct kernfs_node *kn = kobj->sd, *tmp; @@ -241,6 +251,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = { .read = sysfs_kf_bin_read, .write = sysfs_kf_bin_write, .mmap = sysfs_kf_bin_mmap, + .open = sysfs_kf_bin_open, }; int sysfs_add_file_mode_ns(struct kernfs_node *parent, diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 01a3fd6a64d2..c54adce8f6f6 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -90,10 +90,13 @@ * .data. We don't want to pull in .data..other sections, which Linux * has defined. Same for text and bss. * + * With LTO_CLANG, the linker also splits sections by default, so we need + * these macros to combine the sections during the final link. + * * RODATA_MAIN is not used because existing code already defines .rodata.x * sections to be brought in with rodata. */ -#ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION +#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) #define TEXT_MAIN .text .text.[0-9a-zA-Z_]* #define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral* .data.$__unnamed_* .data.$Lubsan_* #define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]* @@ -494,27 +497,6 @@ __stop___ksymtab_gpl = .; \ } \ \ - /* Kernel symbol table: Normal unused symbols */ \ - __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \ - __start___ksymtab_unused = .; \ - KEEP(*(SORT(___ksymtab_unused+*))) \ - __stop___ksymtab_unused = .; \ - } \ - \ - /* Kernel symbol table: GPL-only unused symbols */ \ - __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \ - __start___ksymtab_unused_gpl = .; \ - KEEP(*(SORT(___ksymtab_unused_gpl+*))) \ - __stop___ksymtab_unused_gpl = .; \ - } \ - \ - /* Kernel symbol table: GPL-future-only symbols */ \ - __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \ - __start___ksymtab_gpl_future = .; \ - KEEP(*(SORT(___ksymtab_gpl_future+*))) \ - __stop___ksymtab_gpl_future = .; \ - } \ - \ /* Kernel symbol table: Normal symbols */ \ __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ __start___kcrctab = .; \ @@ -529,27 +511,6 @@ __stop___kcrctab_gpl = .; \ } \ \ - /* Kernel symbol table: Normal unused symbols */ \ - __kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \ - __start___kcrctab_unused = .; \ - KEEP(*(SORT(___kcrctab_unused+*))) \ - __stop___kcrctab_unused = .; \ - } \ - \ - /* Kernel symbol table: GPL-only unused symbols */ \ - __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \ - __start___kcrctab_unused_gpl = .; \ - KEEP(*(SORT(___kcrctab_unused_gpl+*))) \ - __stop___kcrctab_unused_gpl = .; \ - } \ - \ - /* Kernel symbol table: GPL-future-only symbols */ \ - __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \ - __start___kcrctab_gpl_future = .; \ - KEEP(*(SORT(___kcrctab_gpl_future+*))) \ - __stop___kcrctab_gpl_future = .; \ - } \ - \ /* Kernel symbol table: strings */ \ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ *(__ksymtab_strings) \ diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h index 0350393465d4..593322c946e6 100644 --- a/include/linux/eventpoll.h +++ b/include/linux/eventpoll.h @@ -18,7 +18,7 @@ struct file; #ifdef CONFIG_EPOLL -#ifdef CONFIG_CHECKPOINT_RESTORE +#ifdef CONFIG_KCMP struct file *get_epoll_tfile_raw_ptr(struct file *file, int tfd, unsigned long toff); #endif diff --git a/include/linux/export.h b/include/linux/export.h index b962df3c5dd3..1ad5a07cd136 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -157,18 +157,9 @@ struct kernel_symbol { #define EXPORT_SYMBOL(sym) _EXPORT_SYMBOL(sym, "") #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "_gpl") -#define EXPORT_SYMBOL_GPL_FUTURE(sym) _EXPORT_SYMBOL(sym, "_gpl_future") #define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL(sym, "", #ns) #define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL(sym, "_gpl", #ns) -#ifdef CONFIG_UNUSED_SYMBOLS -#define EXPORT_UNUSED_SYMBOL(sym) _EXPORT_SYMBOL(sym, "_unused") -#define EXPORT_UNUSED_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "_unused_gpl") -#else -#define EXPORT_UNUSED_SYMBOL(sym) -#define EXPORT_UNUSED_SYMBOL_GPL(sym) -#endif - #endif /* !__ASSEMBLY__ */ #endif /* _LINUX_EXPORT_H */ diff --git a/include/linux/init.h b/include/linux/init.h index e668832ef66a..a01f01c1a5c5 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -184,19 +184,80 @@ extern bool initcall_debug; * as KEEP() in the linker script. */ +/* Format: ____ */ +#define __initcall_id(fn) \ + __PASTE(__KBUILD_MODNAME, \ + __PASTE(__, \ + __PASTE(__COUNTER__, \ + __PASTE(_, \ + __PASTE(__LINE__, \ + __PASTE(_, fn)))))) + +/* Format: ____ */ +#define __initcall_name(prefix, __iid, id) \ + __PASTE(__, \ + __PASTE(prefix, \ + __PASTE(__, \ + __PASTE(__iid, id)))) + +#ifdef CONFIG_LTO_CLANG +/* + * With LTO, the compiler doesn't necessarily obey link order for + * initcalls. In order to preserve the correct order, we add each + * variable into its own section and generate a linker script (in + * scripts/link-vmlinux.sh) to specify the order of the sections. + */ +#define __initcall_section(__sec, __iid) \ + #__sec ".init.." #__iid + +/* + * With LTO, the compiler can rename static functions to avoid + * global naming collisions. We use a global stub function for + * initcalls to create a stable symbol name whose address can be + * taken in inline assembly when PREL32 relocations are used. + */ +#define __initcall_stub(fn, __iid, id) \ + __initcall_name(initstub, __iid, id) + +#define __define_initcall_stub(__stub, fn) \ + int __init __stub(void); \ + int __init __stub(void) \ + { \ + return fn(); \ + } \ + __ADDRESSABLE(__stub) +#else +#define __initcall_section(__sec, __iid) \ + #__sec ".init" + +#define __initcall_stub(fn, __iid, id) fn + +#define __define_initcall_stub(__stub, fn) \ + __ADDRESSABLE(fn) +#endif + #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS -#define ___define_initcall(fn, id, __sec) \ - __ADDRESSABLE(fn) \ - asm(".section \"" #__sec ".init\", \"a\" \n" \ - "__initcall_" #fn #id ": \n" \ - ".long " #fn " - . \n" \ +#define ____define_initcall(fn, __stub, __name, __sec) \ + __define_initcall_stub(__stub, fn) \ + asm(".section \"" __sec "\", \"a\" \n" \ + __stringify(__name) ": \n" \ + ".long " __stringify(__stub) " - . \n" \ ".previous \n"); #else -#define ___define_initcall(fn, id, __sec) \ - static initcall_t __initcall_##fn##id __used \ - __attribute__((__section__(#__sec ".init"))) = fn; +#define ____define_initcall(fn, __unused, __name, __sec) \ + static initcall_t __name __used \ + __attribute__((__section__(__sec))) = fn; #endif +#define __unique_initcall(fn, id, __sec, __iid) \ + ____define_initcall(fn, \ + __initcall_stub(fn, __iid, id), \ + __initcall_name(initcall, __iid, id), \ + __initcall_section(__sec, __iid)) + +#define ___define_initcall(fn, id, __sec) \ + __unique_initcall(fn, id, __sec, __initcall_id(fn)) + #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) /* @@ -236,7 +297,7 @@ extern bool initcall_debug; #define __exitcall(fn) \ static exitcall_t __exitcall_##fn __exit_call = fn -#define console_initcall(fn) ___define_initcall(fn,, .con_initcall) +#define console_initcall(fn) ___define_initcall(fn, con, .con_initcall) struct obs_kernel_param { const char *str; diff --git a/include/linux/ioport.h b/include/linux/ioport.h index fe48b7840665..55de385c839c 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -334,11 +334,7 @@ static inline void irqresource_disabled(struct resource *res, u32 irq) res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; } -#ifdef CONFIG_IO_STRICT_DEVMEM -void revoke_devmem(struct resource *res); -#else -static inline void revoke_devmem(struct resource *res) { }; -#endif +extern struct address_space *iomem_get_mapping(void); #endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */ diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 481273f0c72d..465060acc981 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -71,15 +71,14 @@ static inline void *dereference_symbol_descriptor(void *ptr) return ptr; } -#ifdef CONFIG_KALLSYMS -/* Lookup the address for a symbol. Returns 0 if not found. */ -unsigned long kallsyms_lookup_name(const char *name); - -/* Call a function on each kallsyms symbol in the core kernel */ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, unsigned long), void *data); +#ifdef CONFIG_KALLSYMS +/* Lookup the address for a symbol. Returns 0 if not found. */ +unsigned long kallsyms_lookup_name(const char *name); + extern int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, unsigned long *offset); @@ -108,14 +107,6 @@ static inline unsigned long kallsyms_lookup_name(const char *name) return 0; } -static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *, - struct module *, - unsigned long), - void *data) -{ - return 0; -} - static inline int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, unsigned long *offset) diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h index 9d12c970f18f..e78e17a76dc9 100644 --- a/include/linux/kconfig.h +++ b/include/linux/kconfig.h @@ -72,4 +72,10 @@ */ #define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option)) +/* + * IF_ENABLED(CONFIG_FOO, ptr) evaluates to (ptr) if CONFIG_FOO is set to 'y' + * or 'm', NULL otherwise. + */ +#define IF_ENABLED(option, ptr) (IS_ENABLED(option) ? (ptr) : NULL) + #endif /* __LINUX_KCONFIG_H */ diff --git a/include/linux/mm.h b/include/linux/mm.h index b161ded1a80d..08956ca8e653 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -593,7 +593,8 @@ struct vm_operations_struct { vm_fault_t (*pfn_mkwrite)(struct vm_fault *vmf); /* called by access_process_vm when get_user_pages() fails, typically - * for use by special VMAs that can switch between memory and hardware + * for use by special VMAs. See also generic_access_phys() for a generic + * implementation useful for any iomem mapping. */ int (*access)(struct vm_area_struct *vma, unsigned long addr, void *buf, int len, int write); @@ -1761,48 +1762,6 @@ int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc); int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc, struct task_struct *task, bool bypass_rlim); -/* Container for pinned pfns / pages */ -struct frame_vector { - unsigned int nr_allocated; /* Number of frames we have space for */ - unsigned int nr_frames; /* Number of frames stored in ptrs array */ - bool got_ref; /* Did we pin pages by getting page ref? */ - bool is_pfns; /* Does array contain pages or pfns? */ - void *ptrs[]; /* Array of pinned pfns / pages. Use - * pfns_vector_pages() or pfns_vector_pfns() - * for access */ -}; - -struct frame_vector *frame_vector_create(unsigned int nr_frames); -void frame_vector_destroy(struct frame_vector *vec); -int get_vaddr_frames(unsigned long start, unsigned int nr_pfns, - unsigned int gup_flags, struct frame_vector *vec); -void put_vaddr_frames(struct frame_vector *vec); -int frame_vector_to_pages(struct frame_vector *vec); -void frame_vector_to_pfns(struct frame_vector *vec); - -static inline unsigned int frame_vector_count(struct frame_vector *vec) -{ - return vec->nr_frames; -} - -static inline struct page **frame_vector_pages(struct frame_vector *vec) -{ - if (vec->is_pfns) { - int err = frame_vector_to_pages(vec); - - if (err) - return ERR_PTR(err); - } - return (struct page **)(vec->ptrs); -} - -static inline unsigned long *frame_vector_pfns(struct frame_vector *vec) -{ - if (!vec->is_pfns) - frame_vector_to_pfns(vec); - return (unsigned long *)(vec->ptrs); -} - struct kvec; int get_kernel_pages(const struct kvec *iov, int nr_pages, int write, struct page **pages); diff --git a/include/linux/module.h b/include/linux/module.h index dbe7eaec42a5..3cfbc90677ed 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -393,18 +393,6 @@ struct module { const s32 *gpl_crcs; bool using_gplonly_symbols; -#ifdef CONFIG_UNUSED_SYMBOLS - /* unused exported symbols. */ - const struct kernel_symbol *unused_syms; - const s32 *unused_crcs; - unsigned int num_unused_syms; - - /* GPL-only, unused exported symbols. */ - unsigned int num_unused_gpl_syms; - const struct kernel_symbol *unused_gpl_syms; - const s32 *unused_gpl_crcs; -#endif - /* * Signature was verified. Unconditionally compiled in Android to * preserve ABI compatibility between kernels without module @@ -414,11 +402,6 @@ struct module { bool async_probe_requested; - /* symbols that will be GPL-only in the near future. */ - const struct kernel_symbol *gpl_future_syms; - const s32 *gpl_future_crcs; - unsigned int num_gpl_future_syms; - /* Exception table */ unsigned int num_exentries; struct exception_table_entry *extable; @@ -553,8 +536,6 @@ static inline unsigned long kallsyms_symbol_value(const Elf_Sym *sym) } #endif -extern struct mutex module_mutex; - /* FIXME: It'd be nice to isolate modules during init, too, so they aren't used before they (may) fail. But presently too much code (IDE & SCSI) require entry into the module during init.*/ @@ -589,20 +570,9 @@ static inline bool within_module(unsigned long addr, const struct module *mod) return within_module_init(addr, mod) || within_module_core(addr, mod); } -/* Search for module by name: must hold module_mutex. */ +/* Search for module by name: must be in a RCU-sched critical section. */ struct module *find_module(const char *name); -struct symsearch { - const struct kernel_symbol *start, *stop; - const s32 *crcs; - enum mod_license { - NOT_GPL_ONLY, - GPL_ONLY, - WILL_BE_GPL_ONLY, - } license; - bool unused; -}; - /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if symnum out of range. */ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, @@ -611,10 +581,6 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, /* Look for this name: can be of form module:name. */ unsigned long module_kallsyms_lookup_name(const char *name); -int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, - struct module *, unsigned long), - void *data); - extern void __noreturn __module_put_and_exit(struct module *mod, long code); #define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code) @@ -798,14 +764,6 @@ static inline unsigned long module_kallsyms_lookup_name(const char *name) return 0; } -static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, - struct module *, - unsigned long), - void *data) -{ - return 0; -} - static inline int register_module_notifier(struct notifier_block *nb) { /* no events will happen anyway, so this can always succeed */ @@ -894,4 +852,8 @@ static inline bool module_sig_ok(struct module *module) } #endif /* CONFIG_MODULE_SIG */ +int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, + struct module *, unsigned long), + void *data); + #endif /* _LINUX_MODULE_H */ diff --git a/include/linux/objtool.h b/include/linux/objtool.h index 577f51436cf9..7e72d975cb76 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -29,11 +29,14 @@ struct unwind_hint { * * UNWIND_HINT_TYPE_REGS_PARTIAL: Used in entry code to indicate that * sp_reg+sp_offset points to the iret return frame. + * + * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function. + * Useful for code which doesn't have an ELF function annotation. */ #define UNWIND_HINT_TYPE_CALL 0 #define UNWIND_HINT_TYPE_REGS 1 #define UNWIND_HINT_TYPE_REGS_PARTIAL 2 -#define UNWIND_HINT_TYPE_RET_OFFSET 3 +#define UNWIND_HINT_TYPE_FUNC 3 #ifdef CONFIG_STACK_VALIDATION @@ -109,6 +112,12 @@ struct unwind_hint { .popsection .endm +.macro STACK_FRAME_NON_STANDARD func:req + .pushsection .discard.func_stack_frame_non_standard, "aw" + .long \func - . + .popsection +.endm + #endif /* __ASSEMBLY__ */ #else /* !CONFIG_STACK_VALIDATION */ @@ -122,6 +131,8 @@ struct unwind_hint { #define ANNOTATE_INTRA_FUNCTION_CALL .macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 .endm +.macro STACK_FRAME_NON_STANDARD func:req +.endm #endif #endif /* CONFIG_STACK_VALIDATION */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 53f4904ee83d..86c799c97b77 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1926,7 +1926,7 @@ enum pci_fixup_pass { }; #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS -#define __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ +#define ___DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ class_shift, hook) \ __ADDRESSABLE(hook) \ asm(".section " #sec ", \"a\" \n" \ @@ -1935,10 +1935,33 @@ enum pci_fixup_pass { ".long " #class ", " #class_shift " \n" \ ".long " #hook " - . \n" \ ".previous \n"); + +/* + * Clang's LTO may rename static functions in C, but has no way to + * handle such renamings when referenced from inline asm. To work + * around this, create global C stubs for these cases. + */ +#ifdef CONFIG_LTO_CLANG +#define __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ + class_shift, hook, stub) \ + void stub(struct pci_dev *dev); \ + void stub(struct pci_dev *dev) \ + { \ + hook(dev); \ + } \ + ___DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ + class_shift, stub) +#else +#define __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ + class_shift, hook, stub) \ + ___DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ + class_shift, hook) +#endif + #define DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ class_shift, hook) \ __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ - class_shift, hook) + class_shift, hook, __UNIQUE_ID(hook)) #else /* Anonymous variables would be nice... */ #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \ diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 2caa34c1ca1a..d76a1ddf83a3 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -164,11 +164,13 @@ __ATTRIBUTE_GROUPS(_name) struct file; struct vm_area_struct; +struct address_space; struct bin_attribute { struct attribute attr; size_t size; void *private; + struct address_space *mapping; ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *, diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 26de0cae2a0a..d15a7730ee18 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -311,7 +311,7 @@ enum { WQ_MEM_RECLAIM = 1 << 3, /* may be used for memory reclaim */ WQ_HIGHPRI = 1 << 4, /* high priority */ WQ_CPU_INTENSIVE = 1 << 5, /* cpu intensive workqueue */ - WQ_SYSFS = 1 << 6, /* visible in sysfs, see wq_sysfs_register() */ + WQ_SYSFS = 1 << 6, /* visible in sysfs, see workqueue_sysfs_register() */ /* * Per-cpu workqueues are generally preferred because they tend to diff --git a/include/media/frame_vector.h b/include/media/frame_vector.h new file mode 100644 index 000000000000..bfed1710dc24 --- /dev/null +++ b/include/media/frame_vector.h @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef _MEDIA_FRAME_VECTOR_H +#define _MEDIA_FRAME_VECTOR_H + +/* Container for pinned pfns / pages in frame_vector.c */ +struct frame_vector { + unsigned int nr_allocated; /* Number of frames we have space for */ + unsigned int nr_frames; /* Number of frames stored in ptrs array */ + bool got_ref; /* Did we pin pages by getting page ref? */ + bool is_pfns; /* Does array contain pages or pfns? */ + void *ptrs[]; /* Array of pinned pfns / pages. Use + * pfns_vector_pages() or pfns_vector_pfns() + * for access */ +}; + +struct frame_vector *frame_vector_create(unsigned int nr_frames); +void frame_vector_destroy(struct frame_vector *vec); +int get_vaddr_frames(unsigned long start, unsigned int nr_pfns, + struct frame_vector *vec); +void put_vaddr_frames(struct frame_vector *vec); +int frame_vector_to_pages(struct frame_vector *vec); +void frame_vector_to_pfns(struct frame_vector *vec); + +static inline unsigned int frame_vector_count(struct frame_vector *vec) +{ + return vec->nr_frames; +} + +static inline struct page **frame_vector_pages(struct frame_vector *vec) +{ + if (vec->is_pfns) { + int err = frame_vector_to_pages(vec); + + if (err) + return ERR_PTR(err); + } + return (struct page **)(vec->ptrs); +} + +static inline unsigned long *frame_vector_pfns(struct frame_vector *vec) +{ + if (!vec->is_pfns) + frame_vector_to_pfns(vec); + return (unsigned long *)(vec->ptrs); +} + +#endif /* _MEDIA_FRAME_VECTOR_H */ diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index a85c97002cc0..5124a640e82d 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -18,6 +18,7 @@ #include #include #include +#include #define VB2_MAX_FRAME (64) #define VB2_MAX_PLANES (8) diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h index 9b8ae961acc5..970cc2ea2850 100644 --- a/include/trace/events/workqueue.h +++ b/include/trace/events/workqueue.h @@ -30,7 +30,7 @@ TRACE_EVENT(workqueue_queue_work, TP_STRUCT__entry( __field( void *, work ) __field( void *, function) - __field( void *, workqueue) + __field( const char *, workqueue) __field( unsigned int, req_cpu ) __field( unsigned int, cpu ) ), @@ -38,12 +38,12 @@ TRACE_EVENT(workqueue_queue_work, TP_fast_assign( __entry->work = work; __entry->function = work->func; - __entry->workqueue = pwq->wq; + __entry->workqueue = pwq->wq->name; __entry->req_cpu = req_cpu; __entry->cpu = pwq->pool->cpu; ), - TP_printk("work struct=%p function=%ps workqueue=%p req_cpu=%u cpu=%u", + TP_printk("work struct=%p function=%ps workqueue=%s req_cpu=%u cpu=%u", __entry->work, __entry->function, __entry->workqueue, __entry->req_cpu, __entry->cpu) ); diff --git a/init/Kconfig b/init/Kconfig index 944d1e9903ad..69962b61179e 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1208,6 +1208,7 @@ endif # NAMESPACES config CHECKPOINT_RESTORE bool "Checkpoint/restore support" select PROC_CHILDREN + select KCMP default n help Enables additional kernel features in a sake of checkpoint/restore. @@ -1762,6 +1763,16 @@ config ARCH_HAS_MEMBARRIER_CALLBACKS config ARCH_HAS_MEMBARRIER_SYNC_CORE bool +config KCMP + bool "Enable kcmp() system call" if EXPERT + help + Enable the kernel resource comparison system call. It provides + user-space with the ability to compare two processes to see if they + share a common resource, such as a file descriptor or even virtual + memory space. + + If unsure, say N. + config RSEQ bool "Enable rseq() system call" if EXPERT default y @@ -2301,25 +2312,8 @@ config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS If unsure, say N. -config UNUSED_SYMBOLS - bool "Enable unused/obsolete exported symbols" - default y if X86 - help - Unused but exported symbols make the kernel needlessly bigger. For - that reason most of these unused exports will soon be removed. This - option is provided temporarily to provide a transition period in case - some external kernel module needs one of these symbols anyway. If you - encounter such a case in your module, consider if you are actually - using the right API. (rationale: since nobody in the kernel is using - this in a module, there is a pretty good chance it's actually the - wrong interface to use). If you really need the symbol, please send a - mail to the linux kernel mailing list mentioning the symbol and why - you really need it, and what the merge plan to the mainline kernel for - your module is. - config TRIM_UNUSED_KSYMS bool "Trim unused exported kernel symbols" - depends on !UNUSED_SYMBOLS help The kernel and some modules make many symbols available for other modules to use via EXPORT_SYMBOL() and variants. Depending @@ -2336,6 +2330,7 @@ config TRIM_UNUSED_KSYMS config UNUSED_KSYMS_WHITELIST string "Whitelist of symbols to keep in ksymtab" depends on TRIM_UNUSED_KSYMS + default "scripts/lto-used-symbollist.txt" if LTO_CLANG help By default, all unused exported symbols will be un-exported from the build when TRIM_UNUSED_KSYMS is selected. diff --git a/kernel/Makefile b/kernel/Makefile index aa7368c7eabf..320f1f3941b7 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -51,7 +51,7 @@ obj-y += livepatch/ obj-y += dma/ obj-y += entry/ -obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o +obj-$(CONFIG_KCMP) += kcmp.o obj-$(CONFIG_FREEZER) += freezer.o obj-$(CONFIG_PROFILING) += profile.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 2cdb4701c639..d08ca2605865 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -4731,8 +4731,8 @@ static int cgroup_attach_permissions(struct cgroup *src_cgrp, return ret; } -static ssize_t cgroup_procs_write(struct kernfs_open_file *of, - char *buf, size_t nbytes, loff_t off) +static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, + bool threadgroup) { struct cgroup *src_cgrp, *dst_cgrp; struct task_struct *task; @@ -4743,7 +4743,7 @@ static ssize_t cgroup_procs_write(struct kernfs_open_file *of, if (!dst_cgrp) return -ENODEV; - task = cgroup_procs_write_start(buf, true, &locked); + task = cgroup_procs_write_start(buf, threadgroup, &locked); ret = PTR_ERR_OR_ZERO(task); if (ret) goto out_unlock; @@ -4753,19 +4753,26 @@ static ssize_t cgroup_procs_write(struct kernfs_open_file *of, src_cgrp = task_cgroup_from_root(task, &cgrp_dfl_root); spin_unlock_irq(&css_set_lock); + /* process and thread migrations follow same delegation rule */ ret = cgroup_attach_permissions(src_cgrp, dst_cgrp, - of->file->f_path.dentry->d_sb, true); + of->file->f_path.dentry->d_sb, threadgroup); if (ret) goto out_finish; - ret = cgroup_attach_task(dst_cgrp, task, true); + ret = cgroup_attach_task(dst_cgrp, task, threadgroup); out_finish: cgroup_procs_write_finish(task, locked); out_unlock: cgroup_kn_unlock(of->kn); - return ret ?: nbytes; + return ret; +} + +static ssize_t cgroup_procs_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + return __cgroup_procs_write(of, buf, true) ?: nbytes; } static void *cgroup_threads_start(struct seq_file *s, loff_t *pos) @@ -4776,41 +4783,7 @@ static void *cgroup_threads_start(struct seq_file *s, loff_t *pos) static ssize_t cgroup_threads_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { - struct cgroup *src_cgrp, *dst_cgrp; - struct task_struct *task; - ssize_t ret; - bool locked; - - buf = strstrip(buf); - - dst_cgrp = cgroup_kn_lock_live(of->kn, false); - if (!dst_cgrp) - return -ENODEV; - - task = cgroup_procs_write_start(buf, false, &locked); - ret = PTR_ERR_OR_ZERO(task); - if (ret) - goto out_unlock; - - /* find the source cgroup */ - spin_lock_irq(&css_set_lock); - src_cgrp = task_cgroup_from_root(task, &cgrp_dfl_root); - spin_unlock_irq(&css_set_lock); - - /* thread migrations follow the cgroup.procs delegation rule */ - ret = cgroup_attach_permissions(src_cgrp, dst_cgrp, - of->file->f_path.dentry->d_sb, false); - if (ret) - goto out_finish; - - ret = cgroup_attach_task(dst_cgrp, task, false); - -out_finish: - cgroup_procs_write_finish(task, locked); -out_unlock: - cgroup_kn_unlock(of->kn); - - return ret ?: nbytes; + return __cgroup_procs_write(of, buf, false) ?: nbytes; } /* cgroup core interface files for the default hierarchy */ diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 90699fd817a7..2565178e069d 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -100,7 +100,7 @@ struct cpuset { * and if it ends up empty, it will inherit the parent's mask. * * - * On legacy hierachy: + * On legacy hierarchy: * * The user-configured masks are always the same with effective masks. */ @@ -1320,10 +1320,10 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd, * @cs: the cpuset to consider * @tmp: temp variables for calculating effective_cpus & partition setup * - * When congifured cpumask is changed, the effective cpumasks of this cpuset + * When configured cpumask is changed, the effective cpumasks of this cpuset * and all its descendants need to be updated. * - * On legacy hierachy, effective_cpus will be the same with cpu_allowed. + * On legacy hierarchy, effective_cpus will be the same with cpu_allowed. * * Called with cpuset_mutex held */ diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index fe9de067771c..8043a90aa50e 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -177,6 +177,11 @@ unsigned long kallsyms_lookup_name(const char *name) return module_kallsyms_lookup_name(name); } +#ifdef CONFIG_LIVEPATCH +/* + * Iterate over all symbols in vmlinux. For symbols from modules use + * module_kallsyms_on_each_symbol instead. + */ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, unsigned long), void *data) @@ -192,8 +197,9 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, if (ret != 0) return ret; } - return module_kallsyms_on_each_symbol(fn, data); + return 0; } +#endif /* CONFIG_LIVEPATCH */ static unsigned long get_symbol_pos(unsigned long addr, unsigned long *symbolsize, diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index f76fdb925532..335d988bd811 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "core.h" #include "patch.h" @@ -57,7 +58,7 @@ static void klp_find_object_module(struct klp_object *obj) if (!klp_is_module(obj)) return; - mutex_lock(&module_mutex); + rcu_read_lock_sched(); /* * We do not want to block removal of patched modules and therefore * we do not take a reference here. The patches are removed by @@ -74,7 +75,7 @@ static void klp_find_object_module(struct klp_object *obj) if (mod && mod->klp_alive) obj->mod = mod; - mutex_unlock(&module_mutex); + rcu_read_unlock_sched(); } static bool klp_initialized(void) @@ -163,12 +164,10 @@ static int klp_find_object_symbol(const char *objname, const char *name, .pos = sympos, }; - mutex_lock(&module_mutex); if (objname) module_kallsyms_on_each_symbol(klp_find_callback, &args); else kallsyms_on_each_symbol(klp_find_callback, &args); - mutex_unlock(&module_mutex); /* * Ensure an address was found. If sympos is 0, ensure symbol is unique; diff --git a/kernel/module.c b/kernel/module.c index d0b359c7e9c9..62822b4a246a 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -87,8 +87,7 @@ * 3) module_addr_min/module_addr_max. * (delete and add uses RCU list operations). */ -DEFINE_MUTEX(module_mutex); -EXPORT_SYMBOL_GPL(module_mutex); +static DEFINE_MUTEX(module_mutex); static LIST_HEAD(modules); /* Work queue for freeing init sections in success case */ @@ -256,11 +255,6 @@ static void mod_update_bounds(struct module *mod) struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ #endif /* CONFIG_KGDB_KDB */ -static void module_assert_mutex(void) -{ - lockdep_assert_held(&module_mutex); -} - static void module_assert_mutex_or_preempt(void) { #ifdef CONFIG_LOCKDEP @@ -414,19 +408,8 @@ extern const struct kernel_symbol __start___ksymtab[]; extern const struct kernel_symbol __stop___ksymtab[]; extern const struct kernel_symbol __start___ksymtab_gpl[]; extern const struct kernel_symbol __stop___ksymtab_gpl[]; -extern const struct kernel_symbol __start___ksymtab_gpl_future[]; -extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; extern const s32 __start___kcrctab[]; extern const s32 __start___kcrctab_gpl[]; -extern const s32 __start___kcrctab_gpl_future[]; -#ifdef CONFIG_UNUSED_SYMBOLS -extern const struct kernel_symbol __start___ksymtab_unused[]; -extern const struct kernel_symbol __stop___ksymtab_unused[]; -extern const struct kernel_symbol __start___ksymtab_unused_gpl[]; -extern const struct kernel_symbol __stop___ksymtab_unused_gpl[]; -extern const s32 __start___kcrctab_unused[]; -extern const s32 __start___kcrctab_unused_gpl[]; -#endif #ifndef CONFIG_MODVERSIONS #define symversion(base, idx) NULL @@ -434,87 +417,14 @@ extern const s32 __start___kcrctab_unused_gpl[]; #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL) #endif -static bool each_symbol_in_section(const struct symsearch *arr, - unsigned int arrsize, - struct module *owner, - bool (*fn)(const struct symsearch *syms, - struct module *owner, - void *data), - void *data) -{ - unsigned int j; - - for (j = 0; j < arrsize; j++) { - if (fn(&arr[j], owner, data)) - return true; - } - - return false; -} - -/* Returns true as soon as fn returns true, otherwise false. */ -static bool each_symbol_section(bool (*fn)(const struct symsearch *arr, - struct module *owner, - void *data), - void *data) -{ - struct module *mod; - static const struct symsearch arr[] = { - { __start___ksymtab, __stop___ksymtab, __start___kcrctab, - NOT_GPL_ONLY, false }, - { __start___ksymtab_gpl, __stop___ksymtab_gpl, - __start___kcrctab_gpl, - GPL_ONLY, false }, - { __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future, - __start___kcrctab_gpl_future, - WILL_BE_GPL_ONLY, false }, -#ifdef CONFIG_UNUSED_SYMBOLS - { __start___ksymtab_unused, __stop___ksymtab_unused, - __start___kcrctab_unused, - NOT_GPL_ONLY, true }, - { __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl, - __start___kcrctab_unused_gpl, - GPL_ONLY, true }, -#endif - }; - - module_assert_mutex_or_preempt(); - - if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data)) - return true; - - list_for_each_entry_rcu(mod, &modules, list, - lockdep_is_held(&module_mutex)) { - struct symsearch arr[] = { - { mod->syms, mod->syms + mod->num_syms, mod->crcs, - NOT_GPL_ONLY, false }, - { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms, - mod->gpl_crcs, - GPL_ONLY, false }, - { mod->gpl_future_syms, - mod->gpl_future_syms + mod->num_gpl_future_syms, - mod->gpl_future_crcs, - WILL_BE_GPL_ONLY, false }, -#ifdef CONFIG_UNUSED_SYMBOLS - { mod->unused_syms, - mod->unused_syms + mod->num_unused_syms, - mod->unused_crcs, - NOT_GPL_ONLY, true }, - { mod->unused_gpl_syms, - mod->unused_gpl_syms + mod->num_unused_gpl_syms, - mod->unused_gpl_crcs, - GPL_ONLY, true }, -#endif - }; - - if (mod->state == MODULE_STATE_UNFORMED) - continue; - - if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data)) - return true; - } - return false; -} +struct symsearch { + const struct kernel_symbol *start, *stop; + const s32 *crcs; + enum mod_license { + NOT_GPL_ONLY, + GPL_ONLY, + } license; +}; struct find_symbol_arg { /* Input */ @@ -535,28 +445,8 @@ static bool check_exported_symbol(const struct symsearch *syms, { struct find_symbol_arg *fsa = data; - if (!fsa->gplok) { - if (syms->license == GPL_ONLY) - return false; - if (syms->license == WILL_BE_GPL_ONLY && fsa->warn) { - pr_warn("Symbol %s is being used by a non-GPL module, " - "which will not be allowed in the future\n", - fsa->name); - } - } - -#ifdef CONFIG_UNUSED_SYMBOLS - if (syms->unused && fsa->warn) { - pr_warn("Symbol %s is marked as UNUSED, however this module is " - "using it.\n", fsa->name); - pr_warn("This symbol will go away in the future.\n"); - pr_warn("Please evaluate if this is the right api to use and " - "if it really is, submit a report to the linux kernel " - "mailing list together with submitting your code for " - "inclusion.\n"); - } -#endif - + if (!fsa->gplok && syms->license == GPL_ONLY) + return false; fsa->owner = owner; fsa->crc = symversion(syms->crcs, symnum); fsa->sym = &syms->start[symnum]; @@ -619,31 +509,44 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms, * Find an exported symbol and return it, along with, (optional) crc and * (optional) module which owns it. Needs preempt disabled or module_mutex. */ -static const struct kernel_symbol *find_symbol(const char *name, - struct module **owner, - const s32 **crc, - enum mod_license *license, - bool gplok, - bool warn) +static bool find_symbol(struct find_symbol_arg *fsa) { - struct find_symbol_arg fsa; + static const struct symsearch arr[] = { + { __start___ksymtab, __stop___ksymtab, __start___kcrctab, + NOT_GPL_ONLY }, + { __start___ksymtab_gpl, __stop___ksymtab_gpl, + __start___kcrctab_gpl, + GPL_ONLY }, + }; + struct module *mod; + unsigned int i; - fsa.name = name; - fsa.gplok = gplok; - fsa.warn = warn; + module_assert_mutex_or_preempt(); - if (each_symbol_section(find_exported_symbol_in_section, &fsa)) { - if (owner) - *owner = fsa.owner; - if (crc) - *crc = fsa.crc; - if (license) - *license = fsa.license; - return fsa.sym; + for (i = 0; i < ARRAY_SIZE(arr); i++) + if (find_exported_symbol_in_section(&arr[i], NULL, fsa)) + return true; + + list_for_each_entry_rcu(mod, &modules, list, + lockdep_is_held(&module_mutex)) { + struct symsearch arr[] = { + { mod->syms, mod->syms + mod->num_syms, mod->crcs, + NOT_GPL_ONLY }, + { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms, + mod->gpl_crcs, + GPL_ONLY }, + }; + + if (mod->state == MODULE_STATE_UNFORMED) + continue; + + for (i = 0; i < ARRAY_SIZE(arr); i++) + if (find_exported_symbol_in_section(&arr[i], mod, fsa)) + return true; } - pr_debug("Failed to find symbol %s\n", name); - return NULL; + pr_debug("Failed to find symbol %s\n", fsa->name); + return false; } /* @@ -669,10 +572,8 @@ static struct module *find_module_all(const char *name, size_t len, struct module *find_module(const char *name) { - module_assert_mutex(); return find_module_all(name, strlen(name), false); } -EXPORT_SYMBOL_GPL(find_module); #ifdef CONFIG_SMP @@ -1108,12 +1009,15 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod) void __symbol_put(const char *symbol) { - struct module *owner; + struct find_symbol_arg fsa = { + .name = symbol, + .gplok = true, + }; preempt_disable(); - if (!find_symbol(symbol, &owner, NULL, NULL, true, false)) + if (!find_symbol(&fsa)) BUG(); - module_put(owner); + module_put(fsa.owner); preempt_enable(); } EXPORT_SYMBOL(__symbol_put); @@ -1383,19 +1287,22 @@ bad_version: static inline int check_modstruct_version(const struct load_info *info, struct module *mod) { - const s32 *crc; + struct find_symbol_arg fsa = { + .name = "module_layout", + .gplok = true, + }; /* * Since this should be found in kernel (which can't be removed), no * locking is necessary -- use preempt_disable() to placate lockdep. */ preempt_disable(); - if (!find_symbol("module_layout", NULL, &crc, NULL, true, false)) { + if (!find_symbol(&fsa)) { preempt_enable(); BUG(); } preempt_enable(); - return check_version(info, "module_layout", mod, crc); + return check_version(info, "module_layout", mod, fsa.crc); } /* First part is kernel version, which we ignore if module has crcs. */ @@ -1489,10 +1396,11 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod, const char *name, char ownername[]) { - struct module *owner; - const struct kernel_symbol *sym; - const s32 *crc; - enum mod_license license; + struct find_symbol_arg fsa = { + .name = name, + .gplok = !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), + .warn = true, + }; int err; /* @@ -1502,42 +1410,40 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod, */ sched_annotate_sleep(); mutex_lock(&module_mutex); - sym = find_symbol(name, &owner, &crc, &license, - !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); - if (!sym) + if (!find_symbol(&fsa)) goto unlock; - if (license == GPL_ONLY) + if (fsa.license == GPL_ONLY) mod->using_gplonly_symbols = true; - if (!inherit_taint(mod, owner)) { - sym = NULL; + if (!inherit_taint(mod, fsa.owner)) { + fsa.sym = NULL; goto getname; } - if (!check_version(info, name, mod, crc)) { - sym = ERR_PTR(-EINVAL); + if (!check_version(info, name, mod, fsa.crc)) { + fsa.sym = ERR_PTR(-EINVAL); goto getname; } - err = verify_namespace_is_imported(info, sym, mod); + err = verify_namespace_is_imported(info, fsa.sym, mod); if (err) { - sym = ERR_PTR(err); + fsa.sym = ERR_PTR(err); goto getname; } - err = ref_module(mod, owner); + err = ref_module(mod, fsa.owner); if (err) { - sym = ERR_PTR(err); + fsa.sym = ERR_PTR(err); goto getname; } getname: /* We must make copy under the lock if we failed to get ref. */ - strncpy(ownername, module_name(owner), MODULE_NAME_LEN); + strncpy(ownername, module_name(fsa.owner), MODULE_NAME_LEN); unlock: mutex_unlock(&module_mutex); - return sym; + return fsa.sym; } static const struct kernel_symbol * @@ -2298,16 +2204,19 @@ static void free_module(struct module *mod) void *__symbol_get(const char *symbol) { - struct module *owner; - const struct kernel_symbol *sym; + struct find_symbol_arg fsa = { + .name = symbol, + .gplok = true, + .warn = true, + }; preempt_disable(); - sym = find_symbol(symbol, &owner, NULL, NULL, true, true); - if (sym && strong_try_module_get(owner)) - sym = NULL; + if (!find_symbol(&fsa) || strong_try_module_get(fsa.owner)) { + preempt_enable(); + return NULL; + } preempt_enable(); - - return sym ? (void *)kernel_symbol_value(sym) : NULL; + return (void *)kernel_symbol_value(fsa.sym); } EXPORT_SYMBOL_GPL(__symbol_get); @@ -2320,7 +2229,6 @@ EXPORT_SYMBOL_GPL(__symbol_get); static int verify_exported_symbols(struct module *mod) { unsigned int i; - struct module *owner; const struct kernel_symbol *s; struct { const struct kernel_symbol *sym; @@ -2328,21 +2236,19 @@ static int verify_exported_symbols(struct module *mod) } arr[] = { { mod->syms, mod->num_syms }, { mod->gpl_syms, mod->num_gpl_syms }, - { mod->gpl_future_syms, mod->num_gpl_future_syms }, -#ifdef CONFIG_UNUSED_SYMBOLS - { mod->unused_syms, mod->num_unused_syms }, - { mod->unused_gpl_syms, mod->num_unused_gpl_syms }, -#endif }; for (i = 0; i < ARRAY_SIZE(arr); i++) { for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) { - if (find_symbol(kernel_symbol_name(s), &owner, NULL, - NULL, true, false)) { + struct find_symbol_arg fsa = { + .name = kernel_symbol_name(s), + .gplok = true, + }; + if (find_symbol(&fsa)) { pr_err("%s: exports duplicate symbol %s" " (owned by %s)\n", mod->name, kernel_symbol_name(s), - module_name(owner)); + module_name(fsa.owner)); return -ENOEXEC; } } @@ -2350,6 +2256,21 @@ static int verify_exported_symbols(struct module *mod) return 0; } +static bool ignore_undef_symbol(Elf_Half emachine, const char *name) +{ + /* + * On x86, PIC code and Clang non-PIC code may have call foo@PLT. GNU as + * before 2.37 produces an unreferenced _GLOBAL_OFFSET_TABLE_ on x86-64. + * i386 has a similar problem but may not deserve a fix. + * + * If we ever have to ignore many symbols, consider refactoring the code to + * only warn if referenced by a relocation. + */ + if (emachine == EM_386 || emachine == EM_X86_64) + return !strcmp(name, "_GLOBAL_OFFSET_TABLE_"); + return false; +} + /* Change all symbols so that st_value encodes the pointer directly. */ static int simplify_symbols(struct module *mod, const struct load_info *info) { @@ -2397,8 +2318,10 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) break; } - /* Ok if weak. */ - if (!ksym && ELF_ST_BIND(sym[i].st_info) == STB_WEAK) + /* Ok if weak or ignored. */ + if (!ksym && + (ELF_ST_BIND(sym[i].st_info) == STB_WEAK || + ignore_undef_symbol(info->hdr->e_machine, name))) break; ret = PTR_ERR(ksym) ?: -ENOENT; @@ -2966,7 +2889,7 @@ static int module_sig_check(struct load_info *info, int flags) } if (is_module_sig_enforced()) { - pr_notice("%s: loading of %s is rejected\n", info->name, reason); + pr_notice("Loading of %s is rejected\n", reason); return -EKEYREJECTED; } @@ -2979,9 +2902,33 @@ static int module_sig_check(struct load_info *info, int flags) } #endif /* !CONFIG_MODULE_SIG */ -/* Sanity checks against invalid binaries, wrong arch, weird elf version. */ -static int elf_header_check(struct load_info *info) +static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr) { + unsigned long secend; + + /* + * Check for both overflow and offset/size being + * too large. + */ + secend = shdr->sh_offset + shdr->sh_size; + if (secend < shdr->sh_offset || secend > info->len) + return -ENOEXEC; + + return 0; +} + +/* + * Sanity checks against invalid binaries, wrong arch, weird elf version. + * + * Also do basic validity checks against section offsets and sizes, the + * section name string table, and the indices used for it (sh_name). + */ +static int elf_validity_check(struct load_info *info) +{ + unsigned int i; + Elf_Shdr *shdr, *strhdr; + int err; + if (info->len < sizeof(*(info->hdr))) return -ENOEXEC; @@ -2991,11 +2938,78 @@ static int elf_header_check(struct load_info *info) || info->hdr->e_shentsize != sizeof(Elf_Shdr)) return -ENOEXEC; + /* + * e_shnum is 16 bits, and sizeof(Elf_Shdr) is + * known and small. So e_shnum * sizeof(Elf_Shdr) + * will not overflow unsigned long on any platform. + */ if (info->hdr->e_shoff >= info->len || (info->hdr->e_shnum * sizeof(Elf_Shdr) > info->len - info->hdr->e_shoff)) return -ENOEXEC; + info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; + + /* + * Verify if the section name table index is valid. + */ + if (info->hdr->e_shstrndx == SHN_UNDEF + || info->hdr->e_shstrndx >= info->hdr->e_shnum) + return -ENOEXEC; + + strhdr = &info->sechdrs[info->hdr->e_shstrndx]; + err = validate_section_offset(info, strhdr); + if (err < 0) + return err; + + /* + * The section name table must be NUL-terminated, as required + * by the spec. This makes strcmp and pr_* calls that access + * strings in the section safe. + */ + info->secstrings = (void *)info->hdr + strhdr->sh_offset; + if (info->secstrings[strhdr->sh_size - 1] != '\0') + return -ENOEXEC; + + /* + * The code assumes that section 0 has a length of zero and + * an addr of zero, so check for it. + */ + if (info->sechdrs[0].sh_type != SHT_NULL + || info->sechdrs[0].sh_size != 0 + || info->sechdrs[0].sh_addr != 0) + return -ENOEXEC; + + for (i = 1; i < info->hdr->e_shnum; i++) { + shdr = &info->sechdrs[i]; + switch (shdr->sh_type) { + case SHT_NULL: + case SHT_NOBITS: + continue; + case SHT_SYMTAB: + if (shdr->sh_link == SHN_UNDEF + || shdr->sh_link >= info->hdr->e_shnum) + return -ENOEXEC; + fallthrough; + default: + err = validate_section_offset(info, shdr); + if (err < 0) { + pr_err("Invalid ELF section in module (section %u type %u)\n", + i, shdr->sh_type); + return err; + } + + if (shdr->sh_flags & SHF_ALLOC) { + if (shdr->sh_name >= strhdr->sh_size) { + pr_err("Invalid ELF section name in module (section %u type %u)\n", + i, shdr->sh_type); + return -ENOEXEC; + } + } + break; + } + } + return 0; } @@ -3097,11 +3111,6 @@ static int rewrite_section_headers(struct load_info *info, int flags) for (i = 1; i < info->hdr->e_shnum; i++) { Elf_Shdr *shdr = &info->sechdrs[i]; - if (shdr->sh_type != SHT_NOBITS - && info->len < shdr->sh_offset + shdr->sh_size) { - pr_err("Module len %lu truncated\n", info->len); - return -ENOEXEC; - } /* * Mark all sections sh_addr with their address in the @@ -3135,11 +3144,6 @@ static int setup_load_info(struct load_info *info, int flags) { unsigned int i; - /* Set up the convenience variables */ - info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; - info->secstrings = (void *)info->hdr - + info->sechdrs[info->hdr->e_shstrndx].sh_offset; - /* Try to find a name early so we can log errors with a module name */ info->index.info = find_sec(info, ".modinfo"); if (info->index.info) @@ -3243,22 +3247,7 @@ static int find_module_sections(struct module *mod, struct load_info *info) sizeof(*mod->gpl_syms), &mod->num_gpl_syms); mod->gpl_crcs = section_addr(info, "__kcrctab_gpl"); - mod->gpl_future_syms = section_objs(info, - "__ksymtab_gpl_future", - sizeof(*mod->gpl_future_syms), - &mod->num_gpl_future_syms); - mod->gpl_future_crcs = section_addr(info, "__kcrctab_gpl_future"); -#ifdef CONFIG_UNUSED_SYMBOLS - mod->unused_syms = section_objs(info, "__ksymtab_unused", - sizeof(*mod->unused_syms), - &mod->num_unused_syms); - mod->unused_crcs = section_addr(info, "__kcrctab_unused"); - mod->unused_gpl_syms = section_objs(info, "__ksymtab_unused_gpl", - sizeof(*mod->unused_gpl_syms), - &mod->num_unused_gpl_syms); - mod->unused_gpl_crcs = section_addr(info, "__kcrctab_unused_gpl"); -#endif #ifdef CONFIG_CONSTRUCTORS mod->ctors = section_objs(info, ".ctors", sizeof(*mod->ctors), &mod->num_ctors); @@ -3439,14 +3428,8 @@ static int check_module_license_and_versions(struct module *mod) pr_warn("%s: module license taints kernel.\n", mod->name); #ifdef CONFIG_MODVERSIONS - if ((mod->num_syms && !mod->crcs) - || (mod->num_gpl_syms && !mod->gpl_crcs) - || (mod->num_gpl_future_syms && !mod->gpl_future_crcs) -#ifdef CONFIG_UNUSED_SYMBOLS - || (mod->num_unused_syms && !mod->unused_crcs) - || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs) -#endif - ) { + if ((mod->num_syms && !mod->crcs) || + (mod->num_gpl_syms && !mod->gpl_crcs)) { return try_to_force_load(mod, "no versions for exported symbols"); } @@ -3896,26 +3879,50 @@ static int load_module(struct load_info *info, const char __user *uargs, long err = 0; char *after_dashes; - err = elf_header_check(info); + /* + * Do the signature check (if any) first. All that + * the signature check needs is info->len, it does + * not need any of the section info. That can be + * set up later. This will minimize the chances + * of a corrupt module causing problems before + * we even get to the signature check. + * + * The check will also adjust info->len by stripping + * off the sig length at the end of the module, making + * checks against info->len more correct. + */ + err = module_sig_check(info, flags); + if (err) + goto free_copy; + + /* + * Do basic sanity checks against the ELF header and + * sections. + */ + err = elf_validity_check(info); if (err) { - pr_err("Module has invalid ELF header\n"); + pr_err("Module has invalid ELF structures\n"); goto free_copy; } + /* + * Everything checks out, so set up the section info + * in the info structure. + */ err = setup_load_info(info, flags); if (err) goto free_copy; + /* + * Now that we know we have the correct module name, check + * if it's blacklisted. + */ if (blacklisted(info->name)) { err = -EPERM; pr_err("Module %s is blacklisted\n", info->name); goto free_copy; } - err = module_sig_check(info, flags); - if (err) - goto free_copy; - err = rewrite_section_headers(info, flags); if (err) goto free_copy; @@ -4376,16 +4383,16 @@ unsigned long module_kallsyms_lookup_name(const char *name) return ret; } +#ifdef CONFIG_LIVEPATCH int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, unsigned long), void *data) { struct module *mod; unsigned int i; - int ret; - - module_assert_mutex(); + int ret = 0; + mutex_lock(&module_mutex); list_for_each_entry(mod, &modules, list) { /* We hold module_mutex: no need for rcu_dereference_sched */ struct mod_kallsyms *kallsyms = mod->kallsyms; @@ -4401,11 +4408,13 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, ret = fn(data, kallsyms_symbol_name(kallsyms, i), mod, kallsyms_symbol_value(sym)); if (ret != 0) - return ret; + break; } } - return 0; + mutex_unlock(&module_mutex); + return ret; } +#endif /* CONFIG_LIVEPATCH */ #endif /* CONFIG_KALLSYMS */ /* Maximum number of characters written by module_flags() */ diff --git a/kernel/module_signature.c b/kernel/module_signature.c index 4224a1086b7d..00132d12487c 100644 --- a/kernel/module_signature.c +++ b/kernel/module_signature.c @@ -25,7 +25,7 @@ int mod_check_sig(const struct module_signature *ms, size_t file_len, return -EBADMSG; if (ms->id_type != PKEY_ID_PKCS7) { - pr_err("%s: Module is not signed with expected PKCS#7 message\n", + pr_err("%s: not signed with expected PKCS#7 message\n", name); return -ENOPKG; } diff --git a/kernel/module_signing.c b/kernel/module_signing.c index 9d9fc678c91d..8723ae70ea1f 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c @@ -30,7 +30,7 @@ int mod_verify_sig(const void *mod, struct load_info *info) memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); - ret = mod_check_sig(&ms, modlen, info->name); + ret = mod_check_sig(&ms, modlen, "module"); if (ret) return ret; diff --git a/kernel/resource.c b/kernel/resource.c index 833394f9c608..627e61b0c124 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -18,12 +18,15 @@ #include #include #include +#include #include #include #include #include #include +#include #include +#include #include @@ -1119,6 +1122,55 @@ resource_size_t resource_alignment(struct resource *res) static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait); +static struct inode *iomem_inode; + +#ifdef CONFIG_IO_STRICT_DEVMEM +static void revoke_iomem(struct resource *res) +{ + /* pairs with smp_store_release() in iomem_init_inode() */ + struct inode *inode = smp_load_acquire(&iomem_inode); + + /* + * Check that the initialization has completed. Losing the race + * is ok because it means drivers are claiming resources before + * the fs_initcall level of init and prevent iomem_get_mapping users + * from establishing mappings. + */ + if (!inode) + return; + + /* + * The expectation is that the driver has successfully marked + * the resource busy by this point, so devmem_is_allowed() + * should start returning false, however for performance this + * does not iterate the entire resource range. + */ + if (devmem_is_allowed(PHYS_PFN(res->start)) && + devmem_is_allowed(PHYS_PFN(res->end))) { + /* + * *cringe* iomem=relaxed says "go ahead, what's the + * worst that can happen?" + */ + return; + } + + unmap_mapping_range(inode->i_mapping, res->start, resource_size(res), 1); +} +#else +static void revoke_iomem(struct resource *res) {} +#endif + +struct address_space *iomem_get_mapping(void) +{ + /* + * This function is only called from file open paths, hence guaranteed + * that fs_initcalls have completed and no need to check for NULL. But + * since revoke_iomem can be called before the initcall we still need + * the barrier to appease checkers. + */ + return smp_load_acquire(&iomem_inode)->i_mapping; +} + /** * __request_region - create a new busy resource region * @parent: parent resource descriptor @@ -1186,7 +1238,7 @@ struct resource * __request_region(struct resource *parent, write_unlock(&resource_lock); if (res && orig_parent == &iomem_resource) - revoke_devmem(res); + revoke_iomem(res); return res; } @@ -1786,4 +1838,48 @@ static int __init strict_iomem(char *str) return 1; } +static int iomem_fs_init_fs_context(struct fs_context *fc) +{ + return init_pseudo(fc, DEVMEM_MAGIC) ? 0 : -ENOMEM; +} + +static struct file_system_type iomem_fs_type = { + .name = "iomem", + .owner = THIS_MODULE, + .init_fs_context = iomem_fs_init_fs_context, + .kill_sb = kill_anon_super, +}; + +static int __init iomem_init_inode(void) +{ + static struct vfsmount *iomem_vfs_mount; + static int iomem_fs_cnt; + struct inode *inode; + int rc; + + rc = simple_pin_fs(&iomem_fs_type, &iomem_vfs_mount, &iomem_fs_cnt); + if (rc < 0) { + pr_err("Cannot mount iomem pseudo filesystem: %d\n", rc); + return rc; + } + + inode = alloc_anon_inode(iomem_vfs_mount->mnt_sb); + if (IS_ERR(inode)) { + rc = PTR_ERR(inode); + pr_err("Cannot allocate inode for iomem: %d\n", rc); + simple_release_fs(&iomem_vfs_mount, &iomem_fs_cnt); + return rc; + } + + /* + * Publish iomem revocation inode initialized. + * Pairs with smp_load_acquire() in revoke_iomem(). + */ + smp_store_release(&iomem_inode, inode); + + return 0; +} + +fs_initcall(iomem_init_inode); + __setup("iomem=", strict_iomem); diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 799dbcfe65ad..61cefb157b59 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -602,6 +602,22 @@ config FTRACE_MCOUNT_RECORD depends on DYNAMIC_FTRACE depends on HAVE_FTRACE_MCOUNT_RECORD +config FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY + bool + depends on FTRACE_MCOUNT_RECORD + +config FTRACE_MCOUNT_USE_CC + def_bool y + depends on $(cc-option,-mrecord-mcount) + depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY + depends on FTRACE_MCOUNT_RECORD + +config FTRACE_MCOUNT_USE_RECORDMCOUNT + def_bool y + depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY + depends on !FTRACE_MCOUNT_USE_CC + depends on FTRACE_MCOUNT_RECORD + config TRACING_MAP bool depends on ARCH_HAVE_NMI_SAFE_CMPXCHG diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 8a1cb0878cbc..6fe770d86dc3 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -124,9 +124,9 @@ static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk) if (!p) return true; *p = '\0'; - mutex_lock(&module_mutex); + rcu_read_lock_sched(); ret = !!find_module(tk->symbol); - mutex_unlock(&module_mutex); + rcu_read_unlock_sched(); *p = ':'; return ret; diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 00957eafdf6c..8e1676fa7351 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2968,8 +2968,8 @@ reflush: if (++flush_cnt == 10 || (flush_cnt % 100 == 0 && flush_cnt <= 1000)) - pr_warn("workqueue %s: drain_workqueue() isn't complete after %u tries\n", - wq->name, flush_cnt); + pr_warn("workqueue %s: %s() isn't complete after %u tries\n", + wq->name, __func__, flush_cnt); mutex_unlock(&wq->mutex); goto reflush; diff --git a/lib/bug.c b/lib/bug.c index 7103440c0ee1..8f9d537bfb2a 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -91,8 +91,6 @@ void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, char *secstrings; unsigned int i; - lockdep_assert_held(&module_mutex); - mod->bug_table = NULL; mod->num_bugs = 0; @@ -118,7 +116,6 @@ void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, void module_bug_cleanup(struct module *mod) { - lockdep_assert_held(&module_mutex); list_del_rcu(&mod->bug_list); } diff --git a/mm/Kconfig b/mm/Kconfig index f730605b8dcf..24c045b24b95 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -804,9 +804,6 @@ config DEVICE_PRIVATE config VMAP_PFN bool -config FRAME_VECTOR - bool - config ARCH_USES_HIGH_VMA_FLAGS bool config ARCH_HAS_PKEYS diff --git a/mm/Makefile b/mm/Makefile index b6cd2fffa492..135bbb65511a 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -110,7 +110,6 @@ obj-$(CONFIG_PAGE_EXTENSION) += page_ext.o obj-$(CONFIG_CMA_DEBUGFS) += cma_debug.o obj-$(CONFIG_USERFAULTFD) += userfaultfd.o obj-$(CONFIG_IDLE_PAGE_TRACKING) += page_idle.o -obj-$(CONFIG_FRAME_VECTOR) += frame_vector.o obj-$(CONFIG_DEBUG_PAGE_REF) += debug_page_ref.o obj-$(CONFIG_HARDENED_USERCOPY) += usercopy.o obj-$(CONFIG_PERCPU_STATS) += percpu-stats.o diff --git a/mm/memory.c b/mm/memory.c index 44f057c4a4df..c545baf53401 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4814,28 +4814,68 @@ out: return ret; } +/** + * generic_access_phys - generic implementation for iomem mmap access + * @vma: the vma to access + * @addr: userspace addres, not relative offset within @vma + * @buf: buffer to read/write + * @len: length of transfer + * @write: set to FOLL_WRITE when writing, otherwise reading + * + * This is a generic implementation for &vm_operations_struct.access for an + * iomem mapping. This callback is used by access_process_vm() when the @vma is + * not page based. + */ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr, void *buf, int len, int write) { resource_size_t phys_addr; unsigned long prot = 0; void __iomem *maddr; - int offset = addr & (PAGE_SIZE-1); + pte_t *ptep, pte; + spinlock_t *ptl; + int offset = offset_in_page(addr); + int ret = -EINVAL; - if (follow_phys(vma, addr, write, &prot, &phys_addr)) + if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) + return -EINVAL; + +retry: + if (follow_pte(vma->vm_mm, addr, &ptep, &ptl)) + return -EINVAL; + pte = *ptep; + pte_unmap_unlock(ptep, ptl); + + prot = pgprot_val(pte_pgprot(pte)); + phys_addr = (resource_size_t)pte_pfn(pte) << PAGE_SHIFT; + + if ((write & FOLL_WRITE) && !pte_write(pte)) return -EINVAL; maddr = ioremap_prot(phys_addr, PAGE_ALIGN(len + offset), prot); if (!maddr) return -ENOMEM; + if (follow_pte(vma->vm_mm, addr, &ptep, &ptl)) + goto out_unmap; + + if (!pte_same(pte, *ptep)) { + pte_unmap_unlock(ptep, ptl); + iounmap(maddr); + + goto retry; + } + if (write) memcpy_toio(maddr + offset, buf, len); else memcpy_fromio(buf, maddr + offset, len); + ret = len; + pte_unmap_unlock(ptep, ptl); +out_unmap: iounmap(maddr); - return len; + return ret; } EXPORT_SYMBOL_GPL(generic_access_phys); #endif diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 4c058f12dd73..d94fc9ab819d 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -111,7 +111,7 @@ endif # --------------------------------------------------------------------------- quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ - cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) -fverbose-asm -S -o $@ $< + cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS) $(CC_FLAGS_LTO), $(c_flags)) -fverbose-asm -S -o $@ $< $(obj)/%.s: $(src)/%.c FORCE $(call if_changed_dep,cc_s_c) @@ -166,6 +166,15 @@ ifdef CONFIG_MODVERSIONS # the actual value of the checksum generated by genksyms # o remove .tmp_.o to .o +ifdef CONFIG_LTO_CLANG +# Generate .o.symversions files for each .o with exported symbols, and link these +# to the kernel and/or modules at the end. +cmd_modversions_c = \ + if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \ + $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ + > $@.symversions; \ + fi; +else cmd_modversions_c = \ if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \ $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ @@ -177,9 +186,9 @@ cmd_modversions_c = \ rm -f $(@D)/.tmp_$(@F:.o=.ver); \ fi endif +endif -ifdef CONFIG_FTRACE_MCOUNT_RECORD -ifndef CC_USING_RECORD_MCOUNT +ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT # compiler will not generate __mcount_loc use recordmcount or recordmcount.pl ifdef BUILD_C_RECORDMCOUNT ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") @@ -206,8 +215,7 @@ recordmcount_source := $(srctree)/scripts/recordmcount.pl endif # BUILD_C_RECORDMCOUNT cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \ $(sub_cmd_record_mcount)) -endif # CC_USING_RECORD_MCOUNT -endif # CONFIG_FTRACE_MCOUNT_RECORD +endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT ifdef CONFIG_STACK_VALIDATION ifneq ($(SKIP_STACK_VALIDATION),1) @@ -388,6 +396,18 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; +# combine symversions for later processing +quiet_cmd_update_lto_symversions = SYMVER $@ +ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y) + cmd_update_lto_symversions = \ + rm -f $@.symversions \ + $(foreach n, $(filter-out FORCE,$^), \ + $(if $(wildcard $(n).symversions), \ + ; cat $(n).symversions >> $@.symversions)) +else + cmd_update_lto_symversions = echo >/dev/null +endif + # # Rule to compile a set of .o files into one .a file (without symbol table) # @@ -395,8 +415,11 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; quiet_cmd_ar_builtin = AR $@ cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs) +quiet_cmd_ar_and_symver = AR $@ + cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin) + $(obj)/built-in.a: $(real-obj-y) FORCE - $(call if_changed,ar_builtin) + $(call if_changed,ar_and_symver) # # Rule to create modules.order file @@ -416,15 +439,26 @@ $(obj)/modules.order: $(obj-m) FORCE # # Rule to compile a set of .o files into one .a file (with symbol table) # +quiet_cmd_ar_lib = AR $@ + cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar) + $(obj)/lib.a: $(lib-y) FORCE - $(call if_changed,ar) + $(call if_changed,ar_lib) # NOTE: # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object # module is turned into a multi object module, $^ will contain header file # dependencies recorded in the .*.cmd file. +ifdef CONFIG_LTO_CLANG +quiet_cmd_link_multi-m = AR [M] $@ +cmd_link_multi-m = \ + $(cmd_update_lto_symversions); \ + rm -f $@; \ + $(AR) cDPrsT $@ $(filter %.o,$^) +else quiet_cmd_link_multi-m = LD [M] $@ cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^) +endif $(multi-used-m): FORCE $(call if_changed,link_multi-m) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 203adad631d1..7048aaafcf89 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -119,9 +119,11 @@ target-stem = $(basename $(patsubst $(obj)/%,%,$@)) # These flags are needed for modversions and compiling, so we define them here # $(modname_flags) defines KBUILD_MODNAME as the name of the module it will # end up in (or would, if it gets compiled in) -name-fix = $(call stringify,$(subst $(comma),_,$(subst -,_,$1))) +name-fix-token = $(subst $(comma),_,$(subst -,_,$1)) +name-fix = $(call stringify,$(call name-fix-token,$1)) basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) -modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) +modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \ + -D__KBUILD_MODNAME=kmod_$(call name-fix-token,$(modname)) modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile)) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \ diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index d49ec001825d..6de2c35b64e8 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -30,6 +30,12 @@ quiet_cmd_cc_o_c = CC [M] $@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) +ifdef CONFIG_LTO_CLANG +# With CONFIG_LTO_CLANG, reuse the object file we compiled for modpost to +# avoid a second slow LTO link +prelink-ext := .lto +endif + quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \ @@ -53,8 +59,9 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ $(cmd); \ printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) + # Re-generate module BTFs if either module's .ko or vmlinux changed -$(modules): %.ko: %.o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE +$(modules): %.ko: %$(prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE +$(call if_changed_except,ld_ko_o,vmlinux) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 0fde9ef49e46..e8bac7553539 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -43,6 +43,9 @@ __modpost: include include/config/auto.conf include scripts/Kbuild.include +# for ld_flags +include scripts/Makefile.lib + MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ @@ -124,12 +127,30 @@ $(input-symdump): @echo >&2 'WARNING: Symbol version dump "$@" is missing.' @echo >&2 ' Modules may not have dependencies or modversions.' +ifdef CONFIG_LTO_CLANG +# With CONFIG_LTO_CLANG, .o files might be LLVM bitcode, so we need to run +# LTO to compile them into native code before running modpost +prelink-ext := .lto + +quiet_cmd_cc_lto_link_modules = LTO [M] $@ +cmd_cc_lto_link_modules = \ + $(LD) $(ld_flags) -r -o $@ \ + $(shell [ -s $(@:.lto.o=.o.symversions) ] && \ + echo -T $(@:.lto.o=.o.symversions)) \ + --whole-archive $^ + +%.lto.o: %.o + $(call if_changed,cc_lto_link_modules) +endif + +modules := $(sort $(shell cat $(MODORDER))) + # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". quiet_cmd_modpost = MODPOST $@ - cmd_modpost = sed 's/ko$$/o/' $< | $(MODPOST) -T - + cmd_modpost = sed 's/\.ko$$/$(prelink-ext)\.o/' $< | $(MODPOST) -T - -$(output-symdump): $(MODORDER) $(input-symdump) FORCE +$(output-symdump): $(MODORDER) $(input-symdump) $(modules:.ko=$(prelink-ext).o) FORCE $(call if_changed,modpost) targets += $(output-symdump) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4b2775fd31d9..ca4201753d5e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4283,8 +4283,7 @@ sub process { if (defined $realline_next && exists $lines[$realline_next - 1] && !defined $suppress_export{$realline_next} && - ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || - $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { + ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) { # Handle definitions which produce identifiers with # a prefix: # XXX(foo); @@ -4311,8 +4310,7 @@ sub process { } if (!defined $suppress_export{$linenr} && $prevline =~ /^.\s*$/ && - ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || - $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { + ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) { #print "FOO B <$lines[$linenr - 1]>\n"; $suppress_export{$linenr} = 2; } diff --git a/scripts/generate_initcall_order.pl b/scripts/generate_initcall_order.pl new file mode 100755 index 000000000000..1a88d3f1b913 --- /dev/null +++ b/scripts/generate_initcall_order.pl @@ -0,0 +1,270 @@ +#!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +# +# Generates a linker script that specifies the correct initcall order. +# +# Copyright (C) 2019 Google LLC + +use strict; +use warnings; +use IO::Handle; +use IO::Select; +use POSIX ":sys_wait_h"; + +my $nm = $ENV{'NM'} || die "$0: ERROR: NM not set?"; +my $objtree = $ENV{'objtree'} || '.'; + +## currently active child processes +my $jobs = {}; # child process pid -> file handle +## results from child processes +my $results = {}; # object index -> [ { level, secname }, ... ] + +## reads _NPROCESSORS_ONLN to determine the maximum number of processes to +## start +sub get_online_processors { + open(my $fh, "getconf _NPROCESSORS_ONLN 2>/dev/null |") + or die "$0: ERROR: failed to execute getconf: $!"; + my $procs = <$fh>; + close($fh); + + if (!($procs =~ /^\d+$/)) { + return 1; + } + + return int($procs); +} + +## writes results to the parent process +## format: +sub write_results { + my ($index, $initcalls) = @_; + + # sort by the counter value to ensure the order of initcalls within + # each object file is correct + foreach my $counter (sort { $a <=> $b } keys(%{$initcalls})) { + my $level = $initcalls->{$counter}->{'level'}; + + # section name for the initcall function + my $secname = $initcalls->{$counter}->{'module'} . '__' . + $counter . '_' . + $initcalls->{$counter}->{'line'} . '_' . + $initcalls->{$counter}->{'function'}; + + print "$index $level $secname\n"; + } +} + +## reads a result line from a child process and adds it to the $results array +sub read_results{ + my ($fh) = @_; + + # each child prints out a full line w/ autoflush and exits after the + # last line, so even if buffered I/O blocks here, it shouldn't block + # very long + my $data = <$fh>; + + if (!defined($data)) { + return 0; + } + + chomp($data); + + my ($index, $level, $secname) = $data =~ + /^(\d+)\ ([^\ ]+)\ (.*)$/; + + if (!defined($index) || + !defined($level) || + !defined($secname)) { + die "$0: ERROR: child process returned invalid data: $data\n"; + } + + $index = int($index); + + if (!exists($results->{$index})) { + $results->{$index} = []; + } + + push (@{$results->{$index}}, { + 'level' => $level, + 'secname' => $secname + }); + + return 1; +} + +## finds initcalls from an object file or all object files in an archive, and +## writes results back to the parent process +sub find_initcalls { + my ($index, $file) = @_; + + die "$0: ERROR: file $file doesn't exist?" if (! -f $file); + + open(my $fh, "\"$nm\" --defined-only \"$file\" 2>/dev/null |") + or die "$0: ERROR: failed to execute \"$nm\": $!"; + + my $initcalls = {}; + + while (<$fh>) { + chomp; + + # check for the start of a new object file (if processing an + # archive) + my ($path)= $_ =~ /^(.+)\:$/; + + if (defined($path)) { + write_results($index, $initcalls); + $initcalls = {}; + next; + } + + # look for an initcall + my ($module, $counter, $line, $symbol) = $_ =~ + /[a-z]\s+__initcall__(\S*)__(\d+)_(\d+)_(.*)$/; + + if (!defined($module)) { + $module = '' + } + + if (!defined($counter) || + !defined($line) || + !defined($symbol)) { + next; + } + + # parse initcall level + my ($function, $level) = $symbol =~ + /^(.*)((early|rootfs|con|[0-9])s?)$/; + + die "$0: ERROR: invalid initcall name $symbol in $file($path)" + if (!defined($function) || !defined($level)); + + $initcalls->{$counter} = { + 'module' => $module, + 'line' => $line, + 'function' => $function, + 'level' => $level, + }; + } + + close($fh); + write_results($index, $initcalls); +} + +## waits for any child process to complete, reads the results, and adds them to +## the $results array for later processing +sub wait_for_results { + my ($select) = @_; + + my $pid = 0; + do { + # unblock children that may have a full write buffer + foreach my $fh ($select->can_read(0)) { + read_results($fh); + } + + # check for children that have exited, read the remaining data + # from them, and clean up + $pid = waitpid(-1, WNOHANG); + if ($pid > 0) { + if (!exists($jobs->{$pid})) { + next; + } + + my $fh = $jobs->{$pid}; + $select->remove($fh); + + while (read_results($fh)) { + # until eof + } + + close($fh); + delete($jobs->{$pid}); + } + } while ($pid > 0); +} + +## forks a child to process each file passed in the command line and collects +## the results +sub process_files { + my $index = 0; + my $njobs = $ENV{'PARALLELISM'} || get_online_processors(); + my $select = IO::Select->new(); + + while (my $file = shift(@ARGV)) { + # fork a child process and read it's stdout + my $pid = open(my $fh, '-|'); + + if (!defined($pid)) { + die "$0: ERROR: failed to fork: $!"; + } elsif ($pid) { + # save the child process pid and the file handle + $select->add($fh); + $jobs->{$pid} = $fh; + } else { + # in the child process + STDOUT->autoflush(1); + find_initcalls($index, "$objtree/$file"); + exit; + } + + $index++; + + # limit the number of children to $njobs + if (scalar(keys(%{$jobs})) >= $njobs) { + wait_for_results($select); + } + } + + # wait for the remaining children to complete + while (scalar(keys(%{$jobs})) > 0) { + wait_for_results($select); + } +} + +sub generate_initcall_lds() { + process_files(); + + my $sections = {}; # level -> [ secname, ...] + + # sort results to retain link order and split to sections per + # initcall level + foreach my $index (sort { $a <=> $b } keys(%{$results})) { + foreach my $result (@{$results->{$index}}) { + my $level = $result->{'level'}; + + if (!exists($sections->{$level})) { + $sections->{$level} = []; + } + + push(@{$sections->{$level}}, $result->{'secname'}); + } + } + + die "$0: ERROR: no initcalls?" if (!keys(%{$sections})); + + # print out a linker script that defines the order of initcalls for + # each level + print "SECTIONS {\n"; + + foreach my $level (sort(keys(%{$sections}))) { + my $section; + + if ($level eq 'con') { + $section = '.con_initcall.init'; + } else { + $section = ".initcall${level}.init"; + } + + print "\t${section} : {\n"; + + foreach my $secname (@{$sections->{$level}}) { + print "\t\t*(${section}..${secname}) ;\n"; + } + + print "\t}\n"; + } + + print "}\n"; +} + +generate_initcall_lds(); diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 6eded325c837..c5919d5a0b4f 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -43,11 +43,37 @@ info() fi } +# Generate a linker script to ensure correct ordering of initcalls. +gen_initcalls() +{ + info GEN .tmp_initcalls.lds + + ${PYTHON} ${srctree}/scripts/jobserver-exec \ + ${PERL} ${srctree}/scripts/generate_initcall_order.pl \ + ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS} \ + > .tmp_initcalls.lds +} + +# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into +# .tmp_symversions.lds +gen_symversions() +{ + info GEN .tmp_symversions.lds + rm -f .tmp_symversions.lds + + for o in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do + if [ -f ${o}.symversions ]; then + cat ${o}.symversions >> .tmp_symversions.lds + fi + done +} + # Link of vmlinux.o used for section mismatch analysis # ${1} output file modpost_link() { local objects + local lds="" objects="--whole-archive \ ${KBUILD_VMLINUX_OBJS} \ @@ -56,7 +82,23 @@ modpost_link() ${KBUILD_VMLINUX_LIBS} \ --end-group" - ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects} + if [ -n "${CONFIG_LTO_CLANG}" ]; then + gen_initcalls + lds="-T .tmp_initcalls.lds" + + if [ -n "${CONFIG_MODVERSIONS}" ]; then + gen_symversions + lds="${lds} -T .tmp_symversions.lds" + fi + + # This might take a while, so indicate that we're doing + # an LTO link + info LTO ${1} + else + info LD ${1} + fi + + ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects} } objtool_link() @@ -103,13 +145,22 @@ vmlinux_link() fi if [ "${SRCARCH}" != "um" ]; then - objects="--whole-archive \ - ${KBUILD_VMLINUX_OBJS} \ - --no-whole-archive \ - --start-group \ - ${KBUILD_VMLINUX_LIBS} \ - --end-group \ - ${@}" + if [ -n "${CONFIG_LTO_CLANG}" ]; then + # Use vmlinux.o instead of performing the slow LTO + # link again. + objects="--whole-archive \ + vmlinux.o \ + --no-whole-archive \ + ${@}" + else + objects="--whole-archive \ + ${KBUILD_VMLINUX_OBJS} \ + --no-whole-archive \ + --start-group \ + ${KBUILD_VMLINUX_LIBS} \ + --end-group \ + ${@}" + fi ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} \ ${strip_debug#-Wl,} \ @@ -225,6 +276,8 @@ cleanup() { rm -f .btf.* rm -f .tmp_System.map + rm -f .tmp_initcalls.lds + rm -f .tmp_symversions.lds rm -f .tmp_vmlinux* rm -f System.map rm -f vmlinux @@ -274,7 +327,6 @@ fi; ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 #link vmlinux.o -info LD vmlinux.o modpost_link vmlinux.o objtool_link vmlinux.o diff --git a/scripts/lto-used-symbollist.txt b/scripts/lto-used-symbollist.txt new file mode 100644 index 000000000000..38e7bb9ebaae --- /dev/null +++ b/scripts/lto-used-symbollist.txt @@ -0,0 +1,5 @@ +memcpy +memmove +memset +__stack_chk_fail +__stack_chk_guard diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile index 78071681d924..c9e38ad937fd 100644 --- a/scripts/mod/Makefile +++ b/scripts/mod/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 OBJECT_FILES_NON_STANDARD := y +CFLAGS_REMOVE_empty.o += $(CC_FLAGS_LTO) hostprogs-always-y += modpost mk_elfconfig always-y += empty.o diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a702ce3c1a77..ba770dbdacca 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include "modpost.h" #include "../../include/linux/license.h" @@ -45,8 +44,9 @@ static int allow_missing_ns_imports; static bool error_occurred; enum export { - export_plain, export_unused, export_gpl, - export_unused_gpl, export_gpl_future, export_unknown + export_plain, + export_gpl, + export_unknown }; /* In kernel, this size is defined in linux/module.h; @@ -86,14 +86,6 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...) error_occurred = true; } -static inline bool strends(const char *str, const char *postfix) -{ - if (strlen(str) < strlen(postfix)) - return false; - - return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; -} - void *do_nofail(void *ptr, const char *expr) { if (!ptr) @@ -303,10 +295,7 @@ static const struct { enum export export; } export_list[] = { { .str = "EXPORT_SYMBOL", .export = export_plain }, - { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused }, { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl }, - { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl }, - { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future }, { .str = "(unknown)", .export = export_unknown }, }; @@ -365,14 +354,8 @@ static enum export export_from_secname(struct elf_info *elf, unsigned int sec) if (strstarts(secname, "___ksymtab+")) return export_plain; - else if (strstarts(secname, "___ksymtab_unused+")) - return export_unused; else if (strstarts(secname, "___ksymtab_gpl+")) return export_gpl; - else if (strstarts(secname, "___ksymtab_unused_gpl+")) - return export_unused_gpl; - else if (strstarts(secname, "___ksymtab_gpl_future+")) - return export_gpl_future; else return export_unknown; } @@ -381,14 +364,8 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec) { if (sec == elf->export_sec) return export_plain; - else if (sec == elf->export_unused_sec) - return export_unused; else if (sec == elf->export_gpl_sec) return export_gpl; - else if (sec == elf->export_unused_gpl_sec) - return export_unused_gpl; - else if (sec == elf->export_gpl_future_sec) - return export_gpl_future; else return export_unknown; } @@ -591,14 +568,8 @@ static int parse_elf(struct elf_info *info, const char *filename) info->modinfo_len = sechdrs[i].sh_size; } else if (strcmp(secname, "__ksymtab") == 0) info->export_sec = i; - else if (strcmp(secname, "__ksymtab_unused") == 0) - info->export_unused_sec = i; else if (strcmp(secname, "__ksymtab_gpl") == 0) info->export_gpl_sec = i; - else if (strcmp(secname, "__ksymtab_unused_gpl") == 0) - info->export_unused_gpl_sec = i; - else if (strcmp(secname, "__ksymtab_gpl_future") == 0) - info->export_gpl_future_sec = i; if (sechdrs[i].sh_type == SHT_SYMTAB) { unsigned int sh_link_idx; @@ -1989,6 +1960,10 @@ static char *remove_dot(char *s) size_t m = strspn(s + n + 1, "0123456789"); if (m && (s[n + m] == '.' || s[n + m] == 0)) s[n] = 0; + + /* strip trailing .lto */ + if (strends(s, ".lto")) + s[strlen(s) - 4] = '\0'; } return s; } @@ -2012,6 +1987,9 @@ static void read_symbols(const char *modname) /* strip trailing .o */ tmp = NOFAIL(strdup(modname)); tmp[strlen(tmp) - 2] = '\0'; + /* strip trailing .lto */ + if (strends(tmp, ".lto")) + tmp[strlen(tmp) - 4] = '\0'; mod = new_module(tmp); free(tmp); } @@ -2149,36 +2127,13 @@ static void check_for_gpl_usage(enum export exp, const char *m, const char *s) error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n", m, s); break; - case export_unused_gpl: - error("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n", - m, s); - break; - case export_gpl_future: - warn("GPL-incompatible module %s.ko uses future GPL-only symbol '%s'\n", - m, s); - break; case export_plain: - case export_unused: case export_unknown: /* ignore */ break; } } -static void check_for_unused(enum export exp, const char *m, const char *s) -{ - switch (exp) { - case export_unused: - case export_unused_gpl: - warn("module %s.ko uses symbol '%s' marked UNUSED\n", - m, s); - break; - default: - /* ignore */ - break; - } -} - static void check_exports(struct module *mod) { struct symbol *s, *exp; @@ -2209,7 +2164,6 @@ static void check_exports(struct module *mod) if (!mod->gpl_compatible) check_for_gpl_usage(exp->export, basename, exp->name); - check_for_unused(exp->export, basename, exp->name); } } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index e6f46eee0af0..c1a895c0d682 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -139,10 +140,7 @@ struct elf_info { Elf_Sym *symtab_start; Elf_Sym *symtab_stop; Elf_Section export_sec; - Elf_Section export_unused_sec; Elf_Section export_gpl_sec; - Elf_Section export_unused_gpl_sec; - Elf_Section export_gpl_future_sec; char *strtab; char *modinfo; unsigned int modinfo_len; @@ -180,6 +178,14 @@ static inline unsigned int get_secindex(const struct elf_info *info, return info->symtab_shndx_start[sym - info->symtab_start]; } +static inline bool strends(const char *str, const char *postfix) +{ + if (strlen(str) < strlen(postfix)) + return false; + + return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; +} + /* file2alias.c */ extern unsigned int cross_build; void handle_moddevtable(struct module *mod, struct elf_info *info, diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index d587f40f1117..760e6baa7eda 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -391,10 +391,14 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) struct md4_ctx md; char *fname; char filelist[PATH_MAX + 1]; + int postfix_len = 1; + + if (strends(modname, ".lto.o")) + postfix_len = 5; /* objects for a module are listed in the first line of *.mod file. */ snprintf(filelist, sizeof(filelist), "%.*smod", - (int)strlen(modname) - 1, modname); + (int)strlen(modname) - postfix_len, modname); buf = read_text_file(filelist); diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 69b9b71a6a47..168cd27e6122 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -11,18 +11,36 @@ SECTIONS { __ksymtab 0 : { *(SORT(___ksymtab+*)) } __ksymtab_gpl 0 : { *(SORT(___ksymtab_gpl+*)) } - __ksymtab_unused 0 : { *(SORT(___ksymtab_unused+*)) } - __ksymtab_unused_gpl 0 : { *(SORT(___ksymtab_unused_gpl+*)) } - __ksymtab_gpl_future 0 : { *(SORT(___ksymtab_gpl_future+*)) } __kcrctab 0 : { *(SORT(___kcrctab+*)) } __kcrctab_gpl 0 : { *(SORT(___kcrctab_gpl+*)) } - __kcrctab_unused 0 : { *(SORT(___kcrctab_unused+*)) } - __kcrctab_unused_gpl 0 : { *(SORT(___kcrctab_unused_gpl+*)) } - __kcrctab_gpl_future 0 : { *(SORT(___kcrctab_gpl_future+*)) } .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } + + __patchable_function_entries : { *(__patchable_function_entries) } + + /* + * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and + * -ffunction-sections, which increases the size of the final module. + * Merge the split sections in the final binary. + */ + .bss : { + *(.bss .bss.[0-9a-zA-Z_]*) + *(.bss..L*) + } + + .data : { + *(.data .data.[0-9a-zA-Z_]*) + *(.data..L*) + } + + .rodata : { + *(.rodata .rodata.[0-9a-zA-Z_]*) + *(.rodata..L*) + } + + .text : { *(.text .text.[0-9a-zA-Z_]*) } } /* bring in arch-specific sections */ diff --git a/security/commoncap.c b/security/commoncap.c index 53d0b19b61a6..6859950d13ea 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -501,7 +501,8 @@ int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size) __u32 magic, nsmagic; struct inode *inode = d_backing_inode(dentry); struct user_namespace *task_ns = current_user_ns(), - *fs_ns = inode->i_sb->s_user_ns; + *fs_ns = inode->i_sb->s_user_ns, + *ancestor; kuid_t rootid; size_t newsize; @@ -524,6 +525,15 @@ int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size) if (nsrootid == -1) return -EINVAL; + /* + * Do not allow allow adding a v3 filesystem capability xattr + * if the rootid field is ambiguous. + */ + for (ancestor = task_ns->parent; ancestor; ancestor = ancestor->parent) { + if (from_kuid(ancestor, rootid) == 0) + return -EINVAL; + } + newsize = sizeof(struct vfs_ns_cap_data); nscap = kmalloc(newsize, GFP_ATOMIC); if (!nscap) diff --git a/tools/arch/x86/include/asm/insn.h b/tools/arch/x86/include/asm/insn.h index 52c6262e6bfd..cc777c185212 100644 --- a/tools/arch/x86/include/asm/insn.h +++ b/tools/arch/x86/include/asm/insn.h @@ -7,9 +7,12 @@ * Copyright (C) IBM Corporation, 2009 */ +#include /* insn_attr_t is defined in inat.h */ #include "inat.h" +#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) + struct insn_field { union { insn_value_t value; @@ -20,6 +23,48 @@ struct insn_field { unsigned char nbytes; }; +static inline void insn_field_set(struct insn_field *p, insn_value_t v, + unsigned char n) +{ + p->value = v; + p->nbytes = n; +} + +static inline void insn_set_byte(struct insn_field *p, unsigned char n, + insn_byte_t v) +{ + p->bytes[n] = v; +} + +#else + +struct insn_field { + insn_value_t value; + union { + insn_value_t little; + insn_byte_t bytes[4]; + }; + /* !0 if we've run insn_get_xxx() for this field */ + unsigned char got; + unsigned char nbytes; +}; + +static inline void insn_field_set(struct insn_field *p, insn_value_t v, + unsigned char n) +{ + p->value = v; + p->little = __cpu_to_le32(v); + p->nbytes = n; +} + +static inline void insn_set_byte(struct insn_field *p, unsigned char n, + insn_byte_t v) +{ + p->bytes[n] = v; + p->value = __le32_to_cpu(p->little); +} +#endif + struct insn { struct insn_field prefixes; /* * Prefixes diff --git a/tools/arch/x86/include/asm/orc_types.h b/tools/arch/x86/include/asm/orc_types.h index fdbffec4cfde..5a2baf28a1dc 100644 --- a/tools/arch/x86/include/asm/orc_types.h +++ b/tools/arch/x86/include/asm/orc_types.h @@ -40,6 +40,8 @@ #define ORC_REG_MAX 15 #ifndef __ASSEMBLY__ +#include + /* * This struct is more or less a vastly simplified version of the DWARF Call * Frame Information standard. It contains only the necessary parts of DWARF @@ -51,10 +53,18 @@ struct orc_entry { s16 sp_offset; s16 bp_offset; +#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned sp_reg:4; unsigned bp_reg:4; unsigned type:2; unsigned end:1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned bp_reg:4; + unsigned sp_reg:4; + unsigned unused:5; + unsigned end:1; + unsigned type:2; +#endif } __packed; #endif /* __ASSEMBLY__ */ diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c index 0151dfc6da61..3d9355ed1246 100644 --- a/tools/arch/x86/lib/insn.c +++ b/tools/arch/x86/lib/insn.c @@ -5,6 +5,7 @@ * Copyright (C) IBM Corporation, 2002, 2004, 2009 */ +#include #ifdef __KERNEL__ #include #else @@ -15,15 +16,28 @@ #include "../include/asm/emulate_prefix.h" +#define leXX_to_cpu(t, r) \ +({ \ + __typeof__(t) v; \ + switch (sizeof(t)) { \ + case 4: v = le32_to_cpu(r); break; \ + case 2: v = le16_to_cpu(r); break; \ + case 1: v = r; break; \ + default: \ + BUILD_BUG(); break; \ + } \ + v; \ +}) + /* Verify next sizeof(t) bytes can be on the same instruction */ #define validate_next(t, insn, n) \ ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) #define __get_next(t, insn) \ - ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) + ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); leXX_to_cpu(t, r); }) #define __peek_nbyte_next(t, insn, n) \ - ({ t r = *(t*)((insn)->next_byte + n); r; }) + ({ t r = *(t*)((insn)->next_byte + n); leXX_to_cpu(t, r); }) #define get_next(t, insn) \ ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) @@ -147,9 +161,9 @@ found: b = insn->prefixes.bytes[3]; for (i = 0; i < nb; i++) if (prefixes->bytes[i] == lb) - prefixes->bytes[i] = b; + insn_set_byte(prefixes, i, b); } - insn->prefixes.bytes[3] = lb; + insn_set_byte(&insn->prefixes, 3, lb); } /* Decode REX prefix */ @@ -157,8 +171,7 @@ found: b = peek_next(insn_byte_t, insn); attr = inat_get_opcode_attribute(b); if (inat_is_rex_prefix(attr)) { - insn->rex_prefix.value = b; - insn->rex_prefix.nbytes = 1; + insn_field_set(&insn->rex_prefix, b, 1); insn->next_byte++; if (X86_REX_W(b)) /* REX.W overrides opnd_size */ @@ -181,13 +194,13 @@ found: if (X86_MODRM_MOD(b2) != 3) goto vex_end; } - insn->vex_prefix.bytes[0] = b; - insn->vex_prefix.bytes[1] = b2; + insn_set_byte(&insn->vex_prefix, 0, b); + insn_set_byte(&insn->vex_prefix, 1, b2); if (inat_is_evex_prefix(attr)) { b2 = peek_nbyte_next(insn_byte_t, insn, 2); - insn->vex_prefix.bytes[2] = b2; + insn_set_byte(&insn->vex_prefix, 2, b2); b2 = peek_nbyte_next(insn_byte_t, insn, 3); - insn->vex_prefix.bytes[3] = b2; + insn_set_byte(&insn->vex_prefix, 3, b2); insn->vex_prefix.nbytes = 4; insn->next_byte += 4; if (insn->x86_64 && X86_VEX_W(b2)) @@ -195,7 +208,7 @@ found: insn->opnd_bytes = 8; } else if (inat_is_vex3_prefix(attr)) { b2 = peek_nbyte_next(insn_byte_t, insn, 2); - insn->vex_prefix.bytes[2] = b2; + insn_set_byte(&insn->vex_prefix, 2, b2); insn->vex_prefix.nbytes = 3; insn->next_byte += 3; if (insn->x86_64 && X86_VEX_W(b2)) @@ -207,7 +220,7 @@ found: * Makes it easier to decode vex.W, vex.vvvv, * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0. */ - insn->vex_prefix.bytes[2] = b2 & 0x7f; + insn_set_byte(&insn->vex_prefix, 2, b2 & 0x7f); insn->vex_prefix.nbytes = 2; insn->next_byte += 2; } @@ -243,7 +256,7 @@ void insn_get_opcode(struct insn *insn) /* Get first opcode */ op = get_next(insn_byte_t, insn); - opcode->bytes[0] = op; + insn_set_byte(opcode, 0, op); opcode->nbytes = 1; /* Check if there is VEX prefix or not */ @@ -295,8 +308,7 @@ void insn_get_modrm(struct insn *insn) if (inat_has_modrm(insn->attr)) { mod = get_next(insn_byte_t, insn); - modrm->value = mod; - modrm->nbytes = 1; + insn_field_set(modrm, mod, 1); if (inat_is_group(insn->attr)) { pfx_id = insn_last_prefix_id(insn); insn->attr = inat_get_group_attribute(mod, pfx_id, @@ -334,7 +346,7 @@ int insn_rip_relative(struct insn *insn) * For rip-relative instructions, the mod field (top 2 bits) * is zero and the r/m field (bottom 3 bits) is 0x5. */ - return (modrm->nbytes && (modrm->value & 0xc7) == 0x5); + return (modrm->nbytes && (modrm->bytes[0] & 0xc7) == 0x5); } /** @@ -353,11 +365,11 @@ void insn_get_sib(struct insn *insn) if (!insn->modrm.got) insn_get_modrm(insn); if (insn->modrm.nbytes) { - modrm = (insn_byte_t)insn->modrm.value; + modrm = insn->modrm.bytes[0]; if (insn->addr_bytes != 2 && X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) { - insn->sib.value = get_next(insn_byte_t, insn); - insn->sib.nbytes = 1; + insn_field_set(&insn->sib, + get_next(insn_byte_t, insn), 1); } } insn->sib.got = 1; @@ -407,19 +419,18 @@ void insn_get_displacement(struct insn *insn) if (mod == 3) goto out; if (mod == 1) { - insn->displacement.value = get_next(signed char, insn); - insn->displacement.nbytes = 1; + insn_field_set(&insn->displacement, + get_next(signed char, insn), 1); } else if (insn->addr_bytes == 2) { if ((mod == 0 && rm == 6) || mod == 2) { - insn->displacement.value = - get_next(short, insn); - insn->displacement.nbytes = 2; + insn_field_set(&insn->displacement, + get_next(short, insn), 2); } } else { if ((mod == 0 && rm == 5) || mod == 2 || (mod == 0 && base == 5)) { - insn->displacement.value = get_next(int, insn); - insn->displacement.nbytes = 4; + insn_field_set(&insn->displacement, + get_next(int, insn), 4); } } } @@ -435,18 +446,14 @@ static int __get_moffset(struct insn *insn) { switch (insn->addr_bytes) { case 2: - insn->moffset1.value = get_next(short, insn); - insn->moffset1.nbytes = 2; + insn_field_set(&insn->moffset1, get_next(short, insn), 2); break; case 4: - insn->moffset1.value = get_next(int, insn); - insn->moffset1.nbytes = 4; + insn_field_set(&insn->moffset1, get_next(int, insn), 4); break; case 8: - insn->moffset1.value = get_next(int, insn); - insn->moffset1.nbytes = 4; - insn->moffset2.value = get_next(int, insn); - insn->moffset2.nbytes = 4; + insn_field_set(&insn->moffset1, get_next(int, insn), 4); + insn_field_set(&insn->moffset2, get_next(int, insn), 4); break; default: /* opnd_bytes must be modified manually */ goto err_out; @@ -464,13 +471,11 @@ static int __get_immv32(struct insn *insn) { switch (insn->opnd_bytes) { case 2: - insn->immediate.value = get_next(short, insn); - insn->immediate.nbytes = 2; + insn_field_set(&insn->immediate, get_next(short, insn), 2); break; case 4: case 8: - insn->immediate.value = get_next(int, insn); - insn->immediate.nbytes = 4; + insn_field_set(&insn->immediate, get_next(int, insn), 4); break; default: /* opnd_bytes must be modified manually */ goto err_out; @@ -487,18 +492,15 @@ static int __get_immv(struct insn *insn) { switch (insn->opnd_bytes) { case 2: - insn->immediate1.value = get_next(short, insn); - insn->immediate1.nbytes = 2; + insn_field_set(&insn->immediate1, get_next(short, insn), 2); break; case 4: - insn->immediate1.value = get_next(int, insn); + insn_field_set(&insn->immediate1, get_next(int, insn), 4); insn->immediate1.nbytes = 4; break; case 8: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - insn->immediate2.value = get_next(int, insn); - insn->immediate2.nbytes = 4; + insn_field_set(&insn->immediate1, get_next(int, insn), 4); + insn_field_set(&insn->immediate2, get_next(int, insn), 4); break; default: /* opnd_bytes must be modified manually */ goto err_out; @@ -515,12 +517,10 @@ static int __get_immptr(struct insn *insn) { switch (insn->opnd_bytes) { case 2: - insn->immediate1.value = get_next(short, insn); - insn->immediate1.nbytes = 2; + insn_field_set(&insn->immediate1, get_next(short, insn), 2); break; case 4: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; + insn_field_set(&insn->immediate1, get_next(int, insn), 4); break; case 8: /* ptr16:64 is not exist (no segment) */ @@ -528,8 +528,7 @@ static int __get_immptr(struct insn *insn) default: /* opnd_bytes must be modified manually */ goto err_out; } - insn->immediate2.value = get_next(unsigned short, insn); - insn->immediate2.nbytes = 2; + insn_field_set(&insn->immediate2, get_next(unsigned short, insn), 2); insn->immediate1.got = insn->immediate2.got = 1; return 1; @@ -565,22 +564,17 @@ void insn_get_immediate(struct insn *insn) switch (inat_immediate_size(insn->attr)) { case INAT_IMM_BYTE: - insn->immediate.value = get_next(signed char, insn); - insn->immediate.nbytes = 1; + insn_field_set(&insn->immediate, get_next(signed char, insn), 1); break; case INAT_IMM_WORD: - insn->immediate.value = get_next(short, insn); - insn->immediate.nbytes = 2; + insn_field_set(&insn->immediate, get_next(short, insn), 2); break; case INAT_IMM_DWORD: - insn->immediate.value = get_next(int, insn); - insn->immediate.nbytes = 4; + insn_field_set(&insn->immediate, get_next(int, insn), 4); break; case INAT_IMM_QWORD: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - insn->immediate2.value = get_next(int, insn); - insn->immediate2.nbytes = 4; + insn_field_set(&insn->immediate1, get_next(int, insn), 4); + insn_field_set(&insn->immediate2, get_next(int, insn), 4); break; case INAT_IMM_PTR: if (!__get_immptr(insn)) @@ -599,8 +593,7 @@ void insn_get_immediate(struct insn *insn) goto err_out; } if (inat_has_second_immediate(insn->attr)) { - insn->immediate2.value = get_next(signed char, insn); - insn->immediate2.nbytes = 1; + insn_field_set(&insn->immediate2, get_next(signed char, insn), 1); } done: insn->immediate.got = 1; diff --git a/tools/include/linux/export.h b/tools/include/linux/export.h index d07e586b9ba0..acb6f4daa2f0 100644 --- a/tools/include/linux/export.h +++ b/tools/include/linux/export.h @@ -3,8 +3,5 @@ #define EXPORT_SYMBOL(sym) #define EXPORT_SYMBOL_GPL(sym) -#define EXPORT_SYMBOL_GPL_FUTURE(sym) -#define EXPORT_UNUSED_SYMBOL(sym) -#define EXPORT_UNUSED_SYMBOL_GPL(sym) #endif diff --git a/tools/include/linux/objtool.h b/tools/include/linux/objtool.h index 577f51436cf9..7e72d975cb76 100644 --- a/tools/include/linux/objtool.h +++ b/tools/include/linux/objtool.h @@ -29,11 +29,14 @@ struct unwind_hint { * * UNWIND_HINT_TYPE_REGS_PARTIAL: Used in entry code to indicate that * sp_reg+sp_offset points to the iret return frame. + * + * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function. + * Useful for code which doesn't have an ELF function annotation. */ #define UNWIND_HINT_TYPE_CALL 0 #define UNWIND_HINT_TYPE_REGS 1 #define UNWIND_HINT_TYPE_REGS_PARTIAL 2 -#define UNWIND_HINT_TYPE_RET_OFFSET 3 +#define UNWIND_HINT_TYPE_FUNC 3 #ifdef CONFIG_STACK_VALIDATION @@ -109,6 +112,12 @@ struct unwind_hint { .popsection .endm +.macro STACK_FRAME_NON_STANDARD func:req + .pushsection .discard.func_stack_frame_non_standard, "aw" + .long \func - . + .popsection +.endm + #endif /* __ASSEMBLY__ */ #else /* !CONFIG_STACK_VALIDATION */ @@ -122,6 +131,8 @@ struct unwind_hint { #define ANNOTATE_INTRA_FUNCTION_CALL .macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 .endm +.macro STACK_FRAME_NON_STANDARD func:req +.endm #endif #endif /* CONFIG_STACK_VALIDATION */ diff --git a/tools/objtool/.gitignore b/tools/objtool/.gitignore index 45cefda24c7b..14236db3677f 100644 --- a/tools/objtool/.gitignore +++ b/tools/objtool/.gitignore @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only arch/x86/lib/inat-tables.c -objtool +/objtool fixdep diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt index 0542e46c7552..30f38fdc0d56 100644 --- a/tools/objtool/Documentation/stack-validation.txt +++ b/tools/objtool/Documentation/stack-validation.txt @@ -315,13 +315,15 @@ they mean, and suggestions for how to fix them. function tracing inserts additional calls, which is not obvious from the sources). -10. file.o: warning: func()+0x5c: alternative modifies stack +10. file.o: warning: func()+0x5c: stack layout conflict in alternatives - This means that an alternative includes instructions that modify the - stack. The problem is that there is only one ORC unwind table, this means - that the ORC unwind entries must be valid for each of the alternatives. - The easiest way to enforce this is to ensure alternatives do not contain - any ORC entries, which in turn implies the above constraint. + This means that in the use of the alternative() or ALTERNATIVE() + macro, the code paths have conflicting modifications to the stack. + The problem is that there is only one ORC unwind table, which means + that the ORC unwind entries must be consistent for all possible + instruction boundaries regardless of which code has been patched. + This limitation can be overcome by massaging the alternatives with + NOPs to shift the stack changes around so they no longer conflict. 11. file.o: warning: unannotated intra-function call diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 5cdb19036d7f..92ce4fce7bc7 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -27,6 +27,7 @@ all: $(OBJTOOL) INCLUDES := -I$(srctree)/tools/include \ -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ -I$(srctree)/tools/arch/$(SRCARCH)/include \ + -I$(srctree)/tools/objtool/include \ -I$(srctree)/tools/objtool/arch/$(SRCARCH)/include WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed -Wno-nested-externs CFLAGS := -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES) $(LIBELF_FLAGS) @@ -46,10 +47,6 @@ ifeq ($(SRCARCH),x86) SUBCMD_ORC := y endif -ifeq ($(SUBCMD_ORC),y) - CFLAGS += -DINSN_USE_ORC -endif - export SUBCMD_CHECK SUBCMD_ORC export srctree OUTPUT CFLAGS SRCARCH AWK include $(srctree)/tools/build/Makefile.include diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index cde9c36e40ae..549813cff8ab 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -11,11 +11,11 @@ #include "../../../arch/x86/lib/inat.c" #include "../../../arch/x86/lib/insn.c" -#include "../../check.h" -#include "../../elf.h" -#include "../../arch.h" -#include "../../warn.h" #include +#include +#include +#include +#include static unsigned char op_to_cfi_reg[][2] = { {CFI_AX, CFI_R8}, @@ -222,15 +222,38 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, break; case 0x89: - if (rex_w && !rex_r && modrm_mod == 3 && modrm_reg == 4) { + if (rex_w && !rex_r && modrm_reg == 4) { - /* mov %rsp, reg */ - ADD_OP(op) { - op->src.type = OP_SRC_REG; - op->src.reg = CFI_SP; - op->dest.type = OP_DEST_REG; - op->dest.reg = op_to_cfi_reg[modrm_rm][rex_b]; + if (modrm_mod == 3) { + /* mov %rsp, reg */ + ADD_OP(op) { + op->src.type = OP_SRC_REG; + op->src.reg = CFI_SP; + op->dest.type = OP_DEST_REG; + op->dest.reg = op_to_cfi_reg[modrm_rm][rex_b]; + } + break; + + } else { + /* skip nontrivial SIB */ + if (modrm_rm == 4 && !(sib == 0x24 && rex_b == rex_x)) + break; + + /* skip RIP relative displacement */ + if (modrm_rm == 5 && modrm_mod == 0) + break; + + /* mov %rsp, disp(%reg) */ + ADD_OP(op) { + op->src.type = OP_SRC_REG; + op->src.reg = CFI_SP; + op->dest.type = OP_DEST_REG_INDIRECT; + op->dest.reg = op_to_cfi_reg[modrm_rm][rex_b]; + op->dest.offset = insn.displacement.value; + } + break; } + break; } @@ -259,8 +282,10 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, op->dest.reg = CFI_BP; op->dest.offset = insn.displacement.value; } + break; + } - } else if (rex_w && !rex_b && modrm_rm == 4 && sib == 0x24) { + if (rex_w && !rex_b && modrm_rm == 4 && sib == 0x24) { /* mov reg, disp(%rsp) */ ADD_OP(op) { @@ -270,6 +295,7 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, op->dest.reg = CFI_SP; op->dest.offset = insn.displacement.value; } + break; } break; @@ -563,8 +589,8 @@ void arch_initial_func_cfi_state(struct cfi_init_state *state) state->cfa.offset = 8; /* initial RA (return address) */ - state->regs[16].base = CFI_CFA; - state->regs[16].offset = -8; + state->regs[CFI_RA].base = CFI_CFA; + state->regs[CFI_RA].offset = -8; } const char *arch_nop_insn(int len) diff --git a/tools/objtool/arch/x86/include/cfi_regs.h b/tools/objtool/arch/x86/include/arch/cfi_regs.h similarity index 100% rename from tools/objtool/arch/x86/include/cfi_regs.h rename to tools/objtool/arch/x86/include/arch/cfi_regs.h diff --git a/tools/objtool/arch/x86/include/arch_elf.h b/tools/objtool/arch/x86/include/arch/elf.h similarity index 100% rename from tools/objtool/arch/x86/include/arch_elf.h rename to tools/objtool/arch/x86/include/arch/elf.h diff --git a/tools/objtool/arch/x86/include/arch/endianness.h b/tools/objtool/arch/x86/include/arch/endianness.h new file mode 100644 index 000000000000..7c362527da20 --- /dev/null +++ b/tools/objtool/arch/x86/include/arch/endianness.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _ARCH_ENDIANNESS_H +#define _ARCH_ENDIANNESS_H + +#include + +#define __TARGET_BYTE_ORDER __LITTLE_ENDIAN + +#endif /* _ARCH_ENDIANNESS_H */ diff --git a/tools/objtool/arch/x86/include/arch_special.h b/tools/objtool/arch/x86/include/arch/special.h similarity index 100% rename from tools/objtool/arch/x86/include/arch_special.h rename to tools/objtool/arch/x86/include/arch/special.h diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c index fd4af88c0ea5..e707d9bcd161 100644 --- a/tools/objtool/arch/x86/special.c +++ b/tools/objtool/arch/x86/special.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include "../../special.h" -#include "../../builtin.h" +#include +#include #define X86_FEATURE_POPCNT (4 * 32 + 23) #define X86_FEATURE_SMAP (9 * 32 + 20) @@ -48,7 +48,7 @@ bool arch_support_alt_relocation(struct special_alt *special_alt, * replacement group. */ return insn->offset == special_alt->new_off && - (insn->type == INSN_CALL || is_static_jump(insn)); + (insn->type == INSN_CALL || is_jump(insn)); } /* diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index c6d199bfd0ae..f47951e19c9d 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -15,8 +15,8 @@ #include #include -#include "builtin.h" -#include "objtool.h" +#include +#include bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux; diff --git a/tools/objtool/builtin-orc.c b/tools/objtool/builtin-orc.c index 7b31121fa60b..8273bbf7cebb 100644 --- a/tools/objtool/builtin-orc.c +++ b/tools/objtool/builtin-orc.c @@ -13,8 +13,8 @@ */ #include -#include "builtin.h" -#include "objtool.h" +#include +#include static const char *orc_usage[] = { "objtool orc generate [] file.o", @@ -51,11 +51,7 @@ int cmd_orc(int argc, const char **argv) if (list_empty(&file->insn_list)) return 0; - ret = create_orc(file); - if (ret) - return ret; - - ret = create_orc_sections(file); + ret = orc_create(file); if (ret) return ret; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f2e5e5ce1a05..331a763d8775 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -6,21 +6,20 @@ #include #include -#include "builtin.h" -#include "cfi.h" -#include "arch.h" -#include "check.h" -#include "special.h" -#include "warn.h" -#include "arch_elf.h" +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#define FAKE_JUMP_OFFSET -1 - struct alternative { struct list_head list; struct instruction *insn; @@ -111,15 +110,20 @@ static struct instruction *prev_insn_same_sym(struct objtool_file *file, static bool is_sibling_call(struct instruction *insn) { + /* + * Assume only ELF functions can make sibling calls. This ensures + * sibling call detection consistency between vmlinux.o and individual + * objects. + */ + if (!insn->func) + return false; + /* An indirect jump is either a sibling call or a jump to a table. */ if (insn->type == INSN_JUMP_DYNAMIC) return list_empty(&insn->alts); - if (!is_static_jump(insn)) - return false; - /* add_jump_destinations() sets insn->call_dest for sibling calls. */ - return !!insn->call_dest; + return (is_static_jump(insn) && insn->call_dest); } /* @@ -156,6 +160,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func, "machine_real_restart", "rewind_stack_do_exit", "kunit_try_catch_throw", + "xen_start_kernel", }; if (!func) @@ -787,22 +792,16 @@ static int add_jump_destinations(struct objtool_file *file) if (!is_static_jump(insn)) continue; - if (insn->offset == FAKE_JUMP_OFFSET) - continue; - reloc = find_reloc_by_dest_range(file->elf, insn->sec, - insn->offset, insn->len); + insn->offset, insn->len); if (!reloc) { dest_sec = insn->sec; dest_off = arch_jump_destination(insn); } else if (reloc->sym->type == STT_SECTION) { dest_sec = reloc->sym->sec; dest_off = arch_dest_reloc_offset(reloc->addend); - } else if (reloc->sym->sec->idx) { - dest_sec = reloc->sym->sec; - dest_off = reloc->sym->sym.st_value + - arch_dest_reloc_offset(reloc->addend); - } else if (strstr(reloc->sym->name, "_indirect_thunk_")) { + } else if (!strncmp(reloc->sym->name, "__x86_indirect_thunk_", 21) || + !strncmp(reloc->sym->name, "__x86_retpoline_", 16)) { /* * Retpoline jumps are really dynamic jumps in * disguise, so convert them accordingly. @@ -814,14 +813,21 @@ static int add_jump_destinations(struct objtool_file *file) insn->retpoline_safe = true; continue; - } else { - /* external sibling call */ + } else if (insn->func) { + /* internal or external sibling call (with reloc) */ insn->call_dest = reloc->sym; if (insn->call_dest->static_call_tramp) { list_add_tail(&insn->static_call_node, &file->static_call_list); } continue; + } else if (reloc->sym->sec->idx) { + dest_sec = reloc->sym->sec; + dest_off = reloc->sym->sym.st_value + + arch_dest_reloc_offset(reloc->addend); + } else { + /* non-func asm code jumping to another file */ + continue; } insn->jump_dest = find_insn(file, dest_sec, dest_off); @@ -862,15 +868,15 @@ static int add_jump_destinations(struct objtool_file *file) * case where the parent function's only reference to a * subfunction is through a jump table. */ - if (!strstr(insn->func->name, ".cold.") && - strstr(insn->jump_dest->func->name, ".cold.")) { + if (!strstr(insn->func->name, ".cold") && + strstr(insn->jump_dest->func->name, ".cold")) { insn->func->cfunc = insn->jump_dest->func; insn->jump_dest->func->pfunc = insn->func; } else if (insn->jump_dest->func->pfunc != insn->func->pfunc && insn->jump_dest->offset == insn->jump_dest->func->offset) { - /* internal sibling call */ + /* internal sibling call (without reloc) */ insn->call_dest = insn->jump_dest->func; if (insn->call_dest->static_call_tramp) { list_add_tail(&insn->static_call_node, @@ -983,73 +989,83 @@ static int add_call_destinations(struct objtool_file *file) } /* - * The .alternatives section requires some extra special care, over and above - * what other special sections require: - * - * 1. Because alternatives are patched in-place, we need to insert a fake jump - * instruction at the end so that validate_branch() skips all the original - * replaced instructions when validating the new instruction path. - * - * 2. An added wrinkle is that the new instruction length might be zero. In - * that case the old instructions are replaced with noops. We simulate that - * by creating a fake jump as the only new instruction. - * - * 3. In some cases, the alternative section includes an instruction which - * conditionally jumps to the _end_ of the entry. We have to modify these - * jumps' destinations to point back to .text rather than the end of the - * entry in .altinstr_replacement. + * The .alternatives section requires some extra special care over and above + * other special sections because alternatives are patched in place. */ static int handle_group_alt(struct objtool_file *file, struct special_alt *special_alt, struct instruction *orig_insn, struct instruction **new_insn) { - static unsigned int alt_group_next_index = 1; - struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump = NULL; - unsigned int alt_group = alt_group_next_index++; + struct instruction *last_orig_insn, *last_new_insn = NULL, *insn, *nop = NULL; + struct alt_group *orig_alt_group, *new_alt_group; unsigned long dest_off; + + orig_alt_group = malloc(sizeof(*orig_alt_group)); + if (!orig_alt_group) { + WARN("malloc failed"); + return -1; + } + orig_alt_group->cfi = calloc(special_alt->orig_len, + sizeof(struct cfi_state *)); + if (!orig_alt_group->cfi) { + WARN("calloc failed"); + return -1; + } + last_orig_insn = NULL; insn = orig_insn; sec_for_each_insn_from(file, insn) { if (insn->offset >= special_alt->orig_off + special_alt->orig_len) break; - insn->alt_group = alt_group; + insn->alt_group = orig_alt_group; last_orig_insn = insn; } + orig_alt_group->orig_group = NULL; + orig_alt_group->first_insn = orig_insn; + orig_alt_group->last_insn = last_orig_insn; - if (next_insn_same_sec(file, last_orig_insn)) { - fake_jump = malloc(sizeof(*fake_jump)); - if (!fake_jump) { + + new_alt_group = malloc(sizeof(*new_alt_group)); + if (!new_alt_group) { + WARN("malloc failed"); + return -1; + } + + if (special_alt->new_len < special_alt->orig_len) { + /* + * Insert a fake nop at the end to make the replacement + * alt_group the same size as the original. This is needed to + * allow propagate_alt_cfi() to do its magic. When the last + * instruction affects the stack, the instruction after it (the + * nop) will propagate the new state to the shared CFI array. + */ + nop = malloc(sizeof(*nop)); + if (!nop) { WARN("malloc failed"); return -1; } - memset(fake_jump, 0, sizeof(*fake_jump)); - INIT_LIST_HEAD(&fake_jump->alts); - INIT_LIST_HEAD(&fake_jump->stack_ops); - init_cfi_state(&fake_jump->cfi); + memset(nop, 0, sizeof(*nop)); + INIT_LIST_HEAD(&nop->alts); + INIT_LIST_HEAD(&nop->stack_ops); + init_cfi_state(&nop->cfi); - fake_jump->sec = special_alt->new_sec; - fake_jump->offset = FAKE_JUMP_OFFSET; - fake_jump->type = INSN_JUMP_UNCONDITIONAL; - fake_jump->jump_dest = list_next_entry(last_orig_insn, list); - fake_jump->func = orig_insn->func; + nop->sec = special_alt->new_sec; + nop->offset = special_alt->new_off + special_alt->new_len; + nop->len = special_alt->orig_len - special_alt->new_len; + nop->type = INSN_NOP; + nop->func = orig_insn->func; + nop->alt_group = new_alt_group; + nop->ignore = orig_insn->ignore_alts; } if (!special_alt->new_len) { - if (!fake_jump) { - WARN("%s: empty alternative at end of section", - special_alt->orig_sec->name); - return -1; - } - - *new_insn = fake_jump; - return 0; + *new_insn = nop; + goto end; } - last_new_insn = NULL; - alt_group = alt_group_next_index++; insn = *new_insn; sec_for_each_insn_from(file, insn) { struct reloc *alt_reloc; @@ -1061,7 +1077,7 @@ static int handle_group_alt(struct objtool_file *file, insn->ignore = orig_insn->ignore_alts; insn->func = orig_insn->func; - insn->alt_group = alt_group; + insn->alt_group = new_alt_group; /* * Since alternative replacement code is copy/pasted by the @@ -1088,14 +1104,8 @@ static int handle_group_alt(struct objtool_file *file, continue; dest_off = arch_jump_destination(insn); - if (dest_off == special_alt->new_off + special_alt->new_len) { - if (!fake_jump) { - WARN("%s: alternative jump to end of section", - special_alt->orig_sec->name); - return -1; - } - insn->jump_dest = fake_jump; - } + if (dest_off == special_alt->new_off + special_alt->new_len) + insn->jump_dest = next_insn_same_sec(file, last_orig_insn); if (!insn->jump_dest) { WARN_FUNC("can't find alternative jump destination", @@ -1110,9 +1120,13 @@ static int handle_group_alt(struct objtool_file *file, return -1; } - if (fake_jump) - list_add(&fake_jump->list, &last_new_insn->list); - + if (nop) + list_add(&nop->list, &last_new_insn->list); +end: + new_alt_group->orig_group = orig_alt_group; + new_alt_group->first_insn = *new_insn; + new_alt_group->last_insn = nop ? : last_new_insn; + new_alt_group->cfi = orig_alt_group->cfi; return 0; } @@ -1404,13 +1418,20 @@ static int add_jump_table_alts(struct objtool_file *file) return 0; } +static void set_func_state(struct cfi_state *state) +{ + state->cfa = initial_func_cfi.cfa; + memcpy(&state->regs, &initial_func_cfi.regs, + CFI_NUM_REGS * sizeof(struct cfi_reg)); + state->stack_size = initial_func_cfi.cfa.offset; +} + static int read_unwind_hints(struct objtool_file *file) { struct section *sec, *relocsec; struct reloc *reloc; struct unwind_hint *hint; struct instruction *insn; - struct cfi_reg *cfa; int i; sec = find_section_by_name(file->elf, ".discard.unwind_hints"); @@ -1445,22 +1466,20 @@ static int read_unwind_hints(struct objtool_file *file) return -1; } - cfa = &insn->cfi.cfa; + insn->hint = true; - if (hint->type == UNWIND_HINT_TYPE_RET_OFFSET) { - insn->ret_offset = hint->sp_offset; + if (hint->type == UNWIND_HINT_TYPE_FUNC) { + set_func_state(&insn->cfi); continue; } - insn->hint = true; - if (arch_decode_hint_reg(insn, hint->sp_reg)) { WARN_FUNC("unsupported unwind_hint sp base reg %d", insn->sec, insn->offset, hint->sp_reg); return -1; } - cfa->offset = hint->sp_offset; + insn->cfi.cfa.offset = bswap_if_needed(hint->sp_offset); insn->cfi.type = hint->type; insn->cfi.end = hint->end; } @@ -1716,27 +1735,18 @@ static bool is_fentry_call(struct instruction *insn) static bool has_modified_stack_frame(struct instruction *insn, struct insn_state *state) { - u8 ret_offset = insn->ret_offset; struct cfi_state *cfi = &state->cfi; int i; if (cfi->cfa.base != initial_func_cfi.cfa.base || cfi->drap) return true; - if (cfi->cfa.offset != initial_func_cfi.cfa.offset + ret_offset) + if (cfi->cfa.offset != initial_func_cfi.cfa.offset) return true; - if (cfi->stack_size != initial_func_cfi.cfa.offset + ret_offset) + if (cfi->stack_size != initial_func_cfi.cfa.offset) return true; - /* - * If there is a ret offset hint then don't check registers - * because a callee-saved register might have been pushed on - * the stack. - */ - if (ret_offset) - return false; - for (i = 0; i < CFI_NUM_REGS; i++) { if (cfi->regs[i].base != initial_func_cfi.regs[i].base || cfi->regs[i].offset != initial_func_cfi.regs[i].offset) @@ -1746,12 +1756,20 @@ static bool has_modified_stack_frame(struct instruction *insn, struct insn_state return false; } +static bool check_reg_frame_pos(const struct cfi_reg *reg, + int expected_offset) +{ + return reg->base == CFI_CFA && + reg->offset == expected_offset; +} + static bool has_valid_stack_frame(struct insn_state *state) { struct cfi_state *cfi = &state->cfi; - if (cfi->cfa.base == CFI_BP && cfi->regs[CFI_BP].base == CFI_CFA && - cfi->regs[CFI_BP].offset == -16) + if (cfi->cfa.base == CFI_BP && + check_reg_frame_pos(&cfi->regs[CFI_BP], -cfi->cfa.offset) && + check_reg_frame_pos(&cfi->regs[CFI_RA], -cfi->cfa.offset + 8)) return true; if (cfi->drap && cfi->regs[CFI_BP].base == CFI_BP) @@ -1880,8 +1898,7 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi, case OP_SRC_REG: if (op->src.reg == CFI_SP && op->dest.reg == CFI_BP && cfa->base == CFI_SP && - regs[CFI_BP].base == CFI_CFA && - regs[CFI_BP].offset == -cfa->offset) { + check_reg_frame_pos(®s[CFI_BP], -cfa->offset)) { /* mov %rsp, %rbp */ cfa->base = op->dest.reg; @@ -1941,6 +1958,38 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi, cfa->offset = -cfi->vals[op->src.reg].offset; cfi->stack_size = cfa->offset; + } else if (cfa->base == CFI_SP && + cfi->vals[op->src.reg].base == CFI_SP_INDIRECT && + cfi->vals[op->src.reg].offset == cfa->offset) { + + /* + * Stack swizzle: + * + * 1: mov %rsp, (%[tos]) + * 2: mov %[tos], %rsp + * ... + * 3: pop %rsp + * + * Where: + * + * 1 - places a pointer to the previous + * stack at the Top-of-Stack of the + * new stack. + * + * 2 - switches to the new stack. + * + * 3 - pops the Top-of-Stack to restore + * the original stack. + * + * Note: we set base to SP_INDIRECT + * here and preserve offset. Therefore + * when the unwinder reaches ToS it + * will dereference SP and then add the + * offset to find the next frame, IOW: + * (%rsp) + offset. + */ + cfa->base = CFI_SP_INDIRECT; + } else { cfa->base = CFI_UNDEFINED; cfa->offset = 0; @@ -1966,6 +2015,17 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi, break; } + if (!cfi->drap && op->src.reg == CFI_SP && + op->dest.reg == CFI_BP && cfa->base == CFI_SP && + check_reg_frame_pos(®s[CFI_BP], -cfa->offset + op->src.offset)) { + + /* lea disp(%rsp), %rbp */ + cfa->base = CFI_BP; + cfa->offset -= op->src.offset; + cfi->bp_scratch = false; + break; + } + if (op->src.reg == CFI_SP && cfa->base == CFI_SP) { /* drap: lea disp(%rsp), %drap */ @@ -2032,6 +2092,13 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi, case OP_SRC_POP: case OP_SRC_POPF: + if (op->dest.reg == CFI_SP && cfa->base == CFI_SP_INDIRECT) { + + /* pop %rsp; # restore from a stack swizzle */ + cfa->base = CFI_SP; + break; + } + if (!cfi->drap && op->dest.reg == cfa->base) { /* pop %rbp */ @@ -2060,6 +2127,14 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi, break; case OP_SRC_REG_INDIRECT: + if (!cfi->drap && op->dest.reg == cfa->base && + op->dest.reg == CFI_BP) { + + /* mov disp(%rsp), %rbp */ + cfa->base = CFI_SP; + cfa->offset = cfi->stack_size; + } + if (cfi->drap && op->src.reg == CFI_BP && op->src.offset == cfi->drap_offset) { @@ -2081,6 +2156,12 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi, /* mov disp(%rbp), %reg */ /* mov disp(%rsp), %reg */ restore_reg(cfi, op->dest.reg); + + } else if (op->src.reg == CFI_SP && + op->src.offset == regs[op->dest.reg].offset + cfi->stack_size) { + + /* mov disp(%rsp), %reg */ + restore_reg(cfi, op->dest.reg); } break; @@ -2158,6 +2239,18 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi, /* mov reg, disp(%rsp) */ save_reg(cfi, op->src.reg, CFI_CFA, op->dest.offset - cfi->cfa.offset); + + } else if (op->dest.reg == CFI_SP) { + + /* mov reg, disp(%rsp) */ + save_reg(cfi, op->src.reg, CFI_CFA, + op->dest.offset - cfi->stack_size); + + } else if (op->src.reg == CFI_SP && op->dest.offset == 0) { + + /* mov %rsp, (%reg); # setup a stack swizzle. */ + cfi->vals[op->dest.reg].base = CFI_SP_INDIRECT; + cfi->vals[op->dest.reg].offset = cfa->offset; } break; @@ -2205,22 +2298,47 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi, return 0; } +/* + * The stack layouts of alternatives instructions can sometimes diverge when + * they have stack modifications. That's fine as long as the potential stack + * layouts don't conflict at any given potential instruction boundary. + * + * Flatten the CFIs of the different alternative code streams (both original + * and replacement) into a single shared CFI array which can be used to detect + * conflicts and nicely feed a linear array of ORC entries to the unwinder. + */ +static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn) +{ + struct cfi_state **alt_cfi; + int group_off; + + if (!insn->alt_group) + return 0; + + alt_cfi = insn->alt_group->cfi; + group_off = insn->offset - insn->alt_group->first_insn->offset; + + if (!alt_cfi[group_off]) { + alt_cfi[group_off] = &insn->cfi; + } else { + if (memcmp(alt_cfi[group_off], &insn->cfi, sizeof(struct cfi_state))) { + WARN_FUNC("stack layout conflict in alternatives", + insn->sec, insn->offset); + return -1; + } + } + + return 0; +} + static int handle_insn_ops(struct instruction *insn, struct insn_state *state) { struct stack_op *op; list_for_each_entry(op, &insn->stack_ops, list) { - struct cfi_state old_cfi = state->cfi; - int res; - res = update_cfi_state(insn, &state->cfi, op); - if (res) - return res; - - if (insn->alt_group && memcmp(&state->cfi, &old_cfi, sizeof(struct cfi_state))) { - WARN_FUNC("alternative modifies stack", insn->sec, insn->offset); - return -1; - } + if (update_cfi_state(insn, &state->cfi, op)) + return 1; if (op->dest.type == OP_DEST_PUSHF) { if (!state->uaccess_stack) { @@ -2410,28 +2528,20 @@ static int validate_return(struct symbol *func, struct instruction *insn, struct return 0; } -/* - * Alternatives should not contain any ORC entries, this in turn means they - * should not contain any CFI ops, which implies all instructions should have - * the same same CFI state. - * - * It is possible to constuct alternatives that have unreachable holes that go - * unreported (because they're NOPs), such holes would result in CFI_UNDEFINED - * states which then results in ORC entries, which we just said we didn't want. - * - * Avoid them by copying the CFI entry of the first instruction into the whole - * alternative. - */ -static void fill_alternative_cfi(struct objtool_file *file, struct instruction *insn) +static struct instruction *next_insn_to_validate(struct objtool_file *file, + struct instruction *insn) { - struct instruction *first_insn = insn; - int alt_group = insn->alt_group; + struct alt_group *alt_group = insn->alt_group; - sec_for_each_insn_continue(file, insn) { - if (insn->alt_group != alt_group) - break; - insn->cfi = first_insn->cfi; - } + /* + * Simulate the fact that alternatives are patched in-place. When the + * end of a replacement alt_group is reached, redirect objtool flow to + * the end of the original alt_group. + */ + if (alt_group && insn == alt_group->last_insn && alt_group->orig_group) + return next_insn_same_sec(file, alt_group->orig_group->last_insn); + + return next_insn_same_sec(file, insn); } /* @@ -2452,7 +2562,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, sec = insn->sec; while (1) { - next_insn = next_insn_same_sec(file, insn); + next_insn = next_insn_to_validate(file, insn); if (file->c_file && func && insn->func && func != insn->func->pfunc) { WARN("%s() falls through to next function %s()", @@ -2485,6 +2595,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, insn->visited |= visited; + if (propagate_alt_cfi(file, insn)) + return 1; + if (!insn->ignore_alts && !list_empty(&insn->alts)) { bool skip_orig = false; @@ -2500,9 +2613,6 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, } } - if (insn->alt_group) - fill_alternative_cfi(file, insn); - if (skip_orig) return 0; } @@ -2540,7 +2650,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, case INSN_JUMP_CONDITIONAL: case INSN_JUMP_UNCONDITIONAL: - if (func && is_sibling_call(insn)) { + if (is_sibling_call(insn)) { ret = validate_sibling_call(insn, &state); if (ret) return ret; @@ -2562,7 +2672,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, case INSN_JUMP_DYNAMIC: case INSN_JUMP_DYNAMIC_CONDITIONAL: - if (func && is_sibling_call(insn)) { + if (is_sibling_call(insn)) { ret = validate_sibling_call(insn, &state); if (ret) return ret; @@ -2605,15 +2715,19 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, break; case INSN_STD: - if (state.df) + if (state.df) { WARN_FUNC("recursive STD", sec, insn->offset); + return 1; + } state.df = true; break; case INSN_CLD: - if (!state.df && func) + if (!state.df && func) { WARN_FUNC("redundant CLD", sec, insn->offset); + return 1; + } state.df = false; break; @@ -2736,9 +2850,6 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio !strcmp(insn->sec->name, ".altinstr_aux")) return true; - if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->offset == FAKE_JUMP_OFFSET) - return true; - if (!insn->func) return false; @@ -2824,10 +2935,7 @@ static int validate_section(struct objtool_file *file, struct section *sec) continue; init_insn_state(&state, sec); - state.cfi.cfa = initial_func_cfi.cfa; - memcpy(&state.cfi.regs, &initial_func_cfi.regs, - CFI_NUM_REGS * sizeof(struct cfi_reg)); - state.cfi.stack_size = initial_func_cfi.cfa.offset; + set_func_state(&state.cfi); warnings += validate_symbol(file, sec, func, &state); } diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index e85988ce04f1..93fa833a49a5 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -15,10 +15,10 @@ #include #include #include -#include "builtin.h" +#include -#include "elf.h" -#include "warn.h" +#include +#include #define MAX_NAME_LEN 128 @@ -814,25 +814,27 @@ static int elf_rebuild_rel_reloc_section(struct section *sec, int nr) { struct reloc *reloc; int idx = 0, size; - GElf_Rel *relocs; + void *buf; /* Allocate a buffer for relocations */ - size = nr * sizeof(*relocs); - relocs = malloc(size); - if (!relocs) { + size = nr * sizeof(GElf_Rel); + buf = malloc(size); + if (!buf) { perror("malloc"); return -1; } - sec->data->d_buf = relocs; + sec->data->d_buf = buf; sec->data->d_size = size; + sec->data->d_type = ELF_T_REL; sec->sh.sh_size = size; idx = 0; list_for_each_entry(reloc, &sec->reloc_list, list) { - relocs[idx].r_offset = reloc->offset; - relocs[idx].r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); + reloc->rel.r_offset = reloc->offset; + reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); + gelf_update_rel(sec->data, idx, &reloc->rel); idx++; } @@ -843,26 +845,28 @@ static int elf_rebuild_rela_reloc_section(struct section *sec, int nr) { struct reloc *reloc; int idx = 0, size; - GElf_Rela *relocs; + void *buf; /* Allocate a buffer for relocations with addends */ - size = nr * sizeof(*relocs); - relocs = malloc(size); - if (!relocs) { + size = nr * sizeof(GElf_Rela); + buf = malloc(size); + if (!buf) { perror("malloc"); return -1; } - sec->data->d_buf = relocs; + sec->data->d_buf = buf; sec->data->d_size = size; + sec->data->d_type = ELF_T_RELA; sec->sh.sh_size = size; idx = 0; list_for_each_entry(reloc, &sec->reloc_list, list) { - relocs[idx].r_offset = reloc->offset; - relocs[idx].r_addend = reloc->addend; - relocs[idx].r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); + reloc->rela.r_offset = reloc->offset; + reloc->rela.r_addend = reloc->addend; + reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); + gelf_update_rela(sec->data, idx, &reloc->rela); idx++; } diff --git a/tools/objtool/arch.h b/tools/objtool/include/objtool/arch.h similarity index 94% rename from tools/objtool/arch.h rename to tools/objtool/include/objtool/arch.h index 4a84c3081b8e..6ff0685f5cc5 100644 --- a/tools/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -8,12 +8,8 @@ #include #include -#include "objtool.h" -#include "cfi.h" - -#ifdef INSN_USE_ORC -#include -#endif +#include +#include enum insn_type { INSN_JUMP_CONDITIONAL, diff --git a/tools/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h similarity index 100% rename from tools/objtool/builtin.h rename to tools/objtool/include/objtool/builtin.h diff --git a/tools/objtool/cfi.h b/tools/objtool/include/objtool/cfi.h similarity index 96% rename from tools/objtool/cfi.h rename to tools/objtool/include/objtool/cfi.h index c7c59c6a44ee..fd5cb0bed9bf 100644 --- a/tools/objtool/cfi.h +++ b/tools/objtool/include/objtool/cfi.h @@ -6,7 +6,7 @@ #ifndef _OBJTOOL_CFI_H #define _OBJTOOL_CFI_H -#include "cfi_regs.h" +#include #define CFI_UNDEFINED -1 #define CFI_CFA -2 diff --git a/tools/objtool/check.h b/tools/objtool/include/objtool/check.h similarity index 64% rename from tools/objtool/check.h rename to tools/objtool/include/objtool/check.h index 5ec00a4b891b..4891ead0e85f 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -7,8 +7,8 @@ #define _CHECK_H #include -#include "cfi.h" -#include "arch.h" +#include +#include struct insn_state { struct cfi_state cfi; @@ -19,6 +19,23 @@ struct insn_state { s8 instr; }; +struct alt_group { + /* + * Pointer from a replacement group to the original group. NULL if it + * *is* the original group. + */ + struct alt_group *orig_group; + + /* First and last instructions in the group */ + struct instruction *first_insn, *last_insn; + + /* + * Byte-offset-addressed len-sized array of pointers to CFI structs. + * This is shared with the other alt_groups in the same alternative. + */ + struct cfi_state **cfi; +}; + struct instruction { struct list_head list; struct hlist_node hash; @@ -33,8 +50,7 @@ struct instruction { bool retpoline_safe; s8 instr; u8 visited; - u8 ret_offset; - int alt_group; + struct alt_group *alt_group; struct symbol *call_dest; struct instruction *jump_dest; struct instruction *first_jump_src; @@ -43,9 +59,6 @@ struct instruction { struct symbol *func; struct list_head stack_ops; struct cfi_state cfi; -#ifdef INSN_USE_ORC - struct orc_entry orc; -#endif }; static inline bool is_static_jump(struct instruction *insn) @@ -54,6 +67,17 @@ static inline bool is_static_jump(struct instruction *insn) insn->type == INSN_JUMP_UNCONDITIONAL; } +static inline bool is_dynamic_jump(struct instruction *insn) +{ + return insn->type == INSN_JUMP_DYNAMIC || + insn->type == INSN_JUMP_DYNAMIC_CONDITIONAL; +} + +static inline bool is_jump(struct instruction *insn) +{ + return is_static_jump(insn) || is_dynamic_jump(insn); +} + struct instruction *find_insn(struct objtool_file *file, struct section *sec, unsigned long offset); diff --git a/tools/objtool/elf.h b/tools/objtool/include/objtool/elf.h similarity index 100% rename from tools/objtool/elf.h rename to tools/objtool/include/objtool/elf.h diff --git a/tools/objtool/include/objtool/endianness.h b/tools/objtool/include/objtool/endianness.h new file mode 100644 index 000000000000..10241341eff3 --- /dev/null +++ b/tools/objtool/include/objtool/endianness.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _OBJTOOL_ENDIANNESS_H +#define _OBJTOOL_ENDIANNESS_H + +#include +#include +#include + +#ifndef __TARGET_BYTE_ORDER +#error undefined arch __TARGET_BYTE_ORDER +#endif + +#if __BYTE_ORDER != __TARGET_BYTE_ORDER +#define __NEED_BSWAP 1 +#else +#define __NEED_BSWAP 0 +#endif + +/* + * Does a byte swap if target endianness doesn't match the host, i.e. cross + * compilation for little endian on big endian and vice versa. + * To be used for multi-byte values conversion, which are read from / about + * to be written to a target native endianness ELF file. + */ +#define bswap_if_needed(val) \ +({ \ + __typeof__(val) __ret; \ + switch (sizeof(val)) { \ + case 8: __ret = __NEED_BSWAP ? bswap_64(val) : (val); break; \ + case 4: __ret = __NEED_BSWAP ? bswap_32(val) : (val); break; \ + case 2: __ret = __NEED_BSWAP ? bswap_16(val) : (val); break; \ + default: \ + BUILD_BUG(); break; \ + } \ + __ret; \ +}) + +#endif /* _OBJTOOL_ENDIANNESS_H */ diff --git a/tools/objtool/objtool.h b/tools/objtool/include/objtool/objtool.h similarity index 84% rename from tools/objtool/objtool.h rename to tools/objtool/include/objtool/objtool.h index 4125d4578b23..e114642efb65 100644 --- a/tools/objtool/objtool.h +++ b/tools/objtool/include/objtool/objtool.h @@ -10,7 +10,7 @@ #include #include -#include "elf.h" +#include #define __weak __attribute__((weak)) @@ -26,7 +26,6 @@ struct objtool_file *objtool_open_read(const char *_objname); int check(struct objtool_file *file); int orc_dump(const char *objname); -int create_orc(struct objtool_file *file); -int create_orc_sections(struct objtool_file *file); +int orc_create(struct objtool_file *file); #endif /* _OBJTOOL_H */ diff --git a/tools/objtool/special.h b/tools/objtool/include/objtool/special.h similarity index 94% rename from tools/objtool/special.h rename to tools/objtool/include/objtool/special.h index abddf38ef334..8a09f4e9d480 100644 --- a/tools/objtool/special.h +++ b/tools/objtool/include/objtool/special.h @@ -7,8 +7,8 @@ #define _SPECIAL_H #include -#include "check.h" -#include "elf.h" +#include +#include #define C_JUMP_TABLE_SECTION ".rodata..c_jump_table" diff --git a/tools/objtool/warn.h b/tools/objtool/include/objtool/warn.h similarity index 98% rename from tools/objtool/warn.h rename to tools/objtool/include/objtool/warn.h index 7799f60de80a..d99c4675e4a5 100644 --- a/tools/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -11,7 +11,7 @@ #include #include #include -#include "elf.h" +#include extern const char *objname; diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index 9df0cd86d310..e848feb0a5fc 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -21,9 +21,9 @@ #include #include -#include "builtin.h" -#include "objtool.h" -#include "warn.h" +#include +#include +#include struct cmd_struct { const char *name; diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c index 5e6a95368d35..f5a8508c42d6 100644 --- a/tools/objtool/orc_dump.c +++ b/tools/objtool/orc_dump.c @@ -6,8 +6,9 @@ #include #include #include -#include "objtool.h" -#include "warn.h" +#include +#include +#include static const char *reg_name(unsigned int reg) { @@ -54,7 +55,7 @@ static void print_reg(unsigned int reg, int offset) if (reg == ORC_REG_BP_INDIRECT) printf("(bp%+d)", offset); else if (reg == ORC_REG_SP_INDIRECT) - printf("(sp%+d)", offset); + printf("(sp)%+d", offset); else if (reg == ORC_REG_UNDEFINED) printf("(und)"); else @@ -197,11 +198,11 @@ int orc_dump(const char *_objname) printf(" sp:"); - print_reg(orc[i].sp_reg, orc[i].sp_offset); + print_reg(orc[i].sp_reg, bswap_if_needed(orc[i].sp_offset)); printf(" bp:"); - print_reg(orc[i].bp_reg, orc[i].bp_offset); + print_reg(orc[i].bp_reg, bswap_if_needed(orc[i].bp_offset)); printf(" type:%s end:%d\n", orc_type_name(orc[i].type), orc[i].end); diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index 9ce68b385a1b..738aa5021bc4 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -9,93 +9,91 @@ #include #include -#include "check.h" -#include "warn.h" +#include +#include +#include -int create_orc(struct objtool_file *file) +static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi) { - struct instruction *insn; + struct instruction *insn = container_of(cfi, struct instruction, cfi); + struct cfi_reg *bp = &cfi->regs[CFI_BP]; - for_each_insn(file, insn) { - struct orc_entry *orc = &insn->orc; - struct cfi_reg *cfa = &insn->cfi.cfa; - struct cfi_reg *bp = &insn->cfi.regs[CFI_BP]; + memset(orc, 0, sizeof(*orc)); - if (!insn->sec->text) - continue; + orc->end = cfi->end; - orc->end = insn->cfi.end; - - if (cfa->base == CFI_UNDEFINED) { - orc->sp_reg = ORC_REG_UNDEFINED; - continue; - } - - switch (cfa->base) { - case CFI_SP: - orc->sp_reg = ORC_REG_SP; - break; - case CFI_SP_INDIRECT: - orc->sp_reg = ORC_REG_SP_INDIRECT; - break; - case CFI_BP: - orc->sp_reg = ORC_REG_BP; - break; - case CFI_BP_INDIRECT: - orc->sp_reg = ORC_REG_BP_INDIRECT; - break; - case CFI_R10: - orc->sp_reg = ORC_REG_R10; - break; - case CFI_R13: - orc->sp_reg = ORC_REG_R13; - break; - case CFI_DI: - orc->sp_reg = ORC_REG_DI; - break; - case CFI_DX: - orc->sp_reg = ORC_REG_DX; - break; - default: - WARN_FUNC("unknown CFA base reg %d", - insn->sec, insn->offset, cfa->base); - return -1; - } - - switch(bp->base) { - case CFI_UNDEFINED: - orc->bp_reg = ORC_REG_UNDEFINED; - break; - case CFI_CFA: - orc->bp_reg = ORC_REG_PREV_SP; - break; - case CFI_BP: - orc->bp_reg = ORC_REG_BP; - break; - default: - WARN_FUNC("unknown BP base reg %d", - insn->sec, insn->offset, bp->base); - return -1; - } - - orc->sp_offset = cfa->offset; - orc->bp_offset = bp->offset; - orc->type = insn->cfi.type; + if (cfi->cfa.base == CFI_UNDEFINED) { + orc->sp_reg = ORC_REG_UNDEFINED; + return 0; } + switch (cfi->cfa.base) { + case CFI_SP: + orc->sp_reg = ORC_REG_SP; + break; + case CFI_SP_INDIRECT: + orc->sp_reg = ORC_REG_SP_INDIRECT; + break; + case CFI_BP: + orc->sp_reg = ORC_REG_BP; + break; + case CFI_BP_INDIRECT: + orc->sp_reg = ORC_REG_BP_INDIRECT; + break; + case CFI_R10: + orc->sp_reg = ORC_REG_R10; + break; + case CFI_R13: + orc->sp_reg = ORC_REG_R13; + break; + case CFI_DI: + orc->sp_reg = ORC_REG_DI; + break; + case CFI_DX: + orc->sp_reg = ORC_REG_DX; + break; + default: + WARN_FUNC("unknown CFA base reg %d", + insn->sec, insn->offset, cfi->cfa.base); + return -1; + } + + switch (bp->base) { + case CFI_UNDEFINED: + orc->bp_reg = ORC_REG_UNDEFINED; + break; + case CFI_CFA: + orc->bp_reg = ORC_REG_PREV_SP; + break; + case CFI_BP: + orc->bp_reg = ORC_REG_BP; + break; + default: + WARN_FUNC("unknown BP base reg %d", + insn->sec, insn->offset, bp->base); + return -1; + } + + orc->sp_offset = cfi->cfa.offset; + orc->bp_offset = bp->offset; + orc->type = cfi->type; + return 0; } -static int create_orc_entry(struct elf *elf, struct section *u_sec, struct section *ip_relocsec, - unsigned int idx, struct section *insn_sec, - unsigned long insn_off, struct orc_entry *o) +static int write_orc_entry(struct elf *elf, struct section *orc_sec, + struct section *ip_rsec, unsigned int idx, + struct section *insn_sec, unsigned long insn_off, + struct orc_entry *o) { struct orc_entry *orc; struct reloc *reloc; /* populate ORC data */ - orc = (struct orc_entry *)u_sec->data->d_buf + idx; + orc = (struct orc_entry *)orc_sec->data->d_buf + idx; memcpy(orc, o, sizeof(*orc)); + orc->sp_offset = bswap_if_needed(orc->sp_offset); + orc->bp_offset = bswap_if_needed(orc->bp_offset); /* populate reloc for ip */ reloc = malloc(sizeof(*reloc)); @@ -114,102 +112,149 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti reloc->type = R_X86_64_PC32; reloc->offset = idx * sizeof(int); - reloc->sec = ip_relocsec; + reloc->sec = ip_rsec; elf_add_reloc(elf, reloc); return 0; } -int create_orc_sections(struct objtool_file *file) -{ - struct instruction *insn, *prev_insn; - struct section *sec, *u_sec, *ip_relocsec; - unsigned int idx; +struct orc_list_entry { + struct list_head list; + struct orc_entry orc; + struct section *insn_sec; + unsigned long insn_off; +}; - struct orc_entry empty = { - .sp_reg = ORC_REG_UNDEFINED, +static int orc_list_add(struct list_head *orc_list, struct orc_entry *orc, + struct section *sec, unsigned long offset) +{ + struct orc_list_entry *entry = malloc(sizeof(*entry)); + + if (!entry) { + WARN("malloc failed"); + return -1; + } + + entry->orc = *orc; + entry->insn_sec = sec; + entry->insn_off = offset; + + list_add_tail(&entry->list, orc_list); + return 0; +} + +static unsigned long alt_group_len(struct alt_group *alt_group) +{ + return alt_group->last_insn->offset + + alt_group->last_insn->len - + alt_group->first_insn->offset; +} + +int orc_create(struct objtool_file *file) +{ + struct section *sec, *ip_rsec, *orc_sec; + unsigned int nr = 0, idx = 0; + struct orc_list_entry *entry; + struct list_head orc_list; + + struct orc_entry null = { + .sp_reg = ORC_REG_UNDEFINED, .bp_reg = ORC_REG_UNDEFINED, .type = UNWIND_HINT_TYPE_CALL, }; + /* Build a deduplicated list of ORC entries: */ + INIT_LIST_HEAD(&orc_list); + for_each_sec(file, sec) { + struct orc_entry orc, prev_orc = {0}; + struct instruction *insn; + bool empty = true; + + if (!sec->text) + continue; + + sec_for_each_insn(file, sec, insn) { + struct alt_group *alt_group = insn->alt_group; + int i; + + if (!alt_group) { + if (init_orc_entry(&orc, &insn->cfi)) + return -1; + if (!memcmp(&prev_orc, &orc, sizeof(orc))) + continue; + if (orc_list_add(&orc_list, &orc, sec, + insn->offset)) + return -1; + nr++; + prev_orc = orc; + empty = false; + continue; + } + + /* + * Alternatives can have different stack layout + * possibilities (but they shouldn't conflict). + * Instead of traversing the instructions, use the + * alt_group's flattened byte-offset-addressed CFI + * array. + */ + for (i = 0; i < alt_group_len(alt_group); i++) { + struct cfi_state *cfi = alt_group->cfi[i]; + if (!cfi) + continue; + if (init_orc_entry(&orc, cfi)) + return -1; + if (!memcmp(&prev_orc, &orc, sizeof(orc))) + continue; + if (orc_list_add(&orc_list, &orc, insn->sec, + insn->offset + i)) + return -1; + nr++; + prev_orc = orc; + empty = false; + } + + /* Skip to the end of the alt_group */ + insn = alt_group->last_insn; + } + + /* Add a section terminator */ + if (!empty) { + orc_list_add(&orc_list, &null, sec, sec->len); + nr++; + } + } + if (!nr) + return 0; + + /* Create .orc_unwind, .orc_unwind_ip and .rela.orc_unwind_ip sections: */ sec = find_section_by_name(file->elf, ".orc_unwind"); if (sec) { WARN("file already has .orc_unwind section, skipping"); return -1; } - - /* count the number of needed orcs */ - idx = 0; - for_each_sec(file, sec) { - if (!sec->text) - continue; - - prev_insn = NULL; - sec_for_each_insn(file, sec, insn) { - if (!prev_insn || - memcmp(&insn->orc, &prev_insn->orc, - sizeof(struct orc_entry))) { - idx++; - } - prev_insn = insn; - } - - /* section terminator */ - if (prev_insn) - idx++; - } - if (!idx) + orc_sec = elf_create_section(file->elf, ".orc_unwind", 0, + sizeof(struct orc_entry), nr); + if (!orc_sec) return -1; - - /* create .orc_unwind_ip and .rela.orc_unwind_ip sections */ - sec = elf_create_section(file->elf, ".orc_unwind_ip", 0, sizeof(int), idx); + sec = elf_create_section(file->elf, ".orc_unwind_ip", 0, sizeof(int), nr); if (!sec) return -1; - - ip_relocsec = elf_create_reloc_section(file->elf, sec, SHT_RELA); - if (!ip_relocsec) + ip_rsec = elf_create_reloc_section(file->elf, sec, SHT_RELA); + if (!ip_rsec) return -1; - /* create .orc_unwind section */ - u_sec = elf_create_section(file->elf, ".orc_unwind", 0, - sizeof(struct orc_entry), idx); - - /* populate sections */ - idx = 0; - for_each_sec(file, sec) { - if (!sec->text) - continue; - - prev_insn = NULL; - sec_for_each_insn(file, sec, insn) { - if (!prev_insn || memcmp(&insn->orc, &prev_insn->orc, - sizeof(struct orc_entry))) { - - if (create_orc_entry(file->elf, u_sec, ip_relocsec, idx, - insn->sec, insn->offset, - &insn->orc)) - return -1; - - idx++; - } - prev_insn = insn; - } - - /* section terminator */ - if (prev_insn) { - if (create_orc_entry(file->elf, u_sec, ip_relocsec, idx, - prev_insn->sec, - prev_insn->offset + prev_insn->len, - &empty)) - return -1; - - idx++; - } + /* Write ORC entries to sections: */ + list_for_each_entry(entry, &orc_list, list) { + if (write_orc_entry(file->elf, orc_sec, ip_rsec, idx++, + entry->insn_sec, entry->insn_off, + &entry->orc)) + return -1; } - if (elf_rebuild_reloc_section(file->elf, ip_relocsec)) + if (elf_rebuild_reloc_section(file->elf, ip_rsec)) return -1; return 0; diff --git a/tools/objtool/special.c b/tools/objtool/special.c index 1a2420febd08..2c7fbda7b055 100644 --- a/tools/objtool/special.c +++ b/tools/objtool/special.c @@ -11,10 +11,11 @@ #include #include -#include "builtin.h" -#include "special.h" -#include "warn.h" -#include "arch_special.h" +#include +#include +#include +#include +#include struct special_entry { const char *sec; @@ -77,8 +78,9 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry, if (entry->feature) { unsigned short feature; - feature = *(unsigned short *)(sec->data->d_buf + offset + - entry->feature); + feature = bswap_if_needed(*(unsigned short *)(sec->data->d_buf + + offset + + entry->feature)); arch_handle_alternative(feature, alt); } diff --git a/tools/objtool/weak.c b/tools/objtool/weak.c index 7843e9a7a72f..8314e824db4a 100644 --- a/tools/objtool/weak.c +++ b/tools/objtool/weak.c @@ -7,7 +7,7 @@ #include #include -#include "objtool.h" +#include #define UNSUPPORTED(name) \ ({ \ @@ -25,12 +25,7 @@ int __weak orc_dump(const char *_objname) UNSUPPORTED("orc"); } -int __weak create_orc(struct objtool_file *file) -{ - UNSUPPORTED("orc"); -} - -int __weak create_orc_sections(struct objtool_file *file) +int __weak orc_create(struct objtool_file *file) { UNSUPPORTED("orc"); } diff --git a/tools/testing/selftests/powerpc/eeh/eeh-basic.sh b/tools/testing/selftests/powerpc/eeh/eeh-basic.sh index 0d783e1065c8..442b666ccdb5 100755 --- a/tools/testing/selftests/powerpc/eeh/eeh-basic.sh +++ b/tools/testing/selftests/powerpc/eeh/eeh-basic.sh @@ -1,28 +1,13 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0-only -KSELFTESTS_SKIP=4 - . ./eeh-functions.sh -if ! eeh_supported ; then - echo "EEH not supported on this system, skipping" - exit $KSELFTESTS_SKIP; -fi - -if [ ! -e "/sys/kernel/debug/powerpc/eeh_dev_check" ] && \ - [ ! -e "/sys/kernel/debug/powerpc/eeh_dev_break" ] ; then - echo "debugfs EEH testing files are missing. Is debugfs mounted?" - exit $KSELFTESTS_SKIP; -fi +eeh_test_prep # NB: may exit pre_lspci=`mktemp` lspci > $pre_lspci -# Bump the max freeze count to something absurd so we don't -# trip over it while breaking things. -echo 5000 > /sys/kernel/debug/powerpc/eeh_max_freezes - # record the devices that we break in here. Assuming everything # goes to plan we should get them back once the recover process # is finished. @@ -30,34 +15,16 @@ devices="" # Build up a list of candidate devices. for dev in `ls -1 /sys/bus/pci/devices/ | grep '\.0$'` ; do - # skip bridges since we can't recover them (yet...) - if [ -e "/sys/bus/pci/devices/$dev/pci_bus" ] ; then - echo "$dev, Skipped: bridge" + if ! eeh_can_break $dev ; then continue; fi - # Skip VFs for now since we don't have a reliable way - # to break them. + # Skip VFs for now since we don't have a reliable way to break them. if [ -e "/sys/bus/pci/devices/$dev/physfn" ] ; then echo "$dev, Skipped: virtfn" continue; fi - if [ "ahci" = "$(basename $(realpath /sys/bus/pci/devices/$dev/driver))" ] ; then - echo "$dev, Skipped: ahci doesn't support recovery" - continue - fi - - # Don't inject errosr into an already-frozen PE. This happens with - # PEs that contain multiple PCI devices (e.g. multi-function cards) - # and injecting new errors during the recovery process will probably - # result in the recovery failing and the device being marked as - # failed. - if ! pe_ok $dev ; then - echo "$dev, Skipped: Bad initial PE state" - continue; - fi - echo "$dev, Added" # Add to this list of device to check @@ -86,5 +53,5 @@ echo "$failed devices failed to recover ($dev_count tested)" lspci | diff -u $pre_lspci - rm -f $pre_lspci -test "$failed" == 0 +test "$failed" -eq 0 exit $? diff --git a/tools/testing/selftests/powerpc/eeh/eeh-functions.sh b/tools/testing/selftests/powerpc/eeh/eeh-functions.sh old mode 100755 new mode 100644 index 00dc32c0ed75..70daa3925dcb --- a/tools/testing/selftests/powerpc/eeh/eeh-functions.sh +++ b/tools/testing/selftests/powerpc/eeh/eeh-functions.sh @@ -1,6 +1,12 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0-only +export KSELFTESTS_SKIP=4 + +log() { + echo >/dev/stderr $* +} + pe_ok() { local dev="$1" local path="/sys/bus/pci/devices/$dev/eeh_pe_state" @@ -39,6 +45,52 @@ eeh_supported() { grep -q 'EEH Subsystem is enabled' /proc/powerpc/eeh } +eeh_test_prep() { + if ! eeh_supported ; then + echo "EEH not supported on this system, skipping" + exit $KSELFTESTS_SKIP; + fi + + if [ ! -e "/sys/kernel/debug/powerpc/eeh_dev_check" ] && \ + [ ! -e "/sys/kernel/debug/powerpc/eeh_dev_break" ] ; then + log "debugfs EEH testing files are missing. Is debugfs mounted?" + exit $KSELFTESTS_SKIP; + fi + + # Bump the max freeze count to something absurd so we don't + # trip over it while breaking things. + echo 5000 > /sys/kernel/debug/powerpc/eeh_max_freezes +} + +eeh_can_break() { + # skip bridges since we can't recover them (yet...) + if [ -e "/sys/bus/pci/devices/$dev/pci_bus" ] ; then + log "$dev, Skipped: bridge" + return 1; + fi + + # The ahci driver doesn't support error recovery. If the ahci device + # happens to be hosting the root filesystem, and then we go and break + # it the system will generally go down. We should probably fix that + # at some point + if [ "ahci" = "$(basename $(realpath /sys/bus/pci/devices/$dev/driver))" ] ; then + log "$dev, Skipped: ahci doesn't support recovery" + return 1; + fi + + # Don't inject errosr into an already-frozen PE. This happens with + # PEs that contain multiple PCI devices (e.g. multi-function cards) + # and injecting new errors during the recovery process will probably + # result in the recovery failing and the device being marked as + # failed. + if ! pe_ok $dev ; then + log "$dev, Skipped: Bad initial PE state" + return 1; + fi + + return 0 +} + eeh_one_dev() { local dev="$1" @@ -46,7 +98,7 @@ eeh_one_dev() { # testing so check that the argument is a well-formed sysfs device # name. if ! test -e /sys/bus/pci/devices/$dev/ ; then - echo "Error: '$dev' must be a sysfs device name (DDDD:BB:DD.F)" + log "Error: '$dev' must be a sysfs device name (DDDD:BB:DD.F)" return 1; fi @@ -70,16 +122,124 @@ eeh_one_dev() { if pe_ok $dev ; then break; fi - echo "$dev, waited $i/${max_wait}" + log "$dev, waited $i/${max_wait}" sleep 1 done if ! pe_ok $dev ; then - echo "$dev, Failed to recover!" + log "$dev, Failed to recover!" return 1; fi - echo "$dev, Recovered after $i seconds" + log "$dev, Recovered after $i seconds" return 0; } +eeh_has_driver() { + test -e /sys/bus/pci/devices/$1/driver; + return $? +} + +eeh_can_recover() { + # we'll get an IO error if the device's current driver doesn't support + # error recovery + echo $1 > '/sys/kernel/debug/powerpc/eeh_dev_can_recover' 2>/dev/null + + return $? +} + +eeh_find_all_pfs() { + devices="" + + # SR-IOV on pseries requires hypervisor support, so check for that + is_pseries="" + if grep -q pSeries /proc/cpuinfo ; then + if [ ! -f /proc/device-tree/rtas/ibm,open-sriov-allow-unfreeze ] || + [ ! -f /proc/device-tree/rtas/ibm,open-sriov-map-pe-number ] ; then + return 1; + fi + + is_pseries="true" + fi + + for dev in `ls -1 /sys/bus/pci/devices/` ; do + sysfs="/sys/bus/pci/devices/$dev" + if [ ! -e "$sysfs/sriov_numvfs" ] ; then + continue + fi + + # skip unsupported PFs on pseries + if [ -z "$is_pseries" ] && + [ ! -f "$sysfs/of_node/ibm,is-open-sriov-pf" ] && + [ ! -f "$sysfs/of_node/ibm,open-sriov-vf-bar-info" ] ; then + continue; + fi + + # no driver, no vfs + if ! eeh_has_driver $dev ; then + continue + fi + + devices="$devices $dev" + done + + if [ -z "$devices" ] ; then + return 1; + fi + + echo $devices + return 0; +} + +# attempts to enable one VF on each PF so we can do VF specific tests. +# stdout: list of enabled VFs, one per line +# return code: 0 if vfs are found, 1 otherwise +eeh_enable_vfs() { + pf_list="$(eeh_find_all_pfs)" + + vfs=0 + for dev in $pf_list ; do + pf_sysfs="/sys/bus/pci/devices/$dev" + + # make sure we have a single VF + echo 0 > "$pf_sysfs/sriov_numvfs" + echo 1 > "$pf_sysfs/sriov_numvfs" + if [ "$?" != 0 ] ; then + log "Unable to enable VFs on $pf, skipping" + continue; + fi + + vf="$(basename $(realpath "$pf_sysfs/virtfn0"))" + if [ $? != 0 ] ; then + log "unable to find enabled vf on $pf" + echo 0 > "$pf_sysfs/sriov_numvfs" + continue; + fi + + if ! eeh_can_break $vf ; then + log "skipping " + + echo 0 > "$pf_sysfs/sriov_numvfs" + continue; + fi + + vfs="$((vfs + 1))" + echo $vf + done + + test "$vfs" != 0 + return $? +} + +eeh_disable_vfs() { + pf_list="$(eeh_find_all_pfs)" + if [ -z "$pf_list" ] ; then + return 1; + fi + + for dev in $pf_list ; do + echo 0 > "/sys/bus/pci/devices/$dev/sriov_numvfs" + done + + return 0; +} diff --git a/tools/testing/selftests/powerpc/eeh/eeh-vf-aware.sh b/tools/testing/selftests/powerpc/eeh/eeh-vf-aware.sh new file mode 100755 index 000000000000..874c11953bb6 --- /dev/null +++ b/tools/testing/selftests/powerpc/eeh/eeh-vf-aware.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only + +. ./eeh-functions.sh + +eeh_test_prep # NB: may exit + +vf_list="$(eeh_enable_vfs)"; +if $? != 0 ; then + log "No usable VFs found. Skipping EEH unaware VF test" + exit $KSELFTESTS_SKIP; +fi + +log "Enabled VFs: $vf_list" + +tested=0 +passed=0 +for vf in $vf_list ; do + log "Testing $vf" + + if ! eeh_can_recover $vf ; then + log "Driver for $vf doesn't support error recovery, skipping" + continue; + fi + + tested="$((tested + 1))" + + log "Breaking $vf..." + if ! eeh_one_dev $vf ; then + log "$vf failed to recover" + continue; + fi + + passed="$((passed + 1))" +done + +eeh_disable_vfs + +if [ "$tested" == 0 ] ; then + echo "No VFs with EEH aware drivers found, skipping" + exit $KSELFTESTS_SKIP +fi + +test "$failed" != 0 +exit $?; diff --git a/tools/testing/selftests/powerpc/eeh/eeh-vf-unaware.sh b/tools/testing/selftests/powerpc/eeh/eeh-vf-unaware.sh new file mode 100755 index 000000000000..8a4c147b9d43 --- /dev/null +++ b/tools/testing/selftests/powerpc/eeh/eeh-vf-unaware.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only + +. ./eeh-functions.sh + +eeh_test_prep # NB: may exit + +vf_list="$(eeh_enable_vfs)"; +if $? != 0 ; then + log "No usable VFs found. Skipping EEH unaware VF test" + exit $KSELFTESTS_SKIP; +fi + +log "Enabled VFs: $vf_list" + +failed=0 +for vf in $vf_list ; do + log "Testing $vf" + + if eeh_can_recover $vf ; then + log "Driver for $vf supports error recovery. Unbinding..." + echo "$vf" > /sys/bus/pci/devices/$vf/driver/unbind + fi + + log "Breaking $vf..." + if ! eeh_one_dev $vf ; then + log "$vf failed to recover" + failed="$((failed + 1))" + fi +done + +eeh_disable_vfs + +test "$failed" != 0 +exit $?; diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 9338df6f4ca8..98c3b647f54d 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -315,7 +315,7 @@ TEST(kcmp) ret = __filecmp(getpid(), getpid(), 1, 1); EXPECT_EQ(ret, 0); if (ret != 0 && errno == ENOSYS) - SKIP(return, "Kernel does not support kcmp() (missing CONFIG_CHECKPOINT_RESTORE?)"); + SKIP(return, "Kernel does not support kcmp() (missing CONFIG_KCMP?)"); } TEST(mode_strict_support)